* fix(plan-tune): lock developer-profile writes and give derive a unique temp file (#3437)
Concurrent background --derive runs shared developer-profile.json.tmp and rewrote the whole profile unlocked, so renames failed with ENOENT and a concurrent --log-session was dropped. Every read-modify-write now holds developer-profile.json.lock and writes a mktemp file.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore(plan-tune): remove applySignal and newDimensionTotals (#3435)
Both lost their last production caller when --derive moved onto accumulateSignals; only three unit tests referenced them.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
Use the PID in the lock token, anchor a relative state root once so do_derive's cd cannot leak the lock, and note the stale-takeover tradeoff.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 2)
Keep Windows drive-letter state roots absolute when anchoring a relative root, and say which writers do not take the lock yet.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: take over a lock only from a dead holder, one taker at a time
Step 11 voices: a late stale-lock mv could evict a fresh owner, a failed mv spun past the timeout, and the 10 s give-up sat under the 30 s stale age. Takeover now checks the holder's pid, re-reads the owner under a takeover lock, falls through to the give-up on failure, and reports an unwritable state directory at once.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: take over an owned lock older than 5 minutes (pid reuse)
A crashed holder whose pid now belongs to a live process kept its lock forever. An owned lock past 5 minutes now counts as abandoned, and cleanup removes a takeover lock this writer holds.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: changelog fragment for the profile lock (#3437) and dead-helper removal (#3435)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: say the 5-minute takeover applies whatever the pid
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: keep the give-up test inside the type ratchet
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>