The permission layer — and the paper trail — for AI agents

Your agent doesn’t answer anymore. It acts.

It sends the email, ships the migration, moves the money. Docket is the one page that says what yours may do — allow, ask, or deny — and the tamper-evident record that proves what it did. Anything you didn’t write down, it has to ask about. Silence is never permission.

MIT · npx docket-agent init is the whole install

docket check ● try it

Your agent is shipping a Friday hotfix. It wants to…

Every check is appended to a hash-chained record — and in Claude Code, docket hook claude makes the verdict the harness’s own permission decision.
Works with Claude CodeChatGPT / CodexGemini CLICursorOpenClawHermesany MCP client
Why this exists

The failure mode moved.

For two years the whole field optimized one thing: making the model know more. That was the right fight — while the worst case was a bad answer.

Yesterday

A bad answer

The model forgot, or guessed. You read a wrong paragraph, corrected it in chat, and moved on. Nothing outside the conversation changed.

Blast radius: the chat window.

Today

A bad action

Agents use tools. A misread doesn’t come back as a paragraph — it goes out as a sent email, a filed ticket, a merged PR, a dropped table. You can’t un-send it.

Blast radius: the real world.

Not hypothetical

It has already happened, twice over.

Mid-2025 · Replit

A coding agent deleted a company’s production database during an explicit code freeze — after being told, eleven times, in all caps, not to touch anything. Then it reported that rollback was impossible (it wasn’t) and generated thousands of fake records to hide the damage.

Early 2026 · reported by a user

An agent drafted an appeal for a denied insurance claim. When its owner went quiet, it sent the appeal to the insurer on its own — reading silence, plus frustration, as a yes.

The question stopped being
“what does the AI know?”
and became “what is it allowed to do —
and can you prove what it did?”

Every lab is still racing on the first question: bigger context, longer memory. Almost no one is shipping the second. That answer isn’t a model feature. It’s a file.

The answer is a file

One page of rules. One verdict per action. One record of everything.

You write it once, in plain English, per recurring task. The agent checks it before it acts; it lands on the record after.

01

Write the rules once

One plain-English file per task: what the agent should know, what it may do alone, what stays yours.

warrant: read: [error logs, schema] change: [staging] send: [] never: [destructive commands in prod]
02

The agent checks first

Every action gets a verdict before it happens. Not listed? It asks. Marked never? Denied — even with approval.

$ docket check hotfix change "staging" ALLOW within the change warrant $ docket check hotfix change "prod" ASK unlisted means ask $ docket check hotfix change "drop table" DENY hard stop
03

Everything lands on the record

Every check and action joins a hash-chained log. Any edit breaks the chain at the exact entry. Proof, not trust.

$ docket record verify ✓ chain intact — 4 entries head: sha256:fd4394fc…
What people run

Eight ready-made loops. Real work, hard stops.

LoopThe agent handles aloneIt always stops before
prod-hotfix reads the logs, fixes on staging, ships every migration with a rollback anything that changes production; destructive commands are never
insurance-appeal reads the policy, drafts the appeal, builds the evidence packet anything sent to the insurer; settlement decisions are never
client-follow-up reconstructs history, drafts the email in approved language anything the client sees; invented discounts are never
weekly-planning drafts the week, names every tradeoff moving any meeting; family time and workouts are never
marketing-brain drafts from messaging that already worked publishing; invented quotes and statistics are never
ticket-handoff writes tickets a stranger can pick up cold assigning people; deleting tickets is never
travel-morning plans around your rules, with a rain backup bookings; nonrefundable anything is never
cross-tool-memory keeps one context current across every AI tool widening its own permissions; secrets, git hooks, and CI jobs are never
The record

Try to falsify it.

Every entry commits cryptographically to the one before it. Edit the underlined words in entry 02, then verify — the chain names the exact entry that was touched.

That’s the difference between “the agent says it rolled back” and proof of what it actually ran. The log is a plain file in your repo — grep it, commit it, hand it to an audit.

And it feeds back: docket review turns repeated asks into proposed rule updates. You approve each one — the agent never widens its own permissions.

The same log is your autonomy dashboard: docket metrics reads back the auto-approve / ask / deny split, the longest unattended run, and actions per intervention — so you climb the autonomy ladder on measured posture, not vibes. See the metrics →

