Skip to content

shipper_groom

Run grooming on a shipper:new issue in headless mode; the worker’s clarifying questions are surfaced to the orchestrator, which answers them via shipper_answer_question.

On macOS, this tool prevents idle system sleep while the session is progress-capable; an observable awaiting-answer wait releases protection, and a durable saved session with no live worker holds none. See Keep the Mac awake during active work. Use this only for shipper:new issues when the orchestrator is prepared to answer worker questions with shipper_answer_question. An ordinary call automatically resumes a saved question session only when it is MCP-owned, retaining its transcript, pending batch, notes, and original round limit; a fresh MCP client can resume after the original host exits. A foreign or legacy unowned session refuses with only issue identity, owner or unowned state, last-saved time, answered-round count, and pending-batch presence—never question, answer, transcript, or note content. Set takeover: true only after human confirmation to transfer that saved conversation permanently to MCP and resume it in the same call. Set refresh_pr_overlaps: true only for the named issue with an existing saved session; it may accompany takeover, which persists ownership before refresh. Refresh preserves the conversation and prior decisions, recalculates current-body Starting Point files, replaces only the frozen overlap evidence and update time, reports capture time and added/removed paths, and retains one-hop supersession. Without a valid saved session it refuses before hooks, worktree, run history, GitHub inspection, or workflow mutation. Fresh grooming captures once; ordinary resume, answers, correction, takeover without refresh, next, and automation never refresh. All open same-repository PRs qualify, including drafts and non-default bases; closed/merged PRs do not. Only explicit repository-relative individual Starting Point files qualify after line-reference removal; directories, globs, prose, inferred files, URLs, traversal, and missing files do not. Matching is exact and case-sensitive, and either side of a rename can match while both paths are disclosed. Evidence contains identity/link/draft/branch/match/rename/capture facts but no authorship, review state, checks, labels, or diff. Coverage is distinctly complete, not evaluable, unavailable with reason, or partial with known overlaps and limitations; partial/unavailable never mean no overlaps and remain active after refresh. Evidence is advisory-only: detection never blocks, sequences, removes scope, or changes requirements; ask only for plausible premise, requirement, or delivery-order impact. Final summaries retain only materially used overlaps with provenance and never place PRs in Related Issues. Mirror-on and store-only behave identically when policy permits GitHub reads; effective transport or pull-request disablement and reachability/bounded-API limits yield truthful unavailable or partial coverage while store-only issue lifecycle remains local. Takeover is unavailable while another issue run is live; elapsed time never expires a session or authorizes transfer. Repeated suspension is safe. Resume always refreshes cross-issue and recorded-blocker context and discloses issue-text drift. The scan agent reads one locally prepared index and referenced detail files without live GitHub lookups. That index contains every other live managed issue at every open workflow stage plus, only in mirror-on, open unadopted GitHub-only issues suppressed by current mirror identity and remembered same-repository import origins. The current issue, closed managed issues, and tombstones are never candidates, and a managed candidate contributes only its current title, body, stage, and blockers—never its accumulated workflow-event history. Every entry carries the same bounded 512-character body skim, and each referenced detail file holds only that issue’s full body. The unmanaged tier is fixed at the 100 most recently updated issues and reports complete, truncated, or unavailable managed-only coverage; store-only performs no sweep or origin lookup and remains offline. An unmanaged index entry contains its GitHub number, title, and the shared bounded body skim, while groom-issue-details/github-<number>.json contains its full body without comments or Shipper workflow fields. A supplemental sweep failure discards partial unmanaged results and continues with explicit managed-only coverage. An unmanaged issue may be a Duplicate only after explicit product-owner confirmation; closure records its GitHub number and does not adopt it. A saved session is discarded for a fresh start only when it belongs to another repository or issue, the issue left New, or the record is unreadable or invalid. A suspended result truthfully reports whether answered rounds and the pending batch, answered rounds only, or nothing were durably preserved. Invalid output receives three total validation passes, and the newest result-bearing input/output tree is preserved as one replaceable recovery bundle if corrections are exhausted. Each awaiting_answer result contains exactly one ordered batch of ordinary authored questions, each requiring an authored answer keyed by its stable id. A saved session that still uses the removed compact-confirmation format is discarded with a plain explanation that grooming must restart. Invalid or incomplete responses reject atomically and redisplay the unchanged batch; if the worker has more pending batches, the next one is returned by shipper_answer_question after the current batch is answered. 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 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, while # Request is authoritative only for the unchanged record of what was asked. Directly observed unchanged shipped behavior needs no establishing confirmation. Grooming receives the issue’s recorded blockers, resolves their lifecycle with the product owner, and restates the complete final blocker set. Omission releases a recorded blocker; there is no separate removal or union mechanism. Each parent and child declaration is applied independently, and children inherit no blockers. Explicit prerequisite reconciliation stays separate from broad discovery: only targets closed as completed are absorbed and noted as satisfied at post-flight, a stated not_planned target remains a blocker until the product owner chooses a replacement or removal, and neither appears as a discovered related issue merely because it is closed. When design, planning, or simple-route implementation cannot proceed because of an external condition, it states the blocking condition, why the condition is outside that stage’s control, and the external action or outcome needed, in ordinary prose, and rejects through its ordinary path with its normal one-step rollback. No heading, field list, claim identifier, exact wording, or valid/invalid ruling is required or emitted, and grooming adjudicates nothing. A report by itself never routes the issue to grooming, marks it durably blocked, files an issue, or picks the next action; rerunning, returning to grooming, attaching an ordinary blocker, directing prerequisite filing, or another response remains the operator’s choice. Older claims and determinations stay readable as advisory history whose wording, labels, dependency fields, and identities never bind a later outcome. The groom worker can declare an existing Shipper prerequisite as { "type": "shipper", "issue_ref": "S#17" }; issue_ref also accepts a bare positive integer or digit string, with bare values resolving Shipper local ID first and mapped GitHub number second. Active native matches become the same ordinary local blocker in mirror-on and store-only repositories. The legacy { "type": "issue", "issue_number": 17 } form is also how an unadopted issue found by the scan becomes an external GitHub blocker in mirror-on; store-only behavior is unchanged, accepting mapped Shipper issues, absorbing completed GitHub-only targets, and rejecting open or not-planned GitHub-only blockers. Grooming may create a new prerequisite issue only on explicit product-owner direction given in the current session; an agent may suggest it, but a stage report, a suggestion, or historical record is not authorization. When directed and no existing issue covers it, add exactly title and body_file to the top-level prerequisites array, use the common grooming-filed request body, and reference its zero-based index as { "type": "prerequisite", "prerequisite_index": 0 } in blocked.blockers in the same accepted action. Every entry must be referenced; Shipper creates it once as a plain normal-priority shipper:new issue and blocks the parent on the resulting local Shipper identity. Every filed prerequisite and follow-up 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. The optional top-level followups array contains entries with exactly title and body_file, each pointing to that common body; Shipper adds the origin attribution and actual-created ## Follow-up Issues Filed summary. 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. Follow-ups are independent normal-priority shipper:new siblings with no explicit priority label, blocker, blocked state, dependency, ordering, scheduling, or decomposition relationship. They are allowed for parent-open and full-replacement grooming, forbidden for duplicate and not-planned closure, and remain outside auto-ship until their own grooming. There is no count cap. The # Request stays concise. Cite surfaced open coverage instead of filing a near duplicate. 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. Targets use exact case-sensitive S#N references and may be any other open Shipper-managed issue regardless of stage, priority, blocked, failed, or locked state. Closed, nonexistent, self, and unadopted GitHub-only issues are ineligible. Delivery creates an authoritative append-only, retractable local Shipper note visible through Shipper in both mirror modes. With issue mirroring enabled, it is also projected as a visibly Shipper-authored GitHub note. Shipper generates attribution identifying the origin and groom stage. The body is advisory free-form prose, changes no target content or workflow state, and never resolves the target’s own product decisions. A follow-up creation failure stops before origin mutation and leaves the origin unfailed and retryable; earlier successfully filed follow-ups remain. The configured agentTimeoutMinutes limit applies independently to each agent attempt; MCP adds no stage-wide deadline, so ordinary retries, corrections, cleanup, projection, run recording, and finalization remain child-owned. Time paused awaiting product-owner answers consumes no agent-running timeout. A terminal timeout returns only after authoritative local agent_timeout history, failed workflow state, terminal MCP-attributed run status, and ownership-safe release of that run’s issue lock. In mirror-on mode, projection debt never rolls back the local failure or retains the lock and is explicitly repairable with shipper issue reconcile --repair. The timeout report identifies the stage, per-attempt limit, attempt count, available session log, discarded staged/unstaged/untracked work, and exact same-stage reset command. When commits survived, that matching reset preserves only the recorded unchanged workflow branch revision—not the physical worktree—and the next groom or scaffold run continues from it; a missing or moved ref invalidates continuation.

  • openWorldHint: true — The tool reaches GitHub or other external systems outside the MCP server.
