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_overridestable is rejected. Migration 078 was rewritten toDROP 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 rowfor money lines, accessible labels on icon-only buttons, etc.) live indocs/nomenclature-doctrine.mdand are cited by the Process Library's codegen export prompt.
Consequences
Positive:
- One source of truth.
grepoverpublic/index.htmlalways finds the real label; no "the DB says something different" surprises. - The Process Library can cross-reference labels reliably — its
region_labeltags 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.