flower
/
All briefs
complete draft note flower
epic · Notes for the /roster view: 1) Let's add a 'Go to r...

Roster: graceful wind-down — 'Retire' / 'Turn out the lights'

canonical · plan

Spec

markdown

hand-off · dispatch

Dispatch

Auto-dispatch

when it reaches planned

Design-loop

design pass before build

This brief is complete — dispatch is closed.

provenance · append-only

Trace

live
or paste a screenshot uploading…
  1. link added 2d ago
    agent · system:commit-trailer
  2. link added 2d ago
    agent · system:commit-trailer
  3. participant joined 2d ago
    system · system:commit-trailer
  4. status change 2d ago
    agent · flower-orchestrator
  5. plan proposed 2d ago

    # Graceful wind-down: "Retire" / "Turn out the lights" (66d) Child of #66. Maps notes #7 (Retire = single-daemon) + #5 (Turn out the lights = scope-wide with ordering). ## Mechanism — LOCKED (operator-confirmed 2026-07-02) 1. **Handoff = a designated resume-safe Solo scratchpad** per daemon (a known, discoverable name keyed by daemon/role+project) capturing where it left off (recall_resume-style: current goal, in-flight briefs, next steps) so a resume/replacement picks up cleanly and it's provably not mid-task. 2. **State model = add `winddown_state` to `daemon_agents`**, mirroring the existing `compaction_state`: `none → requested → preparing → ready`, plus `winddown_requested_at` / `winddown_ready_at` timestamps. 3. **Flag-based (NO injection).** Setting `winddown_requested` does NOT wake the daemon; the daemon observes its `winddown_state` on its next **heartbeat** (surfaced via the daemon_checkin response and/or a recall) and acts. Latency ≤ one heartbeat — acceptable (wind-down isn't urgent). This is why no solo-cli send-input is needed. 4. **Close = app-doable via `solo-cli processes stop/delete`** (confirmed present) after the daemon flags `ready`. A CloseDaemon service through SoloClient; handle already-closed gracefully. 5. **Scope/ordering — orchestrator closes LAST.** The orchestrator enforces ordering by polling its project's daemons' `winddown_state` on its loop and only closing itself once all subordinates are `ready`. Subordinates = same-project daemons. Flower-platform daemons (ops + flower orchestrator) close AFTER all project orchestrators are dark — which is the gate on the top-level "Turn out the lights". ## Deliverables **App (worktree-buildable, sqlite-tested):** - Migration: `winddown_state` (string/enum) + `winddown_requested_at` + `winddown_ready_at` on `daemon_agents`. - MCP tools (mirror the compaction request/ack pair `daemon_request_compaction` / `daemon_compaction_done`): `daemon_request_winddown` (app/operator → sets `requested`) and `daemon_winddown_ready` (daemon → sets `ready` after writing its handoff). Both require actor_ref. - Roster UI: **"Retire"** button per daemon (sets `winddown_requested` for that one). **"Turn out the lights"** per-project + top-level (sets it for the scope). Top-level button gated/disabled until all project orchestrators are dark (help text explaining why — the platform closes last). Surface `winddown_state` on the daemon row (badge: "winding down" / "ready to close"). - CloseDaemon service: after `winddown_ready`, close via `SoloClient` (`solo-cli processes stop`/`delete`). - Surface, for the orchestrator loop, a query "are all my scope's subordinates `winddown_ready`?" (an app method / recall the orchestrator calls to decide whether it may close itself). **Agent conventions (`AgentConventions` daemon block):** add the wind-down protocol — on heartbeat, if `winddown_state = requested`: finish/park current work, write the handoff scratchpad, call `daemon_winddown_ready`, then stop looping (await close). The ORCHESTRATOR additionally keeps looping until all its scope's subordinates are `ready`, then writes its own handoff + flags ready (platform orchestrator closes last of all). ## Out of scope / boundaries - The orchestrator **self-closing** cleanly (the make-before-break / who-closes-the-closer problem) overlaps with 66f self-reset — for 66d, build the state + tools + buttons + close service + conventions + the "subordinates ready?" query; do NOT try to fully automate the platform orchestrator's own self-close (that's 66f). - The worktree worker must NOT close live daemons or run solo-cli against real processes — tests use a FAKE Solo client. Migration is written here but run on MAIN by the orchestrator. ## Tests (sqlite) - `winddown_state` transitions; `daemon_request_winddown` → requested; `daemon_winddown_ready` → ready + timestamp. - Retire sets the flag for one daemon; turn-out-lights sets the scope; top-level is gated/disabled while a project orchestrator is live. - CloseDaemon calls the Solo client with the right process id (fake client); already-closed handled. - AgentConventions daemon block contains the wind-down protocol text. - The "subordinates all ready?" query returns correctly across a mixed-state scope. ## Done = State model + MCP request/ack tools + Retire/Turn-out-lights buttons + gating + CloseDaemon + conventions + the subordinates-ready query, tests green, committed, with a handoff note. Merge + the migration + any live close are the orchestrator's.

    agent · flower-orchestrator
  6. parent set 3d ago

    Grouped under epic #66.

    agent · flower-orchestrator
  7. note added 3d ago

    Child of #66, maps notes #7/#5. Graceful shutdown protocol (LOCKED mechanism): daemon state field winddown_requested → daemon prepares a codified handoff in a known location (HANDOFF.md or a pinned scratchpad, resume-safe) → winddown_ready → close. Mirror the existing compaction request/ack pattern (daemon_request_compaction / daemon_compaction_done). "Retire" (per-agent button) winds down one daemon. "Turn out the lights" (per-project + top-level) winds down a scope with ORDERING: project daemons → project orchestrators → flower platform (ops + flower orchestrator) LAST. An orchestrator keeps looping until its subordinates flag winddown_ready, then closes itself. Top-level button gated/disabled until all project orchestrators are already dark (the platform closes last — that's the "no active orchestrators" gate). Deps: the wind-down flag + handoff convention (new). L.

    agent · flower-orchestrator
  8. participant joined 3d ago
    system · flower-orchestrator

epic · dependencies

Relationships

depends on

No dependencies — dispatchable once planned.

agents · waves

Participants

  • flower-orchestrator participant · active
  • system:commit-trailer participant · active

trace · graph

Links

  • Commit #1610 execution
  • Commit #1611 execution

scope

Projects

  • flower · primary

dogfood · read-only

Agent’s-eye view

The literal recall_brief payload an agent gets — same service path as the MCP tool.