baldart 4.28.0 → 4.29.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 CHANGED
@@ -5,6 +5,23 @@ 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.29.0] - 2026-06-11
9
+
10
+ **Final review (F.4): each domain specialist owns its lane — no cross-domain `code-reviewer` re-judge, no self-judge.** The verification step classified findings by spawning `code-reviewer` over EVERY low-confidence finding. That was wrong on two counts: (a) a `doc` finding from `doc-reviewer` (or an `api`/`perf` finding from `api-perf-cost-auditor`) was re-validated by `code-reviewer` — the WRONG specialist judging another domain (a `code-reviewer` judging prose); (b) when Codex is unavailable the `code-reviewer` *fallback* produces the findings and `code-reviewer` then re-judged its OWN findings — self-judging with no model diversity (the same waste removed from the resolve pass in v4.27.1–2). Now every domain specialist FP-checks its OWN findings in the finding pass (doc-reviewer, api-perf-cost-auditor, and the Codex/`code-reviewer`-fallback code engine), so surviving findings arrive already validated; the residual `confidence < 80` path is routed to the finding's DOMAIN specialist (doc→doc-reviewer, api/perf→api-perf-cost-auditor, security/migration→security-reviewer, test→qa-sentinel, else code-reviewer), and when that specialist is the originating finder the finding is surfaced as `NEEDS_MANUAL_CONFIRMATION` rather than re-judged. Applies to BOTH `/new` (inline F.4 prose, the SSOT) and `new2` (the `new-final-review` workflow). **MINOR** (behavioral refinement of the final-review classification rule; the returned `{findings, classification, summary}` contract is unchanged; no `baldart.config.yml` key, so the schema-change propagation rule does not apply).
11
+
12
+ ### Changed
13
+
14
+ - **`framework/.claude/skills/new/references/final-review.md` Step F.4 step 9** (SSOT) — replaced "Claude agent findings with confidence < 80 → cross-validate by spawning code-reviewer" with the specialist-ownership rule: specialists self-FP-check their own domain, residual unresolved findings route to the domain specialist, finder===verifier ⇒ `NEEDS_MANUAL_CONFIRMATION`.
15
+ - **`framework/.claude/workflows/new-final-review.js`** — `doc-reviewer`/`api-perf-cost-auditor` prompts now mandate an in-domain false-positive check; their findings (and the `code-reviewer` fallback's) are marked `preValidated` so they skip the re-judge; `verifyFinding()` uses a new `domainVerifier()` router (never a hardcoded `code-reviewer`) and short-circuits a finder===verifier case to `NEEDS_MANUAL_CONFIRMATION`. `meta.description` + Verify phase detail updated.
16
+
17
+ ## [4.28.1] - 2026-06-11
18
+
19
+ **Doc: list the `new.migration-example.md` overlay example in the overlays README.** Completes the v4.28.0 Migration Gate docs — the example overlay file shipped in v4.28.0 was not yet listed in the `framework/templates/overlays/README.md` example table. **PATCH** (doc-only).
20
+
21
+ ### Changed
22
+
23
+ - **`framework/templates/overlays/README.md`** — added the `new.migration-example.md` row (Migration-Gate apply modalities for `/new` Phase 0 step 1b · `new2` Step 3.5).
24
+
8
25
  ## [4.28.0] - 2026-06-11
9
26
 
10
27
  **`new2`: front-loaded Migration Gate — declared DB migrations are applied BEFORE the batch, so downstream cards verify against a live schema.** The workflow runs autonomously and cannot apply an owner-gated DB migration mid-run, so a declared migration was deferred to end-of-batch — and every downstream card was built/verified against a schema not yet live (`validation_commands` / QA / E2E / DB-generated `tsc` types fail falsely → those cards cascade into deferral). The new gate runs in the **skill** (the main loop, which can interact — the workflow's zero-ask contract is untouched), mirroring `/new` Phase 0 step 1b: it finds the batch epic's `migration_plan` (`required: true`), verifies artifacts on disk, assembles apply modalities (epic `apply_modalities` + `.baldart/overlays/new.md` `## Migration modalities` + project memory + built-in `Già applicata`/`Abort`), asks ONE pre-launch question, executes the chosen modality in `$MAIN`, and passes a `migration` manifest into the workflow. **MINOR** (additive capability on the EXPERIMENTAL `new2` surface; the gate is a silent no-op when no migration is declared and degrades to today's end-of-batch deferral when artifacts are missing — no regression; the `migration` arg is the skill→workflow contract only, NOT a `baldart.config.yml` key, so the schema-change propagation rule does not apply).
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.28.0
1
+ 4.29.0
@@ -199,8 +199,8 @@ deterministic script outside this orchestrator's context window.
199
199
  the unavailable case, so the final merge gate still gets a full code review.
200
200
 
201
201
  9. **Merge all findings** (Codex + Claude agents) into a consolidated list.
202
- - Codex findings are already FP-validated (Step F.3 protocol includes it).
203
- - Claude agent findings with `confidence < 80` cross-validate by spawning **`code-reviewer`** as the static validator over the cited file:line; on disagreement between the originating agent and `code-reviewer`, classify the finding `NEEDS_MANUAL_CONFIRMATION` (do NOT silently drop it). (Naming the validator avoids the inconsistent "some second agent" interpretation.)
202
+ - **Each domain specialist OWNS its lane end-to-end** — it runs its OWN false-positive check in the finding pass (doc-reviewer for doc, api-perf-cost-auditor for api/perf/data, and the Codex/`code-reviewer`-fallback engine for code), so its surviving findings are **already validated**. Do **NOT** cross-validate a doc or api finding by spawning `code-reviewer` (that is the WRONG specialist judging another domain), and do **NOT** re-run the same specialist over its own findings (self-judge — no model diversity). Codex findings are likewise already FP-validated (Step F.3 protocol includes it).
203
+ - **Residual only:** a finding the originating specialist explicitly leaves UNRESOLVED (`confidence < 80`) is routed to the finding's **domain specialist** (by `domain`: doc→doc-reviewer, api/perf→api-perf-cost-auditor, security/migration→security-reviewer, test→qa-sentinel, else code-reviewer) over the cited file:line. If that domain specialist **is** the originating finder (it already had its pass), classify `NEEDS_MANUAL_CONFIRMATION` instead of re-spawning it never self-judge, never silently drop.
204
204
  - Classify: `VERIFIED` | `FALSE_POSITIVE` | `NEEDS_MANUAL_CONFIRMATION`.
205
205
  - `VERIFIED` findings proceed to fixes. **`NEEDS_MANUAL_CONFIRMATION` findings are NOT discarded** — list them in `## Issues & Flags` and surface them to the user via `AskUserQuestion` (treat as VERIFIED, treat as FALSE_POSITIVE, or hand off) before merge. Only `FALSE_POSITIVE` are dropped.
206
206
 
@@ -1,11 +1,11 @@
1
1
  export const meta = {
2
2
  name: 'new-final-review',
3
3
  description:
4
- "Cross-batch final code review for /new. Fans out a multi-agent review (Codex primary + doc-reviewer + api-perf-cost-auditor + qa-sentinel gates) over the WHOLE batch diff, then adversarially verifies low-confidence findings. Read-only: it returns classified findings and a gate table, and applies NO fixes (the calling skill owns fix application + user gates). Maps to references/final-review.md steps F.2–F.4.",
4
+ "Cross-batch final code review for /new. Fans out a multi-agent review (Codex primary + doc-reviewer + api-perf-cost-auditor + qa-sentinel gates) over the WHOLE batch diff. Each domain specialist OWNS its lane end-to-end — it FP-checks its own findings in the finding pass, so there is no generic code-reviewer re-judge over another specialist's domain (cross-domain) nor over its own findings (self-judge); any residual unresolved finding is routed to its domain specialist. Read-only: returns classified findings + a gate table, applies NO fixes (the calling skill owns fix application + user gates). Maps to references/final-review.md steps F.2–F.4.",
5
5
  phases: [
6
6
  { title: 'Baseline', detail: 'architecture grounding for the batch scope (F.2)' },
7
7
  { title: 'Review', detail: 'parallel multi-agent review of the batch diff (F.3)' },
8
- { title: 'Verify', detail: 'adversarial validation of low-confidence findings (F.4)' },
8
+ { title: 'Verify', detail: 'specialist-owned validation; residual routed to domain specialist (F.4)' },
9
9
  ],
10
10
  }
11
11
 
@@ -155,10 +155,14 @@ const codexPrompt =
155
155
  `Run the mandatory false-positive check on every finding and suppress the unconvincing ones (your findings are treated as already FP-validated). Set codexAvailable:true when the review ran.`
156
156
 
157
157
  const docPrompt =
158
- `Cross-card documentation + SSOT-registry review over the batch diff, per ${protocolRef} Step F.3 (doc-reviewer row). Check doc consistency, ssot-registry completeness, and invariants across the changed files.\n\n${scopeBrief}\n\n${baselineBrief}\n\nReturn findings (domain almost always "doc"). Use the finding schema fields.`
158
+ `Cross-card documentation + SSOT-registry review over the batch diff, per ${protocolRef} Step F.3 (doc-reviewer row). Check doc consistency, ssot-registry completeness, and invariants across the changed files.\n\n${scopeBrief}\n\n${baselineBrief}\n\n` +
159
+ `You OWN the doc domain end-to-end: run the mandatory false-positive check on every finding yourself and SUPPRESS the unconvincing ones — your surviving findings are treated as already validated and are NOT re-judged by another agent (a generic code-reviewer judging prose would be cross-domain). Flag only a finding you genuinely cannot resolve as confidence < 80.\n\n` +
160
+ `Return findings (domain almost always "doc"). Use the finding schema fields.`
159
161
 
160
162
  const apiPrompt =
161
- `API / data-model / performance / cost defect review over the batch diff, per ${protocolRef} Step F.3 (api-perf-cost-auditor row). Look for unbounded reads, N+1, missing pagination, contract drift, and cost regressions.\n\n${scopeBrief}\n\n${baselineBrief}\n\nReturn findings with domain in {code, perf, migration, security}. Use the finding schema fields.`
163
+ `API / data-model / performance / cost defect review over the batch diff, per ${protocolRef} Step F.3 (api-perf-cost-auditor row). Look for unbounded reads, N+1, missing pagination, contract drift, and cost regressions.\n\n${scopeBrief}\n\n${baselineBrief}\n\n` +
164
+ `You OWN the api/perf/data domain end-to-end: run the mandatory false-positive check on every finding yourself and SUPPRESS the unconvincing ones — your surviving findings are treated as already validated and are NOT re-judged by another agent. Flag only a finding you genuinely cannot resolve as confidence < 80.\n\n` +
165
+ `Return findings with domain in {code, perf, migration, security}. Use the finding schema fields.`
162
166
 
163
167
  const qaPrompt =
164
168
  `Run MECHANICAL GATES ONLY over the batch scope, per ${protocolRef} Step F.3 (qa-sentinel row): lint, type-check, the full test suite, build, dependency audit, and markdownlint as applicable to this project. Do NOT read source for code findings, do NOT emit severities — return only a PASS/FAIL/SKIP gate table.\n\nWorktree: ${a.worktreePath || '(cwd)'}\nChanged files:\n${scope.join('\n')}`
@@ -207,7 +211,9 @@ for (const item of reviewResults) {
207
211
  } else if (item.kind === 'qa') {
208
212
  gateTable = (item.r && item.r.gates) || []
209
213
  } else if (item.r && Array.isArray(item.r.findings)) {
210
- raw.push(...item.r.findings.map((f) => ({ ...f, source: item.kind, preValidated: false })))
214
+ // doc-reviewer / api-perf-cost-auditor own their domain and FP-check their OWN findings in
215
+ // the finding pass (their prompts mandate it) → already validated, no cross-domain re-judge.
216
+ raw.push(...item.r.findings.map((f) => ({ ...f, source: item.kind, preValidated: true })))
211
217
  }
212
218
  }
213
219
 
@@ -219,27 +225,53 @@ if (!codexRan) {
219
225
  `Codex was unavailable for the batch final review. Run the FULL code review yourself over the batch diff, per ${protocolRef} Step F.3.\n\n${scopeBrief}\n\n${baselineBrief}\n\nReturn findings using the schema fields, with a self false-positive check applied.`,
220
226
  { label: 'code-reviewer (fallback)', phase: 'Review', agentType: 'code-reviewer', schema: FINDINGS_SCHEMA }
221
227
  )
222
- if (fb && Array.isArray(fb.findings)) raw.push(...fb.findings.map((f) => ({ ...f, source: 'code-reviewer', preValidated: false })))
228
+ // the fallback code-reviewer IS the primary code-review engine here and applied its own FP
229
+ // check (prompt above) → trusted, exactly like Codex. A SECOND code-reviewer pass over its own
230
+ // findings would be self-judging (no model diversity) — preValidated short-circuits it.
231
+ if (fb && Array.isArray(fb.findings)) raw.push(...fb.findings.map((f) => ({ ...f, source: 'code-reviewer', preValidated: true })))
223
232
  }
224
233
 
225
234
  // ───────────────────────────────────────────────────────────────────────────
226
- // Phase Verify (F.4) — adversarial validation of low-confidence findings
227
- // Codex findings are pre-FP-validated VERIFIED. Claude-agent findings with
228
- // confidence < 80 get a code-reviewer static validator; disagreement
229
- // NEEDS_MANUAL_CONFIRMATION (never silently dropped). High-confidence Claude
230
- // findings pass through as VERIFIED.
235
+ // Phase Verify (F.4) — specialist-owned validation (NOT a generic code-reviewer re-judge).
236
+ // Each domain specialist owns its lane end-to-end: it FP-checks its OWN findings in the
237
+ // finding pass, so codex / doc-reviewer / api-perf-cost-auditor / code-reviewer-fallback
238
+ // findings arrive preValidated → VERIFIED with no second pass. This removes two flaws of the
239
+ // old "spawn code-reviewer for every low-confidence finding": (a) code-reviewer judging a doc
240
+ // or api finding is CROSS-DOMAIN (wrong specialist); (b) code-reviewer judging the fallback
241
+ // code-reviewer's OWN findings is SELF-JUDGING (no model diversity). The residual branch only
242
+ // fires for a finding a specialist explicitly left UNRESOLVED (confidence < 80, not
243
+ // preValidated): it is routed to the finding's DOMAIN specialist; if that specialist IS the
244
+ // originating finder, it already had its pass → surface as NEEDS_MANUAL_CONFIRMATION (never a
245
+ // self-judge, never a silent drop).
231
246
  // ───────────────────────────────────────────────────────────────────────────
232
247
  phase('Verify')
233
248
  const classified = (await parallel(raw.map((f) => () => verifyFinding(f)))).filter(Boolean)
234
249
 
250
+ // Route a finding to the specialist that OWNS its domain (never a generic code-reviewer for
251
+ // doc/api/security). Kept in sync with new2-resolve.js normDomain() routing buckets.
252
+ function domainVerifier(domain) {
253
+ const d = String(domain || 'code').toLowerCase()
254
+ if (/doc|wiki|ssot|readme/.test(d)) return 'doc-reviewer'
255
+ if (/sec|auth|secret|rls|migrat|schema|ddl|\bsql\b/.test(d)) return 'security-reviewer'
256
+ if (/perf|cost|\bapi\b|data|latency|throughput|n\+1/.test(d)) return 'api-perf-cost-auditor'
257
+ if (/\btest|qa\b|spec|coverage/.test(d)) return 'qa-sentinel'
258
+ return 'code-reviewer'
259
+ }
260
+
235
261
  async function verifyFinding(f) {
236
262
  if (f.preValidated || (typeof f.confidence === 'number' && f.confidence >= 80)) {
237
263
  return { ...f, classification: 'VERIFIED' }
238
264
  }
265
+ const verifier = domainVerifier(f.domain)
266
+ if (verifier === f.source) {
267
+ // the domain specialist IS the finder and already had its single pass — a second instance of
268
+ // the same agent adds no diversity (self-judge). Surface to the human, do not drop.
269
+ return { ...f, classification: 'NEEDS_MANUAL_CONFIRMATION' }
270
+ }
239
271
  const v = await agent(
240
- `Adversarially validate this code-review finding as a static reviewer over the cited file:line. Default to FALSE_POSITIVE if the evidence does not hold; use NEEDS_MANUAL_CONFIRMATION only when you genuinely cannot decide from the code.\n\n` +
272
+ `Adversarially validate this ${f.domain || 'code'} finding as the DOMAIN specialist over the cited file:line. Default to FALSE_POSITIVE if the evidence does not hold; use NEEDS_MANUAL_CONFIRMATION only when you genuinely cannot decide from the code.\n\n` +
241
273
  `finding_id: ${f.finding_id}\nseverity: ${f.severity}\ntitle: ${f.title}\nevidence: ${f.evidence}\ndomain: ${f.domain}\nsecurity-sensitive paths: ${highRisk.join(', ') || '(none configured)'}`,
242
- { label: `verify:${f.finding_id}`, phase: 'Verify', agentType: 'code-reviewer', schema: VERDICT_SCHEMA }
274
+ { label: `verify:${f.finding_id}`, phase: 'Verify', agentType: verifier, schema: VERDICT_SCHEMA }
243
275
  )
244
276
  return { ...f, classification: (v && v.classification) || 'NEEDS_MANUAL_CONFIRMATION' }
245
277
  }
@@ -50,6 +50,7 @@ Full protocol: [`framework/agents/project-context.md`](../../agents/project-cont
50
50
  |------|------|
51
51
  | `ui-design.fidelity-example.md` | Neo-Brutalism, Recharts/nivo charting stack, merchant theming pairing, Safari open command, evaluation thresholds |
52
52
  | `copywriting.fidelity-example.md` | 4-pillar brand voice, Italian-only rule, segment register matrix (customer/merchant/staff/admin), forbidden vocabulary |
53
+ | `new.migration-example.md` | Migration-Gate apply modalities (`/new` Phase 0 step 1b · `new2` Step 3.5) — how this project front-loads a declared DB migration (db:push / local apply / Prisma deploy) before the batch |
53
54
 
54
55
  Other overlay examples may be added over time. Skills that did not have
55
56
  heavy hard-coded opinions (e.g. `find-skills`, `simplify`) don't need
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.28.0",
3
+ "version": "4.29.0",
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"