fix(mcp): mark a writer record ready only when it is still the owner's own
A daemon or fallback writer now marks writer.pid ready only when the record on disk is still the one it acquired. Before, it stamped ready: true onto any record with its process ID.
markWriterReady (src/mcp/writer-lock.ts) publishes catch-up readiness by renaming a temp file over writer.pid, and retries 100 ms later when the record is busy. Before writing, it checked only that the record's pid was its own. Every other ownership check also compares mode and start time: updateWriterLock, assertOwnedRoot in src/mcp/engine.ts, and the daemon's start and refresh checks in src/mcp/daemon.ts. So a same-pid record of a newer generation, such as the successor record PR #542's test writes, could get the older owner's readiness.
markWriterReady(projectRoot, owned)now takes the acquired record and returns without writing unless mode and start time match.activate()insrc/mcp/project-lifecycle.tspasses the recordtryAcquireWriterLockreturned. That is the record it wrote on a fresh acquisition, or the daemon's own record when it reuses one.ownedis required. Nothing outside the repository calls the function, so the pid-only form is gone. Tests and fixtures pass the record they acquired, or the one on disk where they model a writer's own record.
Nothing changes for users: an owner's own record always matches, and a record of another generation was already rejected by the later ownership checks. No changelog entry.
Validation at e3e89415, Linux:
- New test
__tests__/writer-lock.test.ts"publishes readiness only on the record generation it was given" fails before the change: readiness was stamped onto thestartedAt + 1record. It passes after. - It covers the first, synchronous publication. The 100 ms retry runs the same check from the same closure, and the existing contended-readiness cases cover the retry itself.
- Full suite (
npx vitest run --minWorkers=1 --maxWorkers=8): 754 files and 9,323 tests passed, 40 skipped.
README: no user-visible change; checked the "About this fork" tables, and no row is affected.
Summary by cubic
Fixes catch-up readiness publishing so a daemon or fallback writer only stamps ready: true onto the writer record it actually owns. Before, markWriterReady checked only the process ID, so a same-pid record of a newer generation could receive the older owner's readiness.
- Compares mode and start time against the acquired record and skips publishing when they differ, including on the 100 ms retry.
- Takes the owned record as a required parameter;
activate()passes the recordtryAcquireWriterLockreturned, and tests and fixtures pass the record they acquired.
No user-visible change and no changelog entry.
Summary by CodeRabbit
- Bug Fixes
- Improved project readiness reporting when multiple processes compete for control. A process now marks a project ready only if it still holds the same lock, preventing an outdated process from changing the readiness state of its successor.