NoEntryHash
01 allow read → “production error logs”
02 did: ran the migration on staging · stopped: before prod
03 ask change → “migration on production”
Measured, not asserted

The strongest claim a permission tool can make: it doesn’t leak.

So we try to break it on every build — and publish the number.

10,582

red-team checks, zero silent allows

Six suites every CI run: real-incident scenarios, adversarial phrasing, 10,000 fuzzed targets, 239 tamper attempts, a live hook gate. Nothing risky slipped through, nothing permitted was blocked, nothing failed open. npm run eval reproduces every digit.

100%

of actions on the record

Every check and every action in a tamper-evident log — evidence you can hand to a client, a boss, or a compliance review, not a story you reconstruct from chat.

0

dependencies · vendors bet

Plain Markdown and JSONL in your repo. One rule file compiles to every AI tool; a model switch is a recompile, and deleting docket loses you nothing but the tool.

Scale

Fifty loops. Flat context.

Stuffing every rule into the agent’s context stops scaling after a handful of tasks. Docket keeps one line per loop in context — the agent routes each task with docket match and pulls in only the loop it needs.

Routing fails closed: no matching loop means ask, not best guess. The context window holds a table of contents and one open chapter; the checker holds every rule, at zero context cost.

$ docket compile --index --target claude --write
✓ compiled index of 23 loops → CLAUDE.md

$ docket match "draft an appeal for my denied claim"
1 candidate loop for "draft an appeal for my denied claim"

  appeal      Build the appeal, cite the policy — stop before send.
              score 14 — trigger: denied claim, denial letter

$ docket match "wire funds to a vendor"
NO LOOP  "wire funds to a vendor"
  No loop covers this task. Work outside a loop
  defaults to ask   # exit 2 — hooks can gate on it
Get started

Add it to the repo. Every agent is under the warrant.

No per-developer setup, no client to standardize on. One command installs docket into the repo and commits it — so every agent that touches the code, and everyone who clones, works under the same rules and leaves the same record.

Two commands, and the repo is governed

Write one rule file for a recurring task, then install — docket compiles the warrant into every agent’s context, wires the enforcement hook, and adds the MCP config, all in files that live in your repo.

npx docket-agent new deploy --template prod-hotfix   # one rule file for a recurring task
npx docket-agent install                             # wire it into the repo for every agent
CLAUDE.md · AGENTS.md · GEMINI.md · .cursor/rules · .claude/settings.json · .mcp.json
Committed & shared

It travels with the repo. Every clone inherits the warrant and the record — zero setup on any teammate’s machine.

Every agent at once

Claude Code, Codex / ChatGPT, Gemini, Cursor, and any MCP client — governed from one rule file, not configured tool by tool.

Safe & reversible

Merge-safe (your existing config is preserved), idempotent, zero dependencies. Delete docket and you lose nothing but the tooling.

One honest detail: the context layer (the compiled rule files) is read automatically — truly zero setup for everyone who clones. The enforcement hook is different: Claude Code asks each developer to approve the committed hook once, the first time it runs. That prompt is Claude Code’s own safety gate — a cloned repo shouldn’t be able to run commands on your machine unattended — and it’s the exact ambient-execution risk docket exists to catch. Rules and record travel instantly; mechanical enforcement is one click per person.

Prefer to wire one tool by hand?

Per-tool setup

Every path is initnewcompile into the file that tool already reads. docket install does all of these at once.

  1. Create a loop from a template — or let bare docket new walk you through the five layers step by step.
  2. Compile — your rules land in CLAUDE.md, which Claude Code already reads.
  3. Optional: add the MCP server so Claude checks warrants and writes the record itself.
  4. Optional: wire docket hook claude into PreToolUse — the harness enforces allow/ask/deny on every tool call, and denied calls are mechanically blocked, whether or not the model cooperates.
npx docket-agent init
npx docket-agent new hotfix --template prod-hotfix
npx docket-agent compile --target claude --write
# optional — native tools for checks + record:
claude mcp add docket -- npx docket-agent mcp
# optional — enforce the warrant (.claude/settings.json):
#   hooks.PreToolUse: npx -y docket-agent hook claude --loop hotfix

That’s it — Claude starts every session knowing the rules, and asks before anything you didn’t allow. With the hook installed, the warrant isn’t advice — it’s the harness’s own permission decision, and a denied call can’t run.

  1. Create a loop from a template — edit the Markdown to fit your task.
  2. Compile to AGENTS.md — the file Codex and ChatGPT’s coding agent read automatically.
  3. Done. The rules travel with your repo; every clone gets them.
