Skip to content

Self-hosting phase 5: the 05 dissolution and the agent front door - #14

Merged
darko-mijic merged 19 commits into
mainfrom
feature/protocol-self-application-phase-5
Jul 28, 2026
Merged

Self-hosting phase 5: the 05 dissolution and the agent front door#14
darko-mijic merged 19 commits into
mainfrom
feature/protocol-self-application-phase-5

Conversation

@darko-mijic

@darko-mijic darko-mijic commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Self-hosting phase 5 — the 05 dissolution and the agent front door

What this is

Plan 22, executed end to end across six sessions on feature/protocol-self-application-phase-5.
It does the two things the phase-4 close named as next work, in that order: finish dissolving the
validation-and-honesty concept document
, and then give agents a front door — the CLI-facing
realization of the agent surface, which is also the seam the consumer family needed before it could
honestly claim ready.

The through-line is the Protocol applied to itself. Nothing here is a workflow gate or a
content-quality check; every promotion rides a verifier that resolves in the regenerated graph, and
every refusal is written down with its reason.

What landed

docs/concept/05-validation-and-honesty.md is dissolved and deleted. It had been sitting
exactly two clauses short for a phase. Those two — a per-team severity override for the informative
signals, and a team-overridable readiness floor — are now carried as one clause each on
spec:validation.warn-level-signals and spec:validation.readiness-floor, each stating the
reservation and its actual status in one breath, so neither Spec reads as if the capability
shipped. The document then went, with 24 inbound surfaces re-pointed in the same change: the
CONTEXT.md section pointer, two registry rows, the concept README and the three surviving concept
docs, four JTBD story files, the worked example's README, the source-comment citations across src/, three test citations, and the two pinned quotes in check-carrier-truth.mjs. Both
reference-sweep forms and a widened residue sweep return zero hits. The surviving concept docs
are 00 · 01 · 04 · 06 · 07.

One judgment call is worth naming: plan 21's inventory said to re-point registry row MD-9 at
spec:validation.kind-evidence. Read against the actual text, MD-9's law is the defined-rung
clause about a blocking open question — which readiness-floor states and kind-evidence does not
mention at all. Following the inventory literally would have minted a citation to a Spec that does
not carry the law, so MD-9 went to readiness-floor instead. The pre-close review verified that
correction independently.

The agent front door was ruled before it was built. Three candidates were weighed on the record
against the agent-surface ruling, the second-caller bar, and the gen-1 evidence; candidate (C) won
and is carried as a decision Spec, spec:decisions.agent-front-door, registered MD-22:

The front door is two entrances over one seam — the package exports the reader constructor, and
the CLI carries a single evaluation sink that derives the graph in process, injects that same
reader, and prints the body's pre-shaped return.

sdp q '<body>' adds one verb and zero query vocabulary, which is what makes a single sink the
opposite of the verb wall the founding ruling forbids. Freshness was ruled derive in process: the
extractor runs on every invocation, so a Spec you just authored is queryable immediately and no
committed generated/ artifact answers in the graph's name. That closes the long-carried
no-reparse read seam docket row — re-running the one lawful producer is the graph's
production path, and the sink never opens a carrier.

The on-ramp ships with it. The demand map is authored as four clauses on
spec:consumers.agent-surface: an agent arrives holding a string, a file, or a
changeset — never the Spec id it is looking for — which is exactly why the frozen adapters are
findByConcept · byFile · blastRadius, with bySymbol named-and-deferred and asserted absent
rather than stubbed. Everything past them is a recipe, not a verb: eight runnable bodies at
docs/agent-surface/recipes.md (build backlog, drift alarm, guarantees-and-verifiers, blast radius,
Pack review backbone, concept search, readiness divergence, warn-level signals), each executed
verbatim through the production seam by test/recipes.test.ts on shape-level invariants and never
on frozen counts. The skill at .claude/skills/sdp-agent-surface/SKILL.md is the cold-session
on-ramp; it cites Specs rather than restating them, and its anti-anecdote rule names itself as
the bug when it disagrees with the derived graph.

The consumer family earned its promotions. For two consecutive sweeps this family had refused
promotion honestly — for three distinct reasons, not one: reader refused on its verifier world
being a full graph fixture, design-review stayed defined on evidence with its world already
built at phase 4's S3, and agent-surface refused on two measured-evidence rules beside the world
question (framing corrected at the post-close review; plan 21 recorded the three separately). What
all three still lacked was a whole-pipeline verifier, and this phase built the world for one — a
materialized extraction root carrying, in
one small corpus, every discriminator the wave needed: an enabled verifier beside a declared-only
one, a binding-only source file beside a carrier file, an unrecorded file, a Pack, and exactly one
warning. Six bound points run the real extractor over it, and two of them read the sink's own
stdout rather than the reader, so the front door is verified end to end. All three parents —
spec:consumers.agent-surface, spec:consumers.reader, spec:consumers.design-review — promote to
ready. spec:consumers.edit-model refuses again on its own stated fourth rule, because this phase
lands no write surface.

