carlos / platform Public

console: only a box reconcile would admit can take a region out of automatic eligibility (Ruling F2, refined)

On the "no fresh box fails" side, count only boxes reconcile would admit
for the record: the same region code with the shared pool served and
inbound accepted, mirroring reconcile.go's inScope (poolServed(cfg.Pools,
"")) and its CARLOS_INBOUND=none refusal, the two facts
SharedInstanceEligibility publishes. A box that positively publishes
serves_shared_pool false (named-pool-only) or accepts_inbound false can
never be handed the record, so it neither qualifies nor disqualifies the
region. Absent is not false: reconcile reads its own config, never the
edges file, and its defaults (CARLOS_POOLS unset serves the shared pool,
CARLOS_INBOUND unset accepts) admit a box, so a writer silent on either
field counts as possibly admitted and still fails. The "some fresh box
qualifies" side is unchanged.

Tests: a fresh keyless named-pool-only box beside a fresh keyed eligible
box leaves the region eligible (RED against 82a6369d); a fresh keyless
shared-pool inbound box beside the same box does not; a silent field does
not either.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 9435b01fc53a43c9f95131a9a92bc4dbd5d4acac parent 82a6369
2 files changed, +72 −7
  • internal/console/regioncandidates.go +21 −5
  • internal/console/regioncandidates_test.go +51 −2
