ADR 0230: a consumer the mesh stops asking for is retired, and deleted only by a person
The operator's decision replaces ADR 0229's hourly release: the mesh no longer finishes alone what its bound exists to question. To-be 45 and the module protocol amended; 0229 and 0224 point to where their mechanism moved.
This commit is contained in:
@@ -10,6 +10,7 @@ code:
|
||||
updated: 2026-10-06
|
||||
decisions:
|
||||
- 02-DECISIONS/0224-a-provider-that-keeps-failing-a-consumer-is-a-problem-the-controller-reports.md
|
||||
- 02-DECISIONS/0230-a-consumer-the-mesh-stops-asking-for-is-retired-and-deleted-only-by-a-person.md
|
||||
- 02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md
|
||||
- 02-DECISIONS/0106-the-bus-is-nats.md
|
||||
- 02-DECISIONS/0128-the-mesh-bus-is-required-not-ambient.md
|
||||
@@ -246,6 +247,19 @@ receives contributions may publish both, derived and never declared. The control
|
||||
failing word per provider, machine and consumer, and `status` names each one until it recovers
|
||||
([ADR 0224](../../02-DECISIONS/0224-a-provider-that-keeps-failing-a-consumer-is-a-problem-the-controller-reports.md)).
|
||||
|
||||
### A consumer the mesh stops asking for is retired
|
||||
|
||||
A consumer is active, retired or deleted
|
||||
([ADR 0230](../../02-DECISIONS/0230-a-consumer-the-mesh-stops-asking-for-is-retired-and-deleted-only-by-a-person.md)).
|
||||
The provider's loop retires one only after the same set has gone unasked in five consecutive passes
|
||||
that read the contributions file; retiring disables its access reversibly and marks it, in the
|
||||
provider's own backend, with when and why; asked for again, the ordinary create re-enables it. A set of
|
||||
more than three, or of more than half of those held, waits for a person. Every provider serves four
|
||||
tools for this — `provisioner_retirement`, `provisioner_retire_approve`, `provisioner_retire_reject`,
|
||||
`provisioner_delete` — and says `provisioner.retirement`, permitted like the two events above. The
|
||||
controller's `retire` and `cleanup` verbs ask those tools on the provider's machine; nothing else deletes
|
||||
a consumer.
|
||||
|
||||
### Checked, and it agrees (2026-09-16)
|
||||
|
||||
This looked like the sharpest disagreement and was not one. The live wire is the contributions file
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-lab]
|
||||
code: [mesh-controller, mesh-host, mesh-tools, mesh-catalog, mesh-sdk, mesh-lab]
|
||||
updated: 2026-10-06
|
||||
decisions:
|
||||
- 02-DECISIONS/0227-the-core-holds-nine-rules-each-checked-and-is-built-to-them-in-six-phases.md
|
||||
- 02-DECISIONS/0229-the-cores-order-is-a-lease-the-store-remembers-and-an-epoch-a-machine-is-sent-once-it-reads-one.md
|
||||
- 02-DECISIONS/0231-a-healer-acts-on-what-observation-raised-and-only-observation-says-it-worked.md
|
||||
- 02-DECISIONS/0230-a-consumer-the-mesh-stops-asking-for-is-retired-and-deleted-only-by-a-person.md
|
||||
- 02-DECISIONS/0224-a-provider-that-keeps-failing-a-consumer-is-a-problem-the-controller-reports.md
|
||||
- 02-DECISIONS/0218-a-plan-sends-grants-before-code-rolls-out-one-machine-first-and-a-newer-merge-takes-over-an-older-plan.md
|
||||
- 02-DECISIONS/0141-the-host-delivers-its-own-successor.md
|
||||
@@ -45,8 +46,9 @@ Owning repositories: **mesh-controller** (the condition store, watchdogs, `docto
|
||||
calls, the hand-act log, the facts snapshot), **mesh-host** (the node-engine: the apply queue, report
|
||||
order, epoch refusal, the `report` verb, rollback witnessing), **mesh-tools** (the node tools and the
|
||||
console: their heartbeat, passing every argument, health answers), **mesh-catalog** (the
|
||||
`operator-channel` seat's holder and channels, the watcher, the provider brake, the catalogue's merge
|
||||
gate), **mesh-lab** (the replays and the induced-failure scenarios).
|
||||
`operator-channel` seat's holder and channels, the watcher, the providers' retirement, the catalogue's
|
||||
merge gate), **mesh-sdk** (the TypeScript providers' loop and its retirement), **mesh-lab** (the
|
||||
replays and the induced-failure scenarios).
|
||||
|
||||
---
|
||||
|
||||
@@ -68,6 +70,7 @@ Every kind of state the core keeps, and the one component that writes it. Anyone
|
||||
| builds and their outcomes | the build seat's holder | its own state | the controller asks |
|
||||
| a merge announced | **one** announcer per forge (the hook, or the poll when the hook is absent — never both) | the bus | — |
|
||||
| a provider's standing | the provider | the provider's events | the controller keeps the newest word as a condition |
|
||||
| a consumer's retirement: active, retired (when, why), deleted | the provider | its own backend's mark; said on `provisioner.retirement` | the controller asks the provider's tools; a person approves, rejects and deletes through the controller's verbs |
|
||||
| the operator-channel's open messages | the seat's holder | its own key-value state | — |
|
||||
| the facts snapshot | controller | the artifact store, `facts/latest` | the build seat reads |
|
||||
|
||||
@@ -145,6 +148,13 @@ outlive the history.
|
||||
with their expiry. The all-well sentence requires none open, silenced included.
|
||||
- **ADR 0224's provider standing** is the first kind: `provider-failing`, raised by the provider's
|
||||
event, cleared by its recovery, its silence after thirty minutes the row S8 below.
|
||||
- **Retirement** ([ADR 0230](../../02-DECISIONS/0230-a-consumer-the-mesh-stops-asking-for-is-retired-and-deleted-only-by-a-person.md))
|
||||
raises three, keyed by the provider module and its machine: `retire-waiting` (urgent) while a stable
|
||||
set too large to retire alone waits for `retire approve` or `retire reject`, listing it; `retire-rejected`
|
||||
(warning) while a rejected set is kept active though the mesh no longer asks for it; and
|
||||
`cleanup-waiting` (warning), from the probe D11, while anything retired is older than thirty days. The
|
||||
first two clear on the provider's `retired`, `settled` or `approved` word, and all three when the
|
||||
provider is no longer assigned there.
|
||||
|
||||
## 3. The signals table (rule 5)
|
||||
|
||||
@@ -196,6 +206,7 @@ itself — an unanswered probe is never a pass.
|
||||
| D8 | no address the mesh owns is in a ban list | 238 |
|
||||
| D9 | `status` answers in full within ten seconds | 265 |
|
||||
| D10 | every machine runs the node-engine and node tools builds its plan says, or is inside a plan's window | version split |
|
||||
| D11 | no provider holds a consumer retired more than thirty days: each provider assigned is asked `provisioner_retirement` on its machine (ADR 0230); one that does not serve it yet is named, not failed | ADR 0230 |
|
||||
| DW | the watchdogs of §3 ran within three of their intervals: the watchers are watched, and raise S10 when the self-check stops | rule 6 |
|
||||
| H-* | the health probes of §8, run for every core component on every machine | rule 8 |
|
||||
|
||||
@@ -331,7 +342,9 @@ all healers together, stop every healer — `mesh.healers.braked`, urgent — un
|
||||
A heal is never a hand act. `healers` lists the registry, the acts and the brake.
|
||||
|
||||
**The hand-act log.** Every verb that repairs by hand — a named `push` outside a plan, `plans close`,
|
||||
`broker consumer-reset`, `conditions silence`, and `hand-act record` for an act done outside the mesh —
|
||||
`broker consumer-reset`, `conditions silence`, `retire approve`, `retire reject` and `cleanup delete`
|
||||
(ADR 0230; and an approval, rejection or deletion a provider reports that did not come through the
|
||||
controller), and `hand-act record` for an act done outside the mesh —
|
||||
takes a required `--why` and writes an entry: who, which verb and arguments, why, when, the condition
|
||||
key it addresses if any, and a **cause** (the condition kind, or a word the person gives). `status`
|
||||
shows the week's count. A cause recorded twice within fourteen days raises `healer-wanted` (S15).
|
||||
@@ -396,7 +409,7 @@ outcome, run on every merge to mesh-controller, mesh-host and mesh-tools:
|
||||
| R3 | the node-engine self-updates during its report (230, 264) | the report arrives under the new build |
|
||||
| R4 | the bus's authorization reloads during a call (265) | the call's outcome is readable by id |
|
||||
| R5 | a consumer with several filter subjects under mixed traffic (266) | no announcement is skipped; S5 fires if one is |
|
||||
| R6 | an unreadable contributions file (241) | refused by name; nothing withdrawn; a condition |
|
||||
| R6 | an unreadable contributions file (241) | refused by name; nothing retired; a condition |
|
||||
| R7 | the controller rebuilds itself mid-plan (214) | the plan continues under the new epoch |
|
||||
| R8 | a broken controller, node-engine and node tools build | each rolled back with no hand; condition and message |
|
||||
| R9 | each signal of §3 suppressed | its condition within its bound, cleared on return |
|
||||
@@ -447,11 +460,11 @@ bound corrected in the table.
|
||||
| mesh-controller | the lease and epoch (§6); plans written by compare-and-set; a report kept by sequence; abandoned calls marked; S12, S13, D5; the writers table enforced at grant composition; contract tests for every consumed subject and the check listing them; the empty-on-error lint |
|
||||
| mesh-host | one apply queue; the report sequence kept on disk; epoch refusal reported; the `report` verb; the contract tests and lint |
|
||||
| mesh-tools | refusing an unreadable or unknown input by name; the lint |
|
||||
| mesh-catalog | the withdrawal brake in the providers' loop: a reconcile that would withdraw more than one consumer, or a set fraction, stops and raises a condition |
|
||||
| mesh-catalog, mesh-sdk | retirement in the providers' loop (ADR 0230, replacing ADR 0229's brake): a consumer no longer asked for is retired — disabled, marked, its data kept — only once the same result holds for five passes; a set of more than three, or more than half of those held, waits for a person and raises a condition; the four retirement tools on every provider |
|
||||
| mesh-lab | R1, R2, R6 |
|
||||
|
||||
**Done when:** R1 ends with nothing from the stale epoch applied, R2 with one report of the newest
|
||||
sequence, R6 with the withdrawal braked; every consumed subject has its contract test.
|
||||
sequence, R6 with nothing retired; every consumed subject has its contract test.
|
||||
|
||||
**Built 2026-10-06** ([ADR 0229](../../02-DECISIONS/0229-the-cores-order-is-a-lease-the-store-remembers-and-an-epoch-a-machine-is-sent-once-it-reads-one.md)):
|
||||
the controller's lease and epoch, plans by compare-and-set, accounts kept by order, S12, S13 by writer,
|
||||
@@ -461,6 +474,15 @@ providers' loop and the SDK's. **Not yet:** the replays R1, R2 and R6 in mesh-la
|
||||
and lint; the lint in mesh-host; the SDK's loop announcing a provider's standing, without which its
|
||||
brake is said in its journal only.
|
||||
|
||||
**Amended 2026-10-06** ([ADR 0230](../../02-DECISIONS/0230-a-consumer-the-mesh-stops-asking-for-is-retired-and-deleted-only-by-a-person.md),
|
||||
the operator's decision): the brake's hourly release is replaced by retirement — three states (active,
|
||||
retired, deleted), five stable passes before a consumer is retired, a person for more than three or more
|
||||
than half, `retire approve|reject`, `cleanup list|delete`, `retirement` events and D11. Built on branches
|
||||
in mesh-catalog (both Go providers), mesh-sdk (0.1.12) and mesh-controller, not yet merged. **Not yet:**
|
||||
the TypeScript providers passing their module name and an announcer to the loop, without which a set
|
||||
over the bound there waits with no way to approve it, and adapters that list and delete what they
|
||||
retired.
|
||||
|
||||
### Phase 3 — Healers
|
||||
|
||||
| Repository | Delivers |
|
||||
|
||||
Reference in New Issue
Block a user