baldart 4.14.0 → 4.14.1

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 CHANGED
@@ -5,6 +5,16 @@ 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
+ ## [4.14.1] - 2026-06-04
9
+
10
+ **Il gate Simplify del Team Mode di `/new` (D.3b) ora skippa solo le card davvero trivial (`TRIVIAL_CARDS`), non tutte quelle con `review_profile == skip` — chiude una divergenza col path sequential (Phase 2.55 `IS_TRIVIAL`) e con la stessa D.1.5 di team-mode.** La pipeline per-card di `/new` vive in due modalità (sequential e team) che ri-enunciano alcuni gate; due predicati gemelli erano davvero divergenti. **Drift 1 (bug, fixato)**: il sequential Phase 2.55 ri-conferma `IS_TRIVIAL` sul diff ACTUAL committato (tutte e 3 le condizioni, incl. il check non-source) → una card `review_profile=skip` con un file SORGENTE nel diff reale NON è trivial → ESEGUE Simplify; il team D.3b invece skippava sul solo `review_profile == skip`, ignorando il diff reale → la saltava. Aggravante: team-mode era incoerente con sé stesso — a D.1.5 calcola GIÀ `TRIVIAL_CARDS` col check non-source completo (e la sua nota SSOT dichiara «D.3b already skipped for trivial»), ma il gate D.3b gateava sul set più lasco. Blast radius: solo qualità (la card prendeva comunque D.2 code-review + il Final FULL gate), ma in team mode si perdeva la difesa contro la deviazione del coder che il sequential ha. **Drift 2 (intenzionale, documentato)**: lo scope per-GRUPPO della QA gate (D.4) vs per-CARD del sequential (21b) — stesso predicato (`deep`/risk → FULL, altrimenti defer al Final), granularità per necessità del modello a wave (qa-sentinel gira una volta sul diff combinato del gruppo); è il lato deliberatamente più conservativo (una card rischiosa → tutto il gruppo FULL), nessun gap di correttezza → comportamento invariato, aggiunta solo una frase di chiarimento. **PATCH** (bugfix di un falso-skip in team mode; nessuna capability, nessuna chiave `baldart.config.yml`).
11
+
12
+ > **Why.** I gate ri-enunciati nei due path di `/new` devono restare predicato-identici, o le due modalità divergono silenziosamente. Qui il fix è un puro allineamento: D.3b passa dal set lasco (`review_profile == skip`) al set già calcolato a monte a D.1.5 (`TRIVIAL_CARDS` = `review_profile==skip` AND 0 Step-A triggers AND non-source diff), che è esattamente l'`IS_TRIVIAL` del sequential 2.55. Nessuna nuova logica, nessun ricalcolo: si consuma il set che D.1.5 dichiarava già di pilotare. Il Drift 2 si lascia perché la granularità per-gruppo è una necessità del modello a wave (un solo qa-sentinel sul diff combinato), non una svista, ed è il lato più sicuro — ma ora è documentato come intenzionale per non farlo rifixare in futuro.
13
+
14
+ ### Changed
15
+
16
+ - **`framework/.claude/skills/new/references/team-mode.md`** — gate D.3b (Simplify) riscritto da «SKIP per `review_profile == skip`» a «SKIP per card in `TRIVIAL_CARDS`» (il set già computato a D.1.5), con log-line allineata al sequential (`simplify: SKIPPED (trivial — non-source diff)`); una card `skip` con file sorgente nel diff ora esegue Simplify come nel sequential 2.55. D.4 (QA gate) — aggiunta una frase che documenta lo scope per-gruppo come INTENZIONALE (stesso predicato del sequential 21b, valutato a livello di gruppo perché qa-sentinel gira una volta sul diff combinato; lato deliberatamente più conservativo). Nessun cambio di logica su D.4.
17
+
8
18
  ## [4.14.0] - 2026-06-04
9
19
 
