The L10 heartbeat (chat/always_on, #747) holds CORE alive over uptime but had no
surface. This adds the read-only Lived Life route that renders the continuous-life
evidence: the heartbeat over uptime + the resume-as-same-life verdict — both halves
of "one continuous life" on one surface.
Persist-first, never recompute engine-owned values:
- chat/always_on: serialize_report + write_lived_life persist a run deterministically
(sorted keys) to engine_state/lived_life.json; run_continuous gains an opt-in
report_path so a real continuous-life run leaves its evidence where the workbench
reads it. closure_ceiling is persisted so the artifact is self-describing.
- workbench/lived_life.py: projection + a fail-closed validate() gate — the wrong=0
analogue for the continuity surface: closure_held/closure_observed/totals/converged
are each re-checked against the per-beat measurements, and resume_status is re-checked
against identity-vs-current-substrate, so a tampered artifact RAISES rather than
rendering a false claim (a beat lying about a breached ceiling, an inflated closure,
a miscounted total, a falsely-claimed resume).
- workbench/readers.lived_life(): reads the artifact, computes the resume verdict from
the persisted identity vs the canonical engine_identity_for_config (fail-soft ->
"unknown", like IdentityContinuity). Honest absence when no run has been persisted.
- GET /lived-life + LivedLife/LivedLifeHeartbeat schemas (snapshot regenerated; the
schema-drift gate proves every field is mirrored in src/types/api.ts).
The resume verdict made felt: would_resume / substrate_changed / unknown IS the L11
reboot guarantee (a reboot recomputes identity and refuses if it differs) — so the
surface shows this life wakes up as ITSELF, not a copy. The per-reboot lineage chain
stays owned by Runs > Identity (honest cross-link).
Frontend: /lived-life route (Evidence section, route count 15 -> 16). Renders the
headline (heartbeats, closure-held-by-construction, learned-while-idle, at-rest, resume
pill), the summary, the heartbeat timeline (closure flat below the ceiling — read, never
repaired), and the resume verdict. Honest absence + ADR-0162 route conformance
(loading/error/empty), fail-closed like Vault/Calibration.
Tests (non-vacuous): 12 backend (every tamper case raises; resume tracks identity vs
substrate; run_continuous(report_path) round-trips a readable+valid artifact) + 4
frontend render tests (recorded life renders; a breached beat shows the warning, never a
false "held"; a changed substrate shows would-refuse, never a false resume; absent shows
honest absence). All workbench Python (167) + affected vitest (167) + tsc + vite build
green; architectural invariants green.
engine_state/lived_life.json is runtime state (gitignored, ADR-0146 pattern).
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
First Wave M / Phase B piece (GATING): read-only backend that makes the
calibrated-learning / serving-discipline loop inspectable — 'the engine
earns the right to guess', ADR-0175.
The workbench computes NONE of these numbers:
- GET /calibration/classes — per-class gold-tether view from the persisted
practice arena ledger (evals/gsm8k_math/practice/v1/report.json per_class).
Each class's reliability_floor is the engine's own one-sided Wilson
conservative_floor (via ClassTally.reliability); PROPOSE (θ=0.85) / SERVE
(θ=0.99) license verdicts come from core.reliability_gate.license_for.
Failures-first ordering. A test proves the reader's floor equals a direct
conservative_floor() call — no re-implementation.
- GET /serving/metrics — the live correct/refused/wrong counts read unchanged
from the committed train_sample + holdout_dev report.json (currently
4/46/0 and 5/495/0 — wrong=0). Never re-runs a lane.
Honest current state: the committed practice ledger's three classes
(additive/divisive/multiplicative) are all below N_MIN=10, so none has
earned a license yet — the reader shows exactly that, no fake green light.
- workbench/calibration.py: pure readers; imports core.reliability_gate;
EvidenceUnavailableError -> 501 (fail-closed) when the artifact is absent.
- schemas + TS mirrors (CalibrationClass, ServingMetrics); both snapshots
regenerated (deterministic); both drift gates pass.
- trust boundary: read-only over committed artifacts + engine-owned
derivation; no execution, no mutation, no license ever changed.
Verified: 30 Python tests (incl. the no-reimplementation proof + fail-closed),
390 vitest, both schema drift gates, snapshots deterministic.
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
- EvidenceChainRail: the spine's seven stages rendered per subject with
the honesty contract — lit/hollow/dim derive ONLY from carried fields
(a trace hash lights 'replay' as RECORDED, never as verified); pure
deriveStages() with meaningfully-fail tests (remove one field -> exactly
its stage hollows).
- Hash display standard: DigestBadge default 12-char + copy everywhere;
CopyableHash consolidated away (2 call sites swapped, file deleted).
- Typography: tabular-nums on MetadataTable values + eval metrics;
text-wrap balance on Panel titles + EmptyState statements.
- Selection unification: new --color-selected-bg/-border tokens; selected
(persistent) vs focused (transient) now visually distinct across
Proposals/Replay/Evals lists; focus-ring no longer doubles as selection.
- EmptyState gains a deterministic monochrome inline-SVG glyph.
- Panel adopted in Evals lane list + Proposals queue.
- Doctrine-as-tests: hexScan (no palette literals outside tokens.css/
generated tokens.ts) + schemaDrift gate (scripts/dump-schemas.py AST
walk -> schema-snapshot.json -> every dataclass field mirrored in
types/api.ts; explicit shrink-only NOT_YET_MIRRORED debt list).
The drift gate caught real drift on first run: ChatTurnResult.turn_id
existed in Python, missing from TS — now mirrored.
Verified: build green; vitest 36 files / 279 tests EXIT=0; playwright
12/12; dump-schemas.py runs clean.