Expand description
The contract every checker meets, and the machinery that makes it hold.
§What a checker is for
Law III: model output is a proposal, never ground truth. Something has to decide whether the proposal may commit, and that something must not itself be a model — otherwise the guarantee is circular and the whole engine is an elaborate way of asking a language model twice.
A Checker is that decider. It takes the proposal (WorkOrder) and what
actually happened (Condensate), and returns a verdict. It is the only
thing in BoundGraph whose answer can cause a state change.
§Why check is a provided method
An implementation writes judge and never touches the
rest. check wraps it and does three things the
implementation is not trusted to do for itself:
- Refuses a checker that holds too much authority, before it runs.
- Binds the verdict to what was checked, by putting the digests of the work order and the condensate into the evidence itself.
- Signs, or fails.
Every one of those is a property the system relies on across all checkers,
and a guarantee spread across implementations is a guarantee that the sixth
implementation breaks. This is the same reason Slicer::condense is a
provided method in feature 07.
§A checker cannot call a reasoner
Not by convention, and not by code review. By its capability set.
Checker::grants declares what the checker needs, and check refuses to
run one whose declaration is not within checker_ceiling. The ceiling
omits net and secret, which are the only two ways to reach a model
provider: no egress, no API key, no inference. It also omits time and
rand, which is the same mechanism enforcing the determinism requirement,
and fs:write, so a checker cannot alter the thing it is judging.
An undecidable comparison is a refusal, not a pass — Tri::Unknown is
treated exactly as feature 02 treats it everywhere else.
§A checker has no failure channel except its verdict
judge returns a Judgement, not a Result. That is
deliberate and it is the point of the three-valued Verdict: a checker
whose compiler crashed, whose test run timed out, or whose input was not
what it expected returns Verdict::Inconclusive, which never commits.
Had judge been fallible there would be two ways to say “no answer” — an
Err and an Inconclusive — and somewhere a caller would handle the Err
by logging it and carrying on. There is no such caller here because there is
no such Err.
CheckError exists for the two things that are not a checker’s opinion:
a checker that declared authority it may not hold, and a signature that
could not be produced. Neither yields evidence, so neither commits.
§Determinism
A checker is a pure function of (work order, condensate). No clock, no
randomness, no iteration over a hashed collection, no network. Replay
(US-1006) re-runs a recorded check and compares the evidence byte for byte,
and ed25519 signatures are themselves deterministic, so the whole pipeline
from inputs to signature reproduces — which is what makes a cassette test
(US-1008) able to assert that a verdict did not change.
Structs§
- Constant
- A checker that always returns the same verdict.
- Judgement
- What a checker decided, before it becomes signed
Evidence.
Enums§
- Check
Error - The engine refused to produce evidence.
Traits§
- Checker
- Layer 5: turns a proposal and a result into a signed verdict.
Functions§
- checker_
ceiling - The widest authority any checker may hold.
- ensure_
model_ free - Whether a grant set is narrow enough for a checker to hold.