Skip to main content

Prompt management

Code-first prompt workflow — see Prompt management for concepts and Workflow for the end-to-end guide. Running moda prompts with no subcommand is equivalent to moda prompts status.

moda prompts init

Creates .moda/prompts.yml if absent (never overwrites). The default manifest discovers prompts/**/*.prompt.{md,json,yaml,yml}. Paths are resolved against the current working directory, so run it from the project root. created distinguishes a fresh scaffold from an existing manifest, and manifestPath is the absolute path to verify — the agent envelope also lists it under artifacts.
Output
If the manifest is not on disk after the run, the command exits non-zero with a write_failed-style error rather than reporting status: "ok".

moda prompts status / moda prompts diff

Local-only comparison of discovered prompt files against .moda/prompts.lock.json. No network call. diff is an alias for status (it is not a textual diff). Per-prompt state is new, changed, unchanged, or deleted.
Output (trimmed)

moda prompts sync

Uploads all discovered prompts (unchanged ones are server-side no-ops — versions are content-addressed and immutable), moves each prompt’s current pointer to the synced version, and writes .moda/prompts.lock.json.
Output (trimmed)

moda prompts promote

Moves a release label (dev, staging, prod) to a specific version. Returns the updated prompt with all versions.
A dev promotion moves the same pointer that every sync overwrites, so it is replaced by the next moda prompts sync. Use staging/prod for stable release labels.

moda prompts ab

Judged A/B replay comparison between a baseline and a candidate prompt. Builds (or reuses) a replay set, runs both arms, and reports a verdict — the candidate wins only with strictly more passed cases. See Experiments.
The command polls the run every 15 seconds and prints per-case results plus the final verdict; --no-wait returns immediately after enqueueing.

moda prompts propose

Generates a revised, unlabeled candidate version from a failed A/B run’s failure evidence.

Skills

Moda can distill recurring agent behavior into skill files and sync them with your repo. Skill commands talk to the Ingestion API host (MODA_INGEST_URL) and the control plane using your API key.

moda skills gen

Kicks off tenant-wide skill generation and returns a run ID.
Output
Flags: --source=all|sdk, --max-sessions=N, --start-at=ISO, --end-at=ISO, --wait.

moda skills status

Status, outcome, and recent events for a generation run (latest run when no ID is given). Exits 1 when the run failed.

moda skills pull

Downloads tenant-generated skills into .claude/skills/**/SKILL.md (and .cursor/rules), tracked in .moda/skills.yml.

moda skills sync

Pushes local .claude/skills/**/SKILL.md files up to Moda. --dry-run shows what would be pushed. A real sync (and moda init, which runs one) also maintains a managed <!-- moda:fixes:begin --> block in the repo’s AGENTS.md pointing coding agents at the fix workflow; only the fenced block is Moda-owned — the rest of the file is never touched, and --dry-run skips the write.

moda skills proposals / moda skills proposal apply

moda skills proposals list [--status=ready_for_pr] lists skill improvement proposals with baseline/candidate pass rates. moda skills proposal apply <proposal-id> writes the proposed SKILL.md locally and acknowledges the proposal; it exits 1 if the local write succeeded but the acknowledgment failed (re-run to retry).

Harness

The harness commands produce and sync the cited map of your agent codebase. The supported path for analysis is the Moda GitHub App (see Harness); the CLI analyze path is experimental.

moda harness analyze

Produces a cited harness report. Gated: without --experimental or MODA_HARNESS_ANALYZE_CLI=1 it prints a pointer to the GitHub App and exits 1.
Output (gated)

moda harness pull

Fetches a server-side analyze run (status while running, the report when done). --sync also syncs a passing report. --run-id targets a specific run; otherwise the run recorded in .moda/harness-remote-run.json is used.

moda harness validate-report / approve / sync

validate-report checks .moda/harness-report.json citations. approve --yes validates and writes a hash-bound approval file; sync --from-report uploads the approved report to Moda Cloud (it refuses unapproved reports) and writes .moda/sync-state.json. moda sync and moda sync harness are top-level aliases for harness sync; moda sync prompts aliases moda prompts sync.

moda harness scan / candidates / agents / explain

