Status: Accepted
Date: 2026-07-06
Context
The .context/ frontmatter contract used mixed-case enum values: type and
status were lowercase (plan, draft), severity and value were lowercase
(high, critical), while effort was already upper (S/M/L/TBD). ADR-049
codified value with lowercase enums, consistent with the fields around it. The
casing was inconsistent across the contract and we chose to standardise it.
This ADR amends the enum casing established across ADR-046 (severity,
known-issue), the earlier effort/status/type conventions, and ADR-049
(value). It does not revisit any of their substantive decisions — the
three-axes model, the value rubric, the read protocol, and per-type requiredness
from ADR-049 all stand unchanged. Only the surface form of the values changes.
Decision
All
.context/frontmatter enum values are UPPER_CASE:type:PLAN|FINDING|ANALYSIS|INSTRUCTION|AUDIT|KNOWN_ISSUEstatus:DRAFT|ACTIVE|DONE|SUPERSEDEDseverity:CRITICAL|HIGH|MEDIUM|LOWvalue:HIGH|MEDIUM|LOWeffortwas alreadyS|M|L|TBD— unchanged.
known-issuebecomesKNOWN_ISSUE(SCREAMING_SNAKE_CASE). The directory
staysknown-issues/; the generator maps theKNOWN_ISSUEtype value to that
directory group. The enum value and directory name intentionally differ in case
and separator.ADR status vocabulary is out of scope and stays lowercase. ADRs use
proposed|accepted|deprecated|superseded, a separate vocabulary
with its own tooling (merge-status-sync.sh, the ADR schema). It is not changed
here. Where a script handles both (e.g.merge-status-sync-lib.sh), only the
plan-status branch was uppercased; the ADR-status branch was left as-is.The migration is mechanical and total. The schema enums, the validator’s
per-type conditionals, the index generator’stype_group_keyand
severity_rank,check-plan-drift.sh, the plan-status branch of
merge-status-sync.sh, the Go remediation-plan generator, every existing
.context/**/*.mdfrontmatter value, the authoring skills and their templates,
and the fixture tests were all converted in one PR.
Consequences
- Easier: one casing convention across the whole frontmatter contract; enum
values are visually distinct from surrounding prose and directory names. - Breaking, one-time: every
.context/file changed, so the migration had to
land atomically with the validator, generator, and Go changes, or validation
would fail mid-migration. Done as a single follow-up PR after the value-signal
work (ADR-049) had merged, to keep that PR focused and green. - Case-sensitive going forward:
validate-context-frontmatter.shrejects
lowercase values (its enum checks derive from the schema). A file authored with
status: activenow fails validation with a clear message. - Existing ADRs are unchanged. Per the ADR immutability rule, historical ADRs
(including ADR-049 and ADR-046) keep their original lowercase examples as
point-in-time records; this ADR is the forward-looking casing authority. - Not addressed: ADR-status casing (deliberately out of scope) and the
separate observation that Go-generated remediation plans do not yet carry a
valuefield (tracked independently, not a casing concern).
Amendment (2026-07-06): effort deliberately stays S/M/L/TBD
Decision 1 recorded effort as “unchanged” almost in passing. This amendment
promotes that to an explicit, reasoned decision so it is not re-opened:
effort intentionally keeps its single-letter T-shirt sizes (S/M/L/TBD)
and is the one enum exempt from the full-word UPPER_CASE convention.
A proposed migration to full words (SMALL/MEDIUM/LARGE) was raised as the
effort-single-letter-values known-issue and taken through a 3-reviewer
plan-review (2026-07-06). All three reviewers recommended against it:
- No benefit:
effortalready parses and sorts correctly; nothing downstream
depends on its spelling. Gradedvalue: LOW. - Net-negative: full words make
MEDIUMa legal value foreffort,value,
andseveritysimultaneously — an ambiguity that cannot occur whileeffort
stays single-letter, sinceS/M/Lshare no token with the word-based enums.
The migration would trade one cosmetic inconsistency for a subtler collision. - Disproportionate blast radius: ~73 occurrences across ~28 files, including an
independentaggregationEffort()inreporter/aggregation.gothat the test suite
would not catch — a silent split-brain risk far exceeding the cosmetic gain.
The effort-single-letter-values known-issue is therefore closed SUPERSEDED by
this amendment. Single-letter effort is the deliberate, documented exception to
the UPPER_CASE convention, retained specifically to keep the three magnitude axes
(effort / value / severity) unambiguous at a glance.