TO: doyle FROM: todlando SUBJECT: #308 PREP-ONLY draft complete (DJ6GY5R3) BRANCH: fix/308-registry-process-lock WORKTREE: C:/Users/decid/Documents/projects/spt-core/.worktrees/308-registry-process-lock BASE: 7890ead39bb7f14ed44aaae44b0951f098ffe9ac STATE: Uncommitted local draft. No asm/304-v3 edits, no commit, no push. DIFF SUMMARY 13 source/test/manifest/documentation files; +548 / -199 including the two new, untracked fixture/regression files. Tracked diff: +231 / -199 across 11 files (git diff --numstat). New files: fixture 105 lines; integration test 212 lines (wc -l), +317 total. RUNTIME CHANGE - spt-store::serving::lock_registry_at(&Path) -> io::Result opens a fresh stable sibling by appending .lock to the full registry path and takes fs2's exclusive OS lock. Canonical location: serve/registry.lock. fs2 was already a dependency. - Broker apply_at acquires before its fresh load; brain TTL reaping acquires the same guard before its fresh load and holds through snapshot cleanup and durable publication. The process-local REGISTRY_WRITE and its obsolete helper are removed. - Explicit saves/no-op behavior, attachment rollback, reaper unlink-before-save and user-source protection remain. Docs/LAN still bypass the registry guard. No schema, URL, TTL policy, public CLI or production dependency change. - Five live-daemon E2E mutations now hold the guard in narrow lexical scopes. Attachment fixture stale-write retry loops removed, not expanded. ARM11's identity assertion is untouched. DRAFTED REGRESSION COVERAGE — NOT EXECUTED - New fail-closed daemon unit: unavailable_registry_lock_cannot_publish_an_add. A directory occupying the sentinel path refuses lock acquisition and must prevent publication. - Existing concurrent_requests_publish_distinct_entries_without_lost_updates remains and is tagged for the new hazard. - Obsolete two-thread/sleep-based a_reap_shaped_pass_cannot_clobber_a_concurrent_add removed in favor of the process-level cases below. - New integration cases in serving_registry_two_process_int.rs: loaded_reaper_serializes_registration_without_resurrecting_expiry later_reap_preserves_a_registration_published_while_it_was_waiting abrupt_holder_exit_releases_the_sentinel_for_the_waiting_reaper - Two fixture processes use file readiness/command barriers. The waiter must observe an actual fs2 contention error before and after the holder's atomic publication. Both transaction orderings assert acknowledged registration survival, expired-entry/snapshot removal, and persisted ownership/suffix continuity. The third case force-kills the holder while its published transaction guard is alive and requires waiter completion. - Waiting and child cleanup have deadlines; no sleep establishes ordering. Child ownership is RAII with exact-child kill/reap on failure. No production test knobs or IPC variants added. - Scope limit: the process fixture exercises the shared storage contract, not the production broker/brain entry points. A daemon-callsite-only lock removal/reordering is outside that deterministic fixture's reach; runtime source placement and existing real-daemon E2Es remain necessary coverage. No red/green or mutation sensitivity has been executed in this window. FILE LIST (relative to worktree; plus/minus from tracked diff, new files counted separately) +47 -49 crates/spt-daemon/src/livehost.rs +21 -97 crates/spt-daemon/src/servehost.rs +5 -0 crates/spt-store/Cargo.toml +34 -2 crates/spt-store/src/serving.rs +105 -0 crates/spt-store/tests/fixtures/serving_registry_worker.rs [NEW, untracked] +212 -0 crates/spt-store/tests/serving_registry_two_process_int.rs [NEW, untracked] +11 -28 crates/spt/tests/webserve_attachment_e2e.rs +23 -13 crates/spt/tests/webserve_cross_node_e2e.rs +17 -5 docs-site/src/serving/attachments.md +11 -1 docs-site/src/serving/overview.md +8 -0 docs/KNOWN-HAZARDS.md +48 -4 docs/STORAGE.md +6 -0 traceable-reqs.toml TRACE / DOCS REQ-HAZARD-SERVE-REGISTRY-LOST-UPDATE minted before implementation, scoped to manifest-registry-store; doc/impl/unit/int tags placed with drafted evidence. STORAGE owns the full guard contract; KNOWN-HAZARDS 6.14 records the source-proven gap, inferred incident schedule, and observed 1/10 serial sample without treating it as a probability floor. Public serving docs link the lifetime/coordination behavior. Draft status is explicitly PREP-ONLY. Changelog placement and final status wording remain for the authorized validation/release-cleanup phase once milestone home is ruled. VALIDATION / WINDOW BOUNDARY No cargo command of any kind, build, test, check, formatter, linter, rust-analyzer startup, docs generation, traceable-reqs check, or executable reproduction was run by Main or either drafting agent. Work consisted of source reads/edits, private worktree creation, static review, and the requested diff/file accounting. No build pool claimed and no build/test producer launched. This is NOT compile-clean, test-green, trace-green, or merge/ship evidence. NEXT GATE / ROLLOUT Await doyle's explicit build/test GO after operator milestone ruling and box availability. Then run the focused regressions and actual affected E2Es on admitted Windows/Linux lanes, trace check and applicable checks, and the required fresh-SHA consumer gates. Both broker and brain must run the guard implementation for protection; a mixed pair containing an old unguarded writer remains unsafe. Window7 on unchanged fix2 is untouched.