ADR-0102: Typed Template Variables (text | date | number — and Deliberately No Enum)¶
- Status: accepted
- Date: 2026-08-03
- Deciders: Nicolas Burri ("D1a Option A · D1b tend to agree with NO… skip for now"), from finding #8 of the 2026-08-03 round (an "Audit date" rendered as a free-text input) and the assessment in typed-attributes-options.md.
- Relates to: ADR-0049 (template variables — the grammar this extends), the instantiate flow
(the dialog this types), ADR-0079 D-D (the deliberate free-token precedent this does NOT
disturb),
08_crosscutting_concepts.md(the validation posture this knowingly crosses).
Context¶
Template variables (template-vars fence, ADR-0049) carry no type: every variable renders as a
text input at instantiation, so a checklist's "Audit date" accepts anything. In a QMS, a date
field that is not a date is a data-quality hole — inconsistent formats break any later sorting,
filtering or ageing of the value. The assessment established that no attribute or variable
definition carries a type anywhere in the system, so introducing one is a content-model decision,
not a wiring task.
Decision¶
- The template-variable declaration gains an optional TYPE:
text | date | number, as an additional field of thetemplate-varsgrammar. Absent meanstext, so every existing released template remains valid and unchanged in meaning — the current parser already ignores a trailing field, which is what makes this backward compatible. - The instantiate dialog renders the matching control — a real date picker for
date, a numeric input fornumber— and the server validates the VALUE at instantiation (a non-date in adatevariable is refused with a named message; stored values are normalized: ISO-8601 dates, plain decimal numbers). - No
enum(values)— deliberately (Nicolas: "it would be nice to have but I am worried about the consequences"). An enum member starts foldingtemplate-varstoward a custom-attribute engine, which the conventions explicitly avoid ("fixed vocabularies over custom-attribute engines"). Revisit only when a real template demonstrates the need. - Trace-item attributes are NOT typed by this ADR (Option B declined): ADR-0079 D-D chose free tokens for risk values on purpose, and none of the 24 registered attributes is a date or number today. That decision stands untouched.
- The validation-posture crossing, stated: the architecture doc's boundary is "constrained
by the authoring UI but the server does not value-check." Typed variables cross it — the
second server-side value rule in the system (after
designKind). This is intentional and narrow: the check exists exactly where a wrong value becomes a frozen record.
Consequences¶
- Grammar: one optional field in the
template-varsfence; parser + KDoc; released templates untouched. - Instantiation: typed controls in the dialog, server validation + normalization, named refusals; e2e covers date/number/absent-type paths.
- The manual's template coverage gains one sentence per type; the crosscutting-concepts doc's posture sentence gains the stated exception.
- Existing free-text values in already-instantiated records are NOT migrated (they are released content; the type governs future instantiations only — the ADR-0095 "existing keys are never renamed" principle applied to values).