with one click
cross-review
// Independent code review — Scrum Master spawns code-reviewer and security-reviewer sub-agents for unbiased, design-driven review.
// Independent code review — Scrum Master spawns code-reviewer and security-reviewer sub-agents for unbiased, design-driven review.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | cross-review |
| description | Sprint-end cross-cutting quality gate. Scrum Master runs static analysis, then spawns 5 aspect-specialized reviewers in parallel (each reviews the whole Sprint, not per-PBI fan-out). FAIL routing is aspect-specific: aspects 1-3 revert PBIs to in_progress_impl, aspects 4-5 generate follow-up PBIs in the next Sprint. |
| disable-model-invocation | false |
Sprint-end cross-cutting quality gate. The PBI Pipeline already runs
per-PBI impl + UT reviews via codex-impl-reviewer /
codex-ut-reviewer. This skill complements that with aspect-separated
Sprint-wide review, evaluated independently along five axes:
| # | Aspect | Reviewer agent | FAIL routing |
|---|---|---|---|
| 1 | Requirement conformance | requirement-conformance-reviewer | revert PBI → in_progress_impl |
| 2 | Cross-PBI functional quality | functional-quality-reviewer | revert PBI → in_progress_impl |
| 3 | Security | security-reviewer | revert PBI → in_progress_impl |
| 4 | Maintainability (static-analysis-grounded) | maintainability-reviewer | follow-up PBI in next Sprint |
| 5 | Docs consistency | docs-consistency-reviewer | follow-up PBI in next Sprint |
Each reviewer ingests the entire Sprint Increment, not per-PBI
slices. PBI mapping is recorded inside Findings via reverse-lookup
against paths_touched.
Do NOT duplicate per-PBI quality work; assume per-PBI Pass criteria
already satisfied (see .scrum/pbi/<pbi-id>/impl/review-r{last}.md and
ut/review-r{last}.md for prior context).
state.json (overall project phase: pbi_pipeline_active or review)backlog.json → all Sprint PBIs at
status ∈ {awaiting_cross_review, escalated}. Each PBI's
acceptance_criteria, title..scrum/pbi/<pbi-id>/state.json → paths_touched (set by
mark-pbi-ready-to-merge.sh at handoff; not mirrored to backlog.json).requirements.md + relevant docs/design/specs/**sprint.base_sha (for diff range).scrum/pbi/<pbi-id>/impl/review-r{last}.md.scrum/pbi/<pbi-id>/ut/review-r{last}.md.scrum/pbi/<pbi-id>/metrics/coverage-r{last}.jsonagents/requirement-conformance-reviewer.mdagents/functional-quality-reviewer.mdagents/security-reviewer.mdagents/maintainability-reviewer.mdagents/docs-consistency-reviewer.md.scrum/reviews/static-analysis-r{n}.json — pre-review tool output
(one file per cross-review round; round counter n increments per
full FAIL re-loop).scrum/reviews/sprint-impl-diff.txt — non-doc file diff list for
docs-consistency-reviewer.scrum/reviews/aspect-<aspect>-review.md — raw output per aspect
(5 files: aspect-requirement-conformance-review.md,
aspect-functional-quality-review.md,
aspect-security-review.md,
aspect-maintainability-review.md,
aspect-docs-consistency-review.md).scrum/reviews/<pbi-id>-review.md — per-PBI digest combining all
aspect Findings filtered to that PBI (existing schema preserved)backlog.json items[].status transitions:
awaiting_cross_review → cross_reviewcross_review → donecross_review → in_progress_impldone;
a new follow-up PBI is appended to backlog.json with status
draft for next Sprintbacklog.json → items[].review_doc_path set to per-PBI digeststate.json overall phase: reviewsprint.json.status: "cross_review"status ∈ {awaiting_cross_review, escalated}. Anything else must
be driven to one of those terminal values (via pbi-merge or
pbi-escalation-handler) before this skill runs.awaiting_cross_review; escalated PBIs are not reviewed here).sprint.json.base_sha is set (captured at Sprint start).Set ceremony state. Phase + Sprint status + per-PBI status:
.scrum/scripts/update-state-phase.sh review
.scrum/scripts/update-sprint-status.sh cross_review
for PBI_ID in $(jq -r '.items[] | select(.sprint_id == "<sprint-id>" and .status == "awaiting_cross_review") | .id' .scrum/backlog.json); do
.scrum/scripts/update-backlog-status.sh "$PBI_ID" cross_review
done
Sanity check. Every Sprint PBI now at
status ∈ {cross_review, escalated}. No
awaiting_cross_review / in_progress_* left.
Pre-review build verification. Start app → all tests pass.
Fail → TaskGet Developer status → terminated? re-spawn (Teammate
Liveness Protocol) → relay fix request. Do NOT review non-building
code.
Collect review inputs. For each Sprint PBI gather: design doc
paths, paths_touched, acceptance_criteria. Build the
Sprint-wide source path union for reviewers 1-4 and the
docs/** + diff list for reviewer 5:
git diff --name-only "$(jq -r '.base_sha' .scrum/sprint.json)"..HEAD \
| grep -vE '^docs/|\.md$' \
> .scrum/reviews/sprint-impl-diff.txt
Run static analysis (aspect-4 input). Determine round counter
n from existing .scrum/reviews/static-analysis-r*.json (next
integer; first round = 1):
ROUND=$(ls .scrum/reviews/static-analysis-r*.json 2>/dev/null \
| sed -E 's|.*static-analysis-r([0-9]+)\.json|\1|' \
| sort -n | tail -1)
ROUND=$(( ${ROUND:-0} + 1 ))
Run language tools on the Sprint-wide source path union:
ruff check --select F401,F841,ARG,B --output-format jsonshellcheck -f jsonAggregate results into
.scrum/reviews/static-analysis-r${ROUND}.json matching the schema
in agents/maintainability-reviewer.md § Receives. On any tool
failure, set tools[].exit_code to the non-zero code AND keep going
— do NOT abort the skill.
If every tool fails OR no source files match a supported language,
set skipped_reason to a short string (e.g. "no python/shell sources in diff"); the maintainability reviewer will degrade
accordingly.
Spawn 5 reviewers in parallel via the Agent tool. No
per-PBI fan-out — each reviewer receives the whole Sprint.
Single Agent call per aspect:
requirement-conformance-reviewer → requirements.md,
docs/design/specs/** (touched), Sprint PBI summary (id, title,
acceptance_criteria, paths_touched), Sprint-wide source path
list. Output target:
.scrum/reviews/aspect-requirement-conformance-review.md.functional-quality-reviewer → same Sprint summary + source
list, with explicit reminder that scope is cross-PBI seams
only. Output target:
.scrum/reviews/aspect-functional-quality-review.md.security-reviewer → Sprint-wide source path list +
requirements.md. Output target:
.scrum/reviews/aspect-security-review.md.maintainability-reviewer → Sprint-wide source list +
.scrum/reviews/static-analysis-r${ROUND}.json. Output target:
.scrum/reviews/aspect-maintainability-review.md.docs-consistency-reviewer → docs/** +
.scrum/reviews/sprint-impl-diff.txt + Sprint PBI summary.
Output target:
.scrum/reviews/aspect-docs-consistency-review.md.Do NOT pass: PBI descriptions, dev communications, .scrum/
pipeline state. (Reviewers 1/2/5 may receive PBI id + title +
paths_touched only — the minimum needed for PBI-mapping.)
Reviewer wait barrier. After spawning, wait for ALL 5
.scrum/reviews/aspect-*.md files to exist with mtime ≥ the spawn
timestamp. Do NOT attempt to stop the session in between. Reviewer
completion typically takes 60-120s — do NOT interpret a Stop hook
block (completion-gate.sh "PBIs not done") as reviewer failure.
Use TaskGet to verify status before re-spawning. See
agents/scrum-master.md § Background Subagent + Stop Hook Reading.
Reviewers are single-shot. Their Status = completed is the
success signal — do NOT apply the Teammate Liveness Protocol re-spawn
rule meant for Developer teammates. If the expected aspect-*.md
file does not appear within ~5 minutes after TaskGet shows
completed, then and only then re-spawn that single reviewer.
Collect aspect verdicts + Findings. Persist each reviewer's
raw response to its aspect-*.md output file.
Build per-PBI digests. For each Sprint PBI write
.scrum/reviews/<pbi-id>-review.md containing:
Handle FAIL — aspect-specific routing.
.scrum/scripts/update-backlog-status.sh "$PBI_ID" in_progress_impl
Then TaskGet the PBI's Developer; terminated → re-spawn
(Teammate Liveness Protocol). Relay the Findings as the fix
directive. Developer fixes on top of merged code, re-runs PBI
Review → UT Run → ready-to-merge handoff. SM re-merges; PBI
returns to awaiting_cross_review.# dedup guard — skip if a matching follow-up already exists
TITLE_PREFIX="[cross-review-followup:${PBI_ID}:${ASPECT}]"
EXISTS=$(jq --arg p "$TITLE_PREFIX" \
'[.items[] | select(.title | startswith($p))] | length' \
.scrum/backlog.json)
if [ "$EXISTS" = "0" ]; then
.scrum/scripts/add-backlog-item.sh \
--title "${TITLE_PREFIX} <short summary>" \
--description "<aspect> follow-up for ${PBI_ID}. See .scrum/reviews/${PBI_ID}-review.md for findings." \
--parent "${PBI_ID}"
else
echo "skip dedup ${TITLE_PREFIX}"
fi
<aspect> ∈ {maintainability, docs-consistency}. The PBI itself
is not reverted for these aspects.Re-loop policy. If any aspect 1/2/3 reverted ≥ 1 PBI to
in_progress_impl, the Sprint is incomplete. Wait for the
Developer cycle to bring those PBIs back to
awaiting_cross_review, then re-run the entire skill from
Step 1 for the affected PBIs (round counter n advances;
static analysis runs again; ALL 5 aspects re-evaluate). Aspect
4/5 follow-up PBI generation is fire-and-forget — they do NOT
cause a re-loop.
Mark passing PBIs done. When no aspect 1/2/3 Critical/High Finding remains for a PBI:
.scrum/scripts/update-backlog-status.sh "$PBI_ID" done
.scrum/scripts/set-backlog-item-field.sh "$PBI_ID" review_doc_path \
".scrum/reviews/${PBI_ID}-review.md"
Ref: FR-009
.scrum/reviews/aspect-*.md..scrum/reviews/static-analysis-r{n}.json (or skipped_reason
populated)..scrum/reviews/<pbi-id>-review.md exists for
every Sprint PBI.status: done (no Critical/High aspect
1/2/3 Finding survives).[cross-review-followup:<pbi-id>:<aspect>] title prefix and
parent_pbi_id set; no duplicates.items[].review_doc_path set for every Sprint PBI.state.json overall phase: review.