Skip to content

ci: a plan job decides what a run is — draft PRs run rest, a merge of a verified head runs nothing (#131) - #166

Merged
afflom merged 4 commits into
mainfrom
claude/ci-two-tier-gate
Oct 17, 2026
Merged

afflom merged 4 commits into
mainfrom
claude/ci-two-tier-gate

Conversation

@afflom

@afflom afflom commented Oct 17, 2026

Copy link
Copy Markdown
Member

Closes #131

The owner decided (2026-10-17): resolve #131 now, with a two-tier gate and reuse of an identical tree's verdict; the SPEC amendments below are that decision.

What costs time today

One full run is about 500 runner-minutes. A merged PR costs about 1,450: about 2.7 runs (a draft push already pays the host matrix, examples and every bdd row, about 300 runner-minutes; only Atlas waited for ready) plus the push run on main, which re-proves, on the same runners and pins, the tree a PR run had just passed. The organization's 20 shared concurrent jobs mean a PR's wall time is the queue, not its longest path (#131, 19:32Z).

What this changes

ci.yml starts with a plan job (.github/ci-plan.sh, one tested script) that decides from the event and the repository alone:

Event Jobs
pull request, draft the rest leg only (about 23 runner-minutes, one job)
pull request, ready (opened, pushed to, reopened, marked ready) the whole gate, unchanged
workflow_dispatch the whole gate
push to main the whole gate, except: a merge commit whose tree is the tree of its second parent, when a pull request run of this workflow for that parent passed every job (none skipped; the join of Atlas, every host, every leg among them). Then nothing runs and the plan names the run.

release.yml still runs just vv whole and reads no earlier run. The legs of vv are now the rows of .github/vv-rows.json (the matrix the plan hands to vv); the Atlas jobs and the host matrix wait for the plan's full. Every other behavior of the gate (profiles, shards, bdd parts, evidence upload) is untouched.

Estimated, not measured until this lands: a merged PR goes from about 1,450 to about 600 runner-minutes (two draft pushes at 23, one ready run at about 520, no push run), and the push runs that queued behind each other on main disappear for the merges that satisfy the rule. The maintainer rule that makes the reuse apply is the one already in force: a PR is merged only on a green head that contains main, so the merge commit's tree is the head's tree.

Rigor

  • RP-14 (statement extended in the register, SPEC §31, the scenario) reads the legs from the file and requires every if: of the workflow to be one of three forms (a step's !cancelled(), a job's needs.plan.outputs.full == 'true', vv's needs.plan.outputs.rows != '[]').
  • It runs the script in a scratch git repository with a stand-in for gh against planted events and requires the whole gate everywhere the evidence is not complete: no run, a skipped or failed job, no Atlas join, a missing host, a missing leg, a run of a draft, a failed query, a merge that changed the tree, a push that merges nothing.
  • Nine defects were planted in the script, the workflow and the legs file; each fails the case with its own line (VERIFICATION.md, "The plan of a CI run can fail").
  • R3: the case was changed first and fails against the previous ci.yml (it needs a plan job).
  • SPEC §8.3 and §9.4 name what a run is; the only condition on a recipe is the plan's, stated as such.

Check on this PR's own runs

This PR is a draft on purpose: its first run must be the rest leg alone (plan + one leg), which proves the dynamic matrix and the script on a real runner for about 23 runner-minutes. I mark it ready afterwards, which runs the whole gate once.



Generated by Claude Code

afflom and others added 2 commits October 17, 2026 16:38
… a merge of a verified head runs nothing (#131)

A merged pull request cost about 1,450 runner-minutes on a pool of 20 jobs
shared by the organization: about 2.7 runs of about 500 (a draft push already
paid the host matrix, examples and every bdd row, about 300) and a full
re-run on main of a tree that a pull request run had just passed. The queue,
not the longest path, was the delay (#131).

- ci.yml starts with `plan` (.github/ci-plan.sh), which decides from the event
  and the repository alone: a draft pull request runs the `rest` leg only; a
  ready pull request, workflow_dispatch and a push to main run every job; a
  push to main that merges a head whose tree it equals runs none when a pull
  request run of that head passed every job (the join of Atlas, every host,
  every leg, none skipped), and says which run.
- The legs of `vv` are the rows of .github/vv-rows.json, handed to the matrix
  by the plan; the Atlas jobs and the host matrix wait for the plan's `full`.
- RP-14 reads the legs from the file, requires every condition of the file to
  be one of three forms, and runs the script in a scratch repository against
  planted events (a draft, a ready pull request, a request, a push, a merge
  that lands its head's tree with passing and failing evidence, a merge that
  changed the tree, a failed query). Every planted defect is recorded in
  VERIFICATION.md. The statement of RP-14, SPEC §8.3 and §9.4 are extended.
- release.yml is unchanged: it runs `just vv` whole and reads no earlier run.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013QppGKetUURseXowZun9KY
…ermission denied), and RP-14 requires it

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013QppGKetUURseXowZun9KY
… host leg of the first full run failed on the stand-in's PATH)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013QppGKetUURseXowZun9KY
@afflom
afflom marked this pull request as draft October 17, 2026 18:27
@afflom
afflom marked this pull request as ready for review October 17, 2026 19:03

afflom commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Maintainer review: approved at b5a739d.

This PR was written by the maintainer session, so the approval rests on two things and not on a second pair of eyes: the owner's recorded decision on #131 (two-tier gate plus reuse of an identical tree's verdict, the SPEC §8.3/§9.4/RP-14 amendments, no admin settings), and the evidence on this head.

Evidence, from the runs of this exact head (it contains main at 97a3df7, behind by 0):

  • Draft run (39058429884): plan and just vv (rest) only; every other job skipped by construction. This is the first run of the plan job on a real runner.
  • Ready run (39060792376): the whole gate, every job success: the four hosts, all six just vv legs, Atlas prefix, census a–d, cert4, cert4-replay, closure, orbit, pairs a–d and the join; repro and honesty also green.
  • RP-14 plants (nine, in VERIFICATION.md "The plan of a CI run can fail") each fail the case with their own line.

What is not yet measured: the saving. It is an estimate until the first PR merges under this rule; I will post the measured runner-minutes on #131 from that merge.

Merging with a merge commit, sha pinned.


Generated by Claude Code

@afflom
afflom merged commit 8765fee into main Oct 17, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: the PR gate verifies UOR Atlas by main's signed attestation, not by re-proving it (§9.4)

1 participant