Skip to main content

Module candidate

Module candidate 

Source
Expand description

Candidate content: what a commit or push would add, read from the index or objects, and the scanner run over it. What: Candidate content: what a commit or push would add, read from the index or objects, and the scanner run over it. Why: Policies judge candidates, so the readers and the scanner adapter share a folder.

In TS you’d write (pseudocode):

// candidate/index.ts: one `export * from './file'` per module below.

Modules§

blob_batch
Loading many blobs through one git cat-file --batch. What: Loading many blobs through one git cat-file --batch, optionally from a private object store, with strict parsing of the batch output. Why: Post-landing completion reads the original and intended bytes of every added path; one batch replaces a Git start per object (src/policy-engine/blob-batch.ts).
candidate_attribute
Which candidate paths have their text Git attribute unset, read from the state the candidates were listed from. What: Which candidate paths have their text Git attribute unset (-text, which the binary macro includes), resolved by git check-attr against the same state the candidates were listed from. Why: A path whose text attribute is unset declares that its exact bytes matter, as a fuzz seed’s trailing bytes do. The attribute lives in the package’s own .gitattributes, so it moves with the package, unlike a path list kept elsewhere. Staged and projected candidates are answered from the private index, so a .gitattributes staged by the same command applies to it and an unstaged worktree edit does not; landed and pushed candidates are answered from the tree of the commit they came from.
candidate_batch
Pure framing of one git cat-file --batch reply. What: Read one git cat-file --batch reply from a byte stream, with no process involved. Why: Object bytes are untrusted input that may contain anything, including text that looks like a reply header. The reply is therefore framed only by the header’s declared size, never by searching content, and every malformed shape is a typed failure instead of a guess.
candidate_error
The one failure type of the candidate layer and its closed list of causes. What: The one failure type of the candidate layer, with a closed list of causes. Why: Every candidate failure stops policy evaluation (a file that could not be read was not checked), and callers branch on the cause without parsing message text.
candidate_known_content
Which candidates hold content that a parent commit’s tree already holds, found by exact object name. What: Which candidates hold content that a parent commit’s tree already holds, found by exact blob object name. Why: A pure rename or a copy re-lists a file as an addition, and a merge lists every file one parent lacks as an addition, although the bytes are already in history. Scanning them again refuses moves of files that were accepted when they entered history, while an object name is the hash of the bytes, so a candidate whose object a parent holds carries no byte that is new. The comparison is by object name only: never by pathname, never by similarity, so one changed byte makes the content new.
candidate_object
Validated Git object names and the file modes a candidate can carry. What: The two Git vocabulary types every candidate carries: an object name and a file mode. Why: Object names are written into the object reader’s request stream, so only text proven to be a complete hexadecimal name may ever become one; modes decide whether a candidate has blob content at all.
candidate_prediction
What git add would stage, and the worktree files a direct command selects. What: The two candidate sources that need a private index: what git add would stage, and the worktree files a direct git cli-git check or fix selects. Why: Both are answered before Git touches the real index. git add is replayed on a private copy of the index, and the candidates are the entries the replay changed, as the installed wrapper’s add-policy-facts.ts and add-staged-delta.ts define them. A direct command stages its scope with git add --all on a private copy, as direct-check-facts.ts does, and every selected entry is a candidate. Either way the bytes are blobs Git hashed from the worktree at that moment, read through the one object reader, so the number of Git processes does not grow with the number of files.
candidate_private_index
A private, timestamp-preserving copy of the real index, removed when dropped. What: A private copy of the real index, in its own directory beside it, removed when the copy is dropped. Why: Predicting what git add would stage means running it against an index nobody else reads, so the real index never changes before the policies have answered. The copy keeps the real index’s access and modification times: Git re-reads an entry whose stat data is not older than the index file, and a copy with a fresh time would make it trust stat data from the same second as a later edit of the same size, so the prediction could miss that edit (the installed wrapper’s index-file-timestamps.ts, issue #544).
candidate_reader
The long-lived object reader that answers every blob read of an invocation. What: One long-lived git cat-file --batch process that answers every object read of an invocation. Why: Starting Git costs far more than reading one object, so candidate bytes are read through a single process whose count does not grow with the number of files. Blob bytes are remembered by object name: a name always denotes the same bytes, so a remembered blob can never become stale.
candidate_record
Pure parsing of raw NUL-delimited changed-path records. What: Parse the NUL-delimited raw records of git diff-index and git diff-tree. Why: One listing process names every changed path with its mode, object and change kind, so no per-path Git process is ever needed. Pathnames are kept as the raw bytes Git printed; they are never decoded.
candidate_stage
Pure parsing of git ls-files --stage records and the delta between two index states. What: Parse the NUL-delimited stage records of git ls-files --stage -z, find the paths one staging operation changed, and turn them into candidate records. Why: git add is checked before Git runs it, by replaying it on a private copy of the index. The paths it would stage are exactly those whose index records differ between the copy before and after the replay. Comparing complete records, conflict stages included, finds a resolved conflict like any other change, and an unrelated conflict elsewhere in the index never stops the comparison. Pathnames stay the raw bytes Git printed.
candidate_store
Per-invocation listing, lazy bytes and invalidation of candidate versions. What: The per-invocation owner of candidate versions and candidate bytes. Why: Policies read committed or staged content, never whatever is in the live worktree. A version costs one listing process, its bytes come from one long-lived object reader, and neither count grows with the number of files. After a fix or replay changed the index, invalidate retires every version.
candidate_tree
The files of a commit’s tree with their modes and objects. What: Parse the NUL-delimited records of git ls-tree -r -z --full-tree <commit>: every file of one commit with its mode and object. Why: The dependent-version policy compares the candidate state with HEAD: it reads each workspace manifest’s HEAD bytes, and a direct fix may change a tracked file it did not select only when HEAD holds that file as the same ordinary blob. One listing answers both for every path. Pathnames stay the raw bytes Git printed.
candidate_version
Immutable candidate versions: identity, pathname, mode, change and object per path. What: An immutable candidate version: the paths one Git state changes, each with its identity, mode and object. Why: Every policy of one pass must judge the same files. A version is listed once and then only read, so path metadata is shared instead of re-queried, and a later fix or replay produces a new version instead of altering this one.
scanner_adapter
The linked forbidden-strings scanner: one load per invocation, typed redacted findings. What: The repository’s forbidden-strings scanner, linked in and loaded once per invocation. Why: The TypeScript wrapper wrote each candidate to a temporary file, started the scanner as a child process and parsed its standard error. Here candidate bytes go straight to the scanner library, and its own typed findings come back. Nothing is re-derived: rule loading, the rule cache, matching, redaction and the fail-closed findings all stay the scanner’s.
scanner_failure_code
Which engine failure code each candidate and scanner failure carries. What: Which engine failure code each failure of the candidate and scanner layers carries. Why: An engine failure names its cause. content-unavailable means candidate bytes or a repository fact could not be read; policy-incomplete means the policy’s own machinery failed. Deciding the code here, beside the failures, makes every policy that reads candidates or scans them report the same code for the same cause.
scanner_run
One scan pass over a candidate version’s exact bytes. What: Scan every eligible candidate of one version through the loaded scanner. Why: This is the whole forbidden-strings check of one policy pass: candidate bytes come from the candidate store (staged or committed, never the worktree), go to the scanner in memory, and the scanner’s own results come back. No temporary file is written and no process is started per file.
scanner_selection
Rules-file precedence and which candidates the scanner is given. What: Which rules files the scanner loads, and which candidates it is given. Why: The scanner library filters nothing; the standalone scanner and the TypeScript policy applied these choices around it. They are restated here once, as pure functions: the rules-file precedence (the configured rulesFile entries, then the FORBIDDEN_STRINGS_RULES list, else forbidden-strings.local.txt in the repository root) and the paths that hold the rules themselves, which would otherwise match their own content.