Expand description
Processes: identities, trees, sockets, signals and quiet-time ledgers. What: Processes: identities, trees, sockets, signals and quiet-time ledgers. Why: The facts about processes are shared by locks and pushes.
In TS you’d write (pseudocode):
// process/index.ts: one `export * from './file'` per module below.Modules§
- pid_
namespace - 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.
- process_
identity - Process-birth identities in the incumbent’s exact spelling.
What:
Process-birth identities:
a string that names one process for its whole life and
changes when its PID is reused,
in the incumbent’s exact spelling.
Why:
Every lock and transaction records its owner’s PID and birth identity;
an owner is
alive only while its PID names a process with the recorded identity.
Both wrappers
judge each other’s locks,
so the strings must agree byte for byte
(
src/policy-engine/commit-transaction-process-identity.ts; the decision indoc/handover/cli-git-rust-implementation.md, “Adopted without a question”; that section moved on 2026-11-03 todoc/planning/cli-git-rust-open-decisions.md). - process_
start - Process start times for lock owners,
read from
/proc,psor the Windows process table. What: The wall-clock start time of a process, with its resolution, for comparing a Git lock PID file’s owner with the lock’s change time. Why: A PID file names a live owner only when that process started no later than the lock changed; a younger process reused the PID. Linux derives the start from/proc/<pid>/statfield 22,/proc/uptimeand the current time; macOS readsps -o lstart=; Windows readsGet-ProcessStartTime(src/index-lock/process-start-time.ts). - process_
tree - The processes below one process, read before it is stopped and signalled only while they are still the ones found.
What:
The processes below one process: found before it is stopped, and signalled afterwards, each only while it is still
the process that was found.
Why:
Stopping a process does not stop what it started. A
git pushthat is sentSIGTERMorSIGKILLleaves its transport helper (git-remote-http,ssh) and the hooks it ran (git-lfs) alive, orphaned to the init process, holding their connection until their own timeout ends them (measured: a helper stayed 60 seconds, agit-lfsthat never exits stayed for good). The tree has to be read before the root dies, because a child’s link to its parent is gone once the parent has exited. A process number can be reused, so each process is identified by the start time the kernel recorded for it, and a number whose start time changed is not signalled. The list comes from/proc, so only Linux finds any; elsewhere the tree is empty and only the root is stopped. - process_
use - The processes of this host that use a directory or a file.
What:
The processes of this host that use a directory or a file:
a working directory or an open descriptor inside the directory,
or an open descriptor on the file.
Why:
Recovery may treat a directory or a lock as abandoned only when no process can still be using it.
A process that holds a path open is the one proof of use that survives a lost record,
so the scan reads it from
/procand says what it could not read instead of guessing. Only processes of the scanning account are reported as unreadable: another account’s process cannot have opened a private file this account created, and every unprivileged scan meets some of them. - quiet_
ledger - The longest quiet gap of every Git step and tool this process ran, kept until a timing record takes it.
What:
The longest quiet gap of every Git step and every tool this process ran, kept until a timing record takes it.
A quiet gap is a stretch in which the step showed no sign of work: no bytes moved, no processor time, no task running or
waiting for the disk (the signs of
push_progress.rs). Why: A step ends only when it has been quiet for a window, so the window must be set above the longest gap a healthy step shows (doc/planning/cli-git-shipped-limits-audit.md, “Time limits on Git child steps of a commit”). Nothing logged a gap before this, only whole times, and a whole time is an upper bound of the gap, never the gap. The timing records (commit_timing.rs,add_timing.rs) take the figures when they are written, so a measurement comes from the runs the person’s own work makes. A step that was ended for being quiet is kept apart from the steps that ended by themselves, because only the steps that ended by themselves show how quiet a healthy step gets. - signal_
relay - Catching SIGINT, SIGTERM, SIGHUP and SIGQUIT while a Git child runs, and relaying only process-sent signals.
What:
Catching
SIGINT,SIGTERM,SIGHUPandSIGQUITwhile the wrapper waits for a Git child, relaying a signal to that child only when a process sent it, and reporting how the child ended.SignalGuardowns the handlers for its lifetime and restores the previous dispositions on drop. Why: A wrapper that dies on a signal leaves its commit transaction for recovery and Git running; one that catches the signal can end Git, release its locks and remove the transaction first. A signal from the terminal already reached Git as part of the foreground process group, so relaying it again would deliver it twice. - thread_
quiet - Whether a thread of this process is at work, and the clock that says when it has been quiet for a window.
What:
Whether one thread of this process is at work, judged with the signs the push meter reads for a child process, and the
clock that says when the thread has shown none of them for a window.
Why:
The Markdown linter runs on a thread of this process and the gateway call of the standards review blocks one, so neither
has a child process whose tree
push_progress.rscould sample. Linux keeps the same counters for each thread under/proc/self/task/<tid>/: the bytes it read and wrote (io), and its processor ticks and state (stat). The thread being judged is never the thread that reads these files, so the reading does not count as the thread’s work. Where/proc/self/task/<tid>/ioorstatcannot be read nothing is measured and the thread is never judged quiet.