Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Execution commands

These commands use physics-inspired names (nucleate, evolve, decay, spore, …). New to the vocabulary? See The physics vocabulary.

cs tackle

Tackle a molecule — spawn ONE worker on this node (always leaf; for DAG walks use cs run)

Usage: cs tackle [OPTIONS] <MOLECULE>

EXAMPLES: cs tackle task-example-0001 # worktree + tmux + Claude (one node) cs tackle --dry-run # print the bootstrap prompt cs tackle --no-worktree # reuse current directory cs tackle --base release/2.0 # cut from — and merge back to — that trunk

--base makes the integration branch a property of the MOLECULE: the worker's branch is cut from it, the name is persisted in the molecule's state, and cs done merges back into it with no COSMON_BASE_BRANCH in the environment. Without --base, the branch is cut from the ambient HEAD and cs done falls back to COSMON_BASE_BRANCH → origin/HEAD → main, exactly as before.

cs tackle is ALWAYS leaf — it spawns one worker on the named node and never walks the DAG. To walk a DAG of N≥1 nodes (1 = leaf, N = full orchestration), use cs run instead. Human only. Workers never self-tackle. Pairs with cs done.

The historical --leaf and --force-runtime flags are deprecated no-ops since the verb-unification: the routing decision is now the verb itself, not a flag on a polymorphic command.

SEE ALSO: cs run (DAG walk), cs done (teardown), cs wait (block on completion).

Arguments:
  • <MOLECULE> — Molecule ID, prefix, or fuzzy name (e.g. "ADR-15", "idea-2026")
