Skip to content

Designs ahead of their code: SDP #27 and round 2 on the history view - #12

Merged
darko-mijic merged 67 commits into
mainfrom
unit/design-in-the-graph
Oct 10, 2026
Merged

darko-mijic merged 67 commits into
mainfrom
unit/design-in-the-graph

Conversation

@darko-mijic

@darko-mijic darko-mijic commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Opened stacked on #11 (feature/round-2), merged into main as a758ba4 on 2026-10-10; this pull request now targets main. It shows what the Protocol's merged pull request 27 makes possible here: Specs at different maturities, designs for coming work held as first-class corpus content, and iteration from several perspectives before any code. The history view (5d) is the subject, the next build on the roadmap.

Now: anchors in the code they bind, under the rulings of 2026-10-10

Until this arc, every implementation anchor of this corpus lived in a test. The platform's runtime code may not import the Protocol package, so byFile on a source file returned nothing, a hand-kept join (design/tools/anchor-sites.json) stood in for the binding, and code could name a design only by claiming to realize it. The Protocol's annotations arc, its plan 40 on the branch feature/annotations-v0, moves closer to the Protocol's original design: an anchor can be written as a doc comment, code can name a design it answers to without claiming to build it, and an anchor can say what architectural part its code plays. The owner ruled on the arc on 2026-10-10, and all three of its decisions now state ready. This branch pins the Protocol at 822aea4 (b5fb659), its main after the merge of #29, feature/annotations-v0, which carries the rulings, and applies them (ecba393); a second read by gpt-6.1-sol checked that pass against the code, and its fold-in follows ed4f97f.

1. Anchors in the code they bind. A comment-form anchor is a top-level /** … */ block of reserved @sdp tags. The source carries it with no Protocol import, so the runtime pays nothing. The 22 implementation anchors that lived in nine test files are 46 units in src/, example/ and fixture/, one per realizing file or site, beside 12 component anchors; the harness keeps its 18 constant-form anchors. No test file keeps an implementation anchor. The file is the binding grain of both forms: a block's line locates the anchor and names no declaration. The online rebuild, at the top of src/read-model/rebuild.ts:

/**
 * @sdpAnchor impl:application.rebuild
 * @sdpLabel the online rebuild's operator entries, batch chains, tenant fill and batch bounds
 * @sdpReferences spec:application.rebuild
 * @sdpComponent component:platform.read-model
 * @sdpRole service
 */

2. A reference runs one way. A unit satisfies a Spec when it and the other units that satisfy it realize the whole Spec. A unit references a Spec when it answers to that design without claiming to realize it: it follows the design or realizes part of it, so a change to the design asks the code to follow. A reference confers no delivery fact and moves no floor. A design that builds on existing code says so by its own dependsOn or refines to the Spec the code satisfies, never by a reference from the code. So the online rebuild no longer references spec:application.history-rebuild, a design that builds on it; the history rebuild already depends on spec:application.rebuild. A reference kept only to give byFile an answer is gone too. The graph holds 49 references edges from 41 units, to 22 Specs.

3. Whole Specs, honestly. Anchor targets name whole Specs, so no unit satisfies a Spec while the Spec promises a part no unit builds, and a pinned declaration ahead of its code is such a part (design/PLAN.md 6.7 item 7). The rule, per Spec: list the entries no satisfying unit realizes; none, keep satisfies; a coherent part with its own trigger or step, split it into a child Spec and keep satisfies on the parent; otherwise write references until the code realizes what the Spec promises. The pass checked the twelve Specs the anchor check named against the code and found a thirteenth, spec:command.receipt-table; the second read found two more among the Specs the pass had left satisfied. Each holds a part no unit builds, running through entries the code realizes, so moving entries leaves none of them whole, and its units now reference it:

Spec What no unit builds
spec:context.journal the baseline migration, the stream rebuild, the derived mapping's parts
spec:context.tables the derived mapping's streamParts table
spec:context.persistence-adapter migrate on load (step 3a), the derived state
spec:context.queries the history, rebuild and byOperation queries
spec:context.context-component those queries and the baseline writer in its surface
spec:command.command-declaration the history projection binding, the tombstone retention
spec:command.idempotency-and-receipts tombstones
spec:command.receipt-table the tombstone row and its horizon
spec:command.command-pipeline the history projection's write at step 9
spec:application.read-models the history read model's write path
spec:application.generation-registry sourceIndex in the batch cursor
spec:application.rebuild history targets in the shared rebuild config
spec:application.orders-inventory-example the order allocation history bound to its commands, journal inspection
spec:application.parent-use-cases the business failure policy (carryOrReject), the import command
spec:application.projection-contract the history writer's callers in its callers entry

spec:kernel.outcome-model is referenced for another reason. Its types in src/kernel/outcome.ts and its validators in src/context/outcome.ts, which gained an anchor, are built, but the model reserves three rejection codes for the adapter and gives every other code to a context, while the adapter also raises the boundary's invalidInput, as spec:context.persistence-adapter states. Two Specs disagree and the code follows one, so both units reference the model until the main thread rules which side changes. 9 Specs carry implemented, down from 24. docs/feedback/sdp-feedback-01.md holds the table with the entries, the code and the reason for each Spec.

4. Components with an architectural layer and a context. Twelve component: anchors declare the architecture where it is realized: three in each of the adapter, application, domain and infrastructure layers, with the contexts platform (7), orders (2), inventory (2) and orders-inventory (1), and uses between them. design/PLAN.md section 2.1 lists them with the owner's two rules. The layer rule: domain is business meaning with no runtime import; application coordinates a use case; adapter realizes a kernel or command contract against Convex; edge is transport in; infrastructure is a shared mechanism that owns no use case. The context rule: the platform is the key bounded context, with its own language; orders-inventory is the supporting context and development tool, the composition of the two business contexts it models; nothing in the platform's core carries orders-inventory specifics. A component satisfies its seam's design Spec or binds nothing its members bind: component:platform.gate satisfies the write pause it and its members realize whole, and the components whose seam is only partly built bind nothing.

5. The isolation, read from the graph. design/tools/check.py fails when a component in the context platform has a uses edge to a component in another context, each end resolved to its component directly or through memberOf. Today none of the 21 uses edges from the platform's seven components leaves it.

6. Roles, and the sidecar gone. 37 units name the part they play, in a vocabulary this corpus owns; recipe 28 reads the taxonomy and check.py prints it and judges none of it. design/tools/anchor-sites.json and its test are deleted. tests/pure/byfile-coverage.test.ts reads the anchors in the tree, checks they are the code units the graph holds, and asserts that byFile names every anchored file's units and their Specs. scripts/pack-page.mjs reads code from the graph alone, and the Pack page lists each unit at its file and line with its role, its component's architectural layer and context, and a "References" list per member.

The rulings

The Protocol's branch rules the arc through three decision Specs, and the owner states ready on all three. The paths are in the Protocol's repository, on main since the merge of #29 (822aea4); the pinned package ships the same files under node_modules/@libar-dev/software-delivery-protocol/.

Ratified name Ruling Spec
the comment form (MD-36) A top-level /** … */ block of reserved @sdp* tags is a second form of an anchor, read into the same closed envelope as the constant form. No import is needed, comment prose authors nothing, and the file is the binding grain of both forms. Supersedes MD-35. specs/decisions/anchor-comment-form.sdp.md
bindings are optional, plural, and may reference a design (MD-37) satisfies is optional and plural and targets name whole Specs. The references edge says the code answers to a design without claiming to realize it, runs from code to design only, and confers no delivery fact. specs/decisions/anchor-binding-grain.sdp.md
architectural significance is annotated where it is realized (MD-38) A code anchor may carry a role, and a component: anchor a layer from a closed set of five and a context; the component anchor is the declared component. Roles stay a free vocabulary each corpus owns. Supersedes MD-30 and MD-34. specs/decisions/architectural-annotation.sdp.md

Try it

