Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4099443
plan 41: the design-management contract, Specs first
darko-mijic Oct 10, 2026
fff49bc
plan 41: the Pack page keeps the binding language's present and none
darko-mijic Oct 10, 2026
28dcbdd
plan 41: the location-table type, and the Spec validate --watch lacked
darko-mijic Oct 10, 2026
79fb25e
plan 41: example-space coverage is a capture, not a recipe
darko-mijic Oct 10, 2026
7ba3469
plan 41: architecture crossings tally context and layer pairs
darko-mijic Oct 10, 2026
0f43be4
feat(extract): record Spec entry locations beside graph nodes
darko-mijic Oct 10, 2026
cc3fcab
plan 41: capture the original design's promises ahead of code
darko-mijic Oct 10, 2026
c542a09
plan 41: guidance that taught superseded anchor law, re-pointed
darko-mijic Oct 10, 2026
5f27b56
plan 41: keyed questions, the self-hosting Pack, and backed mentions
darko-mijic Oct 10, 2026
93b4d8b
plan 41: verifier bindings for three ready Specs whose own promise a …
darko-mijic Oct 10, 2026
c8fab22
plan 41: recipe parameters, shipped recipe files, and sdp --version
darko-mijic Oct 10, 2026
8b343a6
plan 41: the Pack design in the reader and on the Design Review's Pac…
darko-mijic Oct 10, 2026
f51ced3
merge: plan 41 lane/e1-locations
darko-mijic Oct 10, 2026
c398d79
merge: plan 41 lane/e2-pack-design
darko-mijic Oct 10, 2026
183d2de
merge: plan 41 lane/e3-cli
darko-mijic Oct 10, 2026
1306b14
merge: plan 41 lane/c1-captures
darko-mijic Oct 10, 2026
dd1b079
merge: plan 41 lane/c2-repairs
darko-mijic Oct 10, 2026
b5c0ad9
plan 41: integrate the lanes' Spec findings
darko-mijic Oct 10, 2026
52ce1a3
plan 41: the drift-queue packet, and the plan's lists as built
darko-mijic Oct 10, 2026
28d76f1
fix(integration): align schema and self-hosting pins with the design arc
darko-mijic Oct 10, 2026
e51367b
plan 41: design recipes 29 to 32 and entry lines in recipes 23 and 25
darko-mijic Oct 10, 2026
6063f45
merge: plan 41 lane/i1-recipes
darko-mijic Oct 10, 2026
c1cce4c
merge: plan 41 lane/i2-schema-gates
darko-mijic Oct 10, 2026
4b964a0
test(self-hosting): re-pin the oracle across the design-management arc
darko-mijic Oct 10, 2026
62d3647
fix(engine): fold plan 41 review findings in the build step and reader
darko-mijic Oct 10, 2026
4fa1792
fix(design-review): fold plan 41 review findings in the Pack page and…
darko-mijic Oct 10, 2026
bd1f1f8
fix(contract): fold plan 41 review findings in --params, two Specs an…
darko-mijic Oct 10, 2026
6a76a47
plan 41: the close record
darko-mijic Oct 10, 2026
e18c101
test(recipes): read the catalog LF-normalized, as the build step does
darko-mijic Oct 10, 2026
9b20bfc
fix: fold the third astra review of PR 30
darko-mijic Oct 10, 2026
90c75dd
plan 41: the owner's rulings of 2026-10-12 and the fold's lanes
darko-mijic Oct 12, 2026
7fbd194
fold: narrowing decisions refine the freeze; supersedes replaces whole
darko-mijic Oct 12, 2026
c1318fa
fold: state ready on the arc's built Specs and the drift queue
darko-mijic Oct 12, 2026
2cad2d9
fix(pack-design): separate boundary relations and clarify next rung
darko-mijic Oct 12, 2026
35539a0
fold: ratify the design-management vocabulary and update the registry
darko-mijic Oct 12, 2026
213d3e0
fix(design-review): encode every link target
darko-mijic Oct 12, 2026
2086781
specs(model): answer the model captures' blocking questions
darko-mijic Oct 12, 2026
4d558ad
feat(reader): expose derived design columns on Spec context
darko-mijic Oct 12, 2026
074ae7f
fold: delete MD-30, MD-34 and MD-35, whose replacements carry what su…
darko-mijic Oct 12, 2026
ad98768
specs: answer the consumer, validation and observation captures
darko-mijic Oct 12, 2026
d9cbbba
merge fold/f2-decisions: decisions, ready statements, vocabulary, del…
darko-mijic Oct 12, 2026
978d889
feat(recipes): list decision narrowing alongside supersession
darko-mijic Oct 12, 2026
dda3432
specs(studio): answer the Studio's blocking questions
darko-mijic Oct 12, 2026
7d260cb
merge fold/f1-captures: the captures' and Studio Specs' rulings
darko-mijic Oct 12, 2026
5188908
test(protocol): bind honest model and regeneration verifiers
darko-mijic Oct 12, 2026
f26cfe6
docs(specs): state ready on the folded design surfaces
darko-mijic Oct 12, 2026
b15010f
test(engine): cover boundary rendering and complete regeneration
darko-mijic Oct 12, 2026
176c4e9
test(worktree): isolate temporary Git and module probes
darko-mijic Oct 12, 2026
5b2d855
fold: Sol's review of the corpus lanes
darko-mijic Oct 12, 2026
c9a2a76
merge fold/f3-engine: Pack page fixes, link encoding, design columns,…
darko-mijic Oct 12, 2026
8d6a6bb
fold: status lines, and no calendar dates in Spec prose
darko-mijic Oct 12, 2026
6a74e30
plan 42: the Spec Studio's phase 0, drafted
darko-mijic Oct 12, 2026
134c184
test(oracle): re-pin intended truth under plan 41's fold
darko-mijic Oct 12, 2026
4abeacb
test(integration): re-pin folded recipe and CLI expectations
darko-mijic Oct 12, 2026
39fb11e
fold: Astra's review of the fold
darko-mijic Oct 12, 2026
92e70d7
plan 41: the fold's record, review and measurements
darko-mijic Oct 12, 2026
ca95171
fold: the owner's second round on the fold's holds
darko-mijic Oct 12, 2026
bc2c84e
test(recipes): give the every-Pack design test the heavy-test timeout
darko-mijic Oct 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 40 additions & 11 deletions .agents/skills/sdp-agent-surface/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ evaluation sink. There is no verb wall — you script the graph.
## The shape of the graph

