Category: bug (latent) / hygiene · Source: agent session, 2026-07-24 — bash scripts/check-skill-portability.sh --all run against the current tree.
Filed by an agent session. The three hits below are the gate's own verbatim output, not a hand-read of the files.
The three couplings
COUPLING: plugins/playbooks/skills/boris/reference/foundations.md:15: origin/(main|master) -> git worktree add .claude/worktrees/my-worktree origin/main
COUPLING: plugins/work-items/skills/track/actions/start.md:61: origin/(main|master) -> … On `yes`, emit `git checkout -b <type>/<N>-<slug> origin/main` for the user. …
COUPLING: plugins/work-items/skills/track/actions/start.md:65: origin/(main|master) -> … Emit `git checkout -b <type>/<N>-<slug> origin/main` for the user.
Reproduce: bash scripts/check-skill-portability.sh --all.
Why CI is green, and why that is correct
The gate runs in changed-file mode against the PR base ref — scripts/check-skill-portability.sh "origin/$BASE_REF" (.github/workflows/ci.yml:658) — so these surface only when those files are themselves touched, or in --all mode, which nothing runs.
That is deliberate and documented, not an oversight. scripts/check-skill-portability.sh header:
Changed-FILE (not whole-skill-dir) scoping keeps a PR responsible only for the files it actually edits, so enabling a token class never red-lines main […] existing violations wait for the owning follow-up fix or the file's next edit.
and ci.yml:636-638:
enabling a token class prevents NEW coupling without red-lining existing violations that member issues own.
What is actually missing: an owner
That design assumes each pre-existing violation has an owning issue. These three do not. All 19 members of the #531 coupling class were checked (#404 #405 #406 #408 #410 #412 #415 #416 #418 #421 #422 #423 #428 #429 #432 #438 #439 #441 #442) — the closest are #442 (origin remote name in source-control:pull-request) and #415/#418 (planning's branch grammar and tracker writes). None covers plugins/playbooks/skills/boris or plugins/work-items/skills/track.
So this is the owning follow-up the gate's own header points at, filed to close the assumption rather than to relitigate the scoping decision.
Resolutions
Each site takes one of the script's three documented escapes — a co-located detection-first branch-resolution command, a portability-ok: <reason> comment at the site, or a portability-scope: <reason> declaration in the file. Per-site read, offered as a starting point rather than a verdict:
work-items/track/actions/start.md:61,65 — the skill emits git checkout -b <type>/<N>-<slug> origin/main for the user on a tracker-agnostic path, and the surrounding action already runs bash for branch detection. A detection-first resolution ladder (origin/HEAD / symbolic-ref / merge-base / PR baseRefName) co-located on the line is the fix the gate is asking for; an escape comment here would record a default nobody chose.
playbooks/skills/boris/reference/foundations.md:15 — this is a fenced example inside a mirror of upstream howborisusesclaudecode.com content, where the example command is the upstream author's, not this repo's recommendation. Rewriting it would make the mirror diverge from its source. Either escape may be right; the choice is a judgment about what that file is, and the owners hold it.
Note for whoever fixes this: #624 will tighten the escape grammar (standalone-comment-only matching, required nonempty reason). Any portability-ok: / portability-scope: written here should already satisfy that form so it does not need a second pass.
Relations
#531 (umbrella), #620 (the branch-class gate engine that flags these), #624 / #611 (escape-hatch grammar, affects any escape chosen above).
Category: bug (latent) / hygiene · Source: agent session, 2026-07-24 —
bash scripts/check-skill-portability.sh --allrun against the current tree.Filed by an agent session. The three hits below are the gate's own verbatim output, not a hand-read of the files.
The three couplings
Reproduce:
bash scripts/check-skill-portability.sh --all.Why CI is green, and why that is correct
The gate runs in changed-file mode against the PR base ref —
scripts/check-skill-portability.sh "origin/$BASE_REF"(.github/workflows/ci.yml:658) — so these surface only when those files are themselves touched, or in--allmode, which nothing runs.That is deliberate and documented, not an oversight.
scripts/check-skill-portability.shheader:and
ci.yml:636-638:What is actually missing: an owner
That design assumes each pre-existing violation has an owning issue. These three do not. All 19 members of the #531 coupling class were checked (#404 #405 #406 #408 #410 #412 #415 #416 #418 #421 #422 #423 #428 #429 #432 #438 #439 #441 #442) — the closest are #442 (
originremote name insource-control:pull-request) and #415/#418 (planning's branch grammar and tracker writes). None coversplugins/playbooks/skills/borisorplugins/work-items/skills/track.So this is the owning follow-up the gate's own header points at, filed to close the assumption rather than to relitigate the scoping decision.
Resolutions
Each site takes one of the script's three documented escapes — a co-located detection-first branch-resolution command, a
portability-ok: <reason>comment at the site, or aportability-scope: <reason>declaration in the file. Per-site read, offered as a starting point rather than a verdict:work-items/track/actions/start.md:61,65— the skill emitsgit checkout -b <type>/<N>-<slug> origin/mainfor the user on a tracker-agnostic path, and the surrounding action already runs bash for branch detection. A detection-first resolution ladder (origin/HEAD/symbolic-ref/merge-base/ PRbaseRefName) co-located on the line is the fix the gate is asking for; an escape comment here would record a default nobody chose.playbooks/skills/boris/reference/foundations.md:15— this is a fenced example inside a mirror of upstreamhowborisusesclaudecode.comcontent, where the example command is the upstream author's, not this repo's recommendation. Rewriting it would make the mirror diverge from its source. Either escape may be right; the choice is a judgment about what that file is, and the owners hold it.Note for whoever fixes this: #624 will tighten the escape grammar (standalone-comment-only matching, required nonempty reason). Any
portability-ok:/portability-scope:written here should already satisfy that form so it does not need a second pass.Relations
#531 (umbrella), #620 (the branch-class gate engine that flags these), #624 / #611 (escape-hatch grammar, affects any escape chosen above).