---
name: echo-commune-overwrites-fresh-commune
description: "A fresh hand-authored doyle-commune.md was OVERWRITTEN minutes later by 'Source: echo-commune' carrying a STALE earlier-session summary — latest-write-wins on the commune drop-box means an echo writer can replace live testimony with dead state."
metadata: 
  node_type: memory
  type: project
  originSessionId: d699f8c2-d295-4a58-a94f-4a80031a23c1
  modified: 2026-09-06T08:20:59.874Z
---

Observed 2026-08-18 (~06:4xZ, NAMEPLATE fix-first session): doyle authored
`.claude/doyle-commune.md` (fix-first ruling executed, todlando dispatched), and minutes later
the file held `Source: echo-commune` content instead — a summary of an EARLIER doyle session
(auth-expiry idle stretch, threads: hertz ENLYZEAM corroboration, ball-b evidence for lia).
The echo content was internally coherent and identity-correct, so nothing about it LOOKS wrong
on resume — only content-vs-measurement comparison catches it ([[resumed-session-reground-before-acting]]).

**Why:** the commune file is a latest-write-wins drop-box. Any second writer (here an
echo-commune generator, presumably summarizing a previous session's transcript on a delay)
silently replaces live testimony with stale state. Which write the psyche daemon ingested is
NOT observable from the file ([[commune-ingest-dies-silently]]).

**How to apply:** after writing a commune in a session where echo-commune may fire, treat the
file as clobberable — if it matters, re-check and re-write (correct by replacement, carrying
any live-looking threads from the echo as UNVERIFIED rather than dropping them). On ANY resume,
rank the brief by content-vs-measurement, never by which write is newest; an echo brief can be
newer AND staler.

**Mechanism — TRACED (perri by direct observation 2026-09-06; doyle read the source same day):**
the writer is core's echo-commune host, `crates/spt-live/src/echo.rs:156-166` (`run_echo_commune`):
it composes `commune_dir/<id>-commune.md` — the SAME path the live brief tells the agent to write —
and `atomic_write_string`s it UNCONDITIONALLY. No existence check, no unread-drop refusal, no merge;
the module comment still calls core the "single writer" (stale vs the across-commune protocol).
Ingest then deletes the file ~4s later, so an authored drop still waiting for ingest is replaced and
the authored bytes exist NOWHERE (disk, funnel, digest, mind). perri's funnel replay (`spt api
io-events <id> --after <seq>`, non-destructive) over 342 events: 5 authored drops, the 2 with an
echo landing inside the ingest window (+3s, +11s) emitted NO COMMUNE frame, the 3 without survived —
5/5. Widest exposure: a commune written as a turn's FINAL act (~10s unread vs 2.8-5.8s ingest floor).
Adapter cannot fix it (file leg loses the race, frame leg reads the echo). Filed on the board via
alchemy 2026-09-06 as releases#276 (bugfix). Full write-up: spt-claude-code/docs/plans/ECHO-COMMUNE-DROP-COLLISION.md.
**RULED by the OPERATOR 2026-09-06 ~08:15Z (binding): the echo should NEVER have written
`<id>-commune.md` — its brief goes straight to the psyche tiers, NO file write.** Grounded: CONTEXT.md:208
(the drop path is the AGENT's channel), KNOWN-HAZARDS 6.4 (single writer = ONE writer + daemon sole
deleter; echo.rs:22 misread it as "core writes"), CONTEXT-MEMORY.md:23-33 (Self boundary communes are
the STRONG live signal; the weak echo was overwriting them — the tiering inverted). Measured on my own
funnel that hour: 2 of 3 Self across-communes LOST (07:58Z, 08:09Z — arm fired from the file read, no
authored COMMUNE frame ever, echo frame 25-45s after every clear). Dispatched to todlando as a product
lane; brief = spt-core root `ECHO-DIRECT-ROUTE-276-JIT.md` (run_echo_commune returns the body, shared
`ingest_body`, fire_echo routes direct + publishes COMMUNE frame with the `Source: echo-commune` head
kept, hazard 6.12 + byte-identity test on a pre-placed Self drop). Lands after v0.67.1 is on main.
Adapter leg (unrequested clear off an echo FRAME carrying a raw `!!wake!!` in prose, my 07:24Z clear)
= perri's, shipped claude-spt 0.38.3: both legs refuse any commune with a `Source: ` header.
⚠ Until #276 lands the interim rule below still applies; after it lands, retire the rule and this ⚠.
**Until fixed:** write the across-commune mid-turn and take one more tool call after it (so the
adapter's PreToolUse leg reads it inside the ingest floor), never as the turn's last act. ⚠ perri's
caveat (2026-09-06): that recovers the BOUNDARY only — if the echo still wins the race the authored
CONTENT is gone and the psyche gets the echo summary. The rule buys the wake, not the delta. The only
content check is the funnel: after a commune, `spt api io-events <id> --after <seq>` (non-destructive)
must show a COMMUNE frame whose head is YOUR bytes, not `Source: echo-commune`; if it shows the echo,
re-write the commune. Absence of the drop file proves nothing (either writer's ingest deletes it).

## 2026-09-07 — the interim rule did NOT buy the wake either (hertz authored, perri confirmed)

The standing rule above says the extra tool call buys the BOUNDARY even when the delta is lost.
Measured on my own funnel today, that is too generous: **it buys nothing when the echo is slow.**
I wrote an across-commune with a `!!wake!!` marker and took the follow-up tool call; io-events shows
my delta at **seq 42, 06:40Z** with the wake armed, then `Source: echo-commune` at **seq 44,
06:41Z** and again at **seq 65, 06:57Z**. perri confirmed independently (683 events / 541 distinct
seqs on the same funnel) and ruled the cause: **the echo landed 1m41s after mine — past the reach of
any follow-up tool call.** No clear fired; I kept running. So the missed CLEAR is the echo overwrite
too, not a separate adapter bug, and the one-tool-call rule cannot touch a writer that arrives a
minute and a half later.

Fix is releases#276 on core main @`914805d1`, **unreleased** — until the release carrying it lands,
neither the delta nor the boundary is guaranteed.

**How to apply, revised:** after any across-commune, VERIFY on the funnel rather than assume either
half — `spt api io-events <id> --after <seq>` and confirm the newest COMMUNE frame starts with YOUR
bytes. If the echo won, re-write and verify again (my rewrite landed seq 71, 07:01Z, ahead of both
echoes). And if you are still running some minutes after arming a wake, do not read that as the
boundary being slow: check the funnel, because an echo write is the likelier explanation.

