zereight-review
Prioritize correctness and risk over style nitpicks.
Default tone: concise, direct, actionable.
Mandatory Review Ensemble -- NON-NEGOTIABLE
When the user invokes zereight-review, $zereight-review, or asks to use the
Zereight review skill, do not complete the review from a single reviewer pass.
You must run a multi-skill, subagent-based review ensemble first, then synthesize
the results.
Required instruction sources to load before reviewing:
- Nearest repo
AGENTS.md
/Users/tao.exe/.codex/instructions.md
/Users/tao.exe/.codex/AGENTS.md
codegraph-review-routing when CodeGraph MCP is available or the review needs impact/call-chain context
code-review
code-review-expert
code-reviewer
agent-skills:code-review-and-quality
agent-skills:using-agent-skills
thermo-nuclear-code-quality-review
Required subagent review passes:
| Subagent pass |
Builtin agent |
Model (required) |
Required basis |
Review focus |
| Baseline full-diff reviewer |
reviewer |
opencode-go/deepseek-v4-pro |
code-review |
finding-first output, severity, full diff coverage, comment-worthy / no comment |
| Regression and contract reviewer |
reviewer |
opencode-go/deepseek-v4-pro |
code-review-expert |
behavioral regressions, API/prop contracts, hidden state and edge-case risk |
| File coverage reviewer |
worker |
opencode-go/deepseek-v4-flash |
code-reviewer |
every changed file and hunk, missing tests, maintainability risks |
| Quality gate reviewer |
worker |
opencode-go/deepseek-v4-flash |
agent-skills:code-review-and-quality |
correctness, reliability, maintainability, security, test quality |
| Thermo-nuclear maintainability reviewer |
reviewer |
opencode-go/deepseek-v4-pro |
thermo-nuclear-code-quality-review |
code judo / structural simplification, 1k-line boundary, spaghetti branching, abstraction quality, layer boundaries |
| Agent orchestration reviewer |
delegate |
opencode-go/deepseek-v4-flash |
agent-skills:using-agent-skills |
whether the work was split correctly and whether any review lens is missing (including thermo-nuclear pass) |
| Zereight coordinator |
(parent) |
parent session model |
this skill |
three-dot diff, RED-team mindset, verification discipline, final synthesis |
Ensemble model policy — MANDATORY
Zereight review subagents use only these models unless the user explicitly
requests a different provider:
| Model |
Use for |
opencode-go/deepseek-v4-pro |
Baseline + Regression (reviewer) — deeper reasoning, contract/regression analysis |
opencode-go/deepseek-v4-flash |
File coverage + Quality gate (worker), Orchestration (delegate) — breadth, five-axis gate, meta review |
cursor/composer-2.5 |
Last-resort fallback when OpenCode Go fails (429, quota, rate limit) — matches defaultProvider/defaultModel in ~/.pi/agent/settings.json |
Ordered fallback chain (pi-subagents auto-retries on 429/quota):
| Agent |
Primary |
Then |
Last resort |
reviewer |
deepseek-v4-pro |
deepseek-v4-flash |
cursor/composer-2.5 |
worker |
deepseek-v4-flash |
deepseek-v4-pro |
cursor/composer-2.5 |
delegate |
deepseek-v4-flash |
deepseek-v4-pro |
cursor/composer-2.5 |
Configured in ~/.pi/agent/settings.json → subagents.agentOverrides.*.fallbackModels.
pi-subagents treats 429 / rate-limit / quota errors as retryable and walks this list automatically.
Never rely on builtin default models (claude-sonnet-4-6, openai-codex/gpt-5.3-codex, etc.).
User-level overrides live in ~/.pi/agent/settings.json under
subagents.agentOverrides, but still pass model on every spawn so the
runtime cannot fall back to Claude when quota is exhausted.
Execution rules:
- Spawn separate subagents for the required review passes whenever the runtime
supports subagents. Give each subagent the exact PR/range, target branch,
repository path, the relevant instruction sources, and the model from the
table above.
- Every subagent must follow the repo
AGENTS.md and global Codex instructions
in addition to its review skill.
- Do not return the final review until every required pass has either completed
or is explicitly blocked.
- All review subagents must use Pi builtin agents (
reviewer, worker,
delegate) with an explicit model parameter. Do not spawn without
model — builtin worker defaults to Claude and will burn quota.
- Do not route review passes through Claude, Claude Code, Chorus, or any
Claude-backed external agent unless the user explicitly requests Claude.
- If a subagent fails with provider/model/quota errors (including 429 from
OpenCode Go), pi-subagents retries the ordered
fallbackModels chain in
settings: paired DeepSeek (pro ↔ flash), then cursor/composer-2.5
(session default). Do not retry Claude paths unless the user explicitly
requests Claude.
- If spawn still fails after the full chain, report which models were attempted
and continue synthesis from completed passes — do not block the final review.
Parallel spawn example (pi-subagents / subagent tool):
{
"tasks": [
{
"agent": "reviewer",
"model": "opencode-go/deepseek-v4-pro",
"task": "Baseline full-diff review. Skill: code-review. PR: ..."
},
{
"agent": "reviewer",
"model": "opencode-go/deepseek-v4-pro",
"task": "Regression and contract review. Skill: code-review-expert. PR: ..."
},
{
"agent": "worker",
"model": "opencode-go/deepseek-v4-flash",
"task": "File coverage review. Skill: code-reviewer. PR: ..."
},
{
"agent": "worker",
"model": "opencode-go/deepseek-v4-flash",
"task": "Quality gate review. Skill: code-review-and-quality. PR: ..."
},
{
"agent": "reviewer",
"model": "opencode-go/deepseek-v4-pro",
"task": "Thermo-nuclear maintainability review. Skill: thermo-nuclear-code-quality-review. PR: ..."
}
],
"concurrency": 5
}
Then spawn orchestration separately:
{
"agent": "delegate",
"model": "opencode-go/deepseek-v4-flash",
"task": "Orchestration review: verify all ensemble axes were covered. ..."
}
Final synthesis must list models used, e.g. reviewer ×3 (deepseek-v4-pro), worker ×2 (deepseek-v4-flash), delegate (deepseek-v4-flash).
Single-pass fallback (subagent unavailable): If the runtime does not support
subagent spawning AND the user explicitly approves (e.g., by switching to
/review mode, stating "fallback" or "single pass"), skip the ensemble and
do a thorough self-contained review instead. Requirements:
- State that subagent ensemble is unavailable.
- Confirm user approval (explicit wording or known review-mode flag).
- Still load all six reviewer instruction sources sequentially (including
thermo-nuclear-code-quality-review).
- Cover all ensemble axes in one pass: correctness, security, regression,
architecture/contracts, clean code, thermo-nuclear maintainability.
- Apply full-diff coverage, RED-team mindset, and verification discipline.
- If the user did NOT approve fallback, stop and report the blocker.
Subagent Failure Budget — MANDATORY
Subagent claims are not primary evidence. A claim becomes a finding only
after current-turn primary evidence (diff, file contents, tests, CI logs,
rtk-grepped source, or reproducible output) confirms it.
Rules:
- A subagent failure or stuck verification is not a blocker — it is a
signal to move on.
- If a verification path (e.g., live API call, official docs fetch) fails
once, retry at most once only when the result is necessary for a
P0/P1 decision.
- If the same verification path fails 2 times total, stop pursuing it
immediately. Do not try a third approach.
- If 2+ subagent/verification attempts fail for the same claim, treat
the claim as unusable for review purposes. Either discard it or
note it as unverified residual risk — never as a blocker.
- Never spend more than one bounded verification pass on any P2/🟡 Minor
or lower concern.
- When verification fails without logs, state "unverified; not used as
blocker" and continue producing the final review.
- Do not block the final review waiting for a subagent or verification
to complete. Synthesize from what is already available, mark any gaps,
and deliver.
- Exception: PR Identity Gate hard stop overrides rules 1–7. When
both mcporter and local API fail to fetch Bitbucket PR metadata, stop the
entire review — do not synthesize findings from local git or subagents.
If subagent spawning IS available, use it — do NOT default to single-pass.
- Keep raw diff output out of the conversation context when possible. Prefer
context-mode indexing/search for large diffs, and use three-dot diff against
the target branch.
MCP transport — mcporter CLI only (MANDATORY)
Zereight review never treats Cursor/Codex native MCP (mcp_get_tools,
mcp_call_tool, MCP panel server list) as the source of truth for mcporter
inventory. Those lists read ~/.cursor/mcp.json / ~/.codex/config.toml and
can be empty even when ~/.mcporter/mcporter.jsonc has healthy servers.
Canonical registry and invocation
| Concern |
Source of truth |
How to invoke |
| Server inventory |
~/.mcporter/mcporter.jsonc |
mcporter list or mcporter list <server> |
| Tool schema |
mcporter |
mcporter list <server> --schema (when needed) |
| Tool execution |
mcporter CLI |
mcporter call <server>.<tool> ... |
Always run MCP tools for this skill through the shell, e.g.:
mcporter call fuck-u-code.analyze \
path="<bounded-path>" \
format=json top=15 verbose=false
Do not substitute mcp_call_tool for mcporter call during review.
Cursor / Codex exposure (mcporter-bridge)
Register mcporter-bridge in ~/.cursor/mcp.json (and optionally
~/.codex/config.toml) when the user wants the full mcporter inventory
visible in the IDE MCP UI. Use the pipx binary path, not
python3 -m mcporter_bridge (often missing):
"mcporter-bridge": {
"command": "/Users/tao.exe/.local/bin/mcporter-bridge",
"args": []
}
Bridge exposes discovery/call helpers (mcporter_list_servers,
mcporter_call_tool, etc.). Even with bridge loaded, zereight-review
preflight and PR fetches still use mcporter call directly — bridge is for
human/IDE visibility, not the review execution path.
Availability mistakes to avoid
| Wrong check |
Why it fails |
Correct check |
mcp_get_tools shows no fuck-u-code |
Cursor mcp.json may omit servers |
mcporter list fuck-u-code |
| Memory from prior session |
Config changes across reloads |
Fresh mcporter list each review |
| Assuming reload fixed MCP |
Reload does not import mcporter.jsonc into Cursor |
CLI mcporter list + optional mcp.json edit |
If mcporter list fuck-u-code shows tools with non-offline status → available.
State fuck-u-code preflight run (mcporter CLI) in the final review.
Only write skipped (unavailable) when mcporter list or mcporter call
fails (binary missing, server offline, timeout, schema mismatch).
Review preflight safeguards:
- Before broad file reading, use context-mode to reduce the diff to changed
files/symbols and high-risk hunks. If CodeGraph MCP is available, run a
bounded impact pass for changed symbols that need surrounding context:
callers, usages, call chains, affected screens/hooks/navigation/API
boundaries, and hotspot/coupling candidates. Treat CodeGraph output only as
candidate discovery; every finding still needs current-turn primary evidence
from the diff, file contents, tests, logs, or context-mode search.
- Do not use CodeGraph for Bitbucket/Jira/Confluence/internal connector reads;
those remain mcporter-first with schema inspection. Do not use CodeGraph for
large diff/log processing; those remain context-mode. Do not use CodeGraph as
durable memory; agentmemory remains curated and verified only.
- If CodeGraph output is
_truncated, stale, unresolved, or conflicts with file
evidence, do not cite it as review evidence. Narrow the query once or fall
back to context-mode plus file evidence.
- RTK command rewrites can fail silently for simple read commands such as
rtk rewrite "sed ...". If that happens, do not stall the review. Use the
repo-approved RTK form when the hook provides one, prefer rtk grep /
rtk git for searched or git commands, and keep direct file reads narrowly
bounded when reading required instruction or skill files.
- If the nearest repo
AGENTS.md is missing, do not treat that as permission to
ignore repo instructions. Use any AGENTS instructions supplied in the current
conversation as the repo instruction source, state that fallback, and continue.
- For React or React Native PRs, include
npx react-doctor@latest in
verification. Run it from the repo root when package-manager and network
access allow it. If it cannot run, report the exact command and blocker.
- MANDATORY: Check fuck-u-code availability BEFORE any preflight or
ensemble step. Run
mcporter list fuck-u-code (CLI only — see
MCP transport — mcporter CLI only above). Confirm the server appears
with a non-failure status (tool count + latency, not "offline" or "error").
Do NOT use mcp_get_tools for this gate. Do NOT skip this check. Do NOT
assume availability from memory, Cursor reload, or prior sessions.
- If available AND the PR has substantial logic changes (not just
locales/styles/tests/assets-only), run the bounded static analysis below
via
mcporter call fuck-u-code.analyze.
- If NOT available (
mcporter missing, mcporter list offline, mcporter call fails): state "fuck-u-code preflight skipped (unavailable — mcporter CLI)" and continue. Do NOT block the review.
- If
mcporter list succeeds but you skip mcporter call without reason
(as in PR #2217 / #2182): PROCESS VIOLATION. The preflight line must
be either fuck-u-code preflight run (mcporter CLI) or skipped (reason). Silence is not permitted.
- From the three-dot diff or PR metadata, extract the list of changed files.
Filter to
*.ts, *.tsx only; exclude **/*.test.*, **/__snapshots__/**,
**/locales/**, dist/, node_modules/.
- Determine the common parent path(s) of the changed files (typically 1-2).
Never scan the entire workspace — only the bounded paths. If changed
files span multiple disjoint paths, run the analysis for each path.
- Invoke
analyze through mcporter:mcporter call fuck-u-code.analyze \
path="<common-parent-path>" \
format=json top=15 verbose=false
- From the JSON output, extract
files[].score and files[].metrics[].
Keep only files that appear in both the PR diff AND the worst-scoring list.
- Read the full content of those files (not just the diff) to understand
whether the PR is introducing new complexity/duplication or inheriting
existing legacy. Check: does the new code worsen the metrics?
- If the PR inherits existing legacy (file was already bad before this PR),
note it as ⚪ Info — do not block. If the PR introduces new hotspots
(complexity/duplication without justification), report as 🟡 Minor.
- Never promote fuck-u-code scores to primary findings without file-content
evidence. Never cite fuck-u-code score alone as 🟠 Major or higher.
- On
mcporter call failure (timeout, unavailable, schema mismatch), skip
preflight with "fuck-u-code preflight skipped (mcporter CLI — <reason>)"
and continue. Do not retry more than once.
- The
ai-review tool is excluded from the default pipeline — it sends
code to external APIs and duplicates the zereight ensemble.
- When spawning review subagents, do not combine
fork_context=true with an
explicit agent_type if the runtime rejects that combination. Retry by
spawning role-specific agents without fork_context and put the exact PR
range, repository path, target branch, and required instruction sources in
each agent prompt.
- Never use ambiguous branch names such as
origin/develop for review diffs if
local refs can shadow remote refs. Resolve and use full refs:
refs/remotes/origin/<target>...refs/remotes/origin/<source>. If an
ambiguous ref caused an unexpectedly large diff, discard that result and
restart scoping from the full-ref three-dot diff.
Synthesis rules:
- Merge findings from all subagents into one final review (including
thermo-nuclear structural/maintainability findings).
- Map thermo-nuclear presumptive blockers (1k-line explosion, spaghetti
special-case growth, missed code-judo simplification, boundary leaks) into
zereight severity when primary evidence confirms: structural regression with
user-facing risk → 🟠 Major; maintainability-only → 🟡 Minor or 🛠️ refactor;
decomposition opportunity with no behavior risk → 🔵 Trivial. Do not promote
thermo tone alone without file/line evidence.
- De-duplicate overlapping findings and keep the strongest, most concrete file
and line reference.
- If reviewers disagree, state the disagreement briefly and choose the outcome
supported by code evidence.
- Preserve whole-diff coverage by listing changed files as
comment-worthy or
no comment.
- Lead with actionable findings ordered by severity. Keep summaries secondary.
RED Team Mindset -- MANDATORY
You are an adversary, not a rubber stamp. Your job is to break the code, not confirm it works.
- Think like an attacker: For every change, ask "How can this fail? How can this be exploited? What input breaks this?"
- Never trust the happy path: Code that works for expected inputs is the baseline, not the goal. Hunt for the unexpected.
- Simulate hostile inputs: Empty strings, negative numbers, null, undefined, MAX_SAFE_INTEGER, special characters, concurrent calls, network timeouts.
- Challenge assumptions: If the author assumes X is always true, find the scenario where X is false.
- Question removed code: Deleted code had a reason to exist. Verify the reason is truly gone, not just hidden.
- Trace error propagation end-to-end: Follow every throw/reject/return-undefined through all callers. One unhandled path = one crash in production.
- Don't approve because it "looks fine": If you can't construct a specific failure scenario, dig deeper -- absence of evidence is not evidence of absence.
Verification Discipline — MANDATORY
Theoretical analysis is NOT enough. Every claim about library behavior, framework semantics, or runtime performance must be empirically verified before assigning severity.
Rule 1: Theoretical claims require evidence
Before labeling any finding as 🟠 Major or higher based on framework/library behavior, verify with at least one of:
- Source grep:
node_modules source of the relevant library
- Official docs: documented behavior from the library's docs
- Actual usage sites: grep the codebase for how the construct is used in practice
- Reproduction test: runnable test case demonstrating the bug
If you can only say "theoretically this could..." without one of the above, demote to 🔵 Trivial or 🟡 Minor until verified.
Rule 2: Detection triggers — STOP and verify
When drafting a finding, if you write any of these phrases, STOP and verify:
- "이론적으로는 ~~" / "theoretically ~~"
- "~~ 일 수도 있다" / "this could ~~"
- "
useMemo / useEffect / SharedValue / context 동작" (React/reanimated semantics)
- "라이브러리 X는 ~~한다" (library behavior assertion)
- "이 setState는 re-render를 일으켜 jank를 유발한다" (performance claim without measurement)
Rule 3: Verification patterns by claim type
| Claim type |
How to verify |
React hook semantics (useMemo deps, useEffect closure) |
Grep actual usage sites; check React docs reference |
| Reanimated SharedValue / worklet |
Grep node_modules/react-native-reanimated/src/; check Reanimated docs |
@gorhom/bottom-sheet animatedIndex vs onChange |
Grep node_modules/@gorhom/bottom-sheet/src/; inspect when callbacks fire |
| List virtualization (FlashList, FlatList) |
Check item count and render path |
| Performance (re-render frequency, memo effectiveness) |
Count actual trigger events in real usage, not hypothetical worst case |
Rule 4: Signal-Trigger Investigation — upstream root cause
Defensive code is a symptom, not a solution. When you see these signals, investigate the upstream cause:
Signals:
- Defensive JSDoc mentioning "stable id", "fallback for ...", "workaround for ...", "client-defined"
- Type assertions:
as unknown as T, enum values cast from raw int (1 as TermCategory)
- Mock/stories comments: "duplicate rows", "non-enum ints", "dev server returns ...", "garbage data"
// FIXME, // TODO, // HACK comments
- Array-index-based key synthesis (
groupIndex + periodIndex + value)
- Over-complex null-handling for "should never happen" cases
Action:
- Read the JSDoc / comment in full
- Check referenced mock data / stories for actual server response shape
- Trace whether the root cause is fixable upstream (server API, schema, type contract)
- Report upstream issue as a separate finding — don't just say "defensive coding is fine"
Rule 5: Mock/Stories = API shape evidence
Mock files and .stories.tsx often contain real server response samples or dev-server captures. Include them in review scope:
- Read
*.stories.tsx args / mock constants
- Check for comments like "sample from api-grpc-{env}", "dev server snapshot"
- Duplicate/malformed mock data = signal of real server data quality issue
- Do NOT dismiss stories as "test fixtures, not production concern"
Failure cases — lessons (calibration)
Document your own missed findings here to build calibration:
- PR #1790 M-3 (SharedValue useMemo staleness): Theoretical claim that
useMemo([sharedValue], …) wouldn't re-run on .value.length change. Verification showed buildFilterableSheetSnapPoints always returns 2-element array → no actual staleness. Demoted Major → Trivial.
- PR #1790 M-6 (onChange re-render jank): Theoretical claim that setState in bottom-sheet onChange causes jank during drag. Library docs confirm
onChange fires only at snap settle, not during drag → no jank. Demoted Major → Trivial.
- PR #1790 period row key: JSDoc "same length can appear in multiple groups" + stories mock comment "duplicate
0 rows, non-enum term ints" were ignored as "defensive coding". Actually evidence of server API data quality issue requiring backend attention. Missed the upstream root cause entirely.
Full-Diff Inline Comment Mindset -- MANDATORY
Review every PR as if you are going to leave inline comments on the full diff, even when the final output is a summarized review.
- Do not stop after finding the first major issue. Continue through every changed file and every changed hunk.
- For each changed file, make an explicit internal decision:
comment-worthy or no comment, instead of silently skipping it.
- Assume each diff hunk may need its own comment. Even if you later collapse findings in the final write-up, the review process must still inspect the full diff at inline-comment granularity.
- Distinguish clearly between:
- actual findings that deserve comments
- changed areas reviewed and intentionally passed with no comment
- When synthesizing the final review, preserve whole-diff coverage. The output should reflect that the PR was reviewed file-by-file, not just around the most obvious issue.
- If the user asks for a PR review without extra direction, default to this mindset automatically.
Workflow -- always follow this sequence
PR Identity Gate — MANDATORY
When the user provides a Bitbucket PR URL, PR metadata is the source of truth.
Do not spawn review subagents, run fuck-u-code preflight, or start file-level
findings until metadata fetch succeeds.
Metadata fetch order (try both before giving up):
- Primary — mcporter Bitbucket MCP (CLI only; see MCP transport):
mcporter call bitbucket.bb_get_pr workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID> includeFullDiff=true
Extract: PR id, source/destination branch, source/destination commit, PR state,
and full diff when included.
- Secondary — local Bitbucket REST API (only if step 1 fails):
node skills/bitbucket-api-env/scripts/bitbucket-api.mjs pr <PR_ID> (from this repo root)
(use diff / diffstat / comments as needed). Requires BITBUCKET_WORKSPACE,
BITBUCKET_REPO_SLUG, and auth env (BITBUCKET_ACCESS_TOKEN or
BITBUCKET_USERNAME + BITBUCKET_API_TOKEN). Report exact HTTP status and body
excerpt on failure.
Hard stop — metadata unavailable
If both mcporter and local API fail to return usable PR metadata (branches,
commits, PR state):
- Stop the review immediately. No ensemble, no preflight, no “best effort”
pass over local files.
- Reply with a short blocker only: which path failed, error excerpts, missing
env vars if any.
- Do not fall back to
git diff …HEAD, current branch, or inferred PR scope.
- Ask the user to fix mcporter/auth/env or supply explicit branch names + diff.
After metadata succeeds:
- Compare local HEAD/current branch with the PR source branch. If they do not
match, do NOT review local HEAD — state the mismatch.
- Review only the PR diff from metadata (
bb_get_pr / API diff), or git
three-dot using metadata branches:
refs/remotes/origin/<destination>...refs/remotes/origin/<source>
- Never use
HEAD unless PR metadata confirms HEAD is the PR source.
Step 1: Fetch and diff against origin/develop (THREE-DOT DIFF)
CRITICAL: Always use three-dot diff (...) not two-dot diff (..).
Two-dot diff includes changes from the target branch that were merged after the PR branch was created, producing false positives. Three-dot diff shows only changes introduced on the PR branch (merge-base diff) -- this matches what Bitbucket/GitHub PR pages display.
For Bitbucket repos with mcporter configured (preferred)
When git commands are blocked (e.g., read-only review mode), fetch via mcporter
after PR Identity Gate succeeds:
- PR metadata + diff:
mcporter call bitbucket.bb_get_pr workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID> includeFullDiff=true
- Comments:
mcporter call bitbucket.bb_ls_pr_comments workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID>
- Source files:
mcporter call bitbucket.bb_get_file workspaceSlug=<ws> repoSlug=<repo> filePath=<path>
- If the user gave a PR URL and metadata gate failed, do not fall back to git here — stop per Hard stop.
For direct git access (fallback)
Use only when the user did not supply a Bitbucket PR URL, or explicitly
requests git-only review without Bitbucket metadata.
git fetch origin
git diff origin/develop...HEAD --stat
git diff origin/develop...HEAD
Reference script: references/three-dot-diff.sh (supports custom target branch and output modes).
- Use
--stat first to get the full list of changed files.
- Then read the full diff to understand every change.
- If the branch is behind origin/develop, note it but still proceed with the diff.
- If the diff looks unexpectedly large, verify you are using
... (three dots) not .. (two dots).
Step 2: Understand codebase context
Before evaluating any finding, understand the domain and conventions:
- Read
CLAUDE.md or LLM.md at the repo root if present — these define project-wide conventions.
- Identify the feature domain (auth, transfer, account, etc.) and apply domain-appropriate risk weighting:
- Payment/auth flows → higher severity bar
- UI-only changes → lower severity bar
- Check what design system components, hook wrappers, and DI patterns are in use.
- Note any existing patterns in nearby unchanged files to distinguish "new smell" from "existing convention".
Step 3: Review each changed file in detail
For every file in the diff:
- Read the full file, not just the changed lines — understand the full component/module shape.
- Identify the file's role (screen, hook, service, util, type, test).
- Apply all mandatory logic checks to that file's specific logic.
- Note findings scoped to that file before moving to the next.
Group findings by file in the output. Do not mix findings from different files in one paragraph.
Step 4: Synthesize and output
After reviewing all files, write the final review following the output template.
When to use
Use this skill when:
- Reviewing PRs, diffs, commits, or changed files
- Verifying bugfix safety and regression risk
- Checking logic with optional inputs, fallbacks, and async flows
Review goals
- Find defects that can affect users or data.
- Detect edge cases hidden behind “usually works” paths.
- Provide minimal, practical fixes with clear reproduction conditions.
- Keep feedback short and high-signal.
Priority order
- Functional correctness
- Security (OWASP Mobile/Web) & data integrity
- State consistency & async timing
- API contract/type safety
- Performance hotspots
- Module composition & data flow architecture
- Clean code (naming, structure, component design)
- Maintainability/readability
Mandatory logic checks (always run)
Invariant checks
- Identify paired/related values that must stay consistent.
- Examples:
(count, maxCount), (value, unit), (start, end), (id, status).
Partial-input checks
- Test cases where only some optional fields/props are provided.
- Verify behavior for missing counterpart values.
Fallback-chain checks
- Trace
??, ||, ternary chains.
- Confirm precedence and source-of-truth are not contradictory.
State vs UI checks
- Ensure render conditions match computed data conditions.
- Detect hidden invalid states (data exists but UI hides it, or vice versa).
Boundary checks
- Validate
0, negative, undefined, empty string, large values, max/min boundaries.
- Require clamps/guards where needed.
Async/race checks
- Check stale closure/state usage.
- Verify open/close/reset/submit/error ordering.
- Ensure loading flags recover in all paths.
UI consistency checks
- Scan repeated UI patterns (section labels, headers, list items, cards) for style mismatches.
- Verify fontSpec, themedColor, spacing, padding are identical across elements that serve the same visual role.
- Flag when one sibling element uses a different token than the rest (e.g., FONT.B16 vs FONT.B18 for section labels in the same screen).
- Check icon sizes, border radii, and gap values for consistency within a component group.
State transition UX checks
- When React
key changes cause remount, verify user input is either preserved, impossible before the transition, or explicitly discarded with clear UX (loading skeleton, disabled fields).
- Detect "input loss on async load" pattern: form renders with placeholder defaults → async data arrives → key change remounts form → any user input typed before load is silently lost.
- Verify loading→loaded transitions: are interactive fields disabled or hidden during loading? Does the transition cause layout shift or flash of empty content?
- Check that
disabled state covers all interactive elements (inputs, dropdowns, buttons) during loading, not just the submit CTA.
Expensive-before-cheap checks
- Before any API call or I/O operation, check if there's a condition that could skip it.
- Trace function calls into their internals — if a cheap check (e.g.,
isSupported, isEnabled, feature flag) lives inside a called function, verify it runs before any expensive operation in the caller.
- Pattern to detect: API call on line N, condition check inside function called on line N+1.
- Fix: Hoist the cheap check before the expensive operation.
- Example:
GetChallenge() called before generateAttestation() which checks isSupported internally → wasteful API call on unsupported devices.
Refactor-only layout responsibility checks
When a PR claims "only code location changes" or extracts a base component, build a before/after style ownership map before concluding equivalence. Map every style property to its owner in both versions.
- interactive wrapper: Pressable / AnimatedPressable / Touchable
- content layout row
- child text/icon/image layout
- feedback/ripple/overlay boundary
- reusable base component boundary
Check these specific risks:
Style owner changed
flexDirection, gap, alignItems, padding, flex, alignSelf, justifyContent
- Moving a style from pressable container to inner view can silently change hit area, feedback area, measurement (flex-basis), or parent layout behavior.
- Example:
paddingHorizontal on containerStyle of BankXAnimatedPressable vs inner BankXView — padding moves out of the pressable feedback boundary.
Conditional style names hide behavior
- Names like
whenLogoStyle must describe the actual effect, not the triggering condition.
- If the style value is
alignItems: 'center', review it as row alignment, not "logo styling".
- Flag names that make a layout invariant look like a visual detail.
Extracted base component leaks parent assumptions
flex: 1, alignSelf: 'stretch', absolute sizing, or margins inside a reusable base component are red flags.
- Base components should expose layout props (via
style) or keep parent-owned layout in the wrapper.
- If
flex: 1 is added only for width fill, verify it won't cause height expansion when reused inside a column parent with bounded height.
Intent, not just same values
- If
MY_BANK and logo-based accounts intentionally align differently, the reason should be obvious from naming or comments.
- If not, ask for clarification or suggest explicit named styles.
Review output guidance:
- If behavior likely still works but intent/reuse risk is unclear, report as 🔵 Trivial or 🟡 Minor.
- Do not say "layout equivalent" until style ownership and reusable-boundary effects are verified.
Architecture review checks (run when PR adds hooks, services, or screens)
When a PR introduces new modules, hooks, services, or screens (or significantly restructures existing ones), evaluate architecture quality. Skip for trivial single-file changes.
Composition & responsibility
- Each hook/module should have a single, clear responsibility.
- Detect God-hooks or God-screens that mix data fetching, business logic, UI state, and navigation.
- Verify separation: data hooks vs UI hooks vs orchestration hooks.
- Check if a hook does too many things that should be split.
Data flow clarity
- Trace how data moves: props → hook → state → render. Identify implicit coupling.
- Evaluate ref vs state choices: refs for values that don't trigger re-render, state for values the UI depends on.
- Flag unnecessary indirection (getter callbacks wrapping refs, redundant wrappers).
- Check prop drilling depth — suggest context or composition when drilling exceeds 3 levels.
Error handling strategy
- Is error handling centralized (single error handler) or distributed (per-callsite try-catch)?
- Verify failure code → UX mapping consistency: same error code should produce same user experience.
- Detect missing error paths: what happens when an API call fails but no handler catches that specific failure code?
- Check error handler completeness: does the switch/if-chain cover all known failure codes?
Interface design
- Function/hook parameters: prefer named params (object destructuring) over positional args when >2 params.
- Naming: domain-specific names over generic (
useCardlessWithdrawalSubmit > useSubmit).
- Return types: explicit and narrow, not
any or overly broad unions.
- API surface: does the module expose only what consumers need?
Navigation patterns
- Push vs replace: replace for correction flows (edit → confirm), push for new destinations.
- Screen lifecycle: does the screen clean up state on unmount? Does going back produce stale state?
- Deep link readiness: can the screen be entered directly with params, or does it depend on prior screen state?
Cross-cutting consistency
- i18n: detect hardcoded user-facing strings (English or any language) that should use translation keys.
- DI patterns: services accessed via
dependencyContainer.get() with proper TYPES, not direct imports of implementations.
- Design system: raw RN primitives (
View, Text) instead of design system components.
- Consistent patterns: does the new code follow the same patterns as neighboring modules?
Architecture findings default to 🔵 Trivial or 🟡 Minor severity.
Exception: data flow bugs or missing error handling gaps that cause user-facing issues → 🟠 Major.
Security checks — OWASP-based (always run)
Apply to every PR. Weight higher for payment, authentication, data storage, and API integration changes.
Based on OWASP Mobile Top 10 and OWASP Web Top 10:
Insecure Data Storage (OWASP M2)
- Detect sensitive data (account numbers, tokens, PII, credentials) stored in plain-text local storage.
- MMKV, AsyncStorage, UserDefaults, SharedPreferences without encryption → flag.
- Sensitive data should use Keychain (iOS) / Keystore (Android) / SecureEnclave.
- Check: is the stored data truly non-sensitive (locale, theme) or PII (account number, national ID)?
Insecure Authentication & Session (OWASP M4)
- Token/session handling: verify expiration checks, refresh logic, secure storage.
- Hardcoded credentials, API keys, or secrets in source code.
- Re-authentication requirements for sensitive operations (e.g., changing withdrawal limits).
Insufficient Input Validation (OWASP A03/M7)
- User input sanitization before API calls or local processing.
- Amount/quantity boundary validation: negative values, overflow, zero, extreme values.
- Format validation: regex-based inputs without ReDoS protection.
Sensitive Data Exposure (OWASP A02)
- Logging sensitive data (account numbers, tokens, passwords) via
console.log or error reporting.
- Error messages exposing internal details (stack traces, server paths, SQL queries) to users.
- Sensitive data in navigation params that may appear in navigation state dumps.
Double Submission / Idempotency (Payment Flows)
- Payment, transfer, and withdrawal flows MUST have double-submission protection.
- Check for: loading state during API call, CTA disable during submission, idempotency keys.
- Missing protection in financial flows → 🔴 Critical.
Broken Access Control (OWASP A01)
- Client-side-only authorization checks without server verification.
- UI hiding features based on role but still allowing API calls.
- Navigation guards that can be bypassed by deep links.
Security severity guide:
- 🔴 Critical: tokens/credentials in plain storage, hardcoded secrets, double submission in payment flows
- 🟠 Major: PII in plain local storage, missing input validation on financial amounts, sensitive data in logs
- 🟡 Minor: debug logging with non-critical data, client-side validation gaps backed by server validation
Thermo-nuclear maintainability checks (always run via ensemble pass)
Load and apply `thermo-nuclear
…(truncated)
1---2name: zereight-review-23description: Comprehensive code review skill for practical PR feedback. Use for feature, bugfix, and refactor reviews. Prioritizes correctness, edge cases, logic invariants, fallback-chain safety, async state transitions, architecture analysis, OWASP security, and clear actionable feedback.4---56# zereight-review78Prioritize **correctness and risk** over style nitpicks.9Default tone: concise, direct, actionable.1011## Mandatory Review Ensemble -- NON-NEGOTIABLE1213When the user invokes `zereight-review`, `$zereight-review`, or asks to use the14Zereight review skill, do not complete the review from a single reviewer pass.15You must run a multi-skill, subagent-based review ensemble first, then synthesize16the results.1718Required instruction sources to load before reviewing:1920- Nearest repo `AGENTS.md`21- `/Users/tao.exe/.codex/instructions.md`22- `/Users/tao.exe/.codex/AGENTS.md`23- `codegraph-review-routing` when CodeGraph MCP is available or the review needs impact/call-chain context24- `code-review`25- `code-review-expert`26- `code-reviewer`27- `agent-skills:code-review-and-quality`28- `agent-skills:using-agent-skills`29- `thermo-nuclear-code-quality-review`3031Required subagent review passes:3233| Subagent pass | Builtin agent | Model (required) | Required basis | Review focus |34| --- | --- | --- | --- | --- |35| Baseline full-diff reviewer | `reviewer` | `opencode-go/deepseek-v4-pro` | `code-review` | finding-first output, severity, full diff coverage, `comment-worthy` / `no comment` |36| Regression and contract reviewer | `reviewer` | `opencode-go/deepseek-v4-pro` | `code-review-expert` | behavioral regressions, API/prop contracts, hidden state and edge-case risk |37| File coverage reviewer | `worker` | `opencode-go/deepseek-v4-flash` | `code-reviewer` | every changed file and hunk, missing tests, maintainability risks |38| Quality gate reviewer | `worker` | `opencode-go/deepseek-v4-flash` | `agent-skills:code-review-and-quality` | correctness, reliability, maintainability, security, test quality |39| Thermo-nuclear maintainability reviewer | `reviewer` | `opencode-go/deepseek-v4-pro` | `thermo-nuclear-code-quality-review` | code judo / structural simplification, 1k-line boundary, spaghetti branching, abstraction quality, layer boundaries |40| Agent orchestration reviewer | `delegate` | `opencode-go/deepseek-v4-flash` | `agent-skills:using-agent-skills` | whether the work was split correctly and whether any review lens is missing (including thermo-nuclear pass) |41| Zereight coordinator | (parent) | parent session model | this skill | three-dot diff, RED-team mindset, verification discipline, final synthesis |4243## Ensemble model policy — MANDATORY4445Zereight review subagents use **only** these models unless the user explicitly46requests a different provider:4748| Model | Use for |49| --- | --- |50| `opencode-go/deepseek-v4-pro` | Baseline + Regression (`reviewer`) — deeper reasoning, contract/regression analysis |51| `opencode-go/deepseek-v4-flash` | File coverage + Quality gate (`worker`), Orchestration (`delegate`) — breadth, five-axis gate, meta review |52| `cursor/composer-2.5` | **Last-resort fallback** when OpenCode Go fails (429, quota, rate limit) — matches `defaultProvider`/`defaultModel` in `~/.pi/agent/settings.json` |5354**Ordered fallback chain (pi-subagents auto-retries on 429/quota):**5556| Agent | Primary | Then | Last resort |57| --- | --- | --- | --- |58| `reviewer` | `deepseek-v4-pro` | `deepseek-v4-flash` | `cursor/composer-2.5` |59| `worker` | `deepseek-v4-flash` | `deepseek-v4-pro` | `cursor/composer-2.5` |60| `delegate` | `deepseek-v4-flash` | `deepseek-v4-pro` | `cursor/composer-2.5` |6162Configured in `~/.pi/agent/settings.json` → `subagents.agentOverrides.*.fallbackModels`.63pi-subagents treats 429 / rate-limit / quota errors as retryable and walks this list automatically.6465**Never rely on builtin default models** (`claude-sonnet-4-6`, `openai-codex/gpt-5.3-codex`, etc.).66User-level overrides live in `~/.pi/agent/settings.json` under67`subagents.agentOverrides`, but **still pass `model` on every spawn** so the68runtime cannot fall back to Claude when quota is exhausted.6970Execution rules:7172- Spawn separate subagents for the required review passes whenever the runtime73 supports subagents. Give each subagent the exact PR/range, target branch,74 repository path, the relevant instruction sources, and the **model from the75 table above**.76- Every subagent must follow the repo `AGENTS.md` and global Codex instructions77 in addition to its review skill.78- Do not return the final review until every required pass has either completed79 or is explicitly blocked.80- All review subagents must use Pi builtin agents (`reviewer`, `worker`,81 `delegate`) with an explicit `model` parameter. **Do not** spawn without82 `model` — builtin `worker` defaults to Claude and will burn quota.83- **Do not** route review passes through Claude, Claude Code, Chorus, or any84 Claude-backed external agent unless the user explicitly requests Claude.85- If a subagent fails with provider/model/quota errors (including **429** from86 OpenCode Go), pi-subagents retries the ordered `fallbackModels` chain in87 settings: paired DeepSeek (`pro` ↔ `flash`), then **`cursor/composer-2.5`**88 (session default). Do not retry Claude paths unless the user explicitly89 requests Claude.90- If spawn still fails after the full chain, report which models were attempted91 and continue synthesis from completed passes — do not block the final review.9293**Parallel spawn example (pi-subagents / `subagent` tool):**9495```json96{97 "tasks": [98 {99 "agent": "reviewer",100 "model": "opencode-go/deepseek-v4-pro",101 "task": "Baseline full-diff review. Skill: code-review. PR: ..."102 },103 {104 "agent": "reviewer",105 "model": "opencode-go/deepseek-v4-pro",106 "task": "Regression and contract review. Skill: code-review-expert. PR: ..."107 },108 {109 "agent": "worker",110 "model": "opencode-go/deepseek-v4-flash",111 "task": "File coverage review. Skill: code-reviewer. PR: ..."112 },113 {114 "agent": "worker",115 "model": "opencode-go/deepseek-v4-flash",116 "task": "Quality gate review. Skill: code-review-and-quality. PR: ..."117 },118 {119 "agent": "reviewer",120 "model": "opencode-go/deepseek-v4-pro",121 "task": "Thermo-nuclear maintainability review. Skill: thermo-nuclear-code-quality-review. PR: ..."122 }123 ],124 "concurrency": 5125}126```127128Then spawn orchestration separately:129130```json131{132 "agent": "delegate",133 "model": "opencode-go/deepseek-v4-flash",134 "task": "Orchestration review: verify all ensemble axes were covered. ..."135}136```137138**Final synthesis must list models used**, e.g. `reviewer ×3 (deepseek-v4-pro),139worker ×2 (deepseek-v4-flash), delegate (deepseek-v4-flash)`.140141**Single-pass fallback (subagent unavailable):** If the runtime does not support142subagent spawning AND the user explicitly approves (e.g., by switching to143/review mode, stating "fallback" or "single pass"), skip the ensemble and144do a thorough self-contained review instead. Requirements:145 1. State that subagent ensemble is unavailable.146 2. Confirm user approval (explicit wording or known review-mode flag).147 3. Still load all six reviewer instruction sources sequentially (including148 `thermo-nuclear-code-quality-review`).149 4. Cover all ensemble axes in one pass: correctness, security, regression,150 architecture/contracts, clean code, thermo-nuclear maintainability.151 5. Apply full-diff coverage, RED-team mindset, and verification discipline.152 6. If the user did NOT approve fallback, stop and report the blocker.153154## Subagent Failure Budget — MANDATORY155156Subagent claims are not primary evidence. A claim becomes a finding only157after current-turn primary evidence (diff, file contents, tests, CI logs,158rtk-grepped source, or reproducible output) confirms it.159160Rules:1611621. A subagent failure or stuck verification is not a blocker — it is a163 signal to move on.1642. If a verification path (e.g., live API call, official docs fetch) fails165 once, retry at most once **only when** the result is necessary for a166 P0/P1 decision.1673. If the same verification path fails 2 times total, stop pursuing it168 immediately. Do not try a third approach.1694. If 2+ subagent/verification attempts fail for the same claim, treat170 the claim as **unusable** for review purposes. Either discard it or171 note it as unverified residual risk — never as a blocker.1725. Never spend more than one bounded verification pass on any P2/🟡 Minor173 or lower concern.1746. When verification fails without logs, state "unverified; not used as175 blocker" and continue producing the final review.1767. Do not block the final review waiting for a subagent or verification177 to complete. Synthesize from what is already available, mark any gaps,178 and deliver.1798. **Exception:** **PR Identity Gate** hard stop overrides rules 1–7. When180 both mcporter and local API fail to fetch Bitbucket PR metadata, stop the181 entire review — do not synthesize findings from local git or subagents.182183If subagent spawning IS available, use it — do NOT default to single-pass.184- Keep raw diff output out of the conversation context when possible. Prefer185 context-mode indexing/search for large diffs, and use three-dot diff against186 the target branch.187188## MCP transport — mcporter CLI only (MANDATORY)189190Zereight review **never** treats Cursor/Codex native MCP (`mcp_get_tools`,191`mcp_call_tool`, MCP panel server list) as the source of truth for mcporter192inventory. Those lists read `~/.cursor/mcp.json` / `~/.codex/config.toml` and193can be empty even when `~/.mcporter/mcporter.jsonc` has healthy servers.194195### Canonical registry and invocation196197| Concern | Source of truth | How to invoke |198| --- | --- | --- |199| Server inventory | `~/.mcporter/mcporter.jsonc` | `mcporter list` or `mcporter list <server>` |200| Tool schema | mcporter | `mcporter list <server> --schema` (when needed) |201| Tool execution | mcporter CLI | `mcporter call <server>.<tool> ...` |202203**Always** run MCP tools for this skill through the shell, e.g.:204205```bash206mcporter call fuck-u-code.analyze \207 path="<bounded-path>" \208 format=json top=15 verbose=false209```210211Do **not** substitute `mcp_call_tool` for `mcporter call` during review.212213### Cursor / Codex exposure (mcporter-bridge)214215Register **`mcporter-bridge`** in `~/.cursor/mcp.json` (and optionally216`~/.codex/config.toml`) when the user wants the **full mcporter inventory**217visible in the IDE MCP UI. Use the pipx binary path, not218`python3 -m mcporter_bridge` (often missing):219220```json221"mcporter-bridge": {222 "command": "/Users/tao.exe/.local/bin/mcporter-bridge",223 "args": []224}225```226227Bridge exposes discovery/call helpers (`mcporter_list_servers`,228`mcporter_call_tool`, etc.). Even with bridge loaded, **zereight-review229preflight and PR fetches still use `mcporter call` directly** — bridge is for230human/IDE visibility, not the review execution path.231232### Availability mistakes to avoid233234| Wrong check | Why it fails | Correct check |235| --- | --- | --- |236| `mcp_get_tools` shows no `fuck-u-code` | Cursor `mcp.json` may omit servers | `mcporter list fuck-u-code` |237| Memory from prior session | Config changes across reloads | Fresh `mcporter list` each review |238| Assuming reload fixed MCP | Reload does not import `mcporter.jsonc` into Cursor | CLI `mcporter list` + optional `mcp.json` edit |239240If `mcporter list fuck-u-code` shows tools with non-offline status → **available**.241State **`fuck-u-code preflight run (mcporter CLI)`** in the final review.242Only write **`skipped (unavailable)`** when `mcporter list` or `mcporter call`243fails (binary missing, server offline, timeout, schema mismatch).244245Review preflight safeguards:246247- Before broad file reading, use context-mode to reduce the diff to changed248 files/symbols and high-risk hunks. If CodeGraph MCP is available, run a249 bounded impact pass for changed symbols that need surrounding context:250 callers, usages, call chains, affected screens/hooks/navigation/API251 boundaries, and hotspot/coupling candidates. Treat CodeGraph output only as252 candidate discovery; every finding still needs current-turn primary evidence253 from the diff, file contents, tests, logs, or context-mode search.254- Do not use CodeGraph for Bitbucket/Jira/Confluence/internal connector reads;255 those remain mcporter-first with schema inspection. Do not use CodeGraph for256 large diff/log processing; those remain context-mode. Do not use CodeGraph as257 durable memory; agentmemory remains curated and verified only.258- If CodeGraph output is `_truncated`, stale, unresolved, or conflicts with file259 evidence, do not cite it as review evidence. Narrow the query once or fall260 back to context-mode plus file evidence.261- RTK command rewrites can fail silently for simple read commands such as262 `rtk rewrite "sed ..."`. If that happens, do not stall the review. Use the263 repo-approved RTK form when the hook provides one, prefer `rtk grep` /264 `rtk git` for searched or git commands, and keep direct file reads narrowly265 bounded when reading required instruction or skill files.266- If the nearest repo `AGENTS.md` is missing, do not treat that as permission to267 ignore repo instructions. Use any AGENTS instructions supplied in the current268 conversation as the repo instruction source, state that fallback, and continue.269- For React or React Native PRs, include `npx react-doctor@latest` in270 verification. Run it from the repo root when package-manager and network271 access allow it. If it cannot run, report the exact command and blocker.272- **MANDATORY: Check fuck-u-code availability BEFORE any preflight or273 ensemble step.** Run **`mcporter list fuck-u-code`** (CLI only — see274 **MCP transport — mcporter CLI only** above). Confirm the server appears275 with a non-failure status (tool count + latency, not "offline" or "error").276 Do NOT use `mcp_get_tools` for this gate. Do NOT skip this check. Do NOT277 assume availability from memory, Cursor reload, or prior sessions.278 - If available AND the PR has substantial logic changes (not just279 locales/styles/tests/assets-only), run the bounded static analysis below280 via **`mcporter call fuck-u-code.analyze`**.281 - If NOT available (`mcporter` missing, `mcporter list` offline, `mcporter282 call` fails): state "`fuck-u-code preflight skipped (unavailable — mcporter283 CLI)`" and continue. Do NOT block the review.284 - If `mcporter list` succeeds but you skip `mcporter call` without reason285 (as in PR #2217 / #2182): **PROCESS VIOLATION**. The preflight line must286 be either **`fuck-u-code preflight run (mcporter CLI)`** or **`skipped287 (reason)`**. Silence is not permitted.288 1. From the three-dot diff or PR metadata, extract the list of changed files.289 Filter to `*.ts`, `*.tsx` only; exclude `**/*.test.*`, `**/__snapshots__/**`,290 `**/locales/**`, `dist/`, `node_modules/`.291 2. Determine the common parent path(s) of the changed files (typically 1-2).292 Never scan the entire workspace — only the bounded paths. If changed293 files span multiple disjoint paths, run the analysis for each path.294 3. Invoke `analyze` through mcporter:295 ```296 mcporter call fuck-u-code.analyze \297 path="<common-parent-path>" \298 format=json top=15 verbose=false299 ```300 4. From the JSON output, extract `files[].score` and `files[].metrics[]`.301 Keep only files that appear in both the PR diff AND the worst-scoring list.302 5. Read the full content of those files (not just the diff) to understand303 whether the PR is introducing new complexity/duplication or inheriting304 existing legacy. Check: does the new code worsen the metrics?305 6. If the PR inherits existing legacy (file was already bad before this PR),306 note it as ⚪ Info — do not block. If the PR introduces new hotspots307 (complexity/duplication without justification), report as 🟡 Minor.308 7. Never promote fuck-u-code scores to primary findings without file-content309 evidence. Never cite fuck-u-code score alone as 🟠 Major or higher.310 8. On `mcporter call` failure (timeout, unavailable, schema mismatch), skip311 preflight with "`fuck-u-code preflight skipped (mcporter CLI — <reason>)`"312 and continue. Do not retry more than once.313 9. The `ai-review` tool is excluded from the default pipeline — it sends314 code to external APIs and duplicates the zereight ensemble.315- When spawning review subagents, do not combine `fork_context=true` with an316 explicit `agent_type` if the runtime rejects that combination. Retry by317 spawning role-specific agents without `fork_context` and put the exact PR318 range, repository path, target branch, and required instruction sources in319 each agent prompt.320- Never use ambiguous branch names such as `origin/develop` for review diffs if321 local refs can shadow remote refs. Resolve and use full refs:322 `refs/remotes/origin/<target>...refs/remotes/origin/<source>`. If an323 ambiguous ref caused an unexpectedly large diff, discard that result and324 restart scoping from the full-ref three-dot diff.325326Synthesis rules:327328- Merge findings from all subagents into one final review (including329 thermo-nuclear structural/maintainability findings).330- Map thermo-nuclear **presumptive blockers** (1k-line explosion, spaghetti331 special-case growth, missed code-judo simplification, boundary leaks) into332 zereight severity when primary evidence confirms: structural regression with333 user-facing risk → 🟠 Major; maintainability-only → 🟡 Minor or 🛠️ refactor;334 decomposition opportunity with no behavior risk → 🔵 Trivial. Do not promote335 thermo tone alone without file/line evidence.336- De-duplicate overlapping findings and keep the strongest, most concrete file337 and line reference.338- If reviewers disagree, state the disagreement briefly and choose the outcome339 supported by code evidence.340- Preserve whole-diff coverage by listing changed files as `comment-worthy` or341 `no comment`.342- Lead with actionable findings ordered by severity. Keep summaries secondary.343344## RED Team Mindset -- MANDATORY345346You are an adversary, not a rubber stamp. Your job is to break the code, not confirm it works.347348- **Think like an attacker**: For every change, ask "How can this fail? How can this be exploited? What input breaks this?"349- **Never trust the happy path**: Code that works for expected inputs is the baseline, not the goal. Hunt for the unexpected.350- **Simulate hostile inputs**: Empty strings, negative numbers, null, undefined, MAX_SAFE_INTEGER, special characters, concurrent calls, network timeouts.351- **Challenge assumptions**: If the author assumes X is always true, find the scenario where X is false.352- **Question removed code**: Deleted code had a reason to exist. Verify the reason is truly gone, not just hidden.353- **Trace error propagation end-to-end**: Follow every throw/reject/return-undefined through all callers. One unhandled path = one crash in production.354- **Don't approve because it "looks fine"**: If you can't construct a specific failure scenario, dig deeper -- absence of evidence is not evidence of absence.355356## Verification Discipline — MANDATORY357358Theoretical analysis is NOT enough. Every claim about library behavior, framework semantics, or runtime performance must be **empirically verified** before assigning severity.359360### Rule 1: Theoretical claims require evidence361362Before labeling any finding as 🟠 Major or higher based on framework/library behavior, verify with **at least one** of:363364- **Source grep**: `node_modules` source of the relevant library365- **Official docs**: documented behavior from the library's docs366- **Actual usage sites**: grep the codebase for how the construct is used in practice367- **Reproduction test**: runnable test case demonstrating the bug368369If you can only say "theoretically this could..." without one of the above, demote to 🔵 Trivial or 🟡 Minor until verified.370371### Rule 2: Detection triggers — STOP and verify372373When drafting a finding, if you write any of these phrases, STOP and verify:374375- "이론적으로는 ~~" / "theoretically ~~"376- "~~ 일 수도 있다" / "this could ~~"377- "`useMemo` / `useEffect` / `SharedValue` / context 동작" (React/reanimated semantics)378- "라이브러리 X는 ~~한다" (library behavior assertion)379- "이 setState는 re-render를 일으켜 jank를 유발한다" (performance claim without measurement)380381### Rule 3: Verification patterns by claim type382383| Claim type | How to verify |384|---|---|385| React hook semantics (`useMemo` deps, `useEffect` closure) | Grep actual usage sites; check React docs reference |386| Reanimated SharedValue / worklet | Grep `node_modules/react-native-reanimated/src/`; check Reanimated docs |387| `@gorhom/bottom-sheet` animatedIndex vs onChange | Grep `node_modules/@gorhom/bottom-sheet/src/`; inspect when callbacks fire |388| List virtualization (FlashList, FlatList) | Check item count and render path |389| Performance (re-render frequency, memo effectiveness) | Count actual trigger events in real usage, not hypothetical worst case |390391### Rule 4: Signal-Trigger Investigation — upstream root cause392393Defensive code is a **symptom**, not a solution. When you see these signals, investigate the upstream cause:394395**Signals**:396- Defensive JSDoc mentioning "stable id", "fallback for ...", "workaround for ...", "client-defined"397- Type assertions: `as unknown as T`, enum values cast from raw `int` (`1 as TermCategory`)398- Mock/stories comments: "duplicate rows", "non-enum ints", "dev server returns ...", "garbage data"399- `// FIXME`, `// TODO`, `// HACK` comments400- Array-index-based key synthesis (`groupIndex + periodIndex + value`)401- Over-complex null-handling for "should never happen" cases402403**Action**:4041. Read the JSDoc / comment in full4052. Check referenced mock data / stories for actual server response shape4063. Trace whether the root cause is fixable upstream (server API, schema, type contract)4074. Report upstream issue as a separate finding — don't just say "defensive coding is fine"408409### Rule 5: Mock/Stories = API shape evidence410411Mock files and `.stories.tsx` often contain real server response samples or dev-server captures. **Include them in review scope**:412413- Read `*.stories.tsx` `args` / mock constants414- Check for comments like "sample from api-grpc-{env}", "dev server snapshot"415- Duplicate/malformed mock data = signal of real server data quality issue416- Do NOT dismiss stories as "test fixtures, not production concern"417418### Failure cases — lessons (calibration)419420Document your own missed findings here to build calibration:421422- **PR #1790 M-3 (SharedValue useMemo staleness)**: Theoretical claim that `useMemo([sharedValue], …)` wouldn't re-run on `.value.length` change. Verification showed `buildFilterableSheetSnapPoints` always returns 2-element array → no actual staleness. Demoted Major → Trivial.423- **PR #1790 M-6 (onChange re-render jank)**: Theoretical claim that setState in bottom-sheet onChange causes jank during drag. Library docs confirm `onChange` fires only at snap settle, not during drag → no jank. Demoted Major → Trivial.424- **PR #1790 period row key**: JSDoc "same length can appear in multiple groups" + stories mock comment "duplicate `0` rows, non-enum `term` ints" were ignored as "defensive coding". Actually evidence of server API data quality issue requiring backend attention. Missed the upstream root cause entirely.425426## Full-Diff Inline Comment Mindset -- MANDATORY427428Review every PR as if you are going to leave inline comments on the full diff, even when the final output is a summarized review.429430- Do not stop after finding the first major issue. Continue through every changed file and every changed hunk.431- For each changed file, make an explicit internal decision: `comment-worthy` or `no comment`, instead of silently skipping it.432- Assume each diff hunk may need its own comment. Even if you later collapse findings in the final write-up, the review process must still inspect the full diff at inline-comment granularity.433- Distinguish clearly between:434 - actual findings that deserve comments435 - changed areas reviewed and intentionally passed with no comment436- When synthesizing the final review, preserve whole-diff coverage. The output should reflect that the PR was reviewed file-by-file, not just around the most obvious issue.437- If the user asks for a PR review without extra direction, default to this mindset automatically.438439## Workflow -- always follow this sequence440441### PR Identity Gate — MANDATORY442443When the user provides a **Bitbucket PR URL**, PR metadata is the source of truth.444**Do not** spawn review subagents, run fuck-u-code preflight, or start file-level445findings until metadata fetch succeeds.446447**Metadata fetch order (try both before giving up):**4484491. **Primary — mcporter Bitbucket MCP** (CLI only; see **MCP transport**):450 `mcporter call bitbucket.bb_get_pr workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID> includeFullDiff=true`451 Extract: PR id, source/destination branch, source/destination commit, PR state,452 and full diff when included.4532. **Secondary — local Bitbucket REST API** (only if step 1 fails):454 `node skills/bitbucket-api-env/scripts/bitbucket-api.mjs pr <PR_ID>` (from this repo root)455 (use `diff` / `diffstat` / `comments` as needed). Requires `BITBUCKET_WORKSPACE`,456 `BITBUCKET_REPO_SLUG`, and auth env (`BITBUCKET_ACCESS_TOKEN` or457 `BITBUCKET_USERNAME` + `BITBUCKET_API_TOKEN`). Report exact HTTP status and body458 excerpt on failure.459460**Hard stop — metadata unavailable**461462If **both** mcporter and local API fail to return usable PR metadata (branches,463commits, PR state):464465- **Stop the review immediately.** No ensemble, no preflight, no “best effort”466 pass over local files.467- Reply with a short **blocker** only: which path failed, error excerpts, missing468 env vars if any.469- Do **not** fall back to `git diff …HEAD`, current branch, or inferred PR scope.470- Ask the user to fix mcporter/auth/env or supply explicit branch names + diff.471472**After metadata succeeds:**4734743. Compare local HEAD/current branch with the PR source branch. If they **do not475 match**, do NOT review local HEAD — state the mismatch.4764. Review only the PR diff from metadata (`bb_get_pr` / API `diff`), or git477 three-dot using metadata branches:478 `refs/remotes/origin/<destination>...refs/remotes/origin/<source>`4795. Never use `HEAD` unless PR metadata confirms HEAD is the PR source.480481### Step 1: Fetch and diff against origin/develop (THREE-DOT DIFF)482483**CRITICAL: Always use three-dot diff (`...`) not two-dot diff (`..`).**484Two-dot diff includes changes from the target branch that were merged after the PR branch was created, producing false positives. Three-dot diff shows only changes introduced on the PR branch (merge-base diff) -- this matches what Bitbucket/GitHub PR pages display.485486### For Bitbucket repos with mcporter configured (preferred)487When git commands are blocked (e.g., read-only review mode), fetch via mcporter488after **PR Identity Gate** succeeds:489490- PR metadata + diff: `mcporter call bitbucket.bb_get_pr workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID> includeFullDiff=true`491- Comments: `mcporter call bitbucket.bb_ls_pr_comments workspaceSlug=<ws> repoSlug=<repo> prId=<PR_ID>`492- Source files: `mcporter call bitbucket.bb_get_file workspaceSlug=<ws> repoSlug=<repo> filePath=<path>`493- If the user gave a PR URL and metadata gate failed, **do not** fall back to git here — stop per **Hard stop**.494495### For direct git access (fallback)496497Use only when the user did **not** supply a Bitbucket PR URL, or explicitly498requests git-only review without Bitbucket metadata.499500```bash501git fetch origin502git diff origin/develop...HEAD --stat503git diff origin/develop...HEAD504```505506Reference script: `references/three-dot-diff.sh` (supports custom target branch and output modes).507508- Use `--stat` first to get the full list of changed files.509- Then read the full diff to understand every change.510- If the branch is behind origin/develop, note it but still proceed with the diff.511- If the diff looks unexpectedly large, verify you are using `...` (three dots) not `..` (two dots).512513### Step 2: Understand codebase context514515Before evaluating any finding, understand the domain and conventions:516517- Read `CLAUDE.md` or `LLM.md` at the repo root if present — these define project-wide conventions.518- Identify the feature domain (auth, transfer, account, etc.) and apply domain-appropriate risk weighting:519 - Payment/auth flows → higher severity bar520 - UI-only changes → lower severity bar521- Check what design system components, hook wrappers, and DI patterns are in use.522- Note any existing patterns in nearby unchanged files to distinguish "new smell" from "existing convention".523524### Step 3: Review each changed file in detail525526For every file in the diff:5275281. Read the full file, not just the changed lines — understand the full component/module shape.5292. Identify the file's role (screen, hook, service, util, type, test).5303. Apply all mandatory logic checks to that file's specific logic.5314. Note findings scoped to that file before moving to the next.532533Group findings by file in the output. Do not mix findings from different files in one paragraph.534535### Step 4: Synthesize and output536537After reviewing all files, write the final review following the output template.538539---540541## When to use542543Use this skill when:544545- Reviewing PRs, diffs, commits, or changed files546- Verifying bugfix safety and regression risk547- Checking logic with optional inputs, fallbacks, and async flows548549## Review goals5505511. Find defects that can affect users or data.5522. Detect edge cases hidden behind “usually works” paths.5533. Provide minimal, practical fixes with clear reproduction conditions.5544. Keep feedback short and high-signal.555556## Priority order5575581. Functional correctness5592. Security (OWASP Mobile/Web) & data integrity5603. State consistency & async timing5614. API contract/type safety5625. Performance hotspots5636. Module composition & data flow architecture5647. Clean code (naming, structure, component design)5658. Maintainability/readability566567## Mandatory logic checks (always run)5685691. **Invariant checks**570 - Identify paired/related values that must stay consistent.571 - Examples: `(count, maxCount)`, `(value, unit)`, `(start, end)`, `(id, status)`.5725732. **Partial-input checks**574 - Test cases where only some optional fields/props are provided.575 - Verify behavior for missing counterpart values.5765773. **Fallback-chain checks**578 - Trace `??`, `||`, ternary chains.579 - Confirm precedence and source-of-truth are not contradictory.5805814. **State vs UI checks**582 - Ensure render conditions match computed data conditions.583 - Detect hidden invalid states (data exists but UI hides it, or vice versa).5845855. **Boundary checks**586 - Validate `0`, negative, `undefined`, empty string, large values, max/min boundaries.587 - Require clamps/guards where needed.5885896. **Async/race checks**590 - Check stale closure/state usage.591 - Verify open/close/reset/submit/error ordering.592 - Ensure loading flags recover in all paths.5935947. **UI consistency checks**595 - Scan repeated UI patterns (section labels, headers, list items, cards) for style mismatches.596 - Verify fontSpec, themedColor, spacing, padding are identical across elements that serve the same visual role.597 - Flag when one sibling element uses a different token than the rest (e.g., FONT.B16 vs FONT.B18 for section labels in the same screen).598 - Check icon sizes, border radii, and gap values for consistency within a component group.5996008. **State transition UX checks**601 - When React `key` changes cause remount, verify user input is either preserved, impossible before the transition, or explicitly discarded with clear UX (loading skeleton, disabled fields).602 - Detect "input loss on async load" pattern: form renders with placeholder defaults → async data arrives → key change remounts form → any user input typed before load is silently lost.603 - Verify loading→loaded transitions: are interactive fields disabled or hidden during loading? Does the transition cause layout shift or flash of empty content?604 - Check that `disabled` state covers all interactive elements (inputs, dropdowns, buttons) during loading, not just the submit CTA.6056069. **Expensive-before-cheap checks**607 - Before any API call or I/O operation, check if there's a condition that could skip it.608 - Trace function calls into their internals — if a cheap check (e.g., `isSupported`, `isEnabled`, feature flag) lives inside a called function, verify it runs before any expensive operation in the caller.609 - Pattern to detect: API call on line N, condition check inside function called on line N+1.610 - Fix: Hoist the cheap check before the expensive operation.611 - Example: `GetChallenge()` called before `generateAttestation()` which checks `isSupported` internally → wasteful API call on unsupported devices.61261310. **Refactor-only layout responsibility checks**614 - When a PR claims "only code location changes" or extracts a base component, build a before/after **style ownership map** before concluding equivalence. Map every style property to its owner in both versions.615 - interactive wrapper: Pressable / AnimatedPressable / Touchable616 - content layout row617 - child text/icon/image layout618 - feedback/ripple/overlay boundary619 - reusable base component boundary620 - Check these specific risks:621622 **Style owner changed**623 - `flexDirection`, `gap`, `alignItems`, `padding`, `flex`, `alignSelf`, `justifyContent`624 - Moving a style from pressable container to inner view can silently change hit area, feedback area, measurement (flex-basis), or parent layout behavior.625 - Example: `paddingHorizontal` on `containerStyle` of `BankXAnimatedPressable` vs inner `BankXView` — padding moves out of the pressable feedback boundary.626627 **Conditional style names hide behavior**628 - Names like `whenLogoStyle` must describe the actual effect, not the triggering condition.629 - If the style value is `alignItems: 'center'`, review it as row alignment, not "logo styling".630 - Flag names that make a layout invariant look like a visual detail.631632 **Extracted base component leaks parent assumptions**633 - `flex: 1`, `alignSelf: 'stretch'`, absolute sizing, or margins inside a reusable base component are red flags.634 - Base components should expose layout props (via `style`) or keep parent-owned layout in the wrapper.635 - If `flex: 1` is added only for width fill, verify it won't cause height expansion when reused inside a column parent with bounded height.636637 **Intent, not just same values**638 - If `MY_BANK` and logo-based accounts intentionally align differently, the reason should be obvious from naming or comments.639 - If not, ask for clarification or suggest explicit named styles.640 - Review output guidance:641 - If behavior likely still works but intent/reuse risk is unclear, report as 🔵 Trivial or 🟡 Minor.642 - Do not say "layout equivalent" until style ownership and reusable-boundary effects are verified.643644## Architecture review checks (run when PR adds hooks, services, or screens)645646When a PR introduces new modules, hooks, services, or screens (or significantly restructures existing ones), evaluate architecture quality. Skip for trivial single-file changes.6476481. **Composition & responsibility**649 - Each hook/module should have a single, clear responsibility.650 - Detect God-hooks or God-screens that mix data fetching, business logic, UI state, and navigation.651 - Verify separation: data hooks vs UI hooks vs orchestration hooks.652 - Check if a hook does too many things that should be split.6536542. **Data flow clarity**655 - Trace how data moves: props → hook → state → render. Identify implicit coupling.656 - Evaluate ref vs state choices: refs for values that don't trigger re-render, state for values the UI depends on.657 - Flag unnecessary indirection (getter callbacks wrapping refs, redundant wrappers).658 - Check prop drilling depth — suggest context or composition when drilling exceeds 3 levels.6596603. **Error handling strategy**661 - Is error handling centralized (single error handler) or distributed (per-callsite try-catch)?662 - Verify failure code → UX mapping consistency: same error code should produce same user experience.663 - Detect missing error paths: what happens when an API call fails but no handler catches that specific failure code?664 - Check error handler completeness: does the switch/if-chain cover all known failure codes?6656664. **Interface design**667 - Function/hook parameters: prefer named params (object destructuring) over positional args when >2 params.668 - Naming: domain-specific names over generic (`useCardlessWithdrawalSubmit` > `useSubmit`).669 - Return types: explicit and narrow, not `any` or overly broad unions.670 - API surface: does the module expose only what consumers need?6716725. **Navigation patterns**673 - Push vs replace: replace for correction flows (edit → confirm), push for new destinations.674 - Screen lifecycle: does the screen clean up state on unmount? Does going back produce stale state?675 - Deep link readiness: can the screen be entered directly with params, or does it depend on prior screen state?6766776. **Cross-cutting consistency**678 - i18n: detect hardcoded user-facing strings (English or any language) that should use translation keys.679 - DI patterns: services accessed via `dependencyContainer.get()` with proper TYPES, not direct imports of implementations.680 - Design system: raw RN primitives (`View`, `Text`) instead of design system components.681 - Consistent patterns: does the new code follow the same patterns as neighboring modules?682683Architecture findings default to 🔵 Trivial or 🟡 Minor severity.684Exception: data flow bugs or missing error handling gaps that cause user-facing issues → 🟠 Major.685686## Security checks — OWASP-based (always run)687688Apply to every PR. Weight higher for payment, authentication, data storage, and API integration changes.689690Based on OWASP Mobile Top 10 and OWASP Web Top 10:6916921. **Insecure Data Storage (OWASP M2)**693 - Detect sensitive data (account numbers, tokens, PII, credentials) stored in plain-text local storage.694 - MMKV, AsyncStorage, UserDefaults, SharedPreferences without encryption → flag.695 - Sensitive data should use Keychain (iOS) / Keystore (Android) / SecureEnclave.696 - Check: is the stored data truly non-sensitive (locale, theme) or PII (account number, national ID)?6976982. **Insecure Authentication & Session (OWASP M4)**699 - Token/session handling: verify expiration checks, refresh logic, secure storage.700 - Hardcoded credentials, API keys, or secrets in source code.701 - Re-authentication requirements for sensitive operations (e.g., changing withdrawal limits).7027033. **Insufficient Input Validation (OWASP A03/M7)**704 - User input sanitization before API calls or local processing.705 - Amount/quantity boundary validation: negative values, overflow, zero, extreme values.706 - Format validation: regex-based inputs without ReDoS protection.7077084. **Sensitive Data Exposure (OWASP A02)**709 - Logging sensitive data (account numbers, tokens, passwords) via `console.log` or error reporting.710 - Error messages exposing internal details (stack traces, server paths, SQL queries) to users.711 - Sensitive data in navigation params that may appear in navigation state dumps.7127135. **Double Submission / Idempotency (Payment Flows)**714 - Payment, transfer, and withdrawal flows MUST have double-submission protection.715 - Check for: loading state during API call, CTA disable during submission, idempotency keys.716 - Missing protection in financial flows → 🔴 Critical.7177186. **Broken Access Control (OWASP A01)**719 - Client-side-only authorization checks without server verification.720 - UI hiding features based on role but still allowing API calls.721 - Navigation guards that can be bypassed by deep links.722723Security severity guide:724- 🔴 Critical: tokens/credentials in plain storage, hardcoded secrets, double submission in payment flows725- 🟠 Major: PII in plain local storage, missing input validation on financial amounts, sensitive data in logs726- 🟡 Minor: debug logging with non-critical data, client-side validation gaps backed by server validation727728## Thermo-nuclear maintainability checks (always run via ensemble pass)729730Load and apply `thermo-nuclear731732…(truncated)