Options:
  • --fleet <FLEET> — Fleet to use (default: molecule's fleet)

  • --workdir <WORKDIR> — Working directory override (default: .worktrees/{mol-id})

  • --base <BRANCH> — Integration base branch for this molecule (default: the ambient HEAD of the main checkout).

    The worker's feat/{mol-id} branch is cut from this ref instead of whatever the main checkout has checked out, and the branch name is persisted on the molecule so cs done merges back into it without any COSMON_BASE_BRANCH in the environment. Makes the base a property of the molecule rather than of the session that launched it.

  • --no-worktree — Skip git worktree creation (use current directory)

  • --dry-run — Skip tmux session — print the prompt to stdout instead

  • --permission-mode <PERMISSION_MODE> — Permission mode for Claude (default: based on molecule kind)

  • --force — Reclaim the molecule's tmux session and respawn (instead of reporting the running one). Also thaws a frozen molecule: the respawned worker is live, so the molecule reads running again. A session left behind by a dead worker is reclaimed without this flag — there is nothing there to protect

  • --name <NAME> — Override the tmux session name. ASCII alphanumerics and hyphens are kept; everything else is replaced with -. Max 50 chars. Default: {slug}-{shortid} derived from the molecule topic + id

  • --bypass-seal — Override the ADR-085 stress-test seal at dispatch (Layer 1).

    Without this flag, cs tackle of a --class stress-test molecule refuses dispatch unless prior.md + prior.b3 exist on disk and a matching cs witness attest event has been emitted. With it, the runtime writes a typed BypassReceipt to <molecule_dir>/bypass-receipt.json and emits EventV2::SealBypassed, then proceeds with dispatch. Requires --bypass-reason "<…>" — silent overrides are forbidden by ADR-085 §3.5.

  • --bypass-reason <TEXT> — One-line reason recorded in the BypassReceipt when --bypass-seal is used.

    Free-text but non-empty; the runtime refuses a blank reason because the entire point of the receipt is to surface accountability for the override (ADR-085 §3.5).

  • --adapter <NAME> — Worker-Spawn Port Adapter to dispatch (ADR-097 / C6; ADR-108 Q5a chain).

    Resolution order (highest priority first): this flag → formula-step adapter = "<name>" pin → $COSMON_DEFAULT_ADAPTER env var → per-galaxy .cosmon/config.toml::[adapters.default] → global ~/.config/cosmon/config.toml::[adapters.default] → built-in "local" (the Ollama-backed in-process loop). Values are looked up against the registered Adapter table (claude, aider, openai, anthropic, llama-cpp, local, …). An unknown name aborts the dispatch with a typed AdapterNotFound carrying the list of available names — no silent fallback. To restore the legacy Claude-Code default pass --adapter claude, export COSMON_DEFAULT_ADAPTER=claude, or set [adapters.default] = "claude" in either config file.

    Capability gate (noogram/cosmon #4)

    A formula may declare what its steps need of a worker (requires_capabilities = ["shell", "vcs"]). A local adapter (local / ollama / llama-cpp / llama) is an in-process chat loop with no shell, no VCS and no cs command, so such a pairing is refused with exit code 17 — before any worktree, pane or model preflight, and under --dry-run too. The molecule stays pending and re-tacklable. Re-run with a coding-agent adapter, or set COSMON_SKIP_CAPABILITY_GATE=1 to dispatch anyway. Formulas that declare nothing are unaffected on every adapter.

    Every invocation (with or without the flag) emits an EventV2::AdapterSelected envelope so the cat-test (jq -c 'select(.type == "adapter_selected")') can answer "which Adapter ran for this molecule?" without parsing shell history.

    Composition with cs run --resident (issue-#21, reconciled)

    The resident loop (cs run --resident) is not a second resolver; it is a composer that delegates to this one chain. Its scheduler owns only the two rung-1 flag intents — a per-molecule pin and the opt-in cs run --adapter <name> run directive — and stamps them onto the shelled cs tackle. When neither is present it stamps no --adapter flag, so this full six-level chain runs unchanged in the child: formula step → $COSMON_DEFAULT_ADAPTER → per-galaxy config → global config → the local floor. The floor is therefore reached under --resident iff it is reached under a bare cs tackle, and the operator's env and committed config are honoured identically on both paths — the #21 fix removed the resident-only --adapter local stamp that used to mask them. See cs run --help (--adapter) and cosmon_runtime::resident.

  • --model <MODEL_ID> — Per-molecule model pin — the model sibling of --adapter (see ADR-097).

    Resolution order (highest priority first): this flag → formula-step model = "<id>" pin → $COSMON_DEFAULT_MODEL (else the legacy $ANTHROPIC_MODEL) env var → per-galaxy .cosmon/config.toml::[adapters.<name>].default_model → global ~/.config/cosmon/config.toml::[adapters.<name>].default_modelfloor None (cosmon pins no model; the adapter's own default applies — byte-identical to today's no-pin behaviour).

    Strong is never inherited. Every dispatch resolves the model fresh; a strong (frontier) model is reachable only from this flag or a formula-step pin — a positive per-molecule act — never from a config/env default that could silently make an entire fleet expensive (the /model-hack leak this axis exists to close).

    The id is carried opaquely: cosmon does not check that it is legal for the resolved adapter. A recognisable cross-family pair produces a non-blocking advisory, but the Adapter remains the authority because custom endpoints can legitimately serve another family's model. Config default_model rows are scoped per adapter because a model id only has meaning inside its adapter.

  • --role-hint <ROLE> — Forensic-only role-of-origin hint propagated through to EventV2::AdapterSelected (ADR-097 / C6).

    Cosmon does not interpret this value — it is the academy-shim's channel for preserving the driver's vocabulary (a --role researcher invocation on the driver side becomes role_hint: "researcher" on the cosmon event), so the role of origin survives the seam between driver (roles) and cosmon (adapters). Optional; absent for direct operator invocations.

  • --fallback-from-local <CAUSE> — Loud opt-in fallback from the local default to a remote oracle after a decidable local hard-failure (Q5b).

    Pass a LocalFailureCause token — crash, oom, timeout, connection-refused, or any bespoke string (recorded verbatim as Other). This flag is the ONLY path from a local hard-failure to a remote oracle: there is no automatic in-loop fallback. It is meaningful only alongside a remote --adapter (claude / openai / anthropic / aider) — combining it with a local adapter is a contradiction and aborts the dispatch.

    When set, cs tackle mints an EventV2::LocalFallback line in the same atom as the RemoteEgressOptIn egress grant, so a remote call carrying a fallback cause can never reach the wire without a matching loud audit record — silent fallback is impossible by construction. Soft "the output looked bad" judgement is NOT a valid cause: that is undecidable (Rice) and belongs to acceptance tests, not this routing flag.

  • --by <ACTOR> — Actor class recording who dispatched this molecule — the anti-preemption lease.

    Accepts human (the default when the flag is absent — a direct operator invocation) or runtime:<pid> (the resident runtime cs run passes its own process id). The value is stamped onto the molecule's tackled_by field when the molecule flips to Running, so the walker can enforce "manual always wins": a human-claimed molecule is never raffled by the runtime, even if it briefly returns to Pending on a revision. This is cs tackle's only role in the lease — recording the claim; honouring it is the walker's job.

    Default value: human

cs done

Done — terminal teardown for a molecule (merge + cleanup, human-callable)

Usage: cs done [OPTIONS] <MOLECULE>

EXAMPLES: cs done task-example-0001 # merge + teardown cs done --strategy ff-only # linear history; attribution off cs done --force # skip completion check cs done --if-completed # silent no-op if not Completed

Not-the-worker. Legitimate callers: humans, external schedulers (cron/launchd), and transport watchdogs (tmux pane-died hooks via cs done --if-completed). Required to close the nucleate → tackle → wait → done cycle: without it the branch never merges and the tmux worktree persists.

--if-completed is the hook-friendly gate: exits success without touching state when the molecule is not Completed or already merged; behaves identically to plain cs done otherwise. Supersedes the former cs harvest verb (ADR-052 §D3).

BASE BRANCH — the branch this merge lands on is resolved once per run, in this order (first that answers wins):

  1. the molecule's own base, stamped by cs tackle --base <branch>
  2. the COSMON_BASE_BRANCH environment variable
  3. git symbolic-ref refs/remotes/origin/HEAD
  4. the literal main

Rung 1 is why a cs done fired from a tmux hook — whose environment froze when the tmux server started and never saw a later export — still merges onto the right trunk. Molecules tackled without --base resolve through rungs 2-4 exactly as they always did. cs done still refuses (NotOnBase) when HEAD is not the resolved base: git merges into the current HEAD, never into a branch by name.

SEE ALSO: cs complete (state transition only), cs tackle (counterpart).

Arguments:
  • <MOLECULE> — Molecule ID to tear down
Options:
  • --force — Proceed even if the molecule is not in a terminal state

  • --if-completed — Silent no-op when the molecule is not Completed or already merged.

    Hook-friendly gate for callers that do not know whether the molecule is ready for teardown — tmux pane-died hooks, patrol sweeps, and the legacy cs harvest alias. Exits success without touching state when the precondition is not met; otherwise, behaves exactly like cs done. Supersedes the stand-alone cs harvest verb (ADR-052).

  • --dry-run — Compute and display the teardown plan without executing any steps.

    Reports what cs done would do: worktree state (clean/dirty), whether a merge is needed, whether the tmux session is alive, whether a fleet worker is registered, and whether the branch exists.

  • --no-merge — Skip merging the worker's branch into the base branch

  • --no-worktree-remove — Skip removing the git worktree

  • --no-branch-delete — Skip deleting the worker's branch after merge

  • --no-kill — Skip killing the tmux session

  • --strategy <STRATEGY> — Merge strategy for the worker's branch.

    merge (default) creates a merge commit (git merge --no-ff) so parallel workers can land independently even when main has moved. ff-only preserves a strictly linear history and refuses anything that is not a fast-forward; it is refused when native attribution is configured because a fast-forward creates no trailer carrier.

    Default value: merge

    Possible values:

    • merge: Non-fast-forward merge (git merge --no-ff --no-edit)
    • ff-only: Fast-forward-only merge (git merge --ff-only)
  • --no-auto-propel — Disable auto-propel escalation on merge conflict.

    By default, when a merge conflict is detected, cs done escalates by sending a resume signal to the worker with rebase instructions, then retries the merge after a backoff delay. This flag restores the old behavior: abort immediately and print a manual-resolution message.

    Mechanical-first escalation: see docs/architectural-invariants.md

  • --propel-message <PROPEL_MESSAGE> — Custom message sent to the worker during auto-propel escalation.

    The default instructs the worker to rebase onto the base branch, resolve conflicts, run tests, and NOT call cs done itself.

  • --max-retries <MAX_RETRIES> — Maximum number of auto-propel escalation retries before giving up

    Default value: 3

  • --skip-pre-done-hook — Skip the blocking [hooks] pre_done gate for this invocation.

    The pre_done hook (when configured) runs before the merge and aborts teardown on a non-zero exit — the galaxy-owned Definition-of- Done gate. This flag is the human operator's kill-switch: it bypasses the gate entirely for a deliverable the operator knows is good but the script cannot see (e.g. evidence living outside the repo). Equivalent to setting the COSMON_SKIP_PRE_DONE_HOOK environment variable. No effect when no pre_done hook is configured.

  • --deploy-off-trunk — Run the [hooks] post_merge deploy hook even when this harvest merges into a parked work branch rather than the reference trunk.

    By default the post_merge hook is bounded to the trunk: it fires only when the resolved integration base is the galaxy's reference trunk (origin/HEAD, or main as a last resort). The hook deploys — the canonical just install refreshes the on-disk cs binary — so running it after a merge into an older parked branch would silently rejuvenate the operator's tool, dropping whatever the parked branch predates (task-20260725-b64f). When the merge targets a parked branch the hook is skipped with a warning naming the reason.

    This flag is the operator's explicit escape hatch for the rare-but- legitimate case of deploying from a parked branch on purpose. No effect when no post_merge hook is configured or when the merge already targets the trunk.

cs sync

Sync — base-sync the current worktree from main, stamping a Base-Sync trailer

Usage: cs sync [OPTIONS]

Options:
  • --base <BASE> — Base branch to sync from (defaults to main)

    Default value: main

  • --dry-run — Report what would happen without performing the merge

cs harvest

Harvest — close a completed-but-unmerged molecule by invoking cs done

Usage: cs harvest [OPTIONS] --molecule <MOLECULE>

EXAMPLES: cs harvest --molecule task-example-0001 # DEPRECATED — see below

DEPRECATED (ADR-052 §D3): use cs done --if-completed <mol> instead. The canonical path carries byte-identical semantics: silent no-op when the molecule is not Completed or already merged; full teardown otherwise. This alias will be removed after one release cycle.

SEE ALSO: cs done --if-completed (canonical), cs patrol --harvest (belt-and-suspenders sweep).

Options:
  • --molecule <MOLECULE> — Molecule to harvest. Required — cs harvest operates on one molecule per invocation. Use cs patrol --harvest for the sweep variant

  • --dry-run — Print what cs harvest would do without exec'ing cs done

  • --from-pane-died — Flag the invocation as caused by a tmux pane-died hook.

    ADR-052 child #4 (I4 + I8 + I10): the probe must emit its observation before acting on it. When set, cs harvest first appends a EventV2::WorkerExited event to events.jsonl (reason = pane_died) and then runs the normal harvest logic. Absent this flag, no WorkerExited is emitted — periodic cs patrol --harvest sweeps observe via witness, not via the kernel-level pane-died channel.

  • --exit-code <EXIT_CODE> — Exit code reported by tmux #{pane_dead_status} when the pane died.

    Only meaningful together with --from-pane-died. Accepts any signed 32-bit integer so the wait-status (which may encode signals) survives round-trip. Strings that fail to parse are treated as "no information" (None in the emitted event).

cs run

Run — walk a molecule DAG of N≥1 nodes via the resident runtime (ADR-016 Layer B)

Usage: cs run [OPTIONS] [MOLECULE]

EXAMPLES: tmux new -d -s runtime cs run --poll-interval 5 cs run # also valid: 1-node DAG = single dispatch cs run --force-runtime # bypass the ADR-048 backlog-sanity guard

Resident runtime — walks a DAG of N≥1 nodes. Calls cs tackle for each ready node and cs done automatically as predecessors complete. The single-node case (1 = leaf) is the same code path as the N-node case; cs tackle <id> is the no-walk equivalent if the operator wants exactly one worker without any runtime ceremony.

NEVER run cs run in the foreground; always detach via tmux so the pilot stays responsive.

SEE ALSO: cs tackle (single node, no runtime), docs/handbook.md#one-primitive.

Arguments:
  • <MOLECULE> — Root molecule ID (supports prefix matching like other commands).

    Required for the legacy DAG-policy mode. With --resident the loop walks the whole ensemble, so this argument is optional (any value, including _, is accepted and ignored).

    Default value: ``

Options:
  • --policy <POLICY> — Scheduling policy to use

    Default value: dag

    Possible values: dag, noop

  • --timeout <TIMEOUT> — Maximum seconds before the runtime exits. 0 means no timeout (default)

    Default value: 0

  • --poll-interval <POLL_INTERVAL> — Seconds between runtime ticks. Lower values are more responsive but increase store I/O

    Default value: 1

  • --no-teardown — Skip automatic teardown of completed molecules after the run

  • --sweep-every <SWEEP_EVERY> — ADR-038 Limit 1: re-walk the store every N ticks to absorb descendants nucleated dynamically by workers (mission-controller decompose, deep-think step 4, etc.) that are not reachable from the runtime's root via pre-existing typed links. Zero disables the sweep (default) — the scope is frozen at compile-plan time, which is the pre-2026-04-14 behavior

    Default value: 0

  • --force-runtime — Override the ADR-048 backlog-sanity guard on runtime bootstrap.

    When a dirty backlog would normally refuse runtime bootstrap (sediment ≥ threshold, default 5), --force-runtime bypasses the refusal and writes a runtime_guard_override audit event to events.jsonl so the override leaves a durable trail.

  • --max-actions <MAX_ACTIONS> — B3 — decreasing action budget (moussage bounds). Each applied runtime action costs one unit; when the budget floor is reached the loop exits with the NAMED reason budget_exhausted (exit code 90) instead of dispatching further. This is the well-founded measure that makes an unbounded moussage total. 0 = unbounded (default, operator-local behaviour unchanged). Server-side callers (the tenant drain path) pass the binding-derived value — the bound is never client-writable

    Default value: 0

  • --max-depth <MAX_DEPTH> — B1 — maximum DAG depth (longest dependency chain, in molecules). Checked at compile-plan time, BEFORE the loop starts: a plan deeper than the bound is refused with the NAMED error max_depth_exceeded (exit code 92), never started. 0 = unbounded (default)

    Default value: 0

  • --max-molecules <MAX_MOLECULES> — B2 — maximum molecules tolerated in the fleet while draining. Checked at compile-plan time AND on every loop tick (so mid-run nucleations count); exceeding it exits with the NAMED reason molecule_quota_exceeded (exit code 91). 0 = unbounded (default)

    Default value: 0

  • --residentADR-095 — switch to the fully event-sourced Resident Runtime loop.

    When set, the legacy in-process DagPolicy is bypassed and the new [cosmon_runtime::RuntimeLoop] takes over. The loop:

    • Shells out to cs ensemble --json, cs tackle, cs done exactly as a human operator would (RR-1). - Wakes on FS changes under .cosmon/state/ (notify backend) plus a --poll-interval heartbeat. - Writes an NDJSON trace line per loop iteration to .cosmon/state/runtime-trace.jsonl (RR-5). - Exits cleanly on SIGTERM / Ctrl-C. - Drains when the ensemble has no pending and no running.

    Does not require <molecule> — the loop walks the whole ensemble. The positional argument is accepted but ignored in resident mode; pass _ if you have nothing to name.

  • --affinityADR-145 — model-affinity ordering of the ready frontier.

    On a single-resident-model local oracle (ollama-g5: 48 GB ≈ one 120 B model in VRAM), an alternating frontier reloads the model (~40 GB off disk) on every dispatch. With --affinity the runtime clusters same-model molecules contiguously and drains the resident model first, so a same-model batch pays the load cost once. The per-molecule model is PRE-RESOLVED from each molecule's formula-step model = pin (the ADR-142 Incarnation model), since a pending frontier molecule has no ModelSelected event yet.

    Off by default: cloud dispatch (many models, no resident constraint) keeps pure critical-path order. The reorder is a permutation — the DAG semantics and the set of dispatched molecules are unchanged; only the order within a ready batch differs. Legacy DAG-policy mode only (not --resident).

  • --resident-model <RESIDENT_MODEL> — Model already warm in the oracle's VRAM at runtime start, so the affinity reorder drains its bucket first with no reload. Only read when --affinity is set; a cold start (unset) simply pays one extra load for the first bucket

  • --adapter <NAME>Opt-in run-wide adapter directive (resident mode only).

    The resident scheduler owns exactly one run-wide flag intent — this flag — and nothing below it (COSMON-DEV #21). Passing --adapter <name> is the operator's explicit, conscious choice to spend on that adapter for this run: it stamps every pin-less molecule dispatched — both static frontier nodes and children a worker nucleates dynamically mid-run (the converge/committee loop). A per-molecule pin still wins over it.

    When this flag is absent, the scheduler stamps nothing: the shelled cs tackle inherits the environment and runs the full canonical resolution chain itself (formula step → $COSMON_DEFAULT_ADAPTER → per-galaxy config → global config → the built-in local floor). So the operator's live env, session hammer, and committed config are all honoured under --resident exactly as they are under a bare cs tackle — the resident loop no longer masks them with a rung-1 --adapter local floor (the #21 defect). The local floor is still reached iff nothing higher speaks, so an inadvertent paid dispatch remains impossible: a paid adapter is chosen only by a conscious flag, formula step, env export, or committed config. See docs/adr (ADR-095) and the cs tackle adapter-chain docs for the single canonical resolution order.

cs spore

Spore germinates a whole polymer from a shareable spore.toml template (validate / run / export, ADR-140)

Usage: cs spore <COMMAND>

EXAMPLES: cs spore install github:noogram/cosmon/spores/cosmon-dev # fetch + place cs spore validate ./spore.toml --var subject="octopus cognition" cs spore run ./bundle/ --var subject="..." --var axes=a,b,c cs spore run ./spore.toml --allow-unchecked-seal # sealed, no TLC cs spore export ./spore.toml --out dist/ # bundle hash + ASTRA cs spore validate ./spore.toml --json # NDJSON expansion

VERBS: install fetch a shareable bundle and place it in this project, copying its recipes into .cosmon/formulas/ so their pins reach dispatch. validate parse + expand as a dry run; prints the ordered nucleate call list, germinates nothing. run parse + expand + seal gate, then germinate the polymer into the live state store. --json emits one NDJSON line per molecule. export content-addressed bundle hash + ASTRA descriptive layer (D6).

SEAL (ADR-140 D4): a sealed spore fails closed unless --allow-unchecked-seal is passed; the status line never claims 'verified' when TLC did not run.

SEE ALSO: cs nucleate (one molecule), ADR-140, docs/design/spore-impl-dag-manifest.md.

Subcommands:
  • validate — Parse + expand a spore as a dry run; print the ordered nucleate call list without germinating anything
  • run — Germinate the polymer: parse + expand + seal gate, then replay the call list against the live state store
  • export — Emit a content-addressed bundle id and an ASTRA descriptive layer (ADR-140 D6) for sharing the spore
  • install — Fetch a shareable bundle and place it into this project, installing its recipes into .cosmon/formulas/ so their per-step pins reach dispatch

cs spore validate

Parse + expand a spore as a dry run; print the ordered nucleate call list without germinating anything

Usage: cs spore validate [OPTIONS] <REF>

EXAMPLES: cs spore validate ./spore.toml --var subject="octopus cognition" cs spore validate ./bundle/ --var axes=a,b,c # directory ref cs spore validate ./spore.toml --json # NDJSON expansion

Dry run only: parse (N2) + expand (N3), print the ordered 'cs nucleate ... --blocked-by ...' call list, germinate nothing. The seal is reported but never gated here; use it to inspect what 'cs spore run' would create. Each --var is coerced into its declared ParamSchema type before expansion; a list param splits on commas.

SEE ALSO: cs spore run, cs spore export, ADR-140 D3.

Arguments:
  • <REF> — Path to a spore.toml manifest (or a directory containing one)
Options:
  • --var <KEY=VALUE> — Bind a parameter (repeatable: --var key=value). Values are coerced into the declared ParamSchema type before expansion

cs spore run

Germinate the polymer: parse + expand + seal gate, then replay the call list against the live state store

Usage: cs spore run [OPTIONS] <REF>

EXAMPLES: cs spore run ./spore.toml --var subject="..." --var axes=a,b,c cs spore run ./bundle/ --fleet default # directory ref cs spore run ./spore.toml --allow-unchecked-seal # sealed, no TLC cs spore run ./spore.toml --json # one NDJSON line/molecule

Germinates the whole polymer: parse + expand + seal gate, then replays the call list against the live state store via the canonical 'cs nucleate' path. Every germinated molecule is tagged temp:warm and wired to its blocked-by predecessors. The seal status note goes to stderr so --json stdout stays clean NDJSON.

SEAL (ADR-140 D4): a spore with no [spore.seal] germinates freely. A sealed spore fails closed unless --allow-unchecked-seal is passed, in which case the status line reads 'seal: present, NOT verified' and never 'verified'.

SEE ALSO: cs spore validate (dry run), cs run (DAG of existing molecules).

Arguments:
  • <REF> — Path to a spore.toml manifest (or a directory containing one)
Options:
  • --var <KEY=VALUE> — Bind a parameter (repeatable: --var key=value)

  • --allow-unchecked-seal — Germinate a sealed spore even though its .tla proof was not verified this run (TLC unavailable). The status line stays honest: seal: present, NOT verified (ADR-140 D4). Without this flag a sealed spore fails closed

  • --fleet <FLEET> — Fleet to germinate the polymer into

    Default value: default

  • --store-dir <DIR> — State store root (default: walk-up .cosmon)

cs spore export

Emit a content-addressed bundle id and an ASTRA descriptive layer (ADR-140 D6) for sharing the spore

Usage: cs spore export [OPTIONS] <REF>

EXAMPLES: cs spore export ./spore.toml # bundle hash to stdout cs spore export ./spore.toml --out dist/ # ASTRA into dist/ cs spore export ./bundle/ --json # machine-readable

Emits a content-addressed bundle id over the manifest and every recipe and seal file it references (BLAKE3, sorted paths), plus an ASTRA-compatible RO-Crate descriptive layer (ADR-140 D6) when [spore.astra].emit is true. The seal verdict is attached honestly: marked present/absent and never claimed verified. The bundle hash is stable: the same bundle content always yields the same id (content-addressing is the registry, ADR-039).

SEE ALSO: cs spore run, ADR-140 D6, ADR-039.

Arguments:
  • <REF> — Path to a spore.toml manifest (or a directory containing one)
Options:
  • --out <DIR> — Output directory for the ASTRA descriptive layer. Defaults to the manifest directory. The crate is always written here as ro-crate-metadata.json unless [spore.astra].output names a different (manifest-relative) path

cs spore install

Fetch a shareable bundle and place it into this project, installing its recipes into .cosmon/formulas/ so their per-step pins reach dispatch

Usage: cs spore install [OPTIONS] <SOURCE>

EXAMPLES: cs spore install github:noogram/cosmon/spores/cosmon-dev cs spore install https://github.com/noogram/cosmon/tree/main/spores/cosmon-dev cs spore install ../shared/bundle --dest spores/shared # local copy cs spore install github:o/r@v1 --expect-hash blake3:... # verified fetch cs spore install github:o/r --dry-run --json # plan only

Fetches the bundle (git remote or local path), places it under /spores// unless --dest says otherwise, and copies each [spore.formulas.*] recipe into .cosmon/formulas/ under the name the recipe DECLARES — which is the name 'cs tackle' resolves at dispatch. That second half is why the verb is called install and not add: without it a bundle germinates fine and then runs with every per-step adapter/model pin silently inert (task-20260725-eb3b).

SOURCE: a local path, 'github:owner/repo[/subdir][@ref]', a GitHub tree/blob URL, or any other git remote (use --git-ref / --subdir to pin one).

REFUSALS, all before anything is written: a bundle whose hash does not match --expect-hash; a bundle missing a file its manifest declares; a symlink inside the fetched tree; a non-empty destination (without --force); and a registry that already holds a DIFFERENT recipe of the same name (without --force), since overwriting changes what already-germinated molecules run. An identical recipe is a no-op, so re-installing is idempotent.

SEE ALSO: cs spore validate (inspect what was installed), cs spore export (the id --expect-hash checks), docs/cs-spore.md.

Arguments:
  • <SOURCE> — Where the bundle comes from: a local path, github:owner/repo[/dir][@ref], a GitHub tree/blob URL, or any other git remote
Options:
  • --dest <DIR> — Where to place the bundle. Defaults to <project>/spores/<spore-name>/
  • --git-ref <REF> — Branch, tag, or commit to fetch. Overrides a ref encoded in the source
  • --subdir <PATH> — Path to the bundle inside the checkout. Overrides one encoded in the source; the way to install from a subdirectory of a non-GitHub remote
  • --expect-hash <BLAKE3> — Refuse unless the fetched bundle hashes to exactly this id (as printed by cs spore export). Checked before anything is written
  • --no-formulas — Place the bundle but do not copy its recipes into .cosmon/formulas/. The bundle then germinates without its per-step adapter/model pins
  • --force — Overwrite a non-empty destination and replace conflicting recipes already in the registry. The copy is a merge: a file the new bundle carries replaces the one there, and a file it does not carry is left alone — nothing is deleted on your behalf
  • --dry-run — Report what would be installed and write nothing
  • --formulas-dir <DIR> — Formula registry to install recipes into (default: walk-up .cosmon/formulas)