hub v0.104.0: the guest network gets a reader (R-319), and the hub half of the naming (R-295)
gates / gates (push) Successful in 14s

Four paper debts and one fact given a reader. Hub-only — nothing to bake.

A4 — the entry about "the tester's machine" named a risk correctly and labelled it
in a way that invited deleting it. Established from the hub's own store: `peti-felhom`
is a REAL machine (482 reports, 2026-02-27 → 2026-07-15, a named person's own box) and
the 3.6 GB with no key and no backup is real. `david` → `tester-1` is a DIFFERENT record
with no host, no escrow and no report, ever — deleted 07:55:49 and re-created 07:56:47
this morning. The prompt's premise conflated the two; the register now says which is which.

A1 — R-312/R-313/R-303 recorded as DECIDED with their re-open triggers, and moved out
of STATUS's "Waiting on you", which is now empty.

A3 — day0-install §C.1 said pushing the installer publishes it. It has not since
R-110. Corrected, with the two manifest pins named and an outside-verification command;
the one copy that repeated it (a dated audit, true when written) carries a superseded note.

A5 — standing rule 5: evidence comes off the machine at the end of the phase that
produced it, before any revert. Earned twice in three days on the same box at the same
point (R-320). Four homes, plus what to do when it is already gone.

R-295 hub half — „Beállító kód" everywhere; „Visszaállító kód" retired. New `reenroll`
mail kind so the mail names the page a REBUILT box actually shows („A szerver
beállítása"), not the „Elfelejtett jelszó" page it has no login screen to reach.
Naming only; the acceptance pin proves the secret is untouched.

R-319 — the hub models `guest_net` after 23 days of receiving and discarding it. The
signal is `heals_last_hour`, not `state`: a guest the watchdog keeps repairing reads
healthy between repairs. `heal_succeeded` decoded too (R-260's lesson). Unknown is never
drawn as healthy — three absences, three sentences. No alarm, deliberately.
Three red-proofs, mutations asserted applied. Wire-gate checked tags 182 → 190.

B1 — the operator's 2026-08-12 dispositions were NOT in the register; they are now.
Third allowlist kind for the five ruled "no reader wanted"; `reporting_disabled`
reclassified redundant. 8 read · 5 deliberately unread · 1 redundant · 6 still owed.

Also filed: R-321 (a deliberately-silent box still alarms stale/down — the checker is
age-only, and decoding the flag would not have fixed it), R-322 (the claim guard has
never scanned the hub; a hand scan returns zero, so it is a scope gap, not a defect).
This commit is contained in:
2026-08-13 10:50:12 +02:00
parent 2d05b29b82
commit 4d6ec7c7bb
22 changed files with 1253 additions and 115 deletions
+55 -19
View File
@@ -103,13 +103,20 @@ GENERIC = {
# someone must be able to re-check later, so none of them is bare. A quiet exclusion would be a
# dropped field with paperwork, which is worse than the defect.
#
# TWO KINDS OF ENTRY, and the difference is deliberate:
# THREE KINDS OF ENTRY, and the differences are deliberate:
# * "redundant" — the hub already decodes something that answers the same question. No consumer
# is wanted; the entry is the end of the matter.
# * "R-264" — a fact with no consumer that ARGUABLY should have one. The entry does NOT
# close the question; it records it against an OPEN register row so that
# allowlisting cannot be mistaken for deciding. R-260 is closed by the gate plus
# the operator-access fix; the leftover appetite is R-264.
# * "not consumed, deliberately" — RULED by the operator, with the date. The question IS closed:
# a reader was considered and declined on stated grounds. This kind was added on
# 2026-08-13 because "arguably owed" had been carried for five days as though it
# were a decision, and an undecided fact and a decided one must not read alike.
# THE EMITTER IS DELIBERATELY LEFT ALONE: removing it is a coordinated two-repo
# change and it also breaks the byte-identical cross-repo host-report golden. The
# honest end here is a recorded decision, not a deletion.
#
# Keyed by (wire label, dotted emit path).
_AH = "agent -> hub (POST /host-report)"
@@ -123,6 +130,14 @@ _R264 = (
"no consumer today, and one is arguably owed — recorded against R-264 (OPEN) rather than "
"decided here. Allowlisting is not deciding.")
# RULED 2026-08-13 by the operator against R-264: these five were considered for a reader and
# declined. The reason each is declined is per-entry below — a bare "not wanted" would be the quiet
# exclusion this gate exists to prevent.
_NOREADER = (
"not consumed, DELIBERATELY — ruled 2026-08-13 (operator, against R-264). A reader was "
"considered and declined; the question is closed, not open. The emitter stays (removing it is a "
"two-repo change and breaks the host-report golden). ")
ALLOWLIST = {
# ---- redundant: the hub already decodes an equivalent ----
(_AH, "host.cpu_temp_c"): _REDUNDANT_HOST_METRICS,
@@ -149,33 +164,54 @@ ALLOWLIST = {
"redundant: hub-side wgsync reconciles peers from its own state, and the OOB path's own "
"wg_handshake_age_s IS now decoded (into HostOOBRow, for the alert text)."),
# ---- no consumer, and one is arguably owed: R-264, OPEN ----
(_AH, "guest_net"): _R264 + " The R-54 guest-network watchdog stanza (whole object).",
(_AH, "guest_net.checked_at"): _R264,
(_AH, "guest_net.guests.has_route"): _R264,
(_AH, "guest_net.guests.dhclient_alive"): _R264,
(_AH, "guest_net.guests.heal_succeeded"): _R264,
(_AH, "guest_net.guests.heals_last_hour"): _R264,
(_AH, "guest_net.guests.last_heal_at"): _R264,
(_AH, "guest_net.guests.damped"): _R264,
# ---- R-319: guest_net AND ALL SEVEN CHILDREN ARE GONE FROM THIS LIST ----
# They are no longer allowlisted because they are no longer unconsumed: the hub models the R-54
# watchdog stanza (web/hosts.go parseGuestNet → the host-detail Guest network card), including
# heals_last_hour and heal_succeeded. Removing the entries is the POINT — an allowlisted tag is
# SKIPPED by this gate, so leaving them here would mean the new reader's fields were never
# actually checked for reachability, and the gate would report a coverage it did not have.
# The first of R-264's readers; three groups remain owed one.
# ---- no consumer, and one is arguably owed: R-264, STILL OPEN ----
(_AH, "selfupdate_pending"): _R264 + (
" NOTE: the agent's own comment beside this field claimed 'the hub reads an absent field as "
"pending=false, the correct default'. The hub had no field at all, so it read nothing "
"either way. The comment was corrected in the same change as this entry."),
(_AH, "selfupdate_pending_version"): _R264,
(_AH, "mgmt_plane.healed_recently"): _R264 + (
" The hub DOES alarm on mgmt_plane.privsep_healed_at, which is the timestamp beside this "
"boolean, so the recurring-clobber signal is not lost — only this flag is."),
(_AH, "pbs_dr.applied_at"): _R264,
(_AH, "mgmt_plane.healed_recently"): _NOREADER + (
"The recurring-clobber signal is NOT lost: the hub already alarms on "
"mgmt_plane.privsep_healed_at, the timestamp sitting beside this boolean. A second reader "
"for the flag would add a second way to say the same thing and no new fact."),
(_AH, "pbs_dr.applied_at"): _NOREADER + (
"A tier-applied TIMESTAMP, and the hub already decodes pbs_dr.state — which is the verdict. "
"Presence is not success: consuming the timestamp without the state is precisely the "
"attempt-read-as-result trap, and with the state it answers nothing further."),
(_AH, "restore_tests.mount_parity"): _R264 + (
" R-262: the hub's own comment claims this contract is mirrored field-for-field and that a "
"key-set test guards drift; it is two fields short and the fixture omits the same two."),
(_AH, "restore_tests.mount_inventory"): _R264 + " R-262, as mount_parity.",
(_CH, "config_hash"): _R264,
(_CH, "reporting_disabled"): _R264,
(_CH, "stacks"): _R264 + (
" The whole per-stack report object; the hub's app view is built from app_telemetry."),
(_CH, "storage.migrated_to"): _R264,
(_CH, "config_hash"): _NOREADER + (
"A config FINGERPRINT. The hub authors the config and knows its own generation "
"(desired_generation, config_version), which is the convergence question it actually asks. "
"A hash it did not compute answers a question nobody has posed."),
(_CH, "reporting_disabled"): (
"redundant: the box sends health.status = \"disabled\" in the SAME minimal report "
"(controller cmd/controller/main.go:1254), the hub decodes it into reports.health_status, and "
"web/rollup.go:25 renders that customer as 'disabled'. The state IS visible; this flag is a "
"second spelling of a fact already read. ⚠ DECIDED ON ITS OWN MERITS 2026-08-13, and the "
"decision came with a REAL finding that a second decoded flag would NOT have fixed: "
"StalenessChecker.Check (monitor/staleness.go:88+) is age-only — it skips BLOCKED customers "
"and nothing else — so a deliberately-silent box still goes stale at 30 min and down at 60. "
"Filed as R-321. The fix belongs in the checker, which already has the health status it "
"needs; adding a field here would have felt like progress and left the alarm firing."),
(_CH, "stacks"): _NOREADER + (
"The whole per-stack report object. The hub's app view is built from app_telemetry, which is "
"a purpose-built wire with its own table; a second, differently-shaped source for the same "
"screen is how two answers to one question get shipped."),
(_CH, "storage.migrated_to"): _NOREADER + (
"A drive-migration marker: box-local bookkeeping about where data was moved ON that box. The "
"hub holds no drive-layout intent to reconcile it against, so it could only be displayed, "
"and a fact displayed with nothing to compare it to is decoration."),
(_CH, "backup.last_db_dump"): _R264,
(_CH, "backup.last_integrity_check"): _R264,
}