Two refusals are recorded as refusals. The S5 readiness sweep dispositioned all 35 Specs
standing at defined and promoted none: not one of them carries has-verifier, so every
promotion would have added an honesty/gaps warning, and no verifier was invented to enable one.
And the optional measured-context refresh was actually constructed and run — a two-arm trial,
3,668 bytes through the sink against 8,895 bytes of grep output — and then refused, because the grep arm does not
answer the question, is measurably wrong where it does answer (58 satisfies lines against 30 real
edges, and it never touches test/), and how far it is allowed to run is an authoring choice that
swings the ratio by an order of magnitude. The numbers are on the record as design input for a
future measurement, explicitly not as evidence of a ratio.

The review, closed on the branch

reviews/11-self-hosting-phase-5-pre-close-review.md. Method: an independently designed mutation
matrix plus adversarial probing of the built product — eleven engine mutations, three aimed at
the recipe check, and thirty-one probes against node dist/cli/sdp.js q. The whole 630-test
tree was re-run after every mutation so discrimination was measured rather than assumed. None
replays a probe the plan's ledger already recorded.

What held. Five of the six bound points discriminate to exactly one point; the two overlaps are
the corpus agreeing with itself. Every headline number was recomputed from scratch at all six
blessed commits by re-deriving the graph — zero corrections. The 35-refusal sweep table
enumerates exactly the defined set, in both directions. The check-carrier-truth.mjs pin was
proved to bite under four separate mutations, including failing closed when its target file is
deleted. 131 Spec citations across the 21 re-pointed files resolve with zero dangling.

What did not, and is fixed here. The defects clustered where a front-door phase can least afford
them.

  • The on-ramp's own documented invocations did not run as written. sdp q '<body>' bare, and
    the two-exclusion form in the recipes header, both exit 1 at this repository's root — the corpus
    needs all three of explorations, examples, test/fixtures/import/parity or the graph does not
    derive and the sink refuses the body outright. The recipe check could not see it: it injects a
    memoized extraction with the correct list and never reads a documented command line. Both surfaces
    are fixed, and the check now pins every documented invocation to the same exclusion set it derives
    with.
  • Three ruled boundary behaviours had no test at all. Gating the read path on any extraction
    finding rather than only an error; detecting a terminal from process.stdin.isTTY rather than
    isatty(0) — the gen-1 hang footgun the ruling names by name; and skipping the strict
    consumer-exclusion contract. All three mutations left the entire 630-test tree green. Each now has
    a case that reddens for it and for nothing else.
  • The handbook's status header was stale by a whole phase, which had also left
    check-self-hosting-gates.mjs failing since the phase-4 close, because that commit dropped the
    stamp string the script pins. Both repaired.
  • Two records repairs: a §8 row that said "all three promotions" of a dependency relation that is
    direct for two, and MD-22's registry gloss, which ran a hundred words against the registry's own
    one-line rule.

Eleven findings, all terminal: seven fixed, three carried with named reasons, and one declined
with a reason — two of the eleven (F-10, F-11) are informational in severity, already inside the
declined and carried counts. (This tally originally read "five fixed, … two informational"; the
post-close review re-counted it against the archived table, which was always right.)

The post-close review, also on the branch

reviews/12-self-hosting-phase-5-post-close-review.md. At the owner's request a second,
multi-agent review ran after the close — over this description and the plans and PR descriptions
of all five self-hosting phases, six finder dimensions with every finding adversarially
re-measured before being acted on. Twenty-three findings, none refuted, all terminal: R-1…R-24
in the archived table, each with its disposition.

What it changed on the branch: four failure-path repairs on sdp q (an EPIPE crash escaping
the diagnostic currency on --json | head, an empty --root silently answering about cwd at
exit 0, the rendering path sitting outside every try/catch, and a toJSON → undefined non-JSON
hole under --json — each with a regression test and a live re-probe); completeness assertions
for the recipe check
(recipes 1, 2, and 7 were soundness-only, so an under-reporting body passed
vacuously — they now assert set equality against graph-derived expectations, still frozen-count
free) plus a tightened invocation guard; a shared test capture helper replacing five copies;
and a set of record corrections folded into plan 22 §10 — including the two sentences of this
description the review caught (the findings tally above and the consumer-family framing, both now
corrected in place), the retired-by-name agent-surface refusal reason, the closed 07 flag, the
restored bound-point series (50 points across 8 bound suites, re-measured from the regenerated
graph), and four phase-5 terms entering CONTEXT.md flagged for ratification at this review.

Verification

  • Full twelve-leg npm run check green at every blessed commit and at the close tip.
  • Clean-clone proof at the tip: git clone --no-local, npm ci, npm run check — green end to
    end.
    • Root tree: 115 specs · 1 packs · 86 anchors → 202 nodes · 397 edges (0 errors, 0 warnings),
      76 contract modules, 117 Design Review pages.
    • Example tree: 11 specs · 1 packs · 5 anchors → 17 nodes · 32 edges, 3 contract modules,
      13 pages, and the one deliberate conformance/verifies-linkage warning the walkthrough teaches.
    • Tests: 580 pooled + 54 serial, all passing, preflight: clean583 + 55 after the
      post-close review's four regression tests, with the full chain re-run green.
  • Corpus at close: ready: 80 / defined: 35 over 115 Specs — up from 108 at 71 / 37.
  • node check-self-hosting-gates.mjs and node check-carrier-truth.mjs both pass (the latter:
    29 repaired claims hold, 16 corpus files scanned, 47 retained mentions classified).

