From 0d30864886ea3cff4fce9bd7c9b9a09fab263960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=27Lilleman=27=20G=C3=B6ransson?= Date: Wed, 2 Sep 2026 12:36:06 +0200 Subject: [PATCH] Say in goal 7 that the scope floor covers the seam too, and decline merge-state persistence --- AGENTS.md | 6 ++++-- todo.md | 11 +++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index a4210b2..9265dcd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,8 +34,10 @@ one wins. They do not override the hard rules below. promise this library can verify. The low-level surface is a passthrough: policy binds what the library composes, never what the caller wrote. 7. **Nothing that needs state wider than one session.** No throughput throttling, no persistence - across a restart, no coordination between processes. This is the scope floor, and it is why an - otherwise reasonable feature is declined without a fresh argument each time. + across a restart, no coordination between processes — and no seam handing the application state to + persist for one of those either, which commits to the same scope through the back door and + publishes an internal shape to do it. This is the scope floor, and it is why an otherwise + reasonable feature is declined without a fresh argument each time. 8. **It builds, tests and runs the same everywhere.** Container-only toolchain, no runtime dependencies, the Node 18 floor verified in CI rather than asserted, every README example executed by the suite. diff --git a/todo.md b/todo.md index b583cce..9860410 100644 --- a/todo.md +++ b/todo.md @@ -118,10 +118,6 @@ session message is a change to every call site. ## Worth doing, not blocking -- [ ] **Merge state does not survive a process restart.** A drop no longer discards it, but a restart - loses every incomplete group, and a peer has no reason to resend a receipt it already had - answered. Surviving one means exposing the merge state for the application to persist and hand - back, which is a public-surface decision. - [ ] **Group the session's collaborators under `src/session/`.** `session.ts` imports `dlr-merger`, `incoming-requests`, `link-timers`, `outgoing-requests`, `pdu-transport`, `reconnect-loop` and `send-sms`, and nothing else does, so the directory would make that @@ -168,6 +164,13 @@ session message is a change to every call site. ## Declined +- **Merge state surviving a process restart.** Declined by AGENTS.md goal 7, maintainer's call, + 2026-09-02. A restart loses every incomplete receipt group and a peer has no reason to resend one it + already had answered, so the loss is real — but surviving it means handing the application the merge + state to persist, which the scope floor covers as squarely as holding the state here would, and + which publishes the shape of `DlrMerger`'s groups against goal 6. Nothing is foreclosed: the seam + can still be added after 1.0.0 as a minor. + - **Throughput throttling — a TPS cap, and backing off on `ESME_RTHROTTLED`.** Declined by AGENTS.md goal 7: an operator's rate limit is scoped to the account, while the widest thing this library owns is a session, so a bucket here cannot see a second process binding the same account and is wrong in