baldart 3.37.0 → 3.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/VERSION +1 -1
- package/framework/.claude/agents/prd-card-writer.md +35 -0
- package/framework/.claude/commands/codexreview.md +18 -12
- package/framework/.claude/commands/new.md +3 -3
- package/framework/.claude/skills/new/SKILL.md +57 -28
- package/framework/.claude/skills/prd/assets/card-template.yml +14 -0
- package/framework/.claude/skills/prd/assets/epic-template.yml +5 -0
- package/framework/.claude/skills/prd/references/backlog-phase.md +1 -0
- package/framework/.claude/skills/prd/references/validation-phase.md +33 -10
- package/framework/templates/feature-card.template.yml +7 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ All notable changes to BALDART will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.38.0] - 2026-06-01
|
|
9
|
+
|
|
10
|
+
**The per-card review depth (QA + Codex) is now decided deterministically in the backlog card via a new `review_profile` field, computed once at PRD authoring time — instead of being re-derived heuristically by `/new` at runtime.** This removes the implementing agent's interpretation latitude: the card carries `skip|light|balanced|deep`, `/new` READS it, and only falls back to runtime computation for legacy cards that predate the field. **No new `baldart.config.yml` keys** — this is a backlog-card schema change, propagated end-to-end across templates + card-writer + validation + `/new` in the same release.
|
|
11
|
+
|
|
12
|
+
> **Why.** Previously the QA Profile Selector (Phase 3.5) and the Codex Review Profile Selector (Phase 3.7) both recomputed the profile inside `/new` from soft signals (title keywords, the self-admittedly-unreliable `files_likely_touched`), so the same card could be reviewed differently depending on the orchestrator's reading. The card already encodes every hard signal needed (`owner_agent`, type, `areas`, `data_fields`, `db_indexes`, `acceptance_criteria`, `estimated_complexity`) — so the decision is now made once, in the card, by the deterministic rules in `prd-card-writer.md § Rule C` (the SSOT).
|
|
13
|
+
|
|
14
|
+
### Added — `review_profile` card field (deterministic review depth)
|
|
15
|
+
|
|
16
|
+
- **[framework/.claude/skills/prd/assets/card-template.yml](framework/.claude/skills/prd/assets/card-template.yml)** + **[framework/templates/feature-card.template.yml](framework/templates/feature-card.template.yml)** + **[framework/.claude/skills/prd/assets/epic-template.yml](framework/.claude/skills/prd/assets/epic-template.yml)**: new `review_profile: skip|light|balanced|deep` field. Epics are always `skip` (trackers, no code work). Authors MAY override the computed value by hand.
|
|
17
|
+
- **[framework/.claude/agents/prd-card-writer.md](framework/.claude/agents/prd-card-writer.md)**: new **Rule C** — the canonical mapping table (metadata → profile) and the SSOT for the decision. Added `review_profile` to the required-fields list. `feature`/`enhancement` cards are floored at `balanced` (never `light`).
|
|
18
|
+
- **[framework/.claude/skills/prd/references/validation-phase.md](framework/.claude/skills/prd/references/validation-phase.md)**: Step 6.0 now BLOCKS on a missing/out-of-enum `review_profile` (mirrors the `owner_agent` gate), with a soft WARN+normalize for `feature`-card-`light` violations and epic non-`skip` values.
|
|
19
|
+
- **[framework/.claude/skills/prd/references/backlog-phase.md](framework/.claude/skills/prd/references/backlog-phase.md)**: documents that `prd-card-writer` populates `review_profile`.
|
|
20
|
+
|
|
21
|
+
### Changed — `/new` reads the field instead of recomputing it
|
|
22
|
+
|
|
23
|
+
- **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** (QA Profile Selector): primary path now READS `review_profile` from the card verbatim; the existing rule table is demoted to a **legacy-card fallback** with an explicit "keep in sync with `prd-card-writer.md § Rule C` (SSOT)" note.
|
|
24
|
+
- **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** (Phase 3.7 Step C.0): the Codex profile derives from the card's `review_profile` (`skip`/`light` → Codex `light`, `balanced`/`deep` → Codex `full`). New **escalation-only invariant**: the Step A high-risk diff detector can only promote `light` → `full` (a risk surfaced at implementation time the authored profile didn't anticipate), never downgrade `full` → `light`. The card's `review_profile` is the deterministic floor; the diff detector is the safety net on top.
|
|
25
|
+
- **[framework/.claude/commands/new.md](framework/.claude/commands/new.md)**: thin mirror updated to the read-from-card primary path with compute-fallback.
|
|
26
|
+
|
|
27
|
+
### Changed — `light` profile no longer runs the per-card Codex adversarial pass
|
|
28
|
+
|
|
29
|
+
- **[framework/.claude/commands/codexreview.md](framework/.claude/commands/codexreview.md)** (Step -0.5) + **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** (Phase 3.7 Step C.0, Team D.4b): at `profile: light`, `/codexreview` now omits agent #5 (Codex adversarial) in addition to qa-sentinel + api-perf-cost-auditor + Step 3.5 CoVe. **`light` per-card = `code-reviewer` + the false-positive gate only.** The Codex adversarial review becomes the prerogative of `full` and of the final cross-check.
|
|
30
|
+
- **Why it's safe (BUG-0530 invariant relocated, not dropped)**: the "never miss a blocker on a low-risk path" guarantee is now carried by (1) the **escalation-only** Step A detector — any high-risk path in the actual diff promotes `light` → `full`, so risky code still gets per-card Codex adversarial immediately; and (2) the unconditional **Final-review FULL gate** (v3.37.0), which runs Codex adversarial over the entire batch diff before merge. So every `light` card's code is still Codex-reviewed at least once pre-merge — the pass is paid once at the batch gate instead of N times per-card. Trade-off: a Codex-class finding on a 0-trigger `light` card surfaces at the final gate rather than per-card (later fix-cycle, still pre-merge).
|
|
31
|
+
- **Revert**: re-add agent #5 to the `light` branch of `/codexreview` Step -0.5.
|
|
32
|
+
|
|
33
|
+
### Backward compatibility
|
|
34
|
+
|
|
35
|
+
- **Non-breaking**: backlogs authored before v3.38.0 have no `review_profile`. `/new` silently falls back to the runtime rule table (logging `computed — review_profile absent`), so existing cards run exactly as before. New PRD-generated cards get the field automatically.
|
|
36
|
+
|
|
37
|
+
## [3.37.1] - 2026-06-01
|
|
38
|
+
|
|
39
|
+
**`/prd` Step 7 merge is fully seamless — auto merge + worktree cleanup with zero end-of-session questions; the user is asked ONLY for conflicts `mw-docs` genuinely cannot auto-resolve.** Fixes a drift between the `/prd` `validation-phase.md` and the real `worktree-manager mw-docs` behaviour that made the skill over-ask. No new `baldart.config.yml` keys.
|
|
40
|
+
|
|
41
|
+
### Fixed — `/prd` no longer over-asks at merge time
|
|
42
|
+
|
|
43
|
+
- **[framework/.claude/skills/prd/references/validation-phase.md](framework/.claude/skills/prd/references/validation-phase.md)**: the cross-PRD-collision note and the Step 7 conflict-resolution table claimed structured registries (`project-status.md`, `ssot-registry.md`, …) "abort the rebase and ask for manual resolution". That contradicted `worktree-manager` `mw-docs`, which actually strips markers + runs a structural validation and only aborts when the validation fails (the rare same-row collision). Aligned both spots to the real behaviour: append-only registries auto-resolve and merge with zero questions; escalation happens **only** on a genuinely unresolvable conflict (code/test/fixture, or a structured registry whose strip+validate failed).
|
|
44
|
+
- **[framework/.claude/skills/prd/references/validation-phase.md](framework/.claude/skills/prd/references/validation-phase.md)** (Step 7 step 9): reinforced "no confirmation prompt" — explicitly forbids the "vuoi che mergi e pulisca il worktree?" pre-emptive gate. Merge **and** cleanup run automatically; the model lets `mw-docs` run and only surfaces what it actually reports as unresolvable, instead of asking "just in case".
|
|
45
|
+
|
|
8
46
|
## [3.37.0] - 2026-05-30
|
|
9
47
|
|
|
10
48
|
**Two-tier review for `/new`: fast `light` per-card during the loop, one guaranteed FULL pass over the whole batch before merge.** This activates the dormant v3.35.0 Review Profile Selector AND re-introduces an unconditional final full review — together they cut tokens/wall-clock on low-risk cards *without* weakening the merge gate. **No new `baldart.config.yml` keys** — both are changes inside the skill, so the schema-propagation rule does not apply.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.38.0
|
|
@@ -155,6 +155,40 @@ files and one file would be torn between two cards), prefer a single
|
|
|
155
155
|
assign `ui-expert` to a mixed card. The dispatcher's specialist routing
|
|
156
156
|
breaks down when scope is mixed.
|
|
157
157
|
|
|
158
|
+
### Rule C — Compute `review_profile` on every child card (SSOT — deterministic)
|
|
159
|
+
|
|
160
|
+
Every child card MUST set `review_profile` to exactly one of:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
skip | light | balanced | deep
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
This field materializes the per-card review DEPTH **at authoring time**, so the
|
|
167
|
+
`/new` orchestrator READS it instead of re-deriving it heuristically at runtime.
|
|
168
|
+
The single field drives BOTH the QA depth (`/new` Phase 3.5) and the Codex review
|
|
169
|
+
profile (`/new` Phase 3.7 — `skip`/`light` → Codex `light`, `balanced`/`deep` →
|
|
170
|
+
Codex `full`). **This table is the Single Source of Truth**; the fallback table in
|
|
171
|
+
`framework/.claude/skills/new/SKILL.md § QA Profile Selector` exists only for legacy
|
|
172
|
+
cards that predate this field and MUST stay in sync with the rules below.
|
|
173
|
+
|
|
174
|
+
Apply the **first matching rule** (priority order — top wins):
|
|
175
|
+
|
|
176
|
+
| Profile | When to assign |
|
|
177
|
+
|---------|----------------|
|
|
178
|
+
| **DEEP** | ANY of: `areas` includes both `api` AND `data` — OR title/scope/areas touch `auth`, `payment`, `permission`, `schema`, `migration`, `cron`, `webhook`, `transaction` — OR `data_fields` has ≥3 entries with `status: new` or `status: modified` — OR `db_indexes` present (legacy `firestore_indexes` too) — OR acceptance criteria count > 5 — OR `estimated_complexity: HIGH` — OR API contract changed |
|
|
179
|
+
| **LIGHT** | Card is a `bugfix` or `refactor` — AND ≤3 files in `files_likely_touched` — AND none of the DEEP high-risk keywords/areas apply. **NEVER for `feature` or `enhancement` cards.** |
|
|
180
|
+
| **SKIP** | Card is `docs`, `chore`, or `config` — OR all `files_likely_touched` are `.md`/non-API `.yml`/CSS with zero logic files — OR a pure-cosmetic card (typo/rename/copy/wording/style) with no code areas |
|
|
181
|
+
| **BALANCED** | Default for everything else — ALL `feature`/`enhancement` cards not matching DEEP, plus any `bugfix`/`refactor` with >3 files or breadth that isn't DEEP |
|
|
182
|
+
|
|
183
|
+
**Critical**: `feature` and `enhancement` cards are ALWAYS `balanced` minimum — never
|
|
184
|
+
`light`. When in doubt between `balanced` and `deep`, choose `deep`. `files_likely_touched`
|
|
185
|
+
counts are advisory only — never downgrade a feature card below `balanced` because the
|
|
186
|
+
file count looks small. **Epic cards** always use `review_profile: skip` (no code work).
|
|
187
|
+
|
|
188
|
+
The human author MAY override the computed value by editing the card YAML — e.g. to
|
|
189
|
+
force `deep` on a card they consider sensitive. Honor any explicit value already present;
|
|
190
|
+
only compute when the field is empty.
|
|
191
|
+
|
|
158
192
|
## Card Atomicity Rules
|
|
159
193
|
|
|
160
194
|
Cards MUST be as atomic as possible to enable parallel execution:
|
|
@@ -284,6 +318,7 @@ Every card MUST include ALL fields from the template:
|
|
|
284
318
|
- `definition_of_done` (checklist including doc invariants)
|
|
285
319
|
- `depends_on` / `blocks` (card IDs)
|
|
286
320
|
- `estimated_complexity`
|
|
321
|
+
- `review_profile` (`skip`|`light`|`balanced`|`deep` — computed via Rule C, or honored if pre-set)
|
|
287
322
|
- `files_likely_touched` (exact paths with NEW/MODIFY)
|
|
288
323
|
- `links.prd` (path to PRD)
|
|
289
324
|
- `links.design` (path to design.html — REQUIRED for any card with UI scope)
|
|
@@ -55,17 +55,21 @@ For the (single) card in scope, check for `/tmp/codexreview-lean-<CARD-ID>.json`
|
|
|
55
55
|
- `skip_doc_reviewer: true` → **omit agent #4 (`doc-reviewer`)** in Step 2. Doc concerns are covered
|
|
56
56
|
by `/new` Phase 3, which runs `doc-reviewer` (with the spec/docs-drift lens) on the same diff
|
|
57
57
|
immediately before this gate. *(A2)*
|
|
58
|
-
- `profile: "light"` → ALSO omit agent #2 (`qa-sentinel`)
|
|
59
|
-
and **skip Step 3.5 (CoVe)**.
|
|
60
|
-
the Step 3 false-positive gate
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
- `profile: "light"` → ALSO omit agent #2 (`qa-sentinel`), agent #3 (`api-perf-cost-auditor`),
|
|
59
|
+
**agent #5 (Codex adversarial)** (since v3.38.0), and **skip Step 3.5 (CoVe)**. Only agent #1
|
|
60
|
+
(`code-reviewer`) and the Step 3 false-positive gate run. The Codex adversarial pass is the
|
|
61
|
+
prerogative of `full` and of the final cross-check — every `light` card's code is still reviewed
|
|
62
|
+
by Codex adversarial at the unconditional Final-review FULL gate before merge (see `/new`
|
|
63
|
+
"Final-review FULL gate"), and any high-risk diff trigger escalates the card to `full` per-card
|
|
64
|
+
so it gets Codex adversarial immediately. *(B1)*
|
|
65
|
+
- `profile: "full"` (or missing) → full agent set incl. Codex adversarial, minus #4 if `skip_doc_reviewer`.
|
|
66
|
+
|
|
67
|
+
**Invariant**: lean mode NEVER suppresses the run itself — at minimum `code-reviewer` + the Step 3
|
|
68
|
+
FP-gate execute on every card (`light`); `full` additionally runs the Codex adversarial pass. If the
|
|
69
|
+
contract file is malformed/unreadable, fall back to **full mode** and note it. **Consume-once**: delete `/tmp/codexreview-lean-<CARD-ID>.json`
|
|
66
70
|
immediately after parsing it, so a later standalone `/codexreview <CARD-ID>` on the same card never
|
|
67
71
|
inherits a stale lean contract from a prior `/new` run. Record the resolved mode in the Step 4 report
|
|
68
|
-
`Method` section, e.g. `lean: profile=light, architect=reused, doc-reviewer=skipped(Phase 3), cove=skipped`.
|
|
72
|
+
`Method` section, e.g. `lean: profile=light, architect=reused, doc-reviewer=skipped(Phase 3), codex=skipped(light), cove=skipped`.
|
|
69
73
|
|
|
70
74
|
---
|
|
71
75
|
|
|
@@ -144,8 +148,10 @@ Launch these agents in parallel for each card:
|
|
|
144
148
|
5. **Codex (GPT-5.5)** — adversarial review via `codex-companion.mjs`
|
|
145
149
|
|
|
146
150
|
> **Lean agent set (Step -0.5)**: when a contract file is active, launch only the agents the resolved
|
|
147
|
-
> mode permits — `skip_doc_reviewer` omits #4; `profile: light` additionally omits #2
|
|
148
|
-
>
|
|
151
|
+
> mode permits — `skip_doc_reviewer` omits #4; `profile: light` additionally omits #2, #3, AND **#5
|
|
152
|
+
> (Codex adversarial)** (since v3.38.0). At `light`, only agent #1 (`code-reviewer`) launches (+ the
|
|
153
|
+
> Step 3 FP-gate). At `full` (and in full mode with no contract file), launch all five (Codex #5
|
|
154
|
+
> included). The standalone `/codexreview <CARD-ID>` invocation (no contract) is always full.
|
|
149
155
|
|
|
150
156
|
**Codex invocation rules (agent #5):**
|
|
151
157
|
|
|
@@ -238,7 +244,7 @@ Write one consolidated report per run to `/tmp/codexreview-report-<TIMESTAMP>.md
|
|
|
238
244
|
Report structure:
|
|
239
245
|
|
|
240
246
|
1. `Scope Reviewed`
|
|
241
|
-
2. `Method` (agents used + validation flow; note whether Codex was available or `CODEX_UNAVAILABLE`; note whether Step 3.5 CoVe ran fully or hit budget cap; in lean mode, record the resolved contract — `lean: profile=<light|full>, architect=<reused|spawned>, doc-reviewer=<skipped(Phase 3)|run>, cove=<skipped|run>`)
|
|
247
|
+
2. `Method` (agents used + validation flow; note whether Codex was available or `CODEX_UNAVAILABLE`; note whether Step 3.5 CoVe ran fully or hit budget cap; in lean mode, record the resolved contract — `lean: profile=<light|full>, architect=<reused|spawned>, doc-reviewer=<skipped(Phase 3)|run>, codex=<skipped(light)|run>, cove=<skipped|run>`)
|
|
242
248
|
3. `Verified Bugs` (ordered: BLOCKER -> HIGH -> MEDIUM -> LOW; tag findings with `[codex]` if originating from Codex; tag `[ripple-expanded]` if Step 3.5 added `ripple_files`; tag `[cove_unverified]` if Step 3.5 budget exhausted before reaching it)
|
|
243
249
|
4. `Needs Manual Confirmation`
|
|
244
250
|
5. `False Positives Discarded` (with reason)
|
|
@@ -98,9 +98,9 @@ Main repo: [/absolute/path/to/main/repo]
|
|
|
98
98
|
|
|
99
99
|
## QA Profile Selector
|
|
100
100
|
|
|
101
|
-
Before Phase 3.5, determine the
|
|
101
|
+
Before Phase 3.5, determine the review profile for each card. **Primary path (since v3.38.0): READ the card's `review_profile` field** (`skip|light|balanced|deep`), computed deterministically by the PRD `prd-card-writer` (SSOT). Use it verbatim — do NOT recompute. **Fallback (legacy cards with no field): compute** from the table below (the SKILL.md version is authoritative — keep in sync with `prd-card-writer.md § Rule C`).
|
|
102
102
|
|
|
103
|
-
| Profile | When to apply |
|
|
103
|
+
| Profile | When to apply (fallback compute only) |
|
|
104
104
|
|---------|--------------|
|
|
105
105
|
| **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 |
|
|
106
106
|
| **LIGHT** | 5 or fewer files likely touched — AND no HIGH-risk keywords in paths/areas — OR card type is `bugfix` with small scope — OR pure refactoring with no logic change |
|
|
@@ -141,7 +141,7 @@ For each card, execute these phases in order:
|
|
|
141
141
|
### Phase 3.5 — QA Validation
|
|
142
142
|
|
|
143
143
|
18. **Update tracker**: phase = "3.5-qa".
|
|
144
|
-
19. **Select QA profile
|
|
144
|
+
19. **Select QA profile**: read the card's `review_profile` field (use verbatim); only compute from the QA Profile Selector table above when the field is absent (legacy card). Log the chosen profile and source (`from card` | `computed`) in the tracker (1 line).
|
|
145
145
|
20. **If profile is SKIP**: log "QA skipped — [reason]" in the tracker. Proceed to Phase 4.
|
|
146
146
|
21. **If profile is LIGHT, BALANCED, or DEEP**: invoke the **`qa-sentinel`** agent (subagent_type: `qa-sentinel`) via Task tool with the following context:
|
|
147
147
|
|
|
@@ -297,7 +297,21 @@ Main repo: [/absolute/path/to/main/repo]
|
|
|
297
297
|
|
|
298
298
|
## QA Profile Selector
|
|
299
299
|
|
|
300
|
-
Before Phase 3.5, determine the
|
|
300
|
+
Before Phase 3.5, determine the review profile for each card.
|
|
301
|
+
|
|
302
|
+
**Primary path (deterministic — since v3.38.0): READ `review_profile` from the card YAML.**
|
|
303
|
+
The PRD `prd-card-writer` computes this field at authoring time (`prd-card-writer.md §
|
|
304
|
+
Rule C` — the SSOT) so the decision is made once, in the card, not re-interpreted here.
|
|
305
|
+
If the card has a `review_profile` ∈ {`skip`, `light`, `balanced`, `deep`}, **use it
|
|
306
|
+
verbatim** — do NOT recompute. Log `profile=<x> (from card)` in the tracker.
|
|
307
|
+
|
|
308
|
+
**Fallback path (legacy cards only): compute from the table below.** Cards authored before
|
|
309
|
+
v3.38.0 (or manually without the field) have no `review_profile`. Only then, derive it using
|
|
310
|
+
the **first matching rule** (priority order). Log `profile=<x> (computed — review_profile absent)`.
|
|
311
|
+
|
|
312
|
+
> ⚠️ This fallback table MUST stay in sync with `prd-card-writer.md § Rule C`, which is the
|
|
313
|
+
> SSOT. If you edit the rules, edit both. The two differ only in *when* they run (authoring
|
|
314
|
+
> time vs `/new` runtime), never in *what* they decide.
|
|
301
315
|
|
|
302
316
|
| Profile | When to apply |
|
|
303
317
|
|---------|--------------|
|
|
@@ -1176,7 +1190,7 @@ skill's Phase 1 falls back to deriving Gherkin scenarios from
|
|
|
1176
1190
|
### Phase 3.5 — QA Validation
|
|
1177
1191
|
|
|
1178
1192
|
18. **Update tracker**: phase = "3.5-qa".
|
|
1179
|
-
19. **Select QA profile
|
|
1193
|
+
19. **Select QA profile**: READ the card's `review_profile` field (use verbatim); only compute from the QA Profile Selector table above when the field is absent (legacy card). Log the chosen profile and its source (`from card` | `computed`) in the tracker (1 line).
|
|
1180
1194
|
20. **If profile is SKIP**: log "QA skipped — [reason]" in the tracker. Proceed to Phase 4.
|
|
1181
1195
|
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.
|
|
1182
1196
|
22. **If profile is BALANCED or DEEP**: invoke the **`qa-sentinel`** agent (subagent_type: `qa-sentinel`) via Task tool with the following context:
|
|
@@ -1215,7 +1229,7 @@ skill's Phase 1 falls back to deriving Gherkin scenarios from
|
|
|
1215
1229
|
|
|
1216
1230
|
**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.
|
|
1217
1231
|
|
|
1218
|
-
**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
|
|
1232
|
+
**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 gate itself is unconditional — what varies is its DEPTH (`light` vs `full`). The protection against a missed blocker on a "low-risk" path (BUG-0530-class regressions) is carried by two mechanisms, not by an always-on per-card Codex pass: (1) the Step A detector escalates any risky diff to `full` per-card, and (2) the unconditional **Final-review FULL gate** runs Codex adversarial over the entire batch diff before merge. So `light` can safely run `code-reviewer` + FP-gate only (since v3.38.0) without weakening the merge gate.
|
|
1219
1233
|
|
|
1220
1234
|
#### Step A — Detect (signal-logging only, NEVER gates the next step)
|
|
1221
1235
|
|
|
@@ -1276,26 +1290,40 @@ Log the detector output in the tracker for traceability. **This step never short
|
|
|
1276
1290
|
|
|
1277
1291
|
For EVERY card (no conditional skip — the gate ALWAYS runs; only its DEPTH varies):
|
|
1278
1292
|
|
|
1279
|
-
0. **Select the review profile (deterministic — Review Profile Selector
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1293
|
+
0. **Select the Codex review profile (deterministic — Review Profile Selector)** by mapping the
|
|
1294
|
+
card's review profile (read from the card's `review_profile` field per the QA Profile Selector
|
|
1295
|
+
above — since v3.38.0; fallback-computed only for legacy cards) and the Step A detector:
|
|
1296
|
+
- **`light`** ⟺ the card's profile ∈ {`skip`, `light`} **AND** Step A matched **zero**
|
|
1297
|
+
high-risk triggers.
|
|
1298
|
+
- **`full`** ⟺ otherwise — i.e. the card's profile ∈ {`balanced`, `deep`}, **OR** any Step A
|
|
1299
|
+
trigger matched.
|
|
1300
|
+
|
|
1301
|
+
**Escalation-only invariant (since v3.38.0)**: the Step A detector runs on the ACTUAL diff and
|
|
1302
|
+
can only ever **escalate** `light` → `full` (a high-risk path surfaced at implementation time
|
|
1303
|
+
that the card's authored profile didn't anticipate). It can NEVER downgrade `full` → `light`.
|
|
1304
|
+
The card's `review_profile` is the deterministic floor; the diff detector is the safety net on
|
|
1305
|
+
top of it.
|
|
1306
|
+
|
|
1307
|
+
`light` is **NOT** a skip: `/codexreview` still runs `code-reviewer` + the Step 3 false-positive
|
|
1308
|
+
gate. **Since v3.38.0 the per-card Codex adversarial pass is NO LONGER run at `light`** — it is the
|
|
1309
|
+
prerogative of `full` and of the final cross-check. `light` drops the Codex adversarial pass AND the
|
|
1310
|
+
breadth agents (qa-sentinel, api-perf-cost-auditor, doc-reviewer) AND Step 3.5 CoVe — leaving exactly
|
|
1311
|
+
`code-reviewer` + FP-gate, the cheap per-card pass that yields the early feedback worth having on a
|
|
1312
|
+
0-trigger, QA-light diff. `full` is unchanged (Codex adversarial + the full agent set, minus the
|
|
1313
|
+
duplicate doc-reviewer).
|
|
1314
|
+
**Where the BUG-0530 invariant now lives.** Pre-v3.38.0 the per-card Codex adversarial was the
|
|
1315
|
+
"never miss a blocker on a low-risk path" guard. Two mechanisms now carry that guarantee instead,
|
|
1316
|
+
so dropping it from `light` is safe:
|
|
1317
|
+
1. **Escalation-only (Step A)** — any high-risk trigger on the ACTUAL diff promotes `light` → `full`,
|
|
1318
|
+
so genuinely risky paths (auth/payment/permission/schema/…) STILL get per-card Codex adversarial.
|
|
1319
|
+
Only a 0-trigger, authored-`light` card defers it.
|
|
1320
|
+
2. **Final-review FULL gate (since v3.37.0)** — the **Final review ALWAYS runs a single FULL
|
|
1321
|
+
`/codexreview` over the entire batch diff before merge** (no N=1 skip, no scope reduction — see
|
|
1322
|
+
"Final review → Final-review FULL gate"), and FULL includes Codex adversarial. So every line of
|
|
1323
|
+
every `light` card receives Codex adversarial at least once before merge.
|
|
1324
|
+
Net effect: `light` per-card = early `code-reviewer` feedback; the Codex adversarial review is paid
|
|
1325
|
+
once, at the final batch gate (or per-card the moment a risk trigger fires). To put per-card Codex
|
|
1326
|
+
back on `light`, re-add agent #5 to the `light` branch of `/codexreview` Step -0.5.
|
|
1299
1327
|
|
|
1300
1328
|
Then dump the card diff (reviewer grounding) and write the lean contract `/codexreview` consumes:
|
|
1301
1329
|
```bash
|
|
@@ -1316,7 +1344,7 @@ For EVERY card (no conditional skip — the gate ALWAYS runs; only its DEPTH var
|
|
|
1316
1344
|
```
|
|
1317
1345
|
## Pre-Merge Codex Review
|
|
1318
1346
|
- Triggered: unconditional (mandatory pre-merge gate)
|
|
1319
|
-
- Profile: light | full — reason: <triggers=0
|
|
1347
|
+
- Profile: light | full — reason: <review_profile=<skip|light|balanced|deep> (from card | computed); triggers=0 | trigger #N matched (escalated light→full)>
|
|
1320
1348
|
- Matched high-risk triggers: <list from detector, or "none">
|
|
1321
1349
|
- Action: invoking /codexreview <CARD-ID> (per-card, pre-merge gate; lean contract written)
|
|
1322
1350
|
```
|
|
@@ -1330,8 +1358,9 @@ For EVERY card (no conditional skip — the gate ALWAYS runs; only its DEPTH var
|
|
|
1330
1358
|
|
|
1331
1359
|
`/codexreview` Step -0.5 consumes `/tmp/codexreview-lean-<CARD-ID>.json`: reuses the Phase-1
|
|
1332
1360
|
architecture baseline (no re-spawn), drops the duplicate doc-reviewer, and for `profile: light`
|
|
1333
|
-
also drops qa-sentinel + api-perf-cost-auditor +
|
|
1334
|
-
FP-gate + Step 4 report ALWAYS run. (`full` = standard
|
|
1361
|
+
also drops qa-sentinel + api-perf-cost-auditor + **the Codex adversarial pass** + Step 3.5 CoVe
|
|
1362
|
+
(since v3.38.0). `code-reviewer` + Step 3 FP-gate + Step 4 report ALWAYS run. (`full` = standard
|
|
1363
|
+
pipeline incl. Codex adversarial, minus the duplicate doc-reviewer.)
|
|
1335
1364
|
|
|
1336
1365
|
3. **Read the consolidated report** from `/tmp/codexreview-report-<TIMESTAMP>.md`. Extract:
|
|
1337
1366
|
- Verified BLOCKER count
|
|
@@ -2198,11 +2227,11 @@ After ALL agents in the group complete successfully:
|
|
|
2198
2227
|
|
|
2199
2228
|
3c. **D.3c — Phase 2.6 E2E-Review (per-card)** — For EACH card in the group, honor the existing Gate table (skip when `features.has_e2e_review: false`, backend-only diff per the diff predicate documented in Phase 2.6, or card type `docs`/`chore`/`config`). For cards that pass the gate, invoke `/e2e-review` in programmatic mode with that card's payload. BLOCKING per-card: if `/e2e-review` returns `"blocked"` or `"error"`, surface to the user via the same `AskUserQuestion` documented in Phase 2.6 — do NOT proceed to D.4 with an unresolved card. Skips are logged with the documented gate reason, never with `"time budget"` or similar.
|
|
2200
2229
|
|
|
2201
|
-
4. **D.4 — QA gate (group)** — Select the HIGHEST
|
|
2230
|
+
4. **D.4 — QA gate (group)** — Read each card's `review_profile` field (fallback: compute via the QA Profile Selector table for legacy cards). Select the HIGHEST 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.
|
|
2202
2231
|
|
|
2203
2232
|
4a. **D.4a — Per-card doc gate (consumes D.2, since v3.35.0)** — Do NOT re-spawn `doc-reviewer`. For EACH card in the group, take that card's doc findings from D.2's per-card-attributed output; if any exist, spawn a targeted fix-coder for that card only. (Previously D.4a re-ran doc-reviewer per card — a duplicate of D.2; collapsed to a single attributed D.2 pass. D.4b's per-card `/codexreview` also skips its doc-reviewer via the lean contract, so doc-review now runs once per group instead of ~3× per card.)
|
|
2204
2233
|
|
|
2205
|
-
4b. **D.4b — Pre-Merge Codex Review Gate (per-card, 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 D.5. The D.5 commits MUST NOT happen until every card in the group has a PASS verdict (or explicit user override via `AskUserQuestion`). Log results in the tracker under `## Pre-Merge Codex Review` per card. **Lean + profile (since v3.35.0)**: before each card's `/codexreview`, apply the same Review Profile Selector and write the same `/tmp/codexreview-lean-<CARD-ID>.json` contract as sequential Phase 3.7 Step C — `arch_baseline_path` pointing at `/tmp/arch-baseline-group-<FIRST-CARD-ID>.md`, `skip_doc_reviewer: true`, and `profile: light|full` from (0
|
|
2234
|
+
4b. **D.4b — Pre-Merge Codex Review Gate (per-card, 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 D.5. The D.5 commits MUST NOT happen until every card in the group has a PASS verdict (or explicit user override via `AskUserQuestion`). Log results in the tracker under `## Pre-Merge Codex Review` per card. **Lean + profile (since v3.35.0)**: before each card's `/codexreview`, apply the same Review Profile Selector and write the same `/tmp/codexreview-lean-<CARD-ID>.json` contract as sequential Phase 3.7 Step C — `arch_baseline_path` pointing at `/tmp/arch-baseline-group-<FIRST-CARD-ID>.md`, `skip_doc_reviewer: true`, and `profile: light|full` derived from the card's `review_profile` (`skip`/`light` → `light`, `balanced`/`deep` → `full`; since v3.38.0 read from the card, not recomputed) — with the same **escalation-only** rule: a Step A high-risk trigger on the actual diff promotes `light` → `full`, never the reverse. LIGHT runs `code-reviewer` + FP-gate only — the per-card **Codex adversarial pass is dropped at `light` since v3.38.0** (prerogative of `full` + the final cross-check). The Review Profile Selector is **ACTIVE since v3.37.0** — same status as sequential Phase 3.7 Step C above: `light` is per-card early feedback, and the merge-gate safety is the post-batch **Final-review FULL gate** (a single FULL `/codexreview` over the entire batch diff, which team mode reaches via "Post-batch — same as sequential mode"). To make per-card always-full again, restore `profile = full`; the final full gate stays regardless.
|
|
2206
2235
|
|
|
2207
2236
|
5. **D.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):
|
|
2208
2237
|
```bash
|
|
@@ -108,6 +108,20 @@ blocks: [{{card IDs}}]
|
|
|
108
108
|
|
|
109
109
|
estimated_complexity: {{LOW|MEDIUM|HIGH}}
|
|
110
110
|
|
|
111
|
+
# review_profile — REQUIRED. Decides the per-card review DEPTH deterministically,
|
|
112
|
+
# at PRD authoring time, so /new READS it instead of re-deriving it at runtime.
|
|
113
|
+
# One field drives BOTH QA depth (Phase 3.5) and the Codex profile (Phase 3.7).
|
|
114
|
+
# skip → docs/chore/config or pure-cosmetic cards; no QA/Codex depth needed
|
|
115
|
+
# light → bugfix/refactor, ≤3 files, no high-risk areas (NEVER for feature/enhancement)
|
|
116
|
+
# balanced → default for feature/enhancement, or bugfix/refactor with breadth/risk
|
|
117
|
+
# deep → api+data, auth/payment/permission/schema/migration, ≥3 new/modified
|
|
118
|
+
# data_fields, db_indexes, AC count > 5, or HIGH estimated_complexity
|
|
119
|
+
# Auto-computed by prd-card-writer (§ Review Profile Rules — the SSOT). You MAY
|
|
120
|
+
# override it by hand to force a deeper/shallower review on a specific card.
|
|
121
|
+
# /new maps skip|light → Codex `light`, balanced|deep → Codex `full` (Phase 3.7);
|
|
122
|
+
# a high-risk path in the actual diff can only ESCALATE the Codex profile, never lower it.
|
|
123
|
+
review_profile: {{skip|light|balanced|deep}}
|
|
124
|
+
|
|
111
125
|
# Parallelization metadata (auto-computed by /prd backlog phase)
|
|
112
126
|
parallel_group: {{N}} # Layer di esecuzione: 0 = prima, 1 = dopo layer 0, etc.
|
|
113
127
|
# Card nello stesso gruppo possono girare in parallelo
|
|
@@ -116,6 +116,11 @@ blocks: []
|
|
|
116
116
|
|
|
117
117
|
estimated_complexity: {{LOW|MEDIUM|HIGH}}
|
|
118
118
|
|
|
119
|
+
# review_profile — epics are trackers with NO code-touching work, so review depth
|
|
120
|
+
# is N/A. Always `skip` (consistent with owner_agent: "" on epics). The real
|
|
121
|
+
# review depth lives on the child cards.
|
|
122
|
+
review_profile: skip
|
|
123
|
+
|
|
119
124
|
parallel_group: 0
|
|
120
125
|
|
|
121
126
|
# =============================================================================
|
|
@@ -216,6 +216,7 @@ The `prd-card-writer` agent owns the entire card writing pipeline:
|
|
|
216
216
|
- `execution_strategy` block on epic parent card
|
|
217
217
|
- State file update with card list and matrices
|
|
218
218
|
- `env_vars` field: per ogni card che introduce/modifica/rimuove env vars (rilevabile da PRD Section 6 o da requirements che menzionano `process.env`, segreti, API keys, feature flags), popola il campo con `action: new|modified|removed`, `scope`, `required`, `note`. Se la card non tocca env vars, scrivi `env_vars: []`.
|
|
219
|
+
- `review_profile` field: deterministic per-card review depth (`skip|light|balanced|deep`) computed via `prd-card-writer.md § Rule C` from the card's own metadata (type, areas, data_fields, db_indexes, AC count, estimated_complexity). This materializes the review decision at authoring time so `/new` reads it instead of re-deriving it. Epics always get `review_profile: skip`. Honor any explicit author override already present in the YAML.
|
|
219
220
|
|
|
220
221
|
### What stays in the main context
|
|
221
222
|
|
|
@@ -24,7 +24,16 @@ Mark task 5 as `in_progress`.
|
|
|
24
24
|
- The check is intentionally a soft gate: substrings like "API contract per il mock" or "consumes the auth state from `useAuth()`" are legitimate UI references. The WARN exists to prompt human review, not to block.
|
|
25
25
|
- Exception (no WARN): the marker appears INSIDE a quoted string that explicitly says "consume", "mock", "contract reference", or "exposed by sibling card" — those are UI cards reading an upstream contract, which is expected.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
c. **`review_profile` enum check (BLOCKING)** — read the `review_profile` field on each child card. It MUST equal one of:
|
|
28
|
+
```
|
|
29
|
+
skip | light | balanced | deep
|
|
30
|
+
```
|
|
31
|
+
- **Missing or empty** = **BLOCKER** — the card-writer must compute it via `prd-card-writer.md § Rule C` (the SSOT mapping table). Message: `"Card <ID> has no review_profile — compute it from Rule C (skip|light|balanced|deep) before commit."`
|
|
32
|
+
- **Out-of-enum value** = **BLOCKER**. Message: `"Card <ID> has review_profile: '<value>' — must be one of {skip, light, balanced, deep}."`
|
|
33
|
+
- **Consistency WARN (soft)**: a `feature`/`enhancement` card with `review_profile: light` violates Rule C ("never light for feature/enhancement"). Log `"[REVIEW-PROFILE-WARN] Card <ID> is feature/enhancement but review_profile: light — Rule C floors these at balanced."` and bump to `balanced` unless the author left an explicit override note.
|
|
34
|
+
- **Epics**: `review_profile` MUST be `skip` (trackers have no code work). Any other value = WARN, normalize to `skip`.
|
|
35
|
+
|
|
36
|
+
**Gate**: every card has `owner_agent` AND `review_profile` in their enums. WARN entries from checks (b)/(c) are noted in the audit log; user may accept them after review.
|
|
28
37
|
|
|
29
38
|
1. **Field Name Audit (runs BEFORE audit agents)** — for each generated card:
|
|
30
39
|
|
|
@@ -73,9 +82,13 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
|
|
|
73
82
|
in parallel. The rebase in step 8 below brings the worktree up to the latest
|
|
74
83
|
`origin/develop` BEFORE the merge, so two parallel PRDs ending at the same
|
|
75
84
|
time produce a clean append-only diff in most cases. If the rebase reports
|
|
76
|
-
conflicts on these two files
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
conflicts on these two files, `worktree-manager mw-docs` does **not** ask
|
|
86
|
+
immediately: it strips the markers ("keep both sides", which on append-only
|
|
87
|
+
registries is the correct additive result) and then runs a structural
|
|
88
|
+
validation. The merge proceeds automatically when the validation passes. It
|
|
89
|
+
escalates to the user **only** in the rare case where both PRDs modified the
|
|
90
|
+
same row and the validation fails — i.e. a conflict that genuinely cannot be
|
|
91
|
+
auto-resolved. See `/mw` step 4b "Structured registries" row.
|
|
79
92
|
|
|
80
93
|
### Commit (inside the worktree)
|
|
81
94
|
|
|
@@ -110,9 +123,18 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
|
|
|
110
123
|
### Merge into develop (worktree-manager mw-docs)
|
|
111
124
|
|
|
112
125
|
9. **Invoke `worktree-manager` programmatic mw-docs immediately** — no
|
|
113
|
-
confirmation prompt
|
|
114
|
-
|
|
115
|
-
il "seamless" che è il
|
|
126
|
+
confirmation prompt, no "vuoi che mergi e pulisca il worktree?" question.
|
|
127
|
+
The user opted into the full PRD pipeline when they ran `/prd`; chiedere
|
|
128
|
+
conferma a fine sessione è friction inutile e rompe il "seamless" che è il
|
|
129
|
+
punto della v3.22.0. Merge **and** worktree cleanup run automatically.
|
|
130
|
+
|
|
131
|
+
**The ONLY thing that stops the automatic merge is a conflict `mw-docs`
|
|
132
|
+
genuinely cannot auto-resolve** (a code/test conflict, or a structured
|
|
133
|
+
registry whose strip+validate failed — see step 10). Everything `mw-docs`
|
|
134
|
+
can auto-resolve (additive docs/YAML/JSONL, append-only registries that pass
|
|
135
|
+
validation) merges with zero questions. Do NOT pre-empt the merge with a
|
|
136
|
+
confirmation gate "just in case there might be conflicts" — let `mw-docs`
|
|
137
|
+
run and only surface what it actually reports as unresolvable.
|
|
116
138
|
|
|
117
139
|
The merge is recoverable: if something goes wrong post-merge the user can
|
|
118
140
|
`git revert` on develop just like any other commit. The hard-to-reverse
|
|
@@ -141,9 +163,10 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
|
|
|
141
163
|
- Conflict auto-resolution table (see `/mw` step 4b): additive docs/yaml and
|
|
142
164
|
append-only `.jsonl` files auto-resolve; **structured registries**
|
|
143
165
|
(`project-status.md`, `ssot-registry.md`, `field-registry.*`,
|
|
144
|
-
`traceability-matrix.md`, `REGISTRY.md`)
|
|
145
|
-
|
|
146
|
-
|
|
166
|
+
`traceability-matrix.md`, `REGISTRY.md`) are auto-resolved by strip +
|
|
167
|
+
structural validation, and only abort (escalating to the user) when the
|
|
168
|
+
validation fails — the rare same-row collision. Code / test / fixture
|
|
169
|
+
conflicts always abort and escalate.
|
|
147
170
|
- Merge via the configured `git.merge_strategy` (`pr` or `local-push`).
|
|
148
171
|
- Cleanup: `git worktree remove` + `git branch -d` + registry entry removal.
|
|
149
172
|
- Local develop ref sync (only if main repo HEAD is already `develop`).
|
|
@@ -123,3 +123,10 @@ metadata:
|
|
|
123
123
|
created: YYYY-MM-DD
|
|
124
124
|
updated: YYYY-MM-DD
|
|
125
125
|
estimated_effort: "" # S | M | L | XL
|
|
126
|
+
# review_profile — decides the per-card review depth deterministically.
|
|
127
|
+
# /new reads this instead of re-deriving it at runtime; one field drives both
|
|
128
|
+
# QA depth (Phase 3.5) and the Codex profile (Phase 3.7).
|
|
129
|
+
# skip | light | balanced | deep
|
|
130
|
+
# Auto-computed by prd-card-writer for PRD-generated cards; set it by hand here
|
|
131
|
+
# when authoring a card manually (omit to let /new fall back to runtime compute).
|
|
132
|
+
review_profile: "" # skip | light | balanced | deep
|