From 713247187022b843c2e4e670c154e20e70648c9e Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 14 Sep 2026 23:06:34 +0200 Subject: [PATCH 001/174] Describe Epiphany as backend-agnostic Codex, Claude and OpenAI-compatible APIs reach Epiphany through connectors that share one standardized Epiphany-facing CultNet API, also used by Ghostlight. Codex is one connector backend, not Epiphany's body. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 5 ++++- state/map.yaml | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6db3f50a..ac980edc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,10 @@ ## Project Purpose -This repo is the forge-temple of Epiphany: an opinionated Codex fork where +This repo is the forge-temple of Epiphany: an opinionated agent harness, born +as a Codex fork and now backend-agnostic. Codex, Claude, and OpenAI-compatible +APIs speak to it through connectors that share one standardized +Epiphany-facing CultNet API, the same one Ghostlight uses. It is the harness where external typed state, explicit mental maps, bounded scratch work, verifier evidence, and anti-churn discipline are wired into the blessed harness instead of taped onto the chat transcript like a purity seal over a cracked reactor. diff --git a/state/map.yaml b/state/map.yaml index 38ab7b8f..1f3ddfd2 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -24,8 +24,8 @@ architecture: idunn: Owns source-change CI/CD observation, compilation, testing, release construction, deployment, and daemon survival. cultmesh: Projects typed state without becoming its owner. brokkr: Owns Unity editor inspection and actuation; Epiphany consumes its typed CultMesh/Eve capabilities and receipts. - model_provider: Owns explicit provider selection and exact provider lowering; the independent CodexConnector is the admitted non-production capstone credential and transport boundary with a distinct caller identity, while production Epiphany remains inactive on its historical OpenRouter configuration. - codex: Retained only where an OpenAI provider needs its earned authentication or transport capability. + model_provider: Owns explicit provider selection and exact provider lowering. Epiphany is backend-agnostic. Codex, Claude, and OpenAI-compatible APIs are reached through separate connectors, which share one standardized Epiphany-facing CultNet API that Ghostlight also consumes. Today the independent CodexConnector is the admitted non-production capstone credential and transport boundary, with a distinct caller identity. Production Epiphany remains inactive on its historical OpenRouter configuration. + codex: One connector backend among several. Epiphany's compiled body holds no Codex implementation or transport (evicted in 7a125d78 and ed7357a2); Codex auth and transport belong to CodexConnector. invariants: - Mind is the sole durable state-admission authority. From 81be7a2f39ead454ea9e63365b2a89deabb55ee8 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 15 Sep 2026 19:06:15 +0200 Subject: [PATCH 002/174] Record the Eureka pipeline state campaign target and ruling Operator ruling (2026-09-15): Epiphany owns the typed schemas and admission for pipeline state (findings, rulings, cut specs and reports, follow-ups). The Eureka Claude Code skill reaches that state through a per-session Rust stdio MCP server, built as an Epiphany package, over one user-level store. voidbot indexes a projection for semantic search. The campaign re-pins CultLib first, and Epiphany adopting Eureka's habits follows later. Co-Authored-By: Claude Opus 5 --- notes/eureka-pipeline-state-target.md | 136 ++++++++++++++++++++++++++ state/map.yaml | 1 + 2 files changed, 137 insertions(+) create mode 100644 notes/eureka-pipeline-state-target.md diff --git a/notes/eureka-pipeline-state-target.md b/notes/eureka-pipeline-state-target.md new file mode 100644 index 00000000..232122e0 --- /dev/null +++ b/notes/eureka-pipeline-state-target.md @@ -0,0 +1,136 @@ +# Eureka pipeline state: target + +Status: target (the ends). The means will live in +`notes/eureka-pipeline-state-cut.md`, written by Imagination. Operator rulings are +dated 2026-09-15. + +## Why + +Eureka is the Claude Code counterpart of this organism. It is a skill at +`~/.claude/skills/eureka` that runs the same faculties (Self, Imagination, +Hands, Soul, Mind Steward) over foundation changes. In its first campaign, the +Aetheria CultCache migration, the pipeline worked, but its findings lived in +prose: the cut map, subagent reports and memory files. Self re-read and +re-summarised that prose at every step. Stale claims survived until a steward +caught them. The postmortem needed a transcript crawl, and one operator quote +survived only in a compaction summary. + +Epiphany already has the other half: typed documents, admission and receipts. +Her own `notes/faculty-workflow-lessons-2026-09-04.md:146-176` proposes typed +forms of Eureka's habits (`Map`, `Spec`, `CutReport`, `Verdict`, rulings, a +landed-names digest), but none of them are built. + +This campaign builds them once, here, and gives Eureka agents access to them. + +## Operator rulings + +1. **Epiphany owns the schemas** for pipeline state. +2. **Searchable state serves agents first.** Self and new agents rehydrate from + it ("what rulings govern stores?", "what is still open?"). Soul and + Imagination check precedent in it ("have nil map keys bitten us?"). Operator + browsing across projects comes later. +3. **Query split.** Epiphany owns the typed store and exact, filtered queries. + voidbot owns semantic search, by indexing a projection of these documents as + one more Qdrant collection. The typed store is the truth and the index is + only a derived copy. +4. **Two campaigns.** This one covers the schemas, the store, admission, the + Eureka MCP server, and a proof on one real Eureka task. The second, Epiphany + adopting Eureka's habits, comes after the schema stops moving. It covers + ahead-of-time cut specs, adversarial Soul with mutations, rulings consumed + by Self, and steward triggers. +5. **MCP hosting.** A Rust stdio MCP server, built as an Epiphany package and + launched by Claude Code per session, so no daemon is added. It writes + through a newly public Epiphany admission path under organ provenance + (`eureka`), so Epiphany's rules decide what is admitted. +6. **One store.** A single user-level pipeline store, outside every repo and + separate from Epiphany's runtime and Mind stores, with its own epoch. +7. **Re-pin first.** Epiphany's CultLib pin (`e171eca3`) is 30 commits behind + `main` (`a0813c6`), from before one-home-store and atomic `push_all`. The + re-pin is the first cut. + +## End state + +- **Documents.** Epiphany defines typed CultCache documents for pipeline state: + - campaign + - target + - cut spec + - cut report + - finding (Soul, with CONFIRMED/PLAUSIBLE and HOLDS/FALSIFIED/UNPROVEN + decided by Imagination against the lessons doc) + - ruling, with supersession + - follow-up + - landed-names digest + + Imagination fixes the exact set and fields, and every one must have a live + Eureka consumer. Each document derives `DatabaseEntry`, has a stable schema + id and version, and a key strategy chosen for identity, not convenience. + Each is published in `schemas/cultnet/index.json` alongside `persona_state` + and `work_organ_state`. +- **Store.** The pipeline store lives at one user-level path. It is written + only through Epiphany's admission, with batch compare-and-swap and receipts. + It refuses foreign epochs, with no compatibility reader. +- **Admission.** A public admission entry point accepts organ provenance + (`eureka`) and applies per-document rules: + - A finding must name its commit range and evidence. + - A ruling supersedes by id, never by overwriting. + - A cut report must cite its cut spec. + + Refusals are typed. +- **MCP server** (`eureka-state`, name to be decided in the map). It is stdio + and speaks Rust `rmcp` in server mode. Its tools are: + - admit a document; + - read by id; + - filtered query (by campaign, repo, cut, kind, status, supersession, time); + - "open items" for a campaign; + - the rulings currently in force. + + Every write is an admission, so no tool writes to the store directly. It is + registered for Claude Code at user scope. +- **Semantic projection.** voidbot gains a collection that indexes a projection + of admitted pipeline documents. The typed store remains the only truth, and + the MCP server returns typed ids that voidbot hits resolve to. +- **Eureka.** The skill's briefs tell Self, Imagination, Hands and Soul to read + from and admit to this state instead of relaying prose. The cut map document + in the target repo becomes a rendering of typed cut specs, or is retired, as + Imagination decides. +- **Proof.** One real Eureka task runs end to end on the typed state: rulings + admitted, a cut spec, Hands' cut report, Soul findings, and the follow-ups + queried back. A fresh agent rehydrates from queries alone. + +## Invariants + +- **Mind admits.** Only Epiphany's admission writes the pipeline store. The MCP + server, voidbot and Eureka agents are clients or projections, never owners. +- **Typed, not prose.** No JSON store and no untyped blob fields where a typed + field exists. JSON appears only in published schemas. +- **No new daemon.** The MCP server is a per-session process. Anything + long-running must earn it by independent lifecycle, privilege, resource or + failure isolation. +- **One package per production entrypoint.** Build economy follows `AGENTS.md`: + focused single-package checks on the shared target dir, and no broad builds. +- **Stores stay separate.** The pipeline store's epoch never gates Epiphany's + runtime or Mind stores, and theirs never gate it. +- **Supersession, not deletion.** An old ruling or finding stays queryable as + superseded. +- **The skill defers to the schema.** The Eureka skill describes how to use the + state; the schema set and admission rules are owned here. + +## Not in scope + +- Epiphany's own organs consuming pipeline documents: the second campaign. +- Operator browsing surfaces (Eve/CultUI) over pipeline state. +- Migrating the Aetheria CultCache campaign's prose into typed documents. + Imagination may propose it as the proof task if it is cheaper than a new real + task. +- Cleanup of `.epiphany-run/` (105 GiB) and the repo-local `target/` (39 GiB): + the operator's call, tracked separately. +- CultNet over-the-wire compare-and-swap. The MCP server attaches the store + locally through `cultcache-rs`, which already has cross-process locking and + conditional commits. + +## Evidence + +- Substrate maps (scratch, 2026-09-15): Epiphany typed state and admission; the + MCP and client landscape. +- Dated comparison: `~/.claude/skills/eureka/references/epiphany-comparison-2026-09-15.md`. +- Campaign precedent: `F:\Projects\Aetheria\docs\cultcache-migration-postmortem.md`. diff --git a/state/map.yaml b/state/map.yaml index 1f3ddfd2..3b73de8b 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -258,6 +258,7 @@ current_status: runtime_event_cut: Exact 27fe11ae deletes persisted generic runtime events, their registry and CultNet contract, CLI/status surfaces, coordinator and lifecycle shadows, archival dependencies, and the obsolete legacy coordinator repair path. Exact d66baa27, 058751fb, and 573ddc8b first removed provider-event duplication, the arbitrary event writer, and paired lifecycle events. Runtime session/job state plus exact typed results, failures, coordinator run receipts, and coordinator death recoveries solely own terminal facts. Events cannot route work, authenticate terminality, or resurrect authority because no runtime-event document remains. active_subgoals: + - "Eureka pipeline state campaign (operator ruling 2026-09-15, branch codex/eureka-pipeline-state; ends in notes/eureka-pipeline-state-target.md). Epiphany owns typed schemas and admission for pipeline state: findings, rulings, cut specs and reports, follow-ups. The Eureka Claude Code skill reaches that state through a per-session Rust stdio MCP server built as an Epiphany package, writing only through a public organ-provenance admission path. The state is one user-level store, separate from runtime and Mind. voidbot indexes a projection of it for semantic search; the typed store stays the truth. Epiphany adopting Eureka's habits is a second, later campaign. The first cut re-pins CultLib from e171eca3 to a0813c6. This campaign does not touch the Luna diagnosis, production, Atlas, or deployment." - Complete the fresh exact-package Decision-Auditable Concurrent Mind capstone before any further operational Gate run. - Prove the ordered Model Atlas Gate 1 with real isolated stores: establish signed sight before engaging all brakes, then prove frozen read-only state and no local Modeling or Soul wakes. - Prove Persona, Self, Eyes, Modeling, Imagination, Hands, Soul, Mind, Continuity, and nervous-system behavior individually. From 0d3f6bd65b43445659bed6322a16c58ab6cdc264 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 15 Sep 2026 19:24:10 +0200 Subject: [PATCH 003/174] Put the Eureka pipeline store in the repo where the task runs Operator ruling (2026-09-15), superseding the user-level store: each campaign's store is committed in the repo where the task runs, and knowledge crosses repos only through explicit sharing. Pushing the working branch syncs it to Yggdrasil, where voidbot's existing repo mirror indexes it. Co-Authored-By: Claude Opus 5 --- notes/eureka-pipeline-state-target.md | 35 +++++++++++++++++++++------ state/map.yaml | 2 +- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/notes/eureka-pipeline-state-target.md b/notes/eureka-pipeline-state-target.md index 232122e0..823c4195 100644 --- a/notes/eureka-pipeline-state-target.md +++ b/notes/eureka-pipeline-state-target.md @@ -42,8 +42,19 @@ This campaign builds them once, here, and gives Eureka agents access to them. launched by Claude Code per session, so no daemon is added. It writes through a newly public Epiphany admission path under organ provenance (`eureka`), so Epiphany's rules decide what is admitted. -6. **One store.** A single user-level pipeline store, outside every repo and - separate from Epiphany's runtime and Mind stores, with its own epoch. +6. **The store lives in the task's repo.** This replaces an earlier ruling from + the same day that put a single user-level store outside every repo. The + operator said: "have the pipeline store sit in the repo where the task takes + place. Each Epiphany learns for itself, with affordances for sharing + knowledge, same when running Eureka. Then the Eureka working branch can sync + with Yggdrasil". + - The pipeline store is committed in the repo where the campaign runs, on its + working branch, next to the target and cut documents. + - It is separate from Epiphany's runtime and Mind stores and has its own + epoch. + - Knowledge crosses repos only through explicit sharing. + - Pushing the branch is the sync, and voidbot's existing repo mirror indexes + it. 7. **Re-pin first.** Epiphany's CultLib pin (`e171eca3`) is 30 commits behind `main` (`a0813c6`), from before one-home-store and atomic `push_all`. The re-pin is the first cut. @@ -66,9 +77,15 @@ This campaign builds them once, here, and gives Eureka agents access to them. id and version, and a key strategy chosen for identity, not convenience. Each is published in `schemas/cultnet/index.json` alongside `persona_state` and `work_organ_state`. -- **Store.** The pipeline store lives at one user-level path. It is written - only through Epiphany's admission, with batch compare-and-swap and receipts. - It refuses foreign epochs, with no compatibility reader. +- **Store.** Each campaign's pipeline store sits at a fixed relative path in the + repo where the task runs, is committed on the campaign's working branch, and + is laid out so that parallel branches merge cleanly. The map decides the + layout. Epiphany's admission is the only writer, using batch compare-and-swap + with receipts. It refuses foreign epochs, with no compatibility reader. +- **Sharing.** Knowledge crosses repos only through explicit affordances, such + as a read-only foreign query or a citation carrying provenance, as the map + decides. A repo's store is written only by admissions made while working in + that repo. - **Admission.** A public admission entry point accepts organ provenance (`eureka`) and applies per-document rules: - A finding must name its commit range and evidence. @@ -86,9 +103,11 @@ This campaign builds them once, here, and gives Eureka agents access to them. Every write is an admission, so no tool writes to the store directly. It is registered for Claude Code at user scope. -- **Semantic projection.** voidbot gains a collection that indexes a projection - of admitted pipeline documents. The typed store remains the only truth, and - the MCP server returns typed ids that voidbot hits resolve to. +- **Semantic projection.** Pushing the working branch syncs the store with + Yggdrasil. voidbot's existing repo mirror finds pipeline stores in the repos + it already pulls and indexes a projection of their admitted documents as a new + collection. The typed store remains the only truth, and voidbot hits resolve to + typed ids in the owning repo's store. - **Eureka.** The skill's briefs tell Self, Imagination, Hands and Soul to read from and admit to this state instead of relaying prose. The cut map document in the target repo becomes a rendering of typed cut specs, or is retired, as diff --git a/state/map.yaml b/state/map.yaml index 3b73de8b..3d49cdd9 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -258,7 +258,7 @@ current_status: runtime_event_cut: Exact 27fe11ae deletes persisted generic runtime events, their registry and CultNet contract, CLI/status surfaces, coordinator and lifecycle shadows, archival dependencies, and the obsolete legacy coordinator repair path. Exact d66baa27, 058751fb, and 573ddc8b first removed provider-event duplication, the arbitrary event writer, and paired lifecycle events. Runtime session/job state plus exact typed results, failures, coordinator run receipts, and coordinator death recoveries solely own terminal facts. Events cannot route work, authenticate terminality, or resurrect authority because no runtime-event document remains. active_subgoals: - - "Eureka pipeline state campaign (operator ruling 2026-09-15, branch codex/eureka-pipeline-state; ends in notes/eureka-pipeline-state-target.md). Epiphany owns typed schemas and admission for pipeline state: findings, rulings, cut specs and reports, follow-ups. The Eureka Claude Code skill reaches that state through a per-session Rust stdio MCP server built as an Epiphany package, writing only through a public organ-provenance admission path. The state is one user-level store, separate from runtime and Mind. voidbot indexes a projection of it for semantic search; the typed store stays the truth. Epiphany adopting Eureka's habits is a second, later campaign. The first cut re-pins CultLib from e171eca3 to a0813c6. This campaign does not touch the Luna diagnosis, production, Atlas, or deployment." + - "Eureka pipeline state campaign (operator ruling 2026-09-15, branch codex/eureka-pipeline-state; ends in notes/eureka-pipeline-state-target.md). Epiphany owns typed schemas and admission for pipeline state: findings, rulings, cut specs and reports, follow-ups. The Eureka Claude Code skill reaches that state through a per-session Rust stdio MCP server built as an Epiphany package, writing only through a public organ-provenance admission path. Each campaign's store is committed in the repo where the task runs (operator ruling 2026-09-15, superseding a user-level store), separate from runtime and Mind. Knowledge crosses repos only through explicit sharing. Pushing the branch syncs with Yggdrasil, where voidbot's repo mirror indexes a projection for semantic search; the typed store stays the truth. Epiphany adopting Eureka's habits is a second, later campaign. The first cut re-pins CultLib from e171eca3 to a0813c6. This campaign does not touch the Luna diagnosis, production, Atlas, or deployment." - Complete the fresh exact-package Decision-Auditable Concurrent Mind capstone before any further operational Gate run. - Prove the ordered Model Atlas Gate 1 with real isolated stores: establish signed sight before engaging all brakes, then prove frozen read-only state and no local Modeling or Soul wakes. - Prove Persona, Self, Eyes, Modeling, Imagination, Hands, Soul, Mind, Continuity, and nervous-system behavior individually. From 0636176a0bbf0f9f611d46ece626257f47369fdc Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 15 Sep 2026 19:31:45 +0200 Subject: [PATCH 004/174] Require one runner per repo and a merge tool for pipeline stores Operator ruling (2026-09-15): only one Epiphany or Eureka may write a repo's pipeline store at a time, and a second concurrent writer is refused. A merge tool still reconciles divergent copies through admission, reporting true conflicts as typed refusals rather than letting the last writer win. Co-Authored-By: Claude Opus 5 --- notes/eureka-pipeline-state-target.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/notes/eureka-pipeline-state-target.md b/notes/eureka-pipeline-state-target.md index 823c4195..1635c818 100644 --- a/notes/eureka-pipeline-state-target.md +++ b/notes/eureka-pipeline-state-target.md @@ -82,6 +82,15 @@ This campaign builds them once, here, and gives Eureka agents access to them. is laid out so that parallel branches merge cleanly. The map decides the layout. Epiphany's admission is the only writer, using batch compare-and-swap with receipts. It refuses foreign epochs, with no compatibility reader. +- **One runner per repo.** Only one Epiphany or Eureka writes a repo's pipeline + store at a time. The operator put it as "There should only ever be one + Epiphany/Eureka running in any one repo. Nonetheless, we should have a merge + tool in case it ever happens." + - A second concurrent writer is refused with a typed refusal naming the + holder. The map chooses the mechanism. + - A merge tool reconciles two divergent copies through Epiphany's admission, + replaying admitted documents. It reports true conflicts as typed refusals + and never lets the last writer win. - **Sharing.** Knowledge crosses repos only through explicit affordances, such as a read-only foreign query or a citation carrying provenance, as the map decides. A repo's store is written only by admissions made while working in From f05686c137c6fe02160d049664ca2307eca818a8 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 15 Sep 2026 19:52:32 +0200 Subject: [PATCH 005/174] Map the Eureka pipeline state cuts Imagination's cut map, built from probes: 1. Re-pin CultLib: 12 load_envelope sites; core 154/154 at the new pin. 2. One profile-parameterized commit owner. 3. The pipeline document set, lease, admission, queries, and a merge command. 4. The eureka-state stdio MCP package. 5. Skill wiring. 6. A proof campaign on the CultRecordRefFormatter follow-ups. 7. voidbot projection. Five operator questions are open. The target now drops the claim that the store merges in git, and records that voidbot indexes only default branches. Co-Authored-By: Claude Opus 5 --- notes/eureka-pipeline-state-cut.md | 1265 +++++++++++++++++++++++++ notes/eureka-pipeline-state-target.md | 14 +- 2 files changed, 1273 insertions(+), 6 deletions(-) create mode 100644 notes/eureka-pipeline-state-cut.md diff --git a/notes/eureka-pipeline-state-cut.md b/notes/eureka-pipeline-state-cut.md new file mode 100644 index 00000000..dbd9f078 --- /dev/null +++ b/notes/eureka-pipeline-state-cut.md @@ -0,0 +1,1265 @@ +# Eureka pipeline state: cut map + +Date: 2026-09-15 (first Imagination pass). + +Status: cut map. The ends are owned by `notes/eureka-pipeline-state-target.md`; +this document owns the means. Self updates this header in every landing commit. +No cut has landed. + +Pins. Code anchors are `file:line` against Epiphany `81be7a2f`. HEAD has since +moved to `0636176a`, but only the target and `state/map.yaml` changed, so every +code anchor still holds. The other pins: + +- CultLib `main` `a0813c6`. +- VoidBot `main` `46d891b`. +- gamecult-ops `main` `647e57e`. +- The Eureka skill at `~/.claude/skills/eureka`, which is not a git repository. + +## Rulings in force (operator, 2026-09-15) + +1. Epiphany owns the schemas and admission. +2. The store serves agents first. Exact and filtered queries live in Epiphany; + voidbot indexes a projection for semantic search. The typed store is the truth. +3. There are two campaigns. This one covers schemas, store, admission, the MCP + server, the voidbot projection, the skill wiring, and a proof. Epiphany's own + organs consuming the documents belong to the second. +4. The MCP server is Rust, stdio, launched per Claude Code session, built as an + Epiphany package, and adds no daemon. It writes through a public admission + path under organ provenance `eureka`. +5. **The store lives in the repo where the task runs.** It is committed on the + campaign's working branch and is separate from the runtime and Mind stores, + with its own epoch. Knowledge crosses repos only through explicit sharing. The + operator's words: "have the pipeline store sit in the repo where the task + takes place. Each Epiphany learns for itself, with affordances for sharing + knowledge, same when running Eureka. Then the Eureka working branch can sync + with Yggdrasil". + (This supersedes the earlier same-day ruling of one user-level store. Nothing + below describes that design.) +6. **One runner per repo, plus a merge tool.** The operator's words: "There + should only ever be one Epiphany/Eureka running in any one repo. Nonetheless, + we should have a merge tool in case it ever happens." +7. Re-pin CultLib from `e171eca3` to `a0813c6` first. + +## Open operator questions + +Each question lists what depends on it. Hands can start Cuts 1 and 2 before any +answer. Cut 3a needs Q1 and Q5, Cut 3c needs Q3, Cut 3a's epoch text needs Q2, +and Cut 7 needs Q4. + +- **Q1. Store layout.** Candidates: + - **A.** One single-file `.cc` per repo, merged by an explicit admission-replay + command. + - **B.** Port C#'s v4 directory store to cultcache-rs. + - **C.** One single-file `.cc` per record, with receipts acting as batch + manifests. + + **Recommended: A.** Git never merges the bytes of a binary file, so every + divergent merge is forced through the merge command, which is Epiphany's + admission. B and C both let git silently union two branches' records around + admission. + - B also adds a CultLib foundation store with C# wire parity, and its manifest + is one hot file that conflicts on every divergent branch anyway + (`DirectoryMessagePackBackingStore.cs:15-18`, `WriteManifest` at `:287-295`). + - C loses batch atomicity: a multi-file batch cannot meet cultcache-rs's + atomic `push_all` contract (`lib.rs:307-336`). + - Probes, 300 documents of about 1 KB each, 30 commits, after + `git gc --aggressive`: + + | Layout | Pack size | + |---|---| + | single file | 20 KiB | + | per record | 46 KiB | + + The payload was highly compressible, so these are lower bounds. The per-record + layout merged disjoint branches cleanly, and a same-subject resolution raised + an add/add conflict. Single-writer (ruling 6) removes the case per-record was + built for. + - Depends on it: Cut 3a's store module, Cut 3c, and Cut 7's discovery path. +- **Q2. An older repo store meets a newer schema.** Candidates: + - **A.** Additive changes (new named fields carrying `#[serde(default)]`) keep + the epoch. A breaking change bumps it, and the new binary refuses the old + store for reads and writes with `ForeignEpoch`. The old store stays in git + history and remains readable by the binary tagged at its epoch. The operator + decides per repo whether to re-author live state. + - **B.** A breaking bump ships a one-release `pipeline-migrate` that + re-admits old documents through admission. + - **C.** A compatibility reader. + + **Recommended: A.** It keeps "no compatibility reader" (target, Store) and + Epiphany's no-migrator precedent (`state/map.yaml:118`, "No compatibility + reader, bootstrap aggregate, schema migrator, or dual reader survives"). + Nested values are named MessagePack maps, which tolerate added fields + (`cultcache-rs` `prepare_entry_named` docs, `lib.rs:2176-2180`). B is the + fallback if a live campaign ever straddles a breaking bump. + - Depends on it: Cut 3a's opener refusal text and the README's evolution rule. +- **Q3. Settling a merge conflict.** Candidates: + - **A.** The merge is all-or-nothing. It reports every conflict and writes + nothing. The operator settles by admitting, on ours, an explicit typed + `merge_exclusion` naming the theirs receipt and the reason, then re-runs the + merge. The merge skips excluded batches and reports their dependents as + conflicts too. The excluded documents are re-authored by hand. + - **B.** The merge only refuses and reports. Settlement happens outside the + tool. + + **Recommended: A.** Under B, a conflicted binary store cannot be merged at + all, because neither side's history can be rewritten. A keeps the settlement + typed, dated and queryable, and never lets the last writer win. + - Depends on it: whether Cut 3c adds the eleventh kind, `merge_exclusion`. +- **Q4. voidbot index scope.** The target says pushing the working branch is the + sync. The Body says otherwise: the mirror catalogs only public repos and fetches + only each repo's `default_branch` (gamecult-ops + `scripts/refresh-voidbot-sources.sh:84-89`, + `scripts/sync-gamecult-org-repos.sh:24-57`). Candidates: + - **A.** Index the default branch only, so learning becomes searchable across + repos when the campaign branch merges. + - **B.** Also mirror and index branches that carry a pipeline store. + + **Recommended: A.** Inside the running repo, Self reads the branch store + directly through `eureka-state`. Cross-repo discovery should surface settled, + merged learning, not abandoned or rebased campaign state. Private repos such as + gamecult-ops are never indexed under either option. + - Depends on it: Cut 7's scope. +- **Q5. `schemars` in `epiphany-core`.** Commit `07529fb5` deleted unused + `schemars` from Epiphany (`state/map.yaml:96-108`). Candidates: + - **A.** Make it an unconditional core dependency, derived on the pipeline + value types. Published JSON schemas and MCP tool schemas then come from one + Rust authority. + - **B.** Put it behind a core feature enabled only by the MCP package. + - **C.** Hand-write the JSON schemas and give MCP its own DTOs. + + **Recommended: A.** It now has two live consumers: the schema publication and + rmcp tool schemas, since rmcp's `server` feature already pulls `schemars` 1.x. + - B compiles `epiphany-core` twice in the shared target, because a + dependency's features change core's fingerprint. + - C creates a second owner of every field. + - Depends on it: Cut 3a's dependency line and Cut 4's tool types. + +## Probes and what they established + +All probes ran under the scratchpad at +`...\scratchpad\eureka-imagination\`. Cargo used +`CARGO_TARGET_DIR=C:\Users\Meta\.cargo-target-codex`, one invocation at a time. +Afterwards 3,796 probe outputs (2.1 GiB) were deleted. The shared target is back +to 5.6 GiB, with `debug\epiphany-state.exe` (1,776,640 bytes, 2026-08-24) +preserved. The scratch worktree was removed. + +| # | Probe | Result | +|---|---|---| +| P1 | Detached worktree at `81be7a2f`, pins sed-replaced to `a0813c6`, then `cargo check -p epiphany-core --lib` and `--lib --tests` | 12 × E0599 `load_envelope` not found; nothing else. `Cargo.lock` changes 5+/5−. | +| P2 | P1 plus `load_envelope` → `put_envelope` at the 12 sites | Lib builds clean except 3 `unused Result` warnings; lib tests add 5 more (8 total). | +| P3 | P2: `cargo test -p epiphany-core --lib`; `cargo check --lib` for `epiphany-model-adapter`, `epiphany-tool-adapter`, `epiphany-openai-runtime`, `epiphany-tool-mcp-runtime` | 154/154 tests pass; all four checks pass. Test children read before running: `git`, a PowerShell sleep, `cargo metadata`. None re-launches itself. | +| P4 | `rmcpprobe`: rmcp 2.2.0 with `default-features=false, features=["server","macros","transport-io"]`; one `#[tool]` returning `Json`; driven over stdin with JSON-RPC | Handshake at `protocolVersion 2025-06-18` works. `tools/list` carries both `inputSchema` and `outputSchema` from schemars. The call returns `structuredContent` plus a text copy. `ErrorData::invalid_params` becomes JSON-RPC `-32602`. The binary spawns nothing. | +| P5 | `lockprobe`: `SingleFileMessagePackBackingStore` at `a0813c6`; 4 writer processes × 200 (a disjoint insert plus a read-modify-CAS counter), 2 reader processes × 500 | 800/800 rows, counter 800/800, 0 read errors. Each writer lost about 500 CAS races, which it retried. The store lock is held per operation (`lib.rs:705-722`), so it serializes commits but excludes nothing at session scope. | +| P6 | `layoutprobe`: per-record files, a store-wide fs2 lock, receipt written last; 4 writers × 60 batches with 2 overlapping unlocked auditors | 240/240 receipts, 720/720 records, about 2.6M audited reads, 0 violations. On Windows, atomic replace is safe under concurrent unlocked readers. Kept as evidence for Q1-C, which is not recommended. | +| P7 | cultcache-ts `inspectCultCacheBytes` (CultLib dist 0.14.0) on a Rust-written record (a `DatabaseEntry` wrapper around a named nested struct holding an enum and an `Option`) | Format is `cultcache.store.v1`. The payload decodes as `[ {id, text, confidence: "Plausible", locations: [...], cut: null} ]`. Rust writes an empty member catalog (`members: []`), so the TS decode is generic, not typed. | +| P8 | Git with `* text=auto` (Epiphany's `.gitattributes`); system `core.autocrlf=true` on this machine | A 434-byte record holds no NUL, so git classified it `text: auto` (numstat `1 0`). With `binary` set, numstat is `- -` and `text/diff/merge` are unset. | +| P9 | Git merge rehearsal on per-record files | Disjoint branches merge cleanly; two branches writing the same resolution key conflict add/add. | +| P10 | Session lease: process A takes fs2 `try_lock_exclusive` and writes a sibling holder file; process B tries; A is killed with `-9`; B tries again | B is refused with `os error 33`, and the holder file is readable while the lock is held. After the kill, B acquires. The OS releases on death, so no repair step is needed. | +| P11 | Git history growth (Q1) | See Q1. | + +Source reads that mechanism claims rely on: + +- **Every `load_envelope` site uses a storeless cache.** Each builds + `CultCache::new()` and feeds it envelopes it pulled separately: + `persona_conversation.rs:959-961`, `persona_social_state.rs:231-251` then + `:846-866`, and `resident_self.rs:764-815`. `put_envelope` with zero stores + inserts into memory only (`home_index` returns `None`, `lib.rs:2425-2432`), + which is exactly the deleted `load_envelope` (CultLib `4ed9871`: "it had no + callers and admitted records into the view without a store"). +- **The old pin already refused unregistered types at pull** + (`e171eca3` `lib.rs:1965-1986`). The re-pin adds only the home-store check, + and every Epiphany cache has a single generic store. +- **Cargo.lock has one CultLib source** (`Cargo.lock:367,385,395,406`). No + second revision arrives through codex-connector or ghostlight. +- **VoidBot's vendored cultcache-ts is 0.1.0** and decodes only the legacy + envelope array (`vendor/cultcache-ts/dist/single-file-messagepack-backing-store.js:31`). + It cannot read a `cultcache.store.v1` store. + +Not probed: the working directory Claude Code gives a user-scope stdio server. +The design does not depend on it, because every tool takes an explicit +`repo_root`. + +## Shared design (cuts cite these sections) + +### D1. Documents + +Every pipeline document follows the Mind value-wrapper pattern +(`mind_documents.rs:129-137`). A `DatabaseEntry` has one slot: + +```rust +#[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)] +#[cultcache(type = "epiphany.pipeline.ruling.v1", schema = "EpiphanyPipelineRulingDocument")] +pub struct EpiphanyPipelineRulingDocument { #[cultcache(key = 0)] pub value: PipelineRuling } +``` + +Encoding and schema follow from that shape: + +- The value is a plain `serde` + `schemars::JsonSchema` struct. +- It is always prepared with `prepare_entry_named` (`lib.rs:2181-2200`). +- On the wire the payload is a one-element MessagePack array whose element is a + named map (P7, derive `lib.rs:216-245`). +- There are no per-field slot numbers: the named map is the evolution surface, + and slot 0 is the only slot. +- The published JSON Schema describes the value, which is exactly what MCP + clients send and receive and what cultcache-ts decodes as + `payloadPreview[0]`. + +Type ids are `epiphany.pipeline..v1`. Schema names are +`EpiphanyPipelineDocument`. The store epoch is `epiphany.pipeline.epoch.v1`. + +**Bounds, with no blob fields.** No `Vec`, no `serde_json::Value`, and no +free-form maps. Text fields use three bounded aliases, checked in UTF-8 bytes +following the `persona_feedback_admission.rs:994` precedent: + +| Alias | Bound | +|---|---| +| `Short` | ≤ 200 bytes | +| `Line` | ≤ 1,000 bytes | +| `Para` | ≤ 4,000 bytes | + +Every list has a maximum count, given below. Long narrative stays in repo docs and +is cited by `DocRef { path: Short, start_line: u32, end_line: u32, commit: Sha }`. +A breach is refused with `FieldBound { field, limit, actual }`. + +**Shared value types.** + +- `Sha`: 7–40 lowercase hex characters. +- `Date`: `YYYY-MM-DD`. +- `PipelineKind` is a closed enum: `Campaign`, `Target`, `Question`, `Ruling`, + `CutSpec`, `CutReport`, `Verdict`, `Finding`, `FollowUp`, `Resolution`, plus + `MergeExclusion` only if Q3 is A. +- `PipelineRef { kind, id: Short }`. +- `CodeLocation { path: Short, line: u32, end_line: Option }`. +- `CommitRange { base: Sha, head: Sha }`. +- `Evidence { kind: EvidenceKind, locator: Line, result: Line }`, where + `EvidenceKind` is one of `Command`, `Test`, `Mutation`, `Probe`, `SourceRead`, + `Capture`. +- `ForeignRef { repo: Short /* Org/Repo */, commit: Sha(40), kind, id: Short, payload_sha256: 64 hex }`: + the sharing citation (D6). +- `Faculty`: `SelfFaculty`, `Imagination`, `Hands`, `Soul`, `MindSteward`, + `Eyes`, `Operator`. + +**Keys: identity, not convenience.** Single-writer means a key only has to be +unique within one repo's history. It must also be stable across a merge, so that +the same document on two copies is the same key and a different document under +the same key surfaces as a real conflict. Keys are semantic and derived from +fields; admission recomputes each key and refuses a mismatch with +`InvalidIdentity { kind, key, expected }`, as `validate_mind_write_envelope` does +for Mind (`mind_documents.rs:357-382`). + +| Kind | Key | +|---|---| +| campaign | `` | +| everything else | `::` | + +`` and `` match `[A-Za-z0-9._-]{1,64}`. `` is the human label +agents already cite: + +| Kind | Local label | Example | +|---|---|---| +| target | `r` | `r2` | +| question | `Q-` | `Q10-1` | +| ruling | label | `R6` | +| cut spec | `cut-