feat(locks): key owner liveness on pid + process start identity (#413) - #435
Merged
Conversation
A bare pid is not an owner. Pids are a small recycled namespace, so a crashed holder's number is handed to something unrelated and a lock keyed on the pid alone reads as held forever - or, keyed on a timeout instead, gets stolen from a holder that is very much alive. proc_identity.zig reads the START identity of a pid: /proc/<pid>/stat field 22 on Linux (counted from the LAST ')', since comm may contain both spaces and parentheses), proc_pidinfo(PROC_PIDTBSDINFO) on macOS - a libSystem call rather than the `ps -o lstart=` subprocess the issue suggested, so there is no fork in a lock path, no locale-dependent date parsing and microsecond rather than one-second resolution - GetProcessTimes on Windows, and pid-only liveness anywhere else. Liveness is now "the pid is alive AND it is still the same process", and only a provable mismatch makes a lock reclaimable. Two rules keep the upgrade safe: a record with no start identity (an older graff's, or an identity-less platform's) keeps the pre-#413 pid-only contract, so an in-flight lock is never bricked; and a probe that FAILS is `.unknown`, which means held - wrongly reclaiming a live lock corrupts, wrongly honouring a dead one only waits. Both lock modules take it up. worktree_lease.Owner.start_ns becomes start_id and gains the producer it never had (selfOwner/probeOwners), with a new live_unverified verdict for a pid we cannot identify. The #289 degraded session write - a filesystem whose advisory locks do not work - stops racing unguarded and brackets itself with an owner record, via the reusable claimOwnerFile/releaseOwnerFile the credential store and any future daemon lease can share. Co-Authored-By: Codegraff <blackfloofie@codegraff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #413 — the lease primitive the detachment arc (#431) needs, adopted from the prime-agent analysis.
What's in it
proc_identity.zig(460 lines): a three-valuedProbe—gone,unknown, or an identity — whereunknown(permission denied, odd errno) is never evidence of death. Identity sources: Linux/proc/<pid>/statfield 22 parsed from the last)(comm may contain spaces and parens — fixture-tested withgraff (test) x, where a naive split returns the wrong field), macOSproc_pidinfo(chosen over the issue'sps -o lstart=: no fork in a lock path, microsecond resolution so two graffs started in the same second can't share an identity; struct layout pinned by comptime asserts), WindowsGetProcessTimes. Other platforms degrade to today's pid-only liveness.gone → reclaimable,unknown → held, identity → held iff the record's matches (or the record predates identities).worktree_lease.ziggains the producer it was missing plus alive_unverifiedverdict;session_lock.zig's Two graff instances on one terminal corrupt each other's session and input (SIGTTOU suspend already fixed in #271) #289 degraded path (no working flock) now brackets writes with an owner-record claim instead of racing unguarded.start_id == 0= record from an older binary → exact pid-only contract; an in-flight lock is never bricked. The reusable owner-file protocol is shaped for the oauth-arc credential-store lock to adopt as-is.Evidence
gone; a forged record naming a livesleeppid with a wrong start-id reclaimed while the innocent process is untouched; same pid with its real identity BLOCKED; legacy and bare-pidfile records honored both ways.zig testcompiles clean for x86_64-linux-gnu / aarch64-linux-musl / x86_64-windows-gnu; CI's ubuntu leg exercises the real/procpath.v0.0.241 (unreleased).Part of the prime-agent adoption batch; unblocks #431 milestone 1.