Fleet management commands
These commands use physics-inspired names (nucleate, evolve, decay, spore, …). New to the vocabulary? See The physics vocabulary.
cs ensemble
Display ensemble status — observe the fleet at a glance
Usage: cs ensemble [OPTIONS]
EXAMPLES: cs ensemble # all molecules, all fleets cs ensemble --tag temp:hot # actionable backlog snapshot cs ensemble --fleet research # one fleet only cs ensemble --json # NDJSON for scripting
Options:
-
--all— Show molecules from all projects, not just the current one -
--cluster[alias:cluster] — Walk every.cosmon/-bearing galaxy under$COSMON_CLUSTER_ROOT(default$HOME/galaxies) and print one aggregated table.This is the cross-galaxy extension of
--all. Where--alldrops the project-id filter within the current state dir,--clustervisits every sibling galaxy on disk and prints their workers + molecule counts. Works in tandem with--all(implicitly drops the project filter because the scope is now the whole cluster).Also prints one host reading — memory, swap, the kernel's own pressure level, CPUs and load, with units — and the machine-wide totals derived from the galaxies scanned, including harvests holding a galaxy's trunk lock (a
cs donein its post-merge gate phase has no live worker). Observations only: no threshold is applied and nothing is refused. A counter that could not be read printsunavailable, never0; if the host cannot be read at all the galaxy view still renders and the reason goes to stderr. -
--cluster-root <DIR>— Override the cluster root directory when--clusteris set. Defaults to$COSMON_CLUSTER_ROOTenv var, then$HOME/galaxies -
--tag <GLOB>— Filter molecules by tag glob pattern (repeatable, any-match).Patterns support
*as wildcard. Example:--tag deferred:*. Molecules without a matching tag are excluded from the molecule summary counts.
cs purge
Purge dead workers from fleet state without changing molecule status
Usage: cs purge [OPTIONS] [WORKER]
EXAMPLES:
cs purge # sweep: remove Stopped / Error / Stale workers
cs purge worker-3 # targeted: remove a single worker (graceful path)
cs purge worker-3 --force # targeted + SIGKILL tmux (supersedes cs kill)
ADR-052 §D3 collapses cs kill + cs purge into this one verb: both
are infrastructure teardown. Sweep mode (no argument) stays unchanged;
targeted mode with --force replaces cs kill.
SEE ALSO: cs freeze (graceful + state preservation), cs teardown (fleet-wide graceful shutdown).
Arguments:
-
<WORKER>— Optional worker ID — when given, targeted purge of that worker only.Without a worker the command sweeps every terminal-state worker from fleet state (the pre-ADR-052 behaviour). With a worker, only that worker is removed; pair with
--forceto SIGKILL its tmux session first (formerlycs kill).
Options:
-
--force— In targeted mode, SIGKILL the tmux session before removing the fleet entry. Ignored in sweep mode. Supersedes the stand-alonecs killverb (ADR-052 §D3) -
--status <STATUS>— Only purge workers matching this desired state (default: sweep all workers — Stopped ones and Running/Paused ones whose tmux session is gone) -
--role <ROLE>— Restrict the purge to workers matching this role discriminator — eithercognitionorruntime(seeWorkerRole). Without this flagcs purgeremoves both runtime and cognition workers that meet the status predicate; with it, operators can clean up one half of a runtime+cognition pair without collapsing the other -
--allow-unharvested— Permit reclaiming a worker whose molecule has unharvested changes.Without this flag
cs purgefails closed: a worker whose pane is gone but whose branch still carries commits — or whose worktree still has uncommitted files — is left in the fleet, its molecule leftrunning, and the commits and files at stake are named in an alert. With this flag the worker is removed but the molecule stays Running. A dead tmux session is evidence about the pane, not about the work (incident 2026-08-02, where four molecules were silently collapsed after a reboot with up to three commits each still unmerged). -
--worktrees— Also run the.worktrees/reclamation pass (issue 61).Enumerates
readdir(.worktrees/) ∪ git worktree list --porcelain— the filesystem and Git's own registry, not the worker roster, which is keyed by molecule and could not see a directory that has none. Reports every candidate: the reclaimable derived output on one side, and on the other every worktree withheld with its reason.Reclamation is opt-in and one tier deep. On its own this flag removes nothing;
--allow-unharvested— the same gesture the sweep already uses, not a second one — executes the derived half. Durable content is never removed by any path in this command, whatever the flags (ADR-178): the eligibility verdict is advisory and is printed, not acted on. -
--sessions— Also run the tmux session reclamation pass (ADR-179).Enumerates the galaxy's tmux socket —
list-panes -a, not the worker roster. The roster is precisely what cannot see this population: the sweep above removes a terminal molecule's worker entry and the session it named lives on, unattributable, holding an agent process and its whole heap for as long as the machine is up. Each session is attributed by computing every known molecule's session name forward and matching, never by parsing a molecule id back out of a session name.Reclamation is opt-in exactly as
--worktreesis: on its own this flag kills nothing, and--allow-unharvested— the same gesture, not a second one — executes it. A session is reclaimed only when its molecule is terminal, no client is attached, and its scrollback has been captured to that molecule's directory first. -
--dry-run— Report what would change and change nothing.Applies to the whole command: no fleet entry is removed, no molecule is changed, no event is emitted and no byte is reclaimed. The
--worktreespass is dry by default and stays dry here.
cs kill
Kill a worker — immediate termination (no state flush)
Usage: cs kill <WORKER>
EXAMPLES: cs kill worker-3 # DEPRECATED — see below
DEPRECATED (ADR-052 §D3): use cs purge worker-3 --force instead. This
alias will be removed after one release cycle.
SEE ALSO: cs purge (canonical), cs freeze (preserve state), cs done (teardown after a molecule completes).
Arguments:
<WORKER>— ID of the worker to terminate
cs quench
Quench a worker — graceful shutdown with state preservation
Usage: cs quench [OPTIONS] <WORKER>
EXAMPLES: cs quench worker-3 # DEPRECATED — see below
DEPRECATED (ADR-052 §D3): use cs freeze worker-3 --reason quench
instead. Graceful shutdown with state preservation IS freeze; --reason
captures operator intent. Note: the canonical path lands in Paused
(resumable via cs thaw) rather than Stopped. This alias will be
removed after one release cycle.
SEE ALSO: cs freeze (canonical), cs purge (fleet teardown), cs teardown (fleet-wide graceful shutdown).
Arguments:
<WORKER>— ID of the worker to gracefully shut down
Options:
-
--timeout <TIMEOUT>— Grace period in seconds before force-killing (default: 30)Default value:
30 -
--force— Skip graceful exit — go straight to force-kill (same askill) -
--no-tmux— Skip tmux interaction (state-only transition, for testing)
cs teardown
Teardown a fleet — gracefully stop all fleet workers
Usage: cs teardown [OPTIONS] <FLEET>
EXAMPLES: cs teardown # gracefully stop every worker in the default fleet cs teardown --fleet research
SEE ALSO: cs kill (single worker, hard), cs quench (single worker, graceful).
Arguments:
<FLEET>— Name of the fleet to tear down (matches fleet.tomlfleet = "..."name)
Options:
--force— Force-kill instead of graceful quench--no-tmux— Skip tmux interaction (state-only, for testing)
cs resume
Resume — convenience alias for cs patrol --propel --molecule <id>
Usage: cs resume [OPTIONS]
EXAMPLES: cs resume # nudge all idle workers cs resume worker-3 # nudge one
Convenience alias for cs patrol --propel --molecule <id> — maintains the
Propelled regime by re-delivering the propulsion signal. Does NOT change
state or advance molecules.
SEE ALSO: cs patrol --propel (canonical command), cs thaw (frozen workers).
Options:
--fleet <FLEET>— Only resume workers in this fleet--agent <AGENT>— Only resume this specific agent (by name, across all fleets)-c,--message <MESSAGE>— Custom resume message (default: standard RESUME signal)
cs patrol
Patrol the fleet — health checks and anomaly detection
Usage: cs patrol [OPTIONS]
EXAMPLES: cs patrol # run one health sweep cs patrol --propel # nudge stale molecules cs patrol --respawn # restart dead workers cs patrol --harvest # close Completed-but-unmerged molecules cs patrol --silence-detect # flag workers that stopped heartbeating cs patrol --livelock # detect circular blocked-on waits cs patrol --event-age # flag Running molecules with a quiet event log cs patrol --heal # remediate safe anomaly classes, each §5-guarded cs patrol --heal --dry-run # preview the Deacon's actions, mutate nothing
Designed to be run by an external scheduler (cron, launchd) in the
Propelled regime. --harvest is the belt-and-suspenders sweep that
complements the tmux pane-died hook installed at cs tackle time.
--silence-detect, --livelock, and --event-age are the
runtime-independent stall detectors: they read state from disk only, so
they fire even when cosmon-runtime is dead (the watchdog's liveness is
independent of the thing it watches). --event-age is the external-modal
backstop — it keys on the age of any event-log append, so it catches a
worker parked at a Claude Code AskUserQuestion modal that emits no
cosmon-visible state. Alerts are tiered by irreversibility: only an
irreversible-class block (signature/push/publish) fires cs notify.
Options:
-
--respawn— Auto-respawn: restart dead workers by re-creating tmux sessions -
--no-tmux— Skip tmux liveness checks and respawn (state-only mode, for testing) -
--propel— Propel: detect running molecules with stale progress and nudge their workers via transport. The cognitive safety net that complements the new propulsion prompt — if a worker falls silent mid-molecule, patrol re-engages it. A worker whose terminal is still producing output is thinking, not idle, and is never nudged; a genuinely silent one is nudged with exponential backoff, at most 4 times, after which the molecule is taggedpropel-exhaustedfor--heal. A worker that lost its briefing (orphaned by a crash / machine-sleep) cannot evolve, so it is never nudged at all: it is taggedpropel-orphaned, the operator is paged viacs notify, and the brief must be re-delivered (cs tackle --force) or the molecule collapsed — closing the 2026-07-21 money-pump where a brief-less worker was nudged for six hours -
--propel-api-stall— Propel on a typed provider stall — the narrow channel. Consults each live worker's provider session journal and re-engages one only when its last assistant record carries the provider's own transport-failure flag (Claude'sisApiErrorMessage), the molecule is still Running, and no human is piloting it. Distinct from--propel, whose trigger is the inference "this worker looks idle" — the trigger that had to be turned off on 2026-07-23 because a worker that is thinking is not a worker that is stuck. The flag is a fact the provider wrote down; a worker parked on it has no turn in flight to interrupt. Never keys on pane text or on the error sentence: auserrecord quoting that sentence verbatim carries no flag and is never propelled (the be1e SEV-1 use/mention trap). Keeps every--propelguardrail — exponential backoff topropel-exhausted, thepropel-orphanedescalation, the ADR-137 §5 no-interference guard and the~/.cosmon/health.offkill-switch.~/.cosmon/stand-down.lockstops everycs patrolsweep, this one included -
--stale-after <STALE_AFTER>— Staleness threshold in seconds for--propel(default: 300). A molecule is a candidate ifupdated_atis older than this AND its worker's terminal has been silent at least as long. Also the first backoff window, doubling per nudge up to 30 min.--propel-api-stallreuses it for the terminal-silence bar and the backoff base, but never as a candidacy test: there, candidacy is the provider's typed flagDefault value:
300 -
--nudge— Nudge: per-step stall remediation. Like--propel, but classifies stalls fromlast_progress_atagainst the active step'stimeout_minutesbudget (M3, default 30 min) and guards idempotence — a worker won't be nudged twice within 60 s. Also covers the boot-stall class (task-20260718-ac03): a Running molecule with NO progress signal at all — the stuck bootstrap paste whose Enter was lost at spawn — is nudged once tackled more than [BOOT_STALL_GRACE] ago, the same grace used bycs health. The nudge text referencesbriefing.mdso the re-engaged worker re-reads its contract before continuing. Increments [cosmon_state::MoleculeData::nudge_count] (M5). This flag does not freeze or collapse molecules; those transitions require the separate--auto-freezeor--auto-collapseflag -
--expire— Expire sweep: scan molecules whoseexpires_atis in the past and apply their [ExpiryPolicy] (ADR-029). Idempotent — safe to run repeatedly on the same state.Warntags the molecule withexpiredand emits a surface alert;Collapsetransitionspending→collapsedwith reasonexpired (TTL);Escalatetagsescalatedand emits the canonicalExpiredevent for downstream transforms -
--auto-freeze— Transition orphaned molecules with a retained stopped worker toFrozenafter the spawn grace. A purged worker leaves its Running molecule available for re-tackle. Without this flag, patrol reports orphans and leaves lifecycle state unchanged.--auto-collapseselects a terminal transition instead -
--auto-collapse— Aggressive orphan remediation: transition orphaned molecules with a retained stopped worker toCollapsedafter the spawn grace. A purged worker leaves its Running molecule available for re-tackle. Use--auto-freezefor a recoverable transition -
--dead-worker-grace-secs <DEAD_WORKER_GRACE_SECS>— Minimum seconds after a tackle before patrol may call its worker dead or freeze/collapse its molecule. Covers spawn and forced re-tackleDefault value:
120 -
--harvest— Harvest sweep: scan everyCompletedmolecule withmerged_at = Noneand invokecs harvest --molecule <id>on each one. Belt-and- suspenders safety net for cases where the tmuxpane-diedhook never armed (tmux server restart, brutal crash, molecule completed before the hook was installed, …). Idempotent: already-merged molecules are silent no-ops insidecs harvest -
--livelock— Livelock sweep: read.cosmon/state/presence/<sid>/blocked_on.jsonfor every live session, build the session-wait graph, and report any non-trivial strongly connected component. Emits atemp:hotissue molecule taggedlivelock-detectedper cycle. Never auto-resolves (turing §6, §8b: propose, don't impose) -
--livelock-stale-after <LIVELOCK_STALE_AFTER>— Staleness threshold for--livelock, in seconds.blocked_on.jsonentries older than this are considered crashed-session residue rather than live waits and are excluded from the graph. Defaults to one hour — the cost of a false negative (missing a real lock) is lower than the cost of a false positive (nuisance issue)Default value:
3600 -
--silence-detect— Silence-detect: scan running molecules for those whose worker has not emitted aWorkerHeartbeatinsilence_afterseconds. Tagstemp:frozen, emitsWorkerSilenceDetected, and firescs notify("absence of signal must itself be a signal"). Does not kill the worker -
--silence-after <SILENCE_AFTER>— Threshold in seconds for--silence-detect(default: 90). Roughly3 ×the recommended 30-second heartbeat cadence; raise it for fleets with longer steps or noisy networksDefault value:
90 -
--event-age— Event-age check: for everyRunningmolecule, raise an ALERT-only signal when the most recent entry in the event log for that molecule is older thanevent_age_afterseconds. Unlike--silence-detect(which keys specifically onWorkerHeartbeat), this keys on any event append, so it catches the external-modal case — a Claude CodeAskUserQuestionmodal that emits no cosmon-visible state at all. It never tags, never kills, never touches transport: it is a pure read overmolecules + events.jsonl, so it works even whencosmon-runtimeis dead (CV-5 — the watchdog's liveness must be independent of the thing it watches). Alerts are tiered by irreversibility (CV-6): only an irreversible-class block (signature / push / publish) firescs notify; operational stalls are report-only, to keep the one load-bearing alert out of an alert-fatigue flood -
--event-age-after <EVENT_AGE_AFTER>— Threshold in seconds for--event-age(default: 900 = 15 min). The panel's suggested floor — long enough that a worker genuinely thinking between event appends is not mistaken for a stallDefault value:
900 -
--abandon— Abandon sweep (patrouille-abandon): fold traces an instance has ALREADY emitted (audit envelopes, phone-home reports, PKCE auth sessions, instance ledgers) into named abandonment motifs per tenant — nucleate-sans-tackle, pkce-start-sans-completed, incarne-sans-login, rafale-4xx-puis-silence, decroissance-de-signalement (the Dave rule, gravity HIGH: losing the client who talks loses the only human sensor). Read-only: reports, never remediates -
--abandon-root <ABANDON_ROOT>— Instance root for--abandon— the instance's.cosmon/directory (containingwhispers/inbox/andstate/). Defaults to the parent of the resolved state dir -
--abandon-quiet-hours <ABANDON_QUIET_HOURS>— Quiet window in hours for the "puis silence" motifs of--abandon(default 24 — one daily patrol cadence)Default value:
24 -
--heal— Heal (the Deacon, ADR-137 §11 P3): run one detect → guard → remediate pass over the molecule-health anomaly catalog, mutating only the safe, reversible classes, each behind the §5 no-interference guard: A1 unsent-paste (delegate to the transport submit-retry), A4/A8 idle-after-complete / completed-unharvested (cs doneharvest from the orchestrator — never a worker self-done), A5 idle-no-progress (nudge), A6 overloaded (backoff hold). The collapse / integrity classes (A3/A7/A9) are reported but never auto-collapsed here (that is P4). Detection is keyed off control-plane state only — never a pane glyph (the be1e SEV-1 lesson). Pair with--dry-runfor a zero-mutation preview. Usecs healthfor the read-only, federation-wide catalog -
--dry-run— Dry-run: with--heal, compute and print the health report + the guarded actions the Deacon would take, but mutate nothing. The safe default for earning operator trust before enabling a scheduled heal pass -
--dialogue-scan— Capture each running worker's pane and classify any blocking dialogue sitting in it (tool-permission prompt vs. the Claude Code spend-/usage-limit dialog vs. a codex interactive dialog — update prompt, reasoning-level picker, rate-limit "switch model" menu; issue #85). The motivating incident: ten synthetic workers blocked on the spend-limit dialog with no human to press Enter. Per the be1e discipline (ADR-137 §2) pane text is read only to surface a finding — amoney_stakeclass always pages the operator viacs notifyand is never auto-confirmed; anunknownblock or alogin_requiredscreen (expired session, login menu) alerts too; a safepermissionprompt is auto-confirmed only when--auto-confirm-safeis also passed. A recognised codex dialog (read on codex panes only) is reported alongside itsclass(codex_dialogin--json) so the finding says why the worker is blocked, not only how severe. Runs on every patrol by default; the flag remains accepted for existing scheduled invocations. No keystroke is sent by defaultDefault value:
true -
--auto-confirm-safe— Opt in to firing the default-accept keystroke (Enter) on safe permission-class prompts only. Money stakes and unrecognised blocks are still never auto-confirmed — that refusal is encoded in the classifier, not in this flag. Off by default: the safe posture is to surface every block to a human -
--dialogue-lines <DIALOGUE_LINES>— Number of pane lines the dialogue scan captures per worker (default 40). The live prompt sits at the bottom of the pane, so a small tail is enough; raise it for TUIs that render tall dialogsDefault value:
40 -
--dialogue-blocked-after <DIALOGUE_BLOCKED_AFTER>— Blocked-duration threshold in seconds for the dialogue scan (default 900 = 15 min). A molecule whose progress has been frozen longer than this and is still sitting on a blocking dialogue escalates to a canary RED operator page — the heartbeat half of the primitive: "blocked > X min despite detection ⇒ RED"Default value:
900
cs fleet
Fleet template discovery and initialization
Usage: cs fleet <COMMAND>
EXAMPLES: cs fleet list-templates # installed templates cs fleet init research # scaffold a .fleet.toml from a template cs fleet resolve # flatten a composable fleet.toml (ADR-038) cs fleet resolve --json # NDJSON for scripting
SEE ALSO: cs deploy (instantiate a fleet from the .fleet.toml).
Subcommands:
list-templates— List available fleet templatesinit— Initialize a fleet from a template (copies to .cosmon/fleet.toml)resolve— Resolve a fleet.toml (follow[[fleet.include]]) and print the flattened fleet
cs fleet list-templates
List available fleet templates
Usage: cs fleet list-templates
cs fleet init
Initialize a fleet from a template (copies to .cosmon/fleet.toml)
Usage: cs fleet init [OPTIONS] <TEMPLATE>
Arguments:
<TEMPLATE>— Template name (fromcs fleet list-templates)
Options:
-o,--output <PATH>— Output path (default: .cosmon/fleet.toml)
cs fleet resolve
Resolve a fleet.toml (follow [[fleet.include]]) and print the flattened fleet
Usage: cs fleet resolve [PATH]
Arguments:
<PATH>— Path to the master fleet.toml (default: .cosmon/fleet.toml via walk-up)
cs wait
Wait — block until a molecule reaches a terminal (or requested) status
Usage: cs wait [OPTIONS] <MOLECULE>
EXAMPLES:
cs wait
This is kubectl-wait, not kubectl-watch. One molecule, bounded poll,
exits on target. Never poll cs observe in a shell loop.
After a whisper to a molecule already in the target status, the wait
also covers the worker's answer: it returns once feat/
SEE ALSO: cs observe (snapshot), cs peek (live fleet view).
Arguments:
<MOLECULE>— Molecule ID to wait on. Must be an exact ID — we never want a prefix to match the wrong molecule under a long-running wait
Options:
-
--for <FOR>— Statuses to wait for, comma-separated. Defaults to the terminal set socs tackle M && cs wait M && cs done Mjust worksDefault value:
completed,collapsed -
--timeout <TIMEOUT>— Maximum seconds to wait before giving upDefault value:
600 -
--poll-interval <POLL_INTERVAL>— Seconds between polls. Clamped internally to the remaining budget, so setting this larger than--timeoutstill terminates on timeDefault value:
5 -
--quiet— Suppress per-poll progress lines — only emit the final result. Implied when--jsonis set