1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! 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):
//! ```ts
//! const sameNamespace = readlinkSync('/proc/self/ns/pid') === record.ownerPidNamespace;
//! ```
use Path;
use ;
/// 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; a crashed foreign owner stops blocking after this long.
/// 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. Measured: the longest worktree add in the add timing log (48 adds, 2026-11-03T08:55Z to
/// 15:06Z, `totalMs`) took 539.7 s, and the nearest log of a command that waits, the commit timing log (1,051 commits,
/// 2026-11-02T09:01:37Z to 2026-11-03T15:10:12Z), has a longest of 750.6 s. No log records the length of a merge, which waits up
/// to the 1,800 s live lock wait (`wait_limit.rs`, `DEFAULT_LIVE_WAIT`) with its record already written, so an hour is twice the
/// longest wait the code allows and 4.8 times the longest command measured. If that wait is lengthened or removed, this value
/// must be revisited with it. The logs hold commands of the host's own PID namespace, so no foreign-namespace hold was observed
/// directly. Kept at an hour as the coordinator's pick under the owner's delegation, open to the owner's veto
/// (`doc/planning/cli-git-shipped-limits-audit.md`, "Foreign-owner patience").
pub const FOREIGN_OWNER_PATIENCE: Duration = from_secs;
/// 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.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// readlinkSync('/proc/self/ns/pid')
/// ```
/// 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.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// recorded !== undefined && current !== undefined && recorded !== current
/// ```
/// What:
/// Whether a record written by an owner of another namespace is old enough to stop counting as alive.
/// 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.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// Date.now() - statSync(recordPath).mtimeMs > FOREIGN_OWNER_PATIENCE_MS
/// ```
/// 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.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// age > FOREIGN_OWNER_PATIENCE_MS
/// ```
/// What:
/// Whether an owner recorded in `recorded` counts as alive without any PID probe, or nothing when the PID decides.
/// Why:
/// Callers share one rule: an owner of another namespace is alive until its record outlives the patience.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// isOtherNamespace(recorded, current) ? !hasExpired(recordPath) : undefined
/// ```
/// Namespace controls stay out of the release executable.