# Dynamic Workflows (`.claude/workflows/`)

**Since v4.14.0.** BALDART can ship Claude Code **dynamic workflows** — JavaScript
orchestration scripts that fan out subagents at scale, with the plan held in code
(deterministic branches/loops) instead of in the orchestrator's context window.
They are distributed as a new per-item payload under `.claude/workflows/`.

This is an **opt-in accelerator**, never a hard dependency. Every skill that
delegates to a workflow keeps a complete inline fallback, so a repo where
workflows are unavailable behaves exactly as before.

## What ships today

| Workflow | Used by | What it does |
| :--- | :--- | :--- |
| `new-final-review` | `/new` Final Review (Step F.1.5) | Runs the read-only cross-batch review fan-out — architecture baseline + Codex ‖ doc-reviewer ‖ api-perf-cost-auditor ‖ qa-sentinel — then adversarially verifies low-confidence findings and returns them classified. Applies no fixes (the skill owns fix application + user gates). **v4.17.1+:** Codex availability is resolved by a **deterministic pre-flight glob + background poll** (no false negatives from a synchronous-run timeout); a **single-card batch** skips the duplicate doc/api reviewers (already run per-card), keeping only the cross-model Codex pass + qa gates. |
| `new-card-review` (v4.34.0) | `/new` per-card review cluster — sequential (`review-cycle.md` § Phase 2.5x) **and** team-mode (`team-mode.md` D.1.6) | Hosts the **per-wave** review-cluster OUTSIDE the orchestrator context — the biggest prefix-growth source on long epics. Takes **1..N co-located cards** (1 = sequential per-card; N = a team-mode group, so it runs **once per wave, not per card**) and fans out the finders per card: Simplify + cross-model Codex (agent-launched binary, `code-reviewer` fallback) + qa-sentinel (group max tier) + security-reviewer (high-risk only), each specialist FP-checking its own findings. Then **ONE `coder` applies all VERIFIED code/perf/security/simplify findings in a single pass** (files disjoint by ownership) and re-verifies lint/tsc/build. Returns a compact `{perCard:{fixesApplied,residual}, gateTable, summary}` — the minority `residual` (doc, needs-manual, scope, unconverged) the skill resolves with the right specialist / user gate. **Doc-review and E2E stay in the skill** (doc is write-mode + must see final code; E2E is human-gated + nests a skill); **api-perf is deferred to the Final FULL gate**. Maps to `review-cycle.md` Phase 2.55+3.5+3.7. |
| `new2` (v4.17.2) | `/new2` skill (the whole batch) | **EXPERIMENTAL A/B variant of `/new`.** Hosts the ENTIRE batch in the background runtime so subagent output never enters the main context. A **dependency-gated DAG scheduler** runs a card only when all in-batch deps are *committed* (and blocks transitive dependents of a failed dep instead of routing them to resolve); each card uses its **owner_agent** + a **specialized review fan-out** (not general-purpose); the worktree is kept **atomic per card** (rollback-to-HEAD on failure); transient API errors are retried and a sustained **outage degrades cleanly** (`degraded` return + durable resume via the skill); a **run ledger** dedups resolves and records accepted deferrals (no re-routing loop); the **merge is integrity-gated** (never force-DONE, never `git add` unreviewed code, never merge an incomplete/degraded batch); the commit step runs on **Haiku** while **follow-up cards are written by `prd-card-writer`**; telemetry carries real **cost** (`total_tokens` via `budget.spent()`, `agent_count`, skill-stamped `wall_clock_s`) + `degraded`. **v4.17.2:** the pre-flight **G3 cross-card Codex check is deterministic** (glob-first + background poll, skipped on single-card batches; `codex_resolved` in telemetry); a non-transient card crash is terminal-with-residual (no orphaned self-healing). Agents Read `/new`'s reference modules for semantics. |
| `new2-resolve` (v4.17.2) | `new2` (self-healing) | Resolution pass for any gate that would otherwise need a human (`ac-unmet · blocker · qa-fail · e2e-blocked · merge-blocker · scope-expansion`). A **terminal short-circuit** skips the costly multi-attempt when the problem is impossible-by-definition (`out-of-ownership` verified in JS; other terminal reasons ratified by a judge); a **MANDATORY adversarial judge** cross-checks every `verified` claim — the judge independently greps the files and the workflow verifies **at least one** falls inside MAY-EDIT (`.some()`, so listing adjacent changed files is not mistaken for fabrication); accepts a **batched `findings` list** (one resolve per fix-area). **The domain is normalized** (freeform `documentation`→`doc`, …) before routing the **fixer** (doc→doc-reviewer, ui→ui-expert, security→security-reviewer, else coder) and judge, and a **doc finding gets doc-tree MAY-EDIT** (not the card's code scope); the 3-angle Tier-2 fan-out is reserved for code domains (single retry for doc/test). Follow-ups are written by **`prd-card-writer`**, offline-safe (deferred to the skill if no agent can write). |

> **`new2` is an experiment, not a replacement.** It exists to A/B-test the
> context-economy of workflow-hosting `/new`. `/new` remains the SSOT, the
> cross-tool default, and the recovery-safe path. `new2` is Claude-only and its
> skill HALTs with a pointer to `/new` when the `Workflow` tool is unavailable.

## How distribution works

- **Per-item symlink**, same model as `.claude/skills/`, `.claude/agents/`,
  `.claude/commands/`: each framework `<name>.js` under
  `.framework/framework/.claude/workflows/` is symlinked into the consumer's
  `.claude/workflows/<name>.js`. `baldart add` / `update` / `doctor` create and
  reconcile these links.
- **Claude-only.** Dynamic workflows are a Claude Code runtime feature with no
  OpenAI Codex equivalent. The Codex tool adapter returns `workflowsDir() = null`,
  so workflow scripts are never linked into a Codex tree. Codex consumers (and any
  Claude consumer with workflows disabled) run the delegating skill's inline path.
- **No overlay.** Overlays are a markdown construct (`## [OVERRIDE]` sections + an
  HTML-comment marker) and do not apply to `.js`. Workflows are distributed as
  plain symlinks; customise the *delegation decision* in the skill/overlay layer,
  not the script.
- **Contamination-scanned.** The `framework-edit-gate` hook scans workflow `.js`
  content by path (not extension), so a hardcoded project path or identity token
  in a workflow is blocked exactly like in any other framework file. Workflows
  must read all project-specific facts from their `args` (passed by the skill from
  `baldart.config.yml`), never hardcode them.

## The opt-in / degradation contract

A delegating skill decides **at runtime**, with no new `baldart.config.yml` key:

1. **IF** the `Workflow` tool is available to the model **AND** the workflow
   script is linked → call `Workflow({ name, args })` and use its return value.
2. **ELSE** → run the skill's inline fallback (the prose remains the SSOT).

There is deliberately no `features.use_workflows` flag: workflow availability is a
property of the Claude Code session (research-preview, plan tier, the native
`disableWorkflows` setting), not a fact the repo can record. Force-disabling is the
native Claude Code toggle; the skill simply detects and degrades.

## Authoring notes (maintainers)

- A workflow script begins with a pure-literal `export const meta = { name,
  description, phases }`, then a body using `agent()` / `parallel()` / `pipeline()`
  / `phase()` / `log()` and the `args` / `budget` globals.
- The script cannot run bash/git/fs — only its agents can. Keep anything that
  needs git, shared state, or a user prompt in the calling skill; give the
  workflow the read-only fan-out.
- Single-source the *semantics*: a workflow's agent briefs should cite the skill's
  reference module for what each agent checks, so the workflow encodes only the
  *orchestration shape*. Carry a drift note in the reference module.