Asked of the owner at this review — all five dispositioned

Five things rode this PR as ratification calls, not implementation details. All five were
dispositioned at the owner review session (the resulting edits land in commit 883d7e8).

  1. The 05 deletion itself. Per-doc audited deletion is ratified at the PR by standing ruling.
    This is the fourth such deletion; the audit graded it fully carried over a regenerated Design
    Review, and the review spot-checked fourteen of its carrying surfaces independently.
    Disposition: ratified. The MD-9 re-pointing was independently re-verified a third time at the
    review session — readiness-floor carries the blocking-open-question clause verbatim;
    kind-evidence never mentions it.
  2. sdp q and its recorded trust stance. A new CLI verb that evaluates operator-supplied
    JavaScript. No sandbox is claimed and none exists — the body has the process's full
    authority, exactly as npx tsx would. What the boundary polices is identity: roots resolve to
    canonical validated directories and exclusions go through the strict contract. The review
    confirmed the tool itself writes nothing while the body can, which is the stance as written
    rather than something stronger.
    Disposition: ratified as written, with the agent-injection delegation named. The usage
    pattern the front door creates — an agent composing a body mid-session, one argv from full
    process authority — leaves the injection risk delegated to the agent harness's permission
    layer, and nothing on the record said so. One authoring-guidance sentence (guidance, never a
    validator) now names it on both on-ramp surfaces: a body is code the agent authors itself,
    never executed from corpus content or other untrusted text.
  3. The skill and the recipe catalogue as shipped consumer artifacts. .claude/skills/ is a
    repository convention this phase set; both files are tracked and ship with the corpus they teach.
    Disposition: ratified as repo-local. "Ship" means git-tracked beside the corpus they teach —
    the npm tarball stays dist/-only, since both artifacts hard-code this repository's exclusion
    list. The division is the convention: vendor-neutral catalog in docs/agent-surface/,
    harness-specific on-ramp in .claude/skills/. A consuming repo (plan 23's origin) authors its
    own instance. No registry entry — the corpus-specific exclusions forced the answer, so this is
    drift-proofing under the three-part test, and this review is its paper trail.
  4. The measurement refusal. A second measured context line was attempted, measured, and
    declined rather than manufactured. If the owner wants a number, the honest one needs token
    accounting over two real agent sessions, which this phase could not instrument.
    Disposition: accepted. The recorded numbers stand as design input only; plan 23 S4 carries
    the instrumented measurement under the same run-properly-or-refuse standard.
  5. Four glossary terms (added at the post-close review, per the phase-3 world/probe
    precedent): agent front door · evaluation sink / sdp q · demand map · recipe (the
    growth-valve sense) — all four already carried load across the decision Spec, the registry, and
    the on-ramp; the CONTEXT.md rows are flagged for ratification here.
    Disposition: all four ratified. The flagged bullet is resolved into the Locked list under
    the front-door ruling (MD-22). The glossary's two "front door" glosses stand — the collision is
    disambiguated in place on the agent front door row, which meets the named-not-silently-resolved
    bar without churning the reader's locked gloss.

What remains

Per plan 22 §5c, honestly:

  • spec:extraction.build-pipeline's rule 6"Every command uses the same extracted graph and
    validation seam"
    — now has a real world for the first time, because sdp q goes through exactly
    that seam. It is the strongest bound-point candidate this Spec has ever had, and it is named for
    the successor rather than converted here, because one point on rule 6 would not clear a Spec whose
    ordered-flow rules still have no cheap world.
  • 06 keeps five gaps (the impact graph's two assist roles · the discipline ≈ kind/section
    mapping · the distribution chart · the per-PR hosted preview · the Mermaid and reference-projection
    surfaces) and 07 keeps three (inline-vs-centralized anchor semantics · when harnesses and
    evidence become CORE · the measure-what-hurts heuristic). All eight are out of scope by this
    plan's own §(c); both documents stay.
  • The edit-model tail waits on a write surface that does not exist. The second-caller bar
    applied to writes is the reason, and spec:consumers.edit-model's own fourth rule says so.
  • bySymbol and the impact graph stay aspirational — the substrate does not exist, and the
    adapter is absent rather than stubbed so its absence cannot read as a landed capability.
  • Carried from the review: check-self-hosting-gates.mjs is not a leg of npm run check, which is
    why a stale handbook stamp went undetected for a phase. Adding a gate leg is a process change no
    ruling here authorizes; it is named for the successor.

Added at this review: the successor's reasoning, and plan 23

After the close, an investigation session surveyed the two ancestors — the gen-1 repo
(@libar-dev/architect 2.0.0-pre.1) and the origin project (new-convex-es /
libar-platform, still running vendored architect 1.0.0-pre.3) — to test this project's
direction against the evidence and to choose the successor phase. The reasoning, compressed:

  • The direction is confirmed by its own prior art. Gen 1's verb wall (74 distinct CLI
    invocations, 23 MCP tools, ~1,800 lines of mandatory skill preamble) was correct scaffolding
    for the Sonnet-3.x era and measurably wrong for this one: its own terminal experiment found
    ~89% of a graph snapshot to be one-consumer precomputed views and measured scripting over
    loaded shapes at ~⅕ the context of the grep/verb path. sdp q is that experiment's
    conclusion, productized — this PR is on the right side of the capability curve.
  • The risk is also confirmed by the prior art. The origin project's product velocity went
    615 commits (Jan) → zero (after May 9), with the terminal months spent entirely on delivery-
    process mechanics — the FSM, the value-transfer doctrine and its rollback PDR, committed
    living docs that now disagree with each other about their own progress numbers. The process
    ate the product. This corpus has removed those mechanisms from the product, but every piece
    of evidence it holds is still first-caller evidence: the only project the Protocol runs
    on is itself. The measured-context refusal in this PR is the honest marker of that gap.
  • The origin is not a candidate second caller — it is the intended consumer, with a
    deadline.
    Its re-entry corpus (drafted 2026-07-14) plans a restart in ~2 months whose
    precondition is a working delivery-process answer, and names the old process as the reason
    the repo is hostile to cold starts. Its corpus maps cleanly onto this model (authored specs →
    behavior Specs, Rule blocks → rule children, PDRs → decision Specs,
    @architect-executable-specs → verifier bindings, planning stubs → declared-but-not-enabled
    verifiers), and the value-transfer problem class dissolves entirely under durable Specs with
    derived facts.

