Skip to content

A projection that stops being applied turns a build red, and a gate that cannot reach GitHub reports that it cannot rather than passing

The neighbouring claim — [GitHub milestones and issues are generated from the canonical

guaranteed Deterministic and blocking. Implemented, and a behavioural test proves it.

The adapter has exited 11 on drift since it was written and nothing called it, so the projection decayed to a tenth of the model over five days with every build green. The gate refuses behind, edited, conflict, unmanaged, state and milestone outright, and ratchets the backlog of unprojected records against .ai/repo/ci/github-drift-baseline.txt, which may fall and may never rise.

What it means

The neighbouring claim — GitHub milestones and issues are generated from the canonical model — is about what scripts/github-sync renders and what it refuses. It says nothing about whether GitHub has actually received any of it. This claim is the other half: that the two agree now, and that a build fails when they stop agreeing.

How it works

scripts/ci/github-check reads the remote and classifies every record. It applies two tolerances rather than one.

Refused outright, from the first run, with no allowance:

statewhat it means
behinda canonical record moved and nobody projected it
editeda person rewrote a generated region
conflicta person rewrote it and the record has moved since
unmanageda remote issue claims a canonical id this repository does not have
statethe remote's open/closed disagrees with the derived status
milestonethe remote's milestone assignment disagrees

Ratcheted against .ai/repo/ci/github-drift-baseline.txt:

statewhat it means
missinga canonical record with no counterpart on GitHub
adopta counterpart carrying no identity marker

The baseline may fall and may never rise. Writing it is a deliberate act, in the same idiom .ai/repo/projection-baseline.txt already uses for the commands no capability claims.

A gate that cannot reach the remote — no gh, no token, no permission — exits 12 and names which. It never exits clean.

How to see it

scripts/ci/github-check                   # 0 in sync, 10 findings, 12 the gate cannot run
scripts/ci/github-check --write-baseline  # record today's backlog as the ceiling, deliberately
scripts/github-sync --plan                # offline: what an apply would create or change

Why it is a separate claim

Because the first claim was true and green for five days while the thing it describes had stopped happening.

--check has exited 11 on drift since the adapter was written. Nothing called it: scripts/ci/core-check ran --plan and --render, which prove a projection can be produced. The projection was applied once, on 2026-09-04, and then the model grew from 19 records to over 200 while GitHub kept the 19. Measured at 867f3a9: 200 drift findings.

All eight projected milestones were in sync throughout, because milestones are few and were touched by hand — so the surface a person looks at was the surface that still agreed. That is what a claim citing a script that exists, rather than a gate that runs, buys you.

What it does not cover

Applying stays a human act. CI proves agreement; it does not create issues. scripts/github-sync --apply is run by a person, deliberately, and the gate's baseline is lowered in the same commit.

Nor does the gate judge the model. It says which of the two sides moved, not whether the canonical records describe the right work — that is the plan's business. And it decides nothing it cannot measure: with no gh, no token or no permission it exits 12 naming which, rather than a green build that read nothing.

Evidence

test/cases/97_github_gate.sh drives every half over a fixture repository with a fixture remote, offline: a record whose canonical text moved fails outright, a record added to the model and never projected breaks the ratchet, a backlog at its baseline passes, an edited region and an unmanaged remote issue are refused, and a gate with no baseline refuses to guess one. test/cases/45_github_projection.sh proves the six states it reads.

The rule is project.github-projection-gated@1.

Detail rendered from docs/claims/github-projection-gated.md.

Provenance

defined in
read it on this site · docs/PLANNING.md
implemented in
scripts/ci/github-check
proved by
test/cases/97_github_gate.sh
claim id
github-projection-gated

Verify it yourself

The test runs in a disposable temporary repository and asserts the behaviour, not a string in the source.

from a clone of the repository
bash test/run.sh 97_github_gate

Where this claim is used

responsibilities it covers