A machine waiting for its push is waiting, not uncomposable (hq issue 275) #89

Merged
mesh-admin merged 1 commits from fix/d1-a-push-not-made-yet-is-pending into main 2026-10-06 16:07:17 +00:00
Contributor

novox/hq issue 275. Seen live 2026-10-06: right after assign <machine> restic and before push, D1 composed the machine's declaration without allocating, failed on restic's own secret repository (which the push makes), and raised an URGENT machine.<n>.uncomposable — a desktop notification for nothing. The same window raised D3 seat.node-backup.<n>.silent and D13 data-unmeasured for a holder that had not been sent yet.

The rule

  • D1 composes as the push would, making nothing (Foreseeing, a third Choosing beside Reading and Allocating). An own secret not made yet is asked of the push's own rules: one the push makes is composed with a stand-in (catalogue.ForeseenSealed) and named in Composed.Foreseen; one the push is refused on — a bus credential nobody issued (issue 203), no sealing key, a given secret under an old key — is refused here with the push's words. So everything else the composition or the node-engine's validator would refuse is still found, and still urgent.
  • A machine whose declaration composes and validates with only stand-ins is waiting for a push: nothing is said until awaitingPushBound (30 min) passes since it began waiting (inventory.AwaitingSince: the oldest assignment since its last send, else its last send), then a warning machine.<n>.awaiting-push naming what the push will make and the verb. Never urgent: nothing is wrong that a push does not fix.
  • The composer's refusal of a secret given no value is typed (*catalogue.NotMadeError), same words; nothing matches error text.
  • D3 and D13 expect a holder only once its machine was sent it and had time to report (lastSend.settled): its last send carried the module (sent_builds), and the machine reported acting on that declaration or reportGrace (10 min) passed. Never sent: not expected. A send from before builds were kept: as before.
  • inventory.WouldMakeSecretForModule is SecretForModule's decision without the insert; both share the refusal text.

Tests

  • TestAModuleAssignedAndNotPushedIsAwaitingAPushNotUncomposable — the window: assign a module with an own secret after a push → Reading fails with NotMadeError, Foreseeing composes naming keeper/repository and makes nothing; D1 says nothing within the bound, a warning awaiting-push past it; push → clear. Fails on main with exactly the live urgent text.
  • TestASecretThePushCannotMakeIsStillUncomposable — an un-issued bus credential stays urgent uncomposable; a real composition failure beside a waiting secret stays urgent.
  • TestAGivenSecretUnderAnOldKeyIsNotForeseen, TestAMachineAwaitsAPushSinceItsOldestAssignmentSinceTheLastSend, TestAHolderIsExpectedOnlyOnceSentAndReported, TestALastSendIsReadFromTheSendAndTheReport.
  • The D13 live test now sends and reports before asking the holders.

Full suite with MESH_TEST_POSTGRES (postgres:17) + MESH_TEST_NATS (nats:2.11), -p 1, vendored, GOPROXY=off: all ok. go vet, gofmt clean. -race on catalogue, inventory and cmd/mesh-controller: ok.

No migration: assignment.assigned, node.sent_at, sent_builds and node_report.declared already hold what is read.

novox/hq issue 275. Seen live 2026-10-06: right after `assign <machine> restic` and before `push`, D1 composed the machine's declaration without allocating, failed on restic's own secret `repository` (which the push makes), and raised an URGENT `machine.<n>.uncomposable` — a desktop notification for nothing. The same window raised D3 `seat.node-backup.<n>.silent` and D13 `data-unmeasured` for a holder that had not been sent yet. ## The rule - **D1 composes as the push would, making nothing** (`Foreseeing`, a third `Choosing` beside `Reading` and `Allocating`). An own secret not made yet is asked of the push's own rules: one the push *makes* is composed with a stand-in (`catalogue.ForeseenSealed`) and named in `Composed.Foreseen`; one the push is *refused* on — a bus credential nobody issued (issue 203), no sealing key, a given secret under an old key — is refused here with the push's words. So everything else the composition or the node-engine's validator would refuse is still found, and still urgent. - A machine whose declaration composes and validates with only stand-ins is **waiting for a push**: nothing is said until `awaitingPushBound` (30 min) passes since it began waiting (`inventory.AwaitingSince`: the oldest assignment since its last send, else its last send), then a **warning** `machine.<n>.awaiting-push` naming what the push will make and the verb. Never urgent: nothing is wrong that a push does not fix. - The composer's refusal of a secret given no value is typed (`*catalogue.NotMadeError`), same words; nothing matches error text. - **D3 and D13 expect a holder only once its machine was sent it and had time to report** (`lastSend.settled`): its last send carried the module (`sent_builds`), and the machine reported acting on that declaration or `reportGrace` (10 min) passed. Never sent: not expected. A send from before builds were kept: as before. - `inventory.WouldMakeSecretForModule` is `SecretForModule`'s decision without the insert; both share the refusal text. ## Tests - `TestAModuleAssignedAndNotPushedIsAwaitingAPushNotUncomposable` — the window: assign a module with an own secret after a push → Reading fails with `NotMadeError`, Foreseeing composes naming `keeper/repository` and makes nothing; D1 says nothing within the bound, a warning `awaiting-push` past it; push → clear. Fails on main with exactly the live urgent text. - `TestASecretThePushCannotMakeIsStillUncomposable` — an un-issued bus credential stays urgent `uncomposable`; a real composition failure beside a waiting secret stays urgent. - `TestAGivenSecretUnderAnOldKeyIsNotForeseen`, `TestAMachineAwaitsAPushSinceItsOldestAssignmentSinceTheLastSend`, `TestAHolderIsExpectedOnlyOnceSentAndReported`, `TestALastSendIsReadFromTheSendAndTheReport`. - The D13 live test now sends and reports before asking the holders. Full suite with MESH_TEST_POSTGRES (postgres:17) + MESH_TEST_NATS (nats:2.11), `-p 1`, vendored, GOPROXY=off: all ok. `go vet`, gofmt clean. `-race` on catalogue, inventory and cmd/mesh-controller: ok. No migration: `assignment.assigned`, `node.sent_at`, `sent_builds` and `node_report.declared` already hold what is read.
mesh-admin added 1 commit 2026-10-06 16:06:11 +00:00
Between assign and push a module's own secrets are not made yet; D1 composed
without making them and raised an urgent 'nothing can be sent' that the next
push resolved silently. D1 now composes as the push would (Foreseeing): a
secret the push makes gets a stand-in and is named, one the push is refused on
is refused with the push's words. Waiting is said only past 30 minutes, as a
warning. D3 and D13 expect a holder only once its machine was sent it and
reported or had ten minutes to.
mesh-admin merged commit 4d05385819 into main 2026-10-06 16:07:17 +00:00
mesh-admin deleted branch fix/d1-a-push-not-made-yet-is-pending 2026-10-06 16:07:17 +00:00
Author
Contributor

Delivery novox/mesh-controller@4d053858193e — delivered since 2026-10-06T23:05:28Z

Machines

  • build-agent on ace: sent
  • mesh-controller on novox: sent

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#89 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
  • 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's plans go
  • 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-controller@4d053858193e` — **delivered** since 2026-10-06T23:05:28Z **Machines** - build-agent on ace: sent - mesh-controller on novox: sent **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#89 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on - 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's `plans go` - 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
This repo is archived. You cannot comment on pull requests.
No Reviewers
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#89