Use when completed work in an active OAT project needs a quality gate before merge. Performs a lifecycle-scoped review after a task, phase, or full implementation, unlike oat-review-provide.
Request and execute a code or artifact review for the current project scope.
Produce an independent review artifact that verifies requirements/design alignment (mode-aware) and code quality.
Required: Active project with at least one completed task.
OAT MODE: Review Request
Purpose: Determine review scope and execute a fresh-context review.
When executing this skill, provide lightweight progress feedback so the user can tell what’s happening after they confirm.
Print a phase banner once at start using horizontal separators, e.g.:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ OAT ▸ PROVIDE REVIEW ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Before multi-step work (scope resolution, file gathering, writing artifact), print 2–5 short step indicators, e.g.:
[1/5] Resolving scope + range…[2/5] Collecting files + context…[3/5] Checking subagent availability…[4/5] Running review…[5/5] Writing review artifact…For long-running operations (reviewing large diffs, running verification commands), print a start line and a completion line (duration optional).
Keep it concise; don’t print a line for every shell command.
BLOCKED Activities:
ALLOWED Activities:
oat-project-review-provide code p02 # Code review for phase
oat-project-review-provide code p02-p03 # Code review for contiguous phase range
oat-project-review-provide code p02-t03 # Code review for task
oat-project-review-provide code final # Final code review
oat-project-review-provide code base_sha=abc # Review since specific SHA
oat-project-review-provide artifact discovery # Artifact review of discovery.md
oat-project-review-provide artifact spec # Artifact review of spec.md
oat-project-review-provide artifact design # Artifact review of design.md
Run the oat-project-review-provide skill and it will:
OAT stores active project context in .oat/config.local.json (activeProject, local-only).
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
Validation rules:
PROJECT_PATH must be set and point to an existing directory."$PROJECT_PATH/state.md" must exist for mode-aware review validation.If either check fails, stop and route. Do not create/guess project pointers in this skill.
Tell user:
activeProject in .oat/config.local.json + project state.md).oat-review-provide.oat-project-open (existing project)oat-project-quick-start (new quick project)oat-project-import-plan (external plan import)If validation passes, derive {project-name} as basename of PROJECT_PATH.
If arguments provided:
$ARGUMENTS[0] as review type: code or artifact$ARGUMENTS[1] as scope tokenIf no arguments — infer from project state:
Read state.md frontmatter to propose the most likely review type and scope:
PHASE=$(grep "^oat_phase:" "$PROJECT_PATH/state.md" 2>/dev/null | awk '{print $2}')
PHASE_STATUS=$(grep "^oat_phase_status:" "$PROJECT_PATH/state.md" 2>/dev/null | awk '{print $2}')
WORKFLOW_MODE=$(grep "^oat_workflow_mode:" "$PROJECT_PATH/state.md" 2>/dev/null | awk '{print $2}')
Inference rules (first match wins):
| Phase | Status | Inferred review |
|---|---|---|
discovery | complete | artifact discovery |
spec | complete | artifact spec |
design | complete | artifact design |
plan | complete | artifact plan |
implement | in_progress | code with current phase scope (derive from implementation.md current task) |
implement | complete | code final |
If inference produces a result, propose it and proceed unless the user overrides:
Based on project state ({phase}, {phase_status}), I'd run: {type} {scope}
Proceed? (Y / or specify different type scope)
If the user confirms (or just presses enter), use the inferred type and scope. If the user provides an alternative, use that instead.
If state.md is missing or phase is unrecognized: fall back to asking:
pNN-tNN task / pNN phase / pNN-pMM contiguous phase range / final / base_sha=SHA / SHA..HEAD rangediscovery / spec / design (and optionally plan)Before validating artifacts or gathering files, verify that the review will run and write artifacts against the correct branch and working directory. This step must run before Step 2 so that PROJECT_PATH points to the correct checkout for all downstream operations.
Detect current state:
CURRENT_BRANCH=$(git branch --show-current)
Handle detached HEAD: If CURRENT_BRANCH is empty (detached HEAD), resolve the branch from the current worktree entry:
if [[ -z "$CURRENT_BRANCH" ]]; then
REPO_ROOT=$(git rev-parse --show-toplevel)
CURRENT_BRANCH=$(git worktree list --porcelain | awk -v wt="$REPO_ROOT" '
/^worktree / { cur=$2 }
/^branch / { if (cur == wt) { sub("refs/heads/", "", $2); print $2 } }
')
fi
If still empty after worktree lookup, ask user: "Unable to detect current branch (detached HEAD). Which branch should the review target?"
TARGET_BRANCH="${TARGET_BRANCH:-$CURRENT_BRANCH}" # from user scope, worktree context, or default
If target branch matches current branch: proceed normally — no path adjustment needed.
If target branch differs from current branch:
Check if the target branch has a worktree:
WORKTREE_PATH=$(git worktree list --porcelain | awk -v branch="$TARGET_BRANCH" '
/^worktree / { wt=$2 }
/^branch / { if ($2 == "refs/heads/" branch) print wt }
')
If worktree exists for target branch:
REL_PROJECT=$(realpath --relative-to="$(git rev-parse --show-toplevel)" "$PROJECT_PATH")PROJECT_PATH to resolve inside the worktree: PROJECT_PATH="$WORKTREE_PATH/$REL_PROJECT"PROJECT_PATH.git -C "$WORKTREE_PATH" ...Review target: worktree at {WORKTREE_PATH} (branch: {TARGET_BRANCH})If no worktree exists (regular branch on main worktree):
Stop and notify the user. Do not silently write to the wrong branch.
Print:
⚠️ Target branch "{TARGET_BRANCH}" differs from current branch "{CURRENT_BRANCH}".
No worktree found for "{TARGET_BRANCH}".
Options:
1. Switch to branch "{TARGET_BRANCH}" (git checkout) — artifact will be written on that branch
2. Provide review inline only (no artifact written to disk)
3. Cancel and create a worktree first
Choose:
If user chooses option 1: run git checkout {TARGET_BRANCH}, then proceed.
If user chooses option 2: set INLINE_ONLY=true — skip artifact write (Step 7/8) and output review findings directly in the session. The user can manually save the output.
If user chooses option 3: stop and suggest oat-worktree-bootstrap-auto.
Resolve workflow mode from state (default spec-driven):
WORKFLOW_MODE=$(grep "^oat_workflow_mode:" "$PROJECT_PATH/state.md" 2>/dev/null | head -1 | awk '{print $2}')
WORKFLOW_MODE=${WORKFLOW_MODE:-spec-driven}
Required for code review (by mode):
spec-driven: spec.md, design.md, plan.mdquick: discovery.md, plan.md (spec.md/design.md optional if present)import: plan.md (references/imported-plan.md recommended, spec.md/design.md optional)Required for artifact review:
spec requires discovery.mddesign in spec-driven mode requires spec.mddesign in quick/import mode requires only discovery.md (spec is skipped in these modes)quick/import mode, missing spec.md must not be treated as a project review gate failure for artifact design; proceed with normal project-scoped review flow, artifact writing, and bookkeepingplan in spec-driven mode requires spec.md + design.mdplan in quick/import mode may use discovery.md and/or references/imported-plan.md insteadIf missing: Report missing required artifacts for the current mode and stop if requirements are not met.
If review type is artifact:
discovery, spec, design, or plan)SCOPE_RANGE="" (no git range required)If review type is code, use the scope resolution below.
Step 3a: Detect Re-Review Context
Before resolving scope, check if this is a re-review of fixes from a prior review cycle:
Scan plan.md for tasks tagged with (review) in the scope being reviewed (e.g., (p02-review) fix tasks for a p02 phase review or (p02-p03-review) for a contiguous phase-range review).
If (review) fix tasks exist and their status is completed:
This is a re-review. Before prompting, check the workflow preference:
AUTO_NARROW=$(oat config get workflow.autoNarrowReReviewScope 2>/dev/null || true)
AUTO_NARROW is true: Auto-narrow. Print Re-review scope: narrowed to fix commits (from workflow.autoNarrowReReviewScope). Gather only the commits for completed (review) fix tasks (see below). Skip the prompt.AUTO_NARROW is false: Use full scope. Print Re-review scope: full (from workflow.autoNarrowReReviewScope). Skip the prompt and proceed with full scope resolution below.Standard prompt (when preference is unset):
Detected completed review fix tasks for this scope:
- {task IDs and descriptions}
Scope to fix task commits only? (Y/n)
If yes (default): gather only the commits associated with those fix tasks using commit convention grep (e.g., git log --oneline --grep="\(pNN-tNN\)" HEAD~50..HEAD for each fix task ID). Set SCOPE_RANGE to cover only those commits.
If no: proceed with full scope resolution below (re-review everything).
If no (review) fix tasks exist, or they are not yet completed, proceed with normal scope resolution.
Priority order for scope resolution:
base_sha=<sha> → review range is <sha>..HEAD<sha1>..<sha2> → exact range reviewpNN-tNN → task scopepNN → phase scopepNN-pMM → contiguous inclusive phase-range scope (for example p02-p03)final → full project reviewPhase-range semantics:
pNN-pMM scopes are inclusive and must represent contiguous implementation phases.oat_review_scope value (for example p02-p03) in frontmatter and plan review rows.Automatic phase detection (if invoked at phase boundary):
Derive current phase from plan.md + implementation.md
Use commit convention grep to find commits:
# Task commits: grep for (pNN-tNN)
git log --oneline --grep="\(p${PHASE}-t" HEAD~50..HEAD
# Phase commits: grep for (pNN-
git log --oneline --grep="\(p${PHASE}-" HEAD~50..HEAD
For contiguous phase-range scopes (pNN-pMM), aggregate commit matches for each phase in the inclusive range:
for PHASE_NUM in $(seq "$START_PHASE_NUM" "$END_PHASE_NUM"); do
PHASE_ID=$(printf "p%02d" "$PHASE_NUM")
git log --oneline --grep="\\(${PHASE_ID}-" HEAD~50..HEAD
done
Fallback (if commit conventions missing/inconsistent):
base_sha=<sha><sha1>..<sha2> rangeMerge-base approach:
MERGE_BASE=$(git merge-base origin/main HEAD 2>/dev/null || git merge-base main HEAD 2>/dev/null)
SCOPE_RANGE="$MERGE_BASE..HEAD"
If review type is code, once scope range is determined:
FILES_CHANGED=$(git diff --name-only "$SCOPE_RANGE" 2>/dev/null)
FILE_COUNT=$(echo "$FILES_CHANGED" | wc -l | tr -d ' ')
If review type is artifact, the "files in scope" are the artifact(s):
case "$SCOPE_TOKEN" in
discovery) FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/discovery.md") ;;
spec) FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/spec.md" "$PROJECT_PATH/discovery.md") ;;
design)
if [[ "$WORKFLOW_MODE" == "spec-driven" ]]; then
FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/design.md" "$PROJECT_PATH/spec.md")
else
FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/design.md" "$PROJECT_PATH/discovery.md")
fi
;;
plan)
if [[ "$WORKFLOW_MODE" == "spec-driven" ]]; then
FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md")
elif [[ "$WORKFLOW_MODE" == "quick" ]]; then
FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/discovery.md")
else
FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/references/imported-plan.md")
fi
;;
esac
FILE_COUNT=$(echo "$FILES_CHANGED" | wc -l | tr -d ' ')
Display to user:
Review scope: {scope}
Range: {SCOPE_RANGE} (code reviews only; artifact reviews have no git range)
Files changed: {FILE_COUNT}
{FILE_LIST preview - first 20 files}
Proceed with review?
If review type == code and scope == final, gather unresolved deferred findings from prior review cycles.
Preferred sources:
implementation.md sections titled Deferred Findings (...)reviews/archived/ when implementation notes are incomplete (plus the current active review file in reviews/, if one exists for the in-flight cycle)Build:
DEFERRED_MEDIUM_COUNTDEFERRED_MINOR_COUNTDEFERRED_LEDGER (one-line summary per finding with source artifact)Rules:
Build the "Review Scope" metadata for the reviewer:
## Review Scope
**Project:** {PROJECT_PATH}
**Type:** {code|artifact}
**Scope:** {scope}{optional: " (" + SCOPE_RANGE + ")"}
**Date:** {today}
**Artifact Paths:**
- Spec: {PROJECT_PATH}/spec.md (required in spec-driven mode; optional in quick/import)
- Design: {PROJECT_PATH}/design.md (required in spec-driven mode; optional in quick/import)
- Plan: {PROJECT_PATH}/plan.md
- Implementation: {PROJECT_PATH}/implementation.md
- Discovery: {PROJECT_PATH}/discovery.md
- Imported Plan Reference: {PROJECT_PATH}/references/imported-plan.md (optional; import mode)
**Tasks in Scope (code review only):** {task IDs from plan.md matching scope}
**Files Changed ({FILE_COUNT}):**
{FILE_LIST}
**Commits (code review only):**
{git log --oneline for SCOPE_RANGE}
**Deferred Findings Ledger (final scope only):**
- Deferred Medium count: {DEFERRED_MEDIUM_COUNT}
- Deferred Minor count: {DEFERRED_MINOR_COUNT}
{DEFERRED_LEDGER}
Step 6a: Probe Subagent Availability
Before selecting a tier, announce the probe and its result so the user can see what's happening:
[3/5] Checking subagent availability…
→ oat-reviewer: {available | authorization required | not resolved} ({reason})
→ Selected: Tier {1|2|3} — {Subagent (fresh context) | Fresh session (recommended) | Inline review}
Detection logic:
If the host is Claude Code, use Task-style subagent dispatch with subagent_type: "oat-reviewer" and resolve from .claude/agents/oat-reviewer.md.
If the host is Cursor, invoke oat-reviewer using Cursor-native explicit invocation (/oat-reviewer) or natural mention, and resolve from .cursor/agents/oat-reviewer.md (or .claude/agents/oat-reviewer.md compatibility path).
If the host is Codex multi-agent, verify Codex requirements first:
[features] multi_agent = true is enabled in active Codex config.
If explicit role pinning is desired, agent_type must be a built-in role (default/worker/explorer) or a custom role declared under [agents.<name>].
Codex may also auto-select and spawn agents without explicit role pinning.
If the current Codex host requires explicit user authorization before calling spawn_agent, do not mark oat-reviewer as unresolved. Announce authorization required and ask one concise confirmation question before selecting Tier 2 or Tier 3:
Delegate this review to `oat-reviewer`?
If the user authorizes delegation and Codex role prerequisites are satisfied, use Tier 1.
If the user declines delegation, continue with the existing Tier 2 / Tier 3 fallback flow.
If the runtime can dispatch reviewer work (subagent_type in Claude Code, Cursor invocation via /name or natural mention, or Codex multi-agent spawn/auto-spawn) → Tier 1.
If the Task tool is not available or subagent dispatch is not supported → Tier 2.
If user explicitly requests inline or confirms they are already in a fresh session → Tier 3.
Step 6b: Tier 1 — Subagent (if available)
First, pre-compute the review artifact path using Step 7 naming conventions so it can be passed to the subagent.
Then spawn the reviewer:
subagent_type: "oat-reviewer" (resolves from .claude/agents/oat-reviewer.md)./oat-reviewer (or natural mention) with agent resolved from .cursor/agents/oat-reviewer.md or .claude/agents/oat-reviewer.md compatibility path.agent_type when a specific built-in/custom role is required.run_in_background: true)The oat-reviewer agent definition contains the full review process, mode contract, severity categories, artifact template, and critical rules. No additional instructions need to be injected.
After the subagent completes:
Step 6c: Tier 2 — Fresh Session (recommended fallback)
If subagent not available:
authorization required and the user approved delegation, do not use Tier 2. Return to Tier 1 and delegate to oat-reviewer.Instructions for fresh session:
To run review in a fresh session:
1. Open a new terminal/session
2. Run the oat-project-review-provide skill with: code {scope}
3. When complete, return to this session
4. Run the oat-project-review-receive skill
Step 6d: Tier 3 — Inline Reset (fallback)
If user insists on inline review in current session:
If INLINE_ONLY=true (user chose inline-only in Step 1.5): skip this step — no artifact path needed.
Review storage contract:
{PROJECT_PATH}/reviews/{PROJECT_PATH}/reviews/archived/oat-project-review-receive consumes a review, that skill moves it into reviews/archived/ for local-only historical storageNaming convention:
{PROJECT_PATH}/reviews/pNN-review-YYYY-MM-DD.md{PROJECT_PATH}/reviews/pNN-tNN-review-YYYY-MM-DD.md{PROJECT_PATH}/reviews/final-review-YYYY-MM-DD.md{PROJECT_PATH}/reviews/range-review-YYYY-MM-DD.md{PROJECT_PATH}/reviews/artifact-{artifact}-review-YYYY-MM-DD.mdIf file exists for today: append -v2, -v3, etc.
Important: PROJECT_PATH here must be the resolved path from Step 1.5. If a worktree was detected, this path is relative to the worktree root, ensuring the artifact is written on the correct branch.
mkdir -p "$PROJECT_PATH/reviews"
If running inline (Tier 3), execute the review and write artifact.
Review checklist (from oat-reviewer):
spec/design for spec-driven mode; discovery/import reference for quick/import)Review artifact template: (see .agents/agents/oat-reviewer.md for full format)
Shared ad-hoc companion reference (non-project mode):
.agents/skills/oat-review-provide/references/review-artifact-template.md---
oat_generated: true
oat_generated_at: { today }
oat_review_scope: { scope }
oat_review_type: { code|artifact }
oat_review_invocation: { manual|auto }
oat_project: { PROJECT_PATH }
---
# {Code|Artifact} Review: {scope}
**Reviewed:** {today}
**Scope:** {scope description}
**Files reviewed:** {N}
**Commits:** {range}
Frontmatter field: oat_review_invocation
manual (default): Review was manually triggered by the user. oat-project-review-receive uses standard disposition behavior (user prompts for triage, minors auto-deferred for non-final scopes).auto: Review was spawned by the auto-review checkpoint trigger in oat-project-implement. oat-project-review-receive uses relaxed disposition: minors are auto-converted to fix tasks (not deferred), no user prompts for disposition decisions.When oat-project-implement spawns this skill for auto-review at checkpoints, it passes context indicating auto invocation. Set oat_review_invocation: auto in the artifact frontmatter. For all other invocations (user-triggered, fresh session), use manual.
{2-3 sentence summary}
{findings or "None"}
{findings or "None"}
{findings or "None"}
{findings or "None"}
| Requirement | Status | Notes |
|---|---|---|
| {ID} | implemented / missing / partial | {notes} |
{list or "None"}
{commands to verify fixes}
Run the oat-project-review-receive skill to convert findings into plan tasks.
### Step 9: Update Plan Reviews Section
After review artifact is written, update `plan.md` `## Reviews` table _if plan.md exists_.
Update or add a row matching `{scope}`:
- `Scope`: `{scope}` (examples: `p02`, `final`, `spec`, `design`)
- Phase-range examples such as `p02-p03` are valid code-review scopes and should be preserved exactly.
- `Type`: `code` or `artifact`
- `Status`: `received` (receive-review will decide `fixes_added` vs `passed`; `passed` now requires no unresolved Critical/Important/Medium and final deferred-medium disposition when applicable)
- `Date`: `{today}`
- `Artifact`: `reviews/{filename}.md`
If plan.md is missing (e.g., spec/design review before planning), skip this update and rely on the review artifact + next-step routing.
### Step 9.5: Commit Review Bookkeeping Atomically (Required)
**If `INLINE_ONLY=true`:** skip this step — no artifact was written to disk.
After writing the review artifact and applying the Step 9 Reviews-table update, create an atomic bookkeeping commit.
**If a worktree was resolved in Step 1.5:** run git commands scoped to the worktree (`git -C "$WORKTREE_PATH" ...`) so the commit lands on the worktree branch, not the current session's branch.
**Commit scope:**
- Always include the active review artifact file: `reviews/{filename}.md`
- Include `plan.md` when Step 9 updated the Reviews table
- Do not write or commit new review artifacts directly into `reviews/archived/`
- Do not include unrelated implementation/code files in this commit
**Commit message:**
- `chore(oat): record {scope} review artifact`
**If the user asks to defer commit:**
- Require explicit user confirmation to proceed without commit
- Warn that uncommitted review bookkeeping can desync workflow routing/restart behavior
- In the summary, clearly state: "bookkeeping not committed (user-approved defer)"
### Step 10: Output Summary
**If subagent used (Tier 1):**
Review requested via subagent.
When the reviewer finishes, run the oat-project-review-receive skill to process findings.
**If fresh session recommended (Tier 2):**
For best review quality, run in a fresh session:
Or say "inline" to run review in current session (less reliable).
**If inline review completed (Tier 3):**
Review complete for {project-name}.
Scope: {scope} Files reviewed: {N} Findings: {N} critical, {N} important, {N} medium, {N} minor
Review artifact: {path} Bookkeeping commit: {sha or "deferred with user approval"}
Next: Run the oat-project-review-receive skill to convert findings into plan tasks.
## Success Criteria
- Active project resolved
- Review type and scope determined
- Target branch and working directory resolved (worktree detection in Step 1.5)
- Commit range identified
- Files changed list obtained
- Review executed (subagent, fresh session guidance, or inline)
- Review artifact written to the correct branch's working directory (worktree path if applicable; inline-only if user chose that option)
- Plan.md Reviews section updated
- Review artifact + plan bookkeeping committed atomically on the correct branch (or explicitly deferred with user approval)
- For final scope, deferred findings ledger included in reviewer context
- User guided to next step (`oat-project-review-receive`)