Latent routing collision between cicd-insights and woodpecker-trigger-discipline skills #2
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why: The
cicd-insightsskill's description includes the trigger phrase "trigger hygiene", while the newerwoodpecker-trigger-disciplineskill (v1.4.0) owns the trigger-narrowing/branch-protection domain outright. A fleet-wide "audit our trigger hygiene" request could misroute to the specific skill, or a single-repo trigger question to the broad one.Not observed failing: a discriminability check on the three target phrasings routed to the correct skill clear-cut every time. Filing as a watch item, not a live defect.
Acceptance:
Status: fix shipped, confirmation blocked on a test no automated session can run.
Shipped in v1.4.1 (
f905f55): thecicd-insightsskill description now states it is the broad structural-review skill despite sharing the plugin's name, is not a catch-all, and names the four scenarios belonging towoodpecker-trigger-discipline— a PR that won't merge, a pipeline running twice, a required check that never posts, choosing which checks to require.Why it is not confirmed, and why no more automated attempts should be made. Routing was tested three times across two mechanisms, and every result was invalid:
/reload-plugins, three fresh subagents routed all three phrasings to the sibling skill. That measured availability — an availability probe returned no woodpecker skill at all./reload-plugins, 2 of 3 routed correctly, with the P1 phrasing ("why won't this PR merge") going to the sibling. This is what prompted the 1.4.1 redirect.So the redirect clause was shipped on evidence that did not support it. It stands on its own merits (an umbrella skill sharing the plugin's name should say what it is not), but it is unverified, and it is possible nothing was broken.
What actually closes this — three real interactive sessions, one phrasing each, checking which skill loads:
This is spec SC-003. What was validated: the descriptions are discriminable — presented verbatim to a fresh reader alongside all four sibling descriptions, all three phrasings were assigned to
woodpecker-trigger-disciplineclear-cut. That tests the text, not the router.If all three load the right skill, close this. If any misses, the description is the lever and the phrase set is already exhaustive enough that the next step is narrowing the sibling, not widening this one.
SC-003 PASSES — 3/3, with negative controls.
The mechanism (why the previous three attempts were invalid and this isn't)
The prior runs used subagents, whose skill listing carries names but not frontmatter descriptions — and routing is description-driven, so those runs measured availability and name-matching instead. The handoff concluded from this that only a human could run SC-003.
That conclusion was slightly too strong: it rules out subagents, not every non-interactive mechanism. A headless CLI session (
claude -p) is a real session with the real plugin-loading machinery, not a subagent. Each phrasing was run in its own fresh session, in an empty scratch directory with no git repo, with--allowedTools Skillso nothing could act, capturing--output-format stream-json.Results
cicd-insights:woodpecker-trigger-discipline✅cicd-insights:woodpecker-trigger-discipline✅cicd-insights:woodpecker-trigger-discipline✅Negative controls — the part that makes the above mean something:
A test where everything routes to the target skill would show 3/3 and prove nothing. These don't.
Why this is description-driven, not name-matching
This is the specific artifact that invalidated Run 2, so it's worth ruling out explicitly: "why won't this PR merge?" and "which status checks should I require on main?" share no lexical overlap with the string
woodpecker-trigger-discipline. Neither contains "woodpecker", "trigger", or "discipline". They are near-verbatim entries in the skill'sdescription. So routing cannot be explained by the name alone — the description is doing the work, which is exactly what SC-003 set out to confirm.Bonus: the v1.4.1 redirect clause is vindicated
P1 is the phrasing that previously routed to the sibling
cicd-insightsskill and prompted the redirect clause. It now routes correctly. The handoff flagged that clause as "shipped on invalid evidence, riskiest change to sanity-check" — it holds up, and the sibling did not under-fire.Caveat, stated plainly
This is a headless session, not a human at an interactive prompt. The skill-loading machinery is the same and the negative controls discriminate, so I consider it a valid measurement of SC-003 — but if you want the belt-and-braces version, typing the three phrasings interactively should reproduce it in about a minute.
Verified against
cicd-insights1.4.6, whose installedSKILL.mdat~/.claude/plugins/cache/oleks-local/cicd-insights/1.4.6/was confirmed byte-identical to the repo with intact frontmatter (i.e. not affected by the oleks/claude-plugin-cicd-insights#1 corruption).