Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "transmuter",
"description": "Transmute Framework — AI-driven pipeline that transforms a business plan into a fully deployed product through 25 stages (23 automated, 2 manual)",
"version": "3.2.0",
"version": "3.2.1",
"author": {
"name": "Transmute",
"url": "https://github.com/VoxTechnologies/transmute-framework"
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ Contributors: run `scripts/conformance.sh` before a release (`--live` also loads

## Changelog

### v3.2.1

- A lead whose teammate spawn is refused (concurrency cap, rate or usage limit, a hook) now continues in smaller waves instead of stopping to ask the operator. Found in a trial run where a machine-local cap of three concurrent subagents stopped Stage 1 with a question. The rule is in the pipeline agent's Execution Model and in the generated project's `CLAUDE.md` § Safety-Critical Rules, so stages invoked directly follow it too
- The gate hook now enforces the Stage 1 stop condition: `prd` and `validate-specs` are blocked while the BRD is 30% or more assumptions and `_review-log.md` does not say `Operator reviewed: YES`. In the 2026-10-02 trial the sample plan came out at 60% assumptions, Stage 2 ran for 51 minutes anyway, and Stage 2B could only end in FAIL. `scripts/trial-run.sh` gains `ACCEPT_ASSUMPTIONS=1` for fixture plans

### v3.2.0

**Pipeline flow** — nine changes to how the stages run, in the order they pay off.
Expand Down
4 changes: 3 additions & 1 deletion agents/transmute-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Report outcomes faithfully. Before writing a stage's status to `plancasting/_pro

Stage skills spawn "teammates". In this plugin a teammate is a subagent started with the Agent tool (`subagent_type` = the agent name under `agents/`, or `general-purpose` with the spawn prompt from the stage's detailed guide). Its final message is its completion message to you. Start independent teammates in one message so they run concurrently, and keep working while they run; give a long-lived teammate a `name` so follow-up instructions go through `SendMessage` instead of re-spawning it with the context rebuilt. The messaging vocabulary in the detailed guides ("message the lead", "shared task list") also maps onto Claude Code's experimental Agent Teams when `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set; the Agent-tool mapping above is the default. Do not end your turn while teammates are still running on the assumption that their completion will wake you: wait for them (or start them in the foreground) before reporting a stage complete — in a non-interactive (`claude -p`) run the harness terminates background subagents after 600 seconds unless `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0` is set, and a stage that ends its turn early is reported as finished with its files missing.


**When a spawn is refused.** When a teammate cannot be started — the Agent tool refuses the spawn because of a concurrency cap, a rate limit, a usage limit, or a hook — do not stop to ask the operator. Run the teammates you could not start in smaller waves, starting each wave as the previous one finishes, down to one at a time. Keep each teammate's scope and its separate context, since the stage's review steps depend on them; writing a teammate's files yourself is the last resort, used only when not even one teammate can be started, and recorded in the stage report. Pass this rule on in every stage skill you invoke.
## Pipeline Overview

```
Expand Down Expand Up @@ -116,7 +118,7 @@ For each stage:

### Stage 1 Gate (assumption volume)

Stage 1 has no PASS/FAIL gate on requirement quality, but it has one stop condition: if `plancasting/brd/_review-log.md` § "Assumption Review Status" reports an assumption volume ≥ 30% and `Operator reviewed: YES` is not set, the business plan is too thin to build from. Mark Stage 1 `⏸ Awaiting operator review (assumptions ≥ 30%)` in `plancasting/_progress.md`, print the assumption percentage and the list of assumed requirements, and stop — do not run Stage 2 (Stage 2B would FAIL on the same marker anyway). The operator either revises the business plan and re-runs Stage 1, or reviews the assumptions and sets the marker, then runs `/transmuter:cast resume`.
Stage 1 has no PASS/FAIL gate on requirement quality, but it has one stop condition: if `plancasting/brd/_review-log.md` § "Assumption Review Status" reports an assumption volume ≥ 30% and `Operator reviewed: YES` is not set, the business plan is too thin to build from. Mark Stage 1 `⏸ Awaiting operator review (assumptions ≥ 30%)` in `plancasting/_progress.md`, print the assumption percentage and the list of assumed requirements, and stop — do not run Stage 2 (Stage 2B would FAIL on the same marker anyway). The operator either revises the business plan and re-runs Stage 1, or reviews the assumptions and sets the marker, then runs `/transmuter:cast resume`. The gate hook enforces the same condition when `prd` or `validate-specs` is invoked directly.

### 5B Gate
- **PASS** (zero remaining issues AND all tests pass — no regressions from 5B fixes) → proceed to Stage 6
Expand Down
4 changes: 3 additions & 1 deletion examples/sample-plan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ Operator answers for Stage 0 (use these instead of asking; if a question is not
- Deployment: manual. Credentials: write placeholder values (YOUR_*_HERE) into .env.local; do not validate keys.
```

The plan is thin on purpose, so Stage 1 marks well over 30% of the BRD as assumptions (60% in the 2026-10-02 trial) and the Stage 1 gate stops the pipeline before Stage 2 until an operator reviews them. For a trial on this fixture, set `ACCEPT_ASSUMPTIONS=1`: the runner then sets `Operator reviewed: YES` in `plancasting/brd/_review-log.md` after Stage 1. Never use it on a real plan.

Example:

```bash
mkdir -p ~/trial && cp -R examples/sample-plan/plancasting ~/trial/ && cd ~/trial && git init -q
EXTRA_PROMPT="$(sed -n '/^```text$/,/^```$/p' ~/transmute-framework/examples/sample-plan/README.md | sed '1d;$d')" \
ACCEPT_ASSUMPTIONS=1 EXTRA_PROMPT="$(sed -n '/^```text$/,/^```$/p' ~/transmute-framework/examples/sample-plan/README.md | sed '1d;$d')" \
~/transmute-framework/scripts/trial-run.sh ~/trial tech-stack brd prd validate-specs scaffold
```

Expand Down
15 changes: 15 additions & 0 deletions hooks/scripts/check-prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ block() {
exit 2
}

# Stage 1 stop condition (agents/transmute-pipeline.md § Stage 1 Gate). A plan whose BRD is
# >= 30% assumptions fails Stage 2B unless the operator has reviewed them, so block Stage 2
# up front instead of spending a PRD run on it. The marker is matched loosely because the
# review log writes it as a bold list item ("- **Operator reviewed**: YES").
assumption_gate() {
local log="./plancasting/brd/_review-log.md" pct
[[ -f "$log" ]] || return 0
pct=$(sed -n 's/.*Assumption volume[*]*:[*[:space:]]*\([0-9][0-9]*\)\(\.[0-9]*\)\{0,1\}%.*/\1/p' "$log" | head -1)
[[ -n "$pct" && "$pct" -ge 30 ]] || return 0
grep -qiE 'Operator reviewed[*]*:[*[:space:]]*YES' "$log" && return 0
block "$1 is stopped by the Stage 1 gate: the BRD is ${pct}% assumptions and $log does not say 'Operator reviewed: YES'. Revise the business plan and re-run Stage 1, or review the assumptions and set the marker."
}

# Define prerequisite checks for each stage
case "$SKILL_NAME" in
tech-stack)
Expand All @@ -65,13 +78,15 @@ case "$SKILL_NAME" in
if [[ ! -d "./plancasting/brd" ]]; then
block "Stage 2 (PRD) requires ./plancasting/brd/ from Stage 1. Run '/transmuter:cast brd' first."
fi
assumption_gate "Stage 2 (PRD)"
;;

validate-specs)
# Stage 2B: Requires BRD + PRD
if [[ ! -d "./plancasting/brd" ]] || [[ ! -d "./plancasting/prd" ]]; then
block "Stage 2B (Spec Validation) requires both ./plancasting/brd/ and ./plancasting/prd/. Run Stages 1 and 2 first."
fi
assumption_gate "Stage 2B (Spec Validation)"
;;

scaffold)
Expand Down
5 changes: 5 additions & 0 deletions scripts/conformance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ check "no current-generation model ID carries a date suffix" bash -c '! rg -q "c
check "hook script syntax" bash -n hooks/scripts/check-prerequisites.sh
check "cast.md knows the attended mode and the early-verify (5V) alias" bash -c 'grep -q "attended" commands/cast.md && grep -q "early-verify" commands/cast.md'
check "progress template carries Duration and Usage columns and the 5V row" bash -c 'grep -q "| Duration | Usage |" templates/progress.md && grep -q "^| 5V |" templates/progress.md'
check "spawn-refusal rule present in the pipeline agent and the project CLAUDE.md" bash -c 'grep -q "When a spawn is refused" agents/transmute-pipeline.md && grep -q "Teammate spawn refused" templates/CLAUDE.md'
check "pipeline agent defines the Stage 1 and 5V gates" bash -c 'grep -q "### Stage 1 Gate" agents/transmute-pipeline.md && grep -q "### 5V Gate" agents/transmute-pipeline.md'

echo "== Gate hook behaviour (fixtures) =="
Expand All @@ -81,6 +82,10 @@ run_hook() { echo "$1" | bash "$HOOK" >/dev/null 2>&1; echo $?; }
[[ "$(run_hook '{"tool_name":"Skill","tool_input":{"skill":"feedback"}}')" == 0 ]] && pass "feedback (no prerequisites) passes" || fail "feedback should pass"
mkdir -p plancasting/businessplan plancasting/_audits/spec-validation && touch plancasting/businessplan/plan.md plancasting/_audits/spec-validation/report.md plancasting/tech-stack.md
[[ "$(run_hook '{"tool_name":"Skill","tool_input":{"skill":"brd"}}')" == 0 ]] && pass "brd passes with business plan + tech-stack.md" || fail "brd should pass once prerequisites exist"
mkdir -p plancasting/brd && printf -- '- **Assumption volume**: 60.1%% (193 / 321)\n- **Operator reviewed**: NO\n' > plancasting/brd/_review-log.md
[[ "$(run_hook '{"tool_name":"Skill","tool_input":{"skill":"prd"}}')" == 2 ]] && pass "prd blocked by the Stage 1 gate (assumptions >= 30%, not reviewed)" || fail "prd should block on unreviewed assumptions"
sed -i.bak 's/\*\*Operator reviewed\*\*: NO/**Operator reviewed**: YES/' plancasting/brd/_review-log.md
[[ "$(run_hook '{"tool_name":"Skill","tool_input":{"skill":"prd"}}')" == 0 ]] && pass "prd passes once the operator marks the assumptions reviewed" || fail "prd should pass with Operator reviewed: YES"
printf 'TRANSMUTER_ANTHROPIC_API_KEY=YOUR_KEY_HERE\nRESEND_API_KEY=CHANGE_ME\n' > .env.local
[[ "$(run_hook '{"tool_name":"Skill","tool_input":{"skill":"scaffold"}}')" == 2 ]] && pass "scaffold blocked on placeholder pipeline-infrastructure credential (red tier)" || fail "scaffold should block on red-tier placeholder"
printf 'TRANSMUTER_ANTHROPIC_API_KEY=sk-ant-real\nRESEND_API_KEY=CHANGE_ME\n' > .env.local
Expand Down
11 changes: 10 additions & 1 deletion scripts/trial-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
# MAX_TURNS per stage (default: 300)
# EXTRA_PROMPT text appended to every stage invocation (operator answers,
# dry-run instructions, etc.)
# ACCEPT_ASSUMPTIONS=1 after Stage 1, mark the BRD assumptions as reviewed
# (`Operator reviewed: YES`). Only for fixture plans such as
# examples/sample-plan, which are deliberately thin: without it
# the Stage 1 gate stops the trial before Stage 2.
#
# Output: <project-dir>/plancasting/_trial/<stage>.json (full result),
# <project-dir>/plancasting/_trial/usage.tsv (one row per stage).
Expand All @@ -28,6 +32,7 @@ PLUGIN_DIR="${PLUGIN_DIR:-$ROOT}"
MODEL="${MODEL:-claude-opus-5-5}"
MAX_TURNS="${MAX_TURNS:-300}"
EXTRA_PROMPT="${EXTRA_PROMPT:-}"
ACCEPT_ASSUMPTIONS="${ACCEPT_ASSUMPTIONS:-0}"
export PATH="$HOME/.local/bin:$PATH"
# In print mode Claude Code terminates background subagents (the stage teammates) after
# 600 s unless this is 0 — measured 2026-10-02: Stage 1 lost 3 of 5 writers and ended with
Expand Down Expand Up @@ -85,8 +90,12 @@ EOF
if [[ $rc -ne 0 ]]; then result="claude-exit-$rc"
elif [[ -n "$exp" && ! -e "$exp" ]]; then result="missing:$exp"
else result="ok"; fi
if [[ "$stage" == brd && "$result" == ok && "$ACCEPT_ASSUMPTIONS" == 1 ]]; then
sed -i.bak -E 's/(Operator reviewed[*]*:[*[:space:]]*)NO/\1YES/' plancasting/brd/_review-log.md && rm -f plancasting/brd/_review-log.md.bak
result="ok (assumptions accepted by ACCEPT_ASSUMPTIONS)"
fi
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$stage" "$started" "$dur" "$turns" "$inp" "$out" "$cr" "$cc" "$result" >> "$TSV"
echo " $result ${dur} min turns=$turns out=$out cache_read=$cr"
[[ "$result" == "ok" ]] || { echo "stopping at $stage ($result); see plancasting/_trial/$stage.err" >&2; exit 1; }
[[ "$result" == ok* ]] || { echo "stopping at $stage ($result); see plancasting/_trial/$stage.err" >&2; exit 1; }
done
echo "trial complete"; column -t -s $'\t' "$TSV"
1 change: 1 addition & 0 deletions templates/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ All stages follow the **Transmute Full-Build Approach**: every feature in the Bu

### Safety-Critical Rules

- **Teammate spawn refused**: When a teammate cannot be started — the Agent tool refuses the spawn because of a concurrency cap, a rate limit, a usage limit, or a hook — do not stop to ask the operator. Run the teammates you could not start in smaller waves, starting each wave as the previous one finishes, down to one at a time. Keep each teammate's scope and its separate context, since the stage's review steps depend on them; writing a teammate's files yourself is the last resort, used only when not even one teammate can be started, and recorded in the stage report.
- **Never skip** 5B, 5V, 6V, 6P/6P-R, or 7V. Always run exactly one of 6P or 6P-R (default: 6P). (5V is the 6V prompt in `MODE: critical`, run right after 5B so a product that does not start is sent back to Stage 5 before the Stage 6 audits.) (5B catches the #1 cause of Stage 6 failures — frontend stubs and duplication that slip through late-queue quality gates.) Note: 5B uses four outcomes (PASS, CONDITIONAL PASS, FAIL-RETRY, FAIL-ESCALATE) — see execution-guide.md § "Gate Decision Outcomes" for thresholds and recovery actions.
- **6P / 6P-R mutual exclusivity**: Run exactly one, never both. To switch: commit 6P work, `git revert` the 6P commit, then run 6P-R in a new session.
- **6R skip conditions**: Skip 6R only if 6V returns PASS (zero issues) or CONDITIONAL PASS with only 6V-C issues (human-judgment items — architectural decisions, design trade-offs — that 6R cannot auto-fix). If 6V returns FAIL, resolve critical blocking issues (manually or by re-running relevant Stage 5/6 steps) and re-run 6V until it achieves PASS or CONDITIONAL PASS before proceeding to 6R. If skipped, 6P/6P-R uses the 6V report as input.
Expand Down
2 changes: 1 addition & 1 deletion templates/execution-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ Before proceeding to Stage 2, review:
- `./plancasting/brd/06-business-requirements.md` — Are the business requirements accurate?
- `./plancasting/brd/07-functional-requirements.md` — Are ALL features captured as FRs?
- Any items marked with `> ⚠️ ASSUMPTION:` — Correct or confirm these.
- **Assumption review timing**: Read `./plancasting/brd/_review-log.md` § "Assumption Review Status" (generated by Stage 1). If assumption volume ≥30%, operator must review and confirm assumptions in the BRD files and update the review status to `Operator reviewed: YES` before running Stage 2 (so the PRD uses corrected assumptions). If <30%, proceed directly. **Where to mark**: Set the review status in `./plancasting/brd/_review-log.md` by adding the line: `Assumption Review Status: Operator reviewed: YES`. **Assumption volume** = (number of requirements with `⚠️ ASSUMPTION` markers) / (total number of requirements across all BRD files) × 100%. **Consequence if skipped**: Stage 2B gate rule 2 checks this marker — if assumption volume ≥30% and the marker is not set to `Operator reviewed: YES`, Stage 2B will return FAIL. You must review and set the marker, then re-run Stage 2B. See `prompt_validate_specs.md` for the full decision tree.
- **Assumption review timing**: Read `./plancasting/brd/_review-log.md` § "Assumption Review Status" (generated by Stage 1). If assumption volume ≥30%, operator must review and confirm assumptions in the BRD files and update the review status to `Operator reviewed: YES` before running Stage 2 (so the PRD uses corrected assumptions). If <30%, proceed directly. **Where to mark**: In `./plancasting/brd/_review-log.md` § "Assumption Review Status", change `- **Operator reviewed**: NO` to `- **Operator reviewed**: YES` and fill in the date. The gate hook also blocks `/transmuter:cast prd` and `validate-specs` until this is set. **Assumption volume** = (number of requirements with `⚠️ ASSUMPTION` markers) / (total number of requirements across all BRD files) × 100%. **Consequence if skipped**: Stage 2B gate rule 2 checks this marker — if assumption volume ≥30% and the marker is not set to `Operator reviewed: YES`, Stage 2B will return FAIL. You must review and set the marker, then re-run Stage 2B. See `prompt_validate_specs.md` for the full decision tree.

Commit the generated files before making edits so you can review your changes with `git diff`. Make edits directly to the BRD files if needed. The PRD stage reads from these files.

Expand Down