Backend Code Review Hard gates (sequence) Advance only when each pass condition is objectively satisfied (prevents linter-owned false positives and ungrounded findings): | Gate | Pass condition | |------|----------------| | G1 — Diff scope | Step 1 command has been run; the changed paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings). | | G2 — Linters before manual style/type | For and : either no project config exists for that tool, or it was run on the changed files and you captured pass/fail (exit code or clear tool output)…

\n```\n\n## Step 2: Verify Linter Status\n\n**CRITICAL**: Run project linters BEFORE flagging any style or type issues. **Pass (G2):** You may only proceed to Step 3 after each configured linter has been run on the changed files or you have recorded why it was skipped (missing config).\n\n```bash\n# Check if ruff config exists and run it\nif [ -f \"pyproject.toml\" ] || [ -f \"ruff.toml\" ]; then\n ruff check \u003cchanged_files>\nfi\n\n# Check if mypy config exists and run it\nif [ -f \"pyproject.toml\" ] || [ -f \"mypy.ini\" ]; then\n mypy \u003cchanged_files>\nfi\n```\n\n**Rules:**\n- If a linter passes for a specific rule (e.g., line length), DO NOT flag that issue manually\n- Linter configuration is authoritative for style rules\n- Only flag issues that linters cannot detect (semantic issues, architectural problems)\n\n**Why:** Analysis of 24 review outcomes showed 4 false positives (17%) where reviewers flagged line-length violations that `ruff check` confirmed don't exist. The linter's configuration reflects intentional project decisions.\n\n## Step 3: Detect Technologies\n\n```bash\n# Detect Pydantic-AI\ngrep -r \"pydantic_ai\\|@agent\\.tool\\|RunContext\" --include=\"*.py\" -l | head -3\n\n# Detect SQLAlchemy\ngrep -r \"from sqlalchemy\\|Session\\|relationship\" --include=\"*.py\" -l | head -3\n\n# Detect Postgres-specific\ngrep -r \"psycopg\\|asyncpg\\|JSONB\\|GIN\" --include=\"*.py\" -l | head -3\n\n# Check for test files\ngit diff --name-only $(git merge-base HEAD main)..HEAD | grep -E 'test.*\\.py

Backend Code Review Hard gates (sequence) Advance only when each pass condition is objectively satisfied (prevents linter-owned false positives and ungrounded findings): | Gate | Pass condition | |------|----------------| | G1 — Diff scope | Step 1 command has been run; the changed paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings). | | G2 — Linters before manual style/type | For and : either no project config exists for that tool, or it was run on the changed files and you captured pass/fail (exit code or clear tool output)…

\n```\n\n## Step 4: Load Verification Protocol\n\nLoad `beagle-python:review-verification-protocol` skill and keep its checklist in mind throughout the review.\n\n## Step 5: Load Skills\n\nUse the `Skill` tool to load each applicable skill (e.g., `Skill(skill: \"beagle-python:python-code-review\")`).\n\n**Always load:**\n- `beagle-python:python-code-review`\n- `beagle-python:fastapi-code-review`\n\n**Conditionally load based on detection:**\n\n| Condition | Skill |\n|-----------|-------|\n| Test files changed | `beagle-python:pytest-code-review` |\n| Pydantic-AI detected | `beagle-ai:pydantic-ai-common-pitfalls` |\n| SQLAlchemy detected | `beagle-python:sqlalchemy-code-review` |\n| Postgres detected | `beagle-python:postgres-code-review` |\n\n## Step 6: Review\n\n**Sequential (default):**\n1. Load applicable skills\n2. Review Python quality issues first\n3. Review FastAPI patterns\n4. Review detected technology areas\n5. Consolidate findings\n\n**Parallel (--parallel flag):**\n1. Detect all technologies upfront\n2. Spawn one subagent per technology area with `Task` tool\n3. Each agent loads its skill and reviews its domain\n4. Wait for all agents\n5. Consolidate findings\n\n### Before Flagging Optimization or Pattern Issues\n\n1. **Check CLAUDE.md** for documented intentional patterns\n2. **Check code comments** around the flagged area for \"intentional\", \"optimization\", or \"NOTE:\"\n3. **Trace the code path** before claiming missing coverage or inconsistent handling\n4. **Consider framework idioms** - what looks wrong generically may be correct for the framework\n\n**Why:** Analysis showed rejections where reviewers flagged \"inconsistent error handling\" that was intentional optimization, and \"missing test coverage\" for code paths that don't exist.\n\n## Step 7: Verify Findings\n\n**Pass (G4):** No issue ships until all bullets below are true for that issue.\n\nBefore reporting any issue:\n1. Re-read the actual code (not just diff context)\n2. For \"unused\" claims - did you search all references?\n3. For \"missing\" claims - did you check framework/parent handling?\n4. For syntax issues - did you verify against current version docs?\n5. Remove any findings that are style preferences, not actual issues\n\n## Step 8: Review Convergence\n\n**Pass (G5):** Final markdown matches the Output Format template; verdict line reflects only Critical/Major blockers per scope rules below.\n\n### Single-Pass Completeness\n\nYou MUST report ALL issues across ALL categories (style, logic, types, tests, security, performance) in a single review pass. Do not hold back issues for later rounds.\n\nBefore submitting findings, ask yourself:\n- \"If all my recommended fixes are applied, will I find NEW issues in the fixed code?\"\n- \"Am I requesting new code (tests, types, modules) that will itself need review?\"\n\nIf yes to either: include those anticipated downstream issues NOW, in this review, so the author can address everything at once.\n\n### Scope Rules\n\n- Review ONLY the code in the diff and directly related existing code\n- Do NOT request new features, test infrastructure, or architectural changes that didn't exist before the diff\n- If test coverage is missing, flag it as ONE Minor issue (\"Missing test coverage for X, Y, Z\") — do NOT specify implementation details like mock libraries, behaviour extraction, or dependency injection patterns that would introduce substantial new code\n- Typespecs, documentation, and naming issues are Minor unless they affect public API contracts\n- Do NOT request adding new dependencies (e.g. Mox, testing libraries, linter plugins)\n\n### Fix Complexity Budget\n\nFixes to existing code should be flagged at their real severity regardless of size.\n\nHowever, requests for **net-new code that didn't exist before the diff** must be classified as Informational:\n- Adding a new dependency (e.g. Mox, a linter plugin)\n- Creating entirely new modules, files, or test suites\n- Extracting new behaviours, protocols, or abstractions\n\nThese are improvement suggestions for the author to consider in future work, not review blockers.\n\n### Iteration Policy\n\nIf this is a re-review after fixes were applied:\n- ONLY verify that previously flagged issues were addressed correctly\n- Do NOT introduce new findings unrelated to the previous review's issues\n- Accept Minor/Nice-to-Have issues that weren't fixed — do not re-flag them\n- The goal of re-review is VERIFICATION, not discovery\n\n## Output Format\n\n```markdown\n## Review Summary\n\n[1-2 sentence overview of findings]\n\n## Issues\n\n### Critical (Blocking)\n\n1. [FILE:LINE] ISSUE_TITLE\n - Issue: Description of what's wrong\n - Why: Why this matters (bug, type safety, security)\n - Fix: Specific recommended fix\n\n### Major (Should Fix)\n\n2. [FILE:LINE] ISSUE_TITLE\n - Issue: ...\n - Why: ...\n - Fix: ...\n\n### Minor (Nice to Have)\n\nN. [FILE:LINE] ISSUE_TITLE\n - Issue: ...\n - Why: ...\n - Fix: ...\n\n### Informational (For Awareness)\n\nN. [FILE:LINE] SUGGESTION_TITLE\n - Suggestion: ...\n - Rationale: ...\n\n## Good Patterns\n\n- [FILE:LINE] Pattern description (preserve this)\n\n## Verdict\n\nReady: Yes | No | With fixes 1-N (Critical/Major only; Minor items are acceptable)\nRationale: [1-2 sentences]\n```\n\n## Post-Fix Verification\n\nAfter fixes are applied, run:\n\n```bash\nruff check .\nmypy .\npytest\n```\n\nAll checks must pass before approval.\n\n## Rules\n\n- Load skills BEFORE reviewing (not after)\n- Number every issue sequentially (1, 2, 3...)\n- Include FILE:LINE for each issue\n- Separate Issue/Why/Fix clearly\n- Categorize by actual severity\n- Run verification after fixes\n- Report ALL issues in a single pass — do not hold back findings for later iterations\n- Re-reviews verify previous fixes ONLY — no new discovery\n- Requests for net-new code (new modules, dependencies, test suites) are Informational, not blocking\n- The Verdict ignores Minor and Informational items — only Critical and Major block approval\n---","attachment_filenames":[],"attachments":[],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Backend Code Review","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Hard gates (sequence)","type":"text"}]},{"type":"paragraph","content":[{"text":"Advance only when each ","type":"text"},{"text":"pass condition","type":"text","marks":[{"type":"strong"}]},{"text":" is objectively satisfied (prevents linter-owned false positives and ungrounded findings):","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Gate","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pass condition","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"G1 — Diff scope","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Step 1 command has been run; the changed ","type":"text"},{"text":".py","type":"text","marks":[{"type":"code_inline"}]},{"text":" paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"G2 — Linters before manual style/type","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"For ","type":"text"},{"text":"ruff","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"mypy","type":"text","marks":[{"type":"code_inline"}]},{"text":": either no project config exists for that tool, ","type":"text"},{"text":"or","type":"text","marks":[{"type":"strong"}]},{"text":" it was run on the changed files and you captured pass/fail (exit code or clear tool output). ","type":"text"},{"text":"Do not","type":"text","marks":[{"type":"strong"}]},{"text":" add manual style or type findings for rules those tools already enforce when configured.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"G3 — Protocol and base skills","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"beagle-python:review-verification-protocol","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"beagle-python:python-code-review","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"beagle-python:fastapi-code-review","type":"text","marks":[{"type":"code_inline"}]},{"text":" are loaded before Step 6 substantive review.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"G4 — Evidence per issue","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Step 7 checks are satisfied for each reported issue before it appears in the final list (re-read source, search references for “unused”, confirm framework handling for “missing”, verify syntax against current docs).","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"G5 — Output contract","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Findings use sequential numbering, every issue has ","type":"text"},{"text":"FILE:LINE","type":"text","marks":[{"type":"code_inline"}]},{"text":", and the ","type":"text"},{"text":"Verdict","type":"text","marks":[{"type":"strong"}]},{"text":" follows Step 8 (Critical/Major only block; Minor/Informational do not).","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Arguments","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--parallel","type":"text","marks":[{"type":"code_inline"}]},{"text":": Spawn specialized subagents per technology area","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Path: Target directory (default: current working directory)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 1: Identify Changed Files","type":"text"}]},{"type":"paragraph","content":[{"text":"Pass (G1):","type":"text","marks":[{"type":"strong"}]},{"text":" Capture the command output (or equivalent) as your authoritative changed-","type":"text"},{"text":".py","type":"text","marks":[{"type":"code_inline"}]},{"text":" set before Steps 2–3.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"git diff --name-only $(git merge-base HEAD main)..HEAD | grep -E '\\.py

Backend Code Review Hard gates (sequence) Advance only when each pass condition is objectively satisfied (prevents linter-owned false positives and ungrounded findings): | Gate | Pass condition | |------|----------------| | G1 — Diff scope | Step 1 command has been run; the changed paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings). | | G2 — Linters before manual style/type | For and : either no project config exists for that tool, or it was run on the changed files and you captured pass/fail (exit code or clear tool output)…

