DACIP DACIP

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 .dacip store 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.