Expand description
GitHub’s bootstrap plan (§5.3) and the files it commits.
The order is load-bearing: files go in first, then the variables, then the protection. The ruleset has no bypass actors — the bridge included — so after it exists every change to the default branch goes through a pull request and the check.
The pull request must not be able to satisfy its own check (§9). A
pull_request workflow runs from the pull request’s own files, so the
plan takes one of two guards, chosen per namespace (CheckGuard):
-
CheckGuard::RequiredWorkflow(organisations with org rulesets): the check is not committed to the repository at all. It lives in the bridge-managed<org>/.vgirepository and an org ruleset requires it at a pinned commit, so nothing in the pull request changes what runs. The DIDs and the exempt keyring are written into that workflow, not read from the repository under test. -
Elsewhere (personal accounts, organisations without org rulesets) the workflow is committed to the repository, with the DIDs as literals:
CheckGuard::OwnerReview, two or more owners:CODEOWNERSmakes every change under.github/— the workflow, the keyring,CODEOWNERSitself — need another owner’s approving review, which the ruleset requires (dismissed by later pushes, never the last pusher’s own).CheckGuard::SoloOwner, one owner: no review requirement, only the check. The owner could weaken their own workflow; accepted (the user’s decision), since they control the repository anyway.
In both, repository writers are trusted not to forge a “Verify commit trust” check run from a workflow on another branch; only the required workflow closes that.
-
CheckGuard::BridgePosted(the same namespaces, when the adapter is configured withcrate::GitHubConfig::bridge_checks): no workflow at all. The bridge runs verify-trust itself on every pull request and merge group and posts the check as the community’s App; the ruleset requires the check from that App’s integration id, which no workflow can post as. This is what closes the forged-check gap outside a required workflow (§9, decided 2026-09-23).
Enums§
- Check
Guard - How the plan keeps the pull request away from its own check (§9).
Constants§
- CENTRAL_
REPO - The bridge-managed repository in an organisation that holds the required workflow. Public, so the workflow may run on repositories of any visibility (a private source repository’s workflow may run only on private repositories); it holds nothing secret.
- CODEOWNERS_
LOCATIONS - Every place GitHub looks for a
CODEOWNERSfile; the first one found is the only one used. - CODEOWNERS_
PATH - Where the managed code-owner rules are committed. GitHub reads
.github/CODEOWNERSahead ofCODEOWNERSanddocs/CODEOWNERS. - GUARDED_
PATH - The paths owner review guards: everything a workflow run reads from the repository under test to decide how to check it.
- KEYRING_
PATH - Where the exempt platform keyring is committed.
- MANAGED_
BEGIN - First line of the managed block in a
CODEOWNERSfile. - MANAGED_
END - Last line of the managed block.
- ORG_
RULESET_ NAME - Name of the org ruleset that requires the namespace workflow.
- RULESET_
NAME - Name of the ruleset the adapter manages. Found by name on re-runs.
- VAR_
REGISTRY - Registry DID variable.
- VAR_VTC
- VTC DID variable.
- WORKFLOW_
PATH - Where the workflow is committed (in the repository, or in
.vgi).
Functions§
- github_
plan - Build the plan. Validates everything that ends up in a file or a variable, so a bad config fails here rather than half-way through.
- managed_
rules - The managed block of a
CODEOWNERSfile, if it is there and nothing but comments follows it:(pattern, owners, 1-based line)per rule. - render_
codeowners - A
CODEOWNERSfile:community_rules(the file’s own rules, the managed block removed), then the managed block last, so it wins forpaths(the last matching pattern takes precedence).loginsare resolved from numeric ids at run time. - render_
required_ workflow - The required workflow held in
<org>/.vgi. It runs in the context of the repository under test (itsGITHUB_REPOSITORY, its pull request), but everything that decides how to check is fixed here, at the pinned commit: - render_
workflow - The workflow committed to the repository (outside a required-workflow
namespace). Differs from the dormant one in the runbook: there is no
if: vars.TRUST_REGISTRY_DID != ''guard (a skipped required job counts as passing), and the DIDs are literals rather thanvars.*, which any repository admin could change. - strip_
managed textwithout the managed block (so re-rendering keeps only the community’s own rules).