From c893601fdaf722304d3042f1a24d8c726097702f Mon Sep 17 00:00:00 2001 From: Joost de Valk Date: Thu, 23 Jul 2026 16:28:39 +0200 Subject: [PATCH] change(governance): decouple speccing from shipping, add /considered/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two rule changes, plus the public register the second one needs. 1. Speccing no longer requires shipping. The old rule ("do not promote a convention to spec status without us shipping a working implementation first — the site is the proof-of-feasibility") forced a false choice whenever a topic was right for readers but irrelevant to a small static site. It also encouraged the worst outcome: implementing something we don't need, purely to earn the right to document it. Replaced with three honest page shapes — specced and shipped, specced and deliberately not shipped, or not specced — where shape 2 carries a one-line note on the page saying we don't ship it and why. That note is content, not an apology: "we are static, so no response ever means this changed" tells the reader something real about when the topic applies. 2. Adoption, not finality, is the bar for adding a page — and thin adoption is the maintainer's call. A final RFC with permanent IANA registration still doesn't earn a page if nothing implements it; the page would recommend a header no cache reads. The converse also holds — a widely-deployed convention can earn a page before its RFC lands. Where adoption looks thin, an agent must surface it rather than either shipping the page or silently dropping it. 3. New: src/content/considered/ → /considered/ ("Considered, not adopted"). Hand-curated collection, same shape as changelog (not derived, nothing generates it). Per entry: title, date, reason (too-early | out-of-scope | too-narrow), sources, and `revisit` — what would change our mind, which is what keeps the register from being a graveyard. Grouped by reason rather than date, because it reads as a register of decisions, not a timeline. Seeded with four real decisions: - HTTP Cache Groups (RFC 9875) — too-early. Final and IANA-registered, but no MDN page or BCD key, no Chrome Platform Status entry, nothing in Cloudflare's cache docs or changelog, and no sign in Fastly/Varnish/nginx/Squid. Souin is the one candidate and documents itself against the pre-RFC draft. - HTTP QUERY (RFC 10008) — out-of-scope. A property of an API, not a website. - CSS subgrid — out-of-scope. Records why PR #82 was closed; this is the reference case for newly-Baseline authoring features generally. - WebSub — too-narrow. Real, implemented, auditable, but hub publishing is a fediverse/IndieWeb speciality. Entries are decisions already taken, not a queue. When a reason expires, the entry is deleted in the same PR that adds the spec page. Wiring: header + footer nav, OG image, llms.txt Project section, and a "When a topic is absent" section in SKILL.md (digest re-signed) so an agent checks the register before reporting a gap or re-proposing a rejected topic. CONTRIBUTING.md gains the same guidance for human contributors. Verified: page renders correctly at /considered/ in the dev server, three reason groups, four entries. build ✓ lint ✓ format ✓ check ✓ (0 errors) check:skill ✓ Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 28 +++- CONTRIBUTING.md | 6 + ops/routines/daily-standards-scan.md | 30 +++- public/.well-known/agent-skills/index.json | 2 +- .../specification-website/SKILL.md | 12 ++ public/og/considered.png | Bin 0 -> 21524 bytes scripts/generate-assets.mjs | 7 + src/components/SiteFooter.astro | 5 + src/components/SiteHeader.astro | 6 + src/content.config.ts | 20 ++- src/content/considered/css-subgrid.md | 16 +++ src/content/considered/http-cache-groups.md | 19 +++ src/content/considered/http-query-method.md | 16 +++ src/content/considered/websub.md | 16 +++ src/lib/site.ts | 28 ++++ src/pages/considered.astro | 128 ++++++++++++++++++ src/pages/llms.txt.ts | 3 + 17 files changed, 332 insertions(+), 10 deletions(-) create mode 100644 public/og/considered.png create mode 100644 src/content/considered/css-subgrid.md create mode 100644 src/content/considered/http-cache-groups.md create mode 100644 src/content/considered/http-query-method.md create mode 100644 src/content/considered/websub.md create mode 100644 src/pages/considered.astro diff --git a/CLAUDE.md b/CLAUDE.md index df7cba88..fa4166c4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -73,6 +73,7 @@ These mirror `CONTRIBUTING.md`. Enforce them in your own writing and when review | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `src/content/spec//.md` | Spec content. Edit here. | | `src/content.config.ts` | Content collection schema. Edit if adding a field. | +| `src/content/considered/.md` | Hand-curated register of standards deliberately **not** specced, with the reason and what would reverse it. Rendered at `/considered/`. Not derived. | | `src/lib/site.ts` | Site metadata + the canonical category list. | | `src/layouts/BaseLayout.astro` | HTML shell, head, dialog for ⌘K search, Plausible (PROD only). | | `src/layouts/SpecLayout.astro` | Spec page wrapper; emits TechArticle + BreadcrumbList JSON-LD; advertises Markdown alt via `markdownUrl`. | @@ -153,7 +154,32 @@ The same PR must do **one** of: Also update the [api-catalog Linkset](public/.well-known/api-catalog) if the capability adds a discoverable resource, and the global `Link` header in [`public/_headers`](public/_headers) if it has a registered IANA `rel`. Both should match what the new spec page describes. -The reverse holds too: **do not promote a convention to spec status without us shipping a working implementation first.** The site is the proof-of-feasibility. If the underlying convention turns out non-existent or defunct (see the `/.well-known/ai.txt` deletion history), remove the asset _and_ the spec page in the same PR — don't leave the page documenting something we no longer ship. +If the underlying convention turns out non-existent or defunct (see the `/.well-known/ai.txt` deletion history), remove the asset _and_ the spec page in the same PR — don't leave the page documenting something we no longer ship. + +### Speccing and shipping are separate decisions + +**We do not have to ship something to spec it.** The site is a worked example wherever that is useful, not a gate. Plenty of good advice does not apply to a static, cookieless, six-page-of-plumbing site: a page can be right for the sites reading it and irrelevant here. When that is the case, write the page and skip the implementation — but **say so on the page**, in one line, with the reason. "This site does not ship it: we are static, so no response ever means _this changed_" is useful content. Silence is not. + +So there are three honest shapes for a page, and all three are fine: + +1. **Specced and shipped** — the common case. Carry the "this site ships it; see [X]" callout. +2. **Specced, deliberately not shipped** — the topic does not apply to us. Carry a one-line note saying that, and why. +3. **Not specced** — see below. + +### What we don't spec, and where that gets recorded + +**Do not add a page for a convention nothing is using yet.** A standard being final is not sufficient; something has to implement it, or the page recommends a header no cache reads and an element no browser honours. Being final also is not necessary — a widely-deployed convention can earn a page before its RFC lands. + +**This particular call belongs to the maintainer, not to an agent.** If a topic is real and well-sourced but adoption looks thin, do not add the page and do not silently drop it either — surface it (Slack, for the daily scan; the PR description otherwise) and let Joost decide. + +When a topic is turned down, record it in **`src/content/considered/`** — the hand-curated collection rendered at [`/considered/`](src/pages/considered.astro). One file per topic: + +- `title`, `date` (the decision), `reason` (`too-early` | `out-of-scope` | `too-narrow`), `sources`, and `revisit` — the last being _what would change our mind_, which is what keeps the register from becoming a graveyard. +- A two-or-three-paragraph body: what the thing is, why it did not land, and — where the reasoning generalises — what it is the reference case for. + +Being in `/considered/` is not a rejection forever. When the reason expires (something ships it; adoption broadens), delete the entry in the same PR that adds the spec page. + +Like the changelog, this collection is **not derived** — nothing generates it. It is also **not** a to-do list: entries are decisions already taken, not a queue. ## When changing a status diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19ca8030..b8631d8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,6 +49,12 @@ Just open a PR. You can use the "Edit this page on GitHub" link on any spec page 3. Run `npm run dev` locally on port 31337 and verify the page renders. 4. Open a PR. CI will type-check, build, and verify the schema. +A topic has to be **used**, not merely standardised. A final RFC with a permanent IANA registration still does not earn a page if nothing implements it — the page would recommend a header no cache reads. The reverse also holds: a widely-deployed convention can earn a page before its RFC lands. If adoption looks thin, say so in the issue and let the maintainer weigh it. + +Topics that get turned down are recorded publicly at [`/considered/`](https://specification.website/considered/), with the reason and with what would reverse the decision. That page is worth reading before you open an issue — your topic may already be there, in which case the useful contribution is evidence that its `revisit` condition has now been met. + +Note that we do **not** require the site to implement something before specifying it. Plenty of good advice does not apply to a small static site; such a page simply says so in one line, and explains why. + ### New category These are rare. Open an issue first — categories are slow-changing. diff --git a/ops/routines/daily-standards-scan.md b/ops/routines/daily-standards-scan.md index dc2fc83a..f676f574 100644 --- a/ops/routines/daily-standards-scan.md +++ b/ops/routines/daily-standards-scan.md @@ -8,8 +8,8 @@ You maintain **specification.website** — a platform-agnostic spec of what a good website does, generated entirely from Markdown under `src/content/spec//.md`. Read `CLAUDE.md` and `CONTRIBUTING.md` first; they are binding (status discipline, -cardinal content rules, the "ship it before you spec it" rule, the add-a-page workflow, -the SKILL.md digest step). +cardinal content rules, the separation of speccing from shipping, the add-a-page +workflow, the SKILL.md digest step). ## Goal @@ -121,10 +121,24 @@ context. `recommended`/`optional`; `avoid` for outdated/harmful. Default to `recommended`. - Primary sources only (WHATWG / W3C / IETF / IANA / WCAG / schema.org first; MDN / web.dev for context). -- **Ship it before you spec it**: a brand-new _convention_ that would require the site to - implement a new capability does NOT get a PR — flag it in Slack as "needs us to ship X - first" so the maintainer can decide. PRs are only for documenting standards we can - honestly describe (and, where applicable, that the site already satisfies). +- **Speccing does not require shipping.** A page whose topic does not apply to this site + is still a good page — write it, and add a one-line note saying we do not ship it and + why. Do not withhold a PR on the grounds that we would have to implement something. +- **Adoption, not finality, is the bar.** Do NOT open a PR for a convention nothing is + using yet, however final the RFC and however permanent the IANA registration. A page + recommending a header no cache reads is worse than no page. Conversely a widely-deployed + convention can earn a page before its RFC lands. +- **Thin adoption is the maintainer's call, not yours.** When a topic is real and + well-sourced but you cannot find implementations, do not open the PR and do not silently + drop it. Put it in Slack with what you checked (MDN/BCD, Chrome Platform Status, the + relevant CDN or server docs) and let Joost decide. If he says add it, add it. +- **Record every turn-down.** Anything you skip on adoption or scope grounds gets an entry + in `src/content/considered/` — `title`, `date`, `reason` (`too-early` | `out-of-scope` | + `too-narrow`), `sources`, `revisit` (what would change our mind), and a short body. That + register at `/considered/` is public and is the reason the Slack "skipped, and why" + section exists: the two should agree. Adding an entry there is a normal PR, and it is the + right output for a scan that found something real but premature. When the reason later + expires, delete the entry in the same PR that adds the spec page. ## Dedup (critical for a daily job) @@ -160,6 +174,8 @@ DM the maintainer with: - New topics found → PR links (or "flagged, needs implementation decision"). - Status changes → page + what moved + source + PR link. - Stale/dead citations → page + broken source + fix PR link. -- Anything deliberately skipped, and why. +- Anything deliberately skipped, and why — plus whether it earned a `/considered/` entry + (and the PR link if so). Anything you skipped for thin adoption goes here as an explicit + question for Joost, not as a closed decision. Keep it scannable: grouped, one line each, links inline. diff --git a/public/.well-known/agent-skills/index.json b/public/.well-known/agent-skills/index.json index 79feefc2..7798f311 100644 --- a/public/.well-known/agent-skills/index.json +++ b/public/.well-known/agent-skills/index.json @@ -6,7 +6,7 @@ "type": "skill-md", "description": "Query and apply The Website Specification — a platform-agnostic specification of what a good website does. Use when the user asks what their site should have, whether something is required, how to audit a URL, what's missing for agent readiness, or anything else where you'd otherwise be guessing at web best practice. Backs answers with primary sources and ships an MCP server with search, list, fetch, checklist, and audit tools.", "url": "/.well-known/agent-skills/specification-website/SKILL.md", - "digest": "sha256:487b0ea2610fb2e4887e8dc7b682cd6de270934d6a9513409a3c202fd62b9a7c" + "digest": "sha256:71188d9a6b563ac302db37f26e319e246ccba55d03ead299385d9828075a680d" } ] } diff --git a/public/.well-known/agent-skills/specification-website/SKILL.md b/public/.well-known/agent-skills/specification-website/SKILL.md index f675885d..bda1d32f 100644 --- a/public/.well-known/agent-skills/specification-website/SKILL.md +++ b/public/.well-known/agent-skills/specification-website/SKILL.md @@ -138,6 +138,18 @@ status promotion (e.g. a topic moving to `required`) can change a previously passing site into a failing one, so a delta check is worth doing even when no new pages were added. +## When a topic is absent + +Absence is not always an oversight. `https://specification.website/considered/` +lists standards that were evaluated and deliberately left out, each with a reason +— `too-early` (final, but nothing implements it), `out-of-scope` (a way of +building a site, not something a site does), `too-narrow` (real, but applies to +too few sites) — and with what would reverse the decision. + +Check it before concluding the spec has a gap, and before recommending that a +topic be added. If the topic is listed, the useful contribution is evidence that +its stated revisit condition has now been met, not a fresh proposal. + ## Sources and licence Code MIT. Content CC BY 4.0. Site source: . diff --git a/public/og/considered.png b/public/og/considered.png new file mode 100644 index 0000000000000000000000000000000000000000..82bd865ecb6e041f5fba0f4433bf957a70ac6650 GIT binary patch literal 21524 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 QrFDv3wsW~ybpe?4Uv2IU9RL6T literal 0 HcmV?d00001 diff --git a/scripts/generate-assets.mjs b/scripts/generate-assets.mjs index 3aaae2cb..22b3ea93 100644 --- a/scripts/generate-assets.mjs +++ b/scripts/generate-assets.mjs @@ -588,6 +588,13 @@ const marketingPages = [ subtitle: "New topics, status changes, and honest removals. Newest first, with sources.", }, + { + slug: "considered", + eyebrow: "CONSIDERED", + title: "What we left out.", + subtitle: + "Standards we read, weighed, and did not adopt — with the reason, and what would change it.", + }, { slug: "privacy", eyebrow: "PRIVACY", diff --git a/src/components/SiteFooter.astro b/src/components/SiteFooter.astro index fd20a80e..fe81e917 100644 --- a/src/components/SiteFooter.astro +++ b/src/components/SiteFooter.astro @@ -79,6 +79,11 @@ import { site, categories } from "~/lib/site"; >Changelog +
  • + Considered +
  • PrivacyChangelog
  • +
  • + Considered +
  • `, subscribers register with that hub, and the hub delivers new content as it appears instead of every reader re-fetching the feed on a timer. It is a W3C Recommendation, re-published on 2 June 2026 with added cross-site-scripting mitigations for the subscription verification step. + +It clears the bar on every count but one. The convention is real, it is implemented, and it is auditable — `rel="hub"` is right there in the feed. But outside the fediverse and the IndieWeb, very few sites publish a hub, and fewer still would benefit: for a site with a handful of new items a week, polling costs almost nothing and adds no moving parts. Recommending a hub to every site that ships a feed would be recommending infrastructure most of them should not run. + +The existing pages on [feed discovery](/spec/foundations/feed-discovery/) and [feed hygiene](/spec/foundations/feed-hygiene/) cover what nearly every site actually needs from a feed. diff --git a/src/lib/site.ts b/src/lib/site.ts index 5185f419..b1b9d587 100644 --- a/src/lib/site.ts +++ b/src/lib/site.ts @@ -120,3 +120,31 @@ export const changeTypeColor: Record = { status: "bg-amber-50 text-amber-800 border-amber-200", removed: "bg-red-50 text-red-800 border-red-200", }; + +export const consideredReasonLabel: Record = { + "too-early": "Too early", + "out-of-scope": "Out of scope", + "too-narrow": "Too narrow", +}; + +export const consideredReasonColor: Record = { + "too-early": "bg-blue-50 text-blue-800 border-blue-200", + "out-of-scope": "bg-ink-100 text-ink-700 border-ink-200", + "too-narrow": "bg-amber-50 text-amber-800 border-amber-200", +}; + +// Shown as the intro under each group heading on /considered/. +export const consideredReasonBlurb: Record = { + "too-early": + "The standard is real and final, but nothing implements it yet. Speccing it would mean recommending something no visitor, crawler, or cache would notice.", + "out-of-scope": + "Real and widely used, but not a property of a website you could check from the outside. These are ways of building a site, not things a good site does.", + "too-narrow": + "Real, implemented, and auditable — but it applies to too few sites to belong in a general specification.", +}; + +export const consideredReasonOrder = [ + "too-early", + "out-of-scope", + "too-narrow", +] as const; diff --git a/src/pages/considered.astro b/src/pages/considered.astro new file mode 100644 index 00000000..ab9dddf4 --- /dev/null +++ b/src/pages/considered.astro @@ -0,0 +1,128 @@ +--- +import BaseLayout from "~/layouts/BaseLayout.astro"; +import Breadcrumbs from "~/components/Breadcrumbs.astro"; +import { + consideredReasonBlurb, + consideredReasonColor, + consideredReasonLabel, + consideredReasonOrder, +} from "~/lib/site"; +import { getCollection, render } from "astro:content"; + +const entries = await getCollection("considered", ({ data }) => !data.draft); +entries.sort((a, b) => b.data.date.localeCompare(a.data.date)); + +const rendered = await Promise.all( + entries.map(async (entry) => ({ + entry, + Content: (await render(entry)).Content, + })), +); + +const dayFmt = new Intl.DateTimeFormat("en-GB", { + day: "numeric", + month: "short", + year: "numeric", +}); + +// Group by reason, in the fixed order from site.ts rather than by date, so the +// page reads as a register of decisions rather than a timeline. +const groups = consideredReasonOrder + .map((reason) => ({ + reason, + items: rendered.filter(({ entry }) => entry.data.reason === reason), + })) + .filter((g) => g.items.length > 0); +--- + + +
    + +
    +

    + Considered, not adopted +

    +

    + A specification is defined as much by what it leaves out as by what it + contains. These are standards we have read, weighed, and decided not to + cover — each with the reason, and with what would change our mind. The + changelog records what went in; this records what did not. +

    +
    + +
    + { + groups.map((group) => ( +
    +

    + + {consideredReasonLabel[group.reason]} + +

    +

    + {consideredReasonBlurb[group.reason]} +

    + +
      + {group.items.map(({ entry, Content }) => ( +
    1. +
    2. + ))} +
    +
    + )) + } +
    +
    + diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts index 5c0b1779..0a8dcc19 100644 --- a/src/pages/llms.txt.ts +++ b/src/pages/llms.txt.ts @@ -99,6 +99,9 @@ export const GET: APIRoute = async () => { lines.push( `- [Checklist](${site.url}/checklist/): The whole spec as a flat checklist. Also as a copy-and-paste [Markdown task list](${site.url}/checklist.md).`, ); + lines.push( + `- [Considered, not adopted](${site.url}/considered/): Standards deliberately left out of the spec, with the reason for each and what would change it.`, + ); lines.push( `- [MCP server](${site.url}/mcp/): How to connect an MCP client to the spec.`, );