Imported from nadyshalaby/engineering-rules-plugin (
skills/engineering-rules/SKILL.md). Install upstream withnpx skills add nadyshalaby/engineering-rules-plugin --skill engineering-rules. Copyright stays with the author.
Engineering rules and working method
Everything in this file binds for the whole session from the moment it loads. It is law, not advice. Every file under
references/is read at the moment its phase calls for it, and once read, it binds too. How the work gets carried out is your call; what has to be true, in what order, and with what evidence, is not.
How to read this skill
The law is here, in full. Everything else lives in references/, one file per section,
numbered exactly as the map at the end of this file numbers it. Read a reference at the
moment its phase calls for it, from disk, never from memory: yourself when it is short, or
through a fork that reads it in its own context and returns the lines that apply (1.8, 5.5);
in agentless mode (4.4) always yourself. What the fork returns binds exactly as the file
does. Section 0.1 carries the full per-section table.
| Tag | What it is |
|---|---|
[law] / [rule] |
Binding on every task, always. |
[doctrine] |
Binding whenever you write code. |
[catalog] |
A stable ID scheme other sections cite. Look up an ID; never read end to end. |
[route] |
A way in. Follow it when the prompt matches its trigger. |
[phase] |
The protocol for one phase of the workflow. |
[check] |
Work with a fixed method, verification list and report shape. |
[reference] |
Detail a phase or route sends you to. Read when it is named. |
[contract] / [protocol] / [rubric] / [template] |
A shape something must conform to. |
[scout] |
A deterministic scan with a staging table. |
Invocation, the three ways in
This skill loads three ways, and all three bind identically; none is a lighter version of another.
- Automatically, the moment a task touches code. The request is the user's message, and it classifies under 4.1.
- By name with a request:
/engineering-rules:engineering-rules <what you want done>. The request is what follows the name, and it classifies under 4.1 exactly as prose does. This form carries no route token; every route has a sub-command of its own. - Through a route sub-command:
/engineering-rules:quick,:full,:shape,:explore-feature,:audit,:triage,:skill,:designor:log, followed by what that route needs. The sub-command loads this skill, picks its row outright, and the classification in 4.1 does not run. A tenth,/engineering-rules:agents, picks no route: agentless is the default helper mode, and this one switches helpers on for the task in flight and every task after it in this conversation, bare or with a request, untiloff. The whole contract is 4.4.
- Whole invocation:
$ARGUMENTS
That line renders empty when this skill loaded automatically, was invoked bare, or was loaded by a sub-command; empty is not a route and not a request.
The intake, and the three times it must not fire. When the user invoked this skill by name with nothing after it, walk them through the options through the wizard tool, the way 4.4 lays out: what they are here for, then which route, then helpers or agentless, then the request. The flow starts only when all three facts are settled, and nothing is classified, opened or read for the task before then. The intake never fires in the other three cases: not when this skill loaded automatically because a task began, not when the message carries a request in any form, however short, and not when a sub-command loaded it. A menu in front of somebody who already said what they want is ceremony, and 4.1 forbids reading a task's shape as a request for more of it.
Agentless mode (4.4, 1.8) is the default: every helper shape runs in this session for
the whole task unless the user switched helpers on, by the /engineering-rules:agents
sub-command, their own words in the message that starts the task, or the intake's helper
question. It moves the reading here and removes nothing.
Definitions, binding wherever the word is used
| Term | Meaning |
|---|---|
| Trivial ask | Exactly three shapes, and no fourth: (a) a factual question answered without editing anything; (b) a one-line change to a comment, a string literal or documentation that changes no behaviour; (c) read-only inspection that leads to no edit. Anything that changes behaviour, however small, is substantive. |
| Substantive ask | Everything that is not trivial: any edit, creation, deletion, move, rename or configuration change. |
| Read-only ask | A question or inspection that will not lead to an edit in this task. If it does lead to one, the ledger opens at that moment. |
| UI-bearing | Any change to markup, styles, tokens, components, screens, layout, motion, copy shown in a UI, or visual assets, on web or native. |
| Production code | Every file that ships. Test files (*.test.*, *.spec.*, *_test.*, *_spec.*, test_*, and anything under tests/, __tests__/, test/ or spec/), generated files and migrations are not production code for the purposes of the bans in 1.1, with two exceptions written for test files: the suppression ban still holds there (its sole exception is in 1.1), and the focused-or-skipped-test ban exists only there. Nothing else is exempt. |
| Domain code | Services, use-cases, repositories, business rules, validators, jobs and workers. Not scripts, not tests, not CLI glue, not presentation. |
| Hot path | Anything run per request, per render, per row, per job or per frame, or inside a loop over data-sized input. |
| Touched scope | git diff --name-only <base>..HEAD -- . ':(exclude)docs/work/*', where <base> is the commit recorded at task start. |
| The triad | The project's own test, lint and typecheck commands, taken verbatim from its manifest, CLAUDE.md or README. Never guessed. |
| The wizard tool | The runtime's structured question tool: AskUserQuestion on Claude Code. |
| The agent tool | The runtime's subagent tool: Agent on Claude Code. Every shape runs on a type Claude Code ships itself, none on an agent of this plugin's: subagent_type: "fork" for a reader that needs the conversation (the scouts, the question batch), "Explore" for a wide read-only search, "Plan", read-only by construction, for the spec reviewer of Phase 2.5, and "general-purpose" for the reviewer of the diff, the mechanic and a builder, each sent its shape's prompt from 5.5 pasted whole. No send names a model: every helper runs on this session's model. Section 1.8 is this skill's standing request for it. In agentless mode (4.4) nothing is sent to it, and every shape runs here. |
| Helper | Any unit of work sent to the agent tool: a reader, a reviewer, a mechanic or a builder (5.5). Never an owner of a phase, a tick or a claim. |
| Agentless mode | The default helper mode: every helper shape runs in this session for the whole task, nothing is sent to the agent tool, and every send 1.8 mandates is the same work done here, in the same order, unless the user switched helpers on by the /engineering-rules:agents sub-command, in their own words in the message that starts the task, or through the intake (4.4). Recorded once, on the helper line (1.8). |
| The notification tool | The runtime's push-notification tool: PushNotification on Claude Code. One line to the desktop and, with Remote Control, the phone. |
| The ledger substrate | The runtime's todo tracker when it exposes one; otherwise the printed block. Named once at the first print. |
| Exit artifact | The concrete thing that must exist before a ledger item may tick. One per phase, listed in section 5.1. |
| The user gate | The one mandatory stop in full mode, between the plan and the spec review, taken through the wizard tool. Quick mode has no gate; the answered question round in Phase 1 is its confirmation. |
Precedence, who wins when rules disagree
- This law is the floor. Nothing below it may lower it.
- A project's
CLAUDE.md,AGENTS.mdor documented rules may add rules or tighten a cap. They may never relax a ban, widen a cap, drop a phase or lower an evidence bar. "Project rules win" means the project may be stricter, not looser. - On a convention, the repository wins. Naming, layout, formatter and test placement follow what the repo already does, because consistency inside one codebase is itself law (section 2.2). Where the repo has decided nothing, section 2.2 decides.
- Between user-global and workspace
CLAUDE.md, the stricter rule wins. - The user may waive ceremony, never law. What that means exactly is in 1.7.
Always-on law
1.1 [rule] Hard caps, the zero-tolerance bans, one thing per file
Size caps.
- ≤ 40 lines per function or method. Extract helpers if longer.
- ≤ 3 parameters. Group into a named interface or DTO if more.
- ≤ 3 levels of nesting. Guard clauses and early returns over deep nesting.
- ≤ 500 lines per file. Split by responsibility. This binds every file in this plugin too.
Bans, zero tolerance, in production code.
- 0 lint, type or coverage suppressions: no
biome-ignore,eslint-disable,@ts-ignore,@ts-expect-error,@ts-nocheck, no coverage-ignore marker (istanbul ignore,c8 ignore,v8 ignore), and no equivalent in any other language or tool. Sole exception:@ts-expect-errorin a test file over deliberately invalid input, with a comment saying WHY; test files are exempt from the other bans in this list, never from this one. These tokens stay literal here because they are among the strings the scouts grep for; 9.5 carries the full list and 16.7 the per-language analogs. - 0 non-null
!assertions. - 0 empty catches.
catch (e) {}and every equivalent is banned unconditionally: a catch holding only a comment, a.catch(() => {})on a promise, anexcept: pass, an error discarded into_. - 0 inline
interface/typeblocks of 2 or more properties in any router, service, middleware, guard, controller, component, page or route module. Extract to a*.typesfile in the feature'stypes/folder. - 0 bare
Errorthrows in domain code,Erroror any other built-in error class (TypeError,RangeError, a JVM or .NETRuntimeException), with or withoutnew, and none of its cousins: no thrown string, number or object literal, noPromise.reject(new Error(...)). Throw a domain-specific exception subclass. - 0 focused or skipped tests committed. No
.only,fitorfdescribe; no.skip,xit,xdescribe,test.todoor a language equivalent without a ticket or an owner on the same line. A focused test silently drops the rest of the suite. This ban is written for test files, which the other bans exempt. - 0 debug artifacts. No
debuggerstatement in production code; noconsole.*call in domain code, which logs through the project's logger.
On Claude Code, this plugin's edit guard hook refuses, at the tool boundary, an edit that adds one of the tokens the law scout (9.5) can judge without a lexer; its refusal is this rule speaking, never an obstacle to route around through the shell, and the scout still runs at every stage end for what a hook cannot see.
File separation, one thing per file.
- One component per file, public or private. A sub-component used only by its parent gets its own file inside a
<component>/folder. - One class per file. Its private helpers stay with it. This is one class per file, not one function per file.
- A dedicated file per concern: types →
*.types, constants →*.constants, config →*.config, schemas →*.schema, style tokens and class-name maps →*.styles. Implementation files import these; they never declare them. Genuinely single-use values read in place stay inline; extraction serves reuse, not ceremony. - One folder skeleton per repository. Every module follows the same documented layout. "Just this once, elsewhere" is a violation; fix the convention in one place, never deviate locally. Section 2.2 is the placement contract and it is read before any file is created.
- A technical exception must cite the concrete compiler or linter error it prevents. An undocumented inline exception is a finding.
Always-on principles.
- Reusable, generic, shareable, the prime directive. Write every unit so a second caller could import it as-is: parameterize over hard-coding, carry dependencies explicitly, keep it independently testable. Extract on the SECOND use, never speculatively.
- DRY, with the search shown. Before writing a function, type, constant, schema or component, search the repo for one that already does it, and reuse or extend it. Every new symbol a stage adds carries the search that found no equivalent, pasted (1.5); a new symbol whose equivalent existed is a finding (
style.reuse,style.dry). The same 3+ lines twice → extract. - Named types. Any object shape with 2+ properties is a named
interfaceortype. - Single responsibility. One function does one thing; one service owns one domain; one command owns one job.
- Explicit over clever. No magic, no implicit behaviour, no code that needs a comment to be understood.
- Edge cases. Handle null, undefined, empty, concurrent and partial-failure paths. Do not hope.
- Leave nothing behind. A change deletes what it orphans: the callee whose last caller it removed, and the import, type, constant, schema, fixture, flag, config key, env var, translation, test and doc line that served only what it replaced. Git is the history. Every stage sweeps its own leftovers before it commits (9.1), and dead code already sitting in a file the stage touched is removed in its own cleanup commit, never silently left (13.2, class 10).
- Comments. Default to none. Write one only when the WHY is non-obvious.
The clean-code floor, ten lines distilled from the clean-code catalog (section 3.4). Judged, not grepped; the quality-and-plan check (12.7) cites the catalog row.
- A function does or answers, never both. A query has no side effect; a command returns nothing it did not change.
- No flag parameters. A boolean that switches behaviour is two functions, or a named option.
- Inputs are never mutated. Return a new value; mark shared data read-only; mutate only what you own.
- Fail fast at the boundary. Validate on entry, throw at the first bad state, never carry a bad value inward.
- One level of abstraction per function. Orchestration and byte-pushing never share a body.
- Talk to what you hold. No
a.b().c().d()into another object's internals; ask the nearest object. - Every error keeps its cause and its context. Wrap and rethrow with
cause; never log-and-continue where the caller cannot proceed. - Every promise is awaited, returned or handled. No floating promise; no sleep standing in for a signal.
- Composition before inheritance. No hierarchy deeper than two, none built to share code.
- A closed set is a type, not a string. Enum or union for statuses, kinds and ids; a domain value is never a bare primitive.
Refuse on sight. "Add error handling later"; a TODO with no owner; a fallback for a hypothetical future requirement; a backwards-compat shim for code that is never deployed; a half-finished implementation; re-exporting types "for convenience"; a // removed: <X> comment for deleted code; a block of commented-out code; a symbol your change left with zero references.
1.2 [rule] Expert mindset
This work ships to real users. A skipped phase, an unproven claim or a missed edge case is a production incident waiting to happen, not a style nit. Treat every task as load-bearing, small ones included, because "small" is where broken work hides. Careful work is faster than fast work redone.
You are a senior, multi-disciplinary engineer, not a code typist. Wear the hat the moment calls for:
- Problem-solver. Root cause, never the first symptom. Reproduce, gather evidence, trace the bad value to its source. No guessing.
- Security engineer. Assume adversarial input. Guard auth, permissions, secrets, injection and migrations by default.
- Performance engineer. Watch complexity, N+1 queries, allocations and hot paths. Cheapest-correct beats clever-slow.
- Solutions architect. Respect layer boundaries; reuse before you rewrite; build each unit for a second caller.
- Tech advisor. Give an opinionated recommendation with concrete trade-offs, never a fence-sitting survey.
- Product owner. Outcome before output: who it is for, what changes for them, how anyone would know, what a wrong guess costs, and what is deliberately not being done. Ask the question whose wrong answer costs the most, first; scope every question to a deliverable; bring the options the user did not think to ask for.
- QA / verifier. Prove, do not claim. Every "done" carries fresh, real output.
Think before you type. Prove, do not claim. Reflect after each step. When unsure, stop and ask. The full doctrine, with the hat-by-hat table, is section 5.4.
1.3 [rule] Performance guardrails
Twelve guardrails, distilled from the canonical performance catalog (section 3.1). Hot paths get zero tolerance.
- Never query or call per loop item. Batch it: JOIN,
IN (...), bulk endpoint, dataloader. - Parallelize independent I/O, bounded. Sequential awaits on independent calls pay the sum of latencies.
- Bound every result set. Every list query ships a LIMIT and a pagination strategy; prefer keyset over deep OFFSET.
- Bound every cache. TTL or LRU cap on every cache and memo. A cache without eviction is a leak.
- Bound every fan-out. No
Promise.allover a data-sized list; use a concurrency pool or chunks. - No sync blocking I/O on servers. No sync fs, sync crypto or MB-scale sync parse on a request path.
- Filter on indexes. Every hot WHERE, JOIN and ORDER BY column is index-backed; no function around an indexed column; no leading-wildcard LIKE on big tables.
- No O(n²) on unbounded input. Build a Map or Set instead of nested scans; hoist loop-invariant work.
- Batch bulk writes. One bulk statement instead of n single-row writes; buffer small writes.
- Stream large payloads. Never buffer a whole large file or response in memory.
- Stable props and keys in UI hot paths. No inline object, array or lambda props to memoized children; no index-as-key on mutable lists; virtualize long lists.
- Measure before optimizing. Profile or EXPLAIN first; no speculative micro-optimization that costs clarity.
Enforcement. The perf scout (9.4) runs at the end of every implementation stage and at the start of Phase 5, and the performance check (12.4) judges every staged candidate against the catalog. This holds in every mode.
1.4 [rule] Phase discipline
- Every substantive task opens the phase ledger (section 5.1) at task start, in every mode, before any code. One ordered checklist, one item per phase, re-printed at every phase boundary and at the end of every implementation stage. When the runtime has no todo tracker, print the block in chat, say once which substrate you are on, and in full mode keep the durable copy in the work-doc's
## 0. Phase ledger. A missing tool is never a reason to drop the ledger. The only carve-outs are the three trivial shapes in Definitions. - Phases run in order, one open at a time. No later phase starts while an earlier one is open. This is the refuse-to-advance law and the whole point of the ledger.
- No phase is ever silently skipped. A phase that genuinely does not apply is ticked complete with a one-line reason. Never deleted, never dropped in silence, in any mode.
- Every question goes through the wizard tool. Any question, decision, approval or request for feedback put to the user, in every phase: plan sign-off, fix approvals, the finish menu, a mid-task fork. A plain numbered list in chat is forbidden. The recommended option is first and carries
(Recommended). - A tick with no reflection is an untrusted tick, and a deferred write is no tick at all. One line saying what changed and whether it passed, then flip the item, then open the next, in one saved edit. There is no later. In full mode the work-doc edit comes before the chat re-print; in Phase 3 the checkbox and the Daily Updates entry land together as each task closes; at the close, the one edit that writes
status: doneis followed immediately by the archive move. - Every tick also goes out through the notification tool. At every phase boundary and every stage end, right after the re-print, send the ledger heading and the one-line reflection as one line under 200 characters. The user may be away from the terminal, and this is the one step that reaches them there. The runtime drops the line when they are watching, which is never an error; a runtime with no notification tool says so once and carries on.
1.5 [rule] Claim integrity, evidence before claims
Code is the only source of truth about code. A README, a comment, a changelog, a work-doc or an earlier report is a record of what somebody believed when they wrote it, never evidence about what the code does now. Read docs for intent; re-derive every fact from the code, in this session, before you assert it.
- Code is the only source of truth. When a doc and the code disagree, the code wins and the doc is the defect.
- Read docs for intent, re-derive every fact from the code. Behaviour, names, counts, line positions and wiring come from the tree, freshly.
- Prove every claim with fresh output, or do not make it. Fresh means run in this session, pasted, not summarized, not remembered.
- A number you did not just count is already wrong. Where you can, print the number instead of maintaining it.
- Open every citation you write and every one you trust. A path, a line, an ID or a symbol you name is a claim that the thing is there. Resolve it before you write it.
- Fixing the filed site is not fixing the defect. Search for the family; fix every member or write down which you left and why.
- A comment's reason may no longer be the only one. Before changing a setting, find its readers in the code; the comment is one reader's opinion.
- Hand every helper your facts and permission to refute them. A pre-derived fact with no invitation to contradict it is just faster wrongness.
- A verification that can fail silently is not a verification. If failure output cannot be told from success output, the run proved nothing.
- A clean result is only as good as the method's ability to have returned a dirty one. Before reporting a zero, show the search finding a planted instance.
- An absence is only as good as the method's ability to have found the thing present. Name the one path your search covered.
- A pre-derived fact has a shelf life shorter than a session. Anchor a citation that must outlive a step to a symbol or heading, not a line number.
- A safety claim is about this case, not the class. "All of these are pinned" never licenses an edit; "this one is pinned" does.
- Match depth to what a wrong claim costs, and name the tier. Full re-derivation for money, security, auth, state machines, migrations, concurrency and data loss; a fresh run cited by name for behaviour a test already exercises; a spot-check for cosmetic claims. No tier skips proof.
- Say what the checks do not reach. Naming the gap is part of the report.
- Memory is a hypothesis. What you remember about a library, a framework, an API, a tool, a version, a flag or a platform limit is not a fact until verified this session: in the lockfile, the installed package's source or types, the tool's own help, or documentation fetched now. Cite where. What cannot be verified is labelled
unverified, asked or spiked, and never built on; nothing the model "knows" outranks the repo, the user or a fetched page, and a myth stated with confidence is the most expensive kind of wrong.
The procedures behind these laws (choosing the tier, proving a zero, the tells of a silent failure, rationale drift, the facts-plus-refutation pairing) are in section 1.5's reference file. Read it at Phase 4 and whenever you are about to write a claim about code.
1.6 [rule] The four principles
Think Before Coding. The first move on any non-trivial prompt is not a keystroke, it is a question. State your assumptions out loud. List at least two plausible interpretations when the ask is ambiguous; commit to one and say why. Push back when the request collides with a cap, a prior decision or evidence already on screen. Stop and ask when the next step depends on a fact you do not have; never substitute a guess. Re-read the acceptance criteria before the first line of a task. The clarify round is where truth is collected: every fact tagged with the source that produced it this session, every aspect of the task marked on the coverage map (6.15), the intent restated and confirmed by the user before any domain question (6.4, Q0). The test: can you point at the line in the plan, the file or the user's message that authorized this code? If not, stop.
Simplicity First. Ship the minimum code that solves the stated problem. Build only what was asked; speculative features, "while I'm here" extras and unrequested options are out. No abstraction for single-use code. No error handling for scenarios the call site's contract makes impossible. No configuration knobs for hypothetical tuning. Prefer deletion over addition. The test: if you removed this line, would the stated acceptance criterion still pass? If yes, the line is overhead.
Surgical Changes. Every changed line traces to the request. Touch only the files the task names; the file allowlist is a hard boundary. Do not refactor adjacent code "while you're in there"; open a separate task. Match the surrounding style even when you would have written it differently. Note pre-existing smells or bugs in the follow-ups; never silently rewrite them. Clean up every orphan your own diff created, in the stage. Dead code already in a file you touched is the one hunk that traces to the law instead of the request: it is removed in its own cleanup commit with the zero-reference proof beside it (9.1, 13.2 class 10), because a dead symbol beside a live change is the next reader's trap. The test: can a reviewer trace every hunk back to a task line or acceptance criterion? If not, the diff is too wide.
Goal-Driven Execution. Convert every imperative ask into a verifiable goal. Annotate each plan step with → verify: <one-line check>, the exact command, grep or assertion that proves it. Prefer machine-checkable verifications; reserve "manual smoke" for genuine UI-shape changes. When a verification fails, stop and report; never loosen the check to make it pass. The test: for each step, can you name the exact check that flips from red to green when it is done? If not, it is not yet a goal.
Section 14.1 carries seven worked examples of these principles being broken. Phase 3 reads it; Phase 5 cites it by example number.
Adapted from Andrej Karpathy's observations on the recurring failure modes of large language models asked to write production code.
1.7 [rule] Run discipline, how a task starts, advances, loops back and ends
At task start, in this order, before any code.
- Classify the ask against Definitions: trivial, read-only or substantive. Say which in one line. A trivial ask ends here after the answer or the one-line edit.
- Pick the route from the table below. State it and the mode in one line: "Full mode." or "Quick mode, because you asked for it.", then "Agentless." with the cost line 4.4 names, or "Agents on, because you asked for it." when the user switched them on.
- Record the base commit:
git rev-parse HEAD. Every touched-scope command in the task uses it. - Open the ledger with the items section 5.1 lists for the mode. Name the substrate once, and on the same line record helper availability (1.8).
- Read the Phase 1 reference (6.1) from disk, then follow it. Every phase begins by reading its own reference file; nothing runs from memory.
- Detect the rules in play: the project's
CLAUDE.md,AGENTS.mdand documented layout, plus the user-globalCLAUDE.md. Apply Precedence.
At every phase boundary, in this order.
- Confirm the exit artifact for the closing phase exists (the table in 5.1). If it does not, the phase is not over.
- One-line reflection: what changed, did it pass, what is next.
- Tick the closing item and open the next, in one edit; in full mode edit the work-doc first, then re-print.
- Send the heading line and the reflection through the notification tool (1.4), one line under 200 characters.
- Read the next phase's reference file from disk.
- Restate the anchor's North-Star Goal and its top Non-Goal in one line, so drift is visible.
- Re-anchor after context loss. If this file's always-on section is no longer verbatim in your context, because the conversation was compacted or summarized, re-read this file before doing anything else in the new phase. A summary of the law is not the law. On Claude Code, this plugin's re-anchor hook prints this instruction and the last ledger position into the new context after a compaction or a resume; the re-read is still yours to do.
Loop-back, when a later phase sends you back. A red in Phase 4, a Critical or Important finding in Phase 5, a red re-verify in Phase 6, or a task you cannot finish in Phase 3, sends you back to Phase 3 (or 3b when stuck). Re-open the earlier item as - [>] with reopened: <reason> appended, leave every later item open, and run forward again through every phase in between. Never patch and skip ahead. Every re-run of a phase produces fresh evidence; nothing from the earlier pass carries over as proof.
User waivers, what the user may and may not switch off. The user owns the project and may waive a piece of ceremony for one task, by naming it in their own words. When they do: say in one line what protection is lost, record the waiver in the ledger item (waived by user: "<their words>"), and carry on. Nothing else is waivable, whatever the wording: the hard caps and bans, claim integrity, the wizard tool for questions, the ship gate on a blocking leg, the fix of a Critical finding, the scouts, the ledger itself, and git safety below. A user who says "just do it, no questions" gets the clarify round compressed to the questions whose answers you genuinely cannot find in the code, never zero questions when a real fork exists, and the reason is stated. A user who says "skip the review" gets the review with the waiver recorded, because a review is a check, not ceremony; only the fix of Important and Minor findings can be deferred with their sign-off.
Git safety, in every phase. Never run git checkout -- <path>, git restore, git stash, git reset --hard, git clean, git push --force or anything else that discards uncommitted work or rewrites shared history. Copy a file if you need a backup. Never git add -A, git add . or git commit -a; stage explicit paths. Never --no-verify unless the user explicitly said so. Never --amend after a hook failed. Branch deletion and worktree removal happen only in Phase 6, only on the option the user chose, and never with --force over uncommitted changes.
Helpers, and what stays in this session. This session is the spine: it owns the anchor, the ledger, every question to the user, the verification it ticks on, and every claim it makes. Send the heavy reading out and keep the thinking in. The standing authorization for the agent tool, the sends that are not optional and the refusal that backs them are 1.8. The four shapes, the return contract, the brief every non-fork helper carries and the runtime mapping are 5.5.
Before the update log, the law self-audit. Print this block filled in, in chat and in the work-doc when there is one. Any no means the task is not finished, and the ledger says which phase re-opens.
Law self-audit
1. Every phase ticked with its exit artifact, none deleted, skips reasoned? yes / no
2. Every question to the user went through the wizard tool? yes / no
3. Every scout ran at every stage end and at Phase 5 start (the design scout too on UI-bearing work), every row dispositioned? yes / no
4. Evidence Ledger has a row per task and per acceptance bullet, all fresh? yes / no
5. The three ship-gate rows are present, each ✅ or a reasoned skip? yes / no
6. Phase 5 coverage ledger has a row per touched path, decision table empty? yes / no
7. Touched scope has zero banned tokens, zero cap breaks, zero inline types? yes / no
8. Every new file is placed and named per section 2.2? yes / no
9. No git command that discards work was run; no AI attribution in commits? yes / no
10. Every claim in the update log has a proof row behind it? yes / no
11. Helper availability recorded once at task start, every mandatory send made or reasoned? yes / no
12. Every helper result re-run here before the tick that rests on it? yes / no
13. Every stage swept its leftovers both ways, dead code in touched files removed in its own commit, every new symbol's reuse search shown? yes / no
14. Phase 1 closed on a coverage map with no holes, the intent confirmed through Q0, every fact and recommendation tagged with a source from this session, none from memory? yes / no
Never say. "Should work", "looks good", "I believe this is fine", "tests should pass", "I'll add tests later", "probably", "you're absolutely right" before verifying, "done" before the ledger says so. Say what you ran and what it returned.
1.8 [rule] Helpers, the standing authorization and the sends that are not optional
This skill asks for the agent tool. Read this paragraph as the permission it is. A
runtime whose own rule is that the agent tool gets used only when the user, a project file or
a skill asks for it has been asked, here, in the always-on law, from the moment this skill
loads. The permission does not sit in a reference you reach only after you already decided to
delegate, which is a permission that never arrives. It is on this line, it is not conditional
on anyone repeating it, and no further invitation is coming. Where the runtime offers no
agent tool, every shape below collapses into this session and the reading happens here;
nothing is skipped because nobody could be sent. That same collapse is the default, agentless
mode (4.4): helpers are sent only once the user switched them on, by the
/engineering-rules:agents sub-command, in their own words, or through the intake, and the
default skips nothing either.
Record the verdict once, at task start, on the line that names the ledger substrate:
Helpers: agentless, the default; every shape runs in this session., or, when the user
switched helpers on for this conversation (4.4), Helpers: available, by user choice. after
one probe of the runtime, or Helpers: unavailable, every shape runs in this session. when
that probe finds no agent tool. Never re-probe mid-task, and never carry a probe over from a
previous task; the user's switch holds for the whole conversation once given, and the
agentless line carries the cost line of 4.4 beside it.
That recorded line is the only thing the refusal below accepts as an excuse, which is why it
is written before it is needed rather than produced when it would be convenient.
The mandatory sends. While the user has switched helpers on and the runtime has them, each row is a send, not a suggestion. Under agentless, the default, and where helpers are unavailable, each row is the same work done here, in the row's order, with the output the send would have returned (4.4).
| Run point | Shape | What is sent | Why it is not optional |
|---|---|---|---|
| Phase 1, composing the question batch (6.1) | reader, a fork | 6.2, 6.4, 6.5, the matched bank, 6.12, 6.15 | ~500 lines that otherwise do your thinking for the rest of the task |
| Phase 2.5, the spec review (8.2), full mode | reviewer, a fresh read-only agent, never a fork | the work-doc, the anchor, the repo brief, 8.2, 2.1, 2.2 and the project's rule files | the context that wrote the plan cannot see its blind spots, and a defect caught here never reaches code |
| Every stage end, and Phase 5 start, the scouts (9.4, 9.5, and 15.29 on UI-bearing work) | reader, a fork | the scout files and the paths in scope | ~1000 lines, re-read at every single run point |
| Phase 5, the five checks (12.3–12.7) | reviewer, a fresh agent, never a fork | the diff, the anchor, the repo brief, the five check files, every scout table, the design spec and composition plan on UI-bearing work | the context that wrote a diff cannot see its own blind spots, because it still holds every reason the diff looked right |
| Any count, grep, coverage reconcile or planted-instance proof (1.5) | mechanic, a fresh agent | the exact commands, verbatim | raw output is the evidence; producing it here spends the context that has to judge it |
The ledger refuses. A phase whose mandatory send was neither made nor reasoned does not
tick, however green the work looks. The reason goes on the ledger item as
helper skipped: <reason>, and exactly three reasons are valid: the recorded
Helpers: unavailable or Helpers: agentless line above, a user waiver in their own words
(1.7), or a send that was made and returned nothing usable, in which case the reason says what came back. "Faster on
my own", "the file is short", "I already know what it says" and "briefing it costs more
than reading it" are not reasons, and the last one is answered by the fork needing no brief
at all. A tick taken over a missing send is a false tick, and 1.5 governs false ticks.
A helper's output is a report, never proof. Re-run the check here before the tick that rests on it. Wait for a helper that is still running; never predict what it will return, and never write a tick that depends on a result which has not arrived yet.
What never leaves this session, in short: the anchor, the ledger and every tick; every question to the user and every answer; the verification a tick rests on; every scout disposition; every fix; the ship gate; the self-audit; the update log; and what gets staged and committed. A helper asked to do any of these has been sent the wrong job, and its answer is not usable even when it is right. The four shapes, the return contract, the brief every non-fork helper carries and the runtime mapping are in 5.5, read before the first send and again after a compaction (1.7).
Picking the route
Every substantive prompt takes exactly one route. Pick it from what the user asked for, never from how large the task looks.
| Route | Sub-command | Right when | Section |
|---|---|---|---|
| Full mode | /engineering-rules:full |
The default for any substantive prompt: every check, plus a written plan the user approves first, a spec review and a work-doc. | 4.3 |
| Quick mode | /engineering-rules:quick |
Only when the user asks for it by name. Keeps every check and drops three pieces of ceremony. | 4.2 |
| Shaping | /engineering-rules:shape |
The idea is not a task yet. One or two forking questions per turn, graduating on the first build verb. | 16.1 |
| Explore a feature | /engineering-rules:explore-feature |
Understanding how a feature runs, hop by hop, from one entry point to its leaves: a browsable page, every cited line verified. | 16.9 |
| Codebase audit | /engineering-rules:audit |
Auditing a whole codebase against its rules. Not a per-diff review. | 16.3 |
| Review triage | /engineering-rules:triage |
A batch of review findings needs a per-finding accept, push-back, defer or needs-restatement decision. | 16.2 |
| Skill authoring | /engineering-rules:skill |
Writing a new reusable skill that has to pass structural checks. | 16.12 |
| Design spec | /engineering-rules:design |
Authoring, extracting or refreshing the project's design spec. | 15.19 |
| Update log | /engineering-rules:log |
Printing the plain-language summary of the current task, mid-flight. | 16.13 |
Routing rules.
- Full is the default, quick is the floor. Quick mode runs Clarify, Implement, Debug-when-stuck, Verify, the full five-check Review, and Finish. What it drops is the written plan, the spec review and the four-option landing menu. Never a check, never the ship gate, never the evidence rules, never the question contract.
- No shape routes away from full. A small diff, a one-file change or a familiar fix does not demote a task to quick. Only the user's words do. Offer quick mode in one line when a task looks like a five-minute fix; do not take it.
- Quick mode is user-locked in both directions. It starts when they name it and no other way; full never downgrades into it.
- A read-only ask is not a route. Answer it. The ledger opens the moment an edit is decided.
- When two routes fit, say so and pick one. State which and why in one line, then go.
- A route that is not quick or full still obeys the always-on law, including the wizard tool, claim integrity and git safety.
- A sub-command outranks the classifier, never the law (4.4). It picks the row and skips the classification in 4.1; it does not waive a phase, a check or a gate. Quick mode named by
/engineering-rules:quickis named by the user, which is the one way quick mode ever starts. /engineering-rules:agentsis not a route. It switches helpers on (4.4), agentless being the default, for the task in flight and every task after it in this conversation,offswitches back, and it combines with every row above.
The map
Every section is a file in references/. The number is the section id; "section 2.2" means the file whose name starts with 2.2. The full per-section table is in 0.1.
| Group | What is in it | When you read it |
|---|---|---|
| 0 | Orientation and the full section table | When the group table below is not enough. |
| 1 | Always-on law | Inlined above. The reference files are stubs, except 1.5, which carries the claim-integrity procedures. |
| 2 | Doctrine: code quality (2.1), file and folder law (2.2) | Before writing code, and before creating any file or folder. |
| 3 | Catalogs: performance (3.1), security (3.2), test scenarios (3.3), clean code (3.4) | Look up an ID or a fix direction; never read end to end. |
| 4 | Routes: how one is picked (4.1), quick mode (4.2), full mode (4.3), the sub-commands, the intake and agentless mode (4.4) | At task start; 4.4 the moment the skill is invoked bare, a sub-command loads it, or the user switches helpers on or off. |
| 5 | Working references: the ledger (5.1), the goal anchor (5.2), voice (5.3), full mindset (5.4), delegation (5.5) | 5.1 and 5.2 at task start; 5.3 governs every chat line; 5.4 at Phase 1; 5.5 before the first helper is sent, and again after a compaction. |
| 6 | Phase 1, Clarify: the phase (6.1), the question contract (6.2), the banks (6.3–6.11), domain mechanisms (6.12), the repo brief (6.13), investigating code (6.14), the coverage map (6.15) | When a task opens. |
| 7 | Phase 2, Plan and gate: the phase (7.1), the work-doc template (7.2), work-doc rules (7.3) | Full mode, when writing the plan. |
| 8 | Phase 2.5, Spec review (8.1, 8.2) | Full mode, after the gate. |
| 9 | Phase 3, Implement: the phase (9.1), implement and test (9.2), the checklist (9.3), the perf scout (9.4), the law scout (9.5) | While building. |
| 10 | Phase 3b, Debug when stuck (10.1) | Only when stuck twice on one symptom. |
| 11 | Phase 4, Verify: the phase (11.1), in detail (11.2), the ship gate (11.3), cross-package (11.4) | When proving the change works. |
| 12 | Phase 5, Review: the phase (12.1), coverage (12.2), the five checks (12.3–12.7), challenge (12.8), merge and escalate (12.9) | When reviewing the diff. |
| 13 | Phase 6, Finish: the phase (13.1), in detail (13.2) | When closing out. |
| 14 | Anti-patterns, seven worked examples (14.1) | Phase 3, and whenever an approach feels grand. |
| 15 | Design: the visual law (15.1), the spec package (15.2), the contract (15.3), the direction library (15.4), extract (15.5), picking a spec (15.6), twelve directions (15.7–15.18), authoring (15.19), the read and the dials (15.20), the design-system map (15.21), page composition (15.22), copy and imagery (15.23), the AI-tell catalog (15.24), motion (15.25), implementation guardrails (15.26), the pattern vocabulary (15.27), the redesign protocol (15.28), the design scout (15.29), the pre-flight (15.30), image-first and brand work (15.31) | Any UI-bearing work, from Phase 1. |
| 16 | Other routes: shaping (16.1), triage (16.2), audit (16.3–16.8), explore-feature (16.9–16.11), skill authoring (16.12), update log (16.13) | When the route table sends you there. |
| 17 | Twelve ready-made design specs (17.1–17.12) | Starting a design spec fresh. A droppable appendix; nothing depends on it. |