Repository navigation
rewrite: record the CLOSE-aborts-read decision the port already makes #957
Description
The port aborts an in-flight stored read when a CLOSE arrives (crates/nostream-relay/src/handlers/unsubscribe.rs:11-14). The TypeScript capture does not: UnsubscribeMessageHandler only emits Unsubscribe, which reaches onUnsubscribed → subscriptions.delete(id) (src/handlers/unsubscribe-message-handler.ts:9-10, src/web-socket-adapter.ts:107-110), and its read keeps running.
No decision record covers this. docs/rewrite/decisions/0001–0004 mention CLOSE only in the transport frame list (0004-wire-transport.md:105) and id-ordering (:238). The repo rule is that the TypeScript file wins when the two disagree unless a decision record says otherwise, so the port currently holds an unrecorded deviation.
Why it surfaced. Job 010's recon found that #951's defect — a CLOSE during the invite mint losing the abort for the whole stored read and its EOSE — is worse in Rust precisely because Rust aborts on CLOSE. Fixing that defect restores the port's own rule and needs no decision. But the rule itself is a deviation, and a defect job is not the place to legitimise it.
The wire oracle cannot decide it
Of the 16 recorded sessions in crates/nostream-relay/tests/fixtures/wire-sessions.json, three contain CLOSE (sessions 1, 2, 6 — e.g. req-close-abort: ["REQ","c1",{…}] → EOSE, then ["CLOSE","c1"] → no frame), and none closes while a read is still streaming. Replaying them cannot tell "aborted" from "already finished".
What this needs
- A decision record stating whether
CLOSEaborts an in-flight read. This is a maintainer decision; the port and the NIP-01 reading both favour aborting, which is an argument for recording the deviation rather than removing it. - If the port keeps aborting: a captured or synthetic fixture that closes mid-stream, so the oracle can decide it — until then the behaviour is asserted only by unit tests.
Related
- The capture's invite emit is likewise unguarded (
src/handlers/subscribe-message-handler.ts:111), and the port matches it deliberately. Guarding it would be a second unrecorded deviation; the same record should say so, or the two should be decided together. - relay: CLOSE during an invite mint is lost, and frames follow the close #951 fixes the lost abort without touching this question.
Activity
docs(rewrite): the frame queue is byte-bounded in ADR 0007 (#957)
docs(rewrite): disambiguate a test path in ADR 0005 (#957)
docs(rewrite): keep ADR 0005's citation fix to one line (#957)
docs(rewrite): correct the overflow path and a capture name in ADR 00…
docs(rewrite): mark ADR 0007 proposed and satisfy the changeset gate (#…
docs(rewrite): add the empty changeset ADR 0007 needs (#957)
docs(rewrite): record that a CLOSE aborts the read it closes (#957) (#…