baldart 4.92.0 → 4.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,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
+ ## [4.93.0] - 2026-07-02
9
+
10
+ **`/prd` gate-hygiene wave — dai driver misurati (forensics di una sessione reale: 61.6M token, 48% del costo in fasi meccaniche, una famiglia di card con zero audit-trail, 96% del wall-clock in attesa umana).** Sette interventi chirurgici, nessuna nuova chiave di config:
11
+
12
+ - **Tool di misura onesto**: `scripts/new-session-audit.mjs` deduplica l'usage per `message.id` (sovracontava ~2.85× — 175M riportati vs 61.6M reali su FEAT-0061) e riconosce le sessioni `/prd` (`mode=prd`, anche quando la skill è invocata via Skill tool dopo un preambolo; backtrack `self`; confronto col reference FEAT-0041 saltato).
13
+ - **Severità assoluta evidence-anchored** (`prd` skill 1.2.0 + `plan-auditor`): via la quota posizionale "top 20% → HIGH must-apply" — fabbricava cicli di apply su piani puliti e demotava finding reali sui batch grandi. Zero-finding è un esito legittimo.
14
+ - **Validation eseguita, non recitata**: `validate-card-baseline.js --prd` (requirements condizionale PO1, epic `skip`, marker `[NEEDS CLARIFICATION]` bloccanti) + nuovo `framework/scripts/stamp-holistic-audit.js` (stamp `metadata.holistic_audit` deterministico, idempotente; chiamato da 6.9.4 e dal backstop 5b — i due gate-prosa che erano falliti insieme su FEAT-0064).
15
+ - **Context economy dell'orchestratore /prd**: contratto teammate audit estratto in `references/audit-teammate-prompt.md` e passato BY PATH (mai caricato dall'orchestratore; ~−9KB da audit-phase + regola generale per gli spec agent-facing incl. `api-perf-gate.md`); analisi mockup su file delegata a `ui-expert` read-only (misurati ~208KB di mockup in cache per ~300 eventi); Progress Bar solo ai phase-gate con riga compatta intra-fase (~20 righe × 30+ messaggi risparmiate; unifica la policy Codex già esistente).
16
+
17
+ **MINOR** — capability change su skill/agent/script condivisi; nessun cambio di layout install. **No new `baldart.config.yml` key** → la schema-change propagation rule NON si applica. **Codex parity: portable** (script node zero-dep; prosa skill condivisa ai due runtime; il branch file-backed Codex del teammate contract è documentato in-file).
18
+
19
+ ## [4.92.1] - 2026-07-02
20
+
21
+ **Review avversariale post-release del motore new2 (coerenza interna).** Tre reviewer indipendenti a contesto fresco (dataflow / edge-case / contratti) sull'onda v4.90–4.92; ogni finding ri-verificato contro il codice prima di agire: **11 confermati e fixati, 9 refutati con evidenza empirica** (tra i refutati: la "race" del worker-pool adattivo — simulata: 0 buchi; `verify-item.sh` su bash 3.2 reale — funziona; `parseInt` con CRLF; un CAP attribuito a `new2.js` che non esiste).
22
+
23
+ **PATCH** — hardening senza cambi di superficie. **Nessuna nuova chiave config**. **Codex parity: portable/N/A** (prosa + workflow JS Claude-only).
24
+
25
+ ### Fixed
26
+
27
+ - **`new2.js`**: verifier strutturale che si auto-dichiara `status:"skipped"` = UNDERRUN (mai PASS — era l'ultimo canale di under-run mascherato); **re-verify deterministica** una-tantum dopo un fix strutturale risolto (il self-report del fixer non è la conferma del verifier); **`bindingCheck` consumato** (violazioni sopravvissute al pass dell'agent → resolve ui; report assente → ledger fail-open, mai silente); `${MAIN}` quotato dentro `$(git -C …)` (path con spazi).
28
+ - **`/e2e-review` 1.2.1**: stringa lane canonica `skipped:render_unavailable_structural_covered` scritta esplicitamente da Phase 3.8 (l'assertion di Phase 5 valida l'enum chiuso); chiave di convergenza del self-heal estesa con `viewport_role`.
29
+ - **`new2` 1.2.1**: Step 3.5 ramo AUTONOMOUS (CI/`BALDART_AUTONOMOUS`/origine delegata → mai una domanda, mai un apply command autonomo); **origine delegata = autonoma ovunque** (escape hatch 3b SKIPPED anche con TTY — chiuso il rischio di ciclo `/new`→`new2`→`/new` a costo pieno); contatore resume **durabile nel batch tracker** (una compaction non resetta il bound) + teardown broker Codex su ogni uscita per stallo.
30
+ - **`structural-compare.mjs`**: arbitrary value Tailwind con funzioni (`grid-cols-[repeat(2,_minmax(0,1fr))]`) contati con la `countTracks` parens-aware (era `split('_')` → 3 invece di 2, falso segnale di divergenza).
31
+ - **`ui-implement` 1.1.1**: Return Contract documenta i campi `bindings`/`lane_coverage`/`lanes` (schema SSOT in integration.md).
32
+
8
33
  ## [4.92.0] - 2026-07-02
9
34
 
10
35
  **Tier 3 del programma "deep analysis /new+/ui-implement": parity tripwire, bound dei loop, verifica payload new2.** Chiude il programma a 3 tier (4.90.0 → 4.92.0).
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.92.0
1
+ 4.93.0
@@ -348,14 +348,15 @@ Consider:
348
348
 
349
349
  ## SEVERITY CALIBRATION (after challenge pass)
350
350
 