From the repository root, after npm ci. Measured on 2026-10-10 at b5fb659, the pin at 822aea4, after the fold of the sol check of the review repairs (e2c77e8) and the merge of #11 into main (a758ba4). The re-pin moved no number below. Re-run the commands rather than inherit them.

npx sdp q 'return g.byFile("src/read-model/rebuild.ts")' --json
{
  "path": "src/read-model/rebuild.ts",
  "nodes": [{ "id": "impl:application.rebuild", "nodeType": "CodeNode", "line": 2 }],
  "specs": ["spec:application.rebuild"]
}

Recipe 27 over pack:history-view, taken from the pinned package's catalog with only the Pack swapped in. Beside the three facts it now derives what each member builds on: the implemented Specs it depends on or refines, with their units.

R=node_modules/@libar-dev/software-delivery-protocol/docs/agent-surface/recipes.md
npx sdp q "$(awk '/^## 27\./{f=1} /^## 28\./{f=0} f' "$R" | awk '/^```js/{c=1; next} /^```/{if (c) exit} c' | sed 's/pack:spec-studio-v1/pack:history-view/')" --json
{
  "found": true,
  "id": "pack:history-view",
  "totals": { "members": 19, "withReferences": 10, "withImplementations": 2, "withVerifier": 7, "withBuildsOn": 11, "unbound": 7 },
  "rows": [
    {
      "id": "spec:application.history-projection",
      "resolved": true,
      "referencedBy": [{ "id": "impl:application.order-allocation-history", "file": "example/domain/orderAllocationHistory.ts" }],
      "implementedBy": [],
      "hasVerifier": false,
      "buildsOn": [
        { "id": "spec:context.event-envelope", "via": "dependsOn", "implementedBy": [{ "id": "impl:context.event-envelope", "file": "src/context/envelope.ts" }] }
      ]
    },
    …
  ]
}
npx sdp validate .
243 specs · 6 packs · 180 anchors → 429 nodes · 1499 edges (0 errors, 0 warnings)
…
validate: 0 errors · 12 warnings (conformance + honesty over the one graph)

The 12 warnings are the prose mentions listed in design/tools/prose-mentions.json.

npm run check
243 specs · 6 packs · 180 anchors → 429 nodes · 1499 edges (0 errors, 0 warnings)
validate: 0 errors · 12 warnings, 12 prose mentions listed; readiness divergence: []
entry addresses outside the Specs: 497; dependsOn cycles: 0
architecture: 76 code units; roles: codec 1, contract 6, decider 2, event-store 1, operator-entry 1, projection 2, query 5, read-model 1, schema 6, service 10, use-case 2; layers: adapter 3, application 3, domain 3, infrastructure 3; contexts: inventory 2, orders 2, orders-inventory 1, platform 7; 49 references edges from 41 units; platform isolation: 7 platform components, 21 uses edges from them, 0 into another context
…
Pack pages current: 1 of 1
protocol: file:vendor/libar-dev-software-delivery-protocol-0.0.0-822aea4.tgz

OK

npm test passed 1,151 tests in 75 files, with 10 skipped, the not-compared pairs.

For the owner

The rulings of 2026-10-10 closed the layers, the contexts, example/ as architecture, the reference direction and the whole-Spec satisfies. One item remains, from docs/feedback/sdp-feedback-01.md, section "2026-10-10, the rulings at f23e358":

  • The capability steps' name. "Layer" names one of the seven steps of capability in this corpus and, as the Protocol's layer, a component's architectural layer; CONTEXT.md now writes the second in full. Renaming the steps, with "stage" as the candidate, is the one-word-one-meaning answer. It touches a Spec identity (spec:platform.layers-and-profiles), 143 numbered uses across 65 carriers and the decisions document this corpus follows, so the owner makes it deliberately.

Three leads go to a later pass (design/STATE.md, lead 47): seven of the sixteen Specs the pass and the second read moved hold a part with its own trigger or step that could split once its pinned declarations are narrowed to the code; two Spec corrections wait for the main thread, the adapter's invalidInput against the outcome model's reserved codes and the history writer's callers in the projection contract; and the platform's own Specs still carry orders-inventory worked examples in their Design entries, though its code uses nothing of the example.

What it shows, on the history view

1. One maturity per Spec. The projection contract carried three forms under one identity and one readiness. The graph could not tell them apart. It is now three Specs, the text moved verbatim:

Spec Stated Floor Implementation What it is
spec:application.projection-contract defined ready present the per-entity form, and the conventions every form shares
spec:application.history-projection defined ready none the history form, designed, with one pure fold and its tests
spec:application.aggregate-projection scoped scoped none the aggregate form, deferred with OD-075 as its trigger

The split exposed something the old Spec hid. generation-registry, command-declaration and command-pipeline pin ReadModelBinding, the markers and step 9 over all three forms. They now depend on the deferred aggregate Spec, so their ready floor waits on it. That question is in the owner queue.

2. A capability Pack presents the design. pack:history-view gathers the 15 Specs the history view rests on, in reading order and across packages. Its Design Review page (npx sdp view, then generated/design-review/pack/history-view.md) shows each member's rung, floor, implementation binding and verifier binding. That page is the design as it stands, for review between iterations.

3. Design stubs that compile and bind to the code. This is the declarations module that #27 left to the adopter.

  • scripts/pinned.mjs (294 lines) reads recipe 24's body from the shipped catalog. It emits the Pack's pinned declarations, plus the pins they use from other Specs, into generated/pinned/history-view.ts on every sdp:build.
  • tests/types/pinned.test-d.ts names each pair by its entry address and sorts the pairs into three lists:
    • bound (53): the code's type equals the pin.
    • ahead (14): the design leads the code on purpose, for example ReadModelBinding over three forms while the code admits one. The test asserts they still differ, so the build that catches up fails until it moves the pair to bound. Three of them are compared with the ctx parameter erased.
    • not compared (9): differ in the ctx they take, five of them also leading the code with the ctx inside the executor type (lead 44).
  • Adding a literal to the pinned ApplyMode in a Spec fails npm run test:types at spec:application.projection-contract#design.typeApplyMode.
  • The first compile, before any history code exists, found one name pinned twice and 16 names the design used and no Spec pinned. The emitter now refuses a name pinned in two entries, and a bound table pair compares its indexes.

4. Entry addresses as citations. spec:<id>#design.<key> now names a Design entry in code comments, test names, the decision register and advisor memos. check.py resolves the 84 addresses outside the Specs; validate already refuses a broken one inside a Spec. One test comment cited rebuild.sdp.md step5:125, but line 125 already held step1 before this branch. It cites addresses now.

5. Two design iterations, from two perspectives, before the build. Both iterations are in the commit history.

  • The implementation pass (7a2e88a, 3fe0607), read through the pinned module. It made six Spec rulings:
    • WritableGeneration gets one owner.
    • ScopeKey and pageInGeneration take the code's spelling.
    • Two validators gain const.
    • HistoryEvent and OrderAllocation are pinned in the history Spec.
  • The Convex pass (1ee24b5) used the new design/advisors/task-pass.md.
    • advisor-convex wrote ten findings. gpt-6.1-sol checked them on a copy with one planted false citation and caught it.
    • The rulings added six open questions with register rows, OD-156 to OD-161. They cover:
      • the shape of a history batch: one stream per batch, so the pause grows with the stream count;
      • whether the verify pass under the pause is needed, since by its own Spec it finds nothing. This is OD-157, for the owner;
      • the batch chain against the write throughput limit;
      • the tenant ID repeated in every sourceVersions entry, about three quarters of the largest row;
      • the unmeasured live cost of the history binding;
      • a gate exemption no reader reaches.
    • It also added three F13 entries from the limits page, and a pure test that holds the largest history row at the 55,803 bytes the Spec states.

