baldart 4.88.1 → 4.88.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to BALDART will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.88.2] - 2026-07-01
9
+
10
+ **`/prd` reliably stamps `holistic_audit` provenance → `/new`/`new2` stop spawning the plan-auditor on every freshly-authored card.** The v4.7.0 skip already existed: `/new` (`implement.md` Phase 1 step 4) skips the per-card plan-auditor grounding when **P1** (the card carries `metadata.holistic_audit`) **∧ P2** (no git drift on its claimed paths since the audit). But P1 was frequently false: the stamp was written by a **soft, model-driven per-card step** (`audit-phase.md` Step 6.9.4) framed as an "optional optimization hint" — the single most-omitted step under context pressure. When omitted, every card ships without the stamp and `/new`/`new2` fall back to spawning the plan-auditor on **every** card even when the batch is implemented immediately after `/prd` (nothing changed since the audit) — the reported waste. Diagnosis was confirmed on a real run: the FIRST card of a batch (HEAD at trunk, zero intra-batch commits ⇒ P2 trivially holds) still ran the plan-auditor, which is only possible if P1 failed. Fix strengthens the **existing** provenance (no new "freshness" signal, per the chosen direction):
11
+
12
+ - **`audit-phase.md` Step 6.9.4 + Fail-safe contract** — reworded from "optional hint" to **mandatory whenever the audit ran**. If git is genuinely unavailable, write `audited_commit: ""` **explicitly** (never omit the block). The stamp remains an OPTIMIZATION hint for `/new`, never a *correctness* gate.
13
+ - **`validation-phase.md` Step 7 item 5b (new) — deterministic backstop.** Right before commit staging (Step 6 complete ⇒ the audit genuinely ran, so the stamp legitimately certifies it), recompute the three run-level values ONCE and backfill `metadata.holistic_audit` on every **non-EPIC** Step-5 card that lacks a non-empty `audited_commit`. Idempotent (a card already stamped at 6.9.4 is untouched), additive (never overwrites other `metadata` keys), EPIC-excluded (`card-schema.md`). The backfilled YAMLs are staged by item 6's existing `FEAT-XXXX-*.yml` glob. Blocks only *silently shipping cards without the stamp*, **never** the PRD.
14
+ - **`implement.md` Phase 1 step 4** — a clarifying note (no logic change): the skip is now the NORMAL path for a card implemented right after `/prd`, and P1's fail-safe (missing provenance / drift / git error → RUN the plan-auditor) is unchanged. In autonomous mode the skip already auto-applies (it is not gated on interactivity), matching the requested behavior.
15
+
16
+ **Correctness guard:** the stamp also lets `/new` Step 3d skip the Codex cross-card check, so it must vouch only for an audit that actually ran — the backstop lives *after* the Step 6 gate, so it never over-claims. A `/prd` run that skips the audit writes no stamp → `/new` correctly runs the plan-auditor. **PATCH** — robustness fix to an existing mechanism, no new capability surface, no new `baldart.config.yml` key (→ schema-change propagation rule N/A). **Codex parity: portable** — the stamp is YAML + git, and `audit-phase.md` / `validation-phase.md` are runtime-neutral prose consumed by both the Claude and Codex `/prd` paths; the shared Step 7 commit/merge covers both. Per-skill: `prd` → 1.1.1, `new` → 1.1.1.
17
+
18
+ ### Changed
19
+
20
+ - **`framework/.claude/skills/prd/references/audit-phase.md`** — Step 6.9.4 + Fail-safe contract: stamp write is mandatory-when-the-audit-ran, not optional.
21
+ - **`framework/.claude/skills/prd/references/validation-phase.md`** — new Step 7 item 5b: deterministic `holistic_audit` provenance backstop before commit staging.
22
+ - **`framework/.claude/skills/new/references/implement.md`** — Phase 1 step 4: clarifying note that the provenance skip is the normal fresh-batch path (no logic change).
23
+
8
24
  ## [4.88.1] - 2026-07-01
9
25
 
10
26
  **`baldart update` backfills hooks on the aligned/self-heal path too.** The "already up to date" branch of `update` reconciled newly-shipped payload (agents / skills / workflows / output-styles + root primitives) but did **not** backfill hooks. Same gap class the payload reconcile already fixed: a consumer who framework-updated with an **older CLI** (before a given hook shipped — e.g. the v4.88.0 Codex hooks) and then aligned the CLI would hit the "already current" early-exit and **never get the hooks registered** (recoverable only via `doctor`). Now the aligned path registers both Claude (`.claude/settings.json`) and — when `tools.enabled ∋ codex` — Codex (`.codex/hooks.json`) hooks, **idempotently and additively**: SILENT when nothing is missing, drift left to `doctor` (never prompts on the self-heal path), non-fatal on any hiccup. The `--json` payload gains `backfilled_hooks`. **PATCH** — robustness fix, no behavior change on a healthy install. Codex parity: adapter-generated (the same registrar). No new config key.
