Expand description
Completion as a provable state: which gates a task’s own change set must pass, what each one said, whether that verdict still describes the tree, and therefore whether the task may be called finished.
§The problem this exists for
A worker saying “done” is a claim about a repository, and until this module the
repository had no way to contradict it at the level of the validation pipeline.
finish already refused over the task’s requires — the obligation closure of ADR
0030 — but the eighteen-odd gates the CI model declares had no bearing on whether a task
could be completed at all: they were a property of a pull request, not of a task. So a
task could be finished with rust-check red, or with shell-suite never having run.
§Nothing here is a second declaration
- The gates are
.ai/repo/ci/gates.yaml, read bymodel::GateModel.scripts/ci-planis the other reader; the behavioural case asserts they select the same set. - Applicability is that model’s own rules, applied to the task’s own change set — the paths between the task’s starting commit and the working tree. Not a table of “source implies tests”: the classes in the model already say which paths select which gates, and a class edited tomorrow changes the answer tomorrow.
- The obligations are
share/obligations.yaml, judged bycrate::capability::builtin::obligations. This module derives which of them the change set implies — from each token’s own declaredinputs— and reports whether the task declared it. It does not re-judge a declared one;obligations.closureandmj_validate_obligationsown that and there is one judgement, not two. - The evidence and its staleness are the ledger and the inputs hash, the mechanism
majordomus evidencealready writes and ADR 0030 already argues for.
§The one thing that is new
A gate run is now a fact the record can hold: majordomus evidence --gate <id> --exit <n>
writes a task.gate line carrying the hash of the files that select that gate, and
judge turns those lines into a status. Recording is the shell tool’s, because the
ledger has one writer (ADR 0030); judging is here, because a judgement with two
implementations is how check and a gate come to disagree.
§One lifecycle
A change set goes through the model to a plan, the plan and the recorded runs through the judgement to a status per gate, and the statuses fold into one verdict.
use majordomus_cli::gates::GateStatus;
// the vocabulary the whole module reports in, and the two rules that make it useful
assert!(GateStatus::Fail.refuses() && GateStatus::Stale.refuses());
assert!(GateStatus::Queued.unverified() && !GateStatus::Queued.refuses());
// and the one word that discharges anything
assert!(!GateStatus::Pass.refuses() && !GateStatus::Pass.unverified());Structs§
- Completion
- Done
Question - Gate
- Gate
Class - Gate
Class Match - Gate
Decl - Gate
Plan - GateRun
- Implied
Obligation - Obligation
Standing