NameTypeRequiredDefaultDescription
issueinteger | stringyes-Shipper issue reference. S# (GitHub #) accepts ordinary surrounding whitespace and requires the current mirror. Bare numbers are Shipper local IDs first; S# is accepted; gh: and # explicitly target a mapped GitHub issue; GitHub issue URLs are accepted. Responses return S# first with GitHub # second when mapped.
takeoverbooleannofalseDefaults to false. Set true only after human confirmation to transfer a foreign or unowned saved question session permanently to MCP and resume it in this call. A live issue run makes takeover unavailable.
refresh_pr_overlapsbooleannofalseDefaults to false. Set true only for the named issue when an existing saved grooming session should replace its frozen pull-request overlap snapshot without resetting the conversation.
{
"issue": 42
}
Resolved issue: S#42 (GitHub #123): Generate MCP tool reference pages
Status: awaiting_answer
Session: sess-abc123
The headless worker asked a batch of questions and is paused awaiting answers from the orchestrator.
Worker message:
The implementation must preserve existing clients while deciding whether new behavior is opt-in.
The worker's analysis and recommendation are reasoning to weigh, not answers to ratify.
Verify them against the codebase and your own product judgment before answering.
Reply with `shipper_answer_question` providing { session_id, answers }.
The `answers` map must contain one free-text answer for every question id in this batch and no other ids.
Candidate options are informational; answer in free text rather than selecting an option.
An incomplete submission is rejected whole and leaves this batch available for another attempt.
Questions (JSON):
[
{
"id": "0",
"question": "Which compatibility behavior should the implementation preserve?",
"analysis": "Existing clients rely on the current response shape, while the new shape is easier to consume.",
"recommendation": "Preserve the current shape by default and add the new behavior explicitly.",
"header": "Compatibility",
"options": [
{
"label": "Preserve default",
"description": "Keep existing clients unchanged."
},
{
"label": "Adopt new default",
"description": "Require clients to migrate."
}
],
"multiSelect": false
}
]
  • Wrong issue stage: shipper_groom only operates on issues at shipper:new. S# (GitHub #) has labels: .
  • Saved session not MCP-owned: The content-free refusal names Desktop, terminal, or unowned, reports last-saved time, answered-round count, and pending-batch presence, and says that takeover transfers saved answers and requires human confirmation.
  • Takeover unavailable: Cannot take over the saved grooming question session while another issue run is live. No transfer or grooming run starts.
  • Refresh unavailable: Cannot refresh pull-request overlaps for S#: no valid saved grooming question session exists. No hooks, worktree, run history, GitHub inspection, issue state, or workflow state changes.
  • Enriched completion summary unavailable: After the worker completes, a post-completion label or session lookup can fail. The tool returns the plain observed worker result, any locally resolved final message and session log, plus Enriched completion summary unavailable. and Reason: <underlying error>; an exit-0 worker remains successful.
  • Mirror-on pre-completion GitHub lookup failure: When issue mirroring is enabled, a GitHub lookup that fails before worker completion remains a tool error: Command failed: gh
  • Timed out worker: [timed out] shipper groom —mode headless
  • Failed worker: [exit ] shipper groom —mode headless