# SINGLE-WRITE EMISSION — JIT plan (paper stage)

todlando, 2026-08-29. Authored on doyle's call after the v0.65.0 cut: **paper-prep only — no
cargo, no pool, no build.** Every number here is read from source at a sha or from the
toolchain's own std sources; nothing was executed. The lane gets its pool when deployah
source-verifies the counter-100 publish and ir66 reaps.

## 1. The defect, stated as a property rather than a story

A diagnostic line that a test parses (`TOKEN:...`) is emitted today with `eprintln!`. Where the
line interpolates anything, std issues **one write syscall per format fragment**, so a reader on
a shared stderr can observe a line torn between fragments — and the trailing `\n` is itself a
separate fragment, so a torn line can be completed by *another process's* newline.

**Measured at the toolchain's own std source** (`stable-x86_64-pc-windows-msvc`, 1.96 —
`library/std/src/io/stdio.rs`, `library/std/src/io/mod.rs`), not asserted from memory:

- `Stderr` is documented "This handle is not buffered" and is
  `&'static ReentrantLock<RefCell<StderrRaw>>` (stdio.rs:892). No buffering ⇒ no coalescing.
- `Write::write_fmt` (mod.rs:1990) has a fast path: `args.as_statically_known_str()` ⇒ ONE
  `write_all`. Otherwise `default_write_fmt`.
- `default_write_fmt` (mod.rs:615) drives a `fmt::Write` adapter whose `write_str` calls
  `inner.write_all(...)` **per fragment** (mod.rs:628). Fragments = literal pieces + each
  formatted arg + the trailing newline.
- The `ReentrantLock` serializes *threads of one process*. It is not a cross-process lock, and
  the daemon's children inherit the same stderr handle — which is exactly the population the
  census's 26 consumer test files read.

⚠ The 43 static-literal sites are single-write **only because of that `as_statically_known_str`
fast path**. That is a std implementation detail, not a contract. The property must be owned by
our emitter, never inherited from the standard library's current optimizer.

## 2. Population — measured at the cut sha `4d6007ac` (tag v0.65.0 == main == golden r4 head)

