Skip to content

Issue identifiers

Shipper-managed issues have a local ID. Documentation and new examples use that local ID as the primary identity, written with the S# display token.

Under conventions: "shipper", commit subject scopes follow the repository’s mirror mode.

In mirror-on repositories, use the GitHub issue scope #<ISSUE_NUMBER>:

feat(#137): add session validation

In store-only repositories, use the local Shipper scope s<localId> derived from S#<localId>:

feat(s44): add session validation

Store-only commits should not use the GitHub #<n> subject scope because store-only pull request content validation requires the local s<localId> scope.

Under conventions: "native", Shipper asserts no commit-subject shape. The agent follows the host repository’s explicit guidance and recent history, but it must not emit a GitHub closing reference anywhere in a commit subject or body.

S#<localId> remains the local display identity in Shipper under either posture. Native-posture pull-request titles and bodies do not contain that marker; their issue-to-PR association is read from explicit local state instead of reconstructed from pull-request content or git history.

Use these forms for Shipper issue commands:

FormMeaningExample
S#<n>Shipper local ID. This is the preferred form for local issue identity.shipper next S#42
gh:<n>Explicit GitHub issue number for a mirrored issue.shipper next gh:123
GitHub issue URLExplicit GitHub issue URL.shipper next https://github.com/owner/repo/issues/123

When documentation needs to name both identities for the same issue, Shipper leads with the local ID and annotates the mirror, for example S#42 (GitHub #123).

A bare number resolves as a Shipper local ID first. If local issue S#42 exists, input 42 targets S#42. If no local issue matches the bare number, Shipper falls back to a mapped GitHub issue with that number and prints a notice:

Input 42 did not match a Shipper ID; using mapped GitHub #42 -> S#17.

When the same number matches both a Shipper local ID and a GitHub issue number, the Shipper local ID wins. Use gh:<n> when you mean the GitHub issue number and want to avoid local-first resolution.

S#<n> is accepted verbatim anywhere a Shipper issue reference is accepted. The legacy #<n> form is also accepted for explicit GitHub issue input, but new examples should prefer gh:<n> because #42 is easy to confuse with a bare number.

GitHub issue URLs keep their GitHub meaning:

Terminal window
shipper next https://github.com/owner/repo/issues/123

shipper adopt is the GitHub intake bridge. Adoption happens before an item has a Shipper local ID, so it takes a GitHub issue or pull request reference or URL instead of going through the local-ID resolver. Prefer URLs in examples because they are explicit:

Terminal window
shipper adopt https://github.com/owner/repo/issues/42
shipper adopt https://github.com/owner/repo/pull/17

GitHub pull request numbers are a separate identifier space from Shipper issue identity. Commands that take a PR number keep bare PR-number examples:

Terminal window
shipper pr review 42

When a command accepts either an issue target or a PR target and the docs need to avoid ambiguity, use S#<n> for issue targets and a pull request URL for PR targets:

Terminal window
shipper merge S#42 --dry-run
shipper merge https://github.com/owner/repo/pull/17 --dry-run

CLI, MCP, and desktop issue surfaces are local-ID-primary. GitHub issue numbers remain optional projection metadata for mirrored issues; use S#<n> when you mean the Shipper issue and gh:<n> or a GitHub URL when you explicitly need to refer to the GitHub artifact.