Summary
Three defects in the shared convention-home resolver and in the resolution ladder that every consuming skill restates. All three are pre-existing and none of them belongs to any one consuming slice, so they are filed here rather than against a container.
1. A UTF-8 BOM makes a bound pointer region invisible (exit 1)
scripts/../plugins/*/lib/resolve-convention-home.sh scans for <!-- BEGIN GENERATED: convention-home -->. Its trim() strips [:space:], which does not include the UTF-8 byte-order mark, so a BOM immediately before the marker leaves the line unmatched and the file is reported as carrying no region at all.
Reproduced on main at a175a0362. The two runs below differ only by the three leading bytes EF BB BF:
$ head -c 16 "$T/AGENTS.md" | od -c
0000000 357 273 277 < ! - - B E G I N G E
$ bash plugins/planning/lib/resolve-convention-home.sh --root "$T"
no convention-home region in AGENTS.md or CLAUDE.md under ...; ask the operator for the home
EXIT=1
With the BOM removed and nothing else changed:
$ bash plugins/planning/lib/resolve-convention-home.sh --root "$T"
docs/conventions
EXIT=0
Fixture content in both runs:
<!-- BEGIN GENERATED: convention-home -->
`docs/conventions`
<!-- END GENERATED: convention-home -->
Exit 1 is documented as "no pointer line is bound", so a consuming skill takes its soft degrade and serves the default silently. A team whose AGENTS.md is BOM-prefixed, which several Windows editors produce by default, gets its convention ignored with no diagnostic naming the cause. The script is a synced carrier, so the fix belongs in the canonical copy and propagates through scripts/sync-resolve-convention-home.sh.
2. The ladder's step 3 path is cwd-relative as written
The resolution ladder tells a consuming agent to read <home>/authoring-formats/README.md. It never says that the value the resolver prints is repo-relative and must be joined to the root resolved in step 1. An agent whose working directory is not the repository root follows the instruction literally and opens whatever docs/conventions/authoring-formats/README.md exists relative to where it happens to be standing. In the verification run for #3926, that silently opened the publishing repository's own convention document instead of the fixture's, and produced a plausible-looking answer from the wrong file.
The wording is inherited from the copyable ladder block in docs/conventions/authoring-formats/README.md, so the same gap ships in plugins/planning/skills/interview/SKILL.md, plugins/planning/skills/prd/SKILL.md, and plugins/planning/skills/design/SKILL.md. Fixing the owner block and resweeping the three restatements keeps one owner.
Related: the ladder never mentions --root, so step 1's resolved anchor cannot be handed to step 2. This is narrower than it appears, because the script implements the same anchor internally through CLAUDE_PROJECT_DIR, then git top level, then cwd. It only bites when CLAUDE_PROJECT_DIR is unset, the tree is not a git repository, and the working directory is below the root.
3. Exit 3 is described as "grammar failures" but also covers a missing target directory
The exit contract restated in the consuming skills calls exit 3 a grammar failure. A pointer whose target directory does not exist also exits 3, with the message pointer target directory missing. The behaviour is right and step 6 of the ladder already lists "no convention home on disk" as a degrade, so this is a wording defect in the restated contract, not a code defect. It ships identically in interview, prd, and design.
A smaller sibling: "exit 0 prints the home" does not say the home goes to stdout. A caller that captures with $(... 2>&1) and has divergent regions in both root files gets the diagnostic line prepended to the value.
Acceptance criteria
Context
Found by the independent verifier that attacked PR #3926 (issue #3924, the design-skill resolver text). None of these reproduces #3924's symptom, so they did not block that merge; defect 1 was reproduced independently before filing, and defect 2 was observed during that verification run.
Refs #3924, #3926
Summary
Three defects in the shared convention-home resolver and in the resolution ladder that every consuming skill restates. All three are pre-existing and none of them belongs to any one consuming slice, so they are filed here rather than against a container.
1. A UTF-8 BOM makes a bound pointer region invisible (exit 1)
scripts/../plugins/*/lib/resolve-convention-home.shscans for<!-- BEGIN GENERATED: convention-home -->. Itstrim()strips[:space:], which does not include the UTF-8 byte-order mark, so a BOM immediately before the marker leaves the line unmatched and the file is reported as carrying no region at all.Reproduced on
mainata175a0362. The two runs below differ only by the three leading bytesEF BB BF:With the BOM removed and nothing else changed:
Fixture content in both runs:
Exit 1 is documented as "no pointer line is bound", so a consuming skill takes its soft degrade and serves the default silently. A team whose
AGENTS.mdis BOM-prefixed, which several Windows editors produce by default, gets its convention ignored with no diagnostic naming the cause. The script is a synced carrier, so the fix belongs in the canonical copy and propagates throughscripts/sync-resolve-convention-home.sh.2. The ladder's step 3 path is cwd-relative as written
The resolution ladder tells a consuming agent to read
<home>/authoring-formats/README.md. It never says that the value the resolver prints is repo-relative and must be joined to the root resolved in step 1. An agent whose working directory is not the repository root follows the instruction literally and opens whateverdocs/conventions/authoring-formats/README.mdexists relative to where it happens to be standing. In the verification run for #3926, that silently opened the publishing repository's own convention document instead of the fixture's, and produced a plausible-looking answer from the wrong file.The wording is inherited from the copyable ladder block in
docs/conventions/authoring-formats/README.md, so the same gap ships inplugins/planning/skills/interview/SKILL.md,plugins/planning/skills/prd/SKILL.md, andplugins/planning/skills/design/SKILL.md. Fixing the owner block and resweeping the three restatements keeps one owner.Related: the ladder never mentions
--root, so step 1's resolved anchor cannot be handed to step 2. This is narrower than it appears, because the script implements the same anchor internally throughCLAUDE_PROJECT_DIR, then git top level, then cwd. It only bites whenCLAUDE_PROJECT_DIRis unset, the tree is not a git repository, and the working directory is below the root.3. Exit 3 is described as "grammar failures" but also covers a missing target directory
The exit contract restated in the consuming skills calls exit 3 a grammar failure. A pointer whose target directory does not exist also exits 3, with the message
pointer target directory missing. The behaviour is right and step 6 of the ladder already lists "no convention home on disk" as a degrade, so this is a wording defect in the restated contract, not a code defect. It ships identically in interview, prd, and design.A smaller sibling: "exit 0 prints the home" does not say the home goes to stdout. A caller that captures with
$(... 2>&1)and has divergent regions in both root files gets the diagnostic line prepended to the value.Acceptance criteria
scripts/sync-resolve-convention-home.sh --check.docs/conventions/authoring-formats/README.mdand in all three planning restatements.Context
Found by the independent verifier that attacked PR #3926 (issue #3924, the design-skill resolver text). None of these reproduces #3924's symptom, so they did not block that merge; defect 1 was reproduced independently before filing, and defect 2 was observed during that verification run.
Refs #3924, #3926