The proposed successor is plans/23-outward-turn-origin-adoption.md (DRAFTED, in this PR):
phase 6 as the outward turn. S0 rules the three questions the origin forces (the atemporal-
planning stance with Packs as the wave aggregate, the keep-the-Gherkin-as-verifiers stance
with no importer at this bar, the design-stub disposition) and carries the two §5c items that
touch this repo (the rule-6 bound point, the gate-leg question). S1–S4 execute in the origin
repo: a hand-converted tracer cluster under tracer-bullet discipline, a fleet backfill of the
~45 authored specs/PDRs at honest readiness, the origin's restart plan modeled as the first
external build backlog, and the instrumented cold-start measurement this PR refused to
manufacture — run properly or refused with its numbers recorded, to the same standard. The
edit-model stays deferred; S1/S2's authoring-friction log is the evidence base its design has
been waiting for.

https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw

Greptile Summary

The PR completes phase 5 of the self-hosting effort.

  • Dissolves the validation-and-honesty concept document and redirects its references to carrying Specs.
  • Adds the sdp q agent front door, package-reader seam, recipes, and skill documentation.
  • Promotes the agent-surface, reader, and design-review consumer Specs with whole-pipeline verification.
  • Adds phase records, readiness updates, fixtures, regression coverage, and a draft outward-adoption plan.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failures remain within the follow-up review scope.

No blocking failures remain.

T-Rex T-Rex Logs

What T-Rex did

  • Ran agent-front-door-01-before.log to perform the production query without exclusions, which exited with code 1 and produced repository derivation diagnostics.
  • Ran agent-front-door-02-after.log to exercise the excluded-root invocation; it exited with code 0 and stderr was clean, with 115 specs available.
  • Ran focused tests with npm test -- test/cli-q.test.ts; 25 tests passed.
  • Verified the absence of the tracked skill path in this checkout using recipe-skill-blocker.log.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
src/cli/q-command.ts Implements query argument parsing, in-process extraction, reader injection, body evaluation, rendering, and contained diagnostics.
src/cli/sdp.ts Registers the asynchronous q command and adds entrypoint handling for completion, rejection, and closed stdout pipes.
src/cli/build-args.ts Extracts shared root resolution and rejects explicitly empty root values.
docs/agent-surface/recipes.md Adds eight executable graph-query recipes and documents the required corpus exclusions and trust boundary.
test/cli-q.test.ts Adds extensive coverage for query parsing, extraction refusal, evaluation, output formatting, and failure paths.
test/self-hosting-consumers.test.ts Adds whole-pipeline verification for the promoted consumer Specs and the CLI-facing reader seam.

Sequence Diagram

sequenceDiagram
    actor Agent
    participant CLI as sdp q
    participant Extractor
    participant Validator
    participant Reader
    Agent->>CLI: body, root, exclusions
    CLI->>Extractor: extract corpus in process
    Extractor-->>CLI: graph and extraction report
    CLI->>Validator: validateGraph(graph)
    Validator-->>CLI: validation report
    CLI->>Reader: createReader(graph)
    Reader-->>CLI: reader g
    CLI->>CLI: evaluate body(g, graph, report)
    CLI-->>Agent: rendered return value
Loading

Reviews (5): Last reviewed commit: "docs(context,agent-surface): ratify the ..." | Re-trigger Greptile

The last two rows blocking the validation-and-honesty document's dissolution
were both named deferrals that no Spec, registry, code surface, or surviving
document stated. Each is now carried as one clause on the Spec that already
owns its law, following the `doc:`-reservation precedent on
`spec:model.stable-ids`: state the reservation and its actual status in the
same breath.