The adoption itself (332bfbe, 68aa73f).

  • The pin moves to 5e29c03, the merge of #27. The graph keeps its shape.
  • Validate's 83 new mention warnings were read pair by pair. 70 were real dependencies the frontmatter never declared, now 56 relations. 12 stay prose and are listed with a reason in design/tools/prose-mentions.json. One moved with its text in the split.
  • check.py refuses any mention pair that is neither declared nor listed.
  • Declaring the edges closed dependsOn cycles through two old backwards edges of the event envelope. Those two are reversed, and the corpus has no cycle.

Then: one page per capability Pack (2026-10-04)

The second unit on this branch, pack-page, takes round 1 of docs/feedback/sdp-feedback-03-selection.md. That file, -02 and the running file -01 are the feedback to the Protocol, now under docs/feedback/. The aim is a design ahead of its code that a person in the repository can read without reconstructing it from five files.

1. The Pack page. design/pages/history-view.md is generated by scripts/pack-page.mjs (npm run pages) from the graph in memory. It holds:

  • the members in the Pack file's order, each with its stated rung, floor, next rung and the clause that blocks it;
  • implementation anchors and the sources they stand for, verifiers and their tiers;
  • the pinned pairs (bound, ahead, not compared);
  • the Specs outside the Pack, both ways;
  • the open questions joined to their register rows.

The page is committed and deterministic: no commit, timestamp or local path. check.py fails when it is behind the tree, missing or unlisted. The Protocol's floor evaluator takes no target rung, so the generator walks the Protocol's own readinessFloors one rung up.

2. What the page reads, as data.

  • tests/types/pinned-pairs.json holds the type test's 76 pairs (52 bound, 14 ahead, 10 not compared), and a pure test keeps the two in step. The pinned module is formatted by Prettier.
  • design/tools/anchor-sites.json names the source files behind the 22 anchors that live in tests.
  • The register cites each of its 151 open-question sources by Spec and opening text, in place of spec:<id>#<n>. That form collided with the entry-address grammar and had drifted in 47 sources. check.py verifies the text, and test_decisions.py passes again and runs in CI.

3. One maturity per Spec, applied twice.

  • spec:application.history-rebuild takes the rebuild's history path, its two paused examples and the write pause's statements of that path, verbatim. spec:application.rebuild and spec:application.write-pause then carry implementation anchors that claim only what is built.
  • The aggregate form leaves the generation registry, the command declaration and the command pipeline for spec:application.aggregate-projection (OD-162), and their ready floors no longer wait on a scoped Spec.
  • design/PLAN.md 6.7 states the principle: a type the design widens stays as an ahead pair, and a behavior the code lacks gets a Spec of its own.

4. The owner's rulings of 2026-10-04.

  • OD-162: drop the aggregate form from the three built Specs.
  • OD-163: a stated ready means approved to build, the Protocol's reading. No Spec states it yet. The history projection may, after the domain and operator passes.

5. Checked by running it.

  • gpt-6-astra at high reviewed a frozen copy carrying one planted defect.
    • It caught the plant.
    • It found one real blocker: a deleted page left check.py with nothing to check. That is now fixed.
    • It confirmed every member's floor and next rung against the Protocol's own evaluator, the 56 outside dependencies, and determinism.
  • An astra reader given only the page did four of the five acceptance tasks in full. It found OD-157 but could not tell what "blocks S5" meant, and the page now says.

Then: the passes, and the Protocol's round 2 adopted (2026-10-04)

The third unit, sdp-round-2, takes the rest of docs/feedback/sdp-feedback-03-selection.md: step 5 of round 1 and all of round 2. Round 2 was built in the Protocol on its branch feature/adopter-round-2, libar-dev/software-delivery-protocol#28.

1. The domain and operator passes over pack:history-view, each reading the page first. The domain pass ran as Opus 5.5 and the operator pass as gpt-6-astra, each on its advisor definition. Each memo and lean was checked by the other family on a copy with one planted citation, and every plant was caught. Folded in:

  • OD-164 to OD-171: open questions and register rows.
  • OD-172 and OD-173, decided by the domain lens: every declaration that writes a source of a history projection binds it, and a history projection reads every event schema version.
  • OD-174, the owner's "One version + handoff": a history projection keeps one version, and a version-changing deploy, a first binding and an abort follow a handoff under all, so callers see writePaused instead of technical failures.
  • OD-175, decided by the operator lens: a history generation's sources and version are checked against the gate and the generation row before every batch, resume and switch.