| | count |
|---|---|
| `TOKEN:`-shaped emission sites in `crates/*/src` | **487** |
| ...of which INTERPOLATED ⇒ multi-write today | **444** |
| ...of which static-literal ⇒ already one write (by std's fast path) | **43** |
| distinct tokens | 383 |
| consumer test files that parse a token off an inherited-stderr surface | 26 |
| **macro calls that span multiple lines** | **200** |

By crate: spt-daemon 270, spt 195, spt-runtime 8, spt-live 5, spt-net 5, spt-store 4.
By macro: eprintln! 485, println! 1, eprint! 1.

**200 multi-line calls is the number that shapes the work**: any sed-shaped or regex-shaped
mass rewrite silently mangles 41% of the population. The conversion is per-site and reviewed,
or it is not done.

### 2a. Disposition of every site that is not a plain single-line `eprintln!`

Added on doyle's rider 1. All four dispositions are read at the cut sha, not inferred.

- **`reporting.rs:428 DRIVEN_BY` — the lone `println!`. OUT OF LANE.** It goes to **stdout**;
  the tear surface this lane is about is the inherited **stderr** handle.
- **`firewall.rs:607 INBOUND_REACHABILITY` — the lone `eprint!`. OUT OF THE SINGLE-LINE
  CONTRACT, into the BLOCK arm (§4).** It is `eprint!` and not `eprintln!` because the newline
  rides in the **payload**: `InboundVerdict::warning()` (`spt-store/src/inbound.rs:91`) returns
  `Some(String)` in four arms and **every one of them ends with a newline** and **contains
  interior newlines** (`"…Fix:\n  {fix}\n"`; the `PathMismatch` arm carries three). So this is
  not a partial line assembled across calls — it is a complete multi-line operator block emitted
  in one call. Measured corroboration: **zero** consumer test files parse `INBOUND_REACHABILITY`
  (it is absent from the 26-row consumer census), so nothing machine-reads it. It still wants
  ONE write — a block that interleaves between its own lines is the same defect one size up.
- **`servicehost.rs:887 SERVICE_STARTUP_FAULT` — the ONLY site of 487 whose own string literals
  carry an escaped newline (2 of them). BLOCK arm.** It appends a captured tail via
  `format!("\n{t}")`, so the emission is a token line followed by **arbitrary multi-line runtime
  text**. This is the site that decides doyle's rider 4: a static "the literal ends with a
  newline" check cannot see `{t}` at all, so **only a runtime rule can hold the line**.
- The remaining **484** `eprintln!` sites are single logical lines and are the single-line
  contract's population.

⚠ **Instrument note, because the first number was wrong.** A first pass reported "236 sites with
an interior newline". That was slop: the extractor took a fixed 8-line window and ran past the
end of short calls into unrelated code, and Rust's **line-continuation backslash** at end of
line reads at a glance exactly like an escaped `\n`. Re-measured with a balanced-paren
extractor plus a string-literal walker — **487 of 487 calls parsed, 0 skipped** — the true count
is **1**, hand-verified at source. The retracted 236 is recorded here rather than deleted
because the plan's other counts come from the same family of instrument.

## 3. Requirement — NEW-REQ-FIRST

`grep -iE "atomic|single.write|whole.line|tear|interleav"` over `traceable-reqs.toml` returns
nothing covering emission. Per AGENTS.md rule 3 the REQ is minted **before** the code.

Proposed:

- **id**: `REQ-EMIT-SINGLE-WRITE`
- **title** (one sentence, greppable — doyle's rider 2): `A machine-parsed diagnostic emission
  is handed to the OS as exactly ONE write of the complete rendered text including its
  terminating newline.`
- **the rationale rides as a COMMENT beside the entry, not in the title**: the property is
  deterministic and belongs to the emitter — it counts the writes WE issue and makes **no
  atomicity claim on any OS**. POSIX gives pipe writes at or below PIPE_BUF atomicity; Windows
  gives no such guarantee; a file append and a console are different again. We promise the thing
  we control and refuse to promise the thing we do not. If a published surface ever states the
  format, that promise gets a `doc` stage — an undiscoverable shipped guarantee reads as missing.
- **required_stages**: `[]` at MINT, set to `["impl", "unit"]` at **W1 start** (doyle's rider 3 —
  per-wave activation, no pre-fail).
- **title discipline**: no double quotes anywhere in it — a `"` inside a TOML basic string kills
  the registry parse, which exits 2 and means nothing was checked at all.

## 4. Shape — the prototype already exists in the tree

`crates/spt/src/roster.rs:335-355` (my #240 lane) is exactly the target shape and its comment
already states the reasoning: a **pure function composes the whole line into a `String` ending
in a newline**, and the caller does **one `write_all`**. Composing purely is what makes the text
unit-pinnable without reaching through a `Once`.

Generalize it, do not copy it 444 times:

- The emitter lives in **`spt-proto`** — measured to be the dependency root (`spt-proto` has no
  `spt-*` dependencies; spt-store, spt-runtime, spt-msg, spt-net, spt-live, spt-daemon and spt
  all depend on it directly). No new crate, no layering change, one edge that already exists.
- **TWO NAMED ARMS, and the newline is ASSERTED rather than silently appended** (doyle's rider 4,
  decided here at design time rather than deferred to a macro comment):
  - `emit_line!` — the single-line contract, 484 sites. It composes, **refuses an interior
    newline**, terminates the text itself, and issues ONE `write_all`. Silently appending a
    newline would let a payload carrying its own `\n` pass as two logical lines inside one
    write — indistinguishable downstream from the tear we are fixing.
  - `emit_block!` — an explicit opt-in for a composed multi-line block ending in a newline, still
    ONE `write_all` of the whole block. The two sites that need it (§2a) then **declare
    themselves by name** instead of slipping through a weak assertion.
  - **The interior-newline rule must be enforced at RUNTIME, not by a source lint**:
    `servicehost.rs:887` interpolates a captured tail, so the newline is in a value no static
    check can see. One scan of the rendered string is the whole cost.
  - **RULED (doyle, 2026-08-29): ESCAPE plus `debug_assert`, never emit-anyway.** In release,
    `emit_line!` rewrites an interior newline to the two-character escape `\n` so one emission is
    **always** one logical line; in debug the same condition `debug_assert`s, so no new caller
    ships one. His three reasons, kept because they are the durable part: (1) emit-anyway
    reintroduces multi-line text onto the single-line surface — the exact class this lane retires
    — and does it **only in release**, where no assert watches and no test looks, i.e. a defect
    that cannot appear in any build we test; (2) the escape is **its own breadcrumb** — a literal
    backslash-n in a parsed line names the offending caller from the artifact alone, with no
    repro, which is the absence-needs-an-emitter rule applied in advance; (3) consumers keep
    parsing one line, where a torn token line under emit-anyway would be silent parse corruption.
    Both arms get units: the debug arm asserts the panic fires; the release-shaped arm asserts
    ONE write, an escaped payload, and still newline-terminated. **The escape spelling is pinned
    in the unit** so it cannot drift.
- There are **zero** `macro_rules!` in `crates/*/src` today, so this introduces the first — call
  that out in review rather than sliding it in.
- The handle is a parameter, not a hardcoded `stderr()`, or the property is untestable (section 5).

## 5. Validation — the deterministic emitter property, NEVER a CI rate

The gate is a unit test against an **instrumented writer** that counts `write`/`write_all`
calls and records each buffer:

1. render a line with N interpolated arguments through the emitter;
2. assert the writer saw **exactly one** call;
3. assert that one buffer **ends with the newline** and equals the fully rendered line;
4. assert the same for a static-literal line, so we do not silently depend on std's
   `as_statically_known_str` fast path;
5. a RED-FIRST arm: the same assertions against a plain `write_fmt` path must FAIL (a
   multi-fragment count), proving the test can distinguish the two — otherwise it is an arm that
   cannot fail, which is the v0.65.0 arc's head-1 lesson;
6. `emit_line!` REFUSES an interior newline and `emit_block!` accepts one, each pinned, so the
   §2a dispositions are enforced by a test rather than by this document;
7. the interior-newline ruling, both arms: the **debug** arm asserts the `debug_assert` fires,
   and the **release-shaped** arm asserts ONE write, the payload escaped, and the emission still
   newline-terminated — **with the escape spelling pinned in the unit** so it cannot drift.

**W1 STEP 0 IS THE PREMISE PROBE** (doyle's call): before any emitter is written, run the
instrumented writer against a plain interpolated `eprintln!` and record **N**, then against the
emitter and record **1**. That N-vs-1 pair is the REQ's gate evidence — it converts §1 from a
reading of std source into a measurement of this toolchain on this box, which is the one thing
the paper stage cannot do.

**Explicitly out of bounds as validation:** re-firing CI and reading a tear rate. The only
tear-site observation in the record is deployah's four complete SUBSCRIBE_DECISION lines from
run 33236164340 — a zero. A rate that is zero before the fix cannot demonstrate the fix, and
hertz has made no rate claim; do not attribute one to him.

## 6. Sequencing

- **W0 (paper, this doc)**: premise measured, population counted, REQ drafted, shape chosen.
- **W1 step 0**: the premise probe (§5) — N writes for a plain interpolated `eprintln!`, 1 for
  the emitter, recorded as the REQ's gate evidence before any conversion starts.
- **W1**: mint `REQ-EMIT-SINGLE-WRITE` with `required_stages = []`, then set it to
  `["impl", "unit"]` **at W1 start** (activation, not mint); land the `spt-proto` emitter +
  its unit battery incl. the red-first arm. `traceable-reqs check` must pass before anything
  converts. ⚠ Re-run `check` immediately after the hand-edit — exit 2 means the registry did not
  PARSE and nothing was checked, and every reading since the bad edit is vacuous; keep double
  quotes out of the REQ title.
- **W2..Wn**: convert by crate, smallest first — spt-store 4, spt-live 5, spt-net 5,
  spt-runtime 8, then spt 195, then spt-daemon 270. Per-site and reviewed; the 200 multi-line
  calls are why. Fix the POPULATION, not the instance: a crate is done when it has no remaining
  `TOKEN:`-shaped `eprintln!`, and the census generator (parked beside the cut artifacts) is the
  meter for that.
- The 26 consumer test files are the blast radius to re-read after each wave.

## 7. Not in this lane, but must be said in the same breath

`IDLE`, `DISPATCH`, `BUSY`, `BOUND` are single common words matched as **substrings** by the
tests that parse them. A whole-line-write fix does nothing for those — they need anchored
matching. Different defect, same files. It is recorded here so it is not rediscovered as a tear
and mis-attributed to this lane.

## 7a. W1 STEP 0 — MEASURED 2026-08-29, the premise is no longer a reading

Lane `feat/emit-single-write` off the cut sha `4d6007ac`, worktree
`.worktrees/emit-single-write`, pool claimed at lane start.

| path | writes issued |
|---|---|
| interpolated `write_fmt` (what `eprintln!("TOKEN:{id}: {detail}")` builds) | **5** |
| static-literal `write_fmt` (the control) | **1** |

The five: `"SUBSCRIBE_DECISION:"`, `"endpoint-7"`, `": "`, `"the store did not persist"`, `"\n"` —
**the terminator arriving as its own call**, which is the sharp end: another process can complete a
torn line. §1's reading of std source is confirmed on this toolchain, and the probe is kept as a
permanent red-first arm rather than deleted after use.

**doyle's seam ruling (2026-08-29), folded in:** ONE seam and one owner — this emitter is the only
helper, and hertz's autostart conversion becomes its first CONSUMER rather than a second dialect.
`write_all`, not a bare `write`: `write_all` retries a short write and can therefore issue more than
one call, but a bare `write` under that same window **drops the tail**, loses the terminator, and
glues the next emission onto the partial — manufacturing the exact torn-token signature this lane
retires. So the unit shape splits: a non-short-writing counter pins **exactly one call** and the
whole rendered line; a **separate short-writing arm** pins **complete text in order ending with the
newline** and deliberately does **not** assert a count (asserting one there would pin bare-`write`
semantics and fail the ruled impl); the red-first arm stays.

## 7b. Conversion notes (W2+)

Written when W2 opened, so they are read by whoever converts rather than
rediscovered per crate.

- **The conversion spelling is `spt_proto::emit_line_err!` / `emit_block_err!`** — the
  stderr-aimed pair. They are a SEPARATE NAME, not a no-writer arm of `emit_line!`, because a
  macro accepting both `($w, $fmt, ...)` and `($fmt, ...)` would bind a caller's format literal
  as the writer (a literal is also an expression). One seam, two spellings, no ambiguity;
  hertz's `emit_line!(&mut w, …)` contract is untouched and additive.
- **BEHAVIOUR CHANGE, stated rather than slipped in: the `_err` spellings DISCARD a write
  error, where `eprintln!` PANICS.** std's print machinery panics when writing to stderr fails,
  so a closed or full stderr can kill a process at the exact moment it was trying to explain
  itself. A diagnostic must never be the thing that kills the operation it reports on. This is
  a deliberate improvement and it is the one semantic difference a converted site carries.
- **The discard buys an observability gap, and that is the accepted trade** (doyle, ruling A
  rider 2): a diagnostic that fails to write now leaves no trace of having been attempted, so
  emission becomes a place where absence can be silent — IR-71/IR-72 territory. It is accepted
  here ONLY because the alternative is a panic, and it is written down so that a later reader
  meets it as a recorded trade rather than rediscovering it as a defect.
- **THE CENSUS PREDICATE MUST BE NAMED IN EVERY REPORT** — say "the TOKEN-colon population",
  never a bare count. `gate.rs` emits `ACCESS_REFUSED {surface}…` with a SPACE delimiter, which
  the colon predicate cannot see, so one predicate can report a crate done while another reports
  it undone. Ruled (doyle): the space family IS in scope, as W2's TRAILING wave after
  spt-daemon, and **the predicate is widened BEFORE that wave starts** so the meter never
  disagrees with itself. Per-site dispositions inside the ten: `NUL` (epoch.rs:61) is spurious —
  a nested `format!` fragment, hand-checked; `DBG` and `RC_KEYS` get READ at conversion time and
  are either converted (preferred — uniformity is the point) or excluded **by name with the
  reason**. No silent exclusions.
- **A token can have emitters in more than one crate, so "crate at zero" is not "token
  converted".** Measured in wave 1: `PEERADDR_INVARIANT_REJECT` was converted in spt-store and
  is STILL emitted by an unconverted site elsewhere. Report crate-level progress, and check the
  token's whole emitter set before claiming a token's surface is single-write.
- **W-FINAL DEFINITION OF DONE, ruled per-TOKEN and never per-crate** (doyle, wave 1 pass): the
  lane is done when **every emitter of every consumer-parsed token** has been converted — not
  when every crate reports zero. The two differ exactly where a token is emitted from more than
  one crate, which is measured, not hypothetical.
- **A site may already be converted by a CONSUMER lane, in the writer-taking spelling.** hertz
  converted `autostart.rs` with `emit_line!` before the daemon wave reached it. The converter
  therefore recognises **every** emitter spelling as already-converted, not just the stderr pair;
  double-converting would be a silent wrong edit rather than a refusal.
- **THE TOKEN-COLON POPULATION IS 486, NOT 487 — one census row is a PHANTOM.**
  `sealverb.rs:456` is `format!("SEAL_SEND_NO_DAEMON: …")` inside a `map_err`, three lines below
  an unrelated `eprintln!`, and the census's 4-line **lookback window** attributed that macro to
  it. Found because the converter REFUSED mid-run rather than editing a line it could not place;
  then all 487 rows were re-checked by balanced-paren **containment** (is the literal inside the
  macro call's span?) rather than assuming the one that tripped was unique — **exactly one** in
  487. Note the shape: the lookback that fixed the multi-line UNDER-count is the same mechanism
  that introduced this OVER-count. It is the price of that widening, not an argument against it.
  Every earlier figure carrying 487 is high by one.
- **A payload carrying a LITERAL two-character `\n` is indistinguishable from an escaped
  one** (doyle, W1 gate). Accepted: the breadcrumb's job is to name a caller emitting a line
  break, and a payload that already contains those two characters was never going to tear. Do
  not "fix" it with a distinguishable marker — that trades a readable line for a decodable one.
- **Keep one `cargo test` leg per battery**: nextest does not run doctests, and the
  `emit_line!` doctest is real coverage of the public spelling.
- **The census generator is the meter for a crate being done** — no remaining `TOKEN:`-shaped
  `eprintln!` in that crate — not a reviewer's impression. ⚠ And the METER'S OWN PREDICATE has to
  widen with the tree: once conversion started, an `eprintln!`-only predicate stopped measuring
  the population and began measuring the REMAINDER. The generator caught this itself by ABORTING
  on its missing sentinel rather than reporting a triumphant zero. Use the both-delimiter,
  emitter-aware meter and always name the predicate in the report.
- **CONSUMER BATTERIES NEED THE WHOLE FIXTURE PACKAGE PREBUILT, not a hand-listed subset.** A
  `--test` leg never emits fixture exes, and a missing one trips in ~0.01s with a panic that
  reads exactly like a test failure. Enumerating them by grepping their pre-build strings is
  NOT sufficient: `mock-shell`'s call site COMPOSES its command at runtime
  (`fixture_package(name)`), so a literal grep is structurally blind to it — the same
  predicate-blindness the census had. Build `-p spt --bins` AND `-p mock-adapter --bins`.
  Chasing named fixtures one red at a time just finds them one at a time.

## 7c. FINAL STATE — the lane is COMPLETE and PARKED (2026-08-29)

**BOARD: `releases#241`** (state BACKLOG, type BUGFIX, minted through alchemy; full lane evidence
in comment `5461613480` — branch, tip, per-wave verdicts, census arithmetic, rulings, landing
constraint). **Reference #241 in any future comment or commit touching this lane.** It enters
operator triage from BACKLOG; at greenlight it batches into the next milestone.

**Lane tip `d0fdd58d` on `feat/emit-single-write`. Waves 1–4 PASS (doyle). Evidence pinned at that
sha; touch it again only for a defect.**

| wave | scope | sites | verdict |
|---|---|---|---|
| W1 | the `spt-proto` emitter + unit battery | — | PASS (gate at `a27e45fa`) |
| W2.1 | spt-store 4, spt-live 5, spt-net 5, spt-runtime 8 | 22 | PASS |
| W2.2 | spt | 193 | PASS |
| W3 | spt-daemon | 269 (+1 absorbed) | PASS |
| W4 | the TOKEN-space family | 9 | PASS |

Both-delimiter meter at `d0fdd58d`: **498 = 495 real + 2 phantoms + 1 self-reference**. 494 real
converted + the one out-of-lane stdout site (`reporting.rs:428 DRIVEN_BY`) = 495. Consumer
condition: **15 of 26** consumer files parse a converted token; **all 15 green**, per-file exits.

**LANDING SHAPE, ruled by doyle — do NOT merge main into this lane.** The branch is shared (hertz's
carrier rides it) and assembly belongs to the gater: at the next milestone intake he composes the
head off current main, runs the pick-fidelity audit (count AND hash per pick), compile-gates it,
and hands deployah the never-executed-cells list. **A 495-site rewrite is not suite-inert, so it
rides a GOLDEN, not a thin PR** — it batches with the next operator-called milestone. The lane
parks GREEN-AND-READY until then.

## 8. Honest state

Nothing is built. The premise is read from std source and the population from the repo at a
sha; neither has been executed. The first thing the lane does when it gets a pool is prove the
premise by measurement — the instrumented writer showing N writes for an interpolated
`eprintln!` and 1 for the emitter — because a design premise measured only by reading is a
hypothesis, and this project has paid for that mistake before.
