| title | Simard CLI reference | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| description | Reference for the shipped `simard` command tree, the shared-state-root bridge between terminal sessions and the repo-grounded engineer loop, the `engineer read` audit companion, the shipped bounded `engineer copilot-submit` contract, and the legacy compatibility binaries that still expose selected older runtime behaviors. | |||||||||
| last_updated | 2026-04-03 | |||||||||
| review_schedule | as-needed | |||||||||
| owner | simard | |||||||||
| doc_type | reference | |||||||||
| related |
|
simard is the canonical operator-facing CLI.
The legacy simard_operator_probe and simard-gym binaries still ship for compatibility, but new operator workflows should use simard ....
This page documents the shipped operator-facing command tree. When a compatibility surface is listed as none, the command is canonical-only.
simard
|- engineer
| |- run <topology> <workspace-root> <objective> [state-root]
| |- read <topology> [state-root]
| |- terminal <topology> <objective> [state-root]
| |- terminal-file <topology> <objective-file> [state-root]
| |- terminal-recipe-list
| |- terminal-recipe-show <recipe-name>
| |- terminal-recipe <topology> <recipe-name> [state-root]
| |- copilot-submit <topology> [state-root] [--json]
| `- terminal-read <topology> [state-root]
|- meeting
| |- run <base-type> <topology> <structured-objective> [state-root]
| `- read <base-type> <topology> <state-root>
|- goal-curation
| |- run <base-type> <topology> <structured-objective> [state-root]
| `- read <base-type> <topology> [state-root]
|- improvement-curation
| |- run <base-type> <topology> <structured-objective> [state-root]
| `- read <base-type> <topology> <state-root>
|- gym
| |- list
| |- run <scenario-id>
| |- compare <scenario-id>
| `- run-suite <suite-id>
|- review
| |- run <base-type> <topology> <objective> [state-root]
| `- read <base-type> <topology> <state-root>
`- bootstrap
| `- run <identity> <base-type> <topology> <objective> [state-root]
|- ooda
| `- run [--cycles=N] [state-root]
|- goal
| |- list
| |- unblock <goal-id>
| `- unblock-all
|- memory
| |- stats [state-root] [--json]
| `- dump [state-root] [--type=TYPE] [--limit=N] [--json]
|- status [--json]
|- act-on-decisions
|- spawn <agent-name> <goal> <worktree-path>
|- handover [--canary-dir=PATH]
|- update
`- install
Bare simard prints this operator surface directly.
The simard goal subcommand tree is the operator surface for inspecting
and recovering the OODA goal board persisted in cognitive memory. It is
the manual counterpart to the
brain-failure auto-recovery branch
in dispatch_advance_goal. All subcommands resolve the state root via
$SIMARD_STATE_ROOT then fall back to $HOME/.simard, matching the
running daemon's resolution so the operator always reads/writes the
same snapshot.
Print the persisted goal board to stdout. Output is a header line plus one tab-separated row per active goal, then a one-line backlog summary followed (when non-empty) by tab-separated backlog rows:
active goals: 5 / 5
ID PRIORITY STATUS ASSIGNED DESCRIPTION
enhance-simard-meeting-experience p1 blocked: 🔒 [OODA-SAFEGUARD] OODA brain failing for 3 consecutive cycles; needs human review - enhance simard meeting experience
…
backlog: 0 item(s)
Exits non-zero on bridge-open / persistence errors. An empty board prints
(none) and exits zero.
simard goal add <priority> <description> [--repo <slug>]
Add a new active goal at the given <priority> (1–7). The goal id is derived
from <description> via goal_slug. Fails if a goal with the derived id is
already active or the board is at MAX_ACTIVE_GOALS capacity.
--repo <slug> (optional) routes the goal at a specific ecosystem repo under
~/src/. The slug is the bare directory name (e.g. amplihack-rs) and is
validated with validate_repo_slug (charset ^[A-Za-z0-9._-]{1,64}$; no ..,
no leading - or .). When omitted, the goal targets the daemon's own repo
("Simard", repo = None). The slug's existence as a git repo is checked
later, at engineer-spawn time — see
Goal target-repo routing (issue
#2359).
# Target the amplihack-rs ecosystem repo:
simard goal add 2 "Raise amplihack-rs branch coverage to 80%" --repo amplihack-rs
# Target Simard itself (default):
simard goal add 3 "Tidy the meeting REPL help text"The added id and priority are logged to stderr
([simard] goal add: '<id>' added at p<priority>).
Operator escape hatch — clears the goal's Blocked status
unconditionally (regardless of the reason text) and restores
NotStarted. Persists the snapshot via save_goal_board. Use this when
overriding any single goal (brain-failure marker, operator-set Blocked,
scope-blocked, etc.).
Exits non-zero if <goal-id> is not on the active board or if the
snapshot persist fails. The pre-restore status is logged to stderr.
Bulk-clear scoped narrowly to the deterministic brain-failure safeguard
marker (the 🔒 [OODA-SAFEGUARD] … sentinel emitted by the OODA
dispatcher after 3 consecutive brain failures). Goals with any other
Blocked reason (operator-set, scope-blocked, dependency-blocked,
subordinate-blocked) are intentionally untouched so the command is safe
to rerun. Idempotent: empty board → no-op, exit zero. The count of
cleared and skipped goals is logged to stderr.
Operator removal — drops one or more goals from the active board and
from the backlog by id. Variadic: accepts one or more ids in a single
invocation so a single command can sweep a known fixture vector
(simard goal remove stuck-a stuck-b operator-blocked working alpha).
Behaviour contract:
- Routes through the daemon's IPC writer (tier 1 of
launch_writer_bridge) when a daemon socket is reachable, otherwise takes the writer lock directly. The operator never needs to pause the daemon. - Persists via
save_goal_board_with_removalsso the requested ids are filtered after the merge-on-write step introduced by #1915. Goals whose ids are not listed are merged from the persisted snapshot exactly assave_goal_boardwould merge them — concurrent unrelated writers do not have their goals dropped. - Idempotent. Unknown ids are silently skipped (no error), so the
same command is safe to rerun. A short summary is logged to stderr:
removed=N skipped_unknown=M active_after=K backlog_after=L. No goal ids or descriptions are echoed to stdout to keep the surface scriptable. - Exits non-zero only on bridge-open / persistence failure, never on unknown ids.
- Goal payloads are not logged at any verbosity level. Operators wanting
before/after evidence should pipe
simard goal listeither side of the call.
Use this command when an operator has positively identified one or more
goals that must leave the board — for example, the synthetic fixtures
diagnosed in #1923 and
#1925. For unattended
sweeps that target the class of fixture-leak goal (placeholder
descriptions of the form Goal <id>), prefer
simard goal cleanup --placeholders
below.
Defence-in-depth sweep — removes every active or backlog goal whose
description matches the placeholder pattern emitted by the
active_goal() test helper in src/operator_cli/tests_goal.rs:
^Goal <id>$
i.e. the literal three-character prefix Goal , then a value byte-equal
to the goal's id, with no trailing characters. This is intentionally
narrow: production code paths never emit Goal <id> descriptions
outside #[cfg(test)] modules (verified by
rg "format!\(\"Goal \{" src/), so the false-positive risk is the
empty set under the current source tree.
Behaviour contract:
- Same persistence pathway as
simard goal remove— routes through the daemon's IPC writer, persists viasave_goal_board_with_removals, preserves concurrent unrelated writers. - Computes the id list to remove from the freshly read board, then
passes those ids into the same
force_remove_idsslot. The cleanup is therefore exactly as race-safe asgoal removeis. - Idempotent. Empty match set → no-op, exit zero. A summary is
logged to stderr in the same shape as
goal remove:removed=N skipped_unknown=0 active_after=K backlog_after=L. - Exits non-zero only on bridge-open / persistence failure.
Use this command as the live-cleanup tool when the fixture-leak class of corruption is suspected but the operator does not yet know the exact id vector — for example, when triaging a fresh #1923-style sighting. See How to clean a fixture leak from the live goal board for the full runbook.
The --placeholders flag is required so that future cleanup criteria
can be added as additional flags without changing the default behaviour.
Invoking simard goal cleanup with no criteria flag is an error
(exit code 2, usage message on stderr).
The simard memory subcommand tree is the operator surface for
inspecting the six-type cognitive-memory store on the
amplihack-memory-lib
backend, plus a guarded snapshot-restore. stats and dump are read-only
and safe to run while the OODA daemon holds the store — they route through
the daemon's memory socket when it is up and fall back to a direct on-disk open
when it is down. import is the one write path (restore-only) and must run
with the daemon stopped. The state root resolves via $SIMARD_STATE_ROOT then
$HOME/.simard, matching the daemon, so a bare invocation always targets the
live store.
See the full reference — output schema, type→field mapping, sampling caveats, and the stored-vs-recalled episode distinction — in Memory introspection CLI.
Print per-type counts (sensory, working, episodic (episodes),
semantic (facts), procedural (procedures), prospective (triggers))
plus a total, and a few sample rows per populated type. Counts come from
a single authoritative get_statistics() call, so all six types are
always reported.
$ simard memory stats
cognitive memory @ /home/azureuser/.simard/cognitive (via daemon socket)
TYPE COUNT
sensory 4
working 7
episodic 18
semantic 5 (facts)
procedural 5 (procedures)
prospective 5 (triggers)
---------------------
total 44
--json emits a stable object keyed by the raw field stems
(sensory/working/episodic/semantic/procedural/prospective) plus
total. A successful read of an empty store prints all-zeros and exits
zero; only an unparseable invocation or a bridge-open failure exits
non-zero.
Like stats, plus a larger set of sample rows per type for eyeballing
content. --type restricts to one of facts, episodes, procedures,
working, sensory; --limit caps rows per type (default 10).
triggers (prospective) is count-only — the store has no read-only
prospective enumerator, so dump never row-samples triggers (see
Memory introspection CLI). When a sampler is
unavailable over the daemon socket (e.g. the library's get_episodes),
dump prints the count with (samples unavailable over IPC) and
continues — run with the daemon stopped for full rows.
Restore a cognitive-memory snapshot (a backup's cognitive_snapshot.json) back
into the store. Introduced by issue #2550 as the recovery path after the
2026-07-04 corrupt-WAL data-loss incident. import is idempotent — it
deduplicates by content, so it is safe to re-run and safe to run onto a
partially-populated store — and must run with the daemon stopped because it
writes to the store. The daemon also auto-restores from the newest good snapshot
on startup when the live store is empty. See
Memory introspection CLI and the
WAL Recovery Runbook.
simard status [--json] prints one consolidated operational report — the
unified telemetry status snapshot. It assembles a single
StatusSnapshot from durable, process-agnostic
sources (the daemon's ~/.simard/telemetry/metrics_snapshot.json, the cost
ledger, self_metrics, memory IPC, systemctl show simard.service + /proc,
and gh) — never by grepping journald — so it returns the same numbers whether
or not it runs in the daemon process. The dashboard Status tab and the TUI
Status tab render the same snapshot.
- Default — the canonical terminal layout:
DAEMON / UPTIME,RESOURCE SNAPSHOT,LLM USAGE,MEMORY / BRAIN,GYM,GOAL BOARD,ACTIVE WORKSTREAMS,COMPLETED WORK,SELF-IMPROVEMENT, andTELEMETRY / UNEXPECTED SIGNALS. --json— the serializedStatusSnapshot; each section is wrapped in an envelope withavailability(ok/unavailable/error) andfreshness(live/stale/absent) so scripts can tell a real0from "unknown".
The command never panics and always exits zero on a successful assembly, even
when individual sources are degraded — those sections render stale/absent
rather than failing the report. The state root resolves via $SIMARD_STATE_ROOT
then $HOME/.simard, matching the daemon.
See the operator how-to for a full rendered example
and per-section interpretation, the
StatusSnapshot API for the types and --json
schema, and the telemetry metrics reference for the
metric catalog behind it.
Self-update the binary to the latest GitHub release. Downloads the release asset matching the current platform and replaces the running binary.
Install the Simard binary to ~/.simard/bin. Used by the npx wrapper (npx github:rysweet/Simard install) to persist the binary for direct CLI use.
Run the post-deploy health probe against the live store and print a report. The
five probes are version_advanced, memory_intact, goal_board_intact,
brains_llm_backed, and no_quarantine; the report is healthy only when every
probe is. --json emits the structured SelfHealthReport; --pre-deploy-facts=N
supplies the memory baseline the self-deploy orchestrator captures before the
swap. Exit code is 0 when healthy, non-zero otherwise. See the
self-deploy API reference.
Close the merged-but-not-running gap on demand (operator-only — the recipe never
live-redeploys the daemon). With --check it reports deploy drift
(running-vs-merged) and makes no changes; --json emits the DeployDrift JSON.
Without --check it drives the full build-from-source self-deploy. It runs from
any working directory: it first git fetches and checks out the merged
head (not the cwd's HEAD) in a cwd-independent source repo, then builds that
commit into a persistent warm target dir (~/.simard/self-deploy-target/,
incremental ~2–3 min) before the unchanged safety sequence — build → gate →
dual protective backup → drain → orphan-reap → atomic swap → systemd restart →
health check, rolling back to the previous binary on a failed health check. A
source-resolution, fetch, or checkout failure aborts loudly before the daemon
is touched (never a cwd-HEAD fallback). SIMARD_SELF_DEPLOY_REPO overrides the
source repo. See
reconcile-and-self-deploy,
run self-deploy from any directory,
self-deploy source-prep, and
verify and roll back a self-deploy.
| Canonical command | Compatibility surface |
|---|---|
simard engineer run ... |
simard_operator_probe engineer-loop-run ... |
simard engineer terminal ... |
simard_operator_probe terminal-run ... |
simard engineer terminal-file ... |
simard_operator_probe terminal-run-file ... |
simard engineer terminal-recipe ... |
simard_operator_probe terminal-recipe-run ... |
simard engineer terminal-read ... |
simard_operator_probe terminal-read ... |
simard engineer read ... |
simard_operator_probe engineer-read ... |
simard meeting run ... |
simard_operator_probe meeting-run ... |
simard meeting read ... |
simard_operator_probe meeting-read ... |
simard goal-curation run ... |
simard_operator_probe goal-curation-run ... |
simard goal-curation read ... |
none |
simard improvement-curation run ... |
simard_operator_probe improvement-curation-run ... |
simard improvement-curation read ... |
simard_operator_probe improvement-curation-read ... |
simard review run ... |
simard_operator_probe review-run ... |
simard review read ... |
simard_operator_probe review-read ... |
simard bootstrap run ... |
simard_operator_probe bootstrap-run ... |
simard gym ... |
simard-gym ... |
Shipped terminal surface: simard engineer copilot-submit <topology> [state-root] [--json]. It has no compatibility surface and is documented later on this page as the bounded one-shot local Copilot submission contract.
When a command accepts [state-root], Simard validates it before any persistence write or read that depends on durable operator state.
Rejected inputs include:
- any path containing
.. - an existing path that is not a directory
- a symlink root
Safe state roots are canonicalized once and then reused for the rest of the command.
Three operator-probe read subcommands publish the positional argument as
<state-root> (required) rather than [state-root] (optional):
simard meeting read <base-type> <topology> <state-root>simard improvement-curation read <base-type> <topology> <state-root>simard review read <base-type> <topology> <state-root>
When <state-root> is omitted, these three commands hard-fail with the
SimardError::MissingRequiredConfig variant and a stable error message of
the form:
error: missing required config 'state-root': state-root is required for `simard <subcommand> read <base-type>`: pass the positional <state-root> argument explicitly. The SIMARD_STATE_ROOT environment variable is not honored for this command.
<subcommand> is one of meeting, improvement-curation, review.
<base-type> is the literal value the runtime substitutes from the
operator-supplied argument. For example, calling simard meeting read local-harness single-process (with no <state-root>) prints:
error: missing required config 'state-root': state-root is required for `simard meeting read local-harness`: pass the positional <state-root> argument explicitly. The SIMARD_STATE_ROOT environment variable is not honored for this command.
The SIMARD_STATE_ROOT environment variable is intentionally not honored
for these three reads — setting it does not change behavior, and the
operator still gets the error above. This audit-focused contract is tracked
under issue #1909 /
audit #1910 and is
documented end-to-end in
Operator read-subcommand state-root contract.
The simard goal-curation read command keeps the optional [state-root]
positional and still honors SIMARD_STATE_ROOT for operator parity with
its run counterpart. All ... run paths likewise keep the optional
positional and the env fallback.
The cognitive-memory IPC socket (the Unix-domain socket that fronts the
daemon's writer lock — see
bridge helpers) lives next to
the cognitive-memory database it fronts, not at a fixed
$HOME/.simard/memory.sock. This is what makes
SIMARD_STATE_ROOT=$TMPDIR/... actually hermetic: a test that overrides
the state root no longer collides with the live daemon's socket on a
shared user account, and a per-state-root daemon can publish its own
socket without stomping on ~/.simard/memory.sock.
Resolution order, in priority:
SIMARD_MEMORY_SOCKET— explicit override. When set, every Simard binary uses this path verbatim for both server bind and client connect. Use this when running a daemon and clients with mismatched state roots intentionally (e.g. an operator REPL that wants to target a non-default DB while the system daemon owns~/.simard/state).<state_root>/memory.sock— the default.state_rootis resolved via the samedefault_state_root()helper used for the DB (SIMARD_STATE_ROOT→$HOME/.simard/state), so the socket automatically follows any state-root override.
The resolved path is exposed to library callers as
memory_ipc::socket_path_for(state_root: &Path) -> PathBuf and surfaced
to operators on stderr when the daemon binds the socket
(memory_ipc: bound socket at <path>). Both call sites (daemon bind,
client connect) MUST use the same helper — there is no inline
$HOME/.simard/memory.sock literal in production code.
Operator note. If you migrate from a pre-fix Simard build, the daemon will publish its socket at
<state_root>/memory.sockon next start. Stale~/.simard/memory.sockfiles from older daemons are harmless and can be removed: nothing reads or writes them. The dashboard and meeting REPL will pick up the new path automatically because they share the same resolver. See How to clean a fixture leak from the live goal board for the connected remediation.
The simard engineer ... namespace now exposes two distinct shipped operator-visible surfaces:
engineer terminal,engineer terminal-file,engineer terminal-recipe, andengineer terminal-readare bounded local terminal session surfacesengineer runandengineer readare the repo-grounded engineer loop and its read-only audit companion
engineer copilot-submit now sits on the terminal-session side of that boundary as a stricter one-shot local Copilot submission surface.
The bridge between them is explicit and local-only:
- reuse the same explicit
state-root - inspect the persisted terminal summary through
terminal-read - invoke
engineer runexplicitly with a realworkspace-rootand engineer objective
Simard writes mode-scoped handoffs under the shared root:
latest_terminal_handoff.jsonlatest_engineer_handoff.jsonlatest_handoff.jsonas the compatibility bridge
Readback is fail-closed:
terminal-readpreferslatest_terminal_handoff.jsonengineer readpreferslatest_engineer_handoff.json- lookup of
latest_handoff.jsonhappens only when the mode-scoped file is absent - if a mode-scoped handoff exists but is malformed, the command fails instead of silently replaying older data
The bridge is descriptive continuity only. It does not auto-resume, auto-launch engineer mode, infer a repo path, or replace the engineer loop's inspect -> plan -> act -> verify contract.
Runs the repo-grounded bounded engineer loop against the selected repository.
Key behavior:
- inspects the selected repo before acting
- prints the chosen bounded action and explicit verification steps
- may render a separate terminal continuity section when the same
state-rootalready contains a valid terminal-scoped handoff - persists memory, evidence,
latest_engineer_handoff.json, and compatibilitylatest_handoff.jsonunderstate-root - surfaces active goals and carried meeting decisions from the same durable state
- keeps terminal continuity descriptive only; it does not override
workspace-root, the engineer objective, planning, or verification
Example:
STATE_ROOT="$(mktemp -d /tmp/simard-engineer.XXXXXX)"
ENGINEER_OBJECTIVE=$'inspect the repository state
run one safe local engineering action
verify the outcome explicitly
persist truthful local evidence and memory'
simard engineer run single-process "$PWD" "$ENGINEER_OBJECTIVE" "$STATE_ROOT"To continue from a terminal recipe or terminal session, reuse the same STATE_ROOT. The terminal bridge stays local and explicit; Simard does not infer the engineer objective for you.
This is the read-only audit companion to simard engineer run. It inspects the latest persisted engineer state without resuming execution, repairing artifacts, or re-running the engineer loop.
Behavior:
- reuses the same canonical default durable root as
engineer runwhen[state-root]is omitted - validates
topologybefore deriving that default root, so the default still follows the shipped engineer runtime pairing - requires any explicit
state-rootto already exist as a directory - requires
memory_records.jsonandevidence_records.jsonto already exist as readable regular files; symlinked artifacts are rejected - prefers
latest_engineer_handoff.jsonas the authoritative engineer readback artifact and falls back tolatest_handoff.jsononly when the engineer-scoped handoff is absent - prints which handoff artifact was used so mode-scoped readback stays operator-visible
- requires the persisted handoff session objective to already be trusted
objective-metadata(chars=<n>, words=<n>, lines=<n>); malformed or tampered metadata fails instead of being replayed - uses the standalone
memory_records.jsonandevidence_records.jsonfiles as durability checks and supporting evidence counts; if they disagree with the handoff snapshot, the handoff-derived values win - renders only redacted objective metadata such as
objective-metadata(chars=150, words=21, lines=1), never the raw engineer objective text - requires carried meeting state to remain valid persisted meeting records; malformed carried-meeting data fails instead of being downgraded to raw strings
- when the same state root contains a valid terminal-scoped handoff, renders a separate terminal continuity section with sanitized terminal summary fields
- strips terminal control sequences and secret-shaped values from every displayed string before printing it
- prints a stable operator-visible order: runtime header, handoff session summary, repo grounding, carried context, terminal continuity, selected action summary, verification summary, durable record counts
- fails explicitly for invalid
state-rootvalues and for missing, unreadable, or malformed persisted engineer state
When [state-root] is omitted, the command reuses the same canonical durable root that engineer run already writes:
target/operator-probe-state/engineer-loop-run/simard-engineer/terminal-shell/<topology>
Example:
simard engineer read single-process "$STATE_ROOT"Output shape:
Probe mode: engineer-read
Engineer handoff source: latest_engineer_handoff.json
Identity: simard-engineer
Selected base type: terminal-shell
Topology: single-process
State root: /tmp/simard-engineer.XXXXXX
Session phase: complete
Objective metadata: objective-metadata(chars=150, words=21, lines=1)
Mode boundary: engineer
Repo root: /path/to/repo
Repo branch: main
Repo head: 4b6cb7de0179e9adb480dfdea1cb2aee4a5d5e18
Worktree dirty: false
Changed files: <none>
Active goals count: 1
Active goal 1: p1 [active] Preserve meeting handoff
Carried meeting decisions: 1
Carried meeting decision 1: preserve meeting-to-engineer continuity
Terminal continuity available: yes
Terminal continuity source: latest_terminal_handoff.json
Terminal recipe source: foundation-check
Terminal working directory: .
Terminal last output line: terminal-recipe-ok
Selected action: cargo-metadata-scan
Action plan: Inspect the repo, query Cargo metadata without mutating files, and verify repo grounding stayed stable.
Verification steps: confirm cargo metadata returns valid workspace JSON || confirm repo root, branch, HEAD, and worktree state stayed stable || confirm carried meeting decisions and active goals stayed stable
Action status: success
Changed files after action: <none>
Verification status: verified
Verification summary: Verified local-only engineer action 'cargo-metadata-scan' against stable repo grounding, unchanged worktree state, and explicit repo-native action checks.
Memory records: 3
Evidence records: 19
Runs one bounded local terminal session on the canonical CLI instead of requiring the legacy probe binary.
This is not the repo-grounded engineer loop. It is the honest terminal-session surface that operators can use before deciding to launch engineer run.
Key behavior:
- selects the
terminal-shellbase type explicitly - accepts bounded terminal objectives with
command:/input:lines pluswait-for:orexpect:checkpoints so a run can pause for expected output before sending the next line - preserves truthful adapter reflection and now renders the terminal audit trail directly on the run surface, including ordered terminal steps, observed checkpoints, the last visible output line, and a sanitized transcript preview
- prints explicit next-step guidance for continuing into
engineer runwith the samestate-root - persists
latest_terminal_handoff.jsonand compatibilitylatest_handoff.jsonunder the shared root - fails visibly for unsupported topology and invalid state-root inputs
- fails explicitly if a requested wait checkpoint never appears instead of pretending the terminal interaction succeeded; when that failure is caused by a missing or non-executable command, the shell's own diagnostic (for example
command not found) is surfaced in the error so the offending command is named - when the underlying shell exits non-zero, reports an actionable error instead of a bare status code: exit
127is explained as a command that could not be found onPATH(and126as a found-but-not-executable command), and the shell's own diagnostic line (for examplebash: say: command not found) is surfaced so the offending command is named - launches the child PTY with a usable
PATH(falling back to the standard system bin directories when the inherited environment has none) and resolves the default shell against$SHELL//bin/bash//bin/shwhen the platform default is absent, so ordinary commands do not silently fail with exit127 - keeps
simard_operator_probe terminal-run ...available for compatibility
Example:
STATE_ROOT="$(mktemp -d /tmp/simard-terminal.XXXXXX)"
simard engineer terminal single-process $'working-directory: .
command: printf "terminal-foundation-ready\n"
wait-for: terminal-foundation-ready
command: printf "terminal-foundation-ok\n"' "$STATE_ROOT"Runs the same bounded terminal-backed engineer substrate, but loads the session recipe from a reusable UTF-8 text file instead of requiring the whole objective inline on the command line.
Behavior:
- reuses the same
terminal-shellbase type and bounded wait/send terminal semantics asengineer terminal - requires
<objective-file>to exist as a readable regular file; symlinks and non-files fail explicitly - preserves the same structured terminal audit trail, mode-scoped terminal handoff, and engineer-next-step guidance as
engineer terminal - keeps
simard_operator_probe terminal-run-file ...available for compatibility
Example:
cat > /tmp/simard-terminal.recipe <<'EOF'
working-directory: .
command: printf "terminal-file-ready\n"
wait-for: terminal-file-ready
input: printf "terminal-file-ok\n"
EOF
simard engineer terminal-file single-process /tmp/simard-terminal.recipe "$STATE_ROOT"Lists the built-in named terminal session recipes shipped under prompt_assets/simard/terminal_recipes/.
Prints the selected built-in terminal recipe asset and its bounded session contents before execution.
Runs one of the built-in named terminal session recipes through the same bounded PTY-backed substrate as engineer terminal and engineer terminal-file.
Behavior:
- loads a named recipe from
prompt_assets/simard/terminal_recipes/*.simard-terminal - currently ships
foundation-checkfor the minimal bounded PTY sanity path,copilot-status-checkfor a bounded local Copilot wrapper availability probe, andcopilot-prompt-checkfor a bounded real interactive prompt-start-and-exit path; the stricter one-shot task submission slice is the dedicatedengineer copilot-submitcommand documented below - preserves the same structured terminal audit trail, mode-scoped terminal handoff, and engineer-next-step guidance as the other terminal session surfaces
- fails explicitly when the requested recipe name is unknown or invalid
copilot-status-checkis intentionally narrow: it only runs the fixed local argvamplihack copilot -- --versioncopilot-status-checkdoes not inspect GitHub auth state, does not open an interactive Copilot session, and fails closed whenamplihackis missing or the expected version signal is absentcopilot-prompt-checkis the first truthful interactive Copilot slice: it startsamplihack copilot, waits for the real prompt guidance text, sends/exit, and waits for the resume hint before succeedingcopilot-prompt-checkstill does not submit a task, inspect auth state, or claim general Copilot orchestration beyond prompt reachability and clean exit- keeps
simard_operator_probe terminal-recipe-run ...available for compatibility
Example:
simard engineer terminal-recipe-list
simard engineer terminal-recipe-show foundation-check
simard engineer terminal-recipe-show copilot-prompt-check
simard engineer terminal-recipe-show copilot-status-check
simard engineer terminal-recipe single-process foundation-check "$STATE_ROOT"This command ships as one bounded truthful local Copilot task-submission attempt that reuses the same terminal-shell PTY substrate as the other terminal surfaces.
Behavior:
- launch the real local argv
amplihack copilotin the current repository context only - use the checked-in flow contract at
prompt_assets/simard/terminal_recipes/copilot-submit.json - accept no
workspace-root, no free-form objective, and no arbitrary task text; the submitted payload must stay fixed and built in - restore workflow-only
.claude/context/PROJECT.mdand.claude/context/PROJECT.md.bakto their pre-launch contents when the Copilot wrapper rewrites them, so truthful terminal probing does not leave repo dirt behind - validate
topologyand[state-root]with the same rules as the other terminal session surfaces; the first implementation only needssingle-process - require the exact ordered visible startup checkpoints from the flow asset, including
Describe a task to get started.and the guidance lineType @ to mention files, # for issues/PRs, / for commands, or ? for shortcuts - submit the fixed payload once after startup checkpoints are satisfied, then observe the visible submit hint from the checked-in flow contract
- declare
successonly when the live PTY transcript satisfies a supportable checked-in post-submit contract after terminal control sequences are stripped from the visible text; the current shipped flow intentionally fails closed before claiming that because the real UI exposesctrl+s run commandrather than a truthful newline submission path - return
unsupportedwhen the Copilot process launched but the visible prompt flow exited early, drifted, stalled after partial visible startup evidence, required folder trust confirmation, required the visible submit hotkey Simard cannot drive through this line-input PTY surface, or surfaced wrapper-specific launch errors - reserve
runtime-failurefor Simard-side command failures such as invalid inputs, local launch failures, or persistence/readback failures before a trustworthy submit result can be claimed - classify startup timeouts after partial visible startup evidence as
unsupportedwithmissing-startup-banner,missing-guidance-checkpoint,workflow-wrapper-noise, orunexpected-startup-text; only zero-evidence startup timeouts stayruntime-failure - persist the same terminal-scoped handoff artifacts as the other terminal surfaces on
successand on anyunsupportedresult that captured truthful terminal evidence; aruntime-failuremay leave partial audit data but must not invent a complete submit summary - reserve
reason_codeforunsupported;successcarries none, andruntime-failureremains an explicit CLI error unless the implementation later publishes a separate failure-code contract - keep
--jsonas a formatting choice only; it must not broaden capability or relax checkpoint matching - keep
copilot-status-checkandcopilot-prompt-checkunchanged as the narrower probe surfaces - avoid GitHub auth inspection, arbitrary slash-command support, worktree creation or reuse, and any claim of general Copilot orchestration beyond this one checked-in flow
Explicit unsupported reason codes:
process-exited-earlyunexpected-startup-textmissing-startup-bannermissing-guidance-checkpointtrust-confirmation-requiredsubmit-hotkey-requiredcopilot-wrapper-errorworkflow-wrapper-noise
Invocation:
simard engineer copilot-submit single-process "$STATE_ROOT"
simard engineer copilot-submit single-process "$STATE_ROOT" --jsonThe eventual operator-visible and --json outputs should make these facts explicit without inventing broader capability:
- the mode boundary is terminal
- the selected base type is
terminal-shell - the checked-in flow asset and fixed payload identifier are visible
- the final outcome is
success,unsupported, orruntime-failure, but the current shipped flow is expected to returnunsupporteduntil Simard can truthfully drive the observed submit gesture ordered_stepsrecords only the launch, waits, and fixed payload step the PTY path actually reached before the flow stopped; startup drift must not pretend the payload step ran- any
unsupportedresult carries one of the explicit reason codes above - the ordered steps, observed checkpoints, last meaningful output line, and transcript preview remain auditable
- later
terminal-readandengineer runsurfaces can point back to the same terminal-scoped handoff artifact when truthful continuity exists
If you only need local wrapper availability or prompt reachability, keep using copilot-status-check or copilot-prompt-check instead.
This is the read-only audit companion to simard engineer terminal. It inspects the latest persisted terminal session state without replaying commands or resuming the PTY session.
Behavior:
- reuses the same canonical default durable root as
engineer terminalwhen[state-root]is omitted - requires any explicit
state-rootto already exist as a directory - requires
memory_records.jsonandevidence_records.jsonto already exist as readable regular files; symlinked artifacts are rejected - prefers
latest_terminal_handoff.jsonas the authoritative terminal readback artifact and falls back tolatest_handoff.jsononly when the terminal-scoped handoff is absent - prints which handoff artifact was used so terminal readback stays operator-visible
- renders mode boundary, terminal shell, working directory, command count, wait count, ordered terminal steps, satisfied wait checkpoints, last output line, transcript preview, and engineer-next-step guidance in stable operator-visible order
- when
engineer copilot-submitpersisted truthful audit data, the same readback exposes the Copilot flow asset, submit outcome, fixed payload identifier, and any explicit unsupported reason code - strips terminal control sequences and secret-shaped values from displayed output before printing it
- fails explicitly for invalid
state-rootvalues and for missing, unreadable, or malformed persisted terminal state
When [state-root] is omitted, the command reuses the same canonical durable root that engineer terminal already writes:
target/operator-probe-state/terminal-run/simard-engineer/terminal-shell/<topology>
Example:
simard engineer terminal-read single-process "$STATE_ROOT"Output shape:
Probe mode: terminal-read
Terminal handoff source: latest_terminal_handoff.json
Mode boundary: terminal
Selected base type: terminal-shell
Topology: single-process
Terminal working directory: .
Terminal recipe source: foundation-check
Terminal steps count: 2
Terminal last output line: terminal-recipe-ok
Terminal transcript preview:
Engineer next step: simard engineer run <topology> <workspace-root> <objective> <same-state-root>
Captures decisions, risks, next steps, open questions, and optional goal updates without editing code.
Supported structured lines include:
agenda: ...update: ...decision: ...risk: ...next-step: ...open-question: ...goal: title | priority=1 | status=active | rationale=...
Example:
STATE_ROOT="$(mktemp -d /tmp/simard-meeting.XXXXXX)"
MEETING_OBJECTIVE="$(cat <<'EOF2'
agenda: align the next Simard workstream
decision: preserve meeting-to-engineer continuity
risk: workflow routing is still unreliable
next-step: keep durable priorities visible
open-question: how aggressively should Simard reprioritize?
goal: Preserve meeting handoff | priority=1 | status=active | rationale=meeting decisions must shape later work
EOF2
)"
simard meeting run local-harness single-process "$MEETING_OBJECTIVE" "$STATE_ROOT"Reads the latest durable meeting record without mutating it.
Key behavior:
- loads the latest persisted meeting decision record from the validated
state-root - requires the positional
<state-root>and hard-fails if it is omitted;SIMARD_STATE_ROOTis not honored. See Operator read-subcommand state-root contract - validates
base-typeandtopologybefore further work - requires explicit read-layout inputs before probing: the state root itself must already exist as a directory and
memory_records.jsonmust already be present - prints sections in this fixed order: latest agenda, updates, decisions, risks, next steps, open questions, goal updates, latest meeting record
- includes explicit zero-state lines for empty update, decision, risk, next-step, open-question, and goal-update sections
- strips terminal control sequences from persisted meeting text before printing it
- preserves
meeting runas the only meeting-state mutation workflow - fails explicitly for invalid
state-rootvalues and for missing, unreadable, or malformed persisted meeting state
Example:
simard meeting read local-harness single-process "$STATE_ROOT"Output shape:
Probe mode: meeting-read
Identity: simard-meeting
Selected base type: local-harness
Topology: single-process
State root: /tmp/simard-meeting.XXXXXX
Meeting records: 1
Latest agenda: align the next Simard workstream
Updates count: 1
Update 1: durable memory foundation merged in PR 29
Decisions count: 1
Decision 1: preserve meeting-to-engineer continuity
Risks count: 1
Risk 1: workflow routing is still unreliable
Next steps count: 1
Next step 1: keep durable priorities visible
Open questions count: 1
Open question 1: how aggressively should Simard reprioritize?
Goal updates count: 1
Goal update 1: p1 [active] Preserve meeting handoff
Latest meeting record: agenda=align the next Simard workstream; ...
Maintains durable backlog records and the active top five goals.
Supported structured lines include:
goal: title | priority=1 | status=active|proposed|paused|completed | rationale=...
Example:
simard goal-curation run local-harness single-process "goal: Keep Simard's top 5 goals current | priority=1 | status=active | rationale=long-horizon stewardship is a shipped product responsibility" "$STATE_ROOT"goal-curation run is the mutation path. It curates durable goal state and still surfaces the active top-five summary for quick operator feedback.
When [state-root] is omitted, goal-curation run writes under the canonical durable root for the selected shipped runtime pairing:
target/operator-probe-state/goal-curation-run/simard-goal-curator/<base-type>/<topology>
Reads the stored durable goal register without mutating it.
Key behavior:
- loads the stored goal register from the validated
state-root - reuses the same canonical default durable root as
goal-curation runwhen[state-root]is omitted - validates
base-typeandtopologybefore deriving that default root - prints sections in this fixed order:
active,proposed,paused,completed - includes explicit zero-state lines for empty sections
- strips terminal control sequences from persisted goal text before printing it
- preserves
goal-curation runas the only curation workflow - fails explicitly for invalid
state-rootvalues and unreadable or malformed durable goal state
Example:
simard goal-curation read local-harness single-process "$STATE_ROOT"You should see output shaped like:
Goal register: durable
State root: /tmp/simard-goal-register.XXXXXX
Active goals count: 2
Active goal 1: p1 [active] Keep Simard's top 5 goals current
Active goal 2: p2 [active] Preserve meeting-to-engineer continuity
Proposed goals count: 1
Proposed goal 1: p3 [proposed] Promote benchmark drift alerts
Paused goals count: 1
Paused goal 1: p4 [paused] Expand multi-process orchestration carefully
Completed goals count: 1
Completed goal 1: p5 [completed] Ship the canonical bootstrap contract
Promotes approved review proposals into durable priorities.
Supported structured lines include:
approve: proposal title | priority=1 | status=active|proposed | rationale=...defer: proposal title | rationale=...
Example:
simard improvement-curation run local-harness single-process "approve: Capture denser execution evidence | priority=1 | status=active | rationale=operators need denser execution evidence now" "$STATE_ROOT"When [state-root] is omitted, improvement-curation run reuses the same canonical durable root that review run uses for the validated runtime pairing:
target/operator-probe-state/review-run/simard-engineer/<base-type>/<topology>
Reads the latest durable improvement-curation state without mutating it.
Key behavior:
- loads the latest persisted review artifact from the validated
state-root, where "latest" means the review artifact with the highestreviewed_at_unix_ms - loads the latest persisted improvement-curation decision record from the same root, where "latest" means the last decision memory record whose key ends with
improvement-curation-record - requires the positional
<state-root>and hard-fails if it is omitted;SIMARD_STATE_ROOTis not honored. See Operator read-subcommand state-root contract - validates
base-typeandtopologybefore further work - requires explicit read-layout inputs before probing: the state root itself must already exist as a directory,
review-artifacts/must exist, and bothmemory_records.jsonandgoal_records.jsonmust already be present - prints sections in this fixed order: latest review metadata, approved proposals, deferred proposals, active goals, proposed goals, latest improvement record
- includes explicit zero-state lines for empty approved, deferred, active-goal, and proposed-goal sections
- strips terminal control sequences from persisted proposal titles, rationales, goal text, review metadata, and decision records before printing them
- preserves
improvement-curation runas the only curation workflow - fails explicitly for invalid
state-rootvalues and for missing, unreadable, or malformed persisted review or improvement state
Example:
simard review run local-harness single-process \
"inspect the current Simard review surface and preserve concrete proposals" \
"$STATE_ROOT"
simard improvement-curation run local-harness single-process \
"$(cat <<'EOF'
approve: Capture denser execution evidence | priority=1 | status=active | rationale=operators need denser execution evidence now
defer: Promote this pattern into a repeatable benchmark | rationale=hold this until the next benchmark planning pass
EOF
)" \
"$STATE_ROOT"
simard improvement-curation read local-harness single-process "$STATE_ROOT"Output shape:
Probe mode: improvement-curation-read
Identity: simard-improvement-curator
Selected base type: local-harness
Topology: single-process
State root: /tmp/simard-improvement-curation.XXXXXX
Latest review artifact: /tmp/simard-improvement-curation.XXXXXX/review_artifacts/review-....json
Review id: review-...
Review target: operator-review
Review proposals: 2
Approved proposals: 1
Approved proposal 1: p1 [active] Capture denser execution evidence
Deferred proposals: 1
Deferred proposal 1: Promote this pattern into a repeatable benchmark (hold this until the next benchmark planning pass)
Active goals count: 1
Active goal 1: p1 [active] Capture denser execution evidence
Proposed goals count: 0
Proposed goals: <none>
Latest improvement record: review=review-... target=operator-review approvals=[p1 [active] Capture denser execution evidence] deferred=[Promote this pattern into a repeatable benchmark (hold this until the next benchmark planning pass)]
Lists the shipped benchmark scenarios.
Runs one benchmark scenario and prints the operator-facing text report for that run.
Key behavior today:
- persists
report.json,report.txt, andreview.jsonundertarget/simard-gym/<scenario-id>/<session-id>/ - preserves exact operator-visible output parity with
simard-gym run <scenario-id> - requires no extra configuration beyond the selected scenario id
The current counting boundary is:
unnecessary_action_count: benchmark-runner-observed benchmark-controlled action boundaries beyond the single scenario execution path required by the current v1 harnessretry_count: benchmark-runner-observed re-attempts of the same scenario work inside one benchmark run
Fresh runs now persist values derived from those benchmark-controlled facts under scorecard.unnecessary_action_count and scorecard.retry_count, surface them through the CLI, and stop emitting fresh review proposals, human_review_notes, or measurement_notes that claim those fields are "not measured". Older or incomplete artifacts should surface unmeasured instead of fabricated zeroes.
Example:
cargo run --quiet -- gym run repo-exploration-localYou should see output shaped like:
Scenario: repo-exploration-local
Suite: starter
Session: session-...
Passed: true
Checks passed: 8/8
Unnecessary actions: 0
Retry count: 0
Artifact report: target/simard-gym/repo-exploration-local/.../report.json
Artifact summary: target/simard-gym/repo-exploration-local/.../report.txt
Review artifact: target/simard-gym/repo-exploration-local/.../review.json
The detailed per-run text artifact at Artifact summary: also includes the identity, base type, topology, plan, execution summary, reflection summary, and the same metric lines.
Compares the latest two completed runs for the selected scenario and prints both source report paths plus a persisted comparison artifact.
The comparison contract is intentionally explicit:
- it fails visibly if fewer than two completed runs exist for the scenario
- it classifies the latest run as
improved,unchanged, orregressed - it writes JSON and text comparison artifacts under
target/simard-gym/comparisons/<scenario-id>/ - it preserves exact operator-visible output parity with
simard-gym compare <scenario-id> - it reports current, previous, and delta values for
unnecessary_action_countandretry_count - it validates the scenario id against the shipped benchmark registry before reading any scenario directory
- those metric lines render
unmeasuredexplicitly when either compared artifact predates the new measurements instead of fabricating0
Example:
cargo run --quiet -- gym compare repo-exploration-localYou should see output shaped like:
Scenario: repo-exploration-local
Comparison status: unchanged
Comparison summary: latest run matched session '...' on pass/fail status and checks, with unnecessary-action delta +0, retry delta +0, memory delta +0, and evidence delta +0
Current session: ...
Current passed: true
Current checks passed: 8/8
Current report: target/simard-gym/repo-exploration-local/.../report.json
Current unnecessary actions: 0
Current retry count: 0
Previous session: ...
Previous passed: true
Previous checks passed: 8/8
Previous report: target/simard-gym/repo-exploration-local/.../report.json
Previous unnecessary actions: 0
Previous retry count: 0
Delta correctness checks passed: +0
Delta unnecessary actions: +0
Delta retry count: +0
Delta exported memory records: +0
Delta exported evidence records: +0
Comparison artifact report: target/simard-gym/comparisons/repo-exploration-local/.../report.json
Comparison artifact summary: target/simard-gym/comparisons/repo-exploration-local/.../report.txt
Only comparisons that involve older artifacts should show unmeasured for those metric lines.
Runs a benchmark suite.
Artifacts are written under target/simard-gym/.
Each scenario run within the suite emits the same scorecard fields as simard gym run <scenario-id>, so single-run reports and suite-generated reports remain directly comparable.
Exit code. run-suite exits non-zero when the suite does not pass
(Suite passed: false) and zero when it passes. This is what makes the
self-test / self-update health gate trustworthy: both shell out to
gym run-suite starter and branch on its exit code, so a failing suite can no
longer be reported as a false-green (#2548). Skipped scenarios
(e.g. a backend whose auth is unavailable at gate time) do not count as failures.
The starter suite is the health gate. It runs only the deterministic,
credential-free session-quality scenarios whose correctness depends on the
binary's own runtime machinery rather than an external reasoning backend, so a
healthy binary's self-test is genuinely and deterministically green. The
repo-exploration, documentation, and safe-code-change scenarios remain in
the catalogue (gym list) and are runnable individually with
gym run <scenario-id> as benchmarks for capable reasoning backends.
The benchmark metric reporting surface does not require feature flags or environment variables.
The public operator contract is:
- pass a scenario id to
simard gym run <scenario-id>orsimard gym compare <scenario-id> - pass a suite id to
simard gym run-suite <suite-id> - read artifacts from the default output root
target/simard-gym/ - expect current reports to preserve exact parity with
simard-gymtoday - expect fresh reports to include
scorecard.unnecessary_action_countandscorecard.retry_count - expect comparisons against legacy reports to remain readable through explicit
unmeasuredoutput
Builds and persists the latest review artifact tied to the selected durable state.
Reads back the latest persisted review artifact from the selected durable state.
Requires the positional <state-root> and hard-fails if it is omitted; SIMARD_STATE_ROOT is not honored. See Operator read-subcommand state-root contract.
Example:
simard review run local-harness single-process "inspect the current Simard review surface and preserve concrete proposals" "$STATE_ROOT"
simard review read local-harness single-process "$STATE_ROOT"Bootstraps an explicit runtime selection from positional CLI arguments. This is the only supported bootstrap entrypoint on the canonical CLI surface; the old zero-argument environment-only bootstrap path is gone.
Example:
simard bootstrap run simard-engineer local-harness single-process "verify current reflection metadata" "$PWD/target/simard-state"Runs the continuous OODA (Observe-Orient-Decide-Act) daemon loop for autonomous operation. Simard observes her goal board, orients by ranking priorities, decides which actions to take, and acts by dispatching bounded work — then sleeps and repeats.
Key behavior:
- launches memory, knowledge, and gym bridges
- loads the goal board from cognitive memory
- runs OODA cycles in a loop with 60-second sleep between cycles
--cycles=Nlimits the daemon to N cycles;--cycles=0or omitting the flag runs indefinitely- logs cycle summaries to stderr: observation counts, priorities, actions dispatched, outcomes
- errors in individual actions do not abort the cycle; the daemon continues to the next phase
- state root defaults to
$SIMARD_STATE_ROOTor/tmp/simard-oodawhen omitted
Environment variables:
SIMARD_STATE_ROOT— override the state root directory (also moves the IPC socket — see Shared socket-path contract)SIMARD_MEMORY_SOCKET— override the IPC socket path explicitly, independent of the state root. Useful when daemon and clients intentionally target different state roots (rare; default is<state_root>/memory.sock).SIMARD_AGENT_NAME— override the agent name (default:simard-ooda)
Example:
# Run 5 cycles then exit
simard ooda run --cycles=5 "$PWD/target/simard-ooda"
# Run indefinitely as a daemon
SIMARD_STATE_ROOT="$PWD/target/simard-state" simard ooda runEach cycle follows the four OODA phases:
- Observe — gather goal statuses, gym health, memory statistics; degrades honestly if a bridge is unavailable (Pillar 11)
- Orient — rank goals by urgency (blocked 1.0 > not-started 0.8 > in-progress scaled by remaining %). Also injects synthetic priorities: memory consolidation (urgency 0.5) when episodic count exceeds 100, and improvement cycles (urgency 0.7) when gym score drops below 70%
- Decide — select up to
max_concurrent_actions(default 3) actions from the priority list; completed goals (urgency 0) are skipped - Act — dispatch actions independently; each action produces its own outcome
Action kinds: AdvanceGoal, RunImprovement, ConsolidateMemory, ResearchQuery, RunGymEval, BuildSkill.
Reads the latest meeting handoff artifact and creates GitHub issues for each decision and action item.
Key behavior:
- loads the handoff from
target/meeting_handoffs/meeting_handoff.json - if no handoff exists, prints a message and exits successfully
- if the handoff is already marked as processed, prints a message and exits
- for each
MeetingDecision: creates a GitHub issue titledDecision: <description>with rationale and participants in the body - for each
ActionItem: creates a GitHub issue titledAction: <description>with owner, priority, and due date in the body - prints open questions to stdout (not filed as issues)
- marks the handoff as processed after creating all issues
- individual
gh issue createfailures are warnings; the command continues
Requires:
ghCLI installed and authenticated- a prior
simard meeting runthat produced a handoff artifact
Example:
# After closing a meeting session
simard act-on-decisionsExample output:
Processing meeting handoff: align next workstream (closed 2026-04-02T14:30:00Z)
Created issue for decision: adopt session builder → https://github.com/rysweet/Simard/issues/155
Created issue for action: wire OODA to RustyClawd → https://github.com/rysweet/Simard/issues/156
Open questions (not filed as issues):
- how aggressively should Simard reprioritize?
Done. Created 2 issue(s). Handoff marked as processed.
From the repository root, use these Cargo forms:
cargo run --quiet -- ...forsimardcargo run --quiet --bin simard_operator_probe -- ...forsimard_operator_probecargo run --quiet --bin simard-gym -- ...forsimard-gym
| Base type selection | Current backend identity | Supported topologies in this scaffold |
|---|---|---|
local-harness |
local-harness |
single-process |
terminal-shell |
terminal-shell::local-pty |
single-process |
rusty-clawd |
rusty-clawd::session-backend |
single-process, multi-process |
copilot-sdk |
local-harness |
single-process |
Notes:
terminal-shellis an engineer-only local terminal path- unsupported topology and base-type pairs fail explicitly instead of degrading silently
copilot-sdkremains an explicit alias of the local harness implementation in this scaffold
Simard fails explicitly for these common operator-facing cases:
- unsupported top-level command
- missing required positional argument, reported as
expected <arg> - invalid
state-root - unsupported base type for the selected identity
- unsupported topology for the selected base type
- missing or invalid workspace root
- missing persisted review state for
review read - nested-worktree or repo-root drift detected during engineer-mode execution
- planned Copilot submit contract should report
unsupportedwithprocess-exited-early,unexpected-startup-text,missing-startup-banner,missing-guidance-checkpoint,trust-confirmation-required,submit-hotkey-required,copilot-wrapper-error, orworkflow-wrapper-noisewhen the visible prompt flow drifts after launch - structured edit requested on a dirty repo