10
20
  **Nuovo tipo di payload `.claude/workflows/` (dynamic workflow di Claude Code) + il primo workflow `new-final-review`: la Final Review F.2–F.4 di `/new` può girare come script di orchestrazione deterministico, opt-in e con fallback inline.** I dynamic workflow (research-preview di Claude Code) spostano l'orchestrazione fan-out fuori dal context-window dell'orchestrator, nel codice. Una review avversariale ha **refutato** l'idea di farne il motore *per-card* di `/new` (rompe la portabilità Codex — sono Claude-only; dipende da una preview come breaking change; duplica la logica di gate col team-mode; introduce attrito-permessi e regressione di recovery proprio dove `/new` è più intrecciata con worktree/git/stato). Il bersaglio scelto è invece la parte dove i rischi spariscono e il valore resta: la **Final Review F.1–F.6** è **read-only** (gli agenti leggono solo il diff committato), ha **definizione SSOT unica** condivisa da sequential e team mode (→ nessun twin), e ha l'**adversarial-verify già nativo** (FP-check di Codex in F.3, cross-validation `code-reviewer` a confidence<80 in F.4). **MINOR** (nuova capability additiva: nuovo payload type + un workflow; nessun breaking change, nessuna chiave `baldart.config.yml` — il gating è runtime via presenza del tool `Workflow`; i consumer senza workflow o Codex-only eseguono la Final Review inline come prima).
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.14.0
1
+ 4.14.1
@@ -173,13 +173,13 @@ After ALL agents in the group complete successfully:
173
173
  3a. **D.3a — Phase 2.5b AC-Closure Gate (per-card, BLOCKING — non-skippable)** — For EACH card in the group, **sequentially**, invoke the full Phase 2.5b gate as documented in `### Phase 2.5b — AC-Closure Gate (BLOCKING — Scope Closure Discipline)`. This includes: build the AC Closure Ledger from the card YAML, run the rationalization scan, invoke `AskUserQuestion` one-per-deferred-AC, run the `implementation_notes` deferral audit, and persist the ledger in the tracker. Until EVERY card in the group exits PASS, do NOT proceed to D.3b. Cards exiting with `not_implemented` ACs that the user routes to "Implementa adesso" must finish their fix-coder loop and re-pass the gate before D.3b starts for the next card. Log under `## AC Closure Ledger — <CARD-ID>` per card.
174
174
 
