From 0dcdfab6d2ccef0b8e65c6494c6ea2ae2c157da1 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 25 Apr 2026 15:41:23 +0100 Subject: [PATCH] Mark Phase 5 complete enough --- AGENTS.md | 1 + notes/epiphany-current-algorithmic-map.md | 4 ++- notes/epiphany-fork-implementation-plan.md | 27 ++++++++-------- notes/fresh-workspace-handoff.md | 37 +++++++++++----------- state/evidence.jsonl | 1 + state/map.yaml | 11 ++++--- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ef682e83..5b357ca5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -80,3 +80,4 @@ Do not wait for the blackout and then act surprised. - Keep maps and prose together; do not replace useful maps with prose-only explanations. - Before adding natural-language explanations or metaphors to an algorithmic map, first read the relevant source paths and anchor the explanation to concrete code references. Metaphor is compression after source grounding, not a substitute for it. - Before handoff, compaction, or phase boundaries, sync `state/map.yaml`, append `state/evidence.jsonl`, refresh `notes/fresh-workspace-handoff.md`, and make the next action explicit. +- Do not write handoff notes that trap the next session in indefinite tiny hardening work. Bounded slices are a landing discipline, not a roadmap; when a phase is complete enough, name the next larger organ to build. diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index 010558c3..784b9647 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -110,7 +110,9 @@ Source audit on 2026-04-25 re-read each flow below against the cited code instea The current landed machine is still coherent. The core shape is not ornamental: one protocol state object flows through session state, prompt rendering, rollout persistence, thread hydration, explicit retrieval/indexing, read-only distillation/proposal, verifier-backed promotion, the single durable update writer, and now a live state notification that reflects completed writes. The useful simplification pressure is already present in the boundaries: retrieval reads, indexing writes only the semantic catalog, distillation/proposal draft patches, promotion gates, update persists, and notification broadcasts only after the write is done. -Nothing in the current typed spine obviously deserves deletion right now. The parts that would turn this into Jenga are still correctly listed as non-flows: automatic tool-output ingestion, watcher invalidation, GUI reflection, specialist scheduling, broad event streaming, and an automatic Compact-Rehydrate-Reorient-Continue coordinator. The next Perfect Machine move is therefore not adding another writer or a shiny surface. After match-kind-aware map-delta judgment, source-output-aware distillation, first risky-delta promotion policy, a richer app-server smoke harness, and the first state-update notification, the next pressure belongs in running that harness as a guardrail and adding only the smallest source-grounded notification/read/proposal/promotion rule real use exposes. +Nothing in the current typed spine obviously deserves deletion right now. The parts that would turn this into Jenga are still correctly listed as non-flows: automatic tool-output ingestion, watcher invalidation, specialist scheduling, broad event streaming, and an automatic Compact-Rehydrate-Reorient-Continue coordinator. Thin GUI/client reflection is no longer forbidden as a category, provided it reflects and steers typed state rather than inventing a second source of truth. + +The next Perfect Machine move is not adding another writer, and it is no longer another generic scrape of notification/read/proposal/promotion hardening. That wording turned into a loop hazard: after a phase is coherent, "one more smallest safety slice" can become a polite way to rearrange the furniture forever. The Phase 5 smoke harness should guard the existing control plane against regressions. The next organ should move outward toward a Phase 6 reflection/scene-surface or job-state precursor that lets clients inspect the machine Epiphany already built. ## Natural Language Spine diff --git a/notes/epiphany-fork-implementation-plan.md b/notes/epiphany-fork-implementation-plan.md index 5ebf6a62..5fbe0f2e 100644 --- a/notes/epiphany-fork-implementation-plan.md +++ b/notes/epiphany-fork-implementation-plan.md @@ -2,7 +2,7 @@ ## Status -Updated on 2026-04-25 after hardening successful update/promote responses and `thread/epiphany/stateUpdated` notifications to publish the same client-visible live Epiphany state projection as `thread/read`, including retrieval-summary backfill. +Updated on 2026-04-25 after recognizing that Phase 5 is complete enough to stop feeding itself tiny safety slices. The update/distill/propose/promote/read/notification control plane is now the regression-guarded baseline, not an excuse to keep rearranging the furniture until everyone dies of responsible boredom. This note tracks Epiphany as a fork of Codex with an opinionated modeling architecture. The point is not to offer Codex another collaboration preset. The point is to make the harness force the model to carry explicit structure about the codebase, the active subgoal, the evidence trail, and the machine it is modifying. @@ -33,9 +33,13 @@ This note tracks Epiphany as a fork of Codex with an opinionated modeling archit - a rejected-promotion silence smoke hardening slice: the reusable Phase 5 app-server smoke now asserts rejected `thread/epiphany/promote` calls do not emit `thread/epiphany/stateUpdated`, preserving the "no mutation, no bell" contract - a direct-update integrity hardening slice: `thread/epiphany/update` now validates appended observation/evidence graph records and structural replacement fields before mutation, rejects empty/duplicate/reused append ids, missing evidence references, and invalid graph/frontier/checkpoint/subgoal/churn replacement shapes, and the reusable smoke asserts invalid direct updates leave revision unchanged with no `thread/epiphany/stateUpdated` notification - a write/read surface consistency hardening slice: successful direct update and accepted promote responses plus their `thread/epiphany/stateUpdated` notifications now reuse the same live Epiphany state projection as `thread/read`, so clients get retrieval-summary backfill consistently instead of receiving a raw just-written state in one surface and a richer read state in another -- current phase: post-Phase-5 live typed state/read-surface hardening +- current phase: Phase 6 reflection boundary / scene-surface precursor -The next job is no longer to prove the retriever exists, sketch the persistent follow-up in prose, invent the first red-pen path, build the first observation proposal surface, make promotion notice broken map/churn replacements, ship the first read-only map/churn proposal surface, teach proposal to avoid duplicating already-mapped code surfaces, make proposal frontier focus follow existing graph links, make selected observations evidence-backed with non-haunted churn pressure, rescue unanchored graph nodes with strict semantic matching, let proposal choose a bounded ready observation set when ids are omitted, make proposal pressure understand match kinds, make the distiller summarize noisy source output, make source-output salience prefer final results over generic warnings, make promotion notice risky deltas, make expansion freshness resistant to low-pressure underreporting, prevent substring verifier-kind accidents, prove that richer chain over app-server by hand, add the first live state notification after successful writes, or make that notification say which revision and state sections changed. Those parts are landed or live-smoked. The next job is to use the reusable smoke harness as a guardrail before adding the next smallest source-grounded notification/read/proposal/promotion rule, and to keep `thread/epiphany/retrieve`, `thread/epiphany/distill`, and `thread/epiphany/propose` out of the durable-writer business. +The next job is no longer to prove the retriever exists, sketch the persistent follow-up in prose, invent the first red-pen path, build the first observation proposal surface, make promotion notice broken map/churn replacements, ship the first read-only map/churn proposal surface, teach proposal to avoid duplicating already-mapped code surfaces, make proposal frontier focus follow existing graph links, make selected observations evidence-backed with non-haunted churn pressure, rescue unanchored graph nodes with strict semantic matching, let proposal choose a bounded ready observation set when ids are omitted, make proposal pressure understand match kinds, make the distiller summarize noisy source output, make source-output salience prefer final results over generic warnings, make promotion notice risky deltas, make expansion freshness resistant to low-pressure underreporting, prevent substring verifier-kind accidents, prove that richer chain over app-server by hand, add the first live state notification after successful writes, make that notification say which revision and state sections changed, reject malformed direct updates, or make write responses match `thread/read` projection. Those parts are landed or live-smoked. + +The next job is to move one layer outward: design and land a meaningful Phase 6 reflection/scene-surface or job-state precursor that lets a client inspect and steer the typed Epiphany machine without making the GUI/client the source of truth. Use `tools/epiphany_phase5_smoke.py` as a regression guardrail when touching the Phase 5 control plane, not as a ritual that justifies another tiny safety slice. + +Workflow trap to avoid: do not leave handoff or plan notes that say only "continue the next smallest hardening slice" after a phase has reached a coherent baseline. Bounded slices are how work lands safely; they are not the project direction. A good handoff should name the next organ, not merely prescribe one more scrape of sandpaper on the same seam. ## Summary @@ -312,14 +316,11 @@ Treat the current retrieval baseline and explicit indexing follow-up as landed P 2. treat the verified and live-smoked `thread/epiphany/index` slice as the bounded persistent-semantic follow-up 3. keep the new `epiphany-core` boundary honest instead of letting vendored Codex re-accumulate the heavy implementation 4. do not add durable retrieval-summary writes from `thread/epiphany/retrieve` without a clean out-of-band rollout/update semantic -5. continue post-Phase-5 live typed state/read-surface hardening above the landed distill/propose/promote/update surfaces: - - better proposal heuristics beyond the current exact-code-ref, same-path, deterministic-id, graph-link, accepting-evidence, semantic-unanchored-node, selected-priority, auto-selection, and match-kind-aware map-delta-pressure checks - - run `tools/epiphany_phase5_smoke.py` as a preflight before changing proposal or promotion policy - - add the next smallest notification/read/proposal/promotion rule only after a source-grounded gap appears in real use or smoke output - - verifier-backed acceptance/rejection evidence - - no hidden retrieval writes - - not GUI work - - not watcher-driven invalidation - - not specialist-agent scheduling +5. declare Phase 5 complete enough unless a concrete bug, regression, or real-use gap appears +6. use the Phase 5 smoke as a guardrail before modifying the existing control plane, not as a reason to keep sanding that same control plane forever +7. choose the next meaningful Phase 6 precursor: + - a typed scene/read model for graph, invariants, evidence, intent, churn, and retrieval status, derived from existing Epiphany state + - or a minimal typed job-state/progress surface for indexing/remap/verification work that a future GUI can render +8. keep the source-of-truth rule intact: GUI/client surfaces reflect and steer typed state, but they do not manufacture canonical understanding -Do not start with GUI. Do not start with automatic graph invalidation. Do not pretend shell transcripts are a retrieval strategy. +Do not start with automatic graph invalidation or specialist-agent scheduling. Do not pretend shell transcripts are a retrieval strategy. GUI reflection is no longer forbidden as a category, but it must start as a thin reflection over the engine, not as a pretty parallel brain. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index d283fbe4..1bad91ef 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -64,9 +64,9 @@ Rehydrate: Reorient: -- current pushed HEAD before this packet was written: `37457d6 Record compact continuity after state projection` +- current pushed HEAD before this packet was written: `10465e1 Persist imminent CRRC reentry packet` - branch should be `main...origin/main` and clean unless a later slice changed it -- current active lane is still post-Phase-5 live typed-state/read-surface hardening +- current active lane has moved from indefinite post-Phase-5 hardening to the Phase 6 reflection boundary - latest landed implementation slice: successful `thread/epiphany/update` and accepted `thread/epiphany/promote` responses/notifications now publish the same client-visible live-state projection as `thread/read`, including retrieval-summary backfill - latest verification slice: richer Phase 5 smoke observed retrieval status `ready` on update/promote responses and notifications, with rejected promotions and invalid direct updates still silent/non-mutating - `thread/epiphany/retrieve`, `thread/epiphany/distill`, and `thread/epiphany/propose` remain read-only @@ -75,9 +75,10 @@ Reorient: Continue: -- do not start GUI, watcher invalidation, specialist-agent scheduling, or broad event-stream work -- use `tools/epiphany_phase5_smoke.py` as the app-server seam guardrail before changing proposal/promotion/write/read behavior -- choose the next smallest source-grounded live typed-state/read-surface hardening slice above the landed update/promote/read seam +- do not restart Phase 5 just because the handoff says to be careful; the update/distill/propose/promote/read/notification seam is complete enough unless a concrete regression appears +- use `tools/epiphany_phase5_smoke.py` as the app-server seam guardrail before changing proposal/promotion/write/read behavior, not as a ritual for generating more tiny safety work +- pick a meaningful Phase 6 reflection/scene-surface or job-state precursor that exposes the existing typed Epiphany machine without making GUI/client state authoritative +- avoid handoff notes that only say "next smallest hardening slice"; they can trap the next agent in furniture-rearrangement mode - before natural-language algorithm-map edits, reread the exact source being described - if a regression or benchmark fix attempt does not move the target, immediately revert that attempt before trying the next hypothesis @@ -510,33 +511,31 @@ Do not restart verification from superstition. Phase 4 retrieval/indexing/core-e The durable state seam exists, the turn loop reads it, clients can load typed Epiphany state directly, successful writes now publish a live typed `thread/epiphany/stateUpdated` notification, the first retrieval slice is real, the explicit persistent-semantic indexing path is landed, the distill/propose/promote/update path is live-smoked, promotion now has a first structural map/churn safety layer and risky-delta policy with token-aware verifier-kind matching, distillation summarizes noisy source output into typed evidence, and proposal now reuses existing architecture nodes before creating new path nodes, expands frontier focus through linked graph context, rejects selected observations without accepting recent evidence, prioritizes stronger selected observations for proposal wording, can reuse unanchored architecture nodes through strict semantic overlap, can auto-select a bounded evidence-backed observation cluster when ids are omitted, and reports match-kind-aware churn pressure from the proposal shape. The richer Phase 5 chain has now been smoke-tested through app-server and captured as a reusable tool instead of a one-off ritual. -Current Phase 5 implementation move: +Phase transition rule: -1. treat the live-smoked retrieval/indexing baseline as Phase 4 and the typed update/distill/propose/promote surfaces as the active Phase 5 baseline +1. treat the live-smoked retrieval/indexing baseline as Phase 4 and the typed update/distill/propose/promote/read/notification control plane as the complete-enough Phase 5 baseline 2. keep the current env/default Qdrant/Ollama config surface for now 3. keep `thread/epiphany/retrieve`, `thread/epiphany/distill`, and `thread/epiphany/propose` read-only -4. continue the next bounded live typed-state/read-surface slice above the distill/propose/promote/update surfaces: - - run `tools/epiphany_phase5_smoke.py` before changing proposal or promotion policy - - add the next smallest notification/read/proposal/promotion rule only after a source-grounded gap appears in real use or smoke output - - verifier-backed acceptance/rejection evidence - - no GUI, watcher, or specialist-agent machinery yet +4. run `tools/epiphany_phase5_smoke.py` before changing proposal, promotion, update, read, or notification behavior +5. do not keep adding tiny Phase 5 hardening rules merely because the harness can; if there is no concrete bug or real-use gap, move outward +6. start the next meaningful Phase 6 precursor: a typed reflection/scene surface or job-state/progress surface that lets clients inspect and steer existing Epiphany state without becoming the source of truth ## What Not To Do Next Not yet: -- GUI work - watcher-driven semantic invalidation - automatic observation promotion - specialist-agent scheduling - user-facing activation flows -The next slice should stay small and mean: +Do not let caution write the roadmap by accident: -- harden the explicit state-update path with a live app-server smoke when useful -- harden distillation/proposal only through explicit promotion checks, not hidden writes -- use `tools/epiphany_phase5_smoke.py` as the current app-server seam guardrail -- keep GUI, watcher mutation, and specialist-agent logic dark +- no more generic "next smallest hardening slice" handoffs without naming the larger organ being advanced +- no more Phase 5 furniture rearrangement unless a concrete failing smoke, bug, or real-use gap demands it +- no GUI-as-source-of-truth work +- no broad watcher mutation or specialist-agent logic yet +- GUI/reflection work is allowed only as a thin view/control surface over already-authoritative typed state ## Verification Commands @@ -559,4 +558,4 @@ cmd /c "\"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxi The repo is in a good state. -Phase 1, Phase 2, the minimal Phase 3 typed read surface, Phase 4 retrieval/indexing/core-extraction, and the current Phase 5 distill/propose/promote/update baseline are landed and verified. `vendor/codex` is first-class in the parent repo now, with the heavier Epiphany organs living in `epiphany-core`. Successful direct updates and accepted promotions now return response-level revision/changed-field metadata and emit experimental `thread/epiphany/stateUpdated` notifications carrying the updated client-visible typed state, source labels, event-level revision, and typed changed fields; accepted promotion responses/notifications include `evidence` whenever verifier evidence is appended, even when patch evidence was empty, and successful write response/notification states include the same retrieval-summary backfill exposed by live `thread/read`. Direct updates now reject malformed appended observations/evidence and structurally invalid replacement fields before mutation, including missing evidence references, duplicate append ids, durable id reuse, and impossible graph frontier/checkpoint/subgoal/churn shapes. Read-only distillation now summarizes noisy tool/model output into typed evidence and ranks final result/error/finished lines above generic warnings, read-only proposal can auto-select a bounded evidence-backed observation cluster and report match-kind-aware map-delta pressure, promotion rejects risky deltas without warning plus strong verifier evidence, expansion freshness cannot bypass warning requirements by claiming low pressure, and verifier kinds are token-matched so `contest` does not pass as `test`. The current Epiphany algorithmic map has been source-audited against the code flow it describes. The richer Phase 5 chain is now live-smoked through app-server by `tools/epiphany_phase5_smoke.py`, including update response/notification revision/changed-fields `1`/`observations,evidence` with retrieval-summary presence, verifier-only accepted promotion response/notification changed-fields `2`/`observations,evidence` with retrieval-summary presence, invalid direct observation/evidence update rejection with `invalidDirectUpdateNotificationCount: 0` and unchanged revision `2`, invalid direct replacement update rejection with `invalidReplacementUpdateNotificationCount: 0` and unchanged revision `2`, expanded-low-pressure and substring-verifier rejection checks, explicit rejected-promotion notification silence with `rejectedPromotionNotificationCount: 0`, accepted graph/churn promotion, and promote response/notification revision/changed-fields `3`/`graphs,graphFrontier,observations,evidence,churn` with retrieval-summary presence. The next clean move is the next bounded live typed-state/read-surface hardening slice, with that smoke harness as a guardrail; not GUI paint, watcher magic, or re-proving retrieval. Pre-compaction persistence is now an explicit design rule, not a lucky habit. +Phase 1, Phase 2, the minimal Phase 3 typed read surface, Phase 4 retrieval/indexing/core-extraction, and the Phase 5 distill/propose/promote/update/read/notification control plane are landed and verified enough to move on. `vendor/codex` is first-class in the parent repo now, with the heavier Epiphany organs living in `epiphany-core`. Successful direct updates and accepted promotions now return response-level revision/changed-field metadata and emit experimental `thread/epiphany/stateUpdated` notifications carrying the updated client-visible typed state, source labels, event-level revision, and typed changed fields; accepted promotion responses/notifications include `evidence` whenever verifier evidence is appended, even when patch evidence was empty, and successful write response/notification states include the same retrieval-summary backfill exposed by live `thread/read`. Direct updates reject malformed appended observations/evidence and structurally invalid replacement fields before mutation. Read-only distillation summarizes noisy tool/model output into typed evidence, read-only proposal can auto-select a bounded evidence-backed observation cluster and report match-kind-aware map-delta pressure, and promotion rejects risky deltas without warning plus strong verifier evidence. The current Epiphany algorithmic map has been source-audited against the code flow it describes. The richer Phase 5 chain is live-smoked through app-server by `tools/epiphany_phase5_smoke.py`. The next clean move is no longer "one more tiny safety slice"; it is a meaningful Phase 6 reflection/scene-surface or job-state precursor over the existing typed machine. Pre-compaction persistence is now an explicit design rule, but persistence notes must name the next organ instead of trapping the agent in endless incremental hardening. diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 04f23d35..8ff1f4dd 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -155,3 +155,4 @@ {"ts": "2026-04-25T13:51:17+00:00", "type": "verification", "status": "ok", "note": "Verified write/read state projection consistency slice with py_compile tools/epiphany_phase5_smoke.py, cargo fmt -p codex-app-server, git diff --check, cargo test -p codex-app-server --lib map_epiphany_, cargo test -p codex-app-server --lib epiphany_promote_changed_fields_reports_appended_verifier_evidence, cargo build -p codex-app-server, and tools/epiphany_phase5_smoke.py. Smoke observed retrieval status ready on update/promote responses and notifications."} {"ts": "2026-04-25T14:12:11+00:00", "type": "verification", "status": "ok", "note": "Verified Compact-Rehydrate-Reorient-Continue continuity after write/read state projection slice. Branch main is clean/synced at ed7c916 before this evidence checkpoint; state/map.yaml, fresh-workspace-handoff, Epiphany algorithmic map, implementation plan, git log, and evidence tail agree that CRRC remains an explicit architecture primitive while automatic runtime CRRC coordination remains a documented non-flow. Next action remains the next bounded live typed-state/read-surface hardening slice with retrieve/distill/propose read-only and accepted writes routed through update/promote."} {"ts": "2026-04-25T14:16:03+00:00", "type": "verification", "status": "ok", "note": "Corrected CRRC continuity planning for imminent compaction: persisted an explicit rehydrate/reorient/continue packet in fresh-workspace-handoff.md with current HEAD, required rehydrate reads/commands, active lane, latest landed write/read projection slice, read-only boundaries, forbidden detours, smoke guardrail, source-grounded map rule, and anti-cruft revert rule."} +{"ts": "2026-04-25T14:41:00+00:00", "type": "decision", "status": "ok", "note": "Corrected repo memory to mark Phase 5 complete enough and prevent self-reinforcing tiny-hardening loops. Updated canonical map, handoff, implementation plan, algorithmic map, and AGENTS operating discipline so future CRRC handoffs name the next larger organ instead of prescribing endless smallest safety slices."} diff --git a/state/map.yaml b/state/map.yaml index c779683f..e1d3d082 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -1,7 +1,7 @@ experiment: name: EpiphanyAgent status: scaffolded - phase: live_typed_state_stream + phase: phase_6_reflection_boundary premise: > Test whether separating map, scratch, and output reduces architectural drift for coding tasks when using a strong general model. @@ -46,10 +46,10 @@ data_flow: - commit or backtrack active_subgoals: - - Keep the Phase 5 distill/propose/promote/update work and first live state notification seam aligned with reality in code and repo memory. + - Treat the Phase 5 distill/propose/promote/update control plane as complete enough unless a concrete regression appears. - Keep vendored Codex as a thin typed host seam while Epiphany-owned prompt and retrieval/indexing logic live in the repo-owned `epiphany-core` crate. - Preserve exact/path lookup and BM25 fallback while the Qdrant path stays explicit and bounded. - - Continue post-Phase-5 live typed state/read-surface hardening while keeping retrieval/distill/propose read-only and accepted writes routed through promotion/update. + - Move toward the next meaningful architecture organ: a Phase 6 reflection/scene surface or job-state precursor that lets clients inspect the typed Epiphany machine without turning the GUI into the source of truth. accepted_design: - external typed state files @@ -114,6 +114,7 @@ accepted_design: - harden rejected-promotion notification silence: the richer Phase 5 app-server smoke now asserts rejected `thread/epiphany/promote` calls do not emit `thread/epiphany/stateUpdated` - harden direct update integrity: `thread/epiphany/update` now rejects malformed appended observations/evidence and structurally invalid replacement fields before durable persistence, including empty append record fields, duplicate append ids, durable id reuse, observations that cite missing evidence ids, and graph/frontier/checkpoint/subgoal/churn replacement shape errors; invalid direct updates leave revision unchanged and emit no state update notification - harden write/read surface consistency: successful direct update and accepted promote responses plus `thread/epiphany/stateUpdated` notifications now publish the same client-visible live Epiphany state projection as `thread/read`, including the non-durable retrieval summary backfill when state exists without persisted retrieval metadata + - avoid self-reinforcing handoff notes that keep prescribing tiny safety-hardening slices after a phase has become complete enough; bounded slices are a way to land work safely, not a reason to orbit the same seam forever rejected_paths: - name: pinned_map_only @@ -130,5 +131,5 @@ rejected_paths: reason: audited candidates were either terminal-only, stale/aspirational, or incoherent wrappers; the comparison clones were removed from vendor to avoid building on untrusted drift current_status: - summary: Workspace initialized with protocol files, typed state, handoff notes, architecture maps, and a rolling implementation plan against vendored Codex. Phase 1 durable state, Phase 2 prompt integration, the minimal Phase 3 typed read surface, and Phase 4 retrieval/indexing/core-extraction are landed on `main`. Phase 5 semantic distillation/promotion/proposal is now active and chewed enough for the first live typed-state stream seam: the current baseline includes explicit Qdrant indexing with BM25 fallback, typed `thread/epiphany/update`, read-only `thread/epiphany/distill`, read-only `thread/epiphany/propose`, verifier-backed `thread/epiphany/promote`, response-level `revision` and `changedFields` on successful direct updates and accepted promotions, experimental `thread/epiphany/stateUpdated` notifications after successful direct updates and accepted promotions with typed `source` values of `update` or `promote`, event-level `revision`, typed `changedFields`, client-visible write response/notification state projection aligned with `thread/read` retrieval-summary backfill, structural map/churn promotion validation, direct-update observation/evidence integrity validation, direct-update structural replacement validation, source-output-aware distillation with result/error/finished lines prioritized over generic warnings, graph-node reuse, linked frontier focus, evidence-backed proposal selection, selected-observation prioritization, strict unanchored-node semantic reuse, automatic bounded observation selection, match-kind-aware map-delta churn pressure, risky-delta promotion policy in `epiphany-core`, expansion-freshness promotion hardening so new map surfaces cannot bypass warning requirements by claiming low pressure, token-aware verifier-kind matching so substring accidents cannot satisfy strong verifier evidence, a reusable richer Phase 5 app-server smoke harness, and thin vendored Codex host seams. Promotion responses and notifications now include `evidence` in `changedFields` whenever accepted promotion appends verifier evidence, even if the patch evidence list was empty. The richer smoke now verifies source-output distillation, read-only proposal, update response/notification revision/changed-fields `1`/`observations,evidence`, update response/notification retrieval-summary presence, verifier-only accepted promotion response/notification `2`/`observations,evidence` with retrieval-summary presence, invalid direct observation/evidence update rejection with `invalidDirectUpdateNotificationCount: 0` and unchanged revision `2`, invalid direct replacement update rejection with `invalidReplacementUpdateNotificationCount: 0` and unchanged revision `2`, risky-delta rejection, expanded-low-pressure rejection, weak-verifier rejection, substring-verifier rejection, rejected-promotion notification silence with `rejectedPromotionNotificationCount: 0`, accepted graph/churn promotion, and graph/churn promote response/notification revision/changed-fields `3`/`graphs,graphFrontier,observations,evidence,churn` with retrieval-summary presence through the app-server seam. The Windows app-server stack-pressure regression was narrowed to test-thread stack size; repo-local Cargo config sets `RUST_MIN_STACK=67108864`, and boxed-future request-dispatch experiments were removed after config-only verification passed. The repo also has source-available/commercial licensing plus a CLA gate for external contributions. - next_action: Continue the next bounded live typed-state/read-surface hardening slice from the now-notified update/promote seam; keep retrieval/distillation/proposal read-only, keep accepted writes routed through promotion/update, and avoid GUI, watcher, or specialist-agent machinery. + summary: Workspace initialized with protocol files, typed state, handoff notes, architecture maps, and a rolling implementation plan against vendored Codex. Phase 1 durable state, Phase 2 prompt integration, the minimal Phase 3 typed read surface, Phase 4 retrieval/indexing/core-extraction, and the Phase 5 update/distill/propose/promote/read/notification control plane are landed on `main` and complete enough to move on. The current baseline includes explicit Qdrant indexing with BM25 fallback, typed `thread/epiphany/update`, read-only `thread/epiphany/distill`, read-only `thread/epiphany/propose`, verifier-backed `thread/epiphany/promote`, response-level and notification-level revision/changed-field metadata, client-visible write/read projection consistency with retrieval-summary backfill, direct-update append/replacement validation, source-output-aware distillation, graph-aware proposal selection, risky-delta promotion policy, token-aware verifier-kind matching, and the reusable richer Phase 5 app-server smoke harness. Treat that smoke harness as a regression guardrail, not a prompt to invent another tiny safety slice. The next lane is Phase 6 reflection boundary work: expose the existing typed Epiphany machine through a thin scene/job-state surface without making GUI/client state authoritative. + next_action: Stop treating Phase 5 as an endless hardening lane. Treat the typed update/distill/propose/promote/read/notification control plane as complete enough, run the Phase 5 smoke only as a regression guardrail, and pick a meaningful Phase 6 reflection/scene-surface or job-state precursor that exposes the existing typed machine without making GUI/client state authoritative.