","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 2: Verify Linter Status","type":"text"}]},{"type":"paragraph","content":[{"text":"CRITICAL","type":"text","marks":[{"type":"strong"}]},{"text":": Run project linters BEFORE flagging any style or type issues. ","type":"text"},{"text":"Pass (G2):","type":"text","marks":[{"type":"strong"}]},{"text":" You may only proceed to Step 3 after each configured linter has been run on the changed files or you have recorded why it was skipped (missing config).","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check if ruff config exists and run it\nif [ -f \"pyproject.toml\" ] || [ -f \"ruff.toml\" ]; then\n ruff check \u003cchanged_files>\nfi\n\n# Check if mypy config exists and run it\nif [ -f \"pyproject.toml\" ] || [ -f \"mypy.ini\" ]; then\n mypy \u003cchanged_files>\nfi","type":"text"}]},{"type":"paragraph","content":[{"text":"Rules:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If a linter passes for a specific rule (e.g., line length), DO NOT flag that issue manually","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Linter configuration is authoritative for style rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Only flag issues that linters cannot detect (semantic issues, architectural problems)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Why:","type":"text","marks":[{"type":"strong"}]},{"text":" Analysis of 24 review outcomes showed 4 false positives (17%) where reviewers flagged line-length violations that ","type":"text"},{"text":"ruff check","type":"text","marks":[{"type":"code_inline"}]},{"text":" confirmed don't exist. The linter's configuration reflects intentional project decisions.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 3: Detect Technologies","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Detect Pydantic-AI\ngrep -r \"pydantic_ai\\|@agent\\.tool\\|RunContext\" --include=\"*.py\" -l | head -3\n\n# Detect SQLAlchemy\ngrep -r \"from sqlalchemy\\|Session\\|relationship\" --include=\"*.py\" -l | head -3\n\n# Detect Postgres-specific\ngrep -r \"psycopg\\|asyncpg\\|JSONB\\|GIN\" --include=\"*.py\" -l | head -3\n\n# Check for test files\ngit diff --name-only $(git merge-base HEAD main)..HEAD | grep -E 'test.*\\.py

Backend Code Review Hard gates (sequence) Advance only when each pass condition is objectively satisfied (prevents linter-owned false positives and ungrounded findings): | Gate | Pass condition | |------|----------------| | G1 — Diff scope | Step 1 command has been run; the changed paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings). | | G2 — Linters before manual style/type | For and : either no project config exists for that tool, or it was run on the changed files and you captured pass/fail (exit code or clear tool output)…

","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 4: Load Verification Protocol","type":"text"}]},{"type":"paragraph","content":[{"text":"Load ","type":"text"},{"text":"beagle-python:review-verification-protocol","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill and keep its checklist in mind throughout the review.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 5: Load Skills","type":"text"}]},{"type":"paragraph","content":[{"text":"Use the ","type":"text"},{"text":"Skill","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool to load each applicable skill (e.g., ","type":"text"},{"text":"Skill(skill: \"beagle-python:python-code-review\")","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"paragraph","content":[{"text":"Always load:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"beagle-python:python-code-review","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"beagle-python:fastapi-code-review","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Conditionally load based on detection:","type":"text","marks":[{"type":"strong"}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Condition","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test files changed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"beagle-python:pytest-code-review","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pydantic-AI detected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"beagle-ai:pydantic-ai-common-pitfalls","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SQLAlchemy detected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"beagle-python:sqlalchemy-code-review","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Postgres detected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"beagle-python:postgres-code-review","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 6: Review","type":"text"}]},{"type":"paragraph","content":[{"text":"Sequential (default):","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load applicable skills","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review Python quality issues first","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review FastAPI patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review detected technology areas","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Consolidate findings","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Parallel (--parallel flag):","type":"text","marks":[{"type":"strong"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect all technologies upfront","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Spawn one subagent per technology area with ","type":"text"},{"text":"Task","type":"text","marks":[{"type":"code_inline"}]},{"text":" tool","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Each agent loads its skill and reviews its domain","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wait for all agents","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Consolidate findings","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Before Flagging Optimization or Pattern Issues","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check CLAUDE.md","type":"text","marks":[{"type":"strong"}]},{"text":" for documented intentional patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Check code comments","type":"text","marks":[{"type":"strong"}]},{"text":" around the flagged area for \"intentional\", \"optimization\", or \"NOTE:\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Trace the code path","type":"text","marks":[{"type":"strong"}]},{"text":" before claiming missing coverage or inconsistent handling","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Consider framework idioms","type":"text","marks":[{"type":"strong"}]},{"text":" - what looks wrong generically may be correct for the framework","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Why:","type":"text","marks":[{"type":"strong"}]},{"text":" Analysis showed rejections where reviewers flagged \"inconsistent error handling\" that was intentional optimization, and \"missing test coverage\" for code paths that don't exist.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 7: Verify Findings","type":"text"}]},{"type":"paragraph","content":[{"text":"Pass (G4):","type":"text","marks":[{"type":"strong"}]},{"text":" No issue ships until all bullets below are true for that issue.","type":"text"}]},{"type":"paragraph","content":[{"text":"Before reporting any issue:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Re-read the actual code (not just diff context)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For \"unused\" claims - did you search all references?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For \"missing\" claims - did you check framework/parent handling?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For syntax issues - did you verify against current version docs?","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Remove any findings that are style preferences, not actual issues","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Step 8: Review Convergence","type":"text"}]},{"type":"paragraph","content":[{"text":"Pass (G5):","type":"text","marks":[{"type":"strong"}]},{"text":" Final markdown matches the Output Format template; verdict line reflects only Critical/Major blockers per scope rules below.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Single-Pass Completeness","type":"text"}]},{"type":"paragraph","content":[{"text":"You MUST report ALL issues across ALL categories (style, logic, types, tests, security, performance) in a single review pass. Do not hold back issues for later rounds.","type":"text"}]},{"type":"paragraph","content":[{"text":"Before submitting findings, ask yourself:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"If all my recommended fixes are applied, will I find NEW issues in the fixed code?\"","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\"Am I requesting new code (tests, types, modules) that will itself need review?\"","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"If yes to either: include those anticipated downstream issues NOW, in this review, so the author can address everything at once.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scope Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review ONLY the code in the diff and directly related existing code","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do NOT request new features, test infrastructure, or architectural changes that didn't exist before the diff","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If test coverage is missing, flag it as ONE Minor issue (\"Missing test coverage for X, Y, Z\") — do NOT specify implementation details like mock libraries, behaviour extraction, or dependency injection patterns that would introduce substantial new code","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Typespecs, documentation, and naming issues are Minor unless they affect public API contracts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do NOT request adding new dependencies (e.g. Mox, testing libraries, linter plugins)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Fix Complexity Budget","type":"text"}]},{"type":"paragraph","content":[{"text":"Fixes to existing code should be flagged at their real severity regardless of size.","type":"text"}]},{"type":"paragraph","content":[{"text":"However, requests for ","type":"text"},{"text":"net-new code that didn't exist before the diff","type":"text","marks":[{"type":"strong"}]},{"text":" must be classified as Informational:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Adding a new dependency (e.g. Mox, a linter plugin)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating entirely new modules, files, or test suites","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Extracting new behaviours, protocols, or abstractions","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"These are improvement suggestions for the author to consider in future work, not review blockers.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Iteration Policy","type":"text"}]},{"type":"paragraph","content":[{"text":"If this is a re-review after fixes were applied:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ONLY verify that previously flagged issues were addressed correctly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do NOT introduce new findings unrelated to the previous review's issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Accept Minor/Nice-to-Have issues that weren't fixed — do not re-flag them","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The goal of re-review is VERIFICATION, not discovery","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"## Review Summary\n\n[1-2 sentence overview of findings]\n\n## Issues\n\n### Critical (Blocking)\n\n1. [FILE:LINE] ISSUE_TITLE\n - Issue: Description of what's wrong\n - Why: Why this matters (bug, type safety, security)\n - Fix: Specific recommended fix\n\n### Major (Should Fix)\n\n2. [FILE:LINE] ISSUE_TITLE\n - Issue: ...\n - Why: ...\n - Fix: ...\n\n### Minor (Nice to Have)\n\n14. [FILE:LINE] ISSUE_TITLE\n - Issue: ...\n - Why: ...\n - Fix: ...\n\n### Informational (For Awareness)\n\n14. [FILE:LINE] SUGGESTION_TITLE\n - Suggestion: ...\n - Rationale: ...\n\n## Good Patterns\n\n- [FILE:LINE] Pattern description (preserve this)\n\n## Verdict\n\nReady: Yes | No | With fixes 1-N (Critical/Major only; Minor items are acceptable)\nRationale: [1-2 sentences]","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Post-Fix Verification","type":"text"}]},{"type":"paragraph","content":[{"text":"After fixes are applied, run:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"ruff check .\nmypy .\npytest","type":"text"}]},{"type":"paragraph","content":[{"text":"All checks must pass before approval.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Load skills BEFORE reviewing (not after)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Number every issue sequentially (1, 2, 3...)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Include FILE:LINE for each issue","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Separate Issue/Why/Fix clearly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Categorize by actual severity","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run verification after fixes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report ALL issues in a single pass — do not hold back findings for later iterations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Re-reviews verify previous fixes ONLY — no new discovery","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Requests for net-new code (new modules, dependencies, test suites) are Informational, not blocking","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The Verdict ignores Minor and Informational items — only Critical and Major block approval","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"review-python","author":"@skillopedia","source":{"stars":61,"repo_name":"beagle","origin_url":"https://github.com/existential-birds/beagle/blob/HEAD/plugins/beagle-python/skills/review-python/SKILL.md","repo_owner":"existential-birds","body_sha256":"e65024fc644c93ef3a27ea928312ef57f8f752685bd072941a833ce27011c822","cluster_key":"166447064c24516d7e0fcc5921e48160c1d8394c6da8235ab2118359e7a8fa6c","clean_bundle":{"format":"clean-skill-bundle-v1","source":"existential-birds/beagle/plugins/beagle-python/skills/review-python/SKILL.md","bundle_sha256":"078e32c855e8f68e8ef203fae40d1611f82bc615a15b22f175b0279cb09867b2","attachment_count":0,"text_attachments":0,"binary_attachments":0},"cluster_size":1,"skill_md_path":"plugins/beagle-python/skills/review-python/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"integrations-apis","category_label":"Integrations"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"integrations-apis","import_tag":"clean-skills-v1","description":"Comprehensive Python/FastAPI backend code review with optional parallel agents","disable-model-invocation":true}},"renderedAt":1782979218634}

Backend Code Review Hard gates (sequence) Advance only when each pass condition is objectively satisfied (prevents linter-owned false positives and ungrounded findings): | Gate | Pass condition | |------|----------------| | G1 — Diff scope | Step 1 command has been run; the changed paths are enumerated in writing (list may be empty — if empty, state that explicitly and do not invent Python findings). | | G2 — Linters before manual style/type | For and : either no project config exists for that tool, or it was run on the changed files and you captured pass/fail (exit code or clear tool output)…