package/README.md CHANGED
@@ -83,7 +83,7 @@ No additional activation steps needed — once installed, Claude Code (and Codex
83
83
  ### Core Protocol
84
84
 
85
85
  - **AGENTS.md**: Mandatory coordination rules (MUST/SHOULD/OPTIONAL)
86
- - **agents/**: 26 domain modules (architecture, workflows, testing, security, card-schema, i18n-protocol, return-contract-protocol, component-manifest-schema, etc.)
86
+ - **agents/**: 28 domain modules (architecture, workflows, testing, security, card-schema, i18n-protocol, return-contract-protocol, runtime-portability-protocol, component-manifest-schema, etc.)
87
87
  - **Routing**: If you touch X, read Y - minimize context loading
88
88
 
89
89
  ### AI Agents (32 specialized agents)
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.88.1
1
+ 4.88.2
@@ -2,6 +2,14 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.1.1 — 2026-07-01
6
+
7
+ - **Plan-auditor grounding skip is now the NORMAL path for a card implemented right after `/prd`** (doc clarification, no logic change). `implement.md` Phase 1 step 4's provenance skip (v4.7.0, P1 = card carries `metadata.holistic_audit`) used to fire only when `/prd` happened to stamp the card; the stamp was frequently omitted, so `/new`/`new2` spawned the plan-auditor on every freshly-authored card. Paired with the `/prd` v1.1.1 fix (deterministic provenance backstop at `validation-phase.md` Step 7 item 5b), P1 now holds whenever the batch is freshly authored — step 4 documents this coupling. The skip's BOTH-conditions logic + fail-safe (missing provenance / drift / git error → RUN the plan-auditor) are unchanged. Framework v4.88.2.
8
+
9
+ ## 1.1.0 — 2026-07-01
10
+
11
+ - Codex-parity (S4): the orchestrator is now runtime-portable. Added a top-level **RUNTIME PORTABILITY** citation of `framework/agents/runtime-portability-protocol.md` (bind agent-spawn / decision-gate / state / workflow-accel / adversarial-review to Claude *or* Codex; detect once, never probe Claude-only primitives on Codex). YOLO MODE reworded runtime-aware (`bypassPermissions` is Claude-only; Codex omits it). Added **runtime guards** on the Codex review gates (`codex-gate.md`, `final-review.md`): "cross-model" holds only on a Claude host; a Codex-hosted pass is fresh-context adversarial, not cross-model. `review-cycle.md` notes Workflow is Claude-only (Codex → inline, no probe). Replaced the Codex-incompatible `model:haiku general-purpose` targeted-revert spawn (`implement.md`) with the deterministic `scripts/revert-files.sh` (portable git plumbing). All Codex additions are additive — the Claude path is unchanged.
12
+
5
13
  ## 1.0.0 — 2026-07-01
6
14
 
7
15
  - Baseline: versioning per-skill introdotto al framework v4.82.0.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: new
3
3
  effort: medium
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  description: >
6
6
  Orchestrate a team of specialized agents to implement one or more backlog cards
7
7
  end-to-end inside a dedicated worktree, with code review, doc review, QA, and
@@ -10,7 +10,9 @@ description: >
10
10
  "esegui le card", "lancia le card".
11
11
  ---
12
12
 
13
- > **YOLO MODE**: All agents spawned via the Task tool MUST use `mode: "bypassPermissions"`. No exceptions.
13
+ > **YOLO MODE**: Agents run without permission friction. On Claude Code, spawn every agent via the Task tool with `mode: "bypassPermissions"` (no exceptions). On Codex there is no `mode` parameter — spawn the custom agent by name and rely on the session sandbox/approval policy; never emit Claude permission fields. (Binding: `framework/agents/runtime-portability-protocol.md`.)
14
+
15
+ > **RUNTIME PORTABILITY**: This orchestrator's mechanics (agent spawn, decision gates, state/tracker tracking, workflow acceleration, adversarial review) bind to Claude Code *or* Codex per `framework/agents/runtime-portability-protocol.md`. Detect the runtime once at kickoff; on **Codex** spawn named agents from `.codex/agents/<name>.toml`, use file-backed tracker state + plain user prompts, and never spend a token probing for `Workflow` / `AskUserQuestion` / the task spine (they don't exist there). Shared policy — delegation (code→`coder`, UI→`ui-expert`), no-silent-fallback, worktree isolation — stays in `AGENTS.md` § Non-negotiables, cited not restated. Every Codex path here is ADDITIVE: a Claude reader's imperatives are unchanged.
14
16
 
15
17
  > **SCOPE CLOSURE DISCIPLINE (BLOCKING)**: This orchestrator NEVER unilaterally defers an acceptance criterion. Silent deferral via `implementation_notes`, commit message, or final recap is a protocol violation per `framework/agents/workflows.md § Scope Closure Discipline`. Under context-window pressure, time pressure, or unforeseen complexity, the correct action is to STOP and route the decision back to the user via `AskUserQuestion` — Auto Mode's "bias toward proceeding" applies to routine decisions, NOT to scope reduction. **Phase 2.5b (AC-Closure Gate)** enforces this at the per-card level before commit and is non-skippable. **When AUTONOMOUS, apply § "AUTONOMOUS RESOLUTION RULE" (category=blocker / AC-Closure → materialize a follow-up card, never approve the deferral).**
16
18
 
@@ -4,6 +4,8 @@
4
4
 
5
5
  ### Phase 3.7 — Pre-Merge Codex Review Gate (MANDATORY — UNCONDITIONAL)
6
6
 
7
+ > **Runtime guard (cross-model vs adversarial)**: the "cross-model" framing in this gate assumes a **Claude-hosted** run, where the Codex companion is a genuinely different model. On a **Codex-hosted** run (`/new` running under Codex) a `/codexreview` pass is the SAME model family — it remains a valid **fresh-context adversarial** review, but it is NOT cross-model, so do not claim model diversity; prefer spawning `code-reviewer` / `plan-auditor` (by name from `.codex/agents/`) as the adversary. The gate still runs unconditionally either way. Rule: `framework/agents/runtime-portability-protocol.md` § "Adversarial vs cross-model". The Claude path below is unchanged.
8
+
7
9
  > **Workflow-delegation carve-out (v4.34.0)**: if the review cluster was delegated to the
8
10
  > `new-card-review` workflow (see `references/review-cycle.md` § "Phase 2.5x — Review-cluster workflow
9
11
  > delegation gate"), this Phase 3.7 is **already covered** — the workflow ran the cross-model Codex pass
@@ -7,6 +7,8 @@
7
7
  > **Primary code reviewer: Codex (a non-Anthropic frontier model, via `codex-companion.mjs`)** — cross-model validation with built-in FP filtering.
8
8
  > Claude `code-reviewer` is the automatic fallback if Codex is unavailable.
9
9
  > The `/codexreview` command remains available for standalone reviews on demand.
10
+ >
11
+ > **Runtime guard**: "cross-model" here assumes a **Claude-hosted** run (Codex = a different model). On a **Codex-hosted** `/new` run this batch pass is the SAME model family — still a valid **fresh-context adversarial** sweep, but NOT cross-model: use `code-reviewer` (by name from `.codex/agents/`) as the adversary and do not claim model diversity. Rule: `framework/agents/runtime-portability-protocol.md` § "Adversarial vs cross-model". The Claude path is unchanged.
10
12
 
11
13
  Once ALL cards are committed in the worktree:
12
14
 
@@ -12,7 +12,7 @@
12
12
  2c. **Trivial-card classification (BLOCKING gate for steps 3–4)** — evaluate `IS_TRIVIAL(card)` per § "Trivial-card fast-lane". Note: condition 3 (non-source diff) cannot be fully evaluated until the coder has produced the diff, so at this point compute the **provisional** trivial flag from conditions 1+2 only (`review_profile == skip` AND no Step-A trigger sourced from the card YAML text + `files_likely_touched` extensions — if EVERY path in `files_likely_touched` is non-source, condition 3 is provisionally satisfied). If provisionally trivial → **SKIP steps 3, 3a, and 4** (architecture grounding); log `trivial: architecture grounding skipped (review_profile=skip + non-source files_likely_touched + 0 triggers)` and jump to Phase 2. Re-confirm `IS_TRIVIAL` on the ACTUAL committed diff at the review gates (Phase 2.55/3.5/3.7); if the coder unexpectedly touched a source file, the guard flips the card back onto the normal review path there. If NOT provisionally trivial → run steps 3, 3a, 4 as normal.
13
13
  3. **(skip when provisionally trivial — see 2c)** Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation. When `features.has_lsp_layer: true`, the architect uses LSP find-references for identifier-shaped lookups — this needs NO handoff from the orchestrator: the architect reads `features.has_lsp_layer` from `baldart.config.yml` directly (the flag is ambient) per `agents/code-search-protocol.md`. Likewise, when `features.has_code_graph: true`, the architect uses the Graphify code graph for structural/relational lookups (ambient flag) per `agents/code-graph-protocol.md`. The orchestrator does NOT propagate either flag. (Earlier doc versions numbered this step 4; the step that read project-status BEFORE the architect was removed because it persisted pre-analysis context — see step 3a.) **Pass `OUTPUT=terse` in the architect prompt (since v4.49.0)** — this is grounding for the coder/reviewer, not an explanation, so the architect returns its structured contract (reuse table + canonical evidence + `path:line — symbol` rows + `totals:`) without narrative prose. The verbatim baseline persisted at step 5b keeps all the substance a lean `/codexreview` needs (paths, signatures, patterns, high-risk paths) while staying small in the orchestrator's context and on disk. **Baseline content contract (MANDATORY — since v4.56.0):** the architect prompt is grounding INPUT only — pass the card scope, `files_likely_touched`, and the question to map. NEVER put line-level fix directives ("remove lines 90-91", "Fix: use X"), the words "implement/fix/apply", or acceptance-criteria framed as a task into the architect prompt. The architect produces a read-only MAP (file/symbol locations, patterns, type signatures, integration points, high-risk paths); it does NOT implement and has no `Task`/Agent tool to delegate (see `codebase-architect.md` § Role boundary). The coder is a separate spawn the orchestrator owns.
14
14
  3a. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project) — do this AFTER the codebase-architect run (step 3) so the "Active Code Context" reflects the architect's findings (which files are actually in scope), not just the card YAML's `files_likely_touched`. Writing it before the architect run would persist pre-analysis claims that downstream agents (e.g. a parallel card) would then read as truth.
15
- 4. **Plan-auditor grounding check** — but first, a **provenance skip (since v4.7.0 — mirror of Step 3d)**: the `/prd` Step 6.6 holistic audit already ran a per-card grounding pass when the card was authored. Re-grounding here is only worth a plan-auditor spawn if something changed since. Skip the plan-auditor when **BOTH** hold:
15
+ 4. **Plan-auditor grounding check** — but first, a **provenance skip (since v4.7.0 — mirror of Step 3d)**: the `/prd` Step 6.6 holistic audit already ran a per-card grounding pass when the card was authored. Re-grounding here is only worth a plan-auditor spawn if something changed since. **This skip is the NORMAL path for a card implemented right after `/prd`, not an occasional optimization** — `/prd` now guarantees the `metadata.holistic_audit` stamp lands on every audited card (deterministic backstop at `validation-phase.md` Step 7 item 5b, since the v4.88.2 provenance-reliability fix), so P1 below holds whenever the batch is freshly authored. Skip the plan-auditor when **BOTH** hold:
16
16
  - **P1 — provenance present**: the card has `metadata.holistic_audit` with non-empty `audited_at`, `audited_commit`, `audited_set`.
17
17
  - **P2 — no drift on this card's claimed paths** since the audit baseline. With `$AC` = `metadata.holistic_audit.audited_commit`, `$MAIN`/`$TRUNK` from the tracker, and this card's `files_likely_touched`/claimed paths (`$CARD_PATHS`):
18
18
  ```bash
@@ -491,4 +491,14 @@
491
491
  (`$TRUNK` is the trunk branch resolved in Phase 0; if the worktree branched from a different base, the `HEAD~1..HEAD` fallback covers the last commit.)
492
492
  Compare against this card's allowed files in `## File Ownership Map`.
493
493
  - **All within allowed set** → proceed to Phase 2.5.
494
- - **Any file outside allowed set** → log the violation in `## Issues & Flags` (`"unauthorized file: <path>"`), then spawn a **targeted revert agent** (`subagent_type: general-purpose`, **`model: "haiku"`** — a file-scoped revert is mechanical git plumbing, not code authoring, so it does NOT need `coder`/opus; this is the sanctioned plumbing carve-out to REGISTRY.md's "never haiku" rule) with an **explicit ROLE BOUNDARY**: "Mechanical file-scoped revert only — restore ONLY these files to their pre-commit state, do NOT write, fix, or refactor any code. Do not touch any other file: [list unauthorized files]". Re-run build + lint to confirm clean state after revert. Update tracker with revert outcome, then proceed to Phase 2.5.
494
+ - **Any file outside allowed set** → log the violation in `## Issues & Flags` (`"unauthorized file: <path>"`), then run the **deterministic file-scoped revert SCRIPT** (a file-scoped revert is mechanical git plumbing, not code authoring a script cannot fabricate or over-reach, and it runs IDENTICALLY on Claude and Codex with no dependency on a `model` param or a `general-purpose` agent Codex lacks). Resolve + run it (opt-in-with-fallback):
495
+ ```bash
496
+ REVERT_SH="$(ls .framework/framework/.claude/skills/new/scripts/revert-files.sh .claude/skills/new/scripts/revert-files.sh 2>/dev/null | head -1)"
497
+ if [ -n "$REVERT_SH" ]; then
498
+ bash "$REVERT_SH" "<worktree-path>" "$TRUNK" <unauthorized-files...> # restores each to trunk (or removes if card-added); refuses paths outside the worktree; prints a JSON verdict
499
+ else
500
+ # Pre-this-release install without the script → inline equivalent (still deterministic, no agent):
501
+ for f in <unauthorized-files...>; do git cat-file -e "$TRUNK:$f" 2>/dev/null && git checkout "$TRUNK" -- "$f" || git rm -f --quiet "$f"; done
502
+ fi
503
+ ```
504
+ Re-run build + lint to confirm clean state after revert. Update tracker with the revert outcome (from the script's JSON: `reverted`/`removed`/`refused`), then proceed to Phase 2.5.
@@ -31,7 +31,9 @@ so it surfaces in telemetry.
31
31
 
32
32
  - **ELSE IF** the `Workflow` tool is available **AND** `.claude/workflows/new-card-review.js` is present
33
33
  (linked by the framework on Claude-enabled installs) → you **MUST delegate the cluster** to it (this
34
- branch is not optional — see the no-discretion rule above). First build the
34
+ branch is not optional — see the no-discretion rule above). *(Workflow is Claude-only: on a **Codex**
35
+ run this tool never exists — skip straight to the inline ELSE below and do not spend a token probing
36
+ for it. See `framework/agents/runtime-portability-protocol.md`.)* First build the
35
37
  inputs (reusing the existing deterministic logic — do NOT re-implement it):
36
38
  - `qaTier` ← the **Phase 3.5 profile selection** (step 19-21b below: `review_profile` floor →
37
39
  `skip`/`light` ⇒ `qaTier:"light"` (qa-sentinel deferred to Final), `deep` **or any Phase 3.7 Step-A
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # revert-files.sh — deterministic, file-scoped revert of unauthorized changes.
4
+ #
5
+ # Restores ONLY the named files to their TRUNK state (their pre-card content) and
6
+ # refuses any path that escapes the worktree root. This is mechanical git
7
+ # plumbing — it replaces the model-in-the-loop "targeted revert agent"
8
+ # (previously `subagent_type: general-purpose, model: haiku`) so the /new
9
+ # orchestrator runs it IDENTICALLY on Claude and Codex, with no dependency on a
10
+ # `model` parameter or a `general-purpose` agent that Codex does not have.
11
+ #
12
+ # A deterministic script cannot fabricate or over-reach the way a model can:
13
+ # each target is restored to `<trunk>:<path>` (or removed if it was newly added
14
+ # by the card), nothing else is touched, and a path outside the worktree is
15
+ # refused, not reverted.
16
+ #
17
+ # Usage:
18
+ # revert-files.sh <worktree-path> <trunk-ref> <file> [<file> ...]
19
+ #
20
+ # Files may be given as paths relative to the worktree or absolute. The revert
21
+ # is left STAGED (not committed) — the caller re-runs build/lint and commits.
22
+ # Prints a compact JSON verdict to stdout. Exit 0 on success (even if some paths
23
+ # were refused/missing — they are reported), non-zero only on a hard usage error.
24
+
25
+ set -u
26
+
27
+ WT="${1:?usage: revert-files.sh <worktree-path> <trunk-ref> <file>...}"; shift
28
+ TRUNK="${1:?usage: revert-files.sh <worktree-path> <trunk-ref> <file>...}"; shift
29
+ [ "$#" -ge 1 ] || { printf '{"ok":false,"error":"no files given"}\n'; exit 2; }
30
+
31
+ cd "$WT" 2>/dev/null || { printf '{"ok":false,"error":"cannot cd to worktree"}\n'; exit 2; }
32
+ WT_ABS="$(pwd -P)"
33
+
34
+ reverted=(); removed=(); refused=(); errored=()
35
+
36
+ for f in "$@"; do
37
+ # Resolve to an absolute path (parent must exist for a robust resolve).
38
+ if [ -e "$f" ] || [ -e "$(dirname "$f")" ]; then
39
+ abs="$(cd "$(dirname "$f")" 2>/dev/null && printf '%s/%s' "$(pwd -P)" "$(basename "$f")")" || abs=""
40
+ else
41
+ abs=""
42
+ fi
43
+ # Refuse anything that does not resolve strictly under the worktree root.
44
+ case "$abs" in
45
+ "$WT_ABS"/*) : ;;
46
+ *) refused+=("$f"); continue ;;
47
+ esac
48
+ rel="${abs#"$WT_ABS"/}"
49
+ if git cat-file -e "$TRUNK:$rel" 2>/dev/null; then
50
+ # Existed at trunk → restore that version (staged).
51
+ if git checkout "$TRUNK" -- "$rel" 2>/dev/null; then reverted+=("$rel"); else errored+=("$rel"); fi
52
+ else
53
+ # Not present at trunk → the card ADDED it → remove it (staged).
54
+ if git rm -f --quiet "$rel" 2>/dev/null; then removed+=("$rel"); else errored+=("$rel"); fi
55
+ fi
56
+ done
57
+
58
+ json_arr() { local out="" first=1; for x in "$@"; do [ -z "$x" ] && continue; e="${x//\\/\\\\}"; e="${e//\"/\\\"}"; if [ $first -eq 1 ]; then out="\"$e\""; first=0; else out="$out,\"$e\""; fi; done; printf '[%s]' "$out"; }
59
+
60
+ printf '{"ok":true,"worktree":"%s","reverted":%s,"removed":%s,"refused":%s,"errored":%s}\n' \
61
+ "$WT_ABS" "$(json_arr "${reverted[@]:-}")" "$(json_arr "${removed[@]:-}")" \
62
+ "$(json_arr "${refused[@]:-}")" "$(json_arr "${errored[@]:-}")"
63
+ exit 0
@@ -2,6 +2,14 @@
2
2
 
3
3
  Formato: [Keep a Changelog](https://keepachangelog.com/) · [SemVer](https://semver.org/).
4
4
 
5
+ ## 1.1.1 — 2026-07-01
6
+
7
+ - **Holistic-audit provenance made reliable (fixes the "plan-auditor spawns on every freshly-authored card" waste).** The `metadata.holistic_audit` stamp — consumed by `/new` (`implement.md` Phase 1 step 4, P1) + `new2` to SKIP the per-card plan-auditor when a card is implemented right after `/prd` — was written by a **soft, model-driven per-card step** (`audit-phase.md` Step 6.9.4) framed as an "optional optimization hint", so it was the first casualty under context pressure. When omitted, P1 fails and `/new`/`new2` fall back to spawning the plan-auditor on **every** card even though nothing changed since the audit. Two in-place moves, no new concept: (1) `audit-phase.md` Step 6.9.4 + the Fail-safe contract reworded from "optional" to **mandatory-when-the-audit-ran** (git-unavailable → write `audited_commit: ""` explicitly, never omit the block); (2) new **deterministic backstop** at `validation-phase.md` Step 7 item 5b — right before the commit staging (Step 6 complete ⇒ the audit genuinely ran), it recomputes the run-level values ONCE and backfills `metadata.holistic_audit` on every non-EPIC Step-5 card that lacks it (idempotent, additive, EPIC-excluded). The stamp stays an OPTIMIZATION hint, never a correctness gate — the backstop blocks only *silently shipping cards without it*, never the PRD. Runtime-neutral (bash + YAML) → identical on Claude and Codex; the stamp SSOT (snippet + block) stays single-sourced in `audit-phase.md`. Framework v4.88.2.
8
+
9
+ ## 1.1.0 — 2026-07-01
10
+
11
+ - Codex-parity (S5): `/prd` is now runtime-portable, ADDITIVELY (every Claude path is byte-unchanged). Added a HARD-RULES runtime-portability citation of `framework/agents/runtime-portability-protocol.md`. **HARD RULE 4** (task spine): Claude keeps TaskCreate/TaskUpdate; Codex uses a file-backed `<slug>-tasks.jsonl` queue with the state file as the recovery SSOT. **HARD RULE 11** (progress bar): Claude keeps the every-message bar; Codex derives it on demand from the state file at phase gates (context economy). `backlog-phase.md` card-writer spawn is dual-tool (Claude subagent_type+mode / Codex by-name, no mode). Audit fan-out (`audit-phase.md` Step 6.6) gains an additive Codex file-backed audit-queue branch. **Adversarial-vs-cross-model guards** on the discovery completeness cross-check + the Step 6.6d Codex plan audit: "cross-model" holds only on a Claude host; a Codex-hosted pass is fresh-context adversarial, not cross-model. The Claude Design handoff is deliberately untouched (provider-specific, not runtime-specific).
12
+
5
13
  ## 1.0.0 — 2026-07-01
6
14
 
7
15
  - Baseline: versioning per-skill introdotto al framework v4.82.0.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: prd
3
3
  effort: high
4
- version: 1.0.0
4
+ version: 1.1.1
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
 
@@ -59,10 +59,12 @@ message. You ask questions, wait for answers, and iterate.
59
59
 
60
60
  ## HARD RULES
61
61
 
62
+ > **Runtime portability.** This skill's orchestration mechanics (agent spawn, decision gates, state tracking, progress visibility, adversarial review) bind to Claude Code *or* Codex per `framework/agents/runtime-portability-protocol.md`. Detect the runtime once at kickoff; the rules below give the Claude binding first, then an explicit **Codex:** branch where the mechanic differs (task spine, progress bar). On Codex use named-agent spawn + file-backed state + plain prompts, and never probe `Workflow`/`AskUserQuestion`/the task spine. Every Codex branch is ADDITIVE — the Claude imperatives are unchanged. Shared policy (delegation, no-silent-fallback, worktree isolation) stays in `AGENTS.md` § Non-negotiables.
63
+
62
64
  1. Follow steps in order. NEVER skip a step or jump ahead.
63
65
  2. Every step MUST update the state file before proceeding.
64
66
  3. Every gate MUST be satisfied before moving to the next step.
65
- 4. Use TaskCreate/TaskUpdate for ALL progress tracking.
67
+ 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.)
66
68
  5. When context is compressed or session resumes: run Step 0 first.
67
69
  6. **ONE question per message during discovery. Never batch questions.**
68
70
  7. No code generation. This skill produces planning artifacts only.
@@ -71,7 +73,7 @@ message. You ask questions, wait for answers, and iterate.
71
73
  **Worktree-mode exception (HARD RULE 17):** when the PRD runs inside a docs worktree (default since v3.22.0), the session-start update is **SKIPPED** — writing `project-status.md` in the worktree wouldn't be visible to other terminals working on the main repo, and writing it on the main repo would pollute `git status` for parallel sessions (exactly what worktree isolation is meant to prevent). The at-commit update still applies and runs inside the worktree as the last write before rebase + merge — see [validation-phase.md](references/validation-phase.md) § Step 7.
72
74
  10. **STOP means STOP.** When you see `STOP`, end your message. Do not make more tool
73
75
  calls. Do not continue to the next step. Wait for the user.
74
- 11. **Every message MUST end with the Progress Bar.** No exceptions.
76
+ 11. **Progress visibility.** Claude Code: every message MUST end with the Progress Bar (no exceptions). **Codex**: the Progress Bar is OPTIONAL — derive it on demand from the state file and show a compact summary at the phase gates (not after every technical/tool message, per `/new`'s context-economy precedent); update the state file after each phase either way. The discovery **user gates** (one question per message) stay conversational on both runtimes.
75
77
  12. **Scope Expansion Detection.** During discovery (Step 2), after every user answer,
76
78
  check if the response introduces NEW structural entities (endpoints, collections,
77
79
  pages, roles, flows) not in the original feature description. If detected, pause
@@ -94,6 +94,8 @@ Gather **only metadata** to build agent prompts — do NOT read full file conten
94
94
 
95
95
  ## Step 6.6 — Create Agent Team & Launch Audits
96
96
 
97
+ > **Runtime portability (ADDITIVE — Claude path below unchanged).** `TeamCreate`/`TaskCreate`/`TaskUpdate` are the Claude task spine. **Codex** has no team/task objects: run the same audit fan-out with a **file-backed queue** — one file per audit task at `$WORKTREE_PATH/${paths.prd_dir}/sessions/<slug>-audit/tasks/<CARD-ID>.<agent>.json` (`status` / `claimed_by` / `input_paths` / `findings_path`), the same atomic `claimed_by` claim-lock, each agent writing to `audit/findings/<agent>-<CARD-ID>.json`, and the orchestrator consolidating **inline** at Step 6.7 (no new script). Agents are spawned **by name** from `.codex/agents/<name>.toml` (not `subagent_type`/`team_name`). Binding: `framework/agents/runtime-portability-protocol.md` § state-spine.
98
+
97
99
  ### 6.6a. Create the team
98
100
 
99
101
  Use `TeamCreate` with name `check-audit` and description based on the cards being reviewed.
@@ -130,6 +132,8 @@ Launch ALL applicable teammates in a single message (parallel tool calls).
130
132
 
131
133
  > **Why Codex**: Cross-model validation — a non-Anthropic frontier model reviews artifacts produced by Claude,
132
134
  > providing genuine diversity of perspective. [DESIGN-CHOICE: adversarial cross-model review catches blind spots that a single model cannot self-detect] Codex reads files directly from the filesystem.
135
+ >
136
+ > **Runtime guard**: the "cross-model" claim holds only when the host is **Claude** (Codex = a different model). On a **Codex-hosted** `/prd` run this is same-model — keep it as a **fresh-context adversarial** plan audit via `plan-auditor` (by name from `.codex/agents/`), but do NOT label it cross-model; true cross-model then needs an explicitly-configured external reviewer. Rule: `runtime-portability-protocol.md` § "Adversarial vs cross-model".
133
137
 
134
138
  Launch **in parallel** with the teammate agents (6.6c). Use `Bash` with `run_in_background: true` so Claude can launch teammate agents concurrently:
135
139
 
@@ -509,7 +513,7 @@ metadata:
509
513
  audited_set: ["FEAT-XXXX-01", "FEAT-XXXX-02", ...] # sorted; the joint cross-card scope
510
514
  ```
511
515
 
512
- > **Fail-safe contract**: this block is an OPTIMIZATION hint, never a gate. If it is absent, partial, or has an empty `audited_commit`, `/new` Step 3d simply RUNS as before there is no correctness risk, only a redundant Codex pass. Do NOT block the PRD if the stamp can't be written.
516
+ > **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.
513
517
 
514
518
  ### Per-card workflow
515
519
 
@@ -517,7 +521,7 @@ For each card:
517
521
  1. Read persisted report → collect all findings for this card ID.
518
522
  2. Read current card YAML.
519
523
  3. Apply HIGH findings first, then MEDIUM, then write audit trail.
520
- 4. Write the `metadata.holistic_audit` provenance block (see "Holistic-audit provenance stamp" above) using the run-level values captured once.
524
+ 4. Write the `metadata.holistic_audit` provenance block (see "Holistic-audit provenance stamp" above) using the run-level values captured once. **MANDATORY when the audit ran** (see the Fail-safe contract above) — this is what lets `/new`/`new2` skip the per-card plan-auditor when the card is implemented right after `/prd`; `validation-phase.md` Step 7 item 5b deterministically backstops it, but do not rely on the backstop.
521
525
  5. Write updated card YAML.
522
526
  6. Re-read to verify edits landed correctly.
523
527
 
@@ -172,8 +172,12 @@ Before delegating to `prd-card-writer`, check each logical card boundary:
172
172
 
173
173
  ## Card Writing — Delegated to `prd-card-writer` Agent
174
174
 
175
- This phase is delegated to the **`prd-card-writer`** agent (`subagent_type: "prd-card-writer"`)
176
- to free main context and ensure high-precision card generation under `effort: high`.
175
+ This phase is delegated to the **`prd-card-writer`** agent to free main context and
176
+ ensure high-precision card generation under `effort: high`. Spawn it via the runtime's
177
+ agent-invocation mechanism — **Claude**: Task with `subagent_type: "prd-card-writer"`;
178
+ **Codex**: the custom agent **by name** from `.codex/agents/prd-card-writer.toml` (same
179
+ prompt below, but **omit the `mode` line** — Codex has no permission parameter). Binding:
180
+ `framework/agents/runtime-portability-protocol.md`.
177
181
 
178
182
  **DO NOT use `EnterPlanMode`/`ExitPlanMode`.** This skill manages its own multi-turn
179
183
  approval flow. Plan mode risks context loss if the user accidentally accepts
@@ -993,6 +993,8 @@ appendix or extended context, not for the signal table):
993
993
 
994
994
  **Before exiting, run the Discovery Completeness Cross-Check (Codex — since v4.19.0):**
995
995
 
996
+ > **Runtime guard**: this sweep's value is **cross-model** diversity — a *different* model catching the interviewer's blind spots. That holds on a **Claude-hosted** run (the sweep is Codex). On a **Codex-hosted** run, a Codex sweep is the SAME model that conducted the interview, so it carries the very blind spot this check targets — treat it as **fresh-context adversarial only** (spawn a fresh `plan-auditor`/`codebase-architect` by name), do NOT claim cross-model diversity, and prefer a genuinely different external reviewer if one is configured. Rule: `framework/agents/runtime-portability-protocol.md` § "Adversarial vs cross-model".
997
+
996
998
  This is the **final, single cross-model sweep** of discovery, run ONLY once all the
997
999
  gates above pass (99% comprehension OR user-proceed, mockup gaps resolved, research
998
1000
  resolved) and BEFORE flipping the status to `ui-design`. Its purpose is the one thing
@@ -132,6 +132,38 @@ created by Step 1 (HARD RULE 17). `$WORKTREE_PATH` is set in the state file.
132
132
  (`paths.metrics` default: `docs/metrics`), which must be part of the same commit.
133
133
  Non-blocking: if it fails, log "Metrics Log: SKIPPED" in the progress bar and continue.
134
134
 
135
+ 5b. **Holistic-audit provenance backstop (BLOCKING on the STAMP, never on the PRD).**
136
+ The per-card stamp write in `audit-phase.md` Step 6.9.4 is model-driven and is the
137
+ single most-omitted step under context pressure. When it is skipped, every card
138
+ ships WITHOUT `metadata.holistic_audit` — and `/new` (`implement.md` Phase 1 step 4,
139
+ P1) + `new2` then spawn the plan-auditor on **every** card even when the batch is
140
+ implemented immediately after this audit (nothing changed). Step 6 is complete (its
141
+ gate passed), so the audit genuinely ran: this is the authoritative, deterministic
142
+ point to guarantee the stamp lands. **Do NOT re-derive the semantics** — reuse the
143
+ run-level values and the YAML block DEFINED in `audit-phase.md` § "Holistic-audit
144
+ provenance stamp".
145
+ - Recompute the three run-level values ONCE (same snippet as audit-phase.md), inside
146
+ `$WORKTREE_PATH`:
147
+ ```bash
148
+ HOLISTIC_AUDITED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
149
+ 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 "")"
150
+ # audited_set = the sorted Step-5 child card IDs (the joint cross-card scope).
151
+ ```
152
+ - For EACH **non-EPIC** card from Step 5: if it lacks `metadata.holistic_audit` with a
153
+ non-empty `audited_commit`, WRITE the block (additive — never overwrite other
154
+ `metadata` keys). A card that already carries it (from Step 6.9.4) is untouched —
155
+ **idempotent**. EPIC-parent cards are excluded (they carry `planning_session` only —
156
+ `card-schema.md`).
157
+ - Re-read one backfilled card to verify the block landed. Log
158
+ `holistic_audit provenance: N/N cards stamped (M backfilled here)`.
159
+ **Fail-safe (unchanged contract):** the stamp is an OPTIMIZATION hint, never a
160
+ *correctness* gate — if `HOLISTIC_AUDITED_COMMIT` resolves to `""` (git genuinely
161
+ unavailable), write it explicitly as `""` so `/new` treats it as drift and RUNS the
162
+ plan-auditor. **NEVER block or abort the PRD over the stamp**; the only thing this gate
163
+ blocks is shipping cards with the stamp SILENTLY absent. Runtime-neutral (bash + YAML
164
+ edits) → identical on Claude and Codex. The backfilled YAMLs are staged by item 6's
165
+ existing `FEAT-XXXX-*.yml` glob.
166
+
135
167
  6. Stage ONLY PRD session artefacts by explicit file name (NEVER `git add .`
136
168
  or `git add -A`):
137
169
  - `$WORKTREE_PATH/${paths.prd_dir}/sessions/YYYY-MM-DD-<slug>-state.md`
@@ -41,6 +41,7 @@ Route agents to the right module with minimal reading.
41
41
  - If touching monitoring/logging -> read `agents/observability.md`.
42
42
  - If tuning reasoning depth — setting a skill's `effort:` baseline or honoring an inline `effort=<level>` override -> read `agents/effort-protocol.md`.
43
43
  - If authoring/auditing a subagent whose return would flood the orchestrator context (free-form analysis/audit/research) -> read `agents/return-contract-protocol.md` and bound its final message: COMPACT headline + `path:line` findings + disk pointer, persist the long form. The input-side twin of the effort protocol.
44
+ - If a skill performs runtime-mechanical operations (spawn an agent, gate on the user, track state, accelerate a fan-out, run an adversarial review) and must work on BOTH Claude Code and Codex -> read `agents/runtime-portability-protocol.md`: bind each abstract operation to the runtime (Claude `Task`/`Workflow`/`AskUserQuestion`/task-spine ↔ Codex named-agent spawn / inline / plain prompt / file-backed queue), detect the runtime once at kickoff, never probe Claude-only primitives on Codex. Shared policy (delegation, no-silent-fallback, worktree isolation) stays in `AGENTS.md` — cited, not restated.
44
45
  - If building or maintaining a derived LLM wiki overlay (`${paths.wiki_dir}/`) -> read `agents/llm-wiki-methodology.md` and invoke `wiki-curator` / `/capture`.
45
46
  - For day-to-day status -> read and update `${paths.references_dir}/project-status.md`.
46
47
  - For legacy context -> read `archive/project_full_legacy.md` if it exists.
@@ -78,6 +79,7 @@ When adding or updating agents, update REGISTRY.md — not this file.
78
79
  - `agents/card-schema.md` — Atomic Card Baseline Schema: the universal, profile-aware (epic/child/standalone) field contract every backlog card satisfies, plus the consumer HALT/BACK-FILL/WARN contract (since v4.35.0)
79
80
  - `agents/component-manifest-schema.md` — Component Manifest Schema: the machine-readable frontmatter HEAD on each `components/<Name>.md` (deterministic-from-TS + agentic fields), on-demand read contract, regeneration + transition-leniency rules (since v4.65.0, gated on `features.has_design_system`)
80
81
  - `agents/return-contract-protocol.md` — Subagent return-message economy: COMPACT (bounded headline + `path:line` findings + disk pointer) vs FULL, persist-then-summarize — the input-side twin of `effort-protocol.md` (since v4.59.0)
82
+ - `agents/runtime-portability-protocol.md` — Runtime-mechanics binding: the abstract-operation ↔ Claude/Codex map (spawn / permissions / workflow-accel / state-spine / decision-gate / read-write path / adversarial-vs-cross-model), detect-once capability contract; cited by `/new` + `/prd`. The runtime-mechanics twin of `effort-protocol.md` + `return-contract-protocol.md` (since the Codex-parity S4 wave)
81
83
 
82
84
  ## Where to Document (Decision Tree)
83
85
 
@@ -0,0 +1,123 @@
1
+ # Runtime Portability Protocol
2
+
3
+ ## Purpose
4
+
5
+ Define ONE abstract vocabulary for the runtime-*mechanical* operations a skill
6
+ performs — spawn an agent, gate on the user, track state, accelerate a fan-out,
7
+ verify with an adversary — so `/new`, `/prd`, and any orchestration skill express
8
+ their flow **once** and bind it to Claude Code **or** Codex at run time. Without
9
+ this, skill bodies hard-code Claude tool names (`Task`, `Workflow`,
10
+ `AskUserQuestion`, `TaskCreate`, `Edit`) that then read as *broken* on Codex — the
11
+ model either improvises or stalls. This module maps each operation to both
12
+ runtimes so the skill text stays runtime-agnostic and correct on both.
13
+
14
+ This is the runtime-mechanics twin of the other two thin authoring protocols:
15
+ `effort-protocol.md` governs how *deeply* an agent reasons, `return-contract-protocol.md`
16
+ governs how *compactly* it reports back, and this governs *which runtime primitive*
17
+ it binds an abstract operation to. All three are cited by skills, never inlined.
18
+
19
+ ## Scope
20
+
21
+ **In**: the abstract-operation ↔ Claude/Codex binding table, the
22
+ capability-detection contract (detect once, commit, never re-probe), and how a
23
+ skill selects a binding at run time.
24
+
25
+ **Out (CITE, do not restate)**: the *policy* behind each operation. Agent-delegation
26
+ ownership (code→`coder`, UI→`ui-expert`), the no-silent-fallback rule, and worktree
27
+ isolation all live in **`framework/templates/primitives/AGENTS.md` § Non-negotiables**
28
+ (the cross-tool SSOT, read by Claude and Codex alike) and their own SSOTs — this
29
+ module maps the *mechanism*, never re-teaches the *rule*. The installer side of
30
+ Codex support (agent transpilation, hooks) is in `docs/CODEX-AGENTS.md` +
31
+ `docs/CODEX-HOOKS.md`.
32
+
33
+ ## Background — one policy, two runtimes
34
+
35
+ BALDART is AI-tool-agnostic: `tools.enabled` in `baldart.config.yml` selects the
36
+ runtimes, shared policy is single-sourced (`AGENTS.md` + base skills + overlays),
37
+ and only the *mechanics* differ. Claude Code has the `Task` tool, dynamic
38
+ workflows, a task spine, `AskUserQuestion`, and PreToolUse hooks. Codex has named
39
+ custom agents (`.codex/agents/<name>.toml`, spawned by name), **no** workflows,
40
+ **no** task spine, plain user prompts, and its own hook surface. A skill that
41
+ names a Claude tool as if it were universal is the bug this fixes.
42
+
43
+ ## What is already law (CITE — never restate here)
44
+
45
+ Three of the operations below are already binding cross-tool in
46
+ `AGENTS.md` § Non-negotiables. This module only records their *binding*; the
47
+ *mandate* stays there:
48
+
49
+ - **Spawn the domain owner.** Understand-before-implement (`codebase-architect`
50
+ first), then delegate — code/logic/tests → `coder`, UI → `ui-expert`. (AGENTS.md)
51
+ - **No silent substitution.** If a named agent is missing / an invocation returns
52
+ empty / times out / is denied → STOP and report; never improvise a generic
53
+ agent. (AGENTS.md)
54
+ - **Worktree isolation.** Every edit/write/delete path resolves under the worktree
55
+ root; branch/worktree creation is the orchestrator's job, never an implementer's.
56
+ (AGENTS.md § Git Workflow)
57
+
58
+ ## The binding table
59
+
60
+ | Abstract operation | Claude binding | Codex binding | Rule owner |
61
+ |---|---|---|---|
62
+ | **Spawn named agent** | `Task` / `Agent` with `subagent_type: "<name>"` | spawn the custom agent **by name** from `.codex/agents/<name>.toml` | AGENTS.md (CITE) |
63
+ | **Agent permissions** | `mode: "bypassPermissions"` where supported | *no equivalent* — Codex relies on the session sandbox / approval policy; **omit the param, never emit Claude permission fields** | this module |
64
+ | **Workflow acceleration** | `Workflow({ name, args })` for a fan-out (e.g. review clusters) | *no equivalent* — **always take the inline/script fallback; never spend a token probing for `Workflow`** | this module |
65
+ | **State / task spine** | `TaskCreate` / `TaskUpdate` / `TaskGet` / `TaskList` | file-backed queue on disk (`<slug>-tasks.jsonl`, `audit/tasks/<id>.<agent>.json`: `status` / `claimed_by` / `findings_path`); the run's state/tracker file stays the recovery SSOT | this module |
66
+ | **Decision gate (ask user)** | `AskUserQuestion` (STOP, wait — the only action that turn) | a plain, single, concise user prompt (or `request_user_input` if the runtime exposes it); in autonomous mode, the skill's AUTONOMOUS RESOLUTION RULE | this module (gate *policy* — e.g. no-silent-AC-deferral — stays in the skill) |
67
+ | **Read / write path** | `Read` / `Write` / `Edit` (absolute paths) | shell / `apply_patch` / filesystem tools | invariant is **worktree-rooted absolute path**, NOT a tool name — `cd` is not sufficient (an absolute path can still escape). Isolation rule: AGENTS.md (CITE) |
68
+ | **Adversarial vs cross-model review** | an external Codex companion from Claude = genuinely **cross-model** | a same-runtime Codex pass (when the host IS Codex) = **adversarial fresh-context only, NOT cross-model** | this module |
69
+
70
+ ## Capability detection contract
71
+
72
+ - **Detect once, at kickoff; commit; never re-probe per operation.** The runtime
73
+ is known for the whole run — record it in the run's state/tracker file.
74
+ - **On Codex, never attempt** `Workflow`, `AskUserQuestion`, or the task spine —
75
+ they do not exist; probing them wastes tokens and reads as confusion. Go
76
+ straight to the inline/script/prompt/file-backed binding.
77
+ - **On Claude, behavior is unchanged** — every existing Claude path is the
78
+ authoritative binding; this module adds the Codex column, it never rewrites the
79
+ Claude one.
80
+ - **Fallbacks are explicit, never silent.** If an optional accelerator (Workflow
81
+ on Claude) is unavailable, say so and take the inline path — same as the
82
+ existing `Workflow`-available carve-outs already in `/new`.
83
+
84
+ ## Adversarial vs cross-model (the correctness rule)
85
+
86
+ "Cross-model diversity" only holds when the reviewer runs a **different model /
87
+ runtime** than the host that produced the artifact. When the host IS Codex,
88
+ spawning another Codex pass (`/codexreview`) is **same-model** — still useful as a
89
+ *fresh-context adversarial* review, but it is **not** cross-model, and labeling it
90
+ so silently weakens the gate. So:
91
+
92
+ - **Host = Claude → Codex companion = cross-model** (unchanged; the historical path).
93
+ - **Host = Codex → prefer** `plan-auditor` / `code-reviewer` / `codebase-architect`
94
+ as the fresh-context adversary; call it "adversarial", not "cross-model". True
95
+ cross-model requires an explicitly-configured external reviewer.
96
+
97
+ ## Honest limits
98
+
99
+ This is a **prompt-level authoring convention**, best-effort — like its two sibling
100
+ protocols. It works because the skill honors its own contract; it is not a runtime
101
+ shim. Two consequences:
102
+
103
+ 1. **The binding is the mechanism, never the policy.** Neutralizing `AskUserQuestion`
104
+ → "decision gate" must NOT weaken the gate's *rule* (e.g. no-silent-AC-deferral
105
+ stays a hard imperative). Change the verb, never the law.
106
+ 2. **Additive, never a Claude rewrite.** A `tools.enabled: [claude]` reader must
107
+ see the exact same imperatives as before — every Codex branch sits behind an
108
+ explicit "Codex:" guard.
109
+
110
+ ## The canonical citation line
111
+
112
+ A skill that performs runtime-mechanical operations pastes ONE line where it first
113
+ names a runtime primitive (its orchestration/HARD-RULES preamble):
114
+
115
+ ```markdown
116
+ > **Runtime portability.** This skill's orchestration mechanics (agent spawn,
117
+ > decision gates, state tracking, workflow acceleration, adversarial review) bind
118
+ > to Claude *or* Codex per `framework/agents/runtime-portability-protocol.md`.
119
+ > Detect the runtime once at kickoff; on Codex use named-agent spawn +
120
+ > file-backed state + plain prompts and never probe `Workflow`/`AskUserQuestion`/
121
+ > the task spine. Shared policy (delegation, no-silent-fallback, worktree
122
+ > isolation) stays in `AGENTS.md` § Non-negotiables — cited, not restated.
123
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.88.1",
3
+ "version": "4.88.2",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"
@@ -337,6 +337,37 @@ async function detectState(cwd, opts = {}) {
337
337
  }
338
338
  } catch (_) { /* never block doctor on probe */ }
