Skip to content

Epic: contract-edge gates — planner wire-surface checklist, contracts registry, mock parity, assembly stage (from the 2026-07-10 one-CP retro) #59

Description

@sawy3r

Finding

A 17-slice release ran under full Baton discipline (per-slice fresh-context adversarial verification, all PASS) and every build halt was a planner-owned cross-slice contract seam — an agreement between two specs that no single spec owned and no per-slice verifier could grade:

  1. Unpinned request-body shape — one spec said an endpoint "accepts the payload" without pinning the body shape against the handler's pre-existing validation gate; the consumer's body could never persist. Found three slices downstream.
  2. Mock encoding the spec author's wrong assumption — a consumer slice passed legitimate adversarial verification with a latently-400 PUT because its mock and its spec shared the same wrong body-shape assumption. Implementer, tests, and verifier had a structurally shared blind spot.
  3. New wire artefact with no owning slice — an If-Match header specced client-side and handler-side, but the CORS AllowHeaders between them was owned by nobody; every real-browser preflight failed. Invisible to every per-slice gate; caught only by an improvised live-browser assembly phase.

With strong models the failure class has moved up a level: gates now catch bad contracts, not bad implementations. Node-level gates verify slices against specs; every failure lived on an edge between two specs.

Full retro + evidence: fired repo, docs/captures/2026-07-10-baton-sworn-edge-contracts-proposal.md.

Recommendations (baton-side)

  • Rec 5 — wire-surface enumeration in role-prompts/planner.md (Layer 4) + interim guard in the Phase 4 self-contained-spec checklist ("any AC satisfiable by a mocked boundary names the live-transport test that pins it"). Prompt-only, agreed do-first. Landed with this issue.
  • Rec 1 — contract registry: contracts-v1.json schema (planner-emitted contracts.json, sibling to board.json: kind / surface / owner / consumers / live_test / fixtures), planner.md Phase 3b "build the contract registry" + Phase 4 "every wire artefact this spec names has a registry entry". Grading gate (sworn lint contracts) lands sworn-side after the schema is stable.
  • Rec 2 — mock parity rule: a consumer slice may mock a registered boundary only with fixtures recorded by the owner's live contract test (file-based pact, inside the existing artefact model). Rule 2 extension / Rule 10 no-mock sub-rule + proof-schema fixture support.
  • Rec 3 — first-class assembly stage: release state machine gains tracks-merged → assembled → journey-validated → merged; /merge-release hard-gates on assembled; Rule 10 wording becomes "journeys re-walked after assemble passes". Machine half (sworn assemble) lands sworn-side.

(Rec 4 — BLOCKED short-circuits the retry loop — is sworn-only and tracked in swornagent/sworn.)

Ordering ruling (Brad + orchestrator, 2026-07-10)

Baton-first, Sworn-second: Baton owns artefact shapes and rule semantics; sworn grades them. A gate cannot grade a record with no defined shape.

  1. Pure-prompt items (Rec 5) — done.
  2. Baton record/rule definitions (contracts-v1.json, mock-parity rule text, assembled state + Rule 10 wording) — governance changes, human-ratified.
  3. Sworn implementations against the stable target.

Skew-window management (binding): every new Baton record lands optional-with-advisory (planner emits it; nothing hard-fails on absence) and flips to required only when the corresponding sworn gate ships. Fold in a version handshake: sworn declares which baton schema versions it grades (natural home: sworn doctor --sync-baton).

Validation set

The 2026-07-10 release folder is the test corpus: reconstruct the pre-fix state and assert each gate fires (lint contracts on the seam-1 specs → FAIL; mock-parity on the seam-2 test file → FAIL; assemble on the pre-fix tree → preflight failure surfaces).

Explicitly not proposed

No change to effort/complexity tiering (delegated slices were clean all day), no loosening of per-slice fresh-context verification (the gap was scope, not rigor), no new agent roles — gates and artefacts only, keeping the "records over roles" bias.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions