Code Task Review
Overview
Review the complete ordered jj task-change series from the supplied base through the current produced change. The reviewer reads the task file, scratchpad evidence (especially work.log), the jj diff and history for that whole range, and every touched file, then produces a structured YAML report at a known path. Repository inspection is jj-only.
The skill supports two modes of invocation with the same Steps below:
- Initial review — first review of a fresh produced jj change. No prior report exists at
{report_path}.
- Re-review — review of a fresh rework change produced in response to a prior review. The kickoff prompt indicates this is a re-review; a prior report exists at
{report_path} and is read from disk before forming new judgements. A re-review focuses on validating that prior critical/important findings and prior non-pass acceptance criteria have been addressed, surfaces regressions, and produces a fresh self-contained report on the current change series.
Each invocation runs in its own session; prior context is reloaded from the on-disk review.yaml rather than carried in conversation history. This keeps state management simple, makes recovery from crashes straightforward (just restart the re-review), and avoids prompt-cache expiry costs that would accrue across the implementer's intervening rework round.
The report format is defined in report-schema.md (sibling file). Findings carry a severity (critical / important / suggestion / nit), a category, and a file/line reference, so the same report can drive an interactive fix loop, PR-comment generation, or human-readable summary without further parsing. An external orchestrator decides what to do with findings.
Note: human-driven invocations. A single ad-hoc invocation (human running the skill once on a jj change) is fully supported and produces a valid review.yaml and a complete spec-workflow-meta block. Re-review behavior is triggered only when both a prior report exists at {report_path} and the prompt directs a re-review. The re-review capability MUST remain non-disruptive for standalone human invocations across future edits to this skill.
Parameters
- agents_dir (optional, default:
.agents): Base directory for structured-spec-to-code artifacts
- task (required): Path to the
.code-task.md file that was implemented
- current_change (optional): Current produced jj
change_id under review. If omitted, you MUST read it from the task's progress.md (recorded by task-to-code after committing)
- base_change (optional): jj
change_id of the task base. When supplied by an orchestrator, review the complete base-to-current range.
- produced_changes (optional): Ordered jj
change_id list for the implementation and rework changes. When supplied, review every listed change in order and describe the complete series in the merge request.
- task_state (optional): Orchestrator task-state path supplying current/base/ordered produced-change context. Use it when available; standalone human invocations remain valid with only the task and current change.
- scratchpad_dir (optional): Base directory for scratchpads. Defaults to
{agents_dir}/scratchpad/. The task's scratchpad is derived by mirroring the task file's path under tasks/, identical to the rule used by task-to-code
- report_path (optional): Where to write the YAML report. Defaults to
{scratchpad}/review.yaml. On a re-review round, the prior report at this path MUST be read before forming new judgements.
Constraints for parameter acquisition:
- You MUST ask for all parameters upfront in a single prompt
- You MUST validate that the task file and scratchpad exist
- You MUST resolve the current jj
change_id before proceeding (from parameters or progress.md); if neither is available, escalate
Escalation Policy
There are two distinct escalation channels, and you MUST NOT conflate them.
1. The escalated verdict — a successfully written report that stops the loop.
You can review the change and produce a complete report, but another rework round would be wasted or harmful. Emit verdict: escalated with a populated escalation block (reason + details) ONLY when:
- Unrecoverable state (
reason: unrecoverable_state) — the produced change cannot be trusted as a base for further rework, e.g. tests deleted or weakened wholesale to force green, or TDD evidence irreconcilable with the diff.
- Spec defect or ambiguity (
reason: spec_defect / spec_ambiguity) — the task as written cannot be satisfied: requirements contradict one another, or the task is under-specified such that any implementation is a guess at intent.
This is still a status: completed report — the report was written; the task needs intervention. See the shared reason taxonomy in report-schema.md.
2. Cannot produce a report at all — escalate to the user / orchestrator.
This is not a verdict; no valid report exists. Escalate this way ONLY when:
- The current jj change ID cannot be resolved
- The task file or scratchpad is missing or malformed in a way that prevents review
- The current change cannot be inspected (jj errors, missing parent, etc.)
In this case emit spec-workflow-meta with status: failed.
Do NOT escalate — by either channel — merely because findings are severe. A genuine but fixable critical finding is changes_requested; the orchestrator auto-reworks it. Record findings in the report and let the orchestrator route them.
Steps
1. Load Inputs
Read everything needed for review before forming any judgement.
Constraints:
- You MUST read the task file in full and extract:
- Acceptance Criteria (verbatim, with their numbering/names preserved)
- Technical Requirements
- Reference Documentation paths
- You MUST read the scratchpad files:
context.md, plan.md, progress.md, and work.log
- You MUST resolve the current jj
change_id and any supplied base/ordered produced changes.
- You MUST obtain the complete jj diff and ordered history from the supplied base through the current change (use jj range commands such as
jj diff -r {base}..{current}; never use Git).
- You MUST list every file touched by the complete jj change series and read each one in its current state.
- You MUST NOT create or move bookmarks, mutate commits or descriptions, amend/squash/rewrite changes, or otherwise change repository state. Review inspection is read-only, except for writing the report file.
- You SHOULD read referenced design documents only when an acceptance criterion or finding genuinely requires them — not by default
- You MUST NOT read prior changes or unrelated parts of the codebase unless a specific finding demands it
- On a re-review round: you SHOULD read the prior report at
{report_path} before forming new judgements. The prior report is the canonical schema-shaped record of the previous cycle's findings and AC statuses; use it to focus the re-review on verifying resolution of prior critical/important findings and non-pass acceptance criteria.
Re-review Round Behavior
When the kickoff prompt indicates a re-review and a prior report exists at {report_path}, the following constraints apply in addition to the standard steps.
Constraints:
- You MUST read the prior
{report_path} before forming judgements (per Step 1). The file is the canonical schema-shaped record of the previous round; it is the only carrier of prior-round context across the session boundary.
- You MUST focus the review on validating that every
critical/important finding from the prior report has been addressed in the new change. For each prior finding, cite the specific code or test change (file:line) that resolves it.
- You MUST focus on validating that every prior acceptance criterion whose status was
fail, partial, or not_verified is now pass (or explain why it remains non-passing).
- You MUST surface any regressions introduced by the rework — for example, newly deleted tests, new style or security issues introduced while fixing prior ones. Regressions are findings in their own right and are not excused by the prior round.
- You MUST overwrite
{report_path} with a fresh, self-contained report on the current change series, conforming in full to report-schema.md. The report is not a delta — it covers the complete series, with prior-finding resolution reflected in the summary and evidence fields.
- You SHOULD reflect prior-finding resolution in the prose
summary field (e.g., "All three prior findings resolved in the new change; one new style suggestion in models.py introduced during the rework.").
- You SHOULD NOT redo a full from-scratch review if the rework was narrow in scope. Focus effort where the rework touched the code; resurface prior-round concerns only if they remain unaddressed.
2. Discover Ecosystem-Specific Reviewers
Detect any installed skills that perform tech-stack-specific review and that fit the project's language/ecosystem.
Constraints:
- You MUST scan the available skills for ones whose purpose is reviewing or auditing within a specific ecosystem (examples: supply-chain audit for npm/pip/cargo, framework-specific lint reviewers, infrastructure-config reviewers)
- You MUST select only those whose ecosystem matches the project (inferred from the touched files' languages, lockfiles in the diff, or the codebase summary if available at
{agents_dir}/summary/)
- You MUST NOT invent ecosystem-specific checks yourself — if no matching skill is installed, simply record
ecosystem_reviews: [] and proceed
- You MUST invoke each selected skill, passing the same task/commit context, and collect its findings
- You MUST merge their findings into the main report's
findings list, setting each finding's source field to the skill's name (built-in checks use source: built-in)
3. Review Tests First
Before assessing production code, evaluate the test changes. This ordering avoids being anchored by the implementation.
Constraints:
- You MUST identify every test file touched by the complete change series and review its jj diff
- You MUST check for deleted or weakened tests using these signals:
- Tests removed in the diff (any
- def test_… / - it(…) / equivalent)
- Assertions removed without equivalent assertions added elsewhere
- Newly added skip/pending markers (
.skip, .todo, xit, pending, @pytest.mark.skip, etc.)
- Coverage of an acceptance criterion narrowed (e.g., a parametrized case dropped)
- For each suspicious change, you MUST consult
progress.md and work.log for justification:
work.log should contain a RED entry (failing test) followed by a GREEN entry (passing test) for each requirement; gaps are evidence the TDD cycle was skipped
- If a test removal is not explained in
progress.md, it is a critical finding by default
- You MUST verify that each behavioral acceptance criterion — one verifiable by executing code and asserting on observable output, state, or errors — has at least one test scenario that exercises it; missing test coverage for a behavioral criterion is at minimum an
important finding
- Some acceptance criteria are non-behavioral — documentation content or currency, presence/shape of configuration, file/directory structure, or prose quality — and have no runtime behavior to exercise. For these you MUST NOT require an automated test. Verify them by artifact inspection, and treat the implementer's cited inspection evidence (in
result.yaml/work.log) or your own inspection as sufficient. Requesting a mechanical test for a non-behavioral criterion is itself a review defect — do not do it.
- You MUST NOT request brittle tests, and you MUST NOT credit them as coverage. A brittle test pins incidental details (exact wording, formatting, ordering) rather than a contract or an observable behavior; the canonical anti-pattern is a change-detector that asserts a file contains literal strings copied from that same file. If the implementer added such a test, raise a
suggestion to remove or narrow it. (Narrow exceptions that ARE legitimate and should not be flagged: asserting the absence of a specific deprecated/stale token, or the presence of a genuine contract string an external consumer copies verbatim — a public env-var name, CLI flag, or API identifier.)
- You SHOULD evaluate test quality: meaningful assertions, edge cases, error paths — but lower-severity unless tied to an unmet criterion
- On a re-review round: pay particular attention to whether prior test-related findings have been addressed; surface any regressions in test coverage introduced by the rework as new findings
4. Verify Acceptance Criteria
For every acceptance criterion in the task file, determine whether the produced change series satisfies it.
Constraints:
- You MUST produce one entry in
acceptance_criteria per criterion in the task file, preserving the original criterion text
- For each criterion, you MUST assign one of:
pass, fail, partial, not_verified
- You MUST cite specific evidence (file:line references to test cases or implementation) in the
evidence field
- A behavioral criterion is
pass only if both the implementation and a test cover it; implementation without a test is at most partial
- A non-behavioral criterion (docs, config, structure, prose) is
pass when the artifact demonstrably satisfies it and you can cite concrete inspection evidence (a file:line or quoted excerpt); it does NOT require an automated test, and the absence of a test is not grounds for partial
- A criterion that cannot be evaluated from the available artifacts is
not_verified — do not guess
- Each non-
pass criterion MUST have a corresponding finding in the findings list, severity critical or important depending on whether it blocks task completion
- On a re-review round: for each criterion that was non-
pass in the prior report, you MUST explicitly state in evidence whether and how it has been addressed in the new commit, citing the specific change
5. Style and LSP Cleanliness
Inspect the touched files for style issues and language-server diagnostics.
Constraints:
- You MUST consult
{agents_dir}/summary/coding_style.md if it exists and treat it as the authoritative reference for naming, structure, error handling, and imports
- You MUST inspect every file touched by the change series for:
- Convention violations relative to coding_style.md or surrounding code
- Dead code, leftover debugging output, commented-out blocks
- Comments that explain what the code does (those are noise) versus why (those may be appropriate)
- You MUST attempt to obtain LSP diagnostics for each touched file; if an LSP tool is available in the harness, use it; otherwise note in the report that LSP coverage was not possible
- LSP errors in touched files are
important findings; LSP warnings are suggestion unless they indicate a real defect
- You MUST NOT report style findings on lines the commit did not modify, unless the issue was caused by the commit (e.g., a now-unused import elsewhere)
6. Security Pass
Assess the produced change series for security issues at the scope of the change.
Constraints:
- You MUST consider, at minimum: input validation at trust boundaries, authentication/authorization changes, handling of secrets and credentials, injection risks (SQL, command, template), unsafe deserialization, broken access control, sensitive data exposure in logs/errors, unsafe file/path operations
- You MUST scope the security pass to the changed code and its immediate callers/callees — this is not a full audit
- You MUST NOT include tech-stack-specific checks (e.g., npm supply chain) here — those come from ecosystem reviewers in step 2
- Security findings are
critical if exploitable as written, important if they create a latent risk, suggestion for hardening opportunities
7. Emit the Report
Write a single YAML file at {report_path} conforming to the schema in report-schema.md, then emit a complete fenced completion-metadata block.
Constraints:
- You MUST follow the schema in
report-schema.md exactly — field names, allowed values, required fields
- You MUST set
verdict by checking these conditions in order and taking the first that matches:
escalated if the loop cannot usefully continue — the change is in an unrecoverable state (e.g. tests deleted or weakened wholesale to force green), or the task itself is spec-defective / ambiguous (requirements contradict, or the task cannot be satisfied as written). You MUST also populate the top-level escalation block with a reason from the shared taxonomy (unrecoverable_state | spec_defect | spec_ambiguity | blocked_dependency) and details explaining the blocker and the intervention needed.
changes_requested if there are critical or important findings, or partial/fail acceptance criteria, and the implementer could reasonably fix them in another round
approved if no critical or important findings, and all acceptance criteria are pass
- A
critical finding blocks approval, not the loop. You MUST NOT escalate a genuine-but-fixable critical bug — emit changes_requested and let the orchestrator rework it. critical still forbids approved.
- You MUST NOT emit
verdict: blocked. It is deprecated; the orchestrator still accepts it only so archived reports keep parsing.
- You MUST include a
summary field with a 2–4 sentence prose summary suitable for a human reader. On a re-review, the summary SHOULD reflect prior-finding resolution (e.g., "All three prior findings resolved in the new jj change; one new style suggestion in models.py introduced during the rework.").
- You MUST sort
findings by severity (critical first), then by file path
- You MUST emit valid YAML — quote strings containing special characters, use block scalars (
|) for multi-line content
- You MUST overwrite any existing report at
{report_path}. The report is always a fresh, self-contained report on the current commit — not a delta or patch. (The orchestrator preserves prior cycles' copies in the run directory before allowing the next cycle to start.)
- Every successfully written report, including
approved, changes_requested, and escalated, MUST include non-blank merge_request.title and merge_request.body. The title MUST describe the complete change series and end with a task reference of the form [<Topic>: Step NN/Task NN] for a planned task or [<Topic>: Task NN] for a standalone interactive task; where <Topic> is a short (2-3 word) reference to the epic, feature/enhancement, etc which the step/task is part of. The body MUST summarize the initial implementation and every subsequent rework change.
- After writing the report, you MUST report to the user (or calling orchestrator) the report path and the verdict; do not paste the entire report into the response.
- After writing the report, you MUST emit a complete fenced block whose info string is exactly
spec-workflow-meta (not bare yaml) carrying status: completed, result_path, and schema_version: 1. This locator means the report was written successfully, regardless of verdict. The complete fence may appear anywhere in the response, with prose before or after it; if multiple complete fences appear, the parser selects the last complete one. Use status: failed only if the skill could not produce a valid report. The format and parser rules are defined in ../task-to-code/result-schema.md.
Example closing block:
status: completed
result_path: .agents/scratchpad/feat-templates-task-01/review.yaml
schema_version: 1
Examples
Example Input
task: ".agents/tasks/template-feature/step02/task-01-create-data-models.code-task.md"
Example Process
1. Load: read task file (3 acceptance criteria), scratchpad (progress.md cites the
current change), work.log (3 RED→GREEN cycles recorded), and the complete jj
base-to-current diff.
2. Ecosystem scan: project is Python; no matching ecosystem-review skill installed →
ecosystem_reviews: [].
3. Tests first: 4 test cases added, none removed, no skip markers. work.log shows
each AC's RED entry preceded its GREEN entry. AC3's test only covers happy path.
4. AC verification:
- AC1 (Templates created with name + description): pass — tested at
tests/models_test.py:14
- AC2 (Field validation rejects empty names): pass — tests/models_test.py:42
- AC3 (Round-trip serialization): partial — tested for valid input only,
no error-path test
5. Style/LSP: 1 unused import in src/models.py (LSP warning).
6. Security: no externally-influenced inputs touched, nothing to flag.
7. Emit: review.yaml verdict = changes_requested (1 partial AC + 1 LSP warning).
Close turn with spec-workflow-meta block.
Example Report Excerpt
review:
task_file: .agents/tasks/template-feature/step02/task-01-create-data-models.code-task.md
change_id: qrstuvwxyz
schema_version: 2
reviewed_at: 2026-04-27T14:32:00Z
verdict: changes_requested
merge_request:
title: "feat(models): add validated data models [REST API: Step 02/Task 01]"
body: |
Adds validated data models for all domain entities:
- models defined in ThingDSL
- validation rules for each model
- comprehensive fuzz test suite
summary: |
Implementation covers AC1 and AC2 with corresponding tests and clean
TDD evidence in work.log. AC3 lacks an error-path test, leaving the
round-trip behavior under-verified. One unused-import warning in models.py.
acceptance_criteria:
- text: "Templates can be created with a name and description"
status: pass
evidence: tests/models_test.py:14-28 covers creation with both fields.
...
findings:
- severity: important
category: acceptance_criteria
file: tests/models_test.py
line: null
title: AC3 missing error-path coverage
details: |
Round-trip serialization is tested for valid input only. The criterion
requires that malformed input be rejected; no test exercises that path.
suggested_action: |
Add a test asserting that deserializing malformed JSON raises the
project's standard validation error.
source: built-in
...
Troubleshooting
Current Change Cannot Be Resolved
If neither the current_change parameter nor progress.md provides a jj change ID:
- You MUST escalate to the user. Do not guess at the latest change — you may review the wrong series
Scratchpad Is Missing or Empty
If the scratchpad does not exist or work.log is absent:
- You SHOULD record this as a
critical finding under category tests titled "TDD evidence missing" — without work.log the test-deletion check cannot rely on RED→GREEN evidence
- You SHOULD still complete the rest of the review using only the diff and task file
LSP Tool Unavailable
If no LSP-diagnostic tool is available in the harness:
- You MUST set
lsp_coverage: unavailable in the report's review block
- You MAY still report style issues identifiable from static reading of the file
Conflicting Evidence Between work.log and Diff
If work.log claims a test exists but the diff shows it removed (or vice versa):
- You MUST treat this as a
critical finding under category tests, titled "TDD evidence inconsistent with change"
- If the discrepancy is narrow and the implementer can plausibly restore the coverage, emit
changes_requested and say so in suggested_action
- If tests were deleted or weakened wholesale — such that the change cannot be trusted as a base for further rework — emit
verdict: escalated with reason: unrecoverable_state
Artifacts
{scratchpad}/
└── review.yaml — Structured review report (schema in report-schema.md); overwritten on every invocation (initial or re-review)
The skill writes one report file. It does not modify the task file, any jj change or description, repository state, or any other scratchpad artifact. On each invocation, {report_path} is overwritten with a fresh, self-contained report on the current change series; the orchestrator archives the prior round's copy before launching the next round.
1---2name: code-task-review3description: Review jj changes produced by `task-to-code`. Supports initial reviews and re-reviews — a re-review is a fresh invocation that reads the prior review from disk and validates that its findings were addressed in the new change. Verifies acceptance-criteria coverage, test integrity (incl. detection of deleted/weakened tests), code style and LSP cleanliness on touched files, and security. Produces a structured YAML report that an orchestrator can use to route remediation back to the implementer.4---56# Code Task Review78## Overview910Review the complete ordered jj task-change series from the supplied base through the current produced change. The reviewer reads the task file, scratchpad evidence (especially `work.log`), the jj diff and history for that whole range, and every touched file, then produces a structured YAML report at a known path. Repository inspection is jj-only.1112The skill supports **two modes of invocation** with the same Steps below:13- **Initial review** — first review of a fresh produced jj change. No prior report exists at `{report_path}`.14- **Re-review** — review of a fresh rework change produced in response to a prior review. The kickoff prompt indicates this is a re-review; a prior report exists at `{report_path}` and is read from disk before forming new judgements. A re-review focuses on validating that prior `critical`/`important` findings and prior non-`pass` acceptance criteria have been addressed, surfaces regressions, and produces a fresh self-contained report on the current change series.1516Each invocation runs in its own session; prior context is reloaded from the on-disk `review.yaml` rather than carried in conversation history. This keeps state management simple, makes recovery from crashes straightforward (just restart the re-review), and avoids prompt-cache expiry costs that would accrue across the implementer's intervening rework round.1718The report format is defined in `report-schema.md` (sibling file). Findings carry a severity (`critical` / `important` / `suggestion` / `nit`), a category, and a file/line reference, so the same report can drive an interactive fix loop, PR-comment generation, or human-readable summary without further parsing. An external orchestrator decides what to do with findings.1920**Note: human-driven invocations.** A single ad-hoc invocation (human running the skill once on a jj change) is fully supported and produces a valid `review.yaml` and a complete `spec-workflow-meta` block. Re-review behavior is triggered only when both a prior report exists at `{report_path}` and the prompt directs a re-review. The re-review capability MUST remain non-disruptive for standalone human invocations across future edits to this skill.2122## Parameters2324- **agents_dir** (optional, default: `.agents`): Base directory for structured-spec-to-code artifacts25- **task** (required): Path to the `.code-task.md` file that was implemented26- **current_change** (optional): Current produced jj `change_id` under review. If omitted, you MUST read it from the task's `progress.md` (recorded by `task-to-code` after committing)27- **base_change** (optional): jj `change_id` of the task base. When supplied by an orchestrator, review the complete base-to-current range.28- **produced_changes** (optional): Ordered jj `change_id` list for the implementation and rework changes. When supplied, review every listed change in order and describe the complete series in the merge request.29- **task_state** (optional): Orchestrator task-state path supplying current/base/ordered produced-change context. Use it when available; standalone human invocations remain valid with only the task and current change.30- **scratchpad_dir** (optional): Base directory for scratchpads. Defaults to `{agents_dir}/scratchpad/`. The task's scratchpad is derived by mirroring the task file's path under `tasks/`, identical to the rule used by `task-to-code`31- **report_path** (optional): Where to write the YAML report. Defaults to `{scratchpad}/review.yaml`. On a re-review round, the prior report at this path MUST be read before forming new judgements.3233**Constraints for parameter acquisition:**34- You MUST ask for all parameters upfront in a single prompt35- You MUST validate that the task file and scratchpad exist36- You MUST resolve the current jj `change_id` before proceeding (from parameters or `progress.md`); if neither is available, escalate3738## Escalation Policy3940There are two distinct escalation channels, and you MUST NOT conflate them.4142**1. The `escalated` verdict — a successfully written report that stops the loop.**4344You can review the change and produce a complete report, but another rework round would be wasted or harmful. Emit `verdict: escalated` with a populated `escalation` block (`reason` + `details`) ONLY when:45- **Unrecoverable state** (`reason: unrecoverable_state`) — the produced change cannot be trusted as a base for further rework, e.g. tests deleted or weakened wholesale to force green, or TDD evidence irreconcilable with the diff.46- **Spec defect or ambiguity** (`reason: spec_defect` / `spec_ambiguity`) — the task as written cannot be satisfied: requirements contradict one another, or the task is under-specified such that any implementation is a guess at intent.4748This is still a `status: completed` report — the report was written; the *task* needs intervention. See the shared reason taxonomy in `report-schema.md`.4950**2. Cannot produce a report at all — escalate to the user / orchestrator.**5152This is not a verdict; no valid report exists. Escalate this way ONLY when:53- The current jj change ID cannot be resolved54- The task file or scratchpad is missing or malformed in a way that prevents review55- The current change cannot be inspected (jj errors, missing parent, etc.)5657In this case emit `spec-workflow-meta` with `status: failed`.5859**Do NOT escalate — by either channel — merely because findings are severe.** A genuine but fixable `critical` finding is `changes_requested`; the orchestrator auto-reworks it. Record findings in the report and let the orchestrator route them.6061## Steps6263### 1. Load Inputs6465Read everything needed for review before forming any judgement.6667**Constraints:**68- You MUST read the task file in full and extract:69 - Acceptance Criteria (verbatim, with their numbering/names preserved)70 - Technical Requirements71 - Reference Documentation paths72- You MUST read the scratchpad files: `context.md`, `plan.md`, `progress.md`, and `work.log`73- You MUST resolve the current jj `change_id` and any supplied base/ordered produced changes.74- You MUST obtain the complete jj diff and ordered history from the supplied base through the current change (use jj range commands such as `jj diff -r {base}..{current}`; never use Git).75- You MUST list every file touched by the complete jj change series and read each one in its current state.76- You MUST NOT create or move bookmarks, mutate commits or descriptions, amend/squash/rewrite changes, or otherwise change repository state. Review inspection is read-only, except for writing the report file.77- You SHOULD read referenced design documents only when an acceptance criterion or finding genuinely requires them — not by default78- You MUST NOT read prior changes or unrelated parts of the codebase unless a specific finding demands it79- **On a re-review round:** you SHOULD read the prior report at `{report_path}` before forming new judgements. The prior report is the canonical schema-shaped record of the previous cycle's findings and AC statuses; use it to focus the re-review on verifying resolution of prior `critical`/`important` findings and non-`pass` acceptance criteria.8081### Re-review Round Behavior8283When the kickoff prompt indicates a re-review and a prior report exists at `{report_path}`, the following constraints apply in addition to the standard steps.8485**Constraints:**86- You MUST read the prior `{report_path}` before forming judgements (per Step 1). The file is the canonical schema-shaped record of the previous round; it is the only carrier of prior-round context across the session boundary.87- You MUST focus the review on validating that every `critical`/`important` finding from the prior report has been addressed in the new change. For each prior finding, cite the specific code or test change (file:line) that resolves it.88- You MUST focus on validating that every prior acceptance criterion whose status was `fail`, `partial`, or `not_verified` is now `pass` (or explain why it remains non-passing).89- You MUST surface any regressions introduced by the rework — for example, newly deleted tests, new style or security issues introduced while fixing prior ones. Regressions are findings in their own right and are not excused by the prior round.90- You MUST overwrite `{report_path}` with a fresh, self-contained report on the **current** change series, conforming in full to `report-schema.md`. The report is not a delta — it covers the complete series, with prior-finding resolution reflected in the `summary` and `evidence` fields.91- You SHOULD reflect prior-finding resolution in the prose `summary` field (e.g., "All three prior findings resolved in the new change; one new style suggestion in models.py introduced during the rework.").92- You SHOULD NOT redo a full from-scratch review if the rework was narrow in scope. Focus effort where the rework touched the code; resurface prior-round concerns only if they remain unaddressed.9394### 2. Discover Ecosystem-Specific Reviewers9596Detect any installed skills that perform tech-stack-specific review and that fit the project's language/ecosystem.9798**Constraints:**99- You MUST scan the available skills for ones whose purpose is reviewing or auditing within a specific ecosystem (examples: supply-chain audit for npm/pip/cargo, framework-specific lint reviewers, infrastructure-config reviewers)100- You MUST select only those whose ecosystem matches the project (inferred from the touched files' languages, lockfiles in the diff, or the codebase summary if available at `{agents_dir}/summary/`)101- You MUST NOT invent ecosystem-specific checks yourself — if no matching skill is installed, simply record `ecosystem_reviews: []` and proceed102- You MUST invoke each selected skill, passing the same task/commit context, and collect its findings103- You MUST merge their findings into the main report's `findings` list, setting each finding's `source` field to the skill's name (built-in checks use `source: built-in`)104105### 3. Review Tests First106107Before assessing production code, evaluate the test changes. This ordering avoids being anchored by the implementation.108109**Constraints:**110- You MUST identify every test file touched by the complete change series and review its jj diff111- You MUST check for deleted or weakened tests using these signals:112 - Tests removed in the diff (any `- def test_…` / `- it(…)` / equivalent)113 - Assertions removed without equivalent assertions added elsewhere114 - Newly added skip/pending markers (`.skip`, `.todo`, `xit`, `pending`, `@pytest.mark.skip`, etc.)115 - Coverage of an acceptance criterion narrowed (e.g., a parametrized case dropped)116- For each suspicious change, you MUST consult `progress.md` and `work.log` for justification:117 - `work.log` should contain a RED entry (failing test) followed by a GREEN entry (passing test) for each requirement; gaps are evidence the TDD cycle was skipped118 - If a test removal is not explained in `progress.md`, it is a `critical` finding by default119- You MUST verify that each **behavioral** acceptance criterion — one verifiable by executing code and asserting on observable output, state, or errors — has at least one test scenario that exercises it; missing test coverage for a behavioral criterion is at minimum an `important` finding120- Some acceptance criteria are **non-behavioral** — documentation content or currency, presence/shape of configuration, file/directory structure, or prose quality — and have no runtime behavior to exercise. For these you MUST NOT require an automated test. Verify them by artifact inspection, and treat the implementer's cited inspection evidence (in `result.yaml`/`work.log`) or your own inspection as sufficient. **Requesting a mechanical test for a non-behavioral criterion is itself a review defect — do not do it.**121- You MUST NOT request brittle tests, and you MUST NOT credit them as coverage. A brittle test pins incidental details (exact wording, formatting, ordering) rather than a contract or an observable behavior; the canonical anti-pattern is a **change-detector** that asserts a file contains literal strings copied from that same file. If the implementer added such a test, raise a `suggestion` to remove or narrow it. (Narrow exceptions that ARE legitimate and should not be flagged: asserting the absence of a specific deprecated/stale token, or the presence of a genuine contract string an external consumer copies verbatim — a public env-var name, CLI flag, or API identifier.)122- You SHOULD evaluate test quality: meaningful assertions, edge cases, error paths — but lower-severity unless tied to an unmet criterion123- **On a re-review round:** pay particular attention to whether prior test-related findings have been addressed; surface any regressions in test coverage introduced by the rework as new findings124125### 4. Verify Acceptance Criteria126127For every acceptance criterion in the task file, determine whether the produced change series satisfies it.128129**Constraints:**130- You MUST produce one entry in `acceptance_criteria` per criterion in the task file, preserving the original criterion text131- For each criterion, you MUST assign one of: `pass`, `fail`, `partial`, `not_verified`132- You MUST cite specific evidence (file:line references to test cases or implementation) in the `evidence` field133- A **behavioral** criterion is `pass` only if both the implementation and a test cover it; implementation without a test is at most `partial`134- A **non-behavioral** criterion (docs, config, structure, prose) is `pass` when the artifact demonstrably satisfies it and you can cite concrete inspection evidence (a file:line or quoted excerpt); it does NOT require an automated test, and the absence of a test is not grounds for `partial`135- A criterion that cannot be evaluated from the available artifacts is `not_verified` — do not guess136- Each non-`pass` criterion MUST have a corresponding finding in the `findings` list, severity `critical` or `important` depending on whether it blocks task completion137- **On a re-review round:** for each criterion that was non-`pass` in the prior report, you MUST explicitly state in `evidence` whether and how it has been addressed in the new commit, citing the specific change138139### 5. Style and LSP Cleanliness140141Inspect the touched files for style issues and language-server diagnostics.142143**Constraints:**144- You MUST consult `{agents_dir}/summary/coding_style.md` if it exists and treat it as the authoritative reference for naming, structure, error handling, and imports145- You MUST inspect every file touched by the change series for:146 - Convention violations relative to coding_style.md or surrounding code147 - Dead code, leftover debugging output, commented-out blocks148 - Comments that explain *what* the code does (those are noise) versus *why* (those may be appropriate)149- You MUST attempt to obtain LSP diagnostics for each touched file; if an LSP tool is available in the harness, use it; otherwise note in the report that LSP coverage was not possible150- LSP errors in touched files are `important` findings; LSP warnings are `suggestion` unless they indicate a real defect151- You MUST NOT report style findings on lines the commit did not modify, unless the issue was caused by the commit (e.g., a now-unused import elsewhere)152153### 6. Security Pass154155Assess the produced change series for security issues at the scope of the change.156157**Constraints:**158- You MUST consider, at minimum: input validation at trust boundaries, authentication/authorization changes, handling of secrets and credentials, injection risks (SQL, command, template), unsafe deserialization, broken access control, sensitive data exposure in logs/errors, unsafe file/path operations159- You MUST scope the security pass to the changed code and its immediate callers/callees — this is not a full audit160- You MUST NOT include tech-stack-specific checks (e.g., npm supply chain) here — those come from ecosystem reviewers in step 2161- Security findings are `critical` if exploitable as written, `important` if they create a latent risk, `suggestion` for hardening opportunities162163### 7. Emit the Report164165Write a single YAML file at `{report_path}` conforming to the schema in `report-schema.md`, then emit a complete fenced completion-metadata block.166167**Constraints:**168- You MUST follow the schema in `report-schema.md` exactly — field names, allowed values, required fields169- You MUST set `verdict` by checking these conditions in order and taking the first that matches:170 - `escalated` if the loop cannot usefully continue — the change is in an **unrecoverable state** (e.g. tests deleted or weakened wholesale to force green), or the task itself is **spec-defective / ambiguous** (requirements contradict, or the task cannot be satisfied as written). You MUST also populate the top-level `escalation` block with a `reason` from the shared taxonomy (`unrecoverable_state` | `spec_defect` | `spec_ambiguity` | `blocked_dependency`) and `details` explaining the blocker and the intervention needed.171 - `changes_requested` if there are `critical` or `important` findings, or `partial`/`fail` acceptance criteria, and the implementer could reasonably fix them in another round172 - `approved` if no `critical` or `important` findings, and all acceptance criteria are `pass`173- A `critical` finding blocks *approval*, not the *loop*. You MUST NOT escalate a genuine-but-fixable critical bug — emit `changes_requested` and let the orchestrator rework it. `critical` still forbids `approved`.174- You MUST NOT emit `verdict: blocked`. It is deprecated; the orchestrator still accepts it only so archived reports keep parsing.175- You MUST include a `summary` field with a 2–4 sentence prose summary suitable for a human reader. On a re-review, the `summary` SHOULD reflect prior-finding resolution (e.g., "All three prior findings resolved in the new jj change; one new style suggestion in models.py introduced during the rework.").176- You MUST sort `findings` by severity (`critical` first), then by file path177- You MUST emit valid YAML — quote strings containing special characters, use block scalars (`|`) for multi-line content178- You MUST overwrite any existing report at `{report_path}`. The report is always a fresh, self-contained report on the **current** commit — not a delta or patch. (The orchestrator preserves prior cycles' copies in the run directory before allowing the next cycle to start.)179- Every successfully written report, including `approved`, `changes_requested`, and `escalated`, MUST include non-blank `merge_request.title` and `merge_request.body`. The title MUST describe the complete change series and end with a task reference of the form `[<Topic>: Step NN/Task NN]` for a planned task or `[<Topic>: Task NN]` for a standalone interactive task; where `<Topic>` is a short (2-3 word) reference to the epic, feature/enhancement, etc which the step/task is part of. The body MUST summarize the initial implementation and every subsequent rework change.180- After writing the report, you MUST report to the user (or calling orchestrator) the report path and the verdict; do not paste the entire report into the response.181- After writing the report, you MUST emit a complete fenced block whose info string is exactly `spec-workflow-meta` (not bare `yaml`) carrying `status: completed`, `result_path`, and `schema_version: 1`. This locator means the report was written successfully, regardless of verdict. The complete fence may appear anywhere in the response, with prose before or after it; if multiple complete fences appear, the parser selects the last complete one. Use `status: failed` only if the skill could not produce a valid report. The format and parser rules are defined in `../task-to-code/result-schema.md`.182183**Example closing block:**184185```spec-workflow-meta186status: completed187result_path: .agents/scratchpad/feat-templates-task-01/review.yaml188schema_version: 1189```190191## Examples192193### Example Input194```195task: ".agents/tasks/template-feature/step02/task-01-create-data-models.code-task.md"196```197198### Example Process199```2001. Load: read task file (3 acceptance criteria), scratchpad (progress.md cites the201 current change), work.log (3 RED→GREEN cycles recorded), and the complete jj202 base-to-current diff.2032. Ecosystem scan: project is Python; no matching ecosystem-review skill installed →204 ecosystem_reviews: [].2053. Tests first: 4 test cases added, none removed, no skip markers. work.log shows206 each AC's RED entry preceded its GREEN entry. AC3's test only covers happy path.2074. AC verification:208 - AC1 (Templates created with name + description): pass — tested at209 tests/models_test.py:14210 - AC2 (Field validation rejects empty names): pass — tests/models_test.py:42211 - AC3 (Round-trip serialization): partial — tested for valid input only,212 no error-path test2135. Style/LSP: 1 unused import in src/models.py (LSP warning).2146. Security: no externally-influenced inputs touched, nothing to flag.2157. Emit: review.yaml verdict = changes_requested (1 partial AC + 1 LSP warning).216 Close turn with spec-workflow-meta block.217```218219### Example Report Excerpt220```yaml221review:222 task_file: .agents/tasks/template-feature/step02/task-01-create-data-models.code-task.md223 change_id: qrstuvwxyz224 schema_version: 2225 reviewed_at: 2026-04-27T14:32:00Z226 verdict: changes_requested227228merge_request:229 title: "feat(models): add validated data models [REST API: Step 02/Task 01]"230 body: |231 Adds validated data models for all domain entities:232 - models defined in ThingDSL233 - validation rules for each model234 - comprehensive fuzz test suite235236summary: |237 Implementation covers AC1 and AC2 with corresponding tests and clean238 TDD evidence in work.log. AC3 lacks an error-path test, leaving the239 round-trip behavior under-verified. One unused-import warning in models.py.240241acceptance_criteria:242 - text: "Templates can be created with a name and description"243 status: pass244 evidence: tests/models_test.py:14-28 covers creation with both fields.245 ...246247findings:248 - severity: important249 category: acceptance_criteria250 file: tests/models_test.py251 line: null252 title: AC3 missing error-path coverage253 details: |254 Round-trip serialization is tested for valid input only. The criterion255 requires that malformed input be rejected; no test exercises that path.256 suggested_action: |257 Add a test asserting that deserializing malformed JSON raises the258 project's standard validation error.259 source: built-in260 ...261```262263## Troubleshooting264265### Current Change Cannot Be Resolved266If neither the `current_change` parameter nor `progress.md` provides a jj change ID:267- You MUST escalate to the user. Do not guess at the latest change — you may review the wrong series268269### Scratchpad Is Missing or Empty270If the scratchpad does not exist or `work.log` is absent:271- You SHOULD record this as a `critical` finding under category `tests` titled "TDD evidence missing" — without `work.log` the test-deletion check cannot rely on RED→GREEN evidence272- You SHOULD still complete the rest of the review using only the diff and task file273274### LSP Tool Unavailable275If no LSP-diagnostic tool is available in the harness:276- You MUST set `lsp_coverage: unavailable` in the report's `review` block277- You MAY still report style issues identifiable from static reading of the file278279### Conflicting Evidence Between work.log and Diff280If `work.log` claims a test exists but the diff shows it removed (or vice versa):281- You MUST treat this as a `critical` finding under category `tests`, titled "TDD evidence inconsistent with change"282- If the discrepancy is narrow and the implementer can plausibly restore the coverage, emit `changes_requested` and say so in `suggested_action`283- If tests were deleted or weakened wholesale — such that the change cannot be trusted as a base for further rework — emit `verdict: escalated` with `reason: unrecoverable_state`284285## Artifacts286287```288{scratchpad}/289└── review.yaml — Structured review report (schema in report-schema.md); overwritten on every invocation (initial or re-review)290```291292The skill writes one report file. It does not modify the task file, any jj change or description, repository state, or any other scratchpad artifact. On each invocation, `{report_path}` is overwritten with a fresh, self-contained report on the current change series; the orchestrator archives the prior round's copy before launching the next round.