Changelog
Every change to the specification, with its impact class and what implementers must do.
Normative process. Every spec change lands here with an impact class (BREAKING / NORMATIVE / ADDITIVE / EDITORIAL) and a required implementer response. Re-check this file before and during any build.
D-011 — 2026-09-24 — Client-neutral documents
Class: EDITORIAL
The specification is published at quoin.croftsware.com, so its public
documents no longer name client sites, people, client pull requests or
correspondence. Named sites become roles (“the reference site”, “a community
campaign site”); a requestor’s quoted words are paraphrased; local paths are
removed. The specifics are unchanged in validation/, which is never
published. No normative change.
Implementer response: none.
D-010 — 2026-09-24 — quoin round (landed from FUTURES, same day)
Class: ADDITIVE
The round mechanism of spec/03 §7, mechanised (quoin-cli, quoin round <label> [--dry-run] [--profile <aws>] [--review <dir>]): folds every
open change/* PR onto origin/main (a clean octopus fold is itself an
integration proof), reloads the site adapter from the fold (the startup
adapter goes stale when the fold changes schemas — found in the first
dry-run), runs the full gate (validate + all-themes conformance), builds,
injects a dated expiry ribbon into every page, and uploads the browsable
preview and optional review directory to STAMPED slugs
(proposed-<label>-<stamp> / review-<label>-<stamp>) on the site’s
preview domain, read from the site’s own deploy.yml. Append-only by
construction: a new round state is a new slug, which also eliminates
CloudFront invalidation. Verified by dry-run against the reference site (four
open PRs folded, 21 pages stamped).
Implementer response: none for sites; agents produce the summary page
and screenshots (the review dir) and pass --review. spec/08 §2 updated.
D-009 — 2026-09-24 — Round-one pipeline learnings
Class: NORMATIVE
Encodes what the first manual execution of the pipeline proved (the round-one walkthrough in the validation study), so it binds every future implementation and operator rather than living in one session’s memory:
- INGEST requires attachment fidelity — silent attachment loss is an intake failure that stops the round (found live).
- CLASSIFY separates four content kinds (spec/03 §3.1) — one-shot changes, standing policies, future intents, sentiment — each with a destination, and marks judgment calls explicitly. Posture: make the call on create-questions; put only edit-questions to humans.
- Drafting discipline gains the prominence review (does the page say anything twice?) and the replacement sweep (no stale references to the replaced target survive).
- New spec/03 §7 “The round” — the requestor reviews the SUM: one message per round with an itemised summary page, a browsable fold preview kept visibly distinct, the item list in the message body, edit-questions only, an AI-disclosure line, and stated expiry dates. Review artefacts are append-only. Dispatch carries a drafts-only ceiling until the nonce loop lands.
- spec/04 §3.1 class split — menu STRUCTURE changes stay
structural; repointing an existing item’s ref or label iscontent-update(resolves the round-one ambiguity).
Implementer response: the quoin round tool (FUTURES) implements §7
mechanically; role specifications built on this pipeline cite spec/03
instead of restating it; intake integrations are rejected if they cannot
prove attachment fidelity.
D-008 — 2026-09-24 — Featured content (flag + featured refs)
Class: ADDITIVE
Featuring is a flag on the content itself: featured: <slot-name>
(kebab-case, optional) on post and document (spec/02 §9), and
featured/<slot> becomes a valid ref anywhere refs are legal
(spec/01 §5.1). A referenced slot must resolve to exactly one carrier;
zero or multiple fail the build loudly, so a half-moved feature cannot
ship. No new file, no new tool: featuring is an ordinary page edit through
the existing content path, classed content-update (spec/04 §3.1) —
promotion requests become routine, low-friction changes for the email
pipeline instead of structural menu edits.
Found live: the reference site carried FOUR authored copies of “latest submission” (hero CTA, feature block, header menu, banner menu), nine months stale. With one flag and shared refs, surfaces cannot disagree.
Revised same-day before any implementation: the first draft used a
featured.yaml slots file with a pick: latest selection rule and a
dedicated tool. Dropped for tool-economy on the owner’s challenge — the
flag form reuses quoin put and keeps state on the content. The rule
form (projection-filled slots, staleness-immune) and document.tags are
recorded in FUTURES as deferred, revisit if flag-moving proves
unreliable in practice.
Origin: the first real requestor email (round-one walkthrough, task 1: a
standing request that the newest submission always lead the front page).
Site convention (reference site): a single slot, current-news; the agent moves
the flag when a new submission publishes, in the same PR.
Implementer response: quoin-cli — accept featured in put page
validation, resolve featured/* refs in the validate/check ref gate
(exactly-one rule, warn on unreferenced flags), show slot resolution in
quoin status. Sites — schema field + build-time resolution so blocks
and menus accept featured refs; the reference site adopts via one structural PR,
then a content PR flagging the current lead item and repointing surfaces.
D-007 — 2026-09-09 — Theme development workflow (landed from FUTURES)
Class: NORMATIVE
Implements the accepted theme-development design (formerly FUTURES.md;
plan in Cairn 2026-09-09:theme-development-workflow-plan):
- Theme jail widened to
themes/**(any theme, active or not, kebab-case dirs; everything outside still unreachable). Building a new theme no longer requires switching to it first — the sequencing friction found live while building a client theme is gone. - Typed
site.yamltheme tools:quoin themes(installed themes + active);quoin theme set <name>(edits ONLY thetheme:field — targeted one-line edit, verified 1/1 diff; refuses unknown/invalid manifests and themes that cannot render current content, naming the missing blocks);quoin theme chrome(edits ONLY the chrome menu wiring; validates menu names;banner=noneremoves). Identity/contact/registration fields remain unreachable by tools. - Per-theme preview:
quoin preview --theme <name|all>via aQUOIN_THEMEbuild-time env override honoured by the site’s theme registry — mutation-free theme comparison (site.yaml untouched). - All-themes validation:
quoin validate --all-themes— content must conform to every installed theme’s manifest.
Companion site fix (both reference sites): token
validation direction flipped — tokens.yaml is the site’s knob set, a theme
manifest declares which knobs it consumes (required), and extra site tokens
are valid (catchall hex). Previously a theme with a narrower token set
(alt) could not build alongside themes that declared more.
Implementer response: update tool implementations (reference: quoin-cli
a13abcc); sites honour QUOIN_THEME at theme resolution; spec/08 §2/§4
updated accordingly.
D-006 — 2026-09-09 — The normative tool surface (spec/08)
Class: NORMATIVE
The tool surface grew with the system but was only documented in tool
descriptions and AGENTS files. spec/08-tooling.md now specifies it
normatively: the enforced loop; the 12-tool catalogue with per-tool
enforcement; the update-intent rule (put_page on an existing page
requires update: true; results report created vs updated — implemented in
quoin-cli after the content migration exposed the missing edit path); the
theme jail (active-theme-only writes, tokens redirect, post-write
validation gate, recorded sequencing limitation); the site adapter and
discovery (cross-ref D-005); and the region annotation and inspect
convention (reserved data-quoin-region names: site-header,
banner-nav, page-main, site-footer, block: <type>; ?inspect
activation; inert-without-param guarantee). §7 lists what no tool may reach.
Also adds FUTURES.md: accepted-but-unbuilt work (theme development
workflow, hosted previews, email pipeline, media migration, lazy theme
loading, shared theme packages) and rejected ideas with reasons.
Implementer response: conform tool implementations to spec/08; themes
MUST emit data-quoin-region annotations per §6; adopt the update-intent
rule. The theme-development workflow itself remains in FUTURES.md until
implemented.
D-005 — 2026-09-09 — The site tool contract (standalone quoin-cli)
Class: NORMATIVE
The tool surface is extracted from site repositories into a standalone,
globally-installed CLI/MCP (quoin-cli; quoin binary; quoin mcp serves
stdio). Site repos MUST contain no tool code.
Change: sites expose the site adapter — <site>/src/lib/schemas.ts
MUST export: collectionSchemas, collectionFileExtensions, REF_PATTERN,
blockDescriptor, menuSchema, siteSchema, trustSchema,
themeManifestSchema, and SHOULD export placeholderEmail (optional 9th).
The tool discovers the site by walking up from the working directory to the
first directory containing site.yaml (env override QUOIN_SITE), loads the
adapter dynamically, and verifies the contract on every load — a missing
symbol is a hard error naming the contract. All enforcement (change-branch
discipline, jail, validation gates, open_pr refusal) is unchanged and now
site-agnostic. MCP clients register one global server (quoin mcp); the site
resolves per call from the client’s working directory.
Implementer response: sites keep only the adapter; remove any local tool
code and register quoin mcp once per client. Reference implementation:
quoin-cli (12 tools, verified against the reference site).
D-004 — 2026-09-08 — Theme layer and the theme contract
Class: NORMATIVE
The owner’s requirement: content, structure, and theme must be independently changeable — a different theme with unchanged structure and content; content changes touching neither; structural changes (adding an element) without re-Theming.
Change: spec/01 §9 adds themes as a first-class layer: themes/<name>/
packages (chrome, block renderers, page templates, styles) behind a
theme.yaml manifest (spec/02 §8), one active theme per site, with
build-fatal conformance: content blocks ⊆ manifest blocks; tokens validated
against manifest-declared knob names; theme swap leaves content and structure
byte-identical. Adding a block type is a conscious coupling of schema +
theme renderers, made loud by the manifest check.
Implementer response: adopt the theme directory layout and manifest
checks; move presentational code out of src/; wire token writes to the
manifest. Reference implementation: the reference site (themes/default +
themes/alt swappability proof).
D-003 — 2026-09-08 — Menu parents may omit ref and href
Class: NORMATIVE
Found by the first validation implementation (a community campaign site as test
case): the spec/02 §4 menu refine required every item to carry exactly one
of ref/href, which forbids label-only dropdown parents (“More”) that
exist on real sites. The spec/01 §3 sentence “items may nest” already implied
such parents are legitimate.
Change: a leaf item MUST carry exactly one of ref/href; a parent item
with children MAY omit both. Renderers must present such parents as
non-navigating labels.
Implementer response: update menu-item validation to exempt parents with children; render them as labels, not links.
D-002 — 2026-09-08 — Protocol renamed Lintel → Quoin
Class: EDITORIAL (renaming; no normative change)
The name lintel was already taken in the owner’s GitHub namespace by an
unrelated project (jwebster/lintel, the Cairn plugin specification), and a
push to it was correctly rejected as non-fast-forward. The protocol is
renamed Quoin: the dressed cornerstone laid at the corner of a wall,
identical in every building on the street — the same metaphor family
(drywalled stone construction) and the same meaning for this protocol (the
shared, repeated element that binds every page).
Implementer response: none. All references updated throughout.
D-001 — 2026-09-08 — Initial draft
Class: NORMATIVE (initial release)
The initial draft of the Quoin specification:
constitution.md— ten invariants (v1)glossary.md— normative vocabulary (v1)spec/00overview, layer model, conformance language, versioningspec/01site model: anatomy, page types/collections, templates, blocks, composed pages, the blob rule, menus, site config, references, tokens, projections, slugsspec/02content schema: mechanics, five reference page types (info,document,post,composed,blob), reference block library, menu/site-config/media schemas, trust filespec/03authoring pipeline: roles, ingest → classify → draft → PR, the email rule, drafting discipline, failure-to-interpretspec/04review & approval: two-level approval, nonce binding, trust dial (L1/L2/L3),trust.yaml, audit record, revocationspec/05delivery: static output contract, preview/live environments, atomic publish, revert-based rollback, backupsspec/06security: threat model, sender identity, approval binding, agent credentials, content hygiene, secrets, incident responsespec/07conformance: checklist (10 checks), levels L0/L1/L2, validation vectors- the validation study (not published) — against four real sites (two community-group sites and two owner-maintained sites); eight gaps found and absorbed into this draft; zero blobs required across all four
Implementer response: build from this draft. Record D-001 as the
CHANGELOG entry ID in conformance reports.
Lineage: research study and decision recorded in Cairn as
2026-09-08:headless-cms-build-vs-buy-research (v3) and
2026-09-08:git-first-agent-authored-websites. Spec lineage and format
follow an earlier Croftsware specification, Drystone (pure documentation, constitution-first,
changelog-as-normative-process).