Files
stack/docs/plans/2026-10-20_agent-lifecycle.md

5.3 KiB

Brief: agent lifecycle from the Console and the CLI, with a per-agent hire/fire veto

Sage, 2026-10-20, for mos-0974 (MVP, DECISIONS Q176, Vikunja #414 "User and main agent can create and spawn agents" and "User maintains ability to terminate, regenerate, or create agents via WebUI or CLI ad-hoc", #415 Case 1 "Chief of staff agent has hire/fire authority for agents as needed; unless user forbids per agent" and "User maintains ability to restructure organization at will"). Gitea #1692. T1 item 5. Owner Honker, reviewer Webby (mos-0981), gate owner Sage. Base: refactor at the brief commit.

Design first. The first deliverable is agents/honker/work/queue-194/DESIGN.md. Webby reviews it before any code.

What exists today (GAP-MAP.md G8, G9, C1.5, C1.6, measured at 9ae8c73ac)

  • The chief launches only listed instances (roles/chief-of-staff.json, harness tools.mjs launch, broker.mjs:1968). No user verb launches an arbitrary agent.
  • Terminate exists (packages/cli/src/cli.mjs:447, instances.mjs:9-11, webui serve.mjs:288, 535). There is no regenerate, no delete and no Console launch.
  • Instance changes need a bus restart (instance-settings.mjs:35,75, organization.mjs:83). Add and change only, no delete.
  • Human-only membership acts as a veto today, but there is no per-agent veto list.

What the design must settle

  1. The verbs: create (from a role and a name), launch, terminate, regenerate (a fresh session with the same identity and role), and delete (with what happens to its sessions, workspace and run evidence, which stays write-once). Each one is a human verb on the CLI and a Console action.
  2. Chief hire/fire. What the chief may do on its own, and the per-agent veto: the human marks an agent so the chief can't fire or replace it, and marks roles the chief can't hire. Where the veto lives and how the broker enforces it.
  3. Live changes. Which changes take effect without a bus restart, and how a running bus picks them up safely.
  4. RBAC. Human roles come from row 193 (Morgana). Until it lands, these verbs are owner-only. The design states the hook that row 193 fills.
  5. Per instance. Row 190 runs one instance per OS user. Lifecycle verbs act on their own instance only.
  6. The kill switch (row 191, Rocko) refuses every launch path. These new launch paths check it too.
  7. A created agent's credential entry (Sage, 2026-10-20, from row 199 note N2, duckworth-0068). Row 199's issue works only for an entry the bus loaded at start. Create either registers the new entry with the running bus or states that the agent needs a restart before issue, and a test covers the one chosen. Honker chose the restart route (honker-0044, plan at 457fb8635 on honker/row194-b2). Sage accepted it because it keeps row 194 D3's fixed-at-start rule and row 199's reviewed store unchanged.
  8. Revoke on fire and delete (Sage, 2026-10-20, row 199 D13, honker-0044). Item 7 lets a human create a credentialed agent, so fire and delete call credentials.revoke(business, agent, {reason, actor}) before they change the business file. A failed revoke stops the verb with credential-revoke-failed and leaves the business file unchanged. Tests cover a revoke that succeeds and a revoke that fails, for each verb. Mutants drop the revoke call, move it after the file write, and ignore its failure.

Boundaries

  • No test touches ~/.mosaic-dev, ~/.config/mosaic-dev, the live units or a slot file.
  • Role authority is declared in roles/ and changes only by reviewed commits (AGENTS.md invariant 7). This row adds verbs, not new role authority. Any role file change is called out for review.
  • The build may chain on rows 190, 191 and 193 candidates (Q177).

Gate

Webby approves DESIGN.md, then the manifest. The bus, cli, business and webui suites and every scripts/test-*.sh are green on Sage's gate, and the design's mutants are killed.

Brief: row 194 follow-up, the revoke under the writer's lock and a fire test

Sage, 2026-10-21, from Duckworth's row 194 b3 N1 (duckworth-0070, duckworth-0074) and Mos's ruling mos-1158. Owner Honker, reviewer Duckworth, gate owner Sage. Builds on row 194's landing.

Row 194 b3 checks the revision in instance-settings.mjs commit() before beforeWrite, which is the revoke on fire and delete. A window is still open. If a write lands between that read and the writer's lock, a fire or delete revokes and then refuses revision-conflict. An outcome-unknown after a revoke also doesn't say the tokens are gone. Two changes:

  1. Run beforeWrite inside writer.write, under its lock, after the organization.mjs:188 revision check. A refusal after a revoke that ran says the tokens may already be revoked. That covers revision-conflict and outcome-unknown, in the CLI and the Console texts. A refusal before any revoke keeps today's text.
  2. Add a fire test for a stale revision, using an injected writer or whatever the design picks. The test checks that nothing is revoked and the business file is unchanged. Keep T21 for delete.

Mutants: run beforeWrite before the lock. Drop the fire refusal. Drop the "may already be revoked" text.

Gate: Duckworth approves the manifest. The bus, business, cli and webui suites and every scripts/test-*.sh are green on Sage's gate, and the mutants are killed.