baseline / v0.4
friedbotstudio/baseline

Claude Code · constitutional baseline

A discipline layer
for Claude.

Constitutional governance, structural enforcement, and a workflow that runs from intake to commit. The baseline ships 22 hooks, 36 skills, and one subagent. Every phase produces one artifact, every gate is user-typed, and Claude cannot self-approve.

v0.4 · Apache 2.0 · open source

browse the 36 skills

22Hooks
36Skills
1Subagent
11Phases
4Gates

§ I

What it is

A repository overlay for Claude Code. It sets the rules Claude follows in this codebase, in this session, with the hooks that enforce them at the tool boundary. Memory, prompts, and skills are helpful. Hooks are load-bearing.

I II III IV
IGenesis IIConstitution IIIImplementation IVTool boundary

01 · Constitution

CLAUDE.md as in-session contract

Ten articles bind authority, architecture, workflow ordering, engineering rules, git rules, and project memory. Genesis lives in seed.md; the constitution governs in-session behavior; hooks enforce the constitution.

02 · Enforcement

22 hooks at every boundary

Pre and post tool-use guards block destructive commands, gate consent markers, validate spec diagrams, and enforce phase ordering. Hooks run outside Claude's tool boundary, which is why Claude cannot forge an approval.

03 · Workflow

Eleven phases, four gates

Intake to commit, in order. Three workflow-phase consent gates are user-typed slash commands: /approve-spec at phase 5, /approve-swarm at phase 6's swarm fork, and /grant-commit at phase 11. A fourth, /grant-push, sits outside the phase pipeline and gates pushes to protected branches. Skipping any phase needs an explicit exception in workflow.json, written by triage.

§ II

Why hooks

Hooks run outside Claude's tool boundary. When a hook blocks a tool call, Claude never executes it. The dashed lines below are the surfaces Claude cannot reach. Memory is helpful, prompts are helpful, hooks are load-bearing.

Hooks intercept the path between user, Claude, and tools. User types a prompt Claude reads, plans, picks tool Tool Write · Edit · Bash Result diff · output · error UserPromptSubmit consent_gate_grant outside Claude's reach PreToolUse 12 guards block · ask · allow PostToolUse lint_runner test_runner
The tool boundary. Hooks fire at the dashed lines. Three of those events are guarded enough to make consent unforgeable: the consent_gate_grant hook on UserPromptSubmit writes the marker; the corresponding PreToolUse guard validates it before allowing the approval-token write.

§ III

How it flows

One pipeline, request to commit. Order is enforced at the write boundary by track_guard. The two filled squares are the consent gates on the main path. A third gate (/approve-swarm) sits inside the TDD-swarm fork of phase 6. A fourth (/grant-push) sits outside the phase pipeline and gates pushes to protected branches. All four are user-typed commands; Claude can't reach the code path that writes the markers. The tail is a paired ending: after /grant-commit, phase 11.5 (changelog) classifies the staged diff into keepachangelog 1.0.0 sections under ## [Unreleased], then phase 11 (commit) stages and writes the commit. The bento marks the two as the ship pair.

Bento composition of the eleven-phase workflow. The plan anchor is spec; the execution arm is tdd. Archive and memory-flush are paired endings; changelog and commit are paired as the ship pair. Three small inline cells mark consent gates A (/approve-spec) and C (/grant-commit). The runtime gate /grant-push sits below the grid with distinct visual treatment because it is outside the phase pipeline. Phase order: intake, scout, research, spec, gate /approve-spec, tdd, simplify, security (optional), integrate, document, archive, memory-flush, gate /grant-commit, changelog, commit. Runtime gate /grant-push fires on git push to a protected branch under Article VII. Diagram renders as an asymmetric bento at viewports wider than 768px and as a vertical stack at narrower viewports. PLAN ANCHOR 04 spec Diagram-driven source of truth. Every AC traces to a sequence; every component to a write_set. Spec-lint and diagram-review gate the draft before /approve-spec. docs/specs/<slug>.md next: /approve-spec → tdd EXECUTION ARM 06 tdd Scenario then implement then verify. Re-runs until verify is binding PASS. scenario implement verify design-ui drift-check solo · or swarm (≥3 components in a git repo) worktree-isolated when swarmed · 5-iter RALPH 01 intake 02 scout 03 research USER-TYPED /approve-spec 07 simplify 08 security OPTIONAL 09 integrate 10 document PAIRED · CLEANUP SHIP PAIR 10.5 archive 10.6 memory-flush /grant-commit 11.5 changelog 11 commit RUNTIME GATE · ART. VII · /grant-push fires on git push to a protected branch · five-minute consent window 01 intake 02 scout 03 research USER-TYPED /approve-spec PLAN ANCHOR 04 spec Diagram-driven source of truth. → /approve-spec EXECUTION ARM 06 tdd scenario → implement → verify → design-ui → drift-check solo · or swarm 07 simplify 08 security OPTIONAL 09 integrate 10 document PAIRED 10.5 archive 10.6 memory-flush /grant-commit SHIP PAIR 11.5 changelog 11 commit
Eleven phases, four gates. The composition reads as five zones: a preamble strip (intake, scout, research), the plan anchor (spec as the hero cell), the execution arm (tdd as a tall right-side cell), a mid strip (simplify, security, integrate, document), and the paired endings (archive with memory-flush; changelog with commit as the ship pair). The two filled accent squares mark workflow-phase gates /approve-spec and /grant-commit. The third phase gate, /approve-swarm, sits inside phase 6's swarm fork and is not shown. The fourth gate, /grant-push below the grid, is a runtime gate that opens a five-minute window for git push on a protected branch. For every gate, the UserPromptSubmit hook writes a short-lived consent marker, and the next PreToolUse guard validates it before the approval-token write goes through. Claude cannot reach the marker path. At viewports narrower than 768px, the bento collapses to a single-column vertical stack in temporal order.