- `spec:validation.warn-level-signals` gains the severity clause: the severity
  the informative signals carry is fixed by the Protocol, no validator reads a
  per-team setting, so a per-team override is a designed-for deferral rather
  than a landed capability.
- `spec:validation.readiness-floor` gains the floor-config clause beside the
  floor-table-as-truth posture (MD-13): the floor is the mechanism while the
  clause thresholds are one chosen representation, so a team-overridable floor
  configuration is a designed-for deferral — no validator reads a per-team
  floor setting and the shipped clause table is the only floor.

Neither clause takes a bound point: a deferral has no executable seam, so a
point would assert nothing the law contains and would be decorative.

The corpus oracle transcribes both new rules verbatim. No new Specs, so the
counts are unmoved: 108 Specs · 1 Pack · 80 anchors → 189 nodes · 371 edges,
`ready: 71 / defined: 37`, 0 errors / 0 warnings. Full `npm run check` green.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
… Specs

Audit basis (the standing per-doc dissolution template), judged over the
regenerated Design Review: with the two deferral clauses carried in the
preceding commit, every row of the phase-4 audit table now maps to a carrying
Spec, lean registry, pinned code surface, or surviving document. Verdict:
fully carried.

- §1 the two check families, the error/gap split, the layered-enforcement
  table → `spec:validation.two-check-families` (+ its `split-report` point).
- §2 the one-validation-path paragraph → `spec:decisions.one-validation-path`
  and `spec:extraction.build-pipeline`; checks 1-9 → the validation family
  (`referential-integrity` · `duplicate-ids` · `claim-separation` ·
  `verification-linkage` · `authored-honesty` · `readiness-floor` ·
  `warn-level-signals`) with their bound points.
- §3 the floors → `spec:validation.readiness-floor` and
  `spec:validation.kind-evidence` clause for clause; the stated-vs-derived
  blockquote → `spec:consumers.derived-readiness-banner`.
- §4 pack coherence → `spec:validation.pack-coherence`; §5 validator
  self-testing → `spec:validation.validator-self-testing`; §6 the aspirational
  tiers and §7 the CI summary were expository against `00`/`07` and the rows
  above.

One judgment correction to the recorded deletion-cost inventory: MD-9's mirror
is the `defined`-rung clause that reads a blocking open question, which
`spec:validation.readiness-floor` states and `spec:validation.kind-evidence`
does not mention — so MD-9 re-points at the floor Spec, not at kind-evidence.

Reference sweep in the same change, 24 inbound surfaces re-pointed: `CONTEXT.md`
and `AGENTS.md`, the DECISIONS registry rows MD-13 and MD-9,
`docs/concept/README.md`, the surviving `01`/`06`/`07`, the four JTBD stories,
the checkout-v1 walkthrough, the source comments in `validators.ts` (13),
`readiness-floor.ts` (5), `contracts.ts`, `reader.ts`, `design-review.ts`,
`sections.ts` and `reify.ts`, the three test-file citations, and the pinned
quotes in `check-carrier-truth.mjs` — the Family A claim re-pointed at
`specs/decisions/one-validation-path.sdp.md`, the Family C classification rule
retired with the document because Family C only classifies mentions inside the
scanned concept/JTBD corpus and its mention no longer exists. Both sweep forms
(path/backtick and the bare citation form) return zero hits outside `plans/`
and `reviews/`; the two surviving `validation-and-honesty` strings are prose
use-mention in the dissolution records themselves.

Graph unmoved: 108 Specs · 1 Pack · 80 anchors → 189 nodes · 371 edges,
`ready: 71 / defined: 37`, 0 errors / 0 warnings. Full `npm run check` green;
`check-carrier-truth.mjs` passes.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
… exported reader

The phase-5 ruling that the front door is never drifted into: candidates (A) a CLI
evaluation sink alone, (B) scripting-only against the exported reader, and (C) both over
one seam were weighed against the agent-surface ruling, the second-caller bar, and the
recorded ergonomics evidence. (C) wins — the sink injects the very `createReader` the
package exports, so a body scripted at the terminal and a module scripted in a repo
compose the same data through the same joins, and a single evaluation sink adds no query
vocabulary at all: it is the opposite of the verb wall, not an instance of it.

It passes the ADR three-part test, so it lands as a decision Spec with a registry row
(MD-22) rather than a plan ruling: the injected binding names become a scripted contract
the moment recipes are authored against them; a verbless CLI adding an evaluation verb is
surprising without the "one sink is zero vocabulary" reading; and the trade-off is real —
the sink pays the body's static typing for ergonomics while the scripting entrance pays a
module per question.

Two sub-rulings ride in the same Spec. Freshness: the sink derives through the extractor
in process on every invocation rather than reading the committed graph artifact, because
a query-time answer from a commit-time-gated artifact would hide a just-authored Spec —
and re-running the one lawful producer is the one graph's production path, not a second
parse. Trust: the sink evaluates local operator-supplied code with the stance of any local
developer tool, claiming no sandbox, with supplied roots resolved to canonical validated
identities at the boundary.

