baldart 4.17.1 → 4.17.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ 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.17.2] - 2026-06-08
9
+
10
+ **`new2` hardening: 7 lacune latenti chiuse da una revisione adversariale dell'intero workflow.** Dopo i fix di v4.17.1 (nati da run reali), una revisione olistica di `new2` (orchestratore + resolve + final-review + skill) ha isolato 7 lacune non ancora emerse nei run ma reali alla lettura del codice — validate di persona scartando i falsi positivi (l'integrity gate di merge è corretto; lo skill "prose-only" è by-design). **PATCH** (hardening dei workflow `new2`/`new2-resolve` + skill/doc; nessuna nuova capability/layout, **nessuna chiave `baldart.config.yml`** → schema-propagation N/A).
11
+
12
+ ### Fixed
13
+
14
+ - **G1 — `new2-resolve.js`: rimossi gli handler self-healing orfani (`agent-crash`, `baseline-fail`).** `new2.js` non vi instradava MAI (un crash → `crashResult` marca `failed` + residual; un baseline fail → `batchFatal`). Erano codice morto irraggiungibile: `runCard` va in crash PRIMA della fase commit, quindi un eventuale `resolved` non potrebbe comunque committare/mergiare. Il path residual (lo skill materializza la follow-up) è la SSOT; commento esplicativo in `crashResult`.
15
+ - **G2 — `new2.js`: detection Codex G3 cross-card deterministica + skip mono-card.** Il check Codex del pre-flight usava ancora il **soft self-report** che v4.17.1 aveva corretto solo nella final review (stesso falso negativo, per batch multi-card). Ora il bullet G3 risolve PRIMA il glob del companion (esistenza decisa dal glob, non dal giudizio dell'agent), gira Codex in **background con poll**, e vieta un `CODEX_NOT_FOUND` prematuro; su batch **mono-card** il check è saltato del tutto (niente cross-card). Nuovo `codexResolved` nello schema pre-flight + ledger `G3-codex` + campo telemetria `codex_resolved` → un falso negativo è ora visibile.
16
+ - **G3 — `new2.js`: niente silent drop dei finding merge-artifact.** Il filtro F-035 scartava i finding "esiste già nel worktree" con solo un ledger SKIP; un regex lasco poteva far sparire un BLOCKER reale. Ora ogni finding scartato diventa anche un `residuals` (`merge-artifact-skipped`, `materialized:false`) → tracciato, nulla perso.
17
+ - **G4 — `new2/SKILL.md`: materializzazione follow-up offline-safe via `prd-card-writer`.** Il fallback dello skill scriveva uno stub minimale, incoerente col fix #2 (F-039, workflow → prd-card-writer). Ora lo Step 5.1 delega a `prd-card-writer` (card-template, Rule C, owner_agent, traceability), con stub minimale solo come ultima risorsa in outage totale.
18
+ - **G5 — `new2.js`: routing `security-reviewer` non solo da `scopeFiles`.** Una card di sicurezza con file non-matchanti saltava la security review quando `high_risk_modules` non è configurato. Ora il trigger considera anche l'`owner_agent` della card e il suo brief (titolo/requirements), oltre allo scope.
19
+ - **G6 — classificatore di dominio doc allineato.** `isDocDomain` (new2.js) e la branch `doc` di `normDomain` (new2-resolve.js) ora portano un commento di sincronizzazione reciproca (stessi token `doc|wiki|ssot|readme`) per prevenire drift.
20
+ - **G7 — sync documentazione.** `WORKFLOWS.md` (righe `new-final-review`/`new2`/`new2-resolve`) e `new2/SKILL.md` allineati al comportamento v4.17.1/v4.17.2 (doc routing, prd-card-writer followup, Codex deterministico, final review snella mono-card, rimozione handler orfani).
21
+
8
22
  ## [4.17.1] - 2026-06-08
9
23
 
10
24
  **`new2` post-refactor: tre falle di routing/detection emerse al secondo run reale (card FEAT-0019-followup).** Dopo l'hardening v4.17.0, gli agent principali sono correttamente specializzati, ma il *resolve* e il *final review* mostravano tre errori di instradamento. **PATCH** (bugfix di orchestrazione nei workflow `new2-resolve`/`new-final-review`; nessuna nuova capability, nessun cambio layout, **nessuna chiave `baldart.config.yml`** → schema-propagation N/A).
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.17.1
1
+ 4.17.2
@@ -128,10 +128,15 @@ returns when the batch is done. It returns:
128
128
 
129
129
  1. **Materialise missing follow-ups (offline-safe — you have filesystem access, the
130
130
  workflow does not).** For every `residuals[]` entry with `materialized:false`,
131
- write a follow-up card `${paths.backlog_dir}/<card>-followup-<kind>.yml` (status:
132
- TODO; ≥1 requirement derived from the residual; acceptance_criteria = the verbatim
133
- residual; files_likely_touched from the card's ownership) it MUST pass the `/new`
134
- pre-flight field check. This is the layer that guarantees **nothing is ever
131
+ create a follow-up card `${paths.backlog_dir}/<card>-followup-<kind>.yml` (status:
132
+ TODO). **Delegate the write to the `prd-card-writer` agent** the same owner the
133
+ workflow uses (card-template, Rule C `review_profile`, `owner_agent` routed to the
134
+ residual's domain, traceability) derived from the residual (≥1 requirement;
135
+ `acceptance_criteria` = the verbatim residual; `files_likely_touched` from the card's
136
+ ownership). Do NOT hand-write a minimal stub — the offline path must match the
137
+ agent-path quality (F-039). It MUST pass the `/new` pre-flight field check. If
138
+ `prd-card-writer` itself is unavailable (total outage), fall back to a minimal valid
139
+ stub so the card still exists. This is the layer that guarantees **nothing is ever
135
140
  dropped, even when every agent was dead** during the run.
136
141
  2. **Resume if degraded.** If `degraded` is true, re-invoke the workflow with
137
142
  `Workflow({ scriptPath, resumeFromRunId })` (same `args` + the new `ts`). The
@@ -1,7 +1,7 @@
1
1
  export const meta = {
2
2
  name: 'new2-resolve',
3
3
  description:
4
- "Self-healing resolution pass for the autonomous new2 batch workflow. Called by new2 whenever a deterministic gate would otherwise need a human: a card fail/blocker (ac-unmet | blocker | qa-fail | e2e-blocked | merge-blocker), a legitimate scope-EXPANDING finding (scope-expansion), or a cross-cutting edge (agent-crash | baseline-fail). Tier-1 targeted fix with a TERMINAL short-circuit (skips the costly multi-attempt when the problem is impossible-by-definition, verified not trusted), then a judged multi-attempt; a MANDATORY adversarial judge cross-checks every verified claim against the real diff (prevents fabricated success). Specialized per domain (doc→doc-reviewer, ui→ui-expert, security→security-reviewer judge, perf→api-perf-cost-auditor judge). Terminal is a tracked follow-up. Accepts a `findings` list (batched per area). Uses agent()/parallel() only — no nested workflows.",
4
+ "Self-healing resolution pass for the autonomous new2 batch workflow. Called by new2 whenever a deterministic gate would otherwise need a human: a card fail/blocker (ac-unmet | blocker | qa-fail | e2e-blocked | merge-blocker) or a legitimate scope-EXPANDING finding (scope-expansion). Tier-1 targeted fix with a TERMINAL short-circuit (skips the costly multi-attempt when the problem is impossible-by-definition, verified not trusted), then a judged multi-attempt; a MANDATORY adversarial judge cross-checks every verified claim against the real diff (prevents fabricated success). Specialized per domain (doc→doc-reviewer, ui→ui-expert, security→security-reviewer judge, perf→api-perf-cost-auditor judge). Terminal is a tracked follow-up. Accepts a `findings` list (batched per area). Uses agent()/parallel() only — no nested workflows.",
5
5
  phases: [
6
6
  { title: 'Diagnose', detail: 'classify + terminal short-circuit + scope-expansion boundary' },
7
7
  { title: 'Repair', detail: 'targeted fix, then judged multi-attempt if needed' },
@@ -28,6 +28,8 @@ const scopeFiles = Array.isArray(a.scopeFiles) ? a.scopeFiles : []
28
28
  // F-038 — review agents emit FREEFORM domain strings (e.g. 'documentation', 'frontend').
29
29
  // Normalize to the routing buckets the fixer/judge maps key on, so a doc finding never
30
30
  // falls through to the costly `coder` (the v4.17.0 'documentation'→coder regression).
31
+ // G6: the doc token set below MUST stay in sync with isDocDomain() in new2.js (which picks
32
+ // the doc MAY-EDIT) — drift would route a finding to doc-reviewer but with code ownership.
31
33
  function normDomain(d) {
32
34
  const s = String(d || 'code').toLowerCase()
33
35
  if (/doc|wiki|ssot|readme/.test(s)) return 'doc'
@@ -136,18 +138,10 @@ function collectOOS(...attemptObjs) {
136
138
 
137
139
  phase('Diagnose')
138
140
 
139
- // ---- baseline-fail (E2): try to make the trunk build; fatal if irrecoverable ---
140
- if (kind === 'baseline-fail') {
141
- let r = null
142
- try {
143
- r = await agentSafe(
144
- `The batch worktree's BASELINE build fails (trunk may not build). Try to make it build per ${REF}/setup.md step 6a.\n\n${brief}\n\nFix tractable build errors (missing dep, stale lock, trivial type error). Re-run tsc+lint+build. verified:true only if the baseline now passes; else verified:false.`,
145
- { label: `resolve:baseline:${card}`, phase: 'Diagnose', agentType: 'coder', schema: FIX_SCHEMA }
146
- )
147
- } catch (e) { if (e && e.transientExhausted) return { status: 'followup', reason: 'outage during baseline repair', outOfScopeFindings: [] } ; throw e }
148
- if (r && r.verified) { log('baseline recovered.'); return { status: 'resolved', outOfScopeFindings: collectOOS(r) } }
149
- return { status: 'fatal', reason: 'baseline build irrecoverable' }
150
- }
141
+ // NOTE: new2.js never routes 'baseline-fail' ( batchFatal at pre-flight) nor 'agent-crash'
142
+ // ( crashResult marks the card 'failed' + residual) here — a crash happens BEFORE runCard's
143
+ // commit phase, so a 'resolved' verdict could never be committed/merged. Those self-healing
144
+ // branches were removed (v4.17.2 G1) as unreachable dead code; the residual path is the SSOT.
151
145
 
152
146
  // ---- scope-expansion (Asse 2): deterministic boundary ---
153
147
  if (kind === 'scope-expansion') {
@@ -167,19 +161,6 @@ if (kind === 'scope-expansion') {
167
161
  return await materialiseFollowup('scope-expansion', (decide && decide.note) || 'outside ownership / new AC / protected', collectOOS(decide))
168
162
  }
169
163
 
170
- // ---- agent-crash (E1) ---
171
- if (kind === 'agent-crash') {
172
- let r = null
173
- try {
174
- r = await agentSafe(
175
- `A subagent crashed. Re-attempt with the CORRECT specialist (${fixerAgent}) per ${REF}/commit.md § Sub-agent failure protocol.\n\n${brief}\n\nRetry once. ${protectedDomain ? 'PROTECTED domain: if you cannot complete it, verified:false — NEVER inline-bypass.' : ''} Re-verify the gate; verified:true only if done.`,
176
- { label: `resolve:crash:${card}`, phase: 'Repair', agentType: fixerAgent, schema: FIX_SCHEMA }
177
- )
178
- } catch (e) { if (e && e.transientExhausted) return { status: 'followup', reason: 'outage during crash recovery', outOfScopeFindings: [] }; throw e }
179
- if (r && r.verified) { const ok = await judgeVerify([{ i: 1, r }]); if (ok.ok) return { status: 'resolved', outOfScopeFindings: collectOOS(r) } }
180
- return await materialiseFollowup('agent-crash', 'subagent crash unrecovered' + (protectedDomain ? ' (protected — not bypassed)' : ''), collectOOS(r))
181
- }
182
-
183
164
  // ───────────────────────────────────────────────────────────────────────────
184
165
  // Asse 1 — Tier-1 (with terminal short-circuit) → judged multi-attempt → follow-up.
185
166
  // ───────────────────────────────────────────────────────────────────────────
@@ -144,6 +144,9 @@ const PREFLIGHT_SCHEMA = {
144
144
  excluded: { type: 'array', items: { type: 'object', additionalProperties: true } },
145
145
  ownershipMapPath: { type: 'string' },
146
146
  crossCard: { type: 'string' },
147
+ // G2 — deterministic Codex availability (glob-resolved, NOT a self-reported judgement),
148
+ // so a false negative on the cross-card check is visible in telemetry. true=companion found.
149
+ codexResolved: { type: 'boolean' },
147
150
  workspaceNote: { type: 'string' },
148
151
  archBaselinePaths: { type: 'array', items: { type: 'string' } },
149
152
  },
@@ -173,6 +176,14 @@ const projectBrief = [
173
176
  // ───────────────────────────────────────────────────────────────────────────
174
177
  // Phase Pre-flight — ONE ops agent runs all git-heavy work + returns the dep graph.
175
178
  // ───────────────────────────────────────────────────────────────────────────
179
+ // G2 — Codex cross-card grounding. SKIP entirely on a single-card batch (nothing
180
+ // cross-card to find). For multi-card, make the availability DETERMINISTIC: resolve the
181
+ // companion glob FIRST (existence taken out of the agent's judgement), run it in the
182
+ // BACKGROUND with a file poll, and forbid a premature CODEX_NOT_FOUND — same discipline as
183
+ // new-final-review.js, fixing the parallel false-negative the v4.17.1 fix #3 left here.
184
+ const g3Bullet = cardIds.length < 2
185
+ ? `• G3 cross-card grounding: SKIPPED — only one runnable card, nothing cross-card exists. Set crossCard='N/A-single-card' and codexResolved:false (not probed).\n`
186
+ : `• G3 cross-card grounding (setup.md 3d), MULTI-card: FIRST resolve the Codex companion deterministically — run \`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\` and set codexResolved:true IFF it prints a path (existence is glob-decided, NOT your judgement; ALWAYS return codexResolved). If resolved, run the cross-card conflict check by launching \`node "$CODEX" task "<cross-card conflict questions: FILE_CONFLICT/IMPLICIT_DEP/ORDER_RISK/STATE_MUTATION>" > "$FILE" 2>&1\` in the BACKGROUND (run_in_background:true) and POLL "$FILE" to completion (full window). Read the audit ONLY via the [codex]-stripping filter; return DISTILLED findings. Fall to code-reviewer / set crossCard='CAPABILITY_UNAVAILABLE' ONLY when the glob is EMPTY, or it resolved but "$FILE" held CODEX_NOT_FOUND / stayed empty after the FULL window — NEVER because a single synchronous Bash call returned slowly. Provenance-skip still applies (same-provenance cards → nothing cross-card). If conflicts FOUND you MUST APPLY them: FILE_CONFLICT/ORDER_RISK → force the cards SEQUENTIAL and encode it in dependsOn (the conflicting later card dependsOn the earlier).\n`
176
187
  phase('Pre-flight')
177
188
  let preflight = null
178
189
  try {
@@ -183,7 +194,7 @@ try {
183
194
  `DETERMINISTIC GATE POLICIES (NO user prompts):\n` +
184
195
  `• G1 dirty-tree (main repo ${MAIN}): partition framework-managed noise exactly as setup.md step 3 ($METRICS=${METRICS}, .baldart/generated|state.json|skill-conflicts.json — NOT overlays/). Genuine user work → auto-stash 'baldart-new2-${firstCard}' (main checkout) and record the label. Never commit/abort/prompt.\n` +
185
196
  `• Worktree (setup.md step 4): create ONE code worktree off ${TRUNK}; install deps; assign a port; run the baseline (tsc+lint+build). Copy ONLY the artifacts needed (env/.env.local/.env.example/supabase/.temp) — do NOT bulk-copy untracked files from the main repo (avoids stray backlog cards in the worktree). Use the git-authoritative idempotency pre-check. E2: baseline FAILS → fix once; still failing → baseline:'fail' + baselineLog (batch-fatal).\n` +
186
- `• G3 cross-card grounding (setup.md 3d): run the Codex cross-card check (provenance skip; CODEX_NOT_FOUND → code-reviewer; both unavailable → crossCard='CAPABILITY_UNAVAILABLE'). Read the audit ONLY via the [codex]-stripping filter; return DISTILLED findings. If conflicts FOUND you MUST APPLY them: FILE_CONFLICT/ORDER_RISK → force the cards SEQUENTIAL and encode it in dependsOn (the conflicting later card dependsOn the earlier).\n` +
197
+ g3Bullet +
187
198
  `• G4 card-field validation (setup.md 1b/1c): card missing requirements/acceptance_criteria/files_likely_touched → EXCLUDE (excluded[] + reason). Never HALT for one bad card.\n` +
188
199
  `• G5 depends-on: a card whose depends_on names a non-DONE card NOT in this batch → EXCLUDE it AND every in-batch card that transitively depends on it.\n` +
189
200
  `• cardGraph (REQUIRED, F-021): for every runnable card return { id, dependsOn:[IN-BATCH deps only], ownerAgent (the card's owner_agent; G25 unknown→'coder'), reviewProfile (the card's review_profile; default 'balanced'), policyDeferredACs }.\n` +
@@ -206,6 +217,8 @@ if (!preflight || preflight.ok === false || preflight.baseline === 'fail') {
206
217
  for (const ex of preflight.excluded || []) ledger(ex.card, 'preflight-exclude', 'EXCLUDED', ex.reason)
207
218
  if (preflight.workspaceNote) ledger(firstCard, 'G1/G2-workspace', 'AUTO', preflight.workspaceNote)
208
219
  if (preflight.crossCard) ledger(firstCard, 'G3-cross-card', 'INFO', preflight.crossCard)
220
+ // G2 — surface the deterministic Codex availability (false negative now visible in telemetry).
221
+ if (cardIds.length >= 2) ledger(firstCard, 'G3-codex', preflight.codexResolved ? 'CODEX' : 'FALLBACK', preflight.codexResolved ? 'companion glob-resolved' : 'companion not found → code-reviewer')
209
222
 
210
223
  const runnableCards = preflight.cards || []
211
224
  const cardGraph = preflight.cardGraph || []
@@ -239,6 +252,8 @@ cardIds.forEach((id, i) => { pathById[id] = cardPaths[i] || `${paths.backlog_dir
239
252
  // fabrication cross-check reject a correct, judge-approved fix → a wasted Tier-2 fan-out
240
253
  // (~150k tok) and a risk of a bogus follow-up for an already-resolved finding. Give doc
241
254
  // findings their real owner territory.
255
+ // G6 — token set MUST stay in sync with the doc branch of normDomain() in new2-resolve.js;
256
+ // drift would route a finding to doc-reviewer there but pass code ownership from here.
242
257
  function isDocDomain(d) { return /doc|wiki|ssot|readme/i.test(String(d || '')) }
243
258
  function domainMayEdit(dom, codeScope) {
244
259
  if (!isDocDomain(dom)) return codeScope
@@ -363,10 +378,15 @@ async function runCard(cardId, cardPath, lessons) {
363
378
  }
364
379
 
365
380
  // --- Review fan-out (F-024/F-025): specialized agents, trimmed by review_profile. ---
381
+ // G5 — scopeFiles tokens alone miss a security card whose files don't carry them. Also
382
+ // trigger security-reviewer on the card's owner_agent and its brief (title/requirements).
383
+ const securityRelevant = highRisk.length
384
+ || ownerAgent === 'security-reviewer'
385
+ || /auth|security|secret|migration|rls/i.test(`${scopeFiles.join(' ')} ${cardBrief}`)
366
386
  const reviewers = reviewProfile === 'skip' ? []
367
387
  : reviewProfile === 'light' ? ['code-reviewer']
368
388
  : ['code-reviewer', 'doc-reviewer', 'qa-sentinel', 'api-perf-cost-auditor'].concat(
369
- (highRisk.length || /auth|security|secret|migration|rls/i.test(scopeFiles.join(' '))) ? ['security-reviewer'] : [])
389
+ securityRelevant ? ['security-reviewer'] : [])
370
390
  let reviewResults = []
371
391
  try {
372
392
  reviewResults = (await parallel(reviewers.map((ra) => () => agentSafe(
@@ -528,7 +548,12 @@ if (committed.length && !batchFatal && !degraded) {
528
548
  const all = (final.findings || []).filter((f) => (f.classification === 'VERIFIED' || f.classification === 'NEEDS_MANUAL_CONFIRMATION') && (f.severity === 'BLOCKER' || f.severity === 'HIGH'))
529
549
  // F-035 — drop merge-artifact doc findings (content exists in worktree, the merge carries it).
530
550
  const actionable = all.filter((f) => !/in (the )?main repo|not (in|on) (the )?main|merge[- ]?time|worktree.*(not|missing).*main/i.test(`${f.title} ${f.evidence}`))
531
- for (const f of all) if (!actionable.includes(f)) ledger(f.finding_id || firstCard, 'final-merge-artifact', 'SKIP', 'resolved-by-merge')
551
+ // G3 the merge-artifact regex is loose; a BLOCKER/HIGH it over-matches must NOT vanish.
552
+ // Track every skipped finding as a residual (the skill materialises it) — no silent drop.
553
+ for (const f of all) if (!actionable.includes(f)) {
554
+ ledger(f.finding_id || firstCard, 'final-merge-artifact', 'SKIP', 'resolved-by-merge')
555
+ residuals.push({ card: f.finding_id || firstCard, kind: 'merge-artifact-skipped', evidence: `${f.severity} ${f.title}: ${f.evidence}`, materialized: false })
556
+ }
532
557
  // F-007/F-037 — group actionable findings by fix-area (file) → one resolve per area.
533
558
  const byArea = {}
534
559
  for (const f of actionable) {
@@ -640,6 +665,7 @@ function buildTelemetry() {
640
665
  degraded,
641
666
  degradation_reasons: degradationReasons,
642
667
  execution_mode: preflight ? preflight.executionMode : 'sequential',
668
+ codex_resolved: (preflight && cardIds.length >= 2) ? !!preflight.codexResolved : null, // G2 — null = not probed (single-card)
643
669
  // cost — total_tokens via budget.spent() delta; agent_count via counter; wall_clock_s stamped by the SKILL.
644
670
  total_tokens: totalTokens,
645
671
  agent_count: agentCount,
@@ -13,9 +13,9 @@ workflows are unavailable behaves exactly as before.
13
13
 
14
14
  | Workflow | Used by | What it does |
15
15
  | :--- | :--- | :--- |
16
- | `new-final-review` | `/new` Final Review (Step F.1.5) | Runs the read-only cross-batch review fan-out — architecture baseline + Codex ‖ doc-reviewer ‖ api-perf-cost-auditor ‖ qa-sentinel — then adversarially verifies low-confidence findings and returns them classified. Applies no fixes (the skill owns fix application + user gates). |
17
- | `new2` (v4.17.0) | `/new2` skill (the whole batch) | **EXPERIMENTAL A/B variant of `/new`.** Hosts the ENTIRE batch in the background runtime so subagent output never enters the main context. **v4.17.0 hardening (single-wave):** a **dependency-gated DAG scheduler** runs a card only when all in-batch deps are *committed* (and blocks transitive dependents of a failed dep instead of routing them to resolve); each card uses its **owner_agent** + a **specialized review fan-out** (not general-purpose); the worktree is kept **atomic per card** (rollback-to-HEAD on failure); transient API errors are retried and a sustained **outage degrades cleanly** (`degraded` return + durable resume via the skill); a **run ledger** dedups resolves and records accepted deferrals (no re-routing loop); the **merge is integrity-gated** (never force-DONE, never `git add` unreviewed code, never merge an incomplete/degraded batch); mechanical steps (commit / follow-up) run on **Haiku**; telemetry carries real **cost** (`total_tokens` via `budget.spent()`, `agent_count`, skill-stamped `wall_clock_s`) + `degraded`. Agents Read `/new`'s reference modules for semantics. |
18
- | `new2-resolve` (v4.17.0) | `new2` (self-healing) | Resolution pass for any gate that would otherwise need a human. **v4.17.0:** a **terminal short-circuit** skips the costly multi-attempt when the problem is impossible-by-definition (`out-of-ownership` verified in JS; other terminal reasons ratified by a judge); a **MANDATORY adversarial judge** cross-checks every `verified` claim — the judge independently greps the files and the workflow verifies they fall inside MAY-EDIT (defeats fabricated success); accepts a **batched `findings` list** (one resolve per fix-area); domain-specialized fixer + judge (doc→doc-reviewer, ui→ui-expert, security→security-reviewer judge, perf→api-perf-cost-auditor judge); incidental out-of-scope findings are surfaced (not dropped); follow-up materialisation is offline-safe (deferred to the skill if no agent can write). |
16
+ | `new-final-review` | `/new` Final Review (Step F.1.5) | Runs the read-only cross-batch review fan-out — architecture baseline + Codex ‖ doc-reviewer ‖ api-perf-cost-auditor ‖ qa-sentinel — then adversarially verifies low-confidence findings and returns them classified. Applies no fixes (the skill owns fix application + user gates). **v4.17.1+:** Codex availability is resolved by a **deterministic pre-flight glob + background poll** (no false negatives from a synchronous-run timeout); a **single-card batch** skips the duplicate doc/api reviewers (already run per-card), keeping only the cross-model Codex pass + qa gates. |
17
+ | `new2` (v4.17.2) | `/new2` skill (the whole batch) | **EXPERIMENTAL A/B variant of `/new`.** Hosts the ENTIRE batch in the background runtime so subagent output never enters the main context. A **dependency-gated DAG scheduler** runs a card only when all in-batch deps are *committed* (and blocks transitive dependents of a failed dep instead of routing them to resolve); each card uses its **owner_agent** + a **specialized review fan-out** (not general-purpose); the worktree is kept **atomic per card** (rollback-to-HEAD on failure); transient API errors are retried and a sustained **outage degrades cleanly** (`degraded` return + durable resume via the skill); a **run ledger** dedups resolves and records accepted deferrals (no re-routing loop); the **merge is integrity-gated** (never force-DONE, never `git add` unreviewed code, never merge an incomplete/degraded batch); the commit step runs on **Haiku** while **follow-up cards are written by `prd-card-writer`**; telemetry carries real **cost** (`total_tokens` via `budget.spent()`, `agent_count`, skill-stamped `wall_clock_s`) + `degraded`. **v4.17.2:** the pre-flight **G3 cross-card Codex check is deterministic** (glob-first + background poll, skipped on single-card batches; `codex_resolved` in telemetry); a non-transient card crash is terminal-with-residual (no orphaned self-healing). Agents Read `/new`'s reference modules for semantics. |
18
+ | `new2-resolve` (v4.17.2) | `new2` (self-healing) | Resolution pass for any gate that would otherwise need a human (`ac-unmet · blocker · qa-fail · e2e-blocked · merge-blocker · scope-expansion`). A **terminal short-circuit** skips the costly multi-attempt when the problem is impossible-by-definition (`out-of-ownership` verified in JS; other terminal reasons ratified by a judge); a **MANDATORY adversarial judge** cross-checks every `verified` claim — the judge independently greps the files and the workflow verifies **at least one** falls inside MAY-EDIT (`.some()`, so listing adjacent changed files is not mistaken for fabrication); accepts a **batched `findings` list** (one resolve per fix-area). **The domain is normalized** (freeform `documentation`→`doc`, …) before routing the **fixer** (doc→doc-reviewer, ui→ui-expert, security→security-reviewer, else coder) and judge, and a **doc finding gets doc-tree MAY-EDIT** (not the card's code scope); the 3-angle Tier-2 fan-out is reserved for code domains (single retry for doc/test). Follow-ups are written by **`prd-card-writer`**, offline-safe (deferred to the skill if no agent can write). |
19
19
 
20
20
  > **`new2` is an experiment, not a replacement.** It exists to A/B-test the
21
21
  > context-economy of workflow-hosting `/new`. `/new` remains the SSOT, the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.17.1",
3
+ "version": "4.17.2",
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"