Skip to content

shipper groom

Usage: shipper groom [options] [issue]

Groom an existing issue

ArgumentRequiredDescriptionChoices
[issue]noShipper issue ID, gh:, or GitHub URL-
LongShortValueDefaultDescriptionChoices
—auto--falsegroom all eligible shipper:new issues in sequence-
—takeover--falsetransfer a foreign or unowned saved question session before resuming-
—refresh-pr-overlaps--falsereplace the frozen PR overlap snapshot for an existing saved session-
—mode-defaultexecution mode: headless, interactive, or defaultheadless, interactive, default
—agent--agent to use: claude, codex, copilot, grok, or opencodeclaude, codex, copilot, grok, opencode
—model--model to use for the agent CLI-
—reasoning-effort--reasoning effort to pass to the agent CLI-
—disable-mcp---disable MCP server loading for this run-
—enable-mcp---enable MCP server loading for this run-

Groom S#42.

Terminal window
shipper groom S#42

Transfer a foreign or unowned saved session, then resume it.

Terminal window
shipper groom S#42 --takeover

Replace the frozen PR overlap snapshot without resetting the saved session.

Terminal window
shipper groom S#42 --refresh-pr-overlaps

Groom all eligible new issues in sequence.

Terminal window
shipper groom --auto
CodeWhen
0The stage completes successfully or returns a reject verdict.
1Preflight, validation, GitHub, agent, or fail verdict handling fails.
75Headless grooming is awaiting answers; durable question progress may be resumed by a later ordinary groom.
79Clean GitHub-outage waiting is exhausted. The issue retains its stage and remains eligible in a later run.
82An attended TTY agent session actually starts but ends without complete valid artifacts. The issue retains its entry stage as a neutral operator cancellation.
  • —disable-mcp and —enable-mcp are mutually exclusive
  • After an attended TTY agent session actually starts, Shipper validates its artifacts once. Complete valid artifacts finish normally even after a nonzero agent exit; missing, partial, or invalid artifacts cancel with exit 82. Cancellation retains the entry stage with null repository-safety impact, runs no correction or agent retry, creates no failed or recovery state, and requires no recovery action. Saved headless groom questions remain resumable. Committed workflow-branch HEAD is reused with continuation context on a later invocation while uncommitted work is removed during teardown. Compound next, ship, and automatic grooming runs start no later stage or issue after cancellation. This terminal outcome is distinct from the resumable exit-75 pause. Non-interactive runs retain their bounded output correction, retry, failure, and recovery behavior.
  • —auto and an explicit issue argument are mutually exclusive
  • A no-flag headless groom resumes a saved question session only when the caller has the same coarse owner surface: Desktop, MCP, or terminal. Suspension is repeatable without limit and exits 75 without marking the issue failed. The message states whether answered rounds and the pending batch, answered rounds only, or no progress were durably preserved.
  • A foreign or legacy unowned saved session refuses ordinary grooming before worktree or workflow mutation. The safe refusal reports only issue identity, owner or unowned, last-saved time, answered-round count, and whether a pending batch exists; it never returns question, answer, transcript, or note content.
  • --takeover requires an explicit issue and cannot be combined with --auto. It permanently transfers a foreign or unowned session to the caller surface and resumes it in the same command. Because takeover transfers another surface’s saved answers, confirm it with the human operator first.
  • --refresh-pr-overlaps requires an explicit issue with a valid saved grooming session and cannot be combined with --auto. Without a saved session it refuses before hooks, worktree preparation, run history, GitHub inspection, or workflow mutation. It may be combined with --takeover; ownership transfers before replacement.
  • A fresh direct groom captures one timestamped PR-overlap snapshot. Ordinary resume, question answering, takeover without refresh, correction, next, automatic grooming, ship, and auto-ship reuse it unchanged. Refresh preserves the transcript, pending batch, notes, answered and maximum round counts, owner, creation time, original issue fingerprint, and prior product decisions while replacing only active overlap evidence and the session update time.
  • Eligibility is recalculated from the current issue body on refresh. Only recognizable repository-relative individual files explicitly named in Starting Point qualify; optional :line[:column] and #Lx[-Lx] references are ignored. Directories, globs, URLs, prose, inferred files, traversal, and missing files do not qualify. Matching is exact and case-sensitive; for a reported rename either old or new path can match and both are disclosed.
  • Every open same-repository pull request is eligible, including drafts and non-default target branches; closed and merged pull requests are excluded. Evidence includes only PR number, title, link, draft state, source/target branches, exact matches, rename pairs, and capture time—not authorship, review state, checks, labels, or diff content.
  • Coverage is always labeled as one of four outcomes: complete (including complete with no overlaps), not evaluable because no eligible Starting Point files exist, unavailable with a reason, or partial with known overlaps and every limitation. Partial and unavailable are never described as no overlaps. Refresh makes even a partial, unavailable, or not-evaluable result active, marks only the immediately previous capture superseded, and discloses capture time plus added/removed eligible paths.
  • Overlap evidence is advisory-only. Detection alone never blocks, sequences, removes scope, or changes a requirement; the product owner is asked only when a premise, requirement, or delivery order could plausibly change. Final summaries retain only overlaps that prompted a question or materially informed a decision, with provenance and capture time, and never list pull requests under Related Issues.
  • The same behavior applies in mirror-on and store-only repositories when effective policy permits GitHub transport and pull requests. Effective transport: none, pullRequests: none, unresolved policy/origin, transport failure, and bounded API limitations produce truthful unavailable or partial evidence and grooming continues; store-only issue lifecycle authority remains local.
  • Takeover is unavailable while another issue run is live. Missing, stale, operator-pause, and queued-reservation states do not block transfer, and elapsed time never authorizes or prevents takeover.
  • Resume retains the original transcript, pending batch, grooming notes, and captured question-round limit. Rounds already answered remain spent. It always reports elapsed saved time, which is informational: sessions have no age-based expiry.
  • Cross-issue results and the recorded-blocker baseline are regenerated on every resume. If the issue title or body changed, Shipper discloses the drift and tells the agent to revisit affected answers while preserving prior decisions that still apply.
  • A saved session is warned about, discarded, and replaced with a fresh start only when it belongs to another repository or issue, the issue is no longer at the New grooming entry stage, or the record is unreadable or invalid. Successful grooming clears it.
  • Ordinary authored questions are the only grooming question item. Every batch is answered by supplying one authored answer for each stable question id; there are no decision or provenance cards, veto controls, or batch-level confirmation actions.
  • A saved session that still holds the removed compact-confirmation format is incompatible. Shipper discards only that session file, explains that grooming must restart for the issue, and never transforms or resumes the removed format. An ordinary-question-only saved session keeps its existing transcript, stable question ids, ownership, pause, and resume behavior.
  • Interactive shipper groom in an external terminal asks its product questions directly in the live agent session using the agent’s native questions. Answers and any follow-up questions stay in that same session: it does not create a new deferred question-file checkpoint and does not relaunch the agent between answer rounds. On macOS, that attended session stays idle-sleep protected even while the native agent may be waiting for an answer; headless and orchestrated operator-answer waits release protection. See Keep the Mac awake during active work.
  • An already-saved terminal-owned question session remains usable. Its transcript, grooming notes, and pending batch are materialized into the worktree as read-only context, the live session resolves any pending decisions through native questions, cancellation or failure retains the record, and only successful grooming clears it. A foreign or unowned session still requires explicit takeover.
  • Automatic and non-deliberate grooming routes never take over. groom --auto, next, ship, and auto-ship report a neutral stand-down for a foreign or unowned session, leave the issue at New, preserve the session and failed/safety state, and continue draining later issues.
  • Grooming requires an initialized local issue-state replica for its local cross-issue scan; run shipper issue reconcile --repair if the replica is unavailable.
  • The automated cross-issue scan uses one locally prepared index containing every other live Shipper-managed issue at every open workflow stage and, only in mirror-on, open unadopted GitHub-only issues. The current issue, closed managed issues, and tombstones are never candidates. Every entry carries the same bounded 512-character body skim and references a local detail file holding only that issue’s full body; the agent performs no live GitHub lookup during the scan.
  • A managed candidate contributes only its current title, current body, current workflow stage, and current blockers. Its accumulated workflow-event history is never supplied as cross-issue evidence.
  • The mirror-on unmanaged sweep suppresses any same-repository issue recognized by Shipper’s current mirror identity or remembered import origin. It includes at most the fixed 100 most recently updated unmanaged issues and reports complete, truncated, or unavailable managed-only coverage in the prepared index and grooming summary. The bound is not configurable.
  • Store-only performs no unmanaged sweep or adoption-origin lookup and retains its fully offline managed-only context. A failure limited to the supplemental mirror-on sweep does not fail grooming; it discards partial unmanaged results and explicitly reports managed-only coverage.
  • An unadopted GitHub-only entry contributes its GitHub number, title, and the shared bounded body skim in the index, with its full body in groom-issue-details/github-<number>.json; it carries no Shipper identifier, workflow attributes, comments, or placeholder managed fields.
  • An unadopted GitHub-only issue may be classified as Duplicate, but closure still requires explicit product-owner confirmation and records its GitHub number without adopting the target.
  • Only product-owner answers obtained through the current grooming session’s question mechanism settle product decisions. Decisions recorded in another open issue, workflow note, or other outside record are advisory: they may inform orientation and questions, but they never bind the result. When one is needed to settle the current result, ask an ordinary question in the current session. Shipped behavior is a current fact grooming must account for. The # Request remains authoritative only for the unchanged record of what was asked.
  • Behavior observed directly in the current product is a factual baseline, and unchanged observed behavior is never reconfirmed merely to establish it.
  • In a groom manifest, declare an existing Shipper-managed prerequisite as { "type": "shipper", "issue_ref": "S#17" }; issue_ref also accepts a bare positive integer or digit string.
  • Bare native grooming references resolve as a Shipper local ID first and as a mapped GitHub issue number second. Active matches become the same ordinary local Shipper blocker in mirror-on and store-only modes.
  • Grooming receives the issue’s recorded blockers and restates the complete final blocker set. Omission releases a recorded blocker; no separate removal or union mechanism applies.
  • Explicit prerequisite reconciliation is separate from broad cross-issue discovery. A recorded prerequisite already closed as completed is satisfied automatically, a recorded not-planned prerequisite stays unresolved until the product owner chooses a replacement or removal, and neither appears as a discovered related issue merely because it is closed.
  • Only prerequisites closed as completed are absorbed and noted as satisfied at post-flight. A stated not_planned prerequisite remains a blocker; missing references fail grooming.
  • Each parent and child declaration is applied independently. Children inherit no blockers from the groomed parent or from siblings.
  • The legacy { "type": "issue", "issue_number": 17 } declaration remains the explicit GitHub-number reference for an unadopted issue accepted as a blocker in mirror-on. Store-only behavior is unchanged: it accepts mapped Shipper issues, absorbs completed GitHub-only targets, and rejects open or not-planned GitHub-only blockers.
  • When design, planning, or simple-route implementation cannot proceed because of an external condition, it explains the blocking condition, why the condition is outside that stage’s control, and the external action or outcome needed, in ordinary prose. The explanation is recorded with the stage’s ordinary rejection and normal one-step rollback; there is no required heading, field list, claim identifier, or valid/invalid ruling, and grooming adjudicates nothing.
  • A recorded blocker report by itself never routes the issue to grooming, marks it durably blocked, files an issue, or selects the next action. Rerunning the stage, returning the issue to grooming, attaching an ordinary blocker, directing prerequisite filing, and any other response all remain the operator’s choice.
  • Older out-of-authority prerequisite claims and grooming determinations remain readable as advisory history only. Their wording, validity labels, dependency fields, and claim identities never bind or independently decide a later workflow outcome.
  • Grooming may create a new prerequisite issue only on explicit product-owner direction given in the current grooming session; an agent may suggest it, but a stage report, a suggestion, or historical record is not authorization. When directed, use an existing issue blocker if one covers it. Otherwise add an entry with exactly title and body_file to the top-level prerequisites array, use the common grooming-filed request body below, and reference it as { "type": "prerequisite", "prerequisite_index": 0 } from blocked.blockers in the same accepted action.
  • Every prerequisite index is zero-based, must resolve to an entry, and every entry must be referenced. Shipper creates it once as a plain, normal-priority shipper:new issue and blocks the parent on its ordinary local Shipper identity.
  • Every follow-up and prerequisite filed by grooming uses the same body: # Request, the unchanged concise plain request, and one or two unheaded sentences that name the originating S#<origin> issue and explain why the work is separate. Do not require an inherited-context heading, advisory marker, relevant-context list, provenance fields, or empty-state text.
  • Historical inherited-context bodies remain accepted without migration. Validation stays limited to the established leading # Request heading and forbidden groomed headings.
  • An agent may propose a follow-up only for adjacent work first identified during grooming and outside original requested scope. Explicitly requested work, work necessarily implied for a complete and usable result, and scope the product owner confirms in the current session are not agent-proposed follow-up candidates. Requested scope remains in the parent-and-children deliverable set unless the product owner directs an existing follow-up or out-of-scope outcome.
  • The optional top-level followups array contains entries with exactly title and body_file; each body uses the common grooming-filed request shape, while Shipper adds the origin attribution and the actual-created ## Follow-up Issues Filed summary list.
  • Follow-ups are allowed for parent-open grooming with or without children and for full replacement, but duplicate and not-planned closed outcomes cannot declare them.
  • A follow-up is an independent normal-priority shipper:new sibling with no explicit priority label, blocker, blocked state, or decomposition relationship. Unlike a prerequisite it does not block the origin, and unlike a decomposition child it remains ungroomed and outside auto-ship until its own grooming.
  • There is no follow-up count cap. The # Request stays concise.
  • When the cross-issue scan surfaced an open issue covering the work, cite that issue in the grooming summary instead of declaring a near-duplicate follow-up.
  • The optional top-level cross_issue_comments array defaults to empty and has no count cap. Declare { "issue_ref": "S#17", "body_file": ".shipper/output/cross-issue-comment-<artifact-id>-1.md" } only when an accepted grooming decision materially changes what another issue should do; zero comments is valid, scan relevance alone is insufficient, and scan membership is not required.
  • Cross-issue comment targets use exact case-sensitive S#N references and may be any other open Shipper-managed issue regardless of workflow stage, priority, blocked, failed, or locked state. Closed, nonexistent, self, and never-adopted GitHub-only issues are ineligible.
  • A delivered cross-issue comment is an append-only, explicitly retractable local Shipper note. It is authoritative and visible through Shipper in both mirror modes; with issue mirroring enabled it is also projected to GitHub as a visibly Shipper-authored note.
  • Shipper generates attribution identifying the originating issue and groom stage. The agent body is advisory free-form prose, changes no target title, body, workflow stage, priority, blockers, blocked, failed, or locked state, and never resolves the target’s own product decisions.