Corpus moves to 109 Specs; the pack manifest, the split oracle, and the frozen totals
follow (190 nodes, 373 edges, ready 71 / defined 38).

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
The ruled front door on the `sdp` surface: `sdp q ['<body>'] [--root PATH]
[--exclude PATH]... [--json]` derives the graph in process, injects `g` (the reader over
the derived graph — the same `createReader` the package exports), `graph` (the raw schema
object), and `report` (the validation report), evaluates the supplied body, and prints
what it returns.

Every recorded footgun is designed in rather than left to a flag. The body is a plain
JavaScript async function body, so the runner never resolves a module on the operator's
behalf and no staleness switch exists to forget. Input is argv or stdin, and the choice
asks the file descriptor rather than probing a stream property: a terminal invocation with
no body prints the usage refusal and exits 1 instead of hanging. The root resolves through
the shared `resolveExtractionRoot` seam every verb now uses — validate-then-use, so what
reaches extraction is a canonical validated directory rather than the operator's string.
Output is the body's pre-shaped return under bounded `util.inspect`, with `--json` as the
exact escape; the tool never truncates behind the caller's back. Extraction findings
render through `formatFinding`, the one diagnostic currency, and refuse the run only when
the graph fails to derive — validation findings are data on `report`, never a gate, because
checks have never gated the read path. The sink writes nothing, anywhere.

The dispatcher's return type gains the one asynchronous branch `q` needs; every other verb
still resolves synchronously.

Nineteen tests in the residual style over materialized fixture corpora cover argv and
stdin input, the terminal refusal, `--json`, a throwing and an uncompilable body, an
awaited body, the three bindings being live, findings-not-gating, the derive refusal, and
the write-nothing discipline. The suite never names the repository root, so it stays in the
pooled leg with no wrapper change.

The CLI surface list in `00` §4 and the agent-surface exposition in `06` §3 are re-pointed
deliberately; the slice-5 rows in `AGENTS.md` and `07` stay as provenance.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
"prints this refusal" had no referent when read inside --help output. The behavior is
unchanged: no body and a terminal stdin refuses with a usage note and exits 1.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
Enrich `spec:consumers.agent-surface` with the entry-point catalog: an agent
arrives holding a concept string, a file it is editing, or the changeset a diff
touches — never the Spec id it is looking for — so the surface is designed
around those entries. Each names its frozen adapter (`findByConcept` · `byFile`
· `blastRadius`, whose answer names every coverage-unknown changed file), the
symbol entry stays designed-for-and-deferred on the corpus's deferral-clause
precedent (`bySymbol` is absent rather than stubbed, so its absence cannot read
as a landed capability), and the recipe valve is stated in the Spec's own words:
past the entry adapters the surface grows by recipe, not by verb.

The oracle transcription follows on the same change. Readiness is untouched —
the Spec stays `defined`, floor-clean, and its promotion is not this session's.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…ten check

`docs/agent-surface/recipes.md` catalogues eight bodies an agent can paste into
`sdp q` unchanged: the build backlog, the drift alarm, one Spec's guarantees and
verifier bindings, blast radius over a changeset, the Pack review backbone,
concept search, readiness divergence, and the warn-level signals as data. Each
carries a one-line "when you need this", a pre-shaped return, and prose that
cites the carrying Specs rather than restating them. The vocabulary is
re-derived for this model throughout: claims decoded and never collapsed,
delivery facts read as bindings and never as liveness, stated readiness beside
derived.

`test/recipes.test.ts` proves the catalog: it pairs every numbered recipe
heading with exactly one fenced `js` body (so a new recipe cannot dodge the
check), then runs each body through the production seam — `runSdpCli` compiling
the body and injecting `g` / `graph` / `report` — against a graph derived once
from the repository root with the standard exclude list. Assertions are
shape-level only, never frozen counts: recipe 1's rows are stated-`ready` with
no `implemented` fact, recipe 4 names all three result classes, recipe 7 may
lawfully be empty. Mutation-probed three ways (a heading with no body, a body
that throws, a dropped filter) and each probe turns the intended leg red. The
suite derives in memory and imports no generated contract, so it stays pooled
and out of the bound-suite list by the standing exclusion rule.

The concept exposition on consumers picks up the demand map and points at the
catalog in the same change, so the two surfaces agree.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
The repo shipped no skills, so this sets the convention:
`.claude/skills/<name>/SKILL.md`, standard frontmatter with the trigger
conditions in the description, tracked in the repo so the on-ramp ships beside
the corpus it teaches. The content is deliberately short — it teaches the
bootstrap discipline (query the graph before reading spec files; the recipes
file is the catalog; `--json` for machine consumption), the binding and body
contract, and the honesty traps (`has-verifier` is not "tests pass",
`implemented` is not "live", claims are never collapsed). It cites Specs and
restates no law.

The anti-anecdote rule is stated first-class: the derived graph outranks the
skill and any summary cached earlier in a session, and when the two disagree the
skill is the bug.

Plan records follow: the three S3 conversion rows and the session row close with
their locations, and both watch items the session touches record what now
guards them.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
Convert the three consumer parents under the four-artifact template, over
real whole-pipeline worlds rather than narrowed probes: a committed
extraction corpus is materialized to disk, the real extractor derives the
graph, and each point reaches the consumer through the seam production
uses — `runSdpCli` for the front door, `createReader` for the reader, and
`renderDesignReview` over the reader for the view.

