baldart 3.38.0 → 3.40.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 +45 -0
- package/VERSION +1 -1
- package/framework/.claude/skills/new/SKILL.md +41 -31
- package/framework/.claude/skills/prd/references/validation-phase.md +47 -1
- package/framework/.claude/skills/worktree-manager/SKILL.md +54 -6
- package/framework/AGENTS.md +2 -2
- package/framework/docs/FIX-APPLICATION-TELEMETRY.md +5 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,51 @@ 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
|
+
## [3.40.0] - 2026-06-01
|
|
9
|
+
|
|
10
|
+
**Doc fixes surfaced by `/new`'s doc-review are now applied by the `doc-reviewer` itself, not delegated to `coder`.** The `doc` fix-domain owner changes from `coder` to `doc-reviewer` (write mode) across every `/new` site that previously spawned a coder for documentation: sequential Phase 3, team-mode D.4a, and the post-batch Final review. **No new `baldart.config.yml` keys** — this is a fix-routing change internal to `/new`.
|
|
11
|
+
|
|
12
|
+
> **Why.** When `/new`'s post-implementation doc-review found stale/missing docs, the remediation was routed to `coder` — the wrong agent on two counts. (1) It's *overkill*: the `doc-reviewer` already ran the audit and has the full doc context in-context; a coder spawn re-derives it from scratch. (2) It's *wrong*: the doc invariants the orchestrator must not break (freshness markers, linking protocol, frontmatter standard, tabular formatting, SSOT/registry coverage, dependency-topological order, SCIP/code refs) are encoded in the **`doc-reviewer`** system prompt, NOT the coder's — so doc fixes were going to the agent *least* equipped for them. The `doc-reviewer.md` Constraints already mandate "WRITE missing docs directly … do not defer to other agents"; `/new` Phase 3 contradicted that by invoking it read-only and handing the fix to `coder`. The v3.28.3 Domain-Override decision was framed as "orchestrator-inline **vs** coder" and simply never put "doc-reviewer writes" on the menu. This release closes that gap. (`/prd` is unaffected — it *produces* docs directly via `prd-card-writer`/the writing phases and has no read-only-audit→remediation loop.)
|
|
13
|
+
|
|
14
|
+
### Changed — `doc` fix-domain owner is now `doc-reviewer` (not `coder`)
|
|
15
|
+
|
|
16
|
+
- **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** — Domain-Override Domains table: the `doc` domain now carries an explicit **Owning agent = `doc-reviewer` (write mode)** column, with a rationale block ("Why `doc` is owned by `doc-reviewer`, not `coder`"). `security` and `migration` stay with `coder`. The mechanical `CHANGELOG.md`/`ssot-registry.md` append edge case now goes through `doc-reviewer`, never `coder`.
|
|
17
|
+
- **Sequential Phase 3** collapses from two spawns (doc-reviewer read-only audit + coder apply) to **one** — the doc-reviewer audits AND applies in a single invocation (it runs alone; code-review moved to Phase 3.7, so the old read-only/parallel-safety constraint no longer applies). The only output it does NOT fix itself is a doc-drift→bug finding rooted in CODE, which follows the code fix path.
|
|
18
|
+
- **Team-mode D.2/D.4a**: D.2 keeps the doc-reviewer **read-only** (it runs in parallel with `code-reviewer` — parallel-safety preserved); D.4a now re-invokes the **doc-reviewer in write mode** over the group to apply the per-card-attributed findings, instead of spawning a fix-coder.
|
|
19
|
+
- **Final review F.5**: verified `>= MEDIUM` findings are now partitioned by domain — `doc`-domain findings → `doc-reviewer`, all other findings → `coder`.
|
|
20
|
+
|
|
21
|
+
### Changed — Fix Application telemetry recognises the new owner
|
|
22
|
+
|
|
23
|
+
- **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** Fix Application Log Schema: `decision` and `applied_by` gain the `doc-reviewer` value; `phase` gains `D.4a`. (The analyzer regex in `framework/scripts/analyze-fix-application.js` already accepts arbitrary `[\w-]+` tokens — no code change needed.)
|
|
24
|
+
- **[framework/docs/FIX-APPLICATION-TELEMETRY.md](framework/docs/FIX-APPLICATION-TELEMETRY.md)**: violation/healthy pattern tables updated — `applied_by=coder` on a Phase 3 `doc` row is now itself a violation; the healthy doc pattern is `decision=doc-reviewer | applied_by=doc-reviewer`.
|
|
25
|
+
|
|
26
|
+
## [3.39.0] - 2026-06-01
|
|
27
|
+
|
|
28
|
+
**A `/prd` or `/new` run now CONCLUDES clean — it never ends by handing the user a list of "azioni tue, non bloccanti" (an uncommitted file blocking the local `develop` fast-forward, a merged remote branch left undeleted).** Every workspace-hygiene leftover is either auto-resolved by the finalizer or put behind ONE explicit `AskUserQuestion` gate. No passive manual TODO ever survives into the final summary. **No new `baldart.config.yml` keys.**
|
|
29
|
+
|
|
30
|
+
> **Why.** A `/prd` finalization closed with: *"il develop locale non si è fast-forwardato per una modifica non committata pre-esistente a `docs/metrics/skill-runs.jsonl` — gestisci quel file e poi `git pull --ff-only`"* and *"il branch remoto non è stato eliminato — puoi cancellarlo a mano"*. The orchestrator declared the run "completato" while leaving the workspace half-finished. Root cause: `worktree-manager mw-docs` printed `⚠️ … Leaving as-is` on a blocked fast-forward, and `/prd` (unlike `/new` Phase 6c) had no workspace-hygiene phase to consume that — it forwarded the warning to the user verbatim.
|
|
31
|
+
|
|
32
|
+
### Changed — the merge finalizer auto-resolves instead of giving up
|
|
33
|
+
|
|
34
|
+
- **[framework/.claude/skills/worktree-manager/SKILL.md](framework/.claude/skills/worktree-manager/SKILL.md)** (Common — sync local develop): the blocked-ff path no longer prints `Leaving as-is`. It partitions the dirty tree: the framework-owned append-only telemetry log (`docs/metrics/skill-runs.jsonl`) is reconciled autonomously and losslessly (commit + `pull --rebase` + best-effort push) so the ff completes; ANY foreign file emits a new `[SYNC-NEEDS-DECISION]` marker the orchestrator MUST convert into one explicit gate. Work this run does not own is never auto-committed.
|
|
35
|
+
- **[framework/.claude/skills/worktree-manager/SKILL.md](framework/.claude/skills/worktree-manager/SKILL.md)** (Cleanup step 6.3 + report): merged remote-branch deletion is now an explicit, reported step (was `2>/dev/null || true` silent) — a denial is retried, never degraded into a "puoi cancellarlo a mano" note.
|
|
36
|
+
|
|
37
|
+
### Added — `/prd` Step 7.5 Workspace Hygiene & finalization (BLOCKING)
|
|
38
|
+
|
|
39
|
+
- **[framework/.claude/skills/prd/references/validation-phase.md](framework/.claude/skills/prd/references/validation-phase.md)**: new Step 7.5 mirrors `/new` Phase 6c — consumes the `[SYNC-NEEDS-DECISION]` / `[SYNC-DEFERRED]` markers, raises ONE `AskUserQuestion` per unresolved residue, ensures the merged remote branch is gone. New **HARD RULE** in Final output: the summary MUST NOT contain a "azioni tue / note non bloccanti" section — a run that prints "gestisci tu il file e poi pulla" has FAILED Step 7.5.
|
|
40
|
+
|
|
41
|
+
### Changed — `/new` Phase 6c parses the new marker
|
|
42
|
+
|
|
43
|
+
- **[framework/.claude/skills/new/SKILL.md](framework/.claude/skills/new/SKILL.md)** (Phase 6c step 2): now also parses `[SYNC-NEEDS-DECISION]` (foreign-file ff block / rebase conflict) as a blocking gate, alongside the existing `[SYNC-DEFERRED]`.
|
|
44
|
+
|
|
45
|
+
### Changed — AGENTS.md scopes branch-deletion approval to unmerged branches
|
|
46
|
+
|
|
47
|
+
- **[framework/AGENTS.md](framework/AGENTS.md)**: owner approval is required before deleting an **unmerged** branch; deleting an **already-merged** feature branch is routine cleanup the merge skill performs automatically (no separate approval). The "prune remote branches only when instructed" rule is clarified to exclude a feature branch's own ref on successful merge.
|
|
48
|
+
|
|
49
|
+
### Revert
|
|
50
|
+
|
|
51
|
+
- Restore the `git -C "$MAIN" pull --ff-only origin develop || echo "⚠️ … Leaving as-is."` one-liner in `worktree-manager` and drop `/prd` Step 7.5.
|
|
52
|
+
|
|
8
53
|
## [3.38.0] - 2026-06-01
|
|
9
54
|
|
|
10
55
|
**The per-card review depth (QA + Codex) is now decided deterministically in the backlog card via a new `review_profile` field, computed once at PRD authoring time — instead of being re-derived heuristically by `/new` at runtime.** This removes the implementing agent's interpretation latitude: the card carries `skip|light|balanced|deep`, `/new` READS it, and only falls back to runtime computation for legacy cards that predate the field. **No new `baldart.config.yml` keys** — this is a backlog-card schema change, propagated end-to-end across templates + card-writer + validation + `/new` in the same release.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.40.0
|
|
@@ -962,16 +962,16 @@ Every fix-application decision in Phases 2.55 / 3 / 3.5 / 3.7 appends one row to
|
|
|
962
962
|
**Row format** (one row per finding processed, including skipped):
|
|
963
963
|
|
|
964
964
|
```
|
|
965
|
-
<phase> | <domain> | est_lines=<n> | decision=<inline|coder|coder-batch|skipped> | applied_by=<orchestrator|coder|orchestrator-fallback|-> | <key=val>...
|
|
965
|
+
<phase> | <domain> | est_lines=<n> | decision=<inline|coder|coder-batch|doc-reviewer|skipped> | applied_by=<orchestrator|coder|doc-reviewer|orchestrator-fallback|-> | <key=val>...
|
|
966
966
|
```
|
|
967
967
|
|
|
968
968
|
| Field | Values |
|
|
969
969
|
|---|---|
|
|
970
|
-
| `phase` | `2.55`, `3`, `3.5`, `3.7` |
|
|
970
|
+
| `phase` | `2.55`, `3`, `3.5`, `3.7`, `D.4a` (team-mode doc gate) |
|
|
971
971
|
| `domain` | `simplify-reuse`, `simplify-quality`, `simplify-efficiency`, `doc`, `qa-blocker`, `qa-major`, `qa-minor`, `qa-none`, `codex-security`, `codex-correctness`, `codex-other` |
|
|
972
972
|
| `est_lines` | Orchestrator's at-a-glance estimate of the diff size suggested by the finding. Bucketed `1-5` / `6-20` / `21+` is sufficient — exact precision not required. Use `0` if no patch (e.g. skipped). |
|
|
973
|
-
| `decision` | `inline` (orchestrator applied), `coder` (single coder spawn for this finding), `coder-batch` (folded into a batched coder spawn covering ≥2 findings), `skipped` (false positive / not worth addressing / no findings) |
|
|
974
|
-
| `applied_by` | `orchestrator`, `coder`, `orchestrator-fallback` (agent crash with non-domain-override fallback — see Sub-agent failure protocol), `-` (skipped) |
|
|
973
|
+
| `decision` | `inline` (orchestrator applied), `coder` (single coder spawn for this finding), `coder-batch` (folded into a batched coder spawn covering ≥2 findings), `doc-reviewer` (doc-domain fix applied by the doc-reviewer in write mode — since v3.40.0), `skipped` (false positive / not worth addressing / no findings) |
|
|
974
|
+
| `applied_by` | `orchestrator`, `coder`, `doc-reviewer` (doc-domain owner — since v3.40.0), `orchestrator-fallback` (agent crash with non-domain-override fallback — see Sub-agent failure protocol), `-` (skipped) |
|
|
975
975
|
| Trailing `key=val` | Phase-specific extras: `finding=<1-line summary>`, `severity=<BLOCKER\|HIGH\|MEDIUM\|FALSE-POSITIVE>`, `retry=<n>`, `reason=<...>` |
|
|
976
976
|
|
|
977
977
|
**Write target**: the same tracker file the orchestrator already writes per-card status to (path resolved from `${paths.references_dir}/trackers/` or the project's tracker convention). Section header `## Fix Application Log` is created on first row of the card. Append-only — never rewrite previous rows.
|
|
@@ -980,17 +980,19 @@ Every fix-application decision in Phases 2.55 / 3 / 3.5 / 3.7 appends one row to
|
|
|
980
980
|
|
|
981
981
|
#### Domain-Override Domains (since v3.28.3)
|
|
982
982
|
|
|
983
|
-
Some fix domains are **never** safe for inline orchestrator apply, regardless of size
|
|
983
|
+
Some fix domains are **never** safe for inline orchestrator apply, regardless of size — the orchestrator MUST delegate every fix in these domains to the **domain-owning agent**, even when the patch is a one-liner. The owning agent is the one whose system prompt + project overlay encodes that domain's invariants; an orchestrator inline edit (or a fix routed to the wrong agent) routinely breaks them.
|
|
984
984
|
|
|
985
985
|
Enumerated tassativamente:
|
|
986
986
|
|
|
987
|
-
| Domain | Match rule |
|
|
988
|
-
|
|
989
|
-
| `doc` | File path matching `*.md` under `${paths.references_dir}`, `${paths.prd_dir}`, project root `CHANGELOG.md`, or any `ssot-registry.md`. |
|
|
990
|
-
| `security` | File path matching the Phase 3.7 detector Triggers #2 (auth/permissions: `src/lib/auth/middleware.ts`, `src/lib/permissions.ts`, anything matching `withAuth`) or #3 (payments: `^src/lib/payments/`, `^src/app/api/v1/billing/`). Also any SQL migration whose content matches `CREATE POLICY|ALTER POLICY|DROP POLICY` (RLS policy mutations). |
|
|
991
|
-
| `migration` | File path matching `supabase/migrations/*.sql` (or `${paths.migrations_dir}/*.sql` if defined in `baldart.config.yml`). |
|
|
987
|
+
| Domain | Owning agent | Match rule |
|
|
988
|
+
|---|---|---|
|
|
989
|
+
| `doc` | **`doc-reviewer`** (write mode) | File path matching `*.md` under `${paths.references_dir}`, `${paths.prd_dir}`, project root `CHANGELOG.md`, or any `ssot-registry.md`. |
|
|
990
|
+
| `security` | `coder` | File path matching the Phase 3.7 detector Triggers #2 (auth/permissions: `src/lib/auth/middleware.ts`, `src/lib/permissions.ts`, anything matching `withAuth`) or #3 (payments: `^src/lib/payments/`, `^src/app/api/v1/billing/`). Also any SQL migration whose content matches `CREATE POLICY|ALTER POLICY|DROP POLICY` (RLS policy mutations). |
|
|
991
|
+
| `migration` | `coder` | File path matching `supabase/migrations/*.sql` (or `${paths.migrations_dir}/*.sql` if defined in `baldart.config.yml`). |
|
|
992
|
+
|
|
993
|
+
**Why `doc` is owned by `doc-reviewer`, not `coder` (since v3.40.0)** — the doc invariants the orchestrator must not break (freshness markers, linking protocol, frontmatter standard, tabular formatting, SSOT/registry coverage, dependency-topological order, SCIP/code refs) are encoded in the **`doc-reviewer`** system prompt, NOT the coder's. The coder is a code-oriented agent that lacks the doc-invariant contract — routing doc fixes to it is the wrong agent doing work the auditing agent already has full context for. The agent that *audits* the docs is also the agent that *fixes* them (`doc-reviewer.md` § Constraints: "WRITE missing docs directly. You are fully responsible — do not defer to other agents"). NEVER route a `doc`-domain fix to `coder`.
|
|
992
994
|
|
|
993
|
-
**Edge case explicit** — a mechanical append-a-row update to `CHANGELOG.md` or `ssot-registry.md` is still classified `doc` and still goes through coder
|
|
995
|
+
**Edge case explicit** — a mechanical append-a-row update to `CHANGELOG.md` or `ssot-registry.md` is still classified `doc` and still goes through `doc-reviewer`, never inline and never `coder`. The uniformity of the rule matters more than the cost of the individual spawn.
|
|
994
996
|
|
|
995
997
|
Domains NOT listed here remain governed by the per-phase rules of the corresponding phase (e.g. `simplify-*` follows Phase 2.55 inline rule).
|
|
996
998
|
|
|
@@ -1158,30 +1160,31 @@ skill's Phase 1 falls back to deriving Gherkin scenarios from
|
|
|
1158
1160
|
- [derive from FRESHNESS_MAP: src/app/api/** → ${paths.references_dir}/api/; src/lib/booking/** → booking.md etc.]
|
|
1159
1161
|
```
|
|
1160
1162
|
|
|
1161
|
-
Invoke the **doc-reviewer** agent
|
|
1163
|
+
Invoke the **doc-reviewer** agent in **audit-and-apply mode** (single invocation — it both finds the gaps AND fixes them, per `doc-reviewer.md` § Constraints), passing the Doc Sync Context:
|
|
1162
1164
|
```
|
|
1163
1165
|
Doc Sync Context:
|
|
1164
1166
|
[paste the Doc Sync Context block built above]
|
|
1165
1167
|
|
|
1166
1168
|
Instructions for doc-reviewer:
|
|
1169
|
+
- You OWN the `doc` domain end-to-end: audit AND apply the fixes in THIS invocation.
|
|
1170
|
+
Do NOT defer doc writes to another agent — you are the agent with the doc-invariant
|
|
1171
|
+
contract and the full context. Write the missing/stale docs directly.
|
|
1167
1172
|
- Set freshness_status: fresh and last_verified_from_code: <today's date> on any doc you touch
|
|
1168
|
-
- Check each invariant in the checklist above and
|
|
1169
|
-
-
|
|
1170
|
-
- Run your standard doc audit on all changed files
|
|
1173
|
+
- Check each invariant in the checklist above and fix any that are unmet
|
|
1174
|
+
- Update any doc in "Related docs to check" that should be marked stale/fresh
|
|
1175
|
+
- Run your standard doc audit on all changed files and apply the corrections
|
|
1171
1176
|
- **Spec/docs-drift → bug lens (MANDATORY since v3.35.0)**: flag any place where the
|
|
1172
1177
|
implementation contradicts a documented contract/spec in a way that can cause incorrect
|
|
1173
1178
|
behavior (response shape diverging from `api/<module>.md`, field semantics diverging from
|
|
1174
1179
|
`data-model.md`, etc.). This lens was previously exclusive to `/codexreview` agent #4; the
|
|
1175
1180
|
per-card Phase 3.7 gate now skips that duplicate (lean mode), so THIS pass MUST carry it.
|
|
1176
|
-
|
|
1181
|
+
A doc-drift→bug finding whose root cause is in CODE (not the doc) is the ONE thing
|
|
1182
|
+
doc-reviewer does NOT fix itself — report it with the conflicting code location + the doc
|
|
1183
|
+
it violates, and the orchestrator routes it to the `security`/code fix path as appropriate.
|
|
1177
1184
|
```
|
|
1178
|
-
Doc-reviewer
|
|
1179
|
-
14. **Obsidian Corpus Dispatch**: Parse section H from doc-reviewer findings. If `Trigger: YES`, dispatch the `obsidian-sync` agent (`.claude/agents/obsidian-sync.md`) with the listed paths after
|
|
1180
|
-
15.
|
|
1181
|
-
|
|
1182
|
-
**Doc fixes are NEVER applied inline by the orchestrator**, regardless of size or perceived triviality (since v3.28.3). `doc` is a domain-override domain — see "Domain-Override Domains" sub-section. A one-line `CHANGELOG.md` append and a 50-line `data-model.md` migration row update both go through coder. The freshness invariants and tabular formatting that the coder's system prompt enforces are routinely broken by orchestrator inline edits; the cost of a coder spawn is the cost of correctness.
|
|
1183
|
-
|
|
1184
|
-
**Telemetry** — after the coder returns, append one row per doc finding to `## Fix Application Log`: `3 | doc | est_lines=<n> | decision=coder-batch | applied_by=coder | finding=<1-line>`. If 0 findings, append one row: `3 | doc | est_lines=0 | decision=skipped | applied_by=- | reason=no-findings`.
|
|
1185
|
+
Doc-reviewer applies all doc-domain fixes itself. The orchestrator does NOT spawn a coder for doc fixes (since v3.40.0 — `doc` is owned by `doc-reviewer`, see "Domain-Override Domains"). The only doc-reviewer output that leaves this phase unfixed is a doc-drift→bug finding rooted in code, which follows the normal code fix path.
|
|
1186
|
+
14. **Obsidian Corpus Dispatch**: Parse section H from doc-reviewer findings. If `Trigger: YES`, dispatch the `obsidian-sync` agent (`.claude/agents/obsidian-sync.md`) with the listed paths after the doc fixes are applied. If `Trigger: NO`, skip. This is non-blocking -- do not wait for obsidian-sync to complete before proceeding.
|
|
1187
|
+
15. **Telemetry** — after doc-reviewer returns, append one row per doc finding to `## Fix Application Log`: `3 | doc | est_lines=<n> | decision=doc-reviewer | applied_by=doc-reviewer | finding=<1-line>`. If 0 findings, append one row: `3 | doc | est_lines=0 | decision=skipped | applied_by=- | reason=no-findings`.
|
|
1185
1188
|
16. Run `npm run lint` and `npx tsc --noEmit` to verify nothing broke. If any check fails, apply the self-healing retry loop (up to 3 times, no user prompt).
|
|
1186
1189
|
17. **Update tracker**: phase = "3-doc-review DONE", log doc findings count, fixes applied.
|
|
1187
1190
|
If doc-reviewer found a recurring gap, append 1-line to `## Lessons Learned`:
|
|
@@ -1557,8 +1560,10 @@ Once ALL cards are committed in the worktree:
|
|
|
1557
1560
|
### Step F.5 — Apply fixes and final build
|
|
1558
1561
|
|
|
1559
1562
|
10. **Persist verified findings** to `/tmp/batch-final-review-<FIRST-CARD-ID>.md`.
|
|
1560
|
-
11. If VERIFIED findings with severity >= MEDIUM exist,
|
|
1561
|
-
|
|
1563
|
+
11. If VERIFIED findings with severity >= MEDIUM exist, apply them by **domain owner** (since v3.40.0 — same Domain-Override routing as per-card phases). Partition the verified findings:
|
|
1564
|
+
- **`doc`-domain findings** (file path matching the `doc` match rule in "Domain-Override Domains" — `*.md` under `${paths.references_dir}`/`${paths.prd_dir}`, `CHANGELOG.md`, `ssot-registry.md`) → invoke the **doc-reviewer** agent once in write mode to apply them. NEVER route doc fixes to coder.
|
|
1565
|
+
- **All other findings** (code, perf, security, migration, test) → invoke the **coder** agent once to apply them in a single pass.
|
|
1566
|
+
Run both in the order doc-reviewer → coder (or skip either if its partition is empty). Pass only the verified findings, not false positives.
|
|
1562
1567
|
12. Run final build: `npm run lint && npx tsc --noEmit && npm run build`.
|
|
1563
1568
|
If any check fails, apply self-healing retry loop (up to 3 times).
|
|
1564
1569
|
13. **Update tracker** with final review results:
|
|
@@ -1745,9 +1750,14 @@ The most common failure mode is leaving cards IN_PROGRESS after merge. This crea
|
|
|
1745
1750
|
git -C "$MAIN" fetch origin --quiet
|
|
1746
1751
|
```
|
|
1747
1752
|
|
|
1748
|
-
2. **Parse `
|
|
1749
|
-
-
|
|
1750
|
-
|
|
1753
|
+
2. **Parse `mw-docs` sync markers** — scan the captured stdout from every `/mw` invocation in this batch (kept in the tracker under `## Worktree Merges`):
|
|
1754
|
+
- **`[SYNC-DEFERRED] main repo HEAD=<branch>`** (main repo HEAD ≠ develop) — surface via `AskUserQuestion`:
|
|
1755
|
+
- Question: `"Una o più merge worktree hanno deferito la sincronizzazione di local develop (main repo HEAD non era develop). Come riconcilio adesso?"`
|
|
1756
|
+
- Options: `[Ora HEAD è develop → ff-pull adesso]` / `[Lascia deferred (riconcilio io manualmente)]` / `[Mostra dettagli e fammi decidere]`.
|
|
1757
|
+
- **`[SYNC-NEEDS-DECISION] …`** (HEAD was develop but the ff was blocked by a **foreign** uncommitted file, or by a divergence/rebase conflict `/mw` would not auto-commit) — this is NEVER a passive note. Surface via `AskUserQuestion`:
|
|
1758
|
+
- Question: `"Il develop locale non si è sincronizzato: <dettaglio dal marker>. Come chiudo?"`
|
|
1759
|
+
- Options: `[Committa tu adesso (descrivi cosa)]` / `[Lo gestisco io — chiudi senza sync locale]` / `[Mostrami il diff e decidiamo]`.
|
|
1760
|
+
- **No marker** — `/mw` fast-forwarded (or auto-reconciled the framework telemetry log); nothing to parse.
|
|
1751
1761
|
|
|
1752
1762
|
3. **Clean-tree assertion (BLOCKING)**:
|
|
1753
1763
|
```bash
|
|
@@ -2052,7 +2062,7 @@ If at ANY point you are unsure where you are in the batch:
|
|
|
2052
2062
|
### Sequential mode (default for small batches)
|
|
2053
2063
|
|
|
2054
2064
|
- Cards execute one at a time through the full per-card pipeline (Phases 1-5).
|
|
2055
|
-
- Code review and doc review for the same card run as **parallel read-only audits**, then fixes are applied
|
|
2065
|
+
- Code review and doc review for the same card run as **parallel read-only audits**, then fixes are applied by domain owner: **doc findings → `doc-reviewer` (write mode)**, code/security/migration findings → `coder`. (Sequential Phase 3 is even simpler — doc-reviewer runs alone, so it audits AND applies in one invocation.)
|
|
2056
2066
|
- This mode is unchanged from the original behavior.
|
|
2057
2067
|
|
|
2058
2068
|
### Team mode (for complex batches)
|
|
@@ -2217,7 +2227,7 @@ After ALL agents in the group complete successfully:
|
|
|
2217
2227
|
|
|
2218
2228
|
1. **D.1 — Build verification (group)** — Run `npm run build` in the worktree to verify combined changes compile. If build fails, identify which card's changes broke it (from `git diff` per card), spawn a targeted fix-coder for those files only.
|
|
2219
2229
|
|
|
2220
|
-
2. **D.2 — Combined static review (group)** — Invoke **code-reviewer** + **doc-reviewer** IN PARALLEL (read-only) across ALL changes in the group. ONE combined pass — catches cross-card issues. The doc-reviewer MUST **attribute every finding to a specific card** (by file → ownership map) and
|
|
2230
|
+
2. **D.2 — Combined static review (group)** — Invoke **code-reviewer** + **doc-reviewer** IN PARALLEL (read-only) across ALL changes in the group. ONE combined pass — catches cross-card issues. The doc-reviewer runs **read-only here** (it cannot write while code-reviewer reads the same diff in parallel — parallel-safety), MUST **attribute every doc finding to a specific card** (by file → ownership map), and applies the full Phase 3 mandate INCLUDING the spec/docs-drift→bug lens (since v3.35.0). D.4a consumes these per-card findings and dispatches the doc-reviewer (now alone, in write mode) to apply them — no second AUDIT spawn, but the FIXES are still owned by doc-reviewer.
|
|
2221
2231
|
|
|
2222
2232
|
3. **D.3 — Apply fixes (group)** — If D.2 findings exist, spawn ONE fix-coder to apply all fixes in a single pass. Run build + lint after.
|
|
2223
2233
|
|
|
@@ -2229,7 +2239,7 @@ After ALL agents in the group complete successfully:
|
|
|
2229
2239
|
|
|
2230
2240
|
4. **D.4 — QA gate (group)** — Read each card's `review_profile` field (fallback: compute via the QA Profile Selector table for legacy cards). Select the HIGHEST profile across all cards in the group (e.g., if one card is BALANCED and another is DEEP, use DEEP). Invoke **qa-sentinel** once for the group.
|
|
2231
2241
|
|
|
2232
|
-
4a. **D.4a — Per-card doc gate (consumes D.2, since v3.35.0)** — Do NOT re-
|
|
2242
|
+
4a. **D.4a — Per-card doc gate (consumes D.2, since v3.35.0; doc-reviewer-applied since v3.40.0)** — Do NOT re-run the doc AUDIT (D.2 already produced per-card-attributed findings). If any card in the group has doc findings, invoke the **doc-reviewer once in write mode** over the group, passing the per-card-attributed findings from D.2, to APPLY all doc fixes in a single pass (it is now alone — code-reviewer is done — so the D.2 parallel-safety constraint no longer applies). Do **NOT** spawn a fix-coder for doc findings: `doc` is owned by `doc-reviewer` (see "Domain-Override Domains"); a code-oriented coder lacks the doc-invariant contract. The only exception is a doc-drift→bug finding rooted in CODE — that follows the D.4b code fix path. (Previously D.4a spawned a fix-coder per card; the audit was already collapsed to a single attributed D.2 pass. D.4b's per-card `/codexreview` also skips its doc-reviewer via the lean contract, so the doc AUDIT runs once per group while the doc FIXES run once per group via doc-reviewer.) **Telemetry** — append one row per applied doc finding to `## Fix Application Log`: `D.4a | doc | est_lines=<n> | decision=doc-reviewer | applied_by=doc-reviewer | card=<ID> | finding=<1-line>`.
|
|
2233
2243
|
|
|
2234
2244
|
4b. **D.4b — Pre-Merge Codex Review Gate (per-card, MANDATORY — UNCONDITIONAL)** — Invoke `/codexreview` for EACH card in the group, one at a time, BEFORE any commit. This mirrors Phase 3.7 of the sequential path and is non-skippable regardless of file paths or perceived risk. Apply the same fix sub-loop: if the consolidated report shows verified BLOCKER/HIGH findings, spawn a fix-coder and re-run `/codexreview <CARD-ID>` (max 2 retries per card). If still BLOCKER/HIGH after retries, ask the user before proceeding to D.5. The D.5 commits MUST NOT happen until every card in the group has a PASS verdict (or explicit user override via `AskUserQuestion`). Log results in the tracker under `## Pre-Merge Codex Review` per card. **Lean + profile (since v3.35.0)**: before each card's `/codexreview`, apply the same Review Profile Selector and write the same `/tmp/codexreview-lean-<CARD-ID>.json` contract as sequential Phase 3.7 Step C — `arch_baseline_path` pointing at `/tmp/arch-baseline-group-<FIRST-CARD-ID>.md`, `skip_doc_reviewer: true`, and `profile: light|full` derived from the card's `review_profile` (`skip`/`light` → `light`, `balanced`/`deep` → `full`; since v3.38.0 read from the card, not recomputed) — with the same **escalation-only** rule: a Step A high-risk trigger on the actual diff promotes `light` → `full`, never the reverse. LIGHT runs `code-reviewer` + FP-gate only — the per-card **Codex adversarial pass is dropped at `light` since v3.38.0** (prerogative of `full` + the final cross-check). The Review Profile Selector is **ACTIVE since v3.37.0** — same status as sequential Phase 3.7 Step C above: `light` is per-card early feedback, and the merge-gate safety is the post-batch **Final-review FULL gate** (a single FULL `/codexreview` over the entire batch diff, which team mode reaches via "Post-batch — same as sequential mode"). To make per-card always-full again, restore `profile = full`; the final full gate stays regardless.
|
|
2235
2245
|
|
|
@@ -184,6 +184,45 @@ the state file (now on `develop` via the merge) shows `completed`.
|
|
|
184
184
|
|
|
185
185
|
Mark task 5 as `completed`.
|
|
186
186
|
|
|
187
|
+
### Step 7.5 — Workspace hygiene & finalization (BLOCKING — the run MUST conclude clean)
|
|
188
|
+
|
|
189
|
+
**Why this exists (v3.39.0).** A PRD run used to end by handing the user a list of
|
|
190
|
+
"azioni tue, non bloccanti" — an uncommitted file blocking the local `develop`
|
|
191
|
+
fast-forward, a remote branch left undeleted. That is a half-finished process.
|
|
192
|
+
`/prd` now closes the loop exactly like `/new` Phase 6c: **no residue is ever
|
|
193
|
+
surfaced as a passive manual TODO.** Every leftover is either auto-resolved or put
|
|
194
|
+
behind ONE explicit `AskUserQuestion` gate.
|
|
195
|
+
|
|
196
|
+
Scan the captured `mw-docs` stdout (the merge step above) for the structured
|
|
197
|
+
markers it can emit, then act:
|
|
198
|
+
|
|
199
|
+
1. **`[SYNC-NEEDS-DECISION] …`** — the local `develop` could not fast-forward and
|
|
200
|
+
the blocker is a **foreign** uncommitted file (one this run does not own), or a
|
|
201
|
+
genuine divergence/rebase conflict. Do NOT auto-commit foreign work. Raise ONE
|
|
202
|
+
`AskUserQuestion`:
|
|
203
|
+
- Question: `"Il develop locale non si è sincronizzato: <dettaglio dal marker>. Come chiudo?"`
|
|
204
|
+
- Options: `[Committa tu adesso (descrivi cosa)]` / `[Lo gestisco io — chiudi senza sync locale]` / `[Mostrami il diff e decidiamo]`.
|
|
205
|
+
Act on the answer in this turn. Never leave it as a printed note.
|
|
206
|
+
|
|
207
|
+
2. **`[SYNC-DEFERRED] …`** (main repo HEAD ≠ `develop`) — fetch already updated
|
|
208
|
+
`refs/remotes/origin/develop`. If the user's HEAD is now `develop`, run
|
|
209
|
+
`git -C "$MAIN" pull --ff-only origin develop`. Otherwise raise ONE
|
|
210
|
+
`AskUserQuestion` (`[ff-pull adesso]` / `[Lascio deferred, riconcilio io]`).
|
|
211
|
+
|
|
212
|
+
3. **No marker** — `mw-docs` already fast-forwarded (or auto-reconciled the
|
|
213
|
+
framework telemetry log). Nothing to do; the tree is clean.
|
|
214
|
+
|
|
215
|
+
4. **Remote feature branch** — `mw-docs` deletes the merged remote branch as
|
|
216
|
+
routine cleanup (see AGENTS.md § branch deletion: deleting an **already-merged**
|
|
217
|
+
feature branch is NOT the gated "branch deletion" that needs owner approval).
|
|
218
|
+
If for any reason the deletion was blocked, do NOT print "puoi cancellarlo a
|
|
219
|
+
mano": run `git push origin --delete <branch>` now, and only if THAT is denied
|
|
220
|
+
raise ONE `AskUserQuestion`.
|
|
221
|
+
|
|
222
|
+
**Gate:** `git -C "$MAIN" status --porcelain` for framework-owned paths is empty,
|
|
223
|
+
no `[SYNC-NEEDS-DECISION]` marker is left unhandled, and the merged remote branch
|
|
224
|
+
is gone (or its deletion is explicitly user-deferred).
|
|
225
|
+
|
|
187
226
|
### Final output
|
|
188
227
|
|
|
189
228
|
Print final summary:
|
|
@@ -193,6 +232,13 @@ Print final summary:
|
|
|
193
232
|
- Card IDs created
|
|
194
233
|
- Branch & merge strategy used
|
|
195
234
|
- PR number (if `strategy = pr`) or merge SHA (if `local-push`)
|
|
196
|
-
- Confirmation that the worktree was cleaned up
|
|
235
|
+
- Confirmation that the worktree was cleaned up AND the remote branch was deleted
|
|
236
|
+
|
|
237
|
+
**HARD RULE — no passive deferral.** The final summary MUST NOT contain a "azioni
|
|
238
|
+
tue / note non bloccanti / puoi farlo a mano" section. If something genuinely needs
|
|
239
|
+
the user, it was already raised as an `AskUserQuestion` in Step 7.5 and acted on —
|
|
240
|
+
it does not reappear here as a TODO. A run that prints "il develop locale non si è
|
|
241
|
+
fast-forwardato, gestisci tu il file e poi pulla" has FAILED Step 7.5 — go back and
|
|
242
|
+
resolve it before printing the summary.
|
|
197
243
|
|
|
198
244
|
Display completed Progress Bar.
|
|
@@ -865,8 +865,44 @@ PR_NUMBER=""
|
|
|
865
865
|
# HEAD alone and they'll pull next time.
|
|
866
866
|
CURRENT_BRANCH=$(git -C "$MAIN" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
867
867
|
if [ "$CURRENT_BRANCH" = "develop" ]; then
|
|
868
|
-
git -C "$MAIN" pull --ff-only origin develop
|
|
869
|
-
echo "
|
|
868
|
+
if git -C "$MAIN" pull --ff-only origin develop 2>/dev/null; then
|
|
869
|
+
echo "✅ Main repo develop fast-forwarded to origin/develop."
|
|
870
|
+
else
|
|
871
|
+
# FF blocked. NEVER leave this as a passive "Leaving as-is" TODO for the user
|
|
872
|
+
# (v3.39.0 — the finalizer MUST conclude). The cause is almost always an
|
|
873
|
+
# uncommitted append to the framework-owned telemetry log left by a prior run.
|
|
874
|
+
# Partition the dirty tree:
|
|
875
|
+
# - framework-owned artifact (docs/metrics/skill-runs.jsonl) → auto-reconcile
|
|
876
|
+
# (commit + rebase) so the ff completes with zero data loss;
|
|
877
|
+
# - ANY foreign file → emit a decision marker the orchestrator MUST convert
|
|
878
|
+
# into ONE explicit user gate. Never auto-commit work this run did not own.
|
|
879
|
+
DIRTY=$(git -C "$MAIN" status --porcelain --untracked-files=no | sed 's/^...//')
|
|
880
|
+
FOREIGN=""
|
|
881
|
+
OWNED=""
|
|
882
|
+
for f in $DIRTY; do
|
|
883
|
+
case "$f" in
|
|
884
|
+
docs/metrics/skill-runs.jsonl) OWNED="$OWNED $f" ;;
|
|
885
|
+
*) FOREIGN="$FOREIGN $f" ;;
|
|
886
|
+
esac
|
|
887
|
+
done
|
|
888
|
+
if [ -n "$FOREIGN" ]; then
|
|
889
|
+
echo "[SYNC-NEEDS-DECISION] main repo develop cannot fast-forward; foreign uncommitted files:${FOREIGN} — orchestrator MUST raise ONE explicit user gate (commit / user-handles), never a passive note."
|
|
890
|
+
elif [ -n "$OWNED" ]; then
|
|
891
|
+
# Only framework-owned telemetry is dirty → reconcile autonomously, lossless.
|
|
892
|
+
git -C "$MAIN" add docs/metrics/skill-runs.jsonl
|
|
893
|
+
git -C "$MAIN" commit -m "chore(metrics): reconcile skill-runs telemetry before develop sync" --quiet
|
|
894
|
+
if git -C "$MAIN" pull --rebase origin develop 2>/dev/null; then
|
|
895
|
+
git -C "$MAIN" push origin develop 2>/dev/null \
|
|
896
|
+
&& echo "✅ Reconciled stale metrics log + synced develop to origin." \
|
|
897
|
+
|| echo "✅ Reconciled stale metrics log (local develop 1 commit ahead; syncs on next push). Tree clean."
|
|
898
|
+
else
|
|
899
|
+
git -C "$MAIN" rebase --abort 2>/dev/null || true
|
|
900
|
+
echo "[SYNC-NEEDS-DECISION] metrics rebase conflict on develop — orchestrator MUST raise ONE explicit user gate."
|
|
901
|
+
fi
|
|
902
|
+
else
|
|
903
|
+
echo "[SYNC-NEEDS-DECISION] main repo develop cannot fast-forward and the working tree is clean (diverged?) — orchestrator MUST raise ONE explicit user gate."
|
|
904
|
+
fi
|
|
905
|
+
fi
|
|
870
906
|
else
|
|
871
907
|
echo "ℹ️ Main repo HEAD is '$CURRENT_BRANCH' — not switching. Next manual `git pull` on develop will sync."
|
|
872
908
|
git -C "$MAIN" fetch origin develop --quiet
|
|
@@ -905,8 +941,17 @@ git branch -d "$BRANCH"
|
|
|
905
941
|
```
|
|
906
942
|
|
|
907
943
|
```bash
|
|
908
|
-
# 3. Delete the remote branch
|
|
909
|
-
|
|
944
|
+
# 3. Delete the remote branch. The branch is ALREADY MERGED into develop at this
|
|
945
|
+
# point, so this is routine cleanup — NOT the gated "branch deletion" that needs
|
|
946
|
+
# owner approval (see AGENTS.md § branch deletion). Report the outcome; never
|
|
947
|
+
# degrade a failure into a passive "puoi cancellarlo a mano" note handed to the user.
|
|
948
|
+
if git push origin --delete "$BRANCH" 2>/dev/null; then
|
|
949
|
+
echo "✅ Remote branch '$BRANCH' deleted (merged → routine cleanup)."
|
|
950
|
+
else
|
|
951
|
+
echo "ℹ️ Remote branch '$BRANCH' not deleted (already gone, or the deletion was denied)."
|
|
952
|
+
echo " If denied: this is a merged branch — retry the delete; only if it is STILL"
|
|
953
|
+
echo " denied must the orchestrator raise ONE explicit user gate, never a passive TODO."
|
|
954
|
+
fi
|
|
910
955
|
```
|
|
911
956
|
|
|
912
957
|
```bash
|
|
@@ -923,12 +968,15 @@ Remove the entry from `.worktrees/registry.json`.
|
|
|
923
968
|
```
|
|
924
969
|
Merge complete:
|
|
925
970
|
Card: <CARD-ID>
|
|
926
|
-
Branch: <BRANCH> (deleted on remote
|
|
971
|
+
Branch: <BRANCH> (deleted on remote — merged branch deletion is routine cleanup, never gated)
|
|
927
972
|
Strategy: <pr | local-push>
|
|
928
973
|
PR: #<PR_NUMBER> merged via `gh pr merge` ← only in `pr` strategy
|
|
929
974
|
Push: fast-forward to origin/develop ← only in `local-push` strategy
|
|
930
975
|
Worktree: <WORKTREE_PATH> (removed)
|
|
931
|
-
develop: remote up to date; local main-repo synced
|
|
976
|
+
develop: remote up to date; local main-repo synced (auto-reconciled framework
|
|
977
|
+
telemetry if it blocked the ff). Any [SYNC-NEEDS-DECISION] /
|
|
978
|
+
[SYNC-DEFERRED] marker above is for the orchestrator to gate on —
|
|
979
|
+
NOT a residue to hand the user as a manual TODO.
|
|
932
980
|
```
|
|
933
981
|
|
|
934
982
|
---
|
package/framework/AGENTS.md
CHANGED
|
@@ -104,9 +104,9 @@ Conflict steps (must follow in order):
|
|
|
104
104
|
- MUST use commit format `[FEAT-XXX] Brief description` or adapt to your project's convention; keep commits small/traceable.
|
|
105
105
|
- MUST NOT commit without updated docs or with failing lint/type checks. Full build is required only before opening a PR, not before every commit.
|
|
106
106
|
- MUST pre-sync: `git fetch origin`, clean status, confirm branch; use `git pull --ff-only` unless approved.
|
|
107
|
-
- MUST get owner approval before force push/reset
|
|
107
|
+
- MUST get owner approval before force push/reset, and before deleting an **unmerged** branch; create a safety tag `backup/<YYYYMMDD>-<reason>`. Deleting a feature branch that is **already merged** into `develop` is routine cleanup (it carries no unmerged work) and does NOT require a separate approval — the merge skill deletes it automatically.
|
|
108
108
|
- MUST NEVER push directly to `main`; all changes reach `main` via PR (release from `develop` or hotfix merge). Pre-push hook enforces this.
|
|
109
|
-
- MUST push working branch and keep `main` merge owner-controlled;
|
|
109
|
+
- MUST push working branch and keep `main` merge owner-controlled; the merge skill prunes a feature branch's own remote ref on successful merge into `develop` (routine), but pruning OTHER remote branches happens only when instructed.
|
|
110
110
|
- MUST run testing gates before DONE: run tests (if exist), run build, and CI checks on PR; manual validation is REQUIRED for local mode and OPTIONAL for cloud mode.
|
|
111
111
|
- MUST pass pre-commit hooks (linting, type checking, markdown lint, build); bypass (`--no-verify`) only for documented emergencies.
|
|
112
112
|
- MUST use API versioning for breaking changes: create new version, deprecate old with appropriate headers, minimum sunset period; see project-specific API migration docs.
|
|
@@ -36,8 +36,9 @@ Output is a tabular summary grouped by `phase × domain × decision × applied_b
|
|
|
36
36
|
|
|
37
37
|
| Pattern | What it means |
|
|
38
38
|
|---|---|
|
|
39
|
-
| `3 \| doc \| ... \| applied_by=orchestrator` | Phase 3 doc-review fix applied inline (violates `
|
|
40
|
-
| `3
|
|
39
|
+
| `3 \| doc \| ... \| applied_by=orchestrator` | Phase 3 doc-review fix applied inline (violates the `doc` Domain-Override rule — doc fixes are owned by `doc-reviewer`). |
|
|
40
|
+
| `3 \| doc \| ... \| applied_by=coder` | Phase 3 doc fix routed to `coder` (violates the `doc` Domain-Override rule since v3.40.0 — doc fixes are owned by `doc-reviewer`, which has the doc-invariant contract the coder lacks). |
|
|
41
|
+
| `3.7 \| codex-security \| ... \| applied_by=orchestrator` | Codex HIGH security finding fixed inline (violates `SKILL.md` Phase 3.7 "spawn `coder` agent"). |
|
|
41
42
|
| `* \| * \| ... \| applied_by=orchestrator-fallback` | Sub-agent failed and orchestrator fell back to inline. Expected to be rare; investigate if frequent. |
|
|
42
43
|
|
|
43
44
|
The analyzer script flags these in its footer automatically.
|
|
@@ -55,7 +56,8 @@ The analyzer script flags these in its footer automatically.
|
|
|
55
56
|
| Pattern | What it means |
|
|
56
57
|
|---|---|
|
|
57
58
|
| `2.55 \| simplify-* \| est_lines∈[1-5] \| decision=inline \| applied_by=orchestrator` | Small inline fixes — efficient, low cost. Expected majority of Phase 2.55. |
|
|
58
|
-
| `3 \| doc \| ... \| decision=
|
|
59
|
+
| `3 \| doc \| ... \| decision=doc-reviewer \| applied_by=doc-reviewer` | Doc fixes applied by the doc-reviewer in write mode (since v3.40.0). Expected for every card with doc impact. |
|
|
60
|
+
| `D.4a \| doc \| ... \| decision=doc-reviewer \| applied_by=doc-reviewer` | Team-mode doc fixes applied by the doc-reviewer over the group. Expected for every group with doc impact. |
|
|
59
61
|
| `3.7 \| * \| decision=skipped \| applied_by=- \| severity=FALSE-POSITIVE` | Codex false positives correctly filtered. |
|
|
60
62
|
|
|
61
63
|
## When to act on the data
|