backlog/1 says what an organisation intends. shipped/1 says what it did. ritual/1 is the tense between them: the recurring, witnessed, consequence-bearing act — what an organisation practises, on a rhythm a stranger can check.
An intention decays unless somebody restates it.
A practice holds only while the rhythm holds — and the rhythm is checkable.
A fact about the past is sealed and never decays.
The act happened, with evidence a stranger can open. It moves nothing yet.
Someone who is neither the performer nor its principal signed — with a basis of their own.
A person conferred consequence. This is the only count that means anything.
A fourth state, void, exists only to correct: it names the observance it supersedes, because the log is append-only and a deletion is not on offer. Walk one observance up the ladder →
Each rule below is an error message the format actually produces — quoted here verbatim, and pinned by a test that provokes it from the shipped validator. A principle that is a thrown string cannot drift into a slogan.
A consecration names a person/ and nothing else. There is no code path by which an agent approves an observance into consequence.
No path exists from performed to consecrated. A witness must be a third party, carrying their own basis — a copy of the performer’s evidence is a citation loop, not a witness.
Money words and amounts are refused at any depth; streaks and scores are refused as derived-only. Coupling to accrual has to be written in reward/1, where the caps live.
Nothing is edited and nothing is deleted. A correction is a new observance that supersedes the old one, and a void that names nothing is refused.
vendor-ritual.mjs imports nothing but node: builtins. Copy it byte-identical and run it before any install.
The npm entry IS the vendored file, so both doors run identical code. Unpublished until the first adopter, by estate rule; it travels by copy today.
A JSON Schema for the shape, and a conformance corpus naming the rule each case exercises. A non-JS implementation proves itself by agreeing with every verdict — the corpus is the count, so this page does not repeat it.
The join kit is the vendored file itself — no install, no account, no conversation with us. This domain serves its own calendar at /.well-known/ritual.json, checkable with the same command we hand you.
Copy the one file, run init. It writes an empty valid calendar and a validation workflow, refuses to overwrite, and refuses a non-person publisher — a liturgy is a human decision from the first command.
The whole ladder is the same CLI: a person publishes the practice, your agent observes with evidence, a third party witnesses with a basis of their own, a person consecrates. Every transition validates the entire fragment before it writes.
Serve the fragment at /.well-known/ritual.json. The same command a stranger runs fetches it over the network the way a stranger would — because a calendar green in a checkout and 404 at the domain reads as success everywhere except where the stranger stands.
Implementing in another language instead? The schema and the conformance corpus are on the specification page, served raw.
The spec, the schema and the conformance corpus live in the monorepo under packages/ritual. It sits beside the other tenses: what shipped, the AAO spec and every package we publish.