The worked example of SpecSheriff: the saloon of a frontier town — its stock, the tabs its regulars run, and the rooms upstairs — specified, tested and built by the method, set up the way any project takes it up.
The saloon is small on purpose; what it shows is the trail. Every rule of its specification was read and confirmed by its owner one node at a time. Every symbol of its code carries a tag naming the rules it implements, every test opens with the sid of the rule it verifies and was written before the code, and every commit names the rules it serves and went through the git hooks and an independent reviewer. The recorded run shows a change that every test and every deterministic check let through, and that the reviewer refused.
What it does
| Domain | Level | What it keeps |
|---|---|---|
| stock | goods | how many of each supply the saloon holds and what each costs, never taking out more than it holds |
| tabs | service | each regular's tab: one for a regular, a limit on the debt, a journal of every charge and repayment, orders priced by their lines and put on the tab whole or not at all |
| rooms | service | the rooms upstairs, each let for 24 hours from the instant its booking is made and never twice for the same hours, the booking charged to the tab as one operation |
It is a library in TypeScript on Node, with everything it holds kept in memory. Money is counted in whole cents.
import { Rooms } from "./src/rooms/rooms.ts";
import { Stock } from "./src/stock/stock.ts";
import { Tabs } from "./src/tabs/tabs.ts";
const clock = () => new Date().toISOString();
const stock = new Stock([{ name: "whiskey", price: 150, inStock: 4 }, { name: "beans", price: 80, inStock: 10 }]);
const tabs = new Tabs(clock);
const rooms = new Rooms(clock, [{ number: 3, price: 300 }]);
tabs.open({ regular: "Doc", limit: 1000 });
tabs.putOrderOnTab({ regular: "Doc", lines: [{ supply: "whiskey", quantity: 2 }, { supply: "beans", quantity: 1 }] }, stock);
rooms.book(3, "Doc", tabs);
tabs.debtOf("Doc"); // 680
tabs.putOrderOnTab({ regular: "Doc", lines: [{ supply: "beans", quantity: 5 }] }, stock);
// throws a Refusal whose rule is s-n7wmxj35vnsc9uk:
// a charge of 400 would take the debt of Doc, 680, above the limit of 1000
Where things are
| Path | What it holds |
|---|---|
specs/_guidelines/project.json |
the project's own guidelines: the levels of the domains, and the rules of the stack no symbol carries |
specs/contracts/ |
the terms the domains share and the rules that hold between them |
specs/stock/, specs/tabs/, specs/rooms/ |
each domain: its header in 00-*.json, then its rules and data records |
specs/tech/ |
the technical appendix: the stack, and how each domain is built |
specs/_confirmations.jsonl |
the owner's confirmation of each node |
src/ |
the code; src/generated/ holds the types and runtime checks generated from the data records |
test/ |
the tests |
recorded-run/ |
the recorded run |
Reading it
Start from a rule and follow it. The rule on the limit, s-n7wmxj35vnsc9uk, is in
specs/tabs/tabs.json, with its reason, its links and the lists of the code and the tests bound to
it; the class Tabs in src/tabs/tabs.ts carries its tag, and the tests in test/tabs.test.ts
that open with its sid verify it. git log reads in the order the work went: the specification,
then the stack, then each domain with its tests.
Running it
With Node 24 or later:
npm install
npm test
npm test checks the code with the TypeScript compiler, then runs the tests.
Changing it
Install the plugin of SpecSheriff as its guide
says, and open Claude Code in your clone: .claude/settings.json offers the plugin once you trust
the folder, and the first session turns on the git hooks in .githooks/. From then on every commit
is checked as the ones in the history were. A change begins in the specification: ask the agent
for the change you want, and it proposes the rule, puts it to the owner, and only then writes its
test and its code.