Claude Code · constitutional baseline
A discipline layer
for Claude Code.
Constitutional governance, structural enforcement, and a workflow that runs from intake to commit. The baseline ships 24 hooks, 42 skills, and one subagent. Every phase produces one artifact, every gate is user-typed, and Claude cannot self-approve.
§ 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.
01 · Constitution
CLAUDE.md as in-session contract
Eleven 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
24 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 tracks
7 canonical tracks, declared in workflows.jsonl
Every kind of work the baseline runs is a track: a DAG of skill nodes with dependencies, consent flags, and optional parallel clusters. 7 canonical shapes ship in the pristine template, declared in .claude/workflows.jsonl. Triage classifies the request and presents the picked track plus alternates via AskUserQuestion; harness walks the chosen DAG.
§ 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.
§ III
How it flows
A track is a DAG of skill nodes. The file .claude/workflows.jsonl holds the canonical set, one record per line, and the validators check eleven invariants on every read. The harness loads the chosen track, walks the DAG, resolves selector nodes by evaluating preconditions in declaration order, expands sub-tracks inline, and dispatches can_parallel clusters concurrently. The diagram below shows the intake-full track, which runs from intake to commit through eleven nodes. Three filled squares mark the consent gates. A fourth gate (/grant-push) sits outside the phase pipeline and gates pushes to protected branches. All four are user-typed commands; Claude cannot reach the code path that writes the markers.
intake-full track. Eleven nodes from request to commit. 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 closing nodes (archive with memory-flush; commit as the ship node). The two filled accent squares mark workflow-phase gates /approve-spec and /grant-commit. The third phase gate, /approve-swarm, sits inside the swarm-implementation sub-track of phase 6 and is not shown. The fourth gate, /grant-push below the grid, opens a five-minute window for git push on a protected branch. The other tracks ship in the same workflows.jsonl: spec-entry (skips intake, scout, research), tdd-quickfix (starts at tdd), chore (no failing-test-driven node), freeform (closing sequence only; relaxed phase ordering), epic (discovery once, then a sliced spec), and epic-child (inherits the epic's discovery). 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.
Where decisions live
Architecture, scenario selection, recipe design, security calls. Anything that depends on conversational visibility, including screenshots and prior rounds.
- scout · research · spec
- scenario decide
- implement decide
- merge audit
Where execution runs
The single subagent (swarm-worker) executes a fully-specified recipe. No design choices, no scope expansion, no test edits.
- Skill(scenario)
- Skill(implement)
- tests pass · fail
- JSON status returns
§ 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.
- 01Run the overlay command in a clean working tree.
- 02Open the repo in Claude Code (or the JetBrains / VS Code extension).
- 03Run
/init-projectto populateproject.jsonfor your stack. - 04Drive work through
/triageor/harness.
# 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?
/grant-commit within the last fifteen 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?
.claude/state/workflow.json via /triage. The exception is recorded, scoped to the current workflow, and visible to the audit. For a recurring need that the 7 canonical tracks do not cover, declare a project-local track in .claude/workflows.jsonl instead. The declared track binds against the same Article IV invariants and survives baseline upgrades verbatim (the file is tier-classified NEVER_TOUCH).Can I declare my own workflow track?
.claude/workflows.jsonl, one record per line. Each track is a DAG of skill nodes with depends_on, blocks, can_parallel, and optional needs_user consent flags. Selector nodes pick among alternates by evaluating declarative preconditions. The file is tier-classified NEVER_TOUCH; baseline upgrades preserve your additions verbatim. Article IV's eleven invariants bind every track regardless of who wrote it; a malformed track is rejected at triage time with a named error citing the violated invariant. Run /init-project doctor to validate your file against the shipped JSON Schema and the invariants before triage runs.Can I disable a hook?
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?
/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?
npx @friedbotstudio/create-baseline upgrade ./project. The CLI does a three-way reconcile against .claude/.baseline-manifest.json: untouched files refresh from the new template, customized tier-1 files (BASE unrecoverable) prompt keep-your-version / use-new-baseline / merge / abort in a TTY (merge stages incoming bytes for /upgrade-project to reconcile, exit 5), tier-2 files auto-merge via git merge-file --diff3, tier-3 files stage for the /upgrade-project Claude Code skill to reconcile, and baseline files removed upstream that you had not touched are pruned automatically. Per-file actions are reported in CI with exit 3 for any preserved customisation.Does the baseline ship its own Claude Code?
npx @friedbotstudio/create-baseline in your project, then open the project in Claude Code.What if /init-project gets my stack wrong?
.claude/project.json directly. Both are sanctioned. The drift check at node .claude/skills/audit-baseline/audit.mjs reports any mismatch between your declarations and the implementation.Where do my project secrets go?
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?
/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?
plantuml is already on your $PATH.