R-204 item 4 (hub half): the hub answers a rebuilt box's request (hub v0.96.0)
New internal/offsiteheal, the sibling of pbsdrheal: it acts ONLY on the state the box declares, sustained across two distinct reports, re-staging the stored credential before ever minting a new one. A healthy box is a pure no-op; it never blind-timer-reissues and never re-runs a provisioning step. RESTAGE IS POSSIBLE because the stored value survives a consume — established from the schema and ConsumeOneTimeSecret (which stamps consumed_at and nothing else), not inherited from the PBS analogy, and pinned by a test that asserts the SAME value comes back. reportHasOffsite is TIGHTENED to require enabled:true. Its comment asserted that presence == applied-on-the-box, and the declaration deliberately breaks that premise; left alone it would have read a request for help as proof the tier was applied. Provably a no-op for every report shape that existed before, because an attached object has always carried enabled:true. R-192's guard half is CLOSED BY REPLACEMENT: the delivery checker's counting inference read the OLDEST 500 reports after a consume — all predating a rebuild, which is why demo-hp sat stranded for 108 reports under a confident regressed-shape verdict. A declaration outranks both inferred shapes, and the checker stands down with a record so the two mechanisms cannot double-issue. No escrow ceremony is ever run or requested: credential automatic, key customer-present.
This commit is contained in:
@@ -978,11 +978,27 @@ func (s *Store) SaveReport(customerID string, reportJSON []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// reportOffsitePresence is the minimal parse for "does this controller report carry an offsite
|
||||
// status object" — the R-70 delivery-state signal. The report builder attaches `offsite` only when
|
||||
// the box actually has an offbox target configured, so presence == applied-on-the-box.
|
||||
// reportOffsitePresence is the minimal parse for "does this controller report show an offsite tier
|
||||
// that is actually CONFIGURED on the box" — the R-70 delivery-state signal, i.e. applied-on-the-box.
|
||||
//
|
||||
// ⚠ TIGHTENED 2026-08-05 (hub v0.96.0, R-204 item 4), and the reason is exactly the trap this
|
||||
// project keeps recording. The predicate used to be bare PRESENCE, under a comment asserting *"the
|
||||
// report builder attaches `offsite` only when the box actually has an offbox target configured, so
|
||||
// presence == applied-on-the-box"*. Controller v0.199.0 breaks that premise deliberately: a REBUILT
|
||||
// box now attaches an offsite object carrying `enabled:false` and a declared `state` in order to ASK
|
||||
// for a credential. Left as presence-only, this function would have read that request for help as
|
||||
// proof the tier was applied — turning `DeliveryStateFor` into DeliveryApplied for the exact boxes
|
||||
// that are stranded, and suppressing the stuck event for them.
|
||||
//
|
||||
// The tightening is `enabled == true`, and it is PROVABLY A NO-OP for every report shape that exists
|
||||
// today: `backup.OffboxReportStatus` returned nil unless `t != nil && t.Enabled`, so an attached
|
||||
// object has ALWAYS carried `enabled:true`. Pinned by
|
||||
// TestReportHasOffsite_EnabledOnly — including a case asserting the pre-v0.199.0 shape still reads
|
||||
// true, so the equivalence is measured rather than argued.
|
||||
type reportOffsitePresence struct {
|
||||
Offsite json.RawMessage `json:"offsite"`
|
||||
Offsite *struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
} `json:"offsite"`
|
||||
}
|
||||
|
||||
func reportHasOffsite(reportJSON string) bool {
|
||||
@@ -990,7 +1006,7 @@ func reportHasOffsite(reportJSON string) bool {
|
||||
if err := json.Unmarshal([]byte(reportJSON), &p); err != nil {
|
||||
return false // unparseable report → no offsite evidence
|
||||
}
|
||||
return len(p.Offsite) > 0 && string(p.Offsite) != "null"
|
||||
return p.Offsite != nil && p.Offsite.Enabled
|
||||
}
|
||||
|
||||
// LatestReportOffsitePresence reports whether the customer's most recent controller report exists
|
||||
@@ -1415,6 +1431,67 @@ func (s *Store) ConsumeOneTimeSecret(customerID string) (string, error) {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// RestageOneTimeSecret re-arms an ALREADY-STORED one-time offsite secret for re-consumption by
|
||||
// clearing its consumed flag — WITHOUT changing the secret value, WITHOUT inserting a row, and
|
||||
// WITHOUT any storage-provider call. It is the off-site sibling of RestageHostPBSSecret (pbsdr.go),
|
||||
// and it exists because a REBUILT box has no credential of its own: its predecessor spent the
|
||||
// one-time password (R-193 / R-204 item 4).
|
||||
//
|
||||
// IT IS POSSIBLE AT ALL ONLY BECAUSE THE VALUE SURVIVES A CONSUME, and that was established from
|
||||
// this file rather than assumed from the PBS analogy (the two secrets are different objects with
|
||||
// different lifecycles, and assuming a shared shape is how two sessions confused the credentials):
|
||||
// ConsumeOneTimeSecret sets `consumed_at` and NOTHING ELSE — the `value` column is never cleared or
|
||||
// overwritten, and the schema declares it `TEXT NOT NULL`. So the row still holds a serviceable
|
||||
// password after consumption, and re-arming it costs no external call and converges in one report
|
||||
// tick. Pinned by TestRestageOneTimeSecret_ReArmsTheSameValue.
|
||||
//
|
||||
// Returns restaged=true when a row existed (its consumed flag is now cleared, so
|
||||
// ConsumeOneTimeSecret will serve it once more); restaged=false when NO secret is stored for the
|
||||
// customer — the caller must then escalate to a fresh mint (ReissueCredentials). The value is never
|
||||
// read or logged here.
|
||||
func (s *Store) RestageOneTimeSecret(customerID string) (bool, error) {
|
||||
res, err := s.db.Exec(`UPDATE one_time_secrets SET consumed_at = NULL WHERE customer_id = ?`, customerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
n, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
// LatestReportOffsiteDeclaration returns the id of the customer's newest controller report and the
|
||||
// state DECLARED on its `offsite` object (controller >= v0.199.0; "" on anything older, on a report
|
||||
// with no offsite object, and on an unparseable one).
|
||||
//
|
||||
// The report id is the debounce currency: the reconciler counts DISTINCT reports, not its own ticks,
|
||||
// so a stuck box is confirmed by fresh evidence rather than by the passage of time.
|
||||
//
|
||||
// found=false when the customer has no reports at all — distinguished from "a report that declares
|
||||
// nothing" so the caller never treats an absent report as a healthy one.
|
||||
func (s *Store) LatestReportOffsiteDeclaration(customerID string) (found bool, reportID int64, state string, err error) {
|
||||
var id int64
|
||||
var reportJSON string
|
||||
err = s.db.QueryRow(`SELECT id, report_json FROM reports WHERE customer_id = ? ORDER BY id DESC LIMIT 1`,
|
||||
customerID).Scan(&id, &reportJSON)
|
||||
if err == sql.ErrNoRows {
|
||||
return false, 0, "", nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, 0, "", err
|
||||
}
|
||||
var p struct {
|
||||
Offsite *struct {
|
||||
State string `json:"state"`
|
||||
} `json:"offsite"`
|
||||
}
|
||||
if json.Unmarshal([]byte(reportJSON), &p) == nil && p.Offsite != nil {
|
||||
state = p.Offsite.State
|
||||
}
|
||||
return true, id, state, nil
|
||||
}
|
||||
|
||||
// OneTimeSecretInfo is the delivery-state metadata of a customer's one-time offsite secret —
|
||||
// timestamps ONLY, the value column is deliberately never selected (R-70 detector input; the
|
||||
// customer-scoped sibling of PBSDRHealStates' SecretUnconsumedFor).
|
||||
|
||||
Reference in New Issue
Block a user