baldart 3.41.0 → 4.0.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/VERSION +1 -1
  3. package/framework/.claude/agents/REGISTRY.md +72 -24
  4. package/framework/.claude/agents/api-perf-cost-auditor.md +12 -5
  5. package/framework/.claude/agents/code-reviewer.md +30 -23
  6. package/framework/.claude/agents/codebase-architect.md +47 -43
  7. package/framework/.claude/agents/coder.md +29 -18
  8. package/framework/.claude/agents/doc-reviewer.md +55 -28
  9. package/framework/.claude/agents/plan-auditor.md +77 -12
  10. package/framework/.claude/agents/prd-card-writer.md +43 -13
  11. package/framework/.claude/agents/prd.md +22 -3
  12. package/framework/.claude/agents/qa-sentinel.md +33 -15
  13. package/framework/.claude/agents/security-reviewer.md +65 -10
  14. package/framework/.claude/agents/senior-researcher.md +8 -1
  15. package/framework/.claude/agents/ui-expert.md +22 -7
  16. package/framework/.claude/commands/check.md +31 -11
  17. package/framework/.claude/commands/codexreview.md +48 -29
  18. package/framework/.claude/commands/new.md +29 -330
  19. package/framework/.claude/commands/qa.md +57 -37
  20. package/framework/.claude/skills/context-primer/SKILL.md +29 -8
  21. package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +36 -36
  22. package/framework/.claude/skills/frontend-design/SKILL.md +10 -8
  23. package/framework/.claude/skills/new/SKILL.md +409 -302
  24. package/framework/.claude/skills/prd/SKILL.md +67 -38
  25. package/framework/.claude/skills/prd/assets/card-template.yml +22 -26
  26. package/framework/.claude/skills/prd/assets/epic-template.yml +5 -5
  27. package/framework/.claude/skills/prd/assets/state-template.md +25 -3
  28. package/framework/.claude/skills/prd/references/api-perf-gate.md +143 -33
  29. package/framework/.claude/skills/prd/references/audit-phase.md +48 -34
  30. package/framework/.claude/skills/prd/references/backlog-phase.md +38 -11
  31. package/framework/.claude/skills/prd/references/discovery-phase.md +121 -44
  32. package/framework/.claude/skills/prd/references/impact-analysis.md +127 -23
  33. package/framework/.claude/skills/prd/references/prd-add-phase.md +18 -214
  34. package/framework/.claude/skills/prd/references/prd-writing-phase.md +52 -42
  35. package/framework/.claude/skills/prd/references/research-phase.md +105 -19
  36. package/framework/.claude/skills/prd/references/ui-design-phase.md +20 -8
  37. package/framework/.claude/skills/prd/references/validation-phase.md +97 -72
  38. package/framework/.claude/skills/prd-add/SKILL.md +70 -20
  39. package/framework/.claude/skills/simplify/SKILL.md +22 -12
  40. package/framework/.claude/skills/ui-design/SKILL.md +26 -7
  41. package/framework/.claude/skills/webapp-testing/SKILL.md +6 -4
  42. package/framework/.claude/skills/worktree-manager/SKILL.md +206 -143
  43. package/framework/agents/coding-standards.md +85 -0
  44. package/framework/agents/skills-mapping.md +85 -82
  45. package/framework/agents/testing.md +6 -4
  46. package/framework/templates/baldart.config.template.yml +29 -7
  47. package/package.json +1 -1
  48. package/src/commands/configure.js +43 -9
  49. package/framework/.claude/skills/prd-add/references/impact-analysis.md +0 -233
@@ -6,11 +6,34 @@ This gate audits the PRD for performance bottlenecks and cost inefficiencies
6
6
  **before** the user sees it, so findings are integrated into the spec — not
7
7
  flagged after implementation.
8
8
 
9
+ > **Execution model:** This protocol is run by the `api-perf-cost-auditor`
10
+ > agent when invoked at Step 4.5. The `/prd` skill spawns the agent via the
11
+ > Task tool with this file as the gate specification; the agent does NOT
12
+ > execute inline. See `prd-writing-phase.md` § Step 4.5 for the spawn
13
+ > instruction. At the audit phase (audit-phase.md), the same agent re-audits
14
+ > the backlog cards using a narrower card-level scope — that is a distinct run;
15
+ > it MUST read the `## API Performance Gate` section from the state file
16
+ > written by this Step 4.5 run to avoid re-flagging already-resolved items.
17
+
9
18
  ---
10
19
 
11
20
  ## When to Run
12
21
 
13
- **Gate 5 (Text Scan) runs ALWAYS** on every PRD. It is a fast keyword match.
22
+ **Step 0 Check Skip Conditions first.** Before running any gate, evaluate
23
+ the skip table below. If a skip condition applies, log the skip reason in the
24
+ state file and stop.
25
+
26
+ ### Skip Conditions
27
+
28
+ | Card / PRD type | Action |
29
+ |-----------------|--------|
30
+ | Hotfix (single-line bug fix, no data/API touch) | Gate 5 only — skip Gates 1-4 |
31
+ | Purely frontend (no persistence or API changes) | Skip all gates entirely |
32
+ | Documentation-only | Skip all gates entirely |
33
+ | Prototype / spike (throw-away) | Skip all gates entirely |
34
+
35
+ **Gate 5 (Text Scan) runs on every PRD that passes the skip check.** It is a
36
+ fast keyword match and takes precedence over all other conditions.
14
37
 
15
38
  **Gates 1-4 run ONLY** when Gate 5 finds matches OR the PRD contains any of:
16
39
  - `## API contract changes` section with endpoints
@@ -19,15 +42,16 @@ flagged after implementation.
19
42
  - Server-side mutations touching the persistence layer
20
43
  - Background jobs, cron, batch operations
21
44
 
22
- If none of the above: log `API Performance Gate: N/A no API/data surface` in
23
- state file and skip to "Present and Confirm".
45
+ If Gate 5 finds zero matches AND none of the above sections are present: log
46
+ `API Performance Gate: N/A no API/data surface` in state file and return
47
+ control to the `/prd` skill (proceed to "Present and Confirm").
24
48
 
25
49
  **Stack-awareness:** before running Gates 1-4, read `stack.database` and
26
50
  `stack.framework` from `baldart.config.yml`. The gate sections below have a
27
51
  universal core (works for any stack) PLUS stack-specific addenda that activate
28
52
  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.
53
+ gate degrades to the universal core and logs a recommendation to run
54
+ `npx baldart configure` so future gates pick up the stack-specific rules.
31
55
 
32
56
  ---
33
57
 
@@ -63,8 +87,10 @@ Scan the PRD text for these keywords. Each match = a finding.
63
87
  | postgres / supabase | "JSONB column" + indexed query | Verify GIN index exists | MEDIUM |
64
88
  | dynamodb | "filter expression" instead of KeyCondition | Filter scans full partition — pick a GSI instead | HIGH |
65
89
 
66
- **If 0 matches AND no API/data sections**: skip Gates 1-4, proceed to present.
67
- **If any match**: continue to Gates 1-4.
90
+ **If 0 matches AND no API/data sections**: skip Gates 1-4; this result was
91
+ already handled by the early-exit in the "When to Run" block above — log
92
+ `API Performance Gate: N/A — no API/data surface` in state file and return.
93
+ **If any match OR API/data sections present**: continue to Gates 1-4.
68
94
 
69
95
  ### Gate 1 — Data Model Review
70
96
 
@@ -83,7 +109,7 @@ Stack-specific addenda (activate when matching `stack.database`):
83
109
  - [ ] firestore: **Index exemptions** for large text fields → MEDIUM (N+1 index writes per doc write)
84
110
  - [ ] mongodb: **Embedded vs referenced** — embedded grows the parent doc; referenced needs $lookup → MEDIUM
85
111
  - [ ] 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
112
+ - [ ] supabase: **RLS coverage** — every new table MUST have RLS policies aligned with the auth contract → CRITICAL. **This is a security requirement, not a performance finding.** When triggered: flag the missing policy as CRITICAL in the findings list AND note `→ HANDOFF TO security-reviewer` (do not attempt to write the RLS policy inline). The `/prd` skill MUST route this finding to `security-reviewer` before the PRD is presented to the user; the performance gate records the finding but does not resolve it unilaterally.
87
113
  - [ ] dynamodb: **Hot partition** — does the partition key distribute evenly under load? → HIGH
88
114
 
89
115
  ### Gate 2 — Query & Index Review
@@ -100,7 +126,7 @@ Stack-specific addenda:
100
126
  - [ ] firestore: **orderBy + inequality on different fields** requires composite index, max 1 inequality per query (inequality field MUST be last) → HIGH
101
127
  - [ ] firestore: **>3 inequality filters on different fields** = index explosion → MEDIUM
102
128
  - [ ] 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
129
+ - [ ] postgres/supabase: **EXPLAIN check** on the slowest query in the PRD — sequential scans on tables above the project's sequential-scan threshold → CRITICAL. Threshold: read `${paths.references_dir}/perf-budgets.md`; if absent, use >100k rows as the ad-hoc default and emit a `BUDGETS_GAP` warning. [DESIGN-CHOICE: 100k-row fallback chosen as a conservative p95-safe default for OLTP workloads; calibrate via perf-budgets.md for your project]
104
130
  - [ ] postgres/supabase: **Covering index** for hot read paths → MEDIUM
105
131
  - [ ] mongodb: **Compound index field order** matches query equality → range → sort rule → HIGH
106
132
  - [ ] dynamodb: **GSI / LSI definition** for every access pattern that doesn't hit the primary key → CRITICAL
@@ -109,7 +135,7 @@ Stack-specific addenda:
109
135
 
110
136
  Universal checks:
111
137
 
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`.
138
+ - [ ] **Payload size**: any endpoint accepting/returning a payload above the platform limit → CRITICAL (use signed URL / multipart upload pattern). Resolve threshold from `stack.deployment`: Vercel 4.5 MB, AWS Lambda → 6 MB sync / 256 KB async, Cloudflare Workers → 100 MB, Firebase Functions gen 2 32 MB. When `stack.deployment` is unset, use 4.5 MB as a conservative fallback and emit a `BUDGETS_GAP` warning. [DESIGN-CHOICE: 4.5 MB unset-fallback matches the most restrictive common platform (Vercel) to avoid silent over-limit on unknown deployments]
113
139
  - [ ] **Sync vs async**: long operations (email, PDF, image processing) in request path → HIGH (use queue / waitUntil / background worker per stack)
114
140
  - [ ] **Function duration**: operations that may exceed the platform timeout (Vercel 300s Hobby / 800s Pro; Lambda 900s; Cloudflare Workers 30s CPU) → HIGH
115
141
  - [ ] **CPU-intensive ops**: image resize, PDF gen, heavy computation in serverless → MEDIUM (consider dedicated worker / container)
@@ -135,27 +161,115 @@ Check data display and freshness requirements for:
135
161
 
136
162
  ## Severity Actions
137
163
 
138
- | Severity | Action |
139
- |----------|--------|
140
- | CRITICAL | MUST fix in PRD before presenting to user. Add/modify NFR, add edge case, change API design. |
141
- | HIGH | MUST add as NFR or documented design decision in PRD. User sees it in the spec. |
142
- | MEDIUM | Add to `Edge cases and failure modes` table in PRD as advisory. |
143
- | LOW | Log in state file only. No PRD change. |
164
+ > **Taxonomy note:** This gate uses CRITICAL/HIGH/MEDIUM/LOW. When the
165
+ > `api-perf-cost-auditor` agent runs this protocol (as it does at Step 4.5
166
+ > and Step 6), its output schema uses BLOCKER/HIGH/MEDIUM/LOW. Mapping:
167
+ > agent BLOCKER (Priority 16) = gate CRITICAL; agent HIGH = gate HIGH.
168
+ > The agent's BLOCKER findings MUST be treated as CRITICAL for PRD action
169
+ > purposes. Never present a PRD with an unresolved BLOCKER/CRITICAL finding.
170
+
171
+ | Severity (gate) | Agent equivalent | Action |
172
+ |-----------------|-----------------|--------|
173
+ | CRITICAL | BLOCKER | MUST fix in PRD before presenting to user. Add/modify NFR, add edge case, change API design. If the fix requires architectural redesign the skill cannot determine unilaterally, **STOP** — see "Unresolvable CRITICAL" procedure below. |
174
+ | HIGH | HIGH | MUST add as NFR or documented design decision in PRD. User sees it in the spec. |
175
+ | MEDIUM | MEDIUM | Add to `Edge cases and failure modes` table in PRD as advisory. |
176
+ | LOW | LOW | Log in state file only. No PRD change. |
177
+
178
+ ### Unresolvable CRITICAL Procedure
179
+
180
+ When a CRITICAL finding cannot be resolved by editing the PRD (e.g. the PRD
181
+ describes an inherently fan-out write or unbounded read that requires an
182
+ architectural redesign), the skill MUST:
183
+
184
+ 1. Record the finding verbatim in the `## API Performance Gate` section of the
185
+ state file with status `UNRESOLVED`.
186
+ 2. **Do NOT present the PRD to the user without surfacing the blocker.** Instead,
187
+ surface an explicit blocker message before "Present and Confirm":
188
+
189
+ ```
190
+ PERFORMANCE GATE BLOCKER — unresolvable CRITICAL finding:
191
+ Finding: <title>
192
+ Reason it cannot be auto-resolved: <one line>
193
+ Required action: <what the user must decide / redesign>
194
+
195
+ The PRD cannot be presented until this is resolved. Please clarify the
196
+ architectural direction so the spec can be updated.
197
+ ```
198
+
199
+ 3. Wait for user input. Resume "Present and Confirm" only after the user
200
+ provides a resolution direction and the PRD is updated accordingly.
144
201
 
145
202
  ---
146
203
 
147
204
  ## Execution Procedure
148
205
 
149
- 1. Run Gate 5 on the full PRD text.
150
- 2. If matches found OR API/data sections present run Gates 1-4.
151
- 3. For each finding:
152
- - CRITICAL/HIGH: edit the PRD directly (add NFR, modify API contract, add edge case).
153
- - MEDIUM: add to edge cases table.
154
- - LOW: note in state file.
155
- 4. Update state file: `## API Performance Gate` section with findings count and actions taken.
156
- 5. If any CRITICAL findings were resolved, add a `### Performance-Informed Decisions` subsection
157
- to the PRD listing what was changed and why.
158
- 6. Proceed to "Present and Confirm" the user sees an already-optimized PRD.
206
+ > **Who runs this:** the `api-perf-cost-auditor` agent, spawned by the `/prd`
207
+ > skill at Step 4.5. Steps below are instructions to that agent. The agent
208
+ > MUST complete all steps before returning control to the skill.
209
+
210
+ **Step 0 Prior findings check (delta-run guard).**
211
+ Read the `## API Performance Gate` section of the state file. If a prior run
212
+ exists (e.g. `/prd-add` re-triggered this gate):
213
+ - Extract all entries from the `findings[]` array where `status: RESOLVED`.
214
+ - Do NOT re-flag any resolved item unless the PRD delta introduces a new
215
+ instance of the same pattern (same root cause, different location is a new
216
+ finding; same location + same root cause = duplicate, skip).
217
+ - Record the prior run's resolved-finding list in your working context as
218
+ `PRIOR_RESOLVED = [...]` before starting Gate 5.
219
+
220
+ **Step 1 — Skip-condition check.**
221
+ Evaluate the Skip Conditions table in the "When to Run" section. If a skip
222
+ condition applies, write `API Performance Gate: SKIPPED — <reason>` to the
223
+ state file and return `status: SKIPPED` to the calling skill. Stop here.
224
+
225
+ **Step 2 — Run Gate 5 on the full PRD text.**
226
+
227
+ **Step 3 — If Gate 5 finds zero matches AND the PRD has no API/data sections:**
228
+ Write `API Performance Gate: N/A — no API/data surface` to the state file and
229
+ return `status: NA`. Stop here.
230
+
231
+ **Step 4 — Run Gates 1-4.** Apply stack-specific addenda from `baldart.config.yml`.
232
+
233
+ **Step 5 — For each finding, apply the Severity Actions table:**
234
+ - CRITICAL: attempt to fix in PRD. If unresolvable → follow "Unresolvable
235
+ CRITICAL" procedure (STOP and surface to user; do NOT proceed to Present).
236
+ - CRITICAL + security handoff (RLS): record as CRITICAL with
237
+ `→ HANDOFF TO security-reviewer`; do not attempt to write security policy.
238
+ - HIGH: add as NFR or design decision in PRD.
239
+ - MEDIUM: add to edge cases table.
240
+ - LOW: note in state file.
241
+
242
+ **Step 6 — Update state file.** Write the machine-readable block below to the
243
+ `## API Performance Gate` section. This is consumed by the audit-phase
244
+ `api-perf-cost-auditor` run (prd/references/audit-phase.md § Step 6) to avoid
245
+ re-flagging already-resolved items when auditing backlog cards:
246
+
247
+ ```
248
+ ## API Performance Gate
249
+ run_at: <ISO timestamp>
250
+ status: PASS | PASS_WITH_NOTES | BLOCKER | SKIPPED | NA
251
+ findings_total: N
252
+ findings_by_severity:
253
+ critical: N # resolved in PRD (or UNRESOLVED — see below)
254
+ high: N # added as NFR
255
+ medium: N # added to edge cases
256
+ low: N # state file only
257
+ findings:
258
+ - title: <finding title>
259
+ severity: CRITICAL | HIGH | MEDIUM | LOW
260
+ status: RESOLVED | UNRESOLVED | SECURITY_HANDOFF
261
+ resolution: <one line — what was changed in the PRD, or "" if UNRESOLVED>
262
+ handoff_to: security-reviewer # only when status == SECURITY_HANDOFF
263
+ ```
264
+
265
+ **Step 7 — If any CRITICAL findings were resolved:** add a
266
+ `### Performance-Informed Decisions` subsection to the PRD listing what was
267
+ changed and why.
268
+
269
+ **Step 8 — Return to skill.** Return `status: <value>` from Step 6
270
+ (machine-readable). If `status == BLOCKER`, the skill MUST NOT proceed
271
+ to "Present and Confirm" — the blocker message in the Severity Actions section
272
+ is displayed to the user instead.
159
273
 
160
274
  ---
161
275
 
@@ -169,7 +283,7 @@ informational and should be removed from the populated PRD section.
169
283
 
170
284
  **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
285
 
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.
286
+ **Supabase / Postgres:** Compute + storage + egress billing. Hot row updates serialize on a single page; HOT updates and `FILLFACTOR` matter for write-heavy tables. Sequential scans above the project's threshold (see `${paths.references_dir}/perf-budgets.md`; default: >100k rows) are a CRITICAL finding regardless of price (see Gate 2).
173
287
 
174
288
  **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
289
 
@@ -194,9 +308,5 @@ informational and should be removed from the populated PRD section.
194
308
 
195
309
  **Astro:** SSG by default; `output: 'server'` enables on-demand rendering; per-route `prerender` toggle.
196
310
 
197
- ### When to Skip
198
-
199
- - Hotfix cards (single-line bug fixes): Gate 5 only
200
- - Purely frontend cards (no persistence/API touch): skip entirely
201
- - Documentation-only: skip entirely
202
- - Prototype/spike (throw-away): skip entirely
311
+ <!-- Skip conditions have been moved to "When to Run" § Skip Conditions table
312
+ and Execution Procedure Step 1. Do not add skip logic here. -->
@@ -31,13 +31,13 @@ Scan each card for security signals to decide whether the `security-reviewer` ag
31
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
- **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.
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 **SEMANTIC** check — keyword and path matching on card prose requires interpretation, so it is biased toward RECALL: when a signal is ambiguous, INCLUDE the reviewer rather than skip it. (It is not "deterministic" — a card whose auth change lives in an auth-suggestive `files_likely_touched` path but whose `requirements` omit the trigger keywords can still slip through; prefer the path heuristic over relying on prose keywords alone.)
35
35
 
36
36
  **Output**: Set internal flag `security_review_needed: true/false`. If ANY card triggers → include `security-reviewer` for ALL cards.
37
37
 
38
38
  **Transparency**: Inform the user:
39
- - If triggered: "Security review attivatorilevate superfici esposte: [list signals]."
40
- - If not: "Security review non necessarionessuna superficie esposta rilevata."
39
+ - If triggered: "Security review triggeredexposed surfaces detected: [list signals]."
40
+ - If not: "Security review not requiredno exposed surfaces detected."
41
41
 
42
42
  ## Step 6.3 — Signal Detection: Performance (AUTOMATIC)
43
43
 
@@ -59,20 +59,21 @@ Scan each card for performance signals to decide whether the `api-perf-cost-audi
59
59
  **Output**: Set internal flag `perf_review_needed: true/false`. If ANY card triggers → include `api-perf-cost-auditor` for ALL cards.
60
60
 
61
61
  **Transparency**: Inform the user:
62
- - If triggered: "Performance audit attivatorilevate superfici con impatto costi/performance: [list signals]."
63
- - If not: "Performance audit non necessarionessuna superficie API/data rilevata."
62
+ - If triggered: "Performance audit triggeredsurfaces with cost/performance impact detected: [list signals]."
63
+ - If not: "Performance audit not requiredno API/data surfaces detected."
64
64
 
65
65
  ## Step 6.4 — Adjacent Card Retrieval (dependency detection)
66
66
 
67
- > Source: Arora 2023 — LLMs miss 60-70% of implicit dependencies without retrieval. With adjacent context, miss rate drops to ~30%.
67
+ [DESIGN-CHOICE: adjacent card context is retrieved to reduce implicit dependency misses — LLMs processing cards in isolation are likely to miss cross-card file conflicts and ordering constraints not captured in explicit `depends_on` fields]
68
68
 
69
69
  To detect implicit dependencies, gather adjacent context:
70
70
 
71
71
  1. For each card being audited, check its `depends_on` field for referenced cards → read those cards.
72
72
  2. Read ALL cards in `${paths.backlog_dir}/` that share the same `epic:` or `parent:` field as the audited cards.
73
73
  3. Read ALL cards whose `files_likely_touched` overlaps with any audited card's files.
74
- 4. Build a summary for each adjacent card: `{id, title, status, requirements (first 3 lines), files_likely_touched}`.
75
- 5. Include these summaries in each audit agent's task description (Step 6.6) under `## Adjacent Cards`.
74
+ 4. **Deduplicate**: merge the results from steps 1-3 into a single set by card ID before building summaries. A card matched by multiple criteria counts once.
75
+ 5. Build a summary for each unique adjacent card: `{id, title, status, requirements (first 3 lines), files_likely_touched}`. Cap at 10 adjacent cards per audited card `[CALIBRATION-NEEDED: the cap is a context-budget guard, not an empirically tuned value — validate against prompt-size telemetry on large epics]`; if more are present, prefer `depends_on` references, then same-epic, then file-overlap.
76
+ 6. Include these summaries in each audit agent's task description (Step 6.6) under `## Adjacent Cards`.
76
77
 
77
78
  This enables agents to detect:
78
79
  - File conflicts between cards planned for parallel execution
@@ -101,10 +102,12 @@ Use `TeamCreate` with name `check-audit` and description based on the cards bein
101
102
 
102
103
  Use `TaskCreate` to create one task per audit agent per card:
103
104
 
104
- - For **N cards × M agents**, create **N × M tasks** (excluding Codex plan-audit — see 6.6d).
105
+ - For **N cards × M agent types**, create **N × M tasks** (one task per agent type per card; excluding Codex plan-audit — see 6.6d). In Step 6.6c, ONE teammate agent per type handles all N tasks in its queue — M agents run in parallel, not N×M.
105
106
  - Each task subject: `[CARD-ID] <agent-type> audit`
106
107
  - Each task description: full card YAML + adjacent card summaries + file paths + PRD path + instructions.
107
108
 
109
+ **Claim-lock (atomicity on the N×M fan-out)**: each task carries a `claimed_by` field, empty at creation. Before a teammate processes a task it MUST atomically set `claimed_by: <its name>` via `TaskUpdate` and re-read; if the field is already non-empty and not its own name, it SKIPS that task (another worker owns it). This prevents two workers — for example a re-spawn after a transient failure, or an overlapping re-audit (Step 6.9) — from both processing the same card+agent pair and producing duplicate findings. The teammate workflow (Step 6.6e) embeds the claim step.
110
+
108
111
  **IMPORTANT**: Embed the full card YAML directly in the task description. For source files and PRDs, only provide paths — agents read those themselves.
109
112
 
110
113
  ### 6.6c. Launch teammate agents in parallel
@@ -119,21 +122,20 @@ For each audit agent type (except plan-auditor), spawn ONE teammate using the `T
119
122
  | code-reviewer | `code-reviewer` | `code-reviewer` | Always |
120
123
  | doc-reviewer | `doc-reviewer` | `doc-reviewer` | Always |
121
124
  | api-perf-cost-auditor | `api-perf-cost-auditor` | `perf-auditor` | `perf_review_needed: true` |
122
- | security-reviewer | `general-purpose` | `security-reviewer` | `security_review_needed: true` |
123
-
124
- **Note**: security-reviewer uses `subagent_type: "general-purpose"` — load its prompt from `.claude/agents/security-reviewer.md`.
125
+ | security-reviewer | `security-reviewer` | `security-reviewer` | `security_review_needed: true` |
125
126
 
126
127
  Launch ALL applicable teammates in a single message (parallel tool calls).
127
128
 
128
129
  ### 6.6d. Codex Adversarial Plan Audit (replaces plan-auditor)
129
130
 
130
- > **Why Codex**: Cross-model validation — GPT-5.4 reviews artifacts produced by Claude,
131
- > providing genuine diversity of perspective. Codex reads files directly from the filesystem.
131
+ > **Why Codex**: Cross-model validation — a non-Anthropic frontier model reviews artifacts produced by Claude,
132
+ > providing genuine diversity of perspective. [DESIGN-CHOICE: adversarial cross-model review catches blind spots that a single model cannot self-detect] Codex reads files directly from the filesystem.
132
133
 
133
134
  Launch **in parallel** with the teammate agents (6.6c). Use `Bash` with `run_in_background: true` so Claude can launch teammate agents concurrently:
134
135
 
135
136
  ```bash
136
- AUDIT_FILE="/tmp/codex-plan-audit-$(date +%Y-%m-%d).md" && \
137
+ SESSION_ID="${SESSION_ID:-$(date +%s%N | md5sum | head -c8)}" && \
138
+ AUDIT_FILE="/tmp/codex-plan-audit-${CARD_ID_SLUG}-${SESSION_ID}.md" && \
137
139
  CODEX_SCRIPT="$(ls -d ~/.claude/plugins/marketplaces/openai-codex/plugins/codex/scripts/codex-companion.mjs ~/.claude/plugins/cache/openai-codex/codex/*/scripts/codex-companion.mjs 2>/dev/null | sort -V | tail -1)" && \
138
140
  [ -z "$CODEX_SCRIPT" ] && echo "CODEX_NOT_FOUND" && exit 1; \
139
141
  node "$CODEX_SCRIPT" task --wait "
@@ -223,21 +225,27 @@ Suppress findings where the strongest false-positive argument is convincing.
223
225
  " 2>&1 | tee "$AUDIT_FILE"
224
226
  ```
225
227
 
226
- **Variable interpolation** (build the command string before execution):
228
+ **Variable interpolation** (build the command string before execution; read all values from the session tracker written at Phase 0 — never guess):
227
229
  - `${CARD_PATHS}`: newline-separated list of `- backlog/FEAT-XXXX-*.yml` paths from Step 5
228
230
  - `${PRD_PATH}`: the PRD file path from the session state
229
231
  - `${ADJACENT_CARD_PATHS}`: newline-separated list from Step 6.4
232
+ - `${CARD_ID_SLUG}`: hyphen-separated list of card IDs being audited (e.g. `FEAT-0042-FEAT-0043`) — written to session tracker at Phase 0
233
+ - `${SESSION_ID}`: unique run identifier written to the session tracker at Phase 0; the bash fallback `$(date +%s%N | md5sum | head -c8)` is a last resort only
230
234
 
231
235
  **Timeout**: Set `timeout: 300000` (5 minutes) on the Bash call.
232
236
 
233
- **Output handling**: The `tee` in the command persists output to `$AUDIT_FILE` (`/tmp/codex-plan-audit-{YYYY-MM-DD}.md`) as it streams. This ensures findings survive regardless of foreground/background execution or stdout truncation.
234
- 1. Read findings from `/tmp/codex-plan-audit-{YYYY-MM-DD}.md` (always available — written by `tee`).
235
- 2. If the file is empty or missing, fall back to `plan-auditor` subagent.
237
+ **Output handling**: The `tee` in the command persists output to `$AUDIT_FILE` (`/tmp/codex-plan-audit-<CARD-ID-SLUG>-<SESSION-ID>.md`) as it streams. This ensures findings survive regardless of foreground/background execution or stdout truncation.
238
+ 1. Read findings from the path stored in `$AUDIT_FILE` (always available — written by `tee`).
239
+ 2. If the file is empty or its content is `CODEX_NOT_FOUND`, fall back to `plan-auditor` subagent.
236
240
  3. Merge into the consolidated report at Step 6.7 under `### Codex Plan Audit Findings`.
237
241
 
238
242
  **Fallback**: If Codex is unavailable (not installed, not authenticated, or timeout), fall back to the `plan-auditor` subagent with `subagent_type: "plan-auditor"`. Log the fallback reason in the audit report.
239
243
 
240
- ### 6.6d. Teammate prompt template
244
+ **Dedup guard on the fallback spawn (avoid double fan-out).** plan-auditor internally auto-spawns `codebase-architect` (always) and `security-reviewer` (when the cards carry auth/session signals). This audit session may have ALREADY produced those artifacts — `security-reviewer` runs as a first-class teammate whenever `security_review_needed: true` (Step 6.6c). To prevent a redundant second pass, the fallback `plan-auditor` invocation MUST be passed a context note instructing it to REUSE this session's artifacts rather than re-spawn:
245
+ - If `codebase-architect` was already spawned earlier this session (its summary is in the session tracker artifact registry), pass that summary in the prompt and instruct plan-auditor NOT to re-invoke `codebase-architect`.
246
+ - If `security_review_needed: true` (security-reviewer already ran as a teammate), instruct plan-auditor NOT to spawn `security-reviewer`; its security findings are already in the task store and will be merged at Step 6.7. plan-auditor should rely on those rather than running an independent, un-merged second review.
247
+
248
+ ### 6.6e. Teammate prompt template
241
249
 
242
250
  Each teammate receives this prompt:
243
251
 
@@ -255,6 +263,7 @@ Your job is RECALL, not precision — catch everything, filter later.
255
263
  1. Call `TaskList` to see your assigned tasks.
256
264
  2. For each task (in ID order):
257
265
  a. Call `TaskGet` to read the full task description (card YAML + adjacent cards + file paths).
266
+ a2. **Claim the task**: if `claimed_by` is already set to a name other than yours, SKIP this task (another worker owns it). Otherwise set `claimed_by: <your name>` via `TaskUpdate`, then re-read via `TaskGet` to confirm your claim held; if a different name won the race, SKIP.
258
267
  b. Mark task as `in_progress` via `TaskUpdate`.
259
268
  c. Read any source files or PRDs referenced in the task (use Read tool).
260
269
  d. Perform your audit (see instructions below).
@@ -357,17 +366,22 @@ After challenge pass, rank ALL surviving findings relative to each other by impa
357
366
 
358
367
  **code-reviewer**: Read existing files in `files_likely_touched` and assess: conflicts with existing patterns? Architectural concerns? Alignment with conventions (per `identity.design_philosophy`, project lint/type-check rules, `identity.language`)? Existing utilities the card should reuse but doesn't mention? Check `## Adjacent Cards` for parallel file modifications.
359
368
 
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`.
369
+ **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. If `.claude/skills/doc-reviewer-support/references/obsidian-integration.md` is present, use its criteria; otherwise apply a minimal check: does the card introduce new or significantly modified public documentation that should appear in the knowledge base? Proceed with a notice if the file is absent.
361
370
 
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`).
371
+ **api-perf-cost-auditor** (only when `perf_review_needed: true`): Apply the 5-gate protocol from `api-perf-gate.md` (see `framework/.claude/skills/prd/references/api-perf-gate.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`). **Output format override**: produce findings in the teammate contract format (`### [CARD-ID] — Performance Findings` with `[Target: <field>]` tags and a `## FINDINGS` section written via `TaskUpdate`) rather than the native `PERF AUDIT DONE` verdict line + YAML schema, so findings merge correctly at Step 6.7 (symmetric with the `security-reviewer` override below).
363
372
 
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.
373
+ **security-reviewer** (only when `security_review_needed: true`): Apply the full security-reviewer 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. **Output format override**: produce findings in the teammate contract format (`### [CARD-ID] — Security Findings` with `[Target: <field>]` tags and `## FINDINGS` section written via `TaskUpdate`) rather than the native `# Security Review Summary` format, so findings merge correctly at Step 6.7.
365
374
 
366
375
  ## Step 6.7 — Collect & Merge Findings
367
376
 
368
- Wait for all teammates AND Codex to complete, then:
369
- 1. **Read teammate findings from the task store** (not `SendMessage`). Use `TaskList` to check all tasks are `completed`, then `TaskGet` on each to read the `## FINDINGS` section.
370
- 2. **Read Codex plan audit findings** from `/tmp/codex-plan-audit-{YYYY-MM-DD}.md` (persisted by `tee` in Step 6.6d). If the file is empty or missing, note "Codex audit unavailable fallback to plan-auditor" and invoke the `plan-auditor` subagent.
377
+ **Fan-in barrier (explicit completion gate — do not read findings before it clears).** The consolidation below MUST NOT begin until BOTH the teammate pool AND the Codex background job have reached a terminal state. Resolve each independently:
378
+
379
+ - **Teammates**: poll `TaskList` until every task is `completed`. Bound the wait with a window of `[CALIBRATION-NEEDED: per-agent budget; align with the 5-min Codex timeout once teammate-duration telemetry exists]` — as a working default, 10 minutes wall-clock from team launch. On expiry, classify any task still `in_progress`/`pending` as **TIMED_OUT**: proceed fail-open with findings from completed tasks, and record `audit_status: partial` plus the timed-out task IDs in the consolidated report so the omission is visible (never wait indefinitely; never silently drop the gap). Do NOT substitute a generic agent for a hung teammate (AGENTS.md anti-fallback rule).
380
+ - **Codex**: the background Bash job (Step 6.6d) is terminal once `$AUDIT_FILE` is non-empty OR its own `timeout: 300000` elapses. Do not block teammate consolidation on Codex beyond its 5-minute cap.
381
+
382
+ Once the barrier clears:
383
+ 1. **Read teammate findings from the task store** (not `SendMessage`). Use `TaskGet` on each `completed` task to read the `## FINDINGS` section.
384
+ 2. **Read Codex plan audit findings** from the path stored as `$AUDIT_FILE` in the session tracker (persisted by `tee` in Step 6.6d; pattern: `/tmp/codex-plan-audit-<CARD-ID-SLUG>-<SESSION-ID>.md`). If the file is absent, empty, or its content is `CODEX_NOT_FOUND`, note "Codex audit unavailable — fallback to plan-auditor" and invoke the `plan-auditor` subagent **with the dedup guard from Step 6.6d** (reuse this session's `codebase-architect` summary and already-merged `security-reviewer` findings instead of re-spawning).
371
385
 
372
386
  Consolidate into a single report:
373
387
 
@@ -376,7 +390,7 @@ Consolidate into a single report:
376
390
 
377
391
  ## [CARD-ID-1] — Card Title
378
392
 
379
- ### Codex Plan Audit Findings (GPT-5.4)
393
+ ### Codex Plan Audit Findings (cross-model)
380
394
  - [ ] Finding 1...
381
395
 
382
396
  ### Code Review Findings
@@ -395,14 +409,14 @@ Consolidate into a single report:
395
409
  ...
396
410
 
397
411
  ## Audit Engine Summary
398
- - Plan audit: Codex GPT-5.4 (cross-model) | Fallback: Claude plan-auditor
412
+ - Plan audit: Codex (cross-model adversarial) | Fallback: Claude plan-auditor
399
413
  - Code review: Claude code-reviewer
400
414
  - Doc review: Claude doc-reviewer
401
415
  - Performance: Claude api-perf-cost-auditor (if triggered)
402
416
  - Security: Claude security-reviewer (if triggered)
403
417
  ```
404
418
 
405
- **CRITICAL — Persist report to file before proceeding.** Write to `/tmp/check-audit-report-{YYYY-MM-DD}.md` using the Write tool. This ensures findings survive context compaction.
419
+ **CRITICAL — Persist report to file before proceeding.** Write to `/tmp/check-audit-report-<CARD-ID-SLUG>-<SESSION-ID>.md` (using `$CARD_ID_SLUG` and `$SESSION_ID` from the session tracker) using the Write tool. Store the path in the session tracker. This ensures findings survive context compaction.
406
420
 
407
421
  Present the consolidated report to the user.
408
422
 
@@ -414,7 +428,7 @@ Use `SendMessage` with `type: "shutdown_request"` to shut down all teammates, th
414
428
 
415
429
  **Goal**: Transform each card from "audited" to "implementation-ready" by editing YAML fields directly.
416
430
 
417
- **Read findings from the persisted report file** (`/tmp/check-audit-report-{YYYY-MM-DD}.md`).
431
+ **Read findings from the persisted report file** (path stored in the session tracker as `$REPORT_FILE`; pattern: `/tmp/check-audit-report-<CARD-ID-SLUG>-<SESSION-ID>.md`).
418
432
 
419
433
  ### Field mapping rules
420
434
 
@@ -426,7 +440,7 @@ Use `SendMessage` with `type: "shutdown_request"` to shut down all teammates, th
426
440
  | `[Target: files_likely_touched]` | `files_likely_touched` | Append missing path (no duplicates) |
427
441
  | `[Target: depends_on]` | `depends_on` | Append missing card ID |
428
442
  | `[Target: areas]` | `areas` | Add missing area key/value |
429
- | `[Target: git_strategy]` | `git_strategy` | Replace `TBD` with `feat/<CARD-ID>-<slug> from develop` |
443
+ | `[Target: git_strategy]` | `git_strategy` | Replace `TBD` with `feat/<CARD-ID>-<slug> from ${git.trunk_branch}` |
430
444
  | `[Target: unknowns]` | `unknowns` | Append new `[U-N] UNKNOWN: ...` entry |
431
445
  | `[Target: existing_patterns]` | `existing_patterns` | Append missing pattern reference or fix stale line_range/anchor_text |
432
446
  | `[Target: validation_commands]` | `validation_commands` | Append missing verification command |
@@ -468,11 +482,11 @@ For each card:
468
482
 
469
483
  ## Maintenance Note
470
484
 
471
- > Source: Anthropic "Harness Design for Long-Running Apps" capability-boundary adaptation principle.
485
+ [DESIGN-CHOICE: each audit component encodes a capability boundary; periodic stress-testing prevents dead scaffolding as model capabilities evolve]
472
486
 
473
- Every component in this audit encodes an assumption about what the model can't do alone. Periodically (every 2-3 months or on major model upgrade), stress-test each component:
487
+ Every component in this audit encodes an assumption about what the model can't do alone. Periodically (every 2-3 months `[CALIBRATION-NEEDED: cadence is a team convention, not validated against model-release frequency]` or on major model upgrade), stress-test each component:
474
488
 
475
489
  - Remove one component at a time, measure audit quality delta.
476
- - If delta < 5%, remove permanently.
490
+ - If delta < 5% `[CALIBRATION-NEEDED: removal threshold is a heuristic; validate against a labelled audit-quality benchmark before treating it as a hard cutoff]`, remove permanently.
477
491
  - **Current load-bearing assumptions**: challenge pass, adjacent card retrieval, evidence quotes, adversarial evaluator tuning.
478
492
  - **Assumptions to re-test**: agent team separation (could single-agent handle N cards?), relative severity ranking (does absolute assignment work with better models?).
@@ -12,11 +12,9 @@ and HALT if violated.
12
12
 
13
13
  ### Rule A — `owner_agent` is mandatory and enum-validated
14
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
- ```
15
+ Every child card MUST declare `owner_agent` with a value from the **`owner_agent` enum**
16
+ defined in `framework/.claude/agents/REGISTRY.md` (the SSOT for all valid values). Do
17
+ not re-list the enum here — consult REGISTRY.md directly to avoid drift.
20
18
 
21
19
  There is no implicit default and `claude` is NOT a valid value. Cards with
22
20
  missing, empty, placeholder, or non-enum values fail Step 6 (validation-phase)
@@ -119,8 +117,37 @@ Templates: `.claude/skills/prd/assets/epic-template.yml` for the epic,
119
117
  Invoke mandatory specialist agents when the feature qualifies:
120
118
 
121
119
  - **`hyper-gamification-designer`** — MUST invoke if the feature touches B2C rewards,
122
- loyalty, engagement, progression, points, referrals, or retention loops. Integrate
123
- findings into requirements and risk sections of the PRD.
120
+ loyalty, engagement, progression, points, referrals, or retention loops.
121
+
122
+ Invoke with:
123
+
124
+ ```
125
+ Agent(
126
+ subagent_type: "hyper-gamification-designer",
127
+ prompt: """
128
+ Audit the approved PRD for gamification / retention quality.
129
+
130
+ WORKING_DIRECTORY: <$WORKTREE_PATH absolute path>
131
+ PRD path: <$WORKTREE_PATH>/<prd_path>
132
+ Feature slug: <slug>
133
+
134
+ Review the PRD's requirements, acceptance criteria, and risks for
135
+ gamification mechanics, reward loop design, progression clarity, and
136
+ retention risks. Return a structured findings list: each finding has
137
+ a section reference, severity (HIGH/MEDIUM/LOW), and a concrete
138
+ recommendation. Do NOT rewrite the PRD — return findings only.
139
+ """,
140
+ mode: "bypassPermissions"
141
+ )
142
+ ```
143
+
144
+ After the agent returns: **present its findings to the user** via
145
+ `AskUserQuestion` (list each HIGH finding explicitly) and request
146
+ confirmation before applying any changes to the PRD. Only incorporate
147
+ findings the user approves. Once the PRD is updated, re-confirm the
148
+ final PRD state with the user before proceeding to card generation —
149
+ the Step 4b gate applies to the post-audit PRD, not only the pre-audit version.
150
+
124
151
  - **`api-perf-cost-auditor`** — already executed at Step 4.5 (API Performance Gate)
125
152
  if the PRD contained API/data surfaces. Do NOT re-invoke here unless the card
126
153
  introduces NEW API patterns not covered in the PRD (e.g., card splits a single
@@ -133,8 +160,8 @@ If neither applies, note "Specialist audits: N/A" in the state file.
133
160
 
134
161
  Before delegating to `prd-card-writer`, check each logical card boundary:
135
162
 
136
- 1. Count expected `files_likely_touched` — flag if **> 12**.
137
- 2. Count expected `acceptance_criteria` — flag if **> 5**.
163
+ 1. Count expected `files_likely_touched` — flag if **> 12**. `[CALIBRATION-NEEDED: pre-write advisory threshold; prd-card-writer Rule C (SSOT) uses > 15 as the DEEP-profile trigger and 8 as the per-card atomicity target — these three thresholds serve distinct purposes and are not interchangeable; empirical grounding is missing for all three]`
164
+ 2. Count expected `acceptance_criteria` — flag if **> 5**. `[DESIGN-CHOICE: matches Rule C's DEEP trigger for AC count — the advisory here prompts a split before delegation, while Rule C deterministically assigns deep regardless of the user's override choice]`
138
165
 
139
166
  **If flagged:**
140
167
 
@@ -215,8 +242,8 @@ The `prd-card-writer` agent owns the entire card writing pipeline:
215
242
  - Parallel group computation (dependency graph + file-conflict map)
216
243
  - `execution_strategy` block on epic parent card
217
244
  - State file update with card list and matrices
218
- - `env_vars` field: per ogni card che introduce/modifica/rimuove env vars (rilevabile da PRD Section 6 o da requirements che menzionano `process.env`, segreti, API keys, feature flags), popola il campo con `action: new|modified|removed`, `scope`, `required`, `note`. Se la card non tocca env vars, scrivi `env_vars: []`.
219
- - `review_profile` field: deterministic per-card review depth (`skip|light|balanced|deep`) computed via `prd-card-writer.md § Rule C` from the card's own metadata (type, areas, data_fields, db_indexes, AC count, estimated_complexity). This materializes the review decision at authoring time so `/new` reads it instead of re-deriving it. Epics always get `review_profile: skip`. Honor any explicit author override already present in the YAML.
245
+ - `env_vars` field: for every card that introduces/modifies/removes env vars (detectable from PRD Section 6 or requirements that mention `process.env`, secrets, API keys, feature flags), populate the field with `action: new|modified|removed`, `scope`, `required`, `note`. If the card does not touch env vars, write `env_vars: []`.
246
+ - `review_profile` field: deterministic per-card review depth (`skip|light|balanced|deep`). The decision criteria (how each profile is chosen) live ONLY in `prd-card-writer.md § Rule C` see that file for the criteria. The `/new` orchestrator reads this value from the card and runs an escalation-only detector; it does NOT re-derive from a duplicate criteria table. Epics always get `review_profile: skip`. Honor any explicit author override already present in the YAML.
220
247
 
221
248
  ### What stays in the main context
222
249