baldart 5.3.2 → 5.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,71 @@ All notable changes to BALDART will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [5.4.1] - 2026-07-03
9
+
10
+ **Minimal light lane — the roster for a simple card is now literally: grounding (inline),
11
+ coder, code review, doc review, commit, merge. Nothing else.** Completes v5.4.0 per the
12
+ maintainer's directive ("per cose così semplici voglio due passaggi in croce"): the compact
13
+ lane cut the CARD COUNT; this cuts the per-run AGENT COUNT. FEAT-0067-class run: ~33
14
+ agents → ~7.
15
+
16
+ - **Per-card doc review at light (single-card batch)**: the light review matrix adds the
17
+ scoped `doc-reviewer` per-card (review-cycle.md deferral-gate exception) because the
18
+ Final pass it used to defer to is now skippable.
19
+ - **Final Review skip gate (`final-review.md` § F.0 + `new2.js` `skipFinalLight`)**: ONE
20
+ light card + zero actionable per-card findings (→ zero fixes applied) → skip F.2–F.5
21
+ entirely. Honors the v4.56.1 refutation (per-card PRE-fix + final POST-fix are
22
+ non-redundant) by scoping the skip to runs where there IS no post-fix state; any
23
+ finding, fix, second card, or degraded reviewer → Final runs as always.
24
+ - **i18n fill spawn cut at light**: the owner briefing instructs the coder to fill every
25
+ target locale itself; the anti-hardcoded lint + locale-parity gates still enforce.
26
+ - **Production-readiness spawn cut for all-light batches**: no deployable surface exists
27
+ by Rule C (no migrations/indexes/cron/schema) — the agent only ever reported zero items.
28
+ - `check-new-parity.mjs` rule 18 locks the prose↔workflow lockstep for every cut.
29
+ - Skills: `new` 2.2.0 · `new2` 1.6.0.
30
+
31
+ Codex parity: portable (prose modules are the cross-tool SSOT; `new2.js` Claude-only by design).
32
+
33
+ ## [5.4.0] - 2026-07-03
34
+
35
+ **Elastic pipeline — `/prd`+`/new` compress to the minimum for trivial features and
36
+ scale up only on Heavy triggers.** Follow-up of the FEAT-0067 post-mortem: a label
37
+ feature was decomposed into an epic + 2 balanced cards and burned ~54M billed tokens in
38
+ `/new` (+8M in `/prd`) — every child card pays a fixed pipeline cost the feature size
39
+ cannot amortize, and nothing bounded decomposition from below. Both skeptic-refuted and
40
+ adjusted before shipping (epic wrapper kept per HARD RULE 15; PRD compresses PROSE, never
41
+ its section inventory; the grounding obligation is untouched — only its delegation scales).
42
+
43
+ - **`/prd` Step 2.1 Tier Gate** (skill 1.5.0, `discovery-phase.md`): at Discovery exit
44
+ the feature is classified TRIVIAL/LIGHT/HEAVY per AGENTS.md § Change Tiers (SSOT,
45
+ cited not restated) with one user confirm → `lane: compact|full` in the state file.
46
+ Compact lane: research skipped by default, Step 3 routed toward mockup-only/skipped,
47
+ compressed-prose PRD (full section structure, 1–2 paragraphs each, ≤3 pages), ONE
48
+ child card + the mandatory epic tracker, no added audit ceremony (agent depth already
49
+ scales with `review_profile`). Full lane byte-unchanged.
50
+ - **`prd-card-writer` v1.1.0 — Proportionality lower-bound + Rule C fixes**: atomicity
51
+ now has a FLOOR (TRIVIAL/LIGHT feature → default ONE child card; split only on an
52
+ isolable Heavy trigger or different-owner halves each >3 files; sizing rules are upper
53
+ bounds, never split targets — the tier travels in the Step 5 briefing). Rule C branch
54
+ (b) gains DS-spec doc-sync transparency (the touched component's spec `.md` counts
55
+ like a locale file; never for `components_primitives` paths or HEAD-API changes) and a
56
+ misapplication guard ("tocca i18n / la spec" is never by itself a disqualifier — the
57
+ exact FEAT-0067-02 misclassification).
58
+ - **AGENTS.md primitive 1.8.0 (+ CLAUDE.md 1.4.3)**: § Change Tiers Heavy trigger
59
+ refined — an ADDITIVE index-only migration is no longer Heavy by itself (keeps Rule C
60
+ `db_indexes` depth + the api-perf gate); and a new orchestrated-pipeline exception:
61
+ inside `/new`/`new2` a `review_profile: light|skip` card satisfies the (unchanged)
62
+ understanding obligation via the OWNER grounding inline instead of a dedicated
63
+ `codebase-architect` spawn.
64
+ - **`/new` 2.1.0 light lane (`implement.md` step 2d) + `new2.js` mirror**: light/skip
65
+ cards skip the Phase-1 retriever spawn; the owner briefing carries the inline-grounding
66
+ instruction. Guarded by `check-new-parity.mjs` rule 17 (prose + workflow + primitive
67
+ must stay in lockstep).
68
+
69
+ Codex parity: portable — the Tier Gate binds `AskUserQuestion` vs plain-prompt via the
70
+ existing `runtime-portability-protocol.md` citation in `/prd`; primitives/AGENTS.md is
71
+ the cross-tool SSOT; `new2.js` stays Claude-only by design (documented gap).
72
+
8
73
  ## [5.3.2] - 2026-07-03
9
74
 
10
75
  **AGENTS.md primitive 1.7.4 — commit-format MUST scoped to card-bound work.**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 5.3.2
