baldart 5.4.1 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/VERSION +1 -1
- package/framework/.claude/agents/CHANGELOG.md +16 -0
- package/framework/.claude/agents/prd-card-writer.md +37 -3
- package/framework/.claude/skills/new/CHANGELOG.md +33 -0
- package/framework/.claude/skills/new/SKILL.md +11 -5
- package/framework/.claude/skills/new/references/commit.md +12 -8
- package/framework/.claude/skills/new/references/completeness.md +10 -0
- package/framework/.claude/skills/new/references/final-review.md +23 -0
- package/framework/.claude/skills/new/references/implement.md +14 -4
- package/framework/.claude/skills/new/references/merge-cleanup.md +35 -14
- package/framework/.claude/skills/new/references/setup.md +1 -1
- package/framework/.claude/skills/new2/CHANGELOG.md +50 -0
- package/framework/.claude/skills/new2/SKILL.md +101 -17
- package/framework/.claude/skills/prd/CHANGELOG.md +36 -0
- package/framework/.claude/skills/prd/SKILL.md +17 -5
- package/framework/.claude/skills/prd/assets/state-template.md +8 -1
- package/framework/.claude/skills/prd/references/audit-phase.md +13 -1
- package/framework/.claude/skills/prd/references/backlog-phase.md +20 -0
- package/framework/.claude/skills/prd/references/discovery-phase.md +35 -0
- package/framework/.claude/skills/prd/references/ui-design-phase.md +28 -0
- package/framework/.claude/skills/prd/references/validation-phase.md +45 -1
- package/framework/.claude/skills/worktree-manager/CHANGELOG.md +13 -0
- package/framework/.claude/skills/worktree-manager/SKILL.md +11 -1
- package/framework/.claude/skills/worktree-manager/scripts/merge-worktree.sh +82 -6
- package/framework/.claude/workflows/new-final-review.js +9 -7
- package/framework/.claude/workflows/new2-resolve.js +29 -1
- package/framework/.claude/workflows/new2.js +153 -17
- package/framework/agents/card-schema.md +18 -1
- package/framework/agents/research-protocol.md +6 -1
- package/framework/scripts/stamp-holistic-audit.js +53 -10
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: new2
|
|
3
3
|
effort: high
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.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
|
|
@@ -85,8 +85,9 @@ everywhere this skill branches on it — Step 3.5 resolves deterministically (it
|
|
|
85
85
|
AUTONOMOUS branch) and **Step 3b's escape hatch is SKIPPED** (the user asked for
|
|
86
86
|
`-auto`; a post-batch question — and a possible `/new` re-invocation at full
|
|
87
87
|
inline cost — would break that promise even with a TTY present). `/new` only
|
|
88
|
-
delegates **migration-free** batches (it probes
|
|
89
|
-
itself
|
|
88
|
+
delegates **migration-free** batches (it probes ALL migration vocabularies
|
|
89
|
+
itself — `migration_plan.required`, epic `db_migrations_summary`, per-card
|
|
90
|
+
`db_migration.required`), so Step 3.5's one interactive question cannot fire on a delegated run —
|
|
90
91
|
if you nonetheless find a declared, unapplied migration in a delegated batch,
|
|
91
92
|
HALT and hand back to `/new` classic (`"batch con migrazione dichiarata — riesegui
|
|
92
93
|
/new <cards> -auto -inline"`) instead of asking. Everything else is identical to a
|
|
@@ -129,8 +130,16 @@ untouched), so the schema is live **before** the workflow starts. It mirrors `/n
|
|
|
129
130
|
1. **Find the batch's epic card(s)** — distinct `group.parent` of the resolved cards (or the `-full`
|
|
130
131
|
parent). Read each epic YAML in `${paths.backlog_dir}` (`<PARENT>-*-epic.yml`, or the card whose
|
|
131
132
|
`id == <PARENT>` / `group.is_epic: true`).
|
|
132
|
-
2. **Look for
|
|
133
|
-
|
|
133
|
+
2. **Look for a declared migration — under ANY recognized vocabulary.** Primary: epic
|
|
134
|
+
`migration_plan` with `required: true`. **Compat aliases (consumer-overlay conventions —
|
|
135
|
+
FEAT-0067 root cause: probing only `migration_plan` made this gate structurally blind to
|
|
136
|
+
`db_migration`-declaring cards)**: epic `db_migrations_summary` (non-empty), or any batch card
|
|
137
|
+
with `db_migration.required: true` (map: `artifacts` ← `db_migration.expected_file`; `summary`
|
|
138
|
+
← the slug; modalities ← `db_migration.remote_push` + overlay). Nothing declared → set
|
|
139
|
+
`migration = { status: 'none' }` and go to Step 4 (identical to today — zero extra prompts; do
|
|
140
|
+
not surface anything). Declared via ANY vocabulary → record `migrationDeclared: true` +
|
|
141
|
+
`declaredVia` in your own working state (Step 5.1b keys off it — it must NOT depend on the
|
|
142
|
+
workflow's residual ledger surviving) and continue below.
|
|
134
143
|
3. **(declared) Verify `migration_plan.artifacts` exist on disk under `$MAIN`.** Any missing → do NOT
|
|
135
144
|
apply or prompt; set `migration = { status: 'degraded', reason: 'artifact missing', artifacts }`
|
|
136
145
|
and go to Step 4 (the migration falls back to the current end-of-batch owner-gated deferral — no
|
|
@@ -193,7 +202,9 @@ Workflow({ name: 'new2', args: {
|
|
|
193
202
|
```
|
|
194
203
|
|
|
195
204
|
Record the kickoff time (`ts`) before the call — Step 5 uses it to stamp the
|
|
196
|
-
real wall-clock duration (the workflow cannot read a clock).
|
|
205
|
+
real wall-clock duration (the workflow cannot read a clock). Also record the
|
|
206
|
+
pre-batch trunk sha (`git -C $MAIN rev-parse ${trunk}`) — Step 5.4b audits every
|
|
207
|
+
non-card commit the batch introduced against it (v5.6.0).
|
|
197
208
|
|
|
198
209
|
Capture `sessionId` the same way, in THIS skill's own context (not a subagent):
|
|
199
210
|
`Bash(echo "${CLAUDE_CODE_SESSION_ID:-}")`. The workflow stamps it as
|
|
@@ -245,6 +256,44 @@ returns when the batch is done. It returns:
|
|
|
245
256
|
step-1b HALT fields — the `/new` pre-flight back-fill (step 1b-ii) then normalizes its
|
|
246
257
|
`review_profile`/`owner_agent` on first ingestion, so even the crisis stub self-heals. This
|
|
247
258
|
main-repo, **disk-verified** write is the SSOT — nothing is dropped even on a non-merged batch.
|
|
259
|
+
**Exception (v5.6.0):** residuals of kind `false-epic-closure` and `main-repo-contamination` are
|
|
260
|
+
**reconciliation ACTIONS, not backlog work** — do NOT mint follow-up cards for them. The former
|
|
261
|
+
is handled by step 2's REOPEN branch; the latter by step 4b's hygiene audit (inspect + restore
|
|
262
|
+
the named main-repo paths).
|
|
263
|
+
1b. **Migration Sync Tail (post-merge "branch B" — the interactive owner-gated deploy the
|
|
264
|
+
autonomous batch could not run).** The workflow has returned and merged; you are the skill
|
|
265
|
+
main loop, in `$MAIN`, typically on `$TRUNK` — exactly the precondition of the project's
|
|
266
|
+
post-merge sync gate (e.g. the overlay's "on trunk, post-merge" branch). **Trigger — EITHER
|
|
267
|
+
condition, independently** (belt-and-braces: the FEAT-0067 failure dropped the residual
|
|
268
|
+
mid-run, so this tail keys on the Step-3.5 DECLARATION, never only on the ledger):
|
|
269
|
+
(a) `migrationDeclared` from Step 3.5 (any vocabulary) with `migration.status ≠ 'applied'`;
|
|
270
|
+
(b) any `residuals[]` entry whose kind/owner-gated action maps to `db-migration-deploy`.
|
|
271
|
+
Neither → skip silently. Steps:
|
|
272
|
+
- **Resolve the project's post-merge sync contract**, in source order: (i) the batch cards'
|
|
273
|
+
`db_migration.remote_push` / `migration_plan` (check command + push command); (ii) the
|
|
274
|
+
post-merge / trunk branch of the Migration Sync Gate section in `.baldart/overlays/new.md`;
|
|
275
|
+
(iii) `migration_plan.verify` alone (check-only). Nothing resolvable → skip the tail (the
|
|
276
|
+
step-1 follow-up card remains the ledger) and say so in the presentation.
|
|
277
|
+
- **Run the read-only sync CHECK first** (e.g. the overlay's check-sync command), from `$MAIN`
|
|
278
|
+
on `$TRUNK` (if `$MAIN` is not on `$TRUNK`, do not switch branches yourself — report and
|
|
279
|
+
leave the follow-up as ledger). **Green** → the migration is live: the `db-migration-deploy`
|
|
280
|
+
residual is SATISFIED (no follow-up needed — if step 1 already created one, delete it in the
|
|
281
|
+
same reconciliation commit and note why); record it and let step 2 DONE-flip the migration
|
|
282
|
+
card with its schema AC satisfied.
|
|
283
|
+
- **Red + INTERACTIVE** → ONE `AskUserQuestion` (post-batch skill-layer interaction, same
|
|
284
|
+
class as Step 3b — the zero-ask-during-batch invariant is untouched): *"La migration del
|
|
285
|
+
batch non risulta applicata al DB remoto (check-sync rosso). Come procedo?"* Options:
|
|
286
|
+
**[Push now]** (run the declared owner-gated push command from `$TRUNK` — honour
|
|
287
|
+
`stack.schema_deploy_from_trunk_only`; output to `/tmp/migration-push-<firstCard>.log`,
|
|
288
|
+
surface the exit code, then RE-RUN the check and require green) / **[Defer]** (keep the
|
|
289
|
+
step-1 follow-up card as the ledger; the card stays DONE-with-follow-up per its
|
|
290
|
+
`owner-gated` class) / **[Override]** (record the user's verbatim reason). Never push
|
|
291
|
+
without the user picking it.
|
|
292
|
+
- **Red + AUTONOMOUS** (env / delegated `/new -auto` origin — Step 1.5) → NEVER push
|
|
293
|
+
(outward, owner-gated). Ensure the step-1 follow-up exists, and surface the pending deploy
|
|
294
|
+
PROMINENTLY in the presentation (step 4) — a truthful "schema NOT live" line, not a footnote.
|
|
295
|
+
- Record `migration_sync_tail: { ran, trigger: 'declared'|'residual'|'both', check:
|
|
296
|
+
'green'|'red'|'unavailable', pushed: <bool>, outcome }` for telemetry (step 5).
|
|
248
297
|
2. **Mark deferred cards DONE — only after their follow-up exists AND every deferral class allows
|
|
249
298
|
it (F-040/H + A3).** Some committed cards were intentionally left **NON-DONE** because they carry
|
|
250
299
|
an open deferred AC: they are `perCardResults[]` entries with `deferred:true` plus a
|
|
@@ -267,11 +316,25 @@ returns when the batch is done. It returns:
|
|
|
267
316
|
**Then re-run the epic-closure check for the cards just marked DONE.** The merge agent's
|
|
268
317
|
epic-closure (Phase 6b step 5e) ran BEFORE this step, when the deferred cards were still
|
|
269
318
|
NON-DONE — so an epic whose last open child was a deferred card is still TODO and nothing
|
|
270
|
-
else will ever close it. For each distinct `group.parent` of the cards marked DONE here
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
319
|
+
else will ever close it. For each distinct `group.parent` of the cards marked DONE here,
|
|
320
|
+
close ONLY when the FULL v5.6.0 predicate holds (the same one the merge agent runs —
|
|
321
|
+
`merge-cleanup.md` § epic closure): (a) `grep -l "parent: <EPIC-ID>" ${paths.backlog_dir}/*.yml
|
|
322
|
+
| xargs grep -L "status: DONE"` prints nothing — **follow-up cards count as children** (step 1
|
|
323
|
+
just materialised them here in the main repo, so this grep now sees them); (b) no `residuals[]`
|
|
324
|
+
entry of a blocking class (`scope-expansion`/`unresolved`/`ac-unmet`/`out-of-ownership`) maps to
|
|
325
|
+
a child of this epic; (c) the epic YAML's own `acceptance_criteria` are all `[x]` — verify any
|
|
326
|
+
still-`[ ]` item with its `ac_verification` oracle (or a targeted check) and flip it ONLY with
|
|
327
|
+
evidence; an unverifiable AC leaves the epic OPEN. When all three hold, set the epic
|
|
328
|
+
`status: DONE` + `completed_date` + note `"epic-closure gate — children DONE + epic ACs
|
|
329
|
+
verified (post-run, new2 skill)"`, folded into the SAME reconciliation commit. Otherwise leave
|
|
330
|
+
the epic untouched and say why in the presentation.
|
|
331
|
+
**REOPEN branch (v5.6.0 — the ratchet is two-way now).** For every `false-epic-closure`
|
|
332
|
+
residual, AND for any epic found `status: DONE` on disk while the grep above still prints an
|
|
333
|
+
open child (follow-ups included) or a closure-invalidating finding stands: flip the epic back
|
|
334
|
+
to `status: IN_PROGRESS`, remove/annotate its `completed_date`, add note `"REOPENED — closed
|
|
335
|
+
against open scope (false DONE, v5.6.0 guard)"`, and fold into the same reconciliation commit.
|
|
336
|
+
An epic whose registry/ADR text says "goal not achieved" while its YAML says DONE is exactly
|
|
337
|
+
the FEAT-0068 contradiction this branch exists to prevent — the STATE wins, not the prose.
|
|
275
338
|
3. **Resume if degraded — HARD-BOUNDED (v4.92.0).** If `degraded` is true, re-invoke
|
|
276
339
|
the workflow with `Workflow({ scriptPath, resumeFromRunId })` (same `args` + the
|
|
277
340
|
new `ts`). The per-card **skip-completed** guard makes the resume idempotent —
|
|
@@ -334,11 +397,31 @@ returns when the batch is done. It returns:
|
|
|
334
397
|
(out of scope by design — the workflow is autonomous).
|
|
335
398
|
- Record `escape_hatch: { eligible: N, offered: <bool>, ran_new: <bool>, followups: [...] }`
|
|
336
399
|
in telemetry (step 5 below) so the A/B stays honest about when the hatch was used.
|
|
337
|
-
4. **Present.** Print `report` verbatim
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
400
|
+
4. **Present.** Print `report` verbatim — **including its verdict headline** (`⚠️ PARTIAL` /
|
|
401
|
+
`✅ COMPLETO`, v5.6.0): NEVER re-headline a PARTIAL run as a success in your own framing, and
|
|
402
|
+
never bury an epic-goal gap under a completion table (the FEAT-0068 report said "✅ 6/6 DONE"
|
|
403
|
+
over a disclosed-but-buried HIGH gap — the user discovered it only by asking). Surface
|
|
404
|
+
`residuals` prominently ("questi residui sono tracciati come follow-up: …") — the post-run
|
|
405
|
+
review that replaced the ~25 mid-run questions; a HIGH residual is REMAINING WORK, present it
|
|
406
|
+
as such. If `degraded`, say so plainly (the run was incomplete and resumed). If the escape
|
|
407
|
+
hatch ran `/new` (step 3b), fold its outcome into the presentation (which follow-ups were
|
|
408
|
+
closed by `/new`).
|
|
409
|
+
4b. **Batch git hygiene audit (v5.6.0 — never assert provenance without checking).** From the
|
|
410
|
+
kickoff you know the trunk's pre-batch sha (record `git -C $MAIN rev-parse ${trunk}` at Step 4
|
|
411
|
+
BEFORE launching the workflow). Now:
|
|
412
|
+
- `git -C $MAIN log --oneline <pre-sha>..HEAD` — for every commit whose subject does NOT
|
|
413
|
+
reference a batch card id (e.g. `[safety]`, unexpected chores), run `git show --stat <sha>`
|
|
414
|
+
and LIST it in the presentation with its files. Never attribute a commit to "a previous run"
|
|
415
|
+
without this check (the FEAT-0068 orchestrator asserted exactly that, and it was false).
|
|
416
|
+
A safety/sweep commit whose files are outside the batch's bookkeeping is a finding to
|
|
417
|
+
surface, not to normalize.
|
|
418
|
+
- `git -C $MAIN stash list` — any stash created during this batch (grep the batch/card ids and
|
|
419
|
+
the `baldart-new2-` label) MUST be reconciled NOW: inspect (`git stash show -p`), then apply
|
|
420
|
+
or drop with the user's standing policy — in AUTONOMOUS mode leave it but list it as a
|
|
421
|
+
PROMINENT pending item, never as a footnote and never "not mine to drop" (if this batch's
|
|
422
|
+
machinery created it, it IS yours to reconcile).
|
|
423
|
+
- Every `main-repo-contamination` residual: inspect the named paths in `$MAIN` and restore
|
|
424
|
+
them (they are the commit-agent detour's droppings), reporting what was restored.
|
|
342
425
|
5. **Record truthful telemetry — reconciled against disk (F-040).** Before appending `telemetry`
|
|
343
426
|
to `${metricsDir}/skill-runs.jsonl`, fill the fields the workflow could not compute and
|
|
344
427
|
**reconcile the report against the real disk state** (agent `reason` strings can over-claim — a
|
|
@@ -358,7 +441,8 @@ returns when the batch is done. It returns:
|
|
|
358
441
|
(partial, output-only, excludes nested workflows). Keep `degraded`/`degradation_reasons` +
|
|
359
442
|
`cards_deferred_done_pending` in the record so
|
|
360
443
|
the A/B comparison stays honest. Also record `migration_gate: <migration.status>`
|
|
361
|
-
(`none`|`applied`|`skipped`|`degraded`)
|
|
444
|
+
(`none`|`applied`|`skipped`|`degraded`) and `migration_sync_tail` (Step 5.1b — whether the
|
|
445
|
+
post-merge check ran, its outcome, and whether an owner-gated push was user-approved) — the Step-3.5 gate is a pre-launch interaction, NOT a
|
|
362
446
|
mid-batch question, so it does not break the zero-ask-during-batch invariant; logging it keeps the
|
|
363
447
|
A/B honest about when a migration was front-loaded. Keep `deferral_breakdown` (per-class counts
|
|
364
448
|
of WHY residuals became follow-ups instead of in-batch fixes) in the record — a class dominating
|
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 1.6.0 — 2026-07-04 (FEAT-0068 post-mortem: il root cause era qui)
|
|
6
|
+
|
|
7
|
+
- **ISA "UI ROLE FAMILY (registry-first)"** (`discovery-phase.md` Dimension 9, gated su
|
|
8
|
+
`features.has_design_system`): per feature chrome/primitive enumera i PROPRIETARI della
|
|
9
|
+
superficie del goal dal registry (role families / Selection Policy), non solo i consumer
|
|
10
|
+
esistenti del meccanismo; **flag BLOCK su `@deprecated`** nel fix-path (i successori
|
|
11
|
+
documentati diventano il target). Era: DrilldownHeader/SectionHeader (~90% degli screen)
|
|
12
|
+
in NESSUNA card, ricetta ancorata su un Header deprecato da 5 pagine.
|
|
13
|
+
- **§0 LOAD CONTRACT** in testa a `discovery-phase.md`: il modulo supera il cap del Read —
|
|
14
|
+
vista PARTIAL ⇒ offset-Read obbligatori fino alla fine (la coda persa conteneva Exit
|
|
15
|
+
condition + Codex completeness cross-check + Research Trigger, mai eseguiti sul run reale).
|
|
16
|
+
- **`module_read` stamps** (SKILL.md): la lettura dei moduli di fase è ESEGUITA non recitata
|
|
17
|
+
— stamp nello state file, verificato dal validator (3 moduli mai letti sul run reale).
|
|
18
|
+
- **`step_3_mode` enum CHIUSO + contratto `skipped`** (`ui-design-phase.md`): `skipped` =
|
|
19
|
+
NESSUN artefatto di design, `links.design` vuoto, ogni explainer passa da `/ui-design`
|
|
20
|
+
(era: modalità fabbricata `design-spec` + design.html hand-authored su 5/6 card);
|
|
21
|
+
**Reconciliation-lite** (no mockup ≠ no reconciliation: role family dal registry ⇒
|
|
22
|
+
`component_bindings`); **trigger di ri-enumerazione ISA** quando la ricetta cambia target.
|
|
23
|
+
- **Gate quantificatore-universale sugli AC epic** (`validation-phase.md` item e):
|
|
24
|
+
"ogni schermata" ⇒ owner della superficie (census fresco) ⊆ unione scope figli, else
|
|
25
|
+
BLOCKER; `invariant_owners:` persistiti nell'epic.
|
|
26
|
+
- **Item 0-ii Phase-evidence audit** (`validation-phase.md`): stamp module_read + gate con
|
|
27
|
+
evidenza (API Perf Gate stampato `N/A` senza spawn sul run reale) + enum step_3_mode.
|
|
28
|
+
- **Stamp holistic evidence-gated** (`stamp-holistic-audit.js --audit-report` →
|
|
29
|
+
`agents_run`/`findings_count`; senza artefatto → `status: skipped` che `/new` tratta come
|
|
30
|
+
ASSENTE). Era: stamp su 6/6 card con zero spawn di audit (phantom stamp).
|
|
31
|
+
- **Card-writer self-validation** (`backlog-phase.md` + agente): il validator gira
|
|
32
|
+
nell'output del writer PRIMA del return (era: round-trip completo su EARS in italiano);
|
|
33
|
+
**Rule A ramo deterministico** (files docs/test-only ⇒ owner coder, mai `links.design`);
|
|
34
|
+
epic con `ac_verification` obbligatoria + mai count hardcodato; invariante lifecycle
|
|
35
|
+
baseline per suite snapshot.
|
|
36
|
+
- **Step 7.9 HARD RULE mw-docs** (`validation-phase.md`): mai `/mw` generico su worktree
|
|
37
|
+
`kind: docs` (+ guardia lato worktree-manager); era ~4M di BUILD_FAIL falso + unblock umano.
|
|
38
|
+
- **EDIT CONTRACT dello state file** (template + HARD RULE 2): anchor sul bare `key:` con
|
|
39
|
+
literal appena letto (5 retry ciechi da ~250k sul run reale).
|
|
40
|
+
|
|
5
41
|
## 1.5.0 — 2026-07-03 (framework v5.4.0)
|
|
6
42
|
|
|
7
43
|
- **Step 2.1 Tier Gate (elastic pipeline).** At Discovery exit the feature is classified
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prd
|
|
3
3
|
effort: high
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.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
|
|
|
@@ -54,9 +54,17 @@ message. You ask questions, wait for answers, and iterate.
|
|
|
54
54
|
| 7 | Resolution, Commit & Merge | [validation-phase.md](references/validation-phase.md) |
|
|
55
55
|
| 7.6 | Obsidian back-reference — FINAL (upgrades the 1.2 provisional block; only if a spec note was given) | [validation-phase.md](references/validation-phase.md) + [obsidian-backref.md](references/obsidian-backref.md) |
|
|
56
56
|
|
|
57
|
-
**Before starting each phase, read the corresponding reference file
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
**Before starting each phase, read the corresponding reference file — EXECUTED, not
|
|
58
|
+
recited (v5.6.0).** After reading a phase module, record `module_read: <file> (full)` in the
|
|
59
|
+
state file's section for that phase; if the Read reported a PARTIAL view (the module exceeds
|
|
60
|
+
the token cap — `discovery-phase.md` does), issue offset Reads until the END of the file
|
|
61
|
+
before proceeding and stamp `(full, N reads)`. The Step 6 validator (`validation-phase.md`
|
|
62
|
+
item 0-ii) checks these stamps deterministically. This exists because a real session ran
|
|
63
|
+
Steps 2.5/4/4.5/5 with `research-phase.md`, `prd-writing-phase.md` and `backlog-phase.md`
|
|
64
|
+
NEVER read (6 Reads total in 73 turns): the improvised Step 5 contract produced a full
|
|
65
|
+
validator-rework round, and the truncated discovery tail silently dropped the mandatory Codex
|
|
66
|
+
completeness cross-check. ONE exception class: **agent-facing specs are passed BY PATH to the
|
|
67
|
+
agent that consumes them and MUST NOT be loaded into the orchestrator context.** Today these are
|
|
60
68
|
`references/api-perf-gate.md` (read by `api-perf-cost-auditor` at Step 4.5 and at the
|
|
61
69
|
Step 6 audit) and `references/audit-teammate-prompt.md` (read by each Step 6.6 audit
|
|
62
70
|
teammate). Rationale: a spec loaded by a subagent costs one cheap Read in a disposable
|
|
@@ -70,7 +78,11 @@ for the rest of the run.
|
|
|
70
78
|
> **Runtime portability.** On **Codex**, bind this skill's mechanics per `framework/agents/runtime-portability-protocol.md` (named-agent spawn, decision gates, file-backed state; never probe `Workflow`/`AskUserQuestion`/the task spine). Rules below are Claude-first with explicit **Codex:** branches (RULES 4, 11) — additive, Claude imperatives unchanged.
|
|
71
79
|
|
|
72
80
|
1. Follow steps in order. NEVER skip a step or jump ahead.
|
|
73
|
-
2. Every step MUST update the state file before proceeding.
|
|
81
|
+
2. Every step MUST update the state file before proceeding. **State-file Edit hygiene
|
|
82
|
+
(v5.6.0):** anchor every Edit on the bare `key:` prefix with a literal you just Read —
|
|
83
|
+
never a recalled literal with trailing comments/alignment/blank lines (the template's
|
|
84
|
+
EDIT CONTRACT header; 5 blind retries at ~250k each on a real session). A failed match →
|
|
85
|
+
Read the exact lines, retry ONCE with the fresh literal.
|
|
74
86
|
3. Every gate MUST be satisfied before moving to the next step.
|
|
75
87
|
4. **Progress tracking.** Claude Code: use TaskCreate/TaskUpdate for ALL progress tracking. **Codex** (no task spine): use a file-backed queue at `$WORKTREE_PATH/${paths.prd_dir}/sessions/<slug>-tasks.jsonl` — one record per task (`status` / `claimed_by` / `findings_path`) — and the session **state file** stays the recovery SSOT either way. (Binding: `framework/agents/runtime-portability-protocol.md` § state-spine.)
|
|
76
88
|
5. When context is compressed or session resumes: run Step 0 first.
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
# PRD Session: {{slug}}
|
|
2
|
+
|
|
3
|
+
<!-- EDIT CONTRACT (v5.6.0 — N8, 5 failed Edits at ~250k context each on a real session):
|
|
4
|
+
when updating a `key: value` line in this file, ANCHOR ON THE BARE KEY PREFIX ONLY
|
|
5
|
+
(`old_string` = from start-of-line through the current value you just Read — never a
|
|
6
|
+
recalled-from-memory literal that includes trailing `# comments`, column alignment, or
|
|
7
|
+
surrounding blank lines; those drift). If an Edit fails to match, Read the exact lines
|
|
8
|
+
FIRST and retry once with the fresh literal — never loop blind retries. -->
|
|
2
9
|
Created: {{YYYY-MM-DD HH:MM}}
|
|
3
10
|
Status: discovery # discovery | mockups-pending-input | research-in-progress | pending-external-handoff | ui-design | writing | specs-confirmed | backlog | audit | validation | committing | completed | done
|
|
4
11
|
stats_enabled: {{true if invoked with -stats/--stats, else false}}
|
|
@@ -121,7 +128,7 @@ mockup_analysis.design_system_alignment:
|
|
|
121
128
|
status: pending # aligned | violations | not-applicable
|
|
122
129
|
violations: []
|
|
123
130
|
|
|
124
|
-
step_3_mode: pending # full | hybrid | skipped | mockup-only
|
|
131
|
+
step_3_mode: pending # CLOSED ENUM: full | hybrid | skipped | mockup-only | pending_external_handoff — any other value is a Step 6 BLOCKER (v5.6.0)
|
|
125
132
|
design.html_path: pending # path | n/a (mockup-only)
|
|
126
133
|
|
|
127
134
|
screens_in_scope: [] # [{ name, slot_id, screen_id, canvas_ref, covered_by_mockups: bool, generated_in_step_3b: bool }]
|
|
@@ -398,8 +398,19 @@ metadata:
|
|
|
398
398
|
audited_at: "<HOLISTIC_AUDITED_AT>"
|
|
399
399
|
audited_commit: "<HOLISTIC_AUDITED_COMMIT>" # "" if git unavailable → /new treats as drift (runs Step 3d)
|
|
400
400
|
audited_set: ["FEAT-XXXX-01", "FEAT-XXXX-02", ...] # sorted; the joint cross-card scope
|
|
401
|
+
agents_run: ["plan-auditor", "codebase-architect", ...] # v5.6.0 EVIDENCE — written by the
|
|
402
|
+
# stamper from the audit report artifact (--audit-report). A stamp WITHOUT a non-empty
|
|
403
|
+
# agents_run is treated as ABSENT by /new P1 (the plan-auditor runs): on FEAT-0068 the
|
|
404
|
+
# stamp landed on all 6 cards while the audit team never spawned (phantom stamp).
|
|
405
|
+
findings_count: 3 # optional, from the report
|
|
401
406
|
```
|
|
402
407
|
|
|
408
|
+
**Write the audit report artifact FIRST (v5.6.0 — the stamp's evidence).** Before running the
|
|
409
|
+
stamper, persist the Step 6.6 audit outcome to `/tmp/prd-audit-<slug>.md` with at minimum a
|
|
410
|
+
literal `agents_run: <comma-separated agent types actually spawned>` line and a
|
|
411
|
+
`findings_count: <N>` line. No spawns happened → do NOT fabricate the file: run the stamper
|
|
412
|
+
without `--audit-report` and it stamps `status: "skipped"` honestly.
|
|
413
|
+
|
|
403
414
|
> **Fail-safe contract**: the block is an OPTIMIZATION hint for `/new`, never a *correctness* gate — if `audited_commit` is empty or the block is absent, `/new` Step 3d **and** the `implement.md` Phase-1 plan-auditor grounding (step 4, P1) simply RUN as before (redundant, never wrong). **But writing the block is MANDATORY whenever the audit ran.** It is the single most-omitted step under context pressure, and its absence is exactly what makes `/new` / `new2` spawn the plan-auditor on **every** freshly-authored card even when the batch is implemented immediately after this audit (nothing changed since). Do NOT skip it "to save a write". If git is genuinely unavailable, write `audited_commit: ""` **explicitly** — never omit the block. `validation-phase.md` Step 7 item 5b is the **deterministic backstop** that guarantees this lands before the PRD commit even if this per-card write is missed — but write it here too; the backstop is a safety net, not a license to skip.
|
|
404
415
|
|
|
405
416
|
**Deterministic writer — EXECUTE, don't hand-edit.** `framework/scripts/stamp-holistic-audit.js` mechanizes this write (idempotent, additive, epic-skipping, self-verifying). Run it ONCE for the whole card set after the per-card field edits:
|
|
@@ -407,7 +418,8 @@ metadata:
|
|
|
407
418
|
```bash
|
|
408
419
|
node .framework/framework/scripts/stamp-holistic-audit.js \
|
|
409
420
|
--at "$HOLISTIC_AUDITED_AT" --commit "$HOLISTIC_AUDITED_COMMIT" \
|
|
410
|
-
--set "<sorted child IDs, comma-separated>"
|
|
421
|
+
--set "<sorted child IDs, comma-separated>" \
|
|
422
|
+
--audit-report "/tmp/prd-audit-<slug>.md" ${CARD_PATHS}
|
|
411
423
|
```
|
|
412
424
|
|
|
413
425
|
Hand-edit the YAML only when the script is genuinely unreachable in this install — and say so in the audit log.
|
|
@@ -22,6 +22,19 @@ and BLOCK the commit. The `/new` orchestrator dispatches implementation
|
|
|
22
22
|
agent by this field (see `framework/.claude/skills/new/SKILL.md` § Agent
|
|
23
23
|
Routing), so a wrong value silently routes the card to the wrong specialist.
|
|
24
24
|
|
|
25
|
+
**Rule A deterministic branch (v5.6.0 — FEAT-0068):** when a card's
|
|
26
|
+
`files_likely_touched` are ALL docs/test/config/meta paths (zero `src/` UI or
|
|
27
|
+
component/style files), `owner_agent` MUST be `coder` regardless of the
|
|
28
|
+
feature's topic — a docs+ADR+test card for a UI epic is still a coder card
|
|
29
|
+
(`owner_agent: ui-expert` with zero UI paths is a Step 6 BLOCKER). Also do NOT
|
|
30
|
+
stamp `links.design` on such a card: `links.design` goes ONLY on cards whose
|
|
31
|
+
scope implements mocked regions (`component_bindings` present or
|
|
32
|
+
`files_likely_touched` intersecting the mocked components); on anything else it
|
|
33
|
+
is a stray pointer that clamps the build to ui-expert downstream (`/new`
|
|
34
|
+
mockup-first router) — the FEAT-0068 docs card cost 6.55M for exactly this.
|
|
35
|
+
This separates HETEROGENEOUS domains; it does not contradict the v5.4.0
|
|
36
|
+
proportionality floor (which discourages splitting a small HOMOGENEOUS change).
|
|
37
|
+
|
|
25
38
|
### Rule B — UI cards have UI-only scope (no mixed scope)
|
|
26
39
|
|
|
27
40
|
A card with `owner_agent: ui-expert` MUST be scoped EXCLUSIVELY to graphical
|
|
@@ -263,6 +276,13 @@ The `prd-card-writer` agent owns the entire card writing pipeline:
|
|
|
263
276
|
- State file update with card list and matrices
|
|
264
277
|
- `env_vars` field: for every card that introduces/modifies/removes env vars (detectable from PRD Section 6 or requirements that mention `process.env`, secrets, API keys, feature flags), populate the field with `action: new|modified|removed`, `scope`, `required`, `note`. If the card does not touch env vars, write `env_vars: []`.
|
|
265
278
|
- `review_profile` field: deterministic per-card review depth (`skip|light|balanced|deep`). The decision criteria (how each profile is chosen) live ONLY in `prd-card-writer.md § Rule C` — see that file for the criteria. The `/new` orchestrator reads this value from the card and runs an escalation-only detector; it does NOT re-derive from a duplicate criteria table. Epics always get `review_profile: skip`. Honor any explicit author override already present in the YAML.
|
|
279
|
+
- **Self-validation BEFORE returning (v5.6.0 — reviewer-owns-its-domain, FEAT-0068 N6):** the
|
|
280
|
+
card-writer brief MUST require the agent to RUN the deterministic validator on its own output
|
|
281
|
+
(`node .framework/framework/scripts/validate-card-baseline.js --prd <card files>`) and return
|
|
282
|
+
only on exit 0, fixing its own deterministic defects (enums, EARS token language, forbidden
|
|
283
|
+
patterns) in-context. Step 6 re-runs the same validator as the independent gate — but a
|
|
284
|
+
deterministic failure discovered only at Step 6 costs a full orchestrator→agent round-trip
|
|
285
|
+
(~1.5M + a resume on the real session, where all 6 children bounced on Italian EARS tokens).
|
|
266
286
|
|
|
267
287
|
### What stays in the main context
|
|
268
288
|
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Discovery Phase (Steps 0-2)
|
|
2
2
|
|
|
3
|
+
> **§0 — LOAD CONTRACT (v5.6.0 — read this first; it exists because of a real truncation).**
|
|
4
|
+
> This module is LARGER than the Read tool's default token cap. A plain `Read` returns a
|
|
5
|
+
> **PARTIAL view** (the banner says so) and silently drops the TAIL — which contains the
|
|
6
|
+
> **Exit condition**, the **mandatory Codex Discovery Completeness Cross-Check**, the
|
|
7
|
+
> **Research Trigger**, and the `mockup_analysis` schema. On the FEAT-0068 session exactly
|
|
8
|
+
> that happened: lines 953+ were never loaded, the cross-check never ran, and the coverage
|
|
9
|
+
> blind spot it exists to catch (integration owners no dimension modelled) shipped into the
|
|
10
|
+
> cards. HARD RULE: **if your Read of this file reports a partial view, you MUST issue
|
|
11
|
+
> follow-up Read calls with `offset` until you have seen the end of the file — BEFORE
|
|
12
|
+
> closing any discovery dimension.** Record `module_read: discovery-phase.md (full, N reads)`
|
|
13
|
+
> in the state file's phase section (the Step 6 validator checks the stamp). The
|
|
14
|
+
> tail-critical gates, so you know what you are looking for: (1) Exit condition — all
|
|
15
|
+
> dimensions covered + user validation; (2) Codex Discovery Completeness Cross-Check —
|
|
16
|
+
> MANDATORY sweep for the questioner's own blind spots before closing; (3) Research
|
|
17
|
+
> Trigger — background launch at 6+ dimensions; (4) `mockup_analysis` schema.
|
|
18
|
+
|
|
3
19
|
## Step 0 — Context Recovery
|
|
4
20
|
|
|
5
21
|
Run BEFORE any other step.
|
|
@@ -815,6 +831,25 @@ Instead, run the ISA scan and present findings for validation.
|
|
|
815
831
|
the picker-mode call, while the live catalog-mode consumer page was never
|
|
816
832
|
enumerated → it surfaced as a HIGH only at the final review.) Grep the function
|
|
817
833
|
name across the codebase and list each distinct caller file:line.
|
|
834
|
+
- UI ROLE FAMILY — registry-first surface OWNERSHIP (v5.6.0; only when
|
|
835
|
+
features.has_design_system is true AND the feature's recipe targets a chrome/
|
|
836
|
+
primitive ROLE: "the header/top edge of every screen", bottom bars, anchored
|
|
837
|
+
overlays/toasts, page shells). Every other category above enumerates EXISTING
|
|
838
|
+
code that references the feature's mechanism — but a component that LACKS the
|
|
839
|
+
mechanism is structurally invisible to that grep. This category enumerates the
|
|
840
|
+
OWNERS of the goal surface instead: read the design-system registry
|
|
841
|
+
(${paths.design_system}/INDEX.md role families / Selection Policy +
|
|
842
|
+
components/<Name>.md) for the family that renders that role, list EVERY member
|
|
843
|
+
as its OWN touchpoint (with its consumer count: `grep -rl <Component> | wc -l`),
|
|
844
|
+
and mark each HIGH (the goal is invisible wherever an unlisted member renders).
|
|
845
|
+
**@deprecated flag (BLOCKING):** if a family member the recipe anchors on carries
|
|
846
|
+
a `@deprecated` docblock, the touchpoint MUST name the documented successors and
|
|
847
|
+
the recipe MUST target them — anchoring a surface-wide goal on a deprecated
|
|
848
|
+
member is a scope error, not a style choice. (FEAT-0068: the ISA enumerated the
|
|
849
|
+
44 existing consumers of env(safe-area-*) and anchored "the header" on a
|
|
850
|
+
@deprecated Header.tsx serving 5 pages, while the successors DrilldownHeader/
|
|
851
|
+
SectionHeader — 63 files, ~90% of screens — appeared in NO card; the coverage
|
|
852
|
+
gate then passed 44/44 vacuously against the wrong inventory.)
|
|
818
853
|
|
|
819
854
|
For each touchpoint found, report:
|
|
820
855
|
- Category (from above)
|
|
@@ -114,6 +114,34 @@ dimension from the discovery checklist. Pick exactly one branch:
|
|
|
114
114
|
| `mockups.status: none` AND `mockups.source: internal` | **Full** | Run the standard pipeline 3a → 3b → 3c → 3d → 3e as below. `step_3_mode: full`. |
|
|
115
115
|
| `mockups.status` ∈ {`provided`, `partial`} AND UI impact ≠ N/A | **Hybrid** | Per-screen routing (see § Hybrid mode below). `step_3_mode: hybrid` (or `mockup-only` if every screen is covered AND no `mockup_analysis.design_system_alignment.violations` — distinct from `skipped`, which means no UI at all). |
|
|
116
116
|
|
|
117
|
+
**`step_3_mode` is a CLOSED ENUM (v5.6.0): `full | hybrid | mockup-only | skipped |
|
|
118
|
+
pending_external_handoff`.** Writing any other value is a protocol violation the Step 6
|
|
119
|
+
validator now rejects deterministically. The FEAT-0068 session invented `design-spec` when the
|
|
120
|
+
user declined mockups on a UI feature — an unscoped gap the model filled by fabrication — and
|
|
121
|
+
the hand-authored inline "visual explainer" it produced became `links.design` on 5/6 cards,
|
|
122
|
+
routing a docs card to ui-expert downstream. The rules that close that gap:
|
|
123
|
+
- **`skipped` means NO design artifact.** No inline design.html, no "visual spec" Write, and
|
|
124
|
+
`links.design` stays EMPTY on every card. Any visual explainer the user asks for goes through
|
|
125
|
+
`Skill(ui-design)` (which runs its craft gates) — the orchestrator NEVER hand-authors design
|
|
126
|
+
HTML.
|
|
127
|
+
- **UI feature + user declines mockups is still `skipped`** (or Full if the user accepts
|
|
128
|
+
internal generation) — there is no third "spec-only" lane. What the cards need instead is
|
|
129
|
+
§ Reconciliation-lite below.
|
|
130
|
+
- **Reconciliation-lite (v5.6.0 — "no mockup" must NOT mean "no reconciliation").** When
|
|
131
|
+
`step_3_mode: skipped` (or `mockup-only`) AND the feature touches design-system primitives
|
|
132
|
+
(`features.has_design_system: true`), STILL run the registry half of Component
|
|
133
|
+
Reconciliation: resolve the affected ROLE FAMILIES from `${paths.design_system}/INDEX.md`
|
|
134
|
+
(Selection Policy + role families — same lens as the ISA "UI ROLE FAMILY" category, which by
|
|
135
|
+
now has enumerated the owners), and emit `component_bindings` for the cards from the registry
|
|
136
|
+
alone. The FEAT-0068 chain — mockups skipped → reconciliation never ran → the registry that
|
|
137
|
+
named DrilldownHeader/SectionHeader as the canonical headers was never consulted → the recipe
|
|
138
|
+
anchored on a @deprecated component — is exactly what this closes.
|
|
139
|
+
- **Re-enumeration trigger (v5.6.0).** If a design/recipe decision taken IN THIS PHASE changes
|
|
140
|
+
WHAT the feature applies to (a different component family, a broader/narrower surface than
|
|
141
|
+
discovery assumed), the ISA surface inventory is STALE: re-run the affected ISA category
|
|
142
|
+
(Dimension 9 — at minimum UI ROLE FAMILY) before PRD writing. Locking a recipe after the scan
|
|
143
|
+
without re-enumerating is how a correct inventory goes wrong silently.
|
|
144
|
+
|
|
117
145
|
Mark task 2 as `in_progress` for the Full and Hybrid branches.
|
|
118
146
|
|
|
119
147
|
## Delegation to `ui-design` Skill
|
|
@@ -52,6 +52,19 @@ Mark task 5 as `in_progress`.
|
|
|
52
52
|
surface / ISA file owned by NO card is a BLOCKER (this is the gap that otherwise surfaces only
|
|
53
53
|
at `/new`'s expensive final review). Message: `"ISA touchpoint <path> (<category>) is owned by
|
|
54
54
|
no card — assign it to a card's files_likely_touched."`
|
|
55
|
+
- **Universal-quantifier epic AC gate (v5.6.0 — FEAT-0068):** for every EPIC acceptance
|
|
56
|
+
criterion carrying a universal quantifier over a UI/route surface ("ogni schermata",
|
|
57
|
+
"tutte le route", "every screen", "all pages", "nessun <difetto> su <superficie>"),
|
|
58
|
+
derive the surface's OWNER components from the **fresh registry/ISA census** (the
|
|
59
|
+
UI ROLE FAMILY touchpoints of discovery Dimension 9 — NOT the raw mechanism-consumer
|
|
60
|
+
touchpoints, or you inherit an incomplete inventory) and verify each owner appears in
|
|
61
|
+
the union of the child cards' `files_likely_touched`/scope. An owner covered by NO
|
|
62
|
+
child is a BLOCKER: `"Epic AC-<n> quantifies over <surface> but owner <component>
|
|
63
|
+
(<N> files) belongs to no card."` Persist the resolved owner list as
|
|
64
|
+
`invariant_owners:` in the epic YAML so the `/new` epic-closure gate can re-verify
|
|
65
|
+
it. (FEAT-0068: the epic promised "no seam on every screen" while DrilldownHeader/
|
|
66
|
+
SectionHeader — ~90% of screens — belonged to no card; the ISA→card gate passed
|
|
67
|
+
44/44 vacuously because the inventory itself was wrong.)
|
|
55
68
|
Both are SEMANTIC (path extraction from prose / ISA needs interpretation) — bias toward flagging.
|
|
56
69
|
|
|
57
70
|
**Gate**: the 0-i validator exits 0 on every card (enums, conditional `requirements`, zero
|
|
@@ -59,6 +72,22 @@ Mark task 5 as `in_progress`.
|
|
|
59
72
|
checks (b)/(c) are noted in the audit log; user may accept them after review. The 0-i and (e)
|
|
60
73
|
BLOCKERs must be fixed before commit.
|
|
61
74
|
|
|
75
|
+
0-ii. **Phase-evidence audit (v5.6.0 — executed, not recited; FEAT-0068 shipped TWO phantom
|
|
76
|
+
gates).** Deterministic checks on the STATE FILE before the audit protocol runs:
|
|
77
|
+
- **`module_read` stamps**: each executed phase section must carry its `module_read:
|
|
78
|
+
<reference file> (full)` stamp (SKILL.md § phase-module loading). A phase that ran with
|
|
79
|
+
its module unread is a protocol violation to surface — on FEAT-0068, `research-phase.md`,
|
|
80
|
+
`prd-writing-phase.md` and `backlog-phase.md` were never read and the improvised Step 5
|
|
81
|
+
contract produced the EARS rework round.
|
|
82
|
+
- **Gate stamps carry evidence**: any gate recorded as run/passed/`N/A` (API Performance
|
|
83
|
+
Gate, holistic audit, Codex Discovery Cross-Check) must name its evidence — an agent
|
|
84
|
+
spawn/report path for agent gates, the concrete reason for an `N/A`. A gate stamp with no
|
|
85
|
+
evidence is treated as NOT RUN (the FEAT-0068 session stamped `pass # N/A` on the API
|
|
86
|
+
gate without ever spawning the auditor, and the holistic stamp landed with zero audit
|
|
87
|
+
spawns).
|
|
88
|
+
- **`step_3_mode` ∈ {full, hybrid, mockup-only, skipped, pending_external_handoff}**: any
|
|
89
|
+
other value (the session fabricated `design-spec`) is a BLOCKER — fix the state file and
|
|
90
|
+
re-run the branch it should have taken.
|
|
62
91
|
1. **Field Name Audit (runs after item 0 — only when item 0 passes for a given card; skipped for cards blocked in item 0)** — for each generated card:
|
|
63
92
|
|
|
64
93
|
a. Verify every `data_fields` entry has `ts_verified: true` OR `status: new` with `schema_ref`.
|
|
@@ -142,9 +171,15 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
|
|
|
142
171
|
HOLISTIC_AUDITED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
143
172
|
HOLISTIC_AUDITED_COMMIT="$(git -C "$WORKTREE_PATH" merge-base HEAD "${git.trunk_branch}" 2>/dev/null || git -C "$WORKTREE_PATH" rev-parse "${git.trunk_branch}" 2>/dev/null || echo "")"
|
|
144
173
|
# --set = the sorted Step-5 child card IDs (the joint cross-card scope), comma-separated.
|
|
174
|
+
# --audit-report (v5.6.0, REQUIRED for a full stamp) = the audit-phase report artifact
|
|
175
|
+
# (e.g. /tmp/prd-audit-<slug>.md, written by audit-phase Step 6.9 with its `agents_run:`
|
|
176
|
+
# line). NO artifact on disk = the audit team never ran (the FEAT-0068 phantom stamp) →
|
|
177
|
+
# run WITHOUT the flag and the script writes `status: skipped` + NO agents_run, which
|
|
178
|
+
# /new's P1 treats as ABSENT (plan-auditor runs — fail-safe, exactly right).
|
|
145
179
|
node .framework/framework/scripts/stamp-holistic-audit.js \
|
|
146
180
|
--at "$HOLISTIC_AUDITED_AT" --commit "$HOLISTIC_AUDITED_COMMIT" \
|
|
147
|
-
--set "<ID1,ID2,...>" "
|
|
181
|
+
--set "<ID1,ID2,...>" --audit-report "/tmp/prd-audit-<slug>.md" \
|
|
182
|
+
"$WORKTREE_PATH/${paths.backlog_dir}"/FEAT-XXXX-*.yml
|
|
148
183
|
```
|
|
149
184
|
The script is **idempotent** (a card already stamped by Step 6.9.4 is untouched),
|
|
150
185
|
**additive** (never overwrites other `metadata` keys), skips EPIC cards (they carry
|
|
@@ -223,6 +258,15 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
|
|
|
223
258
|
Input: { "worktreePath": "$WORKTREE_PATH" }
|
|
224
259
|
```
|
|
225
260
|
|
|
261
|
+
**HARD RULE (v5.6.0 — FEAT-0068 N1): `mw-docs`, NEVER generic `/mw`, for a docs worktree.**
|
|
262
|
+
The registry entry for this worktree says `kind: "docs"` — a generic `/mw` on it runs the
|
|
263
|
+
forbidden unbounded `npm run build` (a docs worktree has no node_modules → guaranteed false
|
|
264
|
+
BUILD_FAIL, manual recovery, classifier-blocked push; ~4M wasted on the real session). If
|
|
265
|
+
you find yourself about to call `/mw`, or to invent invocation args (`checksAlreadyPassed`
|
|
266
|
+
is NOT an input of this contract), STOP — the invocation above is the whole contract.
|
|
267
|
+
`/mw` itself refuses a `kind: "docs"` worktree since v5.6.0 (worktree-manager pre-flight),
|
|
268
|
+
but do not rely on the belt: use the right mode.
|
|
269
|
+
|
|
226
270
|
The skill executes:
|
|
227
271
|
- Safety commit (idempotent — likely no-op after step 8; if any file was
|
|
228
272
|
missed by item 6's explicit list, the safety commit picks it up, but the
|
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 1.2.0 — 2026-07-04 (FEAT-0068 post-mortem)
|
|
6
|
+
|
|
7
|
+
- **`merge-worktree.sh --safety-sweep <all|allowlist:globs>`**: in modalità allowlist il
|
|
8
|
+
safety commit pre-rebase stagia SOLO i file che matchano (bookkeeping del batch), con
|
|
9
|
+
messaggio onesto che li enumera; le modifiche TRACKED fuori allowlist vengono messe in
|
|
10
|
+
quarantena byte-per-byte (`quarantined:` nel manifest) e ripristinate a HEAD, gli
|
|
11
|
+
untracked restano su disco (`uncommitted_left:`). Default `all` invariato per `/mw`
|
|
12
|
+
interattivo. Chiude lo split-brain col F-030 del chiamante ("[safety] Auto-commit" da
|
|
13
|
+
751 righe opaco su develop, ricorrente FEAT-0067/FEAT-0068).
|
|
14
|
+
- **Guardia docs-worktree in `/mw`** (BLOCKING, step 1): registry `kind: "docs"` ⇒ rifiuto
|
|
15
|
+
con puntatore a `mw-docs` (un `/mw` generico su un docs worktree = build unbounded senza
|
|
16
|
+
node_modules ⇒ BUILD_FAIL falso garantito, ~4M su un run `/prd` reale).
|
|
17
|
+
|
|
5
18
|
## 1.1.0 — 2026-07-03
|
|
6
19
|
|
|
7
20
|
### Fixed — local-trunk sync robustness (step 4c "Common", both strategies)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: worktree-manager
|
|
3
3
|
effort: medium
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
description: >
|
|
6
6
|
Manage fully independent git worktrees for parallel coding agents.
|
|
7
7
|
Commands: /nw (new worktree) creates an isolated workspace with its own
|
|
@@ -685,6 +685,16 @@ Supports two modes:
|
|
|
685
685
|
|
|
686
686
|
Read `.worktrees/registry.json`. If multiple entries exist or user didn't specify, list them and ask which to merge.
|
|
687
687
|
|
|
688
|
+
**Docs-worktree guard (v5.6.0 — BLOCKING, before anything else).** If the resolved registry
|
|
689
|
+
entry carries `kind: "docs"`, this is the WRONG mode: REFUSE and route to `mw-docs`
|
|
690
|
+
(programmatic: `Mode: programmatic, mw-docs`). A generic `/mw` on a docs worktree runs the
|
|
691
|
+
build/check pipeline against a tree with no node_modules → a guaranteed false BUILD_FAIL,
|
|
692
|
+
manual recovery, and a blocked push (observed on a real `/prd` session: ~4M tokens + a human
|
|
693
|
+
unblock). Message: `"WRONG MODE: worktree '<slug>' is kind:docs — use mw-docs (docs merge:
|
|
694
|
+
no build, additive-registry resolution). Refusing generic /mw."` Also ignore any invented
|
|
695
|
+
invocation args (`checksAlreadyPassed` is a `/new`-orchestrator flag, not a user contract) —
|
|
696
|
+
the registry entry is the SSOT for what kind of merge this is.
|
|
697
|
+
|
|
688
698
|
Fallback: `git worktree list` if registry is missing.
|
|
689
699
|
|
|
690
700
|
Determine, reading them from the worktree's registry entry (R6):
|