baldart 4.7.0 → 4.9.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 +28 -1
- package/README.md +23 -11
- package/VERSION +1 -1
- package/framework/.claude/agents/prd-card-writer.md +15 -5
- package/framework/.claude/skills/baldart-update/SKILL.md +112 -163
- package/package.json +1 -1
- package/src/commands/overlay.js +1 -1
- package/src/commands/update.js +261 -126
- package/src/utils/__tests__/overlay-capture.test.js +215 -0
- package/src/utils/git.js +0 -15
- package/src/utils/overlay-capture.js +225 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,34 @@ 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.
|
|
8
|
+
## [4.9.0] - 2026-06-04
|
|
9
|
+
|
|
10
|
+
**`prd-card-writer` Rule C apre `light` alle card UI-presentazionali — la metà `-ui` di una coppia split non paga più una review Codex piena su un diff di pixel.** Finora il pavimento era assoluto: *ogni* card `feature`/`enhancement` era `balanced` minimo, mai `light`. La regola nasceva giusta (non sotto-revisionare feature che *sembrano* piccole ma nascondono logica), ma non distingueva una UI card che *contiene* logica da quella genuinamente presentazionale — tipicamente la metà `-ui` di una coppia `logic/ui` già splittata dalla atomicity rule (es. `…-submit-ui`, la cui logica vive nella card sorella `…-submit-logic`). Risultato: su un epic come FEAT-0019, card puramente compositive venivano marcate `balanced` → review Codex-`full` per-card su un diff di soli componenti. Nuovo **ramo LIGHT (b)**, recintato e deterministico: scatta SOLO se TUTTE valgono — card pure-UI (`areas == [ui]`, o `owner_agent: ui-expert` quando `areas` è assente) · ≤3 file, tutti componenti/stili (zero data-fetching / state / API / server) · **nessun path sotto `paths.components_primitives`** (compone primitive esistenti, non ne crea/modifica) · nessun trigger DEEP. **MINOR** (nuova capability di routing in Rule C; nessuna chiave `baldart.config.yml` — si appoggia su `areas`/`owner_agent`/`paths.components_primitives` già esistenti).
|
|
11
|
+
|
|
12
|
+
> **Why.** Il taglio è sicuro perché **la rete DS non dipende dal `review_profile`**: una card `light` mantiene la sua code-review per-card/group con `code-reviewer` rule 8 + la cascade registry-first (gated su `features.has_design_system`), ed è coperta dalla **Final FULL gate** cross-batch — si rimanda solo il Codex-*adversarial* per-card. Quindi la DS-drift (hex/shadow/radius hardcoded = HIGH) viene comunque beccata. Il ramo è **stretto per costruzione**: ogni indizio di logica/state/data-binding, un primitive nuovo/modificato, o `areas` oltre `[ui]` → la card resta `balanced` (la guida resta "in dubbio, `deep`"). Coerente col principio "data-driven sopra threshold arbitrarie": niente soglia a righe, solo segnali strutturali autorati in PRD. Validato su FEAT-0019: dei 3 card `-ui`, solo `05b` (2 file componenti, logica su 05a, compone `BottomActionBar`) qualifica; `06b` (4 file + validazione UI/View Transitions) e `07` (5 file, tocca i view-model + render permission-gated) restano correttamente `balanced`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`framework/.claude/agents/prd-card-writer.md`** — Rule C: riga LIGHT estesa col ramo (b) UI-presentational (predicato recintato a 4 condizioni AND); paragrafo "Critical" riscritto — il pavimento `balanced` per `feature`/`enhancement` ora ha **l'unica eccezione** del ramo (b), col razionale (rete DS profilo-indipendente) e i disqualifier espliciti. SSOT invariato altrove: la fallback table del `/new` continua a puntare a Rule C, il routing escalation-only `light`→`full` resta intatto (una UI card `light` è sempre promuovibile da un trigger Step-A).
|
|
17
|
+
|
|
18
|
+
## [4.8.0] - 2026-06-03
|
|
19
|
+
|
|
20
|
+
**`baldart update` diventa seamless: un solo comando, zero iterazioni — aggiorna e preserva gli overlay.** Un transcript reale (`v4.2.1 → v4.3.0`) ha richiesto **3 invocazioni fallite + git surgery manuale** per un'operazione il cui lavoro è sempre lo stesso. Le cause erano bug di design del CLI, ora rimossi: (1) **asimmetria stash** — `--yes` auto-stasciava il tree sporco ma il path `--reset` lo *rifiutava*, buttando via l'autorizzazione dell'utente e costringendo a stash/drop/mv-a-/tmp/pop a mano; (2) **hard-stop su divergenza già sicura** — il CLI calcolava `overlayCoversTouched` (sa che gli edit sono già negli overlay, lo scrive: "--reset is safe") ma sotto `--yes` *rifiutava* invece di procedere; (3) **flag-maze** — per sbloccarsi serviva `--reset --yes --i-know`, combo da indovinare; (4) **finalizer assente sul path reset** — i generated-agents + `state.json` restavano uncommitted; (5) **preview morta** — `git log HEAD..FETCH_HEAD -- .framework/` è sempre vuoto col subtree-squash. Ora `npx baldart update --yes` fa tutto in un colpo: auto-stash (motore unico, `git stash push -u` senza pathspec → niente più fallimenti su dir `.gitignore`d), auto-risoluzione della divergenza (overlay-covered → reinstall pulito che riapplica gli overlay; **uncovered → auto-cattura in overlay popolati dal diff + VERIFICA che il merge riproduca l'edit** prima del reinstall), riconcilia + committa gli artefatti BALDART-managed (finalizer anche sul path reset), e ripristina lo stash. **MINOR** (capability aggiunta, comandi invariati e retrocompatibili; nessuna chiave `baldart.config.yml`).
|
|
21
|
+
|
|
22
|
+
> **Why.** L'intent dell'utente è vincolante: *"voglio che tutto il processo sia seamless, niente iterazioni — le cose da fare sono sempre le stesse: aggiornare e preservare gli overlay"* (coerente col principio "rispetta l'intent esplicito vs advisor"). L'unica collisione possibile tra "seamless" e "non perdere dati" è un edit a un file framework **non** coperto da overlay: la scelta dell'utente è **auto-cattura + verifica** — il CLI genera l'overlay dal diff (modello section-marker di `overlay-merger.js`) e ri-merge contro il base upstream fresco; se il risultato riproduce l'edit a livello di sezioni+preamble procede muto, altrimenti **si ferma una sola volta** (`divergence-capture-incomplete`) elencando i blocker (section deletion, cambio frontmatter/preamble, file `src/`) — mai un'azione distruttiva silenziosa. La verifica è la rete di sicurezza che rende la cattura sicura a prescindere dalla fedeltà dell'algoritmo. Gli escape hatch espliciti (`--on-divergence pull|scaffold-overlays|abort`, `--reset --yes --i-know`) restano per CI/power-user, ma non sono più il path che l'utente deve scoprire: il default È quello seamless.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`src/utils/overlay-capture.js`** — nuovo modulo `captureAndVerify`: verifica che OGNI edit overlay-able divergente sia preservato da un overlay, esistente o catturato. Per agents/commands è **verificabile** — ri-merge l'overlay (esistente o generato dal diff via `[OVERRIDE]`/H2 plain) contro il base upstream fresco (`FETCH_HEAD`) e confronta sezioni ordinate + preamble; un overlay **esistente ma stale** (non riproduce l'edit `.framework` corrente) diventa un **blocker**, non una perdita silenziosa al reset. Per le skill (runtime-concat, non mergiabili dal CLI) un overlay esistente è fidato, l'assenza è un blocker. Path non mappabili → blocker. Il chiamante passa l'INTERO set di file toccati (mai un sottoinsieme pre-filtrato): un pre-filtro lascerebbe il reset cancellare un edit senza overlay che lo preservi. Esporta helper unit-testabili (12+ test).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **`src/commands/update.js`** — (a) **motore di stash unico** `autoStashNonFramework` (blanket `git stash push -u`, niente pathspec) riusato sia dalla normale flow sia da `runReset` (che prima *rifiutava* il tree sporco). (b) **`runReset` finalizer**: re-apply dello stash + `postUpdateAutoCommit` + emissione JSON (`action: 'reset'`) → tree pulito su tutti i path. (c) **divergenza overlay-able**: il default sotto `--yes` non rifiuta più — `resolveOverlayDivergenceSeamlessly` cattura+verifica gli uncovered (committandoli **prima** del reset così sopravvivono allo stash e alimentano il merge), poi reset-and-reapply; stop singolo solo su blocker. (d) **divergenza mixed/real-custom**: cattura il sottoinsieme overlay-able e si ferma una volta (i path `src/`/CHANGELOG non sono auto-risolvibili). (e) **preview reale**: `changelogSinceInstalled` mostra le entry del CHANGELOG upstream tra versione installata e remota (rimpiazza e **rimuove** il dead-code `git.diffWithRemote`, diff opt-in sempre-vuoto col subtree-squash). `--i-know` resta esplicito solo per il `--reset` standalone (implicito nel path seamless).
|
|
31
|
+
- **`src/utils/git.js`** — rimosso il metodo morto `diffWithRemote` (nessun chiamante dopo la nuova preview).
|
|
32
|
+
- **`src/commands/overlay.js`** — esporta `buildFrontmatter` (riusato da `overlay-capture.js` per scrivere overlay con frontmatter valido senza re-implementare la logica).
|
|
33
|
+
- **`framework/.claude/skills/baldart-update/SKILL.md`** — riscritta per il flusso seamless: rimossa la replica chat dei 2 decision-point (preview + stash) e lo step di preview morto; la skill ora lancia `npx baldart update --yes` e riporta, sorvegliando l'unica pausa legittima (`divergence-capture-incomplete`). Description frontmatter, Hard rule #2, tabella decision-point, workflow (Step 0/1/2) e DRIFT-CHECK (`update_js_prompts: 5`, `last_verified: v4.8.0`) allineati.
|
|
34
|
+
|
|
35
|
+
|
|
9
36
|
|
|
10
37
|
**`/new` smette di rifare per-card 4 review che la Final FULL gate già ripete sull'intero batch.** La Final Review F.3 gira sempre, incondizionata, su tutto il diff di batch: Codex + **doc-reviewer** + **api-perf-cost-auditor** + **qa-sentinel** (suite completa + build + audit). Quindi le passate *per-card* di quegli stessi reviewer sono, per la sicurezza del merge-gate, già coperte dalla rete finale — il loro unico valore residuo è il fail-fast/attribuzione. Quattro pruning, tutti deterministici e con la Final come rete: (1) **plan-auditor grounding** saltato (sequential) quando `/prd` ha già fatto l'holistic audit (`metadata.holistic_audit`) e non c'è drift sui path della card — mirror esatto del gate v4.3.0 Step 3d; (2) **doc-review per-card** deferita alla Final per le card `light` il cui diff non tocca file di documentazione; (3) **qa-sentinel per-card** che gira solo per `deep` (o `balanced` escalata da risk-drift) — `balanced` non-rischiose deferiscono la suite alla Final; (4) **api-perf-cost-auditor per-card** droppato via nuovo flag lean-contract `skip_api_perf_auditor`, deferito alla Final. **MINOR** (comportamento `/new` più lean; nessuna chiave `baldart.config.yml` — si appoggia su `review_profile` + `metadata.holistic_audit` già esistenti).
|
|
11
38
|
|
package/README.md
CHANGED
|
@@ -449,20 +449,32 @@ npx baldart add owner/repo # Install from custom fork
|
|
|
449
449
|
|
|
450
450
|
### `npx baldart update`
|
|
451
451
|
|
|
452
|
-
Update framework to latest version.
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
-
|
|
457
|
-
-
|
|
452
|
+
Update framework to latest version — **seamless** (v4.8.0+): one command, zero
|
|
453
|
+
iterations. The job is always the same — update and preserve overlays — so the
|
|
454
|
+
CLI does the whole thing in one shot:
|
|
455
|
+
|
|
456
|
+
- Shows the upstream CHANGELOG between your version and the remote
|
|
457
|
+
- Auto-stashes any non-framework work and re-applies it after (single blanket
|
|
458
|
+
stash; handles tracked files inside `.gitignore`d dirs)
|
|
459
|
+
- Creates a backup tag (`git reset --hard <tag>` to roll back)
|
|
460
|
+
- Resolves divergence automatically: edits already covered by an overlay → clean
|
|
461
|
+
reinstall that re-applies the overlays; **uncovered edits → auto-captured into
|
|
462
|
+
overlays and verified** (the merge must reproduce the edit) before reinstall
|
|
463
|
+
- Updates via Git subtree, verifies symlinks, and commits the BALDART-managed
|
|
464
|
+
reconcile — leaving a clean tree
|
|
465
|
+
|
|
466
|
+
It stops **once** only when an edit cannot be captured+verified faithfully (a
|
|
467
|
+
section deletion, a frontmatter/preamble change, a `src/` change) — never a
|
|
468
|
+
silent destructive action.
|
|
458
469
|
|
|
459
470
|
**For agents / CI (v3.32.0+):** `npx baldart update --json --yes` emits a single
|
|
460
471
|
machine-readable result object on stdout (`{schema:"baldart.update/1", ok,
|
|
461
|
-
action, installed_after, backup_tag, next_command, …}`) with all human
|
|
462
|
-
stderr — no prose to scrape. `ok:true` ⟺ the framework is now at the
|
|
463
|
-
version
|
|
464
|
-
`--on-divergence pull|scaffold-overlays|abort`
|
|
465
|
-
|
|
472
|
+
action, installed_after, backup_tag, blockers, next_command, …}`) with all human
|
|
473
|
+
output on stderr — no prose to scrape. `ok:true` ⟺ the framework is now at the
|
|
474
|
+
remote version (`action` is `updated`, `reset`, or `already-current`). The escape
|
|
475
|
+
hatches `--reset --yes --i-know` and `--on-divergence pull|scaffold-overlays|abort`
|
|
476
|
+
still exist for power users, but the seamless default makes them unnecessary.
|
|
477
|
+
`--json` requires `--yes` and rejects an explicit `--reset`.
|
|
466
478
|
|
|
467
479
|
### `npx baldart` (no args) / `doctor` (v3.2.0+)
|
|
468
480
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.
|
|
1
|
+
4.9.0
|
|
@@ -187,14 +187,24 @@ Apply the **first matching rule** (priority order — top wins):
|
|
|
187
187
|
| Profile | When to assign |
|
|
188
188
|
|---------|----------------|
|
|
189
189
|
| **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) |
|
|
190
|
-
| **LIGHT** | Card is a `bugfix` or `refactor` — AND ≤3 files in `files_likely_touched` — AND none of the DEEP high-risk keywords/areas apply. **NEVER for `feature`
|
|
190
|
+
| **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. Branch (a) is **NEVER for `feature`/`enhancement` cards**; branch (b) is the ONLY route by which a `feature`/`enhancement` card may be `light`. |
|
|
191
191
|
| **SKIP** | Card is `docs`, `chore`, or `config` — OR all `files_likely_touched` are `.md`/non-API `.yml`/CSS with zero logic files — OR a pure-cosmetic card (typo/rename/copy/wording/style) with no code areas |
|
|
192
192
|
| **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 |
|
|
193
193
|
|
|
194
|
-
**Critical**: `feature` and `enhancement` cards are
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
**Critical**: `feature` and `enhancement` cards are `balanced` minimum — **with exactly one
|
|
195
|
+
exception**: the LIGHT branch (b) above, a strictly UI-presentational card (`areas == [ui]`,
|
|
196
|
+
≤3 component/style files, composes existing primitives without touching any
|
|
197
|
+
`paths.components_primitives` path). This narrow carve-out targets the `-ui` half of a
|
|
198
|
+
logic/ui split pair (e.g. a `…-submit-ui` card whose logic lives in its `…-submit-logic`
|
|
199
|
+
sibling): reviewing a pixels-only diff at Codex-`full` depth is waste, and the design-system
|
|
200
|
+
safety net still fires regardless of profile (a `light` card keeps its per-card/group
|
|
201
|
+
code-review with `code-reviewer` rule 8 / the registry-first DS cascade, and is covered by
|
|
202
|
+
the batch-wide Final FULL gate — only the per-card Codex-*adversarial* pass is deferred). Any
|
|
203
|
+
doubt — a hint of logic, state, data binding, a new/modified primitive, or `areas` beyond
|
|
204
|
+
`[ui]` — disqualifies branch (b): the card stays `balanced`. When in doubt between `balanced`
|
|
205
|
+
and `deep`, choose `deep`. `files_likely_touched` counts are advisory only — never downgrade a
|
|
206
|
+
**logic-bearing** card below `balanced` because the file count looks small. **Epic cards**
|
|
207
|
+
always use `review_profile: skip` (no code work).
|
|
198
208
|
|
|
199
209
|
The human author MAY override the computed value by editing the card YAML — e.g. to
|
|
200
210
|
force `deep` on a card they consider sensitive. Honor any explicit value already present;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: baldart-update
|
|
3
3
|
effort: medium
|
|
4
|
-
description: "Guidance for updating BALDART framework to the latest version in a consumer repo. Use when the user says /baldart-update, 'aggiorna baldart', 'aggiorna framework', 'update del framework', 'pull baldart latest', or wants to bring the framework up-to-date.
|
|
4
|
+
description: "Guidance for updating BALDART framework to the latest version in a consumer repo. Use when the user says /baldart-update, 'aggiorna baldart', 'aggiorna framework', 'update del framework', 'pull baldart latest', or wants to bring the framework up-to-date. The update is SEAMLESS (v4.8.0+): a single `npx baldart update --yes` auto-stashes non-framework work, auto-resolves divergence (overlay-covered edits → clean reinstall that re-applies overlays; uncovered edits → auto-captured into overlays and verified), reconciles + commits BALDART-managed artifacts, and re-applies the stash — zero prompts in the happy path. The skill only narrates and reports; it never re-implements the CLI or replicates its prompts. Two modes, auto-detected: INTERACTIVE (a human is present) and AUTONOMOUS (unattended — CI / scheduled routine, signalled by BALDART_AUTONOMOUS / CI / GITHUB_ACTIONS env, uses --json). The CLI stops ONCE only when an edit cannot be captured+verified (a section deletion, a frontmatter/preamble change, a src/ change) — the skill surfaces that single pause. Always asserts post-flight that .framework/VERSION actually changed. For non-update drift, defers to `npx baldart` (smart doctor)."
|
|
5
5
|
contamination_scan: skip
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -13,10 +13,10 @@ pull_request). When any of the numbers below changes against the actual
|
|
|
13
13
|
sources, a warning is surfaced in the workflow run. The decision whether
|
|
14
14
|
this skill needs an update is left to a human reviewer.
|
|
15
15
|
|
|
16
|
-
update_js_prompts:
|
|
16
|
+
update_js_prompts: 5
|
|
17
17
|
hook_registry_entries: 4
|
|
18
18
|
config_template_top_level_keys: features,git,identity,lsp,paths,stack,tools,version
|
|
19
|
-
last_verified:
|
|
19
|
+
last_verified: v4.8.0
|
|
20
20
|
-->
|
|
21
21
|
|
|
22
22
|
<!--
|
|
@@ -42,10 +42,13 @@ child agent to update autonomously can set it the same way.
|
|
|
42
42
|
|
|
43
43
|
# /baldart-update — Update framework in this consumer
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
Drive a **seamless** update of the BALDART framework inside the consumer repo.
|
|
46
|
+
The CLI does the whole job in one shot — `npx baldart update --yes` — and the
|
|
47
|
+
job is always the same: **update and preserve overlays**. The skill runs that
|
|
48
|
+
command, watches for the single legitimate pause (an edit that can't be
|
|
49
|
+
captured+verified), and reports. It does NOT replicate the CLI's old
|
|
50
|
+
preview/stash confirmations (the CLI handles both automatically since v4.8.0)
|
|
51
|
+
and it NEVER re-implements the CLI's logic.
|
|
49
52
|
|
|
50
53
|
```
|
|
51
54
|
╔══════════════════════════════════════════════════════════════════════╗
|
|
@@ -89,35 +92,36 @@ printenv | grep -qE '^(BALDART_AUTONOMOUS|CI|GITHUB_ACTIONS)=' && echo AUTONOMOU
|
|
|
89
92
|
|
|
90
93
|
## Execution model (INTERACTIVE mode) — IMPORTANT
|
|
91
94
|
|
|
92
|
-
This is an **agent-driven skill
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
replicates every confirmation so nothing is silently auto-accepted.
|
|
95
|
+
This is an **agent-driven, seamless** skill. The flow is short:
|
|
96
|
+
|
|
97
|
+
1. Run the *read-only* pre-flight: `npx baldart version` (+ the CLI version
|
|
98
|
+
drift gate). Already aligned → report "already current" and STOP.
|
|
99
|
+
2. Launch `npx baldart update --yes` via `Bash` (long timeout — see Hard
|
|
100
|
+
rules). No chat confirmation of preview or stash: the CLI auto-stashes the
|
|
101
|
+
dirty tree, shows the CHANGELOG preview itself, auto-resolves overlay-covered
|
|
102
|
+
divergence by a clean reinstall, auto-captures+verifies uncovered edits, and
|
|
103
|
+
auto-commits the BALDART-managed reconcile. The user authorized the seamless
|
|
104
|
+
behavior by invoking the skill — do not re-ask what the CLI already handles.
|
|
105
|
+
3. Post-flight assert that `.framework/VERSION` changed, then report the version
|
|
106
|
+
delta, backup tag, any agent-layout migration, and (if the CLI stopped at the
|
|
107
|
+
single capture pause) the verbatim blockers + next step.
|
|
108
|
+
|
|
109
|
+
The ONLY time the flow is not a single shot is when the CLI exits non-zero
|
|
110
|
+
because an edit could not be captured+verified faithfully (section deletion,
|
|
111
|
+
frontmatter/preamble change, or a `src/` change). That is a deliberate,
|
|
112
|
+
data-safety pause — surface it; never force past it.
|
|
111
113
|
|
|
112
114
|
## Autonomous mode (AUTONOMOUS) — unattended, zero prompts (v3.31.0+)
|
|
113
115
|
|
|
114
116
|
When mode detection returned `AUTONOMOUS`, there is no human to confirm
|
|
115
117
|
anything. The skill drives the update end-to-end with NO chat questions, and
|
|
116
|
-
leans entirely on the CLI's own safety gates — which
|
|
117
|
-
|
|
118
|
+
leans entirely on the CLI's own safety gates — which auto-resolve seamlessly
|
|
119
|
+
under bare `--yes` (auto-stash, overlay-covered reinstall, capture+verify of
|
|
120
|
+
uncovered edits) and **stop hard** only when an edit cannot be captured+verified
|
|
121
|
+
(`divergence-capture-incomplete`).
|
|
118
122
|
|
|
119
|
-
**The contract: autonomy over
|
|
120
|
-
|
|
123
|
+
**The contract: autonomy over the whole seamless flow, hard STOP only on an
|
|
124
|
+
edit that cannot be preserved safely.**
|
|
121
125
|
|
|
122
126
|
### Autonomous workflow
|
|
123
127
|
|
|
@@ -137,8 +141,10 @@ touches the user's custom content.**
|
|
|
137
141
|
requires `--yes` (it refuses interactively) and routes all human output to
|
|
138
142
|
stderr — **stdout carries exactly one JSON object**.
|
|
139
143
|
**Do NOT add `--on-divergence pull` or `--reset`.** Bare `--yes` is the
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
seamless ceiling (v4.8.0+): the CLI auto-stashes, auto-resolves overlay-covered
|
|
145
|
+
divergence by a clean reinstall, and auto-captures+verifies uncovered edits.
|
|
146
|
+
It exits non-zero only when an edit cannot be captured+verified faithfully
|
|
147
|
+
(action `divergence-capture-incomplete`) — a correct stop that a human owns.
|
|
142
148
|
|
|
143
149
|
**Fallback:** if the CLI predates v3.32.0 it rejects `--json` (unknown
|
|
144
150
|
option, non-zero exit, empty/garbled stdout). Re-run without it
|
|
@@ -146,11 +152,12 @@ touches the user's custom content.**
|
|
|
146
152
|
interpretation. Never let a missing `--json` block the update.
|
|
147
153
|
3. **Interpret the result — JSON first, exit code as the safety backstop:**
|
|
148
154
|
- With `--json`, parse the single stdout object. `ok === true` (action
|
|
149
|
-
`updated` or `already-current`) → success, go to post-flight
|
|
150
|
-
`installed_after` / `backup_tag`. `ok === false` → the CLI
|
|
151
|
-
failed; read `action` (`divergence-
|
|
152
|
-
`
|
|
153
|
-
`next_command`. Report them verbatim.
|
|
155
|
+
`updated`, `reset`, or `already-current`) → success, go to post-flight
|
|
156
|
+
using `installed_after` / `backup_tag`. `ok === false` → the CLI stopped
|
|
157
|
+
or failed; read `action` (`divergence-capture-incomplete`, `failed`,
|
|
158
|
+
`framework-missing`, `usage-error`), `reason`, `blockers`, and
|
|
159
|
+
`next_command`. Report them verbatim. `action: 'reset'` is the seamless
|
|
160
|
+
overlay-covered resolution — a normal success, not an escape hatch.
|
|
154
161
|
- The **exit code is still the contract** regardless of `--json`:
|
|
155
162
|
- **Exit 0** → update applied (or already aligned). Go to post-flight.
|
|
156
163
|
- **Exit non-zero** → the CLI hit a wall it will not cross unattended:
|
|
@@ -160,7 +167,7 @@ touches the user's custom content.**
|
|
|
160
167
|
mode, the verbatim stderr) so the human who reads the routine log knows
|
|
161
168
|
exactly what needs a hands-on decision. Forcing a merge or a reset
|
|
162
169
|
unattended is precisely the silent destruction this mode forbids.
|
|
163
|
-
4. **Post-flight assert (MANDATORY)** — identical to interactive Step
|
|
170
|
+
4. **Post-flight assert (MANDATORY)** — identical to interactive Step 2:
|
|
164
171
|
`cat .framework/VERSION`, compare to the pre-update version. If the CLI
|
|
165
172
|
exited 0 but VERSION did not change (and stdout is not "Already up to
|
|
166
173
|
date"), **FAIL LOUD** — do not report success. With `--json` this is a
|
|
@@ -169,16 +176,17 @@ touches the user's custom content.**
|
|
|
169
176
|
`ok:true` but `installed_after` ≠ on-disk VERSION) is the same FAIL LOUD.
|
|
170
177
|
5. **Report** — emit a structured, log-friendly summary (no questions):
|
|
171
178
|
version delta, backup tag + rollback command, any agent-layout migration
|
|
172
|
-
(v3.27.0+), and — on a non-zero exit — the
|
|
173
|
-
|
|
174
|
-
`
|
|
175
|
-
options; it never picks one autonomously.
|
|
179
|
+
(v3.27.0+), and — on a non-zero exit (`divergence-capture-incomplete`) — the
|
|
180
|
+
verbatim `blockers` list plus the `next_command` the CLI printed (typically
|
|
181
|
+
`npx baldart update --on-divergence pull`, or author the overlay by hand).
|
|
182
|
+
The skill names the options; it never picks one autonomously.
|
|
176
183
|
|
|
177
184
|
### What autonomous mode must NEVER do
|
|
178
185
|
|
|
179
186
|
- Ask a chat question (no one is there; a blocked prompt hangs the routine).
|
|
180
187
|
- Pass `--on-divergence pull|scaffold-overlays` or `--reset` to "get past" a
|
|
181
|
-
|
|
188
|
+
`divergence-capture-incomplete` stop. That stop is a *correct* outcome (an
|
|
189
|
+
edit that cannot be preserved safely) and needs a human.
|
|
182
190
|
- Report success when the post-flight assert fails.
|
|
183
191
|
- Auto-resolve a stash-pop or merge conflict with `--hard` / `--no-verify`.
|
|
184
192
|
|
|
@@ -234,13 +242,12 @@ precedence caveats: `framework/agents/effort-protocol.md`.
|
|
|
234
242
|
1. **MUST NOT re-implement the logic of `update.js`.** Same rule as
|
|
235
243
|
`/baldart-push`: the CLI is the source of truth. The skill only
|
|
236
244
|
replicates prompts and parses output.
|
|
237
|
-
2. **
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
`## Autonomous mode`; a blocked prompt hangs the routine.
|
|
245
|
+
2. **MUST NOT replicate CLI prompts in chat.** The seamless CLI (v4.8.0+) has
|
|
246
|
+
no happy-path prompts to replicate: it auto-stashes, shows its own CHANGELOG
|
|
247
|
+
preview, auto-resolves divergence, and auto-commits. Re-asking "Procedo?" or
|
|
248
|
+
"Stash?" is friction the user explicitly does not want. The only stop is the
|
|
249
|
+
CLI's own non-zero exit on an uncapturable edit — surface it, don't pre-empt
|
|
250
|
+
it. **(AUTONOMOUS mode) MUST NOT ask any chat question** either.
|
|
244
251
|
3. **MUST pass `timeout: 600000` (10 minutes)** to the `Bash` call running
|
|
245
252
|
`npx baldart update --yes`. The default 120s is not enough for subtree
|
|
246
253
|
pull + symlink reconcile + post-update wizard + hooks register +
|
|
@@ -256,39 +263,40 @@ precedence caveats: `framework/agents/effort-protocol.md`.
|
|
|
256
263
|
how to proceed or aborts. Never silence a decision point because a
|
|
257
264
|
probe failed.
|
|
258
265
|
|
|
259
|
-
##
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
266
|
+
## Everything the CLI auto-resolves (no chat replication) — v4.8.0+
|
|
267
|
+
|
|
268
|
+
The skill replicates **nothing**. The CLI owns the entire decision space; the
|
|
269
|
+
skill runs it and reports. What the CLI does on its own under bare `--yes`:
|
|
270
|
+
|
|
271
|
+
- **Preview**: prints the upstream CHANGELOG entries between the installed and
|
|
272
|
+
remote versions (the old `git log HEAD..FETCH_HEAD -- .framework/` was always
|
|
273
|
+
empty under subtree-squash — that dead preview is gone).
|
|
274
|
+
- **Working-tree stash**: a single blanket `git stash push -u` auto-stashes any
|
|
275
|
+
dirty non-framework work and re-applies it after the update (or after the
|
|
276
|
+
reset). Handles tracked files inside `.gitignore`d dirs — the exact case the
|
|
277
|
+
old manual workaround failed on.
|
|
278
|
+
- **Divergence** (consumer commits on `.framework/`): classified by the CLI.
|
|
279
|
+
`all-noise` (subtree plumbing / collaboration merges / CLI `[CHORE]`) →
|
|
280
|
+
silent. `overlay-able` where every edit is already covered by an overlay →
|
|
281
|
+
clean reinstall (`--reset`) that re-applies the overlays. `overlay-able`
|
|
282
|
+
uncovered → **auto-captured into populated overlays and VERIFIED** (the merge
|
|
283
|
+
must reproduce the edit) before the reinstall. `mixed` / `real-custom` (a
|
|
284
|
+
`src/`, CHANGELOG, … change) → the overlay-able subset is captured, then the
|
|
285
|
+
CLI **stops once** (action `divergence-capture-incomplete`) because non-overlay
|
|
286
|
+
paths can't be auto-resolved.
|
|
287
|
+
- **Hooks drift**, **schema config drift**, **BALDART-managed auto-commit**,
|
|
288
|
+
**CLI self-upgrade** (`npx baldart@latest` relaunch) — all silent as before.
|
|
289
|
+
|
|
290
|
+
Explicit overrides still exist for power users / CI (`--on-divergence
|
|
291
|
+
pull|scaffold-overlays|abort`, `--reset --yes --i-know`) but are NOT the path
|
|
292
|
+
the skill or the user needs anymore — the default IS the seamless path.
|
|
286
293
|
|
|
287
294
|
## Workflow (INTERACTIVE mode)
|
|
288
295
|
|
|
289
|
-
> In AUTONOMOUS mode follow `## Autonomous mode` instead.
|
|
290
|
-
>
|
|
291
|
-
>
|
|
296
|
+
> In AUTONOMOUS mode follow `## Autonomous mode` instead. All three steps below
|
|
297
|
+
> (pre-flight, run, post-flight) are shared by both modes — the only difference
|
|
298
|
+
> is autonomous uses `--json` and never prints to chat. There are NO chat
|
|
299
|
+
> confirmation steps anymore: the update is seamless.
|
|
292
300
|
|
|
293
301
|
### Step 0 — Pre-flight (read-only)
|
|
294
302
|
|
|
@@ -372,7 +380,7 @@ without suffix only when strictly required; if unsure, ASK the user.
|
|
|
372
380
|
|
|
373
381
|
- Patterns 1 or 4 → "Already up-to-date — version v<installedVersion>". STOP.
|
|
374
382
|
Do not launch the CLI.
|
|
375
|
-
- Patterns 2 or 3 → continue with Step 1 (
|
|
383
|
+
- Patterns 2 or 3 → continue with Step 1 (run the CLI).
|
|
376
384
|
- Pattern 5 → ask the user: "Vuoi forzare un fetch e ritentare, o procedere
|
|
377
385
|
in modalità offline (l'update fallirà nel CLI)?". STOP if unclear.
|
|
378
386
|
- **No pattern matches** → the CLI output format is unknown. Tell the user:
|
|
@@ -382,87 +390,27 @@ without suffix only when strictly required; if unsure, ASK the user.
|
|
|
382
390
|
|
|
383
391
|
If `.framework/` does not exist, `npx baldart version` will say "framework not installed" — STOP and instruct `npx baldart add`. Do not attempt to recover.
|
|
384
392
|
|
|
385
|
-
### Step 1 —
|
|
393
|
+
### Step 1 — Run the CLI (seamless, one shot)
|
|
386
394
|
|
|
387
395
|
```bash
|
|
388
|
-
|
|
389
|
-
# This mirrors src/utils/git.js (fetch + diffWithRemote use FETCH_HEAD,
|
|
390
|
-
# never `git -C .framework`).
|
|
391
|
-
git fetch <BALDART-repo-url> main
|
|
392
|
-
git log HEAD..FETCH_HEAD --oneline -- .framework/
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
Surface to the user:
|
|
396
|
-
|
|
397
|
-
- Current installed version (from Step 0).
|
|
398
|
-
- Number of commits behind (from Step 0).
|
|
399
|
-
- One-line summary of each incoming commit (from the `git log` above).
|
|
400
|
-
|
|
401
|
-
Ask: *"Procedo con l'aggiornamento?"*. If no → STOP.
|
|
402
|
-
|
|
403
|
-
### Step 2 — Replicate decision point #2 (working tree)
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
git status --porcelain
|
|
396
|
+
npx baldart update --yes
|
|
407
397
|
```
|
|
408
398
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
If the user refuses → STOP, instruct them to commit or stash manually
|
|
417
|
-
and re-run `/baldart-update`.
|
|
418
|
-
|
|
419
|
-
### Step 3 — Run the CLI
|
|
399
|
+
**Use the Bash tool with `timeout: 600000`** (10 minutes). Capture stdout and
|
|
400
|
+
stderr — both are needed for Step 2. Do NOT pass `--auto-stash` (redundant with
|
|
401
|
+
`--yes`), `--on-divergence`, or `--reset`: the seamless default already does the
|
|
402
|
+
right thing. There is no chat confirmation before this — running the skill IS the
|
|
403
|
+
authorization (the user asked to update; the CLI has a backup tag + rollback for
|
|
404
|
+
safety).
|
|
420
405
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
406
|
+
Everything the CLI handles on its own is listed in **"## Everything the CLI
|
|
407
|
+
auto-resolves"** above. The one outcome that is NOT a clean success is a non-zero
|
|
408
|
+
exit with action `divergence-capture-incomplete`: an edit could not be
|
|
409
|
+
captured+verified faithfully. Do NOT retry with `--on-divergence` or `--reset` to
|
|
410
|
+
force past it — surface the verbatim blockers + `next_command` and stop (Step 2
|
|
411
|
+
report covers this).
|
|
424
412
|
|
|
425
|
-
|
|
426
|
-
and stderr — both are needed for Step 4.
|
|
427
|
-
|
|
428
|
-
Do NOT pass `--auto-stash` (redundant with `--yes`).
|
|
429
|
-
|
|
430
|
-
**What the CLI auto-resolves without prompting** (since v3.26.0):
|
|
431
|
-
|
|
432
|
-
- **Hooks drift**: missing hooks are auto-registered silently. Hooks with
|
|
433
|
-
modified commands stay user-customised (warning surfaced in `--yes` mode,
|
|
434
|
-
interactive prompt otherwise).
|
|
435
|
-
- **Schema config drift**: new config keys are reported as a warning; the
|
|
436
|
-
user is told to run `npx baldart configure` later. The update never
|
|
437
|
-
blocks on schema drift.
|
|
438
|
-
- **BALDART-managed auto-commit**: in `--yes` mode the CLI commits any
|
|
439
|
-
files it touched during the reconcile with `chore(baldart): post-update
|
|
440
|
-
reconcile to vX.Y.Z`. User-owned files are never staged.
|
|
441
|
-
- **Subtree-merge / chore divergence commits**: when the consumer has
|
|
442
|
-
local commits that are just `git subtree pull` plumbing, ordinary
|
|
443
|
-
collaboration merges (detected by parent count, not just subject), or
|
|
444
|
-
CLI-generated `[CHORE]` commits, the CLI auto-resolves silently. Real
|
|
445
|
-
user-custom commits do NOT auto-resolve under bare `--yes` — but an agent
|
|
446
|
-
is no longer dead-ended: pass `--on-divergence` to resolve non-interactively
|
|
447
|
-
(since v3.29.0):
|
|
448
|
-
- `--on-divergence scaffold-overlays` → auto-creates overlay skeleton(s)
|
|
449
|
-
for the overlay-able commits, then stops so the edits can be filled in
|
|
450
|
-
(then re-run update). Use this when the divergence is `overlay-able`.
|
|
451
|
-
- `--on-divergence pull` → keeps the commits and lets the subtree pull
|
|
452
|
-
create a merge (non-destructive; resolve any conflicts that surface).
|
|
453
|
-
Works for `overlay-able`, `mixed`, and `real-custom`.
|
|
454
|
-
- `--on-divergence abort` → explicit no-op.
|
|
455
|
-
Bare `--yes` without a strategy still refuses (and now prints exactly which
|
|
456
|
-
flag to re-run with), so nothing destructive happens by accident.
|
|
457
|
-
- **CLI self-upgrade**: if the global CLI is older than npm latest, the
|
|
458
|
-
update transparently relaunches itself via `npx baldart@latest update
|
|
459
|
-
--yes`. Loop-guarded by `BALDART_RELAUNCHED=1`.
|
|
460
|
-
|
|
461
|
-
The skill no longer chat-replicates these decision points — they are
|
|
462
|
-
either silent (no user choice involved) or only triggered by genuine
|
|
463
|
-
user content, in which case the CLI surfaces the prompt directly.
|
|
464
|
-
|
|
465
|
-
### Step 4 — Post-flight assert + Report
|
|
413
|
+
### Step 2 — Post-flight assert + Report
|
|
466
414
|
|
|
467
415
|
**Post-flight assert (MANDATORY — safety net against silent CLI bugs)**:
|
|
468
416
|
|
|
@@ -555,10 +503,11 @@ possible actions (install, configure, migrate, repair symlinks, register
|
|
|
555
503
|
hooks, reconcile state ledger, …). When the user knows they want *only*
|
|
556
504
|
to update, going through the doctor is more friction than signal.
|
|
557
505
|
|
|
558
|
-
This skill is the direct path for that case
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
control
|
|
506
|
+
This skill is the direct path for that case: a single seamless `npx baldart
|
|
507
|
+
update --yes` that updates and preserves overlays with zero friction, plus a
|
|
508
|
+
mandatory post-flight assert and a clean report. The user no longer trades
|
|
509
|
+
control for friction — the CLI's backup tag + rollback and its
|
|
510
|
+
capture+verify safety pause keep the work safe without a wall of prompts.
|
|
562
511
|
|
|
563
512
|
`/baldart-push` and `/baldart-update` together form the conversational
|
|
564
513
|
spine of BALDART maintenance:
|
|
@@ -568,7 +517,7 @@ spine of BALDART maintenance:
|
|
|
568
517
|
|
|
569
518
|
Both wrap the CLI without re-implementing it; the CLI remains the source of
|
|
570
519
|
truth. `/baldart-push` always keeps the user in the loop. `/baldart-update`
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
520
|
+
is seamless in both modes; when run unattended (autonomous — CI / scheduled
|
|
521
|
+
routine) it uses `--json`, but in both it leans on the CLI's safety gates,
|
|
522
|
+
stopping hard rather than forcing any
|
|
574
523
|
destructive resolution a human would otherwise own.
|
package/package.json
CHANGED
package/src/commands/overlay.js
CHANGED
|
@@ -486,4 +486,4 @@ async function drift(target, options = {}) {
|
|
|
486
486
|
UI.info(`Summary: ${clean} clean, ${drifted} drifted, ${unknown} unknown — of ${targets.length} overlay(s).`);
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
-
module.exports = { scaffold, scaffoldFile, validate, drift, parseTarget, analyzeSkillConcat };
|
|
489
|
+
module.exports = { scaffold, scaffoldFile, validate, drift, parseTarget, analyzeSkillConcat, buildFrontmatter };
|