@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,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Keyboard rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/keyboard.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Keyboard rule ledger
|
|
7
|
+
|
|
8
|
+
The field is web accessibility, and the authorities are the W3C, through WCAG 2.2 and the ARIA Authoring Practices Guide, MDN for CSS behavior, and the platform guidelines from Apple and Android for native targets. Every bullet here was split from `a11y.md`.
|
|
9
|
+
|
|
10
|
+
## Focus styles
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
14
|
+
| One project focus ring | House choice: per-component focus styles drift apart, and `canon inventory` reports the ring by computed style, so a one-off treatment shows as its own row | 2026-10-18 |
|
|
15
|
+
| No outline removal without a replacement | [outline](https://developer.mozilla.org/en-US/docs/Web/CSS/outline): "Assigning outline a value of 0 or none will remove the browser's default focus style. If an element can be interacted with it must have a visible focus indicator." | 2026-10-18 |
|
|
16
|
+
| 3:1 ring in every theme | [Understanding Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html): visual information needed to identify a state needs "a contrast ratio of at least 3:1 against adjacent color(s)" | 2026-10-18, WCAG 2.2 |
|
|
17
|
+
|
|
18
|
+
## Keyboard operation
|
|
19
|
+
|
|
20
|
+
| Bullet | Source | Read |
|
|
21
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
|
|
22
|
+
| Escape closes | [Dialog (modal) pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/): "Escape : Closes the dialog", and the [combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) gives Escape the same job for a popup | 2026-10-18, APG |
|
|
23
|
+
| No bare character shortcut | [Understanding Character Key Shortcuts](https://www.w3.org/WAI/WCAG22/Understanding/character-key-shortcuts.html): a character-only shortcut needs a way to "Turn off", to "Remap", or to be "Active only on focus" | 2026-10-18, WCAG 2.2 |
|
|
24
|
+
| Drag has a single-pointer path | [Understanding Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html): "For any action that involves dragging, provide a simple pointer alternative" | 2026-10-18, WCAG 2.2 |
|
|
25
|
+
|
|
26
|
+
## Composite widgets
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
|
|
30
|
+
| One item in the tab sequence | [Developing a keyboard interface](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/): "the tab sequence should include only one focusable element of a composite UI component", managed by "a roving tabindex" or "the aria-activedescendant property" | 2026-10-18, APG |
|
|
31
|
+
| Combobox keys | [Combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/): "Down Arrow : If the popup is available, moves focus into the popup", Enter accepts the focused option, and "Escape : Dismisses the popup if it is visible" | 2026-10-18, APG |
|
|
32
|
+
|
|
33
|
+
## Focus management
|
|
34
|
+
|
|
35
|
+
| Bullet | Source | Read |
|
|
36
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
37
|
+
| Focus into a dialog and back | [Dialog (modal) pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/): "When a dialog opens, focus moves to an element inside the dialog", and "When a dialog closes, focus returns to the element that invoked the dialog" | 2026-10-18, APG |
|
|
38
|
+
| Focus never covered | [Understanding Focus Not Obscured (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html): "the component is not entirely hidden due to author-created content" | 2026-10-18, WCAG 2.2 |
|
|
39
|
+
|
|
40
|
+
## Pointer targets
|
|
41
|
+
|
|
42
|
+
| Bullet | Source | Read |
|
|
43
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
44
|
+
| 24 by 24 on the web | [Understanding Target Size (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html): "at least 24 by 24 CSS pixels", except where "a 24 CSS pixel diameter circle is centered on the bounding box of each" and "the circles do not intersect" | 2026-10-18, WCAG 2.2 |
|
|
45
|
+
| Native figures | [Apple accessibility guidelines](https://developer.apple.com/design/human-interface-guidelines/accessibility): a default "44x44 pt" control size on iOS and iPadOS, and [Android accessibility](https://developer.android.com/guide/topics/ui/accessibility/apps): "a focusable area, or touch target size , of at least 48dpx48dp" | 2026-10-18 |
|
|
46
|
+
|
|
47
|
+
## Declined
|
|
48
|
+
|
|
49
|
+
Every bullet the split removed or reshaped, grouped by why.
|
|
50
|
+
|
|
51
|
+
### Browser defaults
|
|
52
|
+
|
|
53
|
+
- Cut the Tab, Enter, and Space bullets of the old keyboard model. A native element does each by default, and `a11y.md` already sends a session to the native element.
|
|
54
|
+
|
|
55
|
+
### Rewritten to what the source says
|
|
56
|
+
|
|
57
|
+
- Replaced "do not introduce non-standard key bindings" with the character key bullet. No reviewer can check "non-standard", and the criterion names the binding that breaks.
|
|
58
|
+
- Narrowed "move focus into any overlay, popover, or dialog on open" to a dialog. The APG moves focus into a modal dialog, and a non-modal popover such as a tooltip leaves focus on its trigger.
|
|
59
|
+
|
|
60
|
+
### Cut without a source or a bug class
|
|
61
|
+
|
|
62
|
+
- Cut "never move focus on hover", a convention Claude already follows that no cited page takes a side on.
|
|
63
|
+
|
|
64
|
+
### Merged or reworded
|
|
65
|
+
|
|
66
|
+
- Merged "arrow keys navigate within composite widgets" into the roving `tabindex` bullet, which names the arrow keys.
|
|
67
|
+
- Merged "Escape cancels in-progress edits" into the Escape bullet, and took in the inline confirmation case from the `ux-completeness.md` rewrite so the Escape behavior has one copy.
|
|
68
|
+
- Reworded the combobox bullet to the pattern's own keys, dropping "typing filters", which the APG leaves to each autocomplete behavior.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Link behavior rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/link-behavior.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Link behavior rule ledger
|
|
7
|
+
|
|
8
|
+
The field is interaction design, and the authority is the Nielsen Norman Group's research on new windows and tabs.
|
|
9
|
+
|
|
10
|
+
## Default target
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
14
|
+
| Same tab, new tab by task | [Opening links in new browser windows and tabs](https://www.nngroup.com/articles/new-browser-windows-and-tabs/): "There is generally one good reason to open a page in a new window, and that is that the user will need to refer to that content in order to complete a task in another window" | 2026-10-18 |
|
|
15
|
+
| No blanket external new tab | [Opening links in new browser windows and tabs](https://www.nngroup.com/articles/new-browser-windows-and-tabs/): "New windows or tabs prevent the use of the Back button" and "can cause disorientation" | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## mailto: links
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
21
|
+
| `mailto:` same tab | House choice: the link opens the mail client and leaves the page in place, so `target="_blank"` only adds an empty tab the person must close | 2026-10-18 |
|
|
22
|
+
|
|
23
|
+
## Declined
|
|
24
|
+
|
|
25
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
26
|
+
|
|
27
|
+
### Rewritten to what the source says
|
|
28
|
+
|
|
29
|
+
- Reworded the new tab exception from "a destination that would discard in-progress work" to a page the person must consult while finishing a task, the one reason NN/g names.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Motion rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/motion.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Motion rule ledger
|
|
7
|
+
|
|
8
|
+
The field is web accessibility, and the authorities are the W3C, through WCAG 2.2 and the ARIA Authoring Practices Guide, and MDN for the media feature.
|
|
9
|
+
|
|
10
|
+
## Moving content
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
14
|
+
| Pause past five seconds | [Understanding Pause, Stop, Hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html): moving information that "starts automatically", "lasts more than five seconds", and sits beside other content needs "a mechanism for the user to pause , stop, or hide it" | 2026-10-18, WCAG 2.2 |
|
|
15
|
+
| Halt rotation on focus or hover | [Carousel pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/): a rotating carousel "Stops rotating when keyboard focus enters the carousel" and "whenever the mouse is hovering over the carousel" | 2026-10-18, APG |
|
|
16
|
+
| Three flashes | [Understanding Three Flashes or Below Threshold](https://www.w3.org/WAI/WCAG22/Understanding/three-flashes-or-below-threshold.html): pages "do not contain anything that flashes more than three times in any one second period" | 2026-10-18, WCAG 2.2 |
|
|
17
|
+
|
|
18
|
+
## Reduced motion
|
|
19
|
+
|
|
20
|
+
| Bullet | Source | Read |
|
|
21
|
+
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
22
|
+
| Honor the preference | [prefers-reduced-motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion): it detects a setting "to minimize the amount of non-essential motion", for an interface "that removes, reduces, or replaces motion-based animations" | 2026-10-18 |
|
|
23
|
+
| Essential changes stay visible | [Understanding Animation from Interactions](https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html): motion can be disabled "unless the animation is essential to the functionality or the information being conveyed" | 2026-10-18, WCAG 2.2 |
|
|
24
|
+
| No autoplay under the preference | [prefers-reduced-motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion): the setting asks the browser for an interface that "removes, reduces, or replaces motion-based animations", and a self-starting video is one | 2026-10-18 |
|
|
25
|
+
|
|
26
|
+
## Declined
|
|
27
|
+
|
|
28
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
29
|
+
|
|
30
|
+
### Merged or reworded
|
|
31
|
+
|
|
32
|
+
- Added the criterion number to the three flashes bullet, so every WCAG bullet in the rule names the criterion it rests on.
|
|
33
|
+
- Reworded "do not" bans to "never" and "start no" forms, with no change of meaning.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Surface capture rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/surface-capture.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Surface capture rule ledger
|
|
7
|
+
|
|
8
|
+
The rule states canon's own evidence procedure for a rendered change, so most rows are house choices naming the bug the bullet prevents. The 320 floor rests on WCAG 2.2, and each explanation the old rule carried moved into a row here.
|
|
9
|
+
|
|
10
|
+
## What a surface is
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Generated pages are surfaces | House choice: reading a generated page's markup reports nothing about how it composes, so a page nobody captured ships its layout unseen | 2026-10-18 |
|
|
15
|
+
| Skip build-stripped components | House choice: the production build removes a dev-only switcher before anything renders, so a capture of it compares nothing a person sees | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## When to capture
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
21
|
+
| Preview, not dev server | House choice: a dev server injects overlays and skips the production build's transforms, so its frame differs from what ships | 2026-10-18 |
|
|
22
|
+
| Every theme, and again | House choice: a defect in the dark theme passes a light-only capture, and a repair inside a shared stylesheet can cancel a rule written earlier in the same file | 2026-10-18 |
|
|
23
|
+
|
|
24
|
+
## What a capture covers
|
|
25
|
+
|
|
26
|
+
| Bullet | Source | Read |
|
|
27
|
+
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
28
|
+
| Full page | House choice: a component captured alone shows none of the spacing, overflow, or stacking its page imposes on it | 2026-10-18 |
|
|
29
|
+
| 320 plus breakpoints | [Understanding Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html): the criterion tests "a width equivalent to 320 CSS pixels". A 320 frame proves a frame was taken there, never that the page reflows, which `a11y.md` states. | 2026-10-18, WCAG 2.2 |
|
|
30
|
+
| Chrome at both clamps | House choice: a sidebar widened to its clamp leaves the content under the floor at a window width the criterion passes, and a frame where the chrome turned into an overlay shows none of the width it takes | 2026-10-18 |
|
|
31
|
+
| State case at one width | House choice: a case driving a menu open tests the state, and repeating it at every layout width multiplies the evidence with no layout to compare | 2026-10-18 |
|
|
32
|
+
| Drive unreachable states | House choice: an initial render reports nothing about a menu that opens, an answer that is chosen, or a rail that tracks scrolling | 2026-10-18 |
|
|
33
|
+
| Case lives with the surface | House choice: a surface with no case ships uncaptured, and a case left after its surface goes fails every later capture run | 2026-10-18 |
|
|
34
|
+
|
|
35
|
+
## Sharing a capture
|
|
36
|
+
|
|
37
|
+
| Bullet | Source | Read |
|
|
38
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
39
|
+
| An `evidence` folder | House choice: the pull request comment collects an image only when a path segment is literally `evidence`, so any other name drops the capture. Several such folders, one per surface, is the ordinary shape. | 2026-10-18 |
|
|
40
|
+
| Commit flagged cases only | House choice: recommitting an unbounded sweep on every run reaches a gigabyte of history inside a hundred merges, while a small committed set lets GitHub draw its own before and after comparison | 2026-10-18 |
|
|
41
|
+
| Byte-identical twice | House choice: a case whose output varies between runs shows a diff on every pull request, so the comparison stops meaning a change | 2026-10-18 |
|
|
42
|
+
| Mask the moving value | House choice: an elapsed-time counter or a relative date differs on every run, and masking the smallest element keeps the check running on the rest of the frame | 2026-10-18 |
|
|
43
|
+
| Name the variance | House choice: a value whose width reflows its neighbors survives the mask, and re-running until two frames match hides the variance rather than removing it | 2026-10-18 |
|
|
44
|
+
|
|
45
|
+
## Declined
|
|
46
|
+
|
|
47
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
48
|
+
|
|
49
|
+
### Moved into a row as the reason
|
|
50
|
+
|
|
51
|
+
- Moved "judge a generated page by the same rule as a route, since reading its markup reports nothing" into the generated pages row.
|
|
52
|
+
- Moved "read a capture at 320 as proof that a frame was taken there, not that the page reflows" into the 320 row.
|
|
53
|
+
- Moved "several `evidence/` folders in one project is the ordinary shape" into the folder row.
|
|
54
|
+
- Moved "recommitting an unbounded sweep reaches a gigabyte of repository history" into the commit row.
|
|
55
|
+
- Moved "do not commit the state as evidence when the masked outputs still differ" into the variance bullet and its row.
|
|
56
|
+
|
|
57
|
+
### Cut as stated elsewhere
|
|
58
|
+
|
|
59
|
+
- Cut "`git-pr` and `git-followup` maintain a comparison comment automatically", which those skills own and which directs nothing at the edit.
|
|
60
|
+
- Cut "fall back to the 320 floor alone when the project has no `DESIGN.md`", merged into the 320 bullet's "or at 320 alone".
|
|
61
|
+
- Cut "read those bounds from the code that clamps the chrome", merged into the chrome bullet's "clamp".
|
|
62
|
+
- Cut "do not impose another project's breakpoints", which the bullet reading `## Layout` already prevents.
|
|
63
|
+
|
|
64
|
+
### Merged or reworded
|
|
65
|
+
|
|
66
|
+
- Merged "run the capture command", "against a running preview", "every theme", and "capture again" into two bullets.
|
|
67
|
+
- Merged "do not commit the sweep" with "commit a flagged case's evidence" and the established convention exception.
|
|
68
|
+
- Merged "add a case" and "remove a surface's case" into one bullet.
|
|
69
|
+
- Shortened every bullet past 200 characters, cutting the rule from 27 bullets and 840 words to 15 and under 300.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: UX completeness rule ledger
|
|
3
|
+
description: Sources for governance/rules/ui/ux-completeness.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# UX completeness rule ledger
|
|
7
|
+
|
|
8
|
+
The field is interaction design, and the authorities are the Nielsen Norman Group's research articles, WCAG 2.2 for timing, MDN for the `title` attribute and CSS truncation, and web.dev for layout shift.
|
|
9
|
+
|
|
10
|
+
## Feedback
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
14
|
+
| Confirm success and failure | [Visibility of system status](https://www.nngroup.com/articles/visibility-system-status/): "Whenever users interact with a system, they need to know whether the interaction was successful" | 2026-10-18 |
|
|
15
|
+
| Auto-dismiss only a redundant message | [Understanding Timing Adjustable](https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html): "If the user has no other means of discovering the same information (or performing the same function), then each message would need to meet this success criterion" | 2026-10-18, WCAG 2.2 |
|
|
16
|
+
| No optimistic status | House choice: a "connected" dot shown over unsaved edits reports a state the system has not reached, and the person leaves believing their change took | 2026-10-18 |
|
|
17
|
+
|
|
18
|
+
## Empty states
|
|
19
|
+
|
|
20
|
+
| Bullet | Source | Read |
|
|
21
|
+
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
22
|
+
| Empty state with a next action | [Designing empty states](https://www.nngroup.com/articles/empty-state-interface-design/): designed empty states "Provide direct pathways for getting started with key tasks" | 2026-10-18 |
|
|
23
|
+
| Distinguish new from filtered | [Designing empty states](https://www.nngroup.com/articles/empty-state-interface-design/): after a filter returns nothing, people wonder "Did an error occur? Did I set the wrong filters or parameters?", and "Totally empty states cause confusion" | 2026-10-18 |
|
|
24
|
+
|
|
25
|
+
## Loading states
|
|
26
|
+
|
|
27
|
+
| Bullet | Source | Read |
|
|
28
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
29
|
+
| Indicator past one second | [Progress indicators](https://www.nngroup.com/articles/progress-indicators/): "Use a progress indicator for any action that takes longer than about 1.0 second" | 2026-10-18 |
|
|
30
|
+
| Mark stale content as updating | [Progress indicators](https://www.nngroup.com/articles/progress-indicators/): "Without any visual change from the system, most users will assume the action was not registered and they will try again" | 2026-10-18 |
|
|
31
|
+
|
|
32
|
+
## Destructive actions
|
|
33
|
+
|
|
34
|
+
| Bullet | Source | Read |
|
|
35
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
|
|
36
|
+
| Confirm unless undoable | [Confirmation dialogs](https://www.nngroup.com/articles/confirmation-dialog/): "consider a confirmation dialog before actions that cannot be undone", and "do try your best to offer undo" | 2026-10-18 |
|
|
37
|
+
|
|
38
|
+
## Element states
|
|
39
|
+
|
|
40
|
+
| Bullet | Source | Read |
|
|
41
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
42
|
+
| Distinct interaction states | [Visibility of system status](https://www.nngroup.com/articles/visibility-system-status/): "Did the system actually catch that button press", and an element with no pressed or hover response leaves the person unable to tell | 2026-10-18 |
|
|
43
|
+
| No intermediate flash | [Cumulative Layout Shift](https://web.dev/articles/cls): "Unexpected layout shifts can disrupt the user experience", caused by content "dynamically added to the page before existing content" | 2026-10-18 |
|
|
44
|
+
|
|
45
|
+
## Overflow
|
|
46
|
+
|
|
47
|
+
| Bullet | Source | Read |
|
|
48
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
49
|
+
| Ellipsis over overflow | [text-overflow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow): `text-overflow: ellipsis` with `overflow: hidden` and `white-space: nowrap` clips text at the box with a visible marker | 2026-10-18 |
|
|
50
|
+
| Never `title` alone | [The title attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/title): "Use of the title attribute is highly problematic for" people using touch-only devices, keyboards, and assistive technology | 2026-10-18 |
|
|
51
|
+
| Focus rings clear of clipping | House choice: a ring cut off by a parent's `overflow` shows on the middle items of a list and vanishes on the first and last, so the focus indicator fails exactly where the list ends | 2026-10-18 |
|
|
52
|
+
|
|
53
|
+
## Declined
|
|
54
|
+
|
|
55
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
56
|
+
|
|
57
|
+
### Contradicted by the source
|
|
58
|
+
|
|
59
|
+
- Replaced the `title`-or-expand truncation bullet with the never-`title`-alone bullet, since MDN calls the attribute "highly problematic" for touch and keyboard users.
|
|
60
|
+
- Qualified "feedback must auto-dismiss after 2 to 3 seconds" against WCAG 2.2.1, since a message carrying the only copy of its information sets a time limit on reading it.
|
|
61
|
+
- Rewrote "do not show stale content while new content is loading", which offered keeping the previous content as its own alternative, to the marking bullet.
|
|
62
|
+
|
|
63
|
+
### Moved to a sibling rule
|
|
64
|
+
|
|
65
|
+
- Moved "confirmation UI must be dismissible via Escape" and "inline confirmation rows must be dismissible via Escape" to the Escape bullet in `keyboard.md`.
|
|
66
|
+
- Moved "status indicators must reset to a neutral state when their source input changes" to `forms.md`, which held the same bullet for derived values.
|
|
67
|
+
- Cut "confirmation labels and destructive buttons must have sufficient contrast", which `a11y.md` holds for every control.
|
|
68
|
+
|
|
69
|
+
### Cut without a source or a bug class
|
|
70
|
+
|
|
71
|
+
- Cut "disabled elements must use muted colors and `cursor: not-allowed`", a convention Claude already follows that no source sets.
|
|
72
|
+
- Cut "use CSS transitions or deferred rendering to prevent visible flicker", merged into the intermediate flash bullet as its remedy.
|
|
73
|
+
|
|
74
|
+
### Merged or reworded
|
|
75
|
+
|
|
76
|
+
- Merged the `## Inline confirmations`, `## Status indicators`, `## State transitions`, `## Interactive element states`, and `## Scroll and clipping` H2s into six, the merge the plan suggested.
|
|
77
|
+
- Merged "every list must handle the empty state" with "empty states must include a next action", and the two filter bullets into one.
|
|
78
|
+
- Merged "do not rely on a single state to communicate interactivity" into the distinct states bullet.
|
|
79
|
+
- Reworded "every async operation must show a loading indicator" to NN/g's one second threshold, since a shorter spinner distracts.
|
package/governance/renames.toml
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
# file.
|
|
16
16
|
[renamed]
|
|
17
17
|
"015-output" = "566-output"
|
|
18
|
-
"035-tasks" = "602-tasks"
|
|
19
18
|
"055-scratch" = "604-scratch"
|
|
20
19
|
"085-worktrees" = "605-worktrees"
|
|
21
20
|
"087-git" = "606-git"
|
|
@@ -32,7 +31,6 @@
|
|
|
32
31
|
"655-tasks" = "tasks"
|
|
33
32
|
"570-skill" = "skill"
|
|
34
33
|
"801-markdown" = "markdown"
|
|
35
|
-
"602-tasks" = "task-scope"
|
|
36
34
|
"604-scratch" = "scratch"
|
|
37
35
|
"605-worktrees" = "worktrees"
|
|
38
36
|
"606-git" = "git"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Report file paths correctly for the reading surface
|
|
2
|
+
description: Report file paths correctly for the reading surface, group them when the response covers many, and name sessions to a person
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Output standards
|
|
@@ -17,3 +17,7 @@ description: Report file paths correctly for the reading surface and group them
|
|
|
17
17
|
|
|
18
18
|
- Group paths under `**Created:**`, `**Modified:**`, and `**Deleted:**` headers when the response covers multiple files, with every path under them in that form.
|
|
19
19
|
- Put a single-file change's path on its own line, with no header.
|
|
20
|
+
|
|
21
|
+
## Naming sessions
|
|
22
|
+
|
|
23
|
+
- Name a session to a person by its roster name from `canon sessions list`, and give its id only beside the name, never alone.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Routes code placement and shape decisions to the skills that carry them
|
|
2
|
+
description: Routes code placement and shape decisions to the skills that carry them, and library calls to the official docs
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Code standards
|
|
@@ -11,3 +11,7 @@ description: Routes code placement and shape decisions to the skills that carry
|
|
|
11
11
|
## Shape
|
|
12
12
|
|
|
13
13
|
- Load the `canon:code-craft` skill before deciding the shape of a new function, class, or module, and report it rather than proceeding silently when it does not resolve.
|
|
14
|
+
|
|
15
|
+
## Libraries
|
|
16
|
+
|
|
17
|
+
- Before calling a library API the codebase does not already use, fetch the official docs for the installed version and match the call to them, since recall of an API goes stale.
|
|
@@ -1,40 +1,31 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enforce Go
|
|
2
|
+
description: Enforce Go error wrapping, context passing, interface placement, and package boundaries
|
|
3
3
|
paths:
|
|
4
4
|
- '**/*.go'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Go standards
|
|
8
8
|
|
|
9
|
-
## Casing conventions
|
|
10
|
-
|
|
11
|
-
- Use `MixedCaps` for exported names and `mixedCaps` for unexported ones. Never use underscores in a Go identifier.
|
|
12
|
-
- Name packages with one short lowercase word. Do not use `util`, `common`, or `helpers` as a package name.
|
|
13
|
-
- Do not repeat the package name in an exported identifier (`user.New`, not `user.NewUser`).
|
|
14
|
-
- Keep initialisms in one case (`userID`, `HTTPClient`), never `userId` or `HttpClient`.
|
|
15
|
-
|
|
16
9
|
## Errors
|
|
17
10
|
|
|
18
|
-
- Return an error as the last result value.
|
|
19
11
|
- Wrap an error with `fmt.Errorf("...: %w", err)` when adding context.
|
|
20
|
-
- Match an error with `errors.Is` or `errors.As`. Never compare `err.Error()` strings.
|
|
21
|
-
- Never discard an error with `_`.
|
|
22
|
-
-
|
|
12
|
+
- Match an error with `errors.Is` or `errors.As`. Never compare with `==` or on `err.Error()` strings, which miss a wrapped error.
|
|
13
|
+
- Never discard an error with `_`. Handle it, return it, or panic on a broken invariant.
|
|
14
|
+
- Return an `error` for a failure a caller can expect. Reserve `panic` for a broken invariant.
|
|
23
15
|
|
|
24
16
|
## Context
|
|
25
17
|
|
|
26
18
|
- Pass `context.Context` as the first parameter, named `ctx`.
|
|
27
|
-
- Never store a `context.Context` in a struct field.
|
|
19
|
+
- Never store a `context.Context` in a struct field. Pass it to each function that needs it.
|
|
28
20
|
- Do not pass a `nil` context. Use `context.TODO()` where none is available yet.
|
|
29
21
|
|
|
30
22
|
## Interfaces
|
|
31
23
|
|
|
32
|
-
- Declare an interface in the package that consumes it,
|
|
33
|
-
- Keep an interface to the methods its consumer calls.
|
|
24
|
+
- Declare an interface in the package that consumes it, holding only the methods that consumer calls.
|
|
34
25
|
- Accept interfaces and return concrete types.
|
|
35
26
|
|
|
36
27
|
## Packages
|
|
37
28
|
|
|
38
29
|
- Place code no other module may import under `internal/`.
|
|
39
30
|
- Do not perform side effects in `init`. Wire dependencies explicitly from `main`.
|
|
40
|
-
- Do not hold mutable state in a package-level variable.
|
|
31
|
+
- Do not hold mutable state in a package-level variable. Pass it through a struct the caller owns.
|
|
@@ -19,7 +19,7 @@ paths:
|
|
|
19
19
|
|
|
20
20
|
## Data shapes
|
|
21
21
|
|
|
22
|
-
- Use
|
|
22
|
+
- Use an `enum` for a closed set over class constants, backed by a string or int when the value is stored or serialized.
|
|
23
23
|
- Use `readonly` properties or a `readonly` class for value objects.
|
|
24
24
|
- Declare classes `final` unless they are designed for extension.
|
|
25
25
|
- Do not pass an associative array across a public boundary where a typed object fits.
|
|
@@ -27,5 +27,5 @@ paths:
|
|
|
27
27
|
## Errors
|
|
28
28
|
|
|
29
29
|
- Throw a domain exception for a failure. Do not return `false` or `null` to signal one.
|
|
30
|
-
- Never suppress an error with the `@` operator.
|
|
31
|
-
- Do not use `extract`, variable variables, or `eval`.
|
|
30
|
+
- Never suppress an error with the `@` operator. Check the condition first or catch the exception.
|
|
31
|
+
- Do not use `extract`, variable variables, or `eval`. Name each variable and call each function directly.
|
|
@@ -1,31 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enforce strict Python type hints,
|
|
2
|
+
description: Enforce strict Python type hints, exception handling, data shapes, and import patterns
|
|
3
3
|
paths:
|
|
4
4
|
- '**/*.py'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Python standards
|
|
8
8
|
|
|
9
|
-
## Casing conventions
|
|
10
|
-
|
|
11
|
-
- Use `snake_case` for modules, functions, variables, and methods.
|
|
12
|
-
- Use `PascalCase` for classes, type aliases, `TypeVar`, and `ParamSpec`.
|
|
13
|
-
- Use `UPPER_SNAKE_CASE` for module-level constants and environment variables.
|
|
14
|
-
- Use `_leading_underscore` for module-private names. Reserve `__dunder__` for the standard protocol.
|
|
15
|
-
|
|
16
9
|
## Type hints
|
|
17
10
|
|
|
18
|
-
- Annotate
|
|
19
|
-
- Use `X | None`
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Do not use `Any`. Reach for `object` or `typing.cast` at boundaries instead.
|
|
11
|
+
- Annotate every public function and method, since a type checker skips the body of an unannotated function.
|
|
12
|
+
- Use `X | None`, `X | Y`, and built-in generics such as `list[str]` over `Optional`, `Union`, and `typing.List`.
|
|
13
|
+
- Do not add `from __future__ import annotations`. Python plans to deprecate and remove it.
|
|
14
|
+
- Use `typing.Protocol` for an interface a class satisfies by shape, over an abstract base class it must subclass.
|
|
15
|
+
- Type a value that can be anything as `object` and narrow it. Never use `Any`, which turns checking off.
|
|
24
16
|
|
|
25
17
|
## Errors
|
|
26
18
|
|
|
27
|
-
- Raise specific built-in
|
|
28
|
-
- Define a project-rooted exception hierarchy for domain errors.
|
|
19
|
+
- Raise a specific built-in exception or one from a project-rooted hierarchy, never bare `Exception`.
|
|
29
20
|
- Catch the narrowest exception class. Never use bare `except:`.
|
|
30
21
|
- Re-raise with `raise ... from err` to preserve the cause chain.
|
|
31
22
|
|
|
@@ -37,6 +28,6 @@ paths:
|
|
|
37
28
|
|
|
38
29
|
## Imports and modules
|
|
39
30
|
|
|
40
|
-
- Use absolute imports rooted at the package
|
|
31
|
+
- Use absolute imports rooted at the package over relative ones.
|
|
41
32
|
- Do not alias imports to shorten internal names. Ecosystem conventions (`numpy as np`, `pandas as pd`) are exceptions.
|
|
42
|
-
- Do not place executable code at module scope. Guard with `if __name__ == "__main__"
|
|
33
|
+
- Do not place executable code at module scope. Guard it with `if __name__ == "__main__":` and call a `main` function.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enforce strict TypeScript type safety and patterns
|
|
2
|
+
description: Enforce strict TypeScript type safety, declarations, and import patterns
|
|
3
3
|
paths:
|
|
4
4
|
- '**/*.ts'
|
|
5
5
|
- '**/*.tsx'
|
|
@@ -7,34 +7,24 @@ paths:
|
|
|
7
7
|
|
|
8
8
|
# TypeScript standards
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## File names
|
|
11
11
|
|
|
12
|
-
- Use `kebab-case` for filenames and directories.
|
|
13
|
-
- Use `camelCase` for variables, functions, and methods.
|
|
14
|
-
- Use `PascalCase` for types, interfaces, classes, and components.
|
|
15
|
-
- Use `UPPER_SNAKE_CASE` for constants and environment variables.
|
|
12
|
+
- Use `kebab-case` for filenames and directories, since a case-only difference resolves on macOS and fails on Linux.
|
|
16
13
|
|
|
17
14
|
## Type declarations
|
|
18
15
|
|
|
19
|
-
-
|
|
20
|
-
- Use `
|
|
21
|
-
- Use `
|
|
22
|
-
- Use `type` for unions, intersections, and utility types.
|
|
23
|
-
- Do not prefix interfaces with `I`.
|
|
24
|
-
- Use constant objects or union types instead of `enum`.
|
|
16
|
+
- Use `unknown` over `any`, and narrow it before use.
|
|
17
|
+
- Use `interface` for an object shape until it needs a feature only `type` has, such as a union or a mapped type.
|
|
18
|
+
- Use a constant object with `as const` or a union of literals instead of `enum`.
|
|
25
19
|
|
|
26
20
|
## Type safety
|
|
27
21
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Use built-in utility types (`Partial`, `Pick`, `Omit`) over manual type manipulation.
|
|
31
|
-
- Prefer `readonly` properties for data objects.
|
|
32
|
-
- Do not use non-null assertions.
|
|
33
|
-
- Use `Promise.all()` for independent async operations.
|
|
22
|
+
- Narrow with a type guard or a runtime check over a type assertion or a non-null `!`, neither of which checks at runtime.
|
|
23
|
+
- Run independent async operations through `Promise.all()` rather than awaiting each in turn.
|
|
34
24
|
|
|
35
25
|
## Imports and configuration
|
|
36
26
|
|
|
37
|
-
-
|
|
27
|
+
- Import through the `@/` alias where tsconfig.json and the bundler both map it to `src/`, over a `../../` chain.
|
|
38
28
|
- Import from the module's source file directly over barrel `index` re-exports.
|
|
39
29
|
- Use `import type` for type-only imports.
|
|
40
30
|
- Enable `strict: true` in tsconfig.json with no exceptions.
|
|
@@ -14,22 +14,22 @@ paths:
|
|
|
14
14
|
## Schema changes
|
|
15
15
|
|
|
16
16
|
- Express every schema change as a migration file committed to version control.
|
|
17
|
-
- Ship a
|
|
17
|
+
- Ship a way back with every schema migration, as a down step or a forward migration that reverses it.
|
|
18
18
|
- Never alter a deployed schema outside a migration.
|
|
19
19
|
- Never edit a migration that has run in a shared environment. Add a new one.
|
|
20
|
-
-
|
|
20
|
+
- Drop a column or table only after a deploy that stops reading and writing it.
|
|
21
21
|
|
|
22
22
|
## Query construction
|
|
23
23
|
|
|
24
24
|
- Pass every runtime value as a bound parameter.
|
|
25
25
|
- Never interpolate, concatenate, or format a value into a statement string.
|
|
26
|
-
-
|
|
26
|
+
- Map a table name, column, or sort direction through an allow-list, since none of them can be bound.
|
|
27
27
|
|
|
28
28
|
## Transactions
|
|
29
29
|
|
|
30
30
|
- Give each transaction one owner that opens it, commits it, and rolls it back.
|
|
31
|
-
- Never
|
|
32
|
-
- Keep network calls, queue publishes, and filesystem writes outside an open transaction.
|
|
31
|
+
- Never commit a transaction a function was handed. Take a savepoint, such as a nested `atomic`, for a partial rollback.
|
|
32
|
+
- Keep network calls, queue publishes, and filesystem writes outside an open transaction, running them after commit.
|
|
33
33
|
|
|
34
34
|
## Access patterns
|
|
35
35
|
|
|
@@ -8,13 +8,12 @@ paths:
|
|
|
8
8
|
|
|
9
9
|
## Waiting
|
|
10
10
|
|
|
11
|
-
- Settle on the condition a step waits for
|
|
11
|
+
- Settle on the condition a step waits for with a web-first assertion or `expect.poll`, never `page.waitForTimeout`.
|
|
12
12
|
- Reserve a fixed duration for an assertion that nothing happened across a window.
|
|
13
|
-
- Bound every settle with an explicit timeout.
|
|
13
|
+
- Bound every settle with an explicit timeout. `toPass` defaults to none and ignores the expect timeout.
|
|
14
14
|
- Do not raise a timeout to clear a failure that reproduces under load. Replace the wait with a settle.
|
|
15
|
-
- Do not read a value once after a pause. Poll it.
|
|
16
15
|
- Settle a smooth scroll on the `scrollend` event. Fall back to a stillness window only when the target was already in view.
|
|
17
|
-
- Run with
|
|
16
|
+
- Run with `reducedMotion: 'reduce'` unless the test asserts motion, and opt back in per test.
|
|
18
17
|
|
|
19
18
|
## Falsifiable guards
|
|
20
19
|
|
|
@@ -26,9 +25,8 @@ paths:
|
|
|
26
25
|
## Reproducing a failure that only appears in CI
|
|
27
26
|
|
|
28
27
|
- Reproduce under `Emulation.setCPUThrottlingRate` rather than by rerunning the gate.
|
|
29
|
-
- Read the state the assertion does not
|
|
28
|
+
- Read the failure's trace for the state the assertion does not read, such as which markers were set and which listeners fired.
|
|
30
29
|
- Vary the condition under suspicion deliberately. Do not compare counts across runs that differed in something uncontrolled.
|
|
31
|
-
- Read the check conclusion as its own act. A green diff review reports nothing about the gate.
|
|
32
30
|
|
|
33
31
|
## Authority
|
|
34
32
|
|