Repository navigation
gate-of-gates: derived manifest proving every check is owned, wired, and reachable #1429
Copy link
Copy link
Closed
Labels
Description
Part of #1412 (Track E — gate integrity). From external review: the most dangerous failure mode is a perfectly designed gate that silently stops running. Nothing currently proves the gates themselves are wired.
Verified holes this closes
CHECK_CATALOGentries declareciJobsas manual strings (scripts/check-affected/checks.ts);assertCatalogCompletecovers only the check-ID universe — a renamed or deleted workflow job leaves a catalog entry pointing at nothing, silently.- ci.yml
paths-ignoreexcludeswebsite/**, so a gate that conceptually owns docs paths never fires on docs-only PRs (see gate: website command docs enumerated against the command registry #1420).
Deliverables
- A derived gate manifest test (unit lane): enumerate every vitest project (parse vitest.config.ts), every
test:*/check:*package script, and every build lane; each must be owned by a PR workflow job, a scheduled workflow, or an explicit local-only declaration with a reason. Derived from the real sources (package.json, vitest config, .github/workflows/*.yml) — no hand-maintained second list. - Model ownership as a transitive execution graph, not string presence:
workflow job → local/composite action → package script → aggregate script → vitest project or native test/build suite. A lane owns a suite only when the graph proves the suite is reachable from the workflow job. - Reuse the R8 workflow-parsing machinery in scripts/layering/ and resolve literal local-action references, package-script invocations, aggregate-script chains, and explicit vitest project selection. Unresolved dynamic
runexpressions, env-dependent dispatch, missing local actions/scripts, and opaque aggregate edges fail closed unless covered by an explicit owned waiver with a reason and tracking issue. Do not infer reachability from a command name merely appearing in workflow text. CHECK_CATALOG.ciJobs→ parse workflow files and assert every named job exists. A job rename without a catalog update fails a PR.- Path-category reachability: for each catalog path category, assert the owning workflow's trigger filters (
paths/paths-ignore) do not exclude that category — the gate: website command docs enumerated against the command registry #1420/website hole, generalized. - Keep the deterministic manifest/reachability gate offline and network-free. It must run on PRs and from a clean checkout without GitHub credentials.
- Branch-protection required-contexts audit is the only online part: run it as a scheduled, read-only GitHub API check. Required contexts must correspond to live job names. If token scope is an obstacle, land it inside the scheduled-lane health job (obs: scheduled-lane health, freshness telemetry, and standard artifact envelope #1430) and say so; never make the deterministic PR gate depend on API availability.
Acceptance
- Renaming any CI job without updating the catalog fails deterministically, naming both sides.
- A new vitest project not owned by any lane fails until declared.
- A workflow that invokes an aggregate script proves reachability through every intermediate edge; removing or renaming an intermediate package script fails instead of leaving a false ownership claim.
- An unresolved dynamic execution edge fails with the exact workflow/job/step and the explicit waiver format needed to classify it.
- The website/** exclusion is either closed or explicitly declared as docs-lane-owned in the manifest.
- The offline manifest test passes with network disabled; branch-protection drift is reported separately by the scheduled read-only audit.
Reactions are currently unavailable
Activity
fix(gate-manifest): only PR and scheduled lanes own a suite; fail clo…
test(ci): govern gates that drive their own runner
test(ci): replace the gate manifest with a canonical CheckId runner (#…
fix(ci): classify wrapped commands the same as bare ones (#1429)
fix(ci): classify commands by token, not by executable position (#1429)
fix(ci): bind the inventory to each step's executable identity (#1429)
fix(ci): fingerprint the environment a lane inherits (#1429)
fix(ci): audit the commands callers hand to composite actions (#1429)
fix(ci): audit the commands callers hand to third-party actions (#1429)
refactor(ci): narrow the construction instead of policing it (#1429)
fix(ci): a step's `if:` decides whether it runs, so it belongs to its…
test(ci): prove every registered gate is owned and reachable (#1429)
fix(ci): credit gates by execution shape, and keep every guard
fix(ci): run the three checks no workflow was running
ci: add the run-gate action that names a gate structurally
fix(ci): run the three checks no workflow was running (#1770)
test(ci): prove every registered gate is owned and reachable (#1429)
fix(ci): credit gates by execution shape, and keep every guard
ci: add the run-gate action that names a gate structurally
refactor(ci): make gate ownership structural (#1429) (#1753)
thymikee commentedon Aug 17, 2026
Landed in #1753 (
scripts/gate/{audit,model,run,workflows,declarations,check}.ts, wired ascheck:gate-manifestundercheck:tooling) and #1770 (the three checks no workflow was running). Closing as part of the #1781 issue sweep; #1412's checkbox was stale.ci: attest manual-only checks against their dispatch lane (#1781 A1)
ci: move parked device replay suites to a dispatch-only workflow (#1781…