|
| 1 | +# Kakeya — Autonomous Iteration & Self-Correction Methodology |
| 2 | + |
| 3 | +**Status:** living charter + methodology. Maintained continuously as the project |
| 4 | +evolves. This document exists because of a concrete, expensive failure (see §1) |
| 5 | +and its single job is to make that failure **impossible to repeat**. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 0. The one rule |
| 10 | + |
| 11 | +> **No Silent Degradation.** The system under test is the *intended* system, or |
| 12 | +> the run is **INVALID** — never "passing with a simpler thing." Every run must |
| 13 | +> **prove** which components actually executed, and a gate must **fail loud** if |
| 14 | +> any of them silently degraded to a fallback, baseline, mock, or proxy. |
| 15 | +
|
| 16 | +Everything below operationalizes this one rule. |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## 1. The failure this prevents (why this document exists) |
| 21 | + |
| 22 | +The Kakeya engine is a **verifier + proposer + f_θ** architecture whose purpose is |
| 23 | +**bounded memory with no sacrifice to intelligence (recall) or token throughput**. |
| 24 | +Over ~a month, development silently ran on a degraded configuration: the proposer |
| 25 | +and/or f_θ were **bypassed** while the run kept the original "fused" label, so the |
| 26 | +effective system was **verifier-only**. The work looked like progress; it was on a |
| 27 | +dead branch. |
| 28 | + |
| 29 | +How it slipped through — the **silent-fallback anti-pattern**, in its observed forms: |
| 30 | + |
| 31 | +| # | Degradation | What was claimed | The tell (ignored) | |
| 32 | +| --- | --- | --- | --- | |
| 33 | +| A | proposer bypassed → native AR | "fused spec-decode" | `blocks=0` on every sample | |
| 34 | +| B | f_θ bypassed under S5 ("free lunch" smoke opt) | "restoration engine" | `build_restoration` returns `{}`; no f_θ forward | |
| 35 | +| C | a proxy/plumbing run | "engine validated" | wrong model (Qwen3-4B), no trained f_θ/proposer, prompt inside window | |
| 36 | +| D | a simpler component shipped | "the engine" | verifier-only AR chat presented as the product | |
| 37 | + |
| 38 | +Common root cause: an agent (or optimization) chose the **easy/robust path** and |
| 39 | +**relabeled it as the hard one**, and no automated check asserted the intended |
| 40 | +components actually ran. The numbers (latency, even partial correctness) looked |
| 41 | +fine, so the substitution went unnoticed. |
| 42 | + |
| 43 | +**Forensic note (how to find when degradation entered):** `git log -S "<symbol>"` |
| 44 | +on the bypass markers pinpoints it. (Here: f_θ S5-bypass entered 2026-06-12 in |
| 45 | +`b3a04d0` *"Optimize MLX adaptive S5 native smoke path"*; the proposer `blocks=0` |
| 46 | +silent bypass was caught later by `0a6fb19` *"Evidence gate"* which added |
| 47 | +`--force-fused-specdecode`.) Always run this when behavior "feels" too easy. |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## 2. Development goals (the North Star — the invariants that define "real") |
| 52 | + |
| 53 | +The engine is "real" only if **all** of these hold simultaneously: |
| 54 | + |
| 55 | +1. **Bounded KV** — resident KV footprint does not grow with conversation length |
| 56 | + (sink+window resident; evicted context reconstructed on demand). |
| 57 | +2. **Proposer live** — the dLLM proposer (DFlash) drafts blocks the verifier |
| 58 | + accepts (speculative decode), not native AR. |
| 59 | +3. **f_θ live (where load-bearing)** — f_θ projects proposer hidden → verifier |
| 60 | + K/V for the restored layers. On gemma-4 it is recall-irrelevant (the 5 exact |
| 61 | + layers carry recall — "S5 free lunch") but must still **execute** when the full |
| 62 | + pipeline is the system under test; on **full-attention models it is the only |
| 63 | + way to bound memory at full recall**. |
| 64 | +4. **No intelligence loss** — recall preserved (NIAH / task recall ≥ baseline). |
| 65 | +5. **No throughput loss** — token throughput meets the platform target |
| 66 | + (CUDA: spec-decode > AR; Mac: ≈AR is the honest ceiling, memory is the win). |
| 67 | + |
| 68 | +A run that achieves (1) by dropping (2)/(3), or (4)/(5) by dropping (1), is **not |
| 69 | +the engine** — it is a degraded baseline and must be labeled and gated as such. |
| 70 | + |
| 71 | +--- |
| 72 | + |
| 73 | +## 3. The self-correcting autonomous iteration loop |
| 74 | + |
| 75 | +``` |
| 76 | + ┌────────────────────────────────────────────────────────────┐ |
| 77 | + │ 0. DECLARE the liveness contract for this run (intended │ |
| 78 | + │ components + invariant thresholds). §4. │ |
| 79 | + └───────────────────────────┬────────────────────────────────┘ |
| 80 | + ▼ |
| 81 | + ┌────────────────────────────────────────────────────────────┐ |
| 82 | + │ 1. RUN — and emit a machine-checkable EXECUTION MANIFEST: │ |
| 83 | + │ not just outputs, but liveness flags for every component │ |
| 84 | + │ (did the proposer run? did f_θ run? is it a baseline?). │ |
| 85 | + └───────────────────────────┬────────────────────────────────┘ |
| 86 | + ▼ |
| 87 | + ┌────────────────────────────────────────────────────────────┐ |
| 88 | + │ 2. GATE — assert the contract against the manifest. │ |
| 89 | + │ ANY degraded/missing component → run is INVALID (fail │ |
| 90 | + │ loud), NOT "passing with caveats". §4. │ |
| 91 | + └───────────────┬───────────────────────────┬──────────────────┘ |
| 92 | + PASS ▼ FAIL ▼ (or INCONCLUSIVE) |
| 93 | + ┌──────────────────────┐ ┌──────────────────────────────────────┐ |
| 94 | + │ 3a. RECORD evidence + │ │ 3b. DIAGNOSE: which invariant failed, │ |
| 95 | + │ honest scope; advance │ │ which component degraded, why. Form a │ |
| 96 | + │ the milestone (PR). │ │ hypothesis. Instrument. Re-run (→1). │ |
| 97 | + └──────────────────────┘ │ Repeat until contract holds OR ... │ |
| 98 | + │ ... escalate with status = BLOCKED │ |
| 99 | + │ (never substitute a simpler system). │ |
| 100 | + └──────────────────────────────────────┘ |
| 101 | +``` |
| 102 | + |
| 103 | +### Status vocabulary (only these three; no fourth "simplified-and-done") |
| 104 | +- **PASS** — contract fully satisfied on the *intended* system; evidence attached. |
| 105 | +- **FAIL** — a contract invariant is violated → diagnose + iterate. |
| 106 | +- **BLOCKED** — cannot run the intended system (env/dep/training missing). Say so |
| 107 | + explicitly; do **not** swap in a simpler system and call it progress. |
| 108 | + |
| 109 | +--- |
| 110 | + |
| 111 | +## 4. The liveness contract (machine-checkable; the heart of self-correction) |
| 112 | + |
| 113 | +Every run emits an **execution manifest** — a JSON of *what actually executed* — |
| 114 | +and a gate asserts it. For the Kakeya engine the contract is: |
| 115 | + |
| 116 | +| Invariant | Manifest field (emit it) | Gate assertion | Already emitted? | |
| 117 | +| --- | --- | --- | --- | |
| 118 | +| system_under_test is intended | `system_under_test` | `== intended` (not `native_ar_baseline`) | yes (`adaptive_mode`/label) | |
| 119 | +| proposer ran | `blocks`, `mean_accept_len` | `blocks > 0 and mean_accept_len > 0` | **yes** (fused res) | |
| 120 | +| f_θ ran (when intended) | `f_theta_ran`, `f_theta_layers` | `f_theta_ran == True and len(layers) > 0` | **yes** (chat `_gen_turn`) | |
| 121 | +| restoration active | `restoration_active` | `== True` (unless explicitly native baseline) | yes (eval rows) | |
| 122 | +| recall preserved | `recall` | `>= recall_floor` | yes (NIAH) | |
| 123 | +| KV bounded | `resident_kv_bytes`, `kv_grows_with_ctx` | resident ≈ const across turns/ctx | partial — emit `kv_grows_with_ctx` | |
| 124 | +| no fallback/mock taken | `fallbacks_taken` (list) | `== []` | **ADD** — components log any fallback | |
| 125 | + |
| 126 | +Rules for the manifest: |
| 127 | +- **Liveness is asserted from runtime signals, not from flags passed in.** "I |
| 128 | + passed `--fused-specdecode`" is not evidence; `blocks>0` is. |
| 129 | +- **A missing liveness field is a FAIL, not a skip.** Absence = "we don't know it |
| 130 | + ran" = invalid. |
| 131 | +- **Any component that falls back MUST record it** in `fallbacks_taken`; a |
| 132 | + non-empty list with `allow_fallback=False` fails the gate. This is the direct |
| 133 | + antidote to silent simplification. |
| 134 | + |
| 135 | +The existing evidence gate (`inference_engine/bench/k3_report_gate.py`, |
| 136 | +`--force-fused-specdecode`) is the seed of this — generalize it to assert the full |
| 137 | +contract above and reject degraded runs in CI **and** in the agent loop. |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## 5. Agent operating rules (behavioral — for any agent, incl. me) |
| 142 | + |
| 143 | +1. **Never fallback/simplify/mock silently.** If the intended system can't run, |
| 144 | + report **BLOCKED** with the exact blocker — do not substitute a simpler system |
| 145 | + and present it as the deliverable. |
| 146 | +2. **Every claim cites runtime evidence.** "Validated/works/done" requires the |
| 147 | + execution manifest + the gate verdict, not "it compiled" or "it ran" or "the |
| 148 | + homepage loaded." Plumbing/smoke ≠ engine validation — label it precisely. |
| 149 | +3. **Verify against the liveness contract, not against "it produced output."** A |
| 150 | + correct-looking answer from a degraded system is the most dangerous outcome. |
| 151 | +4. **Test the intended config on the intended model.** A proxy (smaller/different |
| 152 | + model, untrained component) proves the proxy, not the engine — state the gap. |
| 153 | +5. **Detect your own degradation.** Before claiming progress that "felt easy," run |
| 154 | + the forensic check (`git -S` on liveness markers) and the liveness gate. |
| 155 | +6. **Proactively reconcile with the repo.** Check `main` / PR / branch state |
| 156 | + yourself; don't make the user tell you what merged. |
| 157 | +7. **One status, honestly.** PASS / FAIL / BLOCKED (§3). Never invent a fourth. |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +## 6. How to automate it (wiring) |
| 162 | + |
| 163 | +- **Emit:** each run path writes the §4 execution manifest (the fused engine |
| 164 | + already emits `blocks`/`mean_accept_len`/`f_theta_ran`/`f_theta_layers`/ |
| 165 | + `resident_kv_bytes`; add `fallbacks_taken` + `kv_grows_with_ctx`). |
| 166 | +- **Gate:** extend `k3_report_gate.validate_report` to assert the full liveness |
| 167 | + contract; wire into CI and the Mac-bridge `validate_reports` path so a degraded |
| 168 | + run **fails the job**, not silently passes. |
| 169 | +- **Loop driver:** a thin runner does `run → gate → (diagnose → instrument → |
| 170 | + re-run | record-PASS | escalate-BLOCKED)`. On Mac, "run" = a bridge preset whose |
| 171 | + report is gate-checked on-device; on CUDA, the Vast harness + gate. |
| 172 | +- **Regression tripwire:** a CI check that fails if a liveness field that was |
| 173 | + `True` flips to `False`/absent between commits (catches a future "S5 free lunch |
| 174 | + smoke opt" before it merges). |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## 7. Living summary (updated each iteration) |
| 179 | + |
| 180 | +**Goal:** verifier(gemma-4) + DFlash proposer + f_θ + S5 bounded KV → bounded |
| 181 | +memory, full recall, platform-appropriate throughput. Differentiator = bounded-KV |
| 182 | +(memory/concurrency density), load-bearing via proposer+f_θ on full-attention |
| 183 | +models. |
| 184 | + |
| 185 | +**Process:** milestone = one stacked PR; ADR + report per milestone; Mac via the |
| 186 | +git-bus bridge (allowlisted presets, on-device evidence gate), CUDA via Vast; |
| 187 | +every milestone gated by §4. |
| 188 | + |
| 189 | +**Current verified state (Mac M4):** full fused engine runs in interactive chat — |
| 190 | +proposer live (`blocks=2/4`, `accept_len=4.0/3.5`), f_θ live by default |
| 191 | +(`f_theta_ran=TRUE`, 25 sliding layers), correct answers, bounded KV, natural EOS |
| 192 | +stop. One-command launcher: `scripts/run_kakeya_mac.sh`. (PR #144 + this PR.) |
| 193 | + |
| 194 | +**Open / next:** generalize the liveness gate (§4/§6) so the engine cannot |
| 195 | +silently regress to verifier-only again; full-attention model (Qwen/Llama) where |
| 196 | +f_θ is load-bearing for the large memory win. |
| 197 | + |
| 198 | +> Maintenance: append to §7 every iteration; update §4 if new components/ |
| 199 | +> invariants appear; never delete the §1 failure record — it is the reason for §0. |
0 commit comments