The graph is flat: one array of nodes, one array of edges, nothing nested. Hierarchy is edges, so
every question is a filter or a join, never a tree walk. Four node types exist:
every question is a filter or a join, never a tree walk. Beside them, `graph.locations` is the
location table: the source line of every keyed Design and UI entry and every open question. Nodes
carry no lines, and a location is never an identity or a binding target. Four node types exist:

- `Primitive` — one authored Spec, positioned by `specKind` × `altitude` × `readiness`, carrying
its title, narrative, reified section content, and the derived `deliveryFacts`. Use case, NFR,
Expand Down Expand Up @@ -96,12 +98,22 @@ The public projection publishers are `sdp view`, `sdp census`, `sdp mermaid`, an
In this source checkout, use `npm run generate:self-hosting` or `npm run check:self-hosting` when
all four roots must be published or certified together.

The catalog contains twenty-eight ready-made bodies in `docs/agent-surface/recipes.md` in the
The catalog contains thirty-two ready-made bodies in `docs/agent-surface/recipes.md` in the
Protocol repository and
`node_modules/@libar-dev/software-delivery-protocol/docs/agent-surface/recipes.md` in an adopter.
Recipes 1-28 each open under a numbered heading that names the recipe. Every body there runs
Recipes 1-32 each open under a numbered heading that names the recipe. Every body there runs
verbatim and a test proves it. Start from a recipe; adapt it in place.

A recipe that takes a subject (a Spec id, a Pack id, changed files, addresses, a term) reads it
from `params.<name>`, and the catalog names the parameter. Pass it as JSON data with `--params`,
never by editing the body; `--params @PATH` reads the JSON from a file. The build also ships each
body as `dist/recipes/<NN>-<slug>.js`, so run it as shipped:

```sh
pnpm --silent sdp:q "$(cat dist/recipes/03-what-does-this-spec-guarantee-and-who-verifies-it.js)" --params '{"spec":"spec:consumers.reader"}' --json
pnpm exec sdp q "$(cat node_modules/@libar-dev/software-delivery-protocol/dist/recipes/04-what-breaks-if-i-change-these-files.js)" --params @changed-files.json --json
```