1
+ 5.4.1
@@ -7,6 +7,18 @@ 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.1.0] — 2026-07-03 (framework v5.4.0)
11
+
12
+ - **Proportionality lower-bound** in Card Atomicity Rules: a Tier-Gate TRIVIAL/LIGHT
13
+ feature defaults to ONE child card (+ the mandatory epic tracker); splits only on an
14
+ isolable Heavy trigger or different-owner halves each >3 files. Sizing rules are
15
+ upper bounds, never split targets. (FEAT-0067: label → epic + 2 balanced cards.)
16
+ - **Rule C branch (b)**: DS-spec doc-sync transparency (the per-component spec .md of a
17
+ touched component is transparent like locale files — gated on has_design_system, never
18
+ for components_primitives paths or HEAD-API changes) + misapplication guard ("tocca
19
+ i18n / la spec" is never by itself a disqualifier — FEAT-0067-02 incident).
20
+ - `version:` frontmatter added.
21
+
10
22
  ## [seo-analytics-strategist v1.1.0] — 2026-07-03 (framework v5.3.0)
11
23
 
12
24
  - `model: haiku` → `model: sonnet` — haiku is banned fleet-wide (REGISTRY
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: prd-card-writer
3
+ version: 1.1.0
3
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."
4
5
  model: opus
5
6
  effort: high
@@ -252,15 +253,16 @@ Apply the **first matching rule** (priority order — top wins):
252
253
  | Profile | When to assign |
253
254
  |---------|----------------|
254
255
  | **DEEP** | ANY of: `areas` includes both `api` AND `data` — OR title/scope/areas touch `auth`, `payment`, `permission`, `schema`, `migration`, `cron`, `webhook`, `transaction` — OR a path in `files_likely_touched` falls under a `paths.high_risk_modules` entry — OR `data_fields` has ≥3 entries with `status: new` or `status: modified` — OR `db_indexes` present (legacy `firestore_indexes` too) — OR acceptance criteria count > 5 — OR `estimated_complexity: HIGH` — OR API contract changed — OR `> 15` files in `files_likely_touched` (broad blast radius — review every group deeply) |
255
- | **LIGHT** | EITHER (a) Card is a `bugfix` or `refactor` — AND ≤3 files in `files_likely_touched` — AND none of the DEEP high-risk keywords/areas apply; **OR** (b) **UI-presentational card** — ALL of: the card is pure-UI — `areas` == `[ui]` exactly (no `api`/`data`/`logic`/`auth`), or when `areas` is absent the Rule B signal `owner_agent: ui-expert` stands in for it — AND ≤3 files in `files_likely_touched`, every one a component/style file (no data-fetching, state-management, API-client, or server file) — AND NO path in `files_likely_touched` falls under `paths.components_primitives` (i.e. the card only *composes* existing design-system primitives, it does NOT introduce or modify one) — AND none of the DEEP high-risk keywords/areas apply. **i18n locale-file transparency (when `features.has_i18n: true`):** locale files under `i18n.locales_root` are TRANSPARENT to this branch — exclude them from BOTH the `≤3` count AND the "every file is component/style" test, classifying the card on its NON-locale files only. A label change forces an edit to every locale file (`it.ts`/`en.ts`/…), which would otherwise push a genuinely-presentational card over the file count and inject non-component `.ts` files; but a locale file is a flat string table whose correctness is owned by the i18n gate (anti-hardcoded lint) + `i18n-translator`, NOT the logic cluster — so it must not disqualify the carve-out. Branch (a) is **NEVER for `feature`/`enhancement` cards**; branch (b) is the ONLY route by which a `feature`/`enhancement` card may be `light`. |
256
+ | **LIGHT** | EITHER (a) Card is a `bugfix` or `refactor` — AND ≤3 files in `files_likely_touched` — AND none of the DEEP high-risk keywords/areas apply; **OR** (b) **UI-presentational card** — ALL of: the card is pure-UI — `areas` == `[ui]` exactly (no `api`/`data`/`logic`/`auth`), or when `areas` is absent the Rule B signal `owner_agent: ui-expert` stands in for it — AND ≤3 files in `files_likely_touched`, every one a component/style file (no data-fetching, state-management, API-client, or server file) — AND NO path in `files_likely_touched` falls under `paths.components_primitives` (i.e. the card only *composes* existing design-system primitives, it does NOT introduce or modify one) — AND none of the DEEP high-risk keywords/areas apply. **i18n locale-file transparency (when `features.has_i18n: true`):** locale files under `i18n.locales_root` are TRANSPARENT to this branch — exclude them from BOTH the `≤3` count AND the "every file is component/style" test, classifying the card on its NON-locale files only. A label change forces an edit to every locale file (`it.ts`/`en.ts`/…), which would otherwise push a genuinely-presentational card over the file count and inject non-component `.ts` files; but a locale file is a flat string table whose correctness is owned by the i18n gate (anti-hardcoded lint) + `i18n-translator`, NOT the logic cluster — so it must not disqualify the carve-out. **DS-spec doc-sync transparency (v5.4.0, when `features.has_design_system: true`):** the per-component spec `.md` of a component file ALREADY in the card's file set is TRANSPARENT the same way — it is the mandatory `DS_COMPONENT_STALE` doc-sync artifact of touching that component (owned by `doc-reviewer` + the Post-Intervention Coherence gate), not logic. This transparency applies ONLY when the spec edit is doc-sync (documenting the presentational change — NO `variant_prop`/HEAD-API change) and NEVER makes a `paths.components_primitives` path transparent (that DEEP signal stands). **Misapplication guard (FEAT-0067-02 incident):** "tocca i18n" / "tocca la spec" are NEVER by themselves reasons to disqualify branch (b) — apply the transparencies FIRST, then classify on the residual file set. Branch (a) is **NEVER for `feature`/`enhancement` cards**; branch (b) is the ONLY route by which a `feature`/`enhancement` card may be `light`. |
256
257
  | **SKIP** | Card is `docs`, `chore`, or `config` — OR all `files_likely_touched` are `.md`/non-API `.yml`/CSS with zero logic files (**when `features.has_i18n: true`, locale files under `i18n.locales_root` are EXCLUDED from this set the same way they are for the LIGHT branch — a pure-cosmetic CSS/copy fix that also retouches locale strings stays `skip`; classify on the non-locale files only**) — OR a pure-cosmetic card (typo/rename/copy/wording/style) with no code areas |
257
258
  | **BALANCED** | Default for everything else — ALL `feature`/`enhancement` cards not matching DEEP, plus any `bugfix`/`refactor` with >3 files or breadth that isn't DEEP |
258
259
 
259
260
  **Critical**: `feature` and `enhancement` cards are `balanced` minimum — **with exactly one
260
261
  exception**: the LIGHT branch (b) above, a strictly UI-presentational card (`areas == [ui]`,
261
- ≤3 component/style files — locale files under `i18n.locales_root` excluded from the count when
262
- `features.has_i18n: true`, see the LIGHT row composes existing primitives without touching any
263
- `paths.components_primitives` path). This narrow carve-out targets the `-ui` half of a
262
+ ≤3 component/style files — locale files under `i18n.locales_root` (when
263
+ `features.has_i18n: true`) and DS-spec doc-sync `.md` files of touched components (when
264
+ `features.has_design_system: true`) excluded from the count, see the LIGHT row composes
265
+ existing primitives without touching any `paths.components_primitives` path). This narrow carve-out targets the `-ui` half of a
264
266
  logic/ui split pair (e.g. a `…-submit-ui` card whose logic lives in its `…-submit-logic`
265
267
  sibling): reviewing a pixels-only diff at Codex-`full` depth is waste, and the design-system
266
268
  safety net still fires regardless of profile (a `light` card keeps its per-card code-review —
@@ -285,10 +287,23 @@ only compute when the field is empty.
285
287
 
286
288
  Cards MUST be as atomic as possible to enable parallel execution:
287
289
 
290
+ **Proportionality lower-bound (v5.4.0 — atomicity has a FLOOR, not just a ceiling):**
291
+ every child card carries a fixed pipeline cost in `/new` (grounding + owner + reviews +
292
+ doc + QA + commit) regardless of its size, so splitting a small feature multiplies cost
293
+ without adding safety. When the `/prd` Tier Gate classified the feature **Trivial or
294
+ Light** (AGENTS.md § Change Tiers — passed down by the skill): default to **ONE child
295
+ card** (the epic wrapper stays, per Card Structure below — it is a zero-cost tracker).
296
+ Split a Light feature ONLY when (a) a Heavy trigger applies to an isolable sub-part, or
297
+ (b) the halves have DIFFERENT `owner_agent` AND each half touches **>3 files** on its own
298
+ (real parallelism, not ceremony). A logic+UI pair below that threshold stays ONE mixed
299
+ card (`owner_agent` per Rule B; `review_profile` per Rule C — a mixed feature card is
300
+ `balanced`, which is still one pipeline instead of two). The sizing rules below are
301
+ **upper bounds that trigger splits, never targets to split toward**.
302
+
288
303
  **Sizing rules:**
289
304
  - Each card SHOULD touch at most 8 files. If more, split into sub-cards.
290
305
  - Each card SHOULD have at most 5 acceptance criteria. If more, split by concern.
291
- - If a card has both API + UI work, consider splitting into API card + UI card (unless tightly coupled and sharing <3 files).
306
+ - If a card has both API + UI work, consider splitting into API card + UI card (unless tightly coupled and sharing <3 files, or the feature is Light-tier — see the lower-bound above).
292
307
 
293
308
  **Splitting heuristics:**
294
309
  - Split by concern: data model vs API vs UI vs docs
@@ -2,6 +2,25 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 2.2.0 — 2026-07-03 (framework v5.4.1)
6
+
7
+ - **Minimal light lane — roster cut to the core four.** A single light card now runs:
8
+ grounding-inline (step 2d) → owner → code review (Codex-light/code-reviewer) → scoped
9
+ doc-reviewer per-card (review-cycle deferral exception) → commit → merge. Cut for the
10
+ lane: i18n fill spawn (7c — owner fills locales inline, lint gate enforces), Final
11
+ Review when the per-card review is clean (final-review.md § F.0 Minimal-light skip
12
+ gate — POST-fix verification with zero fixes is vacuous; any finding/fix/second card →
13
+ Final runs), production-readiness spawn for all-light batches (no deployable surface
14
+ by Rule C). Guarded by check-new-parity rule 18.
15
+
16
+ ## 2.1.0 — 2026-07-03 (framework v5.4.0)
17
+
18
+ - **Light-lane inline grounding (implement.md step 2d).** A `review_profile: light` card
19
+ skips the dedicated codebase-architect spawn (steps 3–4); the OWNER grounds inline per
20
+ AGENTS.md § Change Tiers orchestrated-pipeline exception. Obligation unchanged,
21
+ delegation waived at ≤3-file scale. new2.js mirrors (`inline-light` lane); guarded by
22
+ check-new-parity rule 17.
23
+
5
24
  ## 2.0.1 — 2026-07-03
6
25
 
7
26
  Adversarial-verification fixes on the v5.0.0 pipeline wave (framework v5.0.1):
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: new
3
3
  effort: medium
4
- version: 2.0.1
4
+ version: 2.2.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
@@ -42,6 +42,19 @@ Once ALL cards are committed in the worktree:
42
42
  > A single card has no cross-card surface, so a finder's per-card pass and its final pass are genuinely
43
43
  > the same review.
44
44
 
45
+ ### Step F.0 — Minimal-light skip gate (v5.4.1)
46
+
47
+ When the batch has exactly ONE committed card AND it is `review_profile: light` AND its
48
+ per-card review surfaced ZERO actionable findings (no blocks, no scope-expansion → no fix
49
+ pass was applied), **SKIP the entire Final Review** (F.2–F.5) and proceed to merge. The
50
+ Final pass exists for POST-fix verification and cross-card surface (v4.56.1 — per-card
51
+ PRE-fix + final POST-fix are non-redundant); with zero fixes and zero cross-card surface,
52
+ both reasons are absent — and doc coverage already ran per-card (the single-card light
53
+ review matrix includes the scoped doc-reviewer instead of deferring here, see
54
+ review-cycle.md § Deferral gate). Any finding on the card, any fix applied, any second
55
+ card, or any degraded reviewer → run the Final Review as written below. Log
56
+ `final-review: SKIPPED (single light card, clean per-card review — nothing post-fix to verify)`.
57
+
45
58
  ### Step F.1 — Resolve scope
46
59
 
47
60
  (All cards are committed; the batch now enters Final Review. No visibility emission — the internal tracker is the only state surface, see SKILL.md § "State surface — the tracker only". Record the Final-Review start/finish in the tracker only.)
@@ -10,7 +10,8 @@
10
10
  - If `DONE` (or the user chose "proceed anyway") → continue.
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
- 3. **(skip when provisionally trivial — see 2c)** 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 has a non-empty `links.design` OR `links.design_src` (the same mockup bit that drives step 6a), 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 (MANDATORYsince 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.
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=lightno 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 has a non-empty `links.design` OR `links.design_src` (the same mockup bit that drives step 6a), 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.
14
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.
15
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:
16
17
  - **P1 — provenance present**: the card has `metadata.holistic_audit` with non-empty `audited_at`, `audited_commit`, `audited_set`.
@@ -499,7 +500,7 @@
499
500
  - **Grounding (cheap `grep`, like the Phase-1 plan-auditor grounding):** every cited source symbol/class MUST appear in `mockups/_src/` (`grep -rF "<symbol>" <prd_dir>/<slug>/mockups/_src/`), and every cited registry primitive MUST exist in the registry (`grep` `${paths.design_system}/INDEX.md` / `components/`). A symbol that is not in the source, or a primitive that is not in the registry, means a fabricated declaration → reject + re-spawn (do NOT pass it to the gates). Log `design-source: grounded` or `design-source: rejected (<reason>)` in the tracker.
500
501
  - This does NOT re-verify pixels — that stays with `visual-fidelity-verifier` (Phase 2.6). It only proves the source was read and the reuse-mapping targets are real. When the card has no design source, skip this step entirely.
501
502
 
502
- 7c. **i18n fill pass (explicit, deterministic — v5.0.0, promoted from the step-9 sub-bullet).** When `features.has_i18n: true` AND this card's diff added new source-locale keys — detect deterministically, never by intuition:
503
+ 7c. **i18n fill pass (explicit, deterministic — v5.0.0, promoted from the step-9 sub-bullet).** **Light lane (v5.4.1): SKIP this spawn** — on the light lane (step 2d) the owner briefing already instructed the coder to fill EVERY target locale itself (context-aware from the registry); the anti-hardcoded lint + locale-parity gates at step 8 enforce it. Log `i18n-fill: SKIP (light lane — owner fills inline)`. Otherwise: when `features.has_i18n: true` AND this card's diff added new source-locale keys — detect deterministically, never by intuition:
503
504
  ```bash
504
505
  cd <worktree-path>
505
506
  # $SRC_LOCALE = the source-language locale file path (from i18n config / the project's locales root)
@@ -6,6 +6,12 @@
6
6
 
7
7
  After Phase 6 completes (or after the final summary report if Phase 6 is deferred), present a **Production Readiness Checklist** — a clear list of all manual or infrastructure actions required to launch the implemented changes in production.
8
8
 
9
+ > **Minimal light lane (v5.4.1): SKIP the spawn for an all-`light` batch** — a light card
10
+ > carries no deployable surface by Rule C (no migrations, indexes, cron, schema, env); the
11
+ > checklist agent would only report zero items. Log
12
+ > `phase7-production: SKIPPED (all-light batch — no deployable surface)`. Any
13
+ > `balanced`/`deep` card in the batch → run as written.
14
+
9
15
  ### How to detect items
10
16
 
11
17
  Scan ALL files changed across the batch (use the tracker's completed cards + `git diff` against the base branch) and check for the items below.
@@ -305,7 +305,7 @@ skill's Phase 1 falls back to deriving Gherkin scenarios from
305
305
 
306
306
  > **Note**: Code review is NOT performed in this phase — it is handled by the **mandatory unconditional `/codexreview` gate in Phase 3.7**, which runs per-card BEFORE the Phase 4 commit. The post-batch `/codexreview` in the Final review remains as a final FULL-diff sweep over the entire batch (since v3.37.0 — the guaranteed full-depth merge gate). This Phase 3 focuses exclusively on documentation sync, which must happen per-card (tied to the specific commit).
307
307
 
308
- > **Deferral gate (since v4.7.0 — enumerated, `review_profile`-driven)**: SKIP per-card doc-review and defer it to the **Final Review F.3 doc-reviewer** (which runs over the entire batch) when the card is **`review_profile == light` AND its committed diff touches NO documentation file** (no `.md`, no path under `${paths.references_dir}`, no data-model/ssot/api doc). These are small code changes with no doc surface of their own; their only doc concern is drift, which the batch-wide Final doc-reviewer catches. Log `doc-review: DEFERRED to Final FULL gate (light, no doc files in diff)` and proceed to Phase 3.5. **KEEP per-card doc-review** for: `deep` cards, `balanced` cards (they may still PASS-fast via the deterministic gate below — that gate, not this deferral, is their only skip lane), ANY card whose diff touches a doc file (the change IS doc-relevant), and trivial cards (doc-review is their primary gate — § "Trivial-card fast-lane", unchanged). Never defer "for time" — the only enumerated reasons are `light + non-doc diff` and the deterministic PASS-fast below.
308
+ > **Deferral gate (since v4.7.0 — enumerated, `review_profile`-driven)**: SKIP per-card doc-review and defer it to the **Final Review F.3 doc-reviewer** (which runs over the entire batch) when the card is **`review_profile == light` AND its committed diff touches NO documentation file** (no `.md`, no path under `${paths.references_dir}`, no data-model/ssot/api doc). These are small code changes with no doc surface of their own; their only doc concern is drift, which the batch-wide Final doc-reviewer catches. Log `doc-review: DEFERRED to Final FULL gate (light, no doc files in diff)` and proceed to Phase 3.5. **KEEP per-card doc-review** for: `deep` cards, `balanced` cards (they may still PASS-fast via the deterministic gate below — that gate, not this deferral, is their only skip lane), ANY card whose diff touches a doc file (the change IS doc-relevant), and trivial cards (doc-review is their primary gate — § "Trivial-card fast-lane", unchanged). Never defer "for time" — the only enumerated reasons are `light + non-doc diff` and the deterministic PASS-fast below. **Single-card light batch exception (v5.4.1 minimal light lane): do NOT defer** — when the batch has exactly ONE card and it is `light`, the Final Review is itself SKIPPED if the per-card review is clean (see final-review.md § Minimal-light skip gate), so the deferral target would never run: run the scoped per-card doc-reviewer here instead.
309
309
  >
310
310
  > **Deterministic PASS-fast (v5.0.0 — measured: 84/127 per-card doc reviews returned PASS)**: when implement.md step 11c produced `/tmp/docinv-<CARD-ID>.json` AND it says `pass_fast_eligible: true` (zero non-advisory invariant rows triggered + no doc file in the diff + the card declares no `documentation_impact`/`canonical_docs`) AND the card is NOT `deep` → log `doc-review: PASS-fast (doc-invariants: 0 blocking rows) — Final doc-reviewer backstop stands` and **skip the per-card spawn** (proceed to Phase 3.5). No gate is removed: the batch-Final F.3 doc-reviewer still sees this card's diff. Own-Doc Closure: NEW-file obligations are definitionally empty (no invariant row fired, no docs declared); obligations on MODIFIED primitives/routes are covered by the automatic spec resync (`DS_COMPONENT_STALE` serializer gate, v4.70.0) plus the Final F.3 backstop — the invariant table's R1/R3 fire on new files only, by design. `deep` cards always spawn. Missing docinv JSON → no PASS-fast (fall through to the normal path).
311
311
 
@@ -2,6 +2,20 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## (workflow new2.js, framework v5.4.1) — 2026-07-03
6
+
7
+ - Minimal light lane mirror: single-card light adds per-card doc-reviewer to the review
8
+ matrix, skips the i18n fill spawn (owner briefing carries the fill instruction),
9
+ skips new-final-review when `lightLane && cleanReview` (zero actionable findings),
10
+ skips production-readiness for all-light batches. Result objects carry
11
+ `lightLane`/`cleanReview` for the Final gate.
12
+
13
+ ## (workflow new2.js, framework v5.4.0) — 2026-07-03
14
+
15
+ - Light lane: `review_profile: light|skip` cards no longer spawn the Phase-1 retriever —
16
+ the owner briefing carries the inline-grounding instruction instead (implement.md
17
+ step 2d is the prose SSOT). Mirrors /new 2.1.0.
18
+
5
19
  ## 1.4.1 — 2026-07-03
6
20
 
7
21
  - **Multi-card diff scoping (framework v5.0.1)**: the implement brief now instructs the coder
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: new2
3
3
  effort: high
4
- version: 1.4.1
4
+ version: 1.6.0
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
@@ -2,6 +2,17 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.5.0 — 2026-07-03 (framework v5.4.0)
6
+
7
+ - **Step 2.1 Tier Gate (elastic pipeline).** At Discovery exit the feature is classified
8
+ TRIVIAL/LIGHT/HEAVY per AGENTS.md § Change Tiers (SSOT), one user confirm, `lane:
9
+ compact|full` recorded in the state file. Compact lane: research skipped by default,
10
+ Step 3 routed toward mockup-only/skipped, PRD compressed-prose (FULL section structure,
11
+ 1-2 paragraphs each, ≤3 pages), ONE child card + mandatory epic (prd-card-writer
12
+ Proportionality lower-bound; tier passed in the Step 5 briefing), no extra audit
13
+ ceremony (agent depth already scales with review_profile). Full lane unchanged.
14
+ Driven by the FEAT-0067 post-mortem (label feature → epic + 2 balanced cards → ~54M).
15
+
5
16
  ## 1.4.0 — 2026-07-03
6
17
 
7
18
  - **Research-profile contract + library (framework v5.1.0)**: Step 2.5 now
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: prd
3
3
  effort: high
4
- version: 1.4.0
4
+ version: 1.5.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
 
@@ -42,6 +42,7 @@ message. You ask questions, wait for answers, and iterate.
42
42
  | 1.2 | Obsidian provisional back-reference (only if a spec note was given) | [discovery-phase.md](references/discovery-phase.md) + [obsidian-backref.md](references/obsidian-backref.md) |
43
43
  | 1.6 | Mockup Intake | [discovery-phase.md](references/discovery-phase.md) |
44
44
  | 2 | Discovery Question Loop (+ Codex completeness cross-check at exit, v4.19.0) | [discovery-phase.md](references/discovery-phase.md) |
45
+ | 2.1 | Tier Gate — classify TRIVIAL/LIGHT/HEAVY per AGENTS.md § Change Tiers, route `lane: compact\|full` (compact = compressed PRD, 1 child card, research/mockup skipped by default) | [discovery-phase.md](references/discovery-phase.md) § Step 2.1 |
45
46
  | 2→CR | Change Request (auto/manual) | the canonical **`prd-add` skill** ([../prd-add/SKILL.md](../prd-add/SKILL.md)) — worktree-aware (`references/prd-add-phase.md` is a redirect stub, not the implementation) |
46
47
  | 2.5 | Research (opzionale) | [research-phase.md](references/research-phase.md) |
47
48
  | 3 | UI Design (3a-3d) | [ui-design-phase.md](references/ui-design-phase.md) |
@@ -202,6 +202,10 @@ Agent(
202
202
  (The /prd run's session UUID — set provenance.planning_session on every card.
203
203
  See your "Session provenance" section. Omit the field if this value is empty.)
204
204
 
205
+ TIER: <tier from the state file ## Tier section — TRIVIAL|LIGHT|HEAVY>
206
+ (Step 2.1 Tier Gate result. TRIVIAL/LIGHT → apply your "Proportionality
207
+ lower-bound": default ONE child card + the epic; split only per its criteria.)
208
+
205
209
  PRD path: <$WORKTREE_PATH>/<prd_path>
206
210
  State file path: <$WORKTREE_PATH>/<state_file_path>
207
211
  Card template: <$WORKTREE_PATH>/.claude/skills/prd/assets/card-template.yml
@@ -1093,8 +1093,8 @@ End with: 'COMPLETE — no material gaps' if the discovery is genuinely sufficie
1093
1093
  - **After processing (whatever the outcome), write ONE `discovery-completeness:` entry to the Discovery Log** (e.g. `discovery-completeness: 2 gaps asked, 1 skipped` / `COMPLETE — no material gaps`). This entry is the once-per-session guard above — its presence means the sweep has run and MUST NOT run again this session.
1094
1094
  - **Fallback (Codex unavailable — `$CHECK_FILE` empty, contains `CODEX_NOT_FOUND`, or holds no parseable findings)**: **skip the cross-check** and log `discovery-completeness: SKIPPED (Codex unavailable)` in the Discovery Log (this also satisfies the once-per-session guard). This gate is **additive** — the 99% formula + mockup + research gates already gate exit. Do NOT fall back to a same-model Claude pass: the entire value here is cross-model diversity, and Claude just conducted the interview (it carries the very blind spot this check exists to catch), so a Claude self-review adds little and is not worth the spawn. Proceed to exit.
1095
1095
 
1096
- When loop exits: mark task 1 as `completed`. Update state file status to
1097
- `ui-design` (or `specs-confirmed` if UI is N/A).
1096
+ When loop exits: mark task 1 as `completed`. Run **Step 2.1 Tier Gate** (below),
1097
+ then update state file status to `ui-design` (or `specs-confirmed` if UI is N/A).
1098
1098
 
1099
1099
  **Output:**
1100
1100
 
@@ -1103,6 +1103,7 @@ Discovery completata! Tutte le dimensioni sono coperte.
1103
1103
 
1104
1104
  [Brief summary of key decisions made]
1105
1105
  [If research: brief summary of key findings]
1106
+ Tier: <TRIVIAL|LIGHT|HEAVY> → lane <compact|full>
1106
1107
 
1107
1108
  Passo alla fase successiva: [UI Design / Scrittura PRD]
1108
1109
 
@@ -1111,6 +1112,43 @@ Passo alla fase successiva: [UI Design / Scrittura PRD]
1111
1112
 
1112
1113
  ---
1113
1114
 
1115
+ ## Step 2.1 — Tier Gate (proportionality — the pipeline scales with the feature)
1116
+
1117
+ **Purpose**: the `/prd`→`/new` pipeline must scale UP for complex features and COMPRESS
1118
+ to the minimum for trivial ones — every child card and every full-ceremony phase has a
1119
+ fixed cost that a small feature cannot amortize (FEAT-0067: a label feature decomposed
1120
+ into 2 balanced cards burned ~54M tokens; as 1 card on the compact lane it costs a
1121
+ fraction). This gate runs ONCE, at Discovery exit, and routes every later phase.
1122
+
1123
+ 1. **Classify** the whole feature by Change Tier per the installed **`AGENTS.md`
1124
+ § Change Tiers** (the SSOT — do NOT restate its triggers here; read that section).
1125
+ Discovery has already surfaced the classification inputs (data model deltas, new
1126
+ routes/entities, dependencies, refactor breadth). Note the v5.4.0 refinement: an
1127
+ ADDITIVE index-only migration does NOT make the feature Heavy by itself.
1128
+ 2. **Confirm with the user** — ONE question, then proceed (Claude Code:
1129
+ `AskUserQuestion` with the computed tier as the recommended option; Codex: plain
1130
+ prompt — `agents/runtime-portability-protocol.md` § decision gate):
1131
+ "Tier `<computed>` → lane `<compact|full>`. Confermi?" Honor an override silently.
1132
+ 3. **Record** `tier:` and `lane:` in the state file (`## Tier` section). `TRIVIAL`/
1133
+ `LIGHT` → `lane: compact`; `HEAVY` → `lane: full`.
1134
+
1135
+ **Compact lane consequences** (each phase keeps its own doc as SSOT — this list only
1136
+ routes; `lane: full` changes NOTHING):
1137
+
1138
+ | Phase | Compact-lane behavior |
1139
+ |-------|----------------------|
1140
+ | 2.5 Research | Skipped by default (run only on explicit user request) |
1141
+ | 3 UI Design | Route through the EXISTING Step 3 decision tree toward `mockup-only`/`skipped`: no new-screen mockup generation for tweaks on existing screens |
1142
+ | 4 PRD | **Compressed prose, full structure**: keep ALL mandatory sections, write each in 1–2 paragraphs, drop genuinely-N/A sections per the existing rule (target ≤3 pages). NEVER skip ISA/Schema-Verification — downstream consumers read them |
1143
+ | 4.5 API-perf gate | Unchanged (already conditional on api/data surface) |
1144
+ | 5 Cards | **ONE child card + the mandatory epic** (HARD RULE 15 stands — the epic is a zero-cost tracker). The `prd-card-writer` § Proportionality lower-bound governs; pass the tier to the agent in its briefing |
1145
+ | 6 Audit | Deterministic validation (0-i, 0-ii, field-name) ALWAYS runs; agent-depth audits scale with `review_profile` as they already do — no extra teammate panel for a single light/balanced card |
1146
+
1147
+ The tier ALSO travels to the cards: `prd-card-writer` receives `tier: <value>` in its
1148
+ briefing and applies the Proportionality lower-bound + Rule C accordingly.
1149
+
1150
+ ---
1151
+
1114
1152
  ## Appendix — Mockup analysis schema
1115
1153
 
1116
1154
  Used by Step 1.6.5. Populate the `## UI Design` section of the state file with this
@@ -105,7 +105,14 @@ Mark task 3 as `in_progress`.
105
105
 
106
106
  ### PRD sections checklist
107
107
 
108
- Every PRD MUST include these sections (remove only when genuinely N/A):
108
+ Every PRD MUST include these sections (remove only when genuinely N/A).
109
+ **Compact lane (`lane: compact` from Step 2.1 Tier Gate)**: the STRUCTURE is unchanged —
110
+ keep every applicable section (downstream consumers read them: `prd-card-writer` Field
111
+ Grounding reads § Schema Verification, the backlog phase reads § 15 ISA, the Step 6 audit
112
+ reads the whole document) — but write each section in **1–2 paragraphs**, collapse related
113
+ sections' prose (Personas + User stories may share one compact narrative), and drop
114
+ genuinely-N/A sections per the existing rule. Target ≤3 pages. Compression is in the
115
+ PROSE, never in the section inventory:
109
116
 
110
117
  - Problem statement
111
118
  - Strategic rationale (Section 1b — from `## Business Rationale` in state file)
@@ -554,7 +554,15 @@ async function runCard(cardId, cardPath) {
554
554
  const baselinePath = `/tmp/arch-baseline-${cardId}.md`
555
555
  const phase1 = { architect: 'inline-fallback', audit: 'skipped-no-drift' }
556
556
  let arch = null
557
- try {
557
+ // v5.4.0 light lane — a light/skip card (Rule C: ≤3 files, no logic-risk signal) grounds
558
+ // INLINE via its owner instead of a dedicated retriever spawn (AGENTS.md § Change Tiers,
559
+ // orchestrated-pipeline exception): at that scale the spawn costs more than the exploration
560
+ // it isolates (FEAT-0067: ~1.0-1.5M per retriever + schema retries). balanced/deep keep it.
561
+ const lightLane = reviewProfile === 'light' || reviewProfile === 'skip'
562
+ if (lightLane) {
563
+ phase1.architect = 'inline-light'
564
+ g('phase1-architect', 'INLINE-LIGHT', `review_profile=${reviewProfile} — no dedicated retriever; owner grounds inline (AGENTS.md § Change Tiers exception)`)
565
+ } else try {
558
566
  arch = await agentSafe(
559
567
  `You are the Phase-1 context retriever for card ${cardId} (per ${REF}/implement.md Phase 1 step 3 / 5b). cd into the worktree ${sharedCtx.worktreePath}.\n\n` +
560
568
  // Analysis profile (v4.94.0 — implement.md step 3 parallel): deterministic from the
@@ -608,7 +616,9 @@ async function runCard(cardId, cardPath) {
608
616
  // --- Phase 2: dispatch the card's OWNER_AGENT (F-024), not general-purpose. ---
609
617
  const phase1Brief = architectOk
610
618
  ? `Phase 1 already ran as specialist agents. READ the architecture baseline at ${baselinePath} BEFORE writing any code — it is your codebase context; do NOT redo the exploration.${auditCorrections.length ? `\nPlan-audit corrections (apply them as amendments to this briefing — do NOT modify the backlog YAML):\n${auditCorrections.map((c, i) => ` ${i + 1}. ${c}`).join('\n')}` : ''}`
611
- : `Phase 1 fallback: the architect specialist was unavailable — do the Phase 1 claim+architect exploration yourself per ${REF}/implement.md and persist the baseline to ${baselinePath} before coding.`
619
+ : phase1.architect === 'inline-light'
620
+ ? `Phase 1 light lane (v5.4.0): this card is review_profile '${reviewProfile}' (≤3-file scale) — no dedicated retriever ran. Ground INLINE per AGENTS.md § Change Tiers (orchestrated-pipeline exception): BEFORE writing code, read the files in scope + their immediate integration points (imports/consumers). Scoped exploration of the touched area only — not a repo sweep; the understanding obligation is unchanged, only the delegation was waived.${features.has_i18n ? ' I18N (light lane): NO separate fill pass runs for this card — fill EVERY target locale yourself for any new key (context-aware from the registry); the anti-hardcoded lint gate must pass.' : ''}`
621
+ : `Phase 1 fallback: the architect specialist was unavailable — do the Phase 1 claim+architect exploration yourself per ${REF}/implement.md and persist the baseline to ${baselinePath} before coding.`
612
622
  // T1.A (v4.90.0) — mockup cards: binding-compliance is verified deterministically by the
613
623
  // check-bindings.mjs script (ui-implement Step 5b is the SSOT; this is the new2 parallel).
614
624
  const bindingBit = node.hasMockup && node.hasBindings
@@ -660,7 +670,10 @@ async function runCard(cardId, cardPath) {
660
670
  // v5.0.0 — explicit i18n fill pass (implement.md step 7c mirror; closes the measured leakage
661
671
  // where locale fills were spawned as general-purpose). The translator is named BY TYPE; it
662
672
  // self-detects new source-locale keys from the diff and no-ops cheaply when there are none.
663
- if (features.has_i18n) {
673
+ // v5.4.1 minimal light lane — no separate fill pass: the owner filled every locale itself
674
+ // (its briefing carries the instruction) and the Phase-2 anti-hardcoded lint gate enforces it.
675
+ if (features.has_i18n && lightLane) g('i18n-fill', 'SKIP', 'light lane — owner fills locales inline; lint gate enforces')
676
+ else if (features.has_i18n) {
664
677
  try {
665
678
  const fill = await agentSafe(
666
679
  `You are i18n-translator (fill pass for card ${cardId} — agents/i18n-protocol.md per-card cascade). cd into the card worktree. FIRST detect deterministically whether this card's diff (/tmp/diff-${cardId}.txt) added NEW source-locale keys; if none → return { ran:false, keys:0 } immediately (no-op). If keys exist: fill the missing TARGET locales for exactly those keys, context-aware from the registry at ${paths.i18n_registry || 'the i18n registry'} — the source locale stays untouched (the coder is source-only by design). Then re-run the project's locale-parity check if one exists. Return: { ran, keys, note }`,
@@ -824,7 +837,14 @@ async function runCard(cardId, cardPath) {
824
837
  }
825
838
  let reviewers
826
839
  if (reviewProfile === 'skip') reviewers = []
827
- else if (reviewProfile === 'light') reviewers = codexAvail ? ['codex'] : ['code-reviewer']
840
+ else if (reviewProfile === 'light') {
841
+ reviewers = codexAvail ? ['codex'] : ['code-reviewer']
842
+ // v5.4.1 minimal light lane — a single-card light batch skips the Final workflow when its
843
+ // per-card review is clean (nothing post-fix to verify), so doc coverage cannot defer
844
+ // there: run the scoped doc-reviewer per-card instead. Multi-card light keeps the
845
+ // deferral (the Final batch pass still runs and covers it).
846
+ if (cardIds.length === 1) reviewers.push('doc-reviewer')
847
+ }
828
848
  else if (noEvidence) reviewers = FULL_FANOUT // balanced/deep, no surface evidence → conservative full
829
849
  else reviewers = relevanceGated() // balanced AND deep — surface-gated breadth
830
850
  if (reviewProfile !== 'skip') g('review-matrix', 'PLANNED', `[${reviewProfile}${noEvidence ? '→conservative-full (no surface evidence)' : ''}] ${reviewers.join('+') || '(none)'} · docs:${touchesDocs} code:${touchesCode} api/data:${touchesApiData} sec:${securityRelevant}`)
@@ -964,8 +984,13 @@ async function runCard(cardId, cardPath) {
964
984
  // B6 — which reviewers ACTUALLY ran (the gated matrix); Phase Final keys its slim/skip
965
985
  // decision on this, and per_card telemetry records it for the A/B spawn accounting.
966
986
  reviewersRun: reviewers,
967
- // B7 — Phase-1 specialist record (architect: done|inline-fallback; audit: pass|fixes|skipped-*).
987
+ // B7 — Phase-1 specialist record (architect: done|inline-fallback|inline-light; audit: pass|fixes|skipped-*).
968
988
  phase1,
989
+ // v5.4.1 minimal light lane — Phase Final keys its skip on these: a single light card whose
990
+ // per-card review surfaced NOTHING actionable has no post-fix state for the Final pass to
991
+ // verify (the Final review's purpose — v4.56.1 — is POST-fix verification, not re-review).
992
+ lightLane,
993
+ cleanReview: blocks.length === 0 && scopeExp.length === 0,
969
994
  scopeFiles, archBaselinePath: `/tmp/arch-baseline-${cardId}.md`, gates,
970
995
  }
971
996
  }
@@ -1141,7 +1166,13 @@ const committed = perCardResults.filter((r) => r.status === 'committed')
1141
1166
  phase('Final')
1142
1167
  let finalSummary = null
1143
1168
  let mergeBlocked = degraded
1144
- if (committed.length && !degraded) {
1169
+ // v5.4.1 minimal light lane — ONE light card, clean per-card review (zero actionable
1170
+ // findings → zero fixes applied): the Final pass has nothing post-fix to verify and its
1171
+ // doc coverage already ran per-card (the light single-card matrix includes doc-reviewer).
1172
+ // Any finding/fix on the card, any second card, or any degradation → Final runs as always.
1173
+ const skipFinalLight = committed.length === 1 && committed[0].lightLane && committed[0].cleanReview && !degraded
1174
+ if (skipFinalLight) ledger(firstCard, 'final-review', 'SKIPPED', 'single light card, clean per-card review — nothing post-fix to verify (doc ran per-card)')
1175
+ if (committed.length && !degraded && !skipFinalLight) {
1145
1176
  const reviewScopeFiles = dedupe(committed.flatMap((r) => r.scopeFiles || []))
1146
1177
  const archPaths = committed.map((r) => r.archBaselinePath).filter(Boolean)
1147
1178
  const allArch = archPaths.length === committed.length ? archPaths : null
@@ -1285,7 +1316,11 @@ if (!committed.length) {
1285
1316
  // Phase Production (Phase 7) — non-blocking; report-not-execute (F-011 infra-deferred).
1286
1317
  // ───────────────────────────────────────────────────────────────────────────
1287
1318
  phase('Production')
1288
- if (mergeResult && mergeResult.merged) {
1319
+ if (mergeResult && mergeResult.merged && committed.length && committed.every((r) => r.lightLane)) {
1320
+ // v5.4.1 minimal light lane — light cards carry no deployable surface by Rule C (no
1321
+ // migrations/indexes/cron/schema); the checklist would only burn a spawn to report zero items.
1322
+ ledger(firstCard, 'phase7-production', 'SKIPPED', 'all-light batch — no deployable surface (Rule C)')
1323
+ } else if (mergeResult && mergeResult.merged) {
1289
1324
  try {
1290
1325
  // Schema-deploy-from-trunk-only invariant (v4.33.0): a remote schema/RLS/index/
1291
1326
  // migration deploy desyncs a shared remote datastore when run off-trunk. When the
@@ -4,6 +4,19 @@ Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://sem
4
4
  Questo è il changelog INTERNO dello skeleton spedito (`primitive_version`), separato dal
5
5
  file `AGENTS.md` generato nel consumer e indipendente dal `VERSION` del framework.
6
6
 
7
+ ## 1.8.0 — 2026-07-03
8
+
9
+ - **§ Change Tiers — orchestrated-pipeline grounding exception.** Inside a `/new`/`new2`
10
+ run, a `review_profile: light|skip` card satisfies the (unchanged) understanding
11
+ obligation by the OWNER agent grounding inline instead of a dedicated
12
+ `codebase-architect` spawn — delegation waived at ≤3-file scale, obligation intact.
13
+ Driven by the FEAT-0067 post-mortem (a dedicated retriever per tiny card costs more
14
+ than the exploration it isolates). `balanced`/`deep` keep the spawn.
15
+ - **§ Change Tiers — Heavy trigger refined.** "introduces a new DB schema / migration" →
16
+ "changes DB STRUCTURE"; an ADDITIVE index-only migration is no longer Heavy by itself
17
+ (it keeps Rule C `db_indexes` review depth + the api-perf gate). Prevents a perf index
18
+ riding along a small feature from multiplying the whole planning ceremony.
19
+
7
20
  ## 1.7.4 — 2026-07-03
8
21
 
9
22
  - **Commit-format MUST scoped to card-bound work — no borrowed card IDs, no inherited
@@ -1,4 +1,4 @@
1
- <!-- baldart-primitive: name=AGENTS primitive_version=1.7.4
1
+ <!-- baldart-primitive: name=AGENTS primitive_version=1.8.0
2
2
  This is the SHIPPED SKELETON. The writer (src/utils/root-primitives.js) strips
3
3
  this banner, resolves every {{ slot }} / {{> partial }} / {{#flag}} from
4
4
  baldart.config.yml (+ package.json/README), merges .baldart/overlays/AGENTS.md,
@@ -130,6 +130,12 @@ doubt, treat it as Light** and escalate only when a Heavy trigger is actually pr
130
130
  NOT part of this tier-gated machinery** — it precedes the tier decision and applies to Light
131
131
  too; only a Trivial one-liner or a bare symbol-presence Grep skips it, and any UI work —
132
132
  change OR a spec/responsive-grounded verification — always grounds via `PROFILE=ui`.
133
+ **Orchestrated-pipeline exception (scale, not obligation):** inside a `/new`/`new2` run, a
134
+ card authored `review_profile: light` or `skip` (Rule C: ≤3 files, no logic-risk signal)
135
+ satisfies the understanding obligation by the owner agent grounding INLINE in its own
136
+ context instead of a separate `codebase-architect` spawn — the obligation is unchanged,
137
+ only the delegation is waived at that scale (a dedicated retriever for a ≤3-file diff costs
138
+ more than the exploration it isolates). `balanced`/`deep` cards keep the dedicated spawn.
133
139
 
134
140
  - **Trivial** — a one-liner, typo, or obvious bug with a clear fix. Just do it.
135
141
  - **Light** — the default for most work. Any change that does **not** hit a Heavy trigger,
@@ -139,9 +145,13 @@ change OR a spec/responsive-grounded verification — always grounds via `PROFIL
139
145
  `codebase-architect` first** when the task needs real understanding (UI work — change or
140
146
  spec/responsive-grounded verification → `PROFILE=ui`).
141
147
  Docs stay in sync and the pre-commit gates still run.
142
- - **Heavy** — escalate ONLY when the change: introduces a new DB schema / migration; adds a
143
- new external dependency; adds a new API contract / route or a new domain entity; is a wide
144
- or cross-module refactor; or runs in parallel with other agents/sessions on shared files.
148
+ - **Heavy** — escalate ONLY when the change: changes DB **structure** (new table, column,
149
+ constraint, RLS policy, or any destructive migration an ADDITIVE index-only migration is
150
+ NOT by itself Heavy: it is a rollback-safe performance artifact that keeps its per-card
151
+ review depth via Rule C `db_indexes` and the api-perf gate, without multiplying the
152
+ planning ceremony); adds a new external dependency; adds a new API contract / route or a
153
+ new domain entity; is a wide or cross-module refactor; or runs in parallel with other
154
+ agents/sessions on shared files.
145
155
  → Full machinery: plan mode → reviewed plan (`plan-auditor` + `doc-reviewer`) → delegation
146
156
  to the domain agent → a git **worktree** (`/nw`) → a backlog card (when the backlog feature
147
157
  is on). Project overlays may add project-specific Heavy triggers.
@@ -4,6 +4,12 @@ Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://sem
4
4
  Changelog INTERNO dello stub spedito (`primitive_version`), separato dal `CLAUDE.md`
5
5
  generato nel consumer e indipendente dal `VERSION` del framework.
6
6
 
7
+ ## 1.4.3 — 2026-07-03
8
+
9
+ - Plan Mode section: parenthetical pointing to the new AGENTS.md § Change Tiers
10
+ orchestrated-pipeline exception (light|skip cards ground inline via the owner agent
11
+ inside `/new`/`new2`) — keeps the two primitives from drifting on the grounding rule.
12
+
7
13
  ## 1.4.2 — 2026-07-02
8
14
 
9
15
  - **Name the built-in `Explore` guard for the understanding step**: § Subagents now says the
@@ -1,4 +1,4 @@
1
- <!-- baldart-primitive: name=CLAUDE primitive_version=1.4.2
1
+ <!-- baldart-primitive: name=CLAUDE primitive_version=1.4.3
2
2
  SHIPPED SKELETON. The writer strips this banner, resolves {{ slot }}/{{#flag}} from
3
3
  baldart.config.yml, merges .baldart/overlays/CLAUDE.md, stamps a baldart-generated
4
4
  marker, and writes the result to the repo root.
@@ -23,7 +23,9 @@ understanding you don't already have, and **every UI task grounds via `PROFILE=u
23
23
  OR a verification/question whose correct answer needs design-system-spec or responsive/state
24
24
  grounding (e.g. "is page X already on the new layout, on desktop and tablet?") — even for a small
25
25
  tweak. Only a genuine Trivial one-liner or a bare symbol-presence check (does file X import Y)
26
- skips it. For a Heavy task:
26
+ skips it. (Inside a `/new`/`new2` pipeline run, a `review_profile: light|skip` card grounds
27
+ inline via its owner agent instead of a dedicated spawn — see `AGENTS.md` § Change Tiers,
28
+ orchestrated-pipeline exception.) For a Heavy task:
27
29
 
28
30
  - Enter plan mode (`EnterPlanMode`) before writing code.
29
31
  - Invoke `codebase-architect` before writing the plan — never plan blind. Pass the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "5.3.2",
3
+ "version": "5.4.1",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"