Files
transcription/.github/skills/python-code-reviewer/skill.md
T
Jim LancasterandCopilot App 626b5d4b10 Harden python-code-reviewer skill with lessons from executing its own review
Three gaps surfaced by implementing the 2026-08-23 review's recommendations.

1. Recommendations were never verified the way claims were. The report's fix for
   the error path leak would have stripped root-cause data from evidence records,
   because the review traced one consumer of AppError.message and missed that
   format_error_detail writes it to ExecutionAttempt.error_detail. Adds workflow
   step 9 (validate recommendations against consumers), a Blast Radius field on
   findings, and the worked example so the failure mode is concrete.

2. Fixes that sit between competing invariants were not flagged. The atomicity
   recommendation did not note that per-page durability and terminal-status
   atomicity pull in opposite directions, so the obvious simplification silently
   breaks multi-page durability. Recommendations must now name both invariants,
   the test guarding each, and the over-correction to avoid.

3. Severity could not express reachability. Two findings were latent behind a
   default setting and a single-instance deployment, which is a sequencing
   constraint: they must be fixed before the change that makes them live. Adds an
   explicit Reachability field with Live / Latent / Theoretical.

Verified: meta contract guards and traceability tests pass.

Co-authored-by: Copilot App <[email protected]>
2026-08-23 19:14:35 -05:00

18 KiB

name, description
name description
python-code-reviewer Perform an evidence-based, senior architect code review for Python codebases using FastAPI, NiceGUI, SQLModel, SQLAlchemy, Pydantic V2, asyncio, and OpenRouter. Use when asked to review Python repositories, perform architectural or code audits, or evaluate code against Python 3.12+ best practices.

Python Code Reviewer

Perform thorough, evidence-based code reviews for Python projects. Every finding must cite concrete file paths and line ranges, avoid speculation, and include recommended fixes.

When to Use

  • Performing an architectural or code quality review of a Python codebase.
  • Auditing applications using FastAPI, NiceGUI, SQLModel/SQLAlchemy, Pydantic V2, or asyncio workers.
  • Generating structured Markdown review reports in ./docs/reviews.

Technical Stack Scope

  • Runtime: Python 3.12+
  • Web Application: FastAPI and NiceGUI
  • Persistence: SQLModel, SQLAlchemy (SQLite and PostgreSQL support)
  • Validation & Settings: Pydantic V2 and pydantic-settings
  • Concurrency: Python asyncio workers
  • Vision/LLM Integration: OpenRouter / provider adapters
  • Image & Print Pipeline: Pillow-backed media handling and print/export rendering
  • Quality & Testing: pytest, pytest-asyncio, Ruff, and ty

NiceGUI is pinned to an exact version (nicegui==3.13.0 in pyproject.toml); API guidance must be correct for that release rather than for the latest published version. The exact pin is a deliberate release-stability decision recorded in docs/production-runbook.md ("Dependency upgrade policy") — do not report it as a defect or recommend widening it.

