Forge playbook — top-tier project-CLAUDE.md generation
Why this exists
A thin CLAUDE.md that is just a bullet list of file paths gives an agent no real leverage — it doesn't say
what the project actually IS, which of the owner's global rulesets actually apply here, or which rules are
non-negotiable. Deep research on Anthropic's own published best practices (code.claude.com/docs/best-practices,
the Agent Skills docs, and independent 2026 field guides) converges on the same verdict: the worst CLAUDE.md
files aren't empty, they're thorough ones — bloat dilutes the rules that matter until Claude quietly stops
following them. The gold-standard shape (proven in the AutoWeb project, now formalized against that research)
is a real PROJECT BRAIN: a tight five-part core (description, stack+versions, exact commands, architecture,
conventions) + boundaries + pointers to detail docs, environment rules ADAPTED to the project's real tooling,
universal anti-generic guardrails kept verbatim, a real Hard Rules section, and Governance. This skill is the
repeatable METHOD for producing that shape for any Forge project; forge-bin/forge-projectbrain.cjs automates it.
The research this method is built on (cite before you deviate)
- The five-part core framework: (1) one-line project description, (2) tech stack with versions, (3) EXACT build/test/lint/run/deploy commands, (4) architecture as 3-5 key dirs with file:line-style pointers (never prose describing a "typical" layout), (5) conventions a linter can't enforce. Plus boundaries/off-limits dirs and pointers to detail docs.
- The prune test (official Anthropic guidance): for every line, ask "would removing this cause Claude to make mistakes? If not, cut it." A bloated CLAUDE.md causes Claude to ignore the instructions that actually matter — conciseness is not a nice-to-have, it is the mechanism that keeps the file effective.
- EXCLUDE, always: anything derivable from the code itself, standard conventions Claude already knows, file-by-file listings, pasted code blocks, frequently-changing information, and "obvious advice" filler ("write clean code", "follow best practices"). None of these belong in a generated CLAUDE.md.
- Imperative language, not hedging: "Never commit
.env" beats "we generally prefer not to commit .env". - Emphasis discipline: reserve IMPORTANT/YOU-MUST-style emphasis for the 1-2 truly critical rules (honesty, project-isolation) — emphasizing everything is the same as emphasizing nothing.
- A practical line budget (guidance, not a hard gate): keep the generated document in the neighborhood of ~150-200 lines for a typical project. The verbatim anti-generic guardrails block for website-flavored projects is a deliberate, documented exception to that budget (see step 3) — verbatim reuse there is a strength, not bloat, because it is the SAME trusted rule every project quotes.
- KEY INSIGHT — skills/docs are NOT reliably auto-invoked. Independent evals (Vercel) measured a 56% non-invocation rate for progressive-disclosure Skills matched only by a vague trigger description. A Hard Rule or an environment-ruleset line is not a Skill — it is always-loaded text — so every rule this generator emits must be a sharp, explicit, self-contained imperative ("Apply the frontend-design method before writing ANY frontend code"), never a bare pointer like "see the frontend-design skill for guardrails." When a real Skill genuinely needs to be referenced, name WHEN it triggers, not just that it exists.
@-imports buy organization, not context budget. An@pathreference inside CLAUDE.md loads automatically alongside it at session start (unlike a Skill) — so the generated "Detail docs" pointers are honest about that: they are real, but they are not a free lunch, and each imported doc should stay focused.
The method (five steps)
Detect the real stack — never assume. Read
package.json(name, description, scripts, dependencies, devDependencies — capturing each framework's LITERAL declared semver range, never a resolved/guessed installed version), look for a framework signature (Astro/Next/Vite/React/Vue/Svelte/Angular/Express/ Fastify/NestJS/Electron), look for an n8n workflow export (workflows/*.jsonwithnodes/connections), read real ports ONLY from a literal--port N/PORT=Nin a script or.env.example, list up to 5 real top-level source directories (excluding build/dependency/tooling noise) with a real entry-file pointer when one genuinely exists, and list up to 4 real detail docs (README.md+docs/*.md) that already exist.forge-projectbrain.cjs::detectStack()does all of this programmatically; if you're doing it by hand, the same discipline applies: only claim what a real file proves — an honest "not detected" note always beats a plausible-looking guess.Select the applicable global ruleset(s) and ADAPT them. Pick the owner's global ruleset(s) that match the detected project type (frontend-website rules for
website/fullstackfrontends, n8n rules forautomation-n8n, the domain principles in the owner's own global CLAUDE.md for other types). Rewrite the environment-specific subsections (local server / screenshot command / output defaults / domain-specific hard rules) to name the project's REAL commands, ports, and file conventions — and flag every adapted line`[<ProjectName>]`(or`[<ProjectName> — adapted]`) so a reader can tell "this is now true HERE" from "this is the generic default". This is exactly what distinguishes AutoWeb's CLAUDE.md (Astro + Playwright,[AutoWeb]-flagged throughout) from a copy-pasted generic template.Keep universal guardrails + honesty core VERBATIM. The anti-generic design guardrails (colors, shadows, typography, gradients, animations, interactive states, images, spacing, depth) and the honesty-core principle ("never claim a check/test/build ran unless it actually ran") are NOT project-specific — copy them unchanged. Do not water them down and do not re-word them per project; verbatim reuse is a strength, not laziness — it means every project quotes the same trusted rule (and it is the one deliberate exception to the line-budget guidance above).
Emit the five-part core PLUS boundaries and detail-doc pointers. In order:
## Project identity(name/type/stack+versions/tooling/ports, no prose),## Commands(every real script, verbatim — placed near the top because it is the highest-ROI content: an agent that knows the real command makes fewer mistakes than one that guesses),## Architecture(the real key dirs from step 1, never a fabricated "typical layout"),## Conventions(a linter can't enforce these — tie every bullet to something step 1 actually detected, never an invented project-specific rule), the adapted environment ruleset from step 2,## Boundaries(universal off-limits dirs —node_modules/, build output,.git/— plus this project's own.claude/when it genuinely exists), and## Detail docs(real@pathimports of the docs found in step 1, or an honest "none found yet" note — never a fabricated pointer to a file that doesn't exist).Emit a real
## Hard Rulessection wired toFORGE_HARD_RULES.json, then## Governance, and SAFE-MERGE the write. Start from Forge's universal non-negotiables (project isolation, honesty core, secrets-in-env, no-auto-push, input validation, file-size discipline —DEFAULT_HARD_RULESinforge-projectbrain.cjs). If<project>/.claude/FORGE_HARD_RULES.jsonexists, merge its{id,text}entries in (a project can EXTEND the list, never silently override a universal id) — this file is the machine-checkable source a futureforge-doctorpass can read to verify the rules are actually being followed, not just documented. Reserve IMPORTANT-style emphasis for exactlyhonesty-coreandproject-isolation— every other rule stays a plain, still-imperative bullet. Governance names the real Forge memory files (FORGE_MEMORY.md,FORGE_DECISIONS.md,FORGE_AGENT_LEDGER.md,FORGE_TASK_HISTORY.md), states secrets live in.envonly, and reiterates never-auto-push / no production changes without explicit approval. Never blindly overwrite an existing CLAUDE.md. If the target file already has Forge-managed markers (<!-- FORGE-PROJECTBRAIN:BEGIN v1 -->/<!-- FORGE-PROJECTBRAIN:END -->), replace only that marked region — everything the owner wrote outside it is preserved untouched. If the file exists with NO markers, refuse to write unless the caller explicitly opts into a full overwrite (--force) — an unmarked file is presumed hand-authored by the owner and must never be silently clobbered.
Using the companion tool
node .claude/forge-bin/forge-projectbrain.cjs detect --dir <projectDir> [--json]
node .claude/forge-bin/forge-projectbrain.cjs generate --dir <projectDir> [--out CLAUDE.md] [--force]
generate without --out only prints to stdout (safe to inspect before writing anything). See
template.md in this folder for the annotated structure the generator's output follows, and
forge-bin/forge-projectbrain.test.cjs for the real hermetic proof (three project-shape fixtures + the
research-enriched core-framework sections + safe-merge behavior + a mutation-verified Hard-Rules-emphasis and
Architecture-entry-pointer check).
Hard rules for this skill itself
- Never invent a stack, framework, version, port, directory, doc, or script the real files don't show — an honest "not detected" note beats a plausible-looking guess, in every one of the five core sections.
- Never silently overwrite an owner-authored CLAUDE.md that has no Forge markers.
- Every environment-adapted rule must carry a
[<ProjectName>]flag; unflagged text must be the verbatim universal guardrail/honesty-core wording, not a paraphrase. - Never render an excluded phrase (obvious advice, "write clean code"-style filler) or a pasted fenced code block — a generated CLAUDE.md states real facts and real non-negotiables only.
- Reserve emphasis (
**IMPORTANT:**) for exactlyhonesty-coreandproject-isolation; every other Hard Rule is a plain bullet. - This skill produces documentation/config only — it does not touch secrets, does not deploy, and does not
register the
projectbrain_generatedevent_type itself (the event_type is registered in log-event.cjs; the calling Boss/skill step owns the real log call, same doctrine as forge-scout.cjs/forge-capabilities.cjs).