Problem
Original suggestion (verbatim):
「我在想 idd 要能夠支持 submodule 的設定,可能最上層的 idd 設定可以用來調整 submodule 吧?」
When working inside a git submodule, IDD's walked-up config resolution (Step 0.5.B) finds the parent repo's .claude/issue-driven-dev.local.json and uses its github_repo field — which targets the parent repo, not the submodule. The submodule's own GitHub remote is silently ignored.
The user is asking for: the topmost (parent) IDD config could declare per-submodule routing, so a single parent config drives both parent-repo issues and submodule-repo issues without the user having to maintain a separate config file inside each submodule.
Type
feature / enhancement (config-protocol)
Concrete pain point (encountered 2026-05-26)
Setup:
- Parent repo:
PsychQuant/IRT_variacne_bootstrapping_estimtor (code + sims)
- Submodule at
manuscript/parametric_bootstrapping_se/ → remote kiki830621/PB-of-IRT-ability (manuscript)
- Parent config:
article2_standard_error/.claude/issue-driven-dev.local.json → "github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor"
Sequence:
cd manuscript/parametric_bootstrapping_se/05xx-2026/ (inside submodule)
/idd-issue ... for a manuscript-content change
- Step 0.5.B walks up, hits parent config →
GITHUB_REPO = PsychQuant/IRT_variacne_bootstrapping_estimtor (WRONG — should be kiki830621/PB-of-IRT-ability)
- The submodule's own
git remote get-url origin (which would derive the correct target) is ignored because Step 0.5.B's walked-up config wins over derivation
- Workaround: manually create
manuscript/parametric_bootstrapping_se/.claude/issue-driven-dev.local.json with "github_repo": "kiki830621/PB-of-IRT-ability"
Same friction applies to idd-diagnose / idd-implement / idd-verify / idd-close — every IDD skill walking-up from submodule cwd hits the wrong parent config.
Expected
A parent IDD config should be able to declare per-submodule routing in one of these forms (proposing two designs, not mutually exclusive):
Option A — Reuse existing candidates + path predicates (documentation pattern)
The candidates mechanism + path_contains predicate already handles this case; it's a discoverability gap, not a missing feature. Document the pattern explicitly:
{
"github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor",
"candidates": [
{
"label": "Manuscript submodule",
"github_repo": "kiki830621/PB-of-IRT-ability",
"when": { "path_contains": "manuscript/parametric_bootstrapping_se" }
}
]
}
Step 0.5.C predicate pre-resolve already picks the candidate when cwd matches the path. The friction is that users (incl. me today) don't know this pattern handles submodules — README and CLAUDE.md call candidates "monorepo sub-package" routing, not "submodule" routing. Fix could be docs-only.
Option B — Native submodule awareness (submodules field in config schema)
Add a first-class field that consumes the parent repo's .gitmodules and auto-routes:
{
"github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor",
"submodules": {
"manuscript/parametric_bootstrapping_se": {
"github_repo": "kiki830621/PB-of-IRT-ability",
"attachments_release": "attachments"
}
}
}
Or with auto-derive (parse .gitmodules, use submodule's git remote get-url origin):
{
"github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor",
"submodules": "auto"
}
Resolution algorithm: Step 0.5 checks if cwd is inside a registered submodule path → use submodule's mapped github_repo; otherwise fall through to parent's github_repo. The submodule's .claude/ directory does NOT need its own config.
Actual (current behaviour)
The fallback chain in Step 0.5 (config-protocol six mechanisms):
--target flag (per-invocation override) — works but heavyweight
ask_each_time menu — only fires if config has candidates / groups
- Predicate pre-resolve — works if candidates are set up (user has to know)
- Cascading config (walk up) — finds parent config, uses parent's
github_repo (silent wrong target)
- git remote fallback — never reached because step 4 already resolved
- Groups — orthogonal, doesn't help
Submodule users currently must either (a) pass --target ... every invocation, (b) set up candidates manually, or (c) duplicate config inside the submodule. None is discoverable from the failure mode (silent wrong-target).
Impact
- Affects any user with
git subtree/git submodule workflow (e.g. manuscript + code projects, Overleaf-synced manuscripts, multi-repo monorepos)
- Particularly painful when the submodule's GitHub remote differs from parent's owner (cross-org submodules)
- Silent failure mode: target goes to wrong repo, user only notices after issue is filed in wrong place
Proposed scope (please confirm)
Related
config-protocol.md Step 0.5 six-mechanism resolution (this issue proposes extension to mechanism 4)
candidates + path_contains (existing, under-documented for submodule case)
- Pain point context: today's session converted
manuscript/parametric_bootstrapping_se/ from git subtree → git submodule (per parent repo CLAUDE.md update 2026-05-26). The mode switch surfaced this gap.
Problem
When working inside a git submodule, IDD's walked-up config resolution (Step 0.5.B) finds the parent repo's
.claude/issue-driven-dev.local.jsonand uses itsgithub_repofield — which targets the parent repo, not the submodule. The submodule's own GitHub remote is silently ignored.The user is asking for: the topmost (parent) IDD config could declare per-submodule routing, so a single parent config drives both parent-repo issues and submodule-repo issues without the user having to maintain a separate config file inside each submodule.
Type
feature / enhancement (config-protocol)
Concrete pain point (encountered 2026-05-26)
Setup:
PsychQuant/IRT_variacne_bootstrapping_estimtor(code + sims)manuscript/parametric_bootstrapping_se/→ remotekiki830621/PB-of-IRT-ability(manuscript)article2_standard_error/.claude/issue-driven-dev.local.json→"github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor"Sequence:
cd manuscript/parametric_bootstrapping_se/05xx-2026/(inside submodule)/idd-issue ...for a manuscript-content changeGITHUB_REPO = PsychQuant/IRT_variacne_bootstrapping_estimtor(WRONG — should bekiki830621/PB-of-IRT-ability)git remote get-url origin(which would derive the correct target) is ignored because Step 0.5.B's walked-up config wins over derivationmanuscript/parametric_bootstrapping_se/.claude/issue-driven-dev.local.jsonwith"github_repo": "kiki830621/PB-of-IRT-ability"Same friction applies to
idd-diagnose/idd-implement/idd-verify/idd-close— every IDD skill walking-up from submodule cwd hits the wrong parent config.Expected
A parent IDD config should be able to declare per-submodule routing in one of these forms (proposing two designs, not mutually exclusive):
Option A — Reuse existing
candidates+ path predicates (documentation pattern)The
candidatesmechanism +path_containspredicate already handles this case; it's a discoverability gap, not a missing feature. Document the pattern explicitly:{ "github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor", "candidates": [ { "label": "Manuscript submodule", "github_repo": "kiki830621/PB-of-IRT-ability", "when": { "path_contains": "manuscript/parametric_bootstrapping_se" } } ] }Step 0.5.C predicate pre-resolve already picks the candidate when cwd matches the path. The friction is that users (incl. me today) don't know this pattern handles submodules — README and CLAUDE.md call
candidates"monorepo sub-package" routing, not "submodule" routing. Fix could be docs-only.Option B — Native submodule awareness (
submodulesfield in config schema)Add a first-class field that consumes the parent repo's
.gitmodulesand auto-routes:{ "github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor", "submodules": { "manuscript/parametric_bootstrapping_se": { "github_repo": "kiki830621/PB-of-IRT-ability", "attachments_release": "attachments" } } }Or with auto-derive (parse
.gitmodules, use submodule'sgit remote get-url origin):{ "github_repo": "PsychQuant/IRT_variacne_bootstrapping_estimtor", "submodules": "auto" }Resolution algorithm: Step 0.5 checks if cwd is inside a registered submodule path → use submodule's mapped
github_repo; otherwise fall through to parent'sgithub_repo. The submodule's.claude/directory does NOT need its own config.Actual (current behaviour)
The fallback chain in Step 0.5 (config-protocol six mechanisms):
--targetflag (per-invocation override) — works but heavyweightask_each_timemenu — only fires if config has candidates / groupsgithub_repo(silent wrong target)Submodule users currently must either (a) pass
--target ...every invocation, (b) set up candidates manually, or (c) duplicate config inside the submodule. None is discoverable from the failure mode (silent wrong-target).Impact
git subtree/git submoduleworkflow (e.g. manuscript + code projects, Overleaf-synced manuscripts, multi-repo monorepos)Proposed scope (please confirm)
candidates+path_containspattern. Probably 1 commit, zero code changes.submodulesfield in config schema + Step 0.5 resolution algorithm update + tests + docs. Larger; depends on whether maintainer prefers extending schema vs steering users tocandidates.candidates, not insubmodules), emit a warning citing the parent target + suggesting the candidates/submodules pattern — instead of silent wrong-target.Related
config-protocol.mdStep 0.5 six-mechanism resolution (this issue proposes extension to mechanism 4)candidates+path_contains(existing, under-documented for submodule case)manuscript/parametric_bootstrapping_se/fromgit subtree→git submodule(per parent repo CLAUDE.md update 2026-05-26). The mode switch surfaced this gap.