Skip to main content

ADR-0028 — Labels live in source, not a runtime override layer

  • Status: Accepted
  • Date: 2026-05-29
  • Decision-makers: Kvick partnership
  • Supersedes: —
  • Superseded by: —

Context

A nomenclature audit (v0.6.250) walked the operator console — 97 sections, 451 fields, ~140 rename proposals — to make the Hub's vocabulary consistent (imperative verbs, no gerunds, industry terms over software terms, an accessible label on every icon-only button). That raised the question of where a renamed label should live.

A tempting answer had already been prototyped: a D1 label_overrides table (migration 078) giving a persistent runtime rename layer — change a label in the UI, store the override in the database, apply it on every render. The v0.6.241 Inline Rename Overlay (Alt+R, hover a data-commentable-label region, edit its text) was the front end for it.

Decision

public/index.html source is the single source of truth for every operator-visible label and every data-commentable-label value. There is no runtime override layer.

  • The label_overrides table is rejected. Migration 078 was rewritten to DROP TABLE IF EXISTS label_overrides.
  • Renames are applied directly to the source HTML, touching every occurrence of a label in one diff.
  • The Inline Rename Overlay survives only as a sparing "fix one cryptic thing later" hover affordance — not as a systematic rename mechanism. Anything systematic goes through a source edit.
  • The canonical vocabulary rules (create = + New <noun>, attach = Attach <noun>, imperative verbs only, ledger row for money lines, accessible labels on icon-only buttons, etc.) live in docs/nomenclature-doctrine.md and are cited by the Process Library's codegen export prompt.

Consequences

Positive:

  • One source of truth. grep over public/index.html always finds the real label; no "the DB says something different" surprises.
  • The Process Library can cross-reference labels reliably — its region_label tags point at strings that actually exist in source.
  • No permanent override layer carried forever to solve a one-time cleanup.

Negative:

  • Renames require a code edit + deploy, not a runtime toggle. For a one-time audit that's correct; for routine per-shop relabelling it would be friction (not a current need under single-tenant-per-shop, where each shop forks its own source).
  • If a button is renamed, Process Library entries that reference the old name must be re-seeded.

Notes

The doctrine is wired into tooling: apiProcessExportPrompt instructs generated code to follow docs/nomenclature-doctrine.md, so codegen stays on-vocabulary.

See also

  • Process Library — depends on labels being grep-able in source.
  • Naming things — the contributor-facing naming guidance.
  • Current state — the v0.26 batch note.