baldart 5.4.0 → 5.4.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 +25 -0
- package/VERSION +1 -1
- package/framework/.claude/skills/new/CHANGELOG.md +11 -0
- package/framework/.claude/skills/new/SKILL.md +1 -1
- package/framework/.claude/skills/new/references/final-review.md +13 -0
- package/framework/.claude/skills/new/references/implement.md +1 -1
- package/framework/.claude/skills/new/references/production-readiness.md +6 -0
- package/framework/.claude/skills/new/references/review-cycle.md +1 -1
- package/framework/.claude/skills/new2/CHANGELOG.md +8 -0
- package/framework/.claude/skills/new2/SKILL.md +1 -1
- package/framework/.claude/workflows/new2.js +31 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ 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
|
+
## [5.4.1] - 2026-07-03
|
|
9
|
+
|
|
10
|
+
**Minimal light lane — the roster for a simple card is now literally: grounding (inline),
|
|
11
|
+
coder, code review, doc review, commit, merge. Nothing else.** Completes v5.4.0 per the
|
|
12
|
+
maintainer's directive ("per cose così semplici voglio due passaggi in croce"): the compact
|
|
13
|
+
lane cut the CARD COUNT; this cuts the per-run AGENT COUNT. FEAT-0067-class run: ~33
|
|
14
|
+
agents → ~7.
|
|
15
|
+
|
|
16
|
+
- **Per-card doc review at light (single-card batch)**: the light review matrix adds the
|
|
17
|
+
scoped `doc-reviewer` per-card (review-cycle.md deferral-gate exception) because the
|
|
18
|
+
Final pass it used to defer to is now skippable.
|
|
19
|
+
- **Final Review skip gate (`final-review.md` § F.0 + `new2.js` `skipFinalLight`)**: ONE
|
|
20
|
+
light card + zero actionable per-card findings (→ zero fixes applied) → skip F.2–F.5
|
|
21
|
+
entirely. Honors the v4.56.1 refutation (per-card PRE-fix + final POST-fix are
|
|
22
|
+
non-redundant) by scoping the skip to runs where there IS no post-fix state; any
|
|
23
|
+
finding, fix, second card, or degraded reviewer → Final runs as always.
|
|
24
|
+
- **i18n fill spawn cut at light**: the owner briefing instructs the coder to fill every
|
|
25
|
+
target locale itself; the anti-hardcoded lint + locale-parity gates still enforce.
|
|
26
|
+
- **Production-readiness spawn cut for all-light batches**: no deployable surface exists
|
|
27
|
+
by Rule C (no migrations/indexes/cron/schema) — the agent only ever reported zero items.
|
|
28
|
+
- `check-new-parity.mjs` rule 18 locks the prose↔workflow lockstep for every cut.
|
|
29
|
+
- Skills: `new` 2.2.0 · `new2` 1.6.0.
|
|
30
|
+
|
|
31
|
+
Codex parity: portable (prose modules are the cross-tool SSOT; `new2.js` Claude-only by design).
|
|
32
|
+
|
|
8
33
|
## [5.4.0] - 2026-07-03
|
|
9
34
|
|
|
10
35
|
**Elastic pipeline — `/prd`+`/new` compress to the minimum for trivial features and
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.4.
|
|
1
|
+
5.4.1
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 2.2.0 — 2026-07-03 (framework v5.4.1)
|
|
6
|
+
|
|
7
|
+
- **Minimal light lane — roster cut to the core four.** A single light card now runs:
|
|
8
|
+
grounding-inline (step 2d) → owner → code review (Codex-light/code-reviewer) → scoped
|
|
9
|
+
doc-reviewer per-card (review-cycle deferral exception) → commit → merge. Cut for the
|
|
10
|
+
lane: i18n fill spawn (7c — owner fills locales inline, lint gate enforces), Final
|
|
11
|
+
Review when the per-card review is clean (final-review.md § F.0 Minimal-light skip
|
|
12
|
+
gate — POST-fix verification with zero fixes is vacuous; any finding/fix/second card →
|
|
13
|
+
Final runs), production-readiness spawn for all-light batches (no deployable surface
|
|
14
|
+
by Rule C). Guarded by check-new-parity rule 18.
|
|
15
|
+
|
|
5
16
|
## 2.1.0 — 2026-07-03 (framework v5.4.0)
|
|
6
17
|
|
|
7
18
|
- **Light-lane inline grounding (implement.md step 2d).** A `review_profile: light` card
|
|
@@ -42,6 +42,19 @@ Once ALL cards are committed in the worktree:
|
|
|
42
42
|
> A single card has no cross-card surface, so a finder's per-card pass and its final pass are genuinely
|
|
43
43
|
> the same review.
|
|
44
44
|
|
|
45
|
+
### Step F.0 — Minimal-light skip gate (v5.4.1)
|
|
46
|
+
|
|
47
|
+
When the batch has exactly ONE committed card AND it is `review_profile: light` AND its
|
|
48
|
+
per-card review surfaced ZERO actionable findings (no blocks, no scope-expansion → no fix
|
|
49
|
+
pass was applied), **SKIP the entire Final Review** (F.2–F.5) and proceed to merge. The
|
|
50
|
+
Final pass exists for POST-fix verification and cross-card surface (v4.56.1 — per-card
|
|
51
|
+
PRE-fix + final POST-fix are non-redundant); with zero fixes and zero cross-card surface,
|
|
52
|
+
both reasons are absent — and doc coverage already ran per-card (the single-card light
|
|
53
|
+
review matrix includes the scoped doc-reviewer instead of deferring here, see
|
|
54
|
+
review-cycle.md § Deferral gate). Any finding on the card, any fix applied, any second
|
|
55
|
+
card, or any degraded reviewer → run the Final Review as written below. Log
|
|
56
|
+
`final-review: SKIPPED (single light card, clean per-card review — nothing post-fix to verify)`.
|
|
57
|
+
|
|
45
58
|
### Step F.1 — Resolve scope
|
|
46
59
|
|
|
47
60
|
(All cards are committed; the batch now enters Final Review. No visibility emission — the internal tracker is the only state surface, see SKILL.md § "State surface — the tracker only". Record the Final-Review start/finish in the tracker only.)
|
|
@@ -500,7 +500,7 @@
|
|
|
500
500
|
- **Grounding (cheap `grep`, like the Phase-1 plan-auditor grounding):** every cited source symbol/class MUST appear in `mockups/_src/` (`grep -rF "<symbol>" <prd_dir>/<slug>/mockups/_src/`), and every cited registry primitive MUST exist in the registry (`grep` `${paths.design_system}/INDEX.md` / `components/`). A symbol that is not in the source, or a primitive that is not in the registry, means a fabricated declaration → reject + re-spawn (do NOT pass it to the gates). Log `design-source: grounded` or `design-source: rejected (<reason>)` in the tracker.
|
|
501
501
|
- This does NOT re-verify pixels — that stays with `visual-fidelity-verifier` (Phase 2.6). It only proves the source was read and the reuse-mapping targets are real. When the card has no design source, skip this step entirely.
|
|
502
502
|
|
|
503
|
-
7c. **i18n fill pass (explicit, deterministic — v5.0.0, promoted from the step-9 sub-bullet).**
|
|
503
|
+
7c. **i18n fill pass (explicit, deterministic — v5.0.0, promoted from the step-9 sub-bullet).** **Light lane (v5.4.1): SKIP this spawn** — on the light lane (step 2d) the owner briefing already instructed the coder to fill EVERY target locale itself (context-aware from the registry); the anti-hardcoded lint + locale-parity gates at step 8 enforce it. Log `i18n-fill: SKIP (light lane — owner fills inline)`. Otherwise: when `features.has_i18n: true` AND this card's diff added new source-locale keys — detect deterministically, never by intuition:
|
|
504
504
|
```bash
|
|
505
505
|
cd <worktree-path>
|
|
506
506
|
# $SRC_LOCALE = the source-language locale file path (from i18n config / the project's locales root)
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
After Phase 6 completes (or after the final summary report if Phase 6 is deferred), present a **Production Readiness Checklist** — a clear list of all manual or infrastructure actions required to launch the implemented changes in production.
|
|
8
8
|
|
|
9
|
+
> **Minimal light lane (v5.4.1): SKIP the spawn for an all-`light` batch** — a light card
|
|
10
|
+
> carries no deployable surface by Rule C (no migrations, indexes, cron, schema, env); the
|
|
11
|
+
> checklist agent would only report zero items. Log
|
|
12
|
+
> `phase7-production: SKIPPED (all-light batch — no deployable surface)`. Any
|
|
13
|
+
> `balanced`/`deep` card in the batch → run as written.
|
|
14
|
+
|
|
9
15
|
### How to detect items
|
|
10
16
|
|
|
11
17
|
Scan ALL files changed across the batch (use the tracker's completed cards + `git diff` against the base branch) and check for the items below.
|
|
@@ -305,7 +305,7 @@ skill's Phase 1 falls back to deriving Gherkin scenarios from
|
|
|
305
305
|
|
|
306
306
|
> **Note**: Code review is NOT performed in this phase — it is handled by the **mandatory unconditional `/codexreview` gate in Phase 3.7**, which runs per-card BEFORE the Phase 4 commit. The post-batch `/codexreview` in the Final review remains as a final FULL-diff sweep over the entire batch (since v3.37.0 — the guaranteed full-depth merge gate). This Phase 3 focuses exclusively on documentation sync, which must happen per-card (tied to the specific commit).
|
|
307
307
|
|
|
308
|
-
> **Deferral gate (since v4.7.0 — enumerated, `review_profile`-driven)**: SKIP per-card doc-review and defer it to the **Final Review F.3 doc-reviewer** (which runs over the entire batch) when the card is **`review_profile == light` AND its committed diff touches NO documentation file** (no `.md`, no path under `${paths.references_dir}`, no data-model/ssot/api doc). These are small code changes with no doc surface of their own; their only doc concern is drift, which the batch-wide Final doc-reviewer catches. Log `doc-review: DEFERRED to Final FULL gate (light, no doc files in diff)` and proceed to Phase 3.5. **KEEP per-card doc-review** for: `deep` cards, `balanced` cards (they may still PASS-fast via the deterministic gate below — that gate, not this deferral, is their only skip lane), ANY card whose diff touches a doc file (the change IS doc-relevant), and trivial cards (doc-review is their primary gate — § "Trivial-card fast-lane", unchanged). Never defer "for time" — the only enumerated reasons are `light + non-doc diff` and the deterministic PASS-fast below.
|
|
308
|
+
> **Deferral gate (since v4.7.0 — enumerated, `review_profile`-driven)**: SKIP per-card doc-review and defer it to the **Final Review F.3 doc-reviewer** (which runs over the entire batch) when the card is **`review_profile == light` AND its committed diff touches NO documentation file** (no `.md`, no path under `${paths.references_dir}`, no data-model/ssot/api doc). These are small code changes with no doc surface of their own; their only doc concern is drift, which the batch-wide Final doc-reviewer catches. Log `doc-review: DEFERRED to Final FULL gate (light, no doc files in diff)` and proceed to Phase 3.5. **KEEP per-card doc-review** for: `deep` cards, `balanced` cards (they may still PASS-fast via the deterministic gate below — that gate, not this deferral, is their only skip lane), ANY card whose diff touches a doc file (the change IS doc-relevant), and trivial cards (doc-review is their primary gate — § "Trivial-card fast-lane", unchanged). Never defer "for time" — the only enumerated reasons are `light + non-doc diff` and the deterministic PASS-fast below. **Single-card light batch exception (v5.4.1 minimal light lane): do NOT defer** — when the batch has exactly ONE card and it is `light`, the Final Review is itself SKIPPED if the per-card review is clean (see final-review.md § Minimal-light skip gate), so the deferral target would never run: run the scoped per-card doc-reviewer here instead.
|
|
309
309
|
>
|
|
310
310
|
> **Deterministic PASS-fast (v5.0.0 — measured: 84/127 per-card doc reviews returned PASS)**: when implement.md step 11c produced `/tmp/docinv-<CARD-ID>.json` AND it says `pass_fast_eligible: true` (zero non-advisory invariant rows triggered + no doc file in the diff + the card declares no `documentation_impact`/`canonical_docs`) AND the card is NOT `deep` → log `doc-review: PASS-fast (doc-invariants: 0 blocking rows) — Final doc-reviewer backstop stands` and **skip the per-card spawn** (proceed to Phase 3.5). No gate is removed: the batch-Final F.3 doc-reviewer still sees this card's diff. Own-Doc Closure: NEW-file obligations are definitionally empty (no invariant row fired, no docs declared); obligations on MODIFIED primitives/routes are covered by the automatic spec resync (`DS_COMPONENT_STALE` serializer gate, v4.70.0) plus the Final F.3 backstop — the invariant table's R1/R3 fire on new files only, by design. `deep` cards always spawn. Missing docinv JSON → no PASS-fast (fall through to the normal path).
|
|
311
311
|
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## (workflow new2.js, framework v5.4.1) — 2026-07-03
|
|
6
|
+
|
|
7
|
+
- Minimal light lane mirror: single-card light adds per-card doc-reviewer to the review
|
|
8
|
+
matrix, skips the i18n fill spawn (owner briefing carries the fill instruction),
|
|
9
|
+
skips new-final-review when `lightLane && cleanReview` (zero actionable findings),
|
|
10
|
+
skips production-readiness for all-light batches. Result objects carry
|
|
11
|
+
`lightLane`/`cleanReview` for the Final gate.
|
|
12
|
+
|
|
5
13
|
## (workflow new2.js, framework v5.4.0) — 2026-07-03
|
|
6
14
|
|
|
7
15
|
- Light lane: `review_profile: light|skip` cards no longer spawn the Phase-1 retriever —
|
|
@@ -617,7 +617,7 @@ async function runCard(cardId, cardPath) {
|
|
|
617
617
|
const phase1Brief = architectOk
|
|
618
618
|
? `Phase 1 already ran as specialist agents. READ the architecture baseline at ${baselinePath} BEFORE writing any code — it is your codebase context; do NOT redo the exploration.${auditCorrections.length ? `\nPlan-audit corrections (apply them as amendments to this briefing — do NOT modify the backlog YAML):\n${auditCorrections.map((c, i) => ` ${i + 1}. ${c}`).join('\n')}` : ''}`
|
|
619
619
|
: phase1.architect === 'inline-light'
|
|
620
|
-
? `Phase 1 light lane (v5.4.0): this card is review_profile '${reviewProfile}' (≤3-file scale) — no dedicated retriever ran. Ground INLINE per AGENTS.md § Change Tiers (orchestrated-pipeline exception): BEFORE writing code, read the files in scope + their immediate integration points (imports/consumers). Scoped exploration of the touched area only — not a repo sweep; the understanding obligation is unchanged, only the delegation was waived
|
|
620
|
+
? `Phase 1 light lane (v5.4.0): this card is review_profile '${reviewProfile}' (≤3-file scale) — no dedicated retriever ran. Ground INLINE per AGENTS.md § Change Tiers (orchestrated-pipeline exception): BEFORE writing code, read the files in scope + their immediate integration points (imports/consumers). Scoped exploration of the touched area only — not a repo sweep; the understanding obligation is unchanged, only the delegation was waived.${features.has_i18n ? ' I18N (light lane): NO separate fill pass runs for this card — fill EVERY target locale yourself for any new key (context-aware from the registry); the anti-hardcoded lint gate must pass.' : ''}`
|
|
621
621
|
: `Phase 1 fallback: the architect specialist was unavailable — do the Phase 1 claim+architect exploration yourself per ${REF}/implement.md and persist the baseline to ${baselinePath} before coding.`
|
|
622
622
|
// T1.A (v4.90.0) — mockup cards: binding-compliance is verified deterministically by the
|
|
623
623
|
// check-bindings.mjs script (ui-implement Step 5b is the SSOT; this is the new2 parallel).
|
|
@@ -670,7 +670,10 @@ async function runCard(cardId, cardPath) {
|
|
|
670
670
|
// v5.0.0 — explicit i18n fill pass (implement.md step 7c mirror; closes the measured leakage
|
|
671
671
|
// where locale fills were spawned as general-purpose). The translator is named BY TYPE; it
|
|
672
672
|
// self-detects new source-locale keys from the diff and no-ops cheaply when there are none.
|
|
673
|
-
|
|
673
|
+
// v5.4.1 minimal light lane — no separate fill pass: the owner filled every locale itself
|
|
674
|
+
// (its briefing carries the instruction) and the Phase-2 anti-hardcoded lint gate enforces it.
|
|
675
|
+
if (features.has_i18n && lightLane) g('i18n-fill', 'SKIP', 'light lane — owner fills locales inline; lint gate enforces')
|
|
676
|
+
else if (features.has_i18n) {
|
|
674
677
|
try {
|
|
675
678
|
const fill = await agentSafe(
|
|
676
679
|
`You are i18n-translator (fill pass for card ${cardId} — agents/i18n-protocol.md per-card cascade). cd into the card worktree. FIRST detect deterministically whether this card's diff (/tmp/diff-${cardId}.txt) added NEW source-locale keys; if none → return { ran:false, keys:0 } immediately (no-op). If keys exist: fill the missing TARGET locales for exactly those keys, context-aware from the registry at ${paths.i18n_registry || 'the i18n registry'} — the source locale stays untouched (the coder is source-only by design). Then re-run the project's locale-parity check if one exists. Return: { ran, keys, note }`,
|
|
@@ -834,7 +837,14 @@ async function runCard(cardId, cardPath) {
|
|
|
834
837
|
}
|
|
835
838
|
let reviewers
|
|
836
839
|
if (reviewProfile === 'skip') reviewers = []
|
|
837
|
-
else if (reviewProfile === 'light')
|
|
840
|
+
else if (reviewProfile === 'light') {
|
|
841
|
+
reviewers = codexAvail ? ['codex'] : ['code-reviewer']
|
|
842
|
+
// v5.4.1 minimal light lane — a single-card light batch skips the Final workflow when its
|
|
843
|
+
// per-card review is clean (nothing post-fix to verify), so doc coverage cannot defer
|
|
844
|
+
// there: run the scoped doc-reviewer per-card instead. Multi-card light keeps the
|
|
845
|
+
// deferral (the Final batch pass still runs and covers it).
|
|
846
|
+
if (cardIds.length === 1) reviewers.push('doc-reviewer')
|
|
847
|
+
}
|
|
838
848
|
else if (noEvidence) reviewers = FULL_FANOUT // balanced/deep, no surface evidence → conservative full
|
|
839
849
|
else reviewers = relevanceGated() // balanced AND deep — surface-gated breadth
|
|
840
850
|
if (reviewProfile !== 'skip') g('review-matrix', 'PLANNED', `[${reviewProfile}${noEvidence ? '→conservative-full (no surface evidence)' : ''}] ${reviewers.join('+') || '(none)'} · docs:${touchesDocs} code:${touchesCode} api/data:${touchesApiData} sec:${securityRelevant}`)
|
|
@@ -974,8 +984,13 @@ async function runCard(cardId, cardPath) {
|
|
|
974
984
|
// B6 — which reviewers ACTUALLY ran (the gated matrix); Phase Final keys its slim/skip
|
|
975
985
|
// decision on this, and per_card telemetry records it for the A/B spawn accounting.
|
|
976
986
|
reviewersRun: reviewers,
|
|
977
|
-
// B7 — Phase-1 specialist record (architect: done|inline-fallback; audit: pass|fixes|skipped-*).
|
|
987
|
+
// B7 — Phase-1 specialist record (architect: done|inline-fallback|inline-light; audit: pass|fixes|skipped-*).
|
|
978
988
|
phase1,
|
|
989
|
+
// v5.4.1 minimal light lane — Phase Final keys its skip on these: a single light card whose
|
|
990
|
+
// per-card review surfaced NOTHING actionable has no post-fix state for the Final pass to
|
|
991
|
+
// verify (the Final review's purpose — v4.56.1 — is POST-fix verification, not re-review).
|
|
992
|
+
lightLane,
|
|
993
|
+
cleanReview: blocks.length === 0 && scopeExp.length === 0,
|
|
979
994
|
scopeFiles, archBaselinePath: `/tmp/arch-baseline-${cardId}.md`, gates,
|
|
980
995
|
}
|
|
981
996
|
}
|
|
@@ -1151,7 +1166,13 @@ const committed = perCardResults.filter((r) => r.status === 'committed')
|
|
|
1151
1166
|
phase('Final')
|
|
1152
1167
|
let finalSummary = null
|
|
1153
1168
|
let mergeBlocked = degraded
|
|
1154
|
-
|
|
1169
|
+
// v5.4.1 minimal light lane — ONE light card, clean per-card review (zero actionable
|
|
1170
|
+
// findings → zero fixes applied): the Final pass has nothing post-fix to verify and its
|
|
1171
|
+
// doc coverage already ran per-card (the light single-card matrix includes doc-reviewer).
|
|
1172
|
+
// Any finding/fix on the card, any second card, or any degradation → Final runs as always.
|
|
1173
|
+
const skipFinalLight = committed.length === 1 && committed[0].lightLane && committed[0].cleanReview && !degraded
|
|
1174
|
+
if (skipFinalLight) ledger(firstCard, 'final-review', 'SKIPPED', 'single light card, clean per-card review — nothing post-fix to verify (doc ran per-card)')
|
|
1175
|
+
if (committed.length && !degraded && !skipFinalLight) {
|
|
1155
1176
|
const reviewScopeFiles = dedupe(committed.flatMap((r) => r.scopeFiles || []))
|
|
1156
1177
|
const archPaths = committed.map((r) => r.archBaselinePath).filter(Boolean)
|
|
1157
1178
|
const allArch = archPaths.length === committed.length ? archPaths : null
|
|
@@ -1295,7 +1316,11 @@ if (!committed.length) {
|
|
|
1295
1316
|
// Phase Production (Phase 7) — non-blocking; report-not-execute (F-011 infra-deferred).
|
|
1296
1317
|
// ───────────────────────────────────────────────────────────────────────────
|
|
1297
1318
|
phase('Production')
|
|
1298
|
-
if (mergeResult && mergeResult.merged) {
|
|
1319
|
+
if (mergeResult && mergeResult.merged && committed.length && committed.every((r) => r.lightLane)) {
|
|
1320
|
+
// v5.4.1 minimal light lane — light cards carry no deployable surface by Rule C (no
|
|
1321
|
+
// migrations/indexes/cron/schema); the checklist would only burn a spawn to report zero items.
|
|
1322
|
+
ledger(firstCard, 'phase7-production', 'SKIPPED', 'all-light batch — no deployable surface (Rule C)')
|
|
1323
|
+
} else if (mergeResult && mergeResult.merged) {
|
|
1299
1324
|
try {
|
|
1300
1325
|
// Schema-deploy-from-trunk-only invariant (v4.33.0): a remote schema/RLS/index/
|
|
1301
1326
|
// migration deploy desyncs a shared remote datastore when run off-trunk. When the
|