# Codify Convention

> Use when a design convention has just been decided (a time grammar, a head style, a title size, a state word, a colour rule) — lands the code, the .impeccable.md sentence, the field-manual paragraph and, when the rule has a signature, the design-contract lint, in one PR.

- Skill: `glassflow/codify-convention` (Agent Skill)
- Install (CLI): `npx skillmds@latest add glassflow/codify-convention`
- Raw SKILL.md: https://api.skillmd.com/api/skills/glassflow/codify-convention/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: glassflow (https://skillmd.com/u/glassflow)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/glassflow/codify-convention

---


# Codify a convention

A design convention that lives only in a decision log is a convention the next PR will break. This skill is
the procedure behind doc 18's rule that **a convention change lands with its codification in the same PR**.
Rationale and the four-artefact model live in
[`../../docs/18-design-governance.md`](../../docs/18-design-governance.md) — this file is the checklist.

## When to use this

Right after a convention is decided: in a critique's priority list ("four grammars for time"), in review
("we say Time here and Timestamp there"), or in a design pass. Not for a one-off visual fix that changes no
rule.

## Procedure

1. **State the convention in one sentence** with its unit of application: *"An instant is a UTC stamp
   `2026-07-03 11:57Z` in mono, in the cell; the relative phrase lives in its tooltip."* If it does not fit
   in a sentence it is two conventions; split it.

2. **Find every site.** Grep for the old grammars, not the new one — the drift is in the variants:

   ```bash
   grep -rnE 'toLocale(Date|Time)?String|Intl\.DateTimeFormat|formatDistance|<th[ >]|rounded-(sm|md|lg|xl)' src
   ```

   List the sites in the PR description. A convention applied to three of five sites is a fourth grammar.

3. **Give the convention one home in code.** A formatter in the time module, a primitive in `ui/`, a class
   in the dress file. Every site imports it; no site re-implements it. Delete the variants.

4. **Write the sentence into `.impeccable.md`** under the matching heading (Time, Table heads, States, …).
   Keep the file short: the sentence and, when useful, the name of the module or primitive that owns it.

5. **Write the paragraph into the field manual** (`docs/design/<date>-<direction>.md`): what was decided,
   what was rejected and why, which sites changed, the gate results at the landing commit.

6. **Add the mechanical rule if the convention has a signature.** Open the product's
   `eslint-design-contract.config.mjs`: if the old grammar is an AST-visible call, import, element or class
   string, add a selector to `SELECTORS` (never a new config object — see the flat-config trap in doc 18)
   and, if a legitimate exception exists, register the file with a reason. Run the gate; it must be red
   before your code change and green after. If the rule cannot tell the legitimate case apart, add the
   convention to the design skill's review-time guardrails instead and say so in the PR.

7. **Re-copy the skill references if a token or dress class moved** (`arche-design/skills/<language>/
   references/tokens.css` / `dress.css`), commit that in `arche-design` with the same date stamp.

8. **Run the gates** (`verify`, or at least lint · typecheck · token-contract · design-contract · unit ·
   the e2e specs that read the changed surfaces) and put the results in the field-manual paragraph.

## Output

One PR containing: the code, the `.impeccable.md` sentence, the field-manual paragraph, the lint selector
(or the stated reason there is none), and the site list in the description.

