Merge pull request 'Say that a condition's looks are kept beside the bucket, not in it (issue 420)' (#321) from fix/420-condition-looks-beside-the-bucket into main

This commit was merged in pull request #321.
This commit is contained in:
2026-10-12 10:43:27 +00:00
@@ -81,7 +81,7 @@ Every kind of state the core keeps, and the one component that writes it. Anyone
| a machine's applied state and its report | the node-engine's apply queue (§6) | the machine; the report on the bus | the reconcile and a delivery *enqueue*, never apply |
| the controller lease | the controller instance holding it | key-value `mesh-controller_lease` | a candidate waits |
| plans and their tiers | controller (lease holder), compare-and-set on the plan's revision | the controller's store | read through `plans` |
| conditions | controller | key-value `mesh-controller_conditions`, and their history `mesh-controller_condition-history` | raise or clear only through observations the controller reads |
| conditions | controller | key-value `mesh-controller_conditions`, and their history `mesh-controller_condition-history`; each open condition's looks (how often observed, when last, its newest evidence) in the controller's store ([issue 420](#the-looks-of-a-condition)) | raise or clear only through observations the controller reads |
| calls and their outcomes | controller | key-value `mesh-controller_calls` | read by id |
| the hand-act log | controller, through the verbs that act | key-value `mesh-controller_hand-acts` | — |
| the healers' acts and their brake | controller (lease holder), each act begun before it is made | the controller's store | read through `healers`; each act said as `healer-acted` and in its condition's `tried` |
@@ -144,14 +144,29 @@ cleared on the first that does not. Designed in [to-be 48](48-a-module-says-how-
| summary | one line in the mesh's words, for whoever looks closer: it may name plans, commits and verbs |
| headline, needs, explanation, resolved | what the operator reads, in plain words (ADR 0253): a few words naming the thing and what is wrong; the one thing the operator can do themselves, or nothing; the explanation, opened by its verdict ("Nothing for you to do." or "Needs you:" and that thing); the line said when it clears |
| actions | the answers a notification offers, each a label and the seat verb the operator channel calls when it is chosen (ADR 0253); a desk click performs only an acknowledgement — Details, Silence for a week — until answers are authorised (ADR 0258) |
| evidence | the newest observations, at most ten, each with its time |
| evidence | the newest observations, at most ten, each with its time — a look, kept in the controller's store |
| source | the signals-table row, probe or event that raised it |
| raised, last observed | times; and how many observations since raised |
| raised, last observed | times; and how many observations since raised — the last observed and the count are looks, kept in the controller's store |
| tried | each healer attempt: when, what, outcome |
| resolver | `self` (clears on observation), `healer:<name>`, `operator`, or `agent` |
| silenced | until when, by whom, why — empty when not silenced |
| epoch | the controller lease epoch that last wrote it |
<a id="the-looks-of-a-condition"></a>
*Added 2026-10-12, issue 420, under ADR 0289 §1 and §4:*
**a condition's looks are kept beside the bucket, not in it.** The count of observations, the last observed
time and the evidence change on every look, so a value that carried them was rewritten every half minute
for a condition that had not changed, and a watcher of the bucket heard each look as a write. The bucket
holds what a condition says — kind, subject, severity, summary, the plain words and actions, source, raised,
count, tried, resolver, silenced, epoch — and is written when it is raised, when one of those changes, and
when it clears. Its looks are a row per open condition in the controller's store, written under the lease on
every look that brings something new and removed when it clears. The `conditions` verb and the three
condition events carry the whole condition, looks included, as before; where the looks could not be read,
the condition says so in `looks-unread` rather than a count of none. Checked by the controller's tests:
repeated looks at an unchanged condition write the bucket once (counted by the fake bucket, and on a real
bus by the bucket stream's sequence), the bucket's value holds none of the looks, and the verb run as a
process of its own reads them back from the store.
*Added 2026-10-08, ADR 0253:*
**a condition says itself to the operator in plain words, beside its summary, and says whether the operator
is needed.** The headline, needs, explanation, resolved line and actions are made where the condition is