Skip to content

The gate

lint exits 1 when anything drifted, and that exit code is the entire difference between a gate and advice. It reports every violation, every line that stopped round-tripping, every dependency nothing can satisfy and every pointer or section nothing answers — as file:line:column, each carrying the command that closes it.

It is the backstop and not the primary rule. The schema is enforced where the text is created, so a project whose every write went through add has nothing here to find; what lint catches is what bypassed that — a hand edit, a bad merge, a file somebody pasted into.

--fix repairs only the derived: an annotation, a pointer, dependency order, a marker’s codepoint, whitespace, a queue entry, an orphaned heading. It never writes prose, which is the law the whole tool is built on — nothing here composes a sentence for you.

explain answers what a finding class is rather than what one line did, which is the read for somebody looking at a failed job. merge is the three-way merge git cannot make on its own, because two branches that both appended a task line produce a conflict git resolves by guessing and this resolves by knowing the format. guard is the hook’s own entry point: a payload arrives on stdin and an answer leaves on stdout, and nobody types it.

merge

Reads — and writes when --register--ours is given. Served to an agent as merge_check.

Merge three versions of one governed file structurally. Every id is decided on its own against the ancestor, so two branches appending under one heading is two additions and not a conflict; an id both branches created is reported by name, because `renumber` moves one of them and a driver that picked a side would be choosing whose task disappears. Anything it cannot prove falls back to git's conflict markers and exits 1. `--register` wires it up, and `--check` reads the wiring back: a driver git can no longer run is otherwise silent until the merge it was registered for.

ArgumentNotesWhat it is
basethe ancestor version (git's %%O)
oursthis branch's version, and where the result is written (%%A)
theirsthe other branch's version (%%B)
--path PATHthe file's pathname in the repository (%%P) — which governed file this is
--registerdefault falsewrite the .gitattributes lines and print the git config this driver needs
--checkdefault falseread the driver back out of git config and say whether it still runs; write nothing
--jsondefault falsemachine-readable form of --check; refused on the driver and on --register

lint

Reads — and writes when --fix is given. Served to an agent as lint.

The backstop for what bypassed `add`. Reports every violation, every line that does not round-trip and every dep nothing can satisfy — and exits non-zero, which is the entire difference between a gate and advice.

ArgumentNotesWhat it is
--fixdefault falsenormalize what is mechanical first, then report what needs a decision
--since REValso report a rationale section edited since REV whose task line was not (RK36): HEAD in a commit hook, the base branch in CI
--baseline REVreport only what this working tree added since REV, forgiving the standing debt (RK84): the gate a repository can adopt before it has paid it off
--quietdefault falseprint only the summary line, for a hook that wants the exit code
--jsondefault falsemachine-readable form

repair

Writes. Served to an agent as repair.

The gate says what is wrong and, since RK420, what closes it. This spends that: the mechanical pass, then every finding whose remedy is a complete command, one at a time with the report re-read between them. What needs a sentence or a choice is printed instead — that half is yours, and the tool writing it would be the generator this project refuses. Exits 1 while anything is left, which is the gate's own contract and not a second one.

ArgumentNotesWhat it is
--dry-rundefault falseprint the commands and run none of them
--jsondefault falsemachine-readable form

explain

Reads. Served to an agent as explain.

A finding is about one line; a code is about a class, and there has never been anywhere to look the second one up. Three fields and no more — the worked example is the argv the finding already carries. With no code, lists every one this gate can report, which is the vocabulary it never published.

ArgumentNotesWhat it is
codea code as `lint` prints it, e.g. id.duplicate; omitted, lists them all
--jsondefault falsemachine-readable form

guard

Reads.

Read one hook payload on stdin and answer it on stdout (RK22). A `PreToolUse` payload naming a governed file is denied with the command to call instead; a `Stop` payload runs `lint` and blocks on what it refuses. Everything else is answered with silence. Not for a human to call: the harness runs it before every write, so it always exits 0 — a non-zero exit is read as the hook itself having failed, which would deny nothing and report a broken hook on every edit in the session.