The gap
--verify-domains reports what each host answers. It has no notion of what the record claims the host will answer, so the claim and the observation can invert silently — which happened in .github-private on 2026-08-07 (.github-private#316): two entries recorded as "recorded-but-absent on purpose … --verify-domains stays red on it until the dialog carries it" kept probing green after the dialog was updated, while their reason prose still said blocked. Both gates stayed green throughout; the drift was caught by a human reading the file.
The convention that makes this possible is load-bearing today: recorded-but-absent entries exist (deliberately) in .github-private's record, and the only place their expected state lives is prose — which nothing checks, by design (the digest hashes domain names and env vars only; correct, and not the thing to change).
Proposal
Each allowedDomains entry may carry "expect": "reachable" | "blocked", defaulting to reachable when absent. --verify-domains goes from reporting observations to reconciling observation against expectation — red only on disagreement, in either direction:
| expect |
probe |
result |
| reachable |
HTTP status |
✓ (today's green) |
| reachable |
000 |
✗ (today's red) |
| blocked |
000 |
✓ (new — today this is red until the dialog changes) |
| blocked |
HTTP status |
✗ (new — this is exactly .github-private#316's drift, machine-caught) |
The third row matters as much as the fourth: today a recorded-but-absent entry keeps the check red for as long as the entry exists, which trains adopters to tolerate a red gate — the posture the repo's own workflow headers argue against.
Semantics
expect is repo-side annotation like reason and probe — excluded from the digest, so adopting it moves no handshake value and requires no dialog edit.
- Unknown
expect value → config error, exit 1, same posture as the existing shape validation (the typo'd-key lesson).
- The all-probes-000 INCONCLUSIVE guard narrows to expected-reachable probes: a 000 that matches
expect: blocked is not evidence of a dead network, but it can't refute one either — the guard's job is unchanged for entries that expect to get through.
- Default
reachable means every existing record (infra, front-desk-scheduler, .github-private) behaves identically until it opts in — re-vendoring is not a flag-day.
Rollout
Canonical bump per README (script + CANONICAL_SHA256, one review), then step-4 re-vendor per adopter. .github-private adopts expect: blocked on nothing initially — both formerly-absent entries are now carried — but gains the field for the next deliberate recorded-but-absent entry, which is the state the convention exists for.
The gap
--verify-domainsreports what each host answers. It has no notion of what the record claims the host will answer, so the claim and the observation can invert silently — which happened in.github-privateon 2026-08-07 (.github-private#316): two entries recorded as "recorded-but-absent on purpose …--verify-domainsstays red on it until the dialog carries it" kept probing green after the dialog was updated, while theirreasonprose still said blocked. Both gates stayed green throughout; the drift was caught by a human reading the file.The convention that makes this possible is load-bearing today: recorded-but-absent entries exist (deliberately) in
.github-private's record, and the only place their expected state lives is prose — which nothing checks, by design (the digest hashes domain names and env vars only; correct, and not the thing to change).Proposal
Each
allowedDomainsentry may carry"expect": "reachable" | "blocked", defaulting toreachablewhen absent.--verify-domainsgoes from reporting observations to reconciling observation against expectation — red only on disagreement, in either direction:The third row matters as much as the fourth: today a recorded-but-absent entry keeps the check red for as long as the entry exists, which trains adopters to tolerate a red gate — the posture the repo's own workflow headers argue against.
Semantics
expectis repo-side annotation likereasonandprobe— excluded from the digest, so adopting it moves no handshake value and requires no dialog edit.expectvalue → config error, exit 1, same posture as the existing shape validation (the typo'd-key lesson).expect: blockedis not evidence of a dead network, but it can't refute one either — the guard's job is unchanged for entries that expect to get through.reachablemeans every existing record (infra, front-desk-scheduler, .github-private) behaves identically until it opts in — re-vendoring is not a flag-day.Rollout
Canonical bump per README (script +
CANONICAL_SHA256, one review), then step-4 re-vendor per adopter..github-privateadoptsexpect: blockedon nothing initially — both formerly-absent entries are now carried — but gains the field for the next deliberate recorded-but-absent entry, which is the state the convention exists for.