baldart 4.56.1 → 4.56.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 +14 -0
- package/VERSION +1 -1
- package/framework/.claude/workflows/new-card-review.js +10 -3
- package/package.json +1 -1
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.56.2] - 2026-06-19
|
|
9
|
+
|
|
10
|
+
**`/new` per-card Codex relay bumped haiku → sonnet — stops a real run from discarding a valid Codex review (incl. a BLOCKER) and falling back to a cold, weaker `code-reviewer`.** A user reported the symptom directly: in the per-wave Discovery phase Codex emitted a perfect sentinel-wrapped JSON array (3 findings, one a BLOCKER race condition on the idempotency key), yet the workflow still ran the cold `code-reviewer (fallback)` — which re-reviewed from scratch (~101k tok) and **missed the BLOCKER**.
|
|
11
|
+
|
|
12
|
+
Root cause: the per-wave Codex relay in `new-card-review.js` ran on `model: 'haiku'`. The relay is "thin" but is still a model in the loop that must follow a multi-branch decision tree AND faithfully pass a large JSON array through the structured schema. Haiku proved too weak on a real run — it went off-script (re-grepped source to "confirm" findings, explicitly forbidden by the prompt) and then failed the pass-through, returning `codexAvailable:false` with empty `codexProse`. The fan-in (`item.r.codexAvailable && Array.isArray(findings)`) therefore discarded every Codex finding and triggered the **plain** cold fallback (not even the codex-seeded one). The "a misfire degrades safely to the fallback" assumption baked into the old comment is false: the cold fallback is a *different model hunting from scratch*, not a backstop — it lost the BLOCKER.
|
|
13
|
+
|
|
14
|
+
`new-final-review.js` already learned this exact lesson (its relay is `model: 'sonnet'` "not haiku because this is the last cross-model gate before merge"); the per-wave relay was simply left behind. This brings it to parity. The relay prompt is low-volume plumbing, so the haiku→sonnet delta is negligible against a dropped BLOCKER plus a ~100k-token cold re-review. Matches the recorded lessons that a weak *model in the loop for pure plumbing* fabricates/abandons, and that the cheap-model-via-structured-output bet only holds if the model can actually emit the structure.
|
|
15
|
+
|
|
16
|
+
**PATCH** — single-line model change (+ rationale comment) in `framework/.claude/workflows/new-card-review.js`; no schema/prose/install/layout change, no new config key. The Codex prompt, awk extraction, sentinel contract, and prose-salvage path are all unchanged.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **`framework/.claude/workflows/new-card-review.js`** — per-wave Codex relay `model: 'haiku'` → `model: 'sonnet'`, with an expanded rationale comment explaining why the misfire-degrades-safely assumption is false (parity with `new-final-review.js`).
|
|
21
|
+
|
|
8
22
|
## [4.56.1] - 2026-06-19
|
|
9
23
|
|
|
10
24
|
**`/new` per-card review-cluster — corrected a prose-vs-implementation drift about Codex depth (doc-only, no behaviour change).** Triggered by a user question — "why does `/new` run a per-card review *and* a final review for a single card, when some agents overlap?". A full read of `new-card-review.js` + `new-final-review.js` + the orchestrating modules, followed by an adversarial refutation pass, established that the apparent double-review is **not** redundant: the per-card Codex/qa-sentinel run in the **Discovery phase (PRE-fix, PRE-E2E)**, while the final Codex/qa-sentinel run on the **post-fix, post-E2E** tree — the same temporal argument the framework already uses to keep `slimDoc:false` on the delegated path (`final-review.md`). A proposed `slimCodex` (drop the final Codex on N=1 when per-card Codex ran) was **refuted and NOT implemented**: it would review materially different code and reopen the v3.35.0 scope-reduction hole that v3.37.0 closed (Codex + qa-sentinel are the explicit never-slim exceptions to F-041).
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.56.
|
|
1
|
+
4.56.2
|
|
@@ -302,9 +302,16 @@ for (const c of cards) {
|
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
if (codexResolved) {
|
|
305
|
-
// model: haiku —
|
|
306
|
-
//
|
|
307
|
-
|
|
305
|
+
// model: sonnet (NOT haiku) — parity with new-final-review.js. The wrapper is a thin relay (launch +
|
|
306
|
+
// poll + awk-extract + faithfully pass Codex's JSON array through the schema), but it is STILL a model
|
|
307
|
+
// in the loop, and haiku proved too weak for it on a real run: it went off-script (re-grepped source to
|
|
308
|
+
// "confirm" findings, explicitly forbidden) and then failed the pass-through — Codex emitted a valid
|
|
309
|
+
// array (incl. a BLOCKER) yet the relay returned codexAvailable:false, so the workflow discarded all of
|
|
310
|
+
// Codex's findings and ran the COLD code-reviewer fallback, which missed the BLOCKER. The "misfire
|
|
311
|
+
// degrades safely to the fallback" assumption is false: the cold fallback is a different model hunting
|
|
312
|
+
// from scratch, not a backstop. Pass-through fidelity on a low-volume plumbing prompt costs little, and
|
|
313
|
+
// a dropped BLOCKER + a 100k-token cold fallback dwarf the haiku→sonnet delta.
|
|
314
|
+
findThunks.push(() => agent(codexPrompt, { label: 'codex', phase: 'Discovery', model: 'sonnet', schema: CODEX_SCHEMA }).then((r) => ({ kind: 'codex', card: null, r })))
|
|
308
315
|
}
|
|
309
316
|
if (maxQaTier === 'full') {
|
|
310
317
|
findThunks.push(() => agent(qaPrompt, { label: 'qa-sentinel', phase: 'Discovery', agentType: 'qa-sentinel', schema: GATES_SCHEMA }).then((r) => ({ kind: 'qa', card: null, r })))
|