@erclx/canon 5.44.0 → 5.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/REQUIREMENT.md +15 -31
- package/claude/skills/auto-ship/REQUIREMENT.md +14 -25
- package/claude/skills/backlog-triage/REQUIREMENT.md +12 -23
- package/claude/skills/build-in-slices/REQUIREMENT.md +15 -25
- package/claude/skills/canon-cli/REQUIREMENT.md +15 -27
- package/claude/skills/canon-cli/SKILL.md +0 -1
- package/claude/skills/canon-feedback/REQUIREMENT.md +10 -18
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +10 -15
- package/claude/skills/canvas-board/REQUIREMENT.md +14 -28
- package/claude/skills/ci-workflow/REQUIREMENT.md +12 -21
- package/claude/skills/code-craft/REQUIREMENT.md +14 -28
- package/claude/skills/codebase-layout/REQUIREMENT.md +14 -31
- package/claude/skills/context-fold/REQUIREMENT.md +15 -39
- package/claude/skills/context-fold/references/context.md +3 -3
- package/claude/skills/create-rule/REQUIREMENT.md +10 -24
- package/claude/skills/create-rule/SKILL.md +3 -0
- package/claude/skills/create-skill/REQUIREMENT.md +10 -21
- package/claude/skills/decision-escalate/REQUIREMENT.md +12 -24
- package/claude/skills/deploy-app/REQUIREMENT.md +12 -22
- package/claude/skills/deprecation-migration/REQUIREMENT.md +14 -42
- package/claude/skills/design-identity/REQUIREMENT.md +14 -20
- package/claude/skills/design-taste/REQUIREMENT.md +16 -57
- package/claude/skills/docs-sync/REQUIREMENT.md +14 -23
- package/claude/skills/document-health/REQUIREMENT.md +15 -29
- package/claude/skills/document-health/SKILL.md +2 -2
- package/claude/skills/document-repair/REQUIREMENT.md +32 -0
- package/claude/skills/document-repair/SKILL.md +76 -0
- package/claude/skills/document-repair/references/batches.md +44 -0
- package/claude/skills/draft-and-pick/REQUIREMENT.md +4 -3
- package/claude/skills/draft-doc/REQUIREMENT.md +4 -3
- package/claude/skills/draft-figure/REQUIREMENT.md +4 -3
- package/claude/skills/draft-identity/REQUIREMENT.md +4 -3
- package/claude/skills/draft-ready/REQUIREMENT.md +4 -3
- package/claude/skills/draft-screencast/REQUIREMENT.md +4 -3
- package/claude/skills/draft-slides/REQUIREMENT.md +4 -3
- package/claude/skills/draw-figure/REQUIREMENT.md +15 -39
- package/claude/skills/git-branch/REQUIREMENT.md +12 -26
- package/claude/skills/git-commit/REQUIREMENT.md +11 -15
- package/claude/skills/git-followup/REQUIREMENT.md +11 -22
- package/claude/skills/git-issue/REQUIREMENT.md +9 -15
- package/claude/skills/git-pr/REQUIREMENT.md +13 -32
- package/claude/skills/git-pr/SKILL.md +10 -2
- package/claude/skills/git-pr/references/closing-issues.md +47 -0
- package/claude/skills/git-pr/references/pr.md +4 -0
- package/claude/skills/git-ship/REQUIREMENT.md +13 -26
- package/claude/skills/git-split/REQUIREMENT.md +10 -17
- package/claude/skills/git-stage/REQUIREMENT.md +12 -18
- package/claude/skills/git-worktree/REQUIREMENT.md +15 -19
- package/claude/skills/make-deck/REQUIREMENT.md +13 -21
- package/claude/skills/markdown-craft/REQUIREMENT.md +9 -3
- package/claude/skills/pick-by-eye/REQUIREMENT.md +17 -67
- package/claude/skills/plan-feature/REQUIREMENT.md +15 -24
- package/claude/skills/plan-groundwork/REQUIREMENT.md +12 -28
- package/claude/skills/plan-groundwork/SKILL.md +5 -2
- package/claude/skills/plan-groundwork/references/output.md +47 -1
- package/claude/skills/plan-intake/REQUIREMENT.md +11 -26
- package/claude/skills/plan-intake/references/intake.md +2 -2
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +14 -29
- package/claude/skills/plan-intake-answer/SKILL.md +7 -1
- package/claude/skills/plan-ready/REQUIREMENT.md +17 -36
- package/claude/skills/pr-evidence/REQUIREMENT.md +11 -17
- package/claude/skills/read-frames/REQUIREMENT.md +3 -8
- package/claude/skills/record-screencast/REQUIREMENT.md +14 -17
- package/claude/skills/review-address/REQUIREMENT.md +14 -38
- package/claude/skills/review-craft/REQUIREMENT.md +14 -32
- package/claude/skills/review-pr/REQUIREMENT.md +15 -34
- package/claude/skills/review-ui/REQUIREMENT.md +14 -39
- package/claude/skills/role-orchestrator/REQUIREMENT.md +16 -99
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +5 -0
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +9 -0
- package/claude/skills/role-planner/REQUIREMENT.md +15 -73
- package/claude/skills/role-reviewer/REQUIREMENT.md +15 -65
- package/claude/skills/role-reviewer/SKILL.md +5 -1
- package/claude/skills/role-worker/REQUIREMENT.md +13 -41
- package/claude/skills/role-worker/SKILL.md +2 -0
- package/claude/skills/script-screencast/REQUIREMENT.md +10 -16
- package/claude/skills/search-craft/REQUIREMENT.md +12 -36
- package/claude/skills/search-craft/SKILL.md +1 -1
- package/claude/skills/search-craft/references/adopted.md +2 -2
- package/claude/skills/session-compact/REQUIREMENT.md +13 -23
- package/claude/skills/session-map/REQUIREMENT.md +13 -29
- package/claude/skills/session-relay/REQUIREMENT.md +14 -58
- package/claude/skills/session-relay/SKILL.md +6 -0
- package/claude/skills/session-resume/REQUIREMENT.md +13 -27
- package/claude/skills/session-worktree/REQUIREMENT.md +14 -43
- package/claude/skills/systematic-debugging/REQUIREMENT.md +13 -34
- package/claude/skills/target-check/REQUIREMENT.md +16 -23
- package/claude/skills/target-setup/REQUIREMENT.md +11 -34
- package/claude/skills/target-setup/SKILL.md +2 -2
- package/claude/skills/target-setup/references/detect.md +0 -1
- package/claude/skills/target-setup/references/verify.md +2 -2
- package/claude/skills/task-board/REQUIREMENT.md +13 -22
- package/claude/skills/task-board/SKILL.md +7 -0
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/task-complete/REQUIREMENT.md +11 -24
- package/claude/skills/task-complete/references/archive.md +1 -0
- package/claude/skills/teach-workspace/REQUIREMENT.md +14 -45
- package/claude/skills/teach-workspace/references/promotion.md +5 -5
- package/claude/skills/test-craft/REQUIREMENT.md +15 -46
- package/claude/skills/test-first/REQUIREMENT.md +14 -20
- package/claude/skills/ui-checklist/REQUIREMENT.md +14 -29
- package/claude/skills/ux-audit/REQUIREMENT.md +3 -7
- package/claude/skills/ux-measure/REQUIREMENT.md +14 -28
- package/claude/skills/video-craft/REQUIREMENT.md +14 -27
- package/claude/skills/write-doc/REQUIREMENT.md +14 -24
- package/claude/skills/write-human/REQUIREMENT.md +15 -27
- package/claude/skills/youtube-transcripts/REQUIREMENT.md +9 -15
- package/docs/agents/context-audit.md +19 -12
- package/docs/agents/install-and-sync.md +2 -2
- package/docs/agents/markdown-audit.md +15 -10
- package/docs/agents/output-shape.md +1 -2
- package/docs/target/migrations.md +18 -0
- package/docs/target/projects.md +3 -2
- package/docs/target/scenarios.md +4 -1
- package/docs/workflow/skill-map-on-request.md +1 -1
- package/docs/workflow/skill-map.md +6 -5
- package/governance/detect.toml +4 -0
- package/governance/ledger/lang/go.md +61 -0
- package/governance/ledger/lang/php.md +50 -0
- package/governance/ledger/lang/python.md +68 -0
- package/governance/ledger/lang/typescript.md +64 -0
- package/governance/ledger/lib/database.md +65 -0
- package/governance/ledger/lib/e2e-reliability.md +57 -0
- package/governance/ledger/lib/pydantic.md +61 -0
- package/governance/ledger/lib/security-server.md +62 -0
- package/governance/ledger/lib/security-web.md +51 -0
- package/governance/ledger/lib/tanstack-query.md +57 -0
- package/governance/ledger/lib/test-scope.md +43 -0
- package/governance/ledger/lib/testing-go.md +57 -0
- package/governance/ledger/lib/testing-php.md +51 -0
- package/governance/ledger/lib/testing-py.md +67 -0
- package/governance/ledger/lib/testing-ts.md +63 -0
- package/governance/ledger/lib/zod.md +47 -0
- package/governance/ledger/tooling/ci-workflow.md +33 -0
- package/governance/ledger/tooling/code-comments.md +48 -0
- package/governance/ledger/tooling/config-comments.md +27 -0
- package/governance/ledger/tooling/dependencies.md +38 -0
- package/governance/ledger/ui/a11y.md +55 -0
- package/governance/ledger/ui/copy.md +49 -0
- package/governance/ledger/ui/design-reference.md +42 -0
- package/governance/ledger/ui/design-taste.md +19 -0
- package/governance/ledger/ui/forms.md +71 -0
- package/governance/ledger/ui/interface-casing.md +47 -0
- package/governance/ledger/ui/keyboard.md +68 -0
- package/governance/ledger/ui/link-behavior.md +29 -0
- package/governance/ledger/ui/motion.md +33 -0
- package/governance/ledger/ui/surface-capture.md +69 -0
- package/governance/ledger/ui/ux-completeness.md +79 -0
- package/governance/renames.toml +0 -2
- package/governance/rules/claude/output.md +5 -1
- package/governance/rules/code/routing.md +5 -1
- package/governance/rules/lang/go.md +7 -16
- package/governance/rules/lang/php.md +3 -3
- package/governance/rules/lang/python.md +9 -18
- package/governance/rules/lang/typescript.md +9 -19
- package/governance/rules/lib/database.md +5 -5
- package/governance/rules/lib/e2e-reliability.md +4 -6
- package/governance/rules/lib/pydantic.md +14 -16
- package/governance/rules/lib/security-server.md +4 -4
- package/governance/rules/lib/security-web.md +6 -10
- package/governance/rules/lib/tanstack-query.md +10 -12
- package/governance/rules/lib/test-scope.md +4 -4
- package/governance/rules/lib/testing-go.md +1 -2
- package/governance/rules/lib/testing-php.md +4 -5
- package/governance/rules/lib/testing-py.md +11 -19
- package/governance/rules/lib/testing-ts.md +7 -16
- package/governance/rules/lib/zod.md +6 -8
- package/governance/rules/tooling/code-comments.md +2 -4
- package/governance/rules/tooling/config-comments.md +1 -4
- package/governance/rules/tooling/dependencies.md +1 -1
- package/governance/rules/ui/a11y.md +16 -45
- package/governance/rules/ui/copy.md +6 -9
- package/governance/rules/ui/forms.md +13 -19
- package/governance/rules/ui/interface-casing.md +5 -7
- package/governance/rules/ui/keyboard.md +38 -0
- package/governance/rules/ui/link-behavior.md +3 -3
- package/governance/rules/ui/motion.md +3 -3
- package/governance/rules/ui/surface-capture.md +15 -27
- package/governance/rules/ui/ux-completeness.md +16 -39
- package/governance/stacks/base.toml +0 -1
- package/package.json +1 -1
- package/scripts/core/install-check.sh +1 -1
- package/src/claude/cases/workflow.ts +12 -0
- package/src/cli/help.ts +0 -1
- package/src/cli.ts +0 -2
- package/src/commands/context.ts +57 -3
- package/src/commands/gov.ts +4 -0
- package/src/commands/init.ts +2 -2
- package/src/commands/labels.ts +83 -3
- package/src/commands/markdown.ts +188 -21
- package/src/commands/sessions.ts +36 -3
- package/src/commands/tasks.ts +180 -0
- package/src/commands/tooling.ts +18 -5
- package/src/commands/worktrees.ts +2 -0
- package/src/context/coverage.ts +210 -0
- package/src/context/gate.ts +12 -3
- package/src/design/components.ts +1 -1
- package/src/gate/stages.ts +1 -1
- package/src/gov/audit.ts +22 -2
- package/src/init/plan.ts +1 -8
- package/src/init/steps.ts +44 -7
- package/src/intake/items.ts +14 -0
- package/src/inventory/subjects.ts +1 -1
- package/src/labels/closing.ts +46 -0
- package/src/markdown/gated.ts +250 -0
- package/src/markdown/scope.ts +119 -2
- package/src/migrate/rename.ts +6 -0
- package/src/migrate/scratch-evidence.ts +12 -4
- package/src/records/backup.ts +3 -3
- package/src/records/validate.ts +3 -3
- package/src/roots/record.ts +17 -8
- package/src/sessions/claim.ts +7 -0
- package/src/sessions/live.ts +53 -6
- package/src/sessions/registry.ts +11 -0
- package/src/sessions/resolve.ts +32 -5
- package/src/tasks/closes.ts +136 -0
- package/src/tasks/record.ts +1 -1
- package/src/tooling/inject.ts +26 -7
- package/src/tooling/package.ts +32 -0
- package/src/tooling/read.ts +46 -3
- package/src/tooling/scan.ts +8 -2
- package/src/worktrees/reclaim.ts +16 -1
- package/tooling/astro/reference.md +64 -93
- package/tooling/base/configs/.github/workflows/phase-label-gate.yml +1 -1
- package/tooling/base/configs/scripts/verify.ts +2 -2
- package/tooling/base/reference.md +1 -9
- package/tooling/base/seeds/canon/context/{ci.md → development/ci.md} +1 -1
- package/tooling/base/seeds/canon/context/development/index.md +11 -0
- package/tooling/base/seeds/canon/context/{development.md → development/setup.md} +8 -12
- package/tooling/base/seeds/canon/context/index.md +1 -2
- package/tooling/claude/manifest.toml +1 -5
- package/tooling/claude/reference.md +36 -59
- package/tooling/claude/seeds/.claude/hooks/board-validate.sh +1 -1
- package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +2 -7
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +2 -7
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +3 -10
- package/tooling/claude/seeds/.claude/hooks/search-reminder.sh +2 -7
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +2 -4
- package/tooling/claude/seeds/CLAUDE.md +2 -2
- package/tooling/nextjs/reference.md +0 -6
- package/tooling/php/reference.md +0 -4
- package/tooling/web/configs/.github/workflows/verify.yml +28 -0
- package/tooling/web/configs/.oxlintrc.json +7 -0
- package/tooling/web/configs/e2e/capture-types.ts +35 -0
- package/tooling/web/configs/e2e/screenshot.ts +23 -72
- package/tooling/web/manifest.toml +1 -1
- package/tooling/web/reference.md +77 -124
- package/tooling/web/seeds/e2e/capture/cases.ts +47 -0
- package/governance/rules/canon/task-scope.md +0 -12
- package/src/commands/wiki.ts +0 -100
- package/src/wiki/init.ts +0 -85
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TypeScript testing rule ledger
|
|
3
|
+
description: Sources for governance/rules/lib/testing-ts.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TypeScript testing rule ledger
|
|
7
|
+
|
|
8
|
+
The field is JavaScript and TypeScript testing. The authorities are the Vitest documentation at vitest.dev, the Testing Library documentation at testing-library.com, and the Playwright documentation at playwright.dev. None of the pages read names a major, so the rows record the read date alone.
|
|
9
|
+
|
|
10
|
+
## Unit and integration
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Vitest as the runner | House choice: the toolkit's web stacks install and configure Vitest, so a test written for a second runner never runs in the gate | 2026-10-18 |
|
|
15
|
+
| `userEvent` over `fireEvent` | [user-event](https://testing-library.com/docs/user-event/intro): it "factors in that the browser e.g. wouldn't let a user click a hidden element or type in a disabled text box" | 2026-10-18 |
|
|
16
|
+
| MSW, no hand mocks or real calls | [Vitest, mocking requests](https://vitest.dev/guide/mocking/requests): "We recommend Mock Service Worker to accomplish this", since it mocks "http, WebSocket and GraphQL network requests" | 2026-10-18 |
|
|
17
|
+
| Role or label first | [Testing Library queries](https://testing-library.com/docs/queries/about): `getByRole` "should be your top preference for just about everything", and a test ID "is only recommended for cases where you can't match by role or text" | 2026-10-18 |
|
|
18
|
+
|
|
19
|
+
## End-to-end
|
|
20
|
+
|
|
21
|
+
| Bullet | Source | Read |
|
|
22
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
23
|
+
| Playwright for end-to-end | House choice: the toolkit's web stack configures Playwright, so a second browser runner's tests never run in the gate | 2026-10-18 |
|
|
24
|
+
| Playwright tests under `e2e/` | [Vitest include](https://vitest.dev/config/include) defaults to `**/*.{test,spec}.?(c\|m)[jt]s?(x)`, so a Playwright spec under `src/` is collected by Vitest too, where it fails | 2026-10-18 |
|
|
25
|
+
|
|
26
|
+
## Timers and async
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
30
|
+
| `advanceTimers` with fake timers | [user-event options](https://testing-library.com/docs/user-event/options): "When using fake timers it is necessary to set this option to your test runner's time advancement function" | 2026-10-18 |
|
|
31
|
+
| Restore after pending timers | [Using fake timers](https://testing-library.com/docs/using-fake-timers): "you usually call `useRealTimers` in `afterEach`", and "It's important to also call `runOnlyPendingTimers` before switching to real timers" | 2026-10-18 |
|
|
32
|
+
|
|
33
|
+
## Conventions
|
|
34
|
+
|
|
35
|
+
| Bullet | Source | Read |
|
|
36
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
37
|
+
| `.test` for unit, `.spec` otherwise | House choice: [Playwright](https://playwright.dev/docs/test-configuration) runs "`**/*.@(spec\|test).?(c\|m)[jt]s?(x)` files" and Vitest matches the same pair, so the suffix is what a config separates the two runs on | 2026-10-18 |
|
|
38
|
+
|
|
39
|
+
## Declined
|
|
40
|
+
|
|
41
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
42
|
+
|
|
43
|
+
### Contradicted by the docs
|
|
44
|
+
|
|
45
|
+
- Cut "never use `vi.useFakeTimers()` in `beforeEach` when tests use `waitFor`, `act`, or `userEvent`". [Using fake timers](https://testing-library.com/docs/using-fake-timers) shows `beforeEach` as the usual setup, and names `advanceTimers` as the fix for the `userEvent` timeout, which the kept bullet carries.
|
|
46
|
+
- Cut "scope fake timers to the individual test that needs them" with it, since no page read scopes them below the file.
|
|
47
|
+
|
|
48
|
+
### Cut without a source or a bug class
|
|
49
|
+
|
|
50
|
+
- Cut "`it()` descriptions use "should" + sentence case". The rule-standard audit flagged it as contested style naming no bug class.
|
|
51
|
+
- Cut "`describe()` labels use the exact identifier of the subject" as naming style naming no failure.
|
|
52
|
+
|
|
53
|
+
### Owned elsewhere
|
|
54
|
+
|
|
55
|
+
- Cut "co-locate unit tests with their respective components". The `codebase-layout` skill's test reference places a unit test beside its module.
|
|
56
|
+
- Cut "keep specs apart from their fixtures, page objects, and helpers inside `e2e/`", which the same reference owns.
|
|
57
|
+
|
|
58
|
+
### Merged or reworded
|
|
59
|
+
|
|
60
|
+
- Folded "place all Playwright tests within `e2e/`", "never place Playwright tests inside `src/`", and the scope bullet for a Vitest test driving a browser into one placement bullet.
|
|
61
|
+
- Merged "do not make real network calls in unit tests" into the MSW bullet.
|
|
62
|
+
- Merged the two suffix bullets into one.
|
|
63
|
+
- Reworded "use `userEvent` over synthetic events" and the accessible-query bullet to name what each source says the choice prevents.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Zod rule ledger
|
|
3
|
+
description: Sources for governance/rules/lib/zod.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Zod rule ledger
|
|
7
|
+
|
|
8
|
+
The field is TypeScript runtime validation, and the authority is the Zod documentation at zod.dev with its changelog in the colinhacks/zod repository. The rule assumes Zod 4, since the methods it replaces stay available as legacy and a Zod 3 target keeps `z.strictObject()`.
|
|
9
|
+
|
|
10
|
+
## Type inference
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- |
|
|
14
|
+
| `z.infer`, no twin interface | [Basic usage](https://zod.dev/basics): "Zod infers a static type from your schema definitions. You can extract this type with the `z.infer<>` utility" | 2026-10-18, Zod 4 |
|
|
15
|
+
|
|
16
|
+
## Boundary validation
|
|
17
|
+
|
|
18
|
+
| Bullet | Source | Read |
|
|
19
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
|
|
20
|
+
| `z.strictObject()` on untrusted input | [Zod 4 changelog](https://raw.githubusercontent.com/colinhacks/zod/main/packages/docs/content/v4/changelog.mdx): "Instead use the top-level `z.strictObject()` and `z.looseObject()` functions", and the old methods "are considered legacy" | 2026-10-18, Zod 4 |
|
|
21
|
+
| `.pick()` or `.omit()`, not loose | [Defining schemas](https://zod.dev/api): "Zod provides dedicated APIs for picking and omitting certain keys from an object schema", and a loose schema "allows unknown keys to pass through" | 2026-10-18, Zod 4 |
|
|
22
|
+
| `.parse()` or `.safeParse()` | [Basic usage](https://zod.dev/basics): `.parse()` "will throw a `ZodError`", and `.safeParse()` returns "a plain result object containing either the successfully parsed data or a `ZodError`" | 2026-10-18, Zod 4 |
|
|
23
|
+
| `z.coerce` at string boundaries | [Defining schemas](https://zod.dev/api): "The coerced variant of these schemas attempts to convert the input value to the appropriate type", applying `String(input)` for `z.coerce.string()` | 2026-10-18, Zod 4 |
|
|
24
|
+
|
|
25
|
+
## Schema safety
|
|
26
|
+
|
|
27
|
+
| Bullet | Source | Read |
|
|
28
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------- | ----------------- |
|
|
29
|
+
| `z.unknown()`, not `z.any()` | [Defining schemas](https://zod.dev/api): `z.any()` infers `any`, and `z.unknown()` infers `unknown` | 2026-10-18, Zod 4 |
|
|
30
|
+
|
|
31
|
+
## Declined
|
|
32
|
+
|
|
33
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
34
|
+
|
|
35
|
+
### Contradicted by the docs
|
|
36
|
+
|
|
37
|
+
- Replaced "use `.strict()` for untrusted external API boundaries". The [Zod 4 changelog](https://raw.githubusercontent.com/colinhacks/zod/main/packages/docs/content/v4/changelog.mdx) marks `.strict()` legacy and names `z.strictObject()`.
|
|
38
|
+
- Replaced "prefer `.strict()` at boundaries or explicit `.pick()`/`.omit()` over `.passthrough()`", which recommended the legacy method and read as a preference. The kept bullet names `z.looseObject()` beside it.
|
|
39
|
+
|
|
40
|
+
### Cut without a source or a bug class
|
|
41
|
+
|
|
42
|
+
- Cut "do not export the runtime Schema if only the inferred Type is required by consumers" as an export taste naming no failure.
|
|
43
|
+
|
|
44
|
+
### Merged or reworded
|
|
45
|
+
|
|
46
|
+
- Merged "do not manually declare interfaces that duplicate Zod schemas" into the `z.infer` bullet.
|
|
47
|
+
- Narrowed "restrict `z.coerce` to I/O boundaries" to string input and named the conversion, which is why `z.coerce.boolean()` reads `"false"` as `true`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CI workflow rule ledger
|
|
3
|
+
description: Sources for governance/rules/tooling/ci-workflow.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CI workflow rule ledger
|
|
7
|
+
|
|
8
|
+
The field is continuous integration on GitHub Actions, and the authority is GitHub's own Actions documentation at docs.github.com. The rule is the second half of a pair with the `ci-workflow` skill, which owns triggers, pinning, job shape, and the top-level read-only default, so this ledger covers only what the rule itself states.
|
|
9
|
+
|
|
10
|
+
## Authority
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Load the skill, routing | Routing only: it sends workflow authoring to the `canon:ci-workflow` skill, which carries the sourced directives, and claims no outside source | 2026-10-18 |
|
|
15
|
+
|
|
16
|
+
## Commit-back
|
|
17
|
+
|
|
18
|
+
| Bullet | Source | Read |
|
|
19
|
+
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
20
|
+
| Commit back only what the branch moved | House choice: a refresh an outside input moved, such as a font or a build-time count, lands a diff on a pull request whose change did not cause it, so the reviewer reads churn the author cannot explain | 2026-10-18 |
|
|
21
|
+
| Deterministic output, diff check first | House choice: a step that regenerates differently on each run commits noise on every push, and a commit step with no diff check ahead of it pushes a capture that did not change | 2026-10-18 |
|
|
22
|
+
| Skip a fork's pull request | [Workflow syntax, permissions](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax): "if the workflow was triggered by a pull request event other than `pull_request_target` from a forked repository, and the Send write tokens to workflows from pull requests setting is not selected, the permissions are adjusted to change any write permissions to read only" | 2026-10-18 |
|
|
23
|
+
| Never commit back to the trunk | House choice: a workflow pushing onto the trunk lands a change no pull request carried and no reviewer read | 2026-10-18 |
|
|
24
|
+
|
|
25
|
+
## Token scopes
|
|
26
|
+
|
|
27
|
+
| Bullet | Source | Read |
|
|
28
|
+
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
29
|
+
| Write scope on the job only | [Workflow syntax, permissions](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax): "For a specific job, you can use `jobs.<job_id>.permissions` to modify the default permissions granted to the `GITHUB_TOKEN`, adding or removing access as required, so that you only allow the minimum required access" | 2026-10-18 |
|
|
30
|
+
|
|
31
|
+
## Declined
|
|
32
|
+
|
|
33
|
+
Nothing was cut. Every bullet already sat inside the shape limits, and the rule keeps its split with the skill, a pointer plus at most five directives.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Code comments rule ledger
|
|
3
|
+
description: Sources for governance/rules/tooling/code-comments.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code comments rule ledger
|
|
7
|
+
|
|
8
|
+
The field is software engineering practice for source comments, which has no spec. The authorities are the published style guides of large codebases, here Google's guides for Python, C++, TypeScript, JavaScript, and shell, read as practice from one large codebase rather than as a settlement of the field.
|
|
9
|
+
|
|
10
|
+
## When a comment should exist
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Only a fact the code cannot carry | [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html): "The final place to have comments is in tricky parts of the code. If you're going to have to explain it at the next code review, you should comment it now." | 2026-10-18 |
|
|
15
|
+
| Do not restate the line | [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html): "never describe the code. Assume the person reading the code knows Python (though not what you're trying to do) better than you do." | 2026-10-18 |
|
|
16
|
+
| No comment on a self-describing function | [Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html): "Method, parameter, and return descriptions may be omitted if they are obvious from the rest of the method's JSDoc or from the method name and type signature." | 2026-10-18 |
|
|
17
|
+
| No comment moved to hit a density figure | House choice: a comment added to reach a figure restates the line beside it, and one deleted to reach it drops a contract the code cannot carry. No style guide states a density target to depart from. | 2026-10-18 |
|
|
18
|
+
|
|
19
|
+
## What a comment may claim
|
|
20
|
+
|
|
21
|
+
| Bullet | Source | Read |
|
|
22
|
+
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
23
|
+
| True as written, updated in the change | House choice: a comment describing behavior the code does not have, whether planned or since changed, reads as authoritative and misleads the next reader. Updating it in the same change puts both sides in front of one reviewer. | 2026-10-18 |
|
|
24
|
+
| Contract, not steps | [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html): "The docstring should describe the function's calling syntax and its semantics, but generally not its implementation details, unless those details are relevant to how the function is to be used." | 2026-10-18 |
|
|
25
|
+
| No person, ticket, or date in its place | House choice: a comment that only points at a person, a ticket, or a date tells the reader nothing once the person leaves or the ticket closes. Google's guides attach a bug or a name to a `TODO` beside its description, and the Python guide adds "Avoid adding TODOs that refer to an individual or team as the context". | 2026-10-18 |
|
|
26
|
+
|
|
27
|
+
## What never goes in a comment
|
|
28
|
+
|
|
29
|
+
| Bullet | Source | Read |
|
|
30
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
31
|
+
| Delete commented-out code | House choice: commented-out code escapes the type checker and the tests, so it rots while reading as an option still open, and version control already keeps it | 2026-10-18 |
|
|
32
|
+
| No edit history | House choice: a comment recording the edit that made the code goes stale at the next edit and duplicates what `git log` and `git blame` hold | 2026-10-18 |
|
|
33
|
+
| No deferred work | House choice: deferred work in a comment is work no tracker query finds, so nobody schedules it. [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) asks for `TODO` comments carrying "the bug ID, name, e-mail address, or other identifier", which is Google's convention for its own code. | 2026-10-18 |
|
|
34
|
+
|
|
35
|
+
## Degradation vocabulary
|
|
36
|
+
|
|
37
|
+
| Bullet | Source | Read |
|
|
38
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
39
|
+
| `TODO`, `FIXME`, `HACK`, `XXX` | House choice: each term marks deferred work or a known defect in a place no tracker query reaches. Google's guides depart, asking for a `TODO` with an owner or a bug link so it "can be searched to find out how to get more details" (Python guide). Google's guide governs Google's code rather than settling the field, so this rule keeps the ban and sends the work to the tracker. | 2026-10-18 |
|
|
40
|
+
|
|
41
|
+
## Declined
|
|
42
|
+
|
|
43
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
44
|
+
|
|
45
|
+
### Merged or reworded
|
|
46
|
+
|
|
47
|
+
- Merged "Let comment density follow how much of a file's behavior is decided outside that file" into the density bullet as its reason. On its own it named no line a reviewer could check.
|
|
48
|
+
- Merged "State only what is true of the code as written" into the update bullet, which states the same requirement and adds when to meet it
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Config comments rule ledger
|
|
3
|
+
description: Sources for governance/rules/tooling/config-comments.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Config comments rule ledger
|
|
7
|
+
|
|
8
|
+
The field is comment style in configuration files. Neither the YAML spec nor the JSON-with-comments convention takes a side on what a comment says, and no published style guide covers config files the way Google's guides cover source. So every kept bullet stands on a house-choice row naming its bug class.
|
|
9
|
+
|
|
10
|
+
## Comments
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
14
|
+
| What a key does or accepts, not its name | House choice: the allowed values are set by the tool reading the file, a fact the key name does not carry, while a comment restating the name adds a line that tells the reader nothing and can drift from the key | 2026-10-18 |
|
|
15
|
+
|
|
16
|
+
## Declined
|
|
17
|
+
|
|
18
|
+
Every bullet the rewrite removed, grouped by why.
|
|
19
|
+
|
|
20
|
+
### A convention Claude follows unprompted
|
|
21
|
+
|
|
22
|
+
- Cut "Match the comment density of the surrounding file", since the Claude Code system prompt already tells the model to match the surrounding code's comment density
|
|
23
|
+
|
|
24
|
+
### Cut without a source or a bug class
|
|
25
|
+
|
|
26
|
+
- Cut "Keep each comment to one short line", since comment length is taste and no reviewer could point at a defect a two-line comment causes
|
|
27
|
+
- Cut "Prefer a one-word category label over a sentence for a group header", as taste with no bug class
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dependencies rule ledger
|
|
3
|
+
description: Sources for governance/rules/tooling/dependencies.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dependencies rule ledger
|
|
7
|
+
|
|
8
|
+
The field is package management for JavaScript and Python projects. The authorities are each package manager's own documentation, being Bun at bun.com, npm at docs.npmjs.com, uv at docs.astral.sh, and pnpm at pnpm.io for the hoisting behavior it was built to remove.
|
|
9
|
+
|
|
10
|
+
Bun's docs moved from bun.sh to bun.com, where the old paths now return a not-found page.
|
|
11
|
+
|
|
12
|
+
## Declaration
|
|
13
|
+
|
|
14
|
+
| Bullet | Source | Read |
|
|
15
|
+
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
|
16
|
+
| Declare before importing | [Isolated installs](https://bun.com/docs/pm/isolated-installs): under isolated installs "packages can only access their explicitly declared dependencies", the default for new workspaces, so an undeclared import fails to resolve there | 2026-10-18, Bun 1.3 |
|
|
17
|
+
| Add through the package manager | [uv, managing dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/): "uv supports modifying the project's dependencies with `uv add` and `uv remove`, but dependency metadata can also be updated by editing the `pyproject.toml` directly", and [uv, locking](https://docs.astral.sh/uv/concepts/projects/sync/): "if you add a dependency to your `pyproject.toml`, the lockfile will be considered outdated" | 2026-10-18 |
|
|
18
|
+
| Commit the lockfile with the change | [Bun lockfile](https://bun.com/docs/pm/lockfile): "Should it be committed to git? Yes". [package-lock.json](https://docs.npmjs.com/cli/v11/configuring-npm/package-lock-json): "This file is intended to be committed into source repositories". [bun install](https://bun.com/docs/pm/cli/install): a frozen install fails when the manifest and lockfile disagree, so "Run `bun install` and commit the updated `bun.lock`" | 2026-10-18, Bun 1.3, npm 11 |
|
|
19
|
+
| Development-only as a dev dependency | [package.json](https://docs.npmjs.com/cli/v11/configuring-npm/package-json): a module's users "probably don't want or need to download and build the external test or documentation framework that you use. In this case, it's best to map these additional items in a `devDependencies` object". [bun add](https://bun.com/docs/pm/cli/add): "Bun writes the package to `dependencies` unless you pass `--dev`, `--optional`, or `--peer`" | 2026-10-18, Bun 1.3, npm 11 |
|
|
20
|
+
| No transitive-only imports | [pnpm motivation](https://pnpm.io/motivation): under npm or Yarn Classic hoisting, "source code has access to dependencies that are not added as dependencies to the project". The import works until the parent package drops or bumps the dependency, then breaks with no change to this project's manifest | 2026-10-18 |
|
|
21
|
+
|
|
22
|
+
## Removal
|
|
23
|
+
|
|
24
|
+
| Bullet | Source | Read |
|
|
25
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
26
|
+
| Remove with the last import | House choice: an entry nothing imports keeps installing on every machine and in every build, and nothing fails to point at it, so it stays until someone audits the manifest by hand | 2026-10-18 |
|
|
27
|
+
|
|
28
|
+
## Declined
|
|
29
|
+
|
|
30
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
31
|
+
|
|
32
|
+
### Contradicted by the docs
|
|
33
|
+
|
|
34
|
+
- Rewrote "Never hand-edit the manifest" to re-locking after a hand edit, since uv documents editing `pyproject.toml` directly. The bug the ban guarded against is a stale lockfile.
|
|
35
|
+
|
|
36
|
+
### Merged or reworded
|
|
37
|
+
|
|
38
|
+
- Cut "never install without recording the result", which the declare bullet already covers, and which brought the line to 206 characters against the 200 limit
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Accessibility rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/a11y.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Accessibility rule ledger
|
|
7
|
+
|
|
8
|
+
The field is web accessibility, and the authority is the W3C, through WCAG 2.2 and its Understanding documents, the WAI tutorials, and the ARIA notes. The keyboard and focus half of the old rule moved to `keyboard.md`, whose ledger records those bullets.
|
|
9
|
+
|
|
10
|
+
## Semantics
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
14
|
+
| Native `<button>` or `<a>` over a `<div>` | [Using ARIA, first rule](https://www.w3.org/TR/using-aria/): "If you can use a native HTML element or attribute with the semantics and behavior you require already built in", use it "instead of re-purposing an element and adding an ARIA role" | 2026-10-18 |
|
|
15
|
+
| Attribute spelling per syntax | [React common components](https://react.dev/reference/react-dom/components/common): the DOM prop is `tabIndex`, "A number. Overrides the default Tab button behavior", where HTML spells it `tabindex` | 2026-10-18, React 19 |
|
|
16
|
+
| Role and synchronized state | [Understanding Name, Role, Value](https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html): "the name and role can be programmatically determined" and "notification of changes to these items is available to user agents" | 2026-10-18, WCAG 2.2 |
|
|
17
|
+
| Name for a control with no visible text | [Understanding Name, Role, Value](https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html): every user interface component's "name and role can be programmatically determined" | 2026-10-18, WCAG 2.2 |
|
|
18
|
+
|
|
19
|
+
## Text alternatives
|
|
20
|
+
|
|
21
|
+
| Bullet | Source | Read |
|
|
22
|
+
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
23
|
+
| `alt` on every image, empty for decoration | [Decorative images](https://www.w3.org/WAI/tutorials/images/decorative/): "a null (empty) alt text should be provided ( alt="" ) so that they can be ignored by assistive technologies" | 2026-10-18 |
|
|
24
|
+
| Meaning or action, not appearance | [Functional images](https://www.w3.org/WAI/tutorials/images/functional/): the text "should convey the action that will be initiated (the purpose of the image), rather than a description of the image", so "print this page" rather than "(image of a) printer" | 2026-10-18 |
|
|
25
|
+
|
|
26
|
+
## Contrast and color
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
30
|
+
| 3:1 for boundaries and graphics | [Understanding Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html): "Ensure meaningful visual cues achieve 3:1 against the background" | 2026-10-18, WCAG 2.2 |
|
|
31
|
+
| Color never the only carrier | [Understanding Use of Color](https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html): "Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element" | 2026-10-18, WCAG 2.2 |
|
|
32
|
+
|
|
33
|
+
## Reflow
|
|
34
|
+
|
|
35
|
+
| Bullet | Source | Read |
|
|
36
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
37
|
+
| Reflow at 320 | [Understanding Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html): "without requiring scrolling in two dimensions" at "a width equivalent to 320 CSS pixels", "Except for parts of the content which require two-dimensional layout", such as "maps and diagrams" and "data tables" | 2026-10-18, WCAG 2.2 |
|
|
38
|
+
| 320 is 1280 at 400 percent | [Understanding Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html): "320 CSS pixels is equivalent to a starting viewport width of 1280 CSS pixels wide at 400% zoom" | 2026-10-18, WCAG 2.2 |
|
|
39
|
+
| The same floor beside resizable chrome | House choice: a panel widened to 480 in a 768 window leaves 288 for the content, under the floor at a window width the criterion passes | 2026-10-18 |
|
|
40
|
+
|
|
41
|
+
## Declined
|
|
42
|
+
|
|
43
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
44
|
+
|
|
45
|
+
### Moved to `keyboard.md`
|
|
46
|
+
|
|
47
|
+
- Moved the focus styles, keyboard model, pointer targets, composite widgets, and focus management H2s to `keyboard.md`, whose ledger records each of those bullets.
|
|
48
|
+
|
|
49
|
+
### Merged or reworded
|
|
50
|
+
|
|
51
|
+
- Merged "a `<div>` with a click handler requires a role, a tab index, and keyboard handlers" into the native element bullet, which states the same choice from the other side.
|
|
52
|
+
- Merged "set role on custom controls" and "synchronize state attributes with visual state" into one bullet, since both rest on the same success criterion.
|
|
53
|
+
- Merged "describe the content or function, not its appearance" and "alt text for functional images should describe the action" into one bullet.
|
|
54
|
+
- Shortened the reflow criterion bullet and its 1280 equivalence to fit the 200 character limit, keeping the criterion's exceptions.
|
|
55
|
+
- Shortened the resizable chrome bullet and moved its worked example into this ledger's row, since it explained rather than directed.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: UI copy rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/copy.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# UI copy rule ledger
|
|
7
|
+
|
|
8
|
+
The field is content design, and the authority for researched interface copy is the GOV.UK Design System and its style guide.
|
|
9
|
+
|
|
10
|
+
## Punctuation
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| No em dash or semicolon | House choice: both read as generated copy in an interface, and a comma, a period, or a split sentence carries the same meaning in a shorter line | 2026-10-18 |
|
|
15
|
+
| No trailing label punctuation | [Button](https://design-system.service.gov.uk/components/button/): every example label, such as "Start now", "Sign in", and "Continue", carries no trailing punctuation | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## Button copy
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
21
|
+
| The action's verb | [Button](https://design-system.service.gov.uk/components/button/): "Write button text in sentence case, describing the action it performs" | 2026-10-18 |
|
|
22
|
+
|
|
23
|
+
## Error messages
|
|
24
|
+
|
|
25
|
+
| Bullet | Source | Read |
|
|
26
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
27
|
+
| Say how to fix it | [Error message](https://design-system.service.gov.uk/components/error-message/): "Describe what has happened and tell them how to fix it", and "'Enter your first name' is clearer, more direct and natural than 'First name must have an entry'" | 2026-10-18 |
|
|
28
|
+
| Short and plain | [Error message](https://design-system.service.gov.uk/components/error-message/): "The message must be in plain English, use positive language and get to the point", with no "technical jargon like 'form post error'" | 2026-10-18 |
|
|
29
|
+
|
|
30
|
+
## Placeholder text
|
|
31
|
+
|
|
32
|
+
| Bullet | Source | Read |
|
|
33
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
34
|
+
| No placeholder, a hint instead | [Text input](https://design-system.service.gov.uk/components/text-input/): "Do not use placeholder text in place of a label, or for hints or examples", since "it vanishes when the user starts typing" and "not all screen readers read it out" | 2026-10-18 |
|
|
35
|
+
|
|
36
|
+
## Declined
|
|
37
|
+
|
|
38
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
39
|
+
|
|
40
|
+
### Contradicted by the source
|
|
41
|
+
|
|
42
|
+
- Replaced "show format examples over instructions in placeholder text" with the hint text bullet, since GOV.UK says not to use a placeholder "for hints or examples".
|
|
43
|
+
- Cut "reserve instructions for labels or helper text", which the new placeholder bullet now carries.
|
|
44
|
+
|
|
45
|
+
### Merged or reworded
|
|
46
|
+
|
|
47
|
+
- Merged the imperative verb and padded phrasing bullets. The `Save` over `Save changes` example went, since GOV.UK adds words "to better describe the action".
|
|
48
|
+
- Merged "keep messages short and actionable" and "one sentence maximum" into the plain language bullet.
|
|
49
|
+
- Reworded the error example to `Enter an email address`, the instruction form GOV.UK prefers over a description.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Design reference rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/design-reference.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design reference rule ledger
|
|
7
|
+
|
|
8
|
+
The rule states canon's own design handoff, generalized from Frameboard's project rule, so every row is a house choice naming the bug the bullet prevents.
|
|
9
|
+
|
|
10
|
+
## Where the design lives
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Build against the tracked copy | House choice: a canvas changes under the build with no history, so a reviewer cannot tell which version a surface was built against | 2026-10-18 |
|
|
15
|
+
| Land a design first | House choice: a design landing inside a feature pull request is reviewed as code, and a second feature building against it meanwhile reads a design nobody accepted | 2026-10-18 |
|
|
16
|
+
| No hand edits | House choice: a reference edited by hand drifts from its canvas source, and the next sync overwrites the edit or reports it as a change nobody made | 2026-10-18 |
|
|
17
|
+
| Index row before the sync | House choice: the sync writes only the surfaces the index names, so a missing row drops the new surface's reference, and a stale row keeps a removed surface's | 2026-10-18 |
|
|
18
|
+
|
|
19
|
+
## Building against a reference
|
|
20
|
+
|
|
21
|
+
| Bullet | Source | Read |
|
|
22
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
23
|
+
| Open both themes first | House choice: a build read from the dark image alone ships a light theme nobody saw | 2026-10-18 |
|
|
24
|
+
| Values from the frame HTML | House choice: sizes and colors read off an image are estimates, and the frame HTML carries the exact values the design set | 2026-10-18 |
|
|
25
|
+
|
|
26
|
+
## Showing the comparison
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
30
|
+
| Reference beside capture | House choice: a reviewer shown the build alone has nothing to compare it to, and approves a departure without seeing it | 2026-10-18 |
|
|
31
|
+
| Name each departure | House choice: an unnamed departure reads as an accident, and the next build against the same reference repeats or reverts it | 2026-10-18 |
|
|
32
|
+
| Unexplained departure is a finding | House choice: without the finding, an unexplained departure merges as the new design with no one having chosen it | 2026-10-18 |
|
|
33
|
+
|
|
34
|
+
## Naming
|
|
35
|
+
|
|
36
|
+
| Bullet | Source | Read |
|
|
37
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
38
|
+
| One folder per app part | House choice: a fixed folder and theme suffix let the sync and a reviewer find a surface's pair of references without reading an index | 2026-10-18 |
|
|
39
|
+
|
|
40
|
+
## Declined
|
|
41
|
+
|
|
42
|
+
The rewrite kept every bullet. Each was already under 200 characters and states a step a reviewer can check against the pull request.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Design taste rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/design-taste.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design taste rule ledger
|
|
7
|
+
|
|
8
|
+
The rule is a pointer to the `design-taste` skill, which carries its own sources, so both rows are house choices naming the bug the pointer prevents.
|
|
9
|
+
|
|
10
|
+
## Authority
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Load the skill | House choice: a style edit made without the layer order or the coherence locks reaches for a model's defaults, and a second copy of them in the rule drifts from the skill | 2026-10-18 |
|
|
15
|
+
| Report an unresolved skill | House choice: the rule ships with the CLI and the skill with the plugin, so a project holding governance alone would otherwise proceed silently without it | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## Declined
|
|
18
|
+
|
|
19
|
+
The rewrite kept both bullets unchanged.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Forms rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/forms.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Forms rule ledger
|
|
7
|
+
|
|
8
|
+
The field is form design inside interaction design, and the authority for researched form patterns is the GOV.UK Design System, with WCAG 2.2 for the two authentication criteria. NN/g was read beside it and disagrees on validation timing, recorded under `## Declined`.
|
|
9
|
+
|
|
10
|
+
## Validation timing
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Validate on submit | [Recover from validation errors](https://design-system.service.gov.uk/patterns/validation/): "Do not validate when the user moves away from a field. Wait until they try to move to the next part of the service" | 2026-10-18 |
|
|
15
|
+
| Re-validate after an error | House choice: an error left in place after the input turns valid tells the person their correct answer is still wrong, and they edit a field that needed nothing | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## Submission
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
21
|
+
| Refuse with errors, never disable | [Button](https://design-system.service.gov.uk/components/button/): "Disabled buttons have poor contrast and can confuse some users, so avoid them if possible", and [validation](https://design-system.service.gov.uk/patterns/validation/) refuses "missing information, if the information is required" | 2026-10-18 |
|
|
22
|
+
|
|
23
|
+
## Error placement
|
|
24
|
+
|
|
25
|
+
| Bullet | Source | Read |
|
|
26
|
+
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
27
|
+
| Error next to its field | [Error message](https://design-system.service.gov.uk/components/error-message/): "Show an error message next to the field and in the Error summary component when there is a validation error" | 2026-10-18 |
|
|
28
|
+
| Cross-field error on the edited field | House choice: an error under the field the person did not touch sends them to change a value they meant, rather than the one they just entered | 2026-10-18 |
|
|
29
|
+
| Focus to a linked summary | [Error summary](https://design-system.service.gov.uk/components/error-summary/): "move keyboard focus to the error summary" and "link to each of the answers that have validation errors" | 2026-10-18 |
|
|
30
|
+
|
|
31
|
+
## Authentication and re-entry
|
|
32
|
+
|
|
33
|
+
| Bullet | Source | Read |
|
|
34
|
+
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
35
|
+
| Allow paste and autofill | [Understanding Accessible Authentication (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html): mechanisms that satisfy it include "support for password entry by password managers" and "copy and paste to reduce the cognitive burden of re-typing" | 2026-10-18, WCAG 2.2 |
|
|
36
|
+
| No redundant entry | [Understanding Redundant Entry](https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html): information previously entered in the same process is "either auto-populated, or available for the user to select" | 2026-10-18, WCAG 2.2 |
|
|
37
|
+
|
|
38
|
+
## Input sanitization
|
|
39
|
+
|
|
40
|
+
| Bullet | Source | Read |
|
|
41
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
42
|
+
| Trim on submit | [Recover from validation errors](https://design-system.service.gov.uk/patterns/validation/): "Use validation to ignore unwanted characters", such as spaces entered "before or after" an answer, since an error over one "would be difficult for the user to see and fix" | 2026-10-18 |
|
|
43
|
+
| Say a field is case-sensitive | House choice: a value rejected or duplicated on case alone fails with no visible reason, since `Foo` and `foo` read as the same answer | 2026-10-18 |
|
|
44
|
+
|
|
45
|
+
## Derived display state
|
|
46
|
+
|
|
47
|
+
| Bullet | Source | Read |
|
|
48
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
49
|
+
| Reset derived state on change | House choice: a status, count, or result left from the previous input reports on a value the field no longer holds, such as a "connected" dot for an old URL | 2026-10-18 |
|
|
50
|
+
|
|
51
|
+
## Declined
|
|
52
|
+
|
|
53
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
54
|
+
|
|
55
|
+
### Contradicted by the source
|
|
56
|
+
|
|
57
|
+
- Replaced "validate on blur" with validation on submit, since GOV.UK says "Do not validate when the user moves away from a field".
|
|
58
|
+
- Kept GOV.UK over NN/g's [form errors guidelines](https://www.nngroup.com/articles/errors-forms-design-guidelines/), which favor validation "as soon as the user has finished filling in a field".
|
|
59
|
+
- Replaced "block save when a required field is empty or invalid" with the submission bullet. Read as a disabled button, it contradicts GOV.UK.
|
|
60
|
+
|
|
61
|
+
### Made redundant by the rewrite
|
|
62
|
+
|
|
63
|
+
- Cut "apply the same validation timing to all fields in a form", since validating on submit gives every field one timing.
|
|
64
|
+
- Cut "do not show an error on a field the user has never touched", since no error shows before a submit.
|
|
65
|
+
|
|
66
|
+
### Merged or reworded
|
|
67
|
+
|
|
68
|
+
- Merged "treat whitespace-only values as empty for required fields" into the submission bullet.
|
|
69
|
+
- Merged the `## Submission errors` H2 into `## Error placement`, which took the form to 6 H2s.
|
|
70
|
+
- Reworded "under the field" to "next to the field", since GOV.UK places the message between the label and the input.
|
|
71
|
+
- Took in the status indicator reset from `ux-completeness.md`, so the reset has one copy.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Interface casing rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/interface-casing.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Interface casing rule ledger
|
|
7
|
+
|
|
8
|
+
The field is content design, and the authority is the GOV.UK style guide, which sets sentence case for every heading and title. The label count and the scope bullets are canon's own.
|
|
9
|
+
|
|
10
|
+
## Sentence case
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Sentence case | [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style): "Always use sentence case, even in page titles and service names" | 2026-10-18 |
|
|
15
|
+
| Proper nouns keep casing | [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style): "The exceptions to this are proper nouns" | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## Uppercase labels
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
21
|
+
| Label count | House choice: an uppercase eyebrow over every section is the template tell `design-taste` reaches past, and the count makes the cap checkable against a page | 2026-10-18 |
|
|
22
|
+
|
|
23
|
+
## Where it applies
|
|
24
|
+
|
|
25
|
+
| Bullet | Source | Read |
|
|
26
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
27
|
+
| Copy outside the globs | House choice: a locale file holds the same rendered strings, so title case there ships with no rule firing on it | 2026-10-18 |
|
|
28
|
+
|
|
29
|
+
## Overriding
|
|
30
|
+
|
|
31
|
+
| Bullet | Source | Read |
|
|
32
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
33
|
+
| Depart where needed | House choice: an acronym or brand mark lowered to sentence case misnames it, the same reason GOV.UK keeps "proper nouns" as its one exception | 2026-10-18 |
|
|
34
|
+
|
|
35
|
+
## Declined
|
|
36
|
+
|
|
37
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
38
|
+
|
|
39
|
+
### Cut without a check
|
|
40
|
+
|
|
41
|
+
- Cut "treat the count as a judgment, since a glob cannot check it", which tells a session nothing it can verify against a line.
|
|
42
|
+
|
|
43
|
+
### Merged or reworded
|
|
44
|
+
|
|
45
|
+
- Folded "treat title case on every heading as a template tell" into the sentence case bullet as its reason.
|
|
46
|
+
- Shortened the uppercase label bullet under 200 characters, keeping the `ceil(sections / 3)` count and the delete remedy.
|
|
47
|
+
- Reworded the scope bullet from a statement of what the rule covers to the directive a session can act on.
|