baldart 3.14.1 → 3.16.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/CHANGELOG.md +79 -0
- package/VERSION +1 -1
- package/framework/.claude/agents/REGISTRY.md +10 -0
- package/framework/.claude/agents/api-perf-cost-auditor.md +47 -10
- package/framework/.claude/agents/coder.md +61 -10
- package/framework/.claude/agents/prd-card-writer.md +92 -19
- package/framework/.claude/agents/security-reviewer.md +1 -1
- package/framework/.claude/skills/bug/references/logging-patterns.md +45 -8
- package/framework/.claude/skills/new/SKILL.md +319 -87
- package/framework/.claude/skills/prd/SKILL.md +30 -2
- package/framework/.claude/skills/prd/assets/card-template.yml +59 -27
- package/framework/.claude/skills/prd/assets/epic-template.yml +11 -3
- package/framework/.claude/skills/prd/assets/prd-template.md +90 -14
- package/framework/.claude/skills/prd/assets/state-template.md +18 -0
- package/framework/.claude/skills/prd/references/api-perf-gate.md +102 -52
- package/framework/.claude/skills/prd/references/audit-phase.md +13 -13
- package/framework/.claude/skills/prd/references/backlog-phase.md +81 -0
- package/framework/.claude/skills/prd/references/discovery-phase.md +214 -28
- package/framework/.claude/skills/prd/references/prd-writing-phase.md +65 -23
- package/framework/.claude/skills/prd/references/research-phase.md +22 -4
- package/framework/.claude/skills/prd/references/ui-design-phase.md +115 -3
- package/framework/.claude/skills/prd/references/validation-phase.md +22 -2
- package/framework/docs/PROJECT-CONFIGURATION.md +41 -1
- package/framework/templates/baldart.config.template.yml +25 -0
- package/package.json +1 -1
- package/src/commands/configure.js +72 -0
- package/src/commands/update.js +13 -1
|
@@ -14,13 +14,21 @@ flagged after implementation.
|
|
|
14
14
|
|
|
15
15
|
**Gates 1-4 run ONLY** when Gate 5 finds matches OR the PRD contains any of:
|
|
16
16
|
- `## API contract changes` section with endpoints
|
|
17
|
-
- `## Data model` section with new
|
|
18
|
-
|
|
17
|
+
- `## Data model` section with new {entity}s/{field}s (collections+documents in
|
|
18
|
+
Firestore/Mongo, tables+rows in SQL, items in DynamoDB)
|
|
19
|
+
- Server-side mutations touching the persistence layer
|
|
19
20
|
- Background jobs, cron, batch operations
|
|
20
21
|
|
|
21
22
|
If none of the above: log `API Performance Gate: N/A — no API/data surface` in
|
|
22
23
|
state file and skip to "Present and Confirm".
|
|
23
24
|
|
|
25
|
+
**Stack-awareness:** before running Gates 1-4, read `stack.database` and
|
|
26
|
+
`stack.framework` from `baldart.config.yml`. The gate sections below have a
|
|
27
|
+
universal core (works for any stack) PLUS stack-specific addenda that activate
|
|
28
|
+
only when the matching value is set. When `stack.database: ""` (unset), the
|
|
29
|
+
gate degrades to the universal core and logs a recommendation to run `npx
|
|
30
|
+
baldart configure` so future gates pick up the stack-specific rules.
|
|
31
|
+
|
|
24
32
|
---
|
|
25
33
|
|
|
26
34
|
## The 5-Gate Protocol
|
|
@@ -39,50 +47,80 @@ Scan the PRD text for these keywords. Each match = a finding.
|
|
|
39
47
|
| "no limit" / "unlimited" / "senza limiti" / "illimitato" | Unbounded data growth | HIGH |
|
|
40
48
|
| "save all in document" / "embed list" / "array nel documento" | Unbounded array in doc (max 1MB, degrades at 40K) | HIGH |
|
|
41
49
|
| "upload file/image via API" / "carica file" | 4.5MB payload limit on Vercel Functions | HIGH |
|
|
42
|
-
| "
|
|
43
|
-
| "
|
|
44
|
-
| "
|
|
45
|
-
| "
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
| "search by name" / "full-text search" / "cerca per nome" | Many DBs need a dedicated search index (Algolia/Typesense/Postgres FTS/Mongo Atlas Search) — DB-specific | HIGH |
|
|
51
|
+
| "page N" / "skip" / "offset" / "pagina N" | Offset pagination is inefficient in most DBs (Firestore charges for skipped docs; SQL scans them) | MEDIUM |
|
|
52
|
+
| "send email/SMS" in request path / "invia email/SMS" | Blocking I/O in request path (use waitUntil / background job) | MEDIUM |
|
|
53
|
+
| "filter by A and B and C" / "filtra per A e B e C" | Composite index explosion (Firestore: explicit indexes; SQL: pick a covering index; Mongo: compound index) | MEDIUM |
|
|
54
|
+
|
|
55
|
+
**Stack-specific keyword addenda** (apply only when matching `stack.database`):
|
|
56
|
+
|
|
57
|
+
| Stack | Keyword | Problem | Severity |
|
|
58
|
+
|-------|---------|---------|----------|
|
|
59
|
+
| firestore | "auto-increment ID" / "sequential ID" / "ID sequenziale" | Firestore write hotspot (sequential keys serialize on a single tablet) | HIGH |
|
|
60
|
+
| firestore | "import CSV" / "bulk insert" / "importa CSV" | Firestore batch limit: 500 docs/write | MEDIUM |
|
|
61
|
+
| firestore / mongodb | "save all in document" / "embed list" / "array nel documento" | Unbounded array in doc (Firestore max 1MB, degrades >40K elements; Mongo 16MB doc cap) | HIGH |
|
|
62
|
+
| postgres / supabase | "SELECT \\*" on hot path | Avoid; specify columns to keep index-only scans viable | MEDIUM |
|
|
63
|
+
| postgres / supabase | "JSONB column" + indexed query | Verify GIN index exists | MEDIUM |
|
|
64
|
+
| dynamodb | "filter expression" instead of KeyCondition | Filter scans full partition — pick a GSI instead | HIGH |
|
|
48
65
|
|
|
49
66
|
**If 0 matches AND no API/data sections**: skip Gates 1-4, proceed to present.
|
|
50
67
|
**If any match**: continue to Gates 1-4.
|
|
51
68
|
|
|
52
69
|
### Gate 1 — Data Model Review
|
|
53
70
|
|
|
54
|
-
|
|
71
|
+
Universal checks (apply to any persistence layer):
|
|
55
72
|
|
|
56
|
-
- [ ] **Unbounded arrays**: any array field that can grow without limit → CRITICAL
|
|
57
|
-
- [ ] **
|
|
58
|
-
- [ ] **
|
|
59
|
-
- [ ] **
|
|
60
|
-
- [ ] **Global counters**: fields incremented by many concurrent writers → HIGH (transaction serialization)
|
|
61
|
-
- [ ] **Real-time listeners**: justified? Can polling or ISR replace them? → HIGH (1 read/matched doc at attach)
|
|
73
|
+
- [ ] **Unbounded arrays/lists**: any array field/JSONB column/list-typed attribute that can grow without limit → CRITICAL
|
|
74
|
+
- [ ] **Row/document size**: will any row exceed a healthy size (Firestore ~100KB, Mongo 16MB, Postgres tuple alignment) regularly? → HIGH
|
|
75
|
+
- [ ] **Fan-out writes**: one user action writing to N rows/docs where N scales with users/data → HIGH
|
|
76
|
+
- [ ] **Global counters**: columns/fields incremented by many concurrent writers → HIGH (write-skew, contention, or transaction serialization depending on stack)
|
|
62
77
|
- [ ] **Denormalization strategy**: read-heavy paths should denormalize; write-heavy should normalize → MEDIUM
|
|
63
|
-
|
|
78
|
+
|
|
79
|
+
Stack-specific addenda (activate when matching `stack.database`):
|
|
80
|
+
|
|
81
|
+
- [ ] firestore: **Sequential/predictable IDs** (timestamp/counter) → HIGH (write hotspot, use auto-ID)
|
|
82
|
+
- [ ] firestore: **Real-time listeners** — justified? Can polling or ISR replace them? → HIGH (1 read/matched doc at attach + 1 per change)
|
|
83
|
+
- [ ] firestore: **Index exemptions** for large text fields → MEDIUM (N+1 index writes per doc write)
|
|
84
|
+
- [ ] mongodb: **Embedded vs referenced** — embedded grows the parent doc; referenced needs $lookup → MEDIUM
|
|
85
|
+
- [ ] postgres/supabase: **JSONB vs typed columns** — JSONB without GIN index = full scan → MEDIUM
|
|
86
|
+
- [ ] supabase: **RLS coverage** — every new table MUST have RLS policies aligned with the auth contract → CRITICAL
|
|
87
|
+
- [ ] dynamodb: **Hot partition** — does the partition key distribute evenly under load? → HIGH
|
|
64
88
|
|
|
65
89
|
### Gate 2 — Query & Index Review
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
Universal checks:
|
|
92
|
+
|
|
93
|
+
- [ ] **Pagination on all list endpoints**: every endpoint returning multiple rows/docs MUST specify cursor-based pagination (keyset / `startAfter` / `cursor`), never raw offset → CRITICAL
|
|
94
|
+
- [ ] **N+1 queries**: "get parent, then for each child get details" pattern → CRITICAL (use a single query with join / `collectionGroup` / `$lookup` / denormalize depending on stack)
|
|
95
|
+
- [ ] **Index table completeness**: if the PRD has read endpoints touching the persistence layer but Section 5 has no `### Database Indexes & Query Optimization` table (or says "nessun indice"), verify this is actually correct by checking each query pattern. Missing the table when compound queries exist → **CRITICAL**
|
|
96
|
+
|
|
97
|
+
Stack-specific addenda:
|
|
68
98
|
|
|
69
|
-
- [ ] **
|
|
70
|
-
- [ ] **
|
|
71
|
-
- [ ]
|
|
72
|
-
- [ ] **
|
|
73
|
-
- [ ] **
|
|
74
|
-
- [ ] **
|
|
75
|
-
- [ ] **
|
|
99
|
+
- [ ] firestore: **Composite index** for every query combining `where()` + `orderBy()` on different fields or multiple `where()` on different fields MUST appear in the PRD index table (Variant A). Missing index = runtime FAILED_PRECONDITION → **CRITICAL**
|
|
100
|
+
- [ ] firestore: **orderBy + inequality on different fields** requires composite index, max 1 inequality per query (inequality field MUST be last) → HIGH
|
|
101
|
+
- [ ] firestore: **>3 inequality filters on different fields** = index explosion → MEDIUM
|
|
102
|
+
- [ ] firestore: **Full-text search** — not native, needs Algolia/Typesense or array-contains workaround → HIGH
|
|
103
|
+
- [ ] postgres/supabase: **EXPLAIN check** on the slowest query in the PRD — sequential scans on >100k rows → CRITICAL
|
|
104
|
+
- [ ] postgres/supabase: **Covering index** for hot read paths → MEDIUM
|
|
105
|
+
- [ ] mongodb: **Compound index field order** matches query equality → range → sort rule → HIGH
|
|
106
|
+
- [ ] dynamodb: **GSI / LSI definition** for every access pattern that doesn't hit the primary key → CRITICAL
|
|
76
107
|
|
|
77
|
-
### Gate 3 — Serverless Architecture Review
|
|
108
|
+
### Gate 3 — Serverless / Runtime Architecture Review
|
|
78
109
|
|
|
79
|
-
|
|
110
|
+
Universal checks:
|
|
80
111
|
|
|
81
|
-
- [ ] **Payload size**: any endpoint accepting/returning >4.5MB → CRITICAL (use signed URL pattern
|
|
82
|
-
- [ ] **Sync vs async**: long operations (email, PDF, image processing) in request path → HIGH (use waitUntil
|
|
83
|
-
- [ ] **Function duration**: operations that may exceed
|
|
84
|
-
- [ ] **CPU-intensive ops**: image resize, PDF gen, heavy computation in serverless → MEDIUM (consider dedicated worker)
|
|
85
|
-
|
|
112
|
+
- [ ] **Payload size**: any endpoint accepting/returning >4.5MB → CRITICAL (use signed URL / multipart upload pattern). Limit varies by deployment (Vercel 4.5MB, Cloudflare Workers 100MB, AWS Lambda 6MB sync) — calibrate to `stack.deployment`.
|
|
113
|
+
- [ ] **Sync vs async**: long operations (email, PDF, image processing) in request path → HIGH (use queue / waitUntil / background worker per stack)
|
|
114
|
+
- [ ] **Function duration**: operations that may exceed the platform timeout (Vercel 300s Hobby / 800s Pro; Lambda 900s; Cloudflare Workers 30s CPU) → HIGH
|
|
115
|
+
- [ ] **CPU-intensive ops**: image resize, PDF gen, heavy computation in serverless → MEDIUM (consider dedicated worker / container)
|
|
116
|
+
|
|
117
|
+
Stack-specific addenda (`stack.framework`):
|
|
118
|
+
|
|
119
|
+
- [ ] nextjs: **GET Route Handler caching** — new GET endpoints MUST specify `revalidate` or `use cache` — dynamic by default since Next.js 15 → HIGH
|
|
120
|
+
- [ ] nextjs: **Server Action vs Route Handler** chosen explicitly per use case → MEDIUM
|
|
121
|
+
- [ ] remix: **`loader`/`action` separation** + `headers` for `Cache-Control` set explicitly → MEDIUM
|
|
122
|
+
- [ ] sveltekit: **`+page.server.ts` vs `+page.ts`** chosen explicitly; Edge vs Node runtime declared → MEDIUM
|
|
123
|
+
- [ ] astro: **`output: 'static'|'server'|'hybrid'`** declared per route group; `prerender` flag set for static routes → MEDIUM
|
|
86
124
|
|
|
87
125
|
### Gate 4 — Caching Strategy Review
|
|
88
126
|
|
|
@@ -123,30 +161,42 @@ Check data display and freshness requirements for:
|
|
|
123
161
|
|
|
124
162
|
## Reference Data
|
|
125
163
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
164
|
+
Cite ONLY the section matching the project's `stack.database` /
|
|
165
|
+
`stack.framework` / `stack.deployment`. Sections for other stacks are
|
|
166
|
+
informational and should be removed from the populated PRD section.
|
|
167
|
+
|
|
168
|
+
### Database pricing & cost-model snapshots
|
|
169
|
+
|
|
170
|
+
**Firestore (Blaze Plan):** Reads $0.06/100K, Writes $0.18/100K, Deletes $0.02/100K. Offset pagination charges for ALL skipped docs. Index writes: N+1 per document. Listener: 1 read/matched doc at attach + 1 per change.
|
|
171
|
+
|
|
172
|
+
**Supabase / Postgres:** Compute + storage + egress billing. Hot row updates serialize on a single page; HOT updates and `FILLFACTOR` matter for write-heavy tables. Sequential scan >100k rows is a HIGH finding regardless of price.
|
|
173
|
+
|
|
174
|
+
**MongoDB Atlas:** Cluster tier dictates IOPS ceiling. Aggregation `$lookup` cost ≈ N queries when uncached. WiredTiger cache hit rate <90% on hot path = HIGH finding.
|
|
175
|
+
|
|
176
|
+
**DynamoDB:** On-demand vs provisioned billing model dictates RCU/WCU sizing. Hot partition (skewed PK distribution) triggers throttle errors before billing impact shows.
|
|
177
|
+
|
|
178
|
+
### Runtime limits (by `stack.deployment`)
|
|
179
|
+
|
|
180
|
+
| Platform | Payload | Duration | Notes |
|
|
181
|
+
|----------|---------|----------|-------|
|
|
182
|
+
| Vercel (Fluid Compute) | 4.5 MB | 300s Hobby / 800s Pro | Active CPU pricing, FD limit 1024 shared, archived after 2w prod / 48h preview |
|
|
183
|
+
| Cloudflare Workers | 100 MB | 30s CPU | No FD pool, smaller heap |
|
|
184
|
+
| AWS Lambda | 6 MB sync / 256 KB async | 900s | Cold start ~100-500ms; provisioned concurrency to mitigate |
|
|
185
|
+
| Firebase Functions (gen 2) | 32 MB | 540s 2nd-gen | Cold start ~200-2000ms |
|
|
186
|
+
|
|
187
|
+
### Framework caching primitives (by `stack.framework`)
|
|
188
|
+
|
|
189
|
+
**Next.js App Router:** GET Route Handlers DYNAMIC by default since v15 (opt-in to caching via `revalidate` / `'use cache'`). `'use cache'` in serverless: in-memory LRU, not persisted across cold starts. `React.cache()`: single-request dedup only. Sequential `await` = waterfall; use `Promise.all()` for independent fetches.
|
|
190
|
+
|
|
191
|
+
**Remix:** `headers` function sets `Cache-Control`; `loader` revalidation via `shouldRevalidate`. No built-in cache layer — relies on CDN.
|
|
192
|
+
|
|
193
|
+
**SvelteKit:** `setHeaders({'cache-control': ...})` in `load`; `prerender = true` for static; Edge vs Node runtime per route.
|
|
194
|
+
|
|
195
|
+
**Astro:** SSG by default; `output: 'server'` enables on-demand rendering; per-route `prerender` toggle.
|
|
146
196
|
|
|
147
197
|
### When to Skip
|
|
148
198
|
|
|
149
199
|
- Hotfix cards (single-line bug fixes): Gate 5 only
|
|
150
|
-
- Purely frontend cards (no API
|
|
200
|
+
- Purely frontend cards (no persistence/API touch): skip entirely
|
|
151
201
|
- Documentation-only: skip entirely
|
|
152
202
|
- Prototype/spike (throw-away): skip entirely
|
|
@@ -24,11 +24,11 @@ Scan each card for security signals to decide whether the `security-reviewer` ag
|
|
|
24
24
|
|--------|---------------|
|
|
25
25
|
| **New or modified API route** | `files_likely_touched` contains `route.ts`, `api/`, or requirements mention new endpoints |
|
|
26
26
|
| **Authentication/authorization changes** | Requirements/files mention `withAuth`, `checkPermission`, `permissions`, login, session, token, JWT, OAuth |
|
|
27
|
-
| **
|
|
27
|
+
| **Persistence-layer access rules** | `files_likely_touched` contains rule/policy files matching `stack.database` (e.g. `firestore.rules`, Supabase RLS migration, MongoDB validator) or requirements mention rule changes |
|
|
28
28
|
| **External integrations** | Requirements mention webhooks, third-party APIs, payment, SMS, email providers, or external callbacks |
|
|
29
29
|
| **File upload or media handling** | Requirements mention upload, image, file, media, or `files_likely_touched` contains upload/media paths |
|
|
30
30
|
| **User input processing** | Requirements mention forms, search, filters, or query parameters that flow into DB queries or server logic |
|
|
31
|
-
| **Multi-tenant data access** | Requirements mention cross-
|
|
31
|
+
| **Multi-tenant data access** | Requirements mention cross-tenant boundaries (cross-org, cross-workspace, cross-store, cross-account — actual tenant noun from `identity.audience_segments[]`) or data visible to multiple tenants |
|
|
32
32
|
| **Sensitive data handling** | Requirements mention PII, credentials, tokens, secrets, or personal data |
|
|
33
33
|
|
|
34
34
|
**How to assess**: Read each card's `requirements`, `acceptance_criteria`, `files_likely_touched`, `areas`, `existing_patterns`, `anti_patterns`, `validation_commands`, `error_handling`, and `scope_boundaries` fields. This is a deterministic check — no LLM judgment calls needed.
|
|
@@ -48,7 +48,7 @@ Scan each card for performance signals to decide whether the `api-perf-cost-audi
|
|
|
48
48
|
| Signal | Where to look |
|
|
49
49
|
|--------|---------------|
|
|
50
50
|
| **New or modified API route** | `files_likely_touched` contains `route.ts`, `api/`, or requirements mention new endpoints |
|
|
51
|
-
| **
|
|
51
|
+
| **Persistence-layer read/write operations** | Requirements mention {entity} read/write, query, transaction, batch, listener/subscription/change-stream (terminology depends on `stack.database`) |
|
|
52
52
|
| **List/search/filter endpoints** | Requirements mention listing, searching, filtering, sorting, pagination, or "show all" |
|
|
53
53
|
| **Background/batch processing** | Requirements mention cron, batch, import, export, bulk, queue, or scheduled tasks |
|
|
54
54
|
| **Real-time/live updates** | Requirements mention real-time, live, auto-update, listener, onSnapshot, subscription |
|
|
@@ -172,12 +172,12 @@ Requirements smell detection:
|
|
|
172
172
|
- Compound requirements covering multiple behaviors
|
|
173
173
|
- Dependency shadows: implicit deps not in depends_on
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
175
|
+
Database-specific (apply the subset matching `stack.database`):
|
|
176
|
+
- Universal: unbounded reads without limit, offset-based pagination instead of cursor/keyset, N+1 read in loops, transaction/concurrency hotspot risks
|
|
177
|
+
- firestore: missing composite index declarations, sequential-ID hotspots, listener attach cost not budgeted
|
|
178
|
+
- postgres/supabase: sequential scan on >100k rows, RLS policy missing on new table, JSONB without GIN index
|
|
179
|
+
- mongodb: missing compound index for hot aggregation, embedded array unbounded growth
|
|
180
|
+
- dynamodb: missing GSI for non-PK access pattern, hot-partition risk
|
|
181
181
|
|
|
182
182
|
Card structure:
|
|
183
183
|
- files_likely_touched missing entries or conflicting across cards
|
|
@@ -339,8 +339,8 @@ After challenge pass, rank ALL surviving findings relative to each other by impa
|
|
|
339
339
|
### Severity Calibration Examples
|
|
340
340
|
|
|
341
341
|
**HIGH** (must fix before implementation):
|
|
342
|
-
- "acceptance_criteria says 'user can see
|
|
343
|
-
> Evidence: "AC-2:
|
|
342
|
+
- "acceptance_criteria says 'user can see <list>' but doesn't specify pagination → unbounded persistence-layer read"
|
|
343
|
+
> Evidence: "AC-2: <persona from identity.audience_segments[]> views <entity>" — no limit/pagination mentioned
|
|
344
344
|
|
|
345
345
|
**MEDIUM** (should fix, skip if ambiguous):
|
|
346
346
|
- "files_likely_touched missing the API route doc update"
|
|
@@ -359,9 +359,9 @@ After challenge pass, rank ALL surviving findings relative to each other by impa
|
|
|
359
359
|
|
|
360
360
|
**doc-reviewer**: Check documentation links, PRD references are valid and aligned, planned changes requiring doc updates not mentioned. Verify `files_likely_touched` includes doc files. Check `areas` completeness. Flag `git_strategy: TBD`. Include Obsidian trigger assessment (section H) in findings -- evaluate whether the planned docs will require KB sync per `.claude/skills/doc-reviewer-support/references/obsidian-integration.md`.
|
|
361
361
|
|
|
362
|
-
**api-perf-cost-auditor** (only when `perf_review_needed: true`): Apply the 5-gate protocol from `.claude/agent-memory/senior-researcher/api-perf-cost-audit-protocol.md`. Read referenced source files.
|
|
362
|
+
**api-perf-cost-auditor** (only when `perf_review_needed: true`): Apply the 5-gate protocol from `.claude/agent-memory/senior-researcher/api-perf-cost-audit-protocol.md`. Read referenced source files. Universal checks: unbounded reads, N+1 queries, fan-out writes, missing pagination, offset pagination, listener vs polling costs, payload size limits per `stack.deployment`, transaction hotspots. Stack-specific addenda apply per `stack.database` + `stack.framework` (see `framework/.claude/skills/prd/references/api-perf-gate.md`).
|
|
363
363
|
|
|
364
|
-
**security-reviewer** (only when `security_review_needed: true`): Read `.claude/agents/security-reviewer.md` for full methodology. Focus on: auth gaps, input validation, multi-tenant isolation, Firestore rules
|
|
364
|
+
**security-reviewer** (only when `security_review_needed: true`): Read `.claude/agents/security-reviewer.md` for full methodology. Focus on: auth gaps, input validation, multi-tenant isolation, persistence-layer access rules alignment (Firestore rules / Supabase RLS / Mongo validator / DynamoDB IAM — per `stack.database`), sensitive data exposure, webhook validation, rate limiting, IDOR risks.
|
|
365
365
|
|
|
366
366
|
## Step 6.7 — Collect & Merge Findings
|
|
367
367
|
|
|
@@ -4,6 +4,87 @@
|
|
|
4
4
|
|
|
5
5
|
Mark task 4 as `in_progress`.
|
|
6
6
|
|
|
7
|
+
## MANDATORY Card Rules (zero tolerance — read first)
|
|
8
|
+
|
|
9
|
+
These two rules apply to EVERY child card (epics use `owner_agent: ""`). The
|
|
10
|
+
`prd-card-writer` agent enforces them; the skill MUST verify post-generation
|
|
11
|
+
and HALT if violated.
|
|
12
|
+
|
|
13
|
+
### Rule A — `owner_agent` is mandatory and enum-validated
|
|
14
|
+
|
|
15
|
+
Every child card MUST declare `owner_agent` with one of the five values:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
coder | ui-expert | plan | visual-designer | motion-expert
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
There is no implicit default and `claude` is NOT a valid value. Cards with
|
|
22
|
+
missing, empty, placeholder, or non-enum values fail Step 6 (validation-phase)
|
|
23
|
+
and BLOCK the commit. The `/new` orchestrator dispatches implementation
|
|
24
|
+
agent by this field (see `framework/.claude/skills/new/SKILL.md` § Agent
|
|
25
|
+
Routing), so a wrong value silently routes the card to the wrong specialist.
|
|
26
|
+
|
|
27
|
+
### Rule B — UI cards have UI-only scope (no mixed scope)
|
|
28
|
+
|
|
29
|
+
A card with `owner_agent: ui-expert` MUST be scoped EXCLUSIVELY to graphical
|
|
30
|
+
concerns: components, layout, styling, token usage, motion, accessibility.
|
|
31
|
+
It MUST NOT bundle:
|
|
32
|
+
|
|
33
|
+
- business logic / domain rules
|
|
34
|
+
- API integration or data fetching
|
|
35
|
+
- state management beyond local UI state
|
|
36
|
+
- form validation logic (rendering validation states is UI; the rules are not)
|
|
37
|
+
- backend changes (routes, handlers, DB schema)
|
|
38
|
+
|
|
39
|
+
If a feature step involves BOTH UI and logic, the writer MUST split it into:
|
|
40
|
+
|
|
41
|
+
- one `owner_agent: ui-expert` card — visual implementation, consumes mocked
|
|
42
|
+
or contract-stable data
|
|
43
|
+
- one `owner_agent: coder` card — logic, API call, state, persistence
|
|
44
|
+
|
|
45
|
+
The two cards are wired via `depends_on:` / `blocks:`. A common ordering is
|
|
46
|
+
`coder → ui-expert` (contract ready before UI), but the reverse is acceptable
|
|
47
|
+
when the UI card consumes a hand-written mock.
|
|
48
|
+
|
|
49
|
+
#### Split example — Login feature
|
|
50
|
+
|
|
51
|
+
**Bad** (single mixed card):
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
id: FEAT-XXXX-01
|
|
55
|
+
owner_agent: coder
|
|
56
|
+
scope:
|
|
57
|
+
summary: |
|
|
58
|
+
Implement the login page: form layout, validation states, call to
|
|
59
|
+
POST /api/auth/login, token storage, redirect to dashboard.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Good** (split into UI + logic):
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
# UI card — visual only, consumes a mocked auth contract
|
|
66
|
+
id: FEAT-XXXX-02
|
|
67
|
+
owner_agent: ui-expert
|
|
68
|
+
depends_on: [FEAT-XXXX-01]
|
|
69
|
+
scope:
|
|
70
|
+
summary: |
|
|
71
|
+
Login form layout (email/password fields, primary CTA, link to recovery),
|
|
72
|
+
visual states (idle / loading / error / success), a11y (focus order,
|
|
73
|
+
aria-live for inline errors), responsive breakpoints. Consumes the
|
|
74
|
+
`useAuth()` mock provided by FEAT-XXXX-01.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
# Logic card — API call + state + redirect
|
|
79
|
+
id: FEAT-XXXX-01
|
|
80
|
+
owner_agent: coder
|
|
81
|
+
blocks: [FEAT-XXXX-02]
|
|
82
|
+
scope:
|
|
83
|
+
summary: |
|
|
84
|
+
POST /api/auth/login handler, token storage in httpOnly cookie, redirect
|
|
85
|
+
on success, `useAuth()` hook exposing { status, error, signIn }.
|
|
86
|
+
```
|
|
87
|
+
|
|
7
88
|
## MANDATORY Card Structure (zero tolerance — read first)
|
|
8
89
|
|
|
9
90
|
Every PRD generates **1 epic card + N children**, regardless of N. The
|