The workbench READMEs were frozen in the W-026..W-031 planning era. Bring them
current after the Wave 1 / R / M arc:
- docs/workbench/README.md (index): add the 5 unindexed docs (wave-1-evidence-
spine, wave-R-mastery-revamp, wave-M-worthiness, b4-leeway-producer-scope,
design-system); replace the false "Current Status" (which still pointed at the
superseded feat/w026 prototype) with the shipped state + a 14-route surface
table; mark the W-026..W-031 queue delivered; note Wave M complete (B+C+D+B4),
Phase E + parallel tracks remaining.
- workbench-ui/README.md: fix the stale one-line surface list and the "src/routes
placeholder components" description (routes are registry-driven in src/app/;
routes.ts is the single source). Left the dump-api-schemas.py reference intact
(it exists, distinct from dump-schemas.py).
- README.md (top level): the workbench section said "eleven routes" — now
fourteen, naming Tour, Contemplation, and Calibration and the per-turn
pipeline/field/leeway/bundle evidence.
Docs-only; no code or gate touched. UI-UX-GUIDE (the routes.docs.test-gated
route table) is unchanged and already at 14.
Clears the long-standing B4 block: the leeway decision was already made on the
serving path (chat/runtime.py::_surface_estimate has a real LicenseDecision +
the ReachPolicy) and then DISCARDED — never threaded to the result, and the
workbench can't import reliability_gate. This wires it through.
Producer (observational, never authorizing):
- core/cognition/leeway.py: LeewayRecord + build_leeway_record(reach_level,
license_decision) — duck-typed on the decision, zero new cross-package
coupling. Maps to: no decision -> "unknown" (STRICT, no latitude); denied
-> "blocked" (gate consulted, said no); licensed SERVE/PROPOSE widening ->
the real class / theta / "[approximate]" disclosure. "verified" is never
emitted (RESERVED state). source_digest content-addresses the decision
(deterministic, no wall-clock).
- core/cognition/result.py: additive `leeway: LeewayRecord | None = None` on
CognitiveTurnResult.
- core/cognition/pipeline.py: build it at result construction from the data
the runtime ALREADY exposes (response.reach_level +
runtime.last_turn_accrual().license). chat/runtime.py is UNTOUCHED.
- workbench/api.py: _leeway_evidence_from_result maps result.leeway ->
LeewayEvidence (pure projection; no reliability_gate import — firewall
intact). The journal already persists it; the B4a UI (Replay / Proposals /
RightInspector) already renders it — no frontend or schema change needed.
Safety (this touches the serving path, so proven, not asserted):
- trace_hash is a NAMED-field hash (core/cognition/trace.py); `leeway` is not
in it -> byte-identical serving. All provenance/trace tests pass.
- response_governance STRICT stays byte-identical (375 governance/serving/
provenance tests green, incl. the live-wiring + estimation-lane + ADR-0206
seam tests).
- core eval cognition: 13 cases, 100% intent / groundedness / versor closure.
- replay determinism holds (leeway is in CRITICAL_FIELDS; deterministic).
Tests: engine (build_leeway_record: strict/blocked/SERVE/PROPOSE, no "verified",
deterministic digest) + workbench mapping (field-for-field, honest absence,
invalid-enum clamp) + integration (a real turn now carries an honest leeway
record, not the null "No evidence recorded"). 151 workbench/leeway Python + 68
frontend (leeway/replay/proposals/schemaDrift) green; schema-snapshot unchanged.
Docs: gate cleared (b4-leeway-feasibility-gate.md), residue ledger flipped to
implemented, scope brief is b4-leeway-producer-scope-2026-06-13.md.
The leeway decision already exists at chat/runtime.py::_surface_estimate
(accrual.license is a real LicenseDecision) but is discarded — never threaded to
CognitiveTurnResult, and the workbench can't import reliability_gate. Brief lays
out: the exact producer seam, the LicenseDecision/ReachPolicy -> LeewayEvidence
mapping, two honest layers (STRICT-now / earned-APPROXIMATE), the firewall-safe
workbench mapping, constraints, a minimal additive Layer-1 first PR, and 4 open
questions.
The "they'd want to use it" first-run surface: a curated narrative that makes
the engine's discipline legible to a newcomer — bring a claim from any model and
watch it get decided, refused, or replayed. Proposer authority ignored.
Honest by construction (the risk with a narrative surface is theater):
- workbench/tour.py determinism_tour() is a curated ordered narrative BOUND to
the real demo registry. Intro (provider-agnostic thesis) → three demo steps
(deductive entailment decides only on engine+oracle agreement; epistemic
truth-state refuses a wrong proposer; proof-carrying promotion ignores
proposer authority) → payoff (replay-to-same-hash + the citable evidence
bundle).
- Each demo step's what_this_proves / what_this_does_not_prove cards and the
demo title are PULLED FROM THE REAL DEMO SPEC — never re-authored — so the
tour can never claim more than the demo it points at.
- A step referencing a missing demo FAILS CLOSED (KeyError), not a dead link.
Tests assert both (cards == spec; phantom demo raises).
Backend: schemas.py DeterminismTour/TourStep; GET /tour. schema-snapshot regen.
Frontend: /tour route registered in the registry (Determinism section, 14
routes; nav/palette/guide counts updated); TourRoute — thesis hero + ordered
step cards with the honesty cards + links to the real demos / replay.
Validation: 140 workbench Python tests incl. tour drift guards; 472/472 frontend
incl. routes/routeConformance/routes.docs (guide↔registry), Shell+palette counts
(14), schemaDrift, and the tour UI test; pnpm build clean; git diff --check
clean. No serving-path imports.
The "they'd want to use it" deliverable: a turn's evidence exported as ONE
deterministic, content-addressed, citable artifact — composing the Phase-C
evidence (pipeline + field) with the trace and the calibration leeway verdict.
Backend (read-only, no engine execution):
- schemas.py: EvidenceBundle.
- workbench/evidence_bundle.py: build_evidence_bundle(entry) assembles a turn
journal entry into the bundle and computes bundle_digest. The digest
content-addresses the DETERMINISTIC cognitive evidence only — journal
position + wall-clock (turn_id, journal_digest, replay_reproducer,
generated_from) are carried for provenance but EXCLUDED, so the same turn
content reproduces the same digest regardless of journal position.
- api.py: GET /trace/{turn_id}/bundle. schema-snapshot.json regenerated.
The bundle carries a replay *reproducer* command (how to verify) rather than a
live-run replay, so the artifact itself stays deterministic — verification is
the consumer's step: re-run the prompt sealed, confirm trace_hash, recompute the
bundle, check the digest.
Frontend:
- types/api.ts EvidenceBundle; client/query hook; Trace route **Bundle** tab —
citable digest, "what this proves / does not prove" honesty note, the
reproducer, and a deterministic JSON download (Blob anchor, leak-safe).
Validation: 135 workbench Python tests incl. non-vacuous bundle guards (digest
reproducible, journal-position/wall-clock excluded, any evidence change flips
the digest, missing Phase-C evidence honest); 468/468 frontend incl. schemaDrift
+ the citable-download bundle test; pnpm build clean; git diff --check clean. No
serving-path imports.
C2-a surfaced contemplation runs but rendered each scene as a flat JSON dump —
outputs, not process. C2-b makes the loop legible: every scene is now a typed
stage in the canonical ADR-0172 arc.
Reader-first (no theater):
- schemas.py: ContemplationScene gains a typed loop projection — stage_role
(cold_attempt | engine_enrichment | engine_proposal | operator_ratifies |
grounded | other) plus the connective ids (proposal_id, candidate_id,
proposal_state, grounding_source). New ContemplationStageRole Literal.
- readers.py: _contemplation_scenes derives stage_role from the scene id
(closed set, "other" fallback) and pulls the connective ids out of the raw
detail. schema-snapshot.json regenerated.
UI:
- ContemplationRoute: the run detail now renders the arc as a staged process —
"attempt → enrich → propose → ratify → grounded" with named stage roles,
cold→grounded bookends (surfaces pulled out of before/after), the connective
ids as evidence, and the raw detail tucked into a collapsible (not lost).
Honest wrinkle (surfaced, not faked): the fixture proposals do NOT resolve in
the live proposal log (source_kinds exemplar_corpus/operator, none
contemplation), so the proposal id is shown as evidence but is intentionally
NOT a clickable cross-route link — a dead link would be theater. Live
Proposals/Calibration navigation is deferred to reader-verified linking once
real contemplation proposals reach the log.
Validation: 128 workbench Python tests + new reader-projection tests (canonical
arc → roles, unknown → "other", id extraction, detail preserved); 466/466
frontend incl. schemaDrift + the staged-process / no-dead-link test; pnpm build
clean; git diff --check clean. No serving-path imports.
Makes the CL(4,1) field geometry legible, honestly. The engine owns the field;
this surfaces ONLY the exact scalar invariants it computes — never the raw
multivector — so the workbench shows "this is the geometry, it's exact, it
can't fake coherence" without a decorative blob or any motion.
Persist-first (the C3 gating work was Python, not React): the honest scalars
were computed live per turn but discarded. Now captured per turn into the
journal so a read-only surface has real evidence.
Backend:
- workbench/field_evidence.py: FieldEvidence computed from the engine result —
exact versor_condition, field_valid (vs the 1e-6 ceiling), a content-
addressed field_digest (sha256 of the engine-canonical array bytes), and
cga_inner(before, after) as the exact transition value. Raw field bytes
never cross the boundary: only floats + digests. validate() is fail-closed —
field_valid can never disagree with versor_condition vs the ceiling (the
wrong=0 analogue for the geometry). No engine math re-implemented
(versor_condition / cga_inner imported from algebra; bytes via array_codec).
- workbench/schemas.py: FieldEvidence dataclass; field_evidence on
ChatTurnResult + TurnJournalEntrySchema. schema-snapshot.json regenerated.
- workbench/journal.py + api.py: persisted at from_chat_turn; first-class read
endpoint GET /trace/{turn_id}/field (trace facet, consistent with /pipeline).
- workbench/replay.py: field_evidence classified CRITICAL — replay now also
proves field determinism (digest + scalars must match on re-execution).
Frontend:
- types/api.ts FieldEvidence + field_evidence passthrough; client/query hook;
FieldInvariantCard (measured value vs ceiling, cga_inner transition, digests;
honest missing_evidence; no blob, no motion); Trace route Field tab.
Honest-empty for pre-widening journal rows (missing_evidence). Deferred:
cross-turn field-coherence trends, session-level field persistence.
Validation: 138 workbench/practice Python tests (incl. non-vacuous field guards
+ replay field-determinism); 465/465 frontend incl. schemaDrift; pnpm build
clean; git diff --check clean. No generate.derivation / reliability_gate /
stream / field.propagate / vault.store imports.
Lands the Phase C "make cognition legible" slice plus Phase A residue, all
backend-reader-first over real engine data (no theater, read-only doctrine
intact, zero serving-path imports).
C1-a — Cognitive pipeline record (persistence-first, per #729 worthiness edit):
- workbench/pipeline_record.py: curated CognitivePipelineRecord over the real
CognitiveTurnResult (input → intent → proposition_graph → articulation_target
→ realizer → walk_telemetry → trace_hash). Raw field multivectors are
DELIBERATELY excluded; _assert_no_raw_field_payload recursively rejects raw
field keys, and validate_pipeline_record fails closed on missing/duplicate
stages, non-recorded status, or dangling edges — the UI can never receive a
partial record that claims to be complete.
- test_workbench_pipeline_record.py: non-vacuous guards — missing stage,
monkeypatched new required stage, and injected raw {"F": [...]} each raise.
C2-a — Contemplation as a process: /contemplation route over real persisted
contemplation/runs/*.json (glob reader; honest-empty when absent).
C4-a — Identity continuity (L10/L11): RunDetail.identity_continuity + Runs
Identity tab, sourced from the real core.engine_identity (engine_identity /
parent_engine_identity lineage relation, re-derived to verify).
Demo Theater: renders backend-owned proof-promotion + entailment DAGs.
Phase A residue: density preference wired end-to-end (settings → shell → tokens);
cross-route consistency touch-ups.
Infra: local API CORS now echoes only validated 127.0.0.1/localhost origins
(hostname-checked, not arbitrary reflection) so Vite fallback ports work.
Route chunk-split keeps the build warning-free.
Cleanup: corrected the stale ADR-0175 practice-lane assertions (build_report is
6 correct / 0 wrong / 44 refused after the current serving lane; wrong=0 held)
and the two registry-derived count tests (LeftNav + CommandPalette 12 → 13 for
the new Contemplation route).
Docs: runtime_contracts.md (pipeline-record contract), UI-UX-GUIDE,
api-contract-v1, data-shapes-v1, wave-M-worthiness, phase-a-residue-ledger.
Validation: 106 workbench/practice Python tests green (incl. wrong=0 lane +
pipeline-record fail-closed guards); 459/459 frontend; pnpm build clean;
git diff --check clean. No generate.derivation / reliability_gate / stream /
field.propagate / vault.store imports.
Completes the Wave M B3.5 consolidation slice (b–e), built on #728.
B3.5-b — calibration as a first-class evidence subject (`calibration_class`,
address `calibration:<class_name>`): RightInspector projection + Evidence
Chain Rail semantics (serving-discipline evidence, not runtime truth).
B3.5-c / B4a — nullable `LeewayEvidence` read model threaded through turn,
replay, cognition-proposal, and math-proposal surfaces, with a shared
absence-honest card. B4 is gated correctly: the tuple exists in typed data but
no producer populates it, so the card renders absence (verified: no non-null
producer in workbench/core/chat).
B3.5-d/e — UI-UX-GUIDE.md, b4-leeway-feasibility-gate.md, phase-a-residue-ledger.md.
Practice artifact — earn-it-for-real (runner-reproducible). The committed
`report.json` (additive earns PROPOSE @0.861, 95/5/50) is now emitted by a
deterministic runner rather than copied from the queue. `propose_runner`
gains `regenerate_practice_artifacts()`, which runs ONE sealed `resolve_pooled`
practice pass and writes BOTH report.json (the per-class ledger the calibration
reader consumes) and ratification_queue.json — two projections of one ledger,
coherent by construction and byte-reproducible. `runner.main()` delegates to
it (lazy import, no cycle), so both entry points produce the identical pair.
This closes the gap where a hand-copied report.json agreed with the queue but
no runner produced it. `resolve_pooled` is the aggressive sealed PROPOSE-regime
scorer (proposal-only/HITL, unsafe for serving, legitimate for
attempt-and-eliminate); wrong=5 is the sealed-practice learning signal, NOT the
serving wrong=0. No serving/derivation/reliability_gate source touched; the
practice lane is not in the serving-frozen SHA gate.
Validated:
- python -m pytest tests/test_workbench_{calibration,journal,replay,schemas}.py -> 31 passed
- python -m pytest tests/ -k "workbench or propose or learning_arena or practice"
-> 190 passed (3 failing tests in test_adr_0175_phase2_practice_lane.py are
PRE-EXISTING reds on clean origin/main: stale 4/0/46 assertions on build_report,
which this change does not touch)
- report.json + ratification_queue.json: deterministic (run1==run2) and
reproduced byte-identically by both `python -m ...runner` and `...propose_runner`
- pnpm build green; 144 UI tests across calibration/leeway/evidence/replay/
doctrine-gates/routes-docs-drift all pass
Two corrections from this session's source verification:
- B3.5 D2 (calibration artifact): coherence between report.json and
ratification_queue.json is necessary but NOT sufficient. The 95/50/5 earned
state is a fossil from the disabled resolve_pooled scorer (queue committed in
b82897a0); no current runner reproduces it (main()=6/44/0, candidate-graph
practice=0/1/149). Acceptance now requires report.json be byte-reproducible
by a documented deterministic runner pass; copying numbers between artifacts
is inadmissible. Three routes named (honest-floor now, earn-it-for-real
follow-up, defer).
- C1 (cognitive pipeline visualizer): corrected the false "reader-first over
existing telemetry" framing. Verified the journal persists only ~12 surface
fields of CognitiveTurnResult's ~25; no /trace/{id}/pipeline endpoint. C1-a's
real first deliverable is a persistence change: a curated
CognitivePipelineRecord (never the raw field_state multivectors — O(n^2)
cost), a runtime-contract update, and a non-vacuous fail-closed test.
The docs/proposal-artifact-substrate-v1 work (#727) — wave-m-consolidation-b3.5,
core-logos-studio-plan, proposal-artifact-substrate-v1 — is the authoritative
consolidation and supersedes the parallel 'Phase A' I'd just drafted. Reconciling
to one source of truth:
- FOLD IN the one genuine gap b3.5 missed (a design review caught it): the
Calibration centerpiece undersells — the reader reads the sub-N_MIN committed
practice report.json, so on live data no class shows licensed, while the
earned state (additive 95/5/100, PROPOSE-licensed) sits in the disagreeing
ratification_queue.json. Added as a diagnosis addendum + a Deliverable-2
acceptance criterion (make the committed practice artifacts coherent; show
≥1 earned class). Data-side fix, not a re-derivation.
- FOLD IN the grouped-navigation idea: a field on the route registry
(Deliverable 1) + the organism's-loop grouping (Converse/Cognition/Evidence/
Determinism/Discipline/Substrate/Settings), with the correction that
'core-logos' is the language/manifold Studio surface, not the cognition cluster.
- REDIRECT wave-M-worthiness.md's consolidation section to point at b3.5 instead
of defining a parallel Phase A.
- SCRAP duplicates: wave-M-phaseA-briefs (duplicated b3.5) and
workbench-ui-ux-guide-brief (superseded by b3.5 Deliverable 4).
Boils the design review and the information-architecture decision into one
integration. Phase B's heart (calibration/serving discipline) is done;
Phase A (Structure & Polish) now runs BEFORE resuming Phase C because two of
its items are structural prerequisites the Cognition cluster lands into.
Key synthesis: the command-palette drift bug and the grouped-nav idea are
the SAME fix — navigation derives from one registry that also encodes
structure. Standing IA constraint: one workbench, one address space, one
Chain Rail; grouping is a wayfinding skin, never an architectural fork; no
separate workbenches (the single evidence model is the thesis); 'levels' are
depth-within-a-surface, not top-level categories.
Phase A brief pack (wave-M-phaseA-briefs):
- A1: navigation registry (one source of truth) + grouped nav by the
organism's loop (Converse/Cognition=core-logos/Evidence/Determinism/
Discipline/Substrate/Settings) + palette fix (Demos+Calibration are
currently unreachable via ⌘K; the ⌘1-0 map is stale)
- A2: Calibration earned-state — the centerpiece undersells (reads the
sub-N_MIN report.json; the earned license lives in the disagreeing
ratification_queue). Primary fix: regenerate coherent practice artifacts;
fallback: reader surfaces both with provenance
- A3: Doctrine station ('how this UI can't lie') — elevate contracts/checks
into a first-class surface; trails, larger
Parked: B4 (needs engine-side license stamping; no re-derivation),
Calibration EvidenceSubject kind.
A teach-everything, indexed docs/workbench/UI-UX-GUIDE.md: thesis + evidence
model, the 11 routes (purpose/evidence/usage/states each), the design system
+ primitives, the full keyboard map, the doctrine gates as honesty proof,
replay-in-depth, glossary. Scoped for a mid-tier model: documentation over
shipped code, accuracy-over-completeness, Markdown-only, ground every claim
in the real components. Dispatch-ready.
Wave M takes the workbench to mastery and closes its biggest design gap:
it surfaces the teaching/ratification loop but is blind to the
calibrated-learning / serving-discipline loop (gold-tether arena, reliability
gate, Wilson floor vs θ ceiling, 'the engine earns the right to guess') and
to cognition itself (pipeline stages, field substrate, identity continuity).
Lens: Anthropic + xAI as target users who'd WANT to use it.
- wave-M-worthiness.md: full plan, Phases A–E, the missing-surfaces table,
the backend-reader-first / never-re-implement-engine-math disciplines,
execution order (B→C→D, A parallel).
- wave-M-phaseB-calibration-briefs: executable Phase B pack grounded in the
real core/reliability_gate shapes (ClassTally / conservative_floor /
license_for / Action θ) and the committed report.json evidence — B1
readers (GATING, Python), B2 Calibration route, B3 wrong=0 global frame,
B4 leeway wiring. Dependency DAG + STOP gates + no-theater rules.
First R3 (Theater) piece. Reworks the stale artifact-keyed ReplayRoute into
the turn-keyed hero over the #716 sealed-replay backend, and fully retires
the dead W-026 artifact-keyed machinery on both sides (the NOT_YET_MIRRORED
comment anticipated this).
The hero makes determinism *felt*: pick a journaled turn, CORE re-executes
its prompt in a sealed fresh runtime, and the result renders as a hash
verdict (≡ equivalent / ≠ diverged) + the original/replay DigestBadges + a
leaf diff (critical weighted above informational, each with a ≠ glyph). The
'What this proves' card surfaces comparison_basis + origin_state and states
the honest limit: a divergence means nondeterminism OR origin-state
influence, never rendered on its own as a determinism failure.
Retirement (verified zero serving uses):
- Python schemas.py: removed ReplayComparison/ReplayDivergence/ReplayStatus/
ReplayDivergenceSeverity; scripts/dump-enums.py drops the two replay enums;
both snapshots regenerated (deterministic: dump == committed)
- TS: removed ReplayComparison/ReplayDivergence/ReplayDivergenceSeverity;
added TurnReplayComparison/TurnReplayDivergence (+ basis/origin/severity
unions); NOT_YET_MIRRORED now empty (every engine schema mirrored)
- badges: removed ReplayStatusBadge + ReplayDivergenceSeverityBadge +
meta/enums + their enumCoverage cases (hero renders severity inline)
- api: fetchReplayComparison/useReplayComparison -> fetchTurnReplay/
useTurnReplay (/replay/<turnId>)
- deleted ArtifactList, ReplayComparisonPanel, ReplayDiffViewer,
ReplayMetadataTable, old replay.test.tsx
- App route /replay/:artifactId? -> /replay/:turnId?; conformance row
turn-keyed (loading 'Loading turns...', empty 'No turns recorded yet.')
Tests: ReplayRoute.test.tsx (equivalence hero + honesty card, diverged
critical leaf, informational-only label, replace-mode select, j/k spine).
Full vitest 358 green; workbench Python 34 green; both snapshots deterministic.
Follow-up flagged (not in this PR to keep it focused): the artifact query
hooks (useArtifacts/useArtifactDetail/fetchArtifacts*) are now orphaned but
entangled with the still-live artifact EvidenceSubject kind — a separate
cleanup once an Artifacts route or that subject's fate is decided.
Brief: docs/handoff/wave-R3-briefs-2026-06-13.md (all four R3 pieces).
Replaces the W-026 501 stub. Re-executes a journaled prompt in a sealed
fresh runtime (ChatRuntime(no_load_state=True): no checkpoint load, no
checkpoint write, no proposal lineage) and compares the envelope
leaf-by-leaf against the recorded TurnJournalEntry.
Design correction vs the scoping doc (amended in-doc): journaled turns
each ran in a fresh ChatRuntime(), never one continuous session, so
genesis-PREFIX replay would manufacture spurious divergence; shipped
basis is sealed_fresh_runtime_single_turn (O(1)). origin_state:
"unrecorded" — the journal does not record whether the original turn's
runtime loaded a checkpoint, so divergence is reported as nondeterminism
OR origin-state influence, never disambiguated.
- workbench/replay.py: pure comparison + injected executor; every
TurnJournalEntry field classified critical/informational exactly once
(exhaustiveness enforced by test)
- api.py: route wiring under _CHAT_TURN_LOCK; runtime failure -> 500
runtime_unavailable, no comparison may be fabricated
- schemas: additive TurnReplayComparison/TurnReplayDivergence (W-026
artifact-keyed pair retires with the frontend Replay Moment PR)
- tests: 10 obligations incl. tamper-prompt, tamper-leaf precision,
no-execution-no-comparison, no-trace (journal + engine_state bytes),
wall-clock tolerance, sealed-construction proof
- snapshot regenerated; NOT_YET_MIRRORED debt entries for the two new
classes (mirrors land with the frontend PR)
- api-contract-v1.md § Replay rewritten for the turn-keyed shape
Decides sealed genesis-prefix replay semantics against the actual
constraints (single rolling post-turn checkpoint; journal appended only
by the workbench handler, so history completeness is unprovable today).
Response carries comparison_basis + history_complete so the UI never
oversells; typed refusals; five MEANINGFULLY-FAILS proof obligations.
Reconciles a stale local edit with the upstream roadmap: the deductive
entailment authority demo (PR #700) moves under Demonstrated with its
evidence caveat, and the merged-boundary count is corrected to five
(#687, #688, #690, #696, #700). Next proposed target: Embodied Authority
Simulation Demo.
Brief 4 of the Wave 1 evidence spine — wire the evidence-context architecture
so every route can project into one shared evidence manifold.
Command registry (1A):
- commandRegistry.ts: useSyncExternalStore-backed command store with a cached
snapshot (referentially stable to avoid render loops); useCommands /
useCommandRegistry; recent-items in localStorage (last 10).
- CommandPalette.tsx: reads from the registry; all ten routes are navigation
commands (was Chat/Proposals/Evals hardcoded); fuzzy filter, recent section,
shortcut badges; Router/Fallback split preserved.
- useGlobalKeyboard.ts: Cmd+K palette, Cmd+I inspector, Cmd+1-0 routes, ? help.
Evidence drawer (1B):
- evidenceContext.tsx: EvidenceSubject union (turn|proposal|artifact|
eval_result|none) + useEvidenceSubject hook + EvidenceProvider above the
router Outlet so inspector state persists across route transitions.
- RightInspector.tsx: five evidence projections (was a null stub); reuses the
Brief 2 primitives (MetadataTable, DigestBadge, Timestamp, badges).
- Shell.tsx: visibility driven by inspectorOpen (collapsed by default); no more
hardcoded collapsed=true.
- KeyboardHelp.tsx: shortcut reference dialog.
- TopBar.tsx: palette open state lifted to Shell via props.
Tests: evidenceContext + RightInspector specs added; CommandPalette keyboard
contract updated for the ten-command navigation set (clamp at both ends).
Deferred (noted in spine doc): per-route register()/setSubject call sites,
action-commands (run eval / copy hash), resizable inspector width.
Verified: tsc -b + vite build green; affected specs pass per-file.
Replace blanket no-mutation language with the admitted-corridor rule: ADR-governed path, visible preconditions, auditable telemetry, and replay evidence before action.
Math ratification is documented as the first admitted proposal corridor. Corpus, pack, workflow, arbitrary file, and unadmitted proposal mutation remain forbidden.
SplitPane, TabBar, MetadataTable, DigestBadge, Timestamp, SearchInput.
All token-driven, keyboard-navigable, ARIA-accessible, dark theme,
motion-respectful. No new dependencies — TabBar uses native ARIA
semantics instead of @radix-ui/react-tabs.
PreviewPage updated with all six components in representative states.
Section 1C checked off in wave-1-evidence-spine.md.
Append-only JSONL journal records the exact ChatTurnResult envelope returned by /chat/turn with stable turn_id, trace_hash, all three surfaces, verdicts, and deterministic journal_digest.
GET /trace/turns and GET /trace/{turn_id} serve journal evidence for the Trace route frontend. Read model only; no teaching, pack, or journal-owned engine_state mutation.
Two-pass hardening of the #690 demo so no epistemic state is proposer-mintable:
Pass 1 (sealed corpus, from the reconciliation pass):
- evidence items are references only (evidence_id + content_sha256) resolved
against a committed content-addressed corpus (evidence_corpus.json)
- support derived from committed subject/predicate match; independence from
distinct provenance_root values; proposer support/independence labels are
rejected by the closed schema
- evidence-strength taxonomy (substrate-capability vs interface-contract) in
PUBLIC-DEMO-ROADMAP / DEMO-PACKAGING-CHECKLIST; position-paper refinements
Pass 2 (entailment-decided inference, closes a live false-status hazard):
- the merged inferred leg required only that premise IDs resolve — a claim
with no support citing one unrelated record as a premise was assigned
'inferred' (empirically confirmed). inferred is now decided by
generate.proof_chain.entail (sound+complete ROBDD) over resolved corpus
premises, cross-checked against the independent truth-table oracle
(evals.deductive_logic.oracle, no shared code); proof keys + oracle verdict
in the trace; disagreement => defensive refusal; refutation => contradicted
- committed adversarial scenario unrelated-premise-still-undetermined proves
the attack now lands on undetermined
- corpus seal (corpus_sha256) pinned into every evaluated trace; scope
refusals no longer consult the corpus; corpus cache hands out copies;
claim subject/predicate constrained to atom-compatible snake_case
- .gitignore: private packet dir, agent worktrees, tooling artifacts
Validation: 30 demo tests; 96 across all three demo suites; 7/7 scenarios
double-run byte-identical; 61 architectural invariants green.
Two-pass hardening of the #690 demo so no epistemic state is proposer-mintable:
Pass 1 (sealed corpus, from the reconciliation pass):
- evidence items are references only (evidence_id + content_sha256) resolved
against a committed content-addressed corpus (evidence_corpus.json)
- support derived from committed subject/predicate match; independence from
distinct provenance_root values; proposer support/independence labels are
rejected by the closed schema
- evidence-strength taxonomy (substrate-capability vs interface-contract) in
PUBLIC-DEMO-ROADMAP / DEMO-PACKAGING-CHECKLIST; position-paper refinements
Pass 2 (entailment-decided inference, closes a live false-status hazard):
- the merged inferred leg required only that premise IDs resolve — a claim
with no support citing one unrelated record as a premise was assigned
'inferred' (empirically confirmed). inferred is now decided by
generate.proof_chain.entail (sound+complete ROBDD) over resolved corpus
premises, cross-checked against the independent truth-table oracle
(evals.deductive_logic.oracle, no shared code); proof keys + oracle verdict
in the trace; disagreement => defensive refusal; refutation => contradicted
- committed adversarial scenario unrelated-premise-still-undetermined proves
the attack now lands on undetermined
- corpus seal (corpus_sha256) pinned into every evaluated trace; scope
refusals no longer consult the corpus; corpus cache hands out copies;
claim subject/predicate constrained to atom-compatible snake_case
- .gitignore: private packet dir, agent worktrees, tooling artifacts
Validation: 30 demo tests; 96 across all three demo suites; 7/7 scenarios
double-run byte-identical; 61 architectural invariants green.
The ratified capability, through the existing mutation owner only:
- teaching/proof_promotion.py — pure decider. Fresh-reads every premise AND
the claim from the store (claim_entry_index; forms never proposer-supplied),
strict status compares (no parse-defaulting), reading_certified must be the
boolean True, engine certification via the pinned deductive engine,
proposer_payload accepted and provably never read (del before use; poisoned-
mapping test), certificate digest emitted for D4 trace-hash folding. Zero
mutation; zero vault.store calls; zero status writes (proven with the
INV-21/INV-29 detectors themselves).
- vault/store.py::apply_certified_promotion — the single transition site.
Independently re-verifies: byte-for-byte replay under DEDUCTIVE_ENGINE_PIN,
promotion_positive, live claim form/reading/status cross-checks, live
premise form/reading/status cross-checks (staleness refuses). Fabricated or
tampered certificates flip nothing; authority is live store state plus
recomputation, never the artifact.
- generate/proof_chain/engine_pin.py — DEDUCTIVE_ENGINE_PIN mirrors the
deductive_logic_v1 lane SHA; sync pinned by AST test against
scripts/verify_lane_shas.py.
- Consistency fix found in lookback: both promotion sites now stamp
epistemic_state alongside epistemic_status (the ADR-0148 site left the
stored state tag stale; recall recomputed it, but the stored key lied).
Obligations: all six strict-xfail markers retired and live (O1/O2
strengthened to prove the transition through the vault owner); the
module-existence pin deleted per its own docstring; the two remaining
honesty pins kept. INV-21 allowlist unchanged; INV-29 allowlist unchanged
({vault/store.py}); INV-29's 29c visibility floor raised 2 -> 3 to cover the
new site.
No runtime turn path calls promotion; the deterministic demo is PR D.
Validation: new suite 49 passed; obligations 8 passed (0 xfail remaining);
invariants 66 passed; certificate 27 passed; 0148 6 passed; epistemic 20
passed; smoke files green; lane SHAs verified.
Architect-directed ratification: D1 (pure decider / vault-owned mutation),
D2 (reading stays curator-certified in the first cut), D3 (exact predicate,
including REFUTED -> no transition), D4 (certificate fields + trace-hash
folding), and INV-29 as the permanent transition-site boundary, all ACCEPTED.
Two fail-closed realizations recorded under D3: the claim form is fresh-read
from the claim's own stored entry (never proposer-supplied), and zero-premise
tautology certificates refuse rather than promote in v1.
Docs-only: no runtime behavior changes in this commit. P3 implementation
(teaching/proof_promotion.py + VaultStore.apply_certified_promotion) follows
in the same PR as separate commits.
Pure evidence substrate for proof-carrying coherence promotion. No
promotion, no vault import, no status transition, no teaching-path
change; ADR-0218 stays Proposed.
- generate/proof_chain/certificate.py: frozen PromotionCertificate
(version/claim_form/premise ids+forms+statuses/entailment_trace/
engine_pin/decision/reason, canonical_json with sort_keys+compact
separators); build_certificate runs evaluate_entailment_with_trace
over entry_id-sorted premises; verify_certificate rebuilds from the
embedded forms and accepts iff byte-identical — tampered forms/claim/
trace/decision/reason/ordering/version all fail replay, structural
breakage fails closed as malformed_certificate.
- promotion_positive is necessary-not-sufficient: entailed over a
non-empty all-coherent recorded premise set; REFUTED/UNKNOWN/REFUSED
verify as themselves but are never positive; zero-premise tautology
certificates fail-closed non-positive in v1.
- engine_pin is recorded provenance; pin tampering is caught only via
caller-supplied expected_engine_pin (P3 must pass the lane SHA) —
limit pinned by dedicated tests.
- entail.py: docstring-only fix removing the incorrect ADR-0206
attribution (numbering collision); now cites ADR-0218. Zero behavior
change. generate_claims.py:74 still carries the label (serving-frozen
surface, flagged for follow-up).
- No xfail markers retire: every PR-A obligation binds to the P3
promoter, which must not exist before ratification. The certificate-
shaped halves of O1/O7 are proven for real in
tests/test_proof_chain_certificate.py (27 tests). ADR phasing bullet
and obligations docstring record the reconciliation.
Validation: certificate 27 passed; obligations 3 passed + 6 xfailed;
architectural invariants 61 passed (INV-21/INV-29 green, allowlists
unchanged); entail/builder/rules 61 passed; smoke files 95 passed.
PR A of the stack specified by docs/issues/proof-carrying-coherence-promotion.md.
No runtime change; no promotion behavior; ADR-0218 is Proposed, not ratified.
- ADR-0218 (Proposed): rulings the issue Section 9 demands — extend the
existing mutation owner (policy decides in teaching/proof_promotion.py at
P3, only vault/store.py mutates), reading stays curator-certified in the
first cut, exact fail-closed admissibility predicate, certificate folds
into trace_hash. Records two substrate corrections: proof_chain Phase 2
(2.1-2.4) is already implemented, and ADR-0148 already automates an
energy-arm promotion.
- INV-29 (passing): epistemic-status transition sites are allowlisted.
ADR-0148's in-place promotion proved INV-21's AST scan cannot see
status transitions (they are not store() calls) — the boundary the
issue calls highest-risk did not actually cover the riskiest shape.
Allowlist pinned to {vault/store.py} BEFORE any promoter exists;
detector mutation-proven non-vacuous (29b/29c).
- Obligations O1-O5, O7 as strict xfail (executable spec; ImportError today;
strict=True forces the P3 PR to retire markers and pass for real) + three
honesty pins that flip red if promotion is wired without review.
Validation (worktree off main@187b008b, python -m pytest):
- tests/test_proof_carrying_promotion_obligations.py: 3 passed, 6 xfailed
- tests/test_architectural_invariants.py: 60 passed (56 prior + 4 INV-29)
- smoke file set: 94 passed
- proof_chain/entail/binding-graph/ADR-0148 set: 84 passed
- epistemic/teaching set: 40 passed
- scripts/verify_lane_shas.py: 8/9 pinned lanes match incl. deductive_logic_v1;
public_demo missed on the known env wall-clock budget flake (47.6s > 30s),
pre-existing and unrelated (diff is docs+tests only).
§3.4 said promotion "requires a curator-mediated coherence judgment." That
over-states a necessity. ADR-0021 §3 only requires promotion be a function of
coherence with the reviewed field. For claims *deductively entailed* by
already-COHERENT facts, the entailment proof IS that coherence judgment and can
be machine-certified by the sound deductive_logic_v1 engine — the logical arm of
the "structural coherence metric" ADR-0021's v2 gap already names.
- position_paper.md §3.4: split "own asserted output" (no standing — kept) from
"deductively entailed from COHERENT facts" (proof = coherence judgment);
relocate review to the *reading*, not the deduction; flag the proof-carrying
path as specified-but-unwired with a link to the new issue.
- teaching/epistemic.py: the EpistemicStatus docstring claimed transitions are
"computed from coherence" — they are not; review_correction carries status as
a curator-supplied input. Docstring now states this honestly.
- docs/issues/proof-carrying-coherence-promotion.md: thorough spec for the
unbuilt capability (scope, the reading hazard, INV-21 impact, trust boundary,
falsification tests, phased plan, proposed ADR-0218).
No runtime behavior change. Green: test_epistemic_invariants,
test_epistemic_phase3_state_tagging, TestINV21OneMutationPath (15 passed).
Tool Authority Demo (#688) was still tagged 'draft PR / in review' but it
merged at c55f7dfb. Hybrid Verification Demo (#687) lacked the claims-authority
framing and the agreement-is-not-safety finding. Reposition both as merged
evidence, name the next public evidence target, and align epistemic-state vocab.
- #687 = authority over claims; #688 = authority over proposed tool actions.
- Removed stale 'In progress / draft PR / in review' status on #688.
- Added explicit next-target ordering: Epistemic Truth-State -> Embodied
Authority Simulation -> SaaS/On-Prem Boundary.
- No named-company, outreach, or production/robotics overclaims introduced.