authoring-specs
Skill127 starsChanged 11 days agoMITView on GitHub
Use when drafting a new spec in docs/specs/ or amending an approved one - covers the sources to read, the admission test, the requirement row, precision rules, ID allocation, protobuf and WebIDL type blocks, and the change summary a reviewer needs
2 other projects use a version of this.
Adopted by
Most recently taken up by
- coinbase/x402their own version, first seen Oct 17, 2026
- x402-foundation/x402their own version, first seen Oct 8, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- x402-foundation/x402★ 6.8ksame name
- coinbase/x402★ 168same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- docs/AGENTS.mdAGENTS.md
- .github/workflows/AGENTS.mdAGENTS.md
- nix/AGENTS.mdAGENTS.md
- proto/AGENTS.mdAGENTS.md
- sdks/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/workflows/CLAUDE.mdCLAUDE.md
- nix/CLAUDE.mdCLAUDE.md
- proto/CLAUDE.mdCLAUDE.md
- sdks/CLAUDE.mdCLAUDE.md
- check-ciSkill
- checking-spec-complianceSkill
- reviewing-specsSkill
- smoke-checkSkill
- working-with-nixSkill
- working-with-worktreesSkill
- writing-agent-docsSkill
- writing-rustSkill
- writing-rust-testsSkill
- writing-typescriptSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 5 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Read docs/specs/SPEC-spec-format.md first: it is the rules, this skill is the order of work.
- Very specific: line 29
MUST and MUST NOT state obligations.
- Distinctive: line 37
Write the check, not a description of it.
- Distinctive: line 44
Delete the words that stand in for a measure: earliest, latest, confirmed, usable, bounded, sufficient, appropriate, promptly.
- Distinctive: line 48
Write a section's prose before its requirements: what the mechanism is and what breaks without it, in a few direct sentences.
- Distinctive: line 55
No file names, no phases, no status prose, no platform choices.
- Distinctive: line 61
Every obligation in the legacy source needs a disposition in the summary: carried into a requirement, retired, or moved to a design note.
- Very specific: line 65
Run dev/nix-shell 'just spec-check'.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Authoring a spec
Read docs/specs/SPEC-spec-format.md first: it is the rules, this skill is the order of work. A spec states promises the system keeps, not what the code does today.
Sources
- The skeleton for this prefix,
docs/specs/README.md, anddocs/specs/GLOSSARY.md. - The superseded spec named in the skeleton, read from git history if it is deleted, the XIPs it cites, and its code anchors. Code is evidence of current behaviour, not authority for intended behaviour; XIPs have no authority of their own. When sources disagree, write the intended behaviour and record the disagreement.
- The sections of RFC 9420 and of any other standard the legacy spec or the code relies on. You will cite them by section (SPEC-074).
just spec-index, for obligations that already exist. Reference them by ID; never restate them.
The requirement row
One obligation per row of a table with the header | ID | Title | Requirement | Why |:
| ID | Title | Requirement | Why |
| --- | --- | --- | --- |
| JOIN-012 | Stale welcome | When a Welcome names a group the client already holds and its epoch is not later than the local epoch, the client MUST discard the Welcome. | An older Welcome would roll a member back to a dead epoch. |Condition first, then the actor, then the keyword. That is the EARS clause order (when, while, where, if ... then) written with MUST and MUST NOT instead of SHALL, and lowercase triggers. A trigger buried at the end of a sentence cannot be tested.
- MUST and MUST NOT state obligations; MAY states freedom. Never
SHALL. SHOULDonly for an app or an operator, which the system cannot enforce. Those need no test.- The ID cell holds the bare identifier. Two to seven words of title in the Title cell, no period. At most three sentences in the Requirement cell.
- The Why cell says what breaks when the rule is violated, or is empty. It never repeats the rule. Section prose carries the reasons by default.
- A row is one line: no fence, no list. A pipe inside a cell is
\|. A type block goes above the table whose rows point at it.
Precision
Write the check, not a description of it. Every vague requirement costs an owner a review comment and you a round trip.
- Name the field, the stored value, and the comparison. "The message with the lowest sequence id at the location", not "the earliest message". "The anchor is greater than the group's stored cursor", not "has not yet read up to". Name the field of the wire type or the MLS object that the check reads.
- A bound states its number, or its default and the rule that chooses it. "A bounded number of attempts" cannot be violated.
- Name the algorithm when one is fixed: "ChaCha20-Poly1305", not "a cipher that authenticates".
- Cite a standard by section, link it, and say only what XMTP adds or removes: "the checks in RFC 9420 §10.1, and in addition ...". Never restate the standard's own validation.
- Say what a thing is and what it carries, not what it intends. A key package is "the public key material and capabilities another member needs to add this installation", not "a standing offer". Use the protocol's term: "expired", "randomly generated topic", "broken group". Say who is trusted for what; never "trustworthy".
- Delete the words that stand in for a measure: earliest, latest, confirmed, usable, bounded, sufficient, appropriate, promptly.
Writing
- Write a section's prose before its requirements: what the mechanism is and what breaks without it, in a few direct sentences. No argument for the design, no alternatives, no decision history (SPEC-010). A reader who wants a reason has the Why cell.
- Apply the admission test (SPEC §2) to every candidate and reject anything that fails one question. Ask in particular who observes a violation: if only the actor that breaks the rule, it is a design note, not a requirement (SPEC-092).
- State the general invariant, never one example of it. A rule and the value it fixes are one row. Two rows a single act would violate are one row (SPEC-028).
- Allocate the next unused number. Never renumber, never reuse; check
git log -Swhen in doubt. An id carried forward from a superseded document, or moved here by a split, goes in theownsfrontmatter key. - A protobuf message is inlined verbatim with its field numbers, which are normative. A structure that never reaches the wire is a WebIDL dictionary. A format defined elsewhere, such as an MLS object in TLS encoding, is cited by section, never reproduced (SPEC §3.1).
- An exact wire, limit, or error value goes in the spec that owns it. Others reference the ID.
- When the obligation you need is not written yet, write
?PREFIXwhere the id will go and say in the section's prose what it should require, not inside the row. Never invent a number: it will resolve to the wrong requirement once that number is allocated. The checker lists every marker, and the PR approving that spec has to replace them. - No file names, no phases, no status prose, no platform choices. Mechanism detail belongs in a design note or module README.
Amending
Same obligation, better words: keep the ID. Different obligation: new ID, delete the old row. Moving a clause out of a requirement into prose is a contract change; say so.
Every obligation in the legacy source needs a disposition in the summary: carried into a requirement, retired, or moved to a design note. A platform choice cannot be carried, so say that it is retired rather than letting it vanish with the file.
Finish
Run dev/nix-shell 'just spec-check'. Return the spec and a change summary: IDs added, amended, removed; legacy requirements not carried, each with a reason; waivers the code will need; questions only an owner can answer. Do not set status: approved.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

