a73x

7612ce44

docs: deinit comment takes both review nits; roadmap strikes the reorder

a73x   2026-08-13 09:43

Commit message
docs: deinit comment takes both review nits; roadmap strikes the reorder

Two Minor findings from the quality review of c492eb2, both wording:
the successor concludes nothing is LISTENING (claim()'s probe cannot
refuse while our fd is open), not that our process exited; and the
stat→unlink gap is named as the floor for deleting by name — Linux has
no inode-predicated unlink. The roadmap entry is struck with the sha
and carries the review's sharpest finding: the old stat-before-close
guard could never fire in the very race it guarded.

Closes: 2cb6f950

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

docs/roadmap.md
Old New
@@ -190,10 +190,12 @@ next one that arrives outranks all of it.
190 - ~~**The transport recipe as a `union(enum)`**~~ — paid by M15 (Task 6). 190 - ~~**The transport recipe as a `union(enum)`**~~ — paid by M15 (Task 6).
191 `Transport.open` takes `union(enum) { sock, via, quic, hand }`, and the 191 `Transport.open` takes `union(enum) { sock, via, quic, hand }`, and the
192 dispatch decision it makes got its first pin in the same task. 192 dispatch decision it makes got its first pin in the same task.
193 - **The stat-after-close reorder in `deinit`** — created by M15 (Task 193 - ~~**The stat-after-close reorder in `deinit`**~~ — paid (M16-b,
194 10). Narrows the window in which a departing daemon's cleanup could 194 c492eb2). Review found the old order was worse than vestigial: a
195 unlink a successor's socket. The analysis is already written, in the 195 successor cannot pass `claim()` while our listener fd is open, so the
196 `sockpath` comment; only the reorder is owed. 196 stat-before-close guard could never fire in the very race it guarded.
197 The residual stat→unlink gap is the floor — Linux has no
198 inode-predicated unlink.
197 - **`egress_cap` ↔ transport-params, one owner** — also M15. `256*1024` 199 - **`egress_cap` ↔ transport-params, one owner** — also M15. `256*1024`
198 is spelled three times and the tie between the copies is prose only. 200 is spelled three times and the tie between the copies is prose only.
199 - **Fold `Transport`'s `alloc`/`qout` into the `.quic` `Link` payload** — 201 - **Fold `Transport`'s `alloc`/`qout` into the `.quic` `Link` payload** —
src/server.zig
Old New
@@ -336,12 +336,15 @@ pub const Server = struct {
336 // The stat comes AFTER the close. Statting first was vestigial: 336 // The stat comes AFTER the close. Statting first was vestigial:
337 // 8a82225 fstat'd the live descriptor and so needed the fd open, 337 // 8a82225 fstat'd the live descriptor and so needed the fd open,
338 // 6090604 switched to statting the path and killed that constraint. 338 // 6090604 switched to statting the path and killed that constraint.
339 // A successor only claims the path after concluding we are gone, so 339 // A successor only claims the path after concluding nothing is
340 // asking on this side of our close is the correct side of that event, 340 // listening here — claim()'s probe cannot refuse while our fd is
341 // and it shrinks the window in which one can claim the path between 341 // open — so asking on this side of our close is the correct side of
342 // our answer and our unlink down to the stat→unlink gap. The close 342 // that event, and it shrinks the window in which one can claim the
343 // itself stays unconditional: the fd is ours whoever owns the path, 343 // path between our answer and our unlink down to the stat→unlink
344 // and only the unlink touches the shared namespace. 344 // gap. That gap is the floor for deleting by name: Linux has no
345 // inode-predicated unlink. The close itself stays unconditional:
346 // the fd is ours whoever owns the path, and only the unlink touches
347 // the shared namespace.
345 self.listener.deinit(); 348 self.listener.deinit();
346 if (self.path_id.stillAt(self.sock_path)) { 349 if (self.path_id.stillAt(self.sock_path)) {
347 std.fs.cwd().deleteFile(self.sock_path) catch {}; 350 std.fs.cwd().deleteFile(self.sock_path) catch {};