fix(cli): bus and Console lifecycle verbs refuse inside an agent run (#1873) #1942

Merged
jason.woltje merged 3 commits from agent-guard into refactor 2026-11-11 22:32:24 +00:00
Owner

Bus and Console lifecycle verbs refuse inside an agent run (#1873, D2 security re-check P1).

An agent could stop, start or restart an organization's bus or the Console from its own shell and skip the Console's owner check and trail. These verbs now refuse with the same refuseInsideAgent refusal bus recover gives (exit 3). No new marker list, no new human gate.

  • Refuse: bus start|stop|restart (including the internal host start), console start with or without --dev-local-owner, console stop|restart, org archive|delete. bus recover now also checks process.env.
  • Open: bus status, console status, org restore.
  • Each guarded verb checks process.env and then io.env, so a sanitized io.env does not hide a marker. Usage errors (exit 4) still come first; the refusal comes before any config or state read.
  • The WebUI keeps the verbs: Restart bus, setup/bus, archive and delete call the library in the Console process; Restart Console relaunches through the supervisor. A test drives Restart bus on a real dev-owner Console and checks the new host's environment has no markers.

The uiorg deploy script now stops buses through the Console's Stop bus route (PR #1941), so a deploy from an agent shell still leaves no stale locks.

Tests: agent-guard.test.mjs, 16 tests; 15 fail on BASE. Lane gate 136 files, 1761/0, plus a 10-file rerun at the fix commit (96/0).

Review: build (Opus) changes 3, all fixed or answered (deploy analysis corrected; org archive/delete now refuse; usage errors first). Security (daybreak-blue) and one re-check, 2 P3 fixed. Lead check: 119 files on a5f227e9f (every packages/cli test, bus-stop and org-admin), 1606/0, 1 opt-in skip (FED R7).

Deferred: the marker check is cooperative (Lead ruling: real enforcement needs agents under a separate OS identity); tests that start real buses need a marker-free runner (env -i); org reload and older callers check io.env only; org lock clear, create, update and queue/project init stay open to agents; the webui README lists the bus verbs without the refusal.

Bus and Console lifecycle verbs refuse inside an agent run (#1873, D2 security re-check P1). An agent could stop, start or restart an organization's bus or the Console from its own shell and skip the Console's owner check and trail. These verbs now refuse with the same `refuseInsideAgent` refusal `bus recover` gives (exit 3). No new marker list, no new human gate. - Refuse: `bus start|stop|restart` (including the internal host start), `console start` with or without `--dev-local-owner`, `console stop|restart`, `org archive|delete`. `bus recover` now also checks process.env. - Open: `bus status`, `console status`, `org restore`. - Each guarded verb checks process.env and then io.env, so a sanitized io.env does not hide a marker. Usage errors (exit 4) still come first; the refusal comes before any config or state read. - The WebUI keeps the verbs: Restart bus, setup/bus, archive and delete call the library in the Console process; Restart Console relaunches through the supervisor. A test drives Restart bus on a real dev-owner Console and checks the new host's environment has no markers. The uiorg deploy script now stops buses through the Console's Stop bus route (PR #1941), so a deploy from an agent shell still leaves no stale locks. Tests: agent-guard.test.mjs, 16 tests; 15 fail on BASE. Lane gate 136 files, 1761/0, plus a 10-file rerun at the fix commit (96/0). Review: build (Opus) changes 3, all fixed or answered (deploy analysis corrected; org archive/delete now refuse; usage errors first). Security (daybreak-blue) and one re-check, 2 P3 fixed. Lead check: 119 files on a5f227e9f (every packages/cli test, bus-stop and org-admin), 1606/0, 1 opt-in skip (FED R7). Deferred: the marker check is cooperative (Lead ruling: real enforcement needs agents under a separate OS identity); tests that start real buses need a marker-free runner (`env -i`); `org reload` and older callers check io.env only; `org lock clear`, create, update and queue/project init stay open to agents; the webui README lists the bus verbs without the refusal.
jason.woltje added 3 commits 2026-11-11 22:32:21 +00:00
D2 security re-check P1 (agent-guard). mosaic bus start|stop|restart and
mosaic console start (with or without --dev-local-owner), stop and restart
refuse inside an agent run with refuseInsideAgent's refusal (exit 3), as
bus recover does. The check reads the given environment and this process's
own, so a sanitized io.env does not hide a marker; bus recover and console
restart now check both too. consoleStart refuses for every Console. Status
verbs stay open. No new marker list and no new human gate.

The Console's Restart bus runs org-bus.mjs in the Console process; its new
host goes through the guarded CLI entry with the Console's own environment.
Restart Console relaunches under the supervisor without the CLI.
Build review finding 2: org archive and org delete stop the organization's
bus, so they now refuse inside an agent run like bus stop, after their usage
checks and before any config is read. Finding 3 (also security P3): the
--pm/--no-launch and Console LAN flag checks now come before the refusal,
so a usage error exits 4 as the docs say.
org delete checks --if-revision before --confirm again, so a bad revision
without --confirm says "invalid revision" as it did on BASE.

The archive and delete "bus untouched" check moves from the status test,
whose fixture has no owner file, to the Restart bus test, which has a real
organization and a live bus. An agent run's archive and delete exit 3 and
leave the bus pid and the organization unchanged; the same archive from a
human shell stops the host, and restore makes the organization active again.
jason.woltje merged commit 35c125fc1f into refactor 2026-11-11 22:32:24 +00:00
Sign in to join this conversation.