diff --git a/research/memory-atlas-r1/S-durable-runtimes/02_outward/crash_recovery.md b/research/memory-atlas-r1/S-durable-runtimes/02_outward/crash_recovery.md index 30c0540a..123a6a0b 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/02_outward/crash_recovery.md +++ b/research/memory-atlas-r1/S-durable-runtimes/02_outward/crash_recovery.md @@ -4,5 +4,9 @@ _Arm-3 §13 + arm-2 foundations. THE LARGEST UNCOVERED ROW IS SQLITE/FSYNC ITSEL ## The four-way split (verified pattern) MUST survive: the ordered record of what happened (journal/ledger) in a store that outlives the process. CAN recompute: decisions from replay; interrupted-step re-execution; catch-up within policy. MUST verify externally: everything about the outside world post-restart (no surveyed system trusts pre-crash beliefs). REMAINS UNKNOWN: in-flight external effects at crash time + the ledger tail after DB crash/partial fsync. +## SQLite/fsync reality (repair-closed 2026-09-20 — full detail: sqlite_fsync_crash_consistency.md) + +Rune's SQLite stores: process-crash-safe, consistent, atomic as observed. WAL+FULL DBs (behavior, abstraction, all opencode-memory) = documented full ACID incl. power-loss durability. Rollback+FULL DBs (store/memory.db, graph.sqlite) = "maybe not durable" last commit. cache.db = WAL+NORMAL by explicit choice (lossy by design). The JSON tmp+rename stores (waitstore — which uses NO SQLite — drift_ledger, ~10 writers) have NEITHER file nor directory fsync = Pillai's most common durability failure class; ext4 rename heuristics give undocumented protection, btrfs gives none. No store handles a failed fsync. Method caveat: PRAGMA synchronous is per-connection — audits must be code-based. T1 spec (not implemented): explicit FULL pragmas; EXTRA/WAL migration for rollback DBs; fsync+dir-fsync in _atomic_write; flush-window docs; tested fsync-error path. + ## Failure-specific recovery (attack-informed) Process crash → resume from last verified checkpoint (dedup + fencing). Host reboot → re-arm all non-expired waiters on boot (attack J). Power loss → torn-tail detection (framed writes) + checksummed checkpoints (attack U). DB crash / partial fsync → **UNCOVERED: Pillai OSDI'15 located not read; SQLite atomic-commit/WAL-recovery docs not researched this tranche — follow-up required before any durability claim is finalized** (the entire Rune durability story rests on SQLite). Provider disconnect → real status preserved (Tranche-16 law). Agent/controller restart → authority re-read (R8-proven pattern). diff --git a/research/memory-atlas-r1/S-durable-runtimes/02_outward/exactly_once_semantics.md b/research/memory-atlas-r1/S-durable-runtimes/02_outward/exactly_once_semantics.md index b637e6a1..674f0a0d 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/02_outward/exactly_once_semantics.md +++ b/research/memory-atlas-r1/S-durable-runtimes/02_outward/exactly_once_semantics.md @@ -9,5 +9,5 @@ _Arm-3 §3 (Kreps + Narkhede FULL READs; Kleppmann DDIA via single-source chain) - **at-least-once execution: the honest default for every Rune step.** - **exactly-once state transition: achievable INSIDE the SQLite ledger iff mutation + checkpoint share one transaction** (DBOS piggyback; S3 CAS for cross-writer races). - **effectively-once effect: external effects ONLY behind idempotency key + semantic-equivalence replay, or natural idempotency.** -- **exactly-once external effect: FORBIDDEN VOCABULARY** — unachievable under timeout-unknown-outcome; any design doc claiming it is a defect. +- **exactly-once external effect: not claimable for ARBITRARY external effects** — only where the effect participates in an atomic/transactional/idempotent protocol whose boundary actually covers that effect (transactional outbox; provider idempotency contract). Repair-scoped wording (2026-09-20): the blanket 'forbidden' phrasing overstated — protocol-covered effects can legitimately support exactly-once claims within their boundary. - unknown outcome: first-class (see unknown_outcome.md). diff --git a/research/memory-atlas-r1/S-durable-runtimes/02_outward/novelty_corrections_repair.md b/research/memory-atlas-r1/S-durable-runtimes/02_outward/novelty_corrections_repair.md new file mode 100644 index 00000000..9739810e --- /dev/null +++ b/research/memory-atlas-r1/S-durable-runtimes/02_outward/novelty_corrections_repair.md @@ -0,0 +1,36 @@ +# #394 repair — Novelty overclaim corrections (actor general-11, fresh context, 2026-09-20) + +_Persisted from the repair actor's report. Verdict: both novelty claims were overclaims; concrete prior art found; reclassifications below propagated through 04/claims/06/07/master per repair mandate §3–§4._ + +## 1. UNKNOWN_OUTCOME — the in-doubt/uncertain-commit lineage (prior art) + +| System | State name | When | Resolution | Distinction from FAILED | +|---|---|---|---|---| +| 2-phase commit (Gray 1978) | coordinator "uncertain"/in-doubt period | crash/partition between prepare-record write and durable decision confirmation | recovery consults coordinator log; retransmit decision; in-doubt participants BLOCK (forbidden to guess) | FAILED is decided-terminal; uncertain is pre-terminal — outcome exists but not locally knowable | +| X/Open XA (1991) | Heuristic outcomes: XA_HEURCOM / XA_HEURRB / XA_HEURMIX / **XA_HEURHAZ** ("may have been heuristically completed" — literally a named unknown-outcome code) | resource manager decides unilaterally during prolonged TM outage | reported outcomes of uncoordinated decision, possibly contradicting global | distinct return-code family from rollback/failure — protocol surface explicitly represents "unknown/mixed" | +| Oracle (19c DBA Guide Ch.35 — FULL READ) | "In-doubt transaction" — first-class named state: DBA_2PC_PENDING (STATE ∈ Collecting/Prepared/Committed/Forced Commit/Forced termination + MIXED column), DBA_2PC_NEIGHBORS | failure during any aspect of 2PC | AUTO: RECO background recoverer resolves when failure clears. MANUAL (DBA): COMMIT FORCE / ROLLBACK FORCE (+SCN); ALTER SESSION ADVISE COMMIT/ROLLBACK/NOTHING | STATE=Prepared lists global state as "**Unknown**", normal action "None" (wait for auto-recovery) — an explicit epistemic state, not a failure; distinct ORA-02050/02053/02054/01591 errors | +| MongoDB 4.0+ (manual FULL READ) | Error label `UnknownTransactionCommitResult` | commit sent, result unknown (network failure / primary stepdown) | retry COMMIT (not transaction) regardless of retryWrites; withTransaction auto-retries; contrast TransientTransactionError → retry whole transaction | commit errors split into THREE epistemic classes: succeeded / definitively-failed / unknown-and-retryable | +| Kafka (design doc section read) | unspecified ack-ambiguity | network failure after possible write | 0.11+: idempotent producer (PID+seq) makes retry safe; transactional.id aborts in-flight on restart | solves by dedup, not by exposing a state — weaker prior art for the state, canonical for the problem | +| Card payments (background) | authorization "pending" between auth and settlement | settlement message lost | reconciliation cycles; pending-timeout rules | pending ≠ approved ≠ declined — decades old | + +**Rune-specific residual assessed:** saga recovery managers (compensation-pending state), Temporal retry-pending, BPMN 2.0 compensation-pending — all analogous shapes. The only residual surface: a task-level first-class state over NON-TRANSACTIONAL HETEROGENEOUS tool calls with reconcile_by + escalation — an application-level design choice, not a new concept; no directly identical artifact found at that granularity in surveyed sources (framing-level distinction only). + +**CORRECTED CLASSIFICATION (adopted): UNKNOWN_OUTCOME = ADAPT of the established in-doubt/uncertain-commit concept (2PC uncertain period, Gray 1978; XA heuristic outcomes incl. XA_HEURHAZ 1991; Oracle in-doubt transactions with DBA_2PC_PENDING + RECO + COMMIT/ROLLBACK FORCE; MongoDB UnknownTransactionCommitResult with retryCommit). The general concept is long-established and NOT novel; the application-level distinction (task-level state over non-transactional heterogeneous tool effects, paired with reconcile_by/escalation) is the Rune-specific transfer.** + +## 2. Quiescence-as-completion — the termination-detection lineage (prior art) + +- **Dijkstra & Scholten, "Termination detection for diffusing computations," IPL 11(1):1–4, 1980** (via Wikipedia FULL READ): a process is idle (locally quiescent) while the computation is still active; termination requires an EXPLICIT detection protocol (signal/deficit accounting) — the algorithm exists precisely because local quiescence does not imply global termination. +- **Francez, "Distributed termination," ACM TOPLAS 2(1), 1980** (cited, not fetched): general detection; stabilization-vs-termination distinction. +- **Chandra & Toueg, unreliable failure detectors, JACM 43(2), 1996** (from knowledge, not fetched): a detector can only SUSPECT; confirmation requires timeouts + assumptions. Suspicion is explicitly not verdict. +- Schedulers/CI (background): timeout-on-silence → failure/neutral state, never success; runner-disconnect green-build bugs fixed by re-verifying final reports. + +**What Rune's incident adds:** a specific ANTI-PATTERN INSTANCE — conflating failure-detector semantics (absence of activity = suspicion at most) with OUTCOME semantics (terminal success requires positive evidence). The literature says silence → "not known terminated" (or → failed/timed out); nothing licenses silence → "succeeded." + +**CORRECTED CLASSIFICATION (adopted): "Quiescence-as-completion" is a documented ANTI-PATTERN INSTANCE of a foundational, decades-old principle — not a novel insight. The principle (local quiescence does not imply global termination; explicit detection required; suspicion ≠ confirmation) is foundational and NOT novel. Rune's contribution: documenting the conflation as an observed failure mode in agent-runtime task accounting. The Rune-specific phrase is retained as a useful label for the instance.** + +## 3. Root-error lesson (atlas-wide) + +Both overclaims share one root error: **citing the absence of a PHRASE MATCH ("UNKNOWN_OUTCOME", "quiescence-as-completion") as the absence of the CONCEPT.** Repair template (transferable): reclassify concept-level novelty claims as ADAPT unless the MECHANISM-level (not terminology-level) search fails. Applied to future domains. + +## Depth ledger +FULL READ: Oracle 19c Ch.35; MongoDB transactions ×2; JTA XAException javadoc; Wikipedia Dijkstra–Scholten; Wikipedia X/Open XA. SECTION+GREP: Kafka design doc. NOT FETCHED (background/secondary): Gray 1978; Francez 1980; Chandra–Toueg 1996; Garcia-Molina–Salem; Temporal docs; Slurm/CI docs; payment lifecycle; HTTP 425. diff --git a/research/memory-atlas-r1/S-durable-runtimes/02_outward/sqlite_fsync_crash_consistency.md b/research/memory-atlas-r1/S-durable-runtimes/02_outward/sqlite_fsync_crash_consistency.md new file mode 100644 index 00000000..3125db16 --- /dev/null +++ b/research/memory-atlas-r1/S-durable-runtimes/02_outward/sqlite_fsync_crash_consistency.md @@ -0,0 +1,63 @@ +# #394 repair — SQLite/fsync crash-consistency deep dive (actor general-10, fresh context, 2026-09-20) + +_Persisted from the repair actor's report. Closes the domain's one UNCOVERED row (repair mandate §5). Load-bearing corrections: Pillai is OSDI 2014 (not '15); Rune's SQLite posture is BETTER than the master implied; the real durability gap is the JSON tmp+rename stores._ + +## 1. SQLite primary-doc semantics (deep reads) + +- **Atomic Commit** (atomiccommit.html, §1–7 verbatim): transactions appear atomic even under OS crash/power failure; commit point = rollback-journal deletion. Assumptions: sector writes linear-not-atomic; PSOW assumed since 3.7.9; broken flush/fsync on some OS versions acknowledged ("nothing SQLite can do"); no redundancy for corruption detection. NORMAL in rollback mode carries a small corruption risk (mitigated by per-page checksums). Crash-test methodology: VFS shim injecting crashes at every commit step (TH3 basis). +- **WAL** (wal.html FULL): COMMIT = append to WAL; main DB untouched until checkpoint (default 1000 pages, PASSIVE). **KEY: "Writers sync the WAL on every transaction commit if synchronous=FULL but omit this sync if NORMAL"** — NORMAL+WAL = consistent+atomic but "transactions… might rollback following a power failure or hard reset." WAL unsafe over network FS (both Rune FS locations are local NVMe → safe). Checkpoints restartable; checkpointing itself syncs. WAL mode file-persistent. **Newly documented WAL-reset bug** (doc updated 2026-08-25): rare multi-connection race corrupting DB, fixed 3.51.3 — version-pin check warranted for bundled SQLite. +- **synchronous** (pragma.html verbatim): EXTRA(3) = FULL + dir-sync after journal unlink (DELETE mode; no different from FULL in WAL). FULL(2) = xSync before continuing — "operating system crash or power failure will not corrupt." Official matrix: FULL+rollback = "Maybe not durable"; **FULL+WAL = ACID (durable)**. NORMAL(1): WAL always consistent, loses durability on power loss; **"Transactions are durable across application crashes regardless of the synchronous setting or journal mode."** OFF(0): corruption possible. **synchronous is per-connection, NEVER persists; journal_mode=WAL is the only persistent mode** — RO-pragma audits silently return compile defaults; honest audit is code-based. +- **PSOW** (psow.html FULL): assumed ON for Unix VFS; torn pages within a DB page → automatic recovery, not corruption, provided storage honors PSOW. fullfsync = macOS-only (irrelevant on CachyOS). + +## 2. Pillai et al. — **OSDI 2014** (citation correction; PDF read: abstract, §1–2+Table 1, §3, §4.1–4.4 incl. SQLite passages, §5) + +- Persistence properties = atomicity + ordering; vary across file systems AND configurations of the same FS. +- The protocol: fsync data → fsync parent directory (for created files) → then rename/commit marker. Correctness depends on specific persistence properties. +- **60 static vulnerabilities (156 dynamic) across 11 systems** (incl. SQLite, PostgreSQL, Git, ZooKeeper); ~half manifest on current ext3/ext4/btrfs. +- **Atomic rename ≠ durability**: rename is atomic, but 7 of 11 applications had durability failures "often due to directory operations not being flushed." +- **SQLite-specific quote**: "SQLite does not provide durability under the default journal-mode… its documentation seems misleading" (rollback-mode FULL = "maybe not durable"; EXTRA required for strict last-commit durability — matches the pragma doc matrix exactly). +- Persistent failure classes even with correct fsync: cross-syscall atomicity; future-storage regressions; out-of-order directory persistence; config-dependent false security. + +## 3. Rune actual-settings audit (READ-ONLY; nothing modified) + +**Filesystems:** /mnt/workdrive = ext4 on local NVMe (rw, noatime → data=ordered + auto_da_alloc heuristics); /home = btrfs on local NVMe (rw, noatime, compress=zstd:1, ssd, discard=async). Both local → WAL safe. + +| Store | FS | journal_mode (file) | synchronous (code audit) | Classification (durability) | +|---|---|---|---|---| +| rune/memory/store/memory.db; graph.sqlite; issue161 memory.db/graph.sqlite | ext4 | delete (rollback) | **FULL by default** (no pragma-setting code) | **IMPLEMENTED_UNPROVEN** — rollback+FULL: C/A/X + "maybe not durable" last commit | +| rune behavior.db, abstraction.db | ext4 | wal | **FULL by default** (only journal_mode=WAL set) | **IMPLEMENTED_UNPROVEN, strongest tier** — WAL+FULL = documented full ACID | +| rune cache.db | ext4 | wal | **NORMAL explicit** (cache.py:156) | **PARTIAL** — consistent+atomic, NOT durable (acceptable for a cache; wrong for a ledger) | +| journal/events.jsonl (DurableEventStore) | ext4 | plain file | fsync per flush | **PARTIAL** — on-disk records append-durable; **in-memory batch buffer = designed durability window** on process crash | +| waitstore waits/*.json + events/*.json (mimo-wait-resume AND wr-bridge — **no SQLite anywhere**; "developer tooling, NOT Rune" per own header) | btrfs/ext4 | JSON + tmp+os.replace | **NO file fsync, NO dir fsync** (_atomic_write, waitstore.py:44–60) | **PARTIAL, weakest tier** — power loss can lose records entirely or expose torn/old state on FSes lacking ext4's rename heuristic | +| waitstore leases | — | ftruncate+write+**fsync(fd)** | content fsync'd; **no dir fsync** on create/release | **PARTIAL** (content-durable; directory-entry not) | +| ~/.config/opencode/memory/store/memory.db (457MB) + 7 WAL DBs | btrfs | wal | **FULL by default** (zero synchronous pragmas across scripts) | **IMPLEMENTED_UNPROVEN, strongest tier** — WAL+FULL | +| spine/current.json + await_intent_log.jsonl writers | ext4 | plain JSON | **writer code NOT LOCATED in audited trees — UNVERIFIED** | **IMPLEMENTED_UNPROVEN — audit gap remains** | +| ~10 other JSON writers (drift_ledger, auto_context, growth_delta, sleep_time, night_mode, etc.) | — | tmp+os.replace | **neither file nor dir fsync** | PARTIAL (same class as waitstore) | + +## 4. Guarantee matrix (C=consistency A=atomicity D=durability X=corruption-resistance) + +| Failure ↓ | Rollback+FULL | WAL+FULL | WAL+NORMAL | Rune as observed | +|---|---|---|---|---| +| Process crash | C A D X | C A D X | C A D X | C A D X everywhere ("durable across application crashes regardless of setting") | +| OS crash / hard reboot / power loss | C A X; **D "maybe not durable"** (EXTRA closes) | **C A D X — full ACID** | C A X; **D lost** (uncheckpointed WAL ≤1000 pages may vanish) | Mixed: WAL DBs keep D (FULL); rollback DBs lose last-commit D; cache.db loses D by design; JSON stores unprotected | +| Torn write | recovered (journal+checksums, PSOW assumed) | recovered (WAL checksums; invalid tail discarded) | same | Recovered, modulo lying-disk caveat | +| fsync lies / lying controller | X at risk ("nothing SQLite can do") | same | same | Unverifiable from userspace; no mitigation in Rune | +| Checkpoint interruption | n/a | restartable; no corruption | same (only sync points; interrupted = lose uncheckpointed commits, still consistent) | Same | +| Failed fsync (error ignored) | unspecified; Python surfaces exception — **Rune handles it nowhere** | same | same | Not handled anywhere | + +**What WAL+NORMAL "not durable" means concretely:** after power loss the DB opens cleanly (A/C/X hold) but the last N commits — WAL since last checkpoint, up to ~4MB — **silently roll back with no error and no gap marker**. For an append-only ledger: silently missing recent entries. + +## 5. Exact wording (adopted into master §21) + +"Rune's SQLite-backed stores are process-crash-safe, consistent, and atomic as observed: the rollback-journal DBs run at compile-default synchronous=FULL, and the WAL DBs run WAL+FULL because no code lowers synchronous — only cache.db explicitly sets NORMAL. Under WAL+FULL the SQLite documentation's own matrix grants full ACID including power-loss durability; under rollback+FULL the same matrix says 'maybe not durable' — the last commit can vanish on power loss (the exact gap Pillai et al. called out in OSDI'14). The JSON-file stores (waitstore waits/events, drift_ledger, ~10 other tmp+os.replace writers) rely on atomic rename with neither file fsync nor directory fsync, which Pillai identifies as the single most common application durability failure class (7 of 11 applications): on ext4 the auto_da_alloc rename heuristics give empirical, undocumented protection; on btrfs there is not even that. No Rune store can claim durability across power loss for the JSON stores, and no store anywhere handles a failed fsync." + +## 6. Required future T1 change (SPECIFICATION ONLY — not implemented per boundary) + +1. Ledger-grade SQLite DBs: explicit `PRAGMA synchronous=FULL` in each connect() (defaults are not an API contract); for strict last-commit durability on rollback-mode DBs, synchronous=EXTRA or migrate to WAL (WAL+FULL = documented full ACID). +2. cache.db: stay WAL+NORMAL, documented lossy-by-design; never point ledger code at it. +3. JSON stores: extend _atomic_write family with file fsync before os.replace + directory fsync after (the exact Pillai protocol) — on paths whose loss is not tolerable. +4. events.jsonl: shrink/document the flush batch window; flush before state transitions other processes consume. +5. Explicit, tested failure path for fsync errors on commit. + +## 7. Depth ledger +Deep: atomiccommit §1–7, wal.html (incl. 2026-08-25 WAL-reset bug addendum), pragma synchronous/journal_mode, psow. Relevant-sections: Pillai OSDI'14 PDF (pdftotext). Read: Rune code (memory_store, cache, behavior, graph_memory, drift_ledger, task_persist, event_store, waitstore full 337 lines) + PRAGMA/fsync greps; opencode scripts connect(). Direct RO measurement: 16 DBs (journal_mode file-persistent = trustworthy; synchronous per-connection = code-audited). NOT audited: spine/current.json + await_intent_log.jsonl writers (open gap). diff --git a/research/memory-atlas-r1/S-durable-runtimes/03_applicability.md b/research/memory-atlas-r1/S-durable-runtimes/03_applicability.md index b0b7e284..e0f0e415 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/03_applicability.md +++ b/research/memory-atlas-r1/S-durable-runtimes/03_applicability.md @@ -43,9 +43,9 @@ Rune's constraint set: single user; single machine; SQLite-centric; workflow cod | CRIU full-state snapshot | Live-process checkpoint | NO — resume-from-journal sufficient; fragility | No | **REJECT** | — | | Giant-context persistence | Convenience | NO — LangGraph unbounded-growth warning | No | **REJECT** | capsule derived from ledger | -## Headline counts (mechanically computed from the table above, sums to 31 rows) +## Headline counts (mechanically computed from the table above, sums to 30 rows) -**Row-derived (mechanism table): four COVERED · ten ADOPT · six ADAPT · one EXPERIMENT · eight REJECT · one PARK — sums to 31.** +**Row-derived (mechanism table): four COVERED · eleven ADOPT · six ADAPT · one EXPERIMENT · seven REJECT · one PARK — sums to 30.** Note on the engines: the workflow-engine category REJECTS as deployable infrastructure (8 REJECT rows) while its 7 transferable mechanisms appear as COVERED/ADOPT/ADAPT rows above — the category verdict and the mechanism verdicts are deliberately separable (arm 2). diff --git a/research/memory-atlas-r1/S-durable-runtimes/04_innovation.md b/research/memory-atlas-r1/S-durable-runtimes/04_innovation.md index 2c9511fe..0f305f76 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/04_innovation.md +++ b/research/memory-atlas-r1/S-durable-runtimes/04_innovation.md @@ -5,14 +5,14 @@ _2026-09-20. Innovation assessment under the strict standard: novelty requires n ## Candidate innovations and their fates ### I1. UNKNOWN_OUTCOME as a first-class, non-terminal state with bounded reconciliation -- **Status: CANDIDATE INNOVATION (strongest).** Arm-3 surveyed Temporal (timeout ⇒ failure ⇒ idempotent retry), Azure Durable Functions (full-text NO MATCH), Stripe/AWS-BL (design AROUND the unknown via keys, never a named state), DBOS, Kafka — **zero prior art for the state itself**. The industry absorbs the unknown into retry-with-key-and-see. -- **Content:** `RUNNING --timeout--> UNKNOWN_OUTCOME` (never directly FAILED); reconciliation (read-after-write probe) converts UNKNOWN → SUCCEEDED/FAILED; `reconcile_by` deadline → ESCALATED(human); retry from UNKNOWN only iff metadata proves idempotent-effect. Prior art exists for every COMPONENT (idempotency keys, reconciliation, semantic equivalence) — the STATE is the novelty, justified by Rune's non-idempotent third-party surface. -- **Falsifier:** a workflow system found representing a distinct unknown/non-terminal-outcome state with bounded reconciliation demotes this to ADAPT. +- **Status: ADAPT (reclassified 2026-09-20 repair — was CANDIDATE INNOVATION; overclaim corrected).** The repair-arm survey found the prior art the original search missed at the terminology level: 2PC's uncertain/in-doubt period (Gray 1978), XA heuristic outcomes incl. **XA_HEURHAZ** ("may have been heuristically completed" — a literally named unknown-outcome code, 1991), **Oracle in-doubt transactions** (DBA_2PC_PENDING with STATE=Prepared ⇒ global state "Unknown"; RECO auto-recovery ≈ reconcile_by; COMMIT/ROLLBACK FORCE ≈ escalation; MIXED flag — the full state-machine shape from the 1990s), MongoDB `UnknownTransactionCommitResult` (three-class commit-error taxonomy: succeeded / failed / unknown-and-retry-commit). Saga compensation-pending and BPMN intermediate states are adjacent. +- **What remains Rune-specific (application-level, not conceptual):** representing uncertain ARBITRARY EXTERNAL TOOL EFFECTS (non-transactional, heterogeneous, no 2PC/compensation contract) as a task-level state with reconcile_by deadlines and escalation over that surface. Framing-level distinction only. +- **Root error recorded (atlas-wide):** the original claim cited absence of a PHRASE MATCH as absence of the CONCEPT. Repair template: reclassify concept-level novelty as ADAPT unless the mechanism-level search fails. ### I2. Quiescence-as-completion fallacy (named failure class) -- **Status: CANDIDATE INNOVATION (naming + definition).** Arm-3 found NO documented system with the deadline_pending-as-success-like failure class — a finding-of-absence. Rune's own incident supplies the definition; SRE watchdog passages supply supporting (not identical) evidence. -- **Content:** the rule "completion claims require positive evidence (receipt, verified state, reconciliation record) — never absence of failure signals"; the six-concept deadline/timeout/SLA/polling-horizon/lease/cancellation-deadline separation whose conflation produces the fallacy. -- **Falsifier:** prior literature naming the class (would convert to ADAPT + citation). +- **Status: RECLASSIFIED (2026-09-20 repair) — documented ANTI-PATTERN INSTANCE of a foundational principle; the phrase is retained as a useful Rune label, the insight is NOT novel.** The termination-detection literature is the prior art: Dijkstra & Scholten (IPL 1980) — local quiescence does not imply global termination, explicit detection protocols required; Francez (TOPLAS 1980) — stabilization vs termination; Chandra–Toueg (JACM 1996) — failure detectors SUSPECT, never confirm. Rune's incident adds the specific instance: conflating failure-detector semantics (silence = suspicion at most) with OUTCOME semantics (success requires positive evidence) — the literature says silence → "not known terminated" or "failed"; nothing licenses silence → "succeeded." +- **Content retained:** the positive-evidence completion rule; the six-concept deadline/timeout separation whose conflation produces the instance. +- **Root error:** same phrase-match-as-concept-absence error as I1. ### I3. Per-step side-effect metadata bundle (side_effect_class / idempotency_key / external_commit_id / reversible / compensatable / duplicate_detection / unknown_outcome) - **Status: ADAPT (novel-as-bundle, not novel-as-parts).** Arm-3: no surveyed runtime declares all per step; each field's lineage individually citable (Stripe keys, AWS request-IDs, saga compensatable, CAS conditions). The four-class schema (NONE/IDEMPOTENT/KEYABLE/DESTRUCTIVE) declared at tool registration is the transferable engineering form. @@ -23,4 +23,4 @@ _2026-09-20. Innovation assessment under the strict standard: novelty requires n ## Net verdict -**Two strong candidates (I1, I2 — both findings-of-absence with Rune-incident grounding), one moderate (I4), one reclassified (I3 → ADAPT).** The domain's contribution is more governance than mechanism: the guarantee vocabulary (exactly-once external effect = FORBIDDEN term), the honest COMPENSATED semantics, and the completion-evidence rule. All carry explicit falsifiers. +**RECLASSIFIED PER REPAIR MANDATE §3–§4: I1 → ADAPT (in-doubt lineage found); I2 → anti-pattern instance of a foundational principle (termination-detection lineage); I3 → ADAPT (unchanged); I4 → CANDIDATE (moderate, falsifier attached).** The domain's remaining contribution is governance vocabulary and engineering form, not conceptual novelty. The domain's contribution is more governance than mechanism: the guarantee vocabulary (exactly-once external effect = FORBIDDEN term), the honest COMPENSATED semantics, and the completion-evidence rule. All carry explicit falsifiers. diff --git a/research/memory-atlas-r1/S-durable-runtimes/06_synthesis.md b/research/memory-atlas-r1/S-durable-runtimes/06_synthesis.md index 5767494e..5752263b 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/06_synthesis.md +++ b/research/memory-atlas-r1/S-durable-runtimes/06_synthesis.md @@ -19,7 +19,7 @@ The batched direction survives; two COVERED verdicts are OVERTURNED-as-stated (e | Fencing generation | Zombie writers | Stale writes rejected | Store checks tokens | Token bypass | (task_id, generation) | durable kernel | ADOPT | EXTERNALLY_ESTABLISHED (Kleppmann) | | Restart-intensity caps | Reboot storms | Bounded restarts | Crash classes bucketable | Budget mis-tuned | OTP-style budget | daemon | ADOPT | EXTERNALLY_ESTABLISHED (OTP) | | Poison-pill quarantine | Poison tasks | No infinite loops | Signature detectable | False quarantine | same-signature N → blocked | daemon | ADOPT | EXTERNALLY_ESTABLISHED (DLQ/OTP) | -| UNKNOWN_OUTCOME state | Timeout conflation | No false verdicts | Reconciliation possible | UNKNOWN rot | non-terminal + reconcile_by | task state model | ADOPT (novel) | RUNE_HYPOTHESIS (zero prior art) | +| UNKNOWN_OUTCOME state | Timeout conflation | No false verdicts | Reconciliation possible | UNKNOWN rot | non-terminal + reconcile_by | task state model | ADAPT (in-doubt lineage: 2PC/XA_HEURHAZ/Oracle/MongoDB) | RUNE_APPLICABLE | | Side-effect class metadata | Unknown retry safety | Per-class policy | Declared at registration | Mis-declaration | 4-class schema | tool registry | ADOPT (novel bundle) | RUNE_HYPOTHESIS | | Reconciliation probes | Resolve unknowns | UNKNOWN → verdict | Read-back possible | Probe itself fails | read-after-write on Gitea/APIs | recovery path | ADOPT | RUNE_APPLICABLE | | Admission gate | LLM-authored corruption | Valid intent only | Checkable pre-exec | False reject | schema+policy on args | tool dispatch | ADOPT (novel) | RUNE_HYPOTHESIS | diff --git a/research/memory-atlas-r1/S-durable-runtimes/07_qualification.md b/research/memory-atlas-r1/S-durable-runtimes/07_qualification.md index c3c5754e..ba0885ba 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/07_qualification.md +++ b/research/memory-atlas-r1/S-durable-runtimes/07_qualification.md @@ -13,7 +13,7 @@ _2026-09-20. Machine-verifiable qualification rows. Counts feed the gate's row-d | Q5 | Idempotency keys + dedup table | ADOPT | EXTERNALLY_ESTABLISHED | 0.9 | Stripe/AWS-BL FULL READs | | Q6 | Fencing generation on authority transfer | ADOPT | EXTERNALLY_ESTABLISHED | 0.85 | Kleppmann FULL READ; single-machine validity | | Q7 | Restart-intensity caps + poison-pill quarantine | ADOPT | EXTERNALLY_ESTABLISHED | 0.85 | OTP FULL READ; "diagnose before blind retry" enforcement | -| Q8 | UNKNOWN_OUTCOME first-class state + reconcile_by | ADOPT | RUNE_HYPOTHESIS | 0.7 | zero prior art (I1); Rune incident grounding | +| Q8 | UNKNOWN_OUTCOME first-class state + reconcile_by | ADAPT | RUNE_APPLICABLE | 0.75 | in-doubt lineage (2PC/XA/Oracle/MongoDB — repair survey); Rune-specific transfer over non-transactional tool surface | | Q9 | Per-step side_effect_class (4-class, registration-declared) | ADOPT | RUNE_HYPOTHESIS | 0.7 | novel bundle; lineage components verified | | Q10 | Reconciliation probes (read-after-write) | ADOPT | RUNE_APPLICABLE | 0.8 | AWS-BL semantic-equivalence doctrine | | Q11 | Admission gate before journaling | ADOPT | RUNE_HYPOTHESIS | 0.6 | attack V; #402-adjacent | @@ -34,7 +34,7 @@ _2026-09-20. Machine-verifiable qualification rows. Counts feed the gate's row-d | Q26 | CRIU full-state snapshots | REJECT | RUNE_APPLICABLE | 0.8 | fragile; journal sufficient | | Q27 | Giant-context persistence | REJECT | RUNE_APPLICABLE | 0.9 | LangGraph unbounded-growth documented | | Q28 | Instruction-level speculation (Netherite) | REJECT | RUNE_APPLICABLE | 0.85 | single machine; opposite needed | -| Q29 | QUIESCENCE-AS-COMPLETION named failure class | ADOPT | RUNE_PROVEN | 0.85 | Rune incident + finding-of-absence (I2) | +| Q29 | QUIESCENCE-AS-COMPLETION named anti-pattern instance | ADAPT | RUNE_APPLICABLE | 0.8 | termination-detection lineage (Dijkstra–Scholten 1980; Francez 1980; Chandra–Toueg 1996) + Rune incident as the instance | | Q30 | Guarantee vocabulary (exactly-once external effect = FORBIDDEN term) | ADOPT | RUNE_APPLICABLE | 0.85 | Kreps/Narkhede/DBOS boundary consistency | -**Row-derived: ADOPT 15 · ADAPT 7 · EXPERIMENT 1 · REJECT 7 · Sum 30.** +**Row-derived: ADOPT 13 · ADAPT 9 · EXPERIMENT 1 · REJECT 7 · Sum 30.** (Repair reclassification: Q8, Q29 ADOPT→ADAPT per novelty corrections.) diff --git a/research/memory-atlas-r1/S-durable-runtimes/S_DURABLE_RUNTIMES_R1_MASTER.md b/research/memory-atlas-r1/S-durable-runtimes/S_DURABLE_RUNTIMES_R1_MASTER.md index ab527c50..b4ea39e3 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/S_DURABLE_RUNTIMES_R1_MASTER.md +++ b/research/memory-atlas-r1/S-durable-runtimes/S_DURABLE_RUNTIMES_R1_MASTER.md @@ -6,9 +6,9 @@ _2026-09-20. Full stage pipeline with four independent evidence arms in fresh co Rune's event-driven continuation is genuinely proven — R8's live fault injection demonstrated watchdog-authority recovery at volume (390 waits, 9,119 events) — **and it is overstated**. The adversarial pass found the architecture lies to itself in three places: it believes events are never lost (at-least-once webhooks + daemon restarts = silent stalls), that heartbeats mean progress (a poisoned tool loop heartbeats happily for hours), and that resume capsules describe the world that moved on while the run slept. The batched R0's "event-driven continuation COVERED" verdict is OVERTURNED as stated and re-lands as ADAPT with concrete machinery: persisted waiters with boot re-arm, per-waiter poll fallback, and a STALLED state. -The deeper verdict is architectural restraint. The workflow-engine category (Temporal, Cadence, Durable Functions, Restate, Airflow…) transfers **zero deployable infrastructure** to a single-user local agent — and **seven core mechanisms that all fit inside Rune's existing SQLite database**: journal + replay (effect-sourced, not instruction replay — LLM outputs are recorded events, never recomputed), checkpoint-before-side-effect + dedup, durable timers as rows, fencing generations, restart-intensity caps + poison-pill quarantine, explicit task states with zombie detection, version-pinned runs. All five "no dedicated durable layer needed" excuses FAIL on evidence (the crash-between-world-and-ledger window alone, ~2% run-level exposure, closes the argument); all of durability's own risks are containable with chaos-tested recovery, default-deny escalation, and an admission gate that validates intent BEFORE journaling — because durability amplifies whatever it persists, including a confused LLM's corruption. +The deeper verdict is architectural restraint. No external workflow engine is currently justified for Rune V1; the mechanisms Rune needs can presently be implemented within its existing local SQLite/runtime architecture (the engines remain deployable-and-useful at fleet scale — the verdict is about Rune's current needs, not the engines' worth) — and **seven core mechanisms that all fit inside Rune's existing SQLite database**: journal + replay (effect-sourced, not instruction replay — LLM outputs are recorded events, never recomputed), checkpoint-before-side-effect + dedup, durable timers as rows, fencing generations, restart-intensity caps + poison-pill quarantine, explicit task states with zombie detection, version-pinned runs. All five "no dedicated durable layer needed" excuses FAIL on evidence (the crash-between-world-and-ledger window alone, ~2% run-level exposure, closes the argument); all of durability's own risks are containable with chaos-tested recovery, default-deny escalation, and an admission gate that validates intent BEFORE journaling — because durability amplifies whatever it persists, including a confused LLM's corruption. -Two findings-of-absence become the domain's novel contributions: **UNKNOWN_OUTCOME as a first-class, non-terminal state with bounded reconciliation** (zero surveyed prior art — the industry folds timeout into failure-and-retry, safe only when activities are idempotent, which Rune's third-party surface cannot guarantee) and the **quiescence-as-completion fallacy** (deadline_pending treated as success-like — no documented equivalent exists; Rune's own incident names it). The normative guarantee vocabulary closes the domain: exactly-once external effect is FORBIDDEN vocabulary; at-least-once execution is the honest default; exactly-once state transition exists only inside one SQLite transaction. +Two overclaims were CORRECTED in the 2026-09-20 repair (novelty → ADAPT): **UNKNOWN_OUTCOME** adapts the four-decade-old in-doubt/uncertain-commit lineage (2PC uncertain period, Gray 1978; XA heuristic outcomes incl. XA_HEURHAZ, 1991; Oracle in-doubt transactions — DBA_2PC_PENDING with STATE=Prepared ⇒ global 'Unknown', RECO auto-recovery ≈ reconcile_by, COMMIT/ROLLBACK FORCE ≈ escalation, MIXED flag; MongoDB UnknownTransactionCommitResult with retry-commit) to a task-level state over Rune's non-transactional heterogeneous tool surface — the general concept is long-established, NOT novel; the application-level transfer is the Rune-specific design. **Quiescence-as-completion** is a documented ANTI-PATTERN INSTANCE of the foundational termination-detection principle (Dijkstra & Scholten IPL 1980; Francez TOPLAS 1980; Chandra–Toueg JACM 1996: detectors suspect, never confirm) — Rune's incident documents the instance (conflating failure-detector semantics with outcome semantics); the principle is NOT novel. The normative guarantee vocabulary closes the domain, scoped per repair mandate §6: Rune must not claim exactly-once for arbitrary external effects unless the relevant effect participates in an atomic/transactional/idempotent protocol whose boundary actually covers that effect. The separate tiers stand: at-least-once execution (default) · exactly-once state transition inside one transactional authority · effectively-once externally via idempotency/dedup · arbitrary non-transactional external effects (no exactly-once claim available). ## 2. Rune inward baseline (read-only audit, 2026-09-20) @@ -48,7 +48,7 @@ Full Jitter >50% call reduction (Brooker FULL); un-jittered backoff SYNCHRONIZES ## 11. UNKNOWN_OUTCOME (mandate §16 — mandatory; the domain's novel contribution) -Zero surveyed prior art (Temporal folds; Durable Functions NO MATCH; Stripe/AWS-BL design around, never name). The FOR argument: timeout carries zero information about the effect; retry-without-reconciliation is safe only for provably idempotent ops (Temporal's precondition — Rune fails it); reconciliation is a distinct action needing a state to park in (its absence is how deadline_pending gets misread); four timeout types already stratified yet all collapse. The AGAINST steelman rebutted: no-prior-art explained (datacenter activities CAN be idempotent; Rune's cannot); rot prevented (non-terminal + reconcile_by → ESCALATED); "make everything idempotent" infeasible for irreversible effects. **Semantics: RUNNING --timeout--> UNKNOWN_OUTCOME (never directly FAILED); UNKNOWN --reconciliation--> SUCCEEDED | FAILED | re-deadlined; reconcile_by exceeded → ESCALATED(human); retry from UNKNOWN only iff metadata proves idempotent-effect. Probes resolve ~95% without user; alert if escalation >2%.** Detail: 02_outward/unknown_outcome.md. +ADAPT of the in-doubt/uncertain-commit lineage (repair-corrected 2026-09-20 — the original 'zero prior art' claim cited phrase-match absence as concept absence; the mechanism-level survey found Oracle in-doubt transactions as the full prior shape: DBA_2PC_PENDING, STATE=Prepared ⇒ global 'Unknown', RECO ≈ reconcile_by, COMMIT/ROLLBACK FORCE ≈ escalation; XA_HEURHAZ is a literally named unknown-outcome code from 1991; MongoDB's commit-error taxonomy splits succeeded/failed/unknown-and-retryable). What REMAINS true from the original survey: the mainstream agent-workflow systems surveyed (Temporal, Durable Functions) fold timeout into failure — the transfer to a task-level state over non-transactional tool effects is Rune's design work. The FOR argument: timeout carries zero information about the effect; retry-without-reconciliation is safe only for provably idempotent ops (Temporal's precondition — Rune fails it); reconciliation is a distinct action needing a state to park in (its absence is how deadline_pending gets misread); four timeout types already stratified yet all collapse. The AGAINST steelman rebutted: no-prior-art explained (datacenter activities CAN be idempotent; Rune's cannot); rot prevented (non-terminal + reconcile_by → ESCALATED); "make everything idempotent" infeasible for irreversible effects. **Semantics: RUNNING --timeout--> UNKNOWN_OUTCOME (never directly FAILED); UNKNOWN --reconciliation--> SUCCEEDED | FAILED | re-deadlined; reconcile_by exceeded → ESCALATED(human); retry from UNKNOWN only iff metadata proves idempotent-effect. Probes resolve ~95% without user; alert if escalation >2%.** Detail: 02_outward/unknown_outcome.md. ## 12. Checkpoints / resume capsules (mandate §17) @@ -80,7 +80,7 @@ Durable suspension verified (Durable Task: WaitForExternalEvent + durable timer ## 19. Completion semantics (mandate §24 — mandatory) -Nine-state taxonomy: SUCCEEDED (evidence-backed) / FAILED (confirmed) / CANCELLED / TIMED_OUT (feeds UNKNOWN) / INTERRUPTED / STALLED / UNKNOWN_OUTCOME / COMPENSATED / PARTIAL_SUCCESS (enumerate effects). **THE NAMED ANTI-PATTERN: quiescence-as-completion fallacy** — treating absence of activity as evidence of completion; no documented equivalent exists (finding-of-absence; Rune's incident supplies the definition; SRE watchdog passages support). **The rule: completion claims require POSITIVE evidence — receipt, verified state, or reconciliation record. Silence is not proof. Deadline-expiry is not success. Timeout is an observation about the wait, never a verdict on the effect.** +Nine-state taxonomy: SUCCEEDED (evidence-backed) / FAILED (confirmed) / CANCELLED / TIMED_OUT (feeds UNKNOWN) / INTERRUPTED / STALLED / UNKNOWN_OUTCOME / COMPENSATED / PARTIAL_SUCCESS (enumerate effects). **THE NAMED ANTI-PATTERN: quiescence-as-completion** (Rune label, retained) — treating absence of activity as evidence of completion. REPAIR-CORRECTED: this is an anti-pattern INSTANCE of the foundational termination-detection principle (Dijkstra & Scholten 1980; Francez 1980; Chandra–Toueg 1996) — the principle is NOT novel; Rune's incident documents the instance (silence = suspicion at most, never a success verdict). **The rule: completion claims require POSITIVE evidence — receipt, verified state, or reconciliation record. Silence is not proof. Deadline-expiry is not success. Timeout is an observation about the wait, never a verdict on the effect.** ## 20. Deadlines / timeouts (mandate §25) @@ -88,7 +88,9 @@ Five distinct concepts — deadline (absolute) / timeout (duration) / SLA (promi ## 21. Crash recovery (mandate §26) -The four-way split: MUST survive (the ordered record — journal); CAN recompute (decisions, interrupted steps, catch-up within policy); MUST verify externally (everything about the outside world — no surveyed system trusts pre-crash beliefs); REMAINS UNKNOWN (in-flight external effects; the ledger tail after DB crash/partial fsync). Per-failure matrix (06 §D): crash → checkpoint + dedup; reboot → re-arm waiters; suspend-wake → wall+mono rebase; lost webhook → poll fallback; timeout-mid-effect → UNKNOWN + probe; checkpoint corruption → last-2 fallback; provider swap → finish pinned or explicit migrate; dual-daemon → epoch stand-down. **UNCOVERED ROW: SQLite/fsync crash-consistency (Pillai OSDI'15 located not read) — REQUIRED FOLLOW-UP before any durability claim is finalized; Rune's entire durability story rests on SQLite.** +The four-way split: MUST survive (the ordered record — journal); CAN recompute (decisions, interrupted steps, catch-up within policy); MUST verify externally (everything about the outside world — no surveyed system trusts pre-crash beliefs); REMAINS UNKNOWN (in-flight external effects; the ledger tail after DB crash/partial fsync). Per-failure matrix (06 §D): crash → checkpoint + dedup; reboot → re-arm waiters; suspend-wake → wall+mono rebase; lost webhook → poll fallback; timeout-mid-effect → UNKNOWN + probe; checkpoint corruption → last-2 fallback; provider swap → finish pinned or explicit migrate; dual-daemon → epoch stand-down. + +**SQLite/fsync crash-consistency (the load-bearing gap, CLOSED by the 2026-09-20 repair — 02_outward/sqlite_fsync_crash_consistency.md):** Rune's SQLite-backed stores are process-crash-safe, consistent, and atomic as observed: the rollback-journal DBs (store/memory.db, graph.sqlite) run at compile-default synchronous=FULL, and the WAL DBs (behavior.db, abstraction.db, all opencode-memory DBs) run WAL+FULL because no code lowers synchronous — only cache.db explicitly sets NORMAL. Under WAL+FULL the SQLite documentation's own matrix grants full ACID including power-loss durability; under rollback+FULL the same matrix says "maybe not durable" — the last commit can vanish on power loss (the exact gap Pillai et al. called out in OSDI'14 — **citation correction: OSDI 2014, not 2015**). The JSON-file stores (waitstore waits/events — which use NO SQLite ("developer tooling, NOT Rune" per their own header) — plus drift_ledger and ~10 other tmp+os.replace writers) rely on atomic rename with **neither file fsync nor directory fsync**, which Pillai identifies as the single most common application durability failure class (7 of 11 applications): on ext4 the auto_da_alloc rename heuristics give empirical, undocumented protection; on btrfs there is not even that. No Rune store can claim durability across power loss for the JSON stores, and no store anywhere handles a failed fsync. Method caveat (load-bearing): PRAGMA synchronous is per-connection and never persists — durability audits must be code-based, not RO-pragma reads. Per-store classifications: WAL+FULL DBs = IMPLEMENTED_UNPROVEN (strongest tier); rollback+FULL = IMPLEMENTED_UNPROVEN; cache.db = PARTIAL (lossy by design); events.jsonl = PARTIAL (in-memory batch window); waitstore JSON = PARTIAL (weakest tier); spine/current.json + await_intent_log writers = UNVERIFIED (writer code not located — audit gap). Required T1 specification (NOT implemented per boundary): explicit synchronous=FULL pragmas; EXTRA or WAL migration for strict last-commit durability; file+directory fsync in the _atomic_write family; flush-window documentation; tested fsync-error path. ## 22. Distributed boundary (mandate §27 — the #395 seam) @@ -104,11 +106,11 @@ The five no-layer excuses refuted (A: crash-window; C: sampling-vs-history confu ## 25. Applicability (mandate §30) -31 mechanisms filtered (03_applicability.md, sums to 31): four COVERED; ten ADOPT; six ADAPT; one EXPERIMENT; eight REJECT; one PARK. (Mechanism-table classification — distinct from the 30-row qualification ledger in 07; totals there are row-derived separately.) The headline: **every multi-machine assumption is unnecessary at Rune's scale, and every surviving mechanism fits in the existing SQLite database.** The contribution is missing TABLES (intent, effect, waiter, lease, generation, approval, version) and missing STATES (UNKNOWN_OUTCOME, STALLED, COMPENSATED) — not a new system. +30 mechanisms filtered (03_applicability.md, sums to 30): four COVERED; eleven ADOPT; six ADAPT; one EXPERIMENT; seven REJECT; one PARK. (Mechanism-table classification — distinct from the 30-row qualification ledger in 07; totals there are row-derived separately.) The headline: **every multi-machine assumption is unnecessary at Rune's scale, and every surviving mechanism fits in the existing SQLite database.** The contribution is missing TABLES (intent, effect, waiter, lease, generation, approval, version) and missing STATES (UNKNOWN_OUTCOME, STALLED, COMPENSATED) — not a new system. ## 26. Innovations (mandate §31) -I1 UNKNOWN_OUTCOME first-class state (zero surveyed prior art; falsifier: a system found with the state). I2 quiescence-as-completion fallacy (named from Rune's incident; falsifier: prior literature naming it). I3 per-step metadata bundle → ADAPT (novel-as-bundle; components individually cited). I4 admission gate before journaling (moderate; falsifier: prior pre-journal validation gates). All with falsifiers; detail: 04_innovation.md. +I1 UNKNOWN_OUTCOME → ADAPT (in-doubt lineage found by repair survey; the Rune-specific residue is the application-level transfer over non-transactional tool effects). I2 quiescence-as-completion → anti-pattern instance of a foundational principle (phrase retained as label). Root error recorded atlas-wide: phrase-match absence ≠ concept absence; reclassify concept-level novelty as ADAPT unless the mechanism-level search fails. I3 per-step metadata bundle → ADAPT (novel-as-bundle; components individually cited). I4 admission gate before journaling (moderate; falsifier: prior pre-journal validation gates). All with falsifiers; detail: 04_innovation.md. ## 27. Independent adversarial results (mandate §32) @@ -120,11 +122,11 @@ Five matrices in 06_synthesis.md: MECHANISM (29 rows × 9 properties — with ow ## 29. R0 reconciliation (mandate §34) -CONFIRMED 5 · OVERTURNED 1 · Sum 6 (r0_reconciliation.md). The OVERTURNED row: "event-driven waits COVERED" — edge-triggered waits without persisted re-arm silently stall. The convergent-lineage thesis is CONFIRMED and strengthened. Cross-domain #393 leads (judge versioning, verdict expiry) treated as hypotheses: version binding (Q12) inherits the pattern; verdict expiry is NOT re-asserted here (owner: #393). +CONFIRMED 6 · OVERTURNED 1 · Sum 7 (r0_reconciliation.md). The OVERTURNED row: "event-driven waits COVERED" — edge-triggered waits without persisted re-arm silently stall. The convergent-lineage thesis is CONFIRMED and strengthened. Cross-domain #393 leads (judge versioning, verdict expiry) treated as hypotheses: version binding (Q12) inherits the pattern; verdict expiry is NOT re-asserted here (owner: #393). ## 30. Batched reconciliation (mandate §34) -CONFIRMED 6 · REFINED 3 · OVERTURNED 1 · Sum 10 (preliminary_reconciliation.md). Batched direction right; under-counted (reconciled 5 rows); missed the event-driven overstatement and both citation defects (Maraschi ID wrong; S3Mirror scope needed refining). Detail: §29–30 + preliminary_reconciliation.md. +CONFIRMED 7 · REFINED 3 · OVERTURNED 0 · Sum 10 (preliminary_reconciliation.md). Batched direction right; under-counted (reconciled 5 rows); missed the event-driven overstatement and both citation defects (Maraschi ID wrong; S3Mirror scope needed refining). Detail: §29–30 + preliminary_reconciliation.md. ## 31. Claim conclusions (mandate §35) @@ -132,11 +134,11 @@ CONFIRMED 6 · REFINED 3 · OVERTURNED 1 · Sum 10 (preliminary_reconciliation.m ## 32. Qualification (mandate §38) -30 rows machine-verified (07_qualification.md): **ADOPT 15 · ADAPT 7 · EXPERIMENT 1 · REJECT 7 · Sum 30.** Evidence levels held separate: RUNE_PROVEN 4 (all in-repo, R8/T21-line), EXTERNALLY_ESTABLISHED 8, RUNE_APPLICABLE 10, RUNE_HYPOTHESIS 6 (novel/zero-prior-art items honestly at hypothesis grade). +30 rows machine-verified (07_qualification.md): **ADOPT 13 · ADAPT 9 · EXPERIMENT 1 · REJECT 7 · Sum 30.** (Repair reclassification: Q8/Q29 ADOPT→ADAPT.) Evidence levels held separate: RUNE_PROVEN 4 (all in-repo, R8/T21-line), EXTERNALLY_ESTABLISHED 8, RUNE_APPLICABLE 10, RUNE_HYPOTHESIS items reduced by repair reclassification (Q8, Q29 → ADAPT/RUNE_APPLICABLE; remaining hypotheses are the genuinely unsourced bundles). ## 33. Machine-computed invariants (mandate §39) -R0: 6 (5/0/1) · Batched: 10 (6/3/1) · Adversarial: 23 (8/10/5) · Qualification: 30 (15/7/1/7) · Sources: 47 rows · Claims: 12 · Saturation: 17 branches. All narrative totals match row-derived counts (reconciliation_arithmetic_check.txt; gate-enforced). +R0: 7 (6/0/1) · Batched: 10 (7/3/0) · Adversarial: 23 (8/10/5) · Qualification: 30 (13/9/1/7) · Sources: 47 rows · Claims: 12 · Saturation: 17 branches. All narrative totals match row-derived counts (reconciliation_arithmetic_check.txt; gate-enforced). ## 34. Architecture implications @@ -156,11 +158,11 @@ E1 crash-matrix: kill -9 at every journal boundary (baseline: current restart sc ## 37. Remaining unknowns -SQLite/fsync crash-consistency (REQUIRED follow-up — Pillai OSDI'15 + SQLite atomic-commit docs). Approval-binding practice (no source). Checkpoint-corruption checksum practice (no source). BG-depth classics (ARIES, Gray & Reuter, Gray 1985, HotOS 2003, Armstrong). Temporal worker-versioning latest. Whether Rune's cron.json/systemd supervise the W/R daemon (supervisor recursion, unverified). +SQLite/fsync crash-consistency: CLOSED as to semantics and observed configuration (repair 2026-09-20); remaining unknowns = spine/current.json + await_intent_log.jsonl writer code (not located), lying-controller behavior (unverifiable from userspace), and the T1 implementation of the specified hardening. Approval-binding practice (no source). Checkpoint-corruption checksum practice (no source). BG-depth classics (ARIES, Gray & Reuter, Gray 1985, HotOS 2003, Armstrong). Temporal worker-versioning latest. Whether Rune's cron.json/systemd supervise the W/R daemon (supervisor recursion, unverified). ## 38. Evidence saturation (mandate §36) -17 branches; REACHED for all load-bearing decisions with one honest uncovered row (17: SQLite-fsync — converted to REQUIRED follow-up) and one gap converted to falsifier (15: approval binding). Late finds (attack V/R, Maraschi correction) prove early saturation would have been false. Detail: evidence_saturation.md. +17 branches; REACHED for all load-bearing decisions; the one uncovered row (17: SQLite-fsync) was CLOSED by the 2026-09-20 repair (deep docs + Pillai OSDI'14 + code audit) and one gap converted to falsifier (15: approval binding). Late finds (attack V/R, Maraschi correction) prove early saturation would have been false. Detail: evidence_saturation.md. ## 39. Final mutation audit (mandate §40) @@ -168,7 +170,7 @@ FINAL-STATE audit in mutation_audit.md, written AFTER closeout actions. Categori ## 40. Bibliography (mandate §35 — anchor sources) -FULL reads: Brooker backoff+jitter; Finagle budgets; SRE ch.22/24; Fowler CircuitBreaker + Event Sourcing; Colyer ×2 (Tail-at-Scale; Leases); Kleppmann fencing; Stripe docs + blog; AWS-BL Featonby; Kreps; Narkhede; Temporal (activity-failures/timeouts/retry/versioning/replay); Durable Functions (error-handling/human-interaction); LangGraph persistence; DBOS; Confluent schema; gRPC deadlines; SQS DLQ; S3 conditional writes ×2; OTP supervisors; Orleans; rr; Airflow tasks. ABS: microreboot cs/0406005; Netherite 2103.00033 (+VLDB DOI); Maraschi 2607.13617 (CORRECTED from 2609.17645); Khan 2606.17182 (CONFIRMED); Vasquez-Grinnell 2506.10886 (REFINED: S3Mirror/DBOS). SECONDARY: Gray & Cheriton (via Colyer); Chubby §2.4 (via quote). BG-flagged: ARIES; Gray & Reuter; Gray 1985; HotOS 2003; Armstrong; Sagas 1987 (DOI located, PDF binary). LOCATED-NOT-READ: Pillai OSDI'15 (required follow-up). Full ledger with depth flags: sources.md. +FULL reads: Brooker backoff+jitter; Finagle budgets; SRE ch.22/24; Fowler CircuitBreaker + Event Sourcing; Colyer ×2 (Tail-at-Scale; Leases); Kleppmann fencing; Stripe docs + blog; AWS-BL Featonby; Kreps; Narkhede; Temporal (activity-failures/timeouts/retry/versioning/replay); Durable Functions (error-handling/human-interaction); LangGraph persistence; DBOS; Confluent schema; gRPC deadlines; SQS DLQ; S3 conditional writes ×2; OTP supervisors; Orleans; rr; Airflow tasks. ABS: microreboot cs/0406005; Netherite 2103.00033 (+VLDB DOI); Maraschi 2607.13617 (CORRECTED from 2609.17645); Khan 2606.17182 (CONFIRMED); Vasquez-Grinnell 2506.10886 (REFINED: S3Mirror/DBOS). SECONDARY: Gray & Cheriton (via Colyer); Chubby §2.4 (via quote). BG-flagged: ARIES; Gray & Reuter; Gray 1985; HotOS 2003; Armstrong; Sagas 1987 (DOI located, PDF binary). Pillai et al. crash-consistency: RELEVANT-SECTIONS read (OSDI 2014 — citation corrected from '15). Full ledger with depth flags: sources.md. ## 41. Artifact pointers (mandate §37) diff --git a/research/memory-atlas-r1/S-durable-runtimes/claims.json b/research/memory-atlas-r1/S-durable-runtimes/claims.json index 53fd52c5..c0882bc3 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/claims.json +++ b/research/memory-atlas-r1/S-durable-runtimes/claims.json @@ -63,9 +63,12 @@ }, { "id": "S-R1-C004", - "claim": "UNKNOWN_OUTCOME as a first-class, non-terminal state with bounded reconciliation (reconcile_by \u2192 ESCALATED) is required by Rune's non-idempotent tool surface and has ZERO surveyed prior art \u2014 a novel contribution.", + "claim": "UNKNOWN_OUTCOME as a task-level, non-terminal state with bounded reconciliation (reconcile_by \u2192 escalation) is an ADAPT of the established in-doubt/uncertain-commit lineage (2PC uncertain period Gray 1978; XA heuristic outcomes incl. XA_HEURHAZ 1991; Oracle in-doubt transactions with DBA_2PC_PENDING + RECO + COMMIT/ROLLBACK FORCE; MongoDB UnknownTransactionCommitResult with retryCommit) \u2014 applied over Rune's heterogeneous, non-transactional tool surface. The general concept is long-established and NOT novel; the application-level transfer (task-level state over arbitrary tool effects with reconcile_by/escalation) is the Rune-specific design.", "evidence_for": [ - "arm3 \u00a74 full survey (Temporal folds timeout\u2192failure; Durable Functions NO MATCH; Stripe/AWS-BL design around, never name)", + "Oracle in-doubt: DBA_2PC_PENDING, STATE=Prepared \u21d2 global 'Unknown', RECO auto-recovery, COMMIT/ROLLBACK FORCE, MIXED flag (FULL READ)", + "XA XA_HEURHAZ = literally named unknown-outcome code (1991 standard)", + "MongoDB UnknownTransactionCommitResult: succeeded/failed/unknown-and-retryable taxonomy (FULL READ)", + "2PC uncertain period (Gray 1978)", "Rune incident class (deadline_pending success-like)", "reconciliation probes resolve ~95% (G-mitigation)" ], @@ -78,27 +81,29 @@ "transfer_assumptions": "third-party surface cannot be made wholly idempotent", "owner": "task state model", "architecture_impact": "new state + transitions + escalation queue", - "classification": "ADOPT", + "classification": "ADAPT", "evidence_level": "RUNE_HYPOTHESIS", "experiment": "E5 UNKNOWN-rate + escalation-rate measurement", - "falsifier": "a surveyed system with the state (demotes to ADAPT)", + "falsifier": "\u2014 (prior art FOUND; claim is now the transfer, not the novelty)", "kill_criterion": "escalation rate >2% sustained or UNKNOWN rot incidents" }, { "id": "S-R1-C005", - "claim": "QUIESCENCE-AS-COMPLETION is a named, Rune-grounded failure class with no documented prior equivalent: completion claims require positive evidence (receipt / verified state / reconciliation record), never absence of failure signals.", + "claim": "QUIESCENCE-AS-COMPLETION (Rune label) is a documented ANTI-PATTERN INSTANCE of the foundational termination-detection principle (Dijkstra & Scholten IPL 1980: local quiescence does not imply global termination, explicit detection required; Francez TOPLAS 1980; Chandra\u2013Toueg JACM 1996: failure detectors suspect, never confirm). The principle is NOT novel. Rune's contribution: documenting the instance \u2014 conflating failure-detector semantics (silence = suspicion) with outcome semantics (success requires positive evidence) \u2014 as an observed failure mode in agent-runtime task accounting, with the positive-evidence completion rule as the design response.", "evidence_for": [ + "Dijkstra & Scholten 1980 (via Wikipedia FULL READ)", + "Francez 1980 (cited)", + "Chandra\u2013Toueg 1996 (knowledge-cited)", "Rune incident (deadline_pending success-like)", - "SRE ch.22/24 supporting passages", - "arm3 finding-of-absence" + "SRE ch.22/24 supporting passages" ], "evidence_against": [], "rune_evidence": "documented continuation lesson partially encoded; completion proof ABSENT for open-ended tasks", "transfer_assumptions": "\u2014", "owner": "completion semantics", "architecture_impact": "nine-state taxonomy; evidence rule in state machine", - "classification": "ADOPT", - "evidence_level": "RUNE_PROVEN (in-house incident)", + "classification": "ADAPT", + "evidence_level": "RUNE_APPLICABLE", "experiment": "E6 completion-claim audit on task history", "falsifier": "prior literature naming the class", "kill_criterion": "\u2014" diff --git a/research/memory-atlas-r1/S-durable-runtimes/evidence_saturation.md b/research/memory-atlas-r1/S-durable-runtimes/evidence_saturation.md index e2b77226..1696cf38 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/evidence_saturation.md +++ b/research/memory-atlas-r1/S-durable-runtimes/evidence_saturation.md @@ -20,6 +20,6 @@ _17 branches. Saturation declared when late searches stop finding new recovery m | 14 | Compensation / sagas | SATURATED for verdict (primary UNVERIFIED-flagged; verdict doesn't rest on it) | | 15 | Human approval | GAP (durable suspension verified; binding practice NO SOURCE FOUND — I-falsifier carried) | | 16 | Completion semantics + deadlines | SATURATED (gRPC/Temporal FULL; finding-of-absence recorded) | -| 17 | Crash recovery / SQLite-fsync | **UNCOVERED ROW: Pillai OSDI'15 located not read; SQLite atomic-commit docs not researched — REQUIRED FOLLOW-UP before any durability claim is finalized** | +| 17 | Crash recovery / SQLite-fsync | **CLOSED by 2026-09-20 repair**: SQLite primary docs deep-read; Pillai OSDI'14 relevant-sections read (citation corrected); Rune settings audited read-only (code-based — synchronous is per-connection); guarantee matrix + per-store classifications + T1 spec produced | -**Saturation verdict: REACHED for all load-bearing decisions, with ONE honest uncovered row (17) converted to a required follow-up, TWO flagged gaps converted to falsifiers (15, approval binding), and all BG-depth classics flagged.** Late finds (attack V admission gate, attack R timer drift, Maraschi citation correction) arrived through the adversarial arm — early saturation would have been false. +**Saturation verdict: REACHED for all load-bearing decisions; the one uncovered row (17) was CLOSED by the repair; TWO flagged gaps converted to falsifiers (15, approval binding); all BG-depth classics flagged.** Late finds (attack V admission gate, attack R timer drift, Maraschi citation correction) arrived through the adversarial arm — early saturation would have been false. diff --git a/research/memory-atlas-r1/S-durable-runtimes/mutation_audit.md b/research/memory-atlas-r1/S-durable-runtimes/mutation_audit.md index 1df25d4e..91c05b0d 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/mutation_audit.md +++ b/research/memory-atlas-r1/S-durable-runtimes/mutation_audit.md @@ -20,13 +20,34 @@ _DRAFT during tranche; FINAL-STATE section appended after closeout actions (mand Any action after the FINAL-STATE section that performs a canonical memory write, DB write, schema/config change, package install, service mutation, or production-code change marks this audit STALE and requires a rerun before any final verdict that depends on it. -## FINAL-STATE audit (appended AFTER closeout actions, mandate §40) +## FINAL-STATE audit (appended AFTER closeout actions, mandate §40; counts made explicit per repair mandate §8, re-run after repair closeout) -- **CANONICAL_MEMORY_WRITE = session summaries only** (verdict-summary adds; dedupe-defect instances carried as evidence, not fixed). -- **SESSION_NOTES_WRITE = session scratchpad appends only.** +- **PRODUCTION_CODE_MUTATION = NONE.** +- **PRODUCTION_SCHEMA_MUTATION = NONE.** +- **PRODUCTION_RUNTIME_BEHAVIOR_MUTATION = NONE.** +- **CANONICAL_MEMORY_WRITE = 1** (the #394 verdict-summary add via the normal memory-store mechanism; recorded with dedupe receipt — see instance log; text authoritative in the Gitea closeout comment). +- **SESSION_NOTES_WRITE = 2** (session scratchpad appends: tranche-close entry + this repair's entry; non-canonical, session-scoped). +- **RESEARCH_TOOLING_MUTATION = YES (1):** scripts/research_gate_check.py extended (repair mandate §2) with row-derived reconciliation/applicability total checking (r0, preliminary, 03_applicability vs their own summary lines and master reference lines; digit-or-word number parsing; explicit header-cell detection). Research governance tooling only; negative controls demonstrated; regression green on Q/P and R-after-fix. +- **GITEA_MUTATION:** #394 reopened + start comment #5775; tranche closeout comment + CLOSED R1_FULL; #375 note; repair addendum (this closeout); #395 untouched. +- **RESEARCH_ARTIFACT_MUTATION:** S-durable-runtimes/ = 00, 01, 02_outward/ ×30 (README + 3 arm files + arm-4 at root + 24 topic files + novelty-corrections + sqlite-fsync reports), 03, 04, 05 + verbatim pass, 06, 07, sources.md, claims.json (12), r0/preliminary reconciliations, evidence_saturation, arithmetic check, mutation_audit, master; batched preserved byte-for-byte; registry S row → R1_FULL; R-domain r0 summary corrected (gate-caught stale narrative). - **RESEARCH_TOOLING_MUTATION = NONE this tranche** (gate script unchanged; no new research tooling required — the staleness + row-derived checks from prior repairs covered every drift the gate caught this tranche: qualification-sum error, table-collision, registry grade, audit staleness). - **GITEA_MUTATION (complete):** #393 addendum #5772; #394 reopened + start comment #5775; closeout comment + CLOSED R1_QUALIFIED (R1_FULL); #375 note; #395 untouched. - **RESEARCH_ARTIFACT_MUTATION (complete):** S-durable-runtimes/ = 00, 01, 02_outward/ (README + 3 arm files + arm-4 at root + 24 topic files), 03, 04, 05 + verbatim pass, 06, 07, sources.md, claims.json (12), r0/preliminary reconciliations, evidence_saturation, arithmetic check, mutation_audit, master; batched preserved byte-for-byte; registry S row → R1_FULL; gate arithmetic corrections recorded (qualification sum 30 not 28 — Q29/Q30 omitted in first narrative; mechanism-table totals spelled out to avoid mechanical collision with qualification aggregates). - **RESEARCH_RESULT_AFFECTED = NO** (adversarial re-scoping and gate fixes happened during the tranche). - **RESEARCH_ONLY_BOUNDARY = HELD.** - **Stale-audit rule reasserted:** this FINAL-STATE section is authoritative as of closeout. + +## REPAIR-PHASE FINAL-STATE addendum (2026-09-20, repair mandate §8 — authoritative as of repair closeout) + +Repair actions since the tranche FINAL-STATE section: arithmetic narratives corrected from canonical rows (R0 6→7 rows; preliminary 6/3/1→7/3/0; mechanism 31→30 with ADOPT 11/REJECT 7); gate hardened (item 2); novelty corrections propagated (items 3–4: Q8/Q29 ADOPT→ADAPT, qualification now 13/9/1/7); SQLite/fsync gap closed (item 5); exactly-once + workflow-engine wording scoped (items 6–7); R-domain stale r0 summary corrected (gate-caught, separate commit). + +- **PRODUCTION_CODE_MUTATION = NONE.** +- **PRODUCTION_SCHEMA_MUTATION = NONE.** +- **PRODUCTION_RUNTIME_BEHAVIOR_MUTATION = NONE.** +- **CANONICAL_MEMORY_WRITE = 1** (the #394 repair verdict-summary add via the normal memory-store mechanism; text authoritative in the Gitea addendum). +- **SESSION_NOTES_WRITE = 1** (this repair's scratchpad entry; non-canonical). +- **RESEARCH_TOOLING_MUTATION = YES (1):** scripts/research_gate_check.py — row-derived reconciliation/applicability checks (parse_verdict_table_rows with digit-or-word numbers, explicit-header detection, bold-tolerant cells, summary-line-only checks; master-reference-line cross-checks); negative controls demonstrated (wrong R0/preliminary/applicability totals all rejected); regressions green (Q/P/S pass; R fixed and passing). Research governance tooling only. +- **GITEA_MUTATION:** repair evidence/proof addendum on #394 + #375 note (this closeout); #395 untouched. +- **RESEARCH_ARTIFACT_MUTATION:** S-folder repair edits (r0/preliminary/03 narratives, 04 reclassification, claims C004/C005, 06 synthesis row, 07 totals 13/9/1/7, master §§1/11/21/26/32/37/38, new 02_outward/novelty_corrections_repair.md + sqlite_fsync_crash_consistency.md, saturation branch 17 closed, arithmetic check); R-folder r0 + master line (gate-caught stale); gate script; registry S row unchanged (already R1_FULL). +- **RESEARCH_RESULT_AFFECTED = NO** (arithmetic corrections + novelty reclassifications + gap closure are precision repairs; the substantive architecture — missing-tables-not-new-systems, adversarial union, guarantee vocabulary — is unchanged). +- **Stale-audit rule reasserted:** this REPAIR-PHASE section is authoritative as of repair closeout. diff --git a/research/memory-atlas-r1/S-durable-runtimes/preliminary_reconciliation.md b/research/memory-atlas-r1/S-durable-runtimes/preliminary_reconciliation.md index 9a3d87d5..8aea2847 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/preliminary_reconciliation.md +++ b/research/memory-atlas-r1/S-durable-runtimes/preliminary_reconciliation.md @@ -15,4 +15,4 @@ _Batched sources: S_DURABLE_RUNTIMES_R1_BATCHED_PRELIMINARY.md (combined-master | "REJECT (unbounded queues, in-place mutation)" | CONFIRMED | — | | "R0: CONFIRMED 4 · REFINED 1 · OVERTURNED 0 · Sum 5" | REFINED | full R0 pass: CONFIRMED 5 · OVERTURNED 1 · Sum 6 (batched under-counted: reconciled 5 rows, missed the event-driven COVERED claim's overstatement) | -**Row-derived: CONFIRMED 6 · REFINED 3 · OVERTURNED 1 · Sum 10.** +**Row-derived: CONFIRMED 7 · REFINED 3 · OVERTURNED 0 · Sum 10.** diff --git a/research/memory-atlas-r1/S-durable-runtimes/r0_reconciliation.md b/research/memory-atlas-r1/S-durable-runtimes/r0_reconciliation.md index 54c4b769..9e62fb8b 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/r0_reconciliation.md +++ b/research/memory-atlas-r1/S-durable-runtimes/r0_reconciliation.md @@ -12,4 +12,4 @@ _R0 source: research/memory-atlas/families/operating_systems_distributed.md §S | Idempotent repair actions ADAPT | CONFIRMED | Stripe/AWS-BL semantics verified; op_id + dedup table specified | | In-place mutation REJECT | CONFIRMED | append-only discipline re-validated by all arms | -**Row-derived: CONFIRMED 5 · REFINED 0 · OVERTURNED 1 · Sum 6.** +**Row-derived: CONFIRMED 6 · REFINED 0 · OVERTURNED 1 · Sum 7.** diff --git a/research/memory-atlas-r1/S-durable-runtimes/reconciliation_arithmetic_check.txt b/research/memory-atlas-r1/S-durable-runtimes/reconciliation_arithmetic_check.txt index 0e07d3af..b9aa44ff 100644 --- a/research/memory-atlas-r1/S-durable-runtimes/reconciliation_arithmetic_check.txt +++ b/research/memory-atlas-r1/S-durable-runtimes/reconciliation_arithmetic_check.txt @@ -3,15 +3,17 @@ Method: counts derived by row-grep from canonical files (r0_reconciliation.md, preliminary_reconciliation.md, 05_adversarial.md row block, 07_qualification.md, sources.md, claims.json, evidence_saturation.md), then narrative totals compared. -R0 reconciliation rows: 6 (CONFIRMED 5 · REFINED 0 · OVERTURNED 1) -Preliminary reconciliation: 10 (CONFIRMED 6 · REFINED 3 · OVERTURNED 1) +R0 reconciliation rows: 7 (CONFIRMED 6 · REFINED 0 · OVERTURNED 1) +Preliminary reconciliation: 10 (CONFIRMED 7 · REFINED 3 · OVERTURNED 0) Adversarial rows: 23 (SUCCEEDS 8 · PARTIAL 10 · FAILS 5) -Qualification rows: 28 (ADOPT 13 · ADAPT 7 · EXPERIMENT 1 · REJECT 7) +Qualification rows: 30 (ADOPT 13 · ADAPT 9 · EXPERIMENT 1 · REJECT 7 — post-repair reclassification Q8/Q29) Source rows: 47 entries across 4 sections + 1 no-source register Claim rows: 12 (S-R1-C001..C012) Saturation branches: 17 (15 SATURATED/PARTIAL→SATURATED, 1 GAP, 1 UNCOVERED→follow-up) -Checks: sums verified by grep -c on row patterns; qualification ADOPT 13 + -ADAPT 7 + EXPERIMENT 1 + REJECT 7 = 28 = row count; adversarial 8+10+5 = 23; -r0 5+0+1 = 6; preliminary 6+3+1 = 10. All narrative totals in master §31–32 -match these row-derived numbers. Gate research_gate_check.py check PASS. +Checks: sums verified by row-grep patterns; qualification ADOPT 13 + +ADAPT 9 + EXPERIMENT 1 + REJECT 7 = 30 = row count (post-repair); adversarial 8+10+5 = 23; +r0 6+0+1 = 7; preliminary 7+3+0 = 10; mechanism table 4+11+6+1+7+1 = 30. +All narrative totals match row-derived numbers. Gate PASS. (Repair 2026-09-20: +R0 6→7 rows, preliminary 6/3/1→7/3/0, mechanism 31→30 rows with ADOPT 11/REJECT 7 +— all previously stale narratives corrected from canonical rows per repair mandate §1.)