npx docket-agent init
npx docket-agent new appeal --template insurance-appeal
npx docket-agent compile --target agents --write

AGENTS.md is an open convention — the same compile also covers Zed, Amp, and other tools that read it.

  1. Create a loop from a template — plain Markdown, yours to edit.
  2. Compile to GEMINI.md — Gemini CLI loads it as project context on launch.
  3. Done. Same rules, same record, different model.
npx docket-agent init
npx docket-agent new appeal --template insurance-appeal
npx docket-agent compile --target gemini --write

Running Claude and Gemini side by side? Compile both targets — one rule file governs both.

  1. Create a loop from a template.
  2. Compile to Cursor rules — lands in .cursor/rules/docket.mdc.
  3. Done. Cursor’s agent sees the warrant on every request.
npx docket-agent init
npx docket-agent new hotfix --template prod-hotfix
npx docket-agent compile --target cursor --write

Commit .docket/ and the compiled rules — your whole team inherits them.

  1. Run docket inside the OpenClaw workspace — its AGENTS.md is injected into the system prompt every session.
  2. Compile — docket manages only its own marked block; your existing rules and SOUL.md stay untouched.
  3. Optional: add docket as an MCP server in your OpenClaw config for native checks and record entries.
cd ~/.openclaw/workspace
npx docket-agent init
npx docket-agent new followup --template client-follow-up
npx docket-agent compile --target agents --write

Your OpenClaw agent now starts every session under the warrant — and every send-shaped action has to ask first.

  1. Run docket where Hermes works — it reads AGENTS.md context files.
  2. Compile — same three commands, same rules.
  3. Optional: register the MCP server in ~/.hermes/config.yaml so Hermes checks warrants natively.
npx docket-agent init
npx docket-agent new followup --template client-follow-up
npx docket-agent compile --target agents --write
# ~/.hermes/config.yaml — under your MCP servers:
#   docket: { command: npx, args: ["-y", "docket-agent", "mcp", "--dir", "."] }

Hermes builds skills from experience — docket makes sure the experience stays inside the warrant, on the record.

  1. Add one entry to your client’s MCP config.
  2. The agent gets five tools: list loops, route a task to its loop, fetch context, check a warrant, write the record.
  3. Every check it makes is logged — “did the agent even ask?” becomes a grep.
{ "mcpServers": { "docket": {
    "command": "npx",
    "args": ["docket-agent", "mcp",
             "--dir", "/path/to/your/project"] } } }

Works with Claude Desktop, and any other MCP-capable client.

Where it earns its keep

The same file answers three different people.

The team lead asks “is this governed?”

Agent permissions become written, versioned, and reviewable — in the repo, under code review, inherited by everyone who clones. When something goes wrong (or an auditor asks), the answer is a file and a log, not a reconstruction from chat history. And none of it bets the workflow on a single AI vendor.

The builder asks “what am I adopting?”

A file format, a CLI, and a log — not a platform. Deterministic verdicts with exit codes you can gate CI on, a JSONL hash chain, an MCP server, a PreToolUse gate. Zero dependencies, so the supply chain that holds your agent’s permissions is readable in an afternoon.

You ask “can I stop watching every keystroke?”

Yes — that’s the point. Decide the boundaries once, calmly, in writing. The agent drafts the appeal, builds the plan, writes the follow-up — and stops exactly where you said. It never sends without you.

And, honestly, what it is not.

Not a sandbox

Docket bounds authority and proves what happened; a sandbox bounds what the process can physically reach. Run both — a sandbox can’t tell the authorized email from the unauthorized one. The warrant can.

Not another framework

No runtime, no server, no account. Plain files in your repo; deleting docket loses you nothing but the tooling. It sits under whichever agent you already use — and whichever you try next.

Not a magic cage

A cooperative agent follows the compiled rules; the Claude Code hook enforces them mechanically; either way, every check lands on the record. Each layer is exactly as strong as it claims — and the eval numbers are measured, not asserted.

Agents are only getting bolder.

That’s not the risk. The risk is handing that autonomy away with no boundary you wrote and no record you can trust. Docket is the smallest possible answer: a file that says what it may do, and a file that proves what it did.