rfc-003: an event addressed to a nobody is write-only

§7.13 — the owed set keys on to_agent, and from_agent is whatever
string the writer puts there, so nothing stops authoring under an
identity no live session runs as. When the reply comes back addressed
to that string, it is stored and delivered to no one. Distinct from
§7.12: the defect is the address, not the status.

Measured 2026-08-27: two directed task.requests planted under a
synthetic from_agent (a provenance label, not a run identity) drew two
correct replies, addressed back to the label as the protocol requires.
Neither reply was ever delivered. One carried a live-credential
exposure finding; it sat unread for ~2h20m and was found only because
a human asked whether mail had arrived.

General rule stated, not just the instance: this fleet has already
produced the same failure shape three ways (synthetic sender above; an
event addressed to a decommissioned device; a device-identity case
mismatch). Permitted exception carried over from existing fleet
practice: a synthetic sender is fine for a controlled experiment, but
the body must then name the real reply-to identity.

Proposed (not implemented): warn at event_append when from_agent
differs from the writer's own session identity, using a DISTINCT
from_agent lookup to say whether anyone has ever authored under it —
stated honestly as a heuristic that catches 'never authored, certainly
unread' but not a decommissioned device that once did.

Decision 9 in the open-decisions list gets a numbered sibling, 10,
pointing at this section — related to decision 7 (agent-name
collision between two devices) but a different failure: not two
devices sharing a name, but one writer using a name nobody runs.
This commit is contained in:
2026-08-27 23:34:20 +02:00
parent a361b71c40
commit 21023e7aa0
+13
View File
@@ -344,6 +344,18 @@ Read the filter precisely: candidacy requires **exactly `open`**, not merely "no
This is the shape of the channel, and it is worth stating because the natural inter-device message — *"here is something you should know"* — is exactly the shape that gets no delivery. Two ways to make news reach a peer: address it as a **directed `status="open"` ask** so it enters the owed set and gets closed when acted on (correct when a response is genuinely wanted), or accept that it is **pull-only** and pair it with a palace drawer, which the peer's search *will* surface later. What does not work is a terminal-status report and an expectation of attention.
### 7.13 An event addressed to an identity no session runs as is write-only
The owed set (§3.3) is the log's only push channel — it is what a client injects at wake-up. It keys on `to_agent`. A `from_agent` is whatever string the writer puts there (§6: "authenticates the fleet, not the agent"), so nothing stops a writer from authoring under an identity that no live session has ever run as. When it later receives a reply, that reply is addressed right back to the string the writer chose — and if nothing runs as that string, the reply is stored, queryable, and delivered to no one. Unlike §7.12, this is not about status; a **directed, `status="open"`** reply is undeliverable here, because the *address* rather than the *shape* is the defect.
**Measured 2026-08-27.** A device planted two directed `task.request`s under a synthetic `from_agent` (a release-provenance label, not an identity any session runs as), intending only to record where the ask came from. Both recipients replied correctly, addressed to that synthetic sender as the protocol requires — one an `event.ack` (`status="claimed"`), one a `task.reply` (`status="applied"`). Neither reply was ever delivered to anyone. One contained a live-credential exposure finding. It sat unread for roughly two and a half hours and was found only because a human asked whether mail had arrived.
**The general rule, not the instance:** before addressing an event, the writer is responsible for the address being an identity a live session actually runs as; and a writer that authors under an identity other than its own session identity has made every reply to that event undeliverable to itself. This fleet has already produced the failure in three unrelated shapes — a synthetic sender (above); an event addressed to a device since decommissioned; and a device-identity case mismatch (an uppercase form written where the fleet's convention is lowercase) — which is why this is recorded as a property of the channel rather than a mistake to remember not to repeat.
**The permitted exception, and its obligation.** Authoring under a synthetic identity is legitimate for controlled experiments — this fleet has run positive/negative mailbox controls this way deliberately — and this RFC does not forbid it. But a synthetic sender then **must name the real identity to reply to** in the body; the address line is not a place to record provenance if a reply is ever wanted.
**Proposed, not implemented:** on `event_append`, if `from_agent` differs from the writer's own stamped session identity, warn that replies to this event will be addressed to that other identity, and say whether any event in the log has ever been authored under it — a plain `DISTINCT from_agent` lookup. State the heuristic's limit honestly: an identity that has never authored is certainly unread by anyone; one that *has* authored may still belong to a device that no longer exists, which this check cannot see.
---
## 8. Phasing
@@ -375,6 +387,7 @@ Replication exists in code — `version_vector()`, `list_ops()`, `apply_remote_e
7. **Agent-name registry.** Nothing prevents two devices sharing one `from_agent` (§7.7). A warning at append time would be cheap.
8. ~~**Does an arriving ask deserve a notification?**~~ **Done 2026-08-26** — delivery note plus `MEMPALACE_MAILBOX_NOTIFY` (§7.11). What stays open is the narrower question: should `desktop` be the *default* rather than opt-in, and does an arriving ask ever deserve a turn (`MEMPALACE_MAILBOX_TRIGGER`)?
9. **Is there a delivery path for news rather than obligations?** (§7.12) Today the only delivered shape is a directed open ask. Options: leave it pull-only and rely on the paired drawer, or give informational events a distinct low-priority surface at wake-up ("3 reports since your last session") separate from the owed set. **Proposed direction in §9.2** — including why the obvious fix (widening the owed set) is not available.
10. **Should a write warn when `from_agent` is not the writer's own identity?** (§7.13) Related to decision 7 but distinct: decision 7 is about two devices *sharing* one identity by accident; this is about a writer deliberately authoring under an identity nobody runs, which makes every reply to that event undeliverable to itself. A `DISTINCT from_agent` lookup at append time is cheap and catches the unread-for-certain case; it cannot catch a decommissioned device that once wrote, which is the harder half of the same problem.
### 9.1 Retention — decided direction (2026-08-26)