Repository navigation
Crm, SocialMedia and Education CALL node-repo-validate at a pin that predates the secret guard — 4 unasserted PR secrets each, MW_REGISTRY_KEY among them #3576
Description
Measured: three satellites CALL node-repo-validate and are not checked by it
Split out of #3504, which fixed the two repos that did not call the lane at all. This is the other
half, and it is the one an adoption matrix cannot see by construction: a lane is pinned by sha, so
a caller whose pin predates a guard calls the lane and still does not run it.
The measurement, 2026-09-07, against each repo's main
| repo | node-repo-validate pin |
check-pr-secret-preflight.py in that pin |
verdict on its main |
|---|---|---|---|
| MeshWeaver.Reinsurance | 1b5350d54 |
✅ | 0 violations |
| MeshWeaver.Manufacturing | 1b5350d54 |
✅ | 0 (adopted, MeshWeaver.Manufacturing#63) |
| MeshWeaver.Plugins | c7fef7a2d |
✅ | 0 (adopted, MeshWeaver.Plugins#1453) |
| MeshWeaver.Crm | 0a2b9017d |
❌ | 4 — AZURE_CLIENT_ID, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, MW_REGISTRY_KEY |
| MeshWeaver.SocialMedia | 0a2b9017d |
❌ | 4 — the same four |
| MeshWeaver.Education | 8ffbe4762 |
❌ | 4 |
🚨 Reinsurance is the control. It is the only pre-existing caller whose pin carries the guard,
and it is the only pre-existing caller at zero. That is what makes this a measurement of the guard
rather than of the script's mood — the column tracks the pin, not the repo.
check-workflow-timeouts.py is in all three pins, so only the secret guard is missing.
Why MW_REGISTRY_KEY in that column is the point
An absent MW_REGISTRY_KEY consumed by a PR-reachable job that no preflight asserts is
Reinsurance#128: compose-sealed-modules.sh: --registry-url needs --registry-key — a message that
names no secret at all, one job after a green preflight. AGENTS.md cites that incident as the
reason the guard exists. Three repositories are one Dependabot pull request away from the same log,
and their preflights will be green when it happens.
How to re-run it (nothing here needs a credential beyond gh auth)
# 1. which lane sha does the repo pin?
git -C <repo> show origin/main:.github/workflows/ci.yml | grep 'node-repo-validate.yml@'
# 2. does that sha's lane carry the guard? 0 ⇒ it predates it
git -C MeshWeaver show <sha>:.github/workflows/node-repo-validate.yml | grep -c check-pr-secret-preflight
# 3. what would the guard say about that repo's main?
python3 .github/scripts/check-pr-secret-preflight.py --root <origin/main workflows, extracted>🚨 Step 3 must read origin/main, not a working tree. Two of these repos' local checkouts were
19 and 52 commits behind while this was being measured; reading them would have scored a tree nobody
runs.
The fix, per repo
Bump uses: and its paired platform-ref to a sha whose lane carries the guard, in ONE commit
(check-pin-set-consistency.py invariant I3 asserts the pairing), then resolve whatever the guard
then names — either a missing+= line in that repo's preflight, or a reasoned entry in
.github/pr-secret-preflight-allow.txt. For the App-token pair forwarded into core's auto-arm.yml
the allow entry is the right instrument (that lane asserts them itself and the static guard cannot
see through a uses:); for a secret a PR job genuinely reads, the preflight is.
Worked examples with both instruments: MeshWeaver.Manufacturing#63 and MeshWeaver.Plugins#1453.
Not filed as "bump the pins"
A pin bump changes what that repository's gates EXECUTE, not just which guard runs — that is a scope
call for whoever owns each repo, and it should land with its own green run rather than as a
fleet-wide sweep. What this issue records is that the coverage gap exists, exactly where, and with a
control that says the numbers mean what they appear to.
Durable form
Doc/Architecture/CiContentBake → "Node repos run the same lane" carries the rule and this table
(MeshWeaver#3575); the /ci skill carries the short version at the point an agent authoring
satellite CI reads.
Related: #3504 (where this was found), #3399 (the Dependabot store), Reinsurance#128 (the incident).
Activity
rbuergi commentedon Sep 7, 2026
Education's row is done: Education #283 (merged 2026-09-07 ~13:30Z) moved
node-repo-validate.yml@and its pairedplatform-refto c7fef7a andnode-repo-tag-modules.yml@to 67bd3d0; the guard at that ref reports 0 violations on Education's main (8 secrets reachable on a Dependabot PR, 6 asserted, none unasserted — re-measured locally fromorigin/mainwith the guard at core main). The Dependabot-authored validate bump (Education #278) was closed because the lane at the new sha fetches the guard at the CALLER'splatform-ref, which was still 8ffbe47 — exactly the "pin older than the guard needs the older lane" refusal; #283 moved both together, as this issue prescribes. Crm and SocialMedia rows remain.rbuergi commentedon Sep 7, 2026
All three rows are at zero. Crm (
9228b8be) and SocialMedia (9dea3668) moved their validate pin + pairedplatform-refto c7fef7a at 12:30Z, Education via Education#283; re-measured with the guard at coremainagainst each repo'sorigin/main: Crm 8/8 asserted, SocialMedia 9/9, Education 6/8 reachable with none unasserted — 0 violations each. The durable table in CiContentBake is brought current by #3606 (it still said four). Closing on the measurement; the doc PR merges on green.