The agent rule
rowshape init --agent writes the rule below into your AGENTS.md (and
CLAUDE.md), inside a managed block marked rowshape:begin v3 … rowshape:end.
Everything outside that block is left byte-for-byte untouched, and a re-run
replaces the block in place — so an improvement to the rule reaches repos that
ran init --agent months ago. It is a versioned product artifact (currently
v3), iterated against real agent sessions like a prompt.
This is the current text, verbatim:
## Database migrations
This repo has `rowshape` wired in as an MCP server. Migrations here get checkedagainst production *shape* — real row counts, null fractions, cardinality,fan-out — not against a dev database with twelve rows in it. Most migrations thatbreak production pass every test on a small dataset first.
**Before writing a migration**, call `describe_shape` for the tables you'retouching. The shape decides the answer: `SET NOT NULL` on a column with a 3% nullfraction fails on contact, and a cascade delete on a foreign key whose fan-out hasa long tail is an outage rather than a cleanup. Guessing costs more than asking.
**Before opening a PR**, call `validate_migration`. It returns a verdict andcompact finding codes (`RS-LOCK-001`, `RS-DATA-014`, …). Call `explain_finding`with a code to get the fix.
**Know what it checked.** `validate_migration` is STATIC: it reasons about yourSQL against the fixture and runs nothing. A PASS means "nothing in the shapecontradicts this", not "this ran". `rowshape validate` in CI hydrates andapplies — that is the stronger check.
**Never hand-wave a FAIL.** A FAIL is not an opinion — it rests on a factmeasured from production, and the finding names that fact. Fix it andre-validate. Do not explain it away in the PR description, do not disable thecheck, and do not ask a human to accept it.
**A WARN is not a pass.** WARN means the verdict rests on a fact rowshape couldnot prove — usually a statistic it could only estimate. The finding names thecommand that resolves it. Run that command; do not assume the optimistic reading.
Both tools need the committed fixture (`rowshape.yaml`). If there isn't one, sayso and ask — creating it means reading a real database, which is a human's call.