2. The Protocol's round 2, adopted at dfa1bd9.

  • Order and floors from the reader. The page takes member order from the reader's Pack context and the next rung's blocking clauses and targets from SpecContext.nextRungFailures. Its own Pack-file read, floor walk and typed-dependency recomputation are gone.
  • Questions by key. All 166 open questions carry a key in the marker ([blocking #verifyPassUnderPause]). The register cites its 152 open sources by entry address, spec:<id>#question.<key>.
  • check.py through the recipes. It resolves the 497 addresses written outside the Specs through recipe 25, and fails on any dependsOn cycle that recipe 26 reports.
  • What the passes found missing. The page shows each question's key and address, links the pinned module, and lists the register rows whose sources lie in the members.

3. Reviewed until it holds. gpt-6-astra at xhigh reviewed this side on a frozen copy with one planted defect, the handoff deploying before all closes, and caught it. It found four contradictions in the new design text and five gaps in the tools' tests. A second read (astra high), a third (astra high) and a gpt-6.1-sol check followed, each folded in. The result:

  • the release procedure states what callers see, by case;
  • a protected abort works inside a handoff and inside a restore;
  • three new examples give 5d's native tests something to bind (a version change, a first installation, a source-order mismatch), and the paused examples hold their backfill by a tenant scope, by construction;
  • tests fail when check.py or the page's --check stop acting on a failure.

How the work is described

  • design/PLAN.md 6.7, "A design ahead of its code": the conventions behind the five points above.
  • design/advisors/task-pass.md: the advisor task for one lens over one Pack. The advisor README says how a pass runs. protocol.md accepts an entry address as a citation.
  • design/STATE.md: tactical decisions 53 to 57 and 64 to 68, and lead 44.
  • design/ROADMAP.md 5d: the domain and operator passes come before the build.
  • docs/feedback/sdp-feedback-01.md: what each adoption showed the Protocol's maintainers, newest first.

For the owner

  • Decided on 2026-10-04: what ready states (OD-163, approved to build) and the aggregate's reach (OD-162, the aggregate form leaves the three built Specs).
  • OD-157: the verify pass for a paused history generation.
  • ready statements. The third read found spec:application.history-projection and the version-change and installation examples ready to state; the history rebuild waits for OD-157.
  • OD-171: the terms of the history form.
  • Words for CONTEXT.md. This branch uses these design words without a ruling: pinned declaration, entry address, mention, pass, capability Pack. The second unit adds history rebuild, Pack page, stated rung, floor, next rung, pair (bound, ahead, not compared), an anchor's site and register row. The Convex pass added batch, source, consistent cut and history view. "Declaration" also collides with "command declaration".
  • New IDs. history-projection, aggregate-projection and history-view follow the code's names while the language rows for those words are open.

Proof

  • Typecheck, lint and format are clean.
  • npm test: 1,151 passed and 10 skipped at b5fb659. The 10 skipped are the not-compared pairs.
  • python3 design/tools/check.py prints OK:
    • 243 Specs and 6 Packs; validate shows 0 errors and 12 listed prose-mention warnings;
    • 497 entry addresses resolved through recipe 25, and no dependsOn cycle;
    • every register source resolved, and the Pack page current.
  • The pin vendor/libar-dev-software-delivery-protocol-0.0.0-822aea4.tgz is a build of the Protocol's main at 822aea4, the merge of #29 (feature/annotations-v0), whose tree equals the branch's head a4bafdc and whose whole npm run check passes, preflight included.
  • No file under src/, example/, fixture/ or harness/ changed in the third unit; the fourth unit changes src/, example/ and fixture/ only in their anchor blocks, and harness/ not at all.
  • One review of every changed line of the first unit's code (gpt-6.1-sol) found five defects, all folded in (5b226be, b81982a).
  • A pre-merge review (2026-10-10) of the four open pull requests found two defects of the pinned-declaration emitter on this branch, neither failing the current corpus, and one contract break on its parent. F4: callSignature turned every initialized parameter into an optional one, so a default followed by a required parameter emitted limit?: number, tenantId: string, which TypeScript refuses (TS1016); a default before a required parameter now emits as a required parameter whose type admits undefined, with the initializer in a comment, and a trailing default keeps ?. F5: namesUsedBy collected parameter and type-parameter names across the whole declaration, so a nested <Outcome> hid an outer Outcome the module needed; names now resolve against a lexical scope chain. Both are repaired in 4a5b653, with pure tests in tests/pure/pinned.test.ts that compile the emitted text with the TypeScript API, and the pinned output is byte-identical. F2, the receipt sweep writing through the write pause and the restore door, was repaired in Rounds 2 and 3 of the roadmap: feature/round-2 into main #11 (bb82f33) and merged here (09224b5); under the mention policy of design/PLAN.md 6.7 the merge declares the sweep's gate read as a dependsOn on spec:application.write-pause in spec:command.receipt-table and spec:command.idempotency-and-receipts, the two edges the validate line now counts, and the Pack page is regenerated (2347cbc). A gpt-6.1-sol read of the repairs (job-mv27ccog-b3a71a66) held two more cases of F5, neither failing the current corpus: a name a conditional type infers was in scope in its false branch, where TypeScript does not see it, so T extends Promise<infer Outcome> ? Outcome : Outcome pulled no outer Outcome in; and a value parameter hid a type reference of its name, so run(Outcome: Outcome): Outcome pulled nothing in. The emitter now resolves a name in its own space, values apart from types, and gives an inferred name to the true branch only; the pure tests compile both cases with and without the pulled-in pin, and the pinned module is byte-identical. The read also found that the merge had joined two clauses of the write pause's exemption list into parkand, restored, and that its typeScopeKey entry still named the builders of a scope without the sweep, which 44a89c1 on Rounds 2 and 3 of the roadmap: feature/round-2 into main #11 adds (merged as ab7a13f). The fold is e2c77e8.

Not in this branch

  • The history view's build (5d).
  • ready on any Spec.

🤖 Generated with Claude Code

darko-mijic and others added 10 commits October 3, 2026 13:34
The merged pull request 27 of the Protocol: the entry address, checked prose
mentions, authored entry order, recipe 24 and graph schema 0.6.0. The graph
keeps its shape (237 Specs, 384 nodes, 1251 edges). validate now reports 83
conformance/prose-mentions warnings, which check.py refuses until the next
commit triages them. npm test passed 1,050 and typecheck is clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d reason

The Protocol's new validator warns once for each pair of Specs where one names
the other in prose and no relation joins them: 83 pairs on this corpus. Of
those, 70 were dependencies and are now backed by 56 declared relations (52
dependsOn, 3 constrainedBy to facts and constraints, 1 decidedBy), 12 stay
prose and are listed with their reason in design/tools/prose-mentions.json,
and one moves with the projection contract's history text in the next commit.

check.py accepts a prose-mention warning only for a listed pair, refuses a
listed pair that no longer warns, and resolves every entry address
(spec:<id>#design.<key>) in the code, the tests, the register, the ledger and
the work documents, which validate does not read.

Ruled while triaging: a component Spec of kind rule is depended on with
dependsOn, and constrainedBy stays for laws, facts and constraints (PLAN.md
3.3); event-envelope no longer dependsOn command-pipeline or
persistence-adapter, which check the envelope's bounds and now depend on it
instead, so the corpus keeps no dependsOn cycle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ew's Pack

The projection contract carried three forms at three maturities under one
identity: the per-entity form, which code realizes; the history form,
designed with one pure fold and its test; and the aggregate form, which no
code realizes and whose build waits for a read model that needs it (OD-075).
The graph could not tell them apart. Each form now has its own Spec, the
moved text verbatim:

- spec:application.projection-contract keeps the per-entity form and every
  convention the forms share, and stays implemented.
- spec:application.history-projection (defined) takes the history form, its
  fold, the order allocation history and its bound. Nothing implements it,
  so the graph shows it designed and not built.
- spec:application.aggregate-projection (scoped) takes the aggregate form,
  with a blocking question that names its trigger, as PLAN.md 6.5 writes a
  deferral.

pack:history-view gathers, in reading order and across packages, the
fifteen Specs the history view rests on. The two code comments that cited
the fold by Spec and key now cite its entry address. The ledger's history
and aggregate items name the new files.

The split shows one consequence: generation-registry, command-declaration
and command-pipeline pin ReadModelBinding and step 9 over all three forms,
so they now depend on the scoped aggregate Spec and their ready floor drops
from ready to defined.

check.py: OK, 239 Specs, 6 packs, 12 listed prose mentions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cipe 24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first pass over pack:history-view, read through the pinned module
(scripts/pinned.mjs) and its compatibility test. Four rulings change Specs:

- WritableGeneration was pinned twice, identically, in the projection
  contract and the generation registry. One owner: the projection contract,
  where the code declares it. The registry's entry becomes
  writableGenerationRole and keeps only the state-to-role mapping, citing the
  shape by entry address; rebuild's step5 cites it the same way.
- ScopeKey takes the code's spelling, "all" | (string & {}): the same values,
  and the literal stays visible to an editor.
- validatorActor opens with const, so it is a declaration the module emits.
- HistoryEvent and OrderAllocation, which the history design used and no Spec
  pinned, are pinned in the history projection from the pure fold's code.

A test comment that cited Spec lines (step5:125 had held step1 since an
earlier edit) now cites entry addresses, which check.py resolves.

The pinned module refuses to emit until its preamble drops the stand-in for
HistoryEvent; the next commit does that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…not-compared pairs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rework of the pinned module found two more things, ruled the way the
first four were:

- validatorActorKind opens with const, so actorKindValidator is a
  declaration and leaves the emitter's list of names no Spec pins.
- pageInGeneration's prefix is readonly Value[], the code's spelling: a
  readonly parameter takes every array the mutable one did. The pair is
  bound in tests/types/pinned.test-d.ts.

The compatibility test now holds 53 bound pairs, 19 ahead and 4 not
compared. npm test passed 1,122 with 4 skipped, the 4 not-compared pairs;
typecheck, lint and format are clean; check.py prints OK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PLAN.md 6.7 says how a capability is designed in its Specs before its code
and how the graph shows it: one maturity per Spec, a capability Pack, pinned
declarations that compile and bind to the code, entries cited by address,
every prose mention a relation or a listed reason, and passes that read the
design from one perspective each before the build.

design/advisors/task-pass.md is the advisor task for a pass: one lens over
one Pack, a memo of at most fifteen findings, each naming the entry address
it concerns and proposing Spec text, an open question, a register row or
nothing. The advisor README says how the main thread runs one, and
protocol.md admits an entry address as the citation of a Design entry.

docs/sdp-feedback.md records what adopting the Protocol's pull request 27
asked of this corpus and what it found: the mention warnings were mostly
missing edges, declaring them closed cycles nothing reports, addresses
outside the Specs need a check of their own, the declarations module needs
a list of pins that lead their code, and a Pack's page sorts its members.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second pass over pack:history-view, by advisor-convex with
design/advisors/task-pass.md (11.7 min): ten findings in a memo outside the
repository. gpt-6.1-sol checked its facts on a copy with one planted false
citation and caught it (job-musctnbl-f5337dfb, 4.6 min); every claim the
proposals rest on held, and the claims that did not are wording outside them.
The main thread ruled:

- Six open questions, each a register row (OD-156 to OD-161): the shape of a
  history batch, one stream per batch and a pause linear in the streams
  (rebuild); whether the verify pass under the pause, which by historyVerify
  finds nothing over a covered generation, is needed (rebuild, OD-157 sorted
  as the owner's, since it reads the doc's words of D9 and Sc L2-6); the batch
  chain against the write throughput limit (rebuild); the tenant ID repeated
  in every sourceVersions entry, three quarters of the largest history row
  (projection contract); the live cost of the binding, unmeasured (history
  projection); and the gate's generation exemption, which no reader reaches
  (write pause).
- Three F13 entries from the limits page read on 2026-10-03: limitDocument
  split into document and value limits, limitWriteThroughput, and
  limitIoOperations.
- A pure test that builds the largest order allocation history row from the
  example's own sources and holds it at the 55,803 bytes the Spec states,
  under the 65,536 budget, with a reviewed bullet that names it.

The roadmap's 5d names its Pack and the domain and operator passes that come
before its build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
STATE.md: the unit in "Where the work stands", the measured lines, the
register's totals after OD-156 to OD-161, tactical decisions 53 to 57 (the
mention policy, one maturity per Spec, the pinned module, entry addresses,
the pass), three items for the owner (what ready states, the aggregate's
reach into built Specs, the design words this unit used) and lead 44.

check.py: OK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 195 files, which is 95 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 72378ba7-7e30-4d08-ad04-adf7bb05452c

📥 Commits

Reviewing files that changed from the base of the PR and between a758ba4 and f9eb362.


⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json

📒 Files selected for processing (195)
  • .github/workflows/ci.yml
  • AGENTS.md
  • CONTEXT.md
  • design/PLAN.md
  • design/README.md
  • design/ROADMAP.md
  • design/SESSIONS.md
  • design/STATE.md
  • design/advisors/README.md
  • design/advisors/protocol.md
  • design/advisors/register.md
  • design/advisors/task-pass.md
  • design/decisions/forks/OD-025.md
  • design/decisions/forks/OD-064.md
  • design/decisions/forks/OD-068.md
  • design/decisions/forks/OD-069.md
  • design/decisions/forks/OD-123.md
  • design/decisions/register.json
  • design/pages/history-view.md
  • design/reviews/consensus-ledger.json
  • design/specs/advanced/coalesced-recomputation.sdp.md
  • design/specs/advanced/cross-stream-online-rebuild.sdp.md
  • design/specs/advanced/ordered-consumer.sdp.md
  • design/specs/advanced/trigger-table.sdp.md
  • design/specs/agents/agent-runs.sdp.md
  • design/specs/agents/budget-accounting.sdp.md
  • design/specs/application.pack.sdp.md
  • design/specs/application/aggregate-projection.sdp.md
  • design/specs/application/first-experiment.sdp.md
  • design/specs/application/generation-registry.sdp.md
  • design/specs/application/history-projection.sdp.md
  • design/specs/application/history-rebuild.sdp.md
  • design/specs/application/history-rebuild.write-pause-rebuild-abort.sdp.md
  • design/specs/application/history-rebuild.write-pause-rebuild-installation.sdp.md
  • design/specs/application/history-rebuild.write-pause-rebuild-interrupt.sdp.md
  • design/specs/application/history-rebuild.write-pause-rebuild-source-order-mismatch.sdp.md
  • design/specs/application/history-rebuild.write-pause-rebuild-version-change.sdp.md
  • design/specs/application/orders-inventory-example.sdp.md
  • design/specs/application/parent-use-cases.sdp.md
  • design/specs/application/projection-contract.sdp.md
  • design/specs/application/read-models.sdp.md
  • design/specs/application/rebuild.sdp.md
  • design/specs/application/rebuild.write-pause-rebuild-abort.sdp.md
  • design/specs/application/restore.sdp.md
  • design/specs/application/write-pause.sdp.md
  • design/specs/command/actor-and-scope.sdp.md
  • design/specs/command/command-declaration.sdp.md
  • design/specs/command/command-pipeline.sdp.md
  • design/specs/command/idempotency-and-receipts.sdp.md
  • design/specs/command/outcome-boundary.sdp.md
  • design/specs/command/receipt-table.sdp.md
  • design/specs/command/tenancy-and-authority.sdp.md
  • design/specs/constraints/events-stay-small.sdp.md
  • design/specs/context/context-component.sdp.md
  • design/specs/context/event-envelope.sdp.md
  • design/specs/context/journal.sdp.md
  • design/specs/context/persistence-adapter.sdp.md
  • design/specs/context/queries.sdp.md
  • design/specs/context/tables.sdp.md
  • design/specs/decisions/d02-context-owns-state-and-journal.sdp.md
  • design/specs/decisions/d03-events-only-source-of-next-state.sdp.md
  • design/specs/decisions/d06-idempotency-client-and-receipts.sdp.md
  • design/specs/decisions/d07-rejections-thrown-not-stored.sdp.md
  • design/specs/decisions/d08-read-models-in-command.sdp.md
  • design/specs/decisions/d09-rebuild-online-by-default.sdp.md
  • design/specs/decisions/d13-deferred-work-is-an-obligation.sdp.md
  • design/specs/decisions/d19-operations-travel-with-capability.sdp.md
  • design/specs/effects/claim-call-settle.sdp.md
  • design/specs/effects/external-effects.sdp.md
  • design/specs/facts/f11-components-have-no-ctx-auth.sdp.md
  • design/specs/facts/f12-backups-exclude-pending-scheduled-functions.sdp.md
  • design/specs/facts/f13-transactions-have-limits.sdp.md
  • design/specs/facts/f16-scheduled-functions-table-shows-failed-runs.sdp.md
  • design/specs/facts/f17-migrations-fits-generation-backfill.sdp.md
  • design/specs/facts/f18-commit-timestamps.sdp.md
  • design/specs/facts/f19-nested-calls-share-time-budgets.sdp.md
  • design/specs/facts/f20-pagination-checks-bytes-after-reading.sdp.md
  • design/specs/facts/probe-plan.sdp.md
  • design/specs/history-view.pack.sdp.md
  • design/specs/kernel/decider-contract.sdp.md
  • design/specs/kernel/domain-kernel.sdp.md
  • design/specs/kernel/initial-state.sdp.md
  • design/specs/kernel/outcome-model.sdp.md
  • design/specs/kernel/state-document-mapping.sdp.md
  • design/specs/obligations/do-nothing-check.sdp.md
  • design/specs/obligations/fan-out-and-chains.sdp.md
  • design/specs/obligations/lifecycle-transitions.sdp.md
  • design/specs/obligations/local-reaction-wrapper.sdp.md
  • design/specs/obligations/obligation-module.sdp.md
  • design/specs/obligations/operator-operations.sdp.md
  • design/specs/obligations/record-contract.sdp.md
  • design/specs/obligations/retention-and-restore.sdp.md
  • design/specs/obligations/sweeper.sdp.md
  • design/specs/operations/baseline-operations.sdp.md
  • design/specs/platform/acceptance-contract.sdp.md
  • design/specs/platform/native-harness.sdp.md
  • design/specs/platform/transactional-domain-platform.sdp.md
  • design/specs/platform/vocabulary.sdp.md
  • design/specs/processes/approvals.sdp.md
  • design/specs/processes/start-checkout-example.sdp.md
  • design/specs/processes/workflow-processes.sdp.md
  • design/tools/check.py
  • design/tools/decisions.py
  • design/tools/prose-mentions.json
  • design/tools/test_decisions.py
  • docs/feedback/pr-12-annotations-section.md
  • docs/feedback/sdp-feedback-01.md
  • docs/feedback/sdp-feedback-02.md
  • docs/feedback/sdp-feedback-03-selection.md
  • docs/sdp-feedback.md
  • example/convex/convex.config.ts
  • example/convex/inventory/convex.config.ts
  • example/convex/inventory/operations.ts
  • example/convex/inventory/queries/stockItem.ts
  • example/convex/inventory/schema.ts
  • example/convex/inventory/streams.ts
  • example/convex/orderSummary.ts
  • example/convex/ordering.ts
  • example/convex/orders/convex.config.ts
  • example/convex/orders/operations.ts
  • example/convex/orders/queries/order.ts
  • example/convex/orders/schema.ts
  • example/convex/orders/streams.ts
  • example/convex/receiving.ts
  • example/domain/order.ts
  • example/domain/orderAllocationHistory.ts
  • example/domain/stockItem.ts
  • fixture/convex/depot/convex.config.ts
  • fixture/convex/depot/operations.ts
  • fixture/convex/depot/queries/document.ts
  • fixture/convex/depot/schema.ts
  • fixture/convex/depot/streams.ts
  • fixture/convex/depotCommands.ts
  • package.json
  • scripts/pack-page.mjs
  • scripts/pinned.mjs
  • src/audit/index.ts
  • src/command/actor-and-scope.ts
  • src/command/authority.ts
  • src/command/declaration.ts
  • src/command/index.ts
  • src/command/outcome-boundary.ts
  • src/command/pipeline.ts
  • src/command/receipts.ts
  • src/command/tables.ts
  • src/context/adapter.ts
  • src/context/envelope.ts
  • src/context/index.ts
  • src/context/journal.ts
  • src/context/operation.ts
  • src/context/outcome.ts
  • src/context/queries.ts
  • src/context/tables.ts
  • src/gate/entries.ts
  • src/gate/gate.ts
  • src/gate/index.ts
  • src/gate/tables.ts
  • src/kernel/decider.ts
  • src/kernel/index.ts
  • src/kernel/outcome.ts
  • src/operations/index.ts
  • src/read-model/generations.ts
  • src/read-model/index.ts
  • src/read-model/projection.ts
  • src/read-model/queries.ts
  • src/read-model/rebuild.ts
  • src/read-model/tables.ts
  • src/read-model/write.ts
  • tests/native/generation-registry.first-rebuild-installs-read-model.test.ts
  • tests/native/read-models.test.ts
  • tests/native/rebuild-install.ts
  • tests/native/rebuild.online-rebuild-interrupt-resume.test.ts
  • tests/pure/byfile-coverage.test.ts
  • tests/pure/command.test.ts
  • tests/pure/context-queries.test.ts
  • tests/pure/context.test.ts
  • tests/pure/example-domain.test.ts
  • tests/pure/example-use-cases.test.ts
  • tests/pure/kernel.test.ts
  • tests/pure/order-allocation-history-row-size.test.ts
  • tests/pure/order-allocation-history.test.ts
  • tests/pure/pack-page.test.ts
  • tests/pure/pinned-pairs.test.ts
  • tests/pure/pinned.test.ts
  • tests/pure/read-model.test.ts
  • tests/pure/rebuild.test.ts
  • tests/simulator/example.test.ts
  • tests/simulator/gate-support.ts
  • tests/simulator/read-model.test.ts
  • tests/simulator/rebuild.test.ts
  • tests/types/pinned-pairs.json
  • tests/types/pinned.test-d.ts
  • tests/types/rebuild.test-d.ts
  • vendor/libar-dev-software-delivery-protocol-0.0.0-5993da7.tgz
  • vendor/libar-dev-software-delivery-protocol-0.0.0-822aea4.tgz

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

darko-mijic and others added 3 commits October 3, 2026 14:31
…what it measures

From the review of the unit's code (gpt-6.1-sol, job-musd8wu4-575a7bee):

- check.py matched an address by a pattern that stopped at the first
  character outside a key, so spec:<id>#design.typeApplyMode-bogus resolved
  as its valid prefix, and it required two segments, so spec:missing#design.x
  was never checked. It now takes a token from spec: to a separator, drops
  trailing punctuation and checks it whole against the address grammar, as
  the Protocol's mention validator does; a # that opens neither design nor ui
  is the register's reference to an open question and is not an address.
- The row-size test measures the row as applyProjection does, without the
  system fields the stored document adds; its comment said the stored
  document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…able pairs compare what they claim

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53 bound, 14 ahead (three compared with the ctx erased), 9 not compared;
lead 44 names the five pairs whose ctx sits inside the executor type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@darko-mijic
darko-mijic marked this pull request as ready for review October 3, 2026 20:42
darko-mijic and others added 15 commits October 4, 2026 02:27
…two reads that select the next work

The owner's move of docs/sdp-feedback.md into docs/feedback/ as it was made:
sdp-feedback-01.md is the running file, 02 and 03-selection are the reads of
2026-10-04 that chose the next work. SESSIONS.md and STATE.md point at the
new path, and the running file's link to the first report goes up one level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…module formatted

tests/types/pinned-pairs.json lists the 76 pairs of tests/types/pinned.test-d.ts
in file order, with state, comparison, the code compared and a reason for each
ahead and not-compared pair. A pure test fails when the two disagree on a name,
a state or the order. scripts/pinned.mjs formats its module with the
repository's Prettier; the parsed declarations are unchanged and the compiled
tier keeps 53 bound, 14 ahead and 9 not compared.

Written by gpt-6.1-sol (job-mut363vp-ed05a575) from the unit's rulings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… verifies it

Every specQuestion source names its Spec and the opening of the question it
was written for, resolved from the commit that introduced it, in place of a
position that moved and that collides with the entry-address grammar. 151
sources rewritten; six whose question was answered and removed keep their
last text with open: false, which check.py admits only on a decided or folded
row. test_decisions.py asserts what holds at every commit, and CI runs it.
OD-162 and OD-163 record the owner's rulings of 2026-10-04 on the aggregate's
reach and on what ready states.

Written by gpt-6.1-sol (job-mut363o8-7111f411) from the unit's rulings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rm leaves the three built Specs (O1)

spec:application.rebuild carried the online path, which src/read-model/rebuild.ts
realizes, and the paused path of a history view, which no code realizes, under
one identity. The paused path moves into spec:application.history-rebuild
(defined), the moved text verbatim as decision 54 moved the projection forms:
the two history types, the page call, the cursor, the start, the steps, the
verify pass and the batch bound, the rules and flows under the pause, the pause
length risk and its three open questions (OD-156, OD-157, OD-158). The entries
both paths share stay in the rebuild and lead the code where a type names the
history form: typeRebuildConfig, fnBatchSizeFor, limitBatchSize, limitPurgeBatch.
The two paused examples move under the new Spec as
spec:application.history-rebuild.write-pause-rebuild-interrupt and -abort.
The new Spec depends on the rebuild; nothing depends back, so no cycle.

O1: the generation registry, the command declaration and the command pipeline
drop the aggregate form. The marker table, its index, its rules and its review
bullet, the aggregate member of ReadModelBinding and the applyAggregate call of
step 9 move to spec:application.aggregate-projection, which now states how the
form extends the three when OD-075 triggers. None of the three depends on the
aggregate Spec, and each one's floor now reaches ready.

check.py: one failure left, the test name at tests/types/pinned.test-d.ts:74,
which the next commit renames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tes of anchors that live in tests

spec:application.rebuild, now the online path alone, and
spec:application.write-pause each get an implementation anchor in the pure
test that binds their library, tests/pure/rebuild.test.ts and
tests/pure/write-pause.test.ts; src/ still imports nothing of the Protocol.

design/tools/anchor-sites.json lists the 22 implementation anchors whose site
is under tests/, with the source files each stands for (interface I2), and
tests/pure/anchor-sites.test.ts reads the anchors from generated/graph.json and
fails on an anchor missing, one listed that is not under tests/, one listed
twice, or a source that is not a file.

The type test follows the Specs: the marker table's pair takes its new address
in spec:application.aggregate-projection, outside the Pack, so the module no
longer emits it and the pair moves from bound to not compared; the binding's
ahead pair no longer names the aggregate form. No other pair changes block.

PLAN.md 6.7 states the principle of the rulings page and O2's reading of ready;
ROADMAP.md says what 4e means under O2 and names the moved IDs. The ledger's
files follow the renamed examples, and the history items name the new carrier.

Gates: typecheck, lint, format:check and npm test (72 files, 1,119 passed,
10 skipped) pass; check.py prints OK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s blocks by prefix

pinned-pairs.json follows the type test after the maturity lane: 52 bound,
14 ahead and 10 not compared, the markers table's pair now outside the Pack.
The pure test finds the three blocks by their title prefixes and fails on a
missing or doubled block.

Written by gpt-6.1-sol (job-mut363vp-ed05a575, round 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e changed Specs become entry addresses

OD-156 to OD-158 cite their questions in the history rebuild, OD-068 and OD-069
take the registry's question text after the aggregate form left it. 24 line
pointers into the Specs this unit changed become the entry addresses they meant,
traced through history; 79 that meant no Design entry stay. check.py imports
decisions.py without writing bytecode into the tree. The advisor register's
example and the forks' Sources lines take the new form.

Written by gpt-6.1-sol (job-mut363o8-7111f411, round 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
check.py runs the generator's --check for each page under design/pages/. An index entry
names the pair of the table it is chained on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…history rebuild, and PLAN names the new IDs

Three Contract bullets of spec:application.write-pause stated what the history
path does as a caller of the pause, behavior no code has: a rebuild that needs a
consistent cut closes its view's sources, startGeneration closes one entry per
source, and a source scope closes only for a generation startGeneration registers.
They move verbatim to spec:application.history-rebuild as Workflow rules, with the
narrative's clause that the rebuild closes the gate for its own scope. What
src/gate realizes stays: the scope kinds, the generation exemption in gateAllows,
closeScope with its generation, the operator entries' refusal of a source scope,
abort's resume, and the gate's persistence across a restore. No Design entry and
no open question moved.

PLAN.md 3.4 names the history rebuild where the rebuild's row meant it, and
section 4's L2-6 row names spec:application.history-rebuild as its parent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sses they meant

108 comment lines in tests/simulator, tests/types/rebuild.test-d.ts and tests/native
pointed into design/specs/application/rebuild.sdp.md by line (decision 56). Each
now names its entry address at the Spec that holds it today, all in
spec:application.rebuild; a bare line number was resolved against the Spec at the
commit that wrote the comment. Seven pointers meant one of four Workflow rules or the Design
narrative, which have no address; they name the Spec and the rule in words.
Comments only; no test changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
darko-mijic and others added 4 commits October 4, 2026 06:52
A second read (gpt-6-astra at high, whole Specs after 3545e9a) found the
release procedure still uneven, folded in from leans piece by piece. Ruled
by the main thread as one statement:

- What callers see, by case: a bound command fails as a technical failure
  only when it passes step 7 with no writable generation of the deployed
  version; the handoff and the protected abort hold `all` closed through
  every such window, so callers see writePaused; a same-version abort opens
  no window.
- historyHandoff closes `all` at its one closing step; a replacement
  generation after a protected abort enters it after that step.
- The restore's read-model check holds for a per-entity read model and
  names OD-166's question for a history view.
- One inventory of the mutations that skip the gate read, in every place.
- Examples whose worlds cannot finish early or race: a stated sample and
  batch size, a wait for the batches before the interrupt and for the
  first batch to park before `all` reopens, and an installed order summary
  before the first order.
- A test runs the page generator as a process and expects --check to exit
  non-zero on a stale page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A third read (gpt-6-astra at high) found the history projection and the
version-change and installation examples ready, and four seams left at the
abort handoff's edges, ruled by the main thread:

- An abort inside a handoff, or inside a restore's recovery, continues with
  `all` already held closed; no step closes a scope the procedure holds.
- The protected abort resumes the passes it interrupted or parked, just
  after it reopens `all`, since a chain resumed while `all` is closed parks
  again.
- Inside a restore's recovery `all` stays closed until finishRestoreRun
  accepts the run; historyAbortHandoff and finishCompatibility cite each
  other.
- The interrupt, abort and source-order examples hold the backfill with
  `all` once two batches are done, and act while it is parked, so a native
  backend cannot finish the backfill before the interrupt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A gpt-6.1-sol check found the round-6 hold still raced: polling
batchesDone and then closing `all` left a window in which the backfill
could end. The interrupt, abort and source-order examples now hold it by
construction: the sample is split between two tenants, the test closes the
scope of the tenant the enumeration reaches second before startGeneration,
so the backfill runs every batch of the first tenant and parks at the
second, and the test interrupts (and, for source order, deploys) while it
is parked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner's scope, "Passes + SDP round 2 + adopt": the domain and operator
passes over pack:history-view read its page first and were folded in
(OD-164 to OD-175, the owner's OD-174); the Protocol's round 2 was built on
its branch feature/adopter-round-2 (its pull request 28) with a slice of the
original design captured as Specs ahead of their code; this corpus adopted
it at dfa1bd9 (166 question keys, the register by address, the page and
check.py on the Protocol's data); and the adopter's design text went
through a review, a second and a third read, and a check, each folded in.

STATE.md is rewritten under its headings with the close's measurements,
decisions 64 to 68, the owner queue and the leads; ROADMAP.md says 5d's
passes are done and its build waits for the owner's ready.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@darko-mijic darko-mijic changed the title Designs ahead of their code: SDP #27 on the history view Designs ahead of their code: SDP #27 and round 2 on the history view Oct 4, 2026
darko-mijic and others added 7 commits October 8, 2026 10:38
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Protocol's plan 40 branch adds the comment form of an anchor, plural
satisfies, the non-conferring references edge and the role, layer and
context attributes. The tarball is packed from a clean clone at da56a34.
Nothing this corpus reads moved: 243 Specs, 393 nodes, 1,382 edges, 12
listed warnings, 497 addresses resolved, no cycle. The page names the new
pin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An independent read of the tree after the re-pin found the showcase
absent: no anchor in src/, no byFile coverage test, the anchor-sites
join still in place, and no feedback section. This commit applies the
decided mapping.

The 22 implementation anchors that lived in nine test files move into
the source as comment-form blocks: 45 units and 12 component anchors,
each unit choosing satisfies or references for what its own code does,
with role, layer and context. The depot fixture only references. The
graph derives 179 anchors into 428 nodes and 1,501 edges, 0 errors and
the same 12 listed warnings; no delivery fact of the 243 Specs changed.

design/tools/anchor-sites.json and its test are deleted, and
tests/pure/byfile-coverage.test.ts asserts byFile names each of the 50
file and Spec pairs it joined. The Pack page reads code from the graph
alone: each unit at its site, with its role and component, and a
Referenced by list. check.py prints the roles, layers and contexts from
recipe 28. The feedback file's dated section records the adoption and
what the owner rules.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The showcase moved every implementation anchor into the source, so the
state file stops describing the anchor-sites join as current. Decision 60
now states how an anchor is written here, decision 67 drops the join from
the adopter's joins, and the pack-page record says the join was retired.
Lead 17's kernel half and the test-resident anchor items of leads 45 and
46 close with a pointer to the feedback file's 2026-10-09 section; what
stands is the file-and-line binding, for the Protocol.

The owner-queue entry on annotations is rewritten: the Protocol's branch
feature/annotations-v0 rules it through three decisions held for the
owner's ready (MD-36, MD-37, MD-38), and the owner decides here the
layers, the contexts, whether example/ is architecture, the reference
direction, and the word layer, which CONTEXT.md already gives another
meaning.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The new top section of the PR 12 description, for the owner to place
above "What it shows, on the history view". It tells what the Protocol's
annotations arc makes possible here: anchors in the code they bind with
no Protocol import, byFile answering for src/, components with layer and
context, roles, references into the history-view design that claim no
realization, and the anchor-sites join gone. Each point links one file
on the branch. A table gives the three held rulings (MD-36 to MD-38),
a try-it block quotes the commands run at 57ed4f8 with their trimmed
output, and "For the owner" carries the feedback section's four
questions and the collision of the word layer with CONTEXT.md. The sol
check of the anchor claims is still running, and the section says so.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A gpt-6.1-sol read of every comment-form anchor from fd5b257 and 57ed4f8
(job-mv1dotsu-5f1f42fd) is folded in, as the main thread sorted it.

src/kernel/outcome.ts holds the outcome types, not the decider, so it no
longer satisfies spec:kernel.decider-contract. It references that Spec and
spec:kernel.outcome-model, which keeps the byFile pair the coverage test
asserts. The gate component exports the write pause its members realize,
so it satisfies spec:application.write-pause; that Spec's delivery facts
are unchanged.

The Pack page's references wording no longer assumes a direction, and the
page is regenerated. The feedback section states the rule as realization
scope, gives the fixture's real grounds, and adds an owner item for the
twelve Specs satisfied whole by code that realizes part of their Design.
STATE's measured block and the PR section are re-measured at da56a34.

Declined with no edit: the platform and orders-inventory context doubts,
the adapter-layer doubts, and the whole-model doubts on example files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
darko-mijic and others added 12 commits October 10, 2026 08:59
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Protocol's branch feature/annotations-v0 now carries the owner's
rulings on the annotations arc: references run one way, from code to the
design it answers to; anchor targets name whole Specs; the binding grain
states ready; and recipe 27 gains a derived builds-on column. The tarball
is packed from a clean clone at f23e358. Nothing this corpus reads moved
on the pin alone: 243 Specs, 428 nodes, 1,501 edges, 12 listed warnings.
The page names the new pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A reference now runs one way: code answers to a design it follows or
realizes in part. The online rebuild's reference to the history rebuild
comes out; the history rebuild already depends on the rebuild's Spec.
src/kernel/outcome.ts drops its byFile-only reference to the decider
contract and, as impl:kernel.outcome-model, satisfies the outcome model
with a new anchor on the validators in src/context/outcome.ts. The
read-model tables keep their reference to the aggregate form, whose
marker table they hold.

Anchor targets name whole Specs. The pass over the twelve Specs the
anchor check named, and spec:command.receipt-table, which promises a
tombstone row and horizon no code writes, found in each a part no unit
builds that runs through entries the code realizes, so no verbatim move
leaves the parent whole: their units reference them. The four components
that referenced a Spec their members bind, and the two context
components that satisfied the example, bind nothing; their members carry
the references. PLAN 6.7 item 7 no longer exempts a pinned declaration
that is ahead of its code.

PLAN 2.1 records the code's components with the owner's layer rule and
context rule, and check.py fails when a platform component uses a
component of another context (0 of 21 uses edges do). CONTEXT.md adds
architectural layer. The byFile coverage test reads its pairs from the
anchors in the tree. The page says the one direction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… section

The feedback file gains the dated section "2026-10-10, the rulings at
f23e358": what the rulings changed in this corpus, the per-Spec table of
the pass with what no unit builds and why each Spec went to references,
the outcome model satisfied, the owner items that closed and the one
that remains, the rename of the capability steps to "stage". The older
section loses the sentence that kept a reference for a byFile pair.

The state file's owner queue holds that one item, its measured block is
re-measured at ecba393, decision 69 records the rulings, decisions 60
and 62 point to it, and lead 47 keeps what the pass found and did not
fix: splits by narrowing, and the orders-inventory worked examples in
the platform's own Specs. The PR section reads as the current state with
its try-it output re-measured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A gpt-6.1-sol read of the rulings pass found three Specs still
satisfied by code that does not realize all of them. Their units now
reference them:

- spec:application.parent-use-cases: no code builds the business
  failure policy (carryOrReject) or the import command.
- spec:application.projection-contract: its callers entry promises the
  history writer's calls at step 9 and in history batches, and none
  exist.
- spec:kernel.outcome-model: the adapter's step 1 raises invalidInput,
  which the model's three reserved codes and its context-owned rule
  leave no room for, while spec:context.persistence-adapter states it.
  Two Specs disagree; the main thread rules which side changes.

9 Specs carry implemented, down from 12. The feedback's 2026-10-10
section, the state file's decision 69, lead 47 and measured block, and
the PR section are re-measured: 49 references edges from 41 units to
22 Specs, recipe 27 totals 10 referenced and 2 implemented. The split
count reads seven Specs, which is what its list names. The Pack page
is regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two defects of the pinned-declaration emitter, found by the review of
2026-10-10 (F4 and F5), neither of which the current corpus reaches.

A call signature with a default before a required parameter emitted an
optional parameter ahead of a required one, which TypeScript refuses
(TS1016). Such a default now keeps its parameter required with a type
that admits undefined, `limit: number | undefined /* = 100 */`; a
trailing default stays optional. A function, constructor or conditional
type is grouped before `| undefined`.

The names a declaration uses were filtered against every parameter and
type parameter in the whole declaration, so a nested `<Outcome>` hid an
outer `Outcome` the module needs. Names now resolve against a lexical
scope chain: a parameter or type parameter is in scope inside the node
that declares it and nowhere else, with a mapped type's key and a
conditional type's inferred names in their own nodes.

The pure parts are exported, the script's main runs only when the file
is the entry, and tests/pure/pinned.test.ts compiles each emitted text
with the TypeScript API and shows the outer dependency pulled in. The
regenerated pinned module is byte-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The typeScopeKey line keeps the branch's `(string & {})` with the parent's
builder list, the state file keeps both repair sentences, and the corpus
digest is re-measured; the Pack page is unchanged by the merge.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A gpt-6.1-sol read of the 2026-10-10 review repairs
(job-mv27ccog-b3a71a66) held two more cases of F5 in scripts/pinned.mjs,
neither failing the current corpus, and found two damaged sentences of
spec:application.write-pause.

- A name a conditional type infers was in scope in its false branch,
  where TypeScript does not see it, so
  `T extends Promise<infer Outcome> ? Outcome : Outcome` pulled no outer
  Outcome in and the module failed with TS2304. An inferred name is
  now in scope in the true branch only.
- A value parameter hid a type reference of its name, so
  `run(Outcome: Outcome): Outcome` pulled nothing in and the module
  failed with two TS2749. A name now resolves in its own space: a
  parameter is a value, a type parameter, a mapped key and an inferred
  name are types, and typeof x names a value.
- tests/pure/pinned.test.ts: both cases in the scope test, and a
  pull-in test that compiles each with the pin pulled in (no
  diagnostic) and alone (the diagnostic named). The old emitter fails
  both. The pinned module regenerates byte-identical.
- The merge 09224b5 had joined two clauses of the write pause's
  exemption list into "parkand"; "park, and" is restored. The
  typeScopeKey follow-up came in through the parent (44a89c1, merged
  as ab7a13f).
- STATE.md records the read, and its corpus digest is re-measured; the
  Pack page is unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@darko-mijic
darko-mijic changed the base branch from feature/round-2 to main October 10, 2026 10:10
darko-mijic and others added 3 commits October 10, 2026 12:16
The Protocol merged #28 (feature/adopter-round-2) into main as 415b095
and #29 (feature/annotations-v0, the annotations arc with the owner's
rulings and the review repairs) as 822aea4, whose tree equals the
branch's head a4bafdc. The tarball is packed from a clean clone at
822aea4, and the Protocol's whole gate passes there (npm run check,
preflight included). Nothing this corpus reads moved on the pin alone:
243 Specs, 429 nodes, 1,499 edges, 12 listed warnings, 497 addresses
resolved, no cycle, the digest b8d5b77dcf27d47c unchanged. Recipe 27
keeps its builds-on column, and the pinned pairs compare as before, 49
bound, 17 ahead and 10 not compared. The page names the new pin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The three pull requests of the unit are merged or ready: #11 into main
as a758ba4, the Protocol's #28 as 415b095 and #29 as 822aea4, and #12
retargeted to main, merging after this close. The pin is 822aea4
(b5fb659). The third read of the history Specs has run, so the owner's
ready on the history projection waits for nothing else, and the history
rebuild's waits for OD-157 alone; the roadmap's 5d and 4e say so. The
measured block, the corpus digest and the close's gates are re-measured
at the new pin, the native tier included. Two owner-queue rows closed by
the merges are dropped: the three pull requests, and the gen-1 quotes
question that preceded their pushes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@darko-mijic
darko-mijic merged commit d310eb1 into main Oct 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant