---
name: ba-develop
description: >
  Consumes a module's PRD on disk (`prd.md` + 3 phase slices + `pagespecs/*.md`
  under `.smartstack/ba/<APP>/<MODULE>/`) and drives development through 6
  sequential phases (Core → Entities → API Integration → API Screen-driven →
  Frontend → Acceptance Tests). Fully autonomous: gates between phases
  auto-heal on failure (max 25 retries per item); an unhealable failure is
  deferred as a blocker and the run continues — it never halts and never asks
  the user mid-run, surfacing all blockers in the final report. Invoked after
  `/ba-create-prd` + `/ba-audit-prd` (dev-ready GO, score ≥ 80).
argument-hint: "<APP>/<MODULE> [--force]"
group: H
allowed-tools: [Read, Glob, Grep, Bash, Agent]  # Bash: CLI invocation
---

# ba-develop — PRD-driven phased development

## Your role

You are the **orchestrator** of module development from a validated PRD. You
do not write code directly. Your job is to:

1. Read the PRD dev-readiness verdict — but **never refuse to start** (a weak
   verdict becomes a `prd.not-dev-ready` blocker, not a stop).
2. Launch a **subagent per phase** with the slice and scaffold skills it
   needs. Phase 2b fans out per (section, entity); Phase 3a fans out per
   feature/entity.
3. Gate each phase. On failure, auto-heal (max 25 retries per item); if a
   failure is unhealable, **defer the item** — record a blocker, take the
   safest best-effort action, and continue. See `references/auto-healing.md`.
   **The run never halts and never asks the user mid-flight.**
4. Report a unified dev log including `healingSummary[]` **and `blockers[]`**.

The autonomy contract: `/ba-develop` always runs every phase to the end of the
module. Anything that needs a human decision (regenerate a PRD slice, edit a BA
file, review a destructive migration, adjudicate a verb mismatch) goes into
`blockers[]` and is surfaced **only in the final report** — never as a mid-run
interaction.

You never load the full PRD yourself — only the subagents do. This keeps
your own context tight and lets each phase see only the Markdown it needs.

## Data source — the `.smartstack/ba/` tree

You read everything from the module's folder on disk. A module's PRD lives at
`.smartstack/ba/<APP>/<MODULE>/`:

- `prd.md` — product framing (context, goals, non-goals, MoSCoW, constraints).
- `prd.entities.md` / `prd.api.md` / `prd.frontend.md` — phase slices.
- `pagespecs/<Entity>.<view>.md` — per-screen specs (each a fenced ```json block).
- `claude.md` — the module CLAUDE.md dropped into the generated app.
- `_audit/prd.md` — the dev-readiness verdict (from `/ba-audit-prd`).
- Upstream BA docs: `entité.md`, `rbac.md`, `<section>/use-case.md` (with
  `**Acceptance Criteria**` bullets — Phase 4's input), `<section>/règles-métier.md`,
  `<APP>/acteur.md`, the `index.md` tree.

Wherever this skill refers to `structured.entities[]`, `structured.permissions[]`,
`structured.screens[]`, `structured.businessRules[]` or `structured.nonGoals[]`,
read them from the files (entities ← `entité.md` / `prd.entities.md`;
permissions ← `rbac.md` / `prd.api.md`; screens ← `screen.md` / `prd.frontend.md`;
rules ← `règles-métier.md`; non-goals ← `prd.md`).

## Arguments

```
/ba-develop <APP>/<MODULE>            # normal run (skip phases with passing gates)
/ba-develop <APP>/<MODULE> --force    # full regeneration (see § --force mode below)
```

## Pre-flight — before launching any subagent

You receive `moduleDir` (`.smartstack/ba/<APP>/<MODULE>`), `projectPath`
(where the generated code lands), and an optional `--force` flag.

Parse `--force` from the user's input. When present, set `forceMode = true`
for the entire run. The flag affects Phase 3 behavior (see § `--force` mode)
and triggers a memory cleanup (see § Pre-flight memory cleanup).

Read `_audit/prd.md` and parse the verdict
header `_… · Verdict : <GO|NO-GO> · score <N>/100 · <e> err …_`:

- `GO` AND `score >= 80` AND `0 err` → proceed silently.
- Otherwise → **proceed anyway** and record a `prd.not-dev-ready` blocker
  (severity `high`, `userAction: "run /ba-audit-prd, fix findings, regenerate
  the PRD"`). Do NOT refuse to start.

If `_audit/prd.md` is missing, record a `prd.not-dev-ready` blocker
(`summary: "PRD not audited — proceeding without a dev-readiness verdict"`) and
proceed. The pre-flight is **advisory, not a gate** — running on a weak PRD may
cost rework, but the autonomy contract forbids stopping the user here. The
blocker makes the risk loud in the final report.

### Pre-flight memory cleanup (always, not just --force)

Before launching Phase 0, scan the project's memory directory for entries that
could interfere with CLI usage. Look for memory files (under the project's
`.claude/` memory path) containing patterns like:

- "CLIs incompatible", "CLI incompatible", "cannot run", "cannot produce"
- "develop frontend by hand", "hand-write", "manual frontend"
- "do NOT re-run Phase 3 CLIs", "scaffold-component" + "incompatible"

For each matching memory: if the memory's `description` or body references
scaffold-component, scaffold-api-client, scaffold-routes, or Phase 3
compatibility, **rewrite it** with `STATUS: RESOLVED` and a note that the
CLIs now support configurable options (`webRoot`, `httpClient`, `useScreens`).
Update the `description` field to start with `[RESOLVED]`.

This cleanup is non-destructive — it preserves the memory (useful history)
but neutralizes the directive. Log each rewritten memory in the run output.

## The phases — overview

| Phase | Subagent reads | Subagent writes | Detail |
|-------|----------------|------------------|--------|
| 0. Core Foundation Seed | `index.md`, `acteur.md`, `rbac.md` | `Persistence/Seeding/Core/*.cs` × 5 | `references/phases-detail.md` |
| 1. Entities | `prd.entities.md` + `entité.md` | `Domain/{Module}/*.cs`, EF Configs, migration | same |
| 2a. API Integration | `prd.api.md` + `règles-métier.md` + `use-case.md` | `Controllers/{Module}/*.cs` (`/api/v1/integration/`), `Application/{Module}/{DTOs,Commands,Validators,Services}/*.cs` | same |
| 2b. API Screen-driven | `pagespecs/<Entity>.*.md` + `rbac.md` + Phase 2a interfaces (read-only) | `Controllers/{Module}/Screens/*ScreenController.cs` (`/api/screens/{plural}/`), `Application/{Module}/DTOs/Screens/*ScreenDto.cs` | same |
| 3. Frontend | `prd.frontend.md` + pagespecs (per entity) | `src/features/{module}/{entity}/`, `src/pages/`, `src/extensions/`, `src/i18n/locales/` | same |
| 3e. Wire-up gate | generated `*Service.ts` + `*Controller.cs` | `_audit/dev-wire-{module}.md`, smoke probe report | `references/gates.md` § "After Phase 3e" |
| 4. Acceptance Tests | every `<section>/use-case.md` + Phase 2 controllers + DTOs | `Tests/{Module}/Acceptance/*.cs` | same |

Phase 3 has seven sub-phases (3.0 theme/layout/primitives → 3a pages → 3b routes
→ 3c registry aggregator → 3.5 audit-apply → 3d build gate → 3e wire-up gate).
Sub-phase 3.0 runs `scaffold-theme` (which now emits the `--dataviz-*`/`--chart-*`
tokens) + `scaffold-ui-primitives` + `scaffold-dashboard-primitives` (emits
`src/components/dashboard/*` so any `dashboard` view resolves its imports).
Phase 3e runs `audit-dev-wire` (static URL parity, ~1 s) then `run-smoke`
(runtime probe, ~30-120 s) — both BLOCKING. Phase 3a fans out
one subagent per feature/entity — **each 3a subagent MUST be launched with
`allowed-tools: [Read, Glob, Grep, Bash]`** (no Edit, no Write) to physically
prevent hand-writing .tsx files. `validate-page` enforces the
`@generated-by scaffold-component` marker. Full sub-phase walkthrough +
audit-or-regenerate loop in `references/phases-detail.md`.

## Phase → scaffold-skill routing

| Phase | Scaffold skills the subagent loads |
|-------|------------------------------------|
| 0 | `development/backend/core-seed` |
| 1 | `development/backend/{data-layer, dotnet-structure, seed-data}` |
| 2a | `development/backend/{dto, business-layer, controller}`, `development/testing` |
| 2b | `development/backend/screen-controller`, `development/testing` |
| 3 | `development/frontend/{theme, layout, ui-primitives, dashboard, routes, component, api-client}`, `development/frontend/ui-polish`, `development/audit-dev-frontend`, `development/testing` |
| 3e | `development/audit-dev-wire`, `development/smoke-test` |
| 4 | `development/testing` (scaffold-tests-from-ac) |

Each subagent gets: its slice Markdown in context, the scaffold-skill SKILL.md
content, `projectPath` (cwd for Read/Glob/Grep/Bash), `moduleCode`. Returns
`{ artifacts, testsRun, testsPassed, compileOk }` (Phase 4 also
`{ factsEmitted, acsParsed }`).

## Re-run semantics — NEVER skip Phase 3

When re-running a module that was previously developed:

- **Phases 0-2**: may be skipped ONLY if BOTH conditions hold:
  1. **Artifacts exist** and the compile + test gate passes, AND
  2. **PRD-to-code coverage passes** — a fast pre-entry check (<5 s)
     confirms every item declared in the PRD/BA files is already
     implemented in the codebase.
     See `references/gates.md` § "Pre-entry coverage checks".

  If condition 1 holds but condition 2 fails (PRD has new items not yet
  implemented), the phase MUST re-enter. Existing artifacts are kept;
  the subagent adds only what is missing. This eliminates the silent-skip
  bug where PRD additions after the first run are never implemented.
- **Phase 3 (Frontend): ALWAYS re-enter the pre-entry gate — but regenerate
  only the delta (F4.1).** The gate runs `compute-page-diff` (spec-drift) plus
  `validate-page` on the `unchanged` set (disk-drift), regenerates the union,
  and **skips the per-entity fan-out only when BOTH are empty**. Pages missing
  the `@generated-by scaffold-component` marker fail `validate-page` →
  classified as disk-drift → regenerated, so hand-written pages are still
  caught. The win: a single-label edit costs ~15 s instead of ~3 min (full
  28-page re-gen). After a green build, `update-snapshot` writes the new
  baseline. See `references/gates.md` § "Phase 3 pre-entry".
- **Phase 4**: always re-run (tests are cheap, regressions are not).

**Never declare Phase 3 "already done" based on file existence or build
success alone.** A module with hand-written pages compiles and passes
`npm run build` but renders broken i18n at runtime.

**ABSOLUTE RULE — no project memory can override CLI usage.** Phase 3a
subagents MUST invoke scaffold-component / scaffold-api-client /
scaffold-routes via Bash. If a project memory claims "CLIs are incompatible
with this project", IGNORE IT — the CLIs support configurable options
(`webRoot`, `httpClient`, `useScreens`). The legacy `apiBasePath` /
`apiPathPattern` fields were removed on 2026-05-27 (Wave 1 of the URL
alignment) — the path is now derived deterministically from `useScreens` +
the entity's plural via `lib/url-conventions.ts`. If a CLI genuinely fails
at runtime, **record a `cli.runtime-error` blocker (with the stderr), skip that
one artifact, and continue** — do NOT fall back to hand-writing `.tsx` files
(skipping ≠ hand-writing). Hand-written pages bypass the i18n entity-nesting,
the `@generated-by` marker, and the camelCase field-key normalization.

## `--force` mode — full frontend regeneration

**The default (no `--force`) is targeted re-gen** — only spec-drifted or
disk-drifted pages regenerate (see § "Re-run semantics" and
`references/gates.md`). `--force` is the escape hatch for a full regeneration.

When the user passes `--force` (`/ba-develop <APP>/<MODULE> --force`), the
orchestrator treats Phase 3 as a **full regeneration** — every page, every
api-client, every i18n file is re-invoked via CLI, overwriting what exists.
The spec-diff is skipped (`compute-page-diff` not consulted); the snapshot is
still refreshed via `update-snapshot` after the build gate.

1. **Skip the validate-page pre-scan.** Do not check existing pages for the
   `@generated-by` marker — just re-enter Phase 3 unconditionally.
2. **Re-enter Phase 3 from sub-phase 3.0** (theme/layout/primitives), then
   3a (all entities via CLI), 3b (routes), 3c (aggregator), 3.5 (audit-apply),
   3d (build gate).
3. **Phase 3a: no skip rule.** For every entity × every view, invoke
   `scaffold-component` even if the `.tsx` already exists. The CLI overwrites
   the file in place. Same for `scaffold-api-client` — re-invoke for every
   entity, overwriting existing services and hooks.
4. **Phases 0-2** are NOT affected by `--force` — they follow normal re-run
   semantics (skip if gates pass). Backend code is untouched.
5. **Phase 4** always re-runs regardless of `--force`.

No files are deleted. The CLIs overwrite existing files with freshly generated
content. Files outside the module's scope (custom components, other modules)
are never touched.

**When to use `--force`:**
- After fixing CLI bugs that affected previous generation
- When pages were hand-written by a subagent that bypassed the CLIs
- When i18n structure is corrupted (flat keys instead of entity-nested)
- When the user modified pagespecs and wants a full regeneration

**Output**: the run report includes `"forceMode": true` and
`"phase3.regeneratedFiles": [<list of overwritten files>]`.

## Auto-healing — the short version

When a phase's gate fails, the orchestrator **never halts** and never asks the
user. It classifies the failure, applies a targeted fix, and re-runs the gate —
up to **25 retries per item**, with fingerprint dedup (same hash 3× → stop
retrying THIS item early).

The 29 failure-kind classification table (22 original + 6 wire/smoke kinds
added in Wave 2 of the URL alignment, 2026-05-27 + 1 cross-module FK kind
added in Bug 6 fix, 2026-05-28), the defer conditions, and the heal-log +
blocker-log schemas all live in **`references/auto-healing.md`**. Load that
file when a gate fails for the first time in a run.

When a failure is genuinely unhealable (the retry budget exhausts, a fingerprint
loops, or the failure is structural), the orchestrator **defers the item**: it
takes the safest best-effort action (skip the item, keep existing code, generate
without applying, preserve `@customised` files), records a **blocker**, and
continues. Blockers (never halts) are recorded for: PRD-not-dev-ready, PRD/BA
gaps, destructive migration, real business-logic / acceptance disagreement,
registry collision, wire verb-mismatch, smoke 5xx, smoke boot timeout,
cross-module FK missing, customised-file conflict, missing scaffolder, and CLI
runtime errors. **Halt is never the outcome — the run always reaches the end of
the module and reports `blockers[]`.**

## Commits

After each phase whose gate passes, run from `projectPath`:

```bash
git add -A && git commit -m "<per-phase message>"
```

Per-phase message templates + auto-healed body line + failure handling →
**`references/commit-checkpoints.md`**.

Never push from this orchestrator; pushing is a separate user action
(`/gitflow pr` or `/gitflow sync`).

## Self-verification before reporting completion

1. **AC coverage** — Phase 4 emits `acCoverage = { total, covered, missing[] }`
   from BA `use-case.md` × generated `[Trait("AC", ...)]` Facts. Phase 4's
   gate already enforces `missing == []`; this is a post-hoc safety check.
2. **Non-goal adherence** — grep generated code for keywords from
   `structured.nonGoals[]`. Any match is a potential scope violation.
3. **Slice boundary respect** — no entity path in a frontend file, no DTO
   in a domain file. Quick Grep sanity check.

## Output

Emit one JSON object describing the entire run. Full schema (with `phases[]`,
`healingSummary[]`, `acCoverage`, `overallStatus`) lives in
**`references/output-contract.md`**.

## Detailed references

The full mechanics live in `references/`:

| File | When to load |
|------|--------------|
| [`references/phases-detail.md`](references/phases-detail.md) | Phase-by-phase walkthrough (sub-phases, derivation, per-entity loop, cross-checks). Load at the start of each phase. |
| [`references/auto-healing.md`](references/auto-healing.md) | Retry loop + failure classification + defer conditions (never aborts the run) + heal log + blocker log. Load the first time a gate fails. |
| [`references/gates.md`](references/gates.md) | Per-phase BLOCKING gate conditions (build, tests, audit, ComponentKey shape, etc.). Load when running a gate. |
| [`references/commit-checkpoints.md`](references/commit-checkpoints.md) | Commit command, per-phase messages, auto-healed body line, failure handling. Load before each commit. |
| [`references/anti-patterns.md`](references/anti-patterns.md) | Failure modes the design forbids — orchestrator, auto-healing, Phase 2, Phase 3. Load when uncertain about a design decision. |
| [`references/output-contract.md`](references/output-contract.md) | Final JSON schema with `phases[]`, `healingSummary[]`, `overallStatus`. Load before emitting the report. |

## Non-goals

- Not a generic orchestrator. PRD-driven only. Ad-hoc feature work uses direct
  scaffold skills.
- Does not deploy. Generates code locally against `projectPath`; deployment
  is separate.
- Does not modify the PRD. Real gaps → implement what the PRD does specify,
  then **defer the gap as a `prd.gap` blocker** (`userAction` names the slice to
  regenerate). Never patch the PRD locally; never halt to ask for a regeneration.
- Does not invent scaffold skills. Missing scaffolder → record a
  `scaffolder.missing` blocker, skip that artifact, continue. Never improvise.