For structural questions, use component membership, uses fan-in and fan-out, structural
neighborhood, census structural coverage, and the projection-coverage upper bound (recipes 12-16).
For architecture questions, use the architecture map to see components and their shaping decisions
Expand All @@ -124,9 +136,11 @@ keyed entry of a Spec's Design or UI section, and `spec:<id>#question.<key>` nam
question whose marker carries that key; it belongs in prose, and `sdp validate` reports an address
whose Spec or key does not exist as an error. When you hold addresses written outside the
Specs, in a register, a test, or a page, address resolution (recipe 25) gives one row per
address: whether it resolves and, when it does not, why. When you hold a key or a term and need
the entry that carries it, use entry search (recipe 23): it matches whole tokens and names the
entry, where concept search stops at the section. It also gives the entry's address when the entry is a
address: whether it resolves and, when it does not, why; a resolving row carries the entry's
value, file, and line. When you hold a key or a term and need the entry that carries it, use entry
search (recipe 23): it matches whole tokens and names the entry and its line, where concept search
stops at the section. Both read lines from the location table, and a null line means not located,
never absent. Entry search also gives the entry's address when the entry is a
top-level Design or UI key that starts with a lowercase ASCII letter and goes on in ASCII letters
and digits, other than `description`, and when the entry is the text of an open question that
carries a key. Every other entry, a lawful `"01"` key included, gets `address: null`. When a
Expand All @@ -136,14 +150,27 @@ the key and the span content as authored. To see where Specs rest on each other
through `dependsOn`, run dependency cycles (recipe 26): it lists each such set with one closed
path through it, and reports without refusing.

For design work, run Pack design (recipe 29): per member, the stated next rung with the clauses
that hold the member below it, the design columns, open questions with addresses and lines,
decisions, and the realizing and referencing units with their components, plus the Pack's
boundary. The Design Review's Pack page renders the same assembly. Before changing a Spec,
design-change impact (recipe 30) lists every Spec that rests on it, transitively, with the units,
verifiers, and Packs to follow. The decision register (recipe 31) lists every decision with its
rung, its supersession both ways, the decisions it narrows and those that narrow it through
`refines`, the Specs it shapes, and its keyed questions. Architecture
crossings (recipe 32) lists the `uses` edges whose components differ in context or layer, tallied
by direction, and refuses nothing.

Reach for the files only when you need the authored prose itself — the exact words to edit.

## The entry adapters

`g.specContext(id)` lists the units that realize the Spec under `implementations` and the units
that answer to it under `references`, each with its file and line. `g.byFile(path)` returns every
node recorded at a path and the Specs reachable from it. A comment-form anchor is recorded at its
own site, so a source file with no Protocol import still answers. A node may come back with an
that answer to it under `references`, each with its file, line, and component, and its rows of the
location table under `entryLocations`. `g.packContext(id)` carries the Pack design: each member's
stated next rung, design columns, and bindings, and the Pack's boundary. `g.byFile(path)` returns
every node recorded at a path and the Specs reachable from it. A comment-form anchor is recorded
at its own site, so a source file with no Protocol import still answers. A node may come back with an
empty Spec list: an identity-only anchor, with no `satisfies` and no `references`, is lawful and
binds no Spec, and the empty list is its honest answer, not a failed lookup.
`g.blastRadius(files)` follows `satisfies`, `references`, `verifies`, and oracle `models` from the
Expand All @@ -153,13 +180,15 @@ list implies coverage.

## The contract

`sdp q ['<body>'] [--root PATH] [--exclude PATH]... [--json]`
`sdp q ['<body>'] [--root PATH] [--exclude PATH]... [--params JSON | --params @PATH] [--json]`

Three bindings are injected:
Four bindings are injected:

- `g` — the reader over the derived graph (the same `createReader` the package exports)
- `graph` — the raw graph schema (nodes, edges, claims)
- `report` — the validation report, so findings are queryable data, never a gate
- `params` — the JSON object `--params` supplies, or `{}` without it; a value that is not a JSON
object, or a file that cannot be read, is refused before the body runs

