Problem
A pull request sometimes exists without a backing ticket (common when a colleague opens a PR against a Jira-tracked project without filing an issue). The branch-derived ticket_id that names the branch and the tickets/{ticket_id}/ artifact subdirectory only accommodates ticket IDs, so a ticketless PR has no clean identifier: no derivable branch name, no artifact home, no stable reference.
Context
ticket_id is derived from the branch name by get-ticket-id and derive-session-context. It is effectively a work identifier: today always a ticket ID, but the value that names the branch and artifact home need not be one (design-and-plan already generates a {YYYYMMDD}-{hex} value when no ticket exists). A PR is a third form.
PR-{n} (e.g. PR-123) already matches the Jira-style extraction pattern [A-Za-z]{2,}-[0-9]+, so it flows through as a valid ticket_id with no change to extraction. The manifest already separates ticket_url from pr_url.
The one interference point: in repos with a configured ticket.base_url (Jira), compose-manifest builds ticket_url by joining that base with the ticket_id. For a PR-{n} value this produces a bogus link to a nonexistent ticket (e.g. .../browse/PR-123).
Renaming ticket_id to a dedicated work identifier is the larger, correct follow-up (#952); this ticket keeps the existing field and stores a PR-{n} value in it.
Proposed solution
Adopt PR-{n} as the identifier form for a ticketless PR, not a bare number (which collides with GitHub issue numbers and is misread as a Jira key by the bare-number fallback). Because PR-{n} already rides the existing extraction, the branch name and artifact subdirectory work unchanged.
Add a guard in the ticket-URL derivation: when the ticket_id is a PR-{n} sentinel, no ticket_url is constructed from a configured ticket base URL (it stays null).
Seeding pr_url from the PR number (so review flows auto-resolve the PR) is out of scope; tracked as a follow-up.
Acceptance criteria
Must have
Problem
A pull request sometimes exists without a backing ticket (common when a colleague opens a PR against a Jira-tracked project without filing an issue). The branch-derived
ticket_idthat names the branch and thetickets/{ticket_id}/artifact subdirectory only accommodates ticket IDs, so a ticketless PR has no clean identifier: no derivable branch name, no artifact home, no stable reference.Context
ticket_idis derived from the branch name byget-ticket-idandderive-session-context. It is effectively a work identifier: today always a ticket ID, but the value that names the branch and artifact home need not be one (design-and-planalready generates a{YYYYMMDD}-{hex}value when no ticket exists). A PR is a third form.PR-{n}(e.g.PR-123) already matches the Jira-style extraction pattern[A-Za-z]{2,}-[0-9]+, so it flows through as a validticket_idwith no change to extraction. The manifest already separatesticket_urlfrompr_url.The one interference point: in repos with a configured
ticket.base_url(Jira),compose-manifestbuildsticket_urlby joining that base with theticket_id. For aPR-{n}value this produces a bogus link to a nonexistent ticket (e.g..../browse/PR-123).Renaming
ticket_idto a dedicated work identifier is the larger, correct follow-up (#952); this ticket keeps the existing field and stores aPR-{n}value in it.Proposed solution
Adopt
PR-{n}as the identifier form for a ticketless PR, not a bare number (which collides with GitHub issue numbers and is misread as a Jira key by the bare-number fallback). BecausePR-{n}already rides the existing extraction, the branch name and artifact subdirectory work unchanged.Add a guard in the ticket-URL derivation: when the
ticket_idis aPR-{n}sentinel, noticket_urlis constructed from a configured ticket base URL (it stays null).Seeding
pr_urlfrom the PR number (so review flows auto-resolve the PR) is out of scope; tracked as a follow-up.Acceptance criteria
Must have
PR-{n}value is accepted as the branch-derivedticket_idand names thetickets/{ticket_id}/artifact subdirectory.ticket_idis aPR-{n}sentinel, noticket_urlis constructed from a configured ticket base URL.PR-{n}is documented as a recognized identifier form in theget-ticket-idskill and the ticket-ID extraction contract.