Six example children, one example space per parent:

- `spec:consumers.agent-surface` gains the scripted-context-body point (a
  body composes verifier bindings through `sdp q`; the printed answer is
  exactly the body's pre-shaped return, and the anchored verifier decodes
  as enabled where the declared-only one does not) and the
  demand-map-entries point (one body reaches the string, file, and
  changeset entries; the symbol entry is honestly absent, not stubbed).
- `spec:consumers.reader` gains the concept, file, and changeset entry
  points: a concept recorded only inside a Spec's sections is reached with
  its field named, a source file reaches the Spec its binding names while
  a carrier reaches its own, and a mixed changeset answers with impact
  reasons, one-hop at-risk edges carrying their claim, and the
  coverage-unknown file named rather than dropped.
- `spec:consumers.design-review` gains the pure-projection point: index
  plus one page per Spec and per Pack, the finding rendered as data beside
  every node it names and no other, two renders from freshly derived
  graphs byte-identical, and the extraction root byte-identical after.

The parents are enriched mirror-faithfully where the code already carried
more law than the Spec stated (the reader's per-adapter answers and their
reasons; the view's graph-only page identity; both realizing entrypoints),
and all three promote to `ready` on the resolving verifiers this wave
lands. The six children stand `ready` on their own test anchors.

`test/self-hosting-consumers.test.ts` is a new bound suite and enters
through the shared `contract-dependent-suites.mjs` row, so the lint
exemption and the wrapper's refusal follow from one edit.

Corpus moves to 115 Specs · 1 Pack · 86 anchors → 202 nodes · 397 edges,
`ready: 80 / defined: 35`, 0 errors / 0 warnings; twelve-leg gate green.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…tions

Plan 22 §7 gains four terminal rows — the shared whole-pipeline world and
one row per parent, each naming its points, what only that point's law can
refuse, and the mutation probe that reddened it alone. The deliberate
two-point overlap is recorded rather than smoothed over: dropping
`coverageUnknown` reddens both the changeset point and the demand-map
point, because that honesty half is stated on both Specs on purpose.

§8 gains the S4 readiness ledger: the three promotions with their floor
and verifier evidence, the enrichment that had to land first on the reader
and the view before either could be called acceptance-grade,
`spec:consumers.edit-model`'s standing self-declared refusal recorded not
regretted, and the note that `spec:consumers.projections-model` cleared
the dependency clause as it stands — nothing was promoted to unblock
anything.

§9's S4 row carries the clean-room transcript for the new bound suite, and
§3's oracle-thrash row records why this wave's bindings cannot freeze
corpus state: every bound literal names the S4 fixture corpus, not the
self-hosting corpus.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…ement refusal

The readiness sweep dispositions all 35 `defined` Specs per-Spec: zero
promotions, 35 named refusals. Not one carries `has-verifier` in the
regenerated graph, so every promotion would trip `checkGaps` and fail the
promotion law's evidence clause; all 35 clear the structural floor, so the
refusals are about evidence, never structure. Both charter checks are
answered on the record — the front-door decision Spec holds at `defined` as
the decision class's 22nd member, and no Spec whose verifier landed in S2-S4
was left behind. Two reasons moved: `spec:consumers.projections-model` (its
family's points are one hop away now, not two; refusal upheld on direct-only
linkage after re-judging its evidence posture against the S4 worlds) and
`spec:extraction.build-pipeline` (`sdp q` gives its rule 6 a real world for
the first time — named for the successor, not converted).

The `06`/`07` re-grades run to the standing template. `06` closes one gap
(`bySymbol`'s frozen-shape-but-aspirational status, now a carried deferral
bound by `demand-map-entries`), moves the second-caller bar off the surviving
documents onto a Spec, and grades both new §3 paragraphs fully carried; five
gaps stand and it stays. `07` moves no row; its three gaps stand and it stays.
Neither audit surprised toward fully-carried, so the re-pointing ruling did
not run. The gap ledger decomposes the old row 8 because exactly one half
closed.

The optional measured-context refresh is refused with the attempted two-arm
trial and its numbers recorded: the grep arm returns raw material rather than
an answer, is measurably wrong where it was run, and its stopping point is the
author's to choose — a manufactured benchmark would be worse evidence than
none. Nothing was added to the Spec.

Records only: no spec file, oracle transcription, or histogram literal moved.
Corpus unmoved at 115 Specs · 1 Pack · 86 anchors → 202 nodes · 397 edges,
`ready: 80 / defined: 35`, 0 errors / 0 warnings; twelve-leg check green.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
An independently designed mutation matrix over the phase's verification
layer, plus adversarial probing of the built CLI. Eleven engine mutations,
three aimed at the recipe check, and thirty-one probes against
`node dist/cli/sdp.js q`; the whole 630-test tree was re-run after each
mutation so discrimination was measured rather than assumed. None replays
a probe the plan's ledger recorded.

Five of the six S4 bound points discriminate to exactly one point; the two
overlaps are the corpus agreeing with itself. Every headline number was
recomputed from scratch at all six blessed commits by re-deriving the graph
— zero corrections. Both `05` sweep forms were re-run independently and
return zero.

Eleven findings, every one terminal. The defects cluster where a front-door
phase can least afford them: the on-ramp's own documented invocations did
not run as written at this repository's root, and three ruled boundary
behaviours had no test at all.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…boundary laws

The review's four accepted defects, each repaired and each re-verified
against the mutation that found it.

The documented invocations did not run as written. `sdp q '<body>'` bare,
and the two-exclusion form, both exit 1 at this repository's root: the
corpus carries deliberate duplicate-id and carrier-parity fixtures, so all
three of `explorations`, `examples` and `test/fixtures/import/parity` are
required or the graph does not derive and the sink refuses the body. The
recipe check could not see it — it injects a memoized extraction with the
correct list and never reads a documented command line. Both surfaces now
show the runnable form and say why, and the check pins every documented
`sdp q '…'` invocation to the same exclusion set it derives with.

Three ruled boundary behaviours had no test. Gating the read path on any
extraction finding rather than only an error, detecting a terminal from
`process.stdin.isTTY` rather than `isatty(0)` — the gen-1 footgun the
ruling names by name — and skipping the strict exclusion contract all left
the whole 630-test tree green. Each now has a case that reddens for it and
for nothing else.

The registry rows follow their own conventions again: MD-22's gloss is one
line, and the front-door decision is no longer listed twice.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…5 status

Plan 22 is stamped EXECUTED. The done-record states what landed and what
was refused, the seven acceptance criteria are graded with evidence, the
watch items and the docket rows are terminal, and the S6 gate row records
the review.

Two refusals are recorded as refusals rather than smoothed over: the S5
sweep promoted nothing across all thirty-five `defined` Specs because not
one carries `has-verifier`, and the optional measured-context refresh was
constructed, run, and declined with its numbers kept as design input rather
than dressed up as a ratio.

The handbook's status header was stale by a whole phase — phase-4 framing
over 103 Specs against a branch carrying 115 — which had also left
`check-self-hosting-gates.mjs` failing since the phase-4 close, because
that commit dropped the stamp string the script pins. Both are repaired:
the status now reads phase 5 with the branch's real numbers, and the
handbook points at the two consumer artifacts this phase shipped.

Claude-Session: https://claude.ai/code/session_01SoBtqnPU6EQrd1tgrUdxcw
…epairs and the record corrections

The multi-agent post-close review (reviews/12) over the PR description and all
five phases' plans and PR descriptions: 23 adversarially verified findings, all
terminal. sdp q gains an EPIPE-quiet exit, an empty-root refusal, a rendering
path inside the diagnostic currency, and a --json no-JSON-form guard — each
with a regression test. The recipe check gains completeness assertions and a
tightened invocation guard; the capture harness is shared from test/helpers.
Plan 22 carries the corrections at §10; CONTEXT.md carries the phase-5 terms
flagged for ratification.

Claude-Session: https://claude.ai/code/session_01RAd2xPjsdNiaRV8HB4YTSZ
Plan 23 (DRAFTED, PLAN-ONLY) proposes phase 6 as the outward turn: S0 rules
the atemporal-planning, Gherkin-as-verifiers, and design-stub questions the
origin corpus forces and carries the two plan-22 §5c items that touch this
repo; S1–S4 execute in the origin repo (tracer cluster, fleet backfill,
restart-plan backlog, instrumented cold-start measurement). Evidence base
from the gen-1 and origin surveys is recorded in §(b) because the sources
live outside this repo.

Claude-Session: https://claude.ai/code/session_01ELvPPmgz67hzwWxzN1ZCvh
The main-thread read of the origin corpus and gen-1's session/reference
skills, plus the owner's testimony (specs served as PRD replacement;
value transfer + docs generation proved invaluable), lands four changes:
the corrected value-transfer framing and the docs-generation re-ranking
in §(b) with the four-tier→readiness mapping and the no-migrate list;
S0 gains the enrichment-lifecycle question as its fourth ruling; §(i)
names the inline-carrier candidate (deferred to an MD-18-style
competition gated on S2 friction evidence), the recipe-to-projection
promotion path, and the authoring-workflow on-ramp gap; S1's friction
log becomes the measured instrument for the inline-carrier gate.

Claude-Session: https://claude.ai/code/session_01ELvPPmgz67hzwWxzN1ZCvh
… terms, name the trust delegation

All five owner calls from the PR's 'Asked of the owner' section are
dispositioned at the review session: the sdp q trust stance is ratified
with the agent-injection delegation named as authoring guidance on both
on-ramp surfaces; the four flagged glossary terms enter the Locked list
under the front-door ruling (MD-22); the consumer-artifact convention is
ratified as repo-local (no registry entry — the corpus-specific exclusion
lists forced the answer); the 05 deletion is ratified with the MD-9
re-pointing independently re-verified against the tree; and the
measured-context refusal is accepted with plan 23 S4 as its carrier.

Claude-Session: https://claude.ai/code/session_0158eQyLnKGzNZTPYcTehw5M
@darko-mijic
darko-mijic merged commit b9b1105 into main Jul 28, 2026
3 checks passed
@darko-mijic
darko-mijic deleted the feature/protocol-self-application-phase-5 branch July 28, 2026 14:34
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