Skip to main content

Module process

Module process 

Source
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 in doc/handover/cli-git-rust-implementation.md, “Adopted without a question”; that section moved on 2026-11-03 to doc/planning/cli-git-rust-open-decisions.md).
process_start
Process start times for lock owners, read from /proc, ps or 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>/stat field 22, /proc/uptime and the current time; macOS reads ps -o lstart=; Windows reads Get-Process StartTime (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 push that is sent SIGTERM or SIGKILL leaves 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, a git-lfs that 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 /proc and 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, SIGHUP and SIGQUIT while 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. SignalGuard owns 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.rs could 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>/io or stat cannot be read nothing is measured and the thread is never judged quiet.