Files

118 lines
7.1 KiB
Diff

diff --git a/docs/plans/DEFERRED.md b/docs/plans/DEFERRED.md
index 197a29ecb..4c0c736f1 100644
--- a/docs/plans/DEFERRED.md
+++ b/docs/plans/DEFERRED.md
@@ -319,6 +319,10 @@ at every gate. Started 2026-09-12 during the control board MVP.
waits 30 s before it calls a lone `sleep 30` a leak. The row 197
lanes scan only at lane end, about 15 minutes after pkg-bus, so they
can't see it (mos-1169). (2026-10-21)
+ Closing note, row 280 (2026-10-22): both scratch sshd fixtures install a
+ bounded 30/60-second sleep stub that exits when its test directory is gone;
+ other sleep arguments exec /usr/bin/sleep unchanged. Evidence is recorded
+ in agents/rocko/work/queue-280/BUILD.md.
- **Row 66 live checks: the unslop notice on a live managed session, both harnesses.**
(mos-1186, Vikunja #454.) Row 66's gate asked for one landing session per
@@ -380,6 +384,81 @@ at every gate. Started 2026-09-12 during the control board MVP.
credential and a real `release.sh activate`, and records both results on
the re-pin row. Morgana's wording (row 244 BUILD.md), Webby N2 on row 244
r1 (#1757). (2026-10-21)
+- **Creative instances: the human can't delete one.** (Sage's ruling
+ sage-2164 on the row 194 b4 rebase, #1692.) Row 213 put the creative
+ definitions in END_PROTECTED, and row 194's `deleteRefusal`
+ (`instance-settings.mjs`) refuses END_PROTECTED for every actor, so
+ the human can't delete a companion instance and fire refuses one too.
+ The Agents page hides Delete on the listing's `endProtected`. The fix
+ threads the actor through `deleteRefusal` and the launcher's delete
+ pass, so the human may delete one and the tester may not
+ (`creativeHumanOnly`). Until then, the human can delist
+ (instances.set launch: false) but neither fire nor delete removes a
+ creative entry (sage-2166). The row covers fire and delete together;
+ Sage files it. (2026-10-21)
+ Closed for delete by row 256 (#1761, REQ-COS-3): `deleteRefusal` takes
+ the actor, so the human deletes a creative instance and any other actor
+ is refused `organization-creative-human-only`, and the listing's
+ endProtected is the same check for its reader. Fire still refuses every
+ END_PROTECTED instance, by the row 256 brief's ruling, not by a code
+ change. (2026-10-22)
+- **A fire stuck between step A and step B has no human escape.** (Webby
+ N4 on row 194 b5, webby-0094; Sage's ruling sage-2241, #1692.) The
+ broker's chief fire records `fire.stopped` at step A, and `#firing`
+ refuses every launch and take of the instance until a `fire.done`. The
+ events are in the store, so a bus restart doesn't clear them. Row 194
+ b6 runs the writer's checks against the file before step A
+ (`instance.fireCheck`), so a keep the bus hasn't loaded no longer
+ strands an instance. A step B that keeps refusing still does: a
+ credential revoke that fails every time, or a file a human changed
+ between the check and the write. Each repeat fire runs step A again
+ and refuses at B. The fix is a human verb, never an agent one, that
+ records the end of the firing (a `fire.done`, or a new
+ `fire.abandoned` that `#firing` also counts) with a reason. Its test:
+ a fire whose step B refuses leaves the instance `instance-firing`, the
+ verb as the chief or the tester refuses, and the verb as the human
+ clears it so the instance launches again. (2026-10-21)
+- **A fire's done with more than 64 stops refuses, and nothing flags a
+ run left alive.** (Webby N2 on row 194 b8 r2, webby-0100; Sage's ruling
+ sage-2290, #1692.) `lifecycleDone` caps `stops` at 64 and refuses
+ `invalid-request` above it (`broker.mjs`). The launcher's fireStop has
+ already signalled every run through stopRun by then, so the killed runs
+ are dead. But the refused done writes no lifecycle.end.killed or
+ lifecycle.end.alive event and no lifecycle.done, and the end request
+ stays taken. A run the stop left alive, or couldn't confirm (unknown),
+ gets no Console flag. The fire itself is unaffected, because
+ `fire.stopped` and `fire.done` are written at the verb. No MVP instance
+ comes near 64 runs. The follow-up row either raises the cap or splits
+ the done. Its test: a fire's done over the cap refuses, and the runs it
+ left alive still get the alive flag. (2026-10-22)
+- **A fired or deleted instance keeps its grants.** (Dewey on the row 236
+ rebase look, dewey-0815; Mos mos-1271; Sage sage-2558.) Row 194's
+ `instance.fire` and row 256's delete revoke only the roles entry's
+ credential services through `revoke()` in `runtime.mjs`. The agent's
+ host grants (row 235) and its Gitea user and token (row 236) stay live
+ until a human runs `mosaic hosts revoke` or `mosaic grants revoke`. The
+ Console has no revoke route and doesn't say a grant is left. Row 281
+ (#1786) closes it: a fire or a delete revokes every host and Gitea grant
+ the instance holds, fail closed, with a test for each kind. It lands
+ before the .53 Case 1 install hires an instance with a grant.
+ (2026-10-22)
+
+- **The runs suite doesn't gate a change to `scripts/mosaic-task.mjs`.**
+ (Dewey N7 on row 191, repeated on the Vikunja 502 review.)
+ `packages/runs/tests/task-cli.test.mjs` spawns `scripts/mosaic-task.mjs`,
+ but row 191's gate didn't run the runs suite. test-task.sh covers the same
+ list and show paths, so nothing is known broken. Binds the next row that
+ changes `scripts/mosaic-task.mjs`: its gate runs the runs suite whole.
+ (2026-10-22)
+
+- **Row 277's M8 is killed by a rethrown error, not an assertion.**
+ (Duckworth N1 on the row 277 manifest round, duckworth-0127.) M8 makes
+ the thread.claims catch in `packages/cli/src/cli.mjs` rethrow. The stubbed
+ `processing-halted` error then escapes `main` and fails
+ `packages/cli/tests/tester.test.mjs:149`. That counts as a kill, but no
+ test pins that `main` resolves on that path. Binds the next row that
+ changes `packages/cli/tests/tester.test.mjs`: add the resolve pin so M8
+ dies on an assertion. (2026-10-22)
## Queue
diff --git a/packages/webui/README.md b/packages/webui/README.md
index 74d438c71..59cb4ee3a 100644
--- a/packages/webui/README.md
+++ b/packages/webui/README.md
@@ -382,6 +382,15 @@ there are others. The page says what each state means. It writes nothing;
the server passes the rows through unchanged. How the bus derives the state
and its limits: `packages/bus/README.md`, "Agent state".
+The same view has a separate **Thread claims** section (row 278, #1783).
+It reads `thread.claims` and shows thread id, holder run, harness and claim time,
+in the bus's order. Thread names, messages, instance and address are not shown.
+An empty read has an empty-state line. A refused or failed read clears only
+this section's kept claims and shows its reason; the held roles and their
+count stay intact. Sign-out clears the claims with the other bus reads.
+The read needs no `--send`. The bus permits human and reader sessions;
+the tester listener refuses it with HTTP 403 `tester-refused` before any bus call.
+
## Board: held roles and signing out (row 95, #1589)
The Board (`#/`) opens with **Held roles**: each role a run holds on the