opsinjs

Release phases

The three statuses are planned, shipped and deprecated, with exactly what each one promises and what none of them promises.

One vocabulary, three values

A kind: component page carries a status in its frontmatter, and the row for that component in registry/catalogue.ts carries the same word. Those are the only two places the word appears. No other page has a status, because on a page about colour or consent the field was describing the prose rather than anything a reader could install.

PhaseIt exists asWhat the API promisesShould you use it
plannedA written specification, no codeNothing. The proposed API is a sketchDesign against it. Do not code against it
shippedInstallable source in the registryIt may change in any release, with a changelog entryYes, if you can take an undeclared migration
deprecatedInstallable source, on its way outFrozen, with a named replacement and a named removal versionNo, for anything new

Do not confuse this with clinical status. The four clinical levels are steady, watch, attention and urgent, and they describe a person's data. These three describe our software. The collision is unfortunate and it is why the system glossary lists both words separately.

What shipped does not mean

Every opsinjs component has been audited against WCAG 2.2 AA by its authors, in a static source pass and a rendered pass, and the findings were fixed in the same change. No component has had an independent accessibility review, and none has had a clinical review. shipped means the source installs and that its authors have run that audit. It does not mean an independent reviewer or a clinician has signed anything. Nothing here is for a production health surface until a clinician does. The author-run audit decision records what the audit covered and what it did not.

This is the whole reason there is no fourth word between shipped and deprecated. A phase ladder with a rung above shipped would have implied that some components had climbed it, and none has. Each component page says what has been checked on that component and what has only been argued, in its own ## Accessibility section and its own <StubNotice>, and that per-component statement is the thing to read before you depend on anything. A single word in frontmatter cannot carry it.

What each phase requires of the page

planned owes eight sections: Preview, Installation, When to use it, Clinical meaning for a health-* category, Anatomy where the component has more than one part, Proposed API, Accessibility and Related. The sections that would need code to be truthful are omitted, not left empty. An empty heading is a promise nobody kept; an absent heading is an accurate description of a component that does not exist. Every planned page also carries <NotBuiltYet>, the machine-readable marker that lets an agent tell a specification from a component without parsing English.

shipped and deprecated owe the same fourteen sections, five of which are optional. They point at one outline on purpose: retiring a component is then a frontmatter change and nothing else, rather than a content edit nobody has time for. Anatomy of a component page has the full table and says which five are optional. At every phase the page is short: <StubNotice> opens it above the first H2 with the review floor and at most three open questions, and assert-ia rule LEAN001 fails the build when the body passes a thousand words, or twelve hundred and fifty on a health-* page.

<PageTemplate> fails the build when a required section is missing, so the status is a claim the build enforces rather than a label somebody set once.

Moving between them

A page reaches shipped in the commit that gives it code. The component's file under registry/bases/base/ renders, pnpm typecheck, pnpm lint and pnpm check pass, <NotBuiltYet> and every <Todo> come off the page, and the page's status and its catalogue row move together in that one commit. Nothing is half-promoted, because the two sources of the word would then disagree and a reader would have no way to tell which one was stale.

A page reaches deprecated when the replacement exists. A deprecated page names that replacement, the version that deprecated it and the version that will remove it, and it appears on the deprecations list from the day it is marked. Nothing is removed without at least one release carrying the deprecation first.

What a documentation page carries instead

A page that is not about a component states its own freshness rather than a phase. reviewed, reviewer and reviewEvery are the fields, and Docs freshness is how they are enforced. A recipe, a pattern or a screen specimen describing something nobody has assembled says so in a <Todo> or a <StubNotice> on the page, which names the specific gap rather than hiding it behind a word that meant six different things.

Edit this page

Last read through against the system on 2026-09-20. Due for review every 12 months; expiry is reported by pnpm run check:freshness.

On this page