Expand description
The PID namespace an owner record names, and the rule for owners of another one. What: The PID namespace an owner record names, and the rule for judging an owner that lives in another one. Why: A PID means something only inside its PID namespace. A wrapper in a container that probes a host owner’s PID finds no process (or an unrelated one), so it would judge a live owner dead and recover or retire what the owner still holds (issues 1781 and 1784). A record therefore names its namespace, and an owner of another namespace is judged by the age of its record instead of by the PID.
In TS you’d write (pseudocode):
const sameNamespace = readlinkSync('/proc/self/ns/pid') === record.ownerPidNamespace;Structs§
- Expired
Foreign Record - What: A record of another PID namespace that is older than the patience: neither alive nor dead. Why: Owner, 2026-11-04, “Refuse and name it (Recommended)”: expiry no longer authorizes a command to treat a foreign owner as dead and to recover, take over or remove what it holds. The age is a length that nothing bounds (a write that cannot be run twice may run past any number, and a step the wrapper left running outlives the wrapper), so it proves no death. The command stops, changes nothing, and says which record it found and what a person checks before removing it.
Constants§
- FOREIGN_
OWNER_ PATIENCE - How long an owner of another PID namespace counts as alive, measured from when its record was written.
A commit or a lock hold lasts seconds to minutes. Past this age a record is neither alive nor dead: the command that finds it stops,
changes nothing and names it (
ExpiredForeignRecord; owner, 2026-11-04, “Refuse and name it (Recommended)”), because the age proves no death, and a crashed foreign owner’s record is removed by the person with thermthe error gives. Three kinds of record are judged by this age. A merge’s intent record (merge_isolation_journal.rs,write_merge_intent, written once and synced per merge) and a claim file (single_owner_claim.rs,write_private, written once) are not rewritten while the owner works, so the age is the owner’s whole hold; the item path of a worktree add is judged by its own modification time (worktree_copy_owner.rs,is_alive), which the add’s work can move, so its age is at most the add’s length. The patience must outlast the longest such hold. Basis: twiceLOCK_CEILING(10 minutes,wait_ceilings.rs), the longest a merge waits for a foreignindex.lockwith its record already written, so 20 minutes. It is derived, not written as a number, so the two cannot drift apart again: it was an hour because it was twice the 30 minute live lock wait ofwait_limit.rs, a file that no longer exists, and the owner’s rule (2026-11-03, “nothing should ever wait forever or indefinitely”) bounded that wait atLOCK_CEILING. Measured: the longest worktree add in the add timing log (79 adds, 2026-11-03T08:55:46Z to 2026-11-04T13:53:17Z,totalMs) took 539.7 s and the longest commit in the commit timing log (1,838 commits to 2026-11-04T14:08:47Z) 750.6 s, so the patience is 1.6 times the longest command measured and 2.2 times the longest add. The logs hold commands of the host’s own PID namespace, so no foreign-namespace hold was observed directly. IfLOCK_CEILINGchanges, this value follows it; revisit the margin then (doc/planning/cli-git-shipped-limits-audit.md, “Foreign-owner patience”).
Functions§
- age_
outlives_ patience - What: Whether a record of this age has outlived the patience; exactly the patience still counts as alive. Why: The boundary is a fact of the rule, so it is separated from the clock to be checked exactly.
- current_
pid_ namespace - What:
The identity of this process’s PID namespace, such as
pid:[4026531836], or nothing where the system has none. Why: The kernel names a namespace by an inode; two processes share a PID space exactly when the names are equal. - foreign_
owner_ standing - What:
How a record is judged when it names another PID namespace: alive while it is younger than the patience, refused after it, and
nothing for a record of this namespace or of none, which the PID decides.
Why:
Callers share one rule: an owner of another namespace is alive until its record outlives the patience, and then the command
stops (
ExpiredForeignRecord) and changes nothing. - foreign_
record_ age - What: The age of a record file, or nothing when it cannot be measured. Why: The record file’s modification time stands for when the owner started; a record that cannot be measured keeps its owner alive, because the wrapper never retires what it cannot prove dead.
- is_
other_ namespace - What: Whether a recorded namespace and the reader’s namespace are both known and differ. Why: Without both names nothing proves the PID space differs, so the PID probe keeps its old meaning; a record written before this field existed carries no name.