@erclx/canon 5.42.0 → 5.44.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/SKILL.md +3 -3
- package/claude/skills/backlog-triage/references/apply.md +6 -6
- package/claude/skills/canon-cli/SKILL.md +4 -4
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +1 -1
- package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
- package/claude/skills/ci-workflow/SKILL.md +12 -2
- package/claude/skills/ci-workflow/references/workflows.md +12 -9
- package/claude/skills/context-fold/references/context.md +1 -1
- package/claude/skills/create-rule/SKILL.md +1 -0
- package/claude/skills/create-skill/REQUIREMENT.md +1 -1
- package/claude/skills/create-skill/SKILL.md +2 -2
- package/claude/skills/create-skill/references/skill-requirement.md +68 -9
- package/claude/skills/create-skill/references/skill.md +1 -1
- package/claude/skills/decision-escalate/SKILL.md +1 -2
- package/claude/skills/design-identity/REQUIREMENT.md +40 -0
- package/claude/skills/design-identity/SKILL.md +138 -0
- package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
- package/claude/skills/design-taste/REQUIREMENT.md +4 -4
- package/claude/skills/design-taste/SKILL.md +2 -2
- package/claude/skills/design-taste/references/kinds.md +1 -1
- package/claude/skills/design-taste/references/preflight.md +1 -1
- package/claude/skills/document-health/references/axes.md +2 -1
- package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
- package/claude/skills/draft-and-pick/SKILL.md +3 -153
- package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
- package/claude/skills/draft-doc/SKILL.md +4 -76
- package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
- package/claude/skills/draft-figure/SKILL.md +3 -77
- package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
- package/claude/skills/draft-identity/SKILL.md +3 -130
- package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
- package/claude/skills/draft-ready/SKILL.md +3 -128
- package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
- package/claude/skills/draft-screencast/SKILL.md +3 -62
- package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
- package/claude/skills/draft-slides/SKILL.md +3 -72
- package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
- package/claude/skills/draw-figure/SKILL.md +85 -0
- package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
- package/claude/skills/git-commit/references/commit.md +1 -5
- package/claude/skills/git-pr/references/pr.md +1 -0
- package/claude/skills/make-deck/REQUIREMENT.md +44 -0
- package/claude/skills/make-deck/SKILL.md +80 -0
- package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
- package/claude/skills/markdown-craft/SKILL.md +2 -2
- package/claude/skills/pick-by-eye/REQUIREMENT.md +86 -0
- package/claude/skills/pick-by-eye/SKILL.md +161 -0
- package/claude/skills/plan-feature/SKILL.md +3 -2
- package/claude/skills/plan-feature/references/plan.md +25 -11
- package/claude/skills/plan-groundwork/SKILL.md +1 -1
- package/claude/skills/plan-intake/SKILL.md +1 -1
- package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
- package/claude/skills/plan-ready/SKILL.md +136 -0
- package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
- package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
- package/claude/skills/pr-evidence/references/evidence.md +1 -1
- package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
- package/claude/skills/record-screencast/SKILL.md +2 -2
- package/claude/skills/role-orchestrator/REQUIREMENT.md +1 -1
- package/claude/skills/role-orchestrator/SKILL.md +2 -0
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -0
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +5 -4
- package/claude/skills/role-worker/REQUIREMENT.md +2 -0
- package/claude/skills/role-worker/SKILL.md +35 -2
- package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
- package/claude/skills/script-screencast/SKILL.md +70 -0
- package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
- package/claude/skills/search-craft/REQUIREMENT.md +4 -4
- package/claude/skills/search-craft/SKILL.md +2 -2
- package/claude/skills/target-setup/SKILL.md +1 -0
- package/claude/skills/task-board/SKILL.md +11 -9
- package/claude/skills/task-board/references/board.md +15 -12
- package/claude/skills/teach-workspace/SKILL.md +1 -1
- package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
- package/claude/skills/ui-checklist/SKILL.md +2 -0
- package/claude/skills/write-doc/REQUIREMENT.md +46 -0
- package/claude/skills/write-doc/SKILL.md +83 -0
- package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +4 -4
- package/claude/skills/{draft-doc → write-doc}/references/wiki.md +1 -1
- package/docs/agents/audits.md +1 -0
- package/docs/agents/markdown-audit.md +4 -2
- package/docs/agents/migrate.md +13 -10
- package/docs/target/migrations.md +28 -4
- package/docs/target/projects.md +1 -1
- package/docs/workflow/parallel-features.md +3 -2
- package/docs/workflow/skill-map-on-request.md +18 -12
- package/docs/workflow/skill-map.md +13 -12
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/governance/detect.toml +4 -0
- package/governance/ledger/framework/astro.md +73 -0
- package/governance/ledger/framework/fastapi.md +76 -0
- package/governance/ledger/framework/nextjs.md +86 -0
- package/governance/ledger/framework/react.md +83 -0
- package/governance/ledger/framework/shadcn.md +60 -0
- package/governance/ledger/framework/tailwind.md +55 -0
- package/governance/rules/canon/context.md +2 -1
- package/governance/rules/canon/plan.md +3 -5
- package/governance/rules/canon/scratch.md +3 -1
- package/governance/rules/canon/task-scope.md +2 -1
- package/governance/rules/canon/tasks.md +2 -1
- package/governance/rules/canon/worktrees.md +5 -2
- package/governance/rules/claude/output.md +7 -4
- package/governance/rules/claude/skill.md +6 -4
- package/governance/rules/framework/astro.md +12 -14
- package/governance/rules/framework/fastapi.md +20 -24
- package/governance/rules/framework/nextjs.md +19 -27
- package/governance/rules/framework/react.md +22 -33
- package/governance/rules/framework/shadcn.md +11 -15
- package/governance/rules/framework/tailwind.md +12 -14
- package/governance/rules/tooling/ci-workflow.md +6 -39
- package/governance/rules/ui/design-reference.md +37 -0
- package/governance/rules/writing/markdown.md +3 -2
- package/package.json +6 -6
- package/src/audits/catalog.ts +42 -0
- package/src/claude/cases/authoring.ts +15 -3
- package/src/claude/cases/misc.ts +12 -0
- package/src/claude/cases/workflow.ts +19 -1
- package/src/claude/settings.ts +8 -4
- package/src/claude/skills-audit.ts +113 -1
- package/src/commands/claude.ts +45 -12
- package/src/commands/demo.ts +1 -1
- package/src/commands/gov.ts +198 -0
- package/src/commands/markdown.ts +1 -1
- package/src/commands/migrate.ts +125 -2
- package/src/commands/pr.ts +34 -83
- package/src/commands/tasks.ts +383 -2
- package/src/commands/tooling.ts +3 -3
- package/src/commands/worktrees.ts +49 -0
- package/src/context/audit.ts +1 -1
- package/src/demo/beats.ts +1 -1
- package/src/gate/stages.ts +15 -0
- package/src/gov/audit.ts +441 -0
- package/src/listeners/belongs.ts +21 -0
- package/src/listeners/machine.ts +93 -0
- package/src/listeners/parse.ts +41 -0
- package/src/markdown/scope.ts +45 -35
- package/src/migrate/record-layout.ts +1 -1
- package/src/migrate/session-defaults.ts +138 -0
- package/src/migrate/skill-names.ts +68 -21
- package/src/pr/frames.ts +14 -3
- package/src/pr/local.ts +4 -69
- package/src/records/validate.ts +31 -0
- package/src/sync/check.ts +15 -0
- package/src/tasks/board.ts +854 -0
- package/src/tasks/record.ts +20 -1
- package/src/tasks/validate.ts +206 -9
- package/src/tooling/stamp.ts +56 -12
- package/src/worktrees/stop.ts +92 -0
- package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
- package/tooling/astro/reference.md +2 -2
- package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
- package/tooling/base/configs/commitlint.config.js +0 -20
- package/tooling/base/reference.md +1 -1
- package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
- package/tooling/claude/reference.md +13 -7
- package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
- package/tooling/claude/seeds/.claude/settings.json +8 -0
- package/tooling/claude/user/settings.template.json +0 -4
- package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
- package/tooling/public/configs/.github/dependabot.yml +12 -0
- package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
- package/tooling/public/manifest.toml +8 -0
- package/tooling/public/reference.md +53 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
- package/tooling/public/seeds/.release-please-manifest.json +3 -0
- package/tooling/public/seeds/CONTRIBUTING.md +50 -0
- package/tooling/public/seeds/LICENSE +21 -0
- package/tooling/public/seeds/SECURITY.md +13 -0
- package/tooling/public/seeds/release-please-config.json +12 -0
- package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
- package/tooling/web/configs/.github/workflows/verify.yml +15 -12
- /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
- /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
- /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: FastAPI rule ledger
|
|
3
|
+
description: Sources for governance/rules/framework/fastapi.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FastAPI rule ledger
|
|
7
|
+
|
|
8
|
+
The field is back-end Python web engineering, and the authority is the FastAPI documentation at fastapi.tiangolo.com. None of the pages read names a FastAPI major, so the rows record the read date alone.
|
|
9
|
+
|
|
10
|
+
## Routers
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| One `APIRouter` per feature | [Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/): "You can think of APIRouter as a mini FastAPI class", and "With app.include_router() we can add each APIRouter" | 2026-10-18 |
|
|
15
|
+
| Router-level dependencies | [Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/): router `dependencies` "can be used, for example, to require authentication for a whole group of path operations" | 2026-10-18 |
|
|
16
|
+
|
|
17
|
+
## Path operations
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
21
|
+
| `async def` only when awaited | [Concurrency and async / await](https://fastapi.tiangolo.com/async/): a plain `def` "is run in an external threadpool that is then awaited", and "use async def unless your path operation functions use code that performs blocking I/O" | 2026-10-18 |
|
|
22
|
+
| Response model omits secrets | [Response Model](https://fastapi.tiangolo.com/tutorial/response-model/): FastAPI "will limit and filter the output data to what is defined in the return type" | 2026-10-18 |
|
|
23
|
+
| Body as a Pydantic model | [Request Body](https://fastapi.tiangolo.com/tutorial/body/): "To declare a request body, you use Pydantic models", which validate it and return "a nice and clear error" when it is invalid | 2026-10-18 |
|
|
24
|
+
|
|
25
|
+
## Dependencies
|
|
26
|
+
|
|
27
|
+
| Bullet | Source | Read |
|
|
28
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
29
|
+
| `Annotated` and type aliases | [Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/): "Prefer to use the Annotated version if possible", and the value can be stored "in a variable and use it in multiple places" | 2026-10-18 |
|
|
30
|
+
| Session per request via `yield` | [Dependencies with yield](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/): "you could use this to create a database session and close it after finishing" | 2026-10-18 |
|
|
31
|
+
| Overrides in tests | [Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/): "your FastAPI application has an attribute app.dependency_overrides" | 2026-10-18 |
|
|
32
|
+
|
|
33
|
+
## Lifespan and settings
|
|
34
|
+
|
|
35
|
+
| Bullet | Source | Read |
|
|
36
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
37
|
+
| `lifespan`, not `on_event` | [Lifespan Events](https://fastapi.tiangolo.com/advanced/events/): "If you provide a lifespan parameter, startup and shutdown event handlers will no longer be called" | 2026-10-18 |
|
|
38
|
+
| Cached `BaseSettings` | [Settings and Environment Variables](https://fastapi.tiangolo.com/advanced/settings/): with `@lru_cache` "the Settings object will be created only once", and a dependency override replaces it during testing | 2026-10-18 |
|
|
39
|
+
|
|
40
|
+
## Errors
|
|
41
|
+
|
|
42
|
+
| Bullet | Source | Read |
|
|
43
|
+
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
44
|
+
| Raise `HTTPException` | [Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/): "To return HTTP responses with errors to the client you use HTTPException" | 2026-10-18 |
|
|
45
|
+
| One exception handler | [Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/): "You could add a custom exception handler with @app.exception_handler()" | 2026-10-18 |
|
|
46
|
+
| Safe summaries only | House choice: an exception message or traceback in a response leaks internals such as SQL, file paths, and library versions to the caller | 2026-10-18 |
|
|
47
|
+
|
|
48
|
+
## Middleware
|
|
49
|
+
|
|
50
|
+
| Bullet | Source | Read |
|
|
51
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
52
|
+
| Explicit CORS origins | [CORS](https://fastapi.tiangolo.com/tutorial/cors/): "None of allow_origins, allow_methods and allow_headers can be set to ['*'] if allow_credentials is set to True" | 2026-10-18 |
|
|
53
|
+
|
|
54
|
+
## Declined
|
|
55
|
+
|
|
56
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
57
|
+
|
|
58
|
+
### Contradicted by the docs
|
|
59
|
+
|
|
60
|
+
- Reworded "define path operations as `async def` unless purely CPU-bound". The [async page](https://fastapi.tiangolo.com/async/) says "If you just don't know, use normal def", and CPU work in `async def` blocks the loop too.
|
|
61
|
+
- Cut "an `app_factory()` callable over a module-level `app` for testability". Every docs example uses a module-level `app` and tests through `app.dependency_overrides`, which the kept bullet names.
|
|
62
|
+
|
|
63
|
+
### Cut without a source or a bug class
|
|
64
|
+
|
|
65
|
+
- Cut "group routers by feature under `src/<pkg>/api/`" as a layout call, which the `codebase-layout` skill owns.
|
|
66
|
+
- Cut "annotate path, query, and body parameters, never `**kwargs`", since FastAPI cannot read `**kwargs` and Claude already annotates them.
|
|
67
|
+
- Cut "configure trusted hosts and HTTPS redirects through middleware" as a deployment choice with no page read taking a side.
|
|
68
|
+
|
|
69
|
+
### Merged or reworded
|
|
70
|
+
|
|
71
|
+
- Merged "mount routes through `APIRouter`, never directly on `FastAPI()`" into the router bullet.
|
|
72
|
+
- Reworded "return pydantic models and set `response_model=`" to name the filter, which is the footgun the [Response Model](https://fastapi.tiangolo.com/tutorial/response-model/) page warns about with passwords.
|
|
73
|
+
- Merged "express shared logic as `Depends(...)` over decorators or globals" into the `Annotated` bullet.
|
|
74
|
+
- Merged "do not perform blocking I/O inside `async def`" into the `async def` bullet.
|
|
75
|
+
- Narrowed "configure CORS through middleware, not per-route checks" to the credentials footgun the CORS page states.
|
|
76
|
+
- Moved "apply `dependencies=[Depends(auth)]` at the router or app level" to the routers section.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Next.js rule ledger
|
|
3
|
+
description: Sources for governance/rules/framework/nextjs.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Next.js rule ledger
|
|
7
|
+
|
|
8
|
+
The field is front-end engineering, and the authority is the Next.js documentation at nextjs.org, read against the App Router docs for Next.js 16. The rule loads on every `.ts` and `.tsx` file in a target, so the rewrite cut it from 352 words to under 250.
|
|
9
|
+
|
|
10
|
+
## Routing
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
14
|
+
| App Router, not `pages/` | House choice: a second router in one app splits layouts, data fetching, and caching across two models, so a change made in one never reaches routes in the other | 2026-10-18 |
|
|
15
|
+
| Await `params` | [route.js](https://nextjs.org/docs/app/api-reference/file-conventions/route): "`context.params` is now a promise" since v15, and every page example types `params: Promise<{ id: string }>` | 2026-10-18, Next.js 16 |
|
|
16
|
+
|
|
17
|
+
## Server and client components
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
21
|
+
| Server by default | [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components): "By default, layouts and pages are Server Components", with Client Components for state, event handlers, lifecycle logic, and browser-only APIs | 2026-10-18, Next.js 16 |
|
|
22
|
+
| `'use client'` at the leaf | [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components): "add 'use client' at the top of the files that define your interactive components instead of marking large parts of your UI as Client Components" | 2026-10-18, Next.js 16 |
|
|
23
|
+
| Serializable, minimal props | [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components): props "need to be serializable", and [Data Security](https://nextjs.org/docs/app/guides/data-security) marks passing a whole row as "EXPOSED" | 2026-10-18, Next.js 16 |
|
|
24
|
+
| `server-only` on secret modules | [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components): "To prevent accidental usage in Client Components, you can use the server-only package" | 2026-10-18, Next.js 16 |
|
|
25
|
+
|
|
26
|
+
## Data and caching
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
30
|
+
| `'use cache'` with `cacheLife` | [Fetching Data](https://nextjs.org/docs/app/getting-started/fetching-data): "fetch requests are not cached by default", and [Caching](https://nextjs.org/docs/app/getting-started/caching): "We recommend pairing every cache directive with a cacheLife" | 2026-10-18, Next.js 16 |
|
|
31
|
+
| `<Suspense>` around runtime data | [Caching](https://nextjs.org/docs/app/getting-started/caching): "Components that access runtime APIs should be wrapped in Suspense" | 2026-10-18, Next.js 16 |
|
|
32
|
+
| Revalidate after a mutation | [Mutating Data](https://nextjs.org/docs/app/getting-started/mutating-data): "you can revalidate the Next.js cache and show the updated data by calling revalidatePath or revalidateTag within the Server Function" | 2026-10-18, Next.js 16 |
|
|
33
|
+
|
|
34
|
+
## Mutations
|
|
35
|
+
|
|
36
|
+
| Bullet | Source | Read |
|
|
37
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
38
|
+
| Verify auth inside the action | [Mutating Data](https://nextjs.org/docs/app/getting-started/mutating-data): "Server Functions are reachable via direct POST requests, not just through your application's UI. Always verify authentication and authorization inside every Server Function." | 2026-10-18, Next.js 16 |
|
|
39
|
+
| Validate input, trim output | [Data Security](https://nextjs.org/docs/app/guides/data-security): "You should always validate input from client", and "Only return what the UI needs, not raw database records" | 2026-10-18, Next.js 16 |
|
|
40
|
+
|
|
41
|
+
## Built-in primitives
|
|
42
|
+
|
|
43
|
+
| Bullet | Source | Read |
|
|
44
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
45
|
+
| `next/link` and `next/image` | [Linking and Navigating](https://nextjs.org/docs/app/getting-started/linking-and-navigating): "Next.js automatically prefetches routes linked with the Link component", and a plain anchor gets "No prefetching" | 2026-10-18, Next.js 16 |
|
|
46
|
+
| Image dimensions or `fill` | [Image Component](https://nextjs.org/docs/app/api-reference/components/image): "If the source image is a dynamic or a remote URL, you must provide the width and height props", and with `fill` "the parent element must be positioned" | 2026-10-18, Next.js 16 |
|
|
47
|
+
|
|
48
|
+
## Environment
|
|
49
|
+
|
|
50
|
+
| Bullet | Source | Read |
|
|
51
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- |
|
|
52
|
+
| `NEXT_PUBLIC_` only when needed | [Environment Variables](https://nextjs.org/docs/app/guides/environment-variables): Next.js can "inline a value, at build time, into the js bundle that is delivered to the client", and the values are "frozen with the value evaluated at build time" | 2026-10-18, Next.js 16 |
|
|
53
|
+
|
|
54
|
+
## Declined
|
|
55
|
+
|
|
56
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
57
|
+
|
|
58
|
+
### Contradicted by the docs
|
|
59
|
+
|
|
60
|
+
- Replaced "set explicit caching on every `fetch`" with the `'use cache'` bullet. New apps run Cache Components, which [Caching](https://nextjs.org/docs/app/getting-started/caching) drives through the directive.
|
|
61
|
+
- Cut "return `NextResponse` over raw `Response`", since the [route.js](https://nextjs.org/docs/app/api-reference/file-conventions/route) reference returns the Web `Response` throughout.
|
|
62
|
+
- Cut "read params from the function signature, not the request URL" as stale. The signature form holds, and the kept bullet adds the `await` the current major requires.
|
|
63
|
+
- Cut "return no `Response` or stream from a Server Action". No page read forbids it, and the kept bullet states what the docs do say about return values.
|
|
64
|
+
|
|
65
|
+
### Cut without a source or a bug class
|
|
66
|
+
|
|
67
|
+
- Cut "use route segment files for their documented purpose" as a convention Claude already follows.
|
|
68
|
+
- Cut "place HTTP endpoints in `app/**/route.ts`, never `pages/api/`" as covered by the App Router bullet.
|
|
69
|
+
- Cut "export named HTTP methods" as enforced by the framework, which only routes the named exports.
|
|
70
|
+
- Cut "export `metadata` or `generateMetadata` over manual head tags" as a convention Claude already follows.
|
|
71
|
+
|
|
72
|
+
### Cut for the word budget
|
|
73
|
+
|
|
74
|
+
A sourced practice cut only because the rule loads on every TypeScript file. A later pass with room can bring it back.
|
|
75
|
+
|
|
76
|
+
- Cut "use `next/font` over manual link tags", which the docs still recommend.
|
|
77
|
+
|
|
78
|
+
### Merged or reworded
|
|
79
|
+
|
|
80
|
+
- Merged "do not fetch in client components when a server alternative exists" into the server-by-default bullet, since the docs list fetching among a Server Component's uses.
|
|
81
|
+
- Merged "do not introduce `pages/` in new code" into the App Router bullet.
|
|
82
|
+
- Merged "push the boundary as deep as possible" into the leaf bullet.
|
|
83
|
+
- Merged "mark Server Actions with `'use server'`", which the build requires, into the mutation bullets.
|
|
84
|
+
- Reworded "validate Server Action inputs with a Zod schema" to any validation, since [Data Security](https://nextjs.org/docs/app/guides/data-security) names no library.
|
|
85
|
+
- Reworded "use `revalidatePath` or `revalidateTag` over manual refetch loops" to the call the mutation page shows.
|
|
86
|
+
- Merged "never read unprefixed env vars in a client component" into the env bullet, since [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components) says "If variables are not prefixed, Next.js replaces them with an empty string".
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: React rule ledger
|
|
3
|
+
description: Sources for governance/rules/framework/react.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# React rule ledger
|
|
7
|
+
|
|
8
|
+
The field is front-end engineering, and the authority is the React team's documentation at react.dev. The rewrite started from groundwork spike S2's draft and reads its three unread leads.
|
|
9
|
+
|
|
10
|
+
## Rendering
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
|
|
14
|
+
| Pure during render | [Components and Hooks must be pure](https://react.dev/reference/rules/components-and-hooks-must-be-pure): side effects "should not run in render, as React can render components multiple times" | 2026-10-18, React 19 |
|
|
15
|
+
| Never mutate props or state | [Components and Hooks must be pure](https://react.dev/reference/rules/components-and-hooks-must-be-pure): "A component's props and state are immutable snapshots. Never mutate them directly." | 2026-10-18, React 19 |
|
|
16
|
+
| Stable data keys, not index | [Rendering lists](https://react.dev/learn/rendering-lists): "Index as a key often leads to subtle and confusing bugs" and "do not generate keys on the fly" | 2026-10-18, React 19 |
|
|
17
|
+
|
|
18
|
+
## State and effects
|
|
19
|
+
|
|
20
|
+
| Bullet | Source | Read |
|
|
21
|
+
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
22
|
+
| Derive during render | [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect): "When something can be calculated from the existing props or state, don't put it in state. Instead, calculate it during rendering." | 2026-10-18, React 19 |
|
|
23
|
+
| Reset with `key` | [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect): "To reset the state of an entire component tree, pass a different key to it." | 2026-10-18, React 19 |
|
|
24
|
+
| External store through `useSyncExternalStore` | [useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore): a browser value "can change without React's knowledge, so you should read it with useSyncExternalStore", and the server snapshot "must be the same between the client and the server" | 2026-10-18, React 19 |
|
|
25
|
+
| Fetching effect in a custom hook | [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect): a race "needs a cleanup function to ignore stale responses", and moving fetching "into a custom Hook will make it easier to adopt an efficient data fetching strategy later" | 2026-10-18, React 19 |
|
|
26
|
+
|
|
27
|
+
## Memoization
|
|
28
|
+
|
|
29
|
+
| Bullet | Source | Read |
|
|
30
|
+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
|
|
31
|
+
| Leave it to the compiler | [React Compiler introduction](https://react.dev/learn/react-compiler/introduction): "For new code, we recommend relying on the compiler for memoization and using useMemo/useCallback where needed to achieve precise control." | 2026-10-18, React Compiler 1 |
|
|
32
|
+
| Without it, memoize only by need | [useMemo](https://react.dev/reference/react/useMemo): worth it for a noticeably slow calculation, "say, 1ms or more", a prop to a `memo` child, or a Hook dependency, and "There is no benefit to wrapping a calculation in useMemo in other cases" | 2026-10-18, React 19 |
|
|
33
|
+
|
|
34
|
+
## Composition
|
|
35
|
+
|
|
36
|
+
| Bullet | Source | Read |
|
|
37
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
|
|
38
|
+
| Props, children, then context | [Passing data deeply with context](https://react.dev/learn/passing-data-deeply-with-context): "Start by passing props", then "Extract components and pass JSX as children", and "If neither of these approaches works well for you, consider context" | 2026-10-18, React 19 |
|
|
39
|
+
|
|
40
|
+
## Error and loading boundaries
|
|
41
|
+
|
|
42
|
+
| Bullet | Source | Read |
|
|
43
|
+
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
|
|
44
|
+
| Error boundaries where a message makes sense | [Component](https://react.dev/reference/react/Component): "consider where it makes sense to display an error message", around the conversation list and each message, and "You don't need to wrap every component" | 2026-10-18, React 19 |
|
|
45
|
+
| What activates Suspense | [Suspense](https://react.dev/reference/react/Suspense): "Suspense does not detect when data is fetched inside an Effect or event handler" | 2026-10-18, React 19 |
|
|
46
|
+
| Boundaries follow the loading sequence | [Suspense](https://react.dev/reference/react/Suspense): "Suspense boundaries should not be more granular than the loading sequence that you want the user to experience" | 2026-10-18, React 19 |
|
|
47
|
+
|
|
48
|
+
## Exports
|
|
49
|
+
|
|
50
|
+
| Bullet | Source | Read |
|
|
51
|
+
| ------------- | -------------------------------------------------------------------------------------------------------- | ---------- |
|
|
52
|
+
| Named exports | House choice: a default export renamed at import drifts from the component's name, so a search misses it | 2026-10-18 |
|
|
53
|
+
|
|
54
|
+
## Declined
|
|
55
|
+
|
|
56
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
57
|
+
|
|
58
|
+
### Contradicted by the docs
|
|
59
|
+
|
|
60
|
+
- Replaced "`useMemo` for derived state over `useEffect`" with the derive bullet. The effect page says "calculate it during rendering" and keeps `useMemo` for a slow calculation.
|
|
61
|
+
- Cut "memoize components receiving non-primitive props" as contradicted. [memo](https://react.dev/reference/react/memo) is "completely useless if the props passed to your component are always different, such as if you pass an object".
|
|
62
|
+
- Cut "memoize every handler passed to a child" as contradicted. [useCallback](https://react.dev/reference/react/useCallback) says "There is no benefit to wrapping a function in useCallback in other cases" than a `memo` child or a Hook dependency.
|
|
63
|
+
- Cut "no passing props past two levels" as contradicted, since the context page says "it's not unusual to pass a dozen props down through a dozen components".
|
|
64
|
+
|
|
65
|
+
### Cut without a source or a bug class
|
|
66
|
+
|
|
67
|
+
- Cut "domain logic in `src/features/`, shared UI in `src/components/`" as a layout call, which the `codebase-layout` skill owns.
|
|
68
|
+
- Cut "no feature components in the global components folder" as the same layout call.
|
|
69
|
+
- Cut "environment variables only from the validated config module", which is no React practice and which no react.dev page takes a side on.
|
|
70
|
+
- Cut "function declarations over arrow functions" as style with no bug class, and no react.dev page takes a side.
|
|
71
|
+
- Cut "props interface directly above the component" as style with no bug class.
|
|
72
|
+
- Cut "extract components when JSX exceeds one responsibility", which no reviewer can check against a line of code.
|
|
73
|
+
- Cut "compare the previous value and set state during render", since [You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect) says "most components shouldn't need it either" and ranks it after a key reset.
|
|
74
|
+
- Cut "use `<>` unless a key is needed" as a convention Claude already follows. [Rendering lists](https://react.dev/learn/rendering-lists) says the shorthand "won't let you pass a key".
|
|
75
|
+
|
|
76
|
+
### Merged or reworded
|
|
77
|
+
|
|
78
|
+
- Merged "no default exports" into the named-exports bullet, which states the same choice.
|
|
79
|
+
- Narrowed "custom hooks for all fetching and complex effects" to data fetching, since [Reusing logic with custom hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) says "you can (but don't have to) extract custom Hooks".
|
|
80
|
+
- Merged "no `setState` in an effect to sync derived state" into the derive bullet, the same ban. Only the `web` and `nextjs` oxlint configs error on `react/set-state-in-effect`.
|
|
81
|
+
- Reworded "a sentinel from asynchronously hydrating hooks" to `useSyncExternalStore` with a matching server snapshot, the API the reference names for a value React does not own.
|
|
82
|
+
- Reworded "error boundaries at route level", since the reference places a boundary by where a message makes sense rather than at a fixed level.
|
|
83
|
+
- Merged "no single root error boundary as the only net" into the placement bullet.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: shadcn/ui rule ledger
|
|
3
|
+
description: Sources for governance/rules/framework/shadcn.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# shadcn/ui rule ledger
|
|
7
|
+
|
|
8
|
+
The field is front-end engineering, and the authority is the shadcn/ui documentation and changelog at ui.shadcn.com. The rewrite reads the July 2026 changelog, which made Base UI the default primitive library.
|
|
9
|
+
|
|
10
|
+
## Source files
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Edit installed code in place | [Introduction](https://ui.shadcn.com/docs): "This is not a component library. It is how you build your component library", and "Modify any part of a component to fit your design and functionality requirements" | 2026-10-18 |
|
|
15
|
+
| Diff before overwrite | [CLI](https://ui.shadcn.com/docs/cli): `add --overwrite` will "overwrite existing files", and `--diff` will "show diff for a file" | 2026-10-18 |
|
|
16
|
+
| Import through the aliases | [components.json](https://ui.shadcn.com/docs/components-json): "The CLI uses these values to place generated components in the correct location and rewrite imports" | 2026-10-18 |
|
|
17
|
+
|
|
18
|
+
## Component authoring
|
|
19
|
+
|
|
20
|
+
| Bullet | Source | Read |
|
|
21
|
+
| ------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
|
22
|
+
| `ComponentProps` typing | [Tailwind v4](https://ui.shadcn.com/docs/tailwind-v4): "Replace React.forwardRef<...> with React.ComponentProps<...>" | 2026-10-18, React 19 |
|
|
23
|
+
| `data-slot` on primitives | [Tailwind v4](https://ui.shadcn.com/docs/tailwind-v4): "Every primitive now has a data-slot attribute for styling" | 2026-10-18, Tailwind CSS 4 |
|
|
24
|
+
|
|
25
|
+
## Tokens and styling
|
|
26
|
+
|
|
27
|
+
| Bullet | Source | Read |
|
|
28
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
29
|
+
| Semantic tokens | [Theming](https://ui.shadcn.com/docs/theming): "We use semantic background and foreground pairs", mapped "into utilities like bg-background, text-foreground, border-border, and ring-ring" | 2026-10-18 |
|
|
30
|
+
| `cn()` merging | [Manual installation](https://ui.shadcn.com/docs/installation/manual): re-export `cn` "from lib/utils.ts so your own code has a single place to import helpers from" | 2026-10-18 |
|
|
31
|
+
|
|
32
|
+
## Composition
|
|
33
|
+
|
|
34
|
+
| Bullet | Source | Read |
|
|
35
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
36
|
+
| `render` or `asChild` | [Base UI as the default](https://ui.shadcn.com/docs/changelog/2026-07-base-ui-default): "New projects now use Base UI by default", "Radix is not being deprecated", and "asChild is now render" | 2026-10-18 |
|
|
37
|
+
| `buttonVariants()` for links | [Button](https://ui.shadcn.com/docs/components/button): "The Base UI Button component always applies role="button", which overrides the semantic link role on a elements" | 2026-10-18 |
|
|
38
|
+
| `sonner` for toasts | [Tailwind v4](https://ui.shadcn.com/docs/tailwind-v4): "We're deprecating the toast component in favor of sonner" | 2026-10-18 |
|
|
39
|
+
|
|
40
|
+
## Declined
|
|
41
|
+
|
|
42
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
43
|
+
|
|
44
|
+
### Contradicted by the docs
|
|
45
|
+
|
|
46
|
+
- Replaced "do not edit installed component files, treat them as vendored". The [introduction](https://ui.shadcn.com/docs) says "The top layer of your component code is open for modification".
|
|
47
|
+
- Cut "extend behavior via wrapper components over modifying installed files" for the same reason.
|
|
48
|
+
- Cut "do not override component internals with arbitrary classes, extend via `className` only". Editing the variants in the owned file is what the docs describe.
|
|
49
|
+
- Reworded "use `asChild` with `<Slot>` for polymorphic rendering", since Base UI projects use `render` and the scoped and open searches agreed on that split.
|
|
50
|
+
|
|
51
|
+
### Cut without a source or a bug class
|
|
52
|
+
|
|
53
|
+
- Cut "compose shadcn primitives as documented", which no reviewer can check against a line of code.
|
|
54
|
+
- Cut "do not destructure or restructure internal component trees" for the same reason.
|
|
55
|
+
- Cut "do not wrap primitives in extra DOM elements" as a style call with no page read taking a side.
|
|
56
|
+
|
|
57
|
+
### Merged or reworded
|
|
58
|
+
|
|
59
|
+
- Reworded "check `components.json` for the install path" to the aliases bullet, which names what the file controls.
|
|
60
|
+
- Reworded "use `cn()` for all className merging" to the override it guarantees.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tailwind CSS rule ledger
|
|
3
|
+
description: Sources for governance/rules/framework/tailwind.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tailwind CSS rule ledger
|
|
7
|
+
|
|
8
|
+
The field is front-end engineering, and the authority is the Tailwind CSS documentation at tailwindcss.com, read for Tailwind CSS 4.
|
|
9
|
+
|
|
10
|
+
## Theme variables
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
|
14
|
+
| `@theme` or `:root` | [Theme variables](https://tailwindcss.com/docs/theme): "use :root for defining regular CSS variables that shouldn't have corresponding utility classes", and theme variables must be "defined top-level and not nested" | 2026-10-18, Tailwind CSS 4 |
|
|
15
|
+
| Custom dark variant for a class | [Dark mode](https://tailwindcss.com/docs/dark-mode): "By default this uses the prefers-color-scheme CSS media feature", and a selector-driven theme overrides it with `@custom-variant dark` | 2026-10-18, Tailwind CSS 4 |
|
|
16
|
+
|
|
17
|
+
## Layout and spacing
|
|
18
|
+
|
|
19
|
+
| Bullet | Source | Read |
|
|
20
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
|
|
21
|
+
| `flex` or `grid` for flow | House choice: a floated or absolutely positioned element leaves the document flow, so its siblings overlap or collapse once the viewport width changes | 2026-10-18 |
|
|
22
|
+
| `gap-*` over child margins | House choice: a margin on each child leaves a stray edge when the last item wraps or a conditional item is hidden, which `gap` never does | 2026-10-18 |
|
|
23
|
+
| `size-*` for equal sides | [Width](https://tailwindcss.com/docs/width): "Use utilities like size-px, size-4, and size-full to set both the width and height of an element at the same time" | 2026-10-18, Tailwind CSS 4 |
|
|
24
|
+
| Mobile first | [Responsive design](https://tailwindcss.com/docs/responsive-design): "unprefixed utilities take effect on all screen sizes", and "Don't think of sm: as meaning on small screens" | 2026-10-18, Tailwind CSS 4 |
|
|
25
|
+
|
|
26
|
+
## Class application
|
|
27
|
+
|
|
28
|
+
| Bullet | Source | Read |
|
|
29
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
|
|
30
|
+
| Complete class names | [Detecting classes in source files](https://tailwindcss.com/docs/detecting-classes-in-source-files): Tailwind "has no way of understanding string concatenation or interpolation", so "map props to complete class names" | 2026-10-18, Tailwind CSS 4 |
|
|
31
|
+
| No conflicting utilities | [Styling with utility classes](https://tailwindcss.com/docs/styling-with-utility-classes): "you should just never add two conflicting classes to the same element" | 2026-10-18, Tailwind CSS 4 |
|
|
32
|
+
| `!` only as a last resort | [Styling with utility classes](https://tailwindcss.com/docs/styling-with-utility-classes): "When you really need to force a specific utility class to take effect and have no other means of managing the specificity, you can add ! to the end" | 2026-10-18, Tailwind CSS 4 |
|
|
33
|
+
| Arbitrary values for one-offs | [Styling with utility classes](https://tailwindcss.com/docs/styling-with-utility-classes): "When you need to use a one-off value outside of your theme, use the special square bracket syntax" | 2026-10-18, Tailwind CSS 4 |
|
|
34
|
+
| Inline style for dynamic values | [Styling with utility classes](https://tailwindcss.com/docs/styling-with-utility-classes): inline styles are useful "when a value is coming from a dynamic source like a database or API", and for "setting CSS variables" | 2026-10-18, Tailwind CSS 4 |
|
|
35
|
+
|
|
36
|
+
## Declined
|
|
37
|
+
|
|
38
|
+
Every bullet the rewrite removed or reshaped, grouped by why.
|
|
39
|
+
|
|
40
|
+
### Contradicted by the docs
|
|
41
|
+
|
|
42
|
+
- Reworded "do not use the `!` important modifier", since the [utility classes](https://tailwindcss.com/docs/styling-with-utility-classes) page documents the trailing `!` for the case nothing else resolves.
|
|
43
|
+
|
|
44
|
+
### Cut without a source or a bug class
|
|
45
|
+
|
|
46
|
+
- Cut "always pair light and dark utilities explicitly". No page read requires it, and a color token redefined for dark mode switches with no `dark:` pair at all.
|
|
47
|
+
- Cut "define dark mode color overrides in `.dark { }` at root level over `@layer base`", which no Tailwind page read takes a side on.
|
|
48
|
+
- Cut "use `cn()` from `@/lib/utils` for all conditional class application" as the import convention the shadcn rule already owns. The kept conflict bullet names `cn()` for the override case.
|
|
49
|
+
|
|
50
|
+
### Merged or reworded
|
|
51
|
+
|
|
52
|
+
- Merged "use `flex` and `grid` for all layouts" and "never use floats or absolute positioning for flow" into one bullet naming the bug class.
|
|
53
|
+
- Reworded "use `size-*` over `w-* h-*`" to the matching pair it replaces.
|
|
54
|
+
- Reworded "mobile-first, default styles apply to mobile" to the `sm:` misreading the responsive page warns about.
|
|
55
|
+
- Added "write every class name in full", the footgun the source detection page names and the old rule missed.
|
|
@@ -8,6 +8,7 @@ paths:
|
|
|
8
8
|
|
|
9
9
|
## Context entries
|
|
10
10
|
|
|
11
|
-
- Load the `canon:context-fold` skill before a hand edit under `canon/context
|
|
11
|
+
- Load the `canon:context-fold` skill before a hand edit under `canon/context/`, since it carries the entry shape and the content rules for a domain entry.
|
|
12
|
+
- Report it rather than proceeding silently when `canon:context-fold` does not resolve.
|
|
12
13
|
- Before non-trivial work in a domain, read its `canon/context/<domain>/` entry. Use `canon/context/index.md` to find it.
|
|
13
14
|
- Leave the entry conforming when work in its domain changes what it describes.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Route edits under .canon/plans/ to the plan-feature skill
|
|
2
|
+
description: Route edits under .canon/plans/ to the plan-feature skill, and keep the five hand-edit floors a plan breaks silently
|
|
3
3
|
paths:
|
|
4
4
|
- '.canon/plans/**'
|
|
5
5
|
---
|
|
@@ -8,11 +8,9 @@ paths:
|
|
|
8
8
|
|
|
9
9
|
## Plan files
|
|
10
10
|
|
|
11
|
-
- Load the `canon:plan-feature` skill before a hand edit under `.canon/plans
|
|
11
|
+
- Load the `canon:plan-feature` skill before a hand edit under `.canon/plans/`, whose references own its shape and lifecycle. Report it rather than proceeding silently when it does not resolve.
|
|
12
12
|
- Never fill an `- Answer:` slot on behalf of the person who owns it. A blank slot accepts the suggestion at execution time.
|
|
13
|
-
-
|
|
14
|
-
- Rewrite the `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when execution deviates from an unanswered question, leaving the slot blank. Put the same deviation in one line under the open task's `## Findings`.
|
|
13
|
+
- Rewrite an unanswered question's `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when execution deviates, leaving the slot blank.
|
|
15
14
|
- Fetch the source a decision rests on and quote the passage under `**Sources:**`, or mark the entry `unverified`. Never cite an outside source from recall.
|
|
16
15
|
- Move a shipped plan to `.canon/plans/archive/`. Never delete one.
|
|
17
16
|
- Amend a plan in place when a decision changes. Do not append a second passage narrating the change.
|
|
18
|
-
- Follow the lifecycle the `canon:plan-feature` skill carries for when a plan is written, how it is amended, and its move to the archive.
|
|
@@ -6,4 +6,6 @@ description: Write temporary files to the scratch folder structure
|
|
|
6
6
|
|
|
7
7
|
## Temporary files
|
|
8
8
|
|
|
9
|
-
- Write temporary files to `.canon/tmp/<slug>/<file>.md` at the current worktree's root,
|
|
9
|
+
- Write temporary files to `.canon/tmp/<slug>/<file>.md` at the current worktree's root, with a kebab-slug tied to the topic rather than a flat `<slug>-<file>.md`.
|
|
10
|
+
- Never take one of the reserved slugs `runs`, `hooks`, `handoff`, `pr`, and `render`.
|
|
11
|
+
- Write scratch at the main root instead only when a skill's own body says so.
|
|
@@ -8,4 +8,5 @@ description: Scope, size, and link a task file correctly
|
|
|
8
8
|
|
|
9
9
|
- Only create a task for work that spans multiple sessions or has real dependencies. Handle small edits immediately without a task entry.
|
|
10
10
|
- Do not add tasks retroactively for work already completed. Completed work is visible in git.
|
|
11
|
-
-
|
|
11
|
+
- Write a plan in `.canon/plans/` when a task needs execution detail beyond its own file, and link it from the task's intro paragraph.
|
|
12
|
+
- Write that plan in the same session as the task, since the executing session would otherwise re-derive the reasoning behind it.
|
|
@@ -8,7 +8,8 @@ paths:
|
|
|
8
8
|
|
|
9
9
|
## Task files
|
|
10
10
|
|
|
11
|
-
- Load the `canon:task-board` skill before a hand edit under `.canon/tasks
|
|
11
|
+
- Load the `canon:task-board` skill before a hand edit under `.canon/tasks/`, since it carries the layout, filenames, format, origin lines, and archiving of a task file.
|
|
12
|
+
- Report it rather than proceeding silently when `canon:task-board` does not resolve.
|
|
12
13
|
- Follow the board shape the `canon:task-board` skill carries for `priority.md` and `backlog.md`, their readiness groups, and row order.
|
|
13
14
|
- Never hand-edit `.canon/tasks/index.md`. A hook regenerates it from sibling frontmatter.
|
|
14
15
|
- Follow the decline shape the `canon:task-board` skill carries for a task decided against.
|
|
@@ -10,5 +10,8 @@ description: Enter a linked worktree for implementation, resolve shared session
|
|
|
10
10
|
|
|
11
11
|
## Shared session scratch
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- Resolve shared session scratch (`.canon/plans/`, `.canon/review/`, `.canon/tasks/`) at the main worktree root, never inside a linked worktree.
|
|
14
|
+
- Read the main root from `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, and fall back to `pwd` outside a git repo.
|
|
15
|
+
- Never take the worktree copy `Edit` and `Write` redirect a main-root path to, since no later session reads it. Revisit when Edit and Write stop redirecting a main-root path from a linked worktree.
|
|
16
|
+
- Route a main-root write from a linked worktree, or from a background session that entered none, the way the `session-worktree` skill states.
|
|
17
|
+
- Report it rather than proceeding silently when `session-worktree` does not resolve, as in a project that installed governance without the plugin.
|
|
@@ -7,10 +7,13 @@ description: Report file paths correctly for the reading surface and group them
|
|
|
7
7
|
## Reporting paths
|
|
8
8
|
|
|
9
9
|
- After creating or modifying a file, include its path on its own line so the reader can open it. Do not paraphrase paths into prose ("the seeds folder", "your CLAUDE.md").
|
|
10
|
-
- Emit a path in the form the surface's own instructions give, such as a markdown link where the harness asks for one, and bare where it gives none.
|
|
11
|
-
-
|
|
12
|
-
-
|
|
10
|
+
- Emit a path in the form the surface's own instructions give, such as a markdown link where the harness asks for one, and bare where it gives none.
|
|
11
|
+
- Never add link markup where the surface gives no form, since a terminal makes a bare path clickable through its own path detection and the markup defeats it.
|
|
12
|
+
- Backtick a path written into a markdown file and never repeat it as a link label, per the markdown standard. The response form above governs a response alone.
|
|
13
|
+
- Emit the absolute path from a linked worktree (under `.claude/worktrees/<name>/`), since the editor is rooted at the main root, where a worktree-relative path resolves nowhere.
|
|
14
|
+
- Prefer the form a `PostToolUse` hook hands back after a write where one is installed.
|
|
13
15
|
|
|
14
16
|
## Grouping multiple files
|
|
15
17
|
|
|
16
|
-
-
|
|
18
|
+
- Group paths under `**Created:**`, `**Modified:**`, and `**Deleted:**` headers when the response covers multiple files, with every path under them in that form.
|
|
19
|
+
- Put a single-file change's path on its own line, with no header.
|
|
@@ -11,7 +11,9 @@ paths:
|
|
|
11
11
|
|
|
12
12
|
## Skill files
|
|
13
13
|
|
|
14
|
-
- Load the `canon:create-skill` skill before a hand edit to a `SKILL.md` or a `REQUIREMENT.md
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
14
|
+
- Load the `canon:create-skill` skill before a hand edit to a `SKILL.md` or a `REQUIREMENT.md`, since it carries the skill structure, the requirement shape, and the path rules.
|
|
15
|
+
- Report it rather than proceeding silently when `canon:create-skill` does not resolve, as in a project that installed governance without the plugin.
|
|
16
|
+
- Confirm `canon:create-skill`'s two creation-time questions are answered before a new `SKILL.md` lands, whoever drafted it, `canon:create-skill` included.
|
|
17
|
+
- Carry its third question into the sibling `REQUIREMENT.md`'s `Must not` section as a review criterion rather than a gate.
|
|
18
|
+
- Re-read a skill body this session edited before invoking that skill again in the same session. Revisit when Claude Code reloads a skill body edited after the session first invoked it.
|
|
19
|
+
- Do not read a resolved file path in a held body as evidence the body is current. Revisit when Claude Code marks a held skill body stale once its source changes.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enforce
|
|
2
|
+
description: Enforce Astro static-first rendering, explicit island hydration, content collections, and asset placement
|
|
3
3
|
paths:
|
|
4
4
|
- '**/*.astro'
|
|
5
5
|
- 'src/pages/**'
|
|
@@ -11,31 +11,29 @@ paths:
|
|
|
11
11
|
|
|
12
12
|
## Static first
|
|
13
13
|
|
|
14
|
-
- Write
|
|
15
|
-
-
|
|
16
|
-
- Prefer server-rendered content over client-fetched data.
|
|
14
|
+
- Write a component as `.astro` when it has no client-side state or event handlers, since it renders to HTML with no client JS.
|
|
15
|
+
- Fetch page data in the component frontmatter, which runs at build or request time, not in a client island.
|
|
17
16
|
|
|
18
17
|
## Islands
|
|
19
18
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- Keep islands leaf-level. Do not wrap layout chrome in a framework component to enable nested islands.
|
|
19
|
+
- Put a `client:*` directive on the framework component itself, imported directly into a `.astro` file.
|
|
20
|
+
- Use `client:visible` for a component below the fold and `client:idle` for a low-priority one. Keep `client:load` for interactive UI above the fold.
|
|
23
21
|
|
|
24
22
|
## Routing and layouts
|
|
25
23
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
24
|
+
- Give a dynamic `[param].astro` route a `getStaticPaths()` in static output, which builds only the paths it returns.
|
|
25
|
+
- Wrap pages in a layout from `src/layouts/` that renders the page through `<slot />`.
|
|
28
26
|
|
|
29
27
|
## Content
|
|
30
28
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
29
|
+
- Define collections in `content.config.ts` at the root of `src/`, each with a `glob()` or `file()` loader and a Zod schema.
|
|
30
|
+
- Read entries through `getCollection()` and `getEntry()`, never by importing content files directly.
|
|
33
31
|
|
|
34
32
|
## Styles and assets
|
|
35
33
|
|
|
36
|
-
-
|
|
37
|
-
-
|
|
34
|
+
- Keep component styles scoped. Use `is:global` or `:global()` only for a reset or base style in a layout.
|
|
35
|
+
- Keep local images in `src/` so Astro optimizes them. Use `public/` only for files served as-is.
|
|
38
36
|
|
|
39
37
|
## Environment
|
|
40
38
|
|
|
41
|
-
- Read
|
|
39
|
+
- Read variables through `astro:env` with a schema, or `import.meta.env`, and prefix client-exposed ones with `PUBLIC_`.
|