Claude Code
Claude Code is an AI agent that takes consequential actions — running shell commands, editing files, opening PRs. Thefact0-claude-code plugin makes those
actions visible: it hooks every Claude Code lifecycle event (prompts, tool
calls, permission decisions, subagents, session start/end), maps it to the Fact0
audit/telemetry schema, and ships it to Fact0. Each coding session becomes a
hash-chained, queryable, governance-ready fact log — with zero per-session
configuration.
- Audit trail for AI-written code — who (agent vs. human vs. system) did what, when, against which resource, with what outcome.
- Execution telemetry — each session maps to a Fact0 execution; turns and tool calls become spans with causality, including subagent nesting.
- Governance — block dangerous tool calls before they run, and prove the decision afterward.
Install
Inside Claude Code:/fact0-status inside Claude
Code to confirm capture is active.
What gets captured
| Claude Code event | Fact0 record |
|---|---|
SessionStart | Starts a telemetry execution keyed by session_id |
UserPromptSubmit | Audit claude_code.prompt.submit (prompt SHA-256 + length) |
PreToolUse | Opens a TOOL_CALL span; governance decision point |
PostToolUse | Closes the span + audit event with the derived resource (file, command, MCP tool) |
Notification | Audit claude_code.permission.request |
SubagentStop | Nested span / causality edge |
Stop | Closes the turn span |
SessionEnd | Ends the execution and flushes |
agent for Claude itself, human for the
developer (OS user by default, or FACT0_CC_ACTOR_ID / FACT0_CC_ACTOR_EMAIL),
system for permission events.
Privacy model
Redaction happens on your machine before anything is sent, at one of three levels set byFACT0_CC_CAPTURE_MODE:
| Mode | What ships raw | What stays hashed |
|---|---|---|
metadata (default) | File paths, command text, prompts, tool names | File contents, tool outputs |
hash | Nothing — every string is SHA-256 + length | Everything |
raw | Everything, including contents and outputs | Nothing |
metadata default is what makes the Coding Agents dashboard view readable
(Edit api/handler.go, Bash go test ./...) without shipping file contents.
Use hash for locked-down environments.
Delivery guarantees
Hooks never block or slow the session, and a network blip does not lose events. When a send fails, the collector persists the payload to a local dead-letter queue and redelivers it automatically on a later hook invocation — oldest first, with original event timestamps preserved in the hash chain. Letters that fail 20 deliveries are kept for inspection but never retried.fact0-cc status
reports the pending count.
Executions self-heal too: if a session has no execution (the session-start call
failed, or the plugin was installed mid-session), the next hook lazily starts
one and telemetry resumes — no session ever permanently loses its trace.
Governance (block & prove)
Enforcement is off by default. Enable built-in safety rules (rm -rf,
curl | sh, secret writes) and/or your own policy file:
{match, tool, action, reason} — a regex tested against the
tool input. A matching deny blocks the tool call before it runs, and every
decision (allow or deny) is recorded as a POLICY_EVALUATION span in the
tamper-evident chain. Governance fails open: a bad policy file can never wedge
a session — the failure is recorded instead.
Verify the chain at any time:
Configuration
| Variable | Default | Purpose |
|---|---|---|
FACT0_API_KEY | — (required) | Authenticates the collector. |
FACT0_BASE_URL | https://api.fact0.io | Self-hosted / staging override. |
FACT0_CC_ACTOR_ID | OS user | Human actor identity for audit events. |
FACT0_CC_ACTOR_EMAIL | — | Human actor email (e.g. git email). |
FACT0_CC_CAPTURE_MODE | metadata | hash | metadata | raw — see Privacy model. |
FACT0_CC_ENFORCE | off | Enable built-in governance safety rules. |
FACT0_CC_POLICY_FILE | — | Path to a custom policy JSON. |
FACT0_CC_DISABLED | off | Disable the collector entirely. |
FACT0_CC_STATE_DIR | ~/.fact0/cc | Local state (session mapping, dead-letter queue). |
Agentless mode
For CI or locked-down hosts where shipping a binary isn’t possible, the plugin can POST events straight from Claude Code toPOST /v1/integrations/claude-code using HTTP hooks. Note that raw payloads
leave the machine before local redaction in this mode — prefer the default
binary collector for secret-bearing environments.
Related
- Audit API - the batch ingest and verify endpoints
- OpenTelemetry - complementary cost/token metrics feed