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

# Retakes and Remediation Plans

> Grant a corrected attempt with a stale-review guard, and validate retake batches without writing.

A retake is a returned submission: the AI trainer sees your reason, the to-do reopens, and they get exactly one extra attempt on the same published version. Requires `project_todos:write`.

## `require_retake`

<ParamField body="action" type="string" required>`require_retake`</ParamField>

<ParamField body="idempotencyKey" type="string" required />

<ParamField body="assignmentId" type="string" required>The quiz to-do assignment to return.</ParamField>
<ParamField body="reason" type="string" required>Worker-visible feedback about what to correct.</ParamField>

<ParamField body="expectedSubmittedAt" type="string" required>
  The exact `submittedAt` you reviewed. If the AI trainer resubmitted in between, the return is rejected with `409` instead of acting on evidence you never saw.
</ParamField>

<ParamField body="attemptId" type="string">
  Optional binding proof: the exact attempt you reviewed. A mismatch rejects the return.
</ParamField>

The retake allowance is additive: each return grants one more attempt beyond the version's published limit. Grading and release remain separate operations.

## `require_retake_plan`

Validates a whole remediation batch without writing, so an agent can build a review-then-execute workflow.

<ParamField body="action" type="string" required>`require_retake_plan`</ParamField>

<ParamField body="jobId" type="string" required />

<ParamField body="rows" type="array" required>
  1–500 rows of `{ "rowKey", "assignmentId", "reason", "expectedSubmittedAt", "attemptId?", "grade?", "release?" }`.
</ParamField>

The plan checks every row against live state — binding identity, current submission, and grade/release feasibility — and returns ordered per-row commands with stable content-derived keys, plus a deterministic plan checksum.

## Limitation

A one-call atomic batch apply is not currently available: execute the plan's emitted commands individually (`grade`, `release`, `require_retake`), each with its provided idempotency key so retries stay convergent. The plan itself never writes.
