> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moda.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Prompt, skill, harness, and fix commands

## Prompt management

Code-first prompt workflow — see [Prompt management](/prompt-management/overview) for concepts and [Workflow](/prompt-management/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`.

```bash theme={"dark"}
moda prompts init
```

```json Output theme={"dark"}
{
  "manifest": ".moda/prompts.yml",
  "manifestPath": "/home/you/project/.moda/prompts.yml",
  "lockfile": ".moda/prompts.lock.json",
  "lockPath": "/home/you/project/.moda/prompts.lock.json",
  "cwd": "/home/you/project",
  "created": true,
  "promptPaths": ["prompts/**/*.prompt.md", "prompts/**/*.prompt.json", "prompts/**/*.prompt.yaml", "prompts/**/*.prompt.yml"]
}
```

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`.

```bash theme={"dark"}
moda prompts status
```

```json Output (trimmed) theme={"dark"}
{
  "manifest": ".moda/prompts.yml",
  "lockfile": ".moda/prompts.lock.json",
  "total": 3,
  "changed": 1,
  "new": 0,
  "deleted": 0,
  "prompts": [
    { "key": "support.triage", "sourcePath": "prompts/support/triage.prompt.md", "contentHash": "b41f0c…", "lockedHash": "a92c7e…", "versionId": "pver_1f2e3d4c5b6a79880911223344556677", "state": "changed" }
  ]
}
```

### 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`.

```bash theme={"dark"}
moda prompts sync
```

```json Output (trimmed) theme={"dark"}
{
  "synced": [
    { "key": "support.triage", "promptId": "prompt_0a1b2c3d4e5f60718293a4b5", "versionId": "pver_1f2e3d4c5b6a79880911223344556677", "contentHash": "b41f0c…", "sourcePath": "prompts/support/triage.prompt.md" }
  ],
  "lockfile": ".moda/prompts.lock.json"
}
```

| Flag         | Default | Description                                                |
| ------------ | ------- | ---------------------------------------------------------- |
| `--dry-run`  | off     | Compute IDs without writing anything (no lockfile update). |
| `--watch`    | off     | Poll local files and re-sync on change.                    |
| `--interval` | 2500    | Poll interval in ms for `--watch` (min 1,000).             |

### moda prompts promote

Moves a release label (`dev`, `staging`, `prod`) to a specific version. Returns the updated prompt with all versions.

```bash theme={"dark"}
moda prompts promote support.triage --label=prod --version=pver_1f2e3d4c5b6a79880911223344556677
```

| Argument / flag | Description                                                                 |
| --------------- | --------------------------------------------------------------------------- |
| `<key>`         | Prompt key (required).                                                      |
| `--label`       | `dev`, `staging`, or `prod` (required).                                     |
| `--version`     | Target version ID from the lockfile (`--version-id` is an alias; required). |

<Note>
  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.
</Note>

### 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](/prompt-management/experiments).

```bash theme={"dark"}
moda prompts ab --baseline=prompts/support/triage.prompt.md --candidate=prompts/support/triage-v2.prompt.md --traces=conv_5e1a9c2b7d3f4680,conv_8c33d2f1a09b44e7
```

The command polls the run every 15 seconds and prints per-case results plus the final verdict; `--no-wait` returns immediately after enqueueing.

| Flag                            | Default     | Description                                                                     |
| ------------------------------- | ----------- | ------------------------------------------------------------------------------- |
| `--baseline` / `--candidate`    | required    | Prompt file paths or synced prompt keys.                                        |
| `--set-id`                      | —           | Reuse an existing replay set (`--replay-set-id` alias).                         |
| `--traces`                      | —           | Comma-separated trace IDs to build a set from. Legacy alias: `--conversations`. |
| `--cases`                       | 5           | Cases for an auto-generated set.                                                |
| `--lookback-days`               | 30          | Window for auto-generated cases.                                                |
| `--seeds`                       | 3           | Seeds per case (max 10).                                                        |
| `--model`                       | —           | Assistant model override for the replay.                                        |
| `--sync`                        | off         | Run `moda prompts sync` first.                                                  |
| `--no-wait`                     | off         | Return after enqueue instead of polling.                                        |
| `--timeout` / `--poll-interval` | 2 h / 15 s  | Polling bounds.                                                                 |
| `--tenant-id`                   | from config | Tenant to run in.                                                               |

### moda prompts propose

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

```bash theme={"dark"}
moda prompts propose support.triage --from-run=run_9d2e --set-id=rset_31ab --out=prompts/support/triage-v2.prompt.md
```

| Argument / flag    | Default  | Description                                                               |
| ------------------ | -------- | ------------------------------------------------------------------------- |
| `<key>`            | required | Prompt key (`--prompt-key` alias).                                        |
| `--from-run`       | required | Source A/B run ID (`--from-run-id` / `--run-id` aliases).                 |
| `--set-id`         | required | Replay set ID (`--replay-set-id` alias).                                  |
| `--max-dossiers`   | 8        | Failure dossiers fed to the revision (max 16).                            |
| `--out`            | —        | Write the candidate content to a file.                                    |
| `--gate`           | off      | Auto-run an A/B of candidate vs. baseline over the replay set.            |
| `--promote-on-win` | off      | Promote the candidate to `prod` only on a strict win (requires `--gate`). |

## 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.

```bash theme={"dark"}
moda skills gen
```

```text Output theme={"dark"}
accepted: true
generation_run_id: 51f2b3a4-9c8d-4e7f-a1b2-c3d4e5f6a7b8
follow progress: moda skills status 51f2b3a4-9c8d-4e7f-a1b2-c3d4e5f6a7b8
```

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.

```bash theme={"dark"}
moda skills status 51f2b3a4-9c8d-4e7f-a1b2-c3d4e5f6a7b8
```

### moda skills pull

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

```bash theme={"dark"}
moda skills pull --status=proposed
```

| Flag       | Default    | Description                       |
| ---------- | ---------- | --------------------------------- |
| `--status` | `approved` | `approved`, `proposed`, or `all`. |

### 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](#fixes); only the fenced block is Moda-owned — the rest of the file is never touched, and `--dry-run` skips the write.

```bash theme={"dark"}
moda skills sync --dry-run
```

### 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).

```bash theme={"dark"}
moda skills proposals list
```

## 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](/harness/overview)); 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.

```bash theme={"dark"}
moda harness analyze --json
```

```json Output (gated) theme={"dark"}
{
  "schema": "harness_analyze_disabled.v0.1",
  "status": "disabled",
  "reason": "cli_analyze_gated",
  "message": "Harness analysis now runs automatically via the Moda GitHub App — connect your repo in the Moda dashboard (Settings → Integrations). To run the experimental CLI analyze anyway, pass --experimental or set MODA_HARNESS_ANALYZE_CLI=1."
}
```

| Flag                                          | Description                                                                           |
| --------------------------------------------- | ------------------------------------------------------------------------------------- |
| `--experimental`                              | Opt in to CLI analysis (or set `MODA_HARNESS_ANALYZE_CLI=1`).                         |
| `--remote`                                    | Upload a safe source snapshot and analyze server-side (no local coding agent needed). |
| `--github-actions`                            | GitHub Actions OIDC mode — no Moda API key on the runner.                             |
| `--analyst=claude\|codex\|cursor\|local-scan` | Local analyst adapter.                                                                |
| `--yes`                                       | Skip the read-plan approval prompt.                                                   |

### 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.

```bash theme={"dark"}
moda harness pull --sync
```

### 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`.

```bash theme={"dark"}
moda harness approve --yes
moda harness sync --from-report .moda/harness-report.json
```

### 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.

```bash theme={"dark"}
moda harness explain --agent=agent_support
```

### moda harness delete

Permanently deletes a synced harness from Moda Cloud.

```bash theme={"dark"}
moda harness delete my-harness-key --yes
```

## Additional init flags

| Flag                                                | Description                                                                                            |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `--remote` / `--local`                              | Run harness analysis server-side (default) or with a local coding agent.                               |
| `--analyst=auto\|claude\|codex\|cursor\|local-scan` | Analyst adapter for harness analysis.                                                                  |
| `--autosync` / `--no-autosync`                      | Create `.github/workflows/moda-autosync.yml` (syncs prompts and skills on push to `main`), or skip it. |
| `--harness-rescan` / `--no-harness-rescan`          | Create `.github/workflows/moda-harness-rescan.yml` (see [CI rescan](/harness/ci-rescan)), or skip it.  |
| `--harness-rescan-paths=GLOBS`                      | Comma-separated path globs that scope the rescan workflow's triggers (implies `--harness-rescan`).     |
| `--tui` / `--no-tui`                                | Force or suppress the full-screen analyst dashboard on a TTY.                                          |

## Fixes

A Fix pairs a candidate change with a replay-gate verdict on held-out production evidence — see [Fixes in the dashboard](/dashboard/fixes) for the concepts and [the fix endpoints](/data-api/fixes) 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:

| Exit | Meaning                                                                                 |
| ---- | --------------------------------------------------------------------------------------- |
| 0    | Gate pass: the candidate beat baseline on the frozen holdout, clear of the noise floor. |
| 1    | Gate fail: per-case findings ride the envelope's `findings[]` as `case:<id>` entries.   |
| 3    | Degraded/inconclusive: too many abstentions, blocked coverage, or no verdict.           |

[`moda fixes drive`](#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).

```bash theme={"dark"}
moda fixes --status=VERIFIED --limit=10
```

```json Output (trimmed) theme={"dark"}
{
  "fixes": [
    { "id": "cme9y2k1q0001l708g6p4xw3v", "shortRef": "7Q2WJX4M", "problemId": "3f6b0a52-9d1c-4e7a-b2f8-6c0d5e4a3b21", "fixType": "PROMPT", "status": "VERIFIED", "targetSourcePath": "prompts/support/triage.prompt.md", "problemRank": 0.92 }
  ],
  "pagination": { "limit": 10, "has_more": false, "next_cursor": null }
}
```

| Flag          | Default     | Description                                                                  |
| ------------- | ----------- | ---------------------------------------------------------------------------- |
| `--status`    | —           | Filter to one fix status (for example `VERIFIED`, `GATE_FAILED`, `PR_OPEN`). |
| `--limit`     | 25          | 1–100.                                                                       |
| `--cursor`    | —           | Opaque cursor from the previous page's `next_cursor`.                        |
| `--tenant-id` | from config | Tenant to read.                                                              |

### 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](/data-api/fixes#post-tenantstenantidfixesdraft-batch) 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.

```bash theme={"dark"}
moda fixes draft-batch --limit=10
```

```json Output (trimmed) theme={"dark"}
{
  "drafted": [
    { "fixId": "cme9y2k1q0001l708g6p4xw3v", "shortRef": "7Q2WJX4M", "problemId": "3f6b0a52-9d1c-4e7a-b2f8-6c0d5e4a3b21", "status": "DRAFT", "problemRank": 0.92 }
  ],
  "skipped": [
    { "problemId": "9a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9", "reason": "an active fix already exists (MODA-FIX-AB12CD34, GATING)" }
  ]
}
```

| Flag          | Default     | Description                                             |
| ------------- | ----------- | ------------------------------------------------------- |
| `--limit`     | 10          | Fixes to draft, 1–25 (rejected locally beyond the cap). |
| `--tenant-id` | from config | Tenant to draft for.                                    |

The envelope's next command is [`moda fixes drive`](#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.

```bash theme={"dark"}
moda fixes drive
```

```json Output (trimmed) theme={"dark"}
{
  "fixes": [
    { "shortRef": "7Q2WJX4M", "status": "VERIFIED", "fixType": "PROMPT", "statusReason": "holdout wins clear the noise floor" },
    { "shortRef": "X1Y2Z3A4", "status": "PROPOSED", "fixType": "SKILL", "statusReason": "skill drafted — gate pending skill registration; deliver via packet or mark-applied" }
  ],
  "passes": 14,
  "rested": 2,
  "stragglers": [],
  "timedOut": false
}
```

| Flag              | Default       | Description                                                                               |
| ----------------- | ------------- | ----------------------------------------------------------------------------------------- |
| `--status`        | all advancing | Drive only this advancing status (`DRAFT`, `SCOPING`, `PROPOSING`, `PROPOSED`, `GATING`). |
| `--timeout`       | 2 h           | Total drive budget in ms (max 24 h).                                                      |
| `--pass-interval` | 20 s          | Sleep between passes in ms (max 120 s).                                                   |
| `--tenant-id`     | from config   | Tenant to drive.                                                                          |

<Warning>
  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`](#moda-fix-fix_id).

  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.
</Warning>

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-mark-applied).

```bash theme={"dark"}
moda fix cme9y2k1q0001l708g6p4xw3v
moda fix cme9y2k1q0001l708g6p4xw3v --packet
moda fix cme9y2k1q0001l708g6p4xw3v --wait
```

| Argument / flag                 | Default    | Description                                                                                                                                                            |
| ------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<fix_id>`                      | required   | Fix ID from `moda fixes` or `moda fix start`.                                                                                                                          |
| `--packet`                      | off        | Print the agent packet (cause, target, evidence links, verify command, handback + magic word); tool/skill candidates are also written under `.moda/fixes/<SHORTREF>/`. |
| `--wait`                        | off        | Drive the advance-on-poll pipeline until the fix rests.                                                                                                                |
| `--timeout` / `--poll-interval` | 2 h / 15 s | Wait bounds in ms.                                                                                                                                                     |

### 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.

```bash theme={"dark"}
moda fix start 3f6b0a52-9d1c-4e7a-b2f8-6c0d5e4a3b21 --wait
```

| Argument / flag                 | Default    | Description                                                            |
| ------------------------------- | ---------- | ---------------------------------------------------------------------- |
| `<problem_id>`                  | required   | Problem UUID from `moda problems`.                                     |
| `--type`                        | `auto`     | `auto` routes from evidence; `prompt` considers only the prompt route. |
| `--wait`                        | off        | Drive the pipeline to a resting status and print the packet.           |
| `--timeout` / `--poll-interval` | 2 h / 15 s | Wait bounds in ms.                                                     |

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).

```bash theme={"dark"}
moda fix verify cme9y2k1q0001l708g6p4xw3v --prompt-file=prompts/support/triage.prompt.md
```

| Argument / flag                 | Default    | Description                                                                                                          |
| ------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
| `<fix_id>`                      | required   | Fix to gate.                                                                                                         |
| `--prompt-file`                 | —          | Local candidate file (≥ 40 characters; rejected locally before the network). Omitted = re-gate the stored candidate. |
| `--no-wait`                     | off        | Return after enqueue with the `gateRunId`; resume with `moda fix <fix_id> --wait`.                                   |
| `--timeout` / `--poll-interval` | 2 h / 15 s | Wait bounds in ms.                                                                                                   |

### 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`.

```bash theme={"dark"}
moda fix checkout cme9y2k1q0001l708g6p4xw3v
```

### 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.

```bash theme={"dark"}
moda fix submit cme9y2k1q0001l708g6p4xw3v --pr
moda fix submit cme9y2k1q0001l708g6p4xw3v --local-ref=moda/fix/7q2wjx4m
```

| Argument / flag      | Description                                                               |
| -------------------- | ------------------------------------------------------------------------- |
| `<fix_id>`           | Fix to deliver (required).                                                |
| `--pr`               | Open the draft fix PR. At most 3 Moda fix PRs may be open per workspace.  |
| `--local-ref=BRANCH` | Record a locally applied branch instead (mutually exclusive with `--pr`). |

### 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.

```bash theme={"dark"}
moda fix mark-applied cme9y2k1q0001l708g6p4xw3v --note="tool description updated in our agent config"
```

| Argument / flag | Description                                                                                                       |
| --------------- | ----------------------------------------------------------------------------------------------------------------- |
| `<fix_id>`      | Fix to confirm (required).                                                                                        |
| `--note=TEXT`   | Optional note (≤ 600 characters; rejected locally beyond that) recorded on the feedback's `fix_ref.applied_note`. |

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.

```bash theme={"dark"}
moda fix dismiss cme9y2k1q0001l708g6p4xw3v --reason="not the right lever; fixing the API enum instead"
```

| Argument / flag | Description                   |
| --------------- | ----------------------------- |
| `<fix_id>`      | Fix to dismiss (required).    |
| `--reason=TEXT` | Required, ≤ 2,000 characters. |
