@flashyos/canon
v0.1.0
Published
canon/1 — a lockfile for facts. One authority per fact, fetched by every property that renders it, with drift as a build failure rather than a silent update.
Maintainers
Readme
@flashyos/canon
A lockfile for facts.
npm install is one authority, versioned, with a lockfile, and a build that
fails when the lock and the manifest disagree. canon/1 is that mechanism for
the facts a site renders — a definition, a count, a status, a path — so prose
stops propagating by memo while code propagates by dependency.
npm i @flashyos/canon
npx canon add directory.organizations.path --from flashyos.com
npx canon check # exit 1 if a fact this property renders has moved
npx canon accept # take the change into the lock, as a reviewable diffWhy not just fetch the fact and render it
Because that is a synchronisation channel, and this is deliberately not one.
Fetching at build makes the same commit render differently on Tuesday than it did on Monday, so nobody can say which page was live when a claim was cited. It turns one bad edit into a simultaneous ten-property incident with no review anywhere in the path. And it makes a network outage a content outage.
So a build reads only the lock — deterministic, offline-safe, unchanged until somebody changes it. A separate check reaches the network and reports drift as a failure that names the fact, both values, the authority and the note explaining the change. Accepting is one command and one diff.
Drift becomes loud and fast instead of silent and slow. The mechanism does not remove the human; it removes the remembering.
The document an authority serves
At /.well-known/canon.json, beside the mesh handshake and the directory
fragment:
{
"canon": "1",
"authority": "flashyos.com",
"facts": [
{
"key": "directory.organizations.path",
"value": "/organizations",
"rev": 1,
"asserted": "2026-08-30",
"note": "Rule 14. The path every host in the ring serves organisation records under."
}
]
}rev is monotonic, authority-assigned, and bumped only when the value
changes. Not a hash — a hash cannot tell a correction from a reformatting. Not
a timestamp — a timestamp moves on every rebuild, which would make every deploy
look like a change to every consumer.
What the check refuses
Five findings, and four of them are ways an authority can be wrong rather than ways a fact can move:
| Finding | What happened |
|---|---|
| changed | The ordinary case. A newer revision. Accept it. |
| withdrawn | The authority stopped publishing a fact this property renders. |
| rolled-back | A revision went backwards: a rollback, a restored backup, or a document that is not what it claims. |
| unversioned | The value changed and rev did not. Never accepted locally — every other consumer still believes it is current, and fixing it here hides that the authority is broken. |
| wrong-authority | The document declares a different host than the one this property named. Never accepted — otherwise a redirect is enough to change what an estate publishes. |
An unreachable authority is not a finding. The lock still renders, and the check says so out loud — a check that silently reached nothing and reported "settled" is the worst possible green.
Not a registry
Every fact names the host that asserts it, and a consumer only accepts a fact
from the authority it declared for that key. There is no central store: a canon
document is served at its asserter's own host, exactly as directory/1 Rule 11
requires of everything else.
A property opts in by locking a fact. Nothing can push content into it.
Licence
Apache-2.0.
