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,41 @@
|
|
|
1
|
+
name: Load Test
|
|
2
|
+
|
|
3
|
+
# Manual only — never runs on push or PR. Trigger from the Actions tab
|
|
4
|
+
# (GitHub → Actions → Load Test → Run workflow) and point it at any reachable URL.
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
base_url:
|
|
9
|
+
description: 'Target base URL (e.g. https://staging.example.com)'
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
test:
|
|
13
|
+
description: 'Which test to run'
|
|
14
|
+
required: true
|
|
15
|
+
type: choice
|
|
16
|
+
default: smoke
|
|
17
|
+
options:
|
|
18
|
+
- smoke
|
|
19
|
+
- stress
|
|
20
|
+
- soak
|
|
21
|
+
auth_token:
|
|
22
|
+
description: 'Bearer token for authenticated endpoints (optional)'
|
|
23
|
+
required: false
|
|
24
|
+
type: string
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
load-test:
|
|
28
|
+
name: k6 ${{ inputs.test }} → ${{ inputs.base_url }}
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Install k6
|
|
35
|
+
uses: grafana/setup-k6-action@v1
|
|
36
|
+
|
|
37
|
+
- name: Run k6 ${{ inputs.test }}
|
|
38
|
+
env:
|
|
39
|
+
BASE_URL: ${{ inputs.base_url }}
|
|
40
|
+
AUTH_TOKEN: ${{ inputs.auth_token }}
|
|
41
|
+
run: k6 run tests/load/${{ inputs.test }}.js
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# gitleaks config — extends the default ruleset and allowlists the template's known,
|
|
2
|
+
# non-secret dev/test placeholders so the CI secret-scan job doesn't false-positive on
|
|
3
|
+
# them. Real secrets anywhere else are still detected. Used by .github/workflows/ci.yml.
|
|
4
|
+
title = "harness-template gitleaks config"
|
|
5
|
+
|
|
6
|
+
[extend]
|
|
7
|
+
useDefault = true
|
|
8
|
+
|
|
9
|
+
[allowlist]
|
|
10
|
+
description = "Template dev/test placeholders — not real secrets"
|
|
11
|
+
# .env.example is an example file by convention — it must never hold real secrets.
|
|
12
|
+
paths = ['''\.env\.example$''']
|
|
13
|
+
# The dev/CI JWT placeholders (docker-compose.yml, ci.yml). Matched by value so the
|
|
14
|
+
# allowlist applies across the whole git history, not just the current commit.
|
|
15
|
+
regexes = [
|
|
16
|
+
'''dev-only-secret-change-me-min-32-characters''',
|
|
17
|
+
'''ci-test-secret-not-a-real-key-min-32-chars''',
|
|
18
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# AGENTS.md — Navigation Map
|
|
2
|
+
|
|
3
|
+
Stack: Node 24 LTS · TypeScript · Express · Sequelize · PostgreSQL · Redis · BullMQ
|
|
4
|
+
(versions mostly unpinned — `/infra-setup` installs the latest LTS; Sequelize is pinned to v6
|
|
5
|
+
for `sequelize-typescript` compatibility)
|
|
6
|
+
|
|
7
|
+
> Common tasks: `make help` (wraps the npm scripts) or run them directly — e.g. `npm run gate`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🗺️ Where Everything Lives
|
|
12
|
+
|
|
13
|
+
| What you need | Where |
|
|
14
|
+
| ---------------------------------- | -------------------------------------- |
|
|
15
|
+
| Layer rules + dependency diagram | `ARCHITECTURE.md` |
|
|
16
|
+
| Engineering constitution (the WHY) | `docs/design-docs/core-beliefs.md` |
|
|
17
|
+
| Active execution plan | `docs/exec-plans/active/` |
|
|
18
|
+
| Completed plans (history) | `docs/exec-plans/completed/` |
|
|
19
|
+
| Product roadmap (epics → specs) | `docs/product-specs/ROADMAP.md` |
|
|
20
|
+
| Product specs (draft) | `docs/product-specs/draft/` |
|
|
21
|
+
| Product specs (approved) | `docs/product-specs/ready/` |
|
|
22
|
+
| Architectural decisions (ADRs) | `docs/design-docs/decisions/` |
|
|
23
|
+
| Known tech debt | `docs/exec-plans/tech-debt-tracker.md` |
|
|
24
|
+
| Domain health grades | `docs/QUALITY_SCORE.md` |
|
|
25
|
+
| Plan format + lifecycle | `docs/PLANS.md` |
|
|
26
|
+
| Generated DB schema | `docs/generated/db-schema.md` |
|
|
27
|
+
| Generated API contract (OpenAPI) | `docs/generated/openapi.json` |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## ⚡ Slash Commands
|
|
32
|
+
|
|
33
|
+
| Command | What it does |
|
|
34
|
+
| ------------------ | ------------------------------------------------------ |
|
|
35
|
+
| `/infra-setup` | Phase 0 — full infra scaffold (run once) |
|
|
36
|
+
| `/write-roadmap` | Brief → ordered, dependency-aware spec roadmap → `docs/product-specs/ROADMAP.md` |
|
|
37
|
+
| `/write-spec` | Write a product spec → `docs/product-specs/draft/` |
|
|
38
|
+
| `/write-plan` | Turn a READY spec into an execution plan |
|
|
39
|
+
| `/build-layer` | Build next unchecked layer from active plan + run gate |
|
|
40
|
+
| `/validate-layer` | Run gate check on current layer without building |
|
|
41
|
+
| `/push-layer` | Commit + push current layer with conventional message |
|
|
42
|
+
| `/layer-check` | Ad-hoc architecture violation scan |
|
|
43
|
+
| `/garbage-collect` | End-of-feature cleanup pass |
|
|
44
|
+
| `/doc-garden` | Scan + fix stale documentation |
|
|
45
|
+
| `/db-optimize` | EXPLAIN ANALYZE workflow for slow queries |
|
|
46
|
+
| `/load-test` | Run k6 smoke / stress / soak test |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🤖 Agents
|
|
51
|
+
|
|
52
|
+
| Agent | When to use |
|
|
53
|
+
| ------------------- | ------------------------------------------------------------ |
|
|
54
|
+
| `gate-checker` | Called automatically by `/build-layer` — PASS/FAIL per layer |
|
|
55
|
+
| `spec-writer` | Use the `/write-spec` skill (invokes this) |
|
|
56
|
+
| `planner` | Use the `/write-plan` skill (invokes this) |
|
|
57
|
+
| `reviewer` | Before opening a PR — full harness review |
|
|
58
|
+
| `arch-validator` | Deep import + layer compliance scan |
|
|
59
|
+
| `db-optimizer` | N+1, missing index, pagination audit on repo layer |
|
|
60
|
+
| `security-auditor` | OWASP Top 10 review — run before any auth/payment PR |
|
|
61
|
+
| `doc-gardener` | Use the `/doc-garden` skill (invokes this) |
|
|
62
|
+
| `garbage-collector` | Use the `/garbage-collect` skill (invokes this) |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## ✅ Non-Negotiable Invariants
|
|
67
|
+
|
|
68
|
+
- No `console.log` → use `logger` from `src/config/logger.ts`
|
|
69
|
+
- No `process.env` outside `src/config/env.ts`
|
|
70
|
+
- No `as SomeType` on external/DB data → Zod parse only
|
|
71
|
+
- No file > 400 lines → split into focused modules
|
|
72
|
+
- No cross-layer imports → enforced by `eslint-plugin-boundaries` + `madge` + structural tests
|
|
73
|
+
- Every DB query result → `Schema.parse(raw.toJSON())`
|
|
74
|
+
- Every list endpoint → cursor-based pagination
|
|
75
|
+
- Every protected route → `requireAuth` as first line
|
|
76
|
+
- Every owned resource → a cross-user isolation test (`tests/architecture/isolation.test.ts` enforces it)
|
|
77
|
+
- Every mutating endpoint → honours `Idempotency-Key` (idempotency middleware)
|
|
78
|
+
- Every route → registered in `runtime/openapi.ts`; commit a fresh `npm run openapi:export`
|
|
79
|
+
- Every external call → retry + timeout
|
|
80
|
+
- Gate green (`npm run gate`) and all tests pass before `/push-layer`
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 🔁 The Flow
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
# Whole product (run once at the start):
|
|
88
|
+
/write-roadmap → human reviews ROADMAP → pick the walking-skeleton spec
|
|
89
|
+
|
|
90
|
+
# Every feature (repeat down the roadmap):
|
|
91
|
+
/write-spec (roadmap-guided) → human marks READY → /write-plan
|
|
92
|
+
→ /build-layer (repeats, gate-enforced)
|
|
93
|
+
→ /garbage-collect → plan closed
|
|
94
|
+
```
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# ARCHITECTURE.md — Layered Architecture
|
|
2
|
+
|
|
3
|
+
Stack: TypeScript 5 · Express 5 · Sequelize 6 · PostgreSQL · Redis · BullMQ
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Dependency Layer Diagram
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────┐
|
|
11
|
+
│ Utils — stateless helpers, zero domain imports │
|
|
12
|
+
│ 100% test coverage required │
|
|
13
|
+
└────────────────────┬────────────────────────────────────┘
|
|
14
|
+
│ (imported by all layers below)
|
|
15
|
+
┌────────────────────▼────────────────────────────────────┐
|
|
16
|
+
│ │
|
|
17
|
+
│ Types ──► Config ──► Models ──► Repo │
|
|
18
|
+
│ │ │
|
|
19
|
+
│ ▼ │
|
|
20
|
+
│ Service │
|
|
21
|
+
│ │ │
|
|
22
|
+
│ ▼ │
|
|
23
|
+
│ Runtime { Routes · Workers } │
|
|
24
|
+
│ │
|
|
25
|
+
│ Providers (auth, telemetry SDK, redis) │
|
|
26
|
+
│ └─ wired in by Runtime (composition root) only │
|
|
27
|
+
│ │
|
|
28
|
+
│ Config also hosts cross-cutting helpers every layer │
|
|
29
|
+
│ needs: logger, tracing (withSpan), metrics │
|
|
30
|
+
│ │
|
|
31
|
+
└──────────────────────────────────────────────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Layer Definitions
|
|
37
|
+
|
|
38
|
+
### Types (`src/types/`)
|
|
39
|
+
- Pure TypeScript interfaces, enums, type aliases, Zod schemas
|
|
40
|
+
- **Zero imports** from any other layer
|
|
41
|
+
- **Zero runtime code** — no function bodies with logic
|
|
42
|
+
- Examples: `Application`, `ApplicationStage`, `CreateApplicationInput`, `PageResult<T>`
|
|
43
|
+
|
|
44
|
+
### Config (`src/config/`)
|
|
45
|
+
- Env vars (Zod-validated), constants, timeouts
|
|
46
|
+
- Cross-cutting helpers every layer may import: `logger` (pino), `withSpan` (tracing), `metrics`
|
|
47
|
+
— these use only the `@opentelemetry/api` global, so they are safe no-ops when the SDK is off
|
|
48
|
+
- Imports: **Types only** (plus third-party: `zod`, `pino`, `@opentelemetry/api`)
|
|
49
|
+
- `env.ts` calls `process.exit(1)` on invalid config — fail fast
|
|
50
|
+
- Examples: `env.ts`, `constants.ts`, `timeouts.ts`, `database.ts`, `logger.ts`, `tracing.ts`, `metrics.ts`
|
|
51
|
+
|
|
52
|
+
### Models (`src/models/`)
|
|
53
|
+
- Sequelize model class definitions — schema only, no logic
|
|
54
|
+
- Imports: **Types, Config**
|
|
55
|
+
- All models: `paranoid: true`, `@Default(() => newId())`, indexes defined
|
|
56
|
+
- Examples: `User.model.ts`, `Application.model.ts`
|
|
57
|
+
|
|
58
|
+
### Repo (`src/repo/`)
|
|
59
|
+
- DB access only. All external data validated with Zod.
|
|
60
|
+
- Imports: **Types, Config, Models**
|
|
61
|
+
- **Every** query result: `Schema.parse(raw.toJSON())`
|
|
62
|
+
- All list methods: cursor-based pagination (cursors encoded with **base64url**)
|
|
63
|
+
- Ownership enforced: `findByIdAndUser(id, userId)` — never `findById` alone
|
|
64
|
+
- **Cross-user isolation**: a resource owned by user A must be invisible to user B.
|
|
65
|
+
When B requests A's resource, the repo returns nothing and the route responds
|
|
66
|
+
**404** (never 403 — do not reveal that the resource exists). **Enforced**: every
|
|
67
|
+
ownership-scoped repo must ship `tests/integration/<resource>.isolation.test.ts`
|
|
68
|
+
(copy `isolation.test.template.ts`); `tests/architecture/isolation.test.ts` fails
|
|
69
|
+
CI if one is missing.
|
|
70
|
+
- Examples: `user.repo.ts`, `application.repo.ts`
|
|
71
|
+
|
|
72
|
+
### Service (`src/services/`)
|
|
73
|
+
- Business logic and use-case orchestration
|
|
74
|
+
- Imports: **Types, Config, Repo**
|
|
75
|
+
- **No** `Request`, `Response`, `HttpException`, `express` imports
|
|
76
|
+
- **No** inline HTTP calls — external APIs go via Repo
|
|
77
|
+
- Examples: `application.service.ts`, `auth.service.ts`
|
|
78
|
+
|
|
79
|
+
### Runtime (`src/runtime/`)
|
|
80
|
+
- HTTP handlers, job workers, CLI entry points
|
|
81
|
+
- Imports: **Types, Config, Repo, Service**
|
|
82
|
+
- Routes: auth → validate → service → respond (this order, every time)
|
|
83
|
+
- Thin layer — zero business logic, delegates everything to Service
|
|
84
|
+
- **Canonical response envelope** (see `.claude/rules/api.md` for full spec):
|
|
85
|
+
- Success: `{ ok: true, data, meta: { requestId, timestamp } }` via the `ok()` helper
|
|
86
|
+
- Error: `{ ok: false, error: { code, message }, meta: { requestId } }` via `errorHandler`
|
|
87
|
+
- `error.code` ∈ `VALIDATION_ERROR | NOT_FOUND | UNAUTHORIZED | FORBIDDEN | CONFLICT | RATE_LIMITED | INTERNAL_ERROR`
|
|
88
|
+
- Mutating routes accept an `Idempotency-Key` header via `middleware/idempotency.ts` (Redis-backed replay)
|
|
89
|
+
- The OpenAPI registry lives in `runtime/openapi.ts`; routes register their schemas + paths there
|
|
90
|
+
- Examples: `routes/v1/applications.route.ts`, `middleware/idempotency.ts`, `workers/reminder.worker.ts`
|
|
91
|
+
|
|
92
|
+
### Providers (`src/providers/`)
|
|
93
|
+
- Stateful cross-cutting singletons: auth, redis, the OpenTelemetry `NodeSDK`, feature flags
|
|
94
|
+
- Wired in by **Runtime** (the composition root) — never imported by Service/Repo/Models
|
|
95
|
+
- `telemetry.ts` is **boot-only**: it owns the `NodeSDK` and is the *only* file that imports it.
|
|
96
|
+
The reusable `withSpan`/`metrics`/`logger` helpers live in **Config** (the api-global, no SDK)
|
|
97
|
+
so that Service and Repo can stay clean without importing this layer.
|
|
98
|
+
- Examples: `redis.ts`, `auth/jwt.ts`, `telemetry.ts`, `featureFlags.ts`
|
|
99
|
+
|
|
100
|
+
### Utils (`src/utils/`)
|
|
101
|
+
- Stateless helpers — **type-only imports from Types allowed** (e.g. the response-envelope types in `response.util.ts`); zero other domain imports
|
|
102
|
+
- **100% test coverage** required — enforced in CI
|
|
103
|
+
- Examples: `retry.ts`, `circuitBreaker.ts`, `mapWithConcurrency.ts`, `uuid.ts`
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Allowed Imports (strict — linter enforces)
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Types → (nothing)
|
|
111
|
+
Config → Types
|
|
112
|
+
Models → Types, Config
|
|
113
|
+
Repo → Types, Config, Models
|
|
114
|
+
Service → Types, Config, Repo
|
|
115
|
+
Runtime → Types, Config, Repo, Service
|
|
116
|
+
Utils → Types (type-only)
|
|
117
|
+
Providers → nothing from domain (domain imports Providers, not reverse)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Forbidden:**
|
|
121
|
+
- Service importing from Runtime or Providers — *blocked by ESLint* (`boundaries/dependencies`)
|
|
122
|
+
- Utils importing from any domain layer other than type-only Types — *blocked by ESLint* (`boundaries/dependencies`)
|
|
123
|
+
- Circular imports of any kind — *blocked by `madge --circular`* (`npm run check:circular`)
|
|
124
|
+
- Repo containing business logic (if/else beyond null checks) — *checked by gate-checker + review*
|
|
125
|
+
(no linter can express this rule; it is a judgment check, not a mechanical one)
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## File Size Limit
|
|
130
|
+
- **400 lines maximum** per file
|
|
131
|
+
- Approaching limit → split into focused sub-modules
|
|
132
|
+
- Enforced by: PostToolUse hook + gate-checker agent
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Naming Conventions
|
|
137
|
+
|
|
138
|
+
| Layer | File pattern | Example |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| Types | `*.types.ts` | `application.types.ts` |
|
|
141
|
+
| Config | `*.ts` in `config/` | `env.ts`, `timeouts.ts` |
|
|
142
|
+
| Models | `*.model.ts` | `Application.model.ts` |
|
|
143
|
+
| Repo | `*.repo.ts` | `application.repo.ts` |
|
|
144
|
+
| Service | `*.service.ts` | `application.service.ts` |
|
|
145
|
+
| Route | `*.route.ts` | `applications.route.ts` |
|
|
146
|
+
| Worker | `*.worker.ts` | `reminder.worker.ts` |
|
|
147
|
+
| Utils | `*.util.ts` | `retry.util.ts` |
|
|
148
|
+
| Zod schemas | `*Schema` | `ApplicationSchema` |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Mechanical Enforcement Stack
|
|
153
|
+
|
|
154
|
+
1. **ESLint** (`eslint.config.mjs`) — `boundaries/dependencies` (eslint-plugin-boundaries v6, with the TypeScript import resolver) blocks cross-layer imports;
|
|
155
|
+
`no-restricted-syntax` blocks `process.env` outside `config/env.ts`; plus `no-console`,
|
|
156
|
+
`no-explicit-any`, `no-unsafe-assignment`, `no-floating-promises`.
|
|
157
|
+
2. **madge** — `npm run check:circular` blocks circular imports (ESLint does not do this).
|
|
158
|
+
3. **Structural tests** — `tests/architecture/layers.test.ts` — a second, independent layer check; fails CI.
|
|
159
|
+
4. **PostToolUse hook** — `.claude/hooks/post-write.sh` warns on write (size, console.log, process.env, unsafe cast).
|
|
160
|
+
5. **gate / gate-checker** — `npm run gate` (humans + CI) and the `gate-checker` agent (called by `/build-layer`);
|
|
161
|
+
PASS required before commit.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Stage 1: Dependencies
|
|
2
|
+
FROM node:24-alpine AS deps
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
COPY package*.json ./
|
|
5
|
+
# --omit=dev installs production deps only (--only=production is deprecated in npm 7+).
|
|
6
|
+
RUN npm ci --omit=dev && npm cache clean --force
|
|
7
|
+
|
|
8
|
+
# Stage 2: Builder
|
|
9
|
+
FROM node:24-alpine AS builder
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
COPY package*.json ./
|
|
12
|
+
RUN npm ci
|
|
13
|
+
COPY . .
|
|
14
|
+
RUN npm run build
|
|
15
|
+
|
|
16
|
+
# Stage 3: Runner
|
|
17
|
+
FROM node:24-alpine AS runner
|
|
18
|
+
WORKDIR /app
|
|
19
|
+
|
|
20
|
+
# Create non-root user
|
|
21
|
+
RUN addgroup -g 1001 -S nodejs && \
|
|
22
|
+
adduser -S nodejs -u 1001
|
|
23
|
+
|
|
24
|
+
# Copy dependencies and build artifacts
|
|
25
|
+
COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules
|
|
26
|
+
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
|
|
27
|
+
COPY --from=builder --chown=nodejs:nodejs /app/package.json ./
|
|
28
|
+
|
|
29
|
+
# Switch to non-root user
|
|
30
|
+
USER nodejs
|
|
31
|
+
|
|
32
|
+
# Expose port
|
|
33
|
+
EXPOSE 3000
|
|
34
|
+
|
|
35
|
+
# Health check
|
|
36
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
|
37
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))"
|
|
38
|
+
|
|
39
|
+
# Start server
|
|
40
|
+
CMD ["node", "dist/runtime/server.js"]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Makefile — thin wrapper over the npm scripts so the same verbs (make gate, make
|
|
2
|
+
# dev, make test, make setup) work identically across the harness family (FastAPI,
|
|
3
|
+
# Express, NestJS). The npm scripts in package.json remain the source of truth;
|
|
4
|
+
# this just gives cross-stack muscle memory. Run `make` or `make help` for the list.
|
|
5
|
+
|
|
6
|
+
.DEFAULT_GOAL := help
|
|
7
|
+
.PHONY: help setup dev build start test test-coverage gate lint format typecheck \
|
|
8
|
+
check-circular audit openapi migrate migrate-undo seed load-smoke load-stress \
|
|
9
|
+
load-soak up down logs
|
|
10
|
+
|
|
11
|
+
help: ## Show this help
|
|
12
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
|
|
13
|
+
| awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}'
|
|
14
|
+
|
|
15
|
+
setup: ## First-run: install deps (the agent flow uses /infra-setup; this is the manual path)
|
|
16
|
+
npm install
|
|
17
|
+
|
|
18
|
+
dev: ## Run the dev server (tsx watch)
|
|
19
|
+
npm run dev
|
|
20
|
+
|
|
21
|
+
build: ## Compile TypeScript to dist/
|
|
22
|
+
npm run build
|
|
23
|
+
|
|
24
|
+
start: ## Run the compiled server
|
|
25
|
+
npm run start
|
|
26
|
+
|
|
27
|
+
test: ## Run the test suite
|
|
28
|
+
npm test
|
|
29
|
+
|
|
30
|
+
test-coverage: ## Run tests with coverage (per-layer thresholds enforced)
|
|
31
|
+
npm run test:coverage
|
|
32
|
+
|
|
33
|
+
gate: ## The deterministic gate: typecheck + lint + circular-check + arch tests
|
|
34
|
+
npm run gate
|
|
35
|
+
|
|
36
|
+
lint: ## ESLint (0 warnings; includes layer-boundary enforcement)
|
|
37
|
+
npm run lint
|
|
38
|
+
|
|
39
|
+
format: ## Prettier write
|
|
40
|
+
npm run format
|
|
41
|
+
|
|
42
|
+
typecheck: ## tsc --noEmit
|
|
43
|
+
npm run typecheck
|
|
44
|
+
|
|
45
|
+
check-circular: ## madge circular-import check
|
|
46
|
+
npm run check:circular
|
|
47
|
+
|
|
48
|
+
audit: ## npm audit (fail on high+)
|
|
49
|
+
npm run audit
|
|
50
|
+
|
|
51
|
+
openapi: ## Regenerate docs/generated/openapi.{json,yaml}
|
|
52
|
+
npm run openapi:export
|
|
53
|
+
|
|
54
|
+
migrate: ## Run DB migrations
|
|
55
|
+
npm run db:migrate
|
|
56
|
+
|
|
57
|
+
migrate-undo: ## Revert the last migration
|
|
58
|
+
npm run db:migrate:undo
|
|
59
|
+
|
|
60
|
+
seed: ## Seed the database
|
|
61
|
+
npm run db:seed
|
|
62
|
+
|
|
63
|
+
load-smoke: ## k6 smoke test
|
|
64
|
+
npm run load:smoke
|
|
65
|
+
|
|
66
|
+
load-stress: ## k6 stress test
|
|
67
|
+
npm run load:stress
|
|
68
|
+
|
|
69
|
+
load-soak: ## k6 soak test
|
|
70
|
+
npm run load:soak
|
|
71
|
+
|
|
72
|
+
up: ## Start the local stack (postgres, redis, app, lgtm, alloy)
|
|
73
|
+
docker compose up -d
|
|
74
|
+
|
|
75
|
+
down: ## Stop the local stack and remove volumes
|
|
76
|
+
docker compose down -v
|
|
77
|
+
|
|
78
|
+
logs: ## Tail the app container logs
|
|
79
|
+
docker compose logs -f app
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# QUICKSTART — Your First 30 Minutes
|
|
2
|
+
|
|
3
|
+
This is an **agent-first** backend template. You don't write code by hand — you
|
|
4
|
+
drive [Claude Code](https://claude.com/claude-code) through a gated, layer-by-layer
|
|
5
|
+
flow. This guide gets you from clone to first feature.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What is this template?
|
|
10
|
+
|
|
11
|
+
A governance skeleton for building Express + TypeScript + Sequelize backends with
|
|
12
|
+
Claude Code. It ships with:
|
|
13
|
+
|
|
14
|
+
- **Rules** (`.claude/rules/`) auto-injected when Claude edits matching files
|
|
15
|
+
- **Skills** (`.claude/skills/`) — the `/slash-commands` that drive the workflow
|
|
16
|
+
- **Agents** (`.claude/agents/`) — e.g. the `gate-checker` that blocks bad layers
|
|
17
|
+
- **Config** (`package.json`, `tsconfig.json`, `jest.config.ts`, `Dockerfile`, …) ready to run
|
|
18
|
+
- **Docs** (`docs/`) — specs, plans, ADRs, quality scores
|
|
19
|
+
|
|
20
|
+
It does **not** ship application code. `/infra-setup` generates `src/` on first run.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
| Tool | Version | Check |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Node.js | 24 LTS | `node -v` |
|
|
29
|
+
| npm | 11+ | `npm -v` |
|
|
30
|
+
| Docker Desktop | latest | `docker --version` |
|
|
31
|
+
| Claude Code | latest | `claude --version` |
|
|
32
|
+
| Git | any recent | `git --version` |
|
|
33
|
+
|
|
34
|
+
Install Claude Code: see https://claude.com/claude-code. Open this folder in your
|
|
35
|
+
IDE (the VS Code / JetBrains extension) or run `claude` in the terminal here.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Step 1 — Start the local services
|
|
40
|
+
|
|
41
|
+
The template includes Postgres + Redis (and an app container) via Docker Compose:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cp .env.example .env # then fill in JWT_SECRET and any blanks
|
|
45
|
+
docker compose up -d postgres redis
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Step 2 — Run infrastructure setup (once)
|
|
49
|
+
|
|
50
|
+
In Claude Code, run:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
/infra-setup
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This installs dependencies (latest LTS — nothing is version-pinned), generates the
|
|
57
|
+
full `src/` layer structure, providers, middleware, health checks, and the ADR-000
|
|
58
|
+
record, then runs the gate and commits. It refuses to run twice (aborts if `src/` exists).
|
|
59
|
+
|
|
60
|
+
When it finishes you should be able to:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm run dev # server on http://localhost:3000
|
|
64
|
+
curl localhost:3000/health # → { "ok": true, ... }
|
|
65
|
+
npm test # green
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Step 3 — Build your first feature
|
|
69
|
+
|
|
70
|
+
Planning a whole product first? Run `/write-roadmap` (brief → ordered, dependency-aware specs in
|
|
71
|
+
`docs/product-specs/ROADMAP.md`), then author each spec down the list. The flow for **every**
|
|
72
|
+
feature is the same:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
/write-roadmap → (whole product, optional) brief → ordered, dependency-aware spec roadmap
|
|
76
|
+
↓ (review the roadmap; build the walking-skeleton spec first, then go down the list)
|
|
77
|
+
/write-spec → describe what you're building (roadmap-guided; saved to docs/product-specs/draft/)
|
|
78
|
+
↓ (you review the spec and mark it READY)
|
|
79
|
+
/write-plan → turns the spec into a layered execution plan
|
|
80
|
+
↓
|
|
81
|
+
/build-layer → builds the next unchecked layer, runs the gate, commits
|
|
82
|
+
↓ (repeat /build-layer until all layers are checked off)
|
|
83
|
+
/garbage-collect → end-of-feature cleanup, closes the plan
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`/build-layer` is the heartbeat: it builds **one layer**, runs the `gate-checker`
|
|
87
|
+
agent, auto-fixes failures (up to 3 attempts), commits, and then **waits for you**
|
|
88
|
+
before the next layer. You stay in control at every boundary.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## What to expect
|
|
93
|
+
|
|
94
|
+
- **You approve direction, the agent does the typing.** Read each layer summary
|
|
95
|
+
before confirming the next.
|
|
96
|
+
- **The gate is non-negotiable.** A layer can't be committed until tsc, eslint,
|
|
97
|
+
madge (circular imports), and the architecture tests pass.
|
|
98
|
+
- **Rules enforce themselves.** Try adding a `console.log` in a service — the
|
|
99
|
+
post-write hook warns you and the gate blocks it. Use `logger` instead.
|
|
100
|
+
- **Everything is documented.** Non-obvious decisions become ADRs in
|
|
101
|
+
`docs/design-docs/decisions/`.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Where to look next
|
|
106
|
+
|
|
107
|
+
| You want to… | Read |
|
|
108
|
+
|---|---|
|
|
109
|
+
| Understand the layers | `ARCHITECTURE.md` |
|
|
110
|
+
| Understand the *why* | `docs/design-docs/core-beliefs.md` |
|
|
111
|
+
| See all commands | `AGENTS.md` |
|
|
112
|
+
| Know the plan format | `docs/PLANS.md` |
|
|
113
|
+
| Work as a team | `docs/design-docs/team-workflow.md` |
|
|
114
|
+
| Check domain health | `docs/QUALITY_SCORE.md` |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Troubleshooting
|
|
119
|
+
|
|
120
|
+
- **`/infra-setup` says it's already set up** — `src/` exists. It only runs once per repo.
|
|
121
|
+
- **`npm test` fails right after clone** — expected. Tests need `npm install` + the
|
|
122
|
+
source `/infra-setup` generates. Run `/infra-setup` first.
|
|
123
|
+
- **DB connection refused** — `docker compose up -d postgres redis` and confirm
|
|
124
|
+
`DATABASE_URL` in `.env` matches the compose credentials.
|
|
125
|
+
- **A skill feels stale** — check its `verified:` date in the frontmatter. If it's
|
|
126
|
+
>60 days old, Claude will re-check library versions before following it (see the
|
|
127
|
+
Skill Freshness Check in `.claude/CLAUDE.md`).
|
|
128
|
+
- **Load tests** — install k6 (`choco install k6` on Windows, `brew install k6` on
|
|
129
|
+
macOS), start the server, then `npm run load:smoke`. The shipped scripts hit
|
|
130
|
+
`/health` out of the box. In CI, run the **Load Test** workflow manually from the
|
|
131
|
+
Actions tab (it never runs on push/PR). See `/load-test`.
|