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

# CLI: Individualized LMS retraining

> Use opentrain lms retraining to create one worker-specific case, review a no-write plan, assign it once, and inspect its live outcome.

`opentrain lms retraining` is the case-orchestration layer for individualized quality remediation. Course authoring, Native Forms, Preview, publishing, grading, result release, and `RETURN` remain in their existing LMS and Project To-do commands.

<Note>
  Individualized retraining requires `@opentrain-ai/cli` 0.9.0 or newer.
</Note>

Install the latest CLI and verify the active token has `lms:read` and `lms:write`:

```bash theme={null}
npm install -g @opentrain-ai/cli@latest
opentrain --version
opentrain auth status --json
```

## Discover the live LMS contract

Start every agent run with:

```bash theme={null}
opentrain capabilities --json
opentrain lms capabilities --json
```

Inspect the root response's `agentSurfaces` LMS family status and each operation's `authorized` value. Then read the LMS response's `retraining`, `assessments`, `course`, `lessonContent`, `assets`, `preview`, and `mastery` sections before generating content or mutations. Do not hard-code question types, limits, or retry rules from an older run.

If either capability command reports `disabled`, `rollout_gated`, or `unauthorized`, stop and return that structured result.

## Use JSON as the agent protocol

Use `--json` for automation. The CLI writes exactly one JSON document to stdout and does not prompt. A failure exits nonzero with this shape:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "CONFLICT",
    "status": 409,
    "message": "The retraining case changed. Read it and plan again.",
    "requestId": "request-id"
  }
}
```

Branch on `error.code`, `error.status`, and structured `error.details`, not the message. Reuse the same `--key` after a transport failure; do not generate a new key for the retry.

## Register a published skill-gap module

```bash theme={null}
opentrain lms retraining modules register \
  --course <course-id> \
  --module <module-key> \
  --label "Reconciliation and cutoff" \
  --description-file ./module-description.txt \
  --key retraining-module-reconciliation-v1 \
  --json

opentrain lms retraining modules list --all --json
```

## Create a draft case

Prefer a stable contract ID:

```bash theme={null}
opentrain lms retraining create \
  --job <job-id> \
  --contract <contract-id> \
  --summary "Review the reconciliation and cutoff workflow" \
  --observed-mistake-file ./observed-mistake.txt \
  --expected-behavior-file ./expected-behavior.txt \
  --mode MASTERY \
  --course <course-id> \
  --module <module-key> \
  --run-limit 3 \
  --due-offset-minutes 1440 \
  --priority URGENT \
  --blocking-mode IMMEDIATE \
  --key retraining-case-contract-123-v1 \
  --json
```

Use `--worker-name` only when you do not have a contract ID. It must resolve to exactly one active contract.

For a wall-clock deadline, replace the offset with all three flags:

```bash theme={null}
--due-date 2026-09-01 --due-time 17:00 --due-zone America/New_York
```

For evidence arrays, Instructions references, and an authoring brief, pass the complete typed request through `--body-json-file`. Do not mix it with field flags.

## Update a draft case

Only a `DRAFT` case can be edited. Read the latest case revision, then apply one revision-fenced patch:

```bash theme={null}
opentrain lms retraining update \
  --case <case-id> \
  --expected-revision <current-revision> \
  --patch-json-file ./retraining-case-patch.json \
  --key retraining-case-update-123-v1 \
  --json
```

Use `--patch-json` for a small inline patch. When switching the due-date channel, clear the old channel and set the new one in the same patch so the case still has exactly one due rule.

## Preview and plan

Use the existing `opentrain lms preview …` commands to test the worker renderer without creating an assignment.

Then generate the assignment plan:

```bash theme={null}
opentrain lms retraining plan --case <case-id> --json
```

Planning performs no writes. An authorized employer must review and explicitly approve the exact masked worker, contract ID, immutable course version, module, content hash, frozen due instant, eligibility, effect counts, request hash, and receipt expiry.

## Confirm the assignment

```bash theme={null}
opentrain lms retraining assign \
  --case <case-id> \
  --expected-revision <revision-from-plan> \
  --receipt <token-from-plan> \
  --confirm-assign \
  --key retraining-assign-contract-123-v1 \
  --json
```

`--confirm-assign` records the employer-approved mutation; it does not let an agent approve its own plan. The write creates exactly one canonical Project To-do assignment. If the receipt is stale or expired, run `plan` again and obtain approval for the new result.

## Monitor and close

```bash theme={null}
opentrain lms retraining get --case <case-id> --json
opentrain lms retraining list --job <job-id> --all --json
```

`--all` follows bounded cursor pages. Before reporting a complete audit, confirm the returned collection is complete; otherwise persist its resume cursor and continue.

Use existing LMS status, run-history, employer-review, grading, result-release, and Project To-do `RETURN` commands for the live assignment.

Close the case only when its requested outcome agrees with that canonical assignment:

```bash theme={null}
opentrain lms retraining close \
  --case <case-id> \
  --expected-revision <current-revision> \
  --outcome PASSED \
  --reason "Completed the assigned remediation" \
  --confirm-close \
  --key retraining-close-contract-123-v1 \
  --json
```

Run `opentrain lms retraining <command> --help` for action-specific flags and safety rules.

See [Manage individualized retraining with an agent](/docs/developers/guides/manage-individualized-retraining) for the complete authoring, Preview, approval, assignment, grading, and retry sequence.