339
339
 
340
+ // ---- Codex agent transpile integrity (S6) --------------------------
341
+ // When Codex is an enabled tool, every framework agent (.md) must have been
342
+ // transpiled to `.codex/agents/<name>.toml` (generated on install/update).
343
+ // A missing .toml is exactly the "skill delegates to an agent Codex can't
344
+ // spawn by name" gap the /new + /prd Codex paths target — and while the
345
+ // agent-discovery-info SessionStart hook warns at runtime, this static probe
346
+ // lets doctor surface it offline. Advisory only (fix = `baldart update`,
347
+ // which re-transpiles); never blocks. Fully fail-safe.
348
+ state.codexAgentsEnabled = false;
349
+ state.codexAgentsMissing = [];
350
+ try {
351
+ if (state.frameworkPresent) {
352
+ const toolsEnabled = (config && !config.__malformed && config.tools && Array.isArray(config.tools.enabled))
353
+ ? config.tools.enabled : ['claude'];
354
+ if (toolsEnabled.includes('codex')) {
355
+ state.codexAgentsEnabled = true;
356
+ const frameworkAgentsDir = path.join(cwd, '.framework', 'framework', '.claude', 'agents');
357
+ const codexAgentsDir = path.join(cwd, '.codex', 'agents');
358
+ if (fs.existsSync(frameworkAgentsDir)) {
359
+ const baldartAgents = fs.readdirSync(frameworkAgentsDir)
360
+ .filter((f) => f.endsWith('.md') && f !== 'REGISTRY.md')
361
+ .map((f) => f.replace(/\.md$/, ''));
362
+ for (const name of baldartAgents) {
363
+ try { fs.statSync(path.join(codexAgentsDir, `${name}.toml`)); }
364
+ catch (_) { state.codexAgentsMissing.push(name); }
365
+ }
366
+ }
367
+ }
368
+ }
369
+ } catch (_) { /* never block doctor on probe */ }
370
+
340
371
  // ---- Workflow symlink integrity (since v4.14.0) --------------------
