Files
stack/agents/dewey/work/queue-83/build.md
T
jason.woltjeandClaude Opus 5.5 e1bf582a1a dewey: row 83 round 1 packet, unit script takes --send (#1576)
build.patch against d13b9300 (brief blob f8d14d70, rev 630), candidate
manifest, identity and mutant harnesses with results, gate summary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 22:59:05 -05:00

213 lines
11 KiB
Markdown

# Row 83 (#1576): Console service, the unit script takes --send, round 1
Owner: Dewey. Reviewers: Darkwing and Filbert, then Sage's gate. Brief:
`docs/plans/2026-10-12_console-service-send.md` § "The unit script takes
--send", blob `f8d14d70` (re-pinned at rev 630 for lead decision 102; first
pinned as `739bea66` at rev 627, briefed at rev 628). Lead decision 101
gives the reason. Base `d13b9300`. None of the candidate's paths, nor the
template, changed between `d13b9300` and `refactor` HEAD (`a1c5c8fc`) when
the packet was built.
`build.patch` is `git diff --cached --binary d13b9300 --` the four paths
below. Apply it with `git apply --index` to a detached worktree of the base;
`candidate-manifest.sha256` then checks 4/4 OK (checked on a fresh
worktree).
## What ships
- `render` and `install` take `--send`, a flag with no value. It is
accepted only with all three preview flags. Otherwise `serve_flags`
refuses before anything is written: exit 1, empty stdout, and on stderr
`webui-service: --send needs the preview mode (--public-host,
--auth-header and --allow-user)`, serve's own wording (cli.mjs:37).
`install` renders before `mkdir`, so a refusal creates no directory and
leaves an installed unit alone (tested).
- With `--send`, ExecStart ends `... --allow-user ID --send`. Nothing else
in the unit changes (tested line by line against the same render without
`--send`).
- Without `--send`, every render is the template with its four
placeholders filled, byte for byte (new test), and the base and
candidate scripts give the same stdout, stderr, status and installed
files on every argument list the base tests use (`identity.txt`).
- `uninstall` and `status` take no `--send`: it sets SERVE_SET like the
other serve flags, so both exit 4 (tested with a stand-in systemctl).
- `status` prints one new line when a unit is installed: `send: on
(--send; human messages to roles)` or `send: off (read-only)`. The brief
allowed this "if small"; it is five lines plus a comment. With no unit
installed there is no send line.
- `USAGE` and the header comment name `[--send]` inside the preview set.
README's service paragraph and TOOLS.md's "Console service" section say
the script takes `--send` only with the preview set (exit 1, nothing
written), that ExecStart then ends with `--send`, and that the Console
needs the system config at start (`--send needs the bus configured`,
exit 2, which the unit doesn't restart: `RestartPreventExitStatus=2` in
the template). README's "Message a role" `--send` paragraph gets one
sentence pointing at `scripts/webui-service.sh install` with `--send`.
- The start wording (lead decision 102). The script's header comment, its
install message, TOOLS.md's "Console service" and README's service
paragraph now say Jason starts and restarts the Console, and so may Mos
under decision 102, which accepts that sends from a Console Mos started
enter the trail as Jason (`human-cli`). Any other agent starting it,
even through systemd, still works around the human proof (decisions 62
and 94). The script still has no start, stop or restart verb. A test
checks the install message's wording.
The template (`packages/webui/systemd/mosaic-webui.service.in`) is
unchanged. `install` prints no new line; its `serve:` line already shows
the ExecStart, `--send` included. The install message's opening sentence
changed wording only (decision 102).
## Decisions and tradeoffs
- **Refusal order.** The `--send` check runs before the all-three check.
`--send` with one or two preview flags therefore gets the `--send`
message, not "all three or none". The brief asks for a message naming
the preview flags the way serve refuses, and serve checks the preview
set first. Both messages name the three flags. A partial preview set
without `--send` still gets "all three or none" (base test unchanged).
- **Status detection is anchored on the allowed user.** My first version
matched `^ExecStart=.* --send$`. The mutant `status-send-anywhere`
survived it, and that showed a real gap: `--allow-user` accepts the value
`--send` (its character set allows `-`, and serve's `USER` pattern
accepts it), so a read-only unit's ExecStart can end
`--allow-user --send`. The check is now
`^ExecStart=.* --allow-user [^ ][^ ]* --send$`. render always puts
`--send` right after the allowed user, so a sending unit ends with both
the allowed user and `--send`. A test installs both cases, read-only
`--allow-user --send` and sending `--allow-user --send --send`, and
checks status for each.
- **No config or bus check in the script** (out of scope per the brief).
A unit installed with `--send` on a host without the system config
installs fine and exits 2 at start; the docs say so.
## Files
- `scripts/webui-service.sh`: `SEND=0`, the `--send` case, the refusal
and the append in `serve_flags`, the status line, USAGE and header.
- `packages/webui/tests/service.test.mjs`: 5 new tests, 2 widened.
- `packages/webui/README.md`: the service paragraph, one sentence in
"Message a role".
- `docs/TOOLS.md`: the "Console service" FLAGS comment and prose.
## Tests
`packages/webui/tests/service.test.mjs`, 15 tests (10 base, 5 new). The
helper `filled(flags)` is the template with `@REPO@`, `@PATH@`, `@NODE@`
and `@FLAGS@` replaced, computed in the test the way the base script does
it.
- *without --send, render is the template with its placeholders filled,
byte for byte*: five flag combinations, from none to every flag.
- *render --send with the preview set ends ExecStart with --send and
changes nothing else*: four argument orders (`--send` first, last, in the
middle of the preview set, with `--port` and `--business`). Each equals
`filled(flags + ' --send')`, and against the same render without
`--send` exactly one line differs, the ExecStart, by ` --send`.
- *--send without the whole preview set is refused and writes nothing*:
`--send` alone, with `--port`, with `--business`, with each one of the
three preview flags, and with each two of the three. Each `render` gives
exit 1, empty stdout and serve's message. Each `install` into a fresh
`--dir` gives the same, and the directory is never created. An install
of `--send` with two preview flags over an installed unit leaves it byte
for byte, with no temp file and no systemctl call.
- *install --send into --dir with --no-reload writes the sending unit, and
status says whether it sends*: `written:`, the `serve:` line ending
`--send`, the file equal to `filled(...)`, mode 0644, no temp file;
status `send: on`; reinstall `unchanged:`; install without `--send`
writes the read-only unit and status says `send: off (read-only)`; the
odd allowed user `--send` case above; no `send:` line without a unit.
The only systemctl calls are status's reads. Status's `/healthz` goes to
a loopback port that was just closed, so it reaches no real Console.
- *uninstall and status take no --send*: exit 4 for `uninstall --send`
(with and without `--no-reload`) and `status --send`, against a stand-in
systemctl that records no call; the unit stays installed.
- Widened: the agent-marker test also renders `[...PREVIEW, '--send']`;
the usage test adds `render --send yes ...PREVIEW` (`--send` takes no
value); the install test checks the decision 102 start wording in the
install message.
Why the uninstall and status cases sit in their own test: in the usage
loop they run with the real `/usr/bin/systemctl` on PATH. A mutant where
`--send` doesn't set SERVE_SET would let `uninstall --send` reach a real
`systemctl --user daemon-reload`. With the stand-in, no mutant can.
## Byte identity (`identity.mjs`, `identity.txt`)
One scratch worktree of `d13b9300` holds the base script as
`scripts/webui-service-base.sh` and the candidate as
`scripts/webui-service.sh`, so REPO and the template are the same for
both. Each script runs the same 86 argument lists from a clean scratch:
every render the base tests make (the value and port refusals included),
the usage list, `--help`, and an install, reinstall, refused install,
install over, status, uninstall, uninstall and status sequence, all with
`--no-reload` and a stand-in systemctl.
Result: 69 identical, 17 expected differences, 0 unexpected. The 17 are
the usage text on 12 exit-4 cases plus `--help` (the FLAGS line names
`[--send]`), three installs whose message differs only in the decision 102
start wording (the base message's opening lines replaced by the
candidate's, then everything else identical, installed unit included),
and one status with a unit installed (the added `send: off (read-only)`
line, nothing else). A self-check: with the append made
unconditional, the same run reports 13 unexpected differences.
## Mutants (`mutants.py`, `mutants.txt`)
15 single-site mutants of `scripts/webui-service.sh`, each run against the
base tests (`d13b9300`'s `service.test.mjs`), the candidate tests and
`identity.mjs`. Baselines: all three pass on the unmutated candidate.
Rerun on the decision 102 candidate, 2026-10-12T03:53Z; same results as
the first run.
| mutant | base tests | candidate tests |
|---|---|---|
| send-no-preview-check | survived | killed |
| send-needs-any-preview | survived | killed |
| send-message-reworded | survived | killed |
| send-no-append | survived | killed |
| send-append-always | killed | killed |
| send-append-before-preview | survived | killed |
| send-default-on | killed | killed |
| send-no-serve-set | survived | killed |
| send-takes-value | survived | killed |
| send-flag-unknown | survived | killed |
| status-send-always-off | survived | killed |
| status-send-always-on | survived | killed |
| status-no-send-line | survived | killed |
| status-send-anywhere | survived | killed |
| status-send-suffix-only | survived | killed |
The candidate tests kill 15 of 15. The two the brief names,
`send-no-preview-check` and `send-no-append`, survive the base tests.
`send-append-always` and `send-default-on` are killed by the base tests
too, as a change to every render should be.
## Gate (my run on the candidate)
On the staged candidate in a worktree of `d13b9300`, run sequentially,
2026-10-12T03:54:20Z to 03:58:42Z (`gate-summary.txt`):
- `packages/webui`, `node --test 'tests/*.test.mjs'`: 81 tests, 81 pass,
rc=0.
- `scripts/test-auth.sh`, `test-conductor.sh`, `test-config.sh`,
`test-discord.sh`, `test-extension-package.sh`, `test-foundation.sh`,
`test-queue.sh`, `test-release.sh`, `test-task.sh`: all rc=0.
## For reviewers
- **Allowed user starting with `-`.** The base script and serve both accept
an allowed user like `--send` or `-x`. That isn't new here, and changing
it would change no-`--send` renders, which the brief rules out. The only
effect on this row was status detection, now anchored. If it should be
refused, that's a follow-up for the script and serve together.
- **The template's comment still says Jason starts it.**
`mosaic-webui.service.in` lines 6-9 say Jason starts it from a personal
shell and that an agent starting it works around the human proof. The
template isn't in this row's files and is rendered into every unit, so
changing it would break the byte identity the brief asks for. Bringing
it in line with decision 102 is a follow-up (a template change plus the
render tests that pin it).
- Nothing here starts, enables or restarts a unit, and no test reaches the
real systemd: every install and uninstall uses `--no-reload` or a
stand-in systemctl.