Merge pull request 'ADR 0292: a consumer of the part a provider waits on is held under the wait, and passes its gate as a wait for a person (issue 405)' (#309) from decisions/405-a-waiting-providers-consumer-passes into main

This commit was merged in pull request #309.
This commit is contained in:
2026-10-11 01:23:31 +00:00
4 changed files with 136 additions and 1 deletions
@@ -184,6 +184,11 @@ that provision's provider for this consumer is unhealthy on the record, the cons
the provider's condition — listed there as waiting on it, raised as nothing of its own — and the consumer's
gate waits rather than fails. What a consumer finds while its provider is healthy is its own.
> **The mechanism changed — 2026-10-11, by [ADR 0292](0292-a-consumer-of-the-part-a-provider-waits-on-is-held-under-the-wait-and-passes-its-gate-as-a-wait-for-a-person.md).** The hold under an unhealthy provider, and its consumer's gate
> waiting, stand. A provider that only waits for the operator (ADR 0283) now holds the consumers of a provision one
> of its waits covers, listed at its `needs-operator` condition, which stays a warning; their gate passes as a wait
> for a person, carrying the wait. A consumer no wait covers is said on its own.
**6. Nothing is restarted for being unhealthy.** The runtime restarts what exits, as now. A condition
reaches a person through the operator's conversation, or a healer; a healer that restarts on health is its
own decision.
@@ -99,6 +99,10 @@ named exactly, once. Nothing here conflicts with GENESIS.
that reason. The type, its constructors and its reader are mesh-sdk's (`go/health`), so the module and
the node-engine read one shape; an answer without `state` is read from `healthy` as before.
> **The mechanism changed — 2026-10-11, by [ADR 0292](0292-a-consumer-of-the-part-a-provider-waits-on-is-held-under-the-wait-and-passes-its-gate-as-a-wait-for-a-person.md).** The three answers stand. Which consumers a waiting module
> holds is now read from its waits: a wait covers a provision when its `part` is that provision's name, or when
> the secret it waits for is the provision's shared credential; a wait that covers nothing holds no consumer.
2. **The node-engine states such a resource `waiting`**, a fifth state beside healthy, unhealthy,
starting, held and unknown (ADR 0240 §4), with its waits. One look that says it is enough, inside the
grace too: it is a statement, not a flake that a second look might not repeat. The next look that says
@@ -0,0 +1,111 @@
---
topic: what runs on it
status: accepted
date: 2026-10-11
deciders: an agent session on the workstation, under jochen's standing rule that small design limits are decided by the session and recorded; jochen may supersede it
reconstructed: false
extends: 02-DECISIONS/0283-a-part-that-waits-for-the-operators-secret-or-setting-is-said-as-waiting-passes-the-first-node-gate-and-names-the-act.md
---
# 292. A consumer of the part a provider waits on is held under the wait, and passes its gate as a wait for a person
## Context
[ADR 0283](0283-a-part-that-waits-for-the-operators-secret-or-setting-is-said-as-waiting-passes-the-first-node-gate-and-names-the-act.md)
gave a module a fifth state, *waiting* for the operator's secret or setting, said as `needs-operator`, and
passed the waiting module's own first-node gate as a wait for a person. It said nothing of the module's consumers.
[ADR 0240](0240-a-module-says-how-it-is-healthy-and-the-node-engine-judges-it.md) rule 5 holds a consumer's
findings under its provider while the provider is *unhealthy*, and makes the consumer's gate wait.
Issue 405, found in the review of ADR 0283's controller change, saw the gap: a provider whose only part not
healthy waits for the operator held nothing. Every consumer that failed because of it raised its own `unhealthy`
condition, whose words say "nothing for you to do", about a fault only the operator could end. The controller
change that closes it is mesh-controller #216.
Holding consumers under a waiting provider raises three questions ADR 0283 did not answer: which consumers a wait
covers, what the held consumer's gate reads, and whether the provider's condition grows urgent while consumers
wait. This record answers them. It was decided by the agent session that built #216, under the operator's standing
rule that an agent decides a small design limit itself and records it; the operator may supersede it.
**Checked against GENESIS.** *Failure must be loud*: a consumer's fault is never hidden behind a wait that does not
cover it. *Evidence over assertion*: a consumer is held only where a wait the provider stated names what the consumer
needs. Nothing here conflicts with GENESIS.
## Considered Options
**Which consumers a waiting provider holds.**
1. *Every consumer of the provider.* ADR 0283 decision 1 says a module that waits is otherwise sound, and each wait
names its part; a consumer of another part fails for a reason of its own, and holding it would hide that.
Rejected.
2. **Only the consumers of a provision a wait covers.** Chosen.
**How a wait is known to cover a provision.**
3. *A declared mapping: a manifest field naming, for each waiting part, the provision it gives.* Exact, and
`module check` could prove it against the module's offers. Rejected for now: it is a change to the manifest
schema, to `module check` and to every waiting module, for a hold no provider needs today — the one waiting
module, mounts, provides nothing. It becomes worth it once a provider gives several provisions from parts that
wait separately, or a convention-named part is found to mislead the hold.
4. **The convention on the free-text `part`**: the part named after the provision, or the wait for the provision's
shared credential. Chosen: no schema change, and dormant until a provider follows it.
**What the held consumer's gate reads.**
5. *Waiting, as ADR 0240 rule 5 says for an unhealthy provider.* The walk then waits for the operator, possibly for
days, and every walk behind it — ADR 0283 option 4, rejected there for this reason. Rejected.
6. **A wait for a person ([ADR 0254](0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md)):
a pass, the wait carried in the verdict**, as ADR 0283 decision 4 reads the waiting module itself. Chosen.
**The provider's severity while consumers wait.**
7. *Urgent, as an unhealthy provider's condition is while consumers wait on it.* ADR 0283 decision 5 says
`needs-operator` is "a warning, the operator's, never escalated by age"; the act is the same act whoever
waits on it, and urgency would page the operator for something only they can do and already know of. Rejected.
8. **A warning, listing who waits on it.** Chosen.
## Decision
1. **A wait covers a provision** when its `part` is that provision's name, or when the secret it waits for is the
provision's shared credential ([ADR 0158](0158-a-provider-with-one-credential-shares-it-with-every-consumer.md)).
This is the convention for module authors: a provider whose waiting part gives a provision names the part after
it, or waits for that provision's shared credential.
2. **A consumer is held under a provider that only waits for the operator** when every finding of it that is not
healthy is of a check naming a provision a wait of that provider covers. It is listed at the provider's
`needs-operator` condition and raises nothing of its own. A provider that is unhealthy holds as ADR 0240 rule 5
says.
3. **A consumer a wait does not cover is said on its own**: its `unhealthy` condition, whose evidence says its
provider waits for the operator, but not for anything the consumer is known to need. So is a consumer whose
provider's waits are not known (its `needs-operator` open, its statement naming none).
4. **The held consumer's first-node gate reads a wait for a person**: a pass, the verdict carrying "… waits on
<provider> on <machine>, which waits for you: <the wait>". Under an unhealthy provider the gate waits, as before.
5. **The provider's `needs-operator` stays a warning** while consumers wait on it.
## Consequences
- No walk waits for the operator's secret, whichever module owes it.
- **The blind spot accepted.** While a wait covers a consumer's provision, a build of the consumer that breaks its
own use of that provision passes its gate; the fault is said once the operator gives what is owed, as the
consumer's own `unhealthy`, and a newer build or a person's push is the way — what ADR 0283 accepts for the
waiting module itself.
- **Dormant today.** No provider names a part after a provision: the mounts module says "the source …" and provides
nothing. The hold acts once a provider follows the convention of decision 1.
- A provider whose wait fails the controller's check is unhealthy and holds as ADR 0240 rule 5 says; whether its
consumers are then listed at its condition is issue 450.
## How it is checked
| Rule | Checked by |
|---|---|
| 1, 2, 3 | mesh-controller `TestAProviderWaitingForTheOperatorHoldsOnlyTheConsumersOfTheWaitingPart`: held by part and by shared credential; not held for another part or when the waits are not known; an unhealthy provider holds; a healthy one does not |
| 3 | `TestAConsumerOfAnotherPartIsRaisedOnItsOwn`: the consumer's own condition, its evidence saying the provider waits |
| 4 | `TestAConsumersGateUnderAWaitingProviderPassesCarryingTheWait`: a wait for a person carrying the wait; waiting under an unhealthy provider |
| 2, 5 | `TestAWaitingProvidersConditionListsWhoWaitsOnItAndStaysAWarning`: one condition, at the provider, listing the consumer, a warning; and `TestAConsumerHeldOnceItsProviderWaitsSaysWhichItIs` |
## References
- Issue 405; mesh-controller #216; issue 450.
- [ADR 0240](0240-a-module-says-how-it-is-healthy-and-the-node-engine-judges-it.md) rule 5,
[ADR 0283](0283-a-part-that-waits-for-the-operators-secret-or-setting-is-said-as-waiting-passes-the-first-node-gate-and-names-the-act.md)
option 4 and decisions 1, 4 and 5, [ADR 0254](0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md),
[ADR 0158](0158-a-provider-with-one-credential-shares-it-with-every-consumer.md).
@@ -2,8 +2,9 @@
layer: to-be
status: in-progress
code: [mesh-host, mesh-controller, mesh-lab, mesh-catalog, mesh-sdk]
updated: 2026-10-10
updated: 2026-10-11
decisions:
- 02-DECISIONS/0292-a-consumer-of-the-part-a-provider-waits-on-is-held-under-the-wait-and-passes-its-gate-as-a-wait-for-a-person.md
- 02-DECISIONS/0283-a-part-that-waits-for-the-operators-secret-or-setting-is-said-as-waiting-passes-the-first-node-gate-and-names-the-act.md
- 02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md
- 02-DECISIONS/0240-a-module-says-how-it-is-healthy-and-the-node-engine-judges-it.md
@@ -218,6 +219,20 @@ condition is open:
P healthy again ─► held findings released: a consumer still failing is now its own
```
**A provider that only waits for the operator holds the consumers of the part it waits for**
([ADR 0292](../../02-DECISIONS/0292-a-consumer-of-the-part-a-provider-waits-on-is-held-under-the-wait-and-passes-its-gate-as-a-wait-for-a-person.md),
issue 405). A wait covers a provision when its `part` is that provision's name, or when the secret it waits for is
the provision's shared credential:
```
provider P waits ─► module.P.<machine>.needs-operator (a warning, whoever waits on it)
evidence: waiting on it — consumer A
consumer A failing, ─► no condition of its own; its gate passes as a wait for a person,
its provision covered carrying P's wait
consumer B failing, ─► module.B.<machine>.unhealthy, saying P waits, but not for anything B
no wait covers it is known to need
```
What a consumer finds while its provider is healthy, or by a check that names no provision, is its own.
A machine-level condition is never pinned on a module
([issue 281](../../04-ISSUES/281-a-tier-sent-one-module-at-a-time-blamed-a-module-for-its-machine/00-report.md)).