Let restic's bundle, not its night's process, write each item's last good night, since the night runs as the operator's account with no bus account (issue 1955, ADR 0436 §1-2)

This commit is contained in:
2026-10-29 23:41:16 +01:00
parent 85f5fd0b22
commit 992ea0ab66
2 changed files with 5 additions and 6 deletions
+3 -5
View File
@@ -630,7 +630,7 @@ func healthChecks(t *testing.T) {
{Module: delivery.AssignerModule, State: []Bucket{bucket(delivery.AssignerModule, delivery.SeatHoldersState)}},
// ADR 0571 clause 3: disk-load keeps the readings; the backup holder reads them.
{Module: "disk-load", State: []Bucket{bucket("disk-load", "readings")}},
{Module: "restic", Reads: []string{"disk-load.readings"}, Processes: []ProcessPrincipal{{Process: "night", State: []string{"good"}}}},
{Module: "restic", Reads: []string{"disk-load.readings"}, State: []Bucket{bucket("restic", "good")}},
// ADR 0571 clauses 1, 9: the indexer reads the builder's log through its own consumer; the catalogue module asks
// the builder's tool.
{Module: delivery.BuilderModule, Logs: []Log{{Module: delivery.BuilderModule, Name: delivery.BuilderLog, MaxAgeDays: 30}}},
@@ -652,10 +652,9 @@ func healthChecks(t *testing.T) {
"$JS.API.DIRECT.GET.KV_mesh-provisioner_plans.$KV.mesh-provisioner_plans.a.keycloak"},
"a.mesh-hand-acts": {"$KV.mesh-hand-acts_warrants.mesh-config.ask-1", "mesh.log.mesh-hand-acts.acts.act-1"},
"a.disk-load": {"$KV.disk-load_readings.a.pg.data"},
// ADR 0571 clause 3: restic's night writes each item's last good night; the self-check reads it.
"a.restic.night": {"$KV.restic_good.a.pg.data"},
// ADR 0571 clause 3: restic's bundle writes each item's last good night as its own state; the self-check reads it.
"a.mesh-self-check": {"$JS.API.DIRECT.GET.KV_restic_good.$KV.restic_good.a.pg.data"},
"a.restic": {"$JS.API.DIRECT.GET.KV_disk-load_readings.$KV.disk-load_readings.a.pg.data",
"a.restic": {"$JS.API.DIRECT.GET.KV_disk-load_readings.$KV.disk-load_readings.a.pg.data", "$KV.restic_good.a.pg.data",
// ADR 0571 clause 7: its own membership from the grants part's state.
"$JS.API.DIRECT.GET.KV_mesh-grants_memberships.$KV.mesh-grants_memberships.a.restic"},
"a.mesh-delivery-indexer": {"$JS.API.CONSUMER.CREATE.LOG_mesh-delivery-builder_build-log.r1.mesh.log.mesh-delivery-builder.build-log.letta",
@@ -680,7 +679,6 @@ func healthChecks(t *testing.T) {
"a.mesh-vault": {"$KV.mesh-provisioner_provisions.a.keycloak.postgres-database", "$KV.mesh-provisioner_plans.a.keycloak",
"mesh.seat.artifact-store.event.artifacts-gone"},
// Each writes its own state alone, and these users are composed.
"a.restic.night": {"$KV.disk-load_readings.a.pg.data"},
"a.disk-load": {"$KV.restic_good.a.pg.data"},
"a.mesh-delivery-builder": {"$KV.disk-load_readings.a.pg.data"},
// Only the assigner writes seat-holders.
+2 -1
View File
@@ -127,7 +127,8 @@ func NextReading(prev *Reading, node string, it catalogue.PlacedDataItem, m Meas
}
// **Each item's last good night** (novox/hq ADR 0571 clause 3, ADR 0564 §6; the lead, 2026-10-29): the node-backup holder
// restic keeps, from its night's process, its own state `good`, one key `<node>.<module>.<item>` for every item a module
// restic keeps, from its tools bundle through the runtime on the night's file event (its night's process runs as the
// operator's account and holds no bus account, ADR 0436 §1-2), its own state `good`, one key `<node>.<module>.<item>` for every item a module
// declares that a backup path covers, written when it changes: the item, the path whose snapshot keeps it and the newest
// good night of its module (zero before the first). The self-check's probe of a stale backup reads it there. Moved here
// from mesh-catalog modules/restic (e5ef3bed).