Summary / 20. Episodic coding memory / Document
Spec 2026-09-06
Shared copy: the operator's name and machine names are replaced by roles. Nothing else is changed.
Rendering…
# Build Spec 20 — Episodic Coding Memory (the evidence-grounded, typed, subtask-indexed episodic memory stage) > Derived from `papers/20-episodic-coding-memory.md` — "Remember What the Attempt Proved, Not What Was Said: Evidence-Grounded, Typed, Subtask-Indexed Episodic Coding Memory for a Weak-Model Coding Harness." > This document drives the build of the **episodic-memory stage**: the typed three-tier library — episodic attempt > records, semantic insight rules, and procedural skills — in which every attempt is recorded immutably, distilled into > a transferable lesson only under an evidence gate, indexed at write time by the cues a *future* task will actually > supply, retrieved by a deterministic scored function with hard scope filters first, injected as a budgeted top-k of > compact advice-shaped memory cards, and governed by a lifecycle of promotion, decay, deduplication, and falsification > audited by a MemoryStats instrument that retires whatever stops earning its context. It sits where the harness's > learned experience either compounds or evaporates: components 01–19 assembled the request, the dependency graph, the > coverage, the candidate, the repair loop, the reflection, and the certification verdict; this component is the library > that gives all of that cross-task and cross-session reach. The sharp distinction is between a TRANSCRIPT and a LIBRARY: > a transcript is everything saved, searched by embedding similarity, injected as advice the model neither needed nor > questioned; a library is the right object in the right shape under the right gate — an immutable episode record ("what > happened"), a distilled semantic rule ("what transfers"), and a verified procedural skill ("what works"), each with its > own write rule, its own lifetime, and its own retrieval treatment. Naive harnesses paste a similar conversation back > into the prompt; this stage stores the conclusion, not the conversation, indexes it by the symptom a future task > presents, retrieves only the smallest high-confidence relevant experience, and measures whether the memory it injects > actually made the next attempt better or worse. Every node in the pipeline is deterministic software on CPU; the weak > model's AT MOST ONE contribution is a single learned step of DISTILLATION (extract the evidence-bound lesson from a > raw episode), and it never decides what is stored, indexed, retrieved, or retired. The guiding rule, made mechanical: > **Do not remember the old conversation. Remember what the old coding attempt proved.** This spec pins the paper's > design to exact primitives, the exact `CodingEpisode` / `CodingMemory` / `MemoryStats` schemas, the exact write-gates, > the exact scored-retrieval function with hard filters first, the exact budgeted-injection discipline, the exact > lifecycle stages, exact L-column firing, exact A/B instruments and thresholds, exact ablation mechanics, and an exact > build sequence. Where the paper says "≈80%", this spec pins *which* 80%. --- ## 1. Purpose & Scope Build a **reversible episodic-memory stage** — a typed three-tier store (episodic attempt records / semantic insight rules / procedural skills) with cue-indexing at write time, scored retrieval (relevance × recency × importance with hard scope filters first), budgeted injection, and a lifecycle of promotion/decay/dedup/falsification, audited by MemoryStats — that turns a completed coding episode plus the current decision point into either a stored, indexed, scoped memory record, or a budgeted, ranked set of memory cards injected into the current decision context, or a lifecycle mutation (promotion, decay, deduplication, falsification). It differs from its predecessors in *kind*, not just position: the repair loop (14) asks *"how do I improve this failed patch?"* and loops the **CANDIDATE**; reflection (15) asks *"what did this failure teach?"* and loops the agent's **UNDERSTANDING**; test execution (17) asks *"which tests passed, what property did each one actually prove?"* and certifies the **VERDICT**; reflection-after-failure (19) distills *one* failure into *one* lesson; episodic memory asks *"what did every attempt so far prove, indexed by the cue the next decision will actually supply?"* and loops the **LIBRARY** across tasks and sessions — without which each context reset pays the full price of every prior mistake again. The paper's eight principles decide every design choice. **P1 Memory is a typed library, not a transcript** — three stores, three write rules, three lifetimes, three retrieval treatments: episodic attempt records (every attempt, cheap, automatic, immutable — what happened), semantic insight rules (distilled claims about what transfers, gated on evidence citations), and procedural skills (verified, recomposable strategies, gated on executed success — Voyager's discipline [27]); "everything is saved" is a transcript, "the right object in the right shape under the right gate" is a library. **P2 Index by the query you will face, not the content you have** — memory is indexed at write time by the cues a future task will actually supply (error class, failure signature, repository area, task shape, language/framework, harness phase), never by the narrative of the task that produced it; retention without retrieval is zero (encoding specificity [23]). **P3 Retrieval is a scored function with hard filters first** — relevance × recency × importance is computed only *after* hard filters on repository/project scope, harness phase, and task shape have narrowed the candidate set, because a cross-repo "similar" memory is exactly the noise CTIM-Rover measured [20]. **P4 Gate every tier by evidence** — every attempt becomes an episode automatically; only a diagnosis that cites its evidence promotes to a rule; only a strategy that executed and verified becomes a skill; workflows earn storage by surviving induction across multiple episodes [6]. **P5 Both polarities are memory** — successes and failures are stored symmetrically, each with its situation, its evidence, and its causal attribution; a falsified approach never stored is re-paid in full on the next task. **P6 Inject the smallest high-confidence advice under an explicit budget** — retrieval returns top-k compact memory cards under an explicit token slice, formatted as advice, not ground truth; more retrieved memory is not automatically better (ReasoningBank's 39.0 → 49.7 → 46.0/45.5/44.4 ablation [4]). **P7 Scope and redact as a security boundary** — per- repository namespaces, secrets stripped at write time, cross-repo or cross-client contamination treated as a security incident, not an indexing bug. **P8 A memory must prove it helps or be retired** — every entry accumulates a MemoryStats record, and the lifecycle runs on it; a memory that hurts is falsified loudly and retired, never preserved out of sentiment. **Round 1 lands the expected ≈80% of the paper's full 100% spec**: everything deterministic — the three typed stores, the write-time cue index, the scored retrieval function, the hard scope filters, budgeted injection, the basic lifecycle (promotion/decay/dedup/falsification), and the MemoryStats audit — plus the *bound* of the *one* distillation call. The heavy pieces (full procedural skill composition à la Voyager, a learned recall policy à la MemRL, cross-repo fleet pooling à la Agent KB, advanced re-verification of stale workflows) are **not** built in Round 1 and are **not excluded** — later rounds climb toward 100% (§2). Round 1 is kept only if it wins a measured A/B test on the *honest* metrics — led by **retrieval precision** and its co-signatory **memory-no-harm**, with companion **token budget of injected memory**, never the end-to-end resolve rate alone and never model self-assessment (§7). The stage lives in `build/20-episodic-coding-memory/` and writes nothing into the live harness. --- ## 2. Round 1 vs later rounds (toward the 100% target) The goal is the paper's full **100%** spec. **~80%** is only the expected **first-round landing**; later rounds climb from there. **BUILD-NOW = the Round 1 build** (rows 1–9); **DEFERRED = later rounds** (rows 10–13), **not excluded** but gated by the same §7 A/B protocol. Every later round of this component still builds within the same `build/20-episodic-coding-memory/` tree. | # | Component (paper §4) | Classification | |---|---|---| | 1 | The typed three-tier store — `record_episode` writes the immutable `CodingEpisode`; episodic / semantic / procedural tiers with three write rules (P1) | **BUILD-NOW** | | 2 | Write-time cue indexing — `index_cues` attaches error class, failure signature, repo area, task shape, language/framework, harness phase (P2) | **BUILD-NOW** | | 3 | Scored retrieval with hard filters first — `score_retrieval` = relevance × recency × importance, computed only after `filter_scope` (P3) | **BUILD-NOW** | | 4 | Hard scope filters — repository/project namespace, harness phase, task shape, applied before any similarity (P3/P7) | **BUILD-NOW** | | 5 | Budgeted injection — `inject_budget` returns the smallest high-confidence top-k of compact cards under an explicit token slice (P6) | **BUILD-NOW** | | 6 | Evidence write-gates — `apply_write_gate` admits episodes always, rules only on resolvable evidence, skills only on executed verification (P4) | **BUILD-NOW** | | 7 | Basic lifecycle — promotion (episode → rule → skill), decay, deduplication, falsification (P8) | **BUILD-NOW** | | 8 | MemoryStats audit — `audit_memory` tracks retrieved/used/successful-after-use/harmful per card (P8) | **BUILD-NOW** | | 9 | (L) Distillation stub + loop driver + A/B harness (§7 metrics + ablation runner + failure-mode audits) | **BUILD-NOW** (bounded stub only) | | 10 | **Full procedural skill composition à la Voyager** — the full skill-library gate: programs admitted only after verified execution, refinement loop on retrieval miss | **DEFERRED** — Round 1 ships the verification gate for a skill's admission; full recomposable-skill composition with a re-prompt-on-miss loop is deferred | | 11 | **Learned recall policy à la MemRL** — runtime reinforcement learning over the episodic store for what to write/recall/trust | **DEFERRED** — Round 1 ships the deterministic lifecycle as the fixed rulebook that approximates MemRL's learned write policy; a learned recall policy is deferred | | 12 | **Cross-repo fleet pooling à la Agent KB** — pooled cross-domain experience shared across a fleet of agents | **DEFERRED** — Round 1 ships the per-repo namespace that makes pooling *safe*; the pooling itself is deferred | | 13 | **Advanced re-verification of stale workflows** — periodic re-execution of stored skills against the evolved repo | **DEFERRED** — Round 1 ships staleness decay on the usage record; re-running stored workflows to re-verify them against the evolved repository is deferred | **The cost rule (explicit).** The single learned entry — distillation — is the AT MOST ONE L-column entry this architecture permits. In Round 1 it is a **bounded stub**: wired in at its firing point (§4), seeded, schema-constrained, never auto-promoted; its full training and calibration is **deferred**. Its cost is bounded before invocation: one call per episode cluster, temperature zero, schema-constrained, bounded payload, parse-failure fallback that returns to the deterministic stage with the violation fed back (§4 caps). It is kept **only if** the §7 no-L-vs-L ablation shows it improves the KEY measures on held-out tasks; otherwise it is removed and the L column stands empty — a permitted, correct state, never a violation. **The full training/calibration of the learned entry is deferred regardless.** **Design decision: DETERMINISTIC-FIRST, LEARNED-EXCEPTIONAL.** Round 1 puts no model in the record, index, gate, scope, score, budget, or lifecycle path by default — the full deterministic library (rows 1–8) plus the *bounded stub* of the single distillation call (§4) is the build; the L step is the exception. Each deferred row would add a trained second model, a learned recall/write policy, a fleet-pooling mechanism, or a re-execution loop — and must clear the same bar as in earlier components: beat the deterministic stage on the honest metrics (§7), on held-out tasks, at a defensible cost, or be rejected. --- ## 3. The Deterministic Pipeline (D) A typed library with a write pipeline, a retrieval pipeline, and a lifecycle; every node is labeled D (deterministic software) or L (a learned model). The invariant that governs the whole is: **the L column contains at most one entry, and the deterministic library is the default.** A pure write of an episode — record the attempt, index its cues, attach its evidence — has zero L entries: the episode record, the cue index, the scope namespace, and the secret redaction are deterministic software on CPU. A pure retrieval — score candidates, filter by scope, budget the injection — has zero L entries: the scored retrieval function, the hard filters, and the top-k budget are deterministic. The single L entry appears only in the distillation step. The pipeline, in the deterministic services plus the one learned entry (L): ``` COMPLETED CODING EPISODE (task, repo, trajectory, patches, failures, evidence, final_patch, outcome) + CURRENT DECISION POINT (active harness phase + pending choice) → record_episode [D] → immutable attempt record appended (P1) → index_cues [D] → write-time future-cue index attached (P2) → (L) distill [L — the at-most-one entry] → the model extracts the evidence-bound lesson → apply_write_gate [D] → evidence-gated admission per store (P4) → scope_redact [D] → per-repo namespace + secret stripping (P7) → score_retrieval [D] → relevance × recency × importance, hard filters first (P3) → inject_budget [D] → top-k compact cards under a token slice (P6) → apply_lifecycle [D] → promotion / decay / dedup / falsification (P8) → audit_memory [D] → the MemoryStats instrument ``` The pipeline reasons over **a completed coding episode made into a stored, indexed, scoped memory record — or a budgeted, ranked set of memory cards injected into the current decision — or a lifecycle mutation**. The task, repository, trajectory, patches, failures with their typed evidence (component 17's verdicts, component 11's failure signatures), final patch, and outcome are the raw material; the active harness phase and the pending choice are the retrieval keys. All artifacts land in `build/20-episodic-coding-memory/`. ### 3.1 The episode record: `CodingEpisode` (immutable) — the D record step (D) **Input:** a completed coding attempt — task, repository, trajectory, patches, failures with typed evidence, final patch, outcome. **Output:** an immutable `CodingEpisode` record appended to the episodic tier. **No language model runs here.** Every attempt, success or failure, cheap and automatic (P1). The record is append-only and never rewritten in place: distillation produces derived memories that point back at it (E-mem's reconstruction discipline [12]), so nothing historical is lost to a lossy rewrite. The record and the claim are different objects: the episode is *what happened*; the rule and the skill are *what transfers* — and the two are never collapsed into one log. **The `CodingEpisode` schema (exact — EXACTLY these fields):** ```json { "episode_id": "…", // stable hash of task+repo+attempt — the immutable record's key "task": "…", // the task/issue identifier "repo": "…", // the per-repository namespace this episode belongs to (§3.5) "trajectory": [ "…" ], // the attempt's step sequence — the actions actually taken "patches": [ "…" ], // candidate patches produced during the attempt "failures": [ "…" ], // failures encountered (component 11 signatures, component 17 verdicts) "evidence": [ "…" ], // typed evidence citations (component 17's verdicts, traces, failing tests) "final_patch": "…", // the final patch, or null if the attempt ended unresolved "outcome": "…" } // the deterministic outcome (resolved / unresolved / falsified) ``` `episode_id` is the stable key; `task` the issue; `repo` the namespace; `trajectory` the step sequence; `patches` the candidate states; `failures` the failure signatures; `evidence` the typed citations that ground any later distillation; `final_patch` the terminal state (or null); `outcome` the deterministic result the harness recorded, never the model's sense of how the attempt went. **Procedure (exact, deterministic):** 1. Assemble the episode fields from the harness's own records (component 17's verdicts, component 11's signatures). 2. Compute `episode_id` as a stable hash over task + repo + attempt index. 3. Append the record; mark it immutable (no in-place rewrite path exists in the store). **Caps:** recording is pure deterministic software on CPU — the model never decides whether an attempt is worth recording (every attempt is), and the record is never rewritten in place; a distillation produces a derived memory that points back at the immutable episode, never a replacement for it. ### 3.2 The typed-store tiers — three stores, three write rules, three lifetimes (D) **Input:** a typed memory object. **Output:** the object admitted to (or refused by) its tier's write gate. **No language model runs here.** The library is three stores, and the refusal to collapse a record into a claim is the immutability lesson of E-mem [12] given teeth (P1, P4). The three tiers and their gates: ``` EPISODE — every attempt, automatic, immutable — write gate: ALWAYS admit — lifetime: never rewritten, decays only in retrieval weight RULE — distilled claim about what transfers — write gate: evidence resolves — lifetime: promoted / falsified on the usage record SKILL — verified, recomposable strategy — write gate: executed verification — lifetime: promoted / retired on the usage record ``` An episode is admitted automatically and cheaply; a rule is admitted only if its evidence citations resolve against the episode's record (the failing test, the trace, the verdict); a skill is admitted only if its execution record verified (component 17's typed green, not the model's self-report — Voyager's gate [27]); a workflow (the composition of several skills) is admitted only after surviving induction across multiple episodes [6]. The gate reads the harness's own evidence records; it does not consult the model about whether the model's lesson is true. **Procedure (exact, deterministic):** 1. Classify the object's `memory_type` (EPISODE / RULE / SKILL). 2. Apply the tier's gate (§3.6): episode always admitted; rule admitted iff evidence resolves; skill admitted iff execution verified. 3. Refuse (record the refusal, keep the source episode) any object that fails its gate. **Caps:** tiering and gating are pure deterministic software on CPU — the model never collapses the three stores, never admits a rule whose evidence does not resolve, and never admits a skill on the model's self-report of success. ### 3.3 Write-time cue indexing — index by the query you will face (D) **Input:** a stored episode (or memory) and the cues of the future queries that will need it. **Output:** a cue index attached at write time. **No language model runs here.** This is the encoding-specificity operation [23]: the cue is derived from the *future query's* vocabulary — the symptom a later task presents — not from the episode's own narrative (P2). An episode stored as "the fix was X" without its cue context is unretrievable, and retention without retrieval is zero. The harness-phase cue comes from the component decomposition itself (Structurally Aligned [7]), made dynamic by the plan pointer (PMCoder [8]): a dependency-impact decision queries the impact bucket and never the editing bucket. **Procedure (exact, deterministic):** 1. Derive the cue set at write time: error class, failure signature, repository area, task shape, language/framework, harness phase. 2. Attach the cues to the record as index keys — the vocabulary a future task will *supply*, never the story of the task that produced it. 3. Key the harness-phase cue off the component decomposition (the active harness subtask), so retrieval is scoped by the harness's own state, not by free-text similarity. **Caps:** cue indexing is pure deterministic software on CPU — the model never decides how an episode is indexed; the index keys are the future query's vocabulary, and a memory indexed by its own content instead of by future cues is a §7.5 cue-mismatch failure. ### 3.4 Scored retrieval with hard scope filters first (D) **Input:** the current decision point (active repository, harness phase, task shape) and the cue index. **Output:** a scored, filtered candidate set. **No language model runs here.** Retrieval is a scored, tunable, three-factor function (Park et al.'s recency × importance × relevance [3]), computed only *after* hard filters on repository/project scope, harness phase, and task shape have narrowed the candidate set (P3). Scope filters precede similarity, never follow it, because a cross-repo "similar" memory is exactly the noise CTIM-Rover measured [20], and the repo namespace is a security boundary before it is a relevance optimization (P7). No memory crosses a scope filter on similarity alone. ``` score = relevance (embedding similarity to the cue) × recency (exponential decay) × importance (write-time scoring) ``` **Procedure (exact, deterministic):** 1. `filter_scope` — narrow candidates to the active repository, harness phase, and task shape (hard partitions, never soft tags). No cross-scope candidate reaches the scorer. 2. `score_retrieval` — compute relevance × recency × importance over the surviving candidates. 3. Return the scored set; the phase filter is fed by the plan pointer (PMCoder's coupling [8]), so the bucket is chosen by the harness's own state, not by free-text similarity. **Caps:** scoring is pure deterministic software on CPU — the model never ranks retrievals by feel and never reorders the scored set; scope filters run before similarity, and a cross-repo candidate is blocked before it is ever scored. ### 3.5 Budgeted injection — smallest high-confidence advice under an explicit token slice (D) **Input:** the scored candidate set and an explicit token budget. **Output:** the top-k compact memory cards to inject, or the empty set. **No language model runs here.** Retrieval returns the smallest high-confidence set — often one — and expands only when the scorer's confidence justifies the extra tokens (P6), because ReasoningBank's ablation [4] is the standing evidence that more retrieved memories are not automatically better, and SWE Context Bench's "unfiltered hurts" [21] is the standing evidence that an always-full top-k is a distractor field wearing a helpful badge. The cards are formatted as **advice, not ground truth**, so the model can disagree. **Procedure (exact, deterministic):** 1. `inject_budget` — select the top-k compact memory cards under the explicit token slice; the k defaults to the smallest high-confidence set (often one) and expands only on justified confidence. 2. Format each card as compact, advice-shaped memory text at the window edges. 3. Mark each card as advice (never ground truth); return the empty set when nothing clears the confidence floor under the budget. **Caps:** injection is pure deterministic software on CPU — the model never decides how many memories to inject and never upgrades a card from advice to ground truth; a budget always exhausted is an advice-flood (§7.5), and a top-k that is always full but rarely used is a similarity engine, not a memory. ### 3.6 The memory contract: `CodingMemory` and the write gate (D) **Input:** the distilled (or directly recorded) memory object. **Output:** a typed `CodingMemory` admitted under its tier's gate, or a refusal. **No language model runs here** — the gate reads the harness's evidence records, never the model's opinion about the model's lesson. Every memory card carries its type, the harness phase it targets, the cue situation, the lesson (either polarity), its cited evidence, its applicability scope, its write-time confidence, and back-pointers to the immutable episode(s) it was distilled from (P4, P5). **The `CodingMemory` schema (exact — EXACTLY these fields):** ```json { "memory_id": "…", // the memory card's key "memory_type": "…", // EPISODE | RULE | SKILL — which tier this card lives in "harness_phase": "…", // the active coding-harness subtask this memory targets (§3.3) "situation": "…", // the cue situation (error class, failure signature, repo area, task shape) "mistake_or_strategy": "…", // the DO or DO-NOT lesson — both polarities stored symmetrically (P5) "evidence": [ "…" ], // cited evidence resolving against the source episode's record (§3.1) "lesson": "…", // the compact transferable lesson text "applicability": "…", // the scope predicate — which repos/phases/task shapes this transfers to "confidence": 0.0, // write-time confidence (0..1) "source_episode_ids": [ "…" ] } // back-pointers to the immutable episode(s) this was distilled from ``` `memory_type` names the tier; `harness_phase` the subtask it targets; `situation` the cue; `mistake_or_strategy` the polarity-aware lesson (a DO THIS strategy or a DO NOT REPEAT THIS failed approach, each with its situation, evidence, and causal attribution — the negative polarity is the cheaper half of the store); `evidence` the citations that keep it a proof rather than prose; `lesson` the compact transferable text; `applicability` the scope predicate (a lesson is only trustworthy within the repository, harness phase, and task shape where it was earned — the boundary CTIM-Rover measured [20]); `confidence` the write-time score; `source_episode_ids` the back-pointers to the immutable record (E-mem's discipline [12]). **Procedure (exact, deterministic):** 1. Bind the memory object into the schema; every field present, every evidence citation resolvable against a source episode. 2. Apply the tier's gate (§3.2/§3.1): a rule is admitted only if its evidence citations resolve; a skill only if its execution record verified; a workflow only after multi-episode induction. 3. Refuse (and record the refusal) any card whose gate does not close — never admit a bare claim on the model's say-so. **Caps:** the write gate is pure deterministic software on CPU — the model never decides whether its own lesson is admitted; a rule whose evidence does not resolve is refused, and a card carrying no resolvable evidence is a bare claim that never enters the store. ### 3.7 The audit contract: `MemoryStats` (D) **Input:** a memory card's injection and outcome history. **Output:** an accumulating `MemoryStats` record driving the lifecycle. **No language model runs here.** This is the Piper rule's last clause made quantitative (P8): a memory that does not improve future outcomes is revised or retired, and this record names exactly which ones. The instrument keeps the library accountable to what each memory actually contributed and what it cost, not to the count of stored episodes. **The `MemoryStats` schema (exact — EXACTLY these fields):** ```json { "memory_id": "…", // the memory card this stats record tracks "retrieved": 0, // times this card was injected into a decision context "used": 0, // times the injected card was actually used (cited in / consistent with the outcome) "successful_after_use": 0, // times a used card preceded a successful outcome "failed_after_use": 0, // times a used card preceded a failure "estimated_helpful": 0, // the audit's count of injections it estimates helped "neutral": 0, // injections with no measurable effect "harmful": 0 } // injections that hurt — the retirement trigger (§3.8) ``` `retrieved` counts injections; `used` counts the injections that were actually used — whether the final patch, diagnosis, or decision cites or is consistent with the card's lesson — versus the ones that sat in context unused; `successful_after_use` and `failed_after_use` split the used ones by outcome; `estimated_helpful` / `neutral` / `harmful` are the audit's counterfactual read (computed deterministically from the usage record, never from the model's sense that "memory helped"). **Procedure (exact, deterministic):** 1. On every injection, increment `retrieved`; on every outcome, deterministically classify the injected cards as used or unused (by citation/consistency with the outcome, not by self-report). 2. Update `successful_after_use` / `failed_after_use` / `estimated_helpful` / `neutral` / `harmful` accordingly. 3. Feed the record to `apply_lifecycle` (§3.8); a `harmful` count is the falsification/retirement trigger. **Caps:** the audit is pure deterministic software on CPU — the model never judges whether a memory helped; the usage classification is a deterministic read of the outcome against the card, and a card that hurts is retired on the record, never on the model's opinion. ### 3.8 The lifecycle — promotion, decay, deduplication, falsification (D) **Input:** the MemoryStats records and the evidence gate. **Output:** lifecycle mutations. **No language model runs here.** The lifecycle is the fixed deterministic rulebook that approximates a learned write policy (MemRL's ceiling [17]), and it is the harness's honest substitute for a learned recall policy (P8). Every mutation is driven by the MemoryStats record, not by the model's opinion, and a retirement writes a visible falsification notice rather than silently deleting. ``` promotion — episode → rule → skill on the evidence gates (§3.6); recurring episodes promote to insight rules (ExpeL [19]) decay — unretrieved entries lose retrieval weight on schedule (recency exponential decay) deduplication — equivalent lessons merge; duplicates fold into one card with the union of evidence and usage falsification — a lesson contradicted by new evidence is retired LOUDLY (a visible notice, never a silent delete) ``` **Procedure (exact, deterministic):** 1. `promotion` — promote a recurring episode to a rule and a verified rule to a skill, strictly on the evidence gates. 2. `decay` — decay the retrieval weight of unretrieved entries on schedule. 3. `deduplication` — merge equivalent lessons; fold duplicate cards into one with the union of their evidence and usage. 4. `falsification` — retire, loudly and visibly, any lesson contradicted by new evidence or flagged harmful; never silently delete. **Caps:** the lifecycle is pure deterministic software on CPU — the model never vetoes a retirement, never decides a rule has "earned" promotion on its say-so, and never suppresses a falsification notice; a store that never retires anything is accumulating, not learning. ### 3.9 Cross-cutting deterministic services (D) Eight services make the library an instrument rather than a log, each pure deterministic software on CPU: `record_episode` (the immutable attempt record, §3.1); `index_cues` (the write-time future-cue index, §3.3); `apply_write_gate` (evidence-gated admission per store, §3.6); `scope_redact` (per-repo namespace and secret stripping, §3.5/§3.4); `score_retrieval` (relevance × recency × importance with hard scope filters first, §3.4); `inject_budget` (top-k memory cards under a token slice, §3.5); `apply_lifecycle` (promotion, decay, deduplication, falsification, §3.8); and `audit_memory` (the MemoryStats instrument, §3.7). Every one is software on CPU, and none consults a model. **Procedure (exact, deterministic):** 1. `record_episode` — assemble and append the immutable episode (task, repo, trajectory, patches, failures, evidence, final_patch, outcome). 2. `index_cues` — attach the future-cue keys (error class, failure signature, repo area, task shape, language/framework, harness phase) at write time. 3. `apply_write_gate` — admit episodes always, rules on resolvable evidence, skills on executed verification. 4. `scope_redact` — assign the per-repo namespace, strip secrets/credentials, raise a security incident on cross-repo or cross-client contamination (run at write and again at retrieval). 5. `score_retrieval` — filter by scope first, then score relevance × recency × importance. 6. `inject_budget` — select the smallest high-confidence top-k under the token slice. 7. `apply_lifecycle` — promote / decay / deduplicate / falsify on the MemoryStats record. 8. `audit_memory` — accumulate and report the MemoryStats instrument. **Caps:** all eight services are pure deterministic software on CPU — the model never records, indexes, gates, scopes, scores, budgets, retires, or audits a memory; it distills one (§4). ### 3.10 The single L entry — distillation (L) **(L) Distillation [L — the at-most-one learned entry].** The model reads one completed episode (or a small aligned cluster of episodes) and extracts the transferable lesson into a typed shape — situation, strategy-or-mistake, evidence citations, causal attribution, applicability, confidence. It produces either a semantic rule (a claim about what transfers, gated on cited evidence) or a candidate procedural skill (a recomposable strategy, gated on executed verification). This is the only stage that can misattribute, and its output is therefore never trusted at write time: a rule enters the store only after its cited evidence resolves against the episode's record, and a skill enters only after the verification gate closes. The distillation is advice-shaped and evidence-bound, never a free-floating claim. This entry is detailed in §4. **The L column holds at most one entry, and the deterministic library is the default.** The record, the cue index, the write gate, the scope namespace, the redaction, the scored retrieval, the budget, and the lifecycle are deterministic software on CPU; the single learned node is §4, and never a model that decides what is stored, indexed, retrieved, or retired. Any addition putting a model elsewhere — deciding what is worth remembering, ranking retrievals by feel, deciding whether an injected memory helped, or vetoing a retirement — is a regression against P1–P8 and must clear the §7 bar on held-out tasks at defensible cost, or be rejected. **Enforced mechanically: "the L column contains at most one entry."** --- ## 4. The LLM Step (L, AT MOST ONE entry) The **single** learned node in the entire stage: **`distill`** — the distillation step. The weak model reads a raw episode (or a small aligned cluster of episodes) and extracts the transferable lesson — the mistake pattern, the successful strategy, the reusable invariant, or the causal attribution — that becomes a semantic rule or a candidate procedural skill. This is the DISTILLATION step and nothing more: **extract the evidence-bound lesson from an episode.** The model is **forbidden from deciding what to store** (every attempt is stored, deterministically), **forbidden from deciding what to index** (the cue indexer does), **forbidden from deciding what to retrieve** (the scorer does), **forbidden from scoring** (the scored retrieval function is deterministic), and **forbidden from deciding whether a memory is retired** (the lifecycle does). The model's only legitimate contribution is extracting a transferable, evidence-bound lesson from a raw episode — never storage, indexing, retrieval, or retirement. **Prompt inputs (assembled deterministically, in this exact order):** 1. **`episode`** — the immutable `CodingEpisode` record (task, repo, trajectory, patches, failures, evidence, final_patch, outcome). 2. **`evidence`** — the typed evidence the episode carries (component 17's verdicts, component 11's failure signatures, traces, failing tests). 3. **`harness_phase`** — the active coding-harness subtask under which the episode occurred, so the lesson is bound to the phase it was earned in. **Input → output schema (exact):** the model emits a JSON object conforming exactly to the `CodingMemory` shape minus the deterministic fields (`memory_id`, `memory_type`, `confidence` are computed by the harness; the model supplies `situation`, `mistake_or_strategy`, `evidence` citations, `lesson`, `applicability`). The output is a **CANDIDATE** rule or skill — never a stored memory, never a retrieval, never a retirement. Every `evidence` citation the model emits must resolve against the episode's record; a citation that does not resolve is a schema violation. **Caps:** **ONE call per episode cluster**, `temperature = 0`, `max_completion_tokens` bounded, schema-constrained; a bounded payload. The model **DISTILLS only, never stores, indexes, retrieves, scores, or retires**. **Gating (exact):** the distilled candidate enters the store only through `apply_write_gate` (§3.6) — a rule is admitted only if its cited evidence resolves against the episode's record, and a skill only if its execution record verified (component 17's typed green, not the model's self-report). The model does **not** decide what is stored, does **not** decide what is indexed, does **not** decide what is retrieved, does **not** score candidates, and does **not** decide whether a memory is retired — those are the deterministic library's properties (§3); an output asserting any of them is rejected deterministically and never admitted on the model's say-so (§8 invariants). **Parse-failure fallback (exact):** any JSON parse failure, schema violation (a missing `situation`, an `evidence` citation that does not resolve against the episode, a `lesson` with no evidence binding, or an output that asserts a storage/indexing/retrieval/retirement decision), or empty/malformed output is **not silently retried as a fresh distillation call**: the stage **returns to the deterministic stage with the violation fed back** — the malformed candidate is recorded as a violation, the episode remains recorded with no derived rule (a permitted state: an episode without a distilled lesson is not a defect), and no memory is admitted on the model's say-so — **never a re-prompt, never a second call at the same seed**. The L column is reached **once** per episode cluster. **Re-invocation on a later round (exact):** distillation is re-considered only when a *later round* processes a *new* episode (or a new cluster of episodes), scoped strictly to that episode's record and fed the episode's own evidence. It remains the **single conceptual learned entry** — a bounded, once-per-episode-cluster call — **never a model that runs over the library**. **Invariant 1 (§8): the L column contains at most one entry — a bounded, seeded distillation call whose output the deterministic write gate disposes of.** An **empty** L column (the stub ablated away in §7.3) is a permitted, correct state — never a violation. --- ## 5. Implementation Order Nine phases, each independently testable and reversible, landing in `build/20-episodic-coding-memory/` as standalone importable modules. Rollback = delete/flag-off that phase's module; nothing earlier breaks because phases only add modules and never mutate live harness code. | Phase | Delivers | Isolated test | Rollback | |---|---|---|---| | **1. Episode record (P1)** | `record.py` (§3.1 the immutable `CodingEpisode` schema + `record_episode`) | A completed attempt produces an immutable `CodingEpisode` with all nine fields; a rewrite attempt is refused; assert **no LLM consulted**. | Delete `record.py`. | | **2. Typed tiers + write gate (P1/P4)** | `tiers.py` (§3.2/§3.6 the three stores, `CodingMemory` schema, `apply_write_gate`) | An episode is always admitted; a rule with unresolvable evidence is refused; a skill without verified execution is refused; assert **no LLM consulted**. | Delete `tiers.py`. | | **3. Cue indexing (P2)** | `index.py` (§3.3 `index_cues` — error class, failure signature, repo area, task shape, language/framework, harness phase) | An episode is indexed by future-cue keys, not by its own narrative; the harness-phase key routes a dependency-impact decision to the impact bucket; assert **no LLM consulted**. | Delete `index.py`. | | **4. Scoped scoring (P3)** | `score.py` (§3.4 `filter_scope` then `score_retrieval` = relevance × recency × importance) | A cross-repo candidate is blocked before scoring; a same-scope candidate scores by the three factors; assert **no LLM consulted**. | Delete `score.py`. | | **5. Budgeted injection (P6)** | `inject.py` (§3.5 `inject_budget` — smallest high-confidence top-k under a token slice) | Under a tight budget, k collapses to one (or empty); cards are advice-shaped, never ground truth; assert **no LLM consulted**. | Delete `inject.py`. | | **6. Scope + redaction (P7)** | `scope.py` (§3.9 `scope_redact` — per-repo namespace, secret stripping, contamination incident) | A secret in a stored episode is stripped; a cross-repo/cross-client reference raises a contamination incident; assert **no LLM consulted**. | Delete `scope.py`. | | **7. Lifecycle + audit (P8)** | `lifecycle.py` (§3.8 promotion/decay/dedup/falsification) + `audit.py` (§3.7 the `MemoryStats` schema + `audit_memory`) | A harmful memory is falsified loudly (visible notice, not silent delete); an unretrieved memory decays; duplicates merge; assert **no LLM consulted**. | Delete `lifecycle.py` / `audit.py`. | | **8. L stub (distillation)** | `distill.py` (§4 ONE call + temperature 0 + seeded + schema-constrained + parse-failure fallback) | With a mocked LLM: the call is **one**, temperature 0; output has exactly the candidate fields; an evidence citation that does not resolve → returns to the deterministic stage, **no second call**; assert no memory is admitted on the model's say-so. | Delete `distill.py`. | | **9. Loop driver + A/B harness** | `pipeline.py` (§3 wiring record→index→(L)→gate→scope→score→inject→lifecycle→audit), `ab.py` (§7 KEY + companion + secondaries + ablation runner + no-L-vs-L + decision) | `pipeline.py` on a fixture with a mocked stub: full write-then-retrieve round trip. `ab.py` runs the §7 pipeline-vs-baseline and ablations on held-out fixtures. | Feature flag `off` → live harness untouched; `ab.py` read-only. | The A/B runner (Phase 9) is the only phase that ever *invokes* the current harness — only to measure it, never to modify it. The pipeline reuses the harness's embedding index for relevance scoring and components 06 (dependency graph), 11 (execution substrate / failure signatures), 17 (typed verdicts), and 19 (distilled reflections) as its raw material; it invents no new embedding model, no new execution substrate, and no new evidence source. --- ## 6. Dependencies & Supply-Chain Per Piper's rule: nothing is installed unless >72h old AND (≥10 stars OR deep-scrutinized). This build is **zero-install for Round 1 (Python-only, stdlib + in-repo + reuse of the harness's own embedding index and the earlier components' artifacts)**: | Dependency | Why | Status / age-stars | Install needed? | |---|---|---|---| | stdlib `sqlite3` | §3.1/§3.2/§3.7 the durable `CodingEpisode` / `CodingMemory` / `MemoryStats` stores | CPython stdlib. | **No** | | stdlib `json` | §3.1/§3.6/§3.7 the schemas and §4 the distillation schema | CPython stdlib. | **No** | | stdlib `hashlib` | §3.1 the stable `episode_id` / `memory_id` hashes; §3.9 secret-strip verification | CPython stdlib. | **No** | | stdlib `math` (exp) | §3.4 the recency exponential-decay term of the scored retrieval | CPython stdlib. | **No** | | Harness embedding index | §3.4 the relevance (embedding similarity) term of the scored retrieval | The harness's own vector index; reused, not reimplemented. | **No** | | Component 06 dependency graph | §3.3/§3.4 repository-area cue derivation | Built by spec 06; reused. | **No** | | Component 11 execution substrate / failure signatures | §3.1/§3.6 the typed failure signatures and non-termination rule | Built by spec 11; reused. | **No** | | Component 17 typed verdicts | §3.1/§3.6/§3.7 the evidence citations and the verification gate for skills | Built by spec 17; reused. | **No** | | Component 19 distilled reflections | §3.1/§3.6 the single-failure lessons that feed the semantic tier | Built by spec 19; reused. | **No** | | Harness weak model (`deepseek-v4-pro`) | §4 the single distillation call (bounded stub in Round 1) | The harness's own model, already vetted. | **No** | **Preferred path: zero-install.** Round 1 is Python-only and deterministic: the stores use stdlib `sqlite3`/`json`/`hashlib`/`math`, and the relevance term reuses the harness's own embedding index rather than pulling a new model; the failure signatures, verdicts, and reflections are **reused wholesale from components 11, 17, and 19**, not duplicated. The single LLM call (§4) goes to the harness's own weak model as a bounded stub. **No new package is installed for Round 1.** The DEFERRED rows (§2 rows 10–13) are a skill-composition scale-up, a learned recall policy, a fleet-pooling mechanism, or a re-verification loop — not new third-party Python installs. Any future trained-model download, fine-tuning run, or learned-recall-policy dependency must clear the **72h-age + star/scrutiny + sandbox-test** gate before use — out of Round 1 scope entirely. --- ## 7. Acceptance Criteria — the A/B Protocol Episodic memory is measured *separately* and *honestly*, because a stage whose whole purpose is to improve future decisions can be defeated in either of two opposite ways: by injecting memories that help (and claiming credit for the underlying model), or by injecting memories that hurt (and claiming neutrality because "more context can't hurt" — it can, and ReasoningBank [4] and SWE Context Bench [21] both measured it). The instruments keep the library accountable to what each memory actually contributed and what it cost, not to the count of stored episodes. **Sample (concrete).** Reuse the **same held-out SWE-bench-Verified instances as specs 01, 11, 12, 13, 14, 15, 16, and 17** (Python-only, single-repo, no-Docker), but arranged as **task sequences** — each sequence groups instances by the dependency/reference relationships between their issues and PRs (SWE Context Bench's construction [21]), so prior experience is genuinely load-bearing. Held out = never seen by any tuning, prompt, generation, or memory pass. Seeded RNG. **Fallback:** `coding-cortex/piperbench` sampled to 20 tasks, held out identically. Held-out sequences feed the store, the retrieval, the budget, and the outcome statistics; in-benchmark tasks feed nothing that scores the stage. **Baseline (concrete).** The **naive transcript-embedding-search memory** — the failure mode this component rejects: on each decision the harness stores the raw conversation, embeds it, and injects the top-k most similar past transcripts with **no typed stores, no cue indexing, no hard scope filters, no evidence write-gate, no budgeted smallest-set discipline, no lifecycle, no MemoryStats audit**, and "memory helped" is whatever the model feels. The typed library must beat *this* on the honest measures below, and the ablation (7.3) removes mechanisms against those same measures. ### 7.1 Retrieval precision + memory-no-harm — the KEY measures The primary instruments, the direct score of the whole stage. **Retrieval precision** — of every injected memory card, whether it was actually *used* in the solution (the final patch, diagnosis, or decision cites or is consistent with the card's lesson) versus whether it sat in context unused; and of the used ones, whether it helped (preceded a successful outcome). A library whose top-k is always full but never used is scoring similarity, not transfer — and this instrument drives the retrieval-calibration loop. **Memory-no-harm** — the on/off ablation reading: whether injecting memory *never* degrades an outcome below the no-memory condition. A library that helps on some tasks and hurts on others is not neutral — it is a poisoned prior with seniority, and this instrument is the cleanest causal reading of whether the library helps (borrowed from SWE Context Bench [21] and CTIM-Rover [20]). Both are computed deterministically and outside the model, because the model cannot be trusted to report whether memory helped it. **State explicitly: "Never the end-to-end resolve rate alone"** — memory must not be judged by whether the eventual patch resolved (component 14's measure) but by whether each injected memory was actually used and whether it helped, because a memory layer that claims credit for the underlying model's resolve is invisible on the resolve number. **State explicitly: "Never introspective fluency or model self-assessment"** — a library scoring highly on the model's own sense that "memory helped" while its injected cards are unused (or harmful) noise is the thesis's exact failure and scores near zero here. **These are the KEY measures — the typed library is adopted only if it STRICTLY beats the naive transcript-embedding-search baseline on retrieval precision AND holds memory-no-harm, and does not regress the token budget (7.2).** ### 7.2 The companion + secondary instruments Report alongside the KEY measures; the secondaries report, do not gate on: 1. **Token budget of injected memory** — the companion: the token cost per actually-used memory card, and the distribution of injection budgets (how often the top-k was filled versus how often the smallest high-confidence set — often one — was returned). This measures the thesis's clause that retrieval returns the smallest high-confidence experience: a memory layer that always exhausts its budget is spending context on interference (ContextSniper's token-efficiency claim [14], SWE Context Bench's "unfiltered hurts" [21]). 2. **Cost** = `$ / instance` (model spend only; deterministic stages are ~free). **Tokens** = `tokens / instance`. **Secondary instruments (report, do not gate on):** 1. **Promotion survival rate** — what fraction of promoted rules and skills fire again and help, versus how many were promoted once and never retrieved again. A low survival rate means the distillation gate is too loose — the model is generating rules that read well and transfer nothing — and it drives the distillation-quality loop. 2. **Falsified-rule retirement rate** — how many harmful memories were actually retired, how many stale memories decayed on schedule, and how many duplicates merged, versus how many *should* have been (the audit computes the counterfactual from the MemoryStats record). A store that never retires anything is a warehouse accumulating noise. 3. **Cue-miss rate** — how often the retrieval cue failed to surface the one past episode that would have helped — the encoding-specificity failure made quantitative [23]. A high cue-miss rate means the store is indexed by content, not by the symptom a future task presents. 4. **Cross-repo contamination rate** — how often the hard scope filters fired (cross-repo or cross-phase candidates blocked before similarity) and how often a contamination incident was raised by `scope_redact`. A zero rate is not proof of safety; it is a signal to check that the namespace partition is actually installed, because a cross-repo leak is a security incident, not an indexing bug (P7). 5. **Evidence-gate rate** — of all distilled rules, what fraction carried resolvable evidence citations versus what fraction were admitted as bare claims. A distillation step whose rules cannot cite their evidence is producing unfalsifiable prose. ### 7.3 Ablation rule (mechanical) The instrument that enforces "never add a memory mechanism because it sounds sensible" mechanically. Two passes, everything else held fixed, the delta measured on the honest measures (retrieval precision + memory-no-harm + token budget + cost/tokens + secondaries): 1. **Ablate cue indexing** — store episodes by their own content, query by embedding similarity only: the direct test of P2 and the encoding-specificity rule. 2. **Ablate the scope filters** — drop the hard repository/phase/task-shape filters, let similarity run unconstrained: the direct test of P3/P7 and the CTIM-Rover warning. 3. **Ablate the lifecycle** — never promote, decay, deduplicate, or falsify: the direct test of P8 and the stale-memory failure mode. 4. **Ablate the single L distillation step** — **no-distill-vs-distill** (episodes-only vs episodes+distilled rules) on the KEY measures: the test of whether the bounded stub (§4) earns its single learned entry at all. A mechanism is **DELETED** iff its removal does **not** degrade the honest measures beyond noise (`Δ = 0`, or `|Δ| ≤ 5%` where continuous). A mechanism whose *addition* degrades the measures is a demonstrated harm and is removed outright. Applied first to the weakest a-priori case (the single L stub, which must survive the no-distill-vs-distill ablation to be kept), then to any other mechanism. **Never add a memory mechanism because it sounds sensible.** ### 7.4 Decision rule (explicit thresholds) Run library-vs-baseline on the *identical* corpus with the *identical* model (the harness's own weak model, `deepseek-v4-pro`) and hardware (this box). The typed library **wins iff**: ``` Retrieval precision STRICTLY beats the naive transcript-embedding-search baseline (KEY) AND memory-no-harm holds — injection never degrades below the no-memory condition (KEY) AND token budget of injected memory ≤ baseline (the smallest high-confidence discipline is cheaper) AND promotion survival rate not regressed (a falling survival rate = too-loose distillation) AND falsified-rule retirement rate not regressed (a zero retirement rate = accumulating noise) AND cue-miss rate not regressed (rising cue misses = indexing by content, not symptom) AND cross-repo contamination rate = 0 (a nonzero rate is a security incident, not an indexing bug) AND cost_library ≤ 1.5 × cost_baseline AND tokens_library ≤ 1.5 × tokens_baseline ``` Both KEY measures must hold — retrieval precision **strictly beats** the naive baseline, and memory-no-harm **holds**; the token budget must not regress; cost and tokens are bounded at 1.5×. **Never the end-to-end resolve rate alone** — resolve is component 14's measure, and a library that improves resolve while its injected cards are unused (or harmful) is **not adopted**. **Never introspective fluency or model self-assessment** — a library that reports the model's confidence that "memory helped" while its cards are unused noise scores *worse* and is rejected. If the library wins it replaces the naive transcript-embedding-search path; if it loses, the build tree is kept for the record and the live harness is unchanged. ### 7.5 Failure-mode audit (mechanical, the ways an episodic library can lie) 1. **Transcript hoarding** — everything stored, nothing indexed: retrieval returns noise and the agent learns to ignore memory entirely. Caught by the cue-miss rate and the retrieval-precision instrument (top-k always full but never used). 2. **Cue mismatch** — episodes stored by content and queried by symptom: the one relevant past fix never surfaces (encoding specificity violated [23]). Caught by the cue-miss rate and the write-time index audit. 3. **Poisoned memory** — a success misattributed to the wrong factor, promoting a bogus rule that ships in every future task: error propagation at library scale. Caught by the evidence-gate rate (a rule without a resolvable citation is refused) and the causal-attribution requirement. 4. **Fighting the last war** — a surface-similar episode hijacking retrieval, the agent rerunning a strategy from a different context: memory lock-in. Caught by the hard scope filters and the applicability predicate (a lesson is only trustworthy where it was earned). 5. **Stale memory** — the repo evolved but the library did not, old invariants firing wrongly and discrediting the store wholesale. Caught by the decay schedule and the falsification instrument (a memory contradicted by new evidence is retired loudly). 6. **Advice-flood** — top-k always filled regardless of relevance: the distractor economics wearing a helpful badge. Caught by the budget-efficiency instrument (a budget always exhausted is interference). 7. **Cross-task contamination** — client A's pattern leaking into client B's task: scoped namespaces skipped once, remembered forever. Caught by the scope-violation/contamination-rate instrument (a nonzero rate is a security incident, not an indexing bug). ### 7.6 Two honest caveats **First, the strong-model caveat:** the paper's headline numbers — ReasoningBank's 39.0 → 49.7 ablation [4], Structurally Aligned's +4.7pp [7], ExpeRepair's 60.3% Lite [10], PMCoder's +5.0pp [8] — will **NOT** reproduce on a weak model, and were measured on repositories and models far larger than a weak-model harness controls; a weak-model harness should expect materially smaller absolute effects while leaning all the harder on the typed stores, the scope filters, and the smallest-high-confidence discipline to make its small budget count. **Second, the held-out caution:** all memory metrics must be reported on held-out and out-of-benchmark task sequences, so a library that has memorized a task set's answers cannot score well on retrieval precision without its usefulness having been measured on problems it never saw. --- ## 8. Guardrails & Reversibility **Revocability.** - The build lives entirely in `build/20-episodic-coding-memory/`; it never writes into the live harness's source. - A **feature flag** (env var `EPIMEM=20library|transcript`, default `transcript`) routes the A/B; the flag alone switches between the typed library and the naive transcript-embedding-search baseline — no code deletion required to revert. - `ab.py` is a read-only driver: it *measures* the current harness, never modifies it. Running old-vs-new is always possible in the same session, repo, model. - The durable `CodingEpisode` / `CodingMemory` / `MemoryStats` stores are append-only and versioned; rolling the build back never loses them. A memory falsified by later evidence is kept with its usage record and its falsification notice — never silently dropped and never silently re-typed by a model. **Invariants (must hold, checked at the end of every phase).** 1. **The L column contains at most one entry** — distillation (§4), the one bounded, seeded call extracting the evidence-bound lesson from an episode, never re-prompted on parse failure. Any phase introducing a model elsewhere (deciding what to store, deciding what to index, ranking retrievals by feel, deciding whether an injected memory helped, or vetoing a retirement) is rejected outright. An **empty** L column (the stub ablated away in §7.3) is a permitted, correct state — never a violation. 2. **An episode is immutable and distinct from a claim** — the `CodingEpisode` record is never rewritten in place, and a distillation produces a derived `CodingMemory` that points back at it, never a replacement (E-mem's discipline [12]). 3. **A memory is indexed by future cues, not stored content** — the write-time cue index keys by error class, failure signature, repo area, task shape, language/framework, and harness phase; a memory indexed by its own content is a cue-mismatch failure (P2, encoding specificity [23]). 4. **Retrieval is smallest-high-confidence under budget** — the injection returns the smallest high-confidence top-k under an explicit token slice, formatted as advice not ground truth; an always-full top-k is an advice-flood (P6). 5. **Cross-repo contamination is a security incident** — the per-repo namespace is a hard partition, secrets are stripped at write time and again at retrieval, and a cross-repo or cross-client reference raises an incident, never an indexing bug (P7). 6. **Every memory carries a usage record** — the `MemoryStats` instrument accumulates retrieved/used/successful- after-use/harmful for every card; a card without a usage record is not a memory the library can be accountable for (P8). 7. **A memory that hurts is retired** — a card whose usage record flags it harmful is falsified loudly (a visible notice, never a silent delete), and a stale memory decays on schedule; a store that never retires anything is accumulating, not learning (P8). 8. **All metrics on held-out/out-of-benchmark task sequences** — the KEY measures and every secondary are reported on held-out task sequences, never tuning or in-benchmark data (§7). --- *End of spec. This document is the build contract; the next document records the A/B outcome.*