Problem
The get-ticket-id skill (Bash script) and the get-session-context skill (zero-Bash inline spec) implement parallel ticket-ID extraction logic that diverges on multiple axes:
- Case sensitivity:
get-ticket-id matches [A-Z]+-[0-9]+ (case-sensitive); get-session-context matches case-insensitively and uppercase-normalizes.
- Author/scope prefixes:
get-ticket-id matches anywhere in the branch (so wt/COMPPLAN-795 → COMPPLAN-795); get-session-context is start-anchored and explicitly returns null for author-prefixed branches.
- Sub-ticket suffix
.N: both skills currently capture .N as part of the ID, but .N has no semantic meaning (it doesn't correspond to a real Jira reference) and has never been used in this project's branches.
Two skills purporting to extract "the ticket ID from a branch name" can disagree on the same input. Most visibly: lowercase project keys (wt/mac-130) yield divergent results.
Context
ticket_id is consumed by both skills' downstream callers — artifact path namespacing, PR rendering, external ticket lookups. Inconsistent extraction means callers can see different IDs depending on which skill they invoke.
.N capture is vestigial — it has been in the regex since the initial agents-workspace commit (CODY-46) without documented design intent and is not used in any branch. Jira has no decimal-sub-ticket concept, so .N IDs cannot be looked up externally; preserving them only causes downstream lookups to fail.
Solution
Establish a single canonical extraction contract, documented in a shared spec file that both skills cite. Update both implementations to match.
Canonical contract:
- Pattern (case-insensitive):
[A-Za-z]{2,}-[0-9]+ — first occurrence anywhere in the branch name wins.
- Output: uppercased.
- Trailing
.N (sub-ticket) and -description suffixes are tolerated in input but not part of the canonical ID. The greedy-digit regex naturally stops at . and -letter boundaries.
Behavior table:
| Input |
Output |
MAC-130 |
MAC-130 |
mac-130 |
MAC-130 |
wt/compPlaN-795 |
COMPPLAN-795 |
wthorsen/MAC-130 |
MAC-130 |
wt/jira-123.1-some-suffix |
JIRA-123 |
jira-123-1 |
JIRA-123 |
MAC-147-some-description |
MAC-147 |
feat-2 |
FEAT-2 |
feat/foo-2 |
FOO-2 |
main |
(empty) |
Files affected:
packages/agents/content/skills/_data/ticket-id-extraction.md (new): canonical spec
packages/agents/content/scripts/get-ticket-id.sh: regex update in extract_jira_id
packages/agents/content/skills/get-ticket-id/SKILL.md: cite spec; update commit-message extraction snippet
packages/agents/content/skills/get-session-context/SKILL.md: relax start-anchor; drop .N; remove "author-prefixed branches return null" constraint and edge case; update worked example 6; add author-prefixed worked example; cite spec
packages/agents/content/scripts/__tests__/get_ticket_id_test.sh: invert/replace tests that assumed case-sensitivity or .N preservation; add positive coverage
The extract_bare_number fallback and ticket_ref_prefix handling in get-ticket-id.sh are unchanged — those serve #-style projects and are orthogonal to the Jira-style alignment.
Acceptance criteria
Problem
The
get-ticket-idskill (Bash script) and theget-session-contextskill (zero-Bash inline spec) implement parallel ticket-ID extraction logic that diverges on multiple axes:get-ticket-idmatches[A-Z]+-[0-9]+(case-sensitive);get-session-contextmatches case-insensitively and uppercase-normalizes.get-ticket-idmatches anywhere in the branch (sowt/COMPPLAN-795 → COMPPLAN-795);get-session-contextis start-anchored and explicitly returnsnullfor author-prefixed branches..N: both skills currently capture.Nas part of the ID, but.Nhas no semantic meaning (it doesn't correspond to a real Jira reference) and has never been used in this project's branches.Two skills purporting to extract "the ticket ID from a branch name" can disagree on the same input. Most visibly: lowercase project keys (
wt/mac-130) yield divergent results.Context
ticket_idis consumed by both skills' downstream callers — artifact path namespacing, PR rendering, external ticket lookups. Inconsistent extraction means callers can see different IDs depending on which skill they invoke..Ncapture is vestigial — it has been in the regex since the initial agents-workspace commit (CODY-46) without documented design intent and is not used in any branch. Jira has no decimal-sub-ticket concept, so.NIDs cannot be looked up externally; preserving them only causes downstream lookups to fail.Solution
Establish a single canonical extraction contract, documented in a shared spec file that both skills cite. Update both implementations to match.
Canonical contract:
[A-Za-z]{2,}-[0-9]+— first occurrence anywhere in the branch name wins..N(sub-ticket) and-descriptionsuffixes are tolerated in input but not part of the canonical ID. The greedy-digit regex naturally stops at.and-letterboundaries.Behavior table:
MAC-130MAC-130mac-130MAC-130wt/compPlaN-795COMPPLAN-795wthorsen/MAC-130MAC-130wt/jira-123.1-some-suffixJIRA-123jira-123-1JIRA-123MAC-147-some-descriptionMAC-147feat-2FEAT-2feat/foo-2FOO-2mainFiles affected:
packages/agents/content/skills/_data/ticket-id-extraction.md(new): canonical specpackages/agents/content/scripts/get-ticket-id.sh: regex update inextract_jira_idpackages/agents/content/skills/get-ticket-id/SKILL.md: cite spec; update commit-message extraction snippetpackages/agents/content/skills/get-session-context/SKILL.md: relax start-anchor; drop.N; remove "author-prefixed branches return null" constraint and edge case; update worked example 6; add author-prefixed worked example; cite specpackages/agents/content/scripts/__tests__/get_ticket_id_test.sh: invert/replace tests that assumed case-sensitivity or.Npreservation; add positive coverageThe
extract_bare_numberfallback andticket_ref_prefixhandling inget-ticket-id.share unchanged — those serve#-style projects and are orthogonal to the Jira-style alignment.Acceptance criteria
get-ticket-id.sh.get-session-contextspec._data/ticket-id-extraction.mdexists and is the single source of truth; bothget-ticket-id/SKILL.mdandget-session-context/SKILL.mdcite it.get-session-context/SKILL.mdno longer states that author-prefixed branches returnnull.