PR Review Checklist
Standalone reviewer reference. Cross-linked from .claude/skills/code-review/SKILL.md and .github/PULL_REQUEST_TEMPLATE.md.
Standalone reviewer reference. Cross-linked from .claude/skills/code-review/SKILL.md and .github/PULL_REQUEST_TEMPLATE.md.
Reviewers should walk the items in order. Items 1–10 are hard gates; CI enforces most but a reviewer's job is to catch what CI misses (intent, naming, taste).
Convention: when you flag an item, cite the number and a one-line reason.
#3: missing changelog for src/back/objects/digitaltwin/DigitalTwin.pyis more useful than "no changelog".
1. Layering (§ src/.coding_rules.md §1)
back/core/imports anything fromfastapi? → block.back/objects/importsRequestorResponse? → block.- Route file does more than 10 lines of business logic? → block.
2. Class-first policy (§ src/.coding_rules.md §2)
- New
.pyinback/objects/orback/core/with no public class? → request changes. - Public class name doesn't match filename? → request changes.
- Module-level functions doing what a class should? → request changes.
3. Error handling (§ src/.coding_rules.md §4)
return {"success": False, ...}anywhere? → block.- Bare
HTTPExceptioninback/core/orback/objects/? → block. - Broad
except Exception:swallow? → request changes (unless explicitly justified). - New error condition without a matching
OntoBricksErrorsubclass? → request changes.
4. Logging (§ src/.coding_rules.md §6)
- f-string or
.format()inlogger.*? → request changes. - Token, password, JWT, or PII in a log line? → block.
print(...)left insrc/? → request changes.
5. Async + I/O (§ src/.coding_rules.md §5)
databricks-sql-connectorcall insideasync defwithoutto_thread? → request changes.asyncio.create_task(...)ad-hoc instead ofTaskManager? → request changes.
6. Public API & re-exports (§ src/.coding_rules.md §7)
- New public class in
back/objects/<subpackage>/not re-exported from__init__.py? → request changes. - Caller imports from the file path instead of the package? → request changes.
7. Tests (§ Section 9 of methodology plan)
- New behaviour in
src/without a matching test diff intests/? → block. - Test name describes implementation, not behaviour? → request changes.
- Inline sample dict where a factory exists? → request changes (factories live in
tests/fixtures/factories/). - Missing pytest marker (
unit/integration/mcp/db/e2e/eval/property)? → request changes. - New code lowers package coverage below threshold in
ci/coverage_thresholds.yaml? → block (CI will too).
8. Changelog (§ changelogs/README.md)
changelogs/<today>.lognot updated? → block (CI will too).- Changelog entry has no "Tests" line? → request changes.
- Title isn't imperative ("add X" / "fix Y" / "refactor Z")? → request changes.
9. Conventional Commits (§ commitlint.config.js)
- PR title doesn't match
<type>(<scope>): <subject>? → block (CI will too). - Allowed types:
feat,fix,docs,style,refactor,perf,test,build,ci,chore,revert. - Scope is the package (
dtwin,ontology,mapping,agents,mcp,ci,tests) or a milestone tag (M2.P1).
10. AI features (§ .cursor/12-ai-feature-lifecycle.mdc)
If the PR touches src/agents/** or adds an MLflow-traced LLM call:
.planning/<slug>/SPEC.mdpresent? → block (CI G2 gate will too)..planning/<slug>/eval/dataset.jsonlpresent with ≥10 (changes) or ≥20 (new agent) examples? → block.- MLflow eval run URI linked in the PR body? → block.
- Judge score ≥ baseline + delta or explicit waiver comment? → block.
11. Soft signals (reviewer judgment)
- Could a Fowler refactoring make this clearer? Suggest it (cite the smell + name).
- Is the diff bigger than ~400 LOC? Ask whether it should be split.
- Does the PLAN.md in
.planning/<slug>/exist and match the actual diff? Mismatch = either the plan changed or the implementation drifted. Either way, update. - Could this be a one-line fix instead of N? Suggest the smaller version.
12. Anti-patterns specific to CNS (§ §3.12 of methodology plan)
- Using Claude Code for a one-file edit when Cursor would do? → comment, don't block.
- Cursor Agent walking a 20-file refactor without a parallel-agent sweep? → comment.
- Re-introducing
gsd-*references? → block. (Pre-commit hook should have caught it.) - Updating
.cursor/*.mdcpriority without bumping the comment? → request changes. - Resuming work by re-reading chat history (visible in commit messages or PR description)? → comment ("re-derive from
PLAN.md+git statusnext time").
After approval
The author runs superpowers:finishing-a-development-branch, then merges. The reviewer checks the merge is clean and the milestone in .planning/ROADMAP.md is updated with the landing date.