eng-skills
v0.4.0
Published
Scaffold battle-tested Claude Code engineering conventions into any repo: enforced docs protocol (features/fixes/decisions/phases), pre/post/stop hooks, research-first slash commands, and a CLAUDE.md that Claude fills in by reading your codebase.
Maintainers
Readme
eng-skills
Battle-tested Claude Code engineering conventions, scaffolded into any repo in one command.
npx eng-skills initMost Claude Code advice lives in blog posts. This package turns it into files: an enforced documentation protocol, safety hooks, and research-first workflows — extracted from a production monorepo where this exact system sustained 100+ feature docs, 100+ fix docs, and a full ADR log without the docs going stale.
Why
Two facts about working with coding agents:
- CLAUDE.md instructions are advisory; hooks are deterministic. An instruction like "always document your changes" gets skipped under context pressure. A Stop hook that refuses to end the turn does not.
- Sessions are ephemeral. Whatever the agent learned — why a decision was made, what a fix's root cause was — evaporates unless it's written where the next session will look.
eng-skills wires those two facts together: hooks that force the knowledge base to stay current, and a knowledge base structured so future sessions (and humans) actually benefit from it.
What you get
CLAUDE.md # protocol + TODO(onboard) markers Claude fills in itself
docs/
README.md # the knowledge-base map and "the rule"
CHANGELOG-AUTO.md # append-only machine-written edit log
_templates/ # feature / fix / decision / phase templates
features/ fixes/ # one doc per feature, one per bug fix
decisions/ # numbered ADRs (seeded with ADR-0001)
phases/ plans/ specs/ # living progress checklists + planning artifacts
.claude/
settings.json # hook wiring (merged safely into an existing file)
hooks/
pre-edit.mjs # PreToolUse: reminds about the protocol on first code edit
post-edit.mjs # PostToolUse: logs every edit to CHANGELOG-AUTO.md
stop-gate.mjs # Stop: BLOCKS ending a turn that changed code but not docs
guard.mjs # PreToolUse(Bash): denies rm -rf, force push, .env exfil, …
commands/
onboard.md # /onboard — Claude researches YOUR codebase, fills CLAUDE.md
kickoff.md # /kickoff — new project: interview → landscape research → spec
feature.md # /feature — clarify → research → plan → implement → verify → document
fix.md # /fix — reproduce → root-cause → fix → prove → document
decide.md # /decide — record an ADR
phase.md # /phase — honest progress review, phase-gate closeout
skills/
brainstorming/ # asks clarifying questions + researches what others do BEFORE building
root-cause/ # systematic RCA discipline — no symptom-patching
frontend-verify/ # screenshot/console/network verification via chrome-devtools MCP
.mcp.json # chrome-devtools MCP server (offered for frontend projects — asks first)Everything is dependency-free Node (~150 lines of hooks total). No runtime, no daemon, nothing to keep updated.
How the enforcement works
- pre-edit (PreToolUse) — on the first code edit of a turn, injects a reminder of the docs protocol into Claude's context. Never blocks.
- post-edit (PostToolUse) — appends
timestamp | session | tool | file | ±linestodocs/CHANGELOG-AUTO.mdfor every tracked edit, and records whether the turn touched code, docs, or both. - stop-gate (Stop) — when Claude tries to end the turn: if code changed but
docs/didn't, it returns{"decision": "block"}and Claude must write the doc before finishing. Includes thestop_hook_activeloop guard. - guard (PreToolUse on Bash) — deny-list for destructive commands (
rm -rfon broad paths,git push --force,git reset --hard,DROP TABLE,.envexfiltration, credential directories). Hooks fire even under--dangerously-skip-permissions, so this holds in unattended runs.
The result: you cannot end a turn that changed source code without documenting it, and you get a free forensic edit log on the side.
Using it on an existing codebase
init is non-destructive, idempotent, and safe to re-run to pick up a new version:
- An existing
CLAUDE.mdgets our section appended, fenced in<!-- eng-skills:protocol:start -->markers. Your content is never touched, and a later version refreshes only what's inside the markers. - An existing
.claude/settings.jsongets our hooks merged in beside yours, de-duplicated by command. Your permissions and hooks are preserved. - An existing
.mcp.jsonkeeps its servers; ours is added. - Hooks, commands and skills are ours, so they upgrade in place — but only if you never
edited them.
initrecords a hash of everything it writes in.claude/.eng-skills.json, so it can tell "untouched, safe to update" from "the user changed this". If you did edit a file, it stays exactly as it is and the new version lands beside it as<file>.newwith adiffcommand printed.--forceoverrides that, on request.
That means re-running npx eng-skills init on a repo that already has it is the upgrade
path: you get new skills and fixed hooks, and keep every customisation you made.
Then open Claude Code and run /onboard: Claude reads your manifests, CI config,
and source layout, fills in every TODO(onboard) marker in CLAUDE.md (stack,
verified commands, hard invariants), and retroactively records your existing
architecture as ADRs — so the knowledge base starts warm, not empty.
The daily workflow
You don't have to remember the slash commands. CLAUDE.md contains an
intent-routing table: a plain "add a dark mode toggle" triggers the same
clarify → research → plan → implement → verify → document workflow as typing
/feature — casual phrasing doesn't skip steps. The commands are just explicit
shortcuts:
| Command | What it does |
|---|---|
| /kickoff <idea> | From-scratch projects: interviews you (mandatory questions), researches the competitive landscape ("what are others doing"), locks stack decisions as ADRs, writes the spec and phase roadmap — then scaffolds. |
| /feature <desc> | Asks clarifying questions first, researches the codebase (and web when useful) before writing code, writes a checkbox plan to docs/plans/, implements with TDD, verifies end-to-end, documents in docs/features/. |
| /fix <bug> | Reproduce first, root-cause (not symptom-patch), failing test → fix, document Symptom/Root cause/Fix/Verification/Prevention in docs/fixes/. |
| /decide <choice> | Numbered ADR with context, options, decision, consequences. Supersede — never delete — old decisions. |
| /phase status | Cross-checks the current phase checklist against reality (do claimed tests actually pass?). |
| /phase next <name> | Phase-gate closeout: verify acceptance criteria, get operator sign-off, open the next phase. |
Skills
Eight skills install to .claude/skills/ and trigger automatically — from their
description, so they fire on intent, not only on a slash command:
- brainstorming — before any non-trivial build: interviews the user
(batched clarifying questions are mandatory, not optional), researches the
codebase and the landscape (what libraries/products already solve this),
presents real options with trade-offs, and locks the user's choices into a
design spec in
docs/specs/. - root-cause — debugging discipline: reproduce before touching code, trace real data instead of theorizing, five-whys to the actual root cause, prove the fix with evidence, add prevention. Explicit anti-pattern list (no retry-loops, no sleep-fixes, no speculative change-stacking).
- frontend-verify — after any UI change: run the app, navigate with the chrome-devtools MCP, screenshot and look, check console messages and network requests, exercise the interaction, iterate 2–3×. "The code looks right" is not verification.
The next five encode the habits that decide whether an agent makes you faster or slower:
- prove-it — before saying anything is done. Replaces self-report with evidence from the
real artifact, and rates it on a ladder: you said so → you pointed at a
file:line→ you showed the bad case can't happen → you ran code that fails loudly if you're wrong → you reproduced it in the running app. Anything short of rung 4 is written "unproven", never rounded up. Never "tests pass" — paste the runner. - guard-context — when the window is filling: route bulk reading to a subagent, don't
read what you won't use, and reset rather than pushing through a degraded session.
Includes the two-strikes rule: two failed corrections on the same problem →
/clear. - blast-radius — before shipping a change you don't trust. Not "list the callers" (grep does that) but the breakage grep can't see: library internals, timing, wire formats, a DB column, production data written by the old code. Finds the one fact the change is safe because of, and proves it by running code.
- encode-lessons — the moment you write the same instruction twice. Routes the correction to the strongest available mechanism — unrepresentable state, lint rule, hook, canonical helper, runtime check — and deletes the prose, because the instruction is the symptom.
- adversarial-review — before merging anything risky. A fresh-context subagent reviews the diff, briefed to refute rather than approve, with one distinct lens per reviewer. The agent that wrote the code is never the one grading it.
For frontend projects (React/Vue/Svelte/Next/… detected in package.json), init
offers to add the chrome-devtools MCP
to .mcp.json — it asks first, merges with existing servers, and never overrides.
CLI reference
npx eng-skills init [dir] # scaffold (default: current directory)
--force # overwrite existing files
--dry-run # print what would happen, write nothing
--yes # accept recommendations without prompting (CI/scripts)
--no-mcp # never offer the chrome-devtools MCP configDesign principles (and their sources)
- "Give Claude a check it can run." Without a runnable check, "looks done" is the agent's only stop signal. The stop-gate is that check for documentation; the templates' Verification sections demand evidence (real command output), not assertions. — Claude Code best practices
- Hooks for zero-exception rules, CLAUDE.md for judgment calls. Anything that must happen every time is a hook; CLAUDE.md carries the judgment-dependent conventions. — Hooks reference
- Research before code.
/featurefront-loads codebase + web research so the plan is grounded in what exists, not what the model remembers. - Keep CLAUDE.md small. It loads into every session; every line costs context.
/onboardtargets ~120 lines. Long-form knowledge goes indocs/where it's read on demand. - ADRs are agent memory. Superseded decisions are marked, never deleted — the decision log is how session N+1 avoids re-litigating what session N settled.
Credits
prove-it, guard-context, blast-radius, encode-lessons and adversarial-review are
adapted for Claude Code from the corresponding skills in
pstack (principle-prove-it-works,
principle-guard-the-context-window, blast-radius, principle-encode-lessons-in-structure,
interrogate) — MIT licensed, © 2026 Lauren Tan. The ideas are theirs; the wording is rewritten
to fit this repo's docs/ protocol, hooks and commands. Worth reading the original — it ships
40 skills, most of which are outside this package's scope.
License
MIT
