What we collect

We collect signals about work — never the work itself.

attribut.ai measures engineering activity — how much, with which tools, how long — so you can understand and attribute AI-assisted work. It never reads or stores your code, your prompts, or the AI’s responses. Below is exactly what a record looks like.

Counts, not contentsPrompts never leave your machineCollector is public & auditable
What a record looks like

Real examples, field by field.

These are representative fields, not the full list — but every one is a count, a timing, or a label. Read them closely: notice what’s here, and what can’t be.

session.jsonmetadata only
{
"sessionId": "a1b2c3d4-…",
// random session id
"device_uuid": "7f3e9b2a-…",
// anonymous device id
"title": "Refactor checkout validation",
// your tool's own session label
"model": "claude-opus-4-8",
// which model ran
"tokens_in": 48210,
// usage counts
"tokens_out": 12904,
"started_at": "2026-07-01T14:03:22Z",
"duration_ms": 734000,
// ≈ 12 minutes
"repo": "~/code/acme/web-app",
// working-directory path
"branch": "feature/checkout",
// git branch name
"commitSHA": ["9f2a1c7"],
// commit hashes produced
"num_turns": 46,
"num_tool_calls": 37,
"tool_uses": [
// tool names + counts only
{ "name": "Edit", "count": 14 },
{ "name": "Bash", "count": 9 }
],
"lines_code_added": 128,
// counts, derived locally
"lines_code_removed": 41,
"lines_comment_added": 12,
"claude_code": {
// client version + subagent counts
"version": "2.1.0",
"subagents": [ … ]
// per-subagent counts + timings
}
}

Counts, timings, and labels — plus one field, title: the short session label your coding tool (Claude Code, Codex, and the like) already assigns. We read that existing label from your session — we don't generate it — and cap it at 200 characters so you can tell sessions apart. How many lines changed — never what they were. Which tools ran — never what they did. Character-length totals are stored as aggregate sums only, never the characters themselves.

git_activity.jsonIf you connect GitHub
{
"repo_full_name": "acme/web-app",
"branch": "main",
"commit_sha": "9f2a1c7e…",
"message": "Fix checkout total rounding",
// commit message, as GitHub shows it
"author_login": "jdoe",
"author_email": "[email protected]",
"pr_number": 412,
"pr_title": "Checkout rounding fix",
"additions": 128,
// line-change counts
"deletions": 41,
"changed_files": 6,
"authored_at": "2026-07-01T14:20:05Z"
}

Standard git metadata — the same fields GitHub shows on any commit or PR, including the commit message and line-change counts. We never store diffs, file patches, file paths, or PR descriptions. Used to connect commits to the people and sessions behind them.

account.jsonmetadata only
{
"email": "[email protected]",
// from your sign-in
"name": "Jane Doe",
"org": "Acme Inc.",
"github_login": "jdoe"
// to match commits to you
}

Basic identity, so your work shows up as yours. Managed through our authentication provider, Clerk.

Technical & security data

Standard request metadata, for safety.

To keep the platform secure and reliable, we record ordinary request metadata. We use it to detect abuse, diagnose issues, and understand where our users connect from — never to inspect your work.

IP addressrequest origin
Locationcountry / region
Network & connectionASN, protocol
Browser / agentclient string
The guarantee

What we never collect.

Not as a policy you have to trust — as a boundary enforced in the collector’s code. None of the following is transmitted, stored, or even read.

Your source code
No file contents. Ever.
Diffs or code snippets
We count changed lines — we never keep the lines.
Your prompts
What you type to the AI never leaves your machine.
AI responses
The model’s output is never captured.
Tool inputs
The actual shell commands, or file contents passed to tools.
Keystrokes, screens, filesystem
No keylogging, no screen capture, no file tree.
Don’t take our word for it

The collector is public and auditable.

The CLI that runs on your machine is published on GitHub under the PolyForm Shield license, and its full source ships inside the package. Read it, run it, and confirm for yourself that your prompts, responses, and code never leave your machine.

attribut audit · run it yourself, on your own sessions
$ attribut audit
auditing 42 local sessions…
✓ schema · 42/42 payloads validated against the frozen contract
✓ leak scan · 1,204 sensitive strings checked · 0 found in any payload
   prompts · responses · tool inputs · file contents — not present
PASS — every payload is metadata-only
The whole story in one line

One session. Both columns.

Everything we can attribute from a single coding session — set against everything we can’t see, by construction.

What we see
What we don’t
61,114 tokens metered
the prompts or responses behind them
14 files edited
which files, or their contents
128 lines of code added
what those lines say
Bash tool used 9 times
what commands ran
3 subagents spawned
what each was asked to do
claude-opus-4-8 · 12 min
your prompts or the model’s replies
Commit 9f2a1c7 · feature/checkout
the code in that commit
Left is what we attribute. The right column is never collected — there’s nothing to leak, subpoena, or lose.