Body rules: a plain JavaScript **async function body**. No `import`/`export`, no TypeScript-only
syntax; `await` is fine. `return` is the machine output contract, but `sdp q` does not suppress
Expand Down
4 changes: 3 additions & 1 deletion .agents/skills/sdp-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ with `sdp q 'return g.specContext("<id>")' --root node_modules/@libar-dev/softwa
or open its carrier under that directory.

At this repository root, the `sdp:q` wrapper supplies the exact self-hosting exclusions. Paste each
recipe body between the quotes:
recipe body between the quotes, or run the file the build ships for it under `dist/recipes/`, and
pass a recipe's parameter as data with `--params`:

```sh
pnpm --silent sdp:q '<body>'
pnpm --silent sdp:q "$(cat dist/recipes/09-promotion-preflight.js)" --params '{"spec":"spec:<id>"}'
```

For an adopter, select its root and exclusions explicitly:
Expand Down
20 changes: 15 additions & 5 deletions .agents/skills/sdp-sessions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ pnpm exec sdp q '<body>' --root PATH
pnpm exec sdp q '<body>' --root PATH --exclude PATH --exclude PATH
```

Open the catalog and substitute only the parameter line of a parameterized recipe. The recipe
result informs the session; it never grants permission or records a verdict.
Pass a parameterized recipe its subject as JSON data with `--params` (or `--params @PATH` for a
file), never by editing the body; each recipe names its parameter, and the build ships every body
as `dist/recipes/<NN>-<slug>.js`. The recipe result informs the session; it never grants
permission or records a verdict.

## Choose an advisory work shape

Expand All @@ -56,7 +58,11 @@ Resolve the target's blocking open questions and review the carrying Specs. The
register (recipe 20) lists every open question in the corpus when the neighbors matter too. A
clear floor is evidence, not an automatic `ready` statement. Use pinned declarations (recipe 24)
to list every signature, type, validator or table the target and its neighbors pin as a code span
opening a keyed Design entry, so a test author and a builder working apart read one list.
opening a keyed Design entry, so a test author and a builder working apart read one list. When the
design is a Pack, read it with Pack design (recipe 29): per member, the stated next rung and what
holds the member below it, the design columns, open questions with their lines, and the code that
answers to it. Before changing a Spec, run design-change impact (recipe 30) for every Spec that
rests on it and the units, verifiers, and Packs the change asks to follow.

### Implement

Expand All @@ -79,15 +85,19 @@ existing code, the design's own `dependsOn` or `refines` says so, never a refere
For a Pack, use the Pack review backbone (recipe 5) and warn-level signals (recipe 8). Without a
Pack, use the target Spec context (recipe 3) with warn-level signals (recipe 8). To review a
change, take the scope from changed-file blast radius (recipe 4) over the diff, then run the
mention audit (recipe 22) with that scope as its parameter. Use address resolution (recipe 25) on
mention audit (recipe 22) with that scope as `params.scope`. Use address resolution (recipe 25) on
the entry addresses a register, a test, or a page cites outside the Specs. When reviewing
component, architecture, or projection questions, use structural neighborhood (recipe 14), census
structural coverage (recipe 15), the projection-coverage upper bound (recipe 16), the architecture
map (recipe 17), and the decision map (recipe 18). For a Pack reviewed from the code side, use
references into a design (recipe 27): per member, the referencing units, the realizing units, and
whether a verifier is bound, with an empty column read as unbound. Use roles, layers and contexts
(recipe 28) to review the architecture vocabulary the anchors state and to spot two spellings of
one value. Review findings and gaps as data; the review never becomes a workflow gate.
one value. To review a Pack's design as it stands, use Pack design (recipe 29); to review decisions,
the decision register (recipe 31), with each decision's rung, supersession, narrowing through `refines` both ways,
and the Specs it shapes; to review dependency direction, architecture crossings (recipe 32), which reports the
`uses` edges that cross a context or layer and refuses nothing. Review findings and gaps as data;
the review never becomes a workflow gate.

### Close / slim

Expand Down
24 changes: 24 additions & 0 deletions .omo/evidence/plan-41/mentions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Plan 41: unbacked mentions and honesty gaps (lane c2-repairs)

Measured on `lane/c2-repairs` from `28dcbdd`. Each line names the pair or the Spec, what the lane
did, and why. Re-run `sdp validate` and recipes 9 and 22 rather than trusting these lines.

## Prose mentions

