baldart 5.4.1 → 5.6.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 +86 -0
- package/VERSION +1 -1
- package/framework/.claude/agents/CHANGELOG.md +16 -0
- package/framework/.claude/agents/prd-card-writer.md +37 -3
- package/framework/.claude/skills/new/CHANGELOG.md +33 -0
- package/framework/.claude/skills/new/SKILL.md +11 -5
- package/framework/.claude/skills/new/references/commit.md +12 -8
- package/framework/.claude/skills/new/references/completeness.md +10 -0
- package/framework/.claude/skills/new/references/final-review.md +23 -0
- package/framework/.claude/skills/new/references/implement.md +14 -4
- package/framework/.claude/skills/new/references/merge-cleanup.md +35 -14
- package/framework/.claude/skills/new/references/setup.md +1 -1
- package/framework/.claude/skills/new2/CHANGELOG.md +50 -0
- package/framework/.claude/skills/new2/SKILL.md +101 -17
- package/framework/.claude/skills/prd/CHANGELOG.md +36 -0
- package/framework/.claude/skills/prd/SKILL.md +17 -5
- package/framework/.claude/skills/prd/assets/state-template.md +8 -1
- package/framework/.claude/skills/prd/references/audit-phase.md +13 -1
- package/framework/.claude/skills/prd/references/backlog-phase.md +20 -0
- package/framework/.claude/skills/prd/references/discovery-phase.md +35 -0
- package/framework/.claude/skills/prd/references/ui-design-phase.md +28 -0
- package/framework/.claude/skills/prd/references/validation-phase.md +45 -1
- package/framework/.claude/skills/worktree-manager/CHANGELOG.md +13 -0
- package/framework/.claude/skills/worktree-manager/SKILL.md +11 -1
- package/framework/.claude/skills/worktree-manager/scripts/merge-worktree.sh +82 -6
- package/framework/.claude/workflows/new-final-review.js +9 -7
- package/framework/.claude/workflows/new2-resolve.js +29 -1
- package/framework/.claude/workflows/new2.js +153 -17
- package/framework/agents/card-schema.md +18 -1
- package/framework/agents/research-protocol.md +6 -1
- package/framework/scripts/stamp-holistic-audit.js +53 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,92 @@ 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.6.0] - 2026-07-04
|
|
9
|
+
|
|
10
|
+
**Outcome-integrity wave (FEAT-0068 post-mortem — mayo, 72.78M token, DONE falso).** Il
|
|
11
|
+
batch chiuse 6/6 card + epic come "✅ DONE, merged" mentre il goal dell'epic era invisibile
|
|
12
|
+
sul ~90% delle schermate: il root cause era in `/prd` (inventario ISA sui consumer del
|
|
13
|
+
meccanismo invece che sui proprietari della superficie; recipe ancorata su un componente
|
|
14
|
+
`@deprecated`; due gate phantom-stampati), attraversava card che nessun gate poteva salvare
|
|
15
|
+
(coverage passata vacuamente su un inventario sbagliato), e veniva sigillato da `/new`/`new2`
|
|
16
|
+
(chiusura epic al commit dell'ultima card — PRIMA della final review — con predicato
|
|
17
|
+
conta-figli, nessun verdetto PARTIAL, safety-commit che spazzava file non gated su develop,
|
|
18
|
+
commit agent in detour sul main checkout). 28 finding crit/high confermati adversarialmente;
|
|
19
|
+
ogni fix è ancorato a un'evidenza del run.
|
|
20
|
+
|
|
21
|
+
- **Chiusura epic v2 (`/new` 2.3.0 + `new2` 1.8.0)**: SOLO in merge phase (il gate
|
|
22
|
+
commit-time v4.99.0 è ritirato — aveva anche un anchor bug `^parent:` che lo rendeva
|
|
23
|
+
no-op); predicato esteso (figli **e follow-up** DONE + nessun residual bloccante +
|
|
24
|
+
**AC epic verificati con oracoli**); blocklist JS + guardia post-merge (F-029 twin) +
|
|
25
|
+
ramo **REOPEN** (il ratchet è bidirezionale); classe finding **closure-invalidating**
|
|
26
|
+
(un "goal not achieved" è un difetto di STATO — il fix di prosa non chiude).
|
|
27
|
+
- **Verdetto PARTIAL calcolato** (`final-review.md` + `buildReport`): residual HIGH+ /
|
|
28
|
+
epic aperta / AC epic `[ ]` ⇒ headline `⚠️ PARTIAL` col gap nominato; sezione
|
|
29
|
+
`## Epic goal`; severity sui residui; "nulla perso" mai come surrogato di "non finito".
|
|
30
|
+
- **Igiene git orchestrata**: `merge-worktree.sh --safety-sweep allowlist:` (worktree-manager
|
|
31
|
+
1.2.0 — il codice non gated va in quarantena etichettata, mai nel trunk sotto un
|
|
32
|
+
"[safety]" opaco); isolamento worktree del commit agent esteso ai TOOL con evidenza
|
|
33
|
+
porcelain + guardia JS (era 7.1M di detour + stash dangling); divieto stash + audit
|
|
34
|
+
post-run dei commit non-card e degli stash del batch (mai "non miei da droppare").
|
|
35
|
+
- **Review**: relay Codex della final review in foreground `--wait` (il polling veniva
|
|
36
|
+
ucciso dall'enforcement structured-output a 83s/600s → fallback freddo da 3.68M);
|
|
37
|
+
esito **refuted** ratificato in `new2-resolve` (premessa falsa = zero edit) + divieto
|
|
38
|
+
di fix che disattivano verifiche mandate da AC (`verification-posture-change`);
|
|
39
|
+
suite aggiunte dalla card ESEGUITE targeted pre-commit (`completeness.md` 1b).
|
|
40
|
+
- **Routing**: `hasMockup` semantico (la card COSTRUISCE la UI mockata — un bare
|
|
41
|
+
`links.design` su card docs va all'owner router; era 6.55M di ui-expert su una card
|
|
42
|
+
docs+ADR).
|
|
43
|
+
- **`/prd` 1.6.0 (il root cause)**: categoria ISA **UI ROLE FAMILY (registry-first)**
|
|
44
|
+
(owner della superficie dal registry + flag BLOCK su `@deprecated`); §0 LOAD CONTRACT
|
|
45
|
+
su `discovery-phase.md` (vista PARTIAL ⇒ offset-Read fino in fondo — la coda persa
|
|
46
|
+
conteneva il Codex completeness cross-check mai eseguito); `module_read` stamps
|
|
47
|
+
ESEGUITI + item 0-ii Phase-evidence audit (2 gate phantom-stampati sul run reale);
|
|
48
|
+
`step_3_mode` enum chiuso + contratto `skipped` (mai design hand-authored fuori
|
|
49
|
+
`/ui-design`) + Reconciliation-lite senza mockup + trigger di ri-enumerazione ISA;
|
|
50
|
+
gate quantificatore-universale sugli AC epic (`invariant_owners:`); stamp holistic
|
|
51
|
+
**evidence-gated** (`stamp-holistic-audit.js --audit-report` → `agents_run`; senza
|
|
52
|
+
artefatto → `status: skipped` = ASSENTE per `/new`); card-writer 1.2.0
|
|
53
|
+
(self-validation eseguita, epic `ac_verification` obbligatoria, mai count hardcodato,
|
|
54
|
+
`links.design` solo su card UI, invariante baseline snapshot); HARD RULE mw-docs
|
|
55
|
+
(+ guardia `/mw` su `kind: docs`); EDIT CONTRACT dello state file (5 retry ciechi
|
|
56
|
+
da ~250k); `research-protocol.md` pre-flight libreria in difesa.
|
|
57
|
+
- **Tooling maintainer**: `new-session-audit.mjs` guadagna **EPIC_AC_UNMET** (FAIL —
|
|
58
|
+
retro-validato: il run FEAT-0068 ora fallisce l'audit invece di passarlo) e
|
|
59
|
+
**GATE_DISABLED_BY_FIX** (WARN) + fix del digest-writer su id workflow con `/`;
|
|
60
|
+
`check-new-parity.mjs` esteso a 21 policy (chiusura epic, PARTIAL, mockup semantico —
|
|
61
|
+
con token FORBIDDEN sui meccanismi ritirati).
|
|
62
|
+
- Deliberatamente rinviati (MED/LOW non verificati dal pass avversariale): digest
|
|
63
|
+
per-batch dei moduli di riferimento (tassa cache ~3-5M), card shape
|
|
64
|
+
VERIFY-ONLY/MECHANICAL-MIGRATION, sampling visivo del goal epic in final review,
|
|
65
|
+
script `update-state.mjs` per `/prd` (mitigato dall'EDIT CONTRACT).
|
|
66
|
+
- Codex parity: **portable** — le policy vivono nei moduli prose SSOT (`/new`, `/prd`)
|
|
67
|
+
e in script zero-dep/shell; i workflow Claude-only (`new2*`, `new-final-review`)
|
|
68
|
+
hanno ricevuto le STESSE policy dei twin prose (guardia di parity estesa a 21 regole).
|
|
69
|
+
Nessuna nuova chiave `baldart.config.yml` → la schema-change propagation rule non si
|
|
70
|
+
applica.
|
|
71
|
+
|
|
72
|
+
## [5.5.0] - 2026-07-03
|
|
73
|
+
|
|
74
|
+
**Migration deploy chain hardened (FEAT-0067 post-mortem — mayo).** The batch's DB
|
|
75
|
+
migration was fully declared in the cards (`db_migration` + `db_migrations_summary`,
|
|
76
|
+
per the consumer's prd-card-writer overlay) but the remote `db:push` was never
|
|
77
|
+
executed nor surfaced: new2's Migration Gate probed ONLY `migration_plan` (structural
|
|
78
|
+
vocabulary mismatch → silent no-op) and the end-of-batch `db-migration-deploy`
|
|
79
|
+
residual was lost by the mid-run DONE-flip, closing the epic against an unmet DoD.
|
|
80
|
+
|
|
81
|
+
- **Vocabulary aliases** (`/new` 2.2.1, `new2` 1.7.0): the `-auto` delegation gate,
|
|
82
|
+
`/new` Phase 0 1b and new2 Step 3.5 now detect a declared migration under
|
|
83
|
+
`migration_plan.required` (epic) OR `db_migrations_summary` (epic) OR
|
|
84
|
+
`db_migration.required: true` (per-card overlay convention).
|
|
85
|
+
- **new2 Step 5.1b Migration Sync Tail (NEW)**: after the autonomous workflow returns
|
|
86
|
+
(post-merge, on trunk), the SKILL runs the project's post-merge sync check
|
|
87
|
+
(overlay "branch B"); on red it asks Push now / Defer / Override interactively —
|
|
88
|
+
never pushes autonomously. Triggered by the Step-3.5 DECLARATION, not only by the
|
|
89
|
+
residual ledger (belt-and-braces vs a dropped residual). Telemetry
|
|
90
|
+
`migration_sync_tail`.
|
|
91
|
+
- Codex parity: portable (prose-only skill/reference edits; `new2` is Claude-only by
|
|
92
|
+
design — `/new` classic remains the Codex path and gains the same alias probe).
|
|
93
|
+
|
|
8
94
|
## [5.4.1] - 2026-07-03
|
|
9
95
|
|
|
10
96
|
**Minimal light lane — the roster for a simple card is now literally: grounding (inline),
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.
|
|
1
|
+
5.6.0
|
|
@@ -7,6 +7,22 @@ per-item agent merge, the doctor probes, and the discovery hooks — like
|
|
|
7
7
|
|
|
8
8
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · per-agent SemVer.
|
|
9
9
|
|
|
10
|
+
## [prd-card-writer v1.2.0] — 2026-07-04 (framework v5.6.0 — FEAT-0068 post-mortem)
|
|
11
|
+
|
|
12
|
+
- **Epic AC rules**: mai count di figli hardcodato ("le 6 sub-card"); AC con
|
|
13
|
+
quantificatore universale su una superficie ⇒ `invariant_owners:` dal census
|
|
14
|
+
registry/ISA; `ac_verification` OBBLIGATORIA sull'epic (≥1 oracolo per goal AC —
|
|
15
|
+
consumata dal gate di chiusura epic).
|
|
16
|
+
- **`links.design` FORBIDDEN su card che non costruiscono UI mockata** (docs/test/
|
|
17
|
+
meta-only ⇒ owner coder, riferimenti di contesto in `canonical_docs.additional_refs`)
|
|
18
|
+
— un pointer vagante clampava la build a ui-expert (6.55M su una card docs).
|
|
19
|
+
- **Invariante snapshot-suite**: una card che CREA una suite visual-regression dichiara
|
|
20
|
+
il lifecycle delle baseline (generate+committate in-card, o assertion-based) — pena
|
|
21
|
+
BLOCKER di authoring.
|
|
22
|
+
- **Self-validation**: il writer ESEGUE `validate-card-baseline.js --prd` sul proprio
|
|
23
|
+
output e ritorna solo su exit 0 (token EARS sempre inglesi verbatim) — mai asserire
|
|
24
|
+
"YAML-valid" senza aver eseguito il validator.
|
|
25
|
+
|
|
10
26
|
## [prd-card-writer v1.1.0] — 2026-07-03 (framework v5.4.0)
|
|
11
27
|
|
|
12
28
|
- **Proportionality lower-bound** in Card Atomicity Rules: a Tier-Gate TRIVIAL/LIGHT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prd-card-writer
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.2.0
|
|
4
4
|
description: "Generates atomic backlog cards from an approved PRD. Handles card YAML writing, dependency graph computation, parallel group assignment, and traceability matrices (FR/NFR, ISA, UI). Invoked by the /prd skill at Step 5 to offload the heaviest mechanical phase from the main context. Also runs in Standalone Single-Card Mode to author ONE baseline-conformant follow-up/CHORE/BUG/issue card (no epic+children) — invoked by /new (AC-deferral), new2/new2-resolve, and /issue-review. The canonical card writer: every card-creation path delegates here rather than hand-writing a partial stub."
|
|
5
5
|
model: opus
|
|
6
6
|
effort: high
|
|
@@ -335,7 +335,18 @@ applies even when N=1.
|
|
|
335
335
|
- `business_rationale` (extended — full strategic context)
|
|
336
336
|
- `scope.summary` + `scope_boundaries` (in_scope summary + out_of_scope deferrals)
|
|
337
337
|
- `acceptance_criteria` as `[ ] [AC-EPIC-N]` items rolling up the PRD ACs (NOT
|
|
338
|
-
duplicating child ACs — track end-to-end outcomes only)
|
|
338
|
+
duplicating child ACs — track end-to-end outcomes only). **v5.6.0 (FEAT-0068)
|
|
339
|
+
epic-AC rules:** (1) NEVER hardcode a child count ("all 6 sub-cards DONE" broke the
|
|
340
|
+
moment follow-ups appeared — write "all child cards **including any added later**");
|
|
341
|
+
(2) an AC with a universal quantifier over a surface ("every screen", "tutte le
|
|
342
|
+
route") MUST list its surface owners in `invariant_owners:` (from the ISA UI ROLE
|
|
343
|
+
FAMILY census) so the closure gate can re-verify them.
|
|
344
|
+
- `ac_verification` — **REQUIRED on the epic (v5.6.0)**: ≥1 executable oracle per
|
|
345
|
+
top-level goal AC (same grounding rule as child cards — only verified commands/greps;
|
|
346
|
+
else `manual:`). The `/new`/`new2` epic-closure gate RUNS these before flipping the
|
|
347
|
+
epic DONE — an epic with no oracle can only close via manual evidence, which is
|
|
348
|
+
slower. (FEAT-0068's goal was greppable at authoring time: "every top-edge family
|
|
349
|
+
member consumes `--safe-area-inset-top`".)
|
|
339
350
|
- `definition_of_done`: epic-level (e.g. "all sub-card DONE", "PRD test scenarios
|
|
340
351
|
executed", "ssot-registry entry added")
|
|
341
352
|
- `execution_strategy` block with `recommended_mode`, `groups[]` (each with
|
|
@@ -505,6 +516,14 @@ Every card MUST include ALL fields from the template:
|
|
|
505
516
|
`manual: <what a human checks>`. Genuinely undecidable → `[NEEDS CLARIFICATION: …]`.
|
|
506
517
|
Non-manual oracles SHOULD also appear in `validation_commands` (the validator warns on
|
|
507
518
|
drift). Consumed by `/new` Phase 2.5, which EXECUTES them.
|
|
519
|
+
- **Snapshot-suite lifecycle invariant (v5.6.0 — FEAT-0068):** a card whose scope CREATES a
|
|
520
|
+
visual-regression / snapshot / screenshot-diff suite MUST declare the baseline lifecycle in
|
|
521
|
+
its requirements + DoD: EITHER "baselines generated (`--update-snapshots` or equivalent) and
|
|
522
|
+
committed IN THIS CARD" (the generate command listed in `validation_commands`/MAY-EDIT
|
|
523
|
+
covering the baseline dir) OR "assertion-based checks with screenshots advisory-only". A
|
|
524
|
+
suite whose baselines "arrive later" with no declared bootstrap is a card-authoring BLOCKER
|
|
525
|
+
— on the real run it detonated as a merge-blocker and the 4.73M repair "fixed" it by
|
|
526
|
+
flag-gating the epic's only visual verification.
|
|
508
527
|
- `definition_of_done` (checklist including doc invariants). **When `features.has_i18n: true`** AND the
|
|
509
528
|
card introduces user-facing strings, the DoD MUST carry an i18n-completeness line — NOT merely "strings
|
|
510
529
|
via `t()` + registered", but: *"new keys authored in the source locale + the i18n context registry (by
|
|
@@ -519,7 +538,12 @@ Every card MUST include ALL fields from the template:
|
|
|
519
538
|
- `review_profile` (`skip`|`light`|`balanced`|`deep` — computed via Rule C, or honored if pre-set)
|
|
520
539
|
- `files_likely_touched` (exact paths with NEW/MODIFY)
|
|
521
540
|
- `links.prd` (path to PRD)
|
|
522
|
-
- `links.design` (REQUIRED for any card with UI scope
|
|
541
|
+
- `links.design` (REQUIRED for any card with UI scope; **FORBIDDEN on cards that build no
|
|
542
|
+
mocked UI — v5.6.0**: a docs/test/meta-only card, or one whose `files_likely_touched` has
|
|
543
|
+
no component/style path, must NOT carry `links.design` even "for context" — downstream the
|
|
544
|
+
`/new` mockup-first router treats it as a build target and clamps the card to `ui-expert`;
|
|
545
|
+
on FEAT-0068 the epic explainer stamped on a docs+ADR card cost 6.55M. Point context-only
|
|
546
|
+
references in `canonical_docs.additional_refs` instead) — the card's screen design
|
|
523
547
|
reference, resolved to a path **that exists on disk in the worktree**:
|
|
524
548
|
- **design.html when one was generated** for this screen (Step 3 produced it).
|
|
525
549
|
- **ELSE the screen's canonical mockup PNG** under `${paths.prd_dir}/<slug>/mockups/`
|
|
@@ -732,6 +756,16 @@ The consumer (`new/SKILL.md`) reads `execution_strategy.groups[].level` and
|
|
|
732
756
|
|
|
733
757
|
## Output Format
|
|
734
758
|
|
|
759
|
+
**Self-validation BEFORE returning (v5.6.0 — you own your domain's deterministic hygiene).**
|
|
760
|
+
Run `node .framework/framework/scripts/validate-card-baseline.js --prd <your card files>` (or
|
|
761
|
+
the `VALIDATOR` path the caller passed) on your own output and fix every deterministic failure
|
|
762
|
+
(enum values, EARS keyword language — the tokens are ALWAYS English verbatim, only the clause
|
|
763
|
+
body follows `identity.language` —, forbidden patterns, missing required fields) IN THIS
|
|
764
|
+
CONTEXT before returning. Return only on exit 0, and state `validator: exit 0 (N cards)` in
|
|
765
|
+
the summary. NEVER assert "YAML-valid / pattern-clean" without having executed the validator —
|
|
766
|
+
on a real session that unexecuted claim cost a full orchestrator round-trip when Step 6
|
|
767
|
+
bounced all 6 children on Italian EARS tokens. Step 6 still re-runs it as the independent gate.
|
|
768
|
+
|
|
735
769
|
Return to the caller a structured summary:
|
|
736
770
|
|
|
737
771
|
1. **Card list** — IDs and titles of all cards created
|
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 2.3.0 — 2026-07-04 (FEAT-0068 post-mortem: integrità dell'esito)
|
|
6
|
+
|
|
7
|
+
- **Chiusura epic: solo in merge phase, predicato esteso** — `commit.md` c-bis RITIRATO
|
|
8
|
+
(timing: chiudeva PRIMA che la final review potesse smentire il goal; anchor bug:
|
|
9
|
+
`^parent:` non matchava il `parent:` annidato sotto `group:` → gate no-op).
|
|
10
|
+
`merge-cleanup.md` 5e ora richiede: figli **e follow-up** DONE + nessun residual
|
|
11
|
+
bloccante/finding closure-invalidating + **AC epic verificati con evidenza**
|
|
12
|
+
(oracoli `ac_verification`); ramo **REOPEN** per un'epic DONE con scope aperto.
|
|
13
|
+
- **Classe finding "closure-invalidating"** (`final-review.md` F.4): un finding
|
|
14
|
+
"goal/AC epic non raggiunto" è un difetto di STATO — il fix testuale non basta,
|
|
15
|
+
l'epic non chiude (o riapre) nello stesso repair commit.
|
|
16
|
+
- **Verdetto PARTIAL calcolato** (`final-review.md` § Report verdict): residual HIGH+ /
|
|
17
|
+
epic aperta / AC epic `[ ]` ⇒ prima riga `⚠️ PARTIAL` col gap nominato; ✅ riservato.
|
|
18
|
+
- **Routing mockup semantico** (`implement.md` 6a): `HAS_MOCKUP` = la card COSTRUISCE
|
|
19
|
+
la UI mockata (design_src, o design + bindings/file UI) — un bare `links.design` su
|
|
20
|
+
card docs/meta va all'owner router (era: clamp a ui-expert, 6.55M su una card docs).
|
|
21
|
+
- **Stamp holistic evidence-gated** (`implement.md` step 4 P1): uno stamp senza
|
|
22
|
+
`agents_run` non vuoto = ASSENTE → il plan-auditor gira (phantom stamp FEAT-0068).
|
|
23
|
+
- **Suite aggiunte dalla card: eseguite, non solo parse** (`completeness.md` 1b): uno
|
|
24
|
+
spec ADDED va RUN targeted pre-commit; suite snapshot senza lifecycle baseline
|
|
25
|
+
dichiarato = `Partial` → gap-fix subito (era: merge-blocker + repair da 4.73M che
|
|
26
|
+
flag-gatava la verifica dell'epic).
|
|
27
|
+
|
|
28
|
+
## 2.2.1 — 2026-07-03 (FEAT-0067 post-mortem: migration vocabulary aliases)
|
|
29
|
+
|
|
30
|
+
- Il gate di delega `-auto` (condizione 4) e il Migration Gate Phase 0 1b (setup.md
|
|
31
|
+
step 2) ora rilevano una migrazione dichiarata sotto QUALSIASI vocabolario:
|
|
32
|
+
`migration_plan.required` (epic), `db_migrations_summary` (epic),
|
|
33
|
+
`db_migration.required: true` (per-card, convenzione overlay consumer). Una
|
|
34
|
+
migrazione dichiarata solo via alias con artifact non ancora su disco degrada come
|
|
35
|
+
oggi (missing-artifact) ma la dichiarazione viene SEMPRE registrata nel tracker —
|
|
36
|
+
il sync post-merge e il ledger dei follow-up devono conoscerla.
|
|
37
|
+
|
|
5
38
|
## 2.2.0 — 2026-07-03 (framework v5.4.1)
|
|
6
39
|
|
|
7
40
|
- **Minimal light lane — roster cut to the core four.** A single light card now runs:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: new
|
|
3
3
|
effort: medium
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
description: >
|
|
6
6
|
Orchestrate a team of specialized agents to implement one or more backlog cards
|
|
7
7
|
end-to-end inside a dedicated worktree, with code review, doc review, QA, and
|
|
@@ -66,10 +66,16 @@ kickoff, right after arg parsing):
|
|
|
66
66
|
2. `FORCE_INLINE == false` (the user did not pass `-inline`).
|
|
67
67
|
3. The `Workflow` tool is available in this session AND `.claude/workflows/new2.js`
|
|
68
68
|
is linked AND the `new2` skill is available.
|
|
69
|
-
4. No
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
4. No card in the batch declares a DB migration, under ANY of the recognized
|
|
70
|
+
vocabularies (cheap YAML probe): epic `migration_plan.required: true`, epic
|
|
71
|
+
`db_migrations_summary` (non-empty), or a batch card with
|
|
72
|
+
`db_migration.required: true` (the consumer-overlay convention — e.g. mayo's
|
|
73
|
+
prd-card-writer overlay). A declared migration keeps the classic path — its
|
|
74
|
+
Phase 0 step 1b owns the owner-gated apply under § "AUTONOMOUS RESOLUTION
|
|
75
|
+
RULE"; `new2`'s own migration gate is interactive. *Why the aliases are
|
|
76
|
+
load-bearing*: probing only `migration_plan` silently classified a
|
|
77
|
+
`db_migration`-declaring batch as migration-free (FEAT-0067 post-mortem — the
|
|
78
|
+
remote `db:push` was never surfaced).
|
|
73
79
|
|
|
74
80
|
**Action**: log ONE tracker line `[DELEGATED] -auto batch → new2 engine
|
|
75
81
|
(off-context): <residual args>` and invoke the `new2` skill with the SAME residual
|
|
@@ -33,14 +33,18 @@
|
|
|
33
33
|
a. Edit the backlog YAML (`${paths.backlog_dir}/<CARD-ID>.yml`): set `status: DONE`, add `completed_date: <today>`, and add `provenance.implementation_session: <SESSION-ID>` (this run's session UUID — get it with `Bash(echo "${CLAUDE_CODE_SESSION_ID:-}")`; if empty, omit the field). Merge into any existing `provenance:` block written by `/prd` — do NOT overwrite `planning_session`. This makes an implementation bug traceable back to the session that produced it (`~/.claude/projects/*/<id>.jsonl`).
|
|
34
34
|
b. Add implementation notes summarizing what was built.
|
|
35
35
|
c. **Update `${paths.references_dir}/ssot-registry.md`** — add/update the entry for this card's feature area. The pre-commit doc-freshness hook BLOCKS commits that touch `${paths.backlog_dir}/` without a corresponding ssot-registry update. Always include ssot-registry.md in the same commit as the backlog YAML.
|
|
36
|
-
c-bis. **Epic
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
c-bis. **Epic closure does NOT happen here (v5.6.0 — the v4.99.0 commit-time gate is RETIRED).**
|
|
37
|
+
Two proven defects (FEAT-0068 post-mortem): (1) **timing** — closing at the last card's
|
|
38
|
+
commit runs structurally BEFORE the final review can disprove the epic goal (the FEAT-0068
|
|
39
|
+
epic closed DONE 13 minutes before the review proved the goal unmet on ~90% of screens),
|
|
40
|
+
and the commit context cannot see follow-up cards materialized later in the batch;
|
|
41
|
+
(2) **anchor bug** — the retired gate grepped `^parent:` but the card schema nests
|
|
42
|
+
`parent:` indented under `group:`, so it was a silent no-op on schema-conformant cards.
|
|
43
|
+
Epic closure now lives ONLY in the merge phase (`merge-cleanup.md` Phase 6b step 5e,
|
|
44
|
+
extended predicate: children **and follow-ups** DONE + no blocking residual + **epic ACs
|
|
45
|
+
verified**), which runs AFTER the final review. At commit time the parent epic and every
|
|
46
|
+
sibling card YAML are READ-ONLY. The epic-staleness safety net the v4.99.0 gate closed
|
|
47
|
+
stays closed by Phase 6b 5e + the nightly doc routine.
|
|
44
48
|
d. **Verify the write**: re-read the YAML file and confirm `status: DONE` is present. If not, retry the edit.
|
|
45
49
|
e. Stage BOTH the updated YAML AND ssot-registry.md, then commit (or as an immediate follow-up commit if the Phase 4 implementation commit already happened). When this produces a SECOND commit for the card, record BOTH hashes in the tracker (`commit: <impl-hash> + <done-hash>`) so traceability/bisect is unambiguous.
|
|
46
50
|
29. **Update tracker**: move card to `## Completed Cards` with commit hash(es), summary, flags, **and `card_status: DONE (verified)`** — the tracker is the only state surface (§ "State surface — the tracker only"); do not also emit a TaskUpdate or Progress-Bar turn for the transition. If you surface the card completion to the user at all, do it as a short prose line folded into the commit turn, never a dedicated turn.
|
|
@@ -36,6 +36,16 @@ Before triggering any review, you MUST verify that the coder agent implemented *
|
|
|
36
36
|
`conditional_items` section → flag as `Missing` (the coder must document the branch taken).
|
|
37
37
|
|
|
38
38
|
1. **Enter Phase 2.5 (completeness)** — **no standalone tracker write** for phase entry (§ "Context Tracking" allowlist; the tracker records only `2.5-completeness DONE` at step 6, co-emitted). Proceed directly to the next step.
|
|
39
|
+
1b. **Card-added test suites must RUN, not just parse (v5.6.0 — FEAT-0068).** If the card's diff
|
|
40
|
+
ADDS or modifies a test/spec file, the completeness evidence for that item is a targeted
|
|
41
|
+
EXECUTION of exactly that file (`npx vitest run <file>` / `npx playwright test <file>` / the
|
|
42
|
+
toolchain equivalent), in the worktree, before commit — a `--list`/parse check only proves the
|
|
43
|
+
file compiles, not that the suite can pass. A suite that cannot run yet by design (e.g. a
|
|
44
|
+
visual-regression suite whose baselines are generated later) is only `Done` if the card
|
|
45
|
+
EXPLICITLY declares that lifecycle (see `card-schema.md` § snapshot-suite invariant) AND the
|
|
46
|
+
declared bootstrap command is exercised; otherwise classify `Partial` and route to the
|
|
47
|
+
gap-fix loop NOW — the FEAT-0068 card shipped a baseline-less suite that detonated as a
|
|
48
|
+
merge-blocker and was "fixed" by flag-gating the epic's only visual verification (4.73M).
|
|
39
49
|
2. Re-read the backlog card (`requirements`, `acceptance_criteria`, `unknowns`, and `definition_of_done` fields).
|
|
40
50
|
3. Build a checklist — one row per item:
|
|
41
51
|
|
|
@@ -334,6 +334,16 @@ that is a **gate violation**: log it as
|
|
|
334
334
|
- **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).
|
|
335
335
|
- **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.
|
|
336
336
|
- Classify: `VERIFIED` | `FALSE_POSITIVE` | `NEEDS_MANUAL_CONFIRMATION`.
|
|
337
|
+
- **Closure-invalidating findings (v5.6.0 — FEAT-0068 post-mortem).** A VERIFIED finding (any
|
|
338
|
+
severity) asserting that an **epic goal or epic AC is NOT met** while state says otherwise —
|
|
339
|
+
overclaim in the SSOT/registry, "DONE but unmet", "goal not achieved" — is a **STATE defect,
|
|
340
|
+
not a prose defect**. Tag it `closure_invalidating: true`. Its fix has TWO mandatory parts:
|
|
341
|
+
(1) the text correction (the doc fixer's job as usual), AND (2) the **state reversal** — the
|
|
342
|
+
named epic must NOT be closed in Phase 6b, or, if already `DONE` on disk, must be REOPENED to
|
|
343
|
+
`IN_PROGRESS` in the same repair commit (`merge-cleanup.md` 5e step a). Accepting the text
|
|
344
|
+
fix alone as resolution merges a registry that says "goal not achieved" alongside an epic
|
|
345
|
+
YAML that says DONE — the exact FEAT-0068 contradiction. The batch verdict becomes PARTIAL
|
|
346
|
+
(§ Report verdict below) whenever one of these stands.
|
|
337
347
|
- `VERIFIED` findings proceed to fixes — **EXCEPT no-action ones** (`requires_action:false`, or a "no fix required" / "acceptable as-is" / "verified non-issue" direction; MEDIUM/LOW only). A no-action finding is TRUE but needs no change: record it (`decision=skipped | reason=no-action`) and do NOT route it to a writer. (The delegated `new-final-review` workflow returns these separately as `noActionFindings` + `summary.noAction`; the inline path classifies them here.) **`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. **When AUTONOMOUS, apply § "AUTONOMOUS RESOLUTION RULE" (SKILL.md): category=blocker; recommended=treat NEEDS_MANUAL_CONFIRMATION as VERIFIED (never as a false positive), else materialize a follow-up card.** Only `FALSE_POSITIVE` are dropped.
|
|
338
348
|
|
|
339
349
|
### Step F.5 — Apply fixes and final build
|
|
@@ -403,6 +413,19 @@ that is a **gate violation**: log it as
|
|
|
403
413
|
4. Emit the **minimal end-of-batch result block** (per § "orchestrator is near-silent" in the core SKILL.md — this is NOT a per-phase report). ONE line per card and nothing more of the process telemetry:
|
|
404
414
|
- `<CARD-ID>: merged @<sha> | failed: <one clause> | deferred → <followup-id>`
|
|
405
415
|
|
|
416
|
+
**Report verdict (v5.6.0 — HARD headline rule, FEAT-0068 post-mortem).** The FIRST line of the
|
|
417
|
+
result block is a verdict, and it is computed, not felt:
|
|
418
|
+
- `⚠️ PARTIAL — obiettivo epic NON raggiunto: <one clause naming the gap>` whenever ANY of:
|
|
419
|
+
a HIGH/BLOCKER residual or follow-up carrying substantive scope work exists; the parent epic
|
|
420
|
+
was left open (or reopened) by Phase 6b 5e; a closure-invalidating finding stands; any epic
|
|
421
|
+
AC is still `[ ]`. Name the gap and its follow-up card in the first three lines.
|
|
422
|
+
- `✅ COMPLETO` is RESERVED for: every card merged, no HIGH+ residual, epic (when present)
|
|
423
|
+
closed with ACs verified.
|
|
424
|
+
A run that ships 6/6 cards but leaves the epic goal on 10% of its surface is PARTIAL — the
|
|
425
|
+
FEAT-0068 report headlined "✅ batch completo" over a disclosed-but-buried HIGH gap, and the
|
|
426
|
+
user discovered it only by asking. "Nulla perso" (tracking) is never a substitute for "non
|
|
427
|
+
finito" (truth): a follow-up that holds the epic's remaining work is REMAINING WORK.
|
|
428
|
+
|
|
406
429
|
Then, **only if non-empty**, the **actionable residue**: issues needing user attention (anything unresolved, partially wired, or flagged — terse, with `path:line` / `CARD-ID` exact). All process telemetry — files changed, test/build/lint status, fix cycles, review-finding counts, UX/QA verdicts, commit + merge hashes, card-status reconciliation, worktree cleanup, knowledge-corpus sync — is **NOT rendered**: it lives in the tracker and `$METRICS/skill-runs.jsonl`. (The Next Steps & Launch Command in 4b below and any Production Readiness manual steps ARE part of the actionable residue — keep them.)
|
|
407
430
|
|
|
408
431
|
4b. **Next Steps & Launch Command** (MANDATORY section — always present):
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
2b. **Claim** — only now set the card status to `IN_PROGRESS` (in the backlog YAML / tracker) and assign yourself. This is a state write, not a visibility emission — do not also spend a TaskUpdate / Progress-Bar turn (§ "State surface — the tracker only").
|
|
12
12
|
2c. **Trivial-card classification (BLOCKING gate for steps 3–4)** — evaluate `IS_TRIVIAL(card)` per § "Trivial-card fast-lane". Note: condition 3 (non-source diff) cannot be fully evaluated until the coder has produced the diff, so at this point compute the **provisional** trivial flag from conditions 1+2 only (`review_profile == skip` AND no Step-A trigger sourced from the card YAML text + `files_likely_touched` extensions — if EVERY path in `files_likely_touched` is non-source, condition 3 is provisionally satisfied). If provisionally trivial → **SKIP steps 3, 3a, and 4** (architecture grounding); log `trivial: architecture grounding skipped (review_profile=skip + non-source files_likely_touched + 0 triggers)` and jump to Phase 2. Re-confirm `IS_TRIVIAL` on the ACTUAL committed diff at the review gates (Phase 2.55/3.5/3.7); if the coder unexpectedly touched a source file, the guard flips the card back onto the normal review path there. If NOT provisionally trivial → run steps 3, 3a, 4 as normal.
|
|
13
13
|
2d. **Light-lane inline grounding (since v5.4.0 — BLOCKING gate for steps 3–4, after 2c)** — when the card is NOT provisionally trivial AND `review_profile == light`: **SKIP step 3 (the dedicated codebase-architect spawn) and step 4** — the OWNER agent grounds INLINE instead, per **AGENTS.md § Change Tiers, orchestrated-pipeline exception** (a light card is ≤3 files with no logic-risk signal by Rule C; a dedicated retriever at that scale costs more than the exploration it isolates). The understanding obligation is UNCHANGED — only the delegation is waived: the owner briefing (step 6/7) MUST carry the line "Ground INLINE before coding: read the files in scope + their immediate integration points; scoped exploration only". Step 3a still runs (write Active Code Context from the card YAML, noting `grounding: inline-light`). Log `phase1: INLINE-LIGHT (review_profile=light — no retriever spawn, owner grounds inline)`. `balanced`/`deep` cards run steps 3, 3a, 4 as written — this lane never applies to them.
|
|
14
|
-
3. **(skip when provisionally trivial — see 2c — or on the light lane — see 2d)** Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation. When `features.has_lsp_layer: true`, the architect uses LSP find-references for identifier-shaped lookups — this needs NO handoff from the orchestrator: the architect reads `features.has_lsp_layer` from `baldart.config.yml` directly (the flag is ambient) per `agents/code-search-protocol.md`. Likewise, when `features.has_code_graph: true`, the architect uses the Graphify code graph for structural/relational lookups (ambient flag) per `agents/code-graph-protocol.md`. The orchestrator does NOT propagate either flag. (Earlier doc versions numbered this step 4; the step that read project-status BEFORE the architect was removed because it persisted pre-analysis context — see step 3a.) **Pass `OUTPUT=terse` in the architect prompt (since v4.49.0)** — this is grounding for the coder/reviewer, not an explanation, so the architect returns its structured contract (reuse table + canonical evidence + `path:line — symbol` rows + `totals:`) without narrative prose. **Pass the analysis profile too (since v4.94.0)**: `PROFILE=ui` when the card
|
|
14
|
+
3. **(skip when provisionally trivial — see 2c — or on the light lane — see 2d)** Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation. When `features.has_lsp_layer: true`, the architect uses LSP find-references for identifier-shaped lookups — this needs NO handoff from the orchestrator: the architect reads `features.has_lsp_layer` from `baldart.config.yml` directly (the flag is ambient) per `agents/code-search-protocol.md`. Likewise, when `features.has_code_graph: true`, the architect uses the Graphify code graph for structural/relational lookups (ambient flag) per `agents/code-graph-protocol.md`. The orchestrator does NOT propagate either flag. (Earlier doc versions numbered this step 4; the step that read project-status BEFORE the architect was removed because it persisted pre-analysis context — see step 3a.) **Pass `OUTPUT=terse` in the architect prompt (since v4.49.0)** — this is grounding for the coder/reviewer, not an explanation, so the architect returns its structured contract (reuse table + canonical evidence + `path:line — symbol` rows + `totals:`) without narrative prose. **Pass the analysis profile too (since v4.94.0)**: `PROFILE=ui` when the card's `HAS_MOCKUP` bit is true (the same semantic mockup test that drives step 6a — v5.6.0: a bare `links.design` pointer on a docs/meta card does NOT make it a UI card), else `PROFILE=feature` — contract and per-profile scoping in `agents/analysis-profiles.md` (its § 3 caller routing table is normative). The profile is deterministic from the card YAML; never leave the architect to infer it. The verbatim baseline persisted at step 5b keeps all the substance a lean `/codexreview` needs (paths, signatures, patterns, high-risk paths) while staying small in the orchestrator's context and on disk. **Baseline content contract (MANDATORY — since v4.56.0):** the architect prompt is grounding INPUT only — pass the card scope, `files_likely_touched`, and the question to map. NEVER put line-level fix directives ("remove lines 90-91", "Fix: use X"), the words "implement/fix/apply", or acceptance-criteria framed as a task into the architect prompt. The architect produces a read-only MAP (file/symbol locations, patterns, type signatures, integration points, high-risk paths); it does NOT implement and has no `Task`/Agent tool to delegate (see `codebase-architect.md` § Role boundary). The coder is a separate spawn the orchestrator owns.
|
|
15
15
|
3a. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project) — do this AFTER the codebase-architect run (step 3) so the "Active Code Context" reflects the architect's findings (which files are actually in scope), not just the card YAML's `files_likely_touched`. Writing it before the architect run would persist pre-analysis claims that downstream agents (e.g. a parallel card) would then read as truth.
|
|
16
16
|
4. **Plan-auditor grounding check** — but first, a **provenance skip (since v4.7.0 — mirror of Step 3d)**: the `/prd` Step 6.6 holistic audit already ran a per-card grounding pass when the card was authored. Re-grounding here is only worth a plan-auditor spawn if something changed since. **This skip is the NORMAL path for a card implemented right after `/prd`, not an occasional optimization** — `/prd` now guarantees the `metadata.holistic_audit` stamp lands on every audited card (deterministic backstop at `validation-phase.md` Step 7 item 5b, since the v4.88.2 provenance-reliability fix), so P1 below holds whenever the batch is freshly authored. Skip the plan-auditor when **BOTH** hold:
|
|
17
|
-
- **P1 — provenance present**: the card has `metadata.holistic_audit` with non-empty `audited_at`, `audited_commit`, `audited_set
|
|
17
|
+
- **P1 — provenance present AND evidence-backed (v5.6.0)**: the card has `metadata.holistic_audit` with non-empty `audited_at`, `audited_commit`, `audited_set`, **and a non-empty `agents_run` list** (the v5.6.0 evidence field the stamper writes only when it received a real audit report). A stamp with `status: skipped` or WITHOUT `agents_run` is treated as **ABSENT** — the FEAT-0068 `/prd` session stamped all 6 cards while the Step 6.2–6.6 audit team never spawned (phantom stamp), and P1∧P2 would have suppressed the plan-auditor on a false premise. Pre-v5.6.0 stamps (no `agents_run` field at all) therefore fall through to RUN the plan-auditor — deliberate fail-safe, not a bug.
|
|
18
18
|
- **P2 — no drift on this card's claimed paths** since the audit baseline. With `$AC` = `metadata.holistic_audit.audited_commit`, `$MAIN`/`$TRUNK` from the tracker, and this card's `files_likely_touched`/claimed paths (`$CARD_PATHS`):
|
|
19
19
|
```bash
|
|
20
20
|
# empty AC, AC not in history, or any git error → treat as drift (do NOT skip)
|
|
@@ -57,7 +57,17 @@
|
|
|
57
57
|
If card is an epic (id ends "-00" OR filename ends "-epic.yml" OR review_profile == "skip"
|
|
58
58
|
with no requirements): SKIP — log "[ROUTER] card <ID> is an epic (tracker) — skipped,
|
|
59
59
|
not implemented" and move to the next card.
|
|
60
|
-
|
|
60
|
+
# v5.6.0 (FEAT-0068): "has a mockup" is SEMANTIC, not a bare-field test. The /prd epic
|
|
61
|
+
# explainer html stamped on 5/6 cards clamped a docs+ADR card to ui-expert (6.55M, the
|
|
62
|
+
# run's costliest agent) and put a meta-only card through the fidelity lane.
|
|
63
|
+
HAS_MOCKUP := links.design_src is non-empty
|
|
64
|
+
OR ( links.design is non-empty
|
|
65
|
+
AND ( component_bindings is non-empty
|
|
66
|
+
OR files_likely_touched intersects component/style/UI source paths ) )
|
|
67
|
+
# A bare links.design on a docs/test/meta-only card is a POINTER to the epic's design
|
|
68
|
+
# explainer, not a build target → route by owner_agent (step 6b). Log the demotion:
|
|
69
|
+
# "[ROUTER] card <ID> carries links.design but builds no mocked UI → owner_agent router".
|
|
70
|
+
If HAS_MOCKUP:
|
|
61
71
|
IF the /ui-implement skill is available:
|
|
62
72
|
DELEGATE this card's mockup→code implement + fidelity verify to /ui-implement
|
|
63
73
|
in programmatic mode (contract: ui-implement/references/integration.md).
|
|
@@ -82,7 +92,7 @@
|
|
|
82
92
|
```
|
|
83
93
|
|
|
84
94
|
`owner_agent` is still honored for **review/ownership semantics** (AC-closure ownership, `security-reviewer` relevance, the mixed-card review cluster) — it simply no longer decides the BUILD agent when a mockup is present.
|
|
85
|
-
6b. **Agent dispatch (router — cards WITHOUT a mockup only).** Reached only when step 6a did not fire (
|
|
95
|
+
6b. **Agent dispatch (router — cards WITHOUT a mockup only).** Reached only when step 6a did not fire (`HAS_MOCKUP` false — no mockup, or a bare `links.design` pointer on a card that builds no mocked UI). Read `owner_agent` from the card YAML and resolve the spawn target per the table in § Agent Routing above:
|
|
86
96
|
|
|
87
97
|
```
|
|
88
98
|
Let raw = card.owner_agent (string, may be missing).
|
|
@@ -93,24 +93,45 @@ The most common failure mode is leaving cards IN_PROGRESS after merge. This crea
|
|
|
93
93
|
|
|
94
94
|
For each **distinct parent epic** referenced by the batch — the set of `group.parent`
|
|
95
95
|
values across the batch cards, PLUS any card in the batch that is itself an epic
|
|
96
|
-
(`group.is_epic: true`) —
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
(`group.is_epic: true`) — close ONLY when the FULL predicate (a)–(d) holds
|
|
97
|
+
(v5.6.0, FEAT-0068 post-mortem: the old children-count-only predicate closed an epic whose
|
|
98
|
+
goal was unmet on ~90% of screens — the count was true and the DoD was false):
|
|
99
|
+
a. Read the epic parent card `${paths.backlog_dir}/<EPIC-ID>.yml`.
|
|
100
|
+
- `status: DONE` already **and** the checks below still hold → skip (idempotent).
|
|
101
|
+
- `status: DONE` already **but** (b)/(c)/(d) now FAIL (an open follow-up child appeared, a
|
|
102
|
+
closure-invalidating finding stands) → **REOPEN** it: set `status: IN_PROGRESS`, annotate
|
|
103
|
+
`completed_date`, add note `"REOPENED — closed against open scope (v5.6.0 guard)"`, fold
|
|
104
|
+
into the reconciliation commit. The ratchet is two-way: a false DONE never survives a
|
|
105
|
+
reconciliation pass.
|
|
106
|
+
b. Check that **every** child is DONE (not just the batch's subset — children implemented in
|
|
107
|
+
earlier sessions count too, and **follow-up cards count as children**: a
|
|
108
|
+
`<card>-followup-*.yml` carrying `parent: <EPIC-ID>` is an OPEN child until implemented):
|
|
101
109
|
```bash
|
|
102
110
|
# Lists children of <EPIC-ID> that are NOT yet DONE. Empty output ⇒ all DONE.
|
|
111
|
+
# No ^ anchor — the schema nests `parent:` indented under `group:` (the v4.99.0
|
|
112
|
+
# commit-time gate anchored it and was a silent no-op; do not re-introduce that).
|
|
103
113
|
grep -l "parent: <EPIC-ID>" ${paths.backlog_dir}/*.yml | xargs grep -L "status: DONE"
|
|
104
114
|
```
|
|
105
|
-
c. **
|
|
106
|
-
|
|
107
|
-
`
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
c. **No blocking open work attached to the epic**: scan the tracker's `## Issues & Flags` +
|
|
116
|
+
residual/follow-up ledger for this batch — any open `scope-expansion` / `unresolved` /
|
|
117
|
+
`ac-unmet` item on a child of this epic, or any **closure-invalidating** final-review
|
|
118
|
+
finding (`final-review.md` § Closure-invalidating findings) naming this epic's goal →
|
|
119
|
+
leave the epic OPEN (a text fix to the overclaiming doc does NOT clear this).
|
|
120
|
+
d. **Epic ACs verified**: read the epic YAML's own `acceptance_criteria`. For each `[ ]`
|
|
121
|
+
item, verify it with concrete evidence — run its `ac_verification` oracle when present,
|
|
122
|
+
else a targeted check — and flip to `[x]` ONLY with evidence recorded in the tracker. An
|
|
123
|
+
AC you cannot verify stays `[ ]` and the epic stays OPEN (report which AC and why).
|
|
124
|
+
Never close an epic whose own checklist still has `[ ]` items.
|
|
125
|
+
e. **Only if (b)+(c)+(d) all pass** → update the epic parent: set `status: DONE`, add
|
|
126
|
+
`completed_date: <today>`, add note `"Marked DONE by epic-closure gate (Phase 6b) —
|
|
127
|
+
children+follow-ups DONE, ACs verified"`. Stage it and **fold into the SAME reconciliation
|
|
128
|
+
commit** as step 5 (or, if step 5 didn't run because all children were already DONE, make a
|
|
129
|
+
dedicated `[BATCH] Close epic <EPIC-ID>` commit, honoring the same COMMIT_LOCK /
|
|
130
|
+
doc-freshness precautions as step 5a–5d).
|
|
131
|
+
f. **If any check fails** → leave the epic untouched (or REOPEN per step a) and report the
|
|
132
|
+
concrete reason: step-4b's "Card rimanenti nell'epic" table + the final report's epic-goal
|
|
133
|
+
line must show it — the batch verdict is **PARTIAL**, never ✅, while the epic is open
|
|
134
|
+
(`final-review.md` § Report verdict).
|
|
114
135
|
6. **Update tracker** with reconciliation results:
|
|
115
136
|
```
|
|
116
137
|
## Phase 6b — Status Reconciliation
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
1b. **Migration Gate (BLOCKING only when a migration is *declared* — else a silent no-op)** — resolve DB migrations interactively **before** the worktree exists, so the schema is live before any card builds against it. *Why this exists*: a migration applied to a shared/remote DB is owner-gated, so without this gate it is deferred to the END of the batch — and every downstream card in the batch is then built and verified against a schema that is not yet live (`validation_commands` / QA / E2E / DB-generated `tsc` types fail falsely → those cards cascade into deferral/blocked). Front-loading the migration removes that root cause. **The declaration lives in the EPIC card** (`migration_plan` block — project-specific, authored by the user, typically via the `.baldart/overlays/new.md` overlay). Steps:
|
|
23
23
|
|
|
24
24
|
1. **Find the batch's epic card(s).** Collect the distinct `group.parent` of the batch cards (or, for a `-full` invocation, the parent already known). For each, locate the epic YAML in `${paths.backlog_dir}` (filename `<PARENT>-*-epic.yml`, or the card whose `id == <PARENT>` / `group.is_epic: true`) and Read it.
|
|
25
|
-
2. **Look for `migration_plan` with `required: true
|
|
25
|
+
2. **Look for a declared migration — under ANY recognized vocabulary.** Primary: epic `migration_plan` with `required: true`. **Compat aliases (consumer-overlay conventions — same semantics, different field names)**: epic `db_migrations_summary` (non-empty), or any batch card carrying `db_migration.required: true` (map: `artifacts` ← each `db_migration.expected_file`; `summary` ← the slug; apply/push modalities ← `db_migration.remote_push` + the overlay's post-merge section; no `verify` unless declared). A migration declared ONLY via alias whose `expected_file` does not yet exist on disk (it will be authored mid-run by the coder) follows the step-3 missing-artifact degradation — but the declaration itself MUST still be recorded in the tracker (`## Migration\ndeclared (via db_migration) — deferred to post-merge sync`) so the post-merge Migration Sync step and the follow-up ledger know about it. If **nothing** declares a migration → write `## Migration\nnone (no migration declared)` to the tracker and **proceed to step 2** (behaviour is identical to today — zero extra prompts). This is the common case; do not surface anything.
|
|
26
26
|
3. **(declared) Verify the artifacts exist on disk.** For each path in `migration_plan.artifacts`, check it exists under `$MAIN`. If **any is missing** → do **NOT** apply or prompt; write `## Migration\ndeclared but artifact(s) missing: <paths> — degraded to deferred (author the migration first)` to the tracker and **proceed to step 2** (the migration falls back to the current end-of-batch owner-gated deferral — no regression). *(Auto-generating a missing artifact is out of scope; the migration must already be authored to be applied up-front.)*
|
|
27
27
|
4. **(declared + artifacts present) Assemble the apply modalities**, in this source order, de-duplicating by `id`: (a) `migration_plan.apply_modalities` from the epic block; (b) a `## Migration modalities` section in `.baldart/overlays/new.md` if present; (c) any project-memory note on how this project applies migrations; (d) the built-in tail `["Già applicata — prosegui", "Abort"]`. Each modality is `{ id, label, command? }`.
|
|
28
28
|
5. **`AskUserQuestion`** — `"La epic dichiara una migrazione DB (<summary>). Va applicata PRIMA del batch così le card downstream verificano contro lo schema reale. Come procedo?"` with up to 4 of the assembled modalities (always include "Già applicata — prosegui" and "Abort" as the last options). This is a legitimate Phase 0 question (Auto Mode does not override it).
|
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 1.8.0 — 2026-07-04 (FEAT-0068 post-mortem: integrità dell'esito + igiene git)
|
|
6
|
+
|
|
7
|
+
- **`new2.js`**: step 4b (chiusura epic) RIMOSSO dal commit agent — la chiusura vive
|
|
8
|
+
SOLO nella merge phase 5e col predicato v5.6.0 (blocklist JS `closureBlockedEpics`
|
|
9
|
+
da residual/follow-up/finding closure-invalidating + figli/follow-up DONE + AC epic
|
|
10
|
+
verificati, `epicsLeftOpen` con motivi); **guardia post-merge** gemella di F-029
|
|
11
|
+
(`epic-closure-guard` VIOLATION + residual `false-epic-closure` HIGH → la skill
|
|
12
|
+
riapre); detection **closure-invalidating** sui finding della final review.
|
|
13
|
+
- **`buildReport`**: verdetto calcolato `⚠️ PARTIAL`/`✅ COMPLETO` come PRIMA sezione,
|
|
14
|
+
sezione `## Epic goal` per-epic, `severity` sui residui (`residualSeverity`),
|
|
15
|
+
"nulla perso" consentito solo senza HIGH.
|
|
16
|
+
- **Commit agent**: clausola WORKTREE ISOLATION estesa ai TOOL (Read/Edit/Write path
|
|
17
|
+
assoluti — il cwd HARD RULE v5.3.0 copriva solo Bash), path del card YAML del
|
|
18
|
+
worktree passato esplicito, sibling/epic READ-ONLY, evidenza porcelain
|
|
19
|
+
before/after sul main + **isolation-guard JS** (main sporcato = VIOLATION +
|
|
20
|
+
residual HIGH). Era: 79 turni/4.30M di detour + stash dangling.
|
|
21
|
+
- **Merge**: `merge-worktree.sh --safety-sweep allowlist:` (solo bookkeeping del
|
|
22
|
+
batch; codice non gated mai spazzato nel trunk — F-030 per costruzione); divieto
|
|
23
|
+
esplicito di `git stash` ovunque (ff-pull bloccato = leave+report).
|
|
24
|
+
- **`new2-resolve.js`**: esito **`refuted`** ratificato avversarialmente (premessa
|
|
25
|
+
falsa = zero edit — era: 4.73M per "fixare" un blocker falso disattivando la suite
|
|
26
|
+
visual-regression) + `terminalReason: verification-posture-change` (un fix che
|
|
27
|
+
skippa/flag-gata una verifica mandata da un AC è FORBIDDEN).
|
|
28
|
+
- **`new-final-review.js`**: relay Codex in **foreground `--wait`** (una sola Bash,
|
|
29
|
+
timeout 600000) — l'enforcement structured-output forzava un TIMEOUT a 83s/600s e
|
|
30
|
+
il processo moriva col relay → fallback freddo da 3.68M; reap dell'orfano scoped
|
|
31
|
+
al worktree su timeout reale.
|
|
32
|
+
- **Routing**: `hasMockup` semantico nel cardGraph (BUILDS the mocked UI) +
|
|
33
|
+
`parentEpic` per blocklist/report.
|
|
34
|
+
- **SKILL.md**: Step 2 predicato di chiusura completo + **ramo REOPEN** (ratchet
|
|
35
|
+
bidirezionale); Step 4 presenta il verdetto verbatim (mai ri-headline un PARTIAL);
|
|
36
|
+
**Step 4b audit igiene git** (commit non-card ispezionati con `git show --stat` —
|
|
37
|
+
mai attribuire provenienza senza check; stash del batch riconciliati, mai "non
|
|
38
|
+
miei"; residual `main-repo-contamination` ripristinati); pre-sha del trunk
|
|
39
|
+
registrato al kickoff.
|
|
40
|
+
|
|
41
|
+
## 1.7.0 — 2026-07-03 (FEAT-0067 post-mortem: migration mai deployata)
|
|
42
|
+
|
|
43
|
+
- **Step 3.5 vocabulary aliases**: il Migration Gate ora riconosce, oltre a
|
|
44
|
+
`migration_plan.required` (epic), anche `db_migrations_summary` (epic) e
|
|
45
|
+
`db_migration.required: true` (per-card — convenzione overlay consumer, es. mayo).
|
|
46
|
+
Root cause FEAT-0067: il probe solo-`migration_plan` classificava la batch come
|
|
47
|
+
migration-free → gate in silent no-op, `db:push` mai emerso.
|
|
48
|
+
- **Step 5.1b Migration Sync Tail (NEW)**: post-merge, il ramo B interattivo del sync
|
|
49
|
+
gate eseguito dalla SKILL (check-sync read-only → su rosso `AskUserQuestion`
|
|
50
|
+
Push now / Defer / Override; mai push in autonomo). Trigger belt-and-braces sulla
|
|
51
|
+
DICHIARAZIONE Step 3.5, non solo sul residual ledger (che il DONE-flip di FEAT-0067
|
|
52
|
+
aveva perso). Telemetria `migration_sync_tail`.
|
|
53
|
+
- Step 1.5: nota di delega aggiornata (il probe di `/new -auto` copre tutti i vocabolari).
|
|
54
|
+
|
|
5
55
|
## (workflow new2.js, framework v5.4.1) — 2026-07-03
|
|
6
56
|
|
|
7
57
|
- Minimal light lane mirror: single-card light adds per-card doc-reviewer to the review
|