SPEC-049-A: Decentralised CI Runner — Tiered Verification Split

Implements: ADR-049 · Status: Accepted (Phase 0 delivered) · Updated: 2026-06-15

This spec defines the contract for the recommended decentralised CI runner architecture: a tiered split where the untrusted contributor performs the expensive elaboration and a mandatory cheap central re-check is the sole load-bearing soundness gate. Phase 0 is delivered (the §5 conformance suite, see §6); the Phase-1+ control-flow change remains a design target. Today’s Gate A (ADR-006/SPEC-006-B) is the conformance reference because the central re-check already exists — this spec scopes which work it repeats and codifies what it must never trust. It is intentionally implementation-light: the full options analysis is in docs/proposals/decentralised-ci-runner-architecture.md, and the decision is ADR-049.

1. Roles

2. The load-bearing invariant (normative)

The central PR-time re-check is the ADR-048 verify-on-ingest event for proof PRs. It MUST NOT consume any contributor-supplied compiled artifact (.olean, exported term, attestation, hash, or manifest field) as a trusted input. For each PR it MUST, on the trusted surface:

  1. Re-derive the statement from canonical goal source (goals/<id>.lean + record, ADR-018 create-only; ADR-011 binding) — never from a contributor-supplied statement.
  2. Re-elaborate the changed-module reverse-import closure from source — the changed library/Unsorry/*.lean modules plus their reverse-import closure and the generated ADR-011 *Binding modules — against dependency oleans that are either rebuilt on trusted CI or restored from a commit-exact trusted-CI cache (ADR-045). Restored dependency oleans are allowed only when their provenance binds them to the exact base commit, Lean toolchain, Lake manifest, and prior trusted Gate A run that produced them. It MUST NOT leanchecker a contributor-supplied olean.
  3. Run the existing authoritative checks verbatim over that closure: leanchecker replay (ADR-033), serialised axiom_audit against the whitelist {propext, Classical.choice, Quot.sound}, and ADR-011 defeq statement-binding of the proved term to the re-derived statement.
  4. Fall back to a full re-check (ADR-033 global-impact rule) on any change to lean-toolchain, lakefile*, lake-manifest.json, or tools/gate_a/**.

A contributor-supplied .olean reaching leanchecker as a trusted input is a soundness defect, not an optimisation. Rationale (ADR-049 soundness argument): leanchecker trusts olean structure and replays the statement it is given, so trusting client oleans is unsound on (i) crafted-invalid oleans and (ii) real proofs of weakened/renamed statements (the ADR-011 / PR-#64 vacuity class).

3. Advisory manifest (hygiene, not trust)

The contributor MAY attach a manifest to the PR/claim record carrying: toolchain hash, mathlib release tag, the set of changed_modules, and the goal_sha. It is hygiene only — used for fast-fail pre-filters, diagnostics, and griefing metrics. The soundness gate does not depend on it; v1 soundness holds even if the manifest is absent, forged, or wrong, because §2 re-derives everything from canonical source. Any manifest parser is TCB-adjacent and lands under CODEOWNERS (ADR-019).

3.1 Carrying Trust Forward

After the central re-check passes, downstream archive or leaderboard flows may trust the proof only as an already-ingested artifact under ADR-048: the artifact identity, statement binding, toolchain/mathlib context, and provenance must be preserved, and any byte or trusted-context change requires re-verification. Contributor-local logs or manifests are never evidence that the artifact was ingested.

4. Sampling discipline

5. Conformance (defined for the eventual implementation, not asserted here)

  1. Soundness regression (binary, must stay green forever): Gate A rejects (a) a crafted structurally-invalid .olean, and (b) a real, type-correct proof of a weaker or renamed statement than the goal demands. No code path lets a contributor-supplied .olean reach leanchecker as a trusted input.
  2. Behaviour preservation: on a known-good proof and a known sorried module, the scoped central re-check yields the same pass / fail-closed outcome as today’s full Gate A (ADR-006/SPEC-006-B).
  3. Scoping correctness: the re-elaborated set equals the ADR-033 changed-module reverse-import closure (incl. *Binding modules); a global-impact change forces the full re-check.
  4. Cache provenance: any restored dependency olean used by the central build is commit-exact, toolchain-exact, and produced by a prior trusted Gate A run; missing or mismatched provenance forces rebuild or fail-closed.
  5. Determinism: under ADR-002 pinning, an unchanged module’s olean rebuilds byte-identically (the ADR-033 invariant); divergence is a hard fail, never a silent accept.
  6. Cost measurement: central runner-minutes per merged PR are measured baseline vs post-change; the reported saving is the elimination of the redundant unchanged-module build (honest framing per ADR-049), not a SETI-scale figure.

6. Phasing (contract milestones)

7. Out of scope (each its own decision)