v0.203.0: the box collects what the hub staged for it (R-218 consume half) + R-220's message
gates / gates (push) Successful in 10s
gates / gates (push) Successful in 10s
R-218's declaration half shipped in v0.201.0 and works. Its consume half never existed. Reconcile ran exactly twice per process — at start-up and when the recovery screen drives it — and BOTH fire before the hub has anything staged, because the hub stages in RESPONSE to the declaration those runs precede. Measured on the R-201 re-walk: unlock reconcile 11:43:07, hub staged 11:44:57 saying 'next cycle', a full report cycle ran 11:55:46, still unconsumed at 12:06. A guest command line applied it in 18 seconds — everything correct except the trigger. Bridge.RetryIfDeclared re-runs the SAME reconcile on a 5-minute tick, driven from the box's own published declaration (OffboxReportStatus().State) — the very statement the hub acts on, so the two cannot disagree. Poll, not an ACK flag, decided on the promise: the no-target message says 'amint megvannak' (no deadline) and the card says 'within a day'. Five minutes is inside both by a wide margin and needs no hub change. It stops by construction — a healthy box does no work and logs nothing — and the settle gate is deliberately kept via ReconcileWhenSettled. The marker was investigated and left alone: applied_marker lives in the guest's DataDir, which a rebuild destroys, so it cannot suppress a legitimate re-run. R-220's customer half: the refusal no longer tells the customer to choose from a list that may be empty. It names the rebuild, points at the Meghajtók page, and promises no outcome. Red-proofs: remove the retry -> credential uncollected (the dead end reproduced); drop the stop condition -> a healthy box hammers the hub; call Reconcile instead of ReconcileWhenSettled -> settle gate bypassed; restore the old sentence -> the impossible action returns. 28 packages ok, vet clean, all controller gates OK.
This commit is contained in:
@@ -1,3 +1,54 @@
|
||||
## v0.203.0 — the box collects what the hub staged for it (2026-08-06, R-218 consume half / R-220 message) — MinAgent 0.127.0
|
||||
|
||||
**R-218's declaration half shipped in v0.201.0 and works. Its consume half never existed.**
|
||||
|
||||
A stranded box says `offsite.state=needs_credential`; the hub's `offsiteheal` re-stages the one-time
|
||||
secret and logs *"the box re-consumes on its next cycle"*. **There was no next cycle.** `Reconcile`
|
||||
ran exactly twice in a process's life — once at start-up (whose own comment said *"retries on next
|
||||
config refresh/restart"*) and once when the recovery screen drives it (R-219) — and **both fire before
|
||||
the hub has anything staged, because the hub stages in RESPONSE to the declaration those runs
|
||||
precede.** So the hub held a credential the box would never fetch.
|
||||
|
||||
**Measured on the R-201 re-walk, 2026-08-06:** unlock reconcile **11:43:07** · hub staged **11:44:57**
|
||||
saying "next cycle" · a full report cycle ran **11:55:46** · **still unconsumed at 12:06**. A guest
|
||||
command line applied it in **18 seconds** — proving the credential, the target and the key were all
|
||||
correct and only the trigger was missing. That was the first of the two dead ends that kept the
|
||||
recovery journey failing.
|
||||
|
||||
**The fix: re-run the SAME reconcile, on a tick, for exactly as long as the box says it needs a
|
||||
credential.** `Bridge.RetryIfDeclared` is driven from the box's own published declaration
|
||||
(`OffboxReportStatus().State`) — **the very statement the hub acts on**, so the two can never disagree
|
||||
about whether a retry is wanted.
|
||||
|
||||
**Why a poll and not an ACK flag.** The deciding criterion was the promise the customer is given: the
|
||||
no-target message says *"amint megvannak"* (no deadline) and the backups card says *"ha egy napon
|
||||
belül nem áll be"* — **within a day**. A 5-minute tick is inside both by a wide margin and needs **no
|
||||
hub change**. If either promise ever tightens to minutes, revisit.
|
||||
|
||||
**It stops by construction.** The instant a target exists the declaration goes false: a healthy box
|
||||
does no work and **logs nothing** (asserted). **The settle gate is deliberately kept** — the retry goes
|
||||
through `ReconcileWhenSettled`, so the day-0 floor race it guards is unchanged.
|
||||
|
||||
**The marker was investigated and left alone.** `applied_marker` lives at `<DataDir>/offbox/` — inside
|
||||
the guest's data dir, which a rebuild destroys — so it cannot suppress a legitimate post-rebuild
|
||||
re-run. It is not part of this defect.
|
||||
|
||||
### R-220's customer-facing half — a refusal that named an impossible action
|
||||
|
||||
The deploy refusal said *"Válasszon a listából csatlakoztatott meghajtót"* — choose an attached drive
|
||||
from the list — **while the list was empty**, on a rebuilt box, for a reason the customer had no part
|
||||
in. That is the I3 breach the campaign recorded. It now says what is true (the drive is not registered
|
||||
**on this machine**, which is what a rebuild causes), points at the page where re-attaching happens
|
||||
rather than at a possibly-empty list, and **promises no outcome**, because whether the drive can be
|
||||
re-attached is not knowable from there. The NAS refusal is a different situation and is untouched.
|
||||
|
||||
Tests: `internal/offsiteapply/retry_test.go` (a credential staged after start-up is collected; a
|
||||
healthy box does nothing and logs nothing; a nil bridge is silent; the settle gate holds) and
|
||||
`internal/settings/refuse_message_test.go`. **Red-proofs:** removing the retry leaves the credential
|
||||
uncollected — the re-walk's dead end reproduced; dropping the stop condition makes a healthy box
|
||||
hammer the hub; calling `Reconcile` instead of `ReconcileWhenSettled` bypasses the settle gate;
|
||||
restoring the old sentence brings the impossible action back.
|
||||
|
||||
## docs — the "CI is still owed" claim was stale; corrected (2026-08-06, R-229 part 2) — no version bump
|
||||
|
||||
**One sentence, no code.** This file asserted that continuous integration was still owed
|
||||
|
||||
Reference in New Issue
Block a user