# okstra-code-review AI Manual

## Sources

- Skill source: [`skills/okstra-code-review/SKILL.md`](../../../skills/okstra-code-review/SKILL.md)
- Census rules: [`skills/okstra-code-review/references/census-rules.md`](../../../skills/okstra-code-review/references/census-rules.md)
- Review calibration: [`skills/okstra-code-review/references/review-calibration.md`](../../../skills/okstra-code-review/references/review-calibration.md)
- Target core (CLI): [`scripts/okstra_ctl/code_review_target.py`](../../../scripts/okstra_ctl/code_review_target.py)
- Review path core: [`scripts/okstra_ctl/code_review_paths.py`](../../../scripts/okstra_ctl/code_review_paths.py)
- Node wrapper: [`src/commands/inspect/code-review.mjs`](../../../src/commands/inspect/code-review.mjs)
- Rules the review applies: [`prompts/coding-preflight/`](../../../prompts/coding-preflight/)

## Purpose

`okstra-code-review` reviews what a diff changed — one okstra `implementation` stage, or any branch unrelated to an okstra run — against this project's coding-preflight rules, and leaves the result as a file under the project.

**Core principle — the census is law.** The orchestrator turns the diff into an explicit worklist of cells **once, deterministically**, before any reviewer is dispatched. Reviewers receive their slice as input and never rebuild, reinterpret, or extend it. Each returns a verdict for **every** cell it was given (`clean` or findings), so a skipped cell is visible rather than silently absent, and the coverage audit re-dispatches every cell that came back without one.

**Second principle — the rules are not in the skill.** They live in `prompts/coding-preflight/` (`overview.md` router + `clean-code.md` + the routed `languages/` / `frameworks/` / `architectures/` resources). Briefs point at absolute pack paths; they never restate a rule.

Distinguish it from writing a PR body (`okstra-pr-gen`), starting a run (`okstra-run`), and inspecting a finished task (`okstra-inspect`).

## Modes

| Mode | Trigger | Diff range | Result file |
|---|---|---|---|
| stage | a task token (`DEV-9184`, or a full `project-id:task-group:task-id` key) | the stage's registry `base_ref` → the stage branch head | `.okstra/tasks/<task-group>/<task-id>/code-reviews/stage-<NN>.md` (re-review: `-r2`, `-r3`, …) |
| branch | a branch name | `--base` when given, otherwise the CLI's estimate against the default branch | `.project-docs/code-reviews/<branch>/<YYYY-MM-DD>-<NN>.md` |

The branch-mode result path is the one deliberate exception to the `.okstra/`-only artifact rule: a branch review belongs to no task bundle.

## Preflight

A single Bash call with the literal `okstra` token (not wrapped in `if` / `eval` / `export` / `$(...)` / `VAR=` / `||` / `&&` / `npx`):

```bash
okstra preflight --runtime claude-code
```

`Okstra preflight: ready` → carry `Project root` as a literal. `Okstra preflight: failed` → retry the intended directory with `--cwd <dir>`; if that also fails, show `Reason` and `Recovery`, then stop. `unknown command: preflight` or `unknown command: code-review` means the `okstra` binary predates the skill — `npm i -g okstra@latest`, then stop.

## Flow

1. **Resolve the target.** A full `project-id:task-group:task-id` token is already the key. For a bare token, run `okstra model-io task-selection-input --project-root <projectRoot> --task-ref <token>` and use the fixed `Match count`, `Task`, and `Updated at` rows. Then run `okstra stage-map <taskKey> --project <projectRoot> --text` and pick from the fixed `Stages` and `Done stages` rows with a 3-option picker (recommendations first, `Enter directly` last). Branch mode picks the branch the same way; a detached HEAD is refused.
2. **Call the target CLI**: `okstra code-review target --task-key <k> --stage <N> --project-root <dir> --text`, or `okstra code-review target --branch <name> [--base <ref>] --project-root <dir> --text`. Carry the returned `Project root`, `Mode`, `Worktree path`, `Branch`, `Base commit`, `Head commit`, `Review path`, and `Round` values; stage mode also carries `Task key`, `Task root`, and `Stage`. Then run `okstra model-io code-review-input --project-root <projectRoot> --base <baseCommit> --head <headCommit>` and pass only that fixed Markdown view to model prompts. **Never derive the base** — the CLI owns it, and `Base commit` may be a ref rather than a commit id, so pass it through verbatim. Run git in `Worktree path` when non-empty, otherwise in `Project root` against `Branch`.
3. **Show the base and confirm it** with a 3-option picker before censusing anything — the returned `baseCommit` plus `git log -1 --oneline <baseCommit>` first, `Enter directly` last. Only an override calls the target CLI a second time, with `--base <ref>`.
4. **Census the diff** per `census-rules.md`: four axes (`structural`, `semantic`, `state-and-tests`, `general`), one cell per target per axis — the axis **is** the rule group, never one cell per individual rule. Membership is mechanical; judgment only ever decides a verdict. Route the coding-preflight packs exactly once here (`okstra paths --field home` → `<okstraHome>/prompts/coding-preflight/overview.md`), and fix the calibration path the briefs carry (`~/.claude/skills/okstra-code-review/references/review-calibration.md`). Print every cell table, every exclusion with its reason, the applied packs, and both completion criteria. Never truncate a large census — report the cell count and confirm.
5. **Materialize and dispatch four reviewers in parallel.** Each reviewer is a separate standalone invocation under `.okstra/agent-invocations/code-review/`. Write `<invocation-id>.instructions.md`, run `okstra agent-prompt materialize --purpose code-review --audience code-reviewer ...`, and verify the returned `metadataPath` before dispatch. A native host call receives the verified prompt body and `hostModelValue`; a deterministic provider process receives the prompt path and `modelExecutionValue` through `okstra worker-dispatch`. Each brief carries the diff, the work directory, its own axis's cell list verbatim, its packs' absolute paths, and the absolute calibration path.
6. **Complete and audit the results.** Capture each raw return under the purpose directory's `.tmp/`, then run `agent-prompt materialize-result`, `complete`, and `verify-completion` in order. Parse only the verified `returnedBody`. Diff those cells against the assigned slice; re-dispatch one gap-fill invocation per axis for missing cells, using a new invocation ID and the same full materialize/verify/result/completion boundary. A missing or unverified verdict is unfinished work, never an implicit `clean`.
7. **Merge and write.** Dedupe across axes, never re-grade a severity, and write the report to `reviewPath` with `Write` (frontmatter `mode` / `taskKey` / `branch` / `stage` / `round` / `baseCommit` / `headCommit` / `packs` / `generatedAt`; body `## Coverage`, `## Must-fix`, `## Should-fix`, `## Nits`, `## Score`). An empty diff dispatches no reviewer and still writes the report — Coverage reading zero cells and a Score table totalling 0.

## Output Rules

- The file is the deliverable. In session, print only `reviewPath`, the count per severity, and the score total — do not replay the findings in chat.
- The report's prose is Korean; paths, identifiers, rule names, and quoted code stay verbatim.
- Every finding cites a line **this diff changed**, and carries a concrete fix (a pseudocode sketch for readability, an alternative name for naming, a destination for structural).
- Read-only against the repository: `okstra code-review target` creates no directory and no file, and the review never reconciles git history. A rewritten base is reported, not force-fixed.
- Branch mode keeps the final review at `.project-docs/code-reviews/<branch>/`, but its invocation prompts, result envelopes, and completion markers remain under `.okstra/agent-invocations/code-review/`.
