Skip to content

Versioning

Shipper publishes a single canonical version of these docs. The live docs describe the current supported workflow rather than maintaining parallel docs for older releases.

The root @baremetallabs-ai/shipper-core package is the stable production contract for core helpers. Its declared ./internal subpath exists only for Shipper workspace test/support code, has no stability guarantee, may change or break at any time, and is not covered by version-compatibility promises.

The current issue-state store boundary is V20. V12 fences the persisted shapes from #2393, #2399, and #2401; V13 additionally fences body acknowledgements and ordinary/note delivery-attempt semantics. V14 adds durable automatic stage-failure attempts and explicit recovery semantics; V13 stores advance losslessly with no recorded automatic stage failure. Upgrade all clients sharing the store before a V14 writer opens it. V15 fences one-use Blocked retry authorization, independent automatic mirror requests, and the Blocked ownership boundary. Advancement never infers POST provenance, marker acceptance, or resolution of an old post-started attempt. V16 fences generalized workflow authorization, projection record v7 failure discovery metadata, projection record v8 explicit legacy-repair readiness, and mirror request payload v3 generic group identity. V1 failures without discovery metadata establish no hold; V2 Blocked requests retain their original bytes, identity and tokens. The boundary is independent of individual record versions.

V17 fences target-specific V4 obligations, finite retry cycles, sparse mirror-work summaries and historical baselines. Initialization is a one-time resumable local pass with no GitHub reads. It preserves real uncertainty, consumed authorization tokens and ownership evidence; a baseline does not prove delivery, deletion or POST ownership. Clean background and display reads open no settled histories.

V18 fences faithful issue/comment content observations, accepted-edit evidence and read-only content verification. V19 fences queued mirror-content upgrade verification and its recovery semantics. V20 adds the source-aware blockedImportSweepPending metadata flag, invocation-specific delivery evidence and manual-recovery semantics. Lossless V18/V19 advancement preserves snapshots, tombstones, extensions, history prefixes, allocator reservations, stopped retry cycles and both upgrade checkpoints.

The first mirror-on repair performs one complete blocked-import sweep for affected V16–V19 stores, supported V1–V10 stores and unreconciled V11–V15 stores. Reconciled V11–V15 stores retain their exclusion. A current V20 store preserves its recorded flag. Repair durably queues eligible unclaimed Shipper-managed blocked issues before clearing the flag; incomplete discovery keeps it pending. Existing queued imports remain serviceable. Ordinary reads perform no remote discovery and never clear eligibility.

Supported V11, V12, V13, V14, V15, V16, V17, V18, and V19 stores advance automatically and one way, with an atomic metadata update that preserves workflow history, pending work, allocator reservations, and the reconciliation flag. No manual repair is needed for this advance. Untouched V11/V12/V13/V14/V15/V16/V17/V18/V19 snapshots and tombstones may remain beneath the current header; ordinary writes upgrade only the records being edited. Supported earlier headers still use their existing historical conversion rules. This advance adds neither historical-store support nor a downgrade path.

The store boundary is independent of individual record versions. Workflow event envelopes remain v1. Projection evidence includes v1/v2 records (including projection record v2 for accepted-but-not-applied evidence) and schema-3 workflow-comment posting records and schema-4 body acknowledgements. Projection v5 records position-scoped retry authorization; v6 records explicit POST provenance or separately observed marker acceptance. Mirror-state payload v2 requests have independent generations, retry deadlines, and completion records; v1 error debt remains independent. Review payloads have their own versions, including schema-3 feedback progress. A store-wide boundary fences incompatible known payloads, strict delivery fields, projections, and pending-import sidecars even when a snapshot gains no new fields.

Independently installed CLI, Desktop, MCP/server, and daemon builds can share a store. An incompatible older build encountering the advanced store refuses it with the existing stale-reader message, stating the observed and supported schema versions. Restart or reconnect running clients and servers. If a freshly launched client or server remains incompatible, update the installed Shipper release or rebuild the source checkout before reconnecting. Preserve the issue-state store unchanged.

An older running reader refuses on its next checked access. An upgrade elsewhere does not terminate an old process or revoke an operation already past its compatibility check. A build on another machine is protected when it encounters the advanced store, rather than merely because another installation upgraded.

Any change making saved records unreadable or unsafe for older builds must advance ISSUE_STATE_SCHEMA_VERSION in the same change. This includes strict saved fields, known payload changes, sidecars, delivery semantics, and recovery semantics. Verify lossless advancement of supported stores and stale-reader refusal before parsing or repair. Never reuse a shipped boundary number for a different compatibility rulebook.

Unknown-kind tolerance is narrower than store compatibility. A current reader skips an event only when its envelope is otherwise valid and its string kind is unknown to that build. It warns once per event-store directory per process, naming the directory and stating that records from a newer build were skipped. Known records around the skipped record continue to read normally. This does not authorize incompatible known payloads, strict delivery fields, projections, ignored sidecars, malformed JSON, missing envelope fields, unknown entry types, or unsupported record versions.

Delivery intent uses projection record v3 (post-ready, post-started, post-rejected). Successful fitted-body acknowledgements use projection record v4 with a validated receipt and SHA-256 body hash. V11, V12, V13, V14, and V15 advancement retains adoption evidence, receipts, event-history bytes, and unresolved attempts. It does not invent readiness for legacy undelivered groups. The historical V13/v4 delivery evidence boundary protected expanded ordinary-comment and note attempt semantics from older writers that recognized v3 syntax but could mishandle its meaning. V15 adds the authorization, request, and ownership fence. Newer stores refuse older readers before incompatible parsing, mutation, or repair.

