Claude Code can forget your rules. Writ can refuse the action. Writ is a governance runtime for Claude Code.
> /plugin marketplace add infinri/Writ> /plugin install writ@writ
What's inside
Claude Code can forget your rules. Writ can refuse the action.
Writ is a governance runtime for Claude Code. It moves important engineering controls outside the model, where they can be enforced, retrieved, and remembered independently of what the model happens to keep in context.
Most coding-agent systems ask the model to remember the process. Writ puts selected parts of the process around the model instead.
Those are mechanism claims, and you do not have to take them on faith. docs/pressure-runs/ holds adversarial runs against real Claude Code sessions, each with the prompt used, the full transcript, every enforcement decision as raw log lines, and a graded analysis of which rules held and which were bypassed, with the failures written up as failures. docs/monthly-reviews/ holds operational reviews built from the system's own audit log. Both are in the repository, dated, and readable before you install anything.
Every number in this file is either measured and dated, or derived from the current source tree. Where this file and the code disagree, the code wins.
You tell Writ what kind of work you are doing. That is the mode. In the read-only modes (conversation, review, investigate) Writ hands over relevant rules and otherwise stays quiet. In Work mode, writes to your source code are blocked until two gates open.
The refusal. Claude attempts a write in Work mode before a plan has been approved. This is exactly what the gate returns, quoted byte for byte from the string literal at writ/session/gates.py lines 803-806, inside the gate arm at 801-809:
[ENF-GATE-PLAN] ALL writes blocked -- plan not yet approved. DO NOT attempt more writes.
Present your plan to the user and say: "Say approved to proceed."
Wait for the user to say "approved" before attempting ANY file writes.
The human opening the gate. You read plan.md and type "approved", or you run /writ-approve, the one slash command Writ ships. The next gate wants a test file that actually asserts something: write it, approve it, and it opens the same way. After both gates clear, the AI writes implementation code freely. The AI cannot approve itself. Opening a gate consumes a one-time secret written to a temporary file, and that secret is created only when your typed message matches an approval phrase. An AI that tries to open its own gate finds no secret, gets refused, and the attempt is written to the audit log as agent_self_approval_blocked. HANDBOOK.md section 7 carries the whole model.
The provenance. Afterwards, what was approved, which rules governed it, which files changed, and which commit resulted reads back through either of these:
writ recall
git log --notes=writ-decisions
The first reads the project's recent rule-grounded decisions back from the graph. The second reads the same content out of git itself, with no server involved.
That block is not unconditional, in three named ways: when the background service is unreachable hooks allow rather than block, subagents skip the write gates by design, and the gate can tell that a plan exists but not whether the plan is any good. Evidence and limits states each one in full.
You do not have to install this yourself. If you are reading this you already use Claude Code, which means you already have something that reads instructions and runs commands. Point it at this page and ask it to install Writ. It handles the setup; the one piece you may need to do by hand is installing Docker, the same way you would install any other application.
You will need: Python 3.11 or newer and Docker (the graph database runs in a container). That is the whole list. jq and curl are used when present and fall back to Python when absent, so a machine without them installs fine.
claude plugin marketplace add infinri/Writ
claude plugin install writ@writ
Open Claude Code once. It detects the un-bootstrapped install and prints one absolute command on its own line, ready to paste:
bash /path/it/prints/scripts/bootstrap-plugin.sh
Run it and restart Claude Code. That one script does everything: environment, database, rules, background service, permissions, and workflow instructions. It is idempotent, and re-running it after an update is the whole update procedure. Check it worked with curl http://localhost:8765/health.
Nothing breaks while you are partway through setup. Hooks stay out of the way until the install finishes, sessions are never blocked, and the startup hook prints exactly what is still missing. Full install detail, the manual path, and troubleshooting live in docs/install.md. Once it is running, HANDBOOK.md is the operator manual: modes, gates, helper AIs, the rulebook, and the command line.
Writ governs three things. Action: what the agent is permitted to do. Context: which engineering rules govern the current action. Continuity: why the action was approved and what future sessions should know. Hooks and gates are the Action mechanism, retrieval over the rule graph is the Context mechanism, and decision provenance is the Continuity mechanism.
W R I T
User request
|
v
Engineering rules -----+
Human approvals -------+
Prior decisions -------+--> Writ --> Claude Code
|
| tries an action
v
Writ checks the action
|
allow / ask / refuse
|
v
Repository
|
v
decision provenance
Selected workflow boundaries run as code at tool time. A Work-mode implementation can be stopped until a human has approved its plan and its tests, and credential writes and other protected actions have their own guards in every mode.
Instructions and enforcement are different primitives, and Writ supplies the second one for the parts of the process you choose to gate. It sits between the AI and your files. In Work mode, a write attempted before you have approved a plan is refused. Not discouraged, refused, by code that runs whether or not the AI is still paying attention to what you said an hour ago. Why that distinction is architectural rather than rhetorical is argued in docs/instructions-vs-enforcement.md.
| Mode | For | What it blocks |
|---|---|---|
conversation | Talking, asking, thinking out loud | Nothing |
review | Judging code against the rules | Nothing |
investigate | Auditing, exploring, researching | Web research cannot be summarized until sources come from two independent sites |
debug | Chasing one specific failure | Source edits, until you have written down a root cause |
work | Building or changing code | Source writes, until the plan gate and the test gate both open |
Rules reach the agent when they apply, based on the task, file, tool, and workflow phase in front of it. Seven universal process and gate rules form a small always-on floor. Other mandatory rules are scoped to the actions they protect, while the rest of the rulebook is retrieved by relevance. Rules that do not apply stay out of context.
Enforcement solves only half the problem. A large rulebook cannot simply be pasted into every turn, so Writ also moves rule selection outside the model. It looks at the work happening now and delivers only the rules that apply. Tool-time checks do not depend on the model remembering the process, and contextual delivery lets the rulebook grow without the cost of every turn growing with it.
The floor: rules that can never be dropped. Thirty-two of the 288 shipped rules are marked mandatory. These are deliberately kept out of the search index entirely and delivered through a separate channel with its own budget, so no change to ranking, no swap of the underlying model, and no retuning of anything can cause a mandatory rule to fall out of delivery because of ranking. Seven of them carry universal scope and inject on every turn; the other 25 are scoped to writes and keyword-gated, so they arrive the moment a write matches them rather than every turn. Both counts are derived from writ-corpus.cypher, the tracked canonical dump, and the mechanics are in docs/reference/retrieval.md.
Everything else is searched for. Writ currently uses a five-stage retrieval pipeline over a Neo4j knowledge graph: narrow the candidates, keyword search, meaning-based search (so a rule about "SQL" surfaces for a question about "database queries"), a walk across the graph to pull in related rules, then weighted ranking. Those five stages are the ones listed at the top of writ/retrieval/pipeline.py, and each is designed to cover a different retrieval failure mode: keyword search catches exact terms, meaning-based search catches paraphrase, and the graph walk reaches rules that share no words with the query at all but are linked to a match. If nothing matches well enough, the pipeline returns nothing rather than injecting noise.
The search fires on what is happening, not just what you typed. Writ's hooks observe the session across the twelve Claude Code events they register for: prompts, file reads, writes, shell commands, subagent start and stop, compaction, and session lifecycle. They attach real context to the query: which file is being written, what is inside it, which tool is running, and what phase the workflow is in. So while Claude works, editing a file whose code touches SQL can pull the parameterized-query and injection rules into context at that moment, even if your prompt never mentioned SQL.
Approved plans, the rule IDs that governed them, changed files, and commits become connected provenance: recorded in the graph, pushed onto pull requests and git notes, and compiled into a briefing for future sessions. The record answers a governance question: under what approved plan and governing rules did this change occur, and which files and commit resulted?
FAQ
writ is a Claude Code plugin with hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it