diff --git a/internal/console/regioncandidates.go b/internal/console/regioncandidates.go
index 24d8f017f..5530bc736 100644
--- a/internal/console/regioncandidates.go
+++ b/internal/console/regioncandidates.go
@@ -47,6 +47,9 @@ func (c regionCandidate) unavailableReason() string {
func isTrue(b *bool) bool { return b != nil && *b }
+// isFalse is a field the box PUBLISHED as false; absent is unknown, not no.
+func isFalse(b *bool) bool { return b != nil && !*b }
+
// regionCandidates folds an edges snapshot into candidates. expectedFP is
// the console's own secrets fingerprint; "" means it cannot judge, and then
// no coded region is KeyOK. The home is exempt from every eligibility fact.
@@ -59,8 +62,8 @@ func isTrue(b *bool) bool { return b != nil && *b }
// - at least one fresh box publishing it passes the whole predicate:
// a dial address, hibernation_configured, serves_shared_pool and
// accepts_inbound all positively true, and the deployment's key;
-// - no fresh box publishing it fails that predicate. Absent and unknown
-// fields fail it.
+// - no fresh box publishing it that reconcile would ADMIT for the record
+// fails that predicate. Absent and unknown fields fail it.
//
// A record names a region, not a box. internal/provision's reconcile pass
// (inScope, and the CARLOS_INBOUND=none refusal) admits every box whose
@@ -68,8 +71,15 @@ func isTrue(b *bool) bool { return b != nil && *b }
// inbound; it never asks whether the box holds the key or has its
// activator wired, so a keyless or activator-less sibling can win the lease
// and wake the instance with nothing. Every box that could serve the record
-// must therefore be able to. Stale boxes count for neither side (F1): they
-// are not evidence that a region works, and not evidence that it is broken.
+// must therefore be able to. A box that POSITIVELY publishes
+// serves_shared_pool false (a named-pool-only box) or accepts_inbound
+// false (CARLOS_INBOUND=none) can never be handed the record, so it neither
+// qualifies nor disqualifies the region (Ruling F2, refined). Absent is not
+// false: a writer predating the field is on an unknown config, and
+// reconcile's defaults (CARLOS_POOLS unset serves the shared pool,
+// CARLOS_INBOUND unset accepts) admit it, so it counts as possibly
+// admitted and fails. Stale boxes count for neither side (F1): they are
+// not evidence that a region works, and not evidence that it is broken.
func regionCandidates(snap edgesSnapshot, homeName, expectedFP string) []regionCandidate {
type acc struct {
c regionCandidate
@@ -130,7 +140,13 @@ func regionCandidates(snap edgesSnapshot, homeName, expectedFP string) []regionC
// nothing can reach it. It just does not make the region Reachable.
eligible := reachable && isTrue(f.HibernationConfigured) && isTrue(f.ServesSharedPool) && isTrue(f.AcceptsInbound) && keyOK
a.anyEligible = a.anyEligible || eligible
- a.allEligible = a.allEligible && eligible
+ // Only a box reconcile would admit can take the region out: one
+ // that does not positively refuse the shared pool or inbound.
+ // This mirrors poolServed(cfg.Pools, "") and cfg.Inbound !=
+ // InboundNone, the two facts SharedInstanceEligibility publishes.
+ if !isFalse(f.ServesSharedPool) && !isFalse(f.AcceptsInbound) {
+ a.allEligible = a.allEligible && eligible
+ }
if !reachable {
continue
}
diff --git a/internal/console/regioncandidates_test.go b/internal/console/regioncandidates_test.go
index 9731dee64..1bb2037a9 100644
--- a/internal/console/regioncandidates_test.go
+++ b/internal/console/regioncandidates_test.go
@@ -261,6 +261,54 @@ func TestRegionCandidatesNeedPositiveEligibility(t *testing.T) {
}
}
+// Ruling F2, refined: the "no fresh box fails" side counts only boxes
+// reconcile would admit for the record, which is the same region code with
+// the shared pool served and inbound accepted (reconcile.go inScope and
+// the CARLOS_INBOUND=none refusal). A named-pool-only or no-inbound box can
+// never be handed the record, so it neither qualifies nor disqualifies the
+// region. ABSENT is not the same as false: a writer that predates the
+// field is on an unknown config, and reconcile's defaults (CARLOS_POOLS
+// unset serves the shared pool, CARLOS_INBOUND unset accepts) admit it, so
+// absent still counts as possibly admitted, and so as failing.
+func TestBoxesReconcileWouldNotAdmitNeitherQualifyNorDisqualify(t *testing.T) {
+ keyless := func(shared, inbound *bool) string {
+ return edgeJSON("uk-box-2", "1.2.3.5", "eu-west-2", "uk", edgeOpts{hib: bp(true), shared: shared, inbound: inbound})
+ }
+ harmless := map[string]string{
+ "keyless named-pool-only box": keyless(bp(false), bp(true)),
+ "keyless no-inbound box": keyless(bp(true), bp(false)),
+ "keyless neither": keyless(bp(false), bp(false)),
+ }
+ for name, body := range harmless {
+ cands := regionCandidates(views(t, homeBox, ukEligible, body), "ie", testKeyFP)
+ if c, _ := findCandidate(cands, "uk"); !c.Eligible {
+ t.Errorf("%s beside a keyed eligible box: uk = %+v, want eligible (reconcile would never admit it)", name, c)
+ }
+ if n := eligibleCount(cands); n != 2 {
+ t.Errorf("%s: %d eligible candidates, want the home and uk", name, n)
+ }
+ }
+ // Possibly admitted, so failing: a keyless box that serves the shared
+ // pool and takes inbound (the flipped mixed-box case), and one that
+ // is silent on either field.
+ hazard := map[string]string{
+ "keyless shared-pool inbound box": keyless(bp(true), bp(true)),
+ "keyless, shared pool absent": keyless(nil, bp(true)),
+ "keyless, inbound absent": keyless(bp(true), nil),
+ }
+ for name, body := range hazard {
+ if c, _ := findCandidate(regionCandidates(views(t, homeBox, ukEligible, body), "ie", testKeyFP), "uk"); c.Eligible {
+ t.Errorf("%s beside a keyed eligible box: uk = %+v, want ineligible", name, c)
+ }
+ }
+ // On its own, a box reconcile would not admit still makes no region
+ // eligible: nothing qualifies it. Keyed, so the reason is the pool.
+ poolOnlyKeyed := edgeJSON("uk-box-2", "1.2.3.5", "eu-west-2", "uk", edgeOpts{hib: bp(true), shared: bp(false), inbound: bp(true), fp: testKeyFP})
+ if c, _ := findCandidate(regionCandidates(views(t, homeBox, poolOnlyKeyed), "ie", testKeyFP), "uk"); c.Eligible || c.unavailableReason() != "not-eligible" {
+ t.Errorf("pool-only box alone: uk = %+v, want not-eligible", c)
+ }
+}
+
// Task 10 (final review, MUST FIX): each capability field ABSENT on its
// own, and each explicitly FALSE on its own, with everything else eligible
// and the key present. The older fixtures that left fields absent also
@@ -349,13 +397,14 @@ func TestEligibilityNeedsEveryFreshBoxToQualify(t *testing.T) {
"wrong key": sibling(edgeOpts{hib: bp(true), shared: bp(true), inbound: bp(true), fp: "sha256:" + strings.Repeat("0", 64)}),
"hibernation false": sibling(keyed(bp(false), bp(true), bp(true))),
"hibernation absent": sibling(keyed(nil, bp(true), bp(true))),
- "shared pool false": sibling(keyed(bp(true), bp(false), bp(true))),
"shared pool absent": sibling(keyed(bp(true), nil, bp(true))),
- "inbound false": sibling(keyed(bp(true), bp(true), bp(false))),
"inbound absent": sibling(keyed(bp(true), bp(true), nil)),
"old writer, every field": sibling(edgeOpts{}),
"no dial address": edgeJSON("uk-box-2", "", "eu-west-2", "uk", eligibleBox),
}
+ // A sibling that POSITIVELY publishes serves_shared_pool false or
+ // accepts_inbound false is one reconcile would never hand the record:
+ // see TestBoxesReconcileWouldNotAdmitNeitherQualifyNorDisqualify.
for name, body := range bad {
cands := regionCandidates(views(t, homeBox, ukEligible, body), "ie", testKeyFP)
c, _ := findCandidate(cands, "uk")