Skip to content

In a session

Half of this tool’s surface is not a command line. Installing the plugin hands a session five things at once, and the README covers installing them rather than what they then do.

The hook runs before an edit and denies a write to a governed file. That is the law the whole design rests on — schema enforced where the text is created — applied to the one author who would otherwise bypass it. Its refusal always names the command to call instead, because a gate that stops at no costs a turn and teaches nothing.

The skill is the authority on which command that is, what it derives, and the rules a schema cannot check. It is trigger-loaded: it costs a session nothing on a turn that touches no governed file, and it arrives on the turn that does. That is why the rules live there and not in an instruction file — an always-resident copy is paid for by every turn that never writes.

The slash commands are the same operations for a person driving the session rather than an agent: one engine, a second front door.

The MCP server is the tool surface priced below.

The launcher exists for sessions where no plugin can be installed. It is committed to the adopting repository, which is the only place a session with no plugin will find it.

Once, when the client connects

A session pays for the tool schemas before it calls anything. Measured against this repository, that is 66,939 utf 16 code units — 65 tool(s) and the handshake, and the session-start notice.

WhatCostBound by
65 tool schemas66,151[tools] session at 66,660 — 100% used
The handshake (instructions, sent once)465
The session-start notice323320

No single tool may exceed [tools] characters, currently 2,850. lint is what refuses one — which is why a tool description is a budgeted surface and not free prose.

The ten that cost the most

ToolCostRoom left of 2,850
ship2,79060
add2,660190
budget2,608242
section_amend2,243607
record_amend2,040810
record_add1,7521,098
amend1,7131,137
delivered1,6951,155
anchors1,6661,184
govern1,5221,328

On every turn

A different cadence, so the two are never added together. These are the files a session loads whether or not it touches a governed file — 7,966 in total here.

FileCostBudget
agents.md7,5088,400 bytes, 840 left
.claude/CLAUDE.md45812 lines, 2 left

When the skill loads

The third cadence, and the one the two tables above are never added to: this is paid on the turns the skill's own description matches, and on no others. What arrives then is an orientation11,629 utf 16 code units — with the reference on pages beside it, opened by the turns that need one and charged only to those.

WhatCostPaid on
SKILL.md, the orientation11,629every turn the trigger matches
writing.md43,965the turns that open it
asking.md18,384the turns that open it

What this project is not sent

A verb that is one role's whole vocabulary is published only where that role is declared, so two projects see two different lists. On this repository 2 verbs are withheld — not missing, and a call to one is refused with the command that opens it rather than with "no such tool".

  • defer — until roadkeep declare deferred
  • resume — until roadkeep declare deferred

Why a number here is a gate and not a note

Section titled “Why a number here is a gate and not a note”

Every figure above is measured by cost, and two of them are enforced. A tool description is prose somebody writes in a docstring, so without a bound it grows the way any prose does — and it grows in the one place where every session pays for it, at connect, whether or not the tool is ever called. lint refuses the surface that goes over.

This is the same argument the whole project makes about a roadmap line, pointed at itself. The saving is the analysis and not the characters: knowing the ceiling before writing a description is what stops one being written that has to be cut later.

A denial is not an error. It means a write reached a governed file by a route that cannot validate it, and the refusal carries the verb that can — add, amend, ship, section add. An agent that reads the refusal and calls the named verb has lost one tool call; an agent that edits the file directly has produced a line the gate will reject later, when the context that would have fixed it is gone.

A tool that is not there. See the withheld list above. A verb whose whole vocabulary belongs to a role the project never declared is not published, so it looks absent rather than unavailable. Calling it anyway is refused with the declare that opens it — the absence is never silent, but it is met before it is explained.

Three copies disagreeing. A checkout, a plugin cache and an installed package can all be reachable at once, and they need not be the same version. Which one answered decides what a refusal means, and a refusal from an old copy about a flag a new one accepts is the confusing case. roadkeep engines reads all of them and says which writes, which judges, which gates and which merges. It is worth running the first time something refuses a call you are sure is correct.