Coding Standards
Every line you write, edit, or review must comply with these rules. They come in two sets, and you
apply common + exactly one framework on every task:
- Universal rules (
references/common/) — clean-code principles that govern the inside of every
function, class, and module, regardless of language.
- Per-framework rules (
references/<framework>/) — folder layout and framework patterns that govern
the outside: where files live and what folders mean.
All paths in this document are relative to this SKILL.md file, so they resolve wherever the skill is
installed.
The flow: bootstrap (once) → skip exclusions → pick a mode → detect framework → resolve structure →
pick execution shape → open a task list → run the branch. Steps 0–6 are that sequence; Step 7 is the
branch (7a pipeline, 7b inline).
Step 0 — Bootstrap the enforcement hooks (once per session, only if needed)
Run the fast read-only check first (single absolute-path command, no cd/&& — it matches the
pre-approved permission rule, so it won't prompt):
python3 <skill-dir>/bootstrap.py --verify
Exit 0 → hooks are wired; go to Step 1. Non-zero → run the full install and act on its output:
python3 <skill-dir>/bootstrap.py --auto-install
Wired / Updated / Install OK → tell the user to restart the session so hooks activate.
Until they do, the PreToolUse hooks are NOT active in this session (Claude Code reads
settings.json at session start), so a Write here won't be blocked. This is the unenforced-first-session
gap. Close it: for any code you write or review in this session, run the linter yourself over the touched
files as a compensating check before reporting done —
python3 <skill-dir>/hooks/review-files.py <file> … works immediately, no restart needed — and fix what
it finds. Tell the user write-time blocking starts next session; this session is covered by the manual
linter pass.
Blocking issues: → surface it verbatim and stop until the user resolves it.
cannot determine install scope → the skill is outside a .claude/skills/ tree; point at README.md
and continue without write-time blocking — the rules still apply, and review-files.py still runs as a
manual linter over what you touch.
The install self-detects project vs global scope and auto-installs the skill's required packages. Flags,
the venv/PEP-668 fallback, and the readiness breakdown live in references/bootstrap.md — read it only
if bootstrap misbehaves.
Step 1 — Skip excluded files (always)
Some files are owned by third-party tooling, not the user — editing them breaks the upgrade path or churns
generated code. A file is excluded if any of these hold:
- Its path matches a built-in default (installed deps, generated code, build output, lock files, ORM
migrations, shadcn
components/ui/**, the skill's own .coding-standards/** reports). Full list:
hooks/_exclusions.py → DEFAULT_EXCLUSIONS.
- Its first 10 lines carry a generation marker (
@generated, DO NOT EDIT, Code generated by, …).
- It matches a pattern in the project's
.coding-standards-ignore (gitignore-style, at the repo root,
seeded by bootstrap).
Check by inspection: the path against the default list, the marker in the file you're reading anyway,
the ignore file if one exists. Review and fix scope you don't filter by hand — hooks/review-files.py
skips excluded files itself, and the write-time hooks exit silently on them.
Refuse to modify an excluded file. If the user explicitly asks to edit one, warn that the file is
tool-owned and changes will be lost on regeneration, then proceed only after consent.
Step 2 — Pick a mode (only on contextless activation)
Skip this if the user's message already names a task — "write X", "refactor Y", "review this PR",
"is this clean?", "what does FN-005 mean?". Those phrases are the mode; go to Step 3.
Trigger it only when the skill activated with no clear task: bare /coding-standards, "what does this
skill do?", or a message too generic to infer mode. Ask with AskUserQuestion, using the exact
mode-picker payload in references/activation.md — the labels are what the routing below matches on.
Route the answer:
- Write code that follows these rules → Write mode, full flow.
- Check existing code against these rules → ask what to check (file, folder, diff, PR). Once the user
answers, the scope is known — so build the whole-workflow task list now, before any reviewing starts
(Step 6), with resolve + record structure as item 1, and fold any extra targets the user named in as
more items.
- Show me the rules → resolve framework + structure silently, load references, present a one-screen
rule index. No structure question, no run-mode question — nothing is written.
There is no picker entry for Fix — it's triggered by phrasing ("fix the findings" / "apply the
review", or "continue the fix" / "resume the fix" to pick up a non-done milestone plan), which routes
straight to Fix mode.
Ask at most once per session; once mode is set, it stays set. Never ask when the user already named a
task.
Step 3 — Detect the framework
Look at the file you're acting on and match the signals below. Stop at the first match whose "owns file
types" includes the extension of the file you're editing. A row whose file types don't include the
current file is skipped even if its repo-level signal is present — so editing a .php file in a
Laravel + Inertia/Vue repo resolves to laravel, not vue-nuxt, and a Component.vue in the same repo
resolves to vue-nuxt. This is the rule; the "more specific" note below only breaks ties within one
language.
| Framework key |
Owns file types |
Detection signals (any of these) |
nextjs |
.ts .tsx .js .jsx |
next.config.{js,ts,mjs} at repo root or next in package.json deps or the file lives under app/ or pages/ next to that config |
react-native |
.ts .tsx .js .jsx |
expo, react-native, or @expo/* in package.json or app.json with "expo" key or metro.config.js |
nativescript |
.ts .js .xml |
nativescript.config.{js,ts} or nativescript in package.json or a .xml file paired with a .ts page |
cocos-creator |
.ts .js |
assets/ + settings/ + (library/ or temp/ in .gitignore) at repo root or cc / cocos-creator import or .scene / .prefab files |
vue-nuxt |
.vue .ts .js |
vue or nuxt in package.json or nuxt.config.{ts,js} or .vue files |
nestjs |
.ts |
@nestjs/* in package.json or *.module.ts / *.controller.ts / *.service.ts with NestJS decorator imports |
node-express |
.ts .js |
express or fastify in package.json and no NestJS |
laravel |
.php |
composer.json with laravel/framework or an artisan file at root or .php under app/ |
csharp |
.cs |
*.csproj, *.sln, *.cs files |
spring-boot |
.java .kt |
pom.xml with spring-boot-starter-* or Gradle with the Spring Boot plugin or @SpringBootApplication |
django |
.py |
manage.py + a settings module or django in pyproject.toml / requirements.txt |
fastapi |
.py |
fastapi in deps or from fastapi import FastAPI and not Django |
flask |
.py |
flask in deps or from flask import Flask and not Django/FastAPI |
go-http |
.go |
go.mod + a router (gin, echo, fiber, chi, mux) or net/http handler routing |
unsupported |
(any) |
A framework/ecosystem the skill recognizes but has no structure reference for. Web: Angular (@angular/core / angular.json), Svelte / SvelteKit (.svelte, svelte in package.json, svelte.config.*), Astro (astro dep / astro.config.* / .astro), Remix (@remix-run/*), Ember, SolidStart, Qwik. Game engines: Unity (Assets/ + ProjectSettings/), Godot (project.godot). Other ecosystems not yet covered in v5: Ruby/Rails, Rust, Swift/iOS, Flutter/Dart, Android native. … |
vanilla-js |
.ts .js |
Plain .ts / .js that fits none of the above and is not one of the recognized-unsupported frameworks (libraries, CLIs, scripts, browserless projects) |
- If two rows of the SAME language could apply (e.g. a
.ts that's both Next.js and vue-nuxt-eligible),
pick the more specific one (a .tsx in a Next.js repo is nextjs, not react-native). The file-type
gate above already separates different languages — this only breaks within-language ties.
- Monorepos pick the framework per file, not per repo — walk up from the file until a signal
matches whose file types include the file.
apps/web/... → nextjs; apps/api/... → nestjs.
- Engine/ecosystem override (checked FIRST): if the project shows a game-engine marker — Unity
(
Assets/ + ProjectSettings/) or Godot (project.godot) — route to unsupported, even though a
.cs would otherwise match csharp. The csharp row's vertical-slice web layout is wrong advice for a
Unity project, so the engine signal wins. common/ line rules still apply; structure review is declined.
- Plain libraries with no framework signal default to
vanilla-js (JS/TS) or common/ only (Python).
- Recognized but unsupported (the
unsupported row): say so and do NOT fall back to vanilla-js —
imposing vanilla-js's business-folder + barrel layout on an Angular or SvelteKit app actively fights the
framework's own conventions, which is worse than declining. Instead: apply all of common/ (it's
universal — the line-level rules and the write-time hooks still enforce on the language), keep the
project's existing layout for placement, and tell the user the skill has no structure reference for
this framework yet so structural/placement review is limited to common/structure.md (ST-*), not a
framework-specific shape. Skip the Step 4 structure question (there's no catalog to offer).
- If you can't tell, ask once — don't guess across frameworks.
Step 4 — Resolve the project structure (the outer shell)
This resolves the outer folder layout — where the top folders sit and what they're called. It decides
placement only; the inside of every folder still follows common/structure.md (business → feature →
sub-feature → unit), whichever shell is chosen. Follow what the project already uses (the framework's
scaffold, or the layout that's there); the choice is remembered in a .coding-standards-structure file
so the user is asked at most once.
Comprehend the structure once, then trust the record. When .coding-standards-structure does not
exist, comprehend the structure (build and confirm the map, references/structure-map.md) and record the
resolved layout in it. When it does exist, follow it and do not re-derive or propose restructuring
— ordinary write/review runs check code against the recorded structure, they never re-open it. Re-run
the full structure comprehension (then update the record) only when the user explicitly asks to
restructure or review the structure — "restructure this", "review the structure", "show me the structure
tree". A normal task ("add X", "review this PR", "is this clean?") is not that request.
The decision in brief:
- File exists at the framework project root → read it and follow it (a
follows: <standard> target,
or a described custom layout). No question. If the file is non-canonical — carries comments, a hooks:
block, or any rule toggle — normalise it in place (keep only the follows: line / layout: body),
write it back, and report it.
- No file, folders match a standard → use that standard's reference, and record it — write
follows: <standard> plus the full layout: tree, so later runs follow it instead of re-comprehending. No question.
- No file, custom layout → ask the user once with
AskUserQuestion (recommended structure first,
"keep current" last), then write the file recording their choice.
The file records placement only — a follows: line and/or a full layout: tree (the actual solved
structure; a project may carry both). It never carries rule toggles: every rule is always enforced,
deep-import is derived from whether a barrel exists, and the ST-008 size/folder checks run at fixed
thresholds. block-structure-file-violations.py enforces this.
Read references/structure-resolution.md before acting on case 3, a monorepo, or a non-canonical file.
It has the full mechanics: monorepo file placement (the sub-project root, not the repo root), the question
shapes, what "keep current" does and doesn't exempt, the self-heal normalisation, and the messy-project
fallback.
The resolved structure replaces references/<framework>/structure.md in the Step 7b load list, and the
pipeline passes it to Worker 1 as STRUCTURE. For "Show me the rules" / pure Q&A, resolve silently —
don't ask or write a file.
Step 5 — Pick the execution shape (orchestrator pipeline vs inline)
Two shapes for Write and Review. Resolve Step 4 first — structure is always the first question, run-mode
the second.
| Trigger |
Shape |
| Single-file edit (≤30 lines), single-function refactor, or rule Q&A |
Inline — you do it yourself. Steps 6 → 7b. |
2+ files, a new feature, a diff/PR review, --thorough, or the /coding-standards command |
Orchestrator pipeline — you dispatch workers. Steps 6 → 7a. |
Agent tool unavailable in this host (Cursor, Codex, OpenCode) |
Inline regardless of scope — flag it in the routing line. |
| Apply review findings ("fix the findings", "continue the fix" / "resume the fix") |
Orchestrator pipeline, MODE: fix, always. No run-mode question. |
The choice is made one of two ways:
A) Invoked via /coding-standards or the Step 2 picker, and Agent is available → ask the run-mode
question with the exact payload in references/activation.md. "Multiple agents" → pipeline (7a);
"Single agent" → inline (7b). Ask at most once per session; reuse the answer afterward.
B) Plain message (no command) → decide from the table.
Announce the routing — one line, before the substantive work
Once mode, framework, structure, and shape are resolved, emit a single line so the user sees the route:
coding-standards: framework=nextjs · structure=route-colocated (matched) · shape=pipeline (2+ files)
Name the shape's trigger (the table row, or "user choice"), and mark how structure resolved — (matched),
(file), or (asked). Pure rule Q&A skips the line; there's nothing to route.
Step 6 — Track the run with a task list
On any real work — writing, editing, refactoring, or reviewing — open the task list up front, the moment
the scope is known: for the Step 2 picker path, right after the "what to review / write" answer; for a
plain message ("review this PR"), as soon as you've identified the files. Open it before Steps 3–4, so
framework detection and resolve + record structure land on the list as the first tracked items, not
pre-work that runs before any list exists. The list is what makes the standards visible — the user sees
each stage applied instead of trusting it happened. Use the host's task-list tool (TodoWrite,
TaskCreate/TaskUpdate, …); skip the list only if the host has none, and skip it for pure rule Q&A —
there's no multi-step work to track.
Build the whole workflow at once, then extend it with any extra targets the user named. Track the work
the user cares about (fold in real file/feature names), keep exactly one item in_progress, and complete
it before starting the next. A typical review list: resolve + record structure → detect framework →
load rules → review → run hooks → write report. A typical write list: resolve + record structure →
detect framework → read existing code → load rules → draft → rewrite the draft → sweep the rules → write
the files. The first item, resolve + record structure, may be
marked completed only when .coding-standards-structure exists at the resolved project root —
resolved one of three ways: matched a standard, asked-and-recorded, or a skip-reason logged (recognized-
unsupported framework, or below the scope threshold). Having run a structure-comprehension agent is not
completion; the file on disk is. The pipeline and Fix shapes add their worker/ledger stages — see
orchestrator-pipeline.md. A milestone-driven fix adds one item per milestone at plan approval — a display
mirror only; the plan file on disk stays the source of truth.
Step 7a — Pipeline branch: orchestrate the workers
You (the main agent) become the orchestrator: you coordinate three sequential workers and do the final
Write yourself, so the hooks fire exactly once on the complete code. Read
references/orchestrator-pipeline.md and follow it — that's the full protocol (worker roster,
Write/Review/Fix pipeline shapes, dispatch loop, validation, retry/fallback, summary).
Invariants, true even before you open the reference:
- Comprehend before you check. Above the scope threshold and when the structure isn't already
recorded in
.coding-standards-structure (or the user explicitly asked to restructure / review the
structure — see Step 4), build and confirm the structure map (references/structure-map.md) before
dispatching Worker 1; pass it as STRUCTURE_MAP. When a record already exists and no such request was
made, skip the map and pass the recorded structure as STRUCTURE — don't re-open the layout.
Cross-feature structure (duplication, mislabeled nesting, split features, themed-cluster promotion) is
found by diffing the real tree against the map — a per-file worker cannot see it.
- Workers never call
Write/Edit. They emit code/findings as JSON; only you write to disk.
- Sequential, not parallel. Worker 1 (Structure) → Worker 2 (Quality) → Worker 3 (Failure); each one's
output is the next one's input.
- No retries past 2. Twice-failed validation or unparseable JSON → fall back to inline.
Step 7b — Inline branch: load the references, then apply
Before writing or reviewing any code, read these fully — once per session, not once per task:
- All eight
common/ files (always): functions.md, naming.md, objects-and-data.md,
formatting.md, comments.md, error-handling.md, code-principles.md, structure.md.
- The resolved structure (from Step 4) — a
structures/<name>.md variant or
references/<framework>/structure.md.
Read them fully because the judgement lives in the worked examples, not the rule names. Recalling "keep
functions small" misapplies FN-001; the examples show where the line actually sits.
Then apply each rule at its scope: common governs the inside of code; the resolved structure governs the
outside (file placement, folder names, public APIs). When the two seem to conflict, that scope split is
the answer — a framework entry file is both thin (the framework rule) and the function it exports is
short (the common rule).
Modes: Write, Review, Fix
Write
Writing gets the same rule-by-rule walk as reviewing. Most common/ rules have no write-time hook, so a
rule you don't name is a rule you don't apply. Seed these steps into the Step 6 task list. Step 1 runs once
per area, not once per file.
- Read the existing code. Open the 2-3 files closest to where the new code lands: those in the
destination folder, else the nearest comparable feature in the same language. Note the project's verb
for each recurring operation, what an entry file exports, how a feature divides into units, which domain
error types exist, how imports are ordered. A rule beats the project's convention; the project's
convention beats the default you would otherwise reach for. An existing file that breaks a rule stays
as it is; a write task does not reorganize what is already there. In a genuinely new area you set the
vocabulary, so keep it consistent across every file you write.
- Load the references (Step 7b): all eight
common/ files plus the resolved structure.
- Draft it. Get the behavior right first. A messy first draft is permitted (FN-012).
- Rewrite the draft. Reread each file as its first reader: split the function you excused at 25 lines,
replace the name you settled for, delete the parameter nobody needs.
- Sweep the rules one at a time. Walk
common/ against what you wrote and file each rule under
applied, already met, or not applicable with a reason. Re-read the reference for any rule you had not
considered before this step. Report the buckets in your reply, not in the file.
- Fix what you find now. A violation ships fixed or does not ship. Never pair one with a
TODO.
Write no comments by default (comments.md). Say it in the names and the shape of the code. A sentence
earns a place in the file only when it carries what the code cannot — a constraint, a rationale, an external
reference, a sharp edge. Never narrate the code, never narrate your edit, and never leave the conversation
behind in the file: no as requested, no I think, no we could also, no untracked TODO, no emoji, no
Note: preamble. If a thought belongs in the reply to the user, put it there and leave the file clean.
A separate model judges the comments a turn wrote before that turn can end (hooks/judge-comments.py),
so a comment that doesn't earn its place comes back as a fix to apply, not a note to ignore. Write it
right the first time and the judge stays silent — it costs one short model call per turn that touched
code, and none at all on a turn whose files gained no comments.
Always author and modify code through the Write / Edit / MultiEdit tools — never by shell
redirection (> file, >>, tee, sed -i, cat <<EOF > file). The enforcement hooks fire only on
Write/Edit/MultiEdit; a file written through the shell silently bypasses every one of them. This is a real
hole in the enforcement perimeter, and the only thing closing it for shell writes is this instruction — so
honor it. If some tool genuinely must generate a source file outside the Write path, run
python3 <skill-dir>/hooks/review-files.py <file> over the result and fix what it reports.
Review
Walk the rules systematically — don't freelance. Seed the Step 6 list first, the moment you know what's
in scope and before you start reviewing; the numbered steps map onto it, and step 0 is the list's
first item.
- Resolve + record the structure — the first task item, done only when
.coding-standards-structure
exists. Above the scope threshold, and only when it isn't already recorded: if
.coding-standards-structure already records the structure and the user didn't ask to restructure /
review the structure, skip this — follow the recorded structure and review code against it; don't
re-open the layout. Otherwise build the structure map (references/structure-map.md) over the tree,
confirm it with the user once, persist it to .coding-standards/structure-map.md, and record the
resolved layout in .coding-standards-structure. Hand the map to the structure worker as
STRUCTURE_MAP: cross-feature findings (duplication, misnested peers, split features, themed-cluster
promotion) are diffs against it, which a per-file pass can't see. Skipped below the threshold — say that
cross-feature structural checks were not run.
- Scope + resolve structure. List each file in the diff; detect its framework (Step 3) and resolve
structure (Step 4).
- Load references. Every
common/ file, plus the resolved structure for each framework in the diff.
- Judgement pass — the rules regex/AST can't catch (FN-001 length nuance, FN-009 CQS, OD-003
Demeter, EH-002 boundaries, the CM-* comment-prose rules, the
structure.md rules). Per rule, report PASS, a finding as
file.tsx:42 — <rule> — <what's wrong>, or SKIPPED — <why it doesn't apply>.
- Run the hooks as a linter (deterministic pass, LAST — don't skip). The
block-*.py hooks only fire
on Write/Edit, so a review must invoke them explicitly:python3 <skill-dir>/hooks/review-files.py <file> [<file> ...]
# diff: git diff --name-only | python3 <skill-dir>/hooks/review-files.py --stdin
# pipeline: add --json and parse per file
It applies the same write-time contract (any, Hungarian, 4+/5+ args, swallowed errors, junk-drawer
paths, deep imports, the TS/Python AST checks) and skips excluded files. review-files.py self-selects
an interpreter that can load the TS/JS grammars (its bundled venv if the launching python3 lacks them)
and flags the gap loudly if none can — it never silently reports a TS file clean. Every finding it
returns is a violation to fix: the existence of the finding is deterministic and never re-litigated
(an any is an any). For the ST-008 decl-count block, the remedy is the reviewer's judgement — a
cohesive split, OR a recorded exemption (.coding-standards-ignore + reason, logged accepted) when the
file is one cohesive job the proxy miscounts. A split that creates scatter or copies a sibling's
machinery is itself an ST-008 + DP-007 violation, not a fix.
- Merge, write the report, summarize. Combine judgement + linter findings into one list, ordered by
file then rule code. There are no severity tiers — every finding is a violation to fix. A finding's
only non-fix exit is at Fix time:
accepted (the reviewer judged it is not a violation here — reason
required) or deferred (a real breach left open). At review time the call is binary: a rule breaks
(file it) or it doesn't (it's a pass, not a soft "consider"). Persist the merged result to a report file
per references/review-report.md (.coding-standards/reviews/<timestamp>.md, gitignored) and tell the
user the path — every review writes one, inline included. The report's Structure baseline: field is
mandatory and names the recorded .coding-standards-structure (or declares NOT RECORDED with a
reason) — see references/review-report.md. Above the scope threshold (defined once in
orchestrator-pipeline.md → Fix mode), trim the chat output to the shape in review-report.md; the
report file always holds everything.
- Verify the structure baseline, then never silently skip a rule. After writing the report, run
python3 <skill-dir>/hooks/check-review-report.py <report.md> (pass --root <sub-project> in a
monorepo). Exit 2 means the report asserts a structure with no .coding-standards-structure behind it
— the structure step (Step 4 / step 0) was skipped: resolve + record it and rewrite the report before
reporting done. Exit 1 is a declared skip — surface the reason. This is the back-stop for the
task-list item: the report can't read as complete while claiming a baseline that was never written. And
if you didn't check a rule, say so — a review with hidden gaps is worse than one that admits its scope.
Fix
Triggered by "fix the findings" / "apply the review" / fixes requested right after a Review — or by
"continue the fix" / "resume the fix" to pick up a non-done milestone plan. Fix mode always runs as
the orchestrator pipeline (MODE: fix) — it's inherently multi-file: it fans out one fix-agent per
file, tracked by a completeness ledger so nothing is silently half-fixed. Don't offer a "single agent"
option; if Agent is unavailable, run the documented sequential-batch fallback and say so.
Every finding ends fixed (violation removed), accepted (judged not a violation — reason required), or
deferred (real breach, not fixed — an open breach). A run with open breaches reports
done-with-open-breaches, never done, until the user resolves them — see references/fix-plan.md.
The input is the most recent .coding-standards/reviews/<ts>.md; if none exists, run Review first.
Everything else — the ledger, the per-file fan-out, the scope threshold, and the milestone-driven plan
file for big fixes (references/fix-plan.md) — lives in references/orchestrator-pipeline.md under
"Fix mode".
Finding a rule on demand
Rules are organized by the kind of question you're asking (functions, naming, objects/data, formatting,
comments, error handling, principles, structure), not by language. The full question→file index is in
references/rule-index.md — use it for "what does FN-005 mean?" lookups or when unsure which reference owns
a concern. During real work Step 7 already loads everything, so the index is just for targeted lookups.
On conflict — the simpler correct design wins
When two designs are both correct and pull apart on other principles, DP-006 (KISS) breaks the
tie: the simpler one wins, even if it mildly bends DRY or another rule. KISS is a tiebreaker, not a trump
card — it never overrides correctness, a real requirement, or SOLID. You cannot invoke it to skip a class
per variant you were handed (OD-002), swallow an error, or ship a silent fallback. Adding a pattern
(Strategy, Visitor, a fifth layer of indirection) just to satisfy a rule? Stop — the simple version is
usually right. Defending a god-file or a duplicated switch as "simple" to avoid the structure? Also stop
— that's not simpler, just smaller.
What this skill does NOT cover
- Performance tuning — use a profiler; clean code is fast enough by default.
- Security review — use a dedicated security skill (e.g.
security-review). Clean-code review catches
some bug classes but is not a security audit.
- Test design — tests follow the same clean-code rules, but TDD/BDD/mutation strategy is out of scope.
- UI/UX visual review — a separate domain (
web-design-guidelines, design-taste-frontend). These
frameworks cover code organization, not visual design.
If the user asks for any of these, say so and point them at the right tool.
1---2name: coding-standards3description: Coding standards for writing, editing, and reviewing code. Routes to language/framework-specific rules (Next.js, NestJS, Laravel, vanilla JS/TS, NativeScript, React Native/Expo, C#/.NET, Node Express/Fastify, Cocos Creator, Vue/Nuxt, Spring Boot, Django, FastAPI, Flask, Go HTTP) PLUS universal clean-code rules (functions, naming, objects/data, formatting, error handling, SOLID/KISS/DRY, universal structural rules) that apply to every language. Consult before any code change. Use when the user says "write a component", "add an endpoint", "refactor this", "review this diff/PR", or "is this clean?". Make sure to consult this skill for ANY code authoring or review task, even when the user does not explicitly ask for "standards" — every write/edit/review must comply.4license: MIT5---67# Coding Standards89Every line you write, edit, or review must comply with these rules. They come in two sets, and you10apply **common + exactly one framework** on every task:1112- **Universal rules** (`references/common/`) — clean-code principles that govern the *inside* of every13 function, class, and module, regardless of language.14- **Per-framework rules** (`references/<framework>/`) — folder layout and framework patterns that govern15 the *outside*: where files live and what folders mean.1617All paths in this document are relative to this SKILL.md file, so they resolve wherever the skill is18installed.1920The flow: **bootstrap (once) → skip exclusions → pick a mode → detect framework → resolve structure →21pick execution shape → open a task list → run the branch**. Steps 0–6 are that sequence; Step 7 is the22branch (7a pipeline, 7b inline).2324---2526## Step 0 — Bootstrap the enforcement hooks (once per session, only if needed)2728Run the fast read-only check first (single absolute-path command, no `cd`/`&&` — it matches the29pre-approved permission rule, so it won't prompt):3031```bash32python3 <skill-dir>/bootstrap.py --verify33```3435Exit 0 → hooks are wired; go to Step 1. Non-zero → run the full install and act on its output:3637```bash38python3 <skill-dir>/bootstrap.py --auto-install39```4041- `Wired` / `Updated` / `Install OK` → tell the user to **restart the session** so hooks activate.42 **Until they do, the PreToolUse hooks are NOT active in *this* session** (Claude Code reads43 `settings.json` at session start), so a Write here won't be blocked. This is the unenforced-first-session44 gap. Close it: for any code you write or review in this session, run the linter yourself over the touched45 files as a compensating check before reporting done —46 `python3 <skill-dir>/hooks/review-files.py <file> …` works immediately, no restart needed — and fix what47 it finds. Tell the user write-time blocking starts next session; this session is covered by the manual48 linter pass.49- `Blocking issues:` → surface it verbatim and **stop** until the user resolves it.50- `cannot determine install scope` → the skill is outside a `.claude/skills/` tree; point at `README.md`51 and continue without write-time blocking — the rules still apply, and `review-files.py` still runs as a52 manual linter over what you touch.5354The install self-detects project vs global scope and auto-installs the skill's required packages. Flags,55the venv/PEP-668 fallback, and the readiness breakdown live in `references/bootstrap.md` — read it only56if bootstrap misbehaves.5758---5960## Step 1 — Skip excluded files (always)6162Some files are owned by third-party tooling, not the user — editing them breaks the upgrade path or churns63generated code. A file is excluded if **any** of these hold:64651. Its path matches a built-in default (installed deps, generated code, build output, lock files, ORM66 migrations, shadcn `components/ui/**`, the skill's own `.coding-standards/**` reports). Full list:67 `hooks/_exclusions.py` → `DEFAULT_EXCLUSIONS`.682. Its first 10 lines carry a generation marker (`@generated`, `DO NOT EDIT`, `Code generated by`, …).693. It matches a pattern in the project's `.coding-standards-ignore` (gitignore-style, at the repo root,70 seeded by bootstrap).7172Check by inspection: the path against the default list, the marker in the file you're reading anyway,73the ignore file if one exists. Review and fix scope you don't filter by hand — `hooks/review-files.py`74skips excluded files itself, and the write-time hooks exit silently on them.7576Refuse to modify an excluded file. If the user explicitly asks to edit one, warn that the file is77tool-owned and changes will be lost on regeneration, then proceed only after consent.7879---8081## Step 2 — Pick a mode (only on contextless activation)8283**Skip this** if the user's message already names a task — "write X", "refactor Y", "review this PR",84"is this clean?", "what does FN-005 mean?". Those phrases *are* the mode; go to Step 3.8586**Trigger it** only when the skill activated with no clear task: bare `/coding-standards`, "what does this87skill do?", or a message too generic to infer mode. Ask with `AskUserQuestion`, using the exact88mode-picker payload in `references/activation.md` — the labels are what the routing below matches on.8990Route the answer:9192- **Write code that follows these rules** → Write mode, full flow.93- **Check existing code against these rules** → ask *what* to check (file, folder, diff, PR). Once the user94 answers, the scope is known — so **build the whole-workflow task list now, before any reviewing starts**95 (Step 6), with *resolve + record structure* as item 1, and fold any extra targets the user named in as96 more items.97- **Show me the rules** → resolve framework + structure silently, load references, present a one-screen98 rule index. No structure question, no run-mode question — nothing is written.99100There is no picker entry for **Fix** — it's triggered by phrasing ("fix the findings" / "apply the101review", or "continue the fix" / "resume the fix" to pick up a non-done milestone plan), which routes102straight to Fix mode.103104Ask at most once per session; once mode is set, it stays set. Never ask when the user already named a105task.106107---108109## Step 3 — Detect the framework110111Look at the file you're acting on and match the signals below. **Stop at the first match whose "owns file112types" includes the extension of the file you're editing.** A row whose file types don't include the113current file is skipped even if its repo-level signal is present — so editing a `.php` file in a114Laravel + Inertia/Vue repo resolves to `laravel`, not `vue-nuxt`, and a `Component.vue` in the same repo115resolves to `vue-nuxt`. This is the rule; the "more specific" note below only breaks ties *within* one116language.117118| Framework key | Owns file types | Detection signals (any of these) |119|---|---|---|120| `nextjs` | `.ts .tsx .js .jsx` | `next.config.{js,ts,mjs}` at repo root **or** `next` in `package.json` deps **or** the file lives under `app/` or `pages/` next to that config |121| `react-native` | `.ts .tsx .js .jsx` | `expo`, `react-native`, or `@expo/*` in `package.json` **or** `app.json` with `"expo"` key **or** `metro.config.js` |122| `nativescript` | `.ts .js .xml` | `nativescript.config.{js,ts}` or `nativescript` in `package.json` **or** a `.xml` file paired with a `.ts` page |123| `cocos-creator` | `.ts .js` | `assets/` + `settings/` + (`library/` or `temp/` in `.gitignore`) at repo root **or** `cc` / `cocos-creator` import **or** `.scene` / `.prefab` files |124| `vue-nuxt` | `.vue .ts .js` | `vue` or `nuxt` in `package.json` **or** `nuxt.config.{ts,js}` **or** `.vue` files |125| `nestjs` | `.ts` | `@nestjs/*` in `package.json` **or** `*.module.ts` / `*.controller.ts` / `*.service.ts` with NestJS decorator imports |126| `node-express` | `.ts .js` | `express` or `fastify` in `package.json` **and** no NestJS |127| `laravel` | `.php` | `composer.json` with `laravel/framework` **or** an `artisan` file at root **or** `.php` under `app/` |128| `csharp` | `.cs` | `*.csproj`, `*.sln`, `*.cs` files |129| `spring-boot` | `.java .kt` | `pom.xml` with `spring-boot-starter-*` **or** Gradle with the Spring Boot plugin **or** `@SpringBootApplication` |130| `django` | `.py` | `manage.py` + a settings module **or** `django` in `pyproject.toml` / `requirements.txt` |131| `fastapi` | `.py` | `fastapi` in deps **or** `from fastapi import FastAPI` **and** not Django |132| `flask` | `.py` | `flask` in deps **or** `from flask import Flask` **and** not Django/FastAPI |133| `go-http` | `.go` | `go.mod` + a router (`gin`, `echo`, `fiber`, `chi`, `mux`) or net/http handler routing |134| `unsupported` | (any) | A framework/ecosystem the skill recognizes but has **no structure reference** for. Web: Angular (`@angular/core` / `angular.json`), Svelte / SvelteKit (`.svelte`, `svelte` in `package.json`, `svelte.config.*`), Astro (`astro` dep / `astro.config.*` / `.astro`), Remix (`@remix-run/*`), Ember, SolidStart, Qwik. Game engines: Unity (`Assets/` + `ProjectSettings/`), Godot (`project.godot`). Other ecosystems not yet covered in v5: Ruby/Rails, Rust, Swift/iOS, Flutter/Dart, Android native. … |135| `vanilla-js` | `.ts .js` | Plain `.ts` / `.js` that fits none of the above **and is not one of the recognized-unsupported frameworks** (libraries, CLIs, scripts, browserless projects) |136137- **If two rows of the SAME language could apply** (e.g. a `.ts` that's both Next.js and vue-nuxt-eligible),138 pick the more specific one (a `.tsx` in a Next.js repo is `nextjs`, not `react-native`). The file-type139 gate above already separates different languages — this only breaks within-language ties.140- **Monorepos** pick the framework **per file**, not per repo — walk up from the file until a signal141 matches whose file types include the file. `apps/web/...` → `nextjs`; `apps/api/...` → `nestjs`.142- **Engine/ecosystem override (checked FIRST):** if the project shows a game-engine marker — Unity143 (`Assets/` + `ProjectSettings/`) or Godot (`project.godot`) — route to `unsupported`, even though a144 `.cs` would otherwise match `csharp`. The `csharp` row's vertical-slice web layout is wrong advice for a145 Unity project, so the engine signal wins. `common/` line rules still apply; structure review is declined.146- **Plain libraries** with no framework signal default to `vanilla-js` (JS/TS) or `common/` only (Python).147- **Recognized but unsupported** (the `unsupported` row): **say so and do NOT fall back to `vanilla-js`** —148 imposing vanilla-js's business-folder + barrel layout on an Angular or SvelteKit app actively fights the149 framework's own conventions, which is worse than declining. Instead: apply all of `common/` (it's150 universal — the line-level rules and the write-time hooks still enforce on the language), keep the151 project's **existing** layout for placement, and tell the user the skill has no structure reference for152 this framework yet so structural/placement review is limited to `common/structure.md` (ST-*), not a153 framework-specific shape. Skip the Step 4 structure question (there's no catalog to offer).154- **If you can't tell**, ask once — don't guess across frameworks.155156---157158## Step 4 — Resolve the project structure (the outer shell)159160This resolves the **outer folder layout** — where the top folders sit and what they're called. It decides161*placement* only; the inside of every folder still follows `common/structure.md` (business → feature →162sub-feature → unit), whichever shell is chosen. Follow what the project already uses (the framework's163scaffold, or the layout that's there); the choice is remembered in a `.coding-standards-structure` file164so the user is asked at most once.165166**Comprehend the structure once, then trust the record.** When `.coding-standards-structure` does **not**167exist, comprehend the structure (build and confirm the map, `references/structure-map.md`) and record the168resolved layout in it. When it **does** exist, follow it and do **not** re-derive or propose restructuring169— ordinary write/review runs check code *against* the recorded structure, they never re-open it. Re-run170the full structure comprehension (then update the record) **only** when the user explicitly asks to171restructure or review the structure — "restructure this", "review the structure", "show me the structure172tree". A normal task ("add X", "review this PR", "is this clean?") is not that request.173174The decision in brief:1751761. **File exists** at the framework project root → read it and follow it (a `follows: <standard>` target,177 or a described custom layout). No question. If the file is non-canonical — carries comments, a `hooks:`178 block, or any rule toggle — **normalise it in place** (keep only the `follows:` line / `layout:` body),179 write it back, and report it.1802. **No file, folders match a standard** → use that standard's reference, and **record it** — write181 `follows: <standard>` plus the full `layout:` tree, so later runs follow it instead of re-comprehending. No question.1823. **No file, custom layout** → ask the user once with `AskUserQuestion` (recommended structure first,183 "keep current" last), then write the file recording their choice.184185The file records **placement only** — a `follows:` line and/or a full `layout:` tree (the actual solved186structure; a project may carry both). It never carries rule toggles: every rule is always enforced,187deep-import is derived from whether a barrel exists, and the ST-008 size/folder checks run at fixed188thresholds. `block-structure-file-violations.py` enforces this.189190Read `references/structure-resolution.md` before acting on case 3, a monorepo, or a non-canonical file.191It has the full mechanics: monorepo file placement (the sub-project root, not the repo root), the question192shapes, what "keep current" does and doesn't exempt, the self-heal normalisation, and the messy-project193fallback.194195The resolved structure replaces `references/<framework>/structure.md` in the Step 7b load list, and the196pipeline passes it to Worker 1 as `STRUCTURE`. For "Show me the rules" / pure Q&A, resolve silently —197don't ask or write a file.198199---200201## Step 5 — Pick the execution shape (orchestrator pipeline vs inline)202203Two shapes for Write and Review. Resolve Step 4 first — structure is always the first question, run-mode204the second.205206| Trigger | Shape |207|---|---|208| Single-file edit (≤30 lines), single-function refactor, or rule Q&A | **Inline** — you do it yourself. Steps 6 → 7b. |209| 2+ files, a new feature, a diff/PR review, `--thorough`, or the `/coding-standards` command | **Orchestrator pipeline** — you dispatch workers. Steps 6 → 7a. |210| `Agent` tool unavailable in this host (Cursor, Codex, OpenCode) | **Inline** regardless of scope — flag it in the routing line. |211| Apply review findings ("fix the findings", "continue the fix" / "resume the fix") | **Orchestrator pipeline, `MODE: fix`, always.** No run-mode question. |212213The choice is made one of two ways:214215**A) Invoked via `/coding-standards` or the Step 2 picker, and `Agent` is available** → ask the run-mode216question with the exact payload in `references/activation.md`. "Multiple agents" → pipeline (7a);217"Single agent" → inline (7b). Ask at most once per session; reuse the answer afterward.218219**B) Plain message (no command)** → decide from the table.220221### Announce the routing — one line, before the substantive work222223Once mode, framework, structure, and shape are resolved, emit a single line so the user sees the route:224225```226coding-standards: framework=nextjs · structure=route-colocated (matched) · shape=pipeline (2+ files)227```228229Name the shape's trigger (the table row, or "user choice"), and mark how structure resolved — `(matched)`,230`(file)`, or `(asked)`. Pure rule Q&A skips the line; there's nothing to route.231232---233234## Step 6 — Track the run with a task list235236On any real work — writing, editing, refactoring, or reviewing — open the task list **up front, the moment237the scope is known**: for the Step 2 picker path, right after the "what to review / write" answer; for a238plain message ("review this PR"), as soon as you've identified the files. Open it **before Steps 3–4**, so239framework detection and *resolve + record structure* land on the list as the **first tracked items**, not240pre-work that runs before any list exists. The list is what makes the standards visible — the user sees241each stage applied instead of trusting it happened. Use the host's task-list tool (`TodoWrite`,242`TaskCreate`/`TaskUpdate`, …); skip the list only if the host has none, and skip it for pure rule Q&A —243there's no multi-step work to track.244245Build the **whole** workflow at once, then extend it with any extra targets the user named. Track the work246the user cares about (fold in real file/feature names), keep exactly one item `in_progress`, and complete247it before starting the next. A typical review list: **resolve + record structure → detect framework →248load rules → review → run hooks → write report**. A typical write list: **resolve + record structure →249detect framework → read existing code → load rules → draft → rewrite the draft → sweep the rules → write250the files**. The first item, *resolve + record structure*, may be251marked `completed` **only when `.coding-standards-structure` exists** at the resolved project root —252resolved one of three ways: matched a standard, asked-and-recorded, or a skip-reason logged (recognized-253unsupported framework, or below the scope threshold). Having run a structure-comprehension agent is **not**254completion; the file on disk is. The pipeline and Fix shapes add their worker/ledger stages — see255`orchestrator-pipeline.md`. A milestone-driven fix adds one item per milestone at plan approval — a display256mirror only; the plan file on disk stays the source of truth.257258---259260## Step 7a — Pipeline branch: orchestrate the workers261262You (the main agent) become the **orchestrator**: you coordinate three sequential workers and do the final263Write yourself, so the hooks fire exactly once on the complete code. **Read264`references/orchestrator-pipeline.md` and follow it** — that's the full protocol (worker roster,265Write/Review/Fix pipeline shapes, dispatch loop, validation, retry/fallback, summary).266267Invariants, true even before you open the reference:268269- **Comprehend before you check.** Above the scope threshold *and* when the structure isn't already270 recorded in `.coding-standards-structure` (or the user explicitly asked to restructure / review the271 structure — see Step 4), build and confirm the structure map (`references/structure-map.md`) before272 dispatching Worker 1; pass it as `STRUCTURE_MAP`. When a record already exists and no such request was273 made, skip the map and pass the recorded structure as `STRUCTURE` — don't re-open the layout.274 Cross-feature structure (duplication, mislabeled nesting, split features, themed-cluster promotion) is275 found by diffing the real tree against the map — a per-file worker cannot see it.276- **Workers never call `Write`/`Edit`.** They emit code/findings as JSON; only you write to disk.277- **Sequential, not parallel.** Worker 1 (Structure) → Worker 2 (Quality) → Worker 3 (Failure); each one's278 output is the next one's input.279- **No retries past 2.** Twice-failed validation or unparseable JSON → fall back to inline.280281---282283## Step 7b — Inline branch: load the references, then apply284285Before writing or reviewing any code, read these fully — once per session, not once per task:2862871. **All eight `common/` files** (always): `functions.md`, `naming.md`, `objects-and-data.md`,288 `formatting.md`, `comments.md`, `error-handling.md`, `code-principles.md`, `structure.md`.2892. **The resolved structure** (from Step 4) — a `structures/<name>.md` variant or290 `references/<framework>/structure.md`.291292Read them fully because the judgement lives in the worked examples, not the rule names. Recalling "keep293functions small" misapplies FN-001; the examples show where the line actually sits.294295Then apply each rule at its scope: **common governs the inside of code; the resolved structure governs the296outside** (file placement, folder names, public APIs). When the two seem to conflict, that scope split is297the answer — a framework entry file is both thin (the framework rule) *and* the function it exports is298short (the common rule).299300---301302## Modes: Write, Review, Fix303304### Write305306Writing gets the same rule-by-rule walk as reviewing. Most `common/` rules have no write-time hook, so a307rule you don't name is a rule you don't apply. Seed these steps into the Step 6 task list. Step 1 runs once308per area, not once per file.3093101. **Read the existing code.** Open the 2-3 files closest to where the new code lands: those in the311 destination folder, else the nearest comparable feature in the same language. Note the project's verb312 for each recurring operation, what an entry file exports, how a feature divides into units, which domain313 error types exist, how imports are ordered. **A rule beats the project's convention; the project's314 convention beats the default you would otherwise reach for.** An existing file that breaks a rule stays315 as it is; a write task does not reorganize what is already there. In a genuinely new area you set the316 vocabulary, so keep it consistent across every file you write.3172. **Load the references** (Step 7b): all eight `common/` files plus the resolved structure.3183. **Draft it.** Get the behavior right first. A messy first draft is permitted (FN-012).3194. **Rewrite the draft.** Reread each file as its first reader: split the function you excused at 25 lines,320 replace the name you settled for, delete the parameter nobody needs.3215. **Sweep the rules one at a time.** Walk `common/` against what you wrote and file each rule under322 applied, already met, or not applicable with a reason. Re-read the reference for any rule you had not323 considered before this step. Report the buckets in your reply, not in the file.3246. **Fix what you find now.** A violation ships fixed or does not ship. Never pair one with a `TODO`.325326**Write no comments by default** (`comments.md`). Say it in the names and the shape of the code. A sentence327earns a place in the file only when it carries what the code cannot — a constraint, a rationale, an external328reference, a sharp edge. Never narrate the code, never narrate your edit, and never leave the conversation329behind in the file: no `as requested`, no `I think`, no `we could also`, no untracked `TODO`, no emoji, no330`Note:` preamble. If a thought belongs in the reply to the user, put it there and leave the file clean.331332A separate model judges the comments a turn wrote before that turn can end (`hooks/judge-comments.py`),333so a comment that doesn't earn its place comes back as a fix to apply, not a note to ignore. Write it334right the first time and the judge stays silent — it costs one short model call per turn that touched335code, and none at all on a turn whose files gained no comments.336337**Always author and modify code through the `Write` / `Edit` / `MultiEdit` tools — never by shell338redirection** (`> file`, `>>`, `tee`, `sed -i`, `cat <<EOF > file`). The enforcement hooks fire **only** on339Write/Edit/MultiEdit; a file written through the shell silently bypasses every one of them. This is a real340hole in the enforcement perimeter, and the only thing closing it for shell writes is this instruction — so341honor it. If some tool genuinely must generate a source file outside the Write path, run342`python3 <skill-dir>/hooks/review-files.py <file>` over the result and fix what it reports.343344### Review345346Walk the rules systematically — don't freelance. Seed the Step 6 list first, the moment you know what's347in scope and **before** you start reviewing; the numbered steps map onto it, and step 0 is the list's348first item.3493500. **Resolve + record the structure — the first task item, done only when `.coding-standards-structure`351 exists.** Above the scope threshold, and only when it isn't already recorded: if352 `.coding-standards-structure` already records the structure and the user didn't ask to restructure /353 review the structure, **skip this** — follow the recorded structure and review code against it; don't354 re-open the layout. Otherwise build the structure map (`references/structure-map.md`) over the tree,355 confirm it with the user once, persist it to `.coding-standards/structure-map.md`, and record the356 resolved layout in `.coding-standards-structure`. Hand the map to the structure worker as357 `STRUCTURE_MAP`: cross-feature findings (duplication, misnested peers, split features, themed-cluster358 promotion) are diffs against it, which a per-file pass can't see. Skipped below the threshold — say that359 cross-feature structural checks were not run.3601. **Scope + resolve structure.** List each file in the diff; detect its framework (Step 3) and resolve361 structure (Step 4).3622. **Load references.** Every `common/` file, plus the resolved structure for each framework in the diff.3633. **Judgement pass** — the rules regex/AST *can't* catch (FN-001 length nuance, FN-009 CQS, OD-003364 Demeter, EH-002 boundaries, the CM-* comment-prose rules, the `structure.md` rules). Per rule, report `PASS`, a finding as365 `file.tsx:42 — <rule> — <what's wrong>`, or `SKIPPED — <why it doesn't apply>`.3664. **Run the hooks as a linter** (deterministic pass, LAST — don't skip). The `block-*.py` hooks only fire367 on Write/Edit, so a review must invoke them explicitly:368 ```bash369 python3 <skill-dir>/hooks/review-files.py <file> [<file> ...]370 # diff: git diff --name-only | python3 <skill-dir>/hooks/review-files.py --stdin371 # pipeline: add --json and parse per file372 ```373 It applies the same write-time contract (`any`, Hungarian, 4+/5+ args, swallowed errors, junk-drawer374 paths, deep imports, the TS/Python AST checks) and skips excluded files. `review-files.py` self-selects375 an interpreter that can load the TS/JS grammars (its bundled venv if the launching `python3` lacks them)376 and flags the gap loudly if none can — it never silently reports a TS file clean. **Every finding it377 returns is a violation to fix:** the *existence* of the finding is deterministic and never re-litigated378 (an `any` is an `any`). For the ST-008 decl-count block, the *remedy* is the reviewer's judgement — a379 cohesive split, OR a recorded exemption (`.coding-standards-ignore` + reason, logged `accepted`) when the380 file is one cohesive job the proxy miscounts. A split that creates scatter or copies a sibling's381 machinery is itself an ST-008 + DP-007 violation, not a fix.3825. **Merge, write the report, summarize.** Combine judgement + linter findings into one list, ordered by383 file then rule code. **There are no severity tiers — every finding is a violation to fix.** A finding's384 only non-fix exit is at Fix time: `accepted` (the reviewer judged it is not a violation here — reason385 required) or `deferred` (a real breach left open). At review time the call is binary: a rule breaks386 (file it) or it doesn't (it's a pass, not a soft "consider"). Persist the merged result to a report file387 per `references/review-report.md` (`.coding-standards/reviews/<timestamp>.md`, gitignored) and tell the388 user the path — every review writes one, inline included. The report's **`Structure baseline:` field is389 mandatory** and names the recorded `.coding-standards-structure` (or declares `NOT RECORDED` with a390 reason) — see `references/review-report.md`. Above the scope threshold (defined once in391 `orchestrator-pipeline.md` → Fix mode), trim the chat output to the shape in `review-report.md`; the392 report file always holds everything.3936. **Verify the structure baseline, then never silently skip a rule.** After writing the report, run394 `python3 <skill-dir>/hooks/check-review-report.py <report.md>` (pass `--root <sub-project>` in a395 monorepo). Exit `2` means the report asserts a structure with no `.coding-standards-structure` behind it396 — the structure step (Step 4 / step 0) was skipped: resolve + record it and rewrite the report before397 reporting done. Exit `1` is a declared skip — surface the reason. This is the back-stop for the398 task-list item: the report can't read as complete while claiming a baseline that was never written. And399 if you didn't check a rule, say so — a review with hidden gaps is worse than one that admits its scope.400401### Fix402403Triggered by "fix the findings" / "apply the review" / fixes requested right after a Review — or by404"continue the fix" / "resume the fix" to pick up a non-done milestone plan. Fix mode **always runs as405the orchestrator pipeline** (`MODE: fix`) — it's inherently multi-file: it fans out one fix-agent per406file, tracked by a completeness ledger so nothing is silently half-fixed. Don't offer a "single agent"407option; if `Agent` is unavailable, run the documented sequential-batch fallback and say so.408409Every finding ends `fixed` (violation removed), `accepted` (judged not a violation — reason required), or410`deferred` (real breach, not fixed — an open breach). A run with open breaches reports411`done-with-open-breaches`, never `done`, until the user resolves them — see `references/fix-plan.md`.412413The input is the most recent `.coding-standards/reviews/<ts>.md`; if none exists, run Review first.414Everything else — the ledger, the per-file fan-out, the scope threshold, and the milestone-driven plan415file for big fixes (`references/fix-plan.md`) — lives in `references/orchestrator-pipeline.md` under416"Fix mode".417418---419420## Finding a rule on demand421422Rules are organized by the kind of question you're asking (functions, naming, objects/data, formatting,423comments, error handling, principles, structure), not by language. The full question→file index is in424`references/rule-index.md` — use it for "what does FN-005 mean?" lookups or when unsure which reference owns425a concern. During real work Step 7 already loads everything, so the index is just for targeted lookups.426427---428429## On conflict — the simpler *correct* design wins430431When two designs are **both correct** and pull apart on other principles, **DP-006 (KISS)** breaks the432tie: the simpler one wins, even if it mildly bends DRY or another rule. KISS is a tiebreaker, not a trump433card — it never overrides correctness, a real requirement, or SOLID. You cannot invoke it to skip a class434per variant you were handed (OD-002), swallow an error, or ship a silent fallback. Adding a pattern435(Strategy, Visitor, a fifth layer of indirection) just to satisfy a rule? Stop — the simple version is436usually right. Defending a god-file or a duplicated `switch` as "simple" to avoid the structure? Also stop437— that's not simpler, just smaller.438439---440441## What this skill does NOT cover442443- **Performance tuning** — use a profiler; clean code is fast *enough* by default.444- **Security review** — use a dedicated security skill (e.g. `security-review`). Clean-code review catches445 some bug classes but is not a security audit.446- **Test design** — tests follow the same clean-code rules, but TDD/BDD/mutation strategy is out of scope.447- **UI/UX visual review** — a separate domain (`web-design-guidelines`, `design-taste-frontend`). These448 frameworks cover *code* organization, not visual design.449450If the user asks for any of these, say so and point them at the right tool.