Local, no-LLM inspection commands:
  • moda harness scan — discover local runtime agents and write .moda/harness.json (--json for structured output).
  • moda harness candidates — static candidate pre-pass with file:line citations (--out=PATH).
  • moda harness agents — list detected runtime agents and families.
  • moda harness explain [--agent=<id>] — explain the discovered harness graph.

moda harness delete

Permanently deletes a synced harness from Moda Cloud.

Additional init flags

Fixes

A Fix pairs a candidate change with a replay-gate verdict on held-out production evidence — see Fixes in the dashboard for the concepts and the fix endpoints for the HTTP surface these commands call (tenant-scoped, resolved from your config or --tenant-id). Fix mutations are sent exactly once (no automatic retries). The pipeline is advance-on-poll: nothing progresses server-side between requests, so the --wait flags drive the pipeline rather than merely watch it — a fix left GATING will not finish on its own. Wait loops poll every 15 seconds (--poll-interval, max 120 s) with a 2-hour default timeout (--timeout, max 24 h), and announce stage transitions on stderr (or as progress events in agent-stream mode). moda fix verify uses exit code 3 for a degraded gate — never treat it as a pass: moda fixes drive also exits 3 whenever it cannot claim a swept queue: its timeout lapsed with fixes still advancing, the queue scan was truncated, or the queue was re-ranked mid-page (all three set data.coverageTruncated: true). Never treat exit 3 as everything having rested — in the truncated case the fixes it did scan all rested, but the queue was not swept.

moda fixes

The ranked Fix queue (ordered by problem rank, then recency).
Output (trimmed)

moda fixes draft-batch

Campaign mode: batch-drafts a fix for each of the tenant’s top-ranked fixable problems in one call (the same endpoint as the dashboard’s Draft fixes for top problems button). Creation only — nothing advances server-side. Problems are taken in rank order; each is skipped with a reason when it already has an active fix, its lifecycle is no longer open/reopened, or it aliases a problem already in the batch. Batches cap at 25 (default 10) — an LLM spend guard: every drafted fix burns distillation + propose budget once driven, so run another batch after the first lands. Sent exactly once (no automatic retries), like every fix mutation.
Output (trimmed)
The envelope’s next command is moda fixes drive — the bulk driver for the batch.

moda fixes drive

The bulk advance driver for campaign mode. Snapshots the ranked queue, keeps every fix in an advancing status (DRAFT, SCOPING, PROPOSING, PROPOSED, GATING), and round-robins one advance step per active fix per pass — fair progress, so one slow gate never starves the rest — sleeping --pass-interval between passes until every fix rests or the timeout lapses. Per-fix transitions stream to stderr (progress events in agent-stream mode); per-fix errors are collected as warnings and retried on the next pass rather than aborting the drive. Two in-flight shapes are handled as designed: a fix resting at PROPOSED with a gate pending/unavailable reason counts as rested (it is deliverable now via packet / mark-applied), and a fix inside a fresh scoping lease returns unchanged from advance — a live run holds the step, and the next pass simply retries.
Output (trimmed)
The fix list is scanned server-side within a bounded window, so a tenant with a very large fix queue can have advancing fixes outside it. Drive exits 3 (degraded) with data.coverageTruncated: true rather than reporting a clean sweep — resting every fix it could scan is not a swept queue, so a script keying on exit 0 is never told otherwise. Re-running unfiltered rescans the same rows — the window is the newest N by creation. Use --status to move it: the backend filters before the scan, so each status gets its own window, and moda fixes drive --status SCOPING reaches older SCOPING fixes an unfiltered drive can’t. If a single status still overflows, advance those fixes individually with moda fix <id> --wait.A second, unrelated cause: the list cursor is a numeric offset into a list the backend re-ranks on every request, so a rank change between pages can shift rows across the boundary — down (served twice) or up (never served, with nothing repeating to reveal it). No client-side probe can rule the second case out, so drive only claims completeness for a single-page snapshot. Any drive that follows a cursor exits 3 with coverageTruncated: true and a warning; re-run until it exits 0. Duplicates are still deduped so no fix is driven twice.
Exits 0 when every driven fix rested; exits 3 when the timeout lapsed with stragglers — re-run moda fixes drive to resume (advance-on-poll picks up exactly where it left off).

