Issue 924 (the provisioner client's refused writes are never tried again), met live 2026-10-25 on ace: the client placed mesh-build-go's files one second before ace's declaration named them, the node-engine refused ('not a file this node's declaration names as filled'), nothing woke the client again, and mesh-build-go crash-looped on a missing broker file.
The filling engine (internal/filling) remembers what it refused or failed to write.
The agent calls Env.Settled(module) after a successful apply or removal, once what runs holds the module (afterApply runs before that, when the declaration does not name the new files yet).
On Settled, Engine.Knock touches the write socket the client watches when the declaration now names a refused path, now names the provisioner's account, or a write had failed; it says which in the journal. It takes the apply's lock (the one a Write takes), so a refusal still being judged when the apply settles is not missed, and it reads the declaration only when something is owed.
No timer: the knock is the node-engine's own event after an apply. The NATS-native trigger (the client reading its module's have) needs a controller grant and goes to ADR 0547's later milestones. The client side is mesh-catalog's PR of the same branch name; each works without the other (the client already watches the socket).
Checked: go test -race -count=1 ./... and go vet -tags integration ./... pass; the integration level was run locally once. No top-level test functions added (rows in TestAnUndeclaredPathIsRefused, including a deterministic race row, and the agent test checks Settled). No try (recovery mode: the operator merges by hand). This is the node-engine on every node.
Issue 924 (the provisioner client's refused writes are never tried again), met live 2026-10-25 on ace: the client placed mesh-build-go's files one second before ace's declaration named them, the node-engine refused ('not a file this node's declaration names as filled'), nothing woke the client again, and mesh-build-go crash-looped on a missing broker file.
- The filling engine (internal/filling) remembers what it refused or failed to write.
- The agent calls `Env.Settled(module)` after a successful apply or removal, once what runs holds the module (afterApply runs before that, when the declaration does not name the new files yet).
- On Settled, `Engine.Knock` touches the write socket the client watches when the declaration now names a refused path, now names the provisioner's account, or a write had failed; it says which in the journal. It takes the apply's lock (the one a Write takes), so a refusal still being judged when the apply settles is not missed, and it reads the declaration only when something is owed.
No timer: the knock is the node-engine's own event after an apply. The NATS-native trigger (the client reading its module's have) needs a controller grant and goes to ADR 0547's later milestones. The client side is mesh-catalog's PR of the same branch name; each works without the other (the client already watches the socket).
Checked: go test -race -count=1 ./... and go vet -tags integration ./... pass; the integration level was run locally once. No top-level test functions added (rows in TestAnUndeclaredPathIsRefused, including a deterministic race row, and the agent test checks Settled). No try (recovery mode: the operator merges by hand). This is the node-engine on every node.
Reviewed-by: review-prov@shanks at 338797a52703177d1e4271d7c6e347f64d7f85d6
ace's filling refused mesh-build-go's files as not named as filled 32 s before
its want arrived; after the apply that named them nothing asked again, and the
runtime crash-looped on its missing broker credential. The filling now keeps
what it refused or failed and, when the node agent says a module's apply or
removal settled (agent.Env.Settled, called once what runs holds it), touches its
write socket if the declaration now names such a path, names the provisioner's
account, or a write had failed; the client watches that socket and fills every
module again. Said in the journal each time.
A write judged by the declaration before the apply settled could record its
refusal just after Knock found nothing owed: the original fault in a small
window. Knock now holds the apply's lock as a write does, reads no declaration
while nothing is owed, and its comment names Settled as its caller.
Deliverynovox/mesh-host@338797a52703 — merged since 2026-10-25T21:08:54Z
Source — source.main moved to novox/mesh-host@e196058f6f. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
composed together: pass — the checker's verdict at the members' heads (9eb0f92fd6b3)
Transitions
2026-10-25 20:50 (new) → proposed (announced): novox/mesh-host#142's head announced
2026-10-25 20:53 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail
2026-10-25 21:08 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-host@338797a52703` — **merged** since 2026-10-25T21:08:54Z
**Source** — source.main moved to novox/mesh-host@e196058f6fb0. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Group** `fix/provisioner-retries-on-declaration`: novox/mesh-catalog@d0566f9ade9a, novox/mesh-host@338797a52703
- composed together: pass — the checker's verdict at the members' heads (9eb0f92fd6b3)
**Transitions**
- 2026-10-25 20:50 (new) → proposed (announced): novox/mesh-host#142's head announced
- 2026-10-25 20:53 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail
- 2026-10-25 21:08 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Issue 924 (the provisioner client's refused writes are never tried again), met live 2026-10-25 on ace: the client placed mesh-build-go's files one second before ace's declaration named them, the node-engine refused ('not a file this node's declaration names as filled'), nothing woke the client again, and mesh-build-go crash-looped on a missing broker file.
Env.Settled(module)after a successful apply or removal, once what runs holds the module (afterApply runs before that, when the declaration does not name the new files yet).Engine.Knocktouches the write socket the client watches when the declaration now names a refused path, now names the provisioner's account, or a write had failed; it says which in the journal. It takes the apply's lock (the one a Write takes), so a refusal still being judged when the apply settles is not missed, and it reads the declaration only when something is owed.No timer: the knock is the node-engine's own event after an apply. The NATS-native trigger (the client reading its module's have) needs a controller grant and goes to ADR 0547's later milestones. The client side is mesh-catalog's PR of the same branch name; each works without the other (the client already watches the socket).
Checked: go test -race -count=1 ./... and go vet -tags integration ./... pass; the integration level was run locally once. No top-level test functions added (rows in TestAnUndeclaredPathIsRefused, including a deterministic race row, and the agent test checks Settled). No try (recovery mode: the operator merges by hand). This is the node-engine on every node.
Reviewed-by: review-prov@shanks at
338797a527Delivery
novox/mesh-host@338797a52703— merged since 2026-10-25T21:08:54ZSource — source.main moved to novox/mesh-host@e196058f6f. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Group
fix/provisioner-retries-on-declaration: novox/mesh-catalog@d0566f9ade, novox/mesh-host@338797a527Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.