Skip to content

The agentic layer

Rules, skills, agents, hooks, solution docs and MCP servers. What each hook does, when it runs, and what Codex and Cursor get.

8 min read

PagesThe agentic layer

Plenty of starter kits wire up Stripe. That part is table stakes. This generator exists for the layer on top: the config that lets an agent open the repo cold and act like it has worked here for a month.

That layer has six parts. They are the six fields of the AgentLayer type in packages/core/src/types.ts, and the six counters in the builder. Every generated repo ships rules, skills, agents, hooks and solution docs. MCP servers come with the batteries that have one (9 of 26), so a Blank repo has none.

LayerWhere it landsWhat it is for
Rules.claude/rules/*.md, AGENTS.md, .cursor/rules/*.mdcConventions, scoped to the paths they govern
Skills.claude/skills/<name>/SKILL.md, .agents/skills/Repeated work, as a slash command
Agents.claude/agents/*.mdSubagents with their own prompt and tool list
Hooks.claude/hooks/* + .claude/settings.jsonChecks that run around a tool call. Wired for Claude Code
Solution docsdocs/solutions/The mistakes, written down in advance
MCP servers.mcp.jsonTools the agent can call

A battery that only adds files is a worse version of installing the package yourself. That is why the contribution gate exists: no config, no battery.

Rules are path-scoped

A rule is markdown with a paths: list in its frontmatter:

---
title: Never build Stripe objects client-side
paths:
  - src/lib/billing/**
  - src/app/api/webhooks/stripe/**
---

Verify every webhook signature. Build every Stripe object on the server.

Scope matters more than content. Put forty rules in one CLAUDE.md and the agent loads all forty on every task. Each one costs context, relevant or not. A rule on src/lib/billing/** loads when the agent reads a billing file. The agent editing a marketing page never sees it.

The stack ships seven rules in every repo:

  • code-style, git and security load every session.
  • testing covers tests/** and test files under src/.
  • deployment covers next.config.ts, vercel.json, package.json, src/proxy.ts, src/app/**/route.ts and .env.example.
  • ui-kit covers src/components/** and src/app/**: build from the component kit, never a one-off.
  • landing-and-legal covers src/lib/site.ts, the landing page, the legal pages and /llms.txt.

Two more come with the features they govern. app-shell ships with any auth battery and covers the signed-in app. billing-core ships with any payments battery and covers the shared billing layer. The design adds tokens-only. Batteries add rules for the paths they own.

Rules are checkable statements, not advice. "Before you finish a task, re-read the files you touched" is a rule an agent can follow. "Write clean code" is not.

Skills are the repeated work

A skill is a slash command with instructions attached. The stack ships /verify, /write-spec, /qa-feature, /deploy-to-vercel, /security-audit, /landing-copy and /help. With an auth battery it adds /add-app-page, and with a payments battery /edit-pricing. Every design adds /new-component. Batteries add their own:

  • Stripe and Lemon Squeezy: /add-plan, /test-webhook
  • Polar and Dodo: /add-product, /test-webhook
  • Better Auth: /add-oauth-provider, /protect-route
  • Admin panel: /add-admin-page, /add-admin-action
  • Neon: /db-branch, /migrate-on-neon
  • Drizzle: /add-table, /migrate
  • PostHog: /add-event, /ask-product

The test: have you explained it twice? The third time, write it down.

Agents are narrower than the main thread

Four subagents ship with the stack:

  • pr-reviewer: reviews against this repo's rules, not general taste.
  • security-auditor: secrets, auth boundaries, injection, dependency scan.
  • documentarian: keeps README, DESIGN.md and the solution docs current.
  • system-manager: owns .claude/ itself, and adds a rule when a correction repeats. It is why the setup gets better instead of going stale.

Every design adds designer. Batteries can add specialists. Neon ships db-inspector, which is told to run SELECT and EXPLAIN only. Its Neon MCP server is read-only (?readonly=true in .mcp.json). It still has Bash, so only its prompt stands between it and a write through psql. The guard-neon-sql hook blocks DDL and unqualified delete, not insert or update. PostHog ships product-analyst.

Hooks: checks the model can't skip

Rules are instructions. An agent can misread them. Hooks are code that Claude Code runs around a tool call.

  • A PreToolUse hook runs before the call. Exit code 2 (or a deny decision) means the call never happens, and the agent is told why in the same turn. It can also rewrite the call.
  • A PostToolUse hook runs after the call. It can't undo it. It can report a problem to the agent, or redact what the agent sees.
HookRunsWhat it doesShips in
block-destructiveBefore BashRefuses recursive force deletes, DROP and TRUNCATE sent to a database, force pushes, git reset --hard, git clean, dd, and truncating redirects onto tracked files.Solo and team
env-leak-detectorBefore Bash, Read, GrepRefuses anything that would print, send or commit a secret: echo $DATABASE_URL, grep KEY .env.local, the Read tool on .env.local, a bearer token in a curl header, git add .env. It also matches live values read from your env files, so a real key is caught even when the command looks innocent.Solo and team
env-leak-detector-writeAfter Edit, Write, MultiEdit, Bash, Read, GrepReplaces any live secret in command, read or search output with [redacted: KEY] before the agent sees it. On writes, it flags a key pasted into a file, a private env var read in a client component, and a secret inside a log call.Solo and team
enforce-typecheckBefore BashRewrites a bare tsc (or npx tsc, ./node_modules/.bin/tsc) into the project's typecheck script before it runs, through the hook's updatedInput. Blocks a tsc inside $(...) or bash -c, where there is nothing clean to rewrite.Solo and team
auto-lintAfter Edit, Write, MultiEditRuns Biome on the one file that changed, applies the safe fixes, and reports what it could not fix.Solo and team
enforce-doc-metaAfter Edit, Write, MultiEditChecks the frontmatter on files in docs/solutions/ and docs/plans/, and says what is missing.Solo and team
enforce-git-trackedBefore BashRefuses a git commit while untracked files exist.Team only
plan-gateBefore Edit, Write, MultiEdit, NotebookEdit, BashRefuses writes under src/ until a plan in docs/plans/ says status: approved. See solo and team mode.Team only
guard-neon-sqlBefore BashRefuses raw DDL through psql, migrations that would run through the Neon pooler, and schema pushes that skip migration files. The repo's own db:migrate scripts pass.Neon battery

How many you get:

  • Solo: 6 hooks. 3 run before the call, 3 after.
  • Team: 8 hooks. 5 before, 3 after.
  • Neon adds 1, before the call.

Know the limits. env-leak-detector-write runs after the write lands, so the secret is on disk before the agent is told to remove it and rotate it. No hook stops a human pasting a key into a file by hand.

Prove they work

A guard is only worth something while it is still wired up. Every generated repo ships a self-test:

bun run verify:hooks

It runs every installed hook, battery hooks included, the way Claude Code does: the command from .claude/settings.json, a hook payload on stdin. Each hook gets block cases and allow cases. Block cases run again from src/, as they would after the agent runs cd. A hook that lets a block case through, or blocks an allow case, fails the script. Run it on a fresh clone and after any change to .claude/.

Solution docs are memory

docs/solutions/ is seeded per battery: idempotent Stripe webhooks, edge session pitfalls with Better Auth, Neon pooling and branching, the PostHog identify race, Sentry source maps on Vercel. The problems your team was going to hit in week three, written before week one.

Every one is also public in the cookbook. Contributors write them for a stranger, because a stranger is who reads them.

New ones get written as you go. /ce-compound at the end of a piece of work turns a debugging session into a doc instead of letting it evaporate.

MCP servers

Batteries declare MCP servers in their manifest, and the generator merges them into .mcp.json. 9 of the 26 batteries ship one: Better Auth, DataFast, Neon, Polar, PostHog, Postmark, Sentry, Stripe and Supabase. A server that doesn't exist is worse than none, so the registry only ships real ones.

What each agent target gets

Agent config is written once in a neutral format and compiled per target. Claude Code is always a target.

RulesSkillsAgentsHooksMCP
Claude Code.claude/rules/*.md, scoped by paths:.claude/skills/.claude/agents/Wired in .claude/settings.json.mcp.json
CodexRoot AGENTS.md plus a nested AGENTS.md per path prefix.agents/skills/Not compiledNot wiredNot compiled
Cursor.cursor/rules/*.mdc with globsOne skill-<name>.mdc each, loaded on requestNot compiledNot wired, but see belowNot compiled

The repo writes hooks for Claude Code only. It writes no Codex or Cursor hook config.

  • Codex reads its own hook file, so out of the box it runs none of these guards. The rules in AGENTS.md are all it has.
  • Cursor can load Claude Code hooks from .claude/settings.json (its third-party hooks setting, on by default). So the guards may fire there too. We only test them under Claude Code.

If your team runs Codex and wants the guarantees, run destructive work through Claude Code, or port the guards to Codex hooks. Don't assume a file being present means a guard is running.

The workflow on top

.claude/settings.json declares the Compound Engineering plugin's marketplace, pinned to a release tag, and enables the plugin. It is not forked. Claude Code adds the marketplace once you trust the folder. If the commands are missing, CLAUDE.md has the one-line install.

You get /ce-brainstorm, /ce-plan, /ce-work, /ce-code-review and /ce-compound. Plans land in docs/plans/. Learnings land in docs/solutions/. The loop closes.

The pin is on purpose. An upstream breaking change should be something you upgrade into, not something that shows up one morning mid-task.