zereight-review
Prioritize correctness and risk over style nitpicks. Default tone: concise, direct, actionable.
Navigation PR rule (non-negotiable): No navigation/back-stack finding
without symbol + production caller(s) + path tag + terminal step (hop vs
push/replace/navigateToDestination). See
references/navigation-review-gate.md.
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.mdcodegraph-review-routingwhen CodeGraph MCP is available or the review needs impact/call-chain contextcode-reviewcode-review-expertcode-revieweragent-skills:code-review-and-qualityagent-skills:using-agent-skillsthermo-nuclear-code-quality-reviewponytail-review(/Users/tao.exe/.cursor/skills/ponytail-review/SKILL.md)review-animations(/Users/tao.exe/.claude/skills/review-animations/SKILL.md+STANDARDS.md)references/flow-ownership-review.md(this skill — screen role, data owner, RN preload vs upstream prepare)references/async-effect-cancellation.md(this skill — generation token vs boolean for async effect cleanup)references/direction-alternative-gate.md(this skill — symptom-fix vs reorder vs delete-a-path; 1-line PRs in scope)references/navigation-review-gate.md(this skill — caller context, hop vs terminal nav diff, path tags, scenario matrix, author observation, echo dedup)references/test-review-gate.md(this skill — test necessity, duplication/placement, slop, axis-linked gaps; RNTL lens when RN component tests)references/problem-map-output.md(this skill — 문제 지도 final-output template: 어디/뭐/언제/유저영향/우선순위)
Required subagent review passes:
| Subagent pass | Builtin agent | Model (required) | Required basis | Review focus |
|---|---|---|---|---|
| Baseline full-diff reviewer | reviewer |
session (inherit) |
code-review |
finding-first output, severity, full diff coverage, comment-worthy / no comment |
| Regression and contract reviewer | reviewer |
session (inherit) |
code-review-expert + references/navigation-review-gate.md when nav scope |
behavioral regressions, API/prop contracts, hidden state and edge-case risk; per-caller stack findings with path tags — no whole-PR nav broadcast |
| File coverage reviewer | worker |
session (inherit) |
code-reviewer |
every changed file and hunk, missing tests, maintainability risks |
| Quality gate reviewer | worker |
session (inherit) |
agent-skills:code-review-and-quality |
correctness, reliability, maintainability, security, test quality |
| Thermo-nuclear maintainability reviewer | reviewer |
session (inherit) |
thermo-nuclear-code-quality-review |
code judo / structural simplification, 1k-line boundary, spaghetti branching, abstraction quality, layer boundaries |
| Flow ownership & screen-role reviewer | reviewer |
session (inherit) |
references/flow-ownership-review.md + repo data layering (CLAUDE.md) |
data owner vs orchestration owner; upstream prepare vs target-owned fetch; navigation.preload; nav-param growth; requirement-change blast radius; loading UI on async gap |
| Ponytail simplicity reviewer | reviewer |
session (inherit) |
ponytail-review + references/direction-alternative-gate.md |
yagni, duplicate orchestration, dual hook paths, shrink/delete, sibling-path grep on target-swap — correctness/security out of scope |
| Motion craft reviewer | reviewer |
session (inherit) |
review-animations + STANDARDS.md |
motion-only hunks; Ten Non-Negotiable Standards; Before/After/Why table + Block/Approve verdict; RN map transform/opacity=spring interruptibility=GPU; not general logic |
| Test quality reviewer | worker |
session (inherit) |
references/test-review-gate.md + consolidate-test-suites + testing-anti-patterns + test-writing (+ zereight-react-native-testing when RN component tests) |
test-only hunks; necessity (one invariant per test), duplication/placement (one owning layer), slop (mock-behavior, prod pollution, overspec), axis-linked gaps; never 🟠 for missing tests alone |
| Agent orchestration reviewer | delegate |
session (inherit) |
agent-skills:using-agent-skills |
whether the work was split correctly and whether any review lens is missing (thermo-nuclear, flow ownership, ponytail, motion craft, React/RN, test quality) |
| React/RN specialist reviewer | reviewer |
session (inherit) |
zereight-react-native-optimizer + react-doctor JSON + references/navigation-review-gate.md when nav scope |
effect/render/list/animation/native perf regressions; Skia GPU readback loops (makeImageSnapshot + readPixels in rAF/effect); reconcile react-doctor diagnostics with diff evidence; nav findings split by caller/path |
| Zereight coordinator | (parent) | session (parent) | this skill + references/direction-alternative-gate.md + references/navigation-review-gate.md when nav scope |
three-dot diff, RED-team, verification, A/B/C direction table, caller/scenario gates, author observation reconcile, echo dedup, final synthesis |
Flow ownership pass rule: Spawn when the PR changes any navigable screen,
navigator, route params, or multi-step handoff (*Screen, *-screen.tsx,
*navigator*, navigation-type.ts, guide→detail flows). Mark
skipped (not a screen/flow PR) when the diff is assets/locales/tests-only or
has no navigation/screen boundary change.
Ponytail pass rule: Spawn when the diff has substantial logic in
*.ts / *.tsx (same scope as react-doctor). Skip for assets/locales/tests-only.
Do not promote ponytail delete/yagni to 🟠+ without user-facing risk evidence.
1-line target-swap is in scope (CLIENTS.A→B, mock↔real, dual upsert).
Do not accept Lean already. Ship until the pass greps the sibling
identifier's production callers. Inject references/direction-alternative-gate.md
into the ponytail prompt.
React/RN pass rule: Spawn when the PR changes any *.ts / *.tsx outside
**/*.test.*, **/__snapshots__/**, **/locales/** only. If the PR is
assets/locales/tests-only, mark the pass skipped (not React/RN logic PR) in
검증 결과 — do not spawn.
Motion craft pass rule: Spawn when the three-dot diff touches motion
code in *.ts / *.tsx / *.css (exclude **/*.test.*,
**/__snapshots__/**, **/locales/** only). Treat as in scope when any
changed hunk matches one or more:
react-native-reanimated,useAnimatedStyle,useAnimatedReaction,useSharedValue,withSpring,withTiming,withDecay,useDerivedValue,useAnimatedScrollHandler,scheduleOnUI,scheduleOnRNin animation paths@gorhom/bottom-sheetanimation config,footerComponent, attached footer / sheet open-close positioning- Reanimated layout/entering/exiting,
@shopify/react-native-skiacanvas motion (craft only — GPU readback loops stay with React/RN pass) - CSS/JS
transition,@keyframes,animation:, Framer Motion / GSAP usage - Scroll-driven UI motion (opacity/transform/gradient toggles tied to scroll), modal/drawer/toast open-close springs
Mark skipped (not a motion PR) when the diff is assets/locales/tests-only or
has no motion hunks after grep. Do not use motion pass for pure API/types/
business-logic refactors with zero animation surface.
Motion vs React/RN split: React/RN pass owns Reanimated correctness, list perf, effect anti-patterns, and Skia GPU readback. Motion craft pass owns feel (justified motion, frequency, easing/duration, interruptibility, physicality, reduced-motion, cohesion) and outputs the skill's Block/Approve verdict. Overlap on scroll→setState: RN pass = perf/thread; motion pass = instant toggle vs fade, cohesion.
Test pass rule: Spawn when the three-dot diff touches test files
(**/*.test.*, **/__tests__/**, **/__snapshots__/**, test-dir
helpers/fixtures). Mark skipped (no test hunks) otherwise — a logic PR
with zero test changes does not spawn this pass; file coverage keeps a
one-line "missing tests" note. Inject references/test-review-gate.md
into the test prompt. Do not promote slop or gaps to 🟠+ without a proven
user-facing defect in the production diff; missing tests alone never reach 🟠.
Ensemble model policy — MANDATORY
Zereight review subagents always use the current session (parent) model.
Do not hard-pin composer-2.5. Do not skip passes with
skipped (model unavailable — composer-2.5 not exposed).
Override only when the user explicitly names a different model in the same turn (e.g. “composer로 리뷰”, “fast로”).
Canonical model id (default = session):
- Cursor
Task/cursor_worker:inherit(parent session model) - Pi
subagent: same model id as the parent session, or omitmodelso the runtime inherits the parent (prefer explicit parent id when the tool requiresmodel) - Coordinator (parent synthesis): current session model (no switch)
| Model | Use for |
|---|---|
session / inherit |
All ensemble passes (reviewer, worker, delegate) and coordinator synthesis |
Runtime mapping — session model is non-negotiable
Every spawn must follow the parent session model. Do not pin a different Composer tier, Grok, Claude, or fast variant unless the user asked for it in this turn.
| Runtime | Required model on spawn |
Forbidden (unless user asked this turn) |
|---|---|---|
Cursor Task / cursor_worker |
inherit |
Pinning composer-2.5, composer-2.5-fast, or another slug instead of session |
Pi subagent |
parent session model id (or omit to inherit) | Pinning a different provider/tier than the parent |
| Coordinator (parent synthesis) | Same session as the invoking turn | Switching models mid-review without user request |
PROCESS VIOLATION: skipping ensemble passes because composer-2.5 is not
on the runtime whitelist, or refusing to spawn when inherit / parent model
is available.
If a pinned override the user requested is rejected (whitelist / schema):
fall back to session inherit / parent model and note it in 검증 결과
(e.g. requested composer-2.5 → fell back to inherit). Never skip the whole
ensemble solely for model-id mismatch.
Spawn checklist (every pass):
- Default: Cursor Task
model: "inherit"; Pi = parent session model. - Do not skip for missing
composer-2.5. - Only pass a non-
inheritslug when the user named that model this turn. - Log actual models in
검증 결과(e.g.reviewer ×4 (inherit / <parent>)).
No model cascade on quota errors: Do not configure or use
fallbackModels to hop providers on failure. On 429, rate-limit, or quota
failure for a subagent spawn, skip that pass — do not retry the same pass
on another model. Continue synthesis from completed passes and note which axes
were skipped.
User-level overrides may live in ~/.pi/agent/settings.json under
subagents.agentOverrides. Still prefer session/inherit on every spawn so
review passes match the model the user is already talking to.
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 session model
(
inherit/ parent) from the table above. - Every subagent must follow the repo
AGENTS.mdand global Codex instructions in addition to its review skill. - Do not return the final review until every required pass has either completed, is explicitly skipped with a logged reason (429, not RN scope, etc.), or the user approved single-pass fallback per Ensemble gate — MANDATORY below.
- PROCESS VIOLATION: delivering a final review without spawning the full
ensemble when subagent spawning is available (Pi
subagent, CursorTask,cursor_worker) and the user did not explicitly approve single-pass fallback. - All review subagents must use Pi builtin agents (
reviewer,worker,delegate) with session/inheritmodel. On Pi, if omittingmodelwould default the builtinworkerto Claude while the parent is not Claude, pass the parent model id explicitly. - Do not route review passes through a different provider than the parent session unless the user explicitly requests that provider this turn.
- If a subagent fails with provider/model/quota errors (including 429),
do not retry on another model and do not use
fallbackModels. Mark that pass as skipped, record the error briefly, and continue synthesis from completed passes — do not block the final review.
Parallel spawn example (pi-subagents / subagent tool — parent session model):
{
"tasks": [
{
"agent": "reviewer",
"task": "Baseline full-diff review. Skill: code-review. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "Regression and contract review. Skill: code-review-expert. Use parent session model. PR: ..."
},
{
"agent": "worker",
"task": "File coverage review. Skill: code-reviewer. Use parent session model. PR: ..."
},
{
"agent": "worker",
"task": "Quality gate review. Skill: code-review-and-quality. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "Thermo-nuclear maintainability review. Skill: thermo-nuclear-code-quality-review + zereight-review references/direction-alternative-gate.md. Dual-path 1-line workarounds: prefer reorder or delete unused client, not extract dual-write helper. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "Flow ownership & screen-role review. Read references/flow-ownership-review.md in zereight-review skill. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "Ponytail simplicity review. Skill: ponytail-review + zereight-review references/direction-alternative-gate.md. On target-swap / dual-client hunks, grep sibling callers before Lean already. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "Motion craft review. Skill: review-animations + STANDARDS.md (/Users/tao.exe/.claude/skills/review-animations/). Motion hunks only. Output Part 1 Before/After/Why table + Part 2 Block/Approve. Use parent session model. PR: ..."
},
{
"agent": "reviewer",
"task": "React/RN specialist review. Skill: zereight-react-native-optimizer. Include react-doctor JSON. Use parent session model. PR: ..."
},
{
"agent": "worker",
"task": "Test quality review. Read references/test-review-gate.md in zereight-review skill. Test hunks only: necessity, duplication/placement, slop, gaps. Use parent session model. PR: ..."
}
],
"concurrency": 10
}
Then spawn orchestration separately:
{
"agent": "delegate",
"task": "Orchestration review: verify all ensemble axes were covered including direction-alternative A/B/C table. Use parent session model. ..."
}
(If the Pi tool requires an explicit model, set it to the same id as the
parent session, not a hard-coded Composer slug.)
Parallel spawn example (Cursor Task tool — session inherit):
{
"subagent_type": "generalPurpose",
"model": "inherit",
"description": "Baseline full-diff review",
"prompt": "Skill: code-review. Use the parent session model (inherit). PR: ..."
}
Repeat for each ensemble pass (baseline, regression, file coverage, quality,
thermo-nuclear, flow ownership, ponytail, motion craft, React/RN, test quality)
with model: "inherit" on every Task call. Spawn orchestration delegate
after worker/reviewer passes. Never skip the ensemble because composer-2.5
is missing from the whitelist.
Final synthesis must list models used, e.g.
reviewer ×7 (inherit / <parent>), worker ×3 (inherit / <parent>), delegate (inherit / <parent>).
If any pass ran on a different model than the session without a same-turn user
request, add PROCESS VIOLATION: <pass> used <actual-model> (expected inherit/session).
Ensemble gate — MANDATORY
Zereight-review always runs the full ensemble before synthesis. Treat single-pass review as an exception, not the default.
Required execution order (after PR Identity Gate succeeds):
- PR Axis Gate (A/B/C) — record in
검증 결과before findings - react-doctor preflight (React/RN PRs — see below)
- rnsec preflight (
rnsecCLI for React Native security scope) - SonarLint preflight (
sonarlint-ls-clilocal scan, diff-scoped — no auth) - fuck-u-code preflight (
fuck-u-codeCLI + boundedanalyze) - Motion scope gate — grep diff for motion triggers (see Motion craft pass
rule). Record in
검증 결과asmotion scope: yes — <triggers>ormotion scope: no. No CLI; scope only decides whether to spawn motion pass. - Test scope gate — grep diff for test files (
**/*.test.*,**/__tests__/**,**/__snapshots__/**; see Test pass rule). Record in검증 결과astest scope: yes — <files>ortest scope: no. No CLI; scope only decides whether to spawn the test pass. - Direction Alternative Gate — load
references/direction-alternative-gate.md. On logic PRs, draft A (PR) / B (reorder) / C (delete a path) before trusting ensemble Approve. Grep sibling identifiers. Read existing PR comments as competing hypotheses, not as things to refute. Record the table in검증 결과. 1-line / single-file does not skip this gate. - Navigation & caller-context gates (when nav scope — see
references/navigation-review-gate.md):- Caller Context Gate — grep production callers per changed nav symbol; fill caller table before any 🟠 navigation finding.
- Navigation Diff Gate — separate hop vs terminal step
(
push/replace/navigateToDestination); never compare hopnavigatewith terminalpushon a different target. - Path tags — tag findings (
resume-from-stem,in-flow-continuous,post-fr-success, …); record in검증 결과. - Scenario Matrix Gate — before 🟠 stack/back findings; UNVERIFIED → max 🟡.
Skip only when zero navigation hunks; record
navigation gate: skipped.
- Spawn all ensemble passes in parallel (or sequential if runtime limits concurrency)
- Spawn orchestration
delegatepass after worker/reviewer passes complete - Coordinator synthesis +
검증 결과(re-check Axis Gate, Direction Alternative Gate, caller/scenario gates, author observations, echo dedup before Approve; do not promote “all passes agree” without per-path evidence)
Subagent spawning counts as available when any of these exist in the runtime:
Pi subagent tool, Cursor Task tool, cursor_worker, or equivalent multi-agent spawn.
Single-pass fallback — DISALLOWED by default. Use only when all of:
- Subagent spawning is unavailable in the current runtime (none of the above).
- User explicitly approved fallback in the same or immediately prior message:
single pass,fallback,앙상블 스킵,서브에이전트 없이. - You record in
검증 결과:ensemble skipped (user-approved single-pass fallback).
When single-pass fallback is active, still:
- Load all reviewer instruction sources sequentially (including
thermo-nuclear-code-quality-review,references/flow-ownership-review.md,ponytail-review,review-animations+STANDARDS.mdwhen motion scope,zereight-react-native-optimizerwhen React/RN scope,references/test-review-gate.mdwhen test scope, andreferences/direction-alternative-gate.mdon logic PRs,references/navigation-review-gate.mdwhen nav scope). - Cover every ensemble axis in one pass (including flow ownership, ponytail, motion craft when in scope, test quality when in scope, and the Direction Alternative A/B/C table).
- Run react-doctor, rnsec, SonarLint, and fuck-u-code prefights when applicable.
If subagent spawning IS available: spawn every required pass. Partial completion is allowed only per Ensemble model policy (429/quota → skip that pass, note in synthesis). Completing the review from one coordinator pass alone = PROCESS VIOLATION.
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.
- Ensemble agreement ≠ evidence. N subagents repeating the same claim only proves a shared premise. If that premise is “base branch is correct” on an axis-B PR, discard or demote until API/PRD/GIF/spec confirms it. Coordinator must re-check the PR Axis Gate before promoting any 🟠+.
- 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.
Tool transport — mcporter for MCP, CLI scanners (MANDATORY)
Use the right transport; do not route every tool through MCP.
| Need | Invocation |
|---|---|
| Bitbucket/Jira/Confluence/internal MCP tools | Shell mcporter call <server>.<tool> ... |
| MCP server inventory/schema | Shell mcporter list / mcporter list <server> --schema |
| fuck-u-code static analysis | Shell fuck-u-code analyze ... from global eff-u-code npm package |
| React Native security scan | Shell rnsec scan ... |
| SonarLint static analysis | Shell sonarlint-ls-cli (scan.sh analyze --files <PR-changed-files>) — local SLOOP backend, no server/auth/token; not SonarQube CLI (sonar) or sonar-scanner. Scope: .ts/.tsx/.js/.jsx/.py/.java only — Kotlin/Swift/Objective-C have no bundled analyzer (verified: silent zero findings, not an error) |
For MCP-backed tools, do not trust Cursor/Codex native MCP panel lists as
source of truth; use mcporter from shell.
For fuck-u-code, do not use MCP at all. Never call mcp_call_tool,
mcporter list fuck-u-code, or mcporter call fuck-u-code.*. The expected
binary after npm install -g eff-u-code is fuck-u-code; verify with:
command -v fuck-u-code
fuck-u-code --version
Unknown MCP server 'fuck-u-code' only means no MCP server is configured; it is
not a blocker. Use the CLI instead.
State fuck-u-code preflight run (CLI) in the final review when the CLI
analysis runs. State fuck-u-code preflight skipped (CLI unavailable — <reason>)
only when the fuck-u-code binary is missing or the CLI command fails.
For rnsec, use the CLI only. Verify with:
command -v rnsec
rnsec --version
State rnsec preflight run (CLI) when the scan runs. State
rnsec preflight skipped (CLI unavailable — <reason>) only when the binary
is missing or the CLI command fails.
For SonarLint, use sonarlint-ls-cli (local SLOOP backend via
sonarlint-language-server, no SonarQube/SonarCloud server, no token, no
project key). Verify prerequisites:
command -v curl
command -v python3
command -v git
State sonarlint preflight run (local CLI) when the diff-scoped scan runs.
State sonarlint preflight skipped (CLI unavailable — <reason>) when
curl/python3/git is missing or the scan fails after retry.
Out of default preflight (do not use):
- SonarQube CLI (
sonar) /sonar auth login/ SonarCloud project key — not needed; this preflight never leaves the machine. - Legacy
sonar-scanner— requires separate install +sonar-project.properties. - Sonar MCP — Cursor/IDE integration only, not shell preflight.
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, preferrtk grep/rtk gitfor searched or git commands, and keep direct file reads narrowly bounded when reading required instruction or skill files. - If the nearest repo
AGENTS.mdis 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. - MANDATORY: Run unnecessary-effect preflight for Effect PRs BEFORE ensemble
synthesis. Detect scope: any added/touched
useEffect/useBankXEffect/useBackgroundEffect(or repo-equivalent wrappers) in*.ts/*.tsx, excluding**/*.test.*,**/__snapshots__/**,**/locales/**,**/*.stories.*. Followreferences/unnecessary-effect-preflight.md(mapped harness run + fix / keep+justify / block triage). Unjustified keeps block the lint-introduction PR. Feed counts into the React/RN ensemble pass prompt. Silence without a검증 결과row = PROCESS VIOLATION (same discipline as react-doctor silence). - MANDATORY: Run react-doctor for React/RN PRs BEFORE ensemble synthesis.
Detect React/RN scope: any changed
*.ts/*.tsxoutside**/*.test.*,**/__snapshots__/**,**/locales/**only.- If not React/RN scope (assets/locales/tests-only): state
react-doctor skipped (not a React/RN logic PR)in검증 결과and continue. - If React/RN scope, run from PR review worktree or confirm primary
workspace
HEADequals PR source commit (network required):
Run inside review worktree when primary workspace is on another branch. Wrong-branch scan → note innpx react-doctor@latest --json --no-score -y \ --diff refs/remotes/origin/<destination>검증 결과; do not cite diagnostics as PR findings. Use PR metadata destination branch. When git refs are unavailable, use--diff origin/developor the PR's known target branch. As a last resort, scan bounded parent path(s) of changed files (same parent-path rule as fuck-u-code — never full-workspace scan). - Parse JSON output; cross-check diagnostics against PR diff hunks and changed files only. Feed the JSON summary into the React/RN ensemble pass prompt.
- Retry once on network/npx/timeout failure. After two failures, state
react-doctor preflight skipped (<reason>)with exact command + error excerpt. - PROCESS VIOLATION on React/RN logic PRs if you skip react-doctor without
a
검증 결과row (same discipline as fuck-u-code silence). - Never promote react-doctor diagnostics to 🟠 Major or higher without file-content evidence from the current turn.
- If not React/RN scope (assets/locales/tests-only): state
- MANDATORY: Run rnsec for React Native security scope BEFORE ensemble
synthesis. Detect scope: any changed
*.ts/*.tsxoutside tests/locales, or RN/native/config files such aspackage*.json,app.json,app.config.*,android/**,ios/**,*.plist,*.gradle,Podfile, orAndroidManifest.xml.- If not RN security scope: state
rnsec skipped (not React Native security scope)in검증 결과and continue. - If in scope, run in the review worktree/root:
Use PR metadata destination branch. If git refs are unavailable, run once withoutrnsec scan --path "<review-worktree>" --json \ --changed-files refs/remotes/origin/<destination>--changed-filesin the review worktree and filter results to PR changed files before reporting. - Parse JSON output; report only issues touching changed files or clearly introduced by changed config. Feed the summary into the security/quality review pass prompts.
- Retry once on timeout/CLI failure. After two failures, state
rnsec preflight skipped (CLI — <reason>)with exact command + error excerpt. - Never promote rnsec diagnostics to 🟠 Major or higher without current-turn file-content/diff evidence and a concrete exploit or user-data impact.
- If not RN security scope: state
- MANDATORY: Run SonarLint local preflight (
sonarlint-ls-cli) BEFORE ensemble synthesis. Run in the review worktree only; do not scan the primary workspace. This replaces the old SonarQube CLI (sonar) preflight — fully local, no auth, no SonarCloud project key, diff-scoped only.- Availability gate (all must pass to run; otherwise skip with reason):
If any is missing: statecommand -v curl && command -v python3 && command -v gitsonarlint preflight skipped (CLI unavailable — <missing tool> not in PATH)and continue. - Diff-scoped file list — PR changed files only, supported extensions
(
.ts .tsx .js .jsx .py .java), excluding**/*.test.*,**/__snapshots__/**,**/locales/**:
Use PR metadata destination branch. If git refs are unavailable, fall back tomapfile -t SONARLINT_FILES < <(git diff --name-only --diff-filter=ACMR \ "refs/remotes/origin/<destination>...HEAD" -- '*.ts' '*.tsx' '*.js' '*.jsx' '*.py' '*.java' \ | grep -vE '\.test\.|__snapshots__|/locales/')git diff --name-only <base>...HEADwith the PR's known target branch. IfSONARLINT_FILESis empty, statesonarlint skipped (no PR-changed .ts/.tsx/.js/.jsx/.py/.java files)and continue. - Kotlin / Swift / Objective-C are NOT in scope for this preflight —
verified empirically, do not attempt to add them. The bundled
sonarlint-vscodeanalyzer set (~/.sonarlint-ls/analyzers/*.jar) has no Kotlin analyzer at all, andsonarcfamily.jar(Swift/Objective-C/C/C++) is shipped as.jar.asc— license-locked, inert without a paid Connected Mode. Feeding these files through the scanner does not error, it silently returns zero findings, which reads as false-clean and is worse than skipping. If the PR touches.kt/.kts/.swift/.m/.mm/.h, review those files manually in the ensemble passes and statesonarlint scope note (.kt/.swift/.m/.mm — no local analyzer, reviewed manually)in검증 결과; do not claim SonarLint coverage for them. - One-time upstream bugfix (idempotent, local cache only): upstream
sonarlint-ls-cli'sscan.pyhardcodeslanguageId: "python"for every file, which makes non-Python files fail asParsingError. Patch the cached copy once per machine before the first scan:SCAN_PY="$HOME/.sonarlint-ls/sonarlint-ls-cli/scan.py" if [ -f "$SCAN_PY" ] && ! grep -q LANGUAGE_ID_BY_SUFFIX "$SCAN_PY"; then python3 - "$SCAN_PY" <<'PYEOF'
- Availability gate (all must pass to run; otherwise skip with reason):
import pathlib, sys
p = pathlib.Path(sys.argv[1])
src = p.read_text()
src = src.replace(
"ERRORS = False\n",
"ERRORS = False\n\n"
"LANGUAGE_ID_BY_SUFFIX = {\n"
' ".py": "python", ".js": "javascript", ".jsx": "javascript",\n'
' ".mjs": "javascript", ".cjs": "javascript", ".ts": "typescript",\n'
' ".tsx": "typescriptreact", ".java": "java",\n'
"}\n\n"
"def get_language_id(file):\n"
' return LANGUAGE_ID_BY_SUFFIX.get(pathlib.Path(file).suffix, "python")\n',
1,
)
src = src.replace('"languageId": "python",', '"languageId": get_language_id(file),')
p.write_text(src)
PYEOF
fi
```
If ~/.sonarlint-ls/sonarlint-ls-cli/scan.py does not exist yet, the first
scan.sh invocation below bootstraps it (clone + venv); re-run this patch
check once after bootstrap, before trusting non-Python results. Java
analysis works standalone (bundled sonarjava.jar, verified with real
findings e.g. java:S2259 nullability) and logs a harmless
sonarlint/getJavaConfig Method Not Found warning — ignore it, it does not
block diagnostics.
- Run the scan (noisy style-only rules disabled by default — this repo's
prettier/eslint conventions already own semicolons/trailing commas):
SONARLINT_DISABLE_RULES="${SONARLINT_DISABLE_RULES:-typescript:S1438,typescript:S1537,javascript:S1438,javascript:S1537}" curl -s https://raw.githubusercontent.com/vincentfenet/sonarlint-ls-cli/refs/heads/master/scan.sh \ | bash -s -- analyze --disable-rules "$SONARLINT_DISABLE_RULES" --files "${SONARLINT_FILES[@]}" - Parse stdout lines (
<file>:<line>:<col> - <message> (<rule>)). Filter to lines that fall inside PR diff hunks — lines outside changed hunks are ⚪ Info (pre-existing), not PR regressions. - Treat SonarLint output as candidate discovery only. Promote to
🟠 Major or higher only with current-turn file/diff evidence (e.g. real
anyusage introducing type-safety risk, genuine high complexity in a changed function — not just the rule firing). - Retry once on timeout/bootstrap failure (first run downloads a ~200MB
sonarlint-vscodeVSIX and clones the CLI repo). After two failures, statesonarlint preflight skipped (CLI — <reason>)with exact command + error excerpt. - MANDATORY: Check fuck-u-code CLI availability BEFORE any preflight or
ensemble step. Run
command -v fuck-u-code(binary installed bynpm install -g eff-u-code). Do NOT use MCP for this gate. Do NOT callmcporter list fuck-u-code,mcporter call fuck-u-code.*, ormcp_call_tool.- If the CLI exists AND the PR has substantial logic changes (not just
locales/styles/tests/assets-only), run the bounded static analysis below
via
fuck-u-code analyze. - If the CLI is missing or fails: state
"
fuck-u-code preflight skipped (CLI unavailable — <reason>)" and continue. Do NOT block the review. - If the CLI exists but you skip analysis without a PR-scoped reason:
PROCESS VIOLATION. The preflight line must be either
fuck-u-code preflight run (CLI)orskipped (reason). Silence is not permitted.
- From the three-dot diff or PR metadata, extract the list of changed files.
Filter to
*.ts,*.tsxonly; 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
analyzethrough the CLI:fuck-u-code analyze "<common-parent-path>" \ --format json \ --top 15 \ --exclude "**/*.test.*" "**/__snapshots__/**" "**/locales/**" "dist/**" "node_modules/**" - From the JSON output, extract
files[].path,files[].score, andfiles[].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 CLI failure (timeout, unavailable, schema mismatch), skip preflight with
"
fuck-u-code preflight skipped (CLI — <reason>)" and continue. Do not retry more than once. - The
ai-reviewsubcommand is excluded from the default pipeline — it sends code to external APIs and duplicates the zereight ensemble.
- If the CLI exists AND the PR has substantial logic changes (not just
locales/styles/tests/assets-only), run the bounded static analysis below
via
- When spawning review subagents, do not combine
fork_context=truewith an explicitagent_typeif the runtime rejects that combination. Retry by spawning role-specific agents withoutfork_contextand 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/developfor 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-worthyorno 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
…(truncated)