assets/skills/review/branch/SKILL.md
Review local branch changes for architecture compliance, conventions, and code quality before pushing/PR. Stack-aware — detects the project stack and applies the matching rules. Use when user says "review changes", "review branch", "check branch", "check changes", "review my code", "review before pr".
npx skillsauth add phuthuycoding/moicle review-branchInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Self-review your branch vs a base branch before pushing or opening a PR. Checks architecture compliance, stack conventions, and code quality — on changed files only, not the whole codebase.
ARGUMENTS: (optional) base branch. Default: main (fallback to master).
/review-pr/review-architect@security-audit agentDetect stack via ~/.claude/architecture/_shared/stack-detection.md. Load ddd-architecture.md + the stack doc — extract forbidden imports + conventions before reviewing.
Severity definitions: ~/.claude/architecture/_shared/severity-levels.md (code severity table).
0 DETECT → 1 COLLECT → 2 BUILD+LINT → 3 ARCH → 4 CONVENTIONS → 5 QUALITY → 6 TESTS → 7 REPORT → 8 FIX
BASE=${1:-main}
git rev-parse --verify "$BASE" >/dev/null 2>&1 || BASE=master
git log "$BASE"..HEAD --oneline
git diff "$BASE"...HEAD --stat
git diff "$BASE"...HEAD --name-only --diff-filter=ACMR
Categorize changed files by layer:
| Layer | Typical paths |
|-------|---------------|
| Domain | domain/, internal/domain/, src/domain/, lib/domain/ |
| Application | application/, internal/application/, src/application/ |
| Infrastructure | infrastructure/, internal/infrastructure/, src/infrastructure/ |
| Presentation / UI | controllers/, pages/, components/, views/, ports/http/ |
| Persistence | models/, entities/ (ORM), prisma/, migrations/ |
| Config / Bootstrap | config/, bootstrap/, cmd/, main.* |
Read all changed files before reviewing — never skim.
Run the stack's build + typecheck + lint commands. If any fail → mark CRITICAL and stop further review until they pass.
# Go: go build ./... && go vet ./...
# NestJS: pnpm typecheck && pnpm lint
# Laravel: composer dump-autoload && ./vendor/bin/phpstan analyse
# Flutter: dart analyze
# React/Remix: pnpm typecheck && pnpm lint
Apply the stack's rules. Common checks per layer:
| # | Rule |
|---|------|
| D1 | Domain purity — no forbidden imports (ORM, HTTP, cache, queue, auth SDK) |
| D2 | No cross-domain imports (only shared kernel allowed) |
| D3 | No persistence-model imports in domain |
| D4 | Entities have behavior (not anemic data bags) |
| D5 | Entities raise events on state change (if architecture uses events) |
| D6 | Ports in ports/ dir (not inline in usecases) |
| D7 | One port per file |
| D8 | Ports return domain types, not primitives |
| D9 | Value objects stdlib-only |
| D10 | Usecases have no infra imports |
Quick check:
CHANGED_DOMAIN=$(git diff "$BASE"...HEAD --name-only --diff-filter=ACMR \
| grep -E '^(src|internal|lib)/domain/')
[ -n "$CHANGED_DOMAIN" ] && echo "$CHANGED_DOMAIN" \
| xargs grep -lEn '<STACK_FORBIDDEN_REGEX>' 2>/dev/null \
&& echo FAIL || echo PASS
| # | Rule | |---|------| | A1 | Handler is thin (parse → service → respond, no business logic) | | A2 | Service justified only when ≥2 usecases orchestrated | | A3 | Listener is side-effect only (no business logic) | | A4 | Listener registered in event bus | | A5 | Event name string matches registry | | A6 | DTOs validated at boundary | | A7 | Composition root only — no inline wiring in handlers |
| # | Rule | |---|------| | I1 | Repository has no business logic | | I2 | Mappers exist (domain ↔ ORM model) | | I3 | Implements port interface (returns domain types) | | I4 | Context / transaction propagation correct |
| # | Rule | |---|------| | M1 | ORM models in infrastructure, NOT domain | | M2 | Schema change → matching migration | | M3 | Nullable columns use nullable types |
| # | Rule |
|---|------|
| G1 | No swallowed errors (no empty catch / if err != nil {}) |
| G2 | Async work uses background context, NOT request context |
| G3 | API-facing types have serialization tags (json:, decorators, etc.) |
| G4 | No hardcoded secrets / tokens / keys |
| G5 | Parameterized queries only — no string-interpolated SQL |
| G6 | Input validation at boundary before reaching domain |
Plus any stack-specific Hard Rules from the architecture doc.
Read the diff. Look for:
| # | Area | What to look for |
|---|------|------------------|
| Q1 | Logic correctness | Off-by-one, nil deref, wrong condition, missed edge case |
| Q2 | Error handling | Errors propagated/wrapped, not silently ignored |
| Q3 | Concurrency | Race conditions, shared mutable state, async leaks |
| Q4 | Resource leaks | Unclosed connections, HTTP bodies, file handles |
| Q5 | Naming | Reveals intent (no data, info, manager, helper) |
| Q6 | Dead code | Unreachable, unused, commented-out |
| Q7 | Duplication | Real duplication across changed files (not coincidental) |
| Q8 | Breaking change | API contract change, removed field, behavior change |
| Q9 | Over-engineering | Abstraction not justified by the change |
| Q10 | Test coverage | New logic has tests; bug fixes have regression tests |
# Tests for changed domains only
CHANGED_DOMAINS=$(git diff "$BASE"...HEAD --name-only --diff-filter=ACMR \
| grep -E '/(domain|modules|features)/' \
| sed -E 's|.*(domain\|modules\|features)/([^/]+)/.*|\2|' | sort -u)
for d in $CHANGED_DOMAINS; do
# Go: go test ./internal/domain/$d/... -v
# NestJS: npx jest src/domain/$d
# Laravel: ./vendor/bin/phpunit --filter $d
# Flutter: flutter test test/domain/$d
echo "Test $d"
done
# Full suite
{full_test_command}
## Code Review: {branch} → {base}
**Stack:** {stack} · **Commits:** {N} · **Files:** {N} (+{add} / -{del})
### Build / Lint / Types
| Check | Status |
|-------|--------|
| Build | PASS/FAIL |
| Lint | PASS/FAIL |
| Types | PASS/FAIL |
### Architecture / Conventions / Quality
| # | Rule | Status | File:line |
|---|------|--------|-----------|
| D1 | Domain purity | PASS | — |
| G4 | No secrets | FAIL | `config/db.ts:42` hardcoded token |
| Q1 | Logic correctness | OK | — |
### Tests
| Check | Status |
|-------|--------|
| Changed area tests | PASS/FAIL |
| Full suite | PASS/FAIL |
### Issues (sorted by severity)
| # | Severity | File:line | Issue | Suggested fix |
|---|----------|-----------|-------|---------------|
| 1 | CRITICAL | config/db.ts:42 | hardcoded token | move to env |
| 2 | HIGH | handlers/user.ts:88 | business logic in handler | extract to usecase |
### Verdict
{APPROVED / CHANGES REQUESTED}
| When | Use |
|------|-----|
| Reviewing teammate's PR | /review-pr |
| Deep DDD audit of a domain | /review-architect |
| Fixing review comments on your PR | /fix-pr-comment |
| Fixing bugs surfaced here | /fix-hotfix |
| Phase | Agent | Purpose |
|-------|-------|---------|
| 3 Architecture | @clean-architect | DDD compliance |
| 4 Conventions | @security-audit | Vulnerability sweep |
| 5 Quality | @code-reviewer | Code smells |
| 6 Tests | @test-writer | Coverage check |
| 8 Fix | Stack-specific dev agent | Apply fixes |
development
Test-Driven Development workflow. Use when doing TDD, writing tests first, or when user says "tdd", "test first", "test driven", "red green refactor".
development
Thorough pull request review workflow with architecture compliance checks. Use when reviewing pull requests, checking code changes, or when user says "review pr", "check pr", "review code", "pr review", "review pull request".
testing
DDD architecture compliance review with automated checks and review loop. Use when user says "architect-review", "architecture review", "review architecture", "check architecture", "review ddd", "ddd review".
development
Research solutions on the internet for a given topic or the current conversation context. Use when user says "research", "tìm giải pháp", "search solution", "investigate", "find best practice", "so sánh giải pháp".