Reading the seven signals
hadur convergence computes one verdict from seven signals. All seven must
be met; the loop stops on evidence, not on fatigue (§7.3). This guide
teaches you to read each one — the authoritative list, like every list on
this site, is the engine export, and the landing page's count is computed
from it, not from this prose.
S1′ — two clean rounds per lens, on the current code
The heart of the verdict. Every lens in the registry needs two
consecutive rounds with zero Criticals and zero Majors — and both rounds
must have reviewed the code that is on disk right now. Each round
records a digest of the git tree (minus .hadur/, the record directory);
two rounds count toward one streak only if their digests match each other
and still match the tree (§7.3.4).
Read a broken streak as information, not punishment: any change to the code — a wave, a hotfix, a "tiny" edit while reviewers were running — voids every lens's streak, because a clean verdict is a statement about the code that existed when it was made. No declaration is required, so no reset can be skipped by failing to write something down.
S2 — every contract section re-verified
A §-section × round coverage matrix over your Plan 0 contract, with no blank rows. S2 tracks where reviewers looked; it says nothing about what kind of question they asked — that is S7's axis, and confusing the two is how suites used to converge with a credential leak still in them.
S3 — the CI regex gate is clean
Your contract's forbidden-alias regex passes against the executable surface on the canonical branch. Mechanical, cheap, and the one signal that runs without a reviewer.
S4 and S5 — the manifest closes
Every plan's declared Exports has a producing task (S4), and every plan's Imports cites its upstream at the current version (S5). Stale pins are drift with a timestamp.
S6 — self-review tables are populated
Every plan's contract-compliance table is filled in — with reasons, not with N/A-for-unclear. A self-review assertion is a claim; this signal checks the claim was at least made explicitly, so a later round can falsify it.
S7 — every lens certifiably exercised
The lens × round matrix has no blank rows — and a row is filled by evidence that the lens ran, never by a label claiming it did. A lens id in a round file is a claim; it counts only with provenance: a reviewer identity distinct within the round, plus a hash-pinned brief on disk that names the lens (§7.3.4). An unlabelled round counts for no lens — inferring one would fail open. Thirteen strings of JSON once bought thirteen "exercised" lenses; that is the bypass this rule exists to close.
The line printed under every met
The tooling verifies artifacts, not attention.
That is the verification floor (§7.3.5), and it prints on every met
verdict on purpose: met is the word after which everything downstream
stops looking, and a tool that reported mechanical confidence past the
point where it has any would be committing the exact failure mode it exists
to detect (§6.5). What the gates buy is real: before them, a false verdict
could be produced by silence; after them, it takes deliberate fabrication.
What they cannot buy is proof that a mind engaged with the code.
Note also the asymmetry the report states: the free sweep's clean streak is weaker evidence than any named lens's — there is no pinned question to re-ask, so its two clean rounds prove only that two independent unfocused passes produced no new question (§7.3.2). Do not round that up.
When the signals say something worse
If a round surfaces many new Criticals and a large share of them are systemic, that is the divergence signal (§7.4): do not dispatch another narrow wave — triage at the contract level, then resume. Convergence and divergence are both verdicts; the tool's job is to stop you from narrating your way past either.
Exit codes
hadur convergence exits 0 when all seven signals are met and non-zero
otherwise, with a distinct code for "computed fine, not met" — see the
CLI reference for the exact table, which is introspected from the
binary and cannot drift from it.