§ IV

Architectural principle

Decisions live in main context. Subagents only execute pre-decided recipes in parallel. The baseline ships exactly one subagent: swarm-worker. It runs scenario then implement against a fully-specified recipe inside an isolated git worktree, and never makes design choices.

§ V

Adoption

One npx command lays down the full overlay: hooks, skills, subagent, MCP servers, and the constitutional documents. Then run /init-project in Claude Code to scout the repo and tailor the config to your stack.

  1. 01Run the overlay command in a clean working tree.
  2. 02Open the repo in Claude Code (or the JetBrains / VS Code extension).
  3. 03Run /init-project to populate project.json for your stack.
  4. 04Drive work through /triage or /harness.
~/your-repo · zsh
# inside a clean git working tree
$ npx @friedbotstudio/create-baseline@latest .

# open in claude code, then:
> /init-project
> /triage "add user-facing onboarding flow"

§ VI

Common questions.

The questions evaluators ask before installing, and the structural answers. Every answer names the mechanism that backs it.

Will it commit to my repo without me knowing?
No. Gate C requires a typed /grant-commit within the last five minutes; without a fresh consent token at .claude/state/commit_consent, the git_commit_guard hook blocks the git commit Bash call. The consent marker is written on UserPromptSubmit, outside Claude's tool boundary. Claude cannot forge it.
What if I want Claude to do something the baseline forbids?
Add a named exception to .claude/state/workflow.json via /triage. The exception is recorded, scoped to the current workflow, and visible to the audit. Nothing else changes; the rest of the constitution still binds.
Can I disable a hook?
Yes, but it requires an explicit amendment to seed.md §4.1 plus the corresponding edit to .claude/settings.json. The disable is constitutional, not silent. The audit (audit-baseline) will catch a settings.json that does not match the seed declaration.
Does it work without git?
Yes. On a non-git project, gate C and phase 11 auto-except at triage time; the workflow ends after /archive. Persistence is on you. Article VII of the constitution scopes git rules to repositories that have .git/ on disk.
Will my existing .claude/ customizations survive an upgrade?
Run npx @friedbotstudio/create-baseline ./project --merge. The CLI does a three-way reconcile against .claude/.baseline-manifest.json: untouched files refresh from the new template, customized files preserve byte-for-byte (exit code 3 reports them), and baseline files removed upstream that you had not touched are pruned automatically.
Does the baseline ship its own Claude Code?
No. The baseline is a repository overlay: the in-session ruleset, the hooks, the skills, the workflow. You bring your own Claude Code. Install Claude Code separately (claude.com/claude-code), run npx @friedbotstudio/create-baseline in your project, then open the project in Claude Code.
What if /init-project gets my stack wrong?
Re-run it, or hand-edit .claude/project.json directly. Both are sanctioned. The drift check at bash .claude/skills/audit-baseline/audit.sh reports any mismatch between your declarations and the implementation.
Where do my project secrets go?
Not into the baseline. The env_guard hook blocks every Edit / Write targeting .env or .env.* files (the one exception is .env.example, which is template-shaped). Secrets stay in your existing secret store; the baseline never touches them.
Will it work on a large existing codebase?
The baseline is project-agnostic by default. It installs without scanning your code. /init-project then scouts the repo, runs the recommender, and proposes a tailored project.json (test command, lint command, TDD source globs, destructive-pattern extensions, optional stack-specific MCP servers and skills). You approve each addition before it lands.
How big is the install?
About 1.5 MB unpacked: 22 hooks, 36 skills, 5 consent commands, 1 subagent, the constitution, the genesis prompt, and three MCP server declarations. The PlantUML jar is a 19 MB side-fetch and is skipped if plantuml is already on your $PATH.