175
175
  3b. **D.3b — Phase 2.55 Simplify (per-card, FANNED OUT across the group)** — The Simplify agents are **read-only analysis on file-disjoint per-card diffs** (the orchestrator applies the fixes afterward), so there is NO reason to run them one card at a time. **Spawn the per-card Simplify analysis for ALL eligible cards in PARALLEL** — in a SINGLE message, fire each card's Phase 2.55 trio (Reuse / Quality / Efficiency) against that card's diff captured to `/tmp/diff-<CARD-ID>.txt` (per Phase 2.55 step 2 — pass each trio the **path**, scoped to the card's File Ownership Map; never inline the diff). Per-card (not group-aggregate) so findings stay attributable. When all analyses return, **apply fixes per card** (file-disjoint → no write conflict), then re-run `npm run lint` and `npx tsc --noEmit` on the worktree ONCE for the whole group (redirect to disk per § "Context economy"). (Concurrency is capped by the platform; passing N cards is safe — excess agents queue.)
176
- - **Gate (enumerated, `review_profile`-driven)**: SKIP D.3b for a card whose `review_profile == skip` (trivial / non-implementable card Simplify is quality-only, so there is no merge-gate coverage to lose, and there is no substantive diff to simplify). Log `simplify: SKIPPED (review_profile=skip)`. For `light`/`balanced`/`deep` cards D.3b runs unchanged. This is the ONLY enumerated skip — never skip D.3b "for time" on a `light`+ card. (Skipped cards are simply omitted from the parallel fan-out.)
176
+ - **Gate (enumerated, `TRIVIAL_CARDS`-driven)**: SKIP D.3b for a card in **`TRIVIAL_CARDS`** (the set already computed at D.1.5 — `review_profile == skip` AND 0 Step-A triggers AND **non-source diff**), aligning team mode with sequential Phase 2.55's `IS_TRIVIAL` re-confirmation on the ACTUAL diff and with team-mode's own D.1.5 SSOT. A trivial card has no substantive diff to simplify, and Simplify is quality-only (no merge-gate coverage to lose). Log `simplify: SKIPPED (trivial — non-source diff)`. **A card with `review_profile == skip` whose committed diff DID touch a source file is NOT in `TRIVIAL_CARDS` → run D.3b for it** (exactly as sequential 2.55 does — `skip` is the floor, the real diff is the deciding check). For `light`/`balanced`/`deep` cards D.3b runs unchanged. This is the ONLY enumerated skip — never skip D.3b "for time" on a non-trivial card. (Skipped cards are simply omitted from the parallel fan-out.)
177
177
 
178
178
  3c. **D.3c — Phase 2.6 E2E-Review (per-card)** — First, evaluate the existing Gate table for EVERY card at once (skip when `features.has_e2e_review: false`, backend-only diff per the diff predicate documented in Phase 2.6, or card type in the Phase 2.6 skip set — `backend`/`api`/`db`/`infra`/`docs`/`chore`/`config`). In practice most cards in a group skip this gate (backend/db/api), so the eligible set is usually 0–1. For the cards that PASS the gate, invoke `/e2e-review` in programmatic mode with that card's payload. Each `/e2e-review` keeps its own isolated state dir (`.baldart/e2e-review/<CARD-ID>/`), so multiple runs do not clobber each other's artifacts.
179
179
  - **Parallel-when-safe**: if **two or more** cards pass the gate, you MAY fan them out in parallel ONLY when they hit **disjoint routes/pages** — the genuinely shared resource is the worktree's single dev-server port, and concurrent Playwright sessions against one server are fine for disjoint routes. If the eligible cards touch overlapping routes (or `/e2e-review` spins its own server and a port clash is possible), run those **sequentially** to avoid a flaky cross-test. Default to parallel for the common disjoint case; fall back to sequential on any contention.
180
180
  - 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.
181
181
 
182
- 4. **D.4 — QA gate (group; since v4.7.0 — runs only for `deep` / risk-escalation, else deferred to Final)** — Read each card's `review_profile` field and the D.1.5 Step-A trigger result. **Run the group qa-sentinel (once, at FULL) iff** the group's MAX profile is `deep` **OR** any card in the group had a Step-A risk escalation. **Otherwise (max profile ≤ `balanced`, no escalation) → DEFER the group QA to the Final Review F.3 qa-sentinel** (FULL suite + build + audit over the entire batch — the unconditional merge gate); log `D.4 QA: DEFERRED to Final FULL gate (group max=balanced, no risk escalation)`. This mirrors sequential step 21b. When it DOES run, invoke qa-sentinel at FULL (the combined group diff must be validated together) using the same prompt contract as Phase 3.5 step 22. ⚠️ A balanced-only group runs its first suite at the Final gate; merge safety is preserved because Final is FULL over the whole batch.
182
+ 4. **D.4 — QA gate (group; since v4.7.0 — runs only for `deep` / risk-escalation, else deferred to Final)** — Read each card's `review_profile` field and the D.1.5 Step-A trigger result. **Run the group qa-sentinel (once, at FULL) iff** the group's MAX profile is `deep` **OR** any card in the group had a Step-A risk escalation. **Otherwise (max profile ≤ `balanced`, no escalation) → DEFER the group QA to the Final Review F.3 qa-sentinel** (FULL suite + build + audit over the entire batch — the unconditional merge gate); log `D.4 QA: DEFERRED to Final FULL gate (group max=balanced, no risk escalation)`. This mirrors sequential step 21b. When it DOES run, invoke qa-sentinel at FULL (the combined group diff must be validated together) using the same prompt contract as Phase 3.5 step 22. **Granularity (INTENTIONAL — not a drift)**: the predicate is identical to sequential 21b (`deep`/risk-escalation → FULL, else defer to the Final FULL gate), but it is evaluated **per-GROUP** here whereas sequential evaluates it per-CARD. This is by design — qa-sentinel runs once over the group's combined diff (the wave-batched model gives it no per-card granularity), so the gate is deliberately the more conservative side: a single `deep`/risk card escalates the WHOLE group to FULL rather than just itself. No correctness gap — every card still reaches a FULL suite no later than the unconditional Final gate. ⚠️ A balanced-only group runs its first suite at the Final gate; merge safety is preserved because Final is FULL over the whole batch.
183
183
 
184
184
  4a. **D.4a — Per-card doc gate (consumes D.2, since v3.35.0; doc-reviewer-applied since v3.40.0)** — Do NOT re-run the doc AUDIT (D.2 already produced per-card-attributed findings). If any card in the group has doc findings, invoke the **doc-reviewer once in write mode** over the group, passing the per-card-attributed findings from D.2, to APPLY all doc fixes in a single pass (it is now alone — code-reviewer is done — so the D.2 parallel-safety constraint no longer applies). Do **NOT** spawn a fix-coder for doc findings: `doc` is owned by `doc-reviewer` (see "Domain-Override Domains"); a code-oriented coder lacks the doc-invariant contract. The only exception is a doc-drift→bug finding rooted in CODE — that follows the D.4b code fix path. (Previously D.4a spawned a fix-coder per card; the audit was already collapsed to a single attributed D.2 pass. D.4b's per-card `/codexreview` also skips its doc-reviewer via the lean contract, so the doc AUDIT runs once per group while the doc FIXES run once per group via doc-reviewer.) **Telemetry** — append one row per applied doc finding to `## Fix Application Log`: `D.4a | doc | est_lines=<n> | decision=doc-reviewer | applied_by=doc-reviewer | card=<ID> | finding=<1-line>`. **Phase-8 producer (named counter)** — ALSO record per card the `doc_gaps: found=<N> fixed=<M>` line in that card's `## Completed Cards` entry (same named counter as sequential Phase 3 step 15), so Phase 8 reads `doc_gaps_found`/`doc_gaps_fixed` from a structured field, not a free-form row.
185
185
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.14.0",
3
+ "version": "4.14.1",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"