1. `spec:carrier.markdown-body-grammar` → `spec:validation.authored-honesty`: declared `constrainedBy`. The grammar refuses delivery-fact and edge names as keys "under" that rule-kind Spec, so the rule bounds the grammar; recipe 9 finds no floor failure.
2. `spec:carrier.markdown-parser` → `spec:carrier.inline-code-spans`: declared `constrainedBy`. The parser keeps matched code spans literal at its raw-HTML guards under that rule, so the rule bounds the parser; the target states `defined`, which the `ready` floor accepts, and recipe 9 finds no failure.
3. `spec:consumers.adopter-on-ramp` → `spec:carrier.markdown-body-grammar`: declared `dependsOn`. The on-ramp ships a table of the body grammar that points at that Spec, so the on-ramp needs the grammar to hold; recipe 26 finds no dependency cycle after the edge.
4. `spec:consumers.delivery-session-on-ramp` → `spec:decisions.planning-truths-placement`: declared `decidedBy`. The decision places session law on the on-ramp's handoff rule, so it shapes this Spec.
5. `spec:consumers.delivery-session-on-ramp` → `spec:decisions.shipped-projections-frozen`: left as prose. The handoff rule names the freeze only as one example of a register carrier the next session re-measures; the on-ramp neither rests on the freeze nor is shaped by it.
6. `spec:decisions.architectural-significance-rides-primitives` → `spec:model.structural-patterns`: left as prose. The mentioning record is superseded by `spec:decisions.architectural-annotation`, a superseded record gains no relation, and the target already names the superseding ruling by `decidedBy`.
7. `spec:decisions.carrier-ruling` → `spec:decisions.carrier-universality`: left as prose. The earlier ruling points forward to a later one that refines it through `spec:decisions.gherkin-carrier-option`; no relation runs from an earlier decision to its later refinement, and `supersedes` would misstate a refinement as a replacement.
8. `spec:decisions.jsdoc-graph-extraction-refused` → `spec:model.spec-sections`: left as prose. The mentioning record is superseded by `spec:decisions.anchor-comment-form`, and it names the promotion law only as the place promoted rules go.
9. `spec:decisions.planning-truths-placement` → `spec:consumers.impact-graph`: left as prose. The decision names the Spec that holds the impact-graph deferral; a decision does not rest on the Spec it places a hold on. If the owner wants the pair backed, the honest edge runs the other way, `decidedBy` from `spec:consumers.impact-graph`; the lane did not add it, because its scope was the mentioning Spec.

## Honesty gaps

1. `spec:carrier.markdown-authoring`: bound, `test:protocol.markdown-authoring` in `test/import-round-trip.test.ts`. The suite builds a TypeScript corpus of all eight kinds with anchors, emits its Markdown twin, asserts both derive the same nodes, edges and delivery facts, and catches a corrupted twin: the Spec's one rule, that both carriers feed one derivation path.
2. `spec:extraction.claim-taxonomy`: gap left. No test takes the taxonomy as its subject. Edge claims are asserted as part of graph derivation (`test/extract.test.ts`, verifying `spec:extraction.derive-graph`), the never-collapsed rule by the claim-separation validator tests and examples (`spec:validation.claim-separation`), and claim inheritance (`belongsTo` carries `declared`) only in passing, in the Pack carrier parity example and the self-hosting oracle suite. `graphClaims` is missing from `test/graph-schema.test.ts`'s schema-contract test; a pin there plus an extraction test of inherited claims would make an honest verifier.
3. `spec:model.pack-aggregate`: bound, `test:protocol.pack-builder` in `test/builders.test.ts`. "Builds packs as plain manifests with no authored truth fields" checks the realizing unit, `src/model/pack.ts`, yields id, title, framing, specs and modelRefs and nothing truth-bearing; `test/builders.typecheck.ts` is the compile-time twin that refuses intent, readiness and constraints on a Pack.
4. `spec:model.relations`: bound, `test:protocol.relation-builders` in `test/builders.test.ts`. "Builds plain serializable specs with declared relations" checks the realizing unit, `src/model/relations.ts`, yields each of the six relations as a declared, directed edge to its target. The kind-typed endpoints are checked under the claim-separation validator in `test/validators.test.ts`.
5. `spec:model.spec-sections`: gap left. The Spec composes laws other Specs carry, and each is checked there: the typing law at compile time in `test/builders.typecheck.ts` (`spec:decisions.typing-law`), content-only sections in the extraction corpora (`spec:decisions.content-only-sections`), direct `verifies` under `spec:extraction.delivery-facts`, and question keys under `spec:model.open-question-keys`. The one test of the section model itself lists the eight section names (`test/descriptors.test.ts`), too thin to call a verifier.
Loading
Loading