Protocol
This is the contract between Shipper and the agents it runs. Commands prepare context, agents do the stage work, and the result file tells Shipper how to interpret the stage.
Prompt-driven execution
Section titled “Prompt-driven execution”Stage prompt bodies are authored once under packages/core/src/prompts/templates/. Intentional
per-agent wording differences, such as setup instruction-file wording and sandbox wording, come from
the capability table in packages/core/src/lib/agent-capabilities.ts. Prompt invocation settings
and issue/PR append flags are structured data in packages/core/src/lib/prompts.ts.
runPrompt() in packages/core/src/lib/prompt-runner.ts consumes the rendered prompt text plus the
structured invocation metadata for the selected agent and step. It then applies runtime
mode/model/MCP/worktree normalization, appends issue or PR context when requested, injects
environment settings, and spawns the configured agent. Repository files under .shipper/prompts/
are ignored legacy leftovers and do not change prompt text.
Verdicts
Section titled “Verdicts”Result files use one of three valid verdicts:
| Verdict | Meaning |
| -------- | ---------------------------------------------------------------------- |
| accept | The stage completed and Shipper should move the issue forward. |
| reject | The stage found a problem and Shipper should roll back as configured. |
| fail | The stage could not complete and the issue should be marked as failed. |
A crash, timeout, or missing result file is treated as a terminal failure. reject is not a command
failure for next or ship; it is an interior workflow event as long as Shipper can apply the
rollback transition from the agent’s result.
Rollback targets come from STAGE_TRANSITIONS in
packages/core/src/lib/stage-transitions.ts. For example, an implementation reject rolls the issue
back to shipper:designed, and a PR review reject rolls it back to shipper:implemented.
For recovery from crashes, missing results, timeouts, and reject loops, see
failed issues and rollback loops.
Label transitions
Section titled “Label transitions”For result-protocol stages, agents do not transition workflow labels directly. The agent writes the
result file. Shipper reads that file, resolves the verdict through STAGE_TRANSITIONS, and then
applies the transition.
executeTransition() in packages/core/src/lib/output-protocol/protocol-actions.ts builds one
atomic gh issue edit call containing every --add-label and --remove-label argument for the
resolved transition.
PR-stage labels are mirrored onto the pull request with a separate best-effort gh pr edit call.
The issue label transition is still the source of truth for workflow state.
shipper new is the narrow exception to the normal result-file shape because it runs before an
issue exists. The new agent writes pre-create draft files under .shipper/output/: result.json
contains issue_draft, which points at issue-draft.json; that draft contains a structured title
and an issue-body.md path. The new draft does not use verdict or comment, and comment is
optional only for this stage. Shipper validates the draft with the standard correction retry budget,
creates the GitHub issue, applies shipper:new, and overwrites result.json with the final
created_issue identity.
Grooming still updates the issue body/comments as part of its workflow. Those direct edits are separate from the result-file transition contract used by downstream stages.
MCP loading policy
Section titled “MCP loading policy”Settings are merged in this order:
- Built-in defaults
.shipper/settings.json.shipper/settings.local.json- One-run CLI flags
commands.default.disableMcp defaults to false. commands.groom.disableMcp defaults to true.
Any commands.<stage>.disableMcp value overrides the default for that stage, and --disable-mcp or
--enable-mcp overrides settings for one invocation.
When MCP loading is disabled, Shipper logs:
MCP loading disabled for stage <name>.It then injects the empty MCP configuration or disable flags appropriate to the selected agent. When MCP loading remains enabled, Shipper does not print an extra MCP line. For setup or tool-loading symptoms, see MCP tool loading issues.