Skip to main content

Module gates

Module gates 

Source
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 by model::GateModel. scripts/ci-plan is 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 by crate::capability::builtin::obligations. This module derives which of them the change set implies — from each token’s own declared inputs — and reports whether the task declared it. It does not re-judge a declared one; obligations.closure and mj_validate_obligations own that and there is one judgement, not two.
  • The evidence and its staleness are the ledger and the inputs hash, the mechanism majordomus evidence already 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
DoneQuestion
Gate
GateClass
GateClassMatch
GateDecl
GatePlan
GateRun
ImpliedObligation
ObligationStanding

Enums§

GatePlanMode
GateStatus