Review Workflow

  1. Map the Repository First: Inspect entry points, package layout, configurations, dependency manifests, and any project-specific rule files (AGENTS.md, CLAUDE.md, .github/instructions/). Project-specific conventions override generic advice.
  2. Establish Canonical Authority First: Read architecture/contracts (docs/*, docs/invariant/*, UI docs) and active instructions/skills before evaluating source behavior.
  3. Read Representative Modules: Sample across all layers (routes/pages, UI components, services, workers, persistence, provider adapters, settings, tests) before drawing conclusions.
  4. Run Drift Analysis: Compare documented intended behavior versus repository ground truth; identify both implementation drift and undocumented-but-repeatable conventions that should be formalized.
  5. Run Dead-Code/Orphan Sweep: Identify candidate orphan modules/functions/classes with zero inbound references, then verify expected exceptions (entrypoints, framework/plugin registration, dynamic imports/reflection, CLI hooks, test-only utilities) before marking as orphaned.
  6. Assess Boundary and Coupling Health: Evaluate UI/service/persistence/provider dependency flow, identify circular dependencies, leaky abstractions, and transaction ownership ambiguity.
  7. Assess Invariant Placement: For each hard rule, decide whether it belongs in docs (rationale), instructions (active steering), skills (periodic audit procedure), or deterministic tests (enforcement).
  8. Verify Claims: This is a uv project (uv.lock, root ruff.toml). Run uv run ruff check ., uv run ty check, and uv run pytest -q -m "not external" rather than guessing, and record the exact commands and their outcomes in the report.
  9. Validate Recommendations Against Consumers: A recommendation is a claim about the future and must be verified like any other. Before recommending a change to a shared symbol — a model field, an exception attribute, a helper's return value, a function signature — enumerate every consumer of that symbol (grep the whole repo, including tests) and confirm the fix is safe for each one. Record the consumers in the finding's Blast Radius. A fix that is correct for the path that produced the finding can silently break a second consumer, and evidence/provenance and logging paths are the usual casualties because they read the same fields the UI does.
  10. Prioritize Hot Paths: Focus deeply on request handling, database sessions, background workers, and external API calls.
  11. Enforce Read-Only Safety: Do not modify code unless explicitly instructed.
  12. Escalate Provenance Audits: For evidence/provenance-heavy changes, apply invariant checks from .github/skills/evidence-provenance-auditor/skill.md and include pass/fail outcomes in the report.
  13. Escalate Test-Suite Audits: When findings touch test coverage, redundancy, or assertion strength, apply .github/skills/test-effectiveness-auditor/skill.md and include its outcomes alongside the provenance results.

Worked example: why step 9 exists

The 2026-08-23 review recommended fixing a filesystem-path leak in classify_unexpected_error by making AppError.message generic and logging the exception detail instead. The analysis of the leak was correct, and the fix was implemented as written.

It was wrong. AppError.message had a second consumer the review never traced: format_error_detail, which writes ExecutionAttempt.error_detail — a provenance record. The recommended fix closed a privacy leak by silently stripping root-cause data from the evidence history this system exists to preserve. It was caught only because an unrelated integration test asserted on the persisted error text.

The correct fix separated the audiences — a user-safe message and an internal-only detail that still reaches evidence and logs. One grep for consumers of .message during the review would have found this. Treat any recommendation that changes a widely-read field as unverified until its consumers are enumerated.

Repo-Specific Deterministic Checks (Transcription)

When reviewing this repository, always include explicit pass/fail checks for the following. Where Enforced by reads unenforced, recommending a deterministic test is itself a finding.

# Check Enforced by
1 Service boundary rule: no service-to-service imports tests/test_service_boundaries.py
2 UI boundary rule: pages/components do not perform persistence access tests/test_ui_boundaries.py
3 Status vocabulary conformance: JobStatus/JobSourceStatus/JobPurpose usage matches current enums in src/transcription/db/models.py; no stringly-typed status literals tests/test_model_contract_guards.py
4 Evidence ownership conformance: append-only attempt history is preserved and projection writes are not mistaken for history mutation (src/transcription/services/sources.py, src/transcription/services/evidence.py) tests/test_v42_evidence.py::test_attempts_are_append_only_and_exported_with_integrity
5 Canonical authority: findings must resolve against docs/* first tests/test_meta_contract_guards.py::test_canonical_authority_references_are_present
6 Schema contract fidelity: when model/persistence behavior changes, docs/schema.md remains field-accurate with src/transcription/db/models.py tests/test_model_contract_guards.py (field names, ordering, enum members, table coverage), tests/test_meta_contract_guards.py (presence and references)
7 Media boundary conformance: print/export media is record-validated and UI media URL generation uses controlled resolver paths tests/test_media_path_safety.py, tests/ui/test_media_urls.py
8 Eager-loading conformance: service/UI read paths satisfy lazy="raise" expectations tests/test_model_contract_guards.py (declaration-side; documented noload exceptions must match docs/schema.md)
9 Cross-cutting error conformance: service/API/UI translation and retry behavior align with .github/instructions/error-handling.instructions.md tests/test_errors.py, tests/api/test_error_responses.py, tests/ui/test_error_presenter.py
10 Orphaned/dead-code conformance: include a deterministic orphan sweep and report confirmed orphans removed/retained with rationale tests/test_orphan_sweep.py (KNOWN_ORPHANS records each retained orphan and its rationale)

Core Review Areas

1. Python Best Practices (3.12+)

  • Type Annotations: Ensure completeness, modern syntax (X | None, builtin generics, Self, type statements), and avoid unparameterized containers or bare Any.
  • Error Handling: Identify bare/broad except, swallowed exceptions, missing raise ... from, and exceptions used for control flow.
  • Resource Management: Verify context managers for files, DB sessions, HTTP clients, and locks. Check for leaked tasks or connections.
  • Data Modeling: Check proper use of dataclasses vs. Pydantic models vs. dictionaries. Eliminate mutable default arguments and stringly-typed payloads.
  • Idioms & Clean Code: Verify pathlib usage over os.path, comprehensions vs manual loops, removal of dead code, and elimination of magic numbers.

2. FastAPI

  • Dependency Injection: Verify Depends is used for shared resources (DB sessions, settings, clients) rather than global singletons.
  • Route Design: Validate HTTP verbs, status codes, path/query/body typing, response_model, and domain-based router organization.
  • Lifecycle & Concurrency: Ensure lifespan handlers are used instead of deprecated @app.on_event. Flag blocking synchronous calls in async def endpoints.

3. NiceGUI

  • Separation of Concerns: Ensure UI components delegate business logic and persistence to service layers.
  • Client State Handling: Verify correct use of client-scoped state vs global state to avoid state leaks across sessions.
  • Async Execution: Check for blocking operations on the UI event loop and unbounded timers/pollers.

4. Persistence (SQLModel / SQLAlchemy)

  • Session Lifecycle: Enforce one session per request/unit of work with explicit commit/rollback/close boundaries.
  • Query Optimization: Detect N+1 patterns, missing eager loads (selectinload/joinedload), queries inside loops, and unindexed filters.
  • Cross-Dialect Portability: Check compatibility for both SQLite (WAL mode, pragmas) and PostgreSQL (JSONB, locking, autoincrement).

5. Pydantic V2 & Settings

  • V2 Migration: Flag legacy V1 patterns (@validator, Config class, .dict(), parse_obj) and use V2 equivalents (@field_validator, model_config = ConfigDict(...), model_dump()).
  • Settings Management: Ensure BaseSettings is the single source of truth without scattered os.getenv calls or committed secrets.

6. Concurrency & Asyncio Workers

  • Task Lifecycle: Flag unreferenced create_task calls that risk garbage collection, missing cancellation handling, and lack of graceful shutdown.
  • Backpressure & Synchronization: Check for appropriate use of asyncio.Queue, TaskGroup, Lock, and backoff retries.

7. Provider Adapters (OpenRouter / APIs)

  • Adapter Encapsulation: Verify provider-specific details (headers, model names, payload formats) do not leak into UI or business logic.
  • Client Lifecycle: Reuse shared AsyncClient instances with proper connection pooling and timeouts. Validate API responses using Pydantic schemas.

8. Testing & Quality Tooling

  • Test Isolation: Verify tests do not rely on live external services, real clocks, or shared global state.
  • Async Test Setup: Check pytest-asyncio configuration and fixture lifecycle.
  • Project Test Contract (pyproject.toml): --strict-markers is enabled, so every marker must be declared; asyncio_mode = "strict" requires explicit @pytest.mark.asyncio; declared markers are unit, integration, and external, and external must be excluded from default verification runs. filterwarnings promotes coroutine ... was never awaited to an error — treat any unawaited coroutine as a hard failure and a Critical/High finding, never a warning.
  • Suite Signal Quality: For low-value, redundant, or tautological tests, escalate to .github/skills/test-effectiveness-auditor/skill.md and fold its outcomes into the report.

9. Duplication & Consolidation

  • Identify repeated code blocks, candidate helper abstractions, divergent patterns for identical operations, and duplicated domain constants.

10. Orphaned/Dead Code Audit

  • Find candidate orphan modules/functions/classes with no inbound references.
  • Validate each candidate against dynamic wiring exceptions (entrypoints, plugin registration, reflection/dynamic imports, CLI hooks, test utilities).
  • Report outcomes as: removed orphan, retained-with-justification, or uncertain-follow-up.

11. Architecture & Governance

  • Architectural Drift: Compare intended architecture rules against implementation behavior and cite concrete drift points.
  • Systemic Health: Evaluate domain cohesion, dependency direction, lifecycle consistency, and operational reliability seams.
  • Invariant Routing: Recommend the correct enforcement layer per rule (docs vs instructions vs skills vs tests).
  • Meta-Tooling Alignment: Recommend updates for instruction files and skills when repository patterns or contracts evolve.

Severity Rubric

Severity reflects concrete consequence, never style preference or effort to fix.

  • Critical: Data or evidence loss/corruption; provenance or append-only history violated; secret leakage; silent wrong output presented as authoritative.
  • High: Architectural boundary violated (service/UI/persistence/provider); runtime failure or unhandled exception on a hot path (request handling, DB sessions, worker loop, external API calls); documented invariant contradicted by implementation.
  • Medium: Correctness risk under load or edge conditions (N+1, missing eager load, leaked task, missing timeout); drift between docs and code with no immediate runtime impact.
  • Low: Maintainability, typing completeness, duplication, naming, or dead code with no behavioral risk.

Reachability

Severity states how bad the consequence is; Reachability states whether it can happen today. They are independent, and a finding is not complete without both. Record one of:

  • Live: reachable in the current configuration and deployment.
  • Latent: the defective code is present but unreachable because of a current setting, single- instance deployment, or absent caller. State the exact condition that unblocks it.
  • Theoretical: requires a combination the project has explicitly ruled out.

Latent findings carry a scheduling constraint that severity alone cannot express: a latent defect must usually be fixed before the change that makes it live, not after. Say so explicitly in the finding and reflect the ordering in the §9 action plan — for example, "fix the retry-category gate before raising worker_max_retries above 0," or "handle this IntegrityError before deploying a second worker replica." Do not downgrade severity merely because a finding is latent.

Conflicting invariants

When a fix sits between two invariants that pull in opposite directions, say so in the Recommendation and name both, along with the test that guards each. Flag explicitly what the over-correction would be, because the simplest-looking fix usually satisfies one invariant by silently destroying the other. A recommendation that resolves one side without naming the other is incomplete and will be implemented incorrectly.

Output Report Structure & Template

Generate Markdown reports at ./docs/reviews/<YYYY-MM-DD>-code-review.md following this exact template structure. Reports are dated, non-canonical artifacts: docs/reviews/** is explicitly not part of the canonical authority set that the canonical-authority check resolves against.

# Architecture & Code Review Report

**Repository Target:** `project-root/`
**Target Stack:** Python 3.12+ | FastAPI | NiceGUI | SQLModel/SQLAlchemy | Pydantic V2 | asyncio | OpenRouter

---

## 1. Executive Summary
- 5-10 bullets on overall health, top risks, and high-leverage refactors.

---

## 2. Executive Architecture Assessment
- High-level verdict on domain cohesion, boundary clarity, and architecture fitness.
- Top 3-5 systemic risks or bottlenecks.

---

## 3. Findings by Severity

### Critical Severity
#### [CRIT-01] Title
- **Location:** `path/to/file.py:lines`
- **Reachability:** Live / Latent (state the exact condition that unblocks it) / Theoretical
- **Problem & Consequence:** Concrete consequence, not a style opinion.
- **Blast Radius:** Every consumer of the symbols the recommendation changes, each confirmed
  safe. Write `None — change is local` only after actually searching. If the fix touches a
  shared field or helper, list the call sites (including tests and evidence/logging paths).
- **Recommendation:** Fix with before/after sketch. If two invariants conflict here, name both,
  name the test guarding each, and state what the over-correction would be.
- **Effort:** S / M / L

### High Severity
#### [HIGH-01] Title
...

### Medium Severity
#### [MED-01] Title
...

### Low Severity
#### [LOW-01] Title
...

---

## 4. Architectural Drift & Gap Analysis

`Direction` is `doc->code` (implementation must change to match documented intent) or
`code->doc` (an undocumented but repeatable convention that should be formalized).

| Area / Component | Direction | Documented / Intended Rule | Actual Implementation State | Severity | Recommended Resolution |
| :--- | :--- | :--- | :--- | :--- | :--- |

---

## 5. Invariant Inventory & Routing Recommendations
| Invariant / Constraint | Current Location | Recommended Target Layer | Rationale |
| :--- | :--- | :--- | :--- |

---

## 6. Stack-Specific Analysis
- Python 3.12+ Best Practices
- FastAPI
- NiceGUI
- SQLModel & SQLAlchemy
- Pydantic V2 & Settings
- Asyncio Workers
- OpenRouter / Adapter Boundary
- Testing & Quality Tooling

---

## 7. Duplication & Consolidation Report
| Pattern / Duplication | Locations | Proposed Canonical Home | Estimated Lines Removed |
| :--- | :--- | :--- | :--- |

### Proposed Canonical Abstractions
- Code signatures and implementation homes.

---

## 8. Meta-Tooling & Instruction Update Recommendations
- Required updates to docs/instructions/skills/tests to keep enforcement current.

---

## 9. Prioritized Dependency-Ordered Action Plan
1. **Phase 1: Blocking fixes**
2. **Phase 2: Enforcement hardening**
3. **Phase 3: Reliability & concurrency**
4. **Phase 4: Consolidation & refactoring**
5. **Phase 5: Non-blocking governance/documentation depth**

---

## 10. Preserved Strengths
- Existing patterns worth maintaining.