HOW IT WORKS
No magic. Just hooks, git, and standards.
We don't read your code. We don't run AI to detect AI. We use hooks the agents already provide and we use git itself as the database.
"Use a model to detect AI-generated code from the diff."
It doesn't work. Detection accuracy hovers around 60%. False positives. False negatives. And once a developer touches the AI code, the signal is gone.
The complete flow
From Claude editing a file to your dashboard
- The agent fires a PreToolUse hook
Before Claude Code (or Cursor, Codex, Windsurf) edits a file, it calls a registered hook with the tool name and target file. We capture a snapshot.
The agent fires a PreToolUse hook# ~/.claude/settings.json
$ "PreToolUse": [{ "command": "iria-monitor ai-checkpoint claude-code" }]
- The agent edits the file
Normal Claude/Cursor behavior. Nothing intercepted. The user accepts or rejects in their normal flow.
- PostToolUse fires — we diff
The agent calls the post-hook. We compare snapshot vs current. The new lines are AI's. The unchanged ones are human's. We attribute, we don't guess.
PostToolUse fires — we diff# lines 5-18 are now attributed to:
$ claude-code/claude-sonnet-4-6 (session abc123)
- Append to the working log
Attribution gets stored in
.git/ai/working_logs/a1b2c3d.jsonl. Append-only, file-locked, safe under concurrent edits. - git commit triggers post-commit hook
Our git post-commit hook reads the working log, builds an Authorship Log, and stores it as a git note under
refs/notes/ai.git commit triggers post-commit hook# view the note for any commit
$ git notes --ref=ai show HEAD
- Local CLI works immediately
No network needed. The local CLI reads the git note and shows attribution immediately.
Local CLI works immediately# for individual developers, this is enough
$ iria-monitor blame foo.py
$ iria-monitor blame src/auth.py
$ iria-monitor stats --durability
- Optional: push to your team dashboard
If your org uses Iria Monitor cloud, the post-commit hook also POSTs the note to your tenant. Or you install our GitHub App and we read the notes via GitHub API on push events.
- Three views of the same data
Personal (private to the dev), Vendor (the team/org), Enterprise (a buyer comparing multiple vendors). Same git notes underneath. Different lenses on top.
What the data looks like
A single file, attributed line by line. Multiplied by every commit, every repo, every vendor.
- 1
import oshuman - 2
import hmachuman - 3
from datetime import datetimehuman - 4
- 5
class AuthManager:claude-code - 6
"""Handle authentication lifecycle."""claude-code - 7
def __init__(self, db):claude-code - 8
self.db = dbclaude-code - 9
self.cache = {}claude-code - 10
def create_token(self, user_id):claude-code - 11
return jwt.encode({"sub": user_id}, SECRET)claude-code - 12
- 13
def authenticate(self, email, pwd):human - 14
user = self.db.get_user(email)human - 15
if not user: raise HTTPException(401)human - 16
def validate_token(self, tok):cursor - 17
try: return jwt.decode(tok, SECRET)cursor - 18
except JWTError: return Nonecursor
Aggregated upward — this is what the dashboards run on.
Architecture
Local-first, cloud-optional
- Claude Code
- Cursor
- Codex
- Windsurf
- Python · stdlib only
- computes diff
- attributes lines
JSONL + flock (concurrent-safe)
git notes --ref=ai show HEAD
- iria-monitor-code-metrics
- webhook receiver
- orgs · repos
- commits · blame
- Enterprise
- Vendor
- Personal
Source code never leaves the developer's machine. Only metadata.
Things you might be wondering
Try it.
Two commands. No account needed for the CLI.
Get started