Claude Code integration
DACIP plays two roles inside a Claude Code session: a fact layer (the agent asks the MCP server instead of guessing symbols and routes) and a guardrail (a PreToolUse hook that judges an edit's effect on the contract graph before the write hits disk). Everything is deterministic and offline — no LLM anywhere in the pipeline, no code leaves the machine.
dacip install
One command writes the integration into the current repo:
dacip install
It writes or merges five files:
| File | What it adds |
|---|---|
.mcp.json |
the dacip MCP server (dacip mcp) |
.claude/settings.local.json |
a PreToolUse hook (dacip hook) matching Edit|Write|MultiEdit |
.claude/skills/dacip/SKILL.md |
the grounded workflow: facts first, validated plan, scoped edits, proven fixes |
CLAUDE.md |
a short DACIP section (only if one isn't already there) |
.gitignore |
.dacip/ |
Existing JSON is merged, never clobbered; if a target file exists but isn't valid JSON, install aborts (exit 2) rather than silently destroy your config. The hook goes into settings.local.json deliberately: it requires dacip on your PATH, and keeping it out of the committed settings spares teammates without DACIP a failing hook. Restart Claude Code afterward to load the server and hook.
The MCP server
dacip mcp is a stdio server exposing the fact graph:
| Tool | Facts returned |
|---|---|
dacip_context |
symbols/routes/API calls relevant to an objective, plus coverage |
dacip_find_symbol |
declared symbols (incl. methods) by name or fqname |
dacip_routes |
backend HTTP route contracts |
dacip_api_contracts |
frontend↔backend contract links, filterable by status |
dacip_impact |
where a symbol name is referenced (name-based; verify before relying) |
dacip_coverage |
what the facts do and do not cover for this snapshot |
dacip_refresh |
re-analyze after code changes |
dacip_findings |
persisted evidence-gated findings with verification commands |
dacip_workorder |
a scoped work order for one finding: facts, repro, plan skeleton, gate rules |
The installed skill tells the agent to always read dacip_coverage — DACIP states what it couldn't resolve, and the agent fills those gaps by reading source, not by guessing. The MCP process also hosts the resident guardrail daemon, which keeps the contract graph warm for sub-second gate decisions.
The edit gate
dacip hook runs on every Edit/Write/MultiEdit, before the write. It synthesizes the post-edit file in memory (nothing touches disk), re-extracts it, and computes a single-file graph delta. The edit is denied only if it would introduce BREAKING_ROUTE_REMOVED, CONTRACT_REGRESSION, or AUTH_MARKER_REMOVED and the active plan's contract_changes doesn't authorize it. The denial carries the blast radius — the exact orphaned call sites with file:line (e.g. renaming GET /api/users/mentionable is denied naming mention-autocomplete.tsx:46) — plus both ways forward: add the route key to the plan's contract_changes and re-run dacip validate-plan, or keep the contract intact.
When a plan is active (approved via dacip validate-plan), the hook also enforces its files_to_modify scope; an out-of-scope edit is denied with the plan id, the approved file list, and the fix (widen the plan, dacip plan clear, or override).
Fail-open, loudly
The guardrail never lies and never hangs:
- Daemon absent or slow → the hook falls back to plain file-scope gating with a visible
[file-scope only — guardrail daemon not running]note. Never a silent block, never a hang. - Extraction error, unsynthesizable edit, or any internal guardrail bug → allow, with the reason in the decision. Failure to analyze is never presented as "clean."
- Every decision and its latency lands in
.dacip/runs/hook_metrics.jsonl(measured p50 ~476 ms on a 500-file repo; ~100 ms for TypeScript files).
Ceilings
- The gate covers file-edit tools (Edit/Write/MultiEdit) only. Bash writes are not gated — the skill instructs the agent not to sidestep the plan that way, but the hook can't stop it.
- Deny decisions are enforced-with-override: a human override outranks the gate, always. The denial message says so explicitly.
- No
.dacipstore or no active plan → the hook allows and says why, pointing at the command that would enable gating.
A standalone Claude Code plugin ships the same three pieces (MCP server, hook, skill); it's a thin layer that stays inert without the dacip CLI on PATH. See the FAQ for licensing and the proof dashboard for measured gate behavior on the pilot repos.

