Decision 94 records Q94 yes and Mos's sage-0054/0055 directions: no broker row (the Console already reads as the human), Jason starts the Console, nine rows deferred, S7's line amended, Gate E partial pass on the dogfood day, no rollback hostname. New brief for the Console service row and the send-to-a-role row. Row 74's start line and S7's request line amended. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1999,3 +1999,48 @@ which stay with him. Each item names who decided it and what happened.
|
|||||||
likely X-authentik-uid. The Console check stays generic (one header
|
likely X-authentik-uid. The Console check stays generic (one header
|
||||||
name, one user id, from flags). Jason's Q93, on the Authentik token,
|
name, one user id, from flags). Jason's Q93, on the Authentik token,
|
||||||
gates ops-01's application, not the Console's landing or install.
|
gates ops-01's application, not the Console's landing or install.
|
||||||
|
|
||||||
|
94. **Dogfood on mosaic.woltje.com within 24 hours; Jason starts the
|
||||||
|
Console (2026-10-11).** Jason, relayed by Mos (sage-0053): "I want the
|
||||||
|
system online and us able to dogfood in the next 24 hours." Q94, his
|
||||||
|
yes to Sage's reading (sage-0055): "Yes, but the old build didn't work
|
||||||
|
anyway. Rollback is likely not a desirable action." Mos's directions
|
||||||
|
are in sage-0054 and sage-0055.
|
||||||
|
- The Console already reads the bus as the human. Its bus reads run
|
||||||
|
the human transport (`packages/webui/src/bus.mjs`, `humanCall`), so
|
||||||
|
the broker binds a human capability after `verifyHuman`, and only
|
||||||
|
Console code limits it to the reads in `packages/bus/src/views.mjs`.
|
||||||
|
A send from the browser needs a Console route, not new broker
|
||||||
|
authority. The broker row Sage proposed in the sage-0053 reply (row
|
||||||
|
A) is dropped. Q95, web write authority, is a ruling on that route.
|
||||||
|
- The process that starts the Console holds human authority. An agent
|
||||||
|
that starts it through `systemd-run` or a user unit gets a clean
|
||||||
|
environment and an ancestry the proof accepts: the detachment gap
|
||||||
|
decision 62 names, which T3 seats must not use. So Jason starts the
|
||||||
|
Console himself, the 03:00Z read-only fallback included. This
|
||||||
|
replaces decision 93's "Sage starts the preview"; the row 74 brief
|
||||||
|
says so (amended line, re-pinned). Agents may install and render the
|
||||||
|
unit and read its status, never start, stop or restart it.
|
||||||
|
- New rows, brief `docs/plans/2026-10-11_dogfood-cutover.md`: the
|
||||||
|
Console user service (owner Rocko, reviewer Filbert), which starts
|
||||||
|
now ahead of rows 72 and 73; and a human message to a role from the
|
||||||
|
Console (owner Dewey after row 74, reviewers Darkwing and Filbert),
|
||||||
|
blocked on Q95.
|
||||||
|
- Deferred until after cutover, each moved to blocked with that
|
||||||
|
reason: rows 49, 61, 63, 64, 65, 66, 69, 70 and 71. Rows 58, 59, 60,
|
||||||
|
67, 72 and 73 continue around the cutover reviews.
|
||||||
|
- S7 (row 42): Jason's five requests may come from the WebUI or the
|
||||||
|
CLI; the brief's one line is amended and re-pinned. S7 runs with
|
||||||
|
the cutover, and his first five requests to the PM are its pieces.
|
||||||
|
- Gate E (row 5): the dogfood day is its demonstration for the scope
|
||||||
|
that exists, the managed PM on the bus. Jason's ruling on that day
|
||||||
|
records a partial pass. The all-seat part stays open and row 5
|
||||||
|
stays waiting on Jason; it isn't called passed.
|
||||||
|
- No rollback hostname. The old build isn't a rollback target, so
|
||||||
|
ops-01 builds no rollback name or flip-back. Its data is kept until
|
||||||
|
Jason rules on deleting it. The live cutover still needs his
|
||||||
|
approval at the time.
|
||||||
|
- The tradeoff: no agent can restart the Console. After a crash the
|
||||||
|
unit's `Restart=on-failure` brings it back; after a reboot, or a
|
||||||
|
logout without linger, it waits for Jason. Deferring nine rows
|
||||||
|
pushes the skills, routing and hygiene work back by about two days.
|
||||||
|
|||||||
@@ -596,8 +596,8 @@ The PRD's acceptance can only be shown end to end.
|
|||||||
|
|
||||||
### What ships
|
### What ships
|
||||||
|
|
||||||
Five one-sentence requests from Jason in the CLI, each carried to a
|
Five one-sentence requests from Jason, sent from the WebUI or the CLI
|
||||||
closed, reviewed task. For each: the trail in `mosaic trail` and the
|
(lead decision 94), each carried to a closed, reviewed task. For each: the trail in `mosaic trail` and the
|
||||||
WebUI, the decisions that reached Jason (gated only), and the event
|
WebUI, the decisions that reached Jason (gated only), and the event
|
||||||
counts from the bus. Those counts are the first measures (REQ-EVT-1).
|
counts from the bus. Those counts are the first measures (REQ-EVT-1).
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# Dogfood cutover: the Console as a service, then sending to a role (2026-10-11)
|
||||||
|
|
||||||
|
Status: written by Sage, lead. It follows `docs/plans/BRIEF-TEMPLATE.md`.
|
||||||
|
Two rows, from Mos's sage-0054 (lead decision 94). The service row starts
|
||||||
|
now. The send row is briefed only; it starts after Jason answers Q95
|
||||||
|
(web write authority), and is amended first if his answer narrows it.
|
||||||
|
Q94, the cutover reading, is answered yes.
|
||||||
|
|
||||||
|
What the code already does, and why there is no broker row. The Console
|
||||||
|
reads the bus as the human. `packages/webui/src/bus.mjs` runs the S4
|
||||||
|
human transport (`packages/bus/src/human-cli.mjs`) as a child, so the
|
||||||
|
broker binds a human capability (`bindHuman`, `via: 'cli'`) after
|
||||||
|
`verifyHuman` checks the process and its ancestry
|
||||||
|
(`packages/bus/src/human.mjs`). The Console limits itself to the read
|
||||||
|
verbs in `packages/bus/src/views.mjs`; the broker doesn't. So a send from
|
||||||
|
the browser needs no new broker authority, only a Console route, and the
|
||||||
|
Q95 ruling is about that route. It also means the process that starts
|
||||||
|
the Console decides whether it holds human authority. A Console started
|
||||||
|
from an agent's shell, detached through systemd, passes the ancestry
|
||||||
|
check: the gap lead decision 62 names. So Jason starts it himself.
|
||||||
|
|
||||||
|
## Console as a user service
|
||||||
|
|
||||||
|
### Problem
|
||||||
|
|
||||||
|
Row 74 cut the service script to make the 10-12 date. Daily use can't run
|
||||||
|
on a transient unit, which a reboot or a logout without linger ends and
|
||||||
|
nobody reviewed as a file. The bus has `scripts/bus-service.sh`; the
|
||||||
|
Console has nothing.
|
||||||
|
|
||||||
|
### Owner and reviewer
|
||||||
|
|
||||||
|
Owner: Rocko. Reviewer: Filbert. Rocko has no Gitea token; Sage runs the
|
||||||
|
review request as jarvis.
|
||||||
|
|
||||||
|
### Files owned
|
||||||
|
|
||||||
|
- `scripts/webui-service.sh` (new)
|
||||||
|
- `packages/webui/systemd/mosaic-webui.service.in` (new)
|
||||||
|
- `packages/webui/tests/service.test.mjs` (new)
|
||||||
|
- `docs/TOOLS.md`, the new script's entry only (row 70, the other row
|
||||||
|
editing it, is deferred)
|
||||||
|
- `agents/rocko/work/queue-<row>/`
|
||||||
|
|
||||||
|
Not `packages/webui/README.md` or any `src/` file: row 74 owns them. The
|
||||||
|
README pointer to the script is a line Sage adds after both rows land.
|
||||||
|
|
||||||
|
### What ships
|
||||||
|
|
||||||
|
- `scripts/webui-service.sh render|install|uninstall|status` on the
|
||||||
|
`bus-service.sh` pattern and exit codes (0 ok, 1 failed, 4 usage):
|
||||||
|
`render` prints the unit; `install [--dir DIR] [--no-reload]` writes it
|
||||||
|
to a temp file, renames it and runs `systemctl --user daemon-reload`;
|
||||||
|
`uninstall` refuses while the unit is active; `status` prints the unit
|
||||||
|
state and the result of `GET /healthz` on its port.
|
||||||
|
- No start, stop, enable or restart verb. The script header and the
|
||||||
|
TOOLS.md entry say why: the Console holds the human's capability, so
|
||||||
|
Jason starts it from his own shell with
|
||||||
|
`systemctl --user enable --now mosaic-webui`.
|
||||||
|
- `render` and `install` take `--port N` (default 7332), `--business ID`,
|
||||||
|
`--board URL`, and row 74's `--public-host NAME --auth-header HEADER
|
||||||
|
--allow-user ID`, all three or none, as `serve` takes them. Each value
|
||||||
|
is held to a plain character set the unit can carry (systemd expands
|
||||||
|
`%` and splits on spaces) and refused otherwise. None is a secret.
|
||||||
|
- `mosaic-webui.service`: one instance, `WorkingDirectory` and `PATH`
|
||||||
|
filled in as the bus unit does, `ExecStart` running
|
||||||
|
`node @REPO@/packages/webui/src/cli.mjs serve` with the rendered flags,
|
||||||
|
`Restart=on-failure`, `RestartPreventExitStatus` for usage and config
|
||||||
|
exits, `NoNewPrivileges=yes`, `WantedBy=default.target`. It sets no
|
||||||
|
`MOSAIC_*`, `CLAUDE*`, `CODEX*` or `PI_*` variable.
|
||||||
|
- Tests: render with and without the preview flags; a partial preview
|
||||||
|
set refused; a value with a space, `%` or newline refused; the rendered
|
||||||
|
unit names none of the agent markers in `packages/bus/src/human.mjs`;
|
||||||
|
install into `--dir` with `--no-reload` writes the file whole;
|
||||||
|
uninstall refuses while active (a stand-in `systemctl` on `PATH`).
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
Starting the unit; the board's service; any `src/` change; a container.
|
||||||
|
If the unit can't run `serve` as written, stop and tell Sage.
|
||||||
|
|
||||||
|
### Gate
|
||||||
|
|
||||||
|
Filbert approves on the row's issue naming the candidate manifest. The
|
||||||
|
webui node suite and every `scripts/test-*.sh` green on Sage's gate rerun.
|
||||||
|
|
||||||
|
## Console sends a message to a role
|
||||||
|
|
||||||
|
### Problem
|
||||||
|
|
||||||
|
For dogfooding, Jason has to ask the PM for work from the browser. Tasks
|
||||||
|
don't need their own path: the PM creates and assigns them (S3). One write
|
||||||
|
covers it, a human `message.send` to a role. The Console refuses every
|
||||||
|
POST in preview mode (row 74), and outside it has no bus write at all.
|
||||||
|
|
||||||
|
### Owner and reviewer
|
||||||
|
|
||||||
|
Owner: Dewey, after row 74. Reviewers: Darkwing and Filbert.
|
||||||
|
|
||||||
|
### Files owned
|
||||||
|
|
||||||
|
- `packages/webui/src/` (serve, bus, cli and the page assets under
|
||||||
|
`public/`), `packages/webui/README.md` and `packages/webui/tests/`
|
||||||
|
- `agents/dewey/work/queue-<row>/`
|
||||||
|
|
||||||
|
### What ships
|
||||||
|
|
||||||
|
- A `--send` flag on `serve`, off by default, accepted only with the
|
||||||
|
three preview flags. Without it the Console behaves as after row 74.
|
||||||
|
- `POST /api/bus/message` with JSON `{to, body, in_reply_to?}`, at most
|
||||||
|
16 KiB. With `--send` it is the one POST preview mode allows. It
|
||||||
|
requires the auth header equal to the allowed user on every request,
|
||||||
|
loopback included, an Origin equal to the request's own origin, and
|
||||||
|
`Content-Type: application/json`. It calls `message.send` through the
|
||||||
|
same human transport the reads use, with exactly those keys. `to` and
|
||||||
|
the body limits are the broker's to refuse; its codes map to HTTP the
|
||||||
|
way `busStatus` maps the reads'.
|
||||||
|
- `outcome-unknown` is shown as unknown, with no resend: the page says
|
||||||
|
the message may have been sent and points at the trail. Nothing retries
|
||||||
|
automatically.
|
||||||
|
- One log line per send on stdout (time, allowed user, `to`, message id
|
||||||
|
or error code), never the body.
|
||||||
|
- On the page: a role picker from the agents read, a text box and Send.
|
||||||
|
The receipt shows the message id and links its trail; replies show in
|
||||||
|
the inbox as today. A draft survives the periodic refresh.
|
||||||
|
- Tests: each refusal (no `--send`, missing or wrong header, a loopback
|
||||||
|
request without the header, bad Origin, wrong type, oversize, an extra
|
||||||
|
key), a send through a stand-in transport with exactly the allowed
|
||||||
|
keys, `outcome-unknown` reported and not retried, and every other POST
|
||||||
|
still 403 `read-only`.
|
||||||
|
- The README states what `--send` grants: anyone the proxy lets through
|
||||||
|
as the allowed user, and any local process that reaches the port and
|
||||||
|
sets the header, can send a human instruction. The second is the same
|
||||||
|
class of exposure as running the human CLI directly (lead decision 62).
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
Decisions from the browser (seen, resolve, withdraw) stay in the CLI
|
||||||
|
(REQ-DEC-3); message classes other than the default; corrections; any
|
||||||
|
bus or broker change; conversations with T3 seats (CHAT-07).
|
||||||
|
|
||||||
|
### Gate
|
||||||
|
|
||||||
|
Darkwing and Filbert approve on the row's issue naming the candidate
|
||||||
|
manifest. The webui, bus, control-board and cli node suites and every
|
||||||
|
`scripts/test-*.sh` green on Sage's gate rerun. Jason's Q95 answer is
|
||||||
|
recorded before the row starts.
|
||||||
@@ -99,10 +99,14 @@ exactly as today, and the existing tests show it.
|
|||||||
- A container image, CI deploy, or changes to the bus unit.
|
- A container image, CI deploy, or changes to the bus unit.
|
||||||
- A service script and unit template (`scripts/webui-service.sh` on the
|
- A service script and unit template (`scripts/webui-service.sh` on the
|
||||||
`bus-service.sh` pattern). That is a follow-up row.
|
`bus-service.sh` pattern). That is a follow-up row.
|
||||||
- Starting it on dragon-lin. After the row lands, Sage starts the preview
|
- Starting it on dragon-lin. The Console reads the bus through the human
|
||||||
as a transient user unit (`systemd-run --user`, loopback port 7332;
|
transport, so whoever starts it holds the human's capability. An agent
|
||||||
7330 holds the operator's own Console). The edge reaches it once
|
starting it, even detached through systemd, works around the human
|
||||||
rev-sol-01 passes ops-01's route.
|
proof (lead decisions 62 and 94). After the row lands, Jason starts it
|
||||||
|
from his own shell as a transient user unit (`systemd-run --user`,
|
||||||
|
loopback port 7332; 7330 holds the operator's own Console), with the
|
||||||
|
command Sage gives him. The edge reaches it once rev-sol-01 passes
|
||||||
|
ops-01's route.
|
||||||
- The group check. Authentik and the proxy limit sign-in to Jason's
|
- The group check. Authentik and the proxy limit sign-in to Jason's
|
||||||
group; the Console checks the header against the one user id.
|
group; the Console checks the header against the one user id.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user