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). -
--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 (Stopped, Error, Stale)
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— Collapse molecules whose work is still unharvested (commits ahead of base, or an unclean worktree).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. 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).
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 -
--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 120 s ago. The nudge text referencesbriefing.mdso the re-engaged worker re-reads its contract before continuing. Increments [cosmon_state::MoleculeData::nudge_count] (M5) -
--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-collapse— Aggressive orphan remediation: transition orphaned molecules toCollapsed(terminal) instead ofFrozen(recoverable). Default isFrozenbecause the molecule can be revived once the worker situation is understood;--auto-collapseis for cases where the operator wants the DAG to advance past the dead work and never revisit it -
--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— 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). 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 alerts too; a safepermissionprompt is auto-confirmed only when--auto-confirm-safeis also passed. Report-only by default (no keystroke) so it is safe to schedule -
--auto-confirm-safe— With--dialogue-scan, 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--dialogue-scancaptures 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--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.
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