Skip to content

cloud-env-check: --verify-domains should reconcile against a per-entry expect, not report raw reachability #27

Description

@bdelanghe

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 probeexcluded 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.

Metadata

Metadata

Assignees

Labels

claimedHeld by an agent or human — see the claim comment. Remove to release.

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions