baldart 3.6.2

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 (230) hide show
  1. package/CHANGELOG.md +599 -0
  2. package/README.md +566 -0
  3. package/VERSION +1 -0
  4. package/bin/baldart.js +143 -0
  5. package/framework/.claude/agents/REGISTRY.md +169 -0
  6. package/framework/.claude/agents/api-perf-cost-auditor.md +291 -0
  7. package/framework/.claude/agents/code-reviewer.md +350 -0
  8. package/framework/.claude/agents/codebase-architect.md +391 -0
  9. package/framework/.claude/agents/coder.md +291 -0
  10. package/framework/.claude/agents/deep-human-insight.md +198 -0
  11. package/framework/.claude/agents/doc-reviewer.md +440 -0
  12. package/framework/.claude/agents/email-deliverability-architect.md +193 -0
  13. package/framework/.claude/agents/hybrid-ml-architect.md +285 -0
  14. package/framework/.claude/agents/hyper-gamification-designer.md +149 -0
  15. package/framework/.claude/agents/legal-counsel-gdpr.md +179 -0
  16. package/framework/.claude/agents/marketing-conversion-strategist.md +162 -0
  17. package/framework/.claude/agents/motion-expert.md +108 -0
  18. package/framework/.claude/agents/onboarding-architect-lead.md +230 -0
  19. package/framework/.claude/agents/plan-auditor.md +546 -0
  20. package/framework/.claude/agents/prd-card-writer.md +372 -0
  21. package/framework/.claude/agents/prd.md +744 -0
  22. package/framework/.claude/agents/qa-sentinel.md +305 -0
  23. package/framework/.claude/agents/remotion-animator-orchestrator.md +218 -0
  24. package/framework/.claude/agents/security-reviewer.md +276 -0
  25. package/framework/.claude/agents/senior-researcher.md +175 -0
  26. package/framework/.claude/agents/seo-analytics-strategist.md +156 -0
  27. package/framework/.claude/agents/skill-improver.md +61 -0
  28. package/framework/.claude/agents/ui-expert.md +191 -0
  29. package/framework/.claude/agents/visual-designer.md +190 -0
  30. package/framework/.claude/agents/website-orchestrator.md +118 -0
  31. package/framework/.claude/agents/wiki-curator.md +145 -0
  32. package/framework/.claude/commands/baldart-push.md +15 -0
  33. package/framework/.claude/commands/check.md +237 -0
  34. package/framework/.claude/commands/codexreview.md +203 -0
  35. package/framework/.claude/commands/design-review.md +11 -0
  36. package/framework/.claude/commands/issue-review.md +34 -0
  37. package/framework/.claude/commands/new.md +331 -0
  38. package/framework/.claude/commands/qa.md +257 -0
  39. package/framework/.claude/hooks/framework-edit-gate.js +208 -0
  40. package/framework/.claude/hooks/lint-before-commit.sh.template +66 -0
  41. package/framework/.claude/settings.local.json.example +32 -0
  42. package/framework/.claude/skills/api-design-principles/SKILL.md +567 -0
  43. package/framework/.claude/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  44. package/framework/.claude/skills/api-design-principles/assets/rest-api-template.py +182 -0
  45. package/framework/.claude/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  46. package/framework/.claude/skills/api-design-principles/references/rest-best-practices.md +408 -0
  47. package/framework/.claude/skills/baldart-push/SKILL.md +222 -0
  48. package/framework/.claude/skills/bug/SKILL.md +200 -0
  49. package/framework/.claude/skills/bug/references/logging-patterns.md +174 -0
  50. package/framework/.claude/skills/capture/SKILL.md +125 -0
  51. package/framework/.claude/skills/capture/references/synthesis-template.md +42 -0
  52. package/framework/.claude/skills/context-primer/SKILL.md +189 -0
  53. package/framework/.claude/skills/copywriting/SKILL.md +273 -0
  54. package/framework/.claude/skills/copywriting/references/copy-frameworks.md +338 -0
  55. package/framework/.claude/skills/copywriting/references/natural-transitions.md +252 -0
  56. package/framework/.claude/skills/doc-writing-for-rag/SKILL.md +119 -0
  57. package/framework/.claude/skills/doc-writing-for-rag/references/before-after-examples.md +291 -0
  58. package/framework/.claude/skills/doc-writing-for-rag/references/compact-templates.md +183 -0
  59. package/framework/.claude/skills/doc-writing-for-rag/references/frontmatter-minimal.md +112 -0
  60. package/framework/.claude/skills/doc-writing-for-rag/references/line-count-targets.md +110 -0
  61. package/framework/.claude/skills/doc-writing-for-rag/references/schemas-and-errors.md +129 -0
  62. package/framework/.claude/skills/find-skills/SKILL.md +133 -0
  63. package/framework/.claude/skills/frontend-design/LICENSE.txt +177 -0
  64. package/framework/.claude/skills/frontend-design/SKILL.md +84 -0
  65. package/framework/.claude/skills/gamification-design/SKILL.md +130 -0
  66. package/framework/.claude/skills/issue-review/SKILL.md +45 -0
  67. package/framework/.claude/skills/kie-ai/SKILL.md +262 -0
  68. package/framework/.claude/skills/kie-ai/references/models-catalog.md +272 -0
  69. package/framework/.claude/skills/kie-ai/scripts/kie_api.sh +209 -0
  70. package/framework/.claude/skills/kie-ai/scripts/remove_greenscreen.py +69 -0
  71. package/framework/.claude/skills/kie-ai/scripts/setup_api_key.sh +77 -0
  72. package/framework/.claude/skills/motion-design/LICENSE +21 -0
  73. package/framework/.claude/skills/motion-design/README.md +82 -0
  74. package/framework/.claude/skills/motion-design/SKILL.md +336 -0
  75. package/framework/.claude/skills/motion-design/director/choreography.md +93 -0
  76. package/framework/.claude/skills/motion-design/director/context-adaptation.md +83 -0
  77. package/framework/.claude/skills/motion-design/director/core-philosophy.md +53 -0
  78. package/framework/.claude/skills/motion-design/director/decision-framework.md +91 -0
  79. package/framework/.claude/skills/motion-design/director/disney-principles.md +102 -0
  80. package/framework/.claude/skills/motion-design/director/emotion-mapping.md +71 -0
  81. package/framework/.claude/skills/motion-design/director/motion-personality.md +89 -0
  82. package/framework/.claude/skills/motion-design/director/narrative-structure.md +62 -0
  83. package/framework/.claude/skills/motion-design/patterns/ambient-continuous.md +81 -0
  84. package/framework/.claude/skills/motion-design/patterns/entrance-exit.md +82 -0
  85. package/framework/.claude/skills/motion-design/patterns/multi-element.md +69 -0
  86. package/framework/.claude/skills/motion-design/patterns/state-feedback.md +96 -0
  87. package/framework/.claude/skills/motion-design/reference/property-selection.md +95 -0
  88. package/framework/.claude/skills/motion-design/reference/quality-checklist.md +67 -0
  89. package/framework/.claude/skills/motion-design/reference/timing-easing-tables.md +106 -0
  90. package/framework/.claude/skills/motion-design/reference/troubleshooting.md +73 -0
  91. package/framework/.claude/skills/new/SKILL.md +1687 -0
  92. package/framework/.claude/skills/playwright-skill/API_REFERENCE.md +652 -0
  93. package/framework/.claude/skills/playwright-skill/SKILL.md +157 -0
  94. package/framework/.claude/skills/playwright-skill/package.json +26 -0
  95. package/framework/.claude/skills/prd/SKILL.md +228 -0
  96. package/framework/.claude/skills/prd/assets/card-template.yml +232 -0
  97. package/framework/.claude/skills/prd/assets/epic-template.yml +190 -0
  98. package/framework/.claude/skills/prd/assets/prd-template.md +230 -0
  99. package/framework/.claude/skills/prd/assets/state-template.md +78 -0
  100. package/framework/.claude/skills/prd/references/api-perf-gate.md +152 -0
  101. package/framework/.claude/skills/prd/references/audit-phase.md +478 -0
  102. package/framework/.claude/skills/prd/references/backlog-phase.md +145 -0
  103. package/framework/.claude/skills/prd/references/discovery-phase.md +359 -0
  104. package/framework/.claude/skills/prd/references/impact-analysis.md +233 -0
  105. package/framework/.claude/skills/prd/references/prd-add-phase.md +214 -0
  106. package/framework/.claude/skills/prd/references/prd-writing-phase.md +145 -0
  107. package/framework/.claude/skills/prd/references/research-phase.md +216 -0
  108. package/framework/.claude/skills/prd/references/ui-design-phase.md +61 -0
  109. package/framework/.claude/skills/prd/references/validation-phase.md +72 -0
  110. package/framework/.claude/skills/prd-add/SKILL.md +222 -0
  111. package/framework/.claude/skills/prd-add/references/impact-analysis.md +233 -0
  112. package/framework/.claude/skills/remotion-best-practices/SKILL.md +48 -0
  113. package/framework/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
  114. package/framework/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
  115. package/framework/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
  116. package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
  117. package/framework/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
  118. package/framework/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
  119. package/framework/.claude/skills/remotion-best-practices/rules/audio.md +169 -0
  120. package/framework/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
  121. package/framework/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
  122. package/framework/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
  123. package/framework/.claude/skills/remotion-best-practices/rules/compositions.md +141 -0
  124. package/framework/.claude/skills/remotion-best-practices/rules/display-captions.md +184 -0
  125. package/framework/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
  126. package/framework/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
  127. package/framework/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
  128. package/framework/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
  129. package/framework/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
  130. package/framework/.claude/skills/remotion-best-practices/rules/gifs.md +141 -0
  131. package/framework/.claude/skills/remotion-best-practices/rules/images.md +130 -0
  132. package/framework/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +69 -0
  133. package/framework/.claude/skills/remotion-best-practices/rules/light-leaks.md +73 -0
  134. package/framework/.claude/skills/remotion-best-practices/rules/lottie.md +67 -0
  135. package/framework/.claude/skills/remotion-best-practices/rules/maps.md +401 -0
  136. package/framework/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
  137. package/framework/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
  138. package/framework/.claude/skills/remotion-best-practices/rules/parameters.md +98 -0
  139. package/framework/.claude/skills/remotion-best-practices/rules/sequencing.md +118 -0
  140. package/framework/.claude/skills/remotion-best-practices/rules/subtitles.md +36 -0
  141. package/framework/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
  142. package/framework/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
  143. package/framework/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
  144. package/framework/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +70 -0
  145. package/framework/.claude/skills/remotion-best-practices/rules/transitions.md +197 -0
  146. package/framework/.claude/skills/remotion-best-practices/rules/transparent-videos.md +106 -0
  147. package/framework/.claude/skills/remotion-best-practices/rules/trimming.md +52 -0
  148. package/framework/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
  149. package/framework/.claude/skills/seo-audit/SKILL.md +394 -0
  150. package/framework/.claude/skills/seo-audit/references/aeo-geo-patterns.md +279 -0
  151. package/framework/.claude/skills/seo-audit/references/ai-writing-detection.md +190 -0
  152. package/framework/.claude/skills/simplify/SKILL.md +137 -0
  153. package/framework/.claude/skills/skill-creator/LICENSE.txt +202 -0
  154. package/framework/.claude/skills/skill-creator/SKILL.md +356 -0
  155. package/framework/.claude/skills/skill-creator/references/output-patterns.md +82 -0
  156. package/framework/.claude/skills/skill-creator/references/workflows.md +28 -0
  157. package/framework/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
  158. package/framework/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  159. package/framework/.claude/skills/skill-creator/scripts/quick_validate.py +95 -0
  160. package/framework/.claude/skills/ui-design/SKILL.md +199 -0
  161. package/framework/.claude/skills/ui-design/references/component-discovery.md +54 -0
  162. package/framework/.claude/skills/ui-design/references/evaluation.md +171 -0
  163. package/framework/.claude/skills/ui-design/references/generation.md +109 -0
  164. package/framework/.claude/skills/ui-design/references/inventory.md +59 -0
  165. package/framework/.claude/skills/webapp-testing/LICENSE.txt +202 -0
  166. package/framework/.claude/skills/webapp-testing/SKILL.md +123 -0
  167. package/framework/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
  168. package/framework/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
  169. package/framework/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
  170. package/framework/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
  171. package/framework/.claude/skills/worktree-manager/SKILL.md +680 -0
  172. package/framework/AGENTS.md +240 -0
  173. package/framework/agents/api-contracts.md +137 -0
  174. package/framework/agents/architecture.md +145 -0
  175. package/framework/agents/coding-standards.md +148 -0
  176. package/framework/agents/data-model.md +110 -0
  177. package/framework/agents/deployment-protocol.md +232 -0
  178. package/framework/agents/design-review.md +172 -0
  179. package/framework/agents/env-reference.md +171 -0
  180. package/framework/agents/github-issue-subagent.md +252 -0
  181. package/framework/agents/index.md +261 -0
  182. package/framework/agents/llm-wiki-methodology.md +216 -0
  183. package/framework/agents/maintenance-protocol.md +305 -0
  184. package/framework/agents/observability.md +162 -0
  185. package/framework/agents/performance.md +155 -0
  186. package/framework/agents/project-context.md +145 -0
  187. package/framework/agents/runbook.md +208 -0
  188. package/framework/agents/security.md +168 -0
  189. package/framework/agents/skills-mapping.md +286 -0
  190. package/framework/agents/testing.md +111 -0
  191. package/framework/agents/workflows.md +215 -0
  192. package/framework/docs/PROJECT-CONFIGURATION.md +336 -0
  193. package/framework/docs/references/brand-guidelines.md +170 -0
  194. package/framework/docs/references/ui-guidelines.template.md +182 -0
  195. package/framework/routines/code-review.routine.yml +46 -0
  196. package/framework/routines/doc-review.routine.yml +45 -0
  197. package/framework/routines/ds-drift.routine.yml +52 -0
  198. package/framework/routines/full-sweep.routine.yml +51 -0
  199. package/framework/routines/index.yml +70 -0
  200. package/framework/routines/skill-improve.routine.yml +50 -0
  201. package/framework/routines/wiki-review.routine.yml +45 -0
  202. package/framework/templates/baldart.config.template.yml +113 -0
  203. package/framework/templates/breaking-change-checklist.md +484 -0
  204. package/framework/templates/feature-card.template.yml +125 -0
  205. package/framework/templates/overlays/README.md +44 -0
  206. package/framework/templates/overlays/copywriting.fidelity-example.md +62 -0
  207. package/framework/templates/overlays/ui-design.fidelity-example.md +75 -0
  208. package/framework/templates/skill-project-context.snippet.md +19 -0
  209. package/framework/templates/spec.template.md +208 -0
  210. package/package.json +51 -0
  211. package/src/commands/add.js +229 -0
  212. package/src/commands/configure.js +385 -0
  213. package/src/commands/doctor.js +486 -0
  214. package/src/commands/migrate.js +185 -0
  215. package/src/commands/push.js +0 -0
  216. package/src/commands/routines.js +269 -0
  217. package/src/commands/status.js +130 -0
  218. package/src/commands/update.js +419 -0
  219. package/src/commands/version.js +88 -0
  220. package/src/utils/contamination.js +400 -0
  221. package/src/utils/git.js +181 -0
  222. package/src/utils/hooks.js +152 -0
  223. package/src/utils/routine-adapters/claude-code-cloud.js +78 -0
  224. package/src/utils/routine-adapters/cron.js +138 -0
  225. package/src/utils/routine-adapters/github-actions.js +141 -0
  226. package/src/utils/routine-adapters/index.js +21 -0
  227. package/src/utils/routines.js +166 -0
  228. package/src/utils/state.js +143 -0
  229. package/src/utils/symlinks.js +425 -0
  230. package/src/utils/ui.js +133 -0
@@ -0,0 +1,1687 @@
1
+ ---
2
+ name: new
3
+ description: >
4
+ Orchestrate a team of specialized agents to implement one or more backlog cards
5
+ end-to-end inside a dedicated worktree, with code review, doc review, QA, and
6
+ commit for each card. Usage: /new CARD-IDS (e.g., /new FEAT-0500 FEAT-0501,
7
+ /new CTP-0001-CTP-0008). Triggers on: /new, "implementa le card",
8
+ "esegui le card", "lancia le card".
9
+ ---
10
+
11
+ > **YOLO MODE**: All agents spawned via the Task tool MUST use `mode: "bypassPermissions"`. No exceptions.
12
+
13
+ ## Project Context
14
+
15
+ **Reads from `baldart.config.yml`:** `paths.backlog_dir`, `paths.references_dir`.
16
+ **Gated by features:** `features.has_backlog` (skill REFUSES to run when `false` — this orchestrator operates on backlog cards by definition).
17
+ **Overlay:** loads `.baldart/overlays/new.md` if present — project-specific canonical-docs registry (e.g. ssot-registry, linking-protocol guides), tooling paths (e.g. validation scripts).
18
+ **On missing/empty keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.
19
+
20
+ You are the **backlog orchestrator**. When the user invokes `/new <CARD-IDS>`, you create and coordinate specialized agents to implement the listed backlog cards. You NEVER write production code yourself — you only orchestrate.
21
+
22
+ Parse the card IDs from the arguments. Cards can be specified as:
23
+ - Space-separated: `GLOB-001 GLOB-002 GLOB-003`
24
+ - Hyphen-range: `GLOB-001-GLOB-008` (expands to all cards in range)
25
+ - Comma-separated: `GLOB-001, GLOB-002, GLOB-003`
26
+
27
+ If no card IDs are provided, ask the user which cards to implement.
28
+
29
+ ---
30
+
31
+ ## Context Tracking (CRITICAL)
32
+
33
+ You MUST maintain a **persistent tracking file** at `/tmp/batch-tracker-<FIRST-CARD-ID>.md` throughout the entire batch run (e.g., `/tmp/batch-tracker-FEAT-0396.md`). Use the **first card ID** from the batch as the suffix. This ensures multiple `/new` sessions running in parallel terminals (e.g., one per worktree) do NOT conflict.
34
+
35
+ This file is your single source of truth — if your context gets compacted or you lose track of what happened, **re-read this file first**.
36
+
37
+ ### Tracking file format
38
+
39
+ At batch start, create `/tmp/batch-tracker-<FIRST-CARD-ID>.md` with:
40
+
41
+ ```markdown
42
+ # Batch Run: [CARD-IDS]
43
+ Started: [timestamp]
44
+ Total cards: [N]
45
+
46
+ ## Worktree
47
+ Branch: [feat/FEAT-XXXX-slug]
48
+ Path: [.worktrees/feat-FEAT-XXXX-slug]
49
+ Port: [from registry]
50
+ Group parent: [FEAT-XXXX or "standalone"]
51
+ Main repo: [/absolute/path/to/main/repo]
52
+
53
+ ## Card Queue
54
+ - [ ] CARD-001 — [title from backlog]
55
+ - [ ] CARD-002 — [title from backlog]
56
+ ...
57
+
58
+ ## Completed Cards
59
+ (none yet)
60
+
61
+ ## Current Card
62
+ (none — starting pre-flight)
63
+
64
+ ## File Ownership Map
65
+ (built during pre-flight — one entry per agent)
66
+ | File | Assigned Agent (Card ID) |
67
+ |------|--------------------------|
68
+
69
+ ## Cross-Card Conflicts (Codex)
70
+ (pending — runs during worktree setup for batches > 1 card)
71
+
72
+ ## Issues & Flags
73
+ (none yet)
74
+
75
+ ## Lessons Learned
76
+ (none yet)
77
+ <!-- Format: "PHASE: pattern — file" e.g. "SIMPLIFY: use formatCurrency util — src/lib/utils.ts" -->
78
+ ```
79
+
80
+ ### Update rules
81
+
82
+ - **Before starting a card**: move it to `## Current Card` with phase info.
83
+ - **After each phase**: update the current card's phase status in the tracker.
84
+ - **After completing a card**: move it from `Current Card` to `## Completed Cards` with:
85
+ - Commit hash
86
+ - One-line summary of what was implemented
87
+ - Any flags/issues found
88
+ - Doc review result (pass/fail + what was added)
89
+ - Test results (new + existing count, pass/fail)
90
+ - Fix cycles count
91
+ - UX testing result (PASS/FAIL/SKIP + test file path if written)
92
+ - QA result (profile used: skip/light/balanced/deep | verdict: PASS/FAIL/SKIP | confidence % | findings: N blockers, N majors | E2E: PASS/FAIL/SKIP)
93
+ - QA findings file (e.g. `/qa/FEAT-XXXX.md` or "skipped")
94
+ - **card_status: DONE (verified)** — confirms the backlog YAML was updated and re-read to verify
95
+ - **When blocked**: log the blocker in `## Issues & Flags`.
96
+ - **On context recovery**: if you ever feel lost or after context compaction, IMMEDIATELY read your tracker file (`/tmp/batch-tracker-<FIRST-CARD-ID>.md`) to restore your state.
97
+
98
+ ---
99
+
100
+ ## Pre-flight (once)
101
+
102
+ 1. Read each backlog card from `${paths.backlog_dir}/*.yml` to understand scope and dependencies. Also read the project's canonical-docs registry — typically `${paths.references_dir}/ssot-registry.md` plus any linking-protocol guide — to understand which canonical docs exist for the feature area being implemented. Exact filenames are listed in `.baldart/overlays/new.md`; skip when absent.
103
+ 1b. **Validate card fields (pre-flight gate)** — for each card, verify it has the minimum required fields before queuing it:
104
+ - `requirements` — must be a non-empty list (>=1 item)
105
+ - `acceptance_criteria` — must be a non-empty list (>=1 item)
106
+ - `files_likely_touched` — must be a non-empty list (>=1 file)
107
+ If any card fails: log the specific missing fields in `## Issues & Flags`, ask the user to fill them in before proceeding with that card, and continue pre-flight for any remaining valid cards.
108
+
109
+ 1c. **Field Registry Validation (pre-flight gate)** — for each card with a `data_fields` block, run the project's field-validation tool if available (path listed in `.baldart/overlays/new.md`; typically `python3 tools/validate-card-fields.py <card-yaml-path>`).
110
+ - If exit 1: display the field errors in `## Issues & Flags` and HALT — ask the user to fix the card before proceeding. Do not start implementation until the card passes validation.
111
+ - If the card has DB-index signals (e.g. `firestore_indexes`, `data.collections`) but NO `data_fields` block: log WARNING in `## Issues & Flags` — "Card `<ID>` touches storage but has no `data_fields` block. Field names are unvalidated."
112
+ - Cards with no `data_fields` and no storage signals: skip silently.
113
+ - If the project does not ship a field-validation tool: skip this step.
114
+ 2. Check `${paths.references_dir}/project-status.md` for current state (skip when absent).
115
+ 3. Determine which cards can run in **parallel** (no shared files/components) vs which must be **sequential** (dependencies or overlapping paths). Use `group.sequence` to determine execution order within a group.
116
+ 3b. **Build a file-ownership map** — for each card, enumerate every source file it is expected to touch (from `claimed_paths`, `paths`, and the implementation plan). Assign each file to **exactly one agent**. If two cards claim the same file, force those cards sequential on a single agent — do NOT spawn them in parallel. Record this map in the tracker under `## File Ownership Map`. This map is the authoritative source for all agent file permissions in Phase 2.
117
+ 3c. **Complexity assessment — team mode decision**
118
+
119
+ Determine whether to use **team mode** (parallel coder agents with isolated contexts) or keep **sequential mode** (current behavior).
120
+
121
+ **Decision logic:**
122
+
123
+ 1. Read `execution_strategy.recommended_mode` from the epic parent card (if it exists). If present, use it as the default.
124
+ 2. If no `execution_strategy` exists, compute:
125
+ - Count total cards in batch
126
+ - Count max cards in any single parallel group (from `parallel_group` field)
127
+ - If any card lacks `parallel_group`, compute it on-the-fly: build dependency graph from `depends_on`/`blocks`, add conflict edges for cards sharing `(MODIFY)` files, compute topological layers via BFS.
128
+ 3. Apply threshold:
129
+ - **Sequential mode** if ANY of: total cards <= 3 — OR all cards are in different parallel groups (max group size = 1, nothing to parallelize) — OR all cards form a linear dependency chain.
130
+ - **Team mode** if: total cards > 3 AND at least one parallel group has 2+ cards.
131
+ 4. Log decision in tracker:
132
+ ```
133
+ ## Execution Mode
134
+ Mode: team | sequential
135
+ Reason: [e.g., "6 cards, 3 parallel groups, max 3 cards in group 1"]
136
+ ```
137
+ 5. Inform the user:
138
+ ```
139
+ Batch: N cards, M file unici
140
+ Gruppi paralleli: K livelli, max P card in parallelo
141
+ Modalita: **team mode** / **sequential mode** — [reason]
142
+ ```
143
+ Proceed without asking (the PRD already approved the strategy).
144
+
145
+ When `mode == sequential`, the per-card pipeline below runs exactly as documented. The `parallel_group` field is simply ignored. When `mode == team`, skip the per-card pipeline and follow the **Team Mode** section at the end of this document.
146
+
147
+ 3d. **Codex batch cross-card grounding check** (runs in background during worktree setup)
148
+
149
+ > **Why**: GPT-5.4 reviews the full card batch for cross-card conflicts that per-card plan-auditor checks cannot detect (each plan-auditor sees only one card).
150
+
151
+ **Skip if**: batch has only 1 card (no cross-card conflicts possible).
152
+
153
+ Launch via `Bash` with `run_in_background: true` and `timeout: 300000`:
154
+
155
+ ```bash
156
+ AUDIT_FILE="/tmp/codex-crosscard-$(date +%Y-%m-%d).md" && \
157
+ 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)" && \
158
+ [ -z "$CODEX_SCRIPT" ] && echo "CODEX_NOT_FOUND" && exit 1; \
159
+ node "$CODEX_SCRIPT" task --wait "
160
+ Cross-card grounding check for a batch of backlog cards about to be implemented together.
161
+ Your job is to find conflicts BETWEEN cards that per-card reviewers would miss.
162
+
163
+ Cards to check (read each file):
164
+ ${CARD_PATHS}
165
+
166
+ File-ownership map:
167
+ ${FILE_OWNERSHIP_MAP}
168
+
169
+ Check:
170
+ 1. FILE CONFLICTS: Do two cards modify the same file in incompatible ways?
171
+ (e.g., Card A adds field X to interface Foo, Card B restructures Foo entirely)
172
+ 2. IMPLICIT DEPENDENCIES: Does Card A change a type/function that Card B's
173
+ requirements assume stays unchanged? Flag missing depends_on.
174
+ 3. EXECUTION ORDER RISKS: Given the parallel_group assignments, will parallel
175
+ execution cause merge conflicts or type errors?
176
+ 4. SHARED STATE MUTATIONS: Do multiple cards write to the same Firestore
177
+ collection/document in ways that could conflict at runtime?
178
+
179
+ For each finding return:
180
+ - **Cards involved**: CARD-A + CARD-B
181
+ - **Conflict type**: FILE_CONFLICT | IMPLICIT_DEP | ORDER_RISK | STATE_MUTATION
182
+ - **Evidence**: exact field/file from each card
183
+ - **Fix**: concrete recommendation (add depends_on, force sequential, etc.)
184
+
185
+ If no cross-card conflicts: return PASS.
186
+ " 2>&1 | tee "$AUDIT_FILE"
187
+ ```
188
+
189
+ **Variable interpolation**:
190
+ - `${CARD_PATHS}`: newline-separated list of all `- backlog/FEAT-XXXX-*.yml` paths in the batch
191
+ - `${FILE_OWNERSHIP_MAP}`: the file-ownership map built in step 3b
192
+
193
+ **Result handling** (read before Phase 1 of first card):
194
+ - Read `/tmp/codex-crosscard-{YYYY-MM-DD}.md` after background command completes.
195
+ - If **PASS** or file empty/missing: proceed normally.
196
+ - If **conflicts found**: log in tracker under `## Cross-Card Conflicts (Codex)` and present to user. For each conflict:
197
+ - `FILE_CONFLICT` / `ORDER_RISK` → force the conflicting cards sequential (update file-ownership map).
198
+ - `IMPLICIT_DEP` → add `depends_on` entry to tracker notes (do NOT modify backlog YAML).
199
+ - `STATE_MUTATION` → add warning to both cards' Phase 2 briefings.
200
+
201
+ 4. **Worktree setup** — delegate to the **worktree-manager** skill (`/nw` in programmatic mode):
202
+ a. Pass all card IDs and their `group.parent` fields to the skill's grouping logic.
203
+ b. The skill handles: grouping cards by `group.parent`, deriving branch names from `git_strategy.branch`, creating the worktree in `.worktrees/`, installing dependencies, copying env files, assigning a free port, and verifying the build.
204
+ c. The skill updates `.worktrees/registry.json` with the worktree entry (including all card IDs in the `cards` field).
205
+ d. If build fails → the skill STOPs and reports. Do NOT continue.
206
+ e. Record the worktree path, branch, and port from the skill's output in the tracker.
207
+ 6. Create the tracking file `/tmp/batch-tracker-<FIRST-CARD-ID>.md` (include worktree path and branch name).
208
+ 7. Create a task list to track progress across all cards.
209
+
210
+ ---
211
+
212
+ ## QA Profile Selector
213
+
214
+ Before Phase 3.5, determine the QA profile for each card by reading its YAML metadata. Use the **first matching rule** (priority order):
215
+
216
+ | Profile | When to apply |
217
+ |---------|--------------|
218
+ | **SKIP** | Card type is `docs`, `chore`, or `config` — OR all changed paths are `.md`/`.yml` (non-API)/CSS with zero logic files — OR title contains only cosmetic keywords (typo, rename, copy, wording, style) with no code areas |
219
+ | **LIGHT** | Card type is `bugfix` OR `refactor` — AND ≤3 files likely touched — AND no HIGH-risk keywords in paths/areas/title. **NEVER applies to `feature` or `enhancement` cards.** |
220
+ | **BALANCED** | Default for ALL `feature` / `enhancement` cards not matching DEEP rules — OR `bugfix`/`refactor` with >3 files or HIGH-risk keywords |
221
+ | **DEEP** | ANY of: areas includes both `api` + `data` — OR paths/title contain `auth`, `payment`, `permission`, `schema`, `migration`, `cron`, `webhook`, `transaction` — OR >15 files likely touched — OR acceptance criteria count > 5 — OR Firestore indexes changed — OR API contract changed — OR `data_fields` block has ≥3 entries with `status: new` or `status: modified` |
222
+
223
+ **Critical**: `feature` and `enhancement` cards are ALWAYS BALANCED minimum — never LIGHT. The `files_likely_touched` field in YAML underestimates actual scope; ignore it for profile decisions on feature cards. When in doubt between BALANCED and DEEP, use DEEP.
224
+
225
+ ---
226
+
227
+ ## Per-card pipeline
228
+
229
+ For each card, execute these phases in order:
230
+
231
+ ### Phase 1 — Claim & Context
232
+ 1. **Update tracker**: set current card, phase = "1-claim".
233
+ 2. Set the card status to `IN_PROGRESS` and assign yourself.
234
+ 2b. **`depends_on` gate** — read the card's `depends_on` field. For each listed card ID:
235
+ - Read that card's backlog YAML and check its `status` field.
236
+ - If NOT `DONE` → HALT: log in `## Issues & Flags` and ask the user: "Card <CARD-ID> depends on <DEP-ID> which is `<status>`. Proceed anyway, or wait?" Do not start implementation until the user responds explicitly.
237
+ - If `DONE` → continue.
238
+ 3. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project).
239
+ 4. Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation.
240
+ 4b. **Plan-auditor grounding check** — invoke the **plan-auditor** agent in QUICK mode with this prompt:
241
+ ```
242
+ Quick grounding check only (not a full audit). Verify this backlog card's requirements are grounded in the actual codebase.
243
+
244
+ Check:
245
+ 1. Do all paths in files_likely_touched actually exist?
246
+ 2. Are all type/field references in requirements correct per the codebase findings below?
247
+ 3. Are any [ASSUMED] items answerable by reading the listed files (i.e., should be verified facts)?
248
+ 4. Do any requirements conflict with known anti-patterns from your memory?
249
+
250
+ Card YAML:
251
+ [paste full card YAML]
252
+
253
+ Codebase-architect findings:
254
+ [paste key findings from step 4]
255
+
256
+ Return: PASS | FIXES NEEDED (list exact corrections). No full audit report needed.
257
+ ```
258
+ - If **FIXES NEEDED**: apply corrections to the tracker notes for this card (do NOT modify the backlog YAML). Carry the corrected requirements into the Phase 2 briefing.
259
+ - If **PASS**: proceed.
260
+ 5. **Update tracker**: phase = "1-claim DONE", log codebase-architect key findings (1-2 lines) and plan-auditor result (PASS or corrections applied).
261
+
262
+ ### Phase 2 — Implement (self-healing, up to 3 retries)
263
+ 6. **Update tracker**: phase = "2-implement".
264
+ 7. Spawn the **coder** agent (or appropriate specialist from `.claude/agents/REGISTRY.md`) using this **standardized mission briefing** — fill in each section from the card YAML, tracker, and codebase-architect findings:
265
+
266
+ ```
267
+ ## MISSION BRIEFING — <CARD-ID>
268
+
269
+ ### Card Specification (verbatim — do not paraphrase)
270
+ Requirements:
271
+ [copy full requirements list from card YAML, including any corrections from plan-auditor step 4b]
272
+
273
+ Acceptance Criteria:
274
+ [copy full acceptance_criteria list from card YAML]
275
+
276
+ ### Unknowns & Conditional Requirements (MANDATORY — resolve before coding)
277
+ [If card has `unknowns` field: copy verbatim. If empty or absent: "None."]
278
+
279
+ Each unknown that says "verify X; if missing → do Y" is a BINARY-OUTCOME ITEM.
280
+ You MUST actively verify and produce one of the two outcomes (implementation OR TODO comment).
281
+ See `coder.md § Conditional Requirements — Binary-Outcome Items`.
282
+
283
+ ### Business Context (WHY this feature exists)
284
+ [paste business_rationale field from card YAML]
285
+ [if field is empty/missing, read PRD Section 1b from card's links.prd path]
286
+
287
+ ### Codebase Context
288
+ [paste codebase-architect key findings: file paths, exact line numbers, type signatures, existing patterns to follow]
289
+ [include any corrections or anti-patterns flagged by plan-auditor grounding check]
290
+
291
+ ### Design Reference (UI cards only — include if card has links.design)
292
+ Design file: [path from card's links.design field]
293
+ Read the design.html file and use it as the visual reference for your implementation.
294
+ The design was approved by the user — your implementation MUST match it.
295
+
296
+ ### File Permissions (ENFORCED — no exceptions)
297
+ MAY EDIT — your files for this card:
298
+ [list from ownership map for this card]
299
+
300
+ MUST READ ONLY — shared dependencies:
301
+ [list from ownership map: files owned by other cards that this card reads]
302
+
303
+ FORBIDDEN:
304
+ - Do NOT edit any file outside the MAY EDIT list above
305
+ - Do NOT refactor unrelated code
306
+ - Do NOT add unrequested features or extra error handling beyond what's specified
307
+ - Do NOT modify test files unless the card explicitly requires it
308
+
309
+ ### Firestore Composite Indexes (if card has `firestore_indexes` field)
310
+ This card requires the following composite indexes in `firestore.indexes.json`.
311
+ You MUST add these in the SAME commit as the query code. Missing indexes cause
312
+ runtime FAILED_PRECONDITION errors (500 in production).
313
+
314
+ [paste firestore_indexes entries from card YAML, formatted as:]
315
+ | Collection | Fields | Query Location | PRD Ref |
316
+ |-----------|--------|----------------|---------|
317
+ | [collection] | [field1 ASC, field2 DESC] | [file path] | [IDX-N] |
318
+
319
+ For each index, add the corresponding entry to `firestore.indexes.json` under
320
+ `indexes[]` with this format:
321
+ ```json
322
+ {
323
+ "collectionGroup": "<collection>",
324
+ "queryScope": "COLLECTION",
325
+ "fields": [
326
+ { "fieldPath": "<field1>", "order": "ASCENDING" },
327
+ { "fieldPath": "<field2>", "order": "DESCENDING" }
328
+ ]
329
+ }
330
+ ```
331
+ Include `firestore.indexes.json` in your staged files.
332
+
333
+ ### Expected Output Locations
334
+ [pre-fill from codebase-architect: for each requirement, the file:line where the change should go]
335
+
336
+ ### Project Anti-Patterns & NFRs (ENFORCED)
337
+ Violating these is a BLOCKER in code review.
338
+
339
+ Deprecated patterns (from AGENTS.md / MEMORY.md — adapt to your project):
340
+ - List the project-specific anti-patterns documented in AGENTS.md / MEMORY.md
341
+ - Example: deprecated permission shortcuts, deprecated client-state APIs, etc.
342
+
343
+ Performance MUST rules (adapt to your stack):
344
+ - Bounded reads on every database query (`.limit()` / equivalent)
345
+ - Cursor-based pagination, not offset
346
+ - No per-row fetches in loops — batch instead
347
+ - Database indexes declared in schema config (same commit as the query that needs them)
348
+
349
+ Security MUST rules:
350
+ - No stack traces in HTTP responses — generic messages + error codes only
351
+ - No PII in console.log or error tracking
352
+ - No hardcoded secrets — env vars only
353
+ - ALL non-public routes MUST use the project's auth middleware
354
+
355
+ Coding standards (agents/coding-standards.md):
356
+ - Use the project's canonical terminology (document it in coding-standards.md)
357
+ - Honor the design-system theming contract (e.g. text/background pairing rules)
358
+ - Honor the project's image-format and asset-pipeline rules
359
+
360
+ Design System SSOT (MANDATORY for UI cards):
361
+ - Master reference: `${paths.design_system}/INDEX.md` (component index + Canonical Authority
362
+ Matrix + Quick rules MUST). Read this BEFORE touching any UI file.
363
+ - For each UI component you modify or create, read `${paths.design_system}/components/<Name>.md`.
364
+ - Merchant-themed surfaces MUST follow the pairing rule in
365
+ `the project's theming pattern doc (listed in `.baldart/overlays/ui-design.md`)`.
366
+ - Motion MUST follow `the project's motion pattern doc (listed in `.baldart/overlays/ui-design.md`)` (reduced-motion variants
367
+ required). The coder agent's own hardening (see `.claude/agents/coder.md`) already enforces
368
+ this — this briefing is an explicit reminder for UI-touching cards.
369
+ - No hardcoded hex/shadow/border values in component styling — canonical tokens only.
370
+
371
+ ### Batch Lessons (from prior cards in this batch)
372
+ [If tracker `## Lessons Learned` has entries, paste them here.
373
+ If empty or first card: "First card — no lessons yet."]
374
+
375
+ ### MANDATORY: Numbered Requirements Checklist (anti-skip measure)
376
+ Before you start coding, print this checklist to confirm you see ALL requirements:
377
+ ```
378
+ REQUIREMENTS TO IMPLEMENT:
379
+ [x] R1: [requirement text]
380
+ [x] R2: [requirement text]
381
+ ...
382
+ ACCEPTANCE CRITERIA TO SATISFY:
383
+ [x] AC1: [criterion text]
384
+ [x] AC2: [criterion text]
385
+ ...
386
+ CONDITIONAL / BINARY-OUTCOME ITEMS (from unknowns + requirements with "verify if / if missing"):
387
+ [ ] C1: [item text] → Branch to take: A (found+implement) | B (missing+TODO)
388
+ [ ] C2: [item text] → Branch to take: A (found+implement) | B (missing+TODO)
389
+ ...
390
+ Total: N requirements + M acceptance criteria + K conditional items = X items
391
+ ```
392
+ You MUST implement ALL items. Skipping even one is a failure.
393
+ For each conditional item: verify actively, then produce the correct branch artifact.
394
+
395
+ ### MANDATORY: Completion Report
396
+ When implementation is done, output this block in EXACTLY this format.
397
+ This report is NOT optional — if you omit it, the orchestrator will flag
398
+ your implementation as incomplete and spawn a fix agent.
399
+
400
+ ```completion-report
401
+ card: <CARD-ID>
402
+ requirements:
403
+ - id: 1
404
+ text: "[verbatim requirement text]"
405
+ status: done | partial | blocked
406
+ evidence: "src/path/to/file.ts:LINE_NUMBER"
407
+ notes: "[if partial or blocked: explain why]"
408
+ - id: 2
409
+ [repeat for each requirement]
410
+ acceptance_criteria:
411
+ - id: 1
412
+ text: "[verbatim criterion text]"
413
+ status: done | partial | blocked
414
+ evidence: "src/path/to/file.ts:LINE_NUMBER"
415
+ items_total: [N]
416
+ items_done: [M]
417
+ items_skipped: [list of skipped item IDs, or "none"]
418
+ conditional_items:
419
+ - item: "[verbatim text of conditional requirement]"
420
+ branch_taken: "A-found" | "B-missing"
421
+ evidence: "src/path/to/file.ts:LINE_NUMBER"
422
+ notes: "[if B-missing: exact TODO location and text left; otherwise omit]"
423
+ ```
424
+
425
+ If `items_skipped` is not "none", you MUST explain why each was skipped.
426
+ The orchestrator treats any skipped item as a gap requiring a fix agent.
427
+ `conditional_items` MUST list every binary-outcome item from the card. If the card has no
428
+ conditional requirements, omit the field. `branch_taken: B-missing` MUST have a `notes`
429
+ field with the exact file path and line where the TODO comment was written.
430
+ ```
431
+
432
+ 8. Run `npm test` (if tests exist), `npm run build`, and `npm run lint` to verify everything passes.
433
+ 9. **If any check fails**: categorize the error (`lint | TypeScript | test | build`), log it in the tracker as `retry-cause: <category>`.
434
+ **Stash recovery (MUST check before rewriting)**: before spawning a fix agent or rewriting code, check if a previous stash contains the needed changes:
435
+ ```bash
436
+ git stash list
437
+ ```
438
+ If a named agent stash exists (e.g., `stash@{0}: On feat/...: agent-XXXXXXXXXX`), inspect it:
439
+ ```bash
440
+ git stash show -p stash@{0}
441
+ ```
442
+ If the stash contains edits that lint-staged removed (e.g., a field definition that was "unused" at commit time but is needed by subsequent code), recover with `git stash pop` instead of rewriting from scratch. Only spawn a fix agent if the stash does NOT contain the needed changes.
443
+ When spawning a fix agent: scope it exclusively to this card's Edit-allowed files (from `## File Ownership Map`) — it MUST NOT touch files owned by other cards. Pass the fix agent: the error output, the error category, the explicit list of files it may edit, and the failing check output. Do NOT ask the user — just fix and re-run. Fix the code, not the tests (unless the test itself is wrong). Repeat up to **3 times**.
444
+ 10. If still failing after 3 retries, log the failure in `## Issues & Flags` and ask the user before continuing.
445
+ 11. **Update tracker**: phase = "2-implement DONE", log files changed (short list), retry count, retry causes (e.g., `"2 retries: TypeScript x1, lint x1"`), and test results (new + existing test count, pass/fail).
446
+ 11b. **File diff gate** — verify the coder only touched its allowed files:
447
+ ```bash
448
+ cd <worktree-path> && git diff --name-only HEAD
449
+ ```
450
+ Compare against this card's allowed files in `## File Ownership Map`.
451
+ - **All within allowed set** → proceed to Phase 2.5.
452
+ - **Any file outside allowed set** → log the violation in `## Issues & Flags` (`"unauthorized file: <path>"`), then spawn a **targeted revert coder agent** with instruction: "Revert ONLY these files to their pre-commit state. Do not touch any other file: [list unauthorized files]". Re-run build + lint to confirm clean state after revert. Update tracker with revert outcome, then proceed to Phase 2.5.
453
+
454
+ ### Phase 2.5 — Implementation Completeness Check (MANDATORY)
455
+
456
+ Before triggering any review, you MUST verify that the coder agent implemented **every requirement and acceptance criterion** in the backlog card. This is a blocking gate — do NOT proceed to Phase 3 with unimplemented items.
457
+
458
+ **Step-by-step**:
459
+
460
+ 0. **Conditional requirements pre-scan** (BLOCKING — before building the main checklist):
461
+
462
+ Scan the card's `requirements`, `acceptance_criteria`, `unknowns`, and `notes` fields for
463
+ conditional language patterns: "verify if / verify whether", "if missing / if not present /
464
+ if not found / if not already", "if already exists / if already included", "leave TODO /
465
+ add TODO / leave a note", "add if needed / create if missing", "add support if missing".
466
+
467
+ For each match, classify as a **binary-outcome item** and verify:
468
+ a. Positive branch: grep changed files for the implementation.
469
+ b. Negative branch (B-missing): grep codebase for `// TODO [CARD-ID]:` at the relevant location.
470
+
471
+ If NEITHER branch artifact exists → classify as `Missing` (not Partial) and trigger the
472
+ gap-resolution fix agent sub-loop immediately for these items (before continuing the checklist).
473
+
474
+ Also check: if the card has conditional requirements but the completion report has no
475
+ `conditional_items` section → flag as `Missing` (the coder must document the branch taken).
476
+
477
+ 1. **Update tracker**: phase = "2.5-completeness".
478
+ 2. Re-read the backlog card (`requirements`, `acceptance_criteria`, `unknowns`, and `definition_of_done` fields).
479
+ 3. Build a checklist — one row per item:
480
+
481
+ ```
482
+ ## Completeness Check — <CARD-ID>
483
+ | # | Requirement / Criterion | Status | Evidence |
484
+ |---|------------------------|--------|----------|
485
+ | 1 | [requirement text] | Done / Missing / Partial | [file:line or "not found"] |
486
+ | 2 | [acceptance criterion] | Done / Missing / Partial | [file:line or "not found"] |
487
+ ```
488
+
489
+ 4. For each item, verify by **reading the actual implementation code** (use Grep/Read).
490
+ Do NOT trust the coder agent's completion report alone — verify independently.
491
+
492
+ **Verification depth per requirement type:**
493
+ - **"Create endpoint/route"** → verify: route file exists, handler has correct HTTP method,
494
+ request validation present, response shape matches requirement, auth middleware applied.
495
+ - **"Add UI component/page"** → verify: component file exists, renders the required elements,
496
+ handles loading/error/empty states if specified, is wired into the page/layout.
497
+ - **"Add field/collection"** → verify: type definition updated, field used in read AND write
498
+ paths, validation present if specified.
499
+ - **"Integrate with X"** → verify: import exists, function is called with correct parameters,
500
+ error handling present.
501
+ - **Data fields completeness** → if card has `data_fields` block:
502
+ - For each `status: existing` field: grep the changed files to confirm the field name is
503
+ referenced in the implementation. A declared-but-unused field is a red flag (wrong name
504
+ or dead code). Log in checklist as Partial if not found.
505
+ - For each `status: new` field: verify the field is BOTH written (setter/creator path)
506
+ AND read (getter/reader path) in the changed files.
507
+ - For each `status: modified` field: verify old-name references are removed and
508
+ new-name references exist.
509
+ - **Firestore compound query** → verify: if the card has a `firestore_indexes` field,
510
+ check that EVERY listed index exists in `firestore.indexes.json` (match collection +
511
+ fields + order). Also grep the query code to confirm `where()` + `orderBy()` field
512
+ names match the index definition exactly. Missing or mismatched index = CRITICAL gap
513
+ (causes runtime 500 FAILED_PRECONDITION).
514
+
515
+ If the completion report has `items_skipped` that is not "none", immediately flag those
516
+ items as Missing regardless of the agent's justification.
517
+
518
+ 5. Classify each item:
519
+ - **Done** — code exists AND satisfies the FULL scope of the requirement (not just partial).
520
+ - **Partial** — some code exists but the criterion is not fully satisfied (e.g., UI renders but no error state, endpoint exists but wrong response shape).
521
+ - **Missing** — no evidence found in the codebase, OR the coder agent explicitly skipped it.
522
+
523
+ **Gap resolution** (for Partial and Missing items):
524
+
525
+ - Spawn a **targeted fix coder agent** with:
526
+ - The exact list of unimplemented items (copy the checklist rows)
527
+ - The file-ownership restrictions from `## File Ownership Map`
528
+ - The instruction: "Implement ONLY these missing items. Do not refactor or expand scope."
529
+ - After the fix agent completes, re-run build + lint (`npm run build && npm run lint`).
530
+ - Re-verify each fixed item against the code — do NOT trust the agent's self-report.
531
+ - Repeat this sub-loop up to **2 times**. After 2 loops, if items remain Missing:
532
+ - Log in `## Issues & Flags`: list each unimplemented requirement.
533
+ - Ask the user whether to proceed to review despite the gap or stop.
534
+
535
+ 5b. **API contract check** (only for MODIFIED `route.ts` files — new routes are exempt):
536
+ - From `git diff --name-only`, identify `route.ts` files that existed before this card.
537
+ - For each modified route:
538
+ a. Derive the API module from path (e.g., `src/app/api/v1/booking/[id]/route.ts` → `booking`).
539
+ b. Read `${paths.references_dir}/api/<module>.md` (or subdirectory match).
540
+ c. Read the modified route, extract response shape from `NextResponse.json()` calls.
541
+ d. Compare against documented schema.
542
+ e. Flag: removed fields or changed types → `[API-CONTRACT] BREAKING` in `## Issues & Flags` (BLOCKER).
543
+ Added fields only → `[API-CONTRACT] ADDITIVE` (informational).
544
+ No doc found → `[API-CONTRACT] NO-DOC` (informational).
545
+
546
+ 5c. **Reference-aliasing mutation check** (MANDATORY — deterministic detector, BUG-0558 prevention).
547
+
548
+ Detect call sites that pair a helper invocation with in-place mutation of an input array
549
+ without an identity guard. Anti-pattern (the BUG-0558 family):
550
+
551
+ ```ts
552
+ const result = filterHelper(input, ...);
553
+ input.length = 0; // ← wipes both input AND result when result === input
554
+ input.push(...result); // ← pushes zero elements (result was just emptied)
555
+ ```
556
+
557
+ Run this exact bash block in the worktree:
558
+
559
+ ```bash
560
+ cd <worktree-path>
561
+ CHANGED_TS="$(git diff --name-only develop...HEAD -- '*.ts' '*.tsx' 2>/dev/null \
562
+ || git diff --name-only HEAD~1 -- '*.ts' '*.tsx')"
563
+
564
+ ALIAS_HITS=()
565
+ for f in $CHANGED_TS; do
566
+ [ -f "$f" ] || continue
567
+ # Heuristic: find lines matching `arr.length = 0` followed within 3 lines by `arr.push(...result)`.
568
+ # Capture the variable name; flag for human/agent review.
569
+ python3 - "$f" <<'PY'
570
+ import re, sys
571
+ src = open(sys.argv[1]).read().splitlines()
572
+ for i, line in enumerate(src):
573
+ m = re.search(r'(\w+)\.length\s*=\s*0', line)
574
+ if not m: continue
575
+ var = m.group(1)
576
+ # Look back 5 lines for a const/let assignment from a function call returning to a different name,
577
+ # then forward 3 lines for `var.push(...other)`.
578
+ back = "\n".join(src[max(0,i-5):i])
579
+ fwd = "\n".join(src[i+1:i+4])
580
+ assign = re.search(rf'const\s+(\w+)\s*=\s*\w+\([^)]*\b{re.escape(var)}\b', back)
581
+ push = re.search(rf'{re.escape(var)}\.push\(\.\.\.(\w+)\)', fwd)
582
+ if assign and push and assign.group(1) == push.group(1):
583
+ print(f"{sys.argv[1]}:{i+1}: ALIAS-MUTATION candidate — '{var}.length = 0' followed by '{var}.push(...{push.group(1)})' where {push.group(1)} comes from a call that received {var}")
584
+ PY
585
+ done
586
+ ```
587
+
588
+ For each hit, classify by reading 10 lines of context around the match:
589
+
590
+ - **Guarded** — an `if (<assignedName> !== <var>)` check wraps the reset+push block. SAFE. Log `[ALIAS-MUTATION] guarded` (informational, no action).
591
+ - **Defensively cloned** — the helper was called with `[...var]` or `var.slice()` instead of `var`. SAFE. Log `[ALIAS-MUTATION] cloned` (informational).
592
+ - **Helper always returns new array** — read every `return` in the helper. If ALL paths return `[...candidates]` / `candidates.filter(...)` / a new array literal, identity collision is impossible. SAFE. Log `[ALIAS-MUTATION] helper-immutable` (informational).
593
+ - **Un-guarded** — none of the above. Flag `[ALIAS-MUTATION] BLOCKER` in `## Issues & Flags` with file:line and the captured pattern.
594
+
595
+ For each `[ALIAS-MUTATION] BLOCKER`:
596
+
597
+ - Spawn a targeted fix `coder` agent with the exact file:line and instruction: "Add identity guard `if (result !== input) { ... }` around the in-place reset, OR clone the input with `[...input]` before passing it to the helper. Add a regression test on the caller pattern (see `tests/booking/apply-orphan-protection-reference.test.ts` as reference). Read `agents/coding-standards.md § Reference-Aliasing Mutation Patterns` before implementing."
598
+ - Re-run the detector after the fix. The hit MUST classify as Guarded, Cloned, or helper-immutable. Repeat **max 2 times**.
599
+ - If still un-guarded after 2 loops → log in `## Issues & Flags` and ask the user.
600
+
601
+ Rationale: BUG-0558 (2026-05-11) shipped to develop and collapsed availability to zero options for any store with protected Solo-Combo tables. Cause: `applyOrphanProtection()` returns the same input reference on 3 of 4 paths; the call site did `options.length = 0; push(...result)` without an identity guard. The helper passed unit tests in isolation; the bug only manifested end-to-end. This detector closes that detection gap.
602
+
603
+ 5d. **Caller-pattern test coverage check** (MANDATORY — when card introduces or modifies an exported helper consumed by 1+ caller with in-place mutation).
604
+
605
+ If the card's diff includes BOTH (a) an `export function` / `export const` declaration in a `src/lib/**` file AND (b) at least one call site in another file that mutates an input array in place (detected via the bash block in 5c), verify that a test file exists that exercises the **caller pattern** — not only the helper in isolation.
606
+
607
+ Required test characteristics:
608
+
609
+ - At least one case asserts the post-call state of the input array (e.g. `assert.strictEqual(options.length, 3)` after the helper invocation).
610
+ - At least one **negative-control case** documents the failure mode that would occur if the identity guard / defensive clone were removed (e.g. `tests/booking/apply-orphan-protection-reference.test.ts:182-205`).
611
+
612
+ If the test is missing:
613
+
614
+ - Spawn a targeted fix `coder` agent to write the test. The test MUST live in a file co-located with similar helpers (e.g. `tests/booking/<helper-name>-reference.test.ts`).
615
+ - This is BLOCKING for Phase 4 commit when the helper is on a high-risk path (auth, payments, booking-availability, DORE primitives). On non-high-risk paths it's a HIGH-severity flag but the orchestrator may proceed and defer to `/codexreview`.
616
+
617
+ Rationale: BUG-0558's introducing card (FEAT-0850-02) had its tests deferred to the later E2E card (FEAT-0850-07). The helper passed in isolation; the caller pattern was never tested. A caller-pattern test at the helper-card level would have caught the bug 2 days earlier.
618
+
619
+ 6. **Update tracker**: phase = "2.5-completeness DONE", log result (PASS / GAPS REMAIN + count).
620
+
621
+ ### Phase 2.55 — Simplify (code cleanup before review)
622
+
623
+ After completeness is verified, clean up the implementation before it reaches reviewers and E2E tests. This phase launches three parallel agents on the card's diff, then applies fixes directly.
624
+
625
+ **Step-by-step**:
626
+
627
+ 1. **Update tracker**: phase = "2.55-simplify".
628
+ 2. Run `git diff` in the worktree to capture all changes for the current card.
629
+ 3. Launch **three agents in parallel** (single message, all receive the full diff):
630
+
631
+ - **Reuse agent** — search the codebase for existing utilities/helpers that could replace newly written code. Flag duplicated functionality, inline logic that could use existing utils.
632
+ - **Quality agent** — flag redundant state, parameter sprawl, copy-paste with slight variation, leaky abstractions, stringly-typed code where constants/enums exist, unnecessary JSX nesting, unnecessary comments (WHAT comments, narration, task references).
633
+ - **Efficiency agent** — flag unnecessary work (redundant computations, duplicate API calls, N+1), missed concurrency, hot-path bloat, recurring no-op updates without change-detection guards, TOCTOU existence checks, memory issues (unbounded structures, missing cleanup), overly broad operations.
634
+
635
+ 4. Aggregate findings from all three agents. For each finding:
636
+ - **Valid** → fix directly (no coder agent spawn — apply edits inline).
637
+ - **False positive / not worth addressing** → skip silently, do not log.
638
+
639
+ 5. After all fixes, run `npm run lint` and `npx tsc --noEmit` to confirm nothing broke.
640
+ If either fails, fix the regression (up to 2 retries).
641
+
642
+ 6. **Update tracker**: phase = "2.55-simplify DONE", log count of fixes applied (or "clean — 0 fixes").
643
+ If any valid finding revealed a reusable pattern or common mistake, append 1-line to `## Lessons Learned`:
644
+ `SIMPLIFY: <pattern> — <file>`
645
+
646
+ ### Phase 2.6 — E2E Testing (PRD-driven, card-level)
647
+
648
+ This phase uses the `test_plan` field from the backlog card YAML to determine whether
649
+ to write and run E2E tests. The test plan was defined during `/prd` discovery.
650
+
651
+ **Trigger detection** — read the card's `test_plan` field:
652
+
653
+ | `test_plan.e2e_required` | Action |
654
+ |--------------------------|--------|
655
+ | `true` | **AUTO-TRIGGER** — proceed directly, no user confirmation needed |
656
+ | `false` | **SKIP** — log "E2E testing: SKIP (PRD evaluation: not needed)" in tracker |
657
+ | field missing | **FALLBACK to legacy detection** (see below) |
658
+
659
+ **Legacy fallback** (only when `test_plan` field is absent — old cards without PRD test plan):
660
+ Check if ALL conditions are met:
661
+ 1. The card's `areas` field includes any of: `ui`, `frontend`, `booking`, `customer`, `merchant-dashboard`, `onboarding`, `settings`.
662
+ 2. The changed files include at least one `.tsx` page file (under `src/app/`).
663
+ 3. The card type is NOT `docs`, `chore`, or `config`.
664
+ If all met, ask the user: `Vuoi testarlo con Playwright E2E? (si/no)`
665
+
666
+ **When E2E runs** (auto-triggered or user-confirmed):
667
+
668
+ 1. **Update tracker**: phase = "2.6-e2e-testing".
669
+ 2. Read test scenarios and credentials from `test_plan`:
670
+ - `test_scenarios` — pre-planned scenarios with mapped user stories/ACs
671
+ - `test_credentials` — persona, auth method, credentials, store
672
+ - `test_data_prerequisites` — data that must exist
673
+ 3. Spawn a **coder** agent to write the Playwright E2E test:
674
+ ```
675
+ Write a Playwright E2E test for card <CARD-ID>.
676
+
677
+ Test file: tests/e2e/<card-id-slug>.spec.ts
678
+ Use: import { test, expect } from '@playwright/test'
679
+
680
+ ## Pre-planned Test Scenarios (from PRD)
681
+ [paste test_scenarios from card YAML — each has description, mapped US/AC, priority]
682
+
683
+ ## Test Credentials
684
+ Persona: [from test_plan.test_credentials.persona]
685
+ Auth method: [from test_plan.test_credentials.auth_method]
686
+ Credentials: [from test_plan.test_credentials.credentials]
687
+ Store: [from test_plan.test_credentials.store]
688
+ Notes: [from test_plan.test_credentials.notes]
689
+
690
+ ## Auth Handling
691
+ - If persona is CUSTOMER with OTP auth: navigate to login, enter phone number,
692
+ then use `await test.step('OTP input (manual)', async () => { await page.pause() })`
693
+ to pause for manual OTP entry by the user. After pause resumes, continue the flow.
694
+ - If persona is MERCHANT with password auth: use page.fill() for username/password
695
+ fields, then submit the login form. No manual intervention needed.
696
+
697
+ ## Test Data Prerequisites
698
+ [paste test_data_prerequisites — data that must exist in Firestore]
699
+
700
+ ## Guidelines
701
+ - Use page.getByRole(), page.getByText(), page.getByTestId() for selectors
702
+ - Use expect(locator) assertions with auto-waiting
703
+ - Group related steps with test.describe()
704
+ - Implement ALL scenarios from the PRD test plan (not just happy path)
705
+ - Use baseURL from config (just page.goto('/relative-path'))
706
+ - Do NOT use chromium.launch() or manual browser management
707
+ - For OTP flows: use page.pause() and document it clearly in test output
708
+ ```
709
+ 4. After the test file is written, run the test in headed mode:
710
+ ```bash
711
+ npx playwright test tests/e2e/<test-file>.spec.ts --headed --reporter=list
712
+ ```
713
+ Note: for OTP-based tests, the test will pause at `page.pause()` for manual OTP input.
714
+ The user enters the OTP in the browser, then resumes (close Playwright Inspector).
715
+ 5. Report the result to the user. If tests fail, the coder agent fixes them (up to 2 retries).
716
+ 6. **Update tracker**: phase = "2.6-e2e-testing DONE", log: test file path, result (PASS/FAIL/SKIP), test count, scenarios covered (N/M from PRD plan).
717
+
718
+ ### Phase 2.7 — Visual Design Review (UI cards only — advisory)
719
+
720
+ **Trigger**: card has `links.design` field. If absent, SKIP.
721
+
722
+ Non-blocking — findings are logged but do NOT block commit.
723
+
724
+ 1. **Update tracker**: phase = "2.7-design-review".
725
+ 2. Extract the route from `files_likely_touched` (look for `page.tsx` under `src/app/`).
726
+ If no page file found, SKIP (log "no page route").
727
+ 3. Invoke the **design-review** agent (`.claude/commands/design-review.md`) on the route,
728
+ passing the worktree dev server port.
729
+ 4. Log findings in tracker: `design-review: [N] blockers, [M] high, [K] medium`.
730
+ If blockers: log in `## Issues & Flags` as `[DESIGN-ADVISORY]`.
731
+ 5. **Do NOT spawn fix agents.** Findings are informational for the user.
732
+ 6. **Update tracker**: phase = "2.7-design-review DONE".
733
+
734
+ ---
735
+
736
+ ### Phase 3 — Doc Review & Sync (code review handled by mandatory Phase 3.7 gate)
737
+
738
+ > **Note**: Code review is NOT performed in this phase — it is handled by the **mandatory unconditional `/codexreview` gate in Phase 3.7**, which runs per-card BEFORE the Phase 4 commit. The post-batch `/codexreview` in Phase 7 remains as a final cross-card sweep. This Phase 3 focuses exclusively on documentation sync, which must happen per-card (tied to the specific commit).
739
+
740
+ 12. **Update tracker**: phase = "3-doc-review".
741
+ 13. Build a **Doc Sync Context** block:
742
+ ```bash
743
+ git diff --name-only HEAD
744
+ ```
745
+ Use the output to build this block:
746
+ ```
747
+ ## Doc Sync Context
748
+
749
+ ### Changed code files (for freshness mapping):
750
+ [list all code files changed — src/, scripts/, etc.]
751
+
752
+ ### Invariant checklist (Linking Protocol — docs/guides/linking-protocol-rollout-v1.md):
753
+ - [ ] New route.ts added? → ${paths.references_dir}/api/<module>.md + api/index.md count
754
+ - [ ] New page.tsx added? → ${paths.references_dir}/ui/<domain>.md + ui/index.md Route Summary
755
+ - [ ] New Firestore collection? → ${paths.references_dir}/data-model.md + collections/<domain>.md
756
+ - [ ] Compound Firestore query (where+orderBy on different fields)? → firestore.indexes.json must include the composite index and be staged
757
+ - [ ] Backlog card set to DONE? → ${paths.references_dir}/ssot-registry.md entry
758
+ - [ ] New external dependency? → agents/architecture.md External Dependencies list
759
+ - [ ] Card has `documentation_impact` field? → verify each listed doc is updated
760
+ - [ ] New `process.env.VAR` added? → entry in `${paths.references_dir}/env-vars.md` (nome, scope, required, feature/card, default)
761
+ - [ ] Last usage of `process.env.VAR` removed? → mark `status: deprecated` in `${paths.references_dir}/env-vars.md` con data
762
+ - [ ] Default value changed in `src/lib/env.ts`? → aggiornare colonna Default in `${paths.references_dir}/env-vars.md`
763
+ - [ ] Card ha campo `env_vars` popolato? → verificare che ogni entry sia tracciata in `${paths.references_dir}/env-vars.md`
764
+
765
+ ### Related docs to check (per convention map):
766
+ - [derive from FRESHNESS_MAP: src/app/api/** → ${paths.references_dir}/api/; src/lib/booking/** → booking.md etc.]
767
+ ```
768
+
769
+ Invoke the **doc-reviewer** agent as a **read-only audit**, passing the Doc Sync Context:
770
+ ```
771
+ Doc Sync Context:
772
+ [paste the Doc Sync Context block built above]
773
+
774
+ Instructions for doc-reviewer:
775
+ - Set freshness_status: fresh and last_verified_from_code: <today's date> on any doc you touch
776
+ - Check each invariant in the checklist above and flag any that are unmet
777
+ - Flag any doc in "Related docs to check" that should be stale but isn't marked yet
778
+ - Run your standard doc audit on all changed files
779
+ ```
780
+ Doc-reviewer collects findings WITHOUT making changes.
781
+ 14. **Obsidian Corpus Dispatch**: Parse section H from doc-reviewer findings. If `Trigger: YES`, dispatch the `obsidian-sync` agent (`.claude/agents/obsidian-sync.md`) with the listed paths after all fixes are applied (step 16). If `Trigger: NO`, skip. This is non-blocking -- do not wait for obsidian-sync to complete before proceeding.
782
+ 15. If doc findings exist, invoke the **coder** agent once to apply **ALL doc fixes in one pass**.
783
+ 16. Run `npm run lint` and `npx tsc --noEmit` to verify nothing broke. If any check fails, apply the self-healing retry loop (up to 3 times, no user prompt).
784
+ 17. **Update tracker**: phase = "3-doc-review DONE", log doc findings count, fixes applied.
785
+ If doc-reviewer found a recurring gap, append 1-line to `## Lessons Learned`:
786
+ `DOC: <pattern>`
787
+
788
+ ### Phase 3.5 — QA Validation
789
+
790
+ 18. **Update tracker**: phase = "3.5-qa".
791
+ 19. **Select QA profile** using the QA Profile Selector table above. Log the chosen profile and rationale in the tracker (1 line).
792
+ 20. **If profile is SKIP**: log "QA skipped — [reason]" in the tracker. Proceed to Phase 4.
793
+ 21. **If profile is LIGHT**: SKIP qa-sentinel — Phase 2 step 8 already ran lint/tsc/test/build gates. Log "QA LIGHT skipped — gates already passed in Phase 2" in the tracker. Proceed to Phase 4.
794
+ 22. **If profile is BALANCED or DEEP**: invoke the **`qa-sentinel`** agent (subagent_type: `qa-sentinel`) via Task tool with the following context:
795
+
796
+ ```
797
+ Run FULL VALIDATION MODE on card <CARD-ID>.
798
+
799
+ Context:
800
+ - Worktree path: <worktree-path>
801
+ - Branch: <branch-name>
802
+ - Changed files: <list from implementation phase>
803
+ - QA profile: [balanced | deep]
804
+
805
+ Run E2E tests: `npx playwright test --reporter=list`
806
+ E2E failures are BLOCKING for deep profile, ADVISORY for balanced profile.
807
+ Also run gates (lint, tsc, test, build, markdownlint) as sanity check.
808
+ Do NOT verify acceptance criteria (Phase 2.5 already did this).
809
+ Do NOT analyze code for bugs/patterns (deferred to /codexreview post-batch).
810
+ Do NOT write recommendations or follow-up actions.
811
+
812
+ Write the gate results + verdict to: /qa/<CARD-ID>.md
813
+ Report should be under 40 lines.
814
+ Return verdict: PASS or FAIL.
815
+ ```
816
+
817
+ 22. **Read qa-sentinel's output.** Verify the findings file was written to `/qa/<CARD-ID>.md`.
818
+ 23. **If QA verdict is FAIL**:
819
+ - Spawn the **coder** agent to fix all BLOCKER findings (pass it the findings file path + list of blockers). Do NOT ask the user.
820
+ - After coder fixes, re-invoke `qa-sentinel` in the same mode to re-validate. Repeat up to **2 times**.
821
+ - If still FAIL after 2 retries: log in `## Issues & Flags` and **ask the user** whether to proceed or stop.
822
+ - The commit in Phase 4 MUST NOT happen until QA verdict is PASS (or user explicitly overrides).
823
+ 24. **Update tracker**: phase = "3.5-qa DONE", log: profile used, verdict (PASS/FAIL/SKIP), confidence %, findings count (blockers/majors/minors), findings file path.
824
+
825
+ ### Phase 3.7 — Pre-Merge Codex Review Gate (MANDATORY — UNCONDITIONAL)
826
+
827
+ **This gate is NON-SKIPPABLE and runs for EVERY card before the Phase 4 commit, no matter what.** A per-card `/codexreview` MUST run BEFORE the Phase 4 commit, regardless of file paths, card type, or perceived risk. The historical conditional High-Risk Path detector is preserved below — but only as a **signal-logging step** to record *which* triggers matched in the tracker. It NEVER suppresses the `/codexreview` invocation. Even if zero triggers match, `/codexreview` runs.
828
+
829
+ **Rationale**: leaving the gate conditional caused it to be silently skipped on the majority of cards, defeating the AGENTS.md "MUST run BEFORE merge" requirement. The cost of a per-card Codex pass is acceptable; the cost of a missed blocker on a "low-risk" path (BUG-0530-class regressions) is not.
830
+
831
+ #### Step A — Detect (signal-logging only, NEVER gates the next step)
832
+
833
+ Run this exact bash block in the worktree. It is deterministic (grep + path match), not LLM-discretionary.
834
+
835
+ ```bash
836
+ cd <worktree-path>
837
+ CARD_ID="<CARD-ID>"
838
+ CARD_FILE="$(find ../../backlog -name "${CARD_ID}*.yml" 2>/dev/null | head -1)"
839
+ CHANGED="$(git diff --name-only develop...HEAD 2>/dev/null || git diff --name-only HEAD~1)"
840
+
841
+ TRIGGERS=()
842
+
843
+ # Trigger #1 — DORE shared scoring/ranking primitive
844
+ echo "$CHANGED" | grep -qE 'src/lib/booking/dore/(engine|reranking)\.ts$' \
845
+ && TRIGGERS+=("#1: DORE shared scoring/ranking primitive")
846
+
847
+ # Trigger #2 — Auth / permissions
848
+ echo "$CHANGED" | grep -qE 'src/lib/auth/middleware\.ts$|src/lib/permissions\.ts$|withAuth' \
849
+ && TRIGGERS+=("#2: Auth/permissions")
850
+
851
+ # Trigger #3 — Payment / billing
852
+ echo "$CHANGED" | grep -qE '^src/lib/payments/|^src/app/api/v1/billing/' \
853
+ && TRIGGERS+=("#3: Payment/billing")
854
+
855
+ # Trigger #4 — Dead-code resurrection (card text + commit messages)
856
+ { cat "$CARD_FILE" 2>/dev/null; git log --format=%B develop...HEAD 2>/dev/null; } \
857
+ | grep -qiE 'dead code|unreachable|resurrect' \
858
+ && TRIGGERS+=("#4: Dead-code resurrection")
859
+
860
+ # Trigger #5 — Cross-card delta-baseline arithmetic
861
+ { cat "$CARD_FILE" 2>/dev/null; echo "$CHANGED" | xargs -I{} git show "HEAD:{}" 2>/dev/null; } \
862
+ | grep -qE 'score_new\s*-\s*score_current|delta-baseline|deltaBaseline' \
863
+ && TRIGGERS+=("#5: Cross-card delta-baseline arithmetic")
864
+
865
+ # Trigger #6 — Reference-aliasing mutation pattern (BUG-0558 family)
866
+ # Card introduces or modifies an exported helper that returns an array/object AND a
867
+ # call site in the diff mutates an input array in place via `length = 0` + `push(...result)`.
868
+ # Even if the call site has an identity guard locally, the high-risk gate runs Codex
869
+ # adversarial review to confirm the contract is robust against future caller patterns.
870
+ echo "$CHANGED" | xargs -I{} sh -c 'git show "HEAD:{}" 2>/dev/null' \
871
+ | grep -qE '\.length\s*=\s*0' \
872
+ && echo "$CHANGED" | xargs -I{} sh -c 'git show "HEAD:{}" 2>/dev/null' \
873
+ | grep -qE '\.push\(\s*\.\.\.' \
874
+ && TRIGGERS+=("#6: Reference-aliasing mutation pattern (BUG-0558 family)")
875
+
876
+ printf '%s\n' "${TRIGGERS[@]}"
877
+ ```
878
+
879
+ #### Step B — Log detector result (never skips)
880
+
881
+ Log the detector output in the tracker for traceability. **This step never short-circuits Step C — `/codexreview` runs unconditionally regardless of whether `TRIGGERS` is empty or populated.**
882
+
883
+ - If `TRIGGERS` is empty: log `## Pre-Merge Codex Review: no high-risk triggers matched (gate still runs unconditionally)` and proceed to Step C.
884
+ - If `TRIGGERS` is non-empty: log the matched triggers (see Step C step 1) and proceed to Step C.
885
+
886
+ #### Step C — Invoke per-card `/codexreview` (ALWAYS)
887
+
888
+ For EVERY card (no conditional skip):
889
+
890
+ 1. **Log gate invocation** in the tracker under `## Pre-Merge Codex Review`:
891
+
892
+ ```
893
+ ## Pre-Merge Codex Review
894
+ - Triggered: unconditional (mandatory pre-merge gate)
895
+ - Matched high-risk triggers: <list from detector, or "none">
896
+ - Action: invoking /codexreview <CARD-ID> (per-card, pre-merge gate)
897
+ ```
898
+
899
+ 2. **Invoke `/codexreview`** for the single card via the Skill tool:
900
+
901
+ ```
902
+ Skill: codexreview
903
+ args: <CARD-ID>
904
+ ```
905
+
906
+ The orchestrator's `/codexreview` skill runs all 5 review agents (incl. adversarial Codex) + Step 3 false-positive gate + Step 3.5 cross-agent CoVe + Step 4 consolidated report. This is the same pipeline used post-batch in Phase 7 — here it runs per-card and BEFORE commit.
907
+
908
+ 3. **Read the consolidated report** from `/tmp/codexreview-report-<TIMESTAMP>.md`. Extract:
909
+ - Verified BLOCKER count
910
+ - Verified HIGH count
911
+ - List of `[ripple-expanded]` findings (Step 3.5 widened scope)
912
+
913
+ 4. **Apply fix sub-loop** (mirror of Phase 3.5 retry pattern):
914
+ - If 0 BLOCKER and 0 HIGH → log `verdict: PASS — proceeding to Phase 4` in tracker. Done.
915
+ - If 1+ BLOCKER OR 1+ HIGH → spawn `coder` agent with the report path + list of VERIFIED bugs to fix. After coder fixes, re-invoke `/codexreview <CARD-ID>` to re-validate. Repeat **max 2 times**.
916
+ - If still BLOCKER/HIGH after 2 retries → log in `## Issues & Flags` and **ask the user** whether to proceed, escalate, or stop. The Phase 4 commit MUST NOT happen until High-Risk Gate verdict is PASS or user explicitly overrides.
917
+
918
+ 5. **Update tracker**: phase = `3.7-highrisk DONE`, log final verdict, retry count, list of fixed findings, and the report path.
919
+
920
+ #### Why deterministic detector + agent pipeline
921
+
922
+ The detector (Step A) is bash + grep — guaranteed to run, no LLM skip. The downstream pipeline (Step C) is the existing `/codexreview` skill — fully tested, includes Codex adversarial review and Step 3.5 cross-agent CoVe. This combination ensures the AGENTS.md "MUST run BEFORE merge" rule is enforced reliably.
923
+
924
+ ### Phase 4 — Commit (in worktree, NO merge yet)
925
+ 25. **Update tracker**: phase = "4-commit".
926
+ 26. Stage and commit **all changes together** in the worktree using format `[CARD-ID] Brief description` (MUST per AGENTS.md). Include all relevant files — implementation, review fixes, QA-driven fixes, and doc updates in a single commit. Do NOT merge or push yet — that happens post-batch.
927
+ - **IMPORTANT — explicit staging**: NEVER use `git add -A` or `git add .`. Always stage files by explicit name:
928
+ ```bash
929
+ cd <worktree-path>
930
+ # List changed files
931
+ git diff --name-only
932
+ git ls-files --others --exclude-standard
933
+ # Stage only the files this card touched (explicit names)
934
+ git add src/path/to/file1.ts src/path/to/file2.ts ...
935
+ # Commit directly — NO stash in worktrees
936
+ git commit -m "[CARD-ID] Brief description"
937
+ ```
938
+ - **WORKTREE COMMIT RULE — NEVER use `git stash` in worktrees.** Stashes are globally shared across all worktrees (`refs/stash` via `git.commondir`). A stash created in one worktree can be popped by another, causing conflicts, data loss, and cascading merge failures. The file ownership map ensures no overlap between cards — explicit staging is sufficient isolation. The stash pattern in AGENTS.md applies ONLY to the main repo working tree.
939
+ - **If commit fails** (e.g., lint-staged or pre-commit hook error):
940
+ 1. **Check for stale COMMIT_LOCK first** — parallel agents and crashed processes leave stale lock files. Always clear before retry:
941
+ ```bash
942
+ rm -f <main-repo>/.git/worktrees/<worktree-name>/COMMIT_LOCK 2>/dev/null
943
+ ```
944
+ 2. Re-stage the same files explicitly and retry. Never run `git commit` alone after a failure — the staging area may have been altered by lint-staged auto-fixes. If lint-staged removed an "unused" variable that IS used by code in a later card, check `git diff` to see what changed, restore the needed code, re-stage, and retry.
945
+ - The Claude Code pre-commit hook automatically skips for worktree commits (Husky handles checks natively in the worktree).
946
+ 27. **Mark card DONE (MANDATORY — do NOT skip)**:
947
+ a. Edit the backlog YAML (`${paths.backlog_dir}/<CARD-ID>.yml`): set `status: DONE`, add `completed_date: <today>`.
948
+ b. Add implementation notes summarizing what was built.
949
+ c. **Update `${paths.references_dir}/ssot-registry.md`** — add/update the entry for this card's feature area. The pre-commit doc-freshness hook BLOCKS commits that touch `backlog/` without a corresponding ssot-registry update. Always include ssot-registry.md in the same commit as the backlog YAML.
950
+ d. **Verify the write**: re-read the YAML file and confirm `status: DONE` is present. If not, retry the edit.
951
+ e. Stage BOTH the updated YAML AND ssot-registry.md, then commit (or as an immediate follow-up commit if Phase 4 commit already happened).
952
+ 28. **Update tracker**: move card to `## Completed Cards` with commit hash, summary, flags, **and `card_status: DONE (verified)`**.
953
+
954
+ ### Sub-agent failure protocol
955
+ - If any sub-agent **crashes or errors** during any phase: log the failure in the tracker, **attempt the work yourself directly**, and note it in the final report.
956
+ - Never block the pipeline waiting for a failed agent — recover and continue.
957
+
958
+ ### Phase 5 — Context Clean & Continue
959
+ 29. Archive the card from Active Code Context in `${paths.references_dir}/project-status.md`.
960
+ 30. **CONTEXT PURGE**: After updating the tracker, deliberately forget the implementation details of this card. From this point forward, you should NOT reference any code, file contents, or review details from this card — only the summary in the tracker. If you need to recall what happened, read the tracker file. This keeps your working context lean for the next card.
961
+ 31. **Update tracker**: clear `## Current Card`, move to next pending card.
962
+ 32. Move to the next card.
963
+
964
+ ---
965
+
966
+ ## Final review (after all cards)
967
+
968
+ > **Primary code reviewer: Codex (GPT-5.4)** — cross-model validation with built-in FP filtering.
969
+ > Claude `code-reviewer` is the automatic fallback if Codex is unavailable.
970
+ > The `/codexreview` command remains available for standalone reviews on demand.
971
+
972
+ Once ALL cards are committed in the worktree:
973
+
974
+ ### Step F.1 — Resolve scope
975
+
976
+ 1. **Read the tracker file** to get the full picture: card IDs, files changed, commit hashes.
977
+ 2. Gather git evidence in the worktree:
978
+ ```bash
979
+ cd <worktree-path>
980
+ git diff --name-only <base-branch>...HEAD
981
+ ```
982
+ 3. Read each card's backlog YAML to collect `acceptance_criteria`, `files_likely_touched`.
983
+ 4. Build `review_scope_files` as union of card-indicated files + git-touched files.
984
+
985
+ ### Step F.2 — Architecture baseline
986
+
987
+ 5. Invoke **codebase-architect** agent to map existing architecture, critical patterns, and
988
+ high-risk code paths for regression across the batch scope. This provides grounding context
989
+ for all downstream review agents.
990
+
991
+ ### Step F.3 — Codex deep code review (primary) + Claude agents (support)
992
+
993
+ > **Primary reviewer: Codex (GPT-5.4)** — cross-model validation. Codex runs the full
994
+ > `/codexreview` protocol: scope resolution, architecture baseline, parallel deep review,
995
+ > and mandatory false-positive validation. Claude agents provide doc review and supplementary checks.
996
+
997
+ 6. **Launch Codex code review** via `Bash` with `run_in_background: true` and `timeout: 600000` (10 min):
998
+
999
+ ```bash
1000
+ REVIEW_FILE="/tmp/codexreview-batch-$(date +%Y%m%d-%H%M%S).md" && \
1001
+ 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)" && \
1002
+ [ -z "$CODEX_SCRIPT" ] && echo "CODEX_NOT_FOUND" && exit 1; \
1003
+ node "$CODEX_SCRIPT" task --wait "
1004
+ Run a deep multi-agent code review for these backlog cards. This is a post-implementation
1005
+ review — the code is already written and committed. Your job is to find bugs, regressions,
1006
+ security issues, and quality problems.
1007
+
1008
+ Cards to review (read each file):
1009
+ ${CARD_PATHS}
1010
+
1011
+ Files changed (review ALL of these):
1012
+ ${REVIEW_SCOPE_FILES}
1013
+
1014
+ Architecture baseline (from codebase-architect):
1015
+ ${ARCH_BASELINE}
1016
+
1017
+ Follow the /codexreview protocol:
1018
+ 1. For each card, read its backlog YAML for acceptance_criteria and entrypoints.
1019
+ 2. Read every changed file in full.
1020
+ 3. Check for: functional bugs, logic flaws, regressions, cross-card inconsistencies,
1021
+ security issues (auth gaps, input validation, multi-tenant isolation),
1022
+ performance issues (unbounded reads, N+1, missing pagination),
1023
+ missing error handling on external boundaries.
1024
+ 4. For each finding, return:
1025
+ - finding_id: <CARD-ID>-F###
1026
+ - title: short description
1027
+ - severity: BLOCKER | HIGH | MEDIUM | LOW
1028
+ - confidence: 0-100
1029
+ - evidence: exact file:line + code quote
1030
+ - minimal_fix_direction: what to change
1031
+ 5. Run mandatory false-positive check: for each finding, ask 'What is the strongest
1032
+ argument this is a false positive?' Suppress if the FP argument is convincing.
1033
+ 6. Classify surviving findings as VERIFIED, FALSE_POSITIVE, or NEEDS_MANUAL_CONFIRMATION.
1034
+
1035
+ Return ONLY verified findings. If zero verified bugs: state 'No verified bugs found.'
1036
+ " 2>&1 | tee "$REVIEW_FILE"
1037
+ ```
1038
+
1039
+ **Variable interpolation** (build the command string before execution):
1040
+ - `${CARD_PATHS}`: newline-separated list of backlog YAML paths
1041
+ - `${REVIEW_SCOPE_FILES}`: newline-separated list from Step F.1
1042
+ - `${ARCH_BASELINE}`: key findings from Step F.2 (2-3 paragraphs max)
1043
+
1044
+ 7. **In parallel with Codex**, launch Claude support agents (single message):
1045
+
1046
+ | Agent | `subagent_type` | Focus |
1047
+ |-------|-----------------|-------|
1048
+ | **doc-reviewer** | `doc-reviewer` | Cross-card doc consistency, ssot-registry completeness, invariants |
1049
+ | **api-perf-cost-auditor** | `api-perf-cost-auditor` | API/data/performance/cost defects (skip if no API/data files in scope) |
1050
+ | **qa-sentinel** | `qa-sentinel` | Edge cases, testing gaps, reproducibility |
1051
+
1052
+ Each agent receives: card IDs, YAML, `review_scope_files`, codebase-architect baseline.
1053
+ Return findings with `finding_id`, `title`, `severity`, `confidence`, `evidence`, `minimal_fix_direction`.
1054
+
1055
+ ### Step F.4 — Collect & merge findings
1056
+
1057
+ 8. **Read Codex findings** from `$REVIEW_FILE` after the background command completes.
1058
+ - If file exists and contains findings → use as **primary code review source**.
1059
+ - If file is empty, missing, or contains `CODEX_NOT_FOUND` → **fallback**: spawn `code-reviewer`
1060
+ agent (subagent_type: `code-reviewer`) with the same scope and instructions. Log fallback
1061
+ reason in tracker: `"Codex unavailable — fallback to Claude code-reviewer"`.
1062
+
1063
+ 9. **Merge all findings** (Codex + Claude agents) into a consolidated list.
1064
+ - Codex findings are already FP-validated (Step F.3 protocol includes it).
1065
+ - Claude agent findings with `confidence < 80` → cross-validate with a second agent.
1066
+ - Classify: `VERIFIED` | `FALSE_POSITIVE` | `NEEDS_MANUAL_CONFIRMATION`.
1067
+ - Only `VERIFIED` findings proceed to fixes.
1068
+
1069
+ ### Step F.5 — Apply fixes and final build
1070
+
1071
+ 10. **Persist verified findings** to `/tmp/batch-final-review-<FIRST-CARD-ID>.md`.
1072
+ 11. If VERIFIED findings with severity >= MEDIUM exist, invoke the **coder** agent once to
1073
+ apply ALL fixes in a single pass. Pass only the verified findings, not false positives.
1074
+ 12. Run final build: `npm run lint && npx tsc --noEmit && npm run build`.
1075
+ If any check fails, apply self-healing retry loop (up to 3 times).
1076
+ 13. **Update tracker** with final review results:
1077
+ - Review engine: Codex GPT-5.4 (primary) | Claude code-reviewer (fallback)
1078
+ - Total findings raised / verified / false positives / needs-manual
1079
+ - Fixes applied count
1080
+ - Build status (pass/fail + retry count)
1081
+ - Highest severity found
1082
+ 7. **SSOT & Documentation Activity** (MANDATORY — run BEFORE merge):
1083
+
1084
+ Summarize all documentation and SSOT updates performed during the batch:
1085
+
1086
+ ```
1087
+ ## Aggiornamenti SSOT & Documentazione
1088
+
1089
+ ### Documenti aggiornati
1090
+ - `${paths.references_dir}/api/<module>.md` — N nuovi endpoint aggiunti
1091
+ - `${paths.references_dir}/ui/<domain>.md` — N nuove route aggiunte
1092
+ - `${paths.references_dir}/data-model.md` — N nuove collection
1093
+ - `${paths.references_dir}/ssot-registry.md` — N entry aggiornate/create
1094
+ - `${paths.references_dir}/project-status.md` — contesto aggiornato
1095
+
1096
+ ### ADR creati
1097
+ - `${paths.adrs_dir}/ADR-YYYYMMDD-<slug>.md` — [titolo] (o "Nessun ADR creato")
1098
+ ```
1099
+
1100
+ 8. **Knowledge Base Sync** (OPTIONAL — only if the project has an external knowledge corpus, e.g. an Obsidian vault, Confluence space, or Notion workspace):
1101
+
1102
+ If the project ships a `knowledge-sync` agent (or equivalent), invoke it after doc updates so the external corpus stays aligned. If no such agent exists, skip this step.
1103
+
1104
+ 9. **Proceed to Phase 6** (post-batch merge & cleanup).
1105
+ 10. Present a **single summary report** to the user per card (and a batch summary at the end):
1106
+ - **Files changed** (short list per card)
1107
+ - **Test results** (new tests + existing tests count, pass rate at each iteration)
1108
+ - **Build/lint status** (pass + retry count if any)
1109
+ - **Fix cycles** (total number of self-healing retries across phases)
1110
+ - **Final review** (findings: N raised / M verified / K false positives | fixes applied: N | highest severity)
1111
+ - **UX testing** (PASS/FAIL/SKIP | test file path if written)
1112
+ - **QA result** (profile: skip/light/balanced/deep | verdict: PASS/FAIL/SKIP | confidence % | findings: N blockers, N majors, N minors | E2E: PASS/FAIL/SKIP | findings file path)
1113
+ - **Issues needing user attention** (anything unresolved, partially wired, or flagged)
1114
+ - **Commit hashes** (from tracker)
1115
+ - **Merge commit hash** (from Phase 6)
1116
+ - **Card status reconciliation** (Phase 6b: N cards verified DONE, K force-updated)
1117
+ - **Worktree cleanup status** (success/failed)
1118
+ - **Obsidian sync status** (from step 8 — COMPLETATO/FALLITO/PARZIALE)
1119
+ - Overall implementation status
1120
+
1121
+ 10b. **Next Steps & Launch Command** (MANDATORY section — always present):
1122
+
1123
+ Check for remaining TODO/READY cards in the same epic group:
1124
+
1125
+ ```bash
1126
+ # Find parent epic from completed cards
1127
+ grep -l "parent: <EPIC-ID>" backlog/*.yml | xargs grep -l "status: TODO\|status: READY"
1128
+ ```
1129
+
1130
+ Present the section:
1131
+
1132
+ ```
1133
+ ## Prossimi Passi
1134
+
1135
+ ### Lancio implementazione (copia e incolla)
1136
+ ```
1137
+ /new FEAT-XXXX-05 FEAT-XXXX-06 FEAT-XXXX-07
1138
+ ```
1139
+
1140
+ ### Card rimanenti nell'epic
1141
+ | Card | Titolo | Status | Gruppo parallelo |
1142
+ |------|--------|--------|-----------------|
1143
+ | FEAT-XXXX-05 | [title] | TODO | 2 |
1144
+ | FEAT-XXXX-06 | [title] | TODO | 2 |
1145
+
1146
+ ### Card completate in questa sessione
1147
+ | Card | Titolo | Commit |
1148
+ |------|--------|--------|
1149
+ | FEAT-XXXX-01 | [title] | abc1234 |
1150
+ | FEAT-XXXX-02 | [title] | def5678 |
1151
+ ```
1152
+
1153
+ If ALL cards in the epic are DONE:
1154
+ ```
1155
+ ## Prossimi Passi
1156
+
1157
+ Tutte le card dell'epic **FEAT-XXXX** sono state completate.
1158
+ Pronto per il deploy: `/deploy` o `git push origin develop`
1159
+ ```
1160
+
1161
+ 11. **Proceed to Phase 7** (production readiness checklist).
1162
+
1163
+ ---
1164
+
1165
+ ## Phase 6 — Post-batch merge & cleanup (delegated to worktree-manager skill)
1166
+
1167
+ After the final review passes AND all cards are committed in the worktree, delegate the entire merge and cleanup to the **worktree-manager** skill (`/mw` in programmatic mode):
1168
+
1169
+ 1. **BEFORE invoking /mw** — verify no uncommitted files remain in the worktree:
1170
+ ```bash
1171
+ cd <worktree-path>
1172
+ git status --porcelain
1173
+ ```
1174
+ If ANY uncommitted files exist (staged, unstaged, or untracked), commit them NOW with `[safety] Auto-commit remaining files before merge`. Do NOT proceed to `/mw` with a dirty worktree — files WILL be lost during rebase.
1175
+ 2. Invoke `/mw` with:
1176
+ - The worktree path and branch from the tracker
1177
+ - `checksAlreadyPassed: true` (final review + QA already validated the build)
1178
+ - All card IDs for the commit message
1179
+ 3. The skill handles: safety commit of any remaining uncommitted files (step 3), rebasing onto latest develop (step 4b — auto-resolves doc conflicts, stops on code conflicts), remote merge to develop via `gh pr merge` (step 4c — NEVER `git checkout develop` on the main repo; this respects the absolute terminal-isolation rule that many consumer projects declare in CLAUDE.md), post-merge verification, worktree removal, registry cleanup, and remote branch deletion.
1180
+ 4. **If code merge conflicts** → the skill STOPs and reports. Doc-only conflicts (ssot-registry.md, project-status.md, etc.) are auto-resolved by keeping both sides.
1181
+ 5. **If post-merge build fails** → the skill STOPs and keeps the worktree intact for investigation.
1182
+ 6. Record the merge commit hash and result in the tracker.
1183
+
1184
+ ### Phase 6b — Backlog Card Status Reconciliation (MANDATORY — ZERO TOLERANCE)
1185
+
1186
+ **This gate runs IMMEDIATELY after Phase 6 merge completes, BEFORE presenting any summary to the user. It is NON-SKIPPABLE.**
1187
+
1188
+ The most common failure mode is leaving cards IN_PROGRESS after merge. This creates SSOT drift and confuses downstream agents (codebase-architect, doc-reviewer). This gate prevents that.
1189
+
1190
+ **Steps:**
1191
+
1192
+ 1. **Read the tracker file** to get the full list of card IDs in the batch.
1193
+ 2. **For EACH card in the batch**, read its backlog YAML (`${paths.backlog_dir}/<CARD-ID>.yml`) and check the `status` field:
1194
+ - If `status: DONE` → OK, skip.
1195
+ - If `status` is anything else (`IN_PROGRESS`, `READY`, `TODO`, etc.) → **FORCE UPDATE to DONE immediately**.
1196
+ 3. **Early exit — all cards already DONE**: if step 2 found ALL cards are already `status: DONE`, skip steps 4-5 entirely. Log in the tracker:
1197
+ ```
1198
+ ## Phase 6b — Status Reconciliation
1199
+ Cards checked: N
1200
+ Already DONE: N (all cards marked DONE by coder agents)
1201
+ Force-updated to DONE: 0
1202
+ Reconciliation commit: not needed
1203
+ ```
1204
+ Proceed directly to step 6.
1205
+ 4. **Force update procedure** for non-DONE cards:
1206
+ ```bash
1207
+ # In the MAIN repo (not worktree — worktree is already cleaned up)
1208
+ cd <main-repo-path>
1209
+ ```
1210
+ Edit the backlog YAML: set `status: DONE`, add `completed_date: <today>`, add implementation note: `"Marked DONE by post-merge reconciliation gate (Phase 6b)"`.
1211
+ 5. **If ANY card was force-updated**: commit in the main repo with these precautions:
1212
+ a. **Clear stale COMMIT_LOCK** (common when coder agents crash or timeout):
1213
+ ```bash
1214
+ # Remove any stale COMMIT_LOCK from main repo or worktrees
1215
+ rm -f <main-repo-path>/.git/COMMIT_LOCK 2>/dev/null
1216
+ find <main-repo-path>/.git/worktrees -name COMMIT_LOCK -delete 2>/dev/null || true
1217
+ ```
1218
+ b. **Stage backlog YAMLs AND related docs** (pre-commit hook requires doc updates):
1219
+ ```bash
1220
+ # Stage only the force-updated backlog YAMLs
1221
+ git add backlog/CARD-001.yml backlog/CARD-002.yml
1222
+ # If ssot-registry.md was modified during the batch, stage it too
1223
+ # (doc-freshness hook blocks commits that touch backlog/ without ssot-registry.md)
1224
+ git diff --name-only ${paths.references_dir}/ssot-registry.md && git add ${paths.references_dir}/ssot-registry.md || true
1225
+ ```
1226
+ c. **Commit with explicit file list**:
1227
+ ```bash
1228
+ git commit -m "[BATCH] Mark cards DONE — post-merge reconciliation"
1229
+ ```
1230
+ d. **If commit fails due to pre-commit hook** (lint-staged, doc-freshness): check the error.
1231
+ - If "no staged files" → all changes were already committed. Log as "not needed".
1232
+ - If doc-freshness requires ssot-registry.md → update its `last_verified_from_code` date, stage it, and retry.
1233
+ - If COMMIT_LOCK → re-run step 5a and retry.
1234
+ - Do NOT retry more than 2 times. Log the failure and move on.
1235
+ 6. **Update tracker** with reconciliation results:
1236
+ ```
1237
+ ## Phase 6b — Status Reconciliation
1238
+ Cards checked: N
1239
+ Already DONE: M
1240
+ Force-updated to DONE: K [list card IDs]
1241
+ Reconciliation commit: <hash> (or "not needed")
1242
+ ```
1243
+ 7. **HALT condition**: if a card cannot be updated (e.g., file read error, YAML parse error), log it in `## Issues & Flags` and continue with the remaining cards. Report the failure in the final summary.
1244
+
1245
+ **Why this exists**: Agents frequently skip the DONE marking in Phase 4 (step 27) due to context compaction, commit failures that interrupt the flow, or team mode where Step D.6 gets lost. This gate is the safety net that catches ALL of these cases.
1246
+
1247
+ ### Fail-safe rules (enforced by worktree-manager skill)
1248
+ - **Never `git checkout`, `git switch`, `git checkout -b`, or `git branch` on the main repo** from inside this orchestrator. The main repo is shared across parallel terminals. Use `gh pr merge` for develop merges and `git -C <main> pull --ff-only` (only when `HEAD = develop` already) for sync. See `/mw` step 4c.
1249
+ - Never merge to `main` — only to `develop`, and only via `gh pr merge` (NOT local checkout).
1250
+ - Never force push to `main` or `develop`. `--force-with-lease` on feature branches after rebase is allowed.
1251
+ - Never delete a branch before successful merge verification.
1252
+ - Never remove a worktree before confirming develop is stable post-merge.
1253
+ - Stop execution immediately if any command fails.
1254
+
1255
+ ---
1256
+
1257
+ ## Phase 7 — Production Readiness Checklist
1258
+
1259
+ After Phase 6 completes (or after the final summary report if Phase 6 is deferred), present a **Production Readiness Checklist** — a clear list of all manual or infrastructure actions required to launch the implemented changes in production.
1260
+
1261
+ ### How to detect items
1262
+
1263
+ Scan ALL files changed across the batch (use the tracker's completed cards + `git diff` against the base branch) and check for:
1264
+
1265
+ | Category | Detection signal | Action to report |
1266
+ |----------|-----------------|------------------|
1267
+ | **Firestore indexes** | New/modified `.firestore.indexes.json`, or code using new compound queries with `orderBy`/`where` on multiple fields | `firebase deploy --only firestore:indexes` |
1268
+ | **Firestore security rules** | New/modified `firestore.rules` | `firebase deploy --only firestore:rules` |
1269
+ | **Storage security rules** | New/modified `storage.rules` | `firebase deploy --only storage:rules` |
1270
+ | **Environment variables** | New `process.env.*` references not present in the base branch, new entries in `.env.example` or `.env.local` | 1. Add to Vercel project settings (list each var name + environments) 2. Update `${paths.references_dir}/env-vars.md` Change Log |
1271
+ | **Firebase Remote Config** | New `remoteConfig` keys in code | Add keys in Firebase Console > Remote Config |
1272
+ | **Firebase Auth providers** | New auth provider configuration | Enable provider in Firebase Console > Authentication |
1273
+ | **Scheduled functions / cron** | New or modified cron/scheduled Cloud Functions | Deploy functions: `firebase deploy --only functions` |
1274
+ | **Database migrations** | New collections, field renames, data backfills referenced in code or ADRs | Run migration script (specify which) |
1275
+ | **New API endpoints** | New route files under `src/app/api/` | Verify CORS/auth config; update API docs if public |
1276
+ | **Third-party services** | New API keys, webhook URLs, or external service integrations | Configure in provider dashboard + add secrets to Vercel |
1277
+ | **DNS / domain changes** | Hosting or redirect config changes | Update DNS records or Vercel domain settings |
1278
+ | **Package upgrades with breaking changes** | Major version bumps in `package.json` | Verify compatibility; check migration guides |
1279
+
1280
+ ### Output format
1281
+
1282
+ Present the checklist as a clearly formatted section in the final report:
1283
+
1284
+ ```
1285
+ ## Production Readiness Checklist
1286
+
1287
+ ### Required before deploy
1288
+ 1. **[Firebase Indexes]** Deploy Firestore composite indexes
1289
+ - Command: `firebase deploy --only firestore:indexes`
1290
+ - Reason: New compound query on `redemptions` (storeId + tableNumber + createdAt)
1291
+
1292
+ 2. **[Environment Variable]** Add `REDIS_URL` to Vercel
1293
+ - Go to: Vercel > Project Settings > Environment Variables
1294
+ - Required for: Production, Preview
1295
+ - Value: (obtain from Upstash dashboard)
1296
+
1297
+ 3. **[Firestore Rules]** Deploy updated security rules
1298
+ - Command: `firebase deploy --only firestore:rules`
1299
+ - Reason: New collection `promoRedemptions` access rules added
1300
+
1301
+ ### No action needed
1302
+ - No new scheduled functions
1303
+ - No database migrations
1304
+ - No DNS changes
1305
+
1306
+ ### Notes
1307
+ - Firebase index deployment can take 5-10 minutes; deploy BEFORE releasing the code
1308
+ - Environment variables must be set BEFORE the Vercel deployment triggers
1309
+ ```
1310
+
1311
+ ### Auto-execution of agent-doable tasks
1312
+
1313
+ Before presenting the checklist, **auto-execute** all items that can be performed by the agent
1314
+ without manual intervention. Do NOT ask the user for approval — just run them.
1315
+
1316
+ **Auto-executable items** (run via Bash tool, no confirmation needed):
1317
+
1318
+ | Category | Command | Auto-execute? |
1319
+ |----------|---------|--------------|
1320
+ | Firestore indexes | `firebase deploy --only firestore:indexes --project <your-firebase-project>` | YES |
1321
+ | Firestore security rules | `firebase deploy --only firestore:rules --project <your-firebase-project>` | YES |
1322
+ | Storage security rules | `firebase deploy --only storage:rules --project <your-firebase-project>` | YES |
1323
+ | Scheduled functions | `firebase deploy --only functions --project <your-firebase-project>` | YES |
1324
+
1325
+ **Manual-only items** (report to user, do NOT auto-execute):
1326
+
1327
+ | Category | Why manual |
1328
+ |----------|-----------|
1329
+ | Environment variables | Requires Vercel dashboard access or secret values |
1330
+ | Firebase Remote Config | Requires Firebase Console UI |
1331
+ | Firebase Auth providers | Requires Firebase Console UI |
1332
+ | Database migrations / backfills | Risk of data loss — needs human judgment |
1333
+ | Third-party service config | Requires external dashboards and secrets |
1334
+ | DNS / domain changes | Risk of downtime — needs human judgment |
1335
+
1336
+ **Auto-execution procedure:**
1337
+
1338
+ 1. For each auto-executable item detected, run the command immediately.
1339
+ 2. Log the result (success/failure) in the tracker under `## Production Readiness`.
1340
+ 3. In the final checklist output, mark auto-executed items with their result:
1341
+ ```
1342
+ 1. **[Firebase Indexes]** Deploy Firestore composite indexes
1343
+ - Command: `firebase deploy --only firestore:indexes --project <your-firebase-project>`
1344
+ - Result: DEPLOYED (took 45s) | FAILED (error: ...)
1345
+ ```
1346
+ 4. If an auto-execution FAILS: log the error, mark it as `MANUAL FALLBACK NEEDED`,
1347
+ and include it in the "Required before deploy" section for the user to handle.
1348
+
1349
+ ### Firestore Index Verification (MUST — after deploy)
1350
+
1351
+ After `firebase deploy --only firestore:indexes` succeeds, you MUST verify that all indexes
1352
+ are actually `READY` before reporting success. The deploy command returns immediately, but
1353
+ indexes can take 5-10 minutes to build.
1354
+
1355
+ **Verification procedure:**
1356
+
1357
+ 1. **Extract expected collection groups** from the local `firestore.indexes.json`:
1358
+ ```bash
1359
+ cat firestore.indexes.json | python3 -c "
1360
+ import sys, json
1361
+ data = json.load(sys.stdin)
1362
+ groups = sorted(set(i['collectionGroup'] for i in data.get('indexes', [])))
1363
+ print('\n'.join(groups))
1364
+ "
1365
+ ```
1366
+
1367
+ 2. **Check index states** via Firestore REST API for each collection group:
1368
+ ```bash
1369
+ TOKEN=$(gcloud auth print-access-token) && \
1370
+ for CG in <collection_groups>; do
1371
+ curl -s "https://firestore.googleapis.com/v1/projects/<your-firebase-project>/databases/(default)/collectionGroups/$CG/indexes" \
1372
+ -H "Authorization: Bearer $TOKEN" 2>/dev/null
1373
+ done | python3 -c "
1374
+ import sys, json, re
1375
+ raw = sys.stdin.read()
1376
+ # Parse multiple JSON responses concatenated
1377
+ creating = []
1378
+ for match in re.finditer(r'\{[^{}]*\"indexes\"[^}]*\}', raw, re.DOTALL):
1379
+ try:
1380
+ data = json.loads(match.group())
1381
+ for idx in data.get('indexes', []):
1382
+ state = idx.get('state', 'UNKNOWN')
1383
+ if state != 'READY':
1384
+ fields = ' + '.join(f.get('fieldPath','?') for f in idx.get('fields',[]))
1385
+ cg = idx.get('name','').split('/collectionGroups/')[1].split('/')[0] if '/collectionGroups/' in idx.get('name','') else '?'
1386
+ creating.append(f'{state}: {cg} ({fields})')
1387
+ except: pass
1388
+ if creating:
1389
+ print(f'NOT_READY ({len(creating)} indexes still building):')
1390
+ for c in creating: print(f' - {c}')
1391
+ else:
1392
+ print('ALL_READY')
1393
+ "
1394
+ ```
1395
+
1396
+ 3. **Poll if NOT_READY** — re-check every 30 seconds, up to 10 retries (5 minutes max).
1397
+ After each retry, print a status update: `Index verification attempt N/10 — still N indexes building...`
1398
+
1399
+ 4. **Final status**:
1400
+ - If all indexes are `READY`: mark as `VERIFIED READY` in the checklist
1401
+ - If indexes are still `CREATING` after 10 retries: mark as `DEPLOYED BUT BUILDING — indexes may take a few more minutes` (this is a warning, not a failure)
1402
+ - If any index is `NEEDS_REPAIR` or `ERROR`: mark as `INDEX ERROR — manual intervention required` and include the index details
1403
+
1404
+ **Checklist output format with verification:**
1405
+ ```
1406
+ 1. **[Firebase Indexes]** Deploy Firestore composite indexes
1407
+ - Command: `firebase deploy --only firestore:indexes --project <your-firebase-project>`
1408
+ - Deploy: SUCCESS (took 45s)
1409
+ - Verification: ALL INDEXES READY (155/155) | BUILDING (3 still creating after 5min) | ERROR (details)
1410
+ ```
1411
+
1412
+ ### Rules
1413
+
1414
+ - **Always present this section**, even if the checklist is empty (in that case, state "No infrastructure changes required — deploy is code-only").
1415
+ - Order items by **deployment sequence** (items that must happen first go first — e.g., indexes before code deploy, env vars before code deploy).
1416
+ - For each item, include the **reason** (which card/feature requires it) and the **exact command or UI path**.
1417
+ - If an item is **uncertain** (e.g., you suspect a new index might be needed but aren't sure), mark it with `VERIFY` and explain what to check.
1418
+ - **Update the tracker** with the full checklist under a new `## Production Readiness` section.
1419
+
1420
+ ---
1421
+
1422
+ ## Context recovery protocol
1423
+
1424
+ If at ANY point you are unsure where you are in the batch:
1425
+ 1. Read your tracker file (`/tmp/batch-tracker-<FIRST-CARD-ID>.md`)
1426
+ 2. Check `## Current Card` — if populated, resume that card at the listed phase.
1427
+ 3. Check `## Card Queue` — find the next unchecked card.
1428
+ 4. Check `## Completed Cards` — know what's already done (don't redo).
1429
+ 5. Continue the pipeline from where you left off.
1430
+
1431
+ ---
1432
+
1433
+ ## Parallelism rules
1434
+
1435
+ ### Sequential mode (default for small batches)
1436
+
1437
+ - Cards execute one at a time through the full per-card pipeline (Phases 1-5).
1438
+ - Code review and doc review for the same card run as **parallel read-only audits**, then fixes are applied in a single sequential pass.
1439
+ - This mode is unchanged from the original behavior.
1440
+
1441
+ ### Team mode (for complex batches)
1442
+
1443
+ - Cards within the same `parallel_group` run in parallel via isolated coder agents.
1444
+ - Groups execute sequentially (group 0 → group 1 → group 2...).
1445
+ - Review + QA run ONCE per group (combined), not per card.
1446
+ - The orchestrator holds ONLY coordination state, never implementation details.
1447
+ - File ownership map is enforced per-agent via MAY EDIT / FORBIDDEN lists.
1448
+ - See "Team Mode" section below for full workflow.
1449
+
1450
+ ### Common rules (both modes)
1451
+
1452
+ - The file-ownership map is the authoritative source for which files each agent may edit.
1453
+ - When running parallel agents, expect "file modified since read" errors on shared files (like the backlog yml) — handle gracefully.
1454
+ - When running in parallel, each parallel branch updates the tracker with its own card — use card ID as prefix to avoid conflicts.
1455
+
1456
+ ---
1457
+
1458
+ ## Team Mode (parallel coder agents with isolated contexts)
1459
+
1460
+ When the complexity assessment (step 3c) selects team mode, the orchestrator changes role: instead of executing each card's pipeline sequentially, it coordinates parallel coder agents — each with its OWN isolated context window.
1461
+
1462
+ **Key principle**: the orchestrator stays LEAN. It holds only:
1463
+ - The tracker file path
1464
+ - Parallel group status (pending/active/done)
1465
+ - Completion verdicts per card (pass/fail + files changed)
1466
+
1467
+ It does NOT accumulate implementation details, codebase-architect findings, or review outputs — those live and die in each agent's isolated context.
1468
+
1469
+ ### Team Mode Pre-flight
1470
+
1471
+ After the standard pre-flight (steps 1-7), add:
1472
+
1473
+ 1. Read all cards' `parallel_group` field and sort into execution layers.
1474
+ 2. Update tracker with team mode section:
1475
+ ```
1476
+ ## Team Mode
1477
+ Status: active
1478
+
1479
+ ## Parallel Groups
1480
+ | Group | Cards | Status |
1481
+ |-------|-------|--------|
1482
+ | 0 | FEAT-01 | pending |
1483
+ | 1 | FEAT-02, FEAT-03 | pending |
1484
+ | 2 | FEAT-04, FEAT-05 | pending |
1485
+ ```
1486
+
1487
+ ### Per-Group Execution
1488
+
1489
+ Process groups in order (0, 1, 2, ...). Within each group, spawn coder agents IN PARALLEL — one per card.
1490
+
1491
+ #### Step A: Pre-compute shared context (ONCE per group)
1492
+
1493
+ Before spawning coders, the orchestrator runs **codebase-architect** ONCE for the entire group (not per card). This single call covers all cards in the group.
1494
+
1495
+ Prompt:
1496
+ ```
1497
+ Explore the codebase for context relevant to these cards:
1498
+ [list card IDs + their scope.summary, one line each]
1499
+
1500
+ Focus on: [combined files_likely_touched from all cards in group]
1501
+ Return: file paths, type signatures, existing patterns. Max 30 lines.
1502
+ ```
1503
+
1504
+ This is the ONLY context the orchestrator accumulates per group. After passing it to the coders, it can be purged.
1505
+
1506
+ #### Step B: Spawn parallel coder agents
1507
+
1508
+ For each card in the current group, spawn a coder agent using the Agent tool. ALL agents for the group MUST be spawned in a **SINGLE message** (multiple Agent tool calls) to run truly in parallel.
1509
+
1510
+ Each coder agent receives a **SELF-CONTAINED** mission briefing that includes EVERYTHING it needs — it will NOT call codebase-architect or plan-auditor itself:
1511
+
1512
+ ```
1513
+ Agent tool call:
1514
+ subagent_type: "coder"
1515
+ mode: "bypassPermissions"
1516
+ run_in_background: true
1517
+ name: "coder-<CARD-ID>"
1518
+ prompt: |
1519
+ ## AUTONOMOUS CARD IMPLEMENTATION — <CARD-ID>
1520
+
1521
+ You are implementing this card AUTONOMOUSLY. Complete ALL phases below
1522
+ without external coordination. You have your own isolated context.
1523
+
1524
+ ### 1. Card Specification (verbatim)
1525
+ Requirements:
1526
+ [copy from card YAML]
1527
+
1528
+ Acceptance Criteria:
1529
+ [copy from card YAML]
1530
+
1531
+ ### 2. Codebase Context (pre-computed)
1532
+ [paste codebase-architect findings from Step A]
1533
+
1534
+ ### 3. Working Directory
1535
+ All work MUST happen in the worktree: <worktree-path>
1536
+ cd to this directory before any file operations.
1537
+
1538
+ ### 4. File Permissions (ENFORCED)
1539
+ MAY EDIT:
1540
+ [files from ownership map for THIS card only]
1541
+
1542
+ FORBIDDEN:
1543
+ - ALL files not in the MAY EDIT list
1544
+ - Do NOT create files outside the designated paths
1545
+
1546
+ ### 5. Design Reference (if UI card)
1547
+ [path to design.html if exists]
1548
+
1549
+ ### 6. Your Pipeline
1550
+ Execute these steps in order:
1551
+ a) Print the numbered requirements checklist (anti-skip measure)
1552
+ b) Implement ALL requirements
1553
+ c) Run: npx tsc --noEmit && npx eslint --max-warnings=0 <your-files>
1554
+ d) Self-heal up to 3 times if checks fail
1555
+ e) Verify completeness: for each requirement, confirm code exists (read it)
1556
+ f) If any requirement is missing after implementation, implement it now
1557
+ g) Output the completion report (MANDATORY format below)
1558
+
1559
+ ### 7. Completion Report (MANDATORY)
1560
+ ```completion-report
1561
+ card: <CARD-ID>
1562
+ status: done | partial | failed
1563
+ requirements:
1564
+ - id: 1
1565
+ text: "[text]"
1566
+ status: done | partial | blocked
1567
+ evidence: "file:line"
1568
+ files_changed:
1569
+ - path/to/file.ts
1570
+ build_status: pass | fail
1571
+ lint_status: pass | fail
1572
+ retry_count: N
1573
+ ```
1574
+ ```
1575
+
1576
+ #### Step C: Wait for group completion
1577
+
1578
+ The orchestrator waits for ALL background agents in the group to complete. It will be notified automatically as each finishes (`run_in_background`).
1579
+
1580
+ For each completed agent:
1581
+ 1. Read the completion report from the agent's output.
1582
+ 2. Log to tracker: card ID, status, files changed, build/lint status.
1583
+ 3. Do NOT read or store implementation details — only the verdict.
1584
+
1585
+ **If an agent fails** (status: failed after 3 retries):
1586
+ - Log failure in tracker `## Issues & Flags`.
1587
+ - Other agents in the group continue unaffected.
1588
+ - After group completes, ask user: retry failed card or skip?
1589
+
1590
+ #### Step D: Post-group review + QA
1591
+
1592
+ After ALL agents in the group complete successfully:
1593
+
1594
+ 1. **Build verification** — Run `npm run build` in the worktree to verify combined changes compile. If build fails, identify which card's changes broke it (from `git diff` per card), spawn a targeted fix-coder for those files only.
1595
+
1596
+ 2. **Combined review** — Invoke **code-reviewer** + **doc-reviewer** IN PARALLEL (read-only, same as Phase 3) across ALL changes in the group. This is ONE combined review, not per-card — more efficient and catches cross-card issues.
1597
+
1598
+ 3. **Apply fixes** — If findings exist, spawn ONE fix-coder to apply all fixes in a single pass. Run build + lint after.
1599
+
1600
+ 4. **QA gate** — Select the HIGHEST QA profile across all cards in the group (e.g., if one card is BALANCED and another is DEEP, use DEEP). Invoke **qa-sentinel** once for the group.
1601
+
1602
+ 4b. **Pre-Merge Codex Review Gate (MANDATORY — UNCONDITIONAL)** — Invoke `/codexreview` for EACH card in the group, one at a time, BEFORE any commit. This mirrors Phase 3.7 of the sequential path and is non-skippable regardless of file paths or perceived risk. Apply the same fix sub-loop: if the consolidated report shows verified BLOCKER/HIGH findings, spawn a fix-coder and re-run `/codexreview <CARD-ID>` (max 2 retries per card). If still BLOCKER/HIGH after retries, ask the user before proceeding to step 5. The Phase 4-equivalent commits in step 5 MUST NOT happen until every card in the group has a PASS verdict (or explicit user override). Log results in the tracker under `## Pre-Merge Codex Review` per card.
1603
+
1604
+ 5. **Commit** — One commit per card using explicit staging from the ownership map. **NO stash in worktrees** (stashes are globally shared via `refs/stash` — see Phase 4 WORKTREE COMMIT RULE):
1605
+ ```bash
1606
+ cd <worktree-path>
1607
+ # For each card in the group:
1608
+ git add <card's-files-only>
1609
+ git commit -m "[CARD-ID] Brief description"
1610
+ ```
1611
+
1612
+ 6. **Update backlog (MANDATORY — do NOT skip)** — For EACH card in the group:
1613
+ a. Edit the backlog YAML (`${paths.backlog_dir}/<CARD-ID>.yml`): set `status: DONE`, add `completed_date: <today>`, add implementation notes.
1614
+ b. **Verify the write**: re-read the YAML file and confirm `status: DONE` is present. If not, retry.
1615
+ c. Stage the updated YAML and include it in the card's commit (or as an immediate follow-up commit).
1616
+ d. Log in tracker: `card_status: DONE (verified)` for each card.
1617
+ Note: Phase 6b (Status Reconciliation) will catch any card missed here, but aim for zero misses.
1618
+
1619
+ #### Step E: Context purge + next group
1620
+
1621
+ After committing all cards in the group:
1622
+ 1. Update tracker: move group to done, log all results per card.
1623
+ 2. **PURGE**: forget all implementation details, review findings, architect context.
1624
+ 3. Move to the next pending group (Step A again).
1625
+
1626
+ ### Sequential fallback within team mode
1627
+
1628
+ If two cards in the same parallel group are discovered at runtime to have a file conflict (e.g., one coder created an unexpected file that overlaps):
1629
+ 1. Detect via file-diff gate after Step C.
1630
+ 2. Revert the later card's conflicting files.
1631
+ 3. Re-run that card as a standalone sequential step after the group.
1632
+
1633
+ ### Dependency gates between groups
1634
+
1635
+ Before starting group N, verify ALL cards in groups 0..N-1 are status: done. If any card in a previous group failed and was skipped:
1636
+ - If cards in group N `depends_on` it: skip those dependent cards too, log in `## Issues & Flags`.
1637
+ - If no dependency: proceed normally.
1638
+
1639
+ ### Post-batch (same as sequential mode)
1640
+
1641
+ After all groups are complete, run the same Final Review, Phase 6 (merge), and Phase 7 (production readiness) as documented above. No changes needed for these phases.
1642
+
1643
+ ---
1644
+
1645
+ ## Phase 8 — Metrics Log (MANDATORY — runs after Phase 7)
1646
+
1647
+ After the Production Readiness Checklist is complete, log this batch run to the skill
1648
+ effectiveness registry. This enables tracking of first-attempt success rate, actionability,
1649
+ and QA quality over time.
1650
+
1651
+ **Steps:**
1652
+
1653
+ 1. Read the batch tracker file (`/tmp/batch-tracker-<FIRST-CARD-ID>.md`) to extract:
1654
+ - Start timestamp (from `Started:` field)
1655
+ - Card list and total count
1656
+ - For each completed card: fix_cycles, qa_profile, qa_verdict, findings_total, findings_verified, blockers_count
1657
+ - Merge commit hash
1658
+
1659
+ 2. Compute aggregate metrics:
1660
+ - `first_attempt_success_rate`: cards with fix_cycles == 0 / total_cards
1661
+ - `mean_fix_cycles`: mean of per-card fix cycle counts
1662
+ - `qa_profiles`: count of {skip, light, balanced, deep}
1663
+ - `qa_pass_first_attempt_rate`: cards with qa_verdict PASS on first attempt / total
1664
+ - `findings_total` / `findings_verified`: sum across all cards
1665
+ - `actionability_rate`: findings_verified / findings_total (conservative proxy; 0 if no findings)
1666
+ - `severity_p0_pct`: blockers_count / findings_total (0 if no findings)
1667
+ - `cycle_time_mins`: minutes from `Started:` timestamp to merge commit time (use `git log --format=%ci <hash>`)
1668
+
1669
+ 3. Write ONE JSON line to `docs/metrics/skill-runs.jsonl` (append):
1670
+
1671
+ ```json
1672
+ {"ts":"<ISO-8601-UTC>","skill":"new","run_id":"batch-<FIRST-CARD-ID>","cards":["FEAT-XXX"],"total_cards":N,"first_attempt_success_rate":0.0,"mean_fix_cycles":0.0,"qa_profiles":{"skip":0,"light":0,"balanced":0,"deep":0},"qa_pass_first_attempt_rate":0.0,"findings_total":0,"findings_verified":0,"actionability_rate":0.0,"severity_p0_pct":0.0,"doc_gaps_found":0,"doc_gaps_fixed":0,"cycle_time_mins":0,"worktree_branch":"","merge_commit":""}
1673
+ ```
1674
+
1675
+ Use `date -u +%Y-%m-%dT%H:%M:%SZ` for the timestamp. Write with `echo '...' >> docs/metrics/skill-runs.jsonl` via Bash.
1676
+
1677
+ 4. Copy the batch tracker to archive:
1678
+
1679
+ ```bash
1680
+ cp /tmp/batch-tracker-<FIRST-CARD-ID>.md docs/metrics/archive/
1681
+ ```
1682
+
1683
+ 5. Note in tracker: `## Metrics Log: WRITTEN (run_id: batch-<FIRST-CARD-ID>)`
1684
+
1685
+ **If `docs/metrics/skill-runs.jsonl` does not exist**: create it first with `touch docs/metrics/skill-runs.jsonl`.
1686
+ **If batch tracker is missing or unreadable**: log "Metrics Log: SKIPPED (tracker not found)" and proceed without blocking.
1687
+ **This phase is NON-BLOCKING** — if it fails for any reason, do not abort the run.