diff --git a/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md b/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md index 8e938154..5416f5a7 100644 --- a/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md +++ b/03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md @@ -419,6 +419,11 @@ not list. The table's test finds every verb the controller records and fails on A `healer-wanted` already open for a decision clears on the next watchdog tick, as any condition its row no longer sees. +**A drill is no repair.** Something broken on purpose to see the mesh raise and clear it is recorded by +`hand-act drill` (the seat's `drill`), cause `drill`, which the table lists as a person's decision; +`hand-act record` refuses that cause, so a repair cannot pass for a drill by the word it gives (issue +292; checked by the controller's S15 tests). + > **Progressive insight — 2026-10-06.** This paragraph said before: "except `retire-waiting` and > `cleanup-waiting`: approving a retirement and deleting what was retired are a person's decision by > design (ADR 0230), and no healer may take them over." The exception was keyed on two causes, and the @@ -531,7 +536,11 @@ A changed file touches exactly the modules whose build reads it; a file no build change reaching a module, or adding one, runs **the gate** on the build seat (`mesh/merge-gate`): the touched manifests through `module check`, failing only what the change brings; every machine composed with the definitions of the modules the plan moves or adds; the replays. Every repository of the mesh runs **its -own** `merge-check.sh` (`mesh/repo-check`) in the toolchain it declares, a warning when it has none. The +own** `merge-check.sh` (`mesh/repo-check`) in the toolchain it declares; one with none has "no repository +check defined", a success where the branch does not require `mesh/repo-check` and a failure for a person +where it does. **A note is never a warning on a required status**: the forge combines `warning` as a +failure, so a note — a wide rebuild, a problem already so on the base — is a success that says it, and only +what a person must decide fails (issue 293; checked by the forge module's status tests). The check's result is the commit's **change plan** — the build plan, the deploy plan machine by machine with what is not an ordinary send, and the verdict — posted on the pull request. The plan is one object with a state machine, kept, followed by the release and written to the commit as a note; which parts are built diff --git a/04-ISSUES/292-a-drill-was-counted-as-a-repair/00-report.md b/04-ISSUES/292-a-drill-was-counted-as-a-repair/00-report.md new file mode 100644 index 00000000..2f31be03 --- /dev/null +++ b/04-ISSUES/292-a-drill-was-counted-as-a-repair/00-report.md @@ -0,0 +1,52 @@ +--- +status: located +opened: 2026-10-07 +located-in: [mesh-controller cmd/mesh-controller (handacts.go, signals.go S15)] +fixed-by: mesh-controller PR #109 +amended-design: 03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md +--- + +# 292. A drill was counted as a repair + +## Symptom + +On 2026-10-07 S15 raised `mesh.hand-acts.drill.healer-wanted`. Its summary said that "drill" was +repaired by hand 2 times in 14 days, and that a healer is wanted for it. Both acts in the hand-act log +were deliberate drills of ADR 0240's module health check: a module stopped on purpose, then a module made +to crash on purpose. Each had operator approval. Both were recorded with `hand-act record --cause drill`, +because no verb existed for a drill. + +## Diagnosis + +S15 decides whether an act is a repair or a person's decision from **the verb that recorded it** +(to-be 45 §7, progressive insight of 2026-10-06), never from the cause word. `hand-act record` is the +verb for an act done outside the mesh. The mesh cannot tell a repair from a decision there, so every act +it records counts. A drill had no verb of its own, so it could only be recorded as a repair. + +Keying the exemption on the cause `drill` was ruled out. Any repair could then avoid S15 by giving that +word. + +## Fix + +- A drill gets its own verb: `hand-act drill --why [--condition ]`, which is + the controller seat's `drill`. It records the cause `drill`, and the controller's table of verbs lists + it as a person's decision. S15 never counts it, however often a drill is run. +- `hand-act record` now refuses the cause `drill` and names the drill verb. Once that refusal exists, the + only acts that `hand-act record` holds with that cause are the ones recorded before the drill verb. The + table exempts exactly those, so the open condition clears on the next tick. Any other verb that gives + `drill` as its cause still counts. + +## How it is checked + +mesh-controller tests: + +- `TestADrillIsNoRepairAndItsHealerWantedClears` covers three cases. Repeated drills want no healer. The + cause word on another verb still counts. And the condition opened by the two acts of 2026-10-07 clears + on the next tick. +- `TestADrillIsRecordedThroughItsOwnVerb` checks that `hand-act record` refuses the cause `drill`, and it + checks the seat verb's command line. +- `TestEveryVerbThatRecordsAHandActIsInTheTable` fails on any verb that writes the log and is missing + from the table. + +Live: once the build is rolled out, `mesh.hand-acts.drill.healer-wanted` closes within a watchdog tick. +Later drills are recorded with `mesh-controller.drill`. diff --git a/04-ISSUES/293-a-warning-on-a-required-check-blocked-the-merge/00-report.md b/04-ISSUES/293-a-warning-on-a-required-check-blocked-the-merge/00-report.md new file mode 100644 index 00000000..ac23a508 --- /dev/null +++ b/04-ISSUES/293-a-warning-on-a-required-check-blocked-the-merge/00-report.md @@ -0,0 +1,59 @@ +--- +status: located +opened: 2026-10-07 +located-in: [mesh-catalog modules/gitea (pulls.ts, delivery.ts, index.ts)] +fixed-by: mesh-catalog PR #102 +amended-design: 03-DESIGN/01-to-be/45-a-core-that-cannot-fail-silently.md +--- + +# 293. A warning on a required check blocked the merge + +## Symptom + +On 2026-10-07 branch protection began to require `mesh/merge-gate` on every repository of the mesh, and +`mesh/repo-check` on the core repositories as well. Administrators may not override either. On a pull +request whose statuses were success, warning and success, the forge's combined status was **failure**. +The forge treats `warning` as failing. So a required check that reported `warning` would block a merge +that nobody had decided to block. + +## Diagnosis + +The controller and the build seat give the merge check a verdict of `pass`, `warning`, `fail` or +`error`. The forge module turned each verdict into a forge state of the same name, `warning` included. +The controller says `warning` in four cases, and each one is a note, not a question for a person: + +- the gate warns that a merge rebuilds a wide set of modules; +- the gate warns that the module check's problems were already present on the base branch; +- a repository's own `merge-check.sh` reports a warning; +- a repository has no `merge-check.sh` at all. + +Separately, the forge module's status tool would set any `mesh/…` context, including both of the merge +check's. + +The design said "a warning when it has none" for the repository check (to-be 45 §9, ADR 0237 as +narrowed by 0238). That was written before a required status could be anything but advisory. + +## Fix + +**A required status is success, or it blocks for a reason a person must act on.** The forge module now +maps verdicts like this: + +- **A note** becomes `success`, and its description starts with "pass, with a note:". +- **A repository without a `merge-check.sh`, where the base branch does not require + `mesh/repo-check`,** becomes `success`, described as "no repository check defined". +- **A repository without a `merge-check.sh`, where `mesh/repo-check` is required (or the protection + cannot be read),** becomes `failure`. The description says that a person adds a check or lifts the + requirement. +- **`fail`** becomes `failure`. +- **`error`** becomes `error`, never a success. + +The status tool now refuses both merge-check contexts: they are set by a verdict only. + +## How it is checked + +The forge module's `test/pulls.test.ts` runs every combination of verdict and repository-check facts. +It asserts that none sets `warning`, and that each case above lands where this report says. +`test/delivery.test.ts` asserts that the status tool refuses the merge-check contexts. + +Live: the next pull request whose gate notes a wide rebuild shows `mesh/merge-gate` as success, and its +combined status is success.