create-rigel 0.1.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/LICENSE +21 -0
- package/README.md +156 -0
- package/cli.js +122 -0
- package/package.json +47 -0
- package/templates/express/.claude/CLAUDE.md +114 -0
- package/templates/express/.claude/agents/arch-validator.md +85 -0
- package/templates/express/.claude/agents/db-optimizer.md +72 -0
- package/templates/express/.claude/agents/doc-gardener.md +67 -0
- package/templates/express/.claude/agents/garbage-collector.md +94 -0
- package/templates/express/.claude/agents/gate-checker.md +176 -0
- package/templates/express/.claude/agents/reviewer.md +84 -0
- package/templates/express/.claude/agents/security-auditor.md +82 -0
- package/templates/express/.claude/hooks/post-write.sh +93 -0
- package/templates/express/.claude/rules/api.md +149 -0
- package/templates/express/.claude/rules/architecture.md +78 -0
- package/templates/express/.claude/rules/database.md +104 -0
- package/templates/express/.claude/rules/jobs.md +81 -0
- package/templates/express/.claude/rules/security.md +92 -0
- package/templates/express/.claude/rules/testing.md +97 -0
- package/templates/express/.claude/settings.json +35 -0
- package/templates/express/.claude/skills/00-infra-setup/SKILL.md +479 -0
- package/templates/express/.claude/skills/01-write-roadmap/SKILL.md +72 -0
- package/templates/express/.claude/skills/02-write-spec/SKILL.md +119 -0
- package/templates/express/.claude/skills/03-write-plan/SKILL.md +124 -0
- package/templates/express/.claude/skills/04-build-layer/SKILL.md +216 -0
- package/templates/express/.claude/skills/05-validate-layer/SKILL.md +43 -0
- package/templates/express/.claude/skills/06-push-layer/SKILL.md +59 -0
- package/templates/express/.claude/skills/07-layer-check/SKILL.md +62 -0
- package/templates/express/.claude/skills/08-garbage-collect/SKILL.md +86 -0
- package/templates/express/.claude/skills/09-doc-garden/SKILL.md +64 -0
- package/templates/express/.claude/skills/10-db-optimize/SKILL.md +96 -0
- package/templates/express/.claude/skills/11-load-test/SKILL.md +77 -0
- package/templates/express/.dockerignore +43 -0
- package/templates/express/.env.example +42 -0
- package/templates/express/.github/CODEOWNERS +22 -0
- package/templates/express/.github/dependabot.yml +48 -0
- package/templates/express/.github/pull_request_template.md +58 -0
- package/templates/express/.github/workflows/ci.yml +278 -0
- package/templates/express/.github/workflows/load-test.yml +41 -0
- package/templates/express/.gitleaks.toml +18 -0
- package/templates/express/.lintstagedrc.json +3 -0
- package/templates/express/.nvmrc +1 -0
- package/templates/express/.prettierrc +8 -0
- package/templates/express/.sequelizerc +8 -0
- package/templates/express/AGENTS.md +94 -0
- package/templates/express/ARCHITECTURE.md +161 -0
- package/templates/express/Dockerfile +40 -0
- package/templates/express/Makefile +79 -0
- package/templates/express/QUICKSTART.md +131 -0
- package/templates/express/docker-compose.yml +114 -0
- package/templates/express/docs/PLANS.md +111 -0
- package/templates/express/docs/QUALITY_SCORE.md +66 -0
- package/templates/express/docs/design-docs/core-beliefs.md +89 -0
- package/templates/express/docs/design-docs/decisions/ADR-000-infrastructure.md +70 -0
- package/templates/express/docs/design-docs/decisions/ADR-001-observability.md +82 -0
- package/templates/express/docs/design-docs/decisions/index.md +23 -0
- package/templates/express/docs/design-docs/index.md +11 -0
- package/templates/express/docs/design-docs/observability.md +194 -0
- package/templates/express/docs/design-docs/team-workflow.md +64 -0
- package/templates/express/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/express/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/express/docs/exec-plans/tech-debt-tracker.md +31 -0
- package/templates/express/docs/generated/.gitkeep +0 -0
- package/templates/express/docs/product-specs/ROADMAP.md +49 -0
- package/templates/express/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/express/docs/product-specs/index.md +21 -0
- package/templates/express/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/express/eslint.config.mjs +94 -0
- package/templates/express/gitignore +36 -0
- package/templates/express/infra/monitoring/alloy/config.alloy +59 -0
- package/templates/express/jest.config.ts +61 -0
- package/templates/express/package.json +45 -0
- package/templates/express/scripts/openapi.export.ts +77 -0
- package/templates/express/tests/architecture/isolation.test.ts +51 -0
- package/templates/express/tests/architecture/layers.test.ts +83 -0
- package/templates/express/tests/integration/health.test.ts +40 -0
- package/templates/express/tests/integration/isolation.test.template.ts +88 -0
- package/templates/express/tests/load/smoke.js +46 -0
- package/templates/express/tests/load/soak.js +45 -0
- package/templates/express/tests/load/stress.js +44 -0
- package/templates/express/tests/unit/utils/response.util.test.ts +53 -0
- package/templates/express/tsconfig.build.json +8 -0
- package/templates/express/tsconfig.json +20 -0
- package/templates/fastapi/.claude/CLAUDE.md +122 -0
- package/templates/fastapi/.claude/agents/arch-validator.md +64 -0
- package/templates/fastapi/.claude/agents/db-optimizer.md +59 -0
- package/templates/fastapi/.claude/agents/doc-gardener.md +55 -0
- package/templates/fastapi/.claude/agents/garbage-collector.md +74 -0
- package/templates/fastapi/.claude/agents/gate-checker.md +133 -0
- package/templates/fastapi/.claude/agents/reviewer.md +74 -0
- package/templates/fastapi/.claude/agents/security-auditor.md +69 -0
- package/templates/fastapi/.claude/hooks/post-write.sh +65 -0
- package/templates/fastapi/.claude/rules/api.md +119 -0
- package/templates/fastapi/.claude/rules/architecture.md +84 -0
- package/templates/fastapi/.claude/rules/database.md +153 -0
- package/templates/fastapi/.claude/rules/jobs.md +85 -0
- package/templates/fastapi/.claude/rules/security.md +102 -0
- package/templates/fastapi/.claude/rules/testing.md +207 -0
- package/templates/fastapi/.claude/settings.json +50 -0
- package/templates/fastapi/.claude/skills/00-infra-setup/SKILL.md +311 -0
- package/templates/fastapi/.claude/skills/01-write-roadmap/SKILL.md +61 -0
- package/templates/fastapi/.claude/skills/02-write-spec/SKILL.md +82 -0
- package/templates/fastapi/.claude/skills/03-write-plan/SKILL.md +83 -0
- package/templates/fastapi/.claude/skills/04-build-layer/SKILL.md +170 -0
- package/templates/fastapi/.claude/skills/05-validate-layer/SKILL.md +20 -0
- package/templates/fastapi/.claude/skills/06-push-layer/SKILL.md +31 -0
- package/templates/fastapi/.claude/skills/07-layer-check/SKILL.md +51 -0
- package/templates/fastapi/.claude/skills/08-garbage-collect/SKILL.md +47 -0
- package/templates/fastapi/.claude/skills/09-doc-garden/SKILL.md +9 -0
- package/templates/fastapi/.claude/skills/10-db-optimize/SKILL.md +53 -0
- package/templates/fastapi/.claude/skills/11-load-test/SKILL.md +81 -0
- package/templates/fastapi/.dockerignore +30 -0
- package/templates/fastapi/.github/dependabot.yml +24 -0
- package/templates/fastapi/AGENTS.md +87 -0
- package/templates/fastapi/ARCHITECTURE.md +141 -0
- package/templates/fastapi/Makefile +42 -0
- package/templates/fastapi/README.md +179 -0
- package/templates/fastapi/docs/PLANS.md +26 -0
- package/templates/fastapi/docs/QUALITY_SCORE.md +26 -0
- package/templates/fastapi/docs/design-docs/core-beliefs.md +46 -0
- package/templates/fastapi/docs/design-docs/decisions/ADR-000-infrastructure.md +79 -0
- package/templates/fastapi/docs/design-docs/decisions/index.md +7 -0
- package/templates/fastapi/docs/design-docs/index.md +9 -0
- package/templates/fastapi/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/fastapi/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/fastapi/docs/exec-plans/tech-debt-tracker.md +19 -0
- package/templates/fastapi/docs/generated/.gitkeep +0 -0
- package/templates/fastapi/docs/product-specs/ROADMAP.md +49 -0
- package/templates/fastapi/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/fastapi/docs/product-specs/index.md +18 -0
- package/templates/fastapi/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/fastapi/gitignore +46 -0
- package/templates/fastapi/scripts/gate.sh +68 -0
- package/templates/nestjs/.claude/CLAUDE.md +121 -0
- package/templates/nestjs/.claude/agents/db-optimizer.md +51 -0
- package/templates/nestjs/.claude/agents/doc-gardener.md +45 -0
- package/templates/nestjs/.claude/agents/garbage-collector.md +50 -0
- package/templates/nestjs/.claude/agents/gate-checker.md +127 -0
- package/templates/nestjs/.claude/agents/reviewer.md +68 -0
- package/templates/nestjs/.claude/agents/security-auditor.md +72 -0
- package/templates/nestjs/.claude/hooks/post-write.sh +91 -0
- package/templates/nestjs/.claude/rules/api.md +87 -0
- package/templates/nestjs/.claude/rules/architecture.md +104 -0
- package/templates/nestjs/.claude/rules/database.md +111 -0
- package/templates/nestjs/.claude/rules/security.md +110 -0
- package/templates/nestjs/.claude/rules/testing.md +145 -0
- package/templates/nestjs/.claude/settings.json +33 -0
- package/templates/nestjs/.claude/skills/00-infra-setup/SKILL.md +222 -0
- package/templates/nestjs/.claude/skills/01-write-spec/SKILL.md +25 -0
- package/templates/nestjs/.claude/skills/02-write-plan/SKILL.md +18 -0
- package/templates/nestjs/.claude/skills/03-build-layer/SKILL.md +242 -0
- package/templates/nestjs/.claude/skills/04-validate-layer/SKILL.md +4 -0
- package/templates/nestjs/.claude/skills/05-push-layer/SKILL.md +6 -0
- package/templates/nestjs/.claude/skills/06-layer-check/SKILL.md +12 -0
- package/templates/nestjs/.claude/skills/07-garbage-collect/SKILL.md +2 -0
- package/templates/nestjs/.claude/skills/08-doc-garden/SKILL.md +4 -0
- package/templates/nestjs/.claude/skills/09-api-sync/SKILL.md +36 -0
- package/templates/nestjs/.claude/skills/10-load-test/SKILL.md +29 -0
- package/templates/nestjs/.env.example +11 -0
- package/templates/nestjs/AGENTS.md +88 -0
- package/templates/nestjs/ARCHITECTURE.md +192 -0
- package/templates/nestjs/docs/PLANS.md +22 -0
- package/templates/nestjs/docs/QUALITY_SCORE.md +27 -0
- package/templates/nestjs/docs/design-docs/core-beliefs.md +18 -0
- package/templates/nestjs/docs/design-docs/decisions/ADR-000-infrastructure.md +58 -0
- package/templates/nestjs/docs/design-docs/decisions/index.md +7 -0
- package/templates/nestjs/docs/design-docs/index.md +7 -0
- package/templates/nestjs/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/nestjs/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/nestjs/docs/exec-plans/tech-debt-tracker.md +16 -0
- package/templates/nestjs/docs/generated/.gitkeep +0 -0
- package/templates/nestjs/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/nestjs/docs/product-specs/index.md +7 -0
- package/templates/nestjs/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/nestjs/gitignore +8 -0
- package/templates/nextjs/.claude/CLAUDE.md +139 -0
- package/templates/nextjs/.claude/agents/arch-validator.md +66 -0
- package/templates/nextjs/.claude/agents/contract-checker.md +78 -0
- package/templates/nextjs/.claude/agents/doc-gardener.md +52 -0
- package/templates/nextjs/.claude/agents/garbage-collector.md +61 -0
- package/templates/nextjs/.claude/agents/gate-checker.md +129 -0
- package/templates/nextjs/.claude/agents/perf-auditor.md +109 -0
- package/templates/nextjs/.claude/agents/reviewer.md +79 -0
- package/templates/nextjs/.claude/agents/security-auditor.md +50 -0
- package/templates/nextjs/.claude/hooks/post-write.sh +121 -0
- package/templates/nextjs/.claude/rules/api-contract.md +166 -0
- package/templates/nextjs/.claude/rules/architecture.md +99 -0
- package/templates/nextjs/.claude/rules/components.md +122 -0
- package/templates/nextjs/.claude/rules/security.md +122 -0
- package/templates/nextjs/.claude/rules/testing.md +187 -0
- package/templates/nextjs/.claude/scripts/infra-setup.sh +550 -0
- package/templates/nextjs/.claude/settings.json +33 -0
- package/templates/nextjs/.claude/skills/00-infra-setup/SKILL.md +471 -0
- package/templates/nextjs/.claude/skills/01-write-roadmap/SKILL.md +77 -0
- package/templates/nextjs/.claude/skills/02-write-spec/SKILL.md +78 -0
- package/templates/nextjs/.claude/skills/03-write-plan/SKILL.md +91 -0
- package/templates/nextjs/.claude/skills/04-build-layer/SKILL.md +141 -0
- package/templates/nextjs/.claude/skills/05-validate-layer/SKILL.md +13 -0
- package/templates/nextjs/.claude/skills/06-push-layer/SKILL.md +20 -0
- package/templates/nextjs/.claude/skills/07-layer-check/SKILL.md +28 -0
- package/templates/nextjs/.claude/skills/08-garbage-collect/SKILL.md +14 -0
- package/templates/nextjs/.claude/skills/09-doc-garden/SKILL.md +12 -0
- package/templates/nextjs/.claude/skills/10-api-sync/SKILL.md +50 -0
- package/templates/nextjs/.claude/skills/11-perf-budget/SKILL.md +51 -0
- package/templates/nextjs/.dockerignore +25 -0
- package/templates/nextjs/.gitattributes +10 -0
- package/templates/nextjs/.github/CODEOWNERS +24 -0
- package/templates/nextjs/.github/dependabot.yml +31 -0
- package/templates/nextjs/.github/pull_request_template.md +59 -0
- package/templates/nextjs/.github/workflows/ci.yml +143 -0
- package/templates/nextjs/.github/workflows/lighthouse.yml +54 -0
- package/templates/nextjs/.github/workflows/load-test.yml +54 -0
- package/templates/nextjs/.husky/pre-commit +1 -0
- package/templates/nextjs/.lintstagedrc.json +4 -0
- package/templates/nextjs/.mcp.json +8 -0
- package/templates/nextjs/.prettierignore +13 -0
- package/templates/nextjs/.prettierrc +9 -0
- package/templates/nextjs/AGENTS.md +88 -0
- package/templates/nextjs/ARCHITECTURE.md +165 -0
- package/templates/nextjs/Dockerfile +38 -0
- package/templates/nextjs/Makefile +50 -0
- package/templates/nextjs/QUICKSTART.md +128 -0
- package/templates/nextjs/docs/PLANS.md +23 -0
- package/templates/nextjs/docs/QUALITY_SCORE.md +27 -0
- package/templates/nextjs/docs/design-docs/core-beliefs.md +43 -0
- package/templates/nextjs/docs/design-docs/decisions/ADR-000-infrastructure.md +72 -0
- package/templates/nextjs/docs/design-docs/decisions/index.md +7 -0
- package/templates/nextjs/docs/design-docs/index.md +7 -0
- package/templates/nextjs/docs/design-docs/team-workflow.md +66 -0
- package/templates/nextjs/docs/exec-plans/active/.gitkeep +0 -0
- package/templates/nextjs/docs/exec-plans/completed/.gitkeep +0 -0
- package/templates/nextjs/docs/exec-plans/tech-debt-tracker.md +19 -0
- package/templates/nextjs/docs/generated/.gitkeep +0 -0
- package/templates/nextjs/docs/product-specs/ROADMAP.md +59 -0
- package/templates/nextjs/docs/product-specs/draft/.gitkeep +0 -0
- package/templates/nextjs/docs/product-specs/index.md +18 -0
- package/templates/nextjs/docs/product-specs/ready/.gitkeep +0 -0
- package/templates/nextjs/eslint.config.mjs +150 -0
- package/templates/nextjs/gitignore +35 -0
- package/templates/nextjs/lighthouserc.js +37 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# /write-plan — Write an Execution Plan
|
|
2
|
+
|
|
3
|
+
Triggered by: `/write-plan`
|
|
4
|
+
|
|
5
|
+
## Step 1 — Find Ready Spec
|
|
6
|
+
```bash
|
|
7
|
+
ls docs/product-specs/ready/
|
|
8
|
+
```
|
|
9
|
+
If none → tell human to mark a spec READY first. Stop.
|
|
10
|
+
|
|
11
|
+
> A large feature area may span MULTIPLE plans — slice it into shippable milestones, each its
|
|
12
|
+
> own `PLAN-XXX` that ends green (e.g. live feed; then drill-in; then filters/export). Plans are
|
|
13
|
+
> numbered independently, so just create the next plan for the same spec.
|
|
14
|
+
|
|
15
|
+
## Step 2 — Get Next Plan Number
|
|
16
|
+
```bash
|
|
17
|
+
ls docs/exec-plans/{active,completed}/ 2>/dev/null | grep "PLAN-" | sort | tail -1
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Step 3 — Read the Spec
|
|
21
|
+
From the spec, identify:
|
|
22
|
+
- API Endpoints Used → determines hooks layer files
|
|
23
|
+
- Screens/Views → determines features + app layers
|
|
24
|
+
- Business rules → determines store needs
|
|
25
|
+
|
|
26
|
+
## Step 4 — Write the Plan
|
|
27
|
+
Save to: `docs/exec-plans/active/PLAN-XXX-{slug}.md`
|
|
28
|
+
|
|
29
|
+
```markdown
|
|
30
|
+
# PLAN-XXX — {Feature Name}
|
|
31
|
+
|
|
32
|
+
**Status:** IN_PROGRESS
|
|
33
|
+
**Spec:** docs/product-specs/ready/SPEC-XXX-{slug}.md
|
|
34
|
+
**Created:** YYYY-MM-DD
|
|
35
|
+
**Completed:** —
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Goal
|
|
40
|
+
{one sentence}
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Pre-Build Step
|
|
45
|
+
Run `/api-sync` to ensure `src/types/api.generated.ts` is current.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Layer Build Order
|
|
50
|
+
|
|
51
|
+
| # | Layer | Files | Gate Focuses On |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| 1 | Types | `src/types/domain.types.ts` additions | Zero imports, no API duplication |
|
|
54
|
+
| 2 | Lib | `src/lib/env.ts` update (if new vars), constants | process.env only in env.ts |
|
|
55
|
+
| 3 | Hooks | `src/hooks/use-{domain}.ts` × N | openapi-fetch only, error handling, query keys |
|
|
56
|
+
| 4 | Store | `src/store/{domain}-store.ts` (if client state needed) | UI state only, no server data |
|
|
57
|
+
| 5 | Features | `src/features/{domain}/` — components + forms | Loading/error/empty states, a11y |
|
|
58
|
+
| 6 | Components | `src/components/shared/` — new shared components | Props typed, no domain logic |
|
|
59
|
+
| 7 | App | `app/(dashboard)/{route}/page.tsx` + layout changes | No business logic in pages |
|
|
60
|
+
| 8 | Tests | `tests/unit/`, `tests/e2e/` | Coverage gates, E2E critical paths |
|
|
61
|
+
|
|
62
|
+
*(Remove layers that don't apply to this feature)*
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Acceptance Criteria
|
|
67
|
+
- [ ] {from spec}
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Progress Log
|
|
72
|
+
### {date} — Plan created
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Decision Log
|
|
77
|
+
*(filled during build)*
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Step 5 — Update Spec + Index
|
|
81
|
+
APPEND `PLAN-XXX` to the spec's `**Plan:**` field (do not overwrite) — a feature split across
|
|
82
|
+
several plans lists them all, e.g. `**Plan:** PLAN-003, PLAN-007`. Update index to `PLANNED`.
|
|
83
|
+
|
|
84
|
+
## Step 6 — Tell Human
|
|
85
|
+
```
|
|
86
|
+
Plan written: docs/exec-plans/active/PLAN-XXX-{slug}.md
|
|
87
|
+
|
|
88
|
+
IMPORTANT: Run /api-sync before /build-layer if openapi.json exists.
|
|
89
|
+
|
|
90
|
+
{N} layers planned. Run /build-layer to start.
|
|
91
|
+
```
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# /build-layer — Build Next Layer from Active Plan
|
|
2
|
+
|
|
3
|
+
Triggered by: `/build-layer` (no argument)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Step 1 — Find Active Plan and Next Layer
|
|
8
|
+
```bash
|
|
9
|
+
PLAN=$(ls docs/exec-plans/active/*.md 2>/dev/null | head -1)
|
|
10
|
+
[[ -z "$PLAN" ]] && echo "No active plan. Run /write-plan first." && exit 1
|
|
11
|
+
cat "$PLAN"
|
|
12
|
+
```
|
|
13
|
+
Find first `[ ]` row. If all `[x]` → run `/garbage-collect`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Step 2 — Check API Contract
|
|
18
|
+
```bash
|
|
19
|
+
ls src/types/api.generated.ts 2>/dev/null || echo "WARNING: api.generated.ts missing — run /api-sync"
|
|
20
|
+
```
|
|
21
|
+
If missing: stop and tell human to run `/api-sync` first.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step 3 — Load Context
|
|
26
|
+
Read: active plan, linked spec, `ARCHITECTURE.md`, path-scoped rule for this layer:
|
|
27
|
+
- Types → `.claude/rules/architecture.md`
|
|
28
|
+
- Lib → `.claude/rules/architecture.md` + `.claude/rules/security.md`
|
|
29
|
+
- Hooks → `.claude/rules/api-contract.md`
|
|
30
|
+
- Store → `.claude/rules/architecture.md`
|
|
31
|
+
- Features → `.claude/rules/components.md` + `.claude/rules/architecture.md`
|
|
32
|
+
- Components → `.claude/rules/components.md`
|
|
33
|
+
- App → `.claude/rules/architecture.md` + `.claude/rules/security.md`
|
|
34
|
+
- Tests → `.claude/rules/testing.md`
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Step 4 — Build the Layer
|
|
39
|
+
|
|
40
|
+
### Types (`src/types/domain.types.ts`)
|
|
41
|
+
- Add frontend-only types (form inputs, UI state, component props)
|
|
42
|
+
- NEVER duplicate what's in `api.generated.ts`
|
|
43
|
+
- Check: `import type { components } from '@/types/api.generated'` and use those
|
|
44
|
+
|
|
45
|
+
### Lib (`src/lib/`)
|
|
46
|
+
- New env vars: add to Zod schema in `env.ts` + `.env.example`
|
|
47
|
+
- New constants: add to `constants.ts`
|
|
48
|
+
- If api-client needs changes: add middleware — never change the base createClient call
|
|
49
|
+
|
|
50
|
+
### Hooks (`src/hooks/`)
|
|
51
|
+
- One file per domain: `use-{domain}.ts`
|
|
52
|
+
- Export `{domain}Keys` query key factory first
|
|
53
|
+
- Use `apiClient.GET/POST/PUT/PATCH/DELETE` — never raw `fetch()`
|
|
54
|
+
- Always `if (error) throw new Error(...)` after destructuring
|
|
55
|
+
- Include: list hook, single hook, create/update/delete mutations
|
|
56
|
+
|
|
57
|
+
### Store (`src/store/`)
|
|
58
|
+
- Only if feature needs client-only state (sidebar, modal, filters not in URL)
|
|
59
|
+
- `create<StoreType>()` with named slice
|
|
60
|
+
- NO server data — that's in TanStack Query
|
|
61
|
+
|
|
62
|
+
### Features (`src/features/{domain}/`)
|
|
63
|
+
Create these sub-files:
|
|
64
|
+
```
|
|
65
|
+
src/features/{domain}/
|
|
66
|
+
index.ts ← barrel export
|
|
67
|
+
{Domain}List.tsx ← list component
|
|
68
|
+
{Domain}Card.tsx ← single item
|
|
69
|
+
{Domain}Form.tsx ← create/edit form
|
|
70
|
+
{Domain}Detail.tsx ← detail view
|
|
71
|
+
use-{domain}-page.ts ← feature-level hooks (compose domain hooks)
|
|
72
|
+
```
|
|
73
|
+
Every component: Loading + Error + Empty states.
|
|
74
|
+
Forms: react-hook-form + zodResolver.
|
|
75
|
+
Every `use client`: has comment `// Client: [reason]`.
|
|
76
|
+
Every interactive element: aria-label, focus-visible.
|
|
77
|
+
|
|
78
|
+
### Components (`src/components/shared/`)
|
|
79
|
+
- New shared components needed by multiple features
|
|
80
|
+
- Props fully typed
|
|
81
|
+
- No hooks, no API calls — pure rendering
|
|
82
|
+
|
|
83
|
+
### App (`app/`)
|
|
84
|
+
- Page files: Server Components by default
|
|
85
|
+
- Import Feature component at top, render it
|
|
86
|
+
- NO `useState`, `useEffect`, `fetch` in page.tsx
|
|
87
|
+
- Layout changes: auth guard, breadcrumbs, nav items
|
|
88
|
+
|
|
89
|
+
### Tests
|
|
90
|
+
- `tests/unit/hooks/use-{domain}.test.ts` — MSW + renderHook
|
|
91
|
+
- `tests/unit/features/{Component}.test.tsx` — RTL + userEvent
|
|
92
|
+
- `tests/unit/utils/{util}.test.ts` — pure function tests
|
|
93
|
+
- `tests/e2e/{feature}.spec.ts` — Playwright happy path + auth
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Step 5 — Run Gate
|
|
98
|
+
Call `gate-checker` agent.
|
|
99
|
+
|
|
100
|
+
**If FAIL:** auto-fix each ITEM, log what was fixed, re-run gate (max 3 attempts).
|
|
101
|
+
**If PASS:** tick checkbox in plan, write ADR if non-obvious decision.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Step 6 — ADR (if needed)
|
|
106
|
+
`docs/design-docs/decisions/ADR-XXX-{slug}.md`
|
|
107
|
+
Update `docs/design-docs/decisions/index.md`.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Step 7 — Commit and Push
|
|
112
|
+
```bash
|
|
113
|
+
git add -A
|
|
114
|
+
git commit -m "{feat|chore|test}({scope}): {description}
|
|
115
|
+
|
|
116
|
+
{bullet points}
|
|
117
|
+
|
|
118
|
+
PLAN-XXX Layer N/Total"
|
|
119
|
+
git push origin main
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Step 8 — Report to Human
|
|
125
|
+
```
|
|
126
|
+
═══════════════════════════════════════════
|
|
127
|
+
✅ Layer N ({layer-name}) — COMPLETE
|
|
128
|
+
═══════════════════════════════════════════
|
|
129
|
+
Files created: [list]
|
|
130
|
+
Gate attempts: N
|
|
131
|
+
Auto-fixed: [list]
|
|
132
|
+
ADR written: ADR-XXX / None needed
|
|
133
|
+
Committed: [hash]
|
|
134
|
+
|
|
135
|
+
Progress: [x] Layer 1 [x] Layer 2 [ ] Layer 3 ...
|
|
136
|
+
|
|
137
|
+
Ready for Layer N+1: {next-layer-name}
|
|
138
|
+
Confirm to continue? [human must respond]
|
|
139
|
+
═══════════════════════════════════════════
|
|
140
|
+
```
|
|
141
|
+
**Wait for human confirmation before next layer.**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# /validate-layer — Run Gate Without Building
|
|
2
|
+
|
|
3
|
+
Triggered by: /validate-layer
|
|
4
|
+
|
|
5
|
+
Calls gate-checker agent on current src/ and app/ state.
|
|
6
|
+
Read-only — no auto-fix, no commit.
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
1. Find most recently checked layer from active plan
|
|
10
|
+
2. Call gate-checker agent
|
|
11
|
+
3. Present full PASS/FAIL report
|
|
12
|
+
|
|
13
|
+
To auto-fix failures: run /build-layer
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# /push-layer — Commit and Push Current Layer
|
|
2
|
+
|
|
3
|
+
Triggered by: /push-layer
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
1. Run the full gate (Cardinal Rule 4 — gate must PASS before commit):
|
|
7
|
+
```bash
|
|
8
|
+
npm run gate # typecheck + lint + format:check + test:coverage (incl. tests/architecture/)
|
|
9
|
+
```
|
|
10
|
+
If it fails → auto-fix what you can, re-run, and only proceed when green. Never commit a red gate.
|
|
11
|
+
|
|
12
|
+
2. Commit:
|
|
13
|
+
```bash
|
|
14
|
+
git add -A
|
|
15
|
+
git commit -m "{type}({scope}): {description from active plan}"
|
|
16
|
+
git push origin $(git branch --show-current)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Commit Types
|
|
20
|
+
feat · fix · chore · refactor · test · docs · style · perf
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# /layer-check — Ad-hoc Architecture Violation Scan
|
|
2
|
+
|
|
3
|
+
Triggered by: /layer-check
|
|
4
|
+
|
|
5
|
+
Runs:
|
|
6
|
+
1. npm run typecheck
|
|
7
|
+
2. npm run lint
|
|
8
|
+
3. grep for direct fetch() in components/features/pages
|
|
9
|
+
4. grep for process.env outside env.ts
|
|
10
|
+
5. grep for console.log
|
|
11
|
+
6. grep for raw <img> tags
|
|
12
|
+
7. file size check (> 400 lines)
|
|
13
|
+
8. npx vitest run tests/architecture/
|
|
14
|
+
|
|
15
|
+
Output:
|
|
16
|
+
```
|
|
17
|
+
LAYER CHECK — {timestamp}
|
|
18
|
+
TypeScript: CLEAN / {N} errors
|
|
19
|
+
ESLint: CLEAN / {N} errors
|
|
20
|
+
fetch(): NONE / {list}
|
|
21
|
+
process.env: NONE / {list}
|
|
22
|
+
console.log: NONE / {list}
|
|
23
|
+
<img>: NONE / {list}
|
|
24
|
+
File sizes: NONE / {list}
|
|
25
|
+
Arch tests: PASS / FAIL
|
|
26
|
+
|
|
27
|
+
OVERALL: CLEAN / {N} violations
|
|
28
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# /garbage-collect — End-of-Feature Cleanup
|
|
2
|
+
|
|
3
|
+
Triggered by: /garbage-collect
|
|
4
|
+
|
|
5
|
+
Calls garbage-collector agent which:
|
|
6
|
+
1. Scans file size violations and splits files > 400 lines
|
|
7
|
+
2. Removes unnecessary use client directives
|
|
8
|
+
3. Runs TypeScript + ESLint --fix
|
|
9
|
+
4. Updates stale docs
|
|
10
|
+
5. Updates QUALITY_SCORE.md
|
|
11
|
+
6. Logs tech debt
|
|
12
|
+
7. Closes plan (active/ to completed/)
|
|
13
|
+
8. Marks spec SHIPPED
|
|
14
|
+
9. Final commit + push
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# /doc-garden — Scan and Fix Stale Docs
|
|
2
|
+
|
|
3
|
+
Triggered by: /doc-garden
|
|
4
|
+
|
|
5
|
+
Calls doc-gardener agent which checks:
|
|
6
|
+
- AGENTS.md vs .claude/ directory
|
|
7
|
+
- ARCHITECTURE.md vs actual src/ structure
|
|
8
|
+
- docs/product-specs/index.md vs actual spec files
|
|
9
|
+
- .env.example vs src/lib/env.ts schema
|
|
10
|
+
- docs/design-docs/decisions/index.md vs actual ADR files
|
|
11
|
+
|
|
12
|
+
Updates anything stale. Commits if changed.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# /api-sync — Regenerate API Types from OpenAPI Spec
|
|
2
|
+
|
|
3
|
+
> **Verified:** 2026-06-05 · **Staleness threshold:** 60 days
|
|
4
|
+
> **Source:** openapi-typescript (https://openapi-ts.dev/)
|
|
5
|
+
> If older than the threshold, fetch current `openapi-typescript` docs via `ctx7` (wired
|
|
6
|
+
> in `.mcp.json`), or `WebFetch`/`WebSearch` if ctx7 is unavailable, before running — its
|
|
7
|
+
> CLI flags and output shape change between majors.
|
|
8
|
+
|
|
9
|
+
Triggered by: /api-sync
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
Regenerates src/types/api.generated.ts from openapi.json in the project root.
|
|
13
|
+
This is the source of truth for all API types in the frontend.
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
### Step 1 — Check spec file
|
|
18
|
+
```bash
|
|
19
|
+
ls openapi.json 2>/dev/null
|
|
20
|
+
```
|
|
21
|
+
If missing: tell human to copy openapi.json from backend to project root.
|
|
22
|
+
- FastAPI backend: generate at http://localhost:8000/openapi.json
|
|
23
|
+
- Express backend: copy from docs/generated/openapi.json
|
|
24
|
+
|
|
25
|
+
### Step 2 — Regenerate
|
|
26
|
+
```bash
|
|
27
|
+
npm run api:sync
|
|
28
|
+
# which runs: openapi-typescript openapi.json -o src/types/api.generated.ts
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Step 3 — TypeScript check
|
|
32
|
+
```bash
|
|
33
|
+
npm run typecheck 2>&1
|
|
34
|
+
```
|
|
35
|
+
List every file with errors — these are places that need updating after the contract changed.
|
|
36
|
+
|
|
37
|
+
### Step 4 — Call contract-checker agent
|
|
38
|
+
Check for hand-written types that duplicate the generated ones.
|
|
39
|
+
|
|
40
|
+
### Step 5 — Commit
|
|
41
|
+
```bash
|
|
42
|
+
git add src/types/api.generated.ts openapi.json
|
|
43
|
+
git commit -m "chore(api): sync contract from backend openapi.json"
|
|
44
|
+
git push origin main
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
- NEVER edit api.generated.ts manually
|
|
49
|
+
- Always run typecheck after sync — errors = contract drift to fix
|
|
50
|
+
- Run before starting every new feature
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# /perf-budget — Performance Budget Check
|
|
2
|
+
|
|
3
|
+
> **Verified:** 2026-06-05 · **Staleness threshold:** 60 days
|
|
4
|
+
> **Sources:** Next.js bundle analyzer (https://nextjs.org/docs/app/guides/package-bundling) ·
|
|
5
|
+
> Core Web Vitals (https://web.dev/vitals)
|
|
6
|
+
> If older than the threshold, fetch current docs via `ctx7` (wired in `.mcp.json`), or
|
|
7
|
+
> `WebFetch`/`WebSearch` if ctx7 is unavailable, before running — `next build` output
|
|
8
|
+
> format and CWV thresholds shift between releases.
|
|
9
|
+
|
|
10
|
+
Triggered by: /perf-budget
|
|
11
|
+
|
|
12
|
+
## Step 1 — Bundle Analysis
|
|
13
|
+
```bash
|
|
14
|
+
ANALYZE=true npm run build 2>&1 | grep -E "Page|First Load JS|kB"
|
|
15
|
+
```
|
|
16
|
+
Flag any route with First Load JS > 150kB.
|
|
17
|
+
|
|
18
|
+
## Step 2 — Client Component Audit
|
|
19
|
+
```bash
|
|
20
|
+
grep -rn "^'use client'" src/ app/ --include="*.tsx" -l
|
|
21
|
+
```
|
|
22
|
+
For each file: verify it actually needs useState/useEffect/browser APIs.
|
|
23
|
+
|
|
24
|
+
## Step 3 — Image Check
|
|
25
|
+
```bash
|
|
26
|
+
grep -rn "<img " src/ app/ --include="*.tsx"
|
|
27
|
+
grep -rn "<Image " src/ app/ --include="*.tsx" | grep -v "width\|fill"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Step 4 — Build Time
|
|
31
|
+
```bash
|
|
32
|
+
time npm run build 2>&1 | tail -5
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Report
|
|
36
|
+
```
|
|
37
|
+
PERF BUDGET — {timestamp}
|
|
38
|
+
|
|
39
|
+
Bundle:
|
|
40
|
+
[route]: [size]kB PASS/FAIL (target < 150kB)
|
|
41
|
+
|
|
42
|
+
Client components: N total
|
|
43
|
+
Unnecessary (review): [files]
|
|
44
|
+
|
|
45
|
+
Images using raw <img>: N (should be 0)
|
|
46
|
+
Images missing dimensions: N
|
|
47
|
+
|
|
48
|
+
Build time: Xs
|
|
49
|
+
|
|
50
|
+
OVERALL: PASS / N issues
|
|
51
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Keep the build context small and secret-free.
|
|
2
|
+
node_modules
|
|
3
|
+
.next
|
|
4
|
+
.git
|
|
5
|
+
.github
|
|
6
|
+
.husky
|
|
7
|
+
.claude
|
|
8
|
+
.harness-hold
|
|
9
|
+
coverage
|
|
10
|
+
playwright-report
|
|
11
|
+
test-results
|
|
12
|
+
tests
|
|
13
|
+
docs
|
|
14
|
+
*.md
|
|
15
|
+
.env
|
|
16
|
+
.env.*
|
|
17
|
+
!.env.example
|
|
18
|
+
npm-debug.log*
|
|
19
|
+
yarn-error.log*
|
|
20
|
+
Dockerfile
|
|
21
|
+
.dockerignore
|
|
22
|
+
.prettierrc
|
|
23
|
+
.prettierignore
|
|
24
|
+
.lintstagedrc.json
|
|
25
|
+
lighthouserc.js
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Normalise line endings. Shell scripts and git hooks MUST be LF or they break
|
|
2
|
+
# on Linux (husky / CI: "bad interpreter"). Let Git decide for everything else.
|
|
3
|
+
* text=auto
|
|
4
|
+
|
|
5
|
+
*.sh text eol=lf
|
|
6
|
+
.husky/* text eol=lf
|
|
7
|
+
*.ps1 text eol=crlf
|
|
8
|
+
|
|
9
|
+
# Treat the generated API contract as generated (better diffs, not hand-edited).
|
|
10
|
+
src/types/api.generated.ts linguist-generated=true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# CODEOWNERS — GitHub auto-requests these reviewers based on which files changed.
|
|
2
|
+
# Order matters: the LAST matching pattern wins.
|
|
3
|
+
#
|
|
4
|
+
# Replace the placeholder team slugs with your real GitHub teams/usernames, then
|
|
5
|
+
# enable "Require review from Code Owners" in branch protection
|
|
6
|
+
# (see docs/design-docs/team-workflow.md). Until then these are inert placeholders.
|
|
7
|
+
|
|
8
|
+
# Default — any engineer on the team can review
|
|
9
|
+
* @your-team/engineers
|
|
10
|
+
|
|
11
|
+
# Security-sensitive — leads must review
|
|
12
|
+
/.claude/hooks/ @your-team/leads
|
|
13
|
+
/src/lib/env.ts @your-team/leads
|
|
14
|
+
/src/lib/api-client.ts @your-team/leads
|
|
15
|
+
/src/features/auth/ @your-team/leads
|
|
16
|
+
/app/api/ @your-team/leads
|
|
17
|
+
/next.config.ts @your-team/leads
|
|
18
|
+
|
|
19
|
+
# API contract is generated — leads review any drift / accidental hand-edit
|
|
20
|
+
/src/types/api.generated.ts @your-team/leads
|
|
21
|
+
|
|
22
|
+
# Platform / infra — platform team owns build, containers, and CI
|
|
23
|
+
/Dockerfile @your-team/platform
|
|
24
|
+
/.github/workflows/ @your-team/platform
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Dependabot — keeps the (unpinned-at-install, locked-after-scaffold) deps current.
|
|
2
|
+
# The harness installs latest LTS once; the committed package-lock.json freezes that,
|
|
3
|
+
# and Dependabot proposes reviewed bumps so the project doesn't silently drift.
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
# npm — application dependencies. Grouped so routine minor/patch bumps are one PR.
|
|
7
|
+
- package-ecosystem: npm
|
|
8
|
+
directory: '/'
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
open-pull-requests-limit: 10
|
|
12
|
+
groups:
|
|
13
|
+
minor-and-patch:
|
|
14
|
+
update-types:
|
|
15
|
+
- minor
|
|
16
|
+
- patch
|
|
17
|
+
labels:
|
|
18
|
+
- dependencies
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: chore
|
|
21
|
+
include: scope
|
|
22
|
+
|
|
23
|
+
# GitHub Actions — keep workflow action versions patched.
|
|
24
|
+
- package-ecosystem: github-actions
|
|
25
|
+
directory: '/'
|
|
26
|
+
schedule:
|
|
27
|
+
interval: weekly
|
|
28
|
+
labels:
|
|
29
|
+
- ci
|
|
30
|
+
commit-message:
|
|
31
|
+
prefix: ci
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
PR title format: <type>(<scope>): <summary>
|
|
3
|
+
type ∈ feat | fix | chore | refactor | docs | test | perf
|
|
4
|
+
Example: feat(applications): add application list feature
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
## What does this PR do?
|
|
8
|
+
|
|
9
|
+
<!-- One sentence. Link the spec it came from. -->
|
|
10
|
+
|
|
11
|
+
- Spec: `docs/product-specs/ready/SPEC-XXX.md`
|
|
12
|
+
|
|
13
|
+
## Execution plan reference
|
|
14
|
+
|
|
15
|
+
<!-- Link the plan that drove this work. -->
|
|
16
|
+
|
|
17
|
+
- Plan: `docs/exec-plans/active/PLAN-XXX.md` (or completed/)
|
|
18
|
+
- Closes #
|
|
19
|
+
|
|
20
|
+
## Layers touched (check each, confirm its rule holds)
|
|
21
|
+
|
|
22
|
+
- [ ] **Types** — zero imports from other layers; no logic; never duplicates `api.generated.ts`
|
|
23
|
+
- [ ] **Lib** — `env.ts` Zod-validated (only place with `process.env`); `api-client.ts` via openapi-fetch `createClient`; auth token read from React context
|
|
24
|
+
- [ ] **Hooks** — TanStack Query wrapping `api-client`; no raw `fetch()`; loading/success/error states covered
|
|
25
|
+
- [ ] **Features** — no direct `fetch()`; no `process.env`; every `'use client'` has a `// Client: <reason>` comment
|
|
26
|
+
- [ ] **App** — pages are layout + data trigger only (no `useState`/`useEffect`/`fetch`); import feature components, not hooks
|
|
27
|
+
- [ ] **Utils** — zero domain imports; **100% test coverage**
|
|
28
|
+
|
|
29
|
+
## Gate check (all green)
|
|
30
|
+
|
|
31
|
+
- [ ] `tsc --noEmit` — type-check passes
|
|
32
|
+
- [ ] `eslint src/ app/ --max-warnings=0` — lint clean
|
|
33
|
+
- [ ] `prettier --check .` — formatting clean
|
|
34
|
+
- [ ] `vitest` — all tests pass
|
|
35
|
+
- [ ] Coverage meets per-layer thresholds (utils 100 · hooks 80 · features 70 · components 70) — enforced by `vitest.config.ts`
|
|
36
|
+
- [ ] Architecture tests pass (`vitest run tests/architecture/`)
|
|
37
|
+
- [ ] No file exceeds 400 lines
|
|
38
|
+
|
|
39
|
+
## Security checklist
|
|
40
|
+
|
|
41
|
+
- [ ] No `console.log` in `src/` or `app/`
|
|
42
|
+
- [ ] No raw `process.env` outside `src/lib/env.ts`
|
|
43
|
+
- [ ] No direct `fetch()` in components/features/pages (all API calls via `src/hooks/`)
|
|
44
|
+
- [ ] Access tokens in memory only — never `localStorage`/`sessionStorage`
|
|
45
|
+
- [ ] All images via `next/image` — no raw `<img>`
|
|
46
|
+
- [ ] `src/types/api.generated.ts` not hand-edited (regenerated via `/api-sync`)
|
|
47
|
+
- [ ] Cross-user isolation test **enabled** (remove `test.skip` in `tests/e2e/isolation.spec.ts`) for each new user-owned resource (User B → 404 on User A's resource)
|
|
48
|
+
|
|
49
|
+
## ADR
|
|
50
|
+
|
|
51
|
+
- [ ] A non-obvious architectural decision was made → ADR written in `docs/design-docs/decisions/`
|
|
52
|
+
- [ ] No ADR needed (nothing non-obvious)
|
|
53
|
+
|
|
54
|
+
## Breaking changes
|
|
55
|
+
|
|
56
|
+
- [ ] None
|
|
57
|
+
- [ ] Yes — documented below (API contract, env var, or config change)
|
|
58
|
+
|
|
59
|
+
<!-- If breaking: describe the change, the migration path, and rollback steps. -->
|