Merge pull request 'Issues 292-293: a drill counted as a repair; a warning on a required check blocked the merge' (#165) from issues/292-293-a-drill-and-a-warning into main
This commit was merged in pull request #165.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 <what> --why <what it tests> [--condition <key>]`, 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`.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user