Upgrade all independently installed clients before introducing V20 recovery evidence into a shared store. Upgrade CLI, Desktop, and MCP clients sharing the store to compatible builds. Do not delete or downgrade persisted evidence to work around a compatibility refusal.

Successful historical ordinary comments with no body hash remain delivered. Blocked ownership requires a currently validated marker for a known local Blocked group or explicit POST provenance for the same comment ID. A heading, matching body, account, saved ID, or hash alone is not proof. Marker acceptance records safe delivery recovery; that saved timestamp alone never grants later PATCH or DELETE rights after the remote marker disappears. Unmarked legacy linkages remain ambiguous and unverifiable copies may require manual removal.

Recovery covers stage comments, notes, PR flake comments, Unblocked and Blocked comments. Completed explicit repair posts wanted legacy work once when no attributable copy is found and no concrete ambiguous-send evidence exists. Superseded or retracted absent work is retired without posting. Closure alone does not retire historical comments, including post-closure notes. Legacy work without an attempt token directs the operator to shipper issue reconcile --repair.

Uncertain delivery retains automatic duplicate protection: another send cannot be promised automatically. Use shipper issue recover-comment S#42 to inspect without posting, then authorize one exact current token with all four options:

Terminal window
shipper issue recover-comment S#42 --group <id> --attempt <token> --retry --accept-duplicate-risk

The earlier attempt may already have posted. Authorizing another attempt can create a duplicate comment.

A found attributable copy wins over authorization. Incomplete, unavailable, malformed or exhausted searches consume no token and never establish absence. Saved authorization, recovered receipt identity, verified body acknowledgement, retirement and cleanup are separate outcomes. Ineffective PATCH and residual cleanup remain pending. Obsolete uncertain work is retired only after evidence or authorization. Routine convergence retains conclusive absence for its matching attempt. Transient unavailable discovery retries at the next due ordinary synchronization without requiring inspection or repair. Explicit repair reuses a completed catalog per actual issue/PR parent and directly validates selected identities before mutation.

shipper issue recover-blocked-comment remains a Blocked-restricted compatibility wrapper using the same flags and engine. Blocked ownership and slot ordering remain stricter: saved ID, heading or body alone never establishes ownership. Store-only policy refuses GitHub recovery without writes. A live stage defers authorization without recording it; rerun after the stage finishes.

Each delivery target permits six failed passes with 1, 2, 4, 8 and 16-second backoff. GitHub holds consume no failure and defer to their deadline. Definitive permission or validation rejection stops immediately. Stopped work remains undelivered with its cause and safest recovery action. Uncertain POSTs retry safe discovery only; another POST requires an exact one-use authorization.

Plain repair may service a stopped target once without resetting its automatic budget. An unsuccessful manual pass leaves it stopped with its prior attempt count; timers and priority changes do not restart that cycle. Active GitHub holds remain in force, including after a priority change. Repair never authorizes an uncertain repost.

A corrupt derived pending-work index stays visible as stopped, non-due work for that issue. Status, issue lists, the desktop board and catch-up remain usable for healthy peers. Explicit repair reconstructs indexes from authoritative local records and removes orphan indexes. Malformed authoritative records or history require correction and remain unchanged.

After successful authorized recovery, pending status updates immediately, before ordinary synchronization. A recovered receipt proves identity; completion still requires the wanted body and required cleanup to be verified. Newer generations, unrelated issue delivery and residual size-limit debt remain pending.

Messaging distinguishes “GitHub delivery held before launch” from “GitHub rejected delivery; automatic retries stopped”. Unknown POST delivery stops without claiming rejection. Causes appear once per target. Authorization-required work explains the exact group/token command instead of promising automatic resumption. Duplicate-risk warnings apply only to unresolved attempted POSTs, never proven-unsent/rejected posts, completed/retired work or accepted-edit observation. Desktop presents stopped delivery as attention, including when local priority was saved successfully.

Notes, CLI and desktop priority changes, and explicit mirror synchronization save locally while a stage owns the issue. Automatically eligible work reports:

Saved locally; GitHub delivery pending while a stage owns this issue. Delivery resumes at the next ordinary synchronization after the stage finishes.

Remote delivery still uses the issue lock. Lock release performs no GitHub work and never waits. The next ordinary issue synchronization services due work. An existing daemon or desktop runtime can deliver after a hold, including with Auto Ship disabled. Current store-only policy cancels automatic requests without GitHub operations. Completion consumes only the handled generation, preserving newer requests and independent pending-error debt. Durable note identities prevent duplicate posts.

Historical breaking changes live in the root CHANGELOG.md and in the repository’s release tags. Those records describe what changed over time while the live docs continue to describe the current supported workflow.

Issue-lock release is network-free. Foreground stage completion makes one due pass outside release and returns without sleeping. Stopped delivery remains visibly undelivered until an applicable explicit recovery action.

CLI-only pending work survives process exit. Run shipper issue reconcile --repair to service it now; repair also respects GitHub holds. Plain repair comes before duplicate-risk authorization when sufficient. No new CLI background process is required.