351
- After challenge pass, rank ALL surviving findings by impact:
352
-
353
- 1. List all surviving findings in order of impact (most impactful first).
354
- 2. Assign severity based on position:
355
- - Top 20% → **HIGH** (must fix before implementation)
356
- - Middle 40% → **MEDIUM** (should fix, mark `[MANUAL]` if ambiguous)
357
- - Bottom 40% → **LOW** (note only, do not edit structured fields)
358
- 3. **Exception**: data loss, security bypass, breaking change, claimed_path collision, ADR required missing = automatically **HIGH** regardless of position.
351
+ Severity is **ABSOLUTE, per finding, anchored to its evidenced consequence** — never a relative ranking, never a quota. (Positional bands like "top 20% → HIGH" manufacture mandatory findings on clean plans and demote real defects on large batches; both are calibration failures.)
352
+
353
+ For each surviving finding ask: *"what happens if the card is implemented exactly as written?"*
354
+
355
+ - **HIGH** (must fix before implementation) — implementing the card as written produces a defect: data loss, security bypass, breaking change, claimed_path collision, ADR required missing, wrong behavior against a stated AC, an unimplementable AC (e.g. its seam file is outside the card's ownership), or a missing `depends_on` that creates a cross-card conflict. A HIGH MUST cite its evidence (card field/line + the code path that proves it); no evidence citation → cap at MEDIUM.
356
+ - **MEDIUM** (should fix, mark `[MANUAL]` if ambiguous) — the card is implementable but a gap will plausibly cost a review cycle: missing doc/file in `files_likely_touched`, vague-but-inferable AC, missing validation command.
357
+ - **LOW** (note only, do not edit structured fields) — informational, no behavioral consequence.
358
+
359
+ Zero HIGH — or zero findings at all — on a well-formed card is a legitimate, reportable outcome. Do NOT stretch severities to fill bands.
359
360
 
360
361
  ## QUANTIFIED RISK SCORING (MANDATORY)
361
362
 
@@ -91,6 +91,14 @@ the card reaches `status: DONE`.
91
91
 
92
92
  6. **Populate `data_fields`** for every card that reads/writes the persistence layer (see Required Fields).
93
93
 
94
+ **Never guess silently — mark the ambiguity.** The grounding rule generalizes beyond field
95
+ names: whenever card material forces you to GUESS (an unresolved behavior, an unspecified
96
+ control/state, a value the PRD/Discovery never pinned down), do NOT pick a plausible answer
97
+ silently — write `[NEEDS CLARIFICATION: <the exact question>]` inline at the ambiguous spot.
98
+ The `/prd` validation gate (`validate-card-baseline.js --prd`) BLOCKS commit while any marker
99
+ is unresolved, so the ambiguity reaches a human instead of shipping as a hidden assumption.
100
+ A marker is a legitimate intermediate state, never a defect — the defect is the silent guess.
101
+
94
102
  ## Mission
95
103
 
96
104
  You receive:
@@ -2,6 +2,16 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.2.1 — 2026-07-02
6
+
7
+ - Phase 3.8: la lane visual del route non renderizzabile con mockup code-form viene
8
+ marcata esplicitamente `skipped:render_unavailable_structural_covered` nel Lane
9
+ Matrix (l'enum canonico che l'assertion di Phase 5 step 0 valida); `gaps[]` tiene
10
+ il diagnostico `render_unavailable` — due stringhe deliberatamente distinte.
11
+ - Phase 5b step 3: chiave di convergenza estesa con `viewport_role`
12
+ (`route, source, category, viewport_role, region`) — una regressione
13
+ viewport-scoped non può più matchare falsamente il finding pre-fix.
14
+
5
15
  ## 1.2.0 — 2026-07-02
6
16
 
7
17
  - **Self-heal convergence detection (Phase 5b step 3)**: se il fix produce finding
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: e2e-review
3
3
  effort: medium
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  description: >
6
6
  Deterministic, BLOCKING end-to-end review run after a feature is implemented.
7
7
  Combines functional E2E (Playwright spec written by `coder`, executed via
@@ -520,8 +520,12 @@ For each route with a mockup (`mockup_source.level != "skip"`):
520
520
  - A comparable render was produced → it is the implementation screenshot for Phase 4.
521
521
  - Still degenerate after the loop **and** the mockup is **code-form** (a Phase 2.7
522
522
  `structural_source` exists) → the structural pass already covered fidelity; record
523
- `render_unavailable` in `gaps[]` and let Phase 4's visual step skip this route's
524
- desktop diff (no false coverage-gap — structure was checked route-free).
523
+ `render_unavailable` in `gaps[]` (diagnostic), set the route's visual lane in the
524
+ Lane Matrix to **`skipped:render_unavailable_structural_covered`** (the canonical
525
+ enum the Phase 5 step 0 assertion validates — the two strings are deliberately
526
+ distinct: `gaps[]` carries the diagnostic, `lanes` carries the closed-set reason),
527
+ and let Phase 4's visual step skip this route's desktop diff (no false
528
+ coverage-gap — structure was checked route-free).
525
529
  - Still degenerate after the loop **and** the mockup is **image-only**
526
530
  (`level ∈ {figma, local}` with no `structural_source`) → mark the route
527
531
  `coverage_obligation_unmet = true` for Phase 4 step 1c (it will synthesize a
@@ -894,7 +898,10 @@ For each iteration:
894
898
  the Phase 4b quality pre-filter already make a clean re-run cheap.
895
899
  3. **Re-aggregate and re-decide** (back to Phase 5 step 1), with **convergence
896
900
  detection (v4.92.0)**: compare the new gating-finding set with the pre-fix one by
897
- `(route, source, category, region)`. If the fix produced **NEW gating findings that
901
+ `(route, source, category, viewport_role, region)` the Phase 4 step 4
902
+ de-duplication key extended with `source`, so a viewport-scoped regression (a fix
903
+ that repairs desktop while breaking the mobile pass on the same route/category) is
904
+ a NEW finding, never a false match. If the fix produced **NEW gating findings that
898
905
  were not present before** (the fixer is regressing while fixing — the documented
899
906
  non-convergent failure mode), do NOT burn another iteration: STOP the loop now and
900
907
  transition to the override path with both sets in the report (`convergence:
@@ -2,6 +2,22 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.2.1 — 2026-07-02
6
+
7
+ Review avversariale post-release (3 lenti indipendenti, finding verificati):
8
+ - **Step 3.5 ramo AUTONOMOUS**: env-autonomous / origine delegata → mai una domanda;
9
+ verify green ⇒ prosegui, altrimenti `degraded` (deferral owner-gated di fine batch);
10
+ mai un apply command autonomo.
11
+ - **Origine delegata = autonoma ovunque** (Step 1.5): l'escape hatch 3b è SKIPPED anche
12
+ con TTY (niente ciclo /new→new2→/new a costo pieno inline).
13
+ - **Contatore resume DURABILE** (Step 5.3): `resume_attempt: N/3` appeso al batch
14
+ tracker prima di ogni re-invocazione (una compaction non resetta il bound) +
15
+ teardown del broker Codex prima di ogni uscita per stallo.
16
+ - `new2.js`: verifier strutturale `status:"skipped"` = UNDERRUN (mai PASS);
17
+ re-verify deterministica una-tantum dopo un fix strutturale risolto;
18
+ `bindingCheck` CONSUMATO (violazioni → resolve ui; assente → ledger, fail-open);
19
+ `${MAIN}` quotato dentro `$(git -C …)` (path con spazi).
20
+
5
21
  ## 1.2.0 — 2026-07-02
6
22
 
7
23
  - **Resume loop HARD-BOUNDED (Step 5.3)**: `resumeMaxAttempts = 3` con contatore
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: new2
3
3
  effort: high
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  description: >
6
6
  Workflow-hosted batch engine for /new. Implements one or
7
7
  more backlog cards end-to-end by delegating the WHOLE batch to a background
@@ -79,7 +79,12 @@ pre-v4.16 install).
79
79
  `/new`'s AUTONOMOUS OFF-CONTEXT DELEGATION GATE invokes this skill with the same
80
80
  residual grammar (card IDs + `-full` + `-stats` + `effort=`) — never
81
81
  `-auto`/`-auto-ship`/`-inline` (this skill IS autonomous by contract; the
82
- `AUTO_SHIP` deploy boundary stays in `/new`'s classic path). `/new` only
82
+ `AUTO_SHIP` deploy boundary stays in `/new`'s classic path). **A delegated run is
83
+ AUTONOMOUS-ORIGIN**: treat it exactly like the env-signalled autonomous state
84
+ everywhere this skill branches on it — Step 3.5 resolves deterministically (its
85
+ AUTONOMOUS branch) and **Step 3b's escape hatch is SKIPPED** (the user asked for
86
+ `-auto`; a post-batch question — and a possible `/new` re-invocation at full
87
+ inline cost — would break that promise even with a TTY present). `/new` only
83
88
  delegates **migration-free** batches (it probes `migration_plan.required`
84
89
  itself), so Step 3.5's one interactive question cannot fire on a delegated run —
85
90
  if you nonetheless find a declared, unapplied migration in a delegated batch,
@@ -139,6 +144,14 @@ untouched), so the schema is live **before** the workflow starts. It mirrors `/n
139
144
  modalities (always include "Già applicata — prosegui" and "Abort"). This is the SAME class as the
140
145
  Step-2 "ONE pre-launch question" — pre-launch, not a mid-run gate; the zero-ask contract is about
141
146
  the *workflow*, which is untouched.
147
+ **AUTONOMOUS branch (v4.92.1 — env `BALDART_AUTONOMOUS` / `CI` / `GITHUB_ACTIONS`, or a
148
+ delegated `/new -auto` origin per Step 1.5): NEVER ask.** Resolve deterministically:
149
+ (a) `migration_plan.verify` exists → run it; green ⇒ treat as "Già applicata — prosegui",
150
+ red/absent ⇒ (b) set `migration = { status: 'degraded', reason: 'autonomous —
151
+ owner-gated apply deferred' }` and continue (the workflow's end-of-batch owner-gated
152
+ deferral handles it — a `db-migration-deploy` residual, exactly the `/new` Phase 0 1b
153
+ autonomous disposition). Never run an apply **command** modality autonomously (it is an
154
+ outward/irreversible action).
142
155
  6. **Execute the choice in `$MAIN`**:
143
156
  - **Schema-deploy-from-trunk-only guard** (when `stack.schema_deploy_from_trunk_only: true`): a
144
157
  **command** modality is a remote schema deploy → run it only from trunk. Check
@@ -260,14 +273,21 @@ returns when the batch is done. It returns:
260
273
  new `ts`). The per-card **skip-completed** guard makes the resume idempotent —
261
274
  already-committed cards are skipped, only the incomplete/blocked ones run.
262
275
  Bounds (BOTH enforced, count explicitly — do not rely on remembering):
263
- - **`resumeMaxAttempts = 3`** total re-invocations per batch. Keep a literal
264
- counter in your working notes (`resume 1/3`, `2/3`, …); at 3 still `degraded`
265
- STOP resuming: surface `"batch stalled after 3 resumes — manual
266
- intervention needed"` with the incomplete card list (their follow-ups are
267
- already on disk from step 1 nothing is lost by stopping).
276
+ - **`resumeMaxAttempts = 3`** total re-invocations per batch. The counter is
277
+ DURABLE, not a working note: append `resume_attempt: N/3 | <ts> | incomplete:
278
+ <card list>` to the batch tracker (`$(git -C "$MAIN" rev-parse
279
+ --git-common-dir)/baldart/run/batch-tracker-<FIRST-CARD-ID>.md`) BEFORE each
280
+ re-invocation a compaction/crash between resumes must not reset the count
281
+ (re-read the tracker's `resume_attempt` lines to recover it). At 3 still
282
+ `degraded` → STOP resuming: run the **Codex broker teardown first** (the same
283
+ idempotent two-line block as step 6 below — a stall exit must not leak the
284
+ broker), then surface `"batch stalled after 3 resumes — manual intervention
285
+ needed"` with the incomplete card list (their follow-ups are already on disk
286
+ from step 1 — nothing is lost by stopping).
268
287
  - **Stall detection**: if a resume completes with the SAME incomplete card set
269
- as the previous attempt (zero progress), stop immediately even before the
270
- cap a second identical pass will not converge either.
288
+ as the previous attempt (zero progress compare against the tracker's last
289
+ `resume_attempt` line), stop immediately even before the cap a second
290
+ identical pass will not converge either. Same teardown-then-surface exit.
271
291
  An unbounded resume loop re-pays the whole batch-loop cost per cycle (~0–200k+
272
292
  tokens each) with no new information; a persistent `degraded` is an outage or a
273
293
  structural blocker, not something iteration fixes.
@@ -283,8 +303,9 @@ returns when the batch is done. It returns:
283
303
  the offer is purely additive over an already-safe ledger — declining (or a closed
284
304
  terminal) never drops a residual.
285
305
  - **Skip this step entirely in AUTONOMOUS mode** (env `BALDART_AUTONOMOUS` / `CI` /
286
- `GITHUB_ACTIONS` set, or no TTY) leave the cards `IN_PROGRESS` + their follow-ups,
287
- exactly as before. The escape hatch is interactive-only.
306
+ `GITHUB_ACTIONS` set, no TTY, **or a delegated `/new -auto` origin Step 1.5**) —
307
+ leave the cards `IN_PROGRESS` + their follow-ups, exactly as before. The escape
308
+ hatch is interactive-only, and a delegated run is autonomous even with a TTY.
288
309
  - **Eligible set** = the follow-ups whose residual `deferralClass` is **code-actionable**:
289
310
  `unresolved`, `out-of-ownership`, `scope-expansion`. EXCLUDE `owner-gated` /
290
311
  `not-a-code-defect` / `policy-deferred-ac` (external infra steps — `/new` cannot perform
@@ -2,6 +2,19 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.2.0 — 2026-07-02
6
+
7
+ **Gate-hygiene wave** — dai driver misurati sul forensics di una sessione /prd reale (61.6M token; 48% del costo in fasi meccaniche a piena finestra; una famiglia di card spedita con zero audit-trail; ~20 righe di progress bar × 30+ messaggi):
8
+
9
+ - **Severità assoluta evidence-anchored** (`audit-phase.md` § Severity Calibration + `plan-auditor.md`): rimossa la calibrazione a quota posizionale ("top 20% → HIGH must-apply") che fabbricava finding HIGH su piani puliti e demotava finding reali sui batch grandi. HIGH ora richiede citazione dell'evidenza; zero-finding è un esito legittimo.
10
+ - **Validation ESEGUITA, non recitata** (`validation-phase.md` Step 6 item 0-i): il gate deterministico gira via `validate-card-baseline.js --prd` (enum, requirements condizionale PO1, epic `review_profile: skip`, matrice campi) — i check semantici restano in prosa (0-ii). Nuovo check bloccante: marker `[NEEDS CLARIFICATION: …]` irrisolti (l'ambiguità di planning è un artefatto gated, mai un'assunzione silenziosa; `prd-card-writer` istruito a marcare invece di indovinare).
11
+ - **Stamp holistic deterministico** (`framework/scripts/stamp-holistic-audit.js`, nuovo, zero-dep): `metadata.holistic_audit` scritto da script idempotente/additivo/epic-skipping/self-verifying, chiamato da `audit-phase.md` 6.9.4 E dal backstop `validation-phase.md` 5b (entrambi i call-site erano prosa e sono falliti INSIEME su un run reale).
12
+ - **Prompt agent-facing passati BY PATH** (context economy, ~−30KB dal contesto orchestratore): il contratto teammate dell'audit estratto in `references/audit-teammate-prompt.md` (letto dai teammate, MAI dall'orchestratore); `api-perf-gate.md` dichiarato agent-facing nella flow table (era già delegato, ma la regola "read before each phase" lo faceva caricare comunque); regola generale in SKILL.md.
13
+ - **Mockup mai nel contesto orchestratore** (`discovery-phase.md` 1.6.5): l'analisi mockup su file è DELEGATA a `ui-expert` read-only (ritorna solo lo YAML `mockup_analysis`); misurati ~208KB di mockup decodificato trascinati in cache per ~300 eventi. Eccezione: immagini incollate in chat (già in contesto).
14
+ - **Progress Bar ai phase-gate** (SKILL.md HARD RULE 11): tabella completa solo alle transizioni di fase; riga compatta sugli STOP intra-fase; niente sui messaggi tecnici — adottata su Claude la policy già scritta per Codex (unificazione, non fork).
15
+
16
+ Codex parity: portable (script node zero-dep + prosa skill condivisa; il branch Codex file-backed del teammate contract è documentato nel file stesso).
17
+
5
18
  ## 1.1.2 — 2026-07-01
6
19
 
7
20
  - Context economy: trimmed the HARD-RULES **Runtime portability** citation to a one-liner (cite, don't restate — the detail lives in `runtime-portability-protocol.md`). ~330 chars off the SKILL.md core, which sits in context every turn. No behavior change; RULE 4/11 Codex branches unchanged.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: prd
3
3
  effort: high
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  description: "Structured PRD creation skill. Use when the user says /prd, 'crea un prd', 'nuova funzionalita', 'pianifica feature', or wants to plan a new feature end-to-end. Also handles /prd-add, 'aggiungi requisito', 'serve anche', 'manca un endpoint' for change requests on active PRD sessions — runs ICIAS impact analysis to determine which phases need SKIP/PATCH/REDO. Produces PRD + UI design + backlog cards, all validated and committed. Multi-turn conversation: asks questions, waits for answers, iterates through discovery, design, spec writing, card creation, and validation phases."
6
6
  ---
7
7
 
@@ -46,14 +46,21 @@ message. You ask questions, wait for answers, and iterate.
46
46
  | 2.5 | Research (opzionale) | [research-phase.md](references/research-phase.md) |
47
47
  | 3 | UI Design (3a-3d) | [ui-design-phase.md](references/ui-design-phase.md) |
48
48
  | 4 | Write PRD | [prd-writing-phase.md](references/prd-writing-phase.md) |
49
- | 4.5 | API Performance Gate | [api-perf-gate.md](references/api-perf-gate.md) |
49
+ | 4.5 | API Performance Gate | [api-perf-gate.md](references/api-perf-gate.md) — **agent-facing**: passed BY PATH to `api-perf-cost-auditor` (spawn per prd-writing-phase § 4.5); the orchestrator does NOT read it |
50
50
  | 4b | Confirm Specs (§ "Present and Confirm") | [prd-writing-phase.md](references/prd-writing-phase.md) |
51
51
  | 5 | Backlog Cards | [backlog-phase.md](references/backlog-phase.md) |
52
52
  | 6 | Quality Audit | [validation-phase.md](references/validation-phase.md) |
53
53
  | 7 | Resolution, Commit & Merge | [validation-phase.md](references/validation-phase.md) |
54
54
  | 7.6 | Obsidian back-reference — FINAL (upgrades the 1.2 provisional block; only if a spec note was given) | [validation-phase.md](references/validation-phase.md) + [obsidian-backref.md](references/obsidian-backref.md) |
55
55
 
56
- **Before starting each phase, read the corresponding reference file.**
56
+ **Before starting each phase, read the corresponding reference file** — with ONE
57
+ exception class: **agent-facing specs are passed BY PATH to the agent that consumes
58
+ them and MUST NOT be loaded into the orchestrator context.** Today these are
59
+ `references/api-perf-gate.md` (read by `api-perf-cost-auditor` at Step 4.5 and at the
60
+ Step 6 audit) and `references/audit-teammate-prompt.md` (read by each Step 6.6 audit
61
+ teammate). Rationale: a spec loaded by a subagent costs one cheap Read in a disposable
62
+ context; the same spec in the orchestrator rides EVERY subsequent full-window API call
63
+ for the rest of the run.
57
64
 
58
65
  ---
59
66
 
@@ -73,7 +80,17 @@ message. You ask questions, wait for answers, and iterate.
73
80
  **Worktree-mode exception (HARD RULE 17):** when the PRD runs inside a docs worktree (default since v3.22.0), the session-start update is **SKIPPED** — writing `project-status.md` in the worktree wouldn't be visible to other terminals working on the main repo, and writing it on the main repo would pollute `git status` for parallel sessions (exactly what worktree isolation is meant to prevent). The at-commit update still applies and runs inside the worktree as the last write before rebase + merge — see [validation-phase.md](references/validation-phase.md) § Step 7.
74
81
  10. **STOP means STOP.** When you see `STOP`, end your message. Do not make more tool
75
82
  calls. Do not continue to the next step. Wait for the user.
76
- 11. **Progress visibility.** Claude Code: every message MUST end with the Progress Bar (no exceptions). **Codex**: the Progress Bar is OPTIONAL derive it on demand from the state file and show a compact summary at the phase gates (not after every technical/tool message, per `/new`'s context-economy precedent); update the state file after each phase either way. The discovery **user gates** (one question per message) stay conversational on both runtimes.
83
+ 11. **Progress visibility — at PHASE GATES, not on every message (context economy,
84
+ unified with the Codex policy).** Display the FULL Progress Bar table only at
85
+ **phase transitions**: entering/completing a numbered phase (1.6, 2, 2.5, 3, 4,
86
+ 4b, 5, 6, 7) and on the final message. On intra-phase STOP messages (e.g. each
87
+ discovery question) end with ONE compact line instead:
88
+ `📋 <slug> · Fase <N> <nome> · <indicatore> · Prossimo: <cosa>` (for discovery
89
+ the indicator is `X/11 dimensioni`). Technical/tool messages carry neither.
90
+ The state file is updated after each phase either way and stays the recovery
91
+ SSOT. (Measured driver: ~20 lines × 30+ messages of orchestrator output per
92
+ run bought no signal the compact line doesn't carry.) The discovery **user
93
+ gates** (one question per message) stay conversational on both runtimes.
77
94
  12. **Scope Expansion Detection.** During discovery (Step 2), after every user answer,
78
95
  check if the response introduces NEW structural entities (endpoints, collections,
79
96
  pages, roles, flows) not in the original feature description. If detected, pause
@@ -297,9 +314,12 @@ the value lives only in the state file `## Worktree` section.
297
314
 
298
315
  ---
299
316
 
300
- ## PROGRESS BAR — MANDATORY ON EVERY MESSAGE
317
+ ## PROGRESS BAR — AT PHASE GATES (see HARD RULE 11)
301
318
 
302
- At the END of every message (after all text, before stopping), display:
319
+ At the END of every **phase-transition** message (a numbered phase entered or
320
+ completed, and the final message), display the full table below. On intra-phase
321
+ STOP messages use only the compact line from HARD RULE 11; on technical/tool
322
+ messages display nothing.
303
323
 
304
324
  ```
305
325
  ---
@@ -324,7 +344,8 @@ Prossimo passo: <what happens next>
324
344
 
325
345
  Legend: ⬜ = da fare, 🔄 = in corso, ✅ = completato, ⏭️ = saltato (N/A)
326
346
 
327
- **If your message doesn't end with this table, you violated the skill rules.**
347
+ **If a phase-transition message doesn't end with this table or an intra-phase STOP
348
+ message lacks the compact line — you violated the skill rules.**
328
349
 
329
350
  ---
330
351
 
@@ -106,7 +106,7 @@ Use `TaskCreate` to create one task per audit agent per card:
106
106
 
107
107
  - For **N cards × M agent types**, create **N × M tasks** (one task per agent type per card; excluding Codex plan-audit — see 6.6d). In Step 6.6c, ONE teammate agent per type handles all N tasks in its queue — M agents run in parallel, not N×M.
108
108
  - Each task subject: `[CARD-ID] <agent-type> audit`
109
- - Each task description: full card YAML + adjacent card summaries + file paths + PRD path + instructions.
109
+ - Each task description: full card YAML + adjacent card summaries + file paths + PRD path. The audit instructions are NOT embedded — each teammate reads them from `audit-teammate-prompt.md` (see 6.6e).
110
110
 
111
111
  **Claim-lock (atomicity on the N×M fan-out)**: each task carries a `claimed_by` field, empty at creation. Before a teammate processes a task it MUST atomically set `claimed_by: <its name>` via `TaskUpdate` and re-read; if the field is already non-empty and not its own name, it SKIPS that task (another worker owns it). This prevents two workers — for example a re-spawn after a transient failure, or an overlapping re-audit (Step 6.9) — from both processing the same card+agent pair and producing duplicate findings. The teammate workflow (Step 6.6e) embeds the claim step.
112
112
 
@@ -259,138 +259,31 @@ Suppress findings where the strongest false-positive argument is convincing.
259
259
  - If `codebase-architect` was already spawned earlier this session (its summary is in the session tracker artifact registry), pass that summary in the prompt and instruct plan-auditor NOT to re-invoke `codebase-architect`.
260
260
  - If `security_review_needed: true` (security-reviewer already ran as a teammate), instruct plan-auditor NOT to spawn `security-reviewer`; its security findings are already in the task store and will be merged at Step 6.7. plan-auditor should rely on those rather than running an independent, un-merged second review.
261
261
 
262
- ### 6.6e. Teammate prompt template
262
+ ### 6.6e. Teammate prompt — passed BY PATH (context economy)
263
263
 
264
- Each teammate receives this prompt:
264
+ The full teammate contract identity, task-queue workflow (claim-lock included), the
265
+ per-role audit instructions, the output format with `[Target:]` tags, the challenge
266
+ pass, and the severity calibration — lives in
267
+ [audit-teammate-prompt.md](audit-teammate-prompt.md). That file is an **AGENT-FACING
268
+ spec**: each teammate reads it in ITS OWN context window; the orchestrator MUST NOT
269
+ load it into its own (in a teammate it costs one cheap Read — in the orchestrator it
270
+ would ride every subsequent full-window API call for the rest of the run).
265
271
 
266
- ```
267
- ## Identity
268
-
269
- You are a SKEPTICAL auditor for a pre-development audit team ("check-audit").
270
- Your default stance is that the card is NOT ready for implementation.
271
- Do not rationalize away issues. Do not give benefit of the doubt.
272
- If something COULD be a problem, flag it. The challenge pass (later) will filter false positives.
273
- Your job is RECALL, not precision — catch everything, filter later.
274
-
275
- ## Your Workflow
276
-
277
- 1. Call `TaskList` to see your assigned tasks.
278
- 2. For each task (in ID order):
279
- a. Call `TaskGet` to read the full task description (card YAML + adjacent cards + file paths).
280
- a2. **Claim the task**: if `claimed_by` is already set to a name other than yours, SKIP this task (another worker owns it). Otherwise set `claimed_by: <your name>` via `TaskUpdate`, then re-read via `TaskGet` to confirm your claim held; if a different name won the race, SKIP.
281
- b. Mark task as `in_progress` via `TaskUpdate`.
282
- c. Read any source files or PRDs referenced in the task (use Read tool).
283
- d. Perform your audit (see instructions below).
284
- e. Run the Challenge Pass on your findings (see below).
285
- f. Run Severity Calibration on surviving findings (see below).
286
- g. **Write findings into the task description** via `TaskUpdate` — append a `## FINDINGS` section.
287
- h. Send a brief notification to orchestrator via `SendMessage` (task ID + one-line summary only).
288
- i. Mark task as `completed` via `TaskUpdate`.
289
- 3. After all tasks: send "all tasks complete" to orchestrator.
290
-
291
- **IMPORTANT**: Always write findings to task description (step g) before notification (step h). Task description is durable; message is just a ping.
292
-
293
- ## Audit Instructions
294
-
295
- {AGENT_SPECIFIC_INSTRUCTIONS}
296
-
297
- ## Output Format (mandatory evidence quotes)
298
-
299
- For each card, return findings as:
300
-
301
- ### [CARD-ID] — {Agent Role} Findings
302
-
303
- - [ ] **Finding title** — Description of the issue, risk, or gap. (Severity: HIGH/MEDIUM/LOW) [Target: <field>]
304
- > **Evidence:** "<exact quote from the card YAML, PRD, or source file>"
305
- > **Source:** `<file path or field name>`
306
-
307
- **MANDATORY**: Every finding MUST include an evidence quote — a direct excerpt that grounds it. Findings without quotable evidence MUST be discarded. State: "Considered but discarded — no quotable evidence found."
308
-
309
- If no findings: "No issues found for [CARD-ID]."
310
-
311
- ### `[Target: <field>]` tag reference (mandatory on every finding)
312
-
313
- | Target tag | When to use |
314
- |---|---|
315
- | `[Target: requirements]` | Missing or wrong requirement text |
316
- | `[Target: acceptance_criteria]` | Missing AC, vague AC needing rewrite |
317
- | `[Target: definition_of_done]` | Missing DoD checkbox |
318
- | `[Target: files_likely_touched]` | Missing file path |
319
- | `[Target: depends_on]` | Missing dependency card ID |
320
- | `[Target: areas]` | Missing area entry (api, docs, data, ui) |
321
- | `[Target: git_strategy]` | `git_strategy: TBD` or wrong value |
322
- | `[Target: unknowns]` | Unresolved unknown to surface |
323
- | `[Target: existing_patterns]` | Missing or stale pattern reference |
324
- | `[Target: validation_commands]` | Missing verification command |
325
- | `[Target: anti_patterns]` | Missing DO NOT constraint |
326
- | `[Target: scope_boundaries]` | Missing scope boundary item |
327
- | `[Target: input_output_examples]` | Missing or incorrect I/O example |
328
- | `[Target: error_handling]` | Missing failure mode spec |
329
- | `[Target: reuse_analysis]` | Missing reuse opportunity or wrong path |
330
- | `[Target: notes]` | LOW severity only — informational |
331
-
332
- ## Challenge Pass (mandatory before reporting)
333
-
334
- After generating initial findings, challenge EACH one:
335
-
336
- "What is the strongest argument that this is a false positive?"
337
-
338
- Consider:
339
- - Is this already handled elsewhere in the codebase?
340
- - Is this a convention in this project I'm unfamiliar with?
341
- - Is the card intentionally deferring this to a later card?
342
- - Am I applying a generic best practice that doesn't fit this context?
343
-
344
- **Suppress the finding if the FP argument is convincing.** Record suppressed findings:
272
+ Spawn each teammate with this THIN prompt (fill the placeholders, nothing more):
345
273
 
346
- <details>
347
- <summary>Suppressed findings (N items challenge pass)</summary>
348
- - **Finding title** FP argument: <why suppressed>
349
- </details>
350
-
351
- ## Severity Calibration (after challenge pass)
352
-
353
- After challenge pass, rank ALL surviving findings relative to each other by impact:
354
-
355
- 1. List all surviving findings in order of impact (most impactful first).
356
- 2. Assign severity based on position:
357
- - Top 20% → HIGH (must apply)
358
- - Middle 40% → MEDIUM (should apply)
359
- - Bottom 40% → LOW (notes only)
360
- 3. Exception: data loss, security bypass, or breaking change = automatically HIGH regardless of position.
361
-
362
- ### Severity Calibration Examples
363
-
364
- **HIGH** (must fix before implementation):
365
- - "acceptance_criteria says 'user can see <list>' but doesn't specify pagination → unbounded persistence-layer read"
366
- > Evidence: "AC-2: <persona from identity.audience_segments[]> views <entity>" — no limit/pagination mentioned
367
-
368
- **MEDIUM** (should fix, skip if ambiguous):
369
- - "files_likely_touched missing the API route doc update"
370
- > Evidence: files_likely_touched lists "src/app/api/v1/<domain>/route.ts" but not "${paths.references_dir}/api/<domain>.md"
371
-
372
- **LOW** (note only):
373
- - "Card title could be more descriptive"
374
- > Evidence: title is "Booking API" — functional but generic
274
+ ```
275
+ You are teammate "<name>" (role: <agent-type>) in team "check-audit".
276
+ FIRST ACTION: Read <references-path>/audit-teammate-prompt.md and follow it exactly —
277
+ it defines your identity, task-queue workflow (TaskList/TaskGet/claim/TaskUpdate),
278
+ your role's audit instructions (§ "<agent-type>"), the output format, the challenge
279
+ pass, and the severity calibration. Then work your task queue until every task you
280
+ can claim is completed.
375
281
  ```
376
282
 
377
- ### Agent-specific instructions
378
-
379
- **plan-auditor**: **Handled by Codex adversarial audit (Step 6.6d).** Not included in the teammate agent team. If Codex is unavailable, the fallback plan-auditor uses INVEST criteria, DoR checks, and requirements smell detection — see Step 6.6d attack_surface for the full checklist.
380
-
381
- **plan-auditor (card grounding)**: This is the Claude-side, codebase-grounded counterpart to the cross-model Codex plan audit (6.6d) — it brings what Codex lacks: project memory (`.claude/agent-memory/plan-auditor/MEMORY.md`) and the card-native `[Target: <field>]` tagging this audit consumes. Apply the **full BACKLOG CARD ATTACK SURFACE** (INVEST, requirements-smell detection, persistence-specific checks per `stack.database`, card-structure checks) against each card's `.yml`, reading the existing files in `files_likely_touched` to ground claims about conflicts with existing patterns, missing reuse opportunities, and convention alignment (per `identity.design_philosophy`, project lint/type-check rules, `identity.language`). Check `## Adjacent Cards` for parallel file modifications and missing `depends_on` edges.
382
-
383
- > **Mode (team-aware — read first)**: you are running inside the coordinating `check-audit` team, so you MUST behave as in QUICK mode for *spawning* while keeping FULL card-attack-surface *coverage*:
384
- > - **Do NOT spawn `codebase-architect`** for grounding — `/prd` already primed codebase context at kickoff (context-primer) and you read `files_likely_touched` directly. A re-spawn here is wasteful and forbidden.
385
- > - **Do NOT auto-spawn specialists** (`security-reviewer` / `api-perf-cost-auditor` / `ui-expert`) — they run as first-class teammates in this same team whenever their signal fires (6.6c). Consume their findings at merge time; never double-spawn.
386
- > - **Output-format override** (symmetric with the security-reviewer / api-perf-cost-auditor overrides above): produce findings in the teammate contract format (`### [CARD-ID] — Plan Audit Findings` with `[Target: <field>]` tags written to a `## FINDINGS` section via `TaskUpdate`) — NOT plan-auditor's native 10-section OUTPUT FORMAT (Hardened Plan, Pre-Mortem, Risk Register, YAML schema dump). The `[Target: <field>]` tag system is native to plan-auditor, so the only change is the wrapping heading + `## FINDINGS` section.
387
- > - Never suppress a `git_strategy: TBD`, missing-auth, `claimed_path_collision`, `adr_required_missing`, or prompt-injection finding (plan-auditor's never-suppress list still binds here).
388
-
389
- **doc-reviewer**: Check documentation links, PRD references are valid and aligned, planned changes requiring doc updates not mentioned. Verify `files_likely_touched` includes doc files. Check `areas` completeness. Flag `git_strategy: TBD`. Include Obsidian trigger assessment (section H) in findings — evaluate whether the planned docs will require KB sync. If `.claude/skills/doc-reviewer-support/references/obsidian-integration.md` is present, use its criteria; otherwise apply a minimal check: does the card introduce new or significantly modified public documentation that should appear in the knowledge base? Proceed with a notice if the file is absent.
390
-
391
- **api-perf-cost-auditor** (only when `perf_review_needed: true`): Apply the 5-gate protocol from `api-perf-gate.md` (see `framework/.claude/skills/prd/references/api-perf-gate.md`). Read referenced source files. Universal checks: unbounded reads, N+1 queries, fan-out writes, missing pagination, offset pagination, listener vs polling costs, payload size limits per `stack.deployment`, transaction hotspots. Stack-specific addenda apply per `stack.database` + `stack.framework` (see `framework/.claude/skills/prd/references/api-perf-gate.md`). **Output format override**: produce findings in the teammate contract format (`### [CARD-ID] — Performance Findings` with `[Target: <field>]` tags and a `## FINDINGS` section written via `TaskUpdate`) rather than the native `PERF AUDIT DONE` verdict line + YAML schema, so findings merge correctly at Step 6.7 (symmetric with the `security-reviewer` override below).
392
-
393
- **security-reviewer** (only when `security_review_needed: true`): Apply the full security-reviewer methodology. Focus on: auth gaps, input validation, multi-tenant isolation, persistence-layer access rules alignment (Firestore rules / Supabase RLS / Mongo validator / DynamoDB IAM — per `stack.database`), sensitive data exposure, webhook validation, rate limiting, IDOR risks. **Output format override**: produce findings in the teammate contract format (`### [CARD-ID] — Security Findings` with `[Target: <field>]` tags and `## FINDINGS` section written via `TaskUpdate`) rather than the native `# Security Review Summary` format, so findings merge correctly at Step 6.7.
283
+ `<references-path>` = the absolute path of this skill's `references/` directory in this
284
+ install — the same directory you read THIS file from (in a consumer typically
285
+ `<repo>/.claude/skills/prd/references`). Do NOT paste the contract's content into the
286
+ spawn prompt or the task descriptions — the path IS the payload.
394
287
 
395
288
  ## Step 6.7 — Collect & Merge Findings
396
289
 
@@ -515,13 +408,23 @@ metadata:
515
408
 
516
409
  > **Fail-safe contract**: the block is an OPTIMIZATION hint for `/new`, never a *correctness* gate — if `audited_commit` is empty or the block is absent, `/new` Step 3d **and** the `implement.md` Phase-1 plan-auditor grounding (step 4, P1) simply RUN as before (redundant, never wrong). **But writing the block is MANDATORY whenever the audit ran.** It is the single most-omitted step under context pressure, and its absence is exactly what makes `/new` / `new2` spawn the plan-auditor on **every** freshly-authored card even when the batch is implemented immediately after this audit (nothing changed since). Do NOT skip it "to save a write". If git is genuinely unavailable, write `audited_commit: ""` **explicitly** — never omit the block. `validation-phase.md` Step 7 item 5b is the **deterministic backstop** that guarantees this lands before the PRD commit even if this per-card write is missed — but write it here too; the backstop is a safety net, not a license to skip.
517
410
 
411
+ **Deterministic writer — EXECUTE, don't hand-edit.** `framework/scripts/stamp-holistic-audit.js` mechanizes this write (idempotent, additive, epic-skipping, self-verifying). Run it ONCE for the whole card set after the per-card field edits:
412
+
413
+ ```bash
414
+ node .framework/framework/scripts/stamp-holistic-audit.js \
415
+ --at "$HOLISTIC_AUDITED_AT" --commit "$HOLISTIC_AUDITED_COMMIT" \
416
+ --set "<sorted child IDs, comma-separated>" ${CARD_PATHS}
417
+ ```
418
+
419
+ Hand-edit the YAML only when the script is genuinely unreachable in this install — and say so in the audit log.
420
+
518
421
  ### Per-card workflow
519
422
 
520
423
  For each card:
521
424
  1. Read persisted report → collect all findings for this card ID.
522
425
  2. Read current card YAML.
523
426
  3. Apply HIGH findings first, then MEDIUM, then write audit trail.
524
- 4. Write the `metadata.holistic_audit` provenance block (see "Holistic-audit provenance stamp" above) using the run-level values captured once. **MANDATORY when the audit ran** (see the Fail-safe contract above) — this is what lets `/new`/`new2` skip the per-card plan-auditor when the card is implemented right after `/prd`; `validation-phase.md` Step 7 item 5b deterministically backstops it, but do not rely on the backstop.
427
+ 4. Write the `metadata.holistic_audit` provenance block (see "Holistic-audit provenance stamp" above) **by EXECUTING `stamp-holistic-audit.js` once for the whole card set** (after the last card's field edits), not by hand-editing YAML. **MANDATORY when the audit ran** (see the Fail-safe contract above) — this is what lets `/new`/`new2` skip the per-card plan-auditor when the card is implemented right after `/prd`; `validation-phase.md` Step 7 item 5b deterministically backstops it, but do not rely on the backstop.
525
428
  5. Write updated card YAML.
526
429
  6. Re-read to verify edits landed correctly.
527
430
 
@@ -538,4 +441,4 @@ Every component in this audit encodes an assumption about what the model can't d
538
441
  - Remove one component at a time, measure audit quality delta.
539
442
  - If delta < 5% `[CALIBRATION-NEEDED: removal threshold is a heuristic; validate against a labelled audit-quality benchmark before treating it as a hard cutoff]`, remove permanently.
540
443
  - **Current load-bearing assumptions**: challenge pass, adjacent card retrieval, evidence quotes, adversarial evaluator tuning.
541
- - **Assumptions to re-test**: agent team separation (could single-agent handle N cards?), relative severity ranking (does absolute assignment work with better models?).
444
+ - **Assumptions to re-test**: agent team separation (could single-agent handle N cards?). (Relative severity ranking was retired in the gate-hygiene wave: severity is now absolute + evidence-anchored positional quotas manufactured mandatory findings on clean plans.)