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.mdat the project root. If absent, the project is not fitted out, and the route forks on production code. Production code present: route to/shipwrightfor fitting out and harbour inventory. No production code: route to/captainfor 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.mdis present, the project is fitted out. Route to/captainfor 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-basicengwhere 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.mddocuments; 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
.featurefiles.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.mdandRIGGING.mdare 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@captainscenario in harbour. Dead code does not block the voyage: it is reported and deferred to harbour, which re-derives it from repository signals.@shipwrightcondemns 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@shipwrighttakes 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,
.invalidendpoints, 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:
.featurespecs,assets/**, andwatchbill.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 optionalwatchbill.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 fromRIGGING.mdand@planks(...)trace annotations on production seams. The write-scope exceptions, one per line:- Boatswain MAY mark a scenario
@shipwrightto condemn it. - Captain MAY add a perturbation to production code, per the Perturbation policy.
- Captain MAY write a tooling value into
RIGGING.mdwhen 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'sbudgetceiling 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.jsonwith the custody commit, per the Watchbill policy. - During harbour only, Shipwright MAY create and refit
AGENTS.mdandRIGGING.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.jsonits 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.
- Boatswain MAY mark a scenario
- 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@captainskeleton 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: oneFeatureper 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:
Givenis concrete starting state,Whenis one named action,Thenis one observable assertion. Keep strictGiven,When,Thenorder with no repeated phase; useAndandButsparingly for same-phase continuation. Gherkin has noOr; split a choice into separate scenarios or aScenario Outline.- Use minimal sufficient
Givenstate, and prefer state over navigation: assert the user is signed in rather than scripting the click path to sign in. UseBackgroundonly for shared starting state. - Removing or merging a
Givenstep 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 theThenasserting 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 Outlineonly 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
@contractscenario 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@conformancescenario 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 probablyormight. Avoid executable requirements buried inRule:prose;Rule:prose adds durable context only, and requirements belong in scenarios. - Bare
#comments in.featurefiles. Durable non-requirement context belongs inRule:prose. Anything non-durable belongs inCAPTAIN.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
scantlingsinRIGGING.mdis 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 thescantlingsvalue, 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-doublemark, 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 Outlinewhose 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
@conformancecheck 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-doubleon 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
budgetwall-clock ceiling inRIGGING.mdunder## 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:
- `
…(truncated)