moda fix

One Fix: status, gate result, and suggested next commands. --packet prints the raw moda.fix_packet.v1 document instead; --wait drives a still-running pipeline (statuses DRAFT, SCOPING, PROPOSING, PROPOSED, GATING) to its next resting status. When the packet carries a tool or skill candidate (candidate_tool / candidate_skill / candidate_skill_edit), --packet also materializes it as local files under .moda/fixes/<SHORTREF>/ and lists them in the envelope’s artifacts: the tool-description diff pair (tool-description.current.md / tool-description.proposed.md), the drafted SKILL.md, or — for an edit to an existing synced skill — the SKILL.current.md / SKILL.proposed.md pair with the change summary as a finding. Apply the artifact in your own stack, then confirm with moda fix mark-applied.

moda fix start

Drafts a Fix from a Problem. Without --wait it returns the drafted fix immediately (status DRAFT); with --wait it drives scope → propose → gate to a resting status and attaches the packet. Drafting is idempotent while a fix is active for the problem — you get the existing fix back, never a fork.
Resting statuses that are not VERIFIED are not errors: NO_EVIDENCE, BLOCKED_COVERAGE, UNROUTED, and NO_HEADROOM fixes are deliverable as diagnosis packets (moda fix <fix_id> --packet). Routing is typed: evidence pointing at a managed prompt drafts a PROMPT fix, a dominant failing tool drafts a TOOL_SCHEMA fix (a proposed rewrite of the tool’s description), and agent-behavior problems draft a SKILL fix (a complete SKILL.md). A SKILL fix rests at PROPOSED until its skill is registered with the Moda skill harness — deliver it via the packet and mark-applied in the meantime.

moda fix verify

Re-gates a fix on the frozen holdout and exits by verdict (see the exit-code table above). With --prompt-file it uploads local candidate content instead of the stored candidate — the fail-to-pass loop for coding agents: edit the target file, verify, read the case:<id> findings, repeat until exit 0. Uploading applies to PROMPT fixes only (400 otherwise); TOOL_SCHEMA fixes re-gate their stored description candidate, and unregistered SKILL candidates cannot enter the gate (409). Waits by default; the verdict is pinned to the gate run this command enqueued (a concurrent verify that supersedes it is surfaced as a warning).

moda fix checkout

Writes the verified candidate’s content at its repo-relative targetSourcePath in the current directory, then prints your next steps: create branch moda/fix/<shortref>, re-gate any edits, and submit. The CLI never runs git — branching and committing are yours. Absolute or .. target paths from the server are refused; packet-only fixes and fixes without a registered candidate exit with an explanatory error. PROMPT fixes only: TOOL_SCHEMA and SKILL candidates are not repo files — read them via moda fix <fix_id> --packet and confirm with mark-applied.

moda fix submit

Delivers a VERIFIED fix through exactly one channel: --pr opens a draft PR via Moda’s GitHub App (body ends with the magic word Fixes MODA-FIX-<SHORTREF>), or --local-ref records the branch you applied the change on yourself. Merging a PR that carries the magic word confirms the fix and starts production monitoring.

moda fix mark-applied

The no-GitHub confirmation: you applied the candidate in your own stack — updated the tool description in your agent’s tool definition, installed the drafted skill, or hand-applied a prompt edit — so there is no PR merge to confirm the fix. mark-applied flips the fix straight to SHIPPED, records your note, posts the same mark_fixed problem feedback the merge webhook would, and starts recurrence monitoring (HELD after 14 clean days, REGRESSED on reopen). Idempotent: repeating it on a confirmed fix is a duplicate no-op. Sent exactly once (no automatic retries), like every fix mutation.
Allowed from any resting or delivered status (UNROUTED, PROPOSED, VERIFIED, GATE_FAILED, GATE_INCONCLUSIVE, PR_OPEN, APPLIED_LOCALLY, HANDED_OFF); pipeline-live, pre-candidate, and terminal statuses return 409.

moda fix dismiss

Rejects a fix; the reason is recorded as problem feedback and steers discovery.