ADR 0001 — The support catalog is rendered, never restated

  • Status: accepted
  • Date: 2026-08-18
  • Scope: putnami.dev (sites/putnami.dev)

Context

A support status is a public promise: it tells a reader whether they can depend on a package today. The workspace root holds exactly one reviewed authority for those promises, putnami.support.json, and protocols/support is explicit that a generated view must point back at that file instead of becoming a second inventory.

The site was doing the opposite. src/lib/tools.ts carried a hand-written status on each documented surface, and the docs hub rendered it as a badge. That list had already drifted in two ways that a reader could not detect:

  • the tooling surface was published as evolving, a token the support protocol does not accept as a wire value at all, while the reviewed catalog classifies @putnami/cli as stable;
  • the catalog's 80 reviewed entries had no published representation anywhere, so a visitor asking "is this stable?" had no answer short of reading the repository.

Drift here is worse than a stale sentence. Publishing preview for something the catalog calls stable understates a commitment; publishing stable for something reviewed as experimental invents one.

Decision

The reviewed catalog is the site's only source of support statuses.

/docs/support is a generated page. src/plugins/support-catalog.plugin.ts reads putnami.support.json at the workspace root and renders every classified package and protocol, with the independent default and parity claims for the subjects that carry them. The page is never committed, and it is a pure function of the catalog bytes, so repeated builds produce identical output.

The reader is strict. Only the three reviewed statuses parse; a token like beta or evolving, a protocolVersion other than the exact integer 1, a repeated (kind, id), or an experimental subject that also claims to be default-on fails the build. Publishing a page that silently omits reviewed statuses would understate a public commitment, which is worse than not building.

src/lib/tools.ts names the catalog subject for each documented surface — supportSubject — and never restates its value. Statuses are resolved server-side, in src/app/docs/loader.ts, which keeps tools.ts client-safe for the islands that import it. A surface the catalog deliberately does not classify carries supportSubject: null and renders no badge.

The managed platform is such a surface. The support protocol classifies packages, protocols, and features — things a user depends on — not services Putnami operates, so neither the platform surface nor the two site projects in sites/ gets an invented classification.

The generated page is written before static paths are enumerated, from the same callback that materializes content bundles, so a cold build and a warm build publish the same page set and the same route digest.

Rejected alternatives

  • Keep the hand-written list and add a test that compares it to the catalog. The test would prevent drift, but the second inventory would remain: every new classification would need two edits, and the page would still show only the five surfaces the site happens to document rather than the reviewed catalog.
  • Import putnami.support.json directly from the client-safe module. It would reach outside the project root through a bundler-resolved relative import, and it would pull the whole catalog into the browser bundle to render five badges.
  • Commit the generated page under doc/. It would then be generated output under review, drifting the moment a classification changed without a rebuild — the exact failure this ADR exists to prevent.
  • Write the page into the source public/docs mirror as well. The statics plugin declares routes from the source public/ folder and the public-surface plugin declares the generated copies; both declaring the same path fails the route inventory with http_routes.duplicate_route.
  • Invent a site support kind so the two site projects appear in the catalog. That is a wire-contract change to a closed vocabulary, made to satisfy a checklist rather than a consumer, and it would turn a promise about dependable artifacts into a promise about hosted services.
  • Tolerate an unparseable catalog and publish what could be read. A partial table reads as a complete one; a missing row is indistinguishable from "not supported".

Consequences

  • Adding, removing, or reclassifying an entry in putnami.support.json changes a published page with no site edit. That is the point, and it also means a careless catalog edit is immediately public.
  • The catalog participates in this project's generate cache key, so a classification change invalidates the site build. Without it the page would serve a stale promise from cache.
  • A malformed catalog now breaks the site build, not just the support protocol's own gate. That is a deliberate second consumer of the same strictness.
  • Surfaces the catalog does not classify render no badge. A future reviewer who wants a badge there must get the subject classified rather than edit the site.
  • The status vocabulary on this site is closed at three values. Presenting a fourth would require a support-protocol version bump first.