Implements the controller side of hq ADR 0230, which replaces ADR 0229's withdrawal brake.
Events and conditions
Hears provisioner.retirement from every module.
Permission to publish it is derived for every module that receives contributions (catalogue.EmitsAll). The writers table row, the consumer filter subject and the contract test are added.
New conditions:
provider.<module>.<node>.retire (retire-waiting, urgent): lists the set waiting and names the verb to answer it.
Each verb asks the provider's own tool on that machine (mesh.mod.<module>.tool.<tool>.<node>). Approve sends the exact set the provider reports waiting.
Each act is written to the hand-act log. An approve, reject or delete event that did not come through the controller is recorded as a hand act too.
No migration needed.
Tests: the full suite passes with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11 (both removed afterwards). New tests cover:
event to condition: waiting urgent, rejected warning, retired and settled clear, unassigned clears;
approve and reject against a fake provider on a real bus;
cleanup deleting only the named consumer;
--older-than without confirm deleting nothing;
D11 at 31 days (condition), 29 days (none), and no responders (not a failure);
seat-verb argv.
Rollout: merge and roll this out before the catalogue PR (mesh-catalog feat/retired-consumers). Otherwise the providers' new event is refused by the bus; it would only be logged.
Implements the controller side of hq ADR 0230, which replaces ADR 0229's withdrawal brake.
**Events and conditions**
- Hears `provisioner.retirement` from every module.
- Permission to publish it is derived for every module that receives contributions (`catalogue.EmitsAll`). The writers table row, the consumer filter subject and the contract test are added.
- New conditions:
- `provider.<module>.<node>.retire` (`retire-waiting`, urgent): lists the set waiting and names the verb to answer it.
- `provider.<module>.<node>.retire-rejected` (`retire-rejected`, warning).
- `provider.<module>.<node>.cleanup` (`cleanup-waiting`, warning), raised by the new probe D11 when something has been retired for more than 30 days.
- All three clear when the provider is unassigned.
**Verbs** (CLI and mesh-controller seat verbs)
- `retire [--json]`
- `retire approve|reject <node> <module> --why`
- `cleanup [list]`
- `cleanup delete <node> <module> <consumer> --why`
- `cleanup delete --older-than <days> --why [--confirm]`: lists only, deletes nothing without `--confirm`.
- Each verb asks the provider's own tool on that machine (`mesh.mod.<module>.tool.<tool>.<node>`). Approve sends the exact set the provider reports waiting.
- Each act is written to the hand-act log. An approve, reject or delete event that did not come through the controller is recorded as a hand act too.
No migration needed.
**Tests:** the full suite passes with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11 (both removed afterwards). New tests cover:
- event to condition: waiting urgent, rejected warning, retired and settled clear, unassigned clears;
- approve and reject against a fake provider on a real bus;
- cleanup deleting only the named consumer;
- `--older-than` without confirm deleting nothing;
- D11 at 31 days (condition), 29 days (none), and no responders (not a failure);
- seat-verb argv.
**Rollout:** merge and roll this out before the catalogue PR (mesh-catalog feat/retired-consumers). Otherwise the providers' new event is refused by the bus; it would only be logged.
A provider can now be mark-only: SDK providers without retire keep the consumer's access. The controller reads two new fields from the retirement state, retires_by and stable_for_seconds, and a per-consumer access field.
cleanup list marks those consumers [MARK ONLY: access kept until deleted] and carries access in the JSON output.
retire approve against a mark-only provider says the consumers were marked, not disabled.
New test: TestNatsAMarkOnlyRetirementIsSaidAsSuch.
The full suite passes again with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11, both removed afterwards.
Updated in c4406aa.
A provider can now be mark-only: SDK providers without `retire` keep the consumer's access. The controller reads two new fields from the retirement state, `retires_by` and `stable_for_seconds`, and a per-consumer `access` field.
- **`cleanup list`** marks those consumers `[MARK ONLY: access kept until deleted]` and carries `access` in the JSON output.
- **`retire approve`** against a mark-only provider says the consumers were marked, not disabled.
New test: `TestNatsAMarkOnlyRetirementIsSaidAsSuch`.
The full suite passes again with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11, both removed afterwards.
A provider now waits for a person before retiring more than three consumers
or half of what it holds, and deletes only when asked. The controller is that
person's way in: it keeps waiting and rejected sets as conditions, answers them
with retire approve|reject, lists and deletes retired consumers through the
provider's own tools on its machine, records each act in the hand-act log, and
probes for anything retired longer than thirty days (D11).
A provider that cannot disable keeps the consumer reachable until a person
deletes it (hq ADR 0230); the listing and the approval say so instead of
claiming access was disabled.
Approving a retirement and deleting what was retired are a person's act by
design (hq ADR 0230); counted by S15 they would ask for a healer that must not
exist.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Transitions
2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#84 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
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@4f4d3653605a` — **held** since 2026-10-06T23:05:28Z
Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on.
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
**Transitions**
- 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-controller#84 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
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.
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.
Implements the controller side of hq ADR 0230, which replaces ADR 0229's withdrawal brake.
Events and conditions
provisioner.retirementfrom every module.catalogue.EmitsAll). The writers table row, the consumer filter subject and the contract test are added.provider.<module>.<node>.retire(retire-waiting, urgent): lists the set waiting and names the verb to answer it.provider.<module>.<node>.retire-rejected(retire-rejected, warning).provider.<module>.<node>.cleanup(cleanup-waiting, warning), raised by the new probe D11 when something has been retired for more than 30 days.Verbs (CLI and mesh-controller seat verbs)
retire [--json]retire approve|reject <node> <module> --whycleanup [list]cleanup delete <node> <module> <consumer> --whycleanup delete --older-than <days> --why [--confirm]: lists only, deletes nothing without--confirm.mesh.mod.<module>.tool.<tool>.<node>). Approve sends the exact set the provider reports waiting.No migration needed.
Tests: the full suite passes with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11 (both removed afterwards). New tests cover:
--older-thanwithout confirm deleting nothing;Rollout: merge and roll this out before the catalogue PR (mesh-catalog feat/retired-consumers). Otherwise the providers' new event is refused by the bus; it would only be logged.
Updated in
c4406aa.A provider can now be mark-only: SDK providers without
retirekeep the consumer's access. The controller reads two new fields from the retirement state,retires_byandstable_for_seconds, and a per-consumeraccessfield.cleanup listmarks those consumers[MARK ONLY: access kept until deleted]and carriesaccessin the JSON output.retire approveagainst a mark-only provider says the consumers were marked, not disabled.New test:
TestNatsAMarkOnlyRetirementIsSaidAsSuch.The full suite passes again with GOFLAGS=-mod=vendor GOPROXY=off against throwaway postgres:17 and nats:2.11, both removed afterwards.
c4406aafbfto08e11ad761Delivery
novox/mesh-controller@4f4d3653605a— held since 2026-10-06T23:05:28ZHeld for a person: merged without a passing check: only a person decides that it goes on —
mesh-delivery.releasewith why lets it go on.Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.