carlos / platform Public

docs: fix the steering operator grep and note the region-field arming check

The canonical journalctl grep in three places (plan steps 4 and the
duty-status note, spec's shrink-guard note) was anchored to
"^steering:" and scoped to "-u carlos". Neither the armed line
(agent: steering loop armed...) nor a duty failure (agent: housekeeper:
steering converge: ...) starts with "steering:", so the anchored grep
matched neither, and "carlos" is an unverified unit name. Unanchor to
"steering" and drop -u, with a caveat to confirm the agent's actual unit
name on the box before filtering by one.

Also adds one sentence to the arming checklist's step 1: confirm each
edges file carries a region field, not just that the file exists — a
box on a pre-region binary folds to zero armed edges regardless of
health, surfacing as the converger's empty-set refusal rather than as
records.
Paul Campbell pushed by paul@keymail.dev ebd930a6bd5a7bcda187d99c90e94c53b37af856 parent 9ecf8be
2 files changed, +28 −10
  • docs/superpowers/plans/2026-08-23-multi-region-steering.md +22 −7
  • docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md +6 −3
diff --git a/docs/superpowers/plans/2026-08-23-multi-region-steering.md b/docs/superpowers/plans/2026-08-23-multi-region-steering.md
index 86e70b18d..4f7d48737 100644
--- a/docs/superpowers/plans/2026-08-23-multi-region-steering.md
+++ b/docs/superpowers/plans/2026-08-23-multi-region-steering.md
@@ -388,6 +388,12 @@ rollout notes and constraints where they name Part 4 directly.
box through its edges file (Part 4's `armedEdges`), so a box missing
one is invisible to the converger exactly as it is invisible to the
home map — it gets no latency records and answers no traffic, silently.
+ Also confirm each edges file carries a non-empty `region` field, not
+ just that the file exists: `armedEdges` requires the AWS-region shape
+ too, so a box still running a pre-region binary folds to ZERO armed
+ edges regardless of health, and with every edge unarmed the converger
+ hits its own empty-set refusal instead of writing records — the
+ alarming failure mode, not the informative one.
2. `tofu apply` with `steering_zone_ids` (and, per the IAM note below,
`steering_record_names`) set for the deployment's region-host module —
**Paul's applies rule**: tofu apply sessions are blocked on Paul
@@ -401,11 +407,18 @@ rollout notes and constraints where they name Part 4 directly.
silently on old behaviour, not broken, so this step has no error
signal of its own — the next two steps are how you catch a miss.
4. Verify the housekeeper's converge log on whichever box holds the
- lease (`journalctl -u carlos -g "^steering:"` — this is the
- canonical operator surface, not the housekeeper's own error log; see
- the duty-status mechanism note below) — expect the "steering loop
- armed... converges only while this box holds the housekeeper lease"
- line, then an actual convergence pass once records exist.
+ lease (`journalctl -g steering` — unanchored: the armed line is
+ `agent: steering loop armed...` and a duty failure is `agent:
+ housekeeper: steering converge: ...`, neither of which starts the
+ journal line with `steering:`, so an anchored `^steering:` grep shows
+ NEITHER; this is the canonical operator surface, not the
+ housekeeper's own error log; see the duty-status mechanism note
+ below) — expect the "steering loop armed... converges only while
+ this box holds the housekeeper lease" line, then an actual
+ convergence pass once records exist. (No `-u <unit>` above —
+ confirm the agent's actual unit name on the box, e.g. `systemctl
+ status carlos-edge.service`, before filtering the journal by unit;
+ don't assume `carlos`.)
5. **Per-EIP wildcard verification BEFORE treating steering as live —
this is a hard gate, not a nice-to-have.** For every armed EIP:
`curl --resolve edge.<apps-domain>:443:<EIP> https://edge.<apps-domain>/`
@@ -494,8 +507,10 @@ rollout notes and constraints where they name Part 4 directly.
so a routine 5-minute error cadence does not bury the one log line that
explains what happened. The housekeeper's own success/failure surface
is therefore NOT where steering health lives: read the journal
- (`journalctl -u carlos -g "^steering:"`) after any arming or
- retirement action, don't trust a clean housekeeper status alone.
+ (`journalctl -g steering` — unanchored, and without `-u`; verify the
+ agent's actual unit name on the box before adding a unit filter, see
+ step 4 of the arming checklist above) after any arming or retirement
+ action, don't trust a clean housekeeper status alone.
- **A GENUINE >half-record withdrawal has no escape hatch.** The
proportional shrink guard (Task 5, hardened in the fix rounds) refuses
to delete more than half the zone's managed records — or more than a
diff --git a/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md b/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
index e7ceec3e8..a3e830387 100644
--- a/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
+++ b/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
@@ -430,9 +430,12 @@ the record) — see the plan's rollout notes.
refused pass regardless — both safety refusals log loudly and return
nil, deliberately, so a five-minute error cadence does not bury the
one line that says what happened — so the operator surface for
- steering health is the JOURNAL
- (`journalctl -u carlos -g "^steering:"`), never the housekeeper's own
- error log.
+ steering health is the JOURNAL (`journalctl -g steering` — unanchored:
+ the armed line is `agent: steering loop armed...` and a duty failure
+ is `agent: housekeeper: steering converge: ...`, so an anchored
+ `^steering:` grep matches neither; skip `-u <unit>` too, or confirm
+ the agent's actual unit name on the box first), never the
+ housekeeper's own error log.
**Rollout.** Stages 1–4 land dormant on single-box deployments
(one-candidate elections; per-box keys with one box; no steered routes):