From 66a18bfb7f0a748dc0238ec884a64b4a8e4fca5c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 11:20:38 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20record=20founder=20approval=20of=20PR?= =?UTF-8?q?=20#7;=20promote=20arm=20(f)=20=E2=80=94=20WRITE=5FLOST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #7 merged as e7e89dc on explicit founder approval, quoted in the entry. That closes the invariant 9 requirement: the change can convert phantom missing_current_fact FAILs into passes, so it needed sign-off before merge. The retry-vs-single-shot deviation was ratified. Promotes the first live namespace-arm result, reported not observed here: arm (f) came back WRITE_LOST — a swallowed write never became retrievable across 25 reads over 120s. That localises the mechanism to delete_all. Per-key delete followed by an immediate write landed at 0s in arms (a), (b) and (c); the namespace-wide delete_all that reset() performs loses the write for at least two minutes. Content dedup and same-scope reaping stay ruled out. The per-key substitution in the earlier arms is confirmed as why they all passed. Flags a sizing risk rather than leaving it to be discovered on a metered run: the shipped sentinel loop is bounded at 30s, while (f) shows the condition persisting for at least 120s under single-write polling. Re-issuing may converge far sooner — that is the difference the retry loop exploits and (f) cannot measure — but it is unmeasured, so _CONVERGE_TIMEOUT stays at 30s until the empty_to_writable_s series sizes it from data. Records what is still missing for the promotion rule: (g)'s outcome and the results filename for the (f) run. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EqxND2pAdrMMubjBnp3VLR --- HANDOFF.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/HANDOFF.md b/HANDOFF.md index 847413c..0033a00 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -2685,3 +2685,105 @@ worth knowing. External launch remains **HELD**. --- +## 2026-08-04 — Founder approval recorded; arm (f) FAILED, the mechanism is real + +### 1. What shipped + +`fix(mem0): reset() proves the namespace is writable, never sleeps` — merged to +`main` as **`e7e89dc`** (PR #7, rebase). + +**Founder approval, per the gated-tier mechanism.** PR #7 was labelled +`needs-founder-review` and held unmerged pending a ruling. Approved +2026-08-04 by the founder, verbatim: + +> Approved. Retry loop is the right call — arm (f) showed a swallowed write +> never becomes retrievable (25 reads / 120s), so re-issuing is the only thing +> that can resolve it and single-shot would abort runs unnecessarily. Merge. + +That closes the invariant 9 requirement: the change can convert phantom +`missing_current_fact` FAILs into passes, so it needed sign-off before merge, +and this is the record of it. The retry-vs-single-shot deviation flagged on the +PR was explicitly ratified. + +### 2. Findings — **arm (f) FAILED** + +**Reported, not observed here.** From the founder's approval message. This is +the first live result for the namespace arms. + +| Arm | Outcome | Evidence | +|---|---|---| +| `f_namespace_delete_all` | **WRITE_LOST** | swallowed write never retrievable — 25 reads over 120s | + +25 reads at the diagnostic's 5s poll interval is the full `CONFIRM_TIMEOUT` +window. The write was acknowledged and then never appeared, for two minutes. + +**What this establishes.** Read against the arms already run: + +| Delete mechanism | Arms | Result | +|---|---|---| +| per-key delete by id | (a), (b), (c) | all RE_ADD_VISIBLE, 0s | +| namespace `delete_all` | **(f)** | **WRITE_LOST, 120s** | + +The mechanism is **specific to `delete_all`**. It is not content-level dedup +(ruled out by (b)), not same-scope delete reaping (ruled out by (a)/(c)) — it +is the namespace-wide delete, which is the one `reset()` performs and the one +no arm tested until now. The per-key substitution in (a)-(e) is confirmed as +the reason those arms all passed. + +**It also directly validates the retry design.** Polling a swallowed write for +120s produced nothing. That is the empirical form of the argument made on the +PR before this result was known here: polling harder cannot resolve a +swallowed write, only re-issuing can. A single-shot sentinel would have turned +this condition into an aborted run. + +### 3. Open — and one of these is a sizing risk + +**(g) is not yet reported.** Without it the transient-vs-persistent question +stays open, and the pre-stated readings diverge sharply: + +- (f) LOST + (g) VISIBLE → the reaping window is bounded and a settle clears + it; the sentinel loop will converge. +- (f) LOST + (g) LOST → `delete_all` suppresses writes for longer than 60s, + which would make it unusable as a reset primitive and would mean the + sentinel loop cannot converge either. + +**Sizing risk, flagged now rather than after a wasted run.** The shipped +sentinel loop is bounded by `_CONVERGE_TIMEOUT` = **30s**, with 5s per +attempt. Arm (f) shows the condition persisting for **at least 120s** when a +single write is polled. If the reaping window genuinely exceeds 30s, then +`reset()` will exhaust its budget and raise — the *safe* outcome, and far +better than silently losing facts, but it would abort runs at every reset that +deletes. + +Re-issuing may well converge much sooner than 120s, since each new write is a +fresh attempt rather than a wait on a dead one — that is precisely the +difference the retry loop exploits, and (f) cannot measure it because it never +re-issues. **But it is unmeasured.** The `empty_to_writable_s` series now +emitted on every deleting reset is what sizes `_CONVERGE_TIMEOUT` honestly; if +attempts routinely run to the ceiling, raise it from data rather than guessing. + +**Missing for the promotion rule.** No results filename was supplied for the +(f) run, so this entry cites none — contrary to the rule added on 2026-08-03. +Also unknown: whether (a)-(e) re-ran in the same execution, the SEARCH spend, +and (g)'s outcome. Please supply the `diagnostics/results/…json` filename so +the raw output can be found again. + +### 4. Decisions + +- **Merged on explicit approval**, quoted above, per the gated-tier mechanism. + The instruction to build the change was not treated as approval to merge it. +- **`_CONVERGE_TIMEOUT` left at 30s for now.** Raising it on the strength of a + number measured under a different procedure (single write, no re-issue) + would be guessing. The series will size it. + +### 5. Next + +1. Report (g), and the (f) results filename. +2. Full 15 × 2 regen, capturing stderr — it now yields the + `empty_to_writable_s` series, which sizes the sentinel budget. +3. Promote the `003` abort with its curve. +4. Founder ruling before any published text changes. + +External launch remains **HELD**. + +---