341
372
  // Dynamic workflows (.js) are Claude-only and per-item symlinked into
342
373
  // `.claude/workflows/`. Unlike agents there is NO hard discovery gate —
@@ -1552,6 +1583,18 @@ function renderDiagnostic(state) {
1552
1583
  if (untrusted) console.log(` • untrusted: ${state.codexHooksUntrusted.join(', ')} (approve once on the next Codex session)`);
1553
1584
  }
1554
1585
 
1586
+ // Codex agent transpile health (S6). Advisory: a missing .codex/agents/<name>.toml
1587
+ // is the "skill delegates to an agent Codex can't spawn" gap — fix is `baldart update`.
1588
+ if (state.codexAgentsEnabled) {
1589
+ const missing = state.codexAgentsMissing ? state.codexAgentsMissing.length : 0;
1590
+ if (missing === 0) {
1591
+ console.log(statusLine('Codex agents', 'all transpiled to .codex/agents/', 'ok'));
1592
+ } else {
1593
+ console.log(statusLine('Codex agents', `${missing} not transpiled — run \`npx baldart update\``, 'warn'));
1594
+ console.log(` • missing: ${state.codexAgentsMissing.join(', ')}`);
1595
+ }
1596
+ }
1597
+
1555
1598
  // Git-hooks health (v3.34.0+). Silent when no versioned-hooks dir exists
1556
1599
  // (`checked:false`) — most consumers have no managed git hooks and must see
1557
1600
  // zero noise here.