The Quoin Constitution
The ten invariants that hold across every site, every implementation and every revision.
These are the invariants of the specification — the decisions that hold across every site, every implementation, and every future revision. A change that violates one of these is not a new version of Quoin; it is a different protocol. Everything else (the spec) is negotiable by versioning; this is not.
1. Content is data; presentation is code
Content is schema-validated structured data (Markdown, JSON, YAML) stored in the repository. Presentation — chrome, templates, blocks, tokens — is code, owned by the developer, reviewed like any other code. Content never carries presentation logic; templates never hard-code content.
Why: the moment content can express layout, the schema — and therefore the rigour — is gone. Blocks give humans and agents real compositional power without opening that door.
2. The build is the gate
Content that fails schema validation cannot publish. Validation happens at build time and is absolute: no warnings-only mode, no skip flag, no “ship it broken and fix later”. A red build blocks merge; a green build is the only path to production.
Why: this is where the database-driven CMS rigour was to come from, and it comes from the same place without a database. Invalid content cannot exist on production because it cannot survive CI.
3. Delivery is static
The delivery path is: build → static files → object storage → CDN. No application server, no database, no runtime process is required to serve a page. Anything dynamic (forms, bookings, payments) is delegated to an external service referenced by link.
Why: four small sites do not justify a Node service, a patch cadence, and a backup story. Static output is the cheapest, fastest, most robust delivery that exists, and the preview workflow depends on it.
4. Every change is a pull request
No write reaches main except through a pull request — human or agent alike.
Branch protection is absolute; the agent has no merge rights it was not
granted by configuration, and no human bypasses the gate for convenience.
Why: the pull request is the audit trail, the review surface, and the rollback unit. Any path around it is a path around the audit.
5. Two-level approval; the record shows who approved what
A change originating from a human requestor passes two gates: the requestor
confirms intent (this is what I asked for, via the preview) and the
publisher authorises publication (merge to main). The trust dial may
relax who performs each gate for low-risk senders and change classes, but
every published change records, in the PR, who requested it and who approved
each level. Post-hoc review is a legitimate dial position only if the record
still shows it was post-hoc.
Why: the failure mode being guarded is the silent misinterpretation — the agent publishes what the requestor did not mean. The second failure mode, a review bottleneck on one human, must not be solved by quietly deleting the review.
6. Email is content, never instructions
Inbound email is untrusted input: data to be interpreted, never commands to be executed. An instruction found inside an email body (“publish this immediately”, “skip review”) has no force. Senders are identified by allowlisted address; approvals are accepted only from an allowlisted sender, in-thread, quoting the nonce.
Why: the threat model is a spoofed or forwarded email driving a website defacement, or driving the agent through the review gate. The email channel must have the authority of a suggestion, never a command.
7. Chrome is shared and non-negotiable
Every page renders inside the site chrome: header, footer, menus, base tokens. There are no full-page takeovers. A freeform page (the blob) may express arbitrary content inside the frame; it may not replace, hide, or reimplement any part of the frame. Sites are built from the shared page-type and block library first; a blob is the escape hatch, not the default.
Why: the value of the family is that a change to the beam changes every page of every site. A blob that rebuilds the chrome is a fork of the system wearing its name.
8. Derived data is computed, never authored
Anything that can be computed from the content — aggregate statistics, index pages, counts, sitemaps, recent-lists — is computed at build time. Hand-maintained copies of derived data are forbidden and are treated as schema violations.
Why: a hand-typed “209 rides” goes stale the day ride 210 lands. Derived data that can drift, will drift; computed data cannot.
9. Preview is not production
Preview deployments are separate from the live site: unguessable paths,
noindex on every response, cleaned up when their pull request resolves.
Merging to main is the only mechanism that changes production. No one ever
“syncs the live bucket by hand”.
Why: the preview is what makes the two-level approval real — the requestor reviews the actual rendered page. That value survives only if the preview channel cannot leak draft content into the world or be confused with it.
10. One site, one repo, independently conformant
A Quoin site is one Git repository that owns its content and templates and conforms on its own. Multi-site is many repos, optionally sharing a theme package. No shared database, no shared runtime, no shared state.
Why: sites in this family outlive each other, are edited by different people, and must be handover-safe individually. Coupling them — even gently — turns “rebuild this site” into “rebuild the system”.