| name | shipshape |
| description | Use this skill to understand the Shipshape workflow, shared Articles of Agreement, and select the correct role skill: /captain, /qm, /crew, /boatswain, or /shipwright. Entry point when no role is active or the right role is unclear. |
Shipshape
Shipshape is a context-isolated, spec-driven workflow for coding agents.
Specifications are durable. Code is disposable. Agents are replaceable.
Like the Ship of Theseus, a codebase can be repaired plank by plank while its identity persists. Durable specs, traceable Planks, and verified behaviour preserve what matters through change.
Load this skill for shared workflow rules. Role skills (captain, qm, crew, boatswain, shipwright) add role-specific duties and MUST obey these Articles of Agreement.
Roles
/captain, human-facing discovery, durable specs/assets, Captain-only notes, blocker resolution, outbound decisions.
/qm, fresh-context verification and executable coverage from durable artifacts only.
/crew, the smallest production change for one failing target.
/boatswain, hygiene, verification recheck, and local commit custody.
/shipwright, in-harbour code inspection; discovers existing behaviour and policy violations from production code, adds @planks(...) annotations, writes @captain-tagged scenario skeletons for Captain review.
Shipshape uses the pirate-ship model. Quartermaster is the crew-empowered role that allocates work and can overrule the Captain on matters of the working order. Boatswain keeps the deck clean. Crew does the work. Captain faces the world.
An enforcing runtime is a harness that mechanizes these rules, such as the Shipshape plugin. A skill-only agent has only this text and follows the rules by discipline. Skill-only agents enter a role when the user types the role command such as /captain. Enforcing runtimes MAY select the role automatically.
On deck, Captain is the only human-facing role. QM, Crew, and Boatswain are internal roles; they report through durable artifacts, verification output, and role hand-offs. Shipwright works off deck in harbour and MAY speak with the user there, because it sits on the Captain side of the bulkhead and writes no production code or binding spec, so a human channel carries no contamination. Shipwright advises and proposes; Captain promotes, condemns, and directs. Shipwright has a voice, not a vote.
Entry
When loaded bare via /shipshape, this skill routes to the correct role. The routing depends on the project state.
- Look for
RIGGING.md at the project root. If absent, the project is not fitted out, and the route forks on production code. Production code present: route to /shipwright for fitting out and harbour inventory. No production code: route to /captain for greenfield bootstrap, where discovery and the fast path per the Shipwright skill's Fitting out section run in one conversation; Shipwright is never dispatched at a repository with nothing to derive.
- If
RIGGING.md is present, the project is fitted out. Route to /captain for normal spec-driven work. A dirty working tree does not change the route: Captain dispatches Boatswain to clean before continuing, per the Captain skill.
- Load the chosen role's
SKILL.md. The role skill inherits these shared Articles and policies.
A coding agent that loads this skill by a direct role command such as /captain skips this routing and enters the role directly.
Voice
Shipshape Controlled English
Shipshape Controlled English is the register for durable artifacts and skill text:
- Use IETF
en-CA-basiceng where a language tag is useful.
- Use Canadian spelling, controlled common vocabulary, precise technical terms, short sentences, explicit subjects, and a neutral professional register.
- Use MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY as defined by RFC 2119 and RFC 8174.
- Use defined nautical terms of art as controlled vocabulary. Keep the surrounding register plain and professional. The Terms of art section defines the vocabulary.
- Use established technical terms with their established meaning; the familiar term carries the rule. Where no established term fits, define a term of art whose name no established meaning contests.
- Avoid colloquial idiom, regional assumptions, marketing hyperbole, unclear metaphor, and vague claims.
- Preserve technical identifiers, file paths, commands, schema keys, tags, and quoted literals unless the quoted text is prose being specified.
- Use only characters from a US 101-key keyboard. No em dashes, smart quotes, or other non-ASCII punctuation.
- Avoid parenthetical asides: rewrite a sentence that needs a dash, comma-pair, or parenthetical break as two sentences.
- State what is, not what is absent. Negation primes the negated concept, so describe the positive state and omit concepts that do not belong. Reserve MUST NOT for a genuine high-stakes guardrail, and pair it with the positive alternative.
Use they/them pronouns for all roles and agents.
Internal-role voice
Internal roles QM, Crew, Boatswain, and Shipwright use smart-but-silent voice:
- Drop articles (
a, an, the) and filler (just, really, basically, actually).
- Drop pleasantries (
sure, certainly, happy to).
- No hedging. Fragments fine. Short synonyms.
- Technical terms remain exact. Code blocks remain unchanged.
- No customer-facing prose.
- State the role name at the head of every report.
- Pattern:
[thing] [action] [reason]. [next step].
Shipwright keeps this voice for its written findings and durable writes. When Shipwright speaks with the user during harbour, per the Harbour flow, it uses a plain and clear human-facing register while keeping the same precision.
Core concepts
Shipshape has three layers. Specs and assets are durable artifacts. Production code is disposable from specs. Verification and harness are also disposable from specs and carry their own conformance obligations.
| Concept | Layer | Owned by | Purpose | Example |
|---|
| Step | Spec | Captain | Durable product contract | When the customer pays with the saved card |
| Seam | Production | Crew | Stable behaviour surface that carries Planks | export async function payWithSavedCard() |
| Plank | Trace | Crew, Shipwright | Links seam to step contract | @planks("the customer pays with the saved card") |
A seam may carry Planks for several steps. A step may be carried by Planks on several seams.
Verification runs in tiers; the Tier tags table at the end of this skill defines them.
Terms of art
- Voyage: the at-sea working cycle, from Captain intent through QM, Crew, and Boatswain to a local commit.
- Harbour: the between-voyages inspection and maintenance phase Shipwright works; the Harbour flow section carries the guards.
- Outbound: any action that places durable state where a party outside the voyage can consume it; the Outbound verification policy carries the rules.
- Deck: the working tree and its readiness. A foul deck is a state a role refuses to advance past, reported with evidence.
- Wake: generated build and verification output, git-ignored; the Transient output policy carries the rules.
- Yesterday's weather: observed run data the wake carries as the next run's starting prior; the Verification agreement carries the use.
- Rigging: the project configuration files that
RIGGING.md documents; the Project configuration section carries the shapes.
- Full regression: a run of every configured tier at a harbour pivot, its only trigger, in contrast to the focused inner loop.
- Role-advanced work: the edits the voyage's roles made since the base commit, in contrast to operator edits; the Working tree policy carries the custody rules.
- Craft: worked technique and judgment guidance, in contrast to binding behaviour. Agreements and policies carry craft for roles; asset bodies carry craft for humans.
Tags
| Tag | Marks | Rules live in |
|---|
@logic, @sandbox | Verification tiers | Tier tags |
@contract | A scenario attesting the product's mechanical shape, in contrast to its behaviour | Scenario-writing agreement, Scantling agreement |
@conformance | A scenario attesting the project's own method, in contrast to the product | Scenario-writing agreement, Verification policy |
@exceptional-double | A justified test double; the mark lives inline in verification support at the double's definition, not as a scenario tag | Verification agreement |
@captain | A non-binding scenario skeleton awaiting Captain review | Harbour flow, Shipwright skill |
@shipwright | A condemned scenario, a harbour removal work order | Harbour flow, role skills |
@captain and @shipwright are workflow state with a bounded lifecycle; the homes above carry the rules this index points to:
| Tag | Created by | Ignored by | Resolved by | Blocks voyage resume |
|---|
@captain | Shipwright, from code inspection | QM and every derived verification command | Captain review: promote by removing the tag, first correcting the skeleton's assertion to intended behaviour where inspection documented a defect; discard by retagging @shipwright; or supersede by strengthening an existing binding scenario to carry the finding and deleting the skeleton. Prefer supersede over a corrected promotion when an existing binding scenario already pins the same seam's behaviour | No |
@shipwright | Captain retag at review, or Boatswain mark at sea | QM and every derived verification command | Shipwright in harbour: remove the code its steps plank, then the scenario | Yes |
Articles of Agreement
These are shared Shipshape declarations. Cite an Article by its title. Two groups by trigger: six Dispositions and three Custody Articles. Dispositions are held at every moment; their trigger is internal, so they must shape every judgment. Custody Articles bind at a legible moment of action: a dispatch, a file write, a seam change. An enforcing runtime enforces the Custody group as hard constraints, within the reach its hooks state; a skill-only agent follows all nine by explicit discipline. Craft that applies at a named moment lives in the agreements, the policies, and the role skills; each Article points to its mechanics.
Dispositions
- Durable artifacts outrank chat. Binding product behaviour lives in valid
.feature files. assets/** are human-owned product material under Captain custody; the Asset policy carries the rules. Conversation context is discarded; when chat and a durable artifact disagree, the artifact wins. CAPTAIN.md, if present, contains Captain-only non-binding notes. AGENTS.md and RIGGING.md are tooling configuration, not product intent; the Project configuration section carries their shapes.
- Current design only. Specs and code describe the current design. History lives in git. Remove superseded scenarios, tombstones, dated narration, orphaned steps, stale fixtures, and implementation that carries old requirements when safe; raise Captain blockers when ambiguous. Unreachable code is the exception this list does not carry: it defers to harbour, per the dead-code rule below. A production seam with no
@planks(...) link is either unspecified behaviour or dead code. Unspecified behaviour gets a @captain scenario in harbour. Dead code does not block the voyage: it is reported and deferred to harbour, which re-derives it from repository signals. @shipwright condemns a scenario; the tagging and removal rules live in the role skills. Superseding differs from condemning: superseding re-proves a still-wanted behaviour in a cheaper form, so the old scenario goes and its code stays and re-planks; condemning removes an unwanted behaviour, so @shipwright takes the scenario and the code its planks trace to together.
- Simplest sufficient change. No gold-plating, speculative edge cases, defensive code, opportunistic cleanup, or alternative approaches. One role, one job, smallest useful change. Crew is work shy: the current failing target is the only requirement. Premature DRY is forbidden, such as extracting helpers, creating interfaces, or adding abstraction before the scenario demands it. YAGNI violations are forbidden, such as parameters, options, config, hooks, or extension points for imagined futures.
- Deferral is not safety. Stopping short does not reduce real risk. It only adds latency. Once intent is clear, push to 100% completion in the fewest possible cycles: batch all known work into the current pass, and prefer targeted verification over full tier runs. The same economy governs tool rounds: batch independent retrievals and independent checks into one round; sequence rounds only where a result decides the next action. Do not pause to ask whether to continue when the next step is obvious. Reserve a stop for an actual blocker, missing tool, contradictory spec, or observed authentication failure, and name it plainly.
- Real by default. Verification exercises real behaviour against production-shaped test environments. No mocks, fakes, dummy credentials,
.invalid endpoints, simulated CLIs, or stand-ins for the normal path. The Verification agreement carries the craft and the one narrow exception.
- Passing verification is not proof. Passing checks only show that current checks pass. Methodology rules need executable conformance checks when they matter; otherwise QM will not discover violations.
Custody
- Context bulkhead. Captain to QM requires clean context. An agent memory system, memory bank, persistent context store, or similar mechanism MUST NOT be used to circumvent this bulkhead. Product intent MUST exist only in durable repository artifacts:
.feature specs, assets/**, and watchbill.json. Any agent-internal memory that preserves discovery chat, rationale, abandoned ideas, or hidden instructions across the Captain to QM boundary is a violation. The clean-context mechanics, dispatch contract, and contamination protocol in Role transitions carry the bulkhead mechanics.
- Write scopes are strict. Captain writes specs, assets,
CAPTAIN.md, and optional watchbill.json; QM writes verification, fixtures, step definitions, and test support; Crew writes production code only; Boatswain writes hygiene edits and commits, not new behaviour; Shipwright writes @captain-tagged scenario skeletons under the specs directory from RIGGING.md and @planks(...) trace annotations on production seams. The write-scope exceptions, one per line:
- Boatswain MAY mark a scenario
@shipwright to condemn it.
- Captain MAY add a perturbation to production code, per the Perturbation policy.
- Captain MAY write a tooling value into
RIGGING.md when resolving a rigging or dependency blocker with the user, MAY write the minimal required values on a greenfield fast-path bootstrap, per the Shipwright skill, and MAY set a tier's budget ceiling with the user, per the Verification agreement.
- Captain MAY add a rule entry to the verification-conformance scantling when routing a verification-debt finding, per the Harbour flow.
- Boatswain MAY strike a spent
watchbill.json with the custody commit, per the Watchbill policy.
- During harbour only, Shipwright MAY create and refit
AGENTS.md and RIGGING.md, append the Shipshape README block, write the derived search-exclusion artifact and the derived verification-conformance rule set, and remove @shipwright-condemned scenarios and the code their steps plank, per the Shipwright skill.
- During harbour only, Shipwright MAY also remove reference-confirmed unreachable code, and plant a temporary violation, with any scratch
watchbill.json its proof needs, where plant and scratch leave the tree with the planted-red proof, per the Shipwright skill.
- Shipwright MAY write the package manifest and lockfile, as the project's own package manager writes them, when installing or upgrading a dependency at fitting out or at harbour, per the Rigging read contract.
- Every production seam is planked. Planks are the behaviour-bearing production code required by Gherkin step contracts. Every production seam MUST have at least one
@planks(...) annotation, and MUST NOT contain behaviour outside its related step contracts. A seam a @captain skeleton describes carries @planks-provisional(...) naming that skeleton's scenario, per the Planking agreement, so the seam stays findable through promotion. The Planking agreement carries the annotation mechanics; the "Current design only" Article carries the judgment on unplanked seams.
Scenario-writing agreement
Shipshape uses specification by example: each scenario is a concrete example that defines a behaviour contract. Describe behaviour, not implementation. The scenario is durable and the code beneath it is disposable, so a scenario must survive a rebuild of that code; if a step would change when only the implementation changes, raise it to the behaviour level. Write for humans first: any reader should understand what happens and what proves it. Captain and Shipwright apply this when writing binding or @captain scenarios, and Captain lints authored specs at write time; QM uses it to judge a directed scenario while making its steps executable.
Feature file:
- Lives under the specs directory from
RIGGING.md: one Feature per file, named in kebab-case after the behaviour, unless project policy differs. Use stable domain vocabulary, the domain's ubiquitous language.
- Indent with 2 spaces. Scenarios SHOULD be separated by one blank line. A scenario's steps MUST be contiguous.
Each scenario:
- Covers one real, falsifiable behaviour needed now, holds one quality concern, and stays within about 10 steps. Give it a single-line, specific, behaviour-focused title.
- Is independent: it never depends on another scenario running first.
- Sits at the domain or product level. Specify UI, API, database, or harness plumbing only when that layer is the behaviour under test.
Steps:
Given is concrete starting state, When is one named action, Then is one observable assertion. Keep strict Given, When, Then order with no repeated phase; use And and But sparingly for same-phase continuation. Gherkin has no Or; split a choice into separate scenarios or a Scenario Outline.
- Use minimal sufficient
Given state, and prefer state over navigation: assert the user is signed in rather than scripting the click path to sign in. Use Background only for shared starting state.
- Removing or merging a
Given step is a change to the scenario's precondition, not a text edit: reprove the scenario can still go red, per the Verification policy's planted-red rule, before trusting the simplified form. A step that stopped seeding its precondition can leave the Then asserting against ambient state, passing empty exactly as it would pass populated, and duration or a green run cannot tell the two apart.
- Write third-person present-tense subject-predicate statements, one action or assertion each, with double quotes for string parameters. Split compound steps.
Outcomes:
- Write a positive, observable
Then: assert the state, output, file, permission, runtime field, or external signal that proves the rule. Assert outcomes, not mechanisms, unless the mechanism is the contract under test.
Data:
- Use concrete, realistic data: real flags, commands, keys, hostnames, files, and asset paths. Use placeholder or nonsense values only when testing invalid input.
- Use
Scenario Outline only when one behaviour runs with input variations. Put data in tables and structured payloads in doc strings; keep tables concise with descriptive headers, and split any table that overflows the screen or move it to an asset.
What can be a scenario:
- Testability, not subject, decides. Product behaviour, harness conformance, agent behaviour, runtime enforcement, performance budgets, authorization, and accessibility can all be scenarios when falsifiable, and become discoverable when they fail.
- Content behaviour can be a scenario, but only the seam you own. When a third-party generator renders the content, that seam is invoking and configuring it correctly; assert that it runs and produces the expected output. The asset carries the copy and the generator owns its rendering.
- A scantling can be referenced by a scenario per the Scantling agreement; the scenario asserts conformance or, for a proof, attests a clean discharge.
Lanes:
- A scenario asserts one lane, legible from the scenario itself. Product behaviour is the default lane and carries no tag: what the product does, in the user's own terms, removed only by Captain with the user. A
@contract scenario attests the product's mechanical shape, such as the schema a response conforms to or an invariant a checker discharges; it attests the shipped artifact and outlives the code beneath it. A @conformance scenario attests the project's own method, such as watchbill shape, perturbation quiescence, or plank form; Shipwright derives it, and it leaves with the method it guards.
- One scenario, one lane. A behaviour and the contract its output satisfies are two scenarios, not one asserting both: a reader of a mixed scenario cannot tell which half is product intent and which is attestation, and a failing count cannot say which lane broke. One scenario proves the resource is created; another attests the response conforms to its schema.
- A report that counts scenarios states the count by lane. A green product lane beside a red conformance lane is a different ship from the reverse, and one blended number tells the reader neither.
Avoid:
- Steps that assert nothing observable, steps whose subject is an abstraction rather than a named actor or system, steps asserting an actor's intent rather than a result, and steps hedged with words such as
should probably or might. Avoid executable requirements buried in Rule: prose; Rule: prose adds durable context only, and requirements belong in scenarios.
- Bare
# comments in .feature files. Durable non-requirement context belongs in Rule: prose. Anything non-durable belongs in CAPTAIN.md, which no role but Captain reads: chat, rationale, or hidden instructions. A comment is neither and reaches every role that reads the spec, so it crosses the Context bulkhead by construction.
- Automation and UI mechanics in step text: selectors, XPath, element IDs, and waits belong in step definitions, not scenarios.
Scantling agreement
A scantling is a machine-readable, testable specification of mechanical shape or a non-behavioural constraint a seam must satisfy. Examples include an OpenAPI document, a JSON Schema, a GraphQL schema, a proof contract with pre-conditions, post-conditions, and invariants discharged by a prover or symbolic checker, or a structural or policy rule set discharged by an engine from the named-engine catalog below. Captain applies this agreement when authoring a scantling; Shipwright uses it to judge a detected candidate for adoption; QM and Boatswain use it to judge existing scantling references.
Named-engine catalog, the one home for the example tools; other text cites this catalog:
- Import-graph policy engines: dependency-cruiser or eslint-plugin-boundaries for a JavaScript or TypeScript import-boundary policy, import-linter for a Python layer contract. These reason over the import graph, so they fit import-boundary and layer constraints and see nothing else.
- Structural query engines: GritQL or Semgrep, declarative queries over syntax. They fit a call-pattern or argument-literal constraint the import-graph engines cannot see. Biome runs GritQL as a plugin, so a project already on Biome adopts one with no new dependency; Semgrep covers Python, JavaScript, and other stacks as a standalone engine. Prefer a declarative query over a grep or regex scan of the source, which matches text rather than syntax and reddens on incidental formatting. These engines query syntax shape, not comment or documentation content: a constraint that keys on an annotation's payload, such as reading a doc-comment attached to a declaration, needs a full AST-with-comments reader instead, such as a ts-morph-backed checker or the stack's own compiler API.
- Duplication scanners: an off-the-shelf scanner for copy-paste or token-similar duplication.
Ownership:
- A scantling is always its own file. Captain owns a project-authored scantling; Crew never writes one, so the durable contract never shares a file with the disposable production code it constrains. A vendored scantling is read-only like any vendored file.
- A scantling creates no work. A scenario references it and asserts a seam conforms; the scantling itself is inert until referenced.
- Every path under
scantlings in RIGGING.md is referenced by at least one scenario. An unreferenced entry is a Captain finding with three outcomes: adopt it with a referencing scenario, remove it, or reclassify it by striking it from the scantlings value, so the file stays as tooling or asset material.
- Do not duplicate scantling shapes or constraints in prose. The Gherkin holds the user or business behaviour; the scantling holds the mechanical shape or constraint: fields, status codes, structure, or a checked invariant.
Attestation:
- When the scantling is a proof, the scenario attests rather than re-enacts: a proof already covers every input, so an example would be strictly weaker and would split the spec across two surfaces that can drift. The scenario names the seam, runs the verifier named in
RIGGING.md, and asserts a clean discharge.
Adoption:
- Prove a newly referenced scantling red once: plant a violation, confirm the conformance step reddens, remove the plant, per the Verification policy's planted-red rule.
- Plant at the cheapest legal layer: a violating fixture or example is QM verification support; a constraint only a production violation can redden, such as an import boundary, waits for Shipwright's harbour plant exception. The deferring report names it unproven and carries it as a harbour item; the next harbour plants it. Nothing records a proof across voyages, and a green run looks the same proven or not, so the obligation lives in the deferral that can see it rather than in every later report that cannot.
Scantling or double:
- Prefer an independent tool when one discharges the constraint, such as a schema validator, a prover, or an engine from the named-engine catalog above, or when the same constraint is consumed by more than one scenario or seam. Match the engine class to the constraint class per the catalog.
- Reach for a bespoke conformance checker when the constraint is structural yet no independent tool expresses it, neither an import-graph engine nor a structural query engine, such as a single-implementation-per-named-behaviour rule that keys on the project's own naming or registration mechanism, or a call-pattern or argument-literal constraint on a stack where no query engine is available. This checker is owned code that asserts real structure, so it is verification support under QM, not a Captain-owned scantling file. It asserts real structure rather than a spied call, so it is not a double.
- Prefer a scenario whose spy carries the inline
@exceptional-double mark, per the Verification agreement, when the constraint is internal composition or wiring observed by a spy rather than an externally checkable contract. There is no independent verifier in that case, only an assertion against recorded calls; relocating that assertion into a scantling file adds a copy of the same fact rather than removing one.
- A
Scenario Outline whose examples all exercise the same central structural seam is a scantling smell, not coverage, and the cost compounds when each example executes a full command or service. The outline's legitimate job is input variation over one behaviour. When the variation collapses to one restated structural fact, prefer a single structural scantling that discharges it once. The same smell survives outside outline form: several separate scenarios, in one feature or scattered across several, that each assert conformance to one exhaustive structural checker are the identical restatement, one checker call per resource where the checker itself already iterates every resource. Fold them into the one scenario the checker's exhaustiveness earns. Distinguish structural acceptance, which a scantling proves, from runtime effect, which one behaviour scenario proves and one feature owns.
- Before authoring a new bespoke conformance checker, search whether one already discharges the constraint. A structural constraint is project-wide by nature; two checkers implementing the identical rule under different names, in different features, both stay green forever, and neither scenario's report can see the other is redundant. The checker belongs in one place, referenced by every scenario that needs it, not reinvented per feature. A search at authoring time only catches the moment of duplication; the recurring case is Shipwright's harbour, per the Fitting out and Work loop sections: derive a
@conformance check over the project's own checker registrations or naming mechanism, proven by a planted red per the Verification policy, so a later feature that reinvents an existing checker reddens the same way any other methodology drift does, rather than waiting on the next harbour's eyes.
- Tag a scantling-backed scenario to the tier matching its checker's real cost. A slow prover or broad static-analysis scan belongs in an opt-in tier, not the default fast tier.
Verification agreement
Verification is the disposable proof of durable scenarios. A scenario states what must be true; verification proves the real thing happened, as fast as real isolation allows. Verification spends time only on the behaviour under test: speed and honesty share one source. In a spec-driven workflow the suite sits on the critical path of every change, so verification latency is iteration latency: a cost paid on every inner-loop run is paid by every future change. QM applies this agreement when writing verification; Shipwright uses it to judge existing verification at harbour, and Captain routes its findings. A violation in verification support routes to QM per the Blocker policy.
Signals:
- End every wait on an observed signal: an event, a status transition, a successful probe. Where no signal is observable, retry in short bounded intervals toward a deadline.
- Gate on readiness after provisioning: poll the resource until it observably serves, bounded by a deadline, and fail with the last observed state. One readiness gate at the provisioning seam replaces every downstream blanket retry.
- Give real-service steps explicit budgets sized to real latency. A budget is a failure ceiling; the step resolves the moment its signal fires.
- Match backoff to the signal. Honour a served
Retry-After. Give transient statuses and connection failures a bounded budget. Fail immediately on a permanent rejection such as an authentication or validation error, so real defects surface fast.
Harmless by design:
- Tests that create or mutate real resources namespace every created object, never modify or delete resources they did not create, use safe or test-mode inputs where relevant, and register idempotent best-effort teardown. Namespaced test-created resources are disposable.
Concurrency has two distinct properties, and only one of them is safe by construction:
- Correctness-safety. Running independent scenarios concurrently produces correct results by construction: the scenario-writing agreement makes scenarios independent and harmless-by-design namespacing makes their resources disjoint, so concurrent results are as trustworthy as serial ones. Isolation gates this property. Before raising worker count, extend the namespace to every path workers share: temp directories, session and state files, caches, ports, resource names. A target that passes only when re-run serially is not yet fixed.
- Resource-safety is NOT safe by construction. More workers can exhaust the machine's real memory or CPU regardless of how well scenarios are isolated from each other, and a resource exhaustion during a sweep can take down unrelated work sharing the box, not just the run that caused it. Start conservative and raise worker count only on confirmed headroom; a worker count sized to theoretical speedup rather than observed capacity is a guess, and a guess that is wrong fails as an outage, not a graceful slowdown. Size concurrency to the tier's binding constraint: local compute for a local tier, the service's real limits for a remote tier. A constant guessed on one machine is wrong on the next.
- Read yesterday's weather. The wake MAY record what each tier's last run observed: wall-clock time, green worker count, and pressure signals such as rate-limit and memory errors. Start from that record and adjust on live pressure, never the reverse: reading pressure signals after a run that already exhausted the machine confirms the failure, it does not prevent it. Per-scenario timing is a harbour concern, captured during Shipwright's full regression per the Shipwright skill, not a standing obligation of this at-sea record.
Reuse:
- Provision ambient state once and share it. State that no scenario asserts is setup cost: build it once per run behind a lock or marker file, or reuse a resource already present. Sharing stays safe because each scenario creates, mutates, and asserts only its own namespaced objects inside the shared state. The amortization horizon is the voyage: a later run MAY reuse ambient state an earlier run built, and the reclaim at suite start stays the safety net.
- A scenario provisions its own copy only when provisioning is the behaviour under assertion.
- Contain real creation of an expensive external resource to the one seam that creates it, tested for real there and reused per this rule. A seam that only calls into that creation seam is tested for the call, its spy marked inline
@exceptional-double on the composition ground, not for creating the resource again.
- Excess setup cost is verification debt. A fixture provisioned larger than the behaviour asserts, or a resource re-created per scenario where once-per-run sharing would serve, breaks this reuse rule. Verification debt on green scenarios reaches QM only as failing verification: where the verification-conformance scantling from the Shipwright skill is derived, the breach reddens its conformance scenario and rides the watchbill like any target; a debt kind the rule set misses is a rule entry Captain adds, never a new scenario.
- A slow real-service scenario is not automatically a scantling candidate. First ask whether the behaviour needs real execution, such as an install actually landing files. When it does, the lever is minimal-sufficient fixture and reuse, not a scantling: exercise the behaviour through the smallest real resource that proves it, and provision a full set only where the full set is the assertion. A scantling MAY add a cheap structural guard for a packaging facet, but it does not replace the runtime proof.
- Expensive spend is licensed, recorded, and joined. Where a tier's scenarios can spend an expensive resource, such as a full toolchain run, a cloud resource creation, or a model invocation, the licence is a tag Captain assigns in the spec, so the set of scenarios entitled to the spend is declared and enumerable, never inferred from prose. The spend is recorded at run time by an interception ledger, such as a PATH shim that logs argv and then execs the real binary, and each ledger entry is attributed to the running scenario. A derived check joins the ledger against the licensed set: an entry attributed to an unlicensed scenario reddens, naming the scenario and the spend it made; shared provisioning recorded more than once per resource class in one run reddens; a run that produced no ledger reddens, so a broken recorder cannot disarm the check. The check is proven by a planted red at adoption, per the Verification policy.
Budgets:
- A tier MAY carry a
budget wall-clock ceiling in RIGGING.md under ## Tiers, and the full regression MAY carry one. A budget is a ceiling, not advice: the derived budget check reads the wall clock the tier's weather record already carries and reddens where the recorded time exceeds the budget, so a suite that outgrows its budget interrupts the voyage like any red rather than waiting for the next harbour economy audit. Captain sets the values with the user; the check needs no new instrumentation.
Seams:
- Exercise behaviour through narrow seams with explicit inputs and observable outputs. Production code SHOULD expose such seams for scenario behaviour, keeping product logic separate from side effects where practical so verification can exercise real behaviour deliberately. Product logic reachable only through constructors, global state, static initialization, singletons, registries, service locators, or framework lifecycle hooks blocks real verification; report the seam as a Crew target or harbour finding.
- Testability refactors MUST serve current verification-discovered work, not speculative architecture cleanup. A verification seam MUST NOT replace normal-path real coverage with the doubles the "Real by default" Article forbids.
Teardown:
- Reclaim leftover namespaced resources at suite start; this is the primary safety net, since a crashed or killed run cannot be trusted to have torn down after itself. A scenario that provisions its own resource additionally registers teardown before creating it, with the same signal-matched retries and a generous budget, and lets failure fail the run loudly. A quiet teardown failure leaks resources and masks green results.
Proof:
- Green means the real thing happened. Assert the artifact only the real path can produce: the live reply, the served response, the persisted record, the package installed from the registry. An assertion a double could satisfy proves the harness, not the behaviour.
- A test double in the Meszaros sense is allowed only for one of three named conditions: a specific condition the real environment genuinely cannot produce on demand; internal composition or wiring with no independent external verifier, per the Scantling agreement's scantling-or-double clause; or a real dependency that the subject under test only calls into, where the subject is a layer above it, the dependency's real behaviour is covered for real in another tier, and every canned response is a golden capture recorded from the real dependency and re-verified against it on a stated cadence such as harbour. A hand-authored canned response is the forbidden fake; only a golden capture, refreshed on its stated cadence, stands. Mark and justify every double inline with
@exceptional-double, naming which condition applies. It MUST never replace normal-path real coverage.
- A non-product failure is a harness defect. Engineer it out with a readiness gate, an isolation fix, or a reclaim at suite start. A harness defect is never a product target and never a reason to rerun: a role that cannot fix it now raises a blocker. Shipshape keeps no register of failures it has agreed to tolerate, because a failure a role is licensed to ignore is a failure nobody fixes, and it masks the product regression that lands behind it.
Planking agreement
Feature files are canon. Shipshape derives trace from current feature files, through scenarios and steps, into step definitions and production seams. An individual plank may be as small as an argument, expression, branch, call, state change, or persisted value, so trace annotations are hoisted to seams: Planks may be distributed below that boundary. Crew and Shipwright apply this agreement when planking; QM and Boatswain use it to judge planks. The "Every production seam is planked" Article carries the seam obligations: at least one @planks(...) annotation, and behaviour only within the related step contracts.
Form:
@planks("<step definition pattern>") is a documentation-comment tag on the seam declaration whose behaviour that step requires. Write it in the language's docblock form, such as /** */ in JavaScript or TypeScript, attached to the declaration that is the seam. Docblock placement lets a docblock or AST reader inventory every plank completely, and makes plank placement an executable form check rather than a human-read judgment.
- The plank string is exactly one of the project's current step-definition patterns, carried verbatim and unmodified, such as
@planks("I ask for the next low tide after {string}"). Verbatim means the pattern exactly as the step definition declares it and exactly as the step-usage command reports it: those two are the same string, and the plank is that string with nothing added. The binding keyword is the step definition's own construct, not part of its pattern, so it is never carried into the plank. A form assembled from parts matches neither source, and every role that writes or judges a plank then pays string surgery to build it and undo it; carrying the reported pattern makes the cross-reference an exact-string set membership on every stack, and lets a stack whose runner reports no usage still check planks against the step-definition source directly. The pattern is the durable contract; a scenario's concrete example values are not, and a plank copying a concrete step line stores a second copy of a join step-usage already derives, then drifts with every data edit. One form makes plank form decidable. A step definition binds Given, When, or Then. Normalize And and But to the inherited Given, When, or Then when reading a scenario to find its binding.
@planks-provisional("<scenario reference>") is the provisional plank, a distinct annotation and never a second form of @planks. A seam a @captain skeleton describes has no step definition, so no pattern exists to name; the provisional plank names the skeleton's scenario instead, in the repo-root-relative <spec>.feature:<Scenario Name> form the watchbill already uses. It announces itself, and it keeps the seam findable: a plank is the durable link from a seam to its behaviour, and a link living only in a role's report dies with that context, so a promoted scenario whose seam was never planked reaches a fresh role with no pointer to the code that already implements it, and the seam is reimplemented and the original left as dead code.
- A provisional plank liquidates itself, and Captain's disposal of the skeleton is the trigger. Captain disposes of a
@captain skeleton in one of two ways, and each liquidates the annotation. Promotion: Captain removes the @captain tag, so a @planks-provisional naming a scenario that no longer carries @captain is red. QM finds the seam by searching for the annotation that names the promoted scenario, with no seam hunt, and dispatches Crew to replace it with @planks(...) carrying the pattern QM has just authored, per the QM skill's plank-only dispatch. Discard: Captain removes a superseded skeleton under the "Current design only" Article, so a @planks-provisional naming a scenario that no longer exists is spent, and it is spent with no pattern to inherit, because no step definition was ever authored for it. QM dispatches Crew to strike the annotation, and the seam is then judged as any other: a seam that keeps another @planks(...) is planked and complete, and a seam left with none is unplanked, which is either behaviour no current scenario describes and goes under the "Current design only" Article, or behaviour the product still needs and is a Captain blocker for the scenario that was discarded with it. Discarding a skeleton disposes of the annotation and MUST NOT be left to harbour: Captain's own act created the state, and the seam is in hand.
- Hoist annotations to the smallest stable seam that owns the behaviour. Do not annotate individual lines, expressions, branches, or helper fragments. A plank in a line comment or on an in-body fragment is malformed; hoist it to the seam declaration.
- A seam MAY carry Planks for several steps. A step MAY be carried by several seams. Not every step requires Planks: setup and assertion steps often use only verification support.
- Where several steps could carry the plank, prefer a behaviour-bearing step over a data-bearing one.
Judging:
- Judge planks by running commands, never by reading them, per the Verification policy's check-precedence rule.
plank-inventory lists @planks and @planks-provisional alike, and also scan for bare tokens across the implementation paths, because a token outside a docblock on a declaration is a malformed plank the docblock reader cannot see. Where the stack has no docblock or AST reader, the plank rules ride the derived verification-conformance rule set, per the Shipwright skill's Methodology checks, each proven red by a plant at adoption.
- The trace runs seam to plank to step definition to scenarios, and the runner owns the last hop:
step-usage reports each pattern with the scenarios that bind it.
- Cross-reference each
@planks string against the step-usage patterns by exact string match, with no normalization on either side: the reported pattern is the plank's whole content, so the join is set membership and nothing else. A plank matching no current pattern is stale or malformed: its step definition was deleted or renamed, or the plank carries text the pattern does not, such as a leading Given, When, or Then.
- Cross-reference each
@planks-provisional reference against the @captain scenarios in the specs. One naming a @captain scenario conforms and waits; one naming a promoted scenario is red and owes its pattern; one naming no current scenario is red and owes its removal, the skeleton having been discarded. Every member of this list carries an act; a state named here with no act is a deck no role can clear.
- Stale and malformed planks are corrected, never trusted. On a touched seam in the role-advanced diff, a plank that is missing, stale, or malformed is the same fault, unfinished Crew work, and routes to Crew for redispatch: the role that wrote the seam this voyage is the role that corrects it, while the seam is still in hand. A malformed plank is the more dangerous of the two, because it reads as coverage the seam does not have. Only plank drift beyond the current diff defers to harbour, per the Blocker policy: harbour is where a fault no current role owns goes, never where a fault this voyage introduced is parked.
- A plank whose pattern survives while its seam no longer serves that step is behaviour-stale and invisible to the pattern join. Harbour's coverage triage is the net; a role observing one reports it rather than trusting the join.
Selection:
- The planks of a touched seam select its recheck. Join the seam's plank patterns through
step-usage to the scenarios that bind them, and run that focused set. When attribution inside a file is unclear, take every plank in the file.
- A touched production hunk with no plank to follow is plank drift, judged per this agreement; static discovery and the derived
typecheck and lint gates stand as its proof meanwhile.
- Verification support code carries no planks, so the plank join does not reach it. It executes inside every scenario whose steps route through it, and its blast radius is the tier it serves, never the spec file the change was declared beside: a touched support hunk selects that tier's enumeration sweep. A focused run over a subset of that tier does not cover it, and neither does a green the caller carried from one: the scenarios such a run never reached are exactly where a support edit does its damage. A support edit that changes behaviour loads, imports, typechecks, and lints exactly as the old one did, so the static gates pass it through and the sweep is the only check that reaches it.
Limits:
- Trace annotations MUST NOT define product intent, create worklists, or replace verification. Worklists come from failing verification over the watchbill's ordered scope, per the Watchbill policy.
- Do not trace production code to features or scenarios. Scenario coverage is derived through Cucumber's scenario-to-step mapping. Support artifacts MAY use project-appropriate comments when ownership or deletion is unclear, but they MUST NOT define product intent.
Role flow
User to Captain: intent becomes durable specs and watchbill.json. Captain routes a dirty deck through Boatswain before dispatch. Context clears. QM runs the watchbill's ordered scope and dispatches Crew per failing target. Crew makes the smallest production change and returns. Boatswain does post-implementation hygiene, reverifies, and commits locally. Captain reports to the user and handles outbound.
Narration
Silence is made by isolation. A foreground role needs no narration rule, because its commands, runs, and edits reach the human as they happen. Dispatching a role into an isolated context hides its work, and the human watches a blank deck for as long as that role runs, so a role that dispatches into isolation owes that visibility back: dispatch only where the dispatched role's progress reaches the human, directly where the runtime surfaces it, or through an active seat that narrates it. Where neither route holds, run the role in the foreground instead.
The narrating seat surfaces plain text while dispatched work is in flight, at least once every two minutes: what is running, what it has produced, what it is waiting on. Narration is prose a human reads; a status display, a task list, and a raw transcript dump are not narration. It carries the dispatched role's observable signals, such as streamed verification output, tier transitions, and touched files, never its context, so internal roles stay terse in their artifacts and only their signals are narrated. A live signal surfaces a wrong turn while a human can still act. An announcer tone is welcome.
Narration is not a wait. The narrating seat reports what it can already see, and completion arrives as the dispatched role's report, per Hand-off custody. A seat that wakes to ask whether the work has finished has built the busy-wait that rule forbids. A runtime that spawns roles SHOULD carry this surfacing as machinery, since a nested role cannot narrate for a role it did not dispatch, and only the runtime sees every seat.
Role transitions
A role hands off to the next role. On any transition, the preceding role's final-report blockers and open questions are the first work item: handle blockers first, then other duties. Current hand-off evidence takes priority over older notes. How the hand-off happens depends on the coding agent.
- If the agent supports context-isolated subagents, spawn the next role as an isolated subagent. Where that mechanism exists it is the route an internal role takes, not merely the better of two. A fresh context window carries no Captain content, which satisfies the clean-context bulkhead and prevents accidental contamination. It is also the only route that carries the role's identity: a runtime enforcing any of this mechanically knows which role is acting from the dispatch, so the same act by the same skill loaded in the human-facing session is unguarded. That asymmetry is invisible where it matters, since both routes announce the same role and read the same skill, and a rule enforced on one route and not the other is worse than one enforced on neither: the guarded route teaches the operator to trust a guard the other route does not have. Where the runtime offers no such mechanism the fallback below stands, and doctrine alone carries the bulkhead there, so every read form these Articles name is obeyed as written rather than left to a guard that will not fire.
- A fresh context window is the isolation floor. A shared on-disk transcript is a residual side channel: discarded conversation context an internal role MUST NOT mine, and the runtime SHOULD block internal-role reads of it. A window-isolated subagent serves a routine transition; reserve a fresh session, which closes the residual fully, for opt-in strict work.
- If the agent supports only context-inheriting subagents, spawn an inheriting subagent. This is acceptable for QM to Crew. It MUST NOT carry Captain or human discovery context across the Captain to QM bulkhead.
- If the agent cannot spawn subagents, the current role temporarily assumes the next role, then returns, except where assuming would take a write scope that is not the assuming role's. The Write scopes are strict Article binds the role that is acting, not the skill text most recently read: a runtime enforcing custody reads the acting role from the dispatch, so an assumed role's writes arrive under the assuming role's identity and are denied, which is the correct outcome and not a fault to route around. Where the next role's job needs a write the current role does not hold, the current role does not assume it: it ends in its final report naming that role, the targets and the base commit, and the caller dispatches, per the flat hand-off in Hand-off custody. A role that cannot spawn is not thereby licensed to write what it could not write anyway. Captain to QM is the exception: Captain never assumes QM, because that boundary requires clean context, as the next paragraph carries. While a role assumes an internal role, it MUST ignore any human input that arrives in flight. It MUST leave that input in context for Captain to handle on return. Only Captain consumes human input.
Captain to QM always requires clean context. A window-isolated subagent or a fresh session both satisfy it. If the runtime provides isolation automatically, continue. If not, Captain tells the user to start a fresh session, then run /qm. A same-session clear resets the window but not the transcript, so it is the weaker option where the transcript persists. QM re-checks context on load and refuses if Captain or human discovery context is visible in its window.
Dispatch contract. A dispatch carries its row and nothing else: the durable artifacts are the hand-off. Craft notes, seam hints, and expected failure modes are contamination even when labelled tooling facts. Each internal role verifies its dispatch against its row on open.
| Dispatch | Carries |
|---|
| Captain to QM | role, base commit |
| QM to Crew | target scenario references: one target, or several targets of one watch whose fixes land on one seam cluster; observed failure evidence per target; solo or parallel marker; for a perturbation target, also the perturbed seam location |
| To Boatswain | job, base commit, and the advanced target references for a post-implementation job |
| Captain to Shipwright | role, base commit, optional scope |
When the project root is not the session's working directory, every dispatch also names the project root. A perturbation's seam location is observed evidence from the failure output, not a seam hint. QM reads watchbill.json at the project root: the file is the channel, so the dispatch carries no pointer. A dispatch to Boatswain names the job: pre-clean for a dirty deck, or post-implementation after Crew work and for harbour custody, per the Boatswain skill. The post-implementation custody dispatch follows QM's final report and is issued by QM's caller, per the flat hand-off in Hand-off custody. A role that enters with no dispatched base commit takes HEAD as the base commit.
Contamination protocol. Contamination is Captain or discovery content in an internal role's context, however it arrives. Three cases, by vector:
- A dispatch beyond the contract, or discovery content arriving by any vector not named below, such as tool output: stop, report contamination in the role hand-off, and await a fresh dispatch.
- Discovery content inside a durable artifact, such as a bare
# comment in a spec: a spec-quality blocker to Captain, not a dispatch refusal. Quarantine the content by not acting on it and continue. The legal alternative to richer prose is a durable check: recast the finding as a scenario or scantling carrying no rationale, for the next role to discover on its own.
- Runtime-injected memory: it recurs by mechanism, so report a Captain configuration blocker naming the mechanism, and Captain disables that memory feature for role sessions before work resumes.
Hand-off custody
A role hand-off carries a final report and any blockers. The report travels by the transition mechanism, not by a separate file. When a role spawns the next role as a subagent, the report is the subagent's return value to the caller. When a role assumes the next role, or uses an inheriting subagent, the report stays in shared context. Shipshape does not persist role reports to disk.
A role never ends its turn holding work that cannot resume it: not a background command, a notification, or a timer. A dispatched agent is not that case, because its report resumes the caller, per the dispatch rule below. Work in flight at report time is either consumed before the report or named in it as a blocker. A verification run whose output the role has not read is not evidence and counts as never run.
A report states what the tree answered. Every factual claim a report makes about the tree, such as a file's presence, an annotation's form, a command's output shape, an endpoint, or a check's result, is the output of a command the role ran, never a recollection and never an inference from what the role wrote earlier. Run the command once and let the tree answer. Where a role has not run a command that establishes a claim, it labels that claim unverified, or it leaves the claim out. An unbacked tree claim is a fault, because a report is the next role's evidence: it spends that role's turn, or its custody, on a fact nobody checked. A role that judges a property by reading the code names the check it lacked, per the Verification policy's check-precedence rule.
A role waits on an observed signal, never on a clock. The Verification agreement binds a role's own waiting as it binds the verification it writes: a run ends on its process exit, and a dispatched agent ends on its report. Where a run would outlast the runtime's foreground command budget, the role first raises that budget for the run: it names a timeout that covers the run's expected duration, and the run stays in the foreground, where its exit is the role's own next line and no hand-off can be lost. A run that has not been given a budget it can finish in has not been set up to be waited on. Detaching is the fallback for a run no budget covers. For a role dispatched as an isolated subagent, it is only a fallback, because a detached run's completion cannot resume a turn that has already ended: such a role consumes the output within the same turn, reading it to the summary line, or names the run in its report as a blocker. A role operating as the operator's own undispatched session carries no such limit where the runtime resumes that session on a background command's exit as reliably as it resumes it on a dispatched agent's report; there, detaching is a live wait, not only a fallback, and the resulting notification is the run's own next line, never polled for. Confirm which case applies before relying on it: an undispatched session that cannot observe its own resumption on a background exit holds the dispatched-subagent rule instead. A sleep loop that re-checks a process, a file, or a clock is a busy-wait, not a signal: it spends the turn to learn what the exit already reports, and it is what a stalled role reaches for. A runtime that spawns roles SHOULD carry this rule as machinery, resuming a role on the signal it waits for, so a turn cannot end holding live work. A skill-only agent holds it by discipline, and discipline alone has been observed to fail here for a dispatched subagent.
The report is the only channel that says a dispatched role is done. A role MAY dispatch several agents in one turn: it ends its turn, and consumes each report as that report arrives. A role never builds its own completion check. Reading a dispatched role's transcript, process table, or working files to infer whether it has finished is that invented check, and the formats such a check reads are runtime internals, not a contract it may rely on. Reading a dispatched role's progress to narrate it, per Narration, asks a different question and is not a completion check.
The QM to Boatswain hand-off is flat. When the watchbill is spent and its targets are green, QM's work is complete: no decision left to QM turns on what custody finds. QM ends in its final report, naming Boatswain, the advanced target references, and the base commit, and QM's caller dispatches custody. Boatswain reports to Captain. A custody foul needs no return path to the QM that ran the voyage, because a fresh QM re-derives the foul from the touched seam and its missing plank, per the QM skill; the foul direction already works this way, and the green direction is its mirror. QM to Crew stays nested: QM needs Crew's outcome to choose the next target.
The Captain to QM boundary is different. Context clears there, so no report crosses it. QM derives everything from durable artifacts by design. The durable artifacts are the hand-off at that boundary. The bulkhead is one-directional, Captain to QM only. Blocker returns to Captain are ordinary hand-offs. "Read the preceding role's blockers first" applies to the transitions that do not cross the bulkhead: Captain to Shipwright, Shipwright to Captain, QM to Crew, Crew to QM, QM to Boatswain, Boatswain to QM, QM to Captain, and Boatswain to Captain.
A blocker that must reach Captain is delivered before any context clear: the role returns to Captain, or encodes the change into a durable artifact. If a role sees no blocker, the deck is clean, not lost.
Harbour flow
Shipwright handles harbour work: existing-codebase onboarding and maintenance between releases. Shipwright inventories production code, adds @planks(...), writes non-binding @captain scenarios, and returns to Captain for review. QM ignores @captain and @shipwright scenarios. Harbour findings that do not become a @captain scenario or a @planks(...) annotation are report-only: they live in the role report, and the next harbour re-derives them from repository signals such as coverage, the plank inventory, the import graph, and the weather record. Harbour begins on a clean working tree; uncommitted voyage work routes through Boatswain custody first, so it enters harbour committed. Pending outbound, local commits ahead of upstream or an unmerged release branch, is no bar: Shipwright names it in the report, harbour work rides the next outbound, proved per the Verification policy. Harbour procedure and guards live in the Shipwright skill.
Shipwright's verification-economy audit reports per-scenario findings to Captain, each with its lens. Captain routes each finding by kind: a cheaper spec form becomes a @captain faster-form skeleton that supersedes the slow scenario; a same-behaviour support cost is verification debt, routed as failing verification: Captain adds the missing rule to the verification-conformance scantling where one is derived and lists the conformance scenario in the watchbill, so the debt reaches QM as a red target rather than prose; a cadence change is a tier retag Captain makes. Whether to split, optimize, retag, or accept is a Captain judgment, not a harbour edit.
Project configuration
RIGGING.md holds the project tooling values that roles read on open. AGENTS.md is the human-facing entry document. It states that the project uses Shipshape and MAY point to RIGGING.md. Longer tooling prose, such as a detailed sandbox provisioning or outbound policy that does not fit a short value, belongs in AGENTS.md. The machine-read values belong in RIGGING.md. Shipwright scaffolds AGENTS.md and RIGGING.md during fitting out. The fitting-out procedure and the templates live in the Shipwright skill.
Rigging read contract
RIGGING.md uses a fixed Markdown shape; the Shipwright skill carries the Rigging shape and derives the file. Roles read it on open and parse it by heading: each value is a Markdown list item - <key>: <value> on its own line, and a multi-value key repeats on a new line for each value. It holds values, not procedure. A context-isolated Crew mate MUST be able to succeed from RIGGING.md alone. The minimum required values are language under ## Stack, implementation and specs under ## Directories, focused under ## Commands, and perturb under ## Perturbation. Roles validate RIGGING.md on read. A malformed file or a missing required value is a configuration blocker to Captain. RIGGING.md is Shipwright's to derive and repair; Captain routes a rigging configuration blocker to Shipwright, which refits the missing values. Captain discovers a value with the user only when Shipwright cannot derive it. A command value is proven by running it, per the Verification policy's check-precedence rule. Before RIGGING.md is written, the deriving role runs the runner once through a derived command and confirms it executes; execution is the whole proof, and no scenario need exist yet nor pass. A command that will not execute is a tooling blocker to Captain, resolved before the next role sails. A derived command that has never run is a claim, not a value, and the role that inherits the claim is the one that pays for it.
Beyond the minimum, roles rely on these read-side conventions. A role runs a derived command verbatim from RIGGING.md, composing only the substitutions this contract names: the {scenario} placeholder and tier tags defined under ## Tiers. An invented tag or a hand-rewritten flag is command drift, not composition. The focused command uses {scenario} as the target placeholder, and a target reference uses the repo-root-relative <spec>.feature:<Scenario Name> form. The discover command is static discovery: the runner's dry-run form, listing undefined and unimplemented steps and executing nothing; the failing set comes from focused runs and ordered enumeration sweeps per the Verification policy. Every verification command composes the tag exclusions, --tags "not @captain and not @shipwright" or the runner's equivalent; a role composes them onto any derived command that lacks them. Optional command keys under ## Commands are discover, broad, coverage, step-usage, plank-inventory, typecheck, and lint, each a single command, with tier-suffixed variants such as coverage-sandbox where a tier needs its own invocation; an underivable slot reads none. The ## Perturbation message value always contains the literal token PERTURBATION, so any role finds a live perturbation by searching for that token. The ## Dependencies policy value locked means installed versions stay pinned until a spec or a Captain decision moves them.
The project configuration files that RIGGING.md documents are the ship's rigging, such as the package manifest, the lockfile, and the tooling and lint configuration. Shipwright fits the rigging during fitting out. Boatswain maintains the code and configuration hygiene tooling; Captain owns and tunes the lint configuration for Captain-authored artifacts, such as a feature lint config. Captain selects dependencies and records them under ## Dependencies, and installation is fitting out. Every install and every upgrade is Shipwright's, at fitting out and at harbour alike, or Captain's on the greenfield fast path where no fitting-out session exists; no dependency routes through Crew. Recording routes with installation: the installing role writes its dependency line under ## Dependencies in the same pass, the runner and each confirmed tool included. Crew is dispatched only for a failing target, so the rigging's own dependencies could never route through it at all: until the runner is installed no target can fail, and that route is a circle. A product dependency does not route through Crew either, for two reasons the consumer split obscured. Installing moves the lockfile, the resolution graph, and the engines constraints, a tree-wide blast radius that contradicts Crew's charter of the smallest change for one failing target. And whether a given dependency is the rigging's own or one the implementation consumes is a judgment needing tree-wide context, which the isolated role is worst placed to hold and the fitting role holds by construction. A spec that needs an uninstalled dependency is a Crew blocker to QM, raised to Captain and routed to Shipwright, one round-trip. An upgrade the dependency policy itself orders, such as a held version under a latest-stable policy, has no failing target and no spec ordering it: it is harbour work Shipwright takes up directly, and needs no Crew route to exist. So none stands under ## Dependencies only where nothing is installed, and a focused command that names a runner above dependency: none is a contradiction the shape forbids.
Project policies
These policies apply to all Shipshape project work.
Blocker policy
Every role reports blockers with concrete evidence in its role hand-off. A finding routes by artifact ownership:
| Finding | Reported to | Resolved by |
|---|
| Missing or contradictory product intent | Captain | Captain updates durable specs, and assets when the asset itself changes |
| Environment or tooling fault, such as a missing tool or an observed authentication failure | Captain | Captain |
| Rigging or configuration fault | Captain | Shipwright refits, per the Rigging read contract |
| Verification-support violation | QM | QM, in place |
| Trace annotation or plank drift | Role hand-off, deferred | Shipwright, at harbour |
Spec or watchbill.json methodology failure | Captain | Captain |
| Production-code failure | QM | Crew, and Crew is dispatched only for production-code failures |
| A deadlock, or a critical correction no available role may make | Captain | Captain, by the minimal action that restores progress, recorded |
Captain's authority at sea. These Articles exist so that production code derives from durable specs. They do not exist to stop Captain making progress. Captain strives to follow them, and departs from them only where following them would stall the voyage or leave a fault uncorrected. Where no legal transition can make progress, or a critical correction is owed that no available role may make, Captain names the situation, states the routes it tried, takes the minimal action that restores progress, and records it as a named decision in its notes and its report.
One boundary holds absolutely: outside the Perturbation policy's narrow, named exception, Captain never writes production code. That is the guarantee these Articles exist to protect, and it always routes through a durable spec to QM and Crew. Everything else is within Captain's authority when the voyage would otherwise stall: striking a spent watchbill, making a custody commit, correcting rigging, repairing a malformed record.
A situation that reaches this rule is a doctrine defect. Report it as one, so the rule stays a last resort rather than a habit.
After Captain resolves product intent, the return to QM crosses the bulkhead again: an isolated subagent, a runtime auto-clear, or a fresh session, per Role transitions.
Working tree policy
Humans edit at any time. A role owns only the edits it makes and leaves every other working-tree change untouched. A role never treats the tree's existing state as its own work. Read that state with the notes excluded. A diff of the working tree or of history prints the content of every changed file, so a CAPTAIN.md the role never named arrives in its context through a command that looks like ordinary deck reading, and the bulkhead is crossed by an act no rule appears to forbid. Carry the exclusion in the command itself, as git diff <base> -- . ':!CAPTAIN.md', and carry the same pathspec on git show, git log -p, and git stash show -p. An unscoped diff of a tree whose notes have moved is an unchecked read, whatever it was reached for. Boatswain stages only role-advanced hunks and leaves unrelated operator work for Captain. Dirt is a change no role in the current voyage owns. Uncommitted durable artifacts that order the current voyage's work, such as Captain's freshly written specs, are work in flight, not dirt: QM reads the artifacts as they stand, and Boatswain stages and commits them together with the role hygiene edits and the production change they order.
Asset policy
assets/** are human-owned product material under Captain custody during Shipshape work. The human operator owns product decisions and content. Captain MAY edit assets to capture approved product material, examples, fixtures, screenshots, pages, copy, media, or other support material.
Assets MAY be referenced by scenarios or verification. Assets MUST NOT define Shipshape workflow, hidden requirements, backlog, rationale, project memory, or agent instructions. Only .feature specs and verification output create agent work. Product-facing content SHOULD live in assets or project-approved content catalogs. Content consumed by a build or generator, such as static-site pages, templates rendered as content, and data files, is product material under this policy, not production code. If asset content or exact catalog content must be protected as behaviour, Captain specifies that behaviour in a .feature scenario. Guaranteed behaviour promotes to a .feature scenario; the asset body carries craft only.
A user-supplied asset is the user's stated intent end to end. When Captain classifies any part of it as out of scope, non-binding, or otherwise excluded from the derived specs, that exclusion is an open question, not a decision. Captain MUST NOT dispatch QM on work derived from that asset while an exclusion stands unconfirmed: the gate holds until the user confirms the exclusion or the sections enter the specs. Record each pending exclusion as a named question in the final report and in CAPTAIN.md until the user rules.
Artifact authority policy
Do not create extra binding Shipshape artifact types such as constitution, project-rules, memory-bank, decision-log, architecture-notes, roadmap, or backlog files. Product behaviour belongs in .feature files. Tooling configuration belongs in AGENTS.md and RIGGING.md. Directed work selection belongs in watchbill.json. Captain-only non-binding notes belong in CAPTAIN.md. Historical rationale belongs in git history and commit messages.
Watchbill policy
watchbill.json is the verification scope order and the only channel that creates QM targets: Captain limits what is verified, and verification output over that scope creates the worklist. The watchbill selects and orders; it creates no work itself. Captain writes fixed-shape watchbill.json as intent lands: a new or edited scenario's entry is written with the edit, a tier tag enumerates a tier's failing set, and a perturbation's planked scenarios enter at plant time per the Perturbation policy. If watchbill.json and verification disagree, verification wins. A spent watchbill is struck: Boatswain removes the file and stages the removal with the custody commit that closes the voyage, per the Boatswain skill. Captain MAY withdraw intent early by removing the file; a watchbill with entries no report verifies is not spent and stays for Captain. Absent at rest is the healthy state: QM dispatched with no watchbill reports the deck at rest. A scenario the scope missed waits for the next harbour full regression, per the Verification policy.
watchbill.json contains only ordered watch objects named watch1, watch2, and onward. Each watch contains only scenarios, an array of references in <spec>.feature:<Scenario Name> form or a tier tag defined under ## Tiers in RIGGING.md, with no prose, metadata, or hidden context. A scenario reference is repo-root-relative and includes the specs directory. A tier tag directs QM to run that tier unfiltered, at normal concurrency, rather than through the per-scenario focused command; a focused reference cannot reproduce a defect that only manifests under real multi-scenario concurrency. A tier-tag watch is the sanctioned full-tier exception: QM runs that tier as a directed watch, distinct from focused confirmation. A tier-tag watch is one enumeration sweep, spent once its red list is dispatched to focused targets; it does not stand as an order to rerun the tier after every fix. When tier-tag watches cover several tiers, order them cheapest tier first; a red tier's dispatches complete before a costlier tier runs. QM processes all watches in order unless verification, product intent, environment, or tooling blocks.
Verification policy
Use project-specific commands from RIGGING.md. Progress is measured by verification status, not by a separate checklist. Passing checks are evidence, not proof. Skipped verification is unverified. Reports MUST distinguish fresh results from cache-backed results, and a deck-clean claim names its scope: the watches spent or the regression run. QM owns verification procedure details.
Verification runs in named shapes. Each question has one minimal shape; spend execution only on the question asked:
| Question | Shape | Cost |
|---|
| Do specs still parse and bind to step definitions? | Static discovery: the discover dry-run, a proof gate rather than a work channel | Executes nothing |
| Does this target pass? | Focused run: the focused command for the target | One scenario |
| What currently fails in a tier? | Enumeration sweep: the tier unfiltered, without stop-on-first-failure, ordered by a tier-tag watch | One full tier, spent when its reds are dispatched |
| Is the ship sound? | Full regression: every configured tier, cheapest tier first | Full suite, at harbour only |
A directed target's undefined steps surface in its own focused run output, so no census precedes the work. When step-usage runs, its dry-run output also stands as static discovery: one run serves both questions. Within a voyage a fix is proven by its own target's focused run, not a tier rerun; re-running known-green scenarios to reach the next failure is wasted cost, acute on a paid tier. Custody inherits the same economy: a fresh focused green carried in the caller's hand-off is inherited commit evidence, and Boatswain reruns only a staged hunk that lacks it or that the diff contradicts, per the Boatswain skill. Selection MAY narrow intermediate confirmation, and the full regression is the one run selection never narrows. The full regression is a harbour action, and harbour is its only trigger: it runs whole there, and it runs nowhere else. Harbour is the one pivot that pairs the run with coverage triage and the verification-economy audit, and that pairing is what makes a whole-suite run worth its cost; the same run at any other pivot spends the cost and discovers nothing with it. Outbound proceeds on the focused and enumeration evidence the voyage already produced. Sequencing is the user's free choice: ship now and harbour later, or harbour first when a whole sweep before shipping is wanted this time.