Skip to content

Support a PR number as the branch and artifact identifier when no ticket exists #950

Description

@williamthorsen

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

  • A PR-{n} value is accepted as the branch-derived ticket_id and names the tickets/{ticket_id}/ artifact subdirectory.
  • When the ticket_id is a PR-{n} sentinel, no ticket_url is constructed from a configured ticket base URL.
  • Existing forms (Jira keys, bare GitHub issue numbers) resolve exactly as before.
  • PR-{n} is documented as a recognized identifier form in the get-ticket-id skill and the ticket-ID extraction contract.
  • New and modified behavior is covered by tests.

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:agents

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions