dotbabel

Quickstart

Last updated: v2.18.2

dotbabel is a verification layer for agentic development: skills that make an agent ground its claims in real source, and gates that check the result.

Two paths — pick yours:

I want… Path
Skills & commands in every Claude Code session Dotfile bootstrap — 30 seconds, no npm required
The CLI in my own repo (verification gates, local attestation, doctor) This page — 10 minutes, Node ≥ 20 required

CLI consumer — install to first green validator in under 10 minutes

1. Install

cd your-project
npm install --save-dev @dotbabel/dotbabel

The package has zero runtime dependencies. It registers seven bins under node_modules/.bin/:

harness
dotbabel-doctor
dotbabel-detect-drift
dotbabel-init
dotbabel-validate-specs
dotbabel-validate-skills
dotbabel-check-spec-coverage
dotbabel-check-instruction-drift

2. Scaffold the governance tree

npx dotbabel-init --project-name your-project --project-type node

This writes:

Every placeholder (,, ``) is substituted at scaffold time.

3. Run the self-diagnostic

npx dotbabel-doctor

You should see rows for env, repo, facts, manifest, specs, drift, and hook. The first run may warn about missing artifacts (e.g. docs/specs/ empty) — that’s expected until you draft your first spec.

A final row reports check-on-stop trust. On a fresh repo it reads “no trust allowlist”, which is informational and never fails the run — turn-end project checks are simply off until you opt in. See hooks.md.

4. Your first spec

Use the /spec skill (if you’re in a Claude Code session) or scaffold manually:

docs/specs/my-first-feature/
├── spec.json
└── spec.md

Minimum viable spec.json:

{
  "id": "my-first-feature",
  "title": "My first feature",
  "status": "draft",
  "owners": ["Your Name"],
  "linked_paths": ["src/my-feature/**"],
  "acceptance_commands": ["npm test"],
  "depends_on_specs": [],
  "active_prs": []
}

Validate it:

npx dotbabel-validate-specs

Green. You’re done.

5. Wire the PR gate

In GitHub branch protection, require the three shipped workflows:

Any PR touching a protected path (see docs/repo-facts.json) must now carry a Spec ID: or ## No-spec rationale section. dotbabel-check-spec-coverage enforces it.

6. Project-scope cross-CLI sync (optional)

If your repo has .claude/commands/*.md and .claude/skills/* that you want visible to Codex, Gemini, and Copilot — not just Claude Code — wire them up with project-sync. This is repo-local; user-scope artifacts stay in ~/.claude/ etc. via dotbabel bootstrap.

cd ~/projects/my-app

# 6a. One-time scaffold (writes .dotbabel.json + a starter CLAUDE.md if missing)
npx dotbabel project-init

# 6b. Preview, then apply
npx dotbabel project-sync --dry-run
npx dotbabel project-sync

# 6c. Verify (CI-safe, read-only)
npx dotbabel check-project-sync

What lands where:

Source Codex / Gemini destination Copilot destination
.claude/commands/<name>.md .codex/skills/<name>/SKILL.md (symlink) .github/prompts/<name>.prompt.md (symlink)
.claude/skills/<id>/SKILL.md .codex/skills/<id>/ (whole-dir symlink) .github/instructions/<id>.instructions.md (symlink)
CLAUDE.md (rule-floor block) rendered into AGENTS.md + GEMINI.md rendered into .github/copilot-instructions.md

.dotbabel.json is optional — without one, project-sync uses defaults (fan_out: ["codex", "gemini", "copilot"], the standard target list, no cli_substitutions). When CLAUDE.md has no <!-- dotbabel:rule-floor:begin --> markers, the whole file becomes the rule floor.

Add $schema to the top of the file for editor autocomplete and validation:

{
  "$schema": "https://dotbabel.dev/schemas/dotbabel.config.schema.json",
  "fan_out": ["codex", "gemini", "copilot"],
  "fan_out_layout": "per-cli",
  "gate_on_cli_presence": true
}

fan_out accepts only codex, gemini, and copilot. A typo such as co-pilot fails with CONFIG_UNKNOWN_CLI instead of being skipped.

fan_out_layout (default per-cli) decides whether Codex and Gemini get one tree each or share a canonical one. Under shared, the table above collapses: .claude/ fans out once to .cli/skills/, and .codex/skills and .gemini/skills become symlinks to it, so each command and skill is tracked once instead of twice. Copilot’s .github/ shapes are unchanged. Switching an existing repo backs the old trees up to .codex/skills.bak-<timestamp>; an unknown value fails with CONFIG_UNKNOWN_LAYOUT. Revert to per-cli if a CLI will not follow the redirect.

gate_on_cli_presence (default true) skips a CLI’s symlink fan-out when its binary is absent from PATH. check-project-sync applies the same gate, so it does not report the un-synced CLI as drift and instead prints skipped <cli>: not on PATH. Pass --all to either command to inspect every CLI in fan_out regardless. Instruction files are always written, never gated.

A repo with .dotbabel.json will also be picked up by dotbabel doctor — the diagnostic adds a project-sync wiring check.

Next