diff --git a/README.md b/README.md
index e15093e..9a564de 100644
--- a/README.md
+++ b/README.md
@@ -480,7 +480,8 @@ carrying the worst status of the segments and each of them under `segments`. An
report never counts. Merging needs the SMSC to number its segment ids `-`, this library's
own server's convention; an SMSC that hands out unrelated ids per segment never fires it. A base is
merged once: a later message the SMSC gives the same ids is reported through `dlr` alone, and an
-earlier one still collecting loses its merged report.
+earlier one still collecting loses its merged report. A send that returned an `err` never fires it,
+even where the SMSC took some of its segments; their receipts still arrive as `dlr`.
## Server in depth
@@ -658,7 +659,8 @@ one wins. They do not override the hard rules below.
nothing, so nothing the library concludes may rest on one; a request the peer may already have
taken is never re-sent on the library's own initiative; work the peer has no reason to send again
is not dropped; a call that reports a message as sent asserts that the wire carried what the caller
- wrote, so a value we cannot send as given is refused before anything goes out.
+ wrote, so a value we cannot send as given is refused before anything goes out; each message gets
+ one answer about it as a whole, so a send that fails is that answer and no merged report follows it.
3. **Strict in what we send, generous in what we read.** The library's own senders follow 3.4, and
the codec parses whatever arrives. Where the letter of the spec would discard traffic a real SMSC
sends, keep the traffic.
diff --git a/todo.md b/todo.md
index 8f9884c..25bc6fd 100644
--- a/todo.md
+++ b/todo.md
@@ -202,13 +202,8 @@ and is also what the panel ranked hardest — two methods, one answer.
`broadcast_sm_resp` is declared, set once and read nowhere. This is the "Dormant filters" row
of the 0.4.0 defect table in a new spelling — metadata that reads as a guarantee.
-- [ ] **Arm the merge for the segments the SMSC did take, or say why not.** `collectSent()` sets
- `failure` if any segment errored, including the `UnansweredError` a mid-send drop produces, and
- `session.ts` only calls `dlrMerger.expect(sent.smsIds)` when `!sent.err`. So a link drop during
- a multipart send leaves per-segment `dlr` events firing while `messageDlr` never can, traced
- only by one `debug` line. `session-extras.test.ts` has the adjacent case — a drop *after* the
- send — and not this one. If goal 2 forbids reporting on a message we cannot fully account for,
- that is the answer; it is stated in no file today either way.
+- [ ] **Test that a multipart send which errors never fires `messageDlr`.** Goal 2 now says so and
+ README promises it; `session-extras.test.ts` covers a drop *after* the send, not one during it.
- [ ] **Return an `err` where `message` is not a string, rather than throwing.**
`sendSms({ message: undefined })` — a forgotten property — reaches `value.replace()` in