The provisioner keeps a provision while a module's newest composition is unread, and withdraws an ask once a key is needed again (issue 1966, recovery)
#638
Merged
mesh-toolsmerged 3 commits from fix/1966-provisioner-newest-held into main2026-11-09 08:07:53 +00:00
Recovery fix under recovery-fixes-merge-and-tell (hq instruction section): merged by fix-1965@shanks without the operator's Approve, the operator told on Telegram.
Cause
mesh-provisioner's FromCompositions read each module's plans at the wanted and the newest build, and skipped a newest composition that was unpublished (and only said a refused one) without marking the module untouched. Every key only the newest build requires then turned retiring and an ask was raised: on 2026-11-09 06:55-06:59 UTC it asked the operator to remove mesh-build-go's go-package-registry provision on all four nodes (the operator answered Keep), and at 07:13 UTC three artifact-store removal asks for keys in use (mesh-build-node on shanks and novox, mesh-build-image on shanks). It breaks ADR 0570 §5, the same kind as issue 940 (not composed is not unneeded), fixed then for the wanted build only. This is the third time the kind was met.
Quick or thorough
Quick: a module held or unread at its newest build joins untouched.
Thorough, chosen (the kind recurred, hid itself, and asked the operator to remove access in use):
S1: an unread or refused newest composition holds its module, so its keys are not judged.
S2: a retiring key that is needed again withdraws its ask on operator-channel, through one helper for the node and the provider-side path; a failed cancel keeps the ask id and is retried.
S3: the newest holds are kept on the bus in the state refused (key <node>.<module>=newest); provisioner_plans shows newest-held, and provisioner_health names a hold past 45 minutes.
Evidence
Every part has a test that fails without it. The in-memory test store now refuses keys outside the bus's key rule, which caught a first key form with @.
vet (also -tags integration) and the module's tests pass. The test count stays at 18 functions.
The provisioner already has the grant mesh.seat.operator-channel.accept.cancel.mesh-provisioner, read live from mesh-grants.grants_membership.
How it is checked live
The three open artifact-store asks disappear from operator-channel.asks on the first pass.
provisioner_provisions keeps go-package-registry provided on all four nodes.
At mesh-build-go's next newest-build move, provisioner_plans shows it in newest-held and no removal ask is raised.
Undo
Revert this merge.
Reviewed-by: mesh-code-reviewer@shanks (for fix-1965) at 4658e1cb1c, three rounds.
Recovery fix under recovery-fixes-merge-and-tell (hq instruction section): merged by fix-1965@shanks without the operator's Approve, the operator told on Telegram.
## Cause
mesh-provisioner's `FromCompositions` read each module's plans at the wanted and the newest build, and skipped a newest composition that was unpublished (and only said a refused one) without marking the module untouched. Every key only the newest build requires then turned retiring and an ask was raised: on 2026-11-09 06:55-06:59 UTC it asked the operator to remove mesh-build-go's go-package-registry provision on all four nodes (the operator answered Keep), and at 07:13 UTC three artifact-store removal asks for keys in use (mesh-build-node on shanks and novox, mesh-build-image on shanks). It breaks ADR 0570 §5, the same kind as issue 940 (not composed is not unneeded), fixed then for the wanted build only. This is the third time the kind was met.
## Quick or thorough
- Quick: a module held or unread at its newest build joins `untouched`.
- Thorough, chosen (the kind recurred, hid itself, and asked the operator to remove access in use):
- S1: an unread or refused newest composition holds its module, so its keys are not judged.
- S2: a retiring key that is needed again withdraws its ask on operator-channel, through one helper for the node and the provider-side path; a failed cancel keeps the ask id and is retried.
- S3: the newest holds are kept on the bus in the state `refused` (key `<node>.<module>=newest`); `provisioner_plans` shows `newest-held`, and `provisioner_health` names a hold past 45 minutes.
## Evidence
- Every part has a test that fails without it. The in-memory test store now refuses keys outside the bus's key rule, which caught a first key form with `@`.
- vet (also `-tags integration`) and the module's tests pass. The test count stays at 18 functions.
- The provisioner already has the grant `mesh.seat.operator-channel.accept.cancel.mesh-provisioner`, read live from mesh-grants.grants_membership.
## How it is checked live
- The three open artifact-store asks disappear from operator-channel.asks on the first pass.
- `provisioner_provisions` keeps go-package-registry `provided` on all four nodes.
- At mesh-build-go's next newest-build move, `provisioner_plans` shows it in `newest-held` and no removal ask is raised.
## Undo
Revert this merge.
Reviewed-by: mesh-code-reviewer@shanks (for fix-1965) at 4658e1cb1c6ca56abdfa2935713a7a98977ba53f, three rounds.
https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
Not read is not unneeded on the newest scope too (issue 940's rule): a module whose newest composition is
unpublished or refused is held at its newest build, said in provisioner_plans newest-held and bounded on the health.
A retiring key needed again cancels its ask on operator-channel (accept.cancel), retried until the router takes it.
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
Deliverynovox/mesh-catalog@4658e1cb1c6c — merged since 2026-11-09T08:07:56Z
Source — source.main moved to novox/mesh-catalog@89cd8a2e8e. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-11-09 08:07 (new) → proposed (announced): novox/mesh-catalog#638's head announced
2026-11-09 08:07 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; or the check gates no merge (check-gates-merge false)
2026-11-09 08:07 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-catalog@4658e1cb1c6c` — **merged** since 2026-11-09T08:07:56Z
**Source** — source.main moved to novox/mesh-catalog@89cd8a2e8ed2. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-11-09 08:07 (new) → proposed (announced): novox/mesh-catalog#638's head announced
- 2026-11-09 08:07 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; or the check gates no merge (check-gates-merge false)
- 2026-11-09 08:07 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.
Recovery fix under recovery-fixes-merge-and-tell (hq instruction section): merged by fix-1965@shanks without the operator's Approve, the operator told on Telegram.
Cause
mesh-provisioner's
FromCompositionsread each module's plans at the wanted and the newest build, and skipped a newest composition that was unpublished (and only said a refused one) without marking the module untouched. Every key only the newest build requires then turned retiring and an ask was raised: on 2026-11-09 06:55-06:59 UTC it asked the operator to remove mesh-build-go's go-package-registry provision on all four nodes (the operator answered Keep), and at 07:13 UTC three artifact-store removal asks for keys in use (mesh-build-node on shanks and novox, mesh-build-image on shanks). It breaks ADR 0570 §5, the same kind as issue 940 (not composed is not unneeded), fixed then for the wanted build only. This is the third time the kind was met.Quick or thorough
untouched.refused(key<node>.<module>=newest);provisioner_plansshowsnewest-held, andprovisioner_healthnames a hold past 45 minutes.Evidence
@.-tags integration) and the module's tests pass. The test count stays at 18 functions.mesh.seat.operator-channel.accept.cancel.mesh-provisioner, read live from mesh-grants.grants_membership.How it is checked live
provisioner_provisionskeeps go-package-registryprovidedon all four nodes.provisioner_plansshows it innewest-heldand no removal ask is raised.Undo
Revert this merge.
Reviewed-by: mesh-code-reviewer@shanks (for fix-1965) at
4658e1cb1c, three rounds.https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
Delivery
novox/mesh-catalog@4658e1cb1c6c— merged since 2026-11-09T08:07:56ZSource — source.main moved to novox/mesh-catalog@89cd8a2e8e. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.