diff --git a/commands/gsd/ultraplan-phase.md b/commands/gsd/ultraplan-phase.md
new file mode 100644
index 00000000..1a5e3aab
--- /dev/null
+++ b/commands/gsd/ultraplan-phase.md
@@ -0,0 +1,33 @@
+---
+name: gsd:ultraplan-phase
+description: "[BETA] Offload plan phase to Claude Code's ultraplan cloud — drafts remotely while terminal stays free, review in browser with inline comments, import back via /gsd-import. Claude Code only."
+argument-hint: "[phase-number]"
+allowed-tools:
+ - Read
+ - Bash
+ - Glob
+ - Grep
+---
+
+
+Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
+
+Ultraplan drafts the plan in a remote cloud session while your terminal stays free.
+Review and comment on the plan in your browser, then import it back via /gsd-import --from.
+
+⚠ BETA: ultraplan is in research preview. Use /gsd-plan-phase for stable local planning.
+Requirements: Claude Code v2.1.91+, claude.ai account, GitHub repository.
+
+
+
+@~/.claude/get-shit-done/workflows/ultraplan-phase.md
+@~/.claude/get-shit-done/references/ui-brand.md
+
+
+
+$ARGUMENTS
+
+
+
+Execute the ultraplan-phase workflow end-to-end.
+
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 8ddf308a..506f8452 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -113,7 +113,7 @@ User-facing entry points. Each file contains YAML frontmatter (name, description
- **Copilot:** Slash commands (`/gsd-command-name`)
- **Antigravity:** Skills
-**Total commands:** 79
+**Total commands:** 80
### Workflows (`get-shit-done/workflows/*.md`)
@@ -124,7 +124,7 @@ Orchestration logic that commands reference. Contains the step-by-step process i
- State update patterns
- Error handling and recovery
-**Total workflows:** 76
+**Total workflows:** 77
### Agents (`agents/*.md`)
@@ -409,11 +409,11 @@ UI-SPEC.md (per phase) ───────────────────
```
~/.claude/ # Claude Code (global install)
-├── commands/gsd/*.md # 79 slash commands
+├── commands/gsd/*.md # 80 slash commands
├── get-shit-done/
│ ├── bin/gsd-tools.cjs # CLI utility
│ ├── bin/lib/*.cjs # 19 domain modules
-│ ├── workflows/*.md # 72 workflow definitions
+│ ├── workflows/*.md # 77 workflow definitions
│ ├── references/*.md # 35 shared reference docs
│ └── templates/ # Planning artifact templates
├── agents/*.md # 31 agent definitions
diff --git a/docs/BETA.md b/docs/BETA.md
new file mode 100644
index 00000000..0e078eb3
--- /dev/null
+++ b/docs/BETA.md
@@ -0,0 +1,98 @@
+# GSD Beta Features
+
+> **Beta features are opt-in and may change or be removed without notice.** They are not covered by the stable API guarantees that apply to the rest of GSD. If a beta feature ships to stable, it will be documented in [COMMANDS.md](COMMANDS.md) and [FEATURES.md](FEATURES.md) with a changelog entry.
+
+---
+
+## `/gsd-ultraplan-phase` — Ultraplan Integration [BETA]
+
+> **Claude Code only · Requires Claude Code v2.1.91+**
+> Ultraplan is itself a Claude Code research preview — both this command and the underlying feature may change.
+
+### What it does
+
+`/gsd-ultraplan-phase` offloads GSD's plan-phase drafting to [Claude Code's ultraplan](https://code.claude.ai) cloud infrastructure. Instead of planning locally in the terminal, the plan is drafted in a browser-based session with:
+
+- An **outline sidebar** for navigating the plan structure
+- **Inline comments** for annotating and refining tasks
+- A persistent browser tab so your terminal stays free while the plan is being drafted
+
+When you're satisfied with the draft, you save it and import it back into GSD — conflict detection, format validation, and plan-checker verification all run automatically.
+
+### Why use it
+
+| Situation | Recommendation |
+|-----------|---------------|
+| Long, complex phases where you want to read and comment on the plan before it executes | Use `/gsd-ultraplan-phase` |
+| Quick phases, familiar domain, or non-Claude Code runtimes | Use `/gsd-plan-phase` (stable) |
+| You have a plan from another source (teammate, external AI) | Use `/gsd-import` |
+
+### Requirements
+
+- **Runtime:** Claude Code only. The command exits with an error on Gemini CLI, Copilot CLI, and other runtimes.
+- **Version:** Claude Code v2.1.91 or later (the `$CLAUDE_CODE_VERSION` env var must be set).
+- **Cost:** No extra charge for Pro and Max subscribers. Ultraplan is included at no additional cost.
+
+### Usage
+
+```bash
+/gsd-ultraplan-phase # Ultraplan the next unplanned phase
+/gsd-ultraplan-phase 2 # Ultraplan a specific phase number
+```
+
+| Argument | Required | Description |
+|----------|----------|-------------|
+| `N` | No | Phase number (defaults to next unplanned phase) |
+
+### How it works
+
+1. **Initialization** — GSD runs the standard plan-phase init, resolving which phase to plan and confirming prerequisites.
+
+2. **Context assembly** — GSD reads `ROADMAP.md`, `REQUIREMENTS.md`, and any existing `RESEARCH.md` for the phase. This context is bundled into a structured prompt so ultraplan has everything it needs without you copying anything manually.
+
+3. **Return-path instructions** — Before launching ultraplan, GSD prints the import command to your terminal so it's visible in your scroll-back buffer after the browser session ends:
+ ```
+ When done: /gsd-import --from
+ ```
+
+4. **Ultraplan launches** — The `/ultraplan` command hands off to the browser. Use the outline sidebar and inline comments to review and refine the draft.
+
+5. **Save the plan** — When satisfied, click **Cancel** in Claude Code. Claude Code saves the plan to a local file and returns you to the terminal.
+
+6. **Import back into GSD** — Run the import command that was printed in step 3:
+ ```bash
+ /gsd-import --from /path/to/saved-plan.md
+ ```
+ This runs conflict detection against `PROJECT.md`, converts the plan to GSD format, validates it with `gsd-plan-checker`, updates `ROADMAP.md`, and commits — the same path as any external plan import.
+
+### What gets produced
+
+| Step | Output |
+|------|--------|
+| After ultraplan | External plan file (saved by Claude Code) |
+| After `/gsd-import` | `{phase}-{N}-PLAN.md` in `.planning/phases/` |
+
+### What this command does NOT do
+
+- Write `PLAN.md` files directly — all writes go through `/gsd-import`
+- Replace `/gsd-plan-phase` — local planning is unaffected and remains the default
+- Run research agents — if you need `RESEARCH.md` first, run `/gsd-plan-phase --skip-verify` or a research-only pass before using this command
+
+### Troubleshooting
+
+**"ultraplan is not available in this runtime"**
+You're running GSD outside of Claude Code. Switch to a Claude Code terminal session, or use `/gsd-plan-phase` instead.
+
+**Ultraplan browser session never opened**
+Check your Claude Code version: `claude --version`. Requires v2.1.91+. Update with `claude update`.
+
+**`/gsd-import` reports conflicts**
+Ultraplan may have proposed something that contradicts a decision in `PROJECT.md`. The import step will prompt you to resolve each conflict before writing anything.
+
+**Plan checker fails after import**
+The imported plan has structural issues. Review the checker output, edit the saved file to fix them, and re-run `/gsd-import --from `.
+
+### Related commands
+
+- [`/gsd-plan-phase`](COMMANDS.md#gsd-plan-phase) — standard local planning (stable, all runtimes)
+- [`/gsd-import`](COMMANDS.md#gsd-import) — import any external plan file into GSD
diff --git a/docs/superpowers/specs/2026-04-17-ultraplan-phase-design.md b/docs/superpowers/specs/2026-04-17-ultraplan-phase-design.md
new file mode 100644
index 00000000..277f7c2a
--- /dev/null
+++ b/docs/superpowers/specs/2026-04-17-ultraplan-phase-design.md
@@ -0,0 +1,160 @@
+# Design: /gsd-ultraplan-phase [BETA]
+
+**Date:** 2026-04-17
+**Status:** Approved — ready for implementation
+**Branch:** Beta feature, isolated from core plan pipeline
+
+---
+
+## Summary
+
+A standalone `/gsd-ultraplan-phase` command that offloads GSD's research+plan phase to Claude Code's ultraplan cloud infrastructure. The plan drafts remotely while the terminal stays free, is reviewed in a rich browser UI with inline comments, then imports back into GSD via the existing `/gsd-import --from` workflow.
+
+This is a **beta of a beta**: ultraplan itself is in research preview, so this command is intentionally isolated from the core `/gsd-plan-phase` pipeline to prevent breakage if ultraplan changes.
+
+---
+
+## Scope
+
+**In scope:**
+- New `commands/gsd/ultraplan-phase.md` command
+- New `get-shit-done/workflows/ultraplan-phase.md` workflow
+- Runtime gate: Claude Code only (checks `$CLAUDE_CODE_VERSION`)
+- Builds structured ultraplan prompt from GSD phase context
+- Return path via existing `/gsd-import --from ` (no new import logic)
+
+**Out of scope (future):**
+- Parallel next-phase planning during `/gsd-execute-phase`
+- Auto-detection of ultraplan's saved file path
+- Text mode / non-interactive fallback
+
+---
+
+## Architecture
+
+```text
+/gsd-ultraplan-phase [phase]
+ │
+ ├─ Runtime gate (CLAUDE_CODE_VERSION check)
+ ├─ gsd-sdk query init.plan-phase → phase context
+ ├─ Build ultraplan prompt (phase scope + requirements + research)
+ ├─ Display return-path instructions card
+ └─ /ultraplan
+ │
+ [cloud: user reviews, comments, revises]
+ │
+ [browser: Approve → teleport back to terminal]
+ │
+ [terminal: Cancel → saves to file]
+ │
+ /gsd-import --from
+ │
+ ├─ Conflict detection
+ ├─ GSD format conversion
+ ├─ gsd-plan-checker validation
+ ├─ ROADMAP.md update
+ └─ Commit
+```
+
+---
+
+## Command File (`commands/gsd/ultraplan-phase.md`)
+
+Frontmatter:
+- `name: gsd:ultraplan-phase`
+- `description:` includes `[BETA]` marker
+- `argument-hint: [phase-number]`
+- `allowed-tools:` Read, Bash, Glob, Grep
+- References: `@~/.claude/get-shit-done/workflows/ultraplan-phase.md`, ui-brand
+
+---
+
+## Workflow Steps
+
+### 1. Banner
+Display GSD `► ULTRAPLAN PHASE [BETA]` banner.
+
+### 2. Runtime Gate
+```bash
+echo $CLAUDE_CODE_VERSION
+```
+If unset/empty: print error and exit.
+```text
+⚠ /gsd-ultraplan-phase requires Claude Code.
+ /ultraplan is not available in this runtime.
+ Use /gsd-plan-phase for local planning.
+```
+
+### 3. Initialize
+```bash
+INIT=$(gsd-sdk query init.plan-phase "$PHASE")
+```
+Parse: phase number, phase name, phase slug, phase dir, roadmap path, requirements path, research path.
+
+If no `.planning/` exists: error — run `/gsd-new-project` first.
+
+### 4. Build Ultraplan Prompt
+Construct a prompt that includes:
+- Phase identification: `"Plan phase {N}: {phase name}"`
+- Phase scope block from ROADMAP.md
+- Requirements summary (if REQUIREMENTS.md exists)
+- Research summary (if RESEARCH.md exists — reduces cloud redundancy)
+- Output format instruction: produce a GSD PLAN.md with standard frontmatter fields
+
+### 5. Return-Path Instructions Card
+Display prominently before triggering (visible in terminal scroll-back):
+```text
+When ◆ ultraplan ready:
+ 1. Open the session link in your browser
+ 2. Review, comment, and revise the plan
+ 3. When satisfied: "Approve plan and teleport back to terminal"
+ 4. At the terminal dialog: choose Cancel (saves plan to file)
+ 5. Run: /gsd-import --from
+```
+
+### 6. Trigger Ultraplan
+```text
+/ultraplan
+```
+
+---
+
+## Return Path
+
+No new code needed. The user runs `/gsd-import --from ` after ultraplan saves the file. That workflow handles everything: conflict detection, GSD format conversion, plan-checker, ROADMAP update, commit.
+
+---
+
+## Runtime Detection
+
+`$CLAUDE_CODE_VERSION` is set by Claude Code in the shell environment. If unset, the session is not Claude Code (Gemini CLI, Copilot, etc.) and `/ultraplan` does not exist.
+
+---
+
+## Pricing
+
+Ultraplan runs as a standard Claude Code on the web session. For Pro/Max subscribers this is included in the subscription — no extra usage billing (unlike ultrareview which bills $5–20/run). No cost gate needed.
+
+---
+
+## Beta Markers
+
+- `[BETA]` in command description
+- `⚠ BETA` in workflow banner
+- Comment in workflow noting ultraplan is in research preview
+
+---
+
+## Test Coverage
+
+`tests/ultraplan-phase.test.cjs` — structural assertions covering:
+- File existence (command + workflow)
+- Command frontmatter completeness (name, description with `[BETA]`, argument-hint)
+- Command references workflow
+- Workflow has runtime gate (`CLAUDE_CODE_VERSION`)
+- Workflow has beta warning
+- Workflow has init step (gsd-sdk query)
+- Workflow builds ultraplan prompt with phase context
+- Workflow triggers `/ultraplan`
+- Workflow has return-path instructions (Cancel path, `/gsd-import --from`)
+- Workflow does NOT directly implement plan writing (delegates to `/gsd-import`)
diff --git a/get-shit-done/workflows/sketch.md b/get-shit-done/workflows/sketch.md
index 8efbd543..72f8e1bc 100644
--- a/get-shit-done/workflows/sketch.md
+++ b/get-shit-done/workflows/sketch.md
@@ -53,7 +53,9 @@ COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
**Otherwise:**
-Before sketching anything, explore the design intent through conversation. Ask one question at a time using AskUserQuestion, with a paragraph of context and reasoning for each.
+**Text mode:** If TEXT_MODE is enabled (set in the banner step), replace AskUserQuestion calls with plain-text numbered lists — emit the options and ask the user to type the number of their choice.
+
+Before sketching anything, explore the design intent through conversation. Ask one question at a time — using AskUserQuestion in normal mode, or a plain-text numbered list if TEXT_MODE is active — with a paragraph of context and reasoning for each.
**Questions to cover (adapt to what the user has already shared):**
diff --git a/get-shit-done/workflows/ultraplan-phase.md b/get-shit-done/workflows/ultraplan-phase.md
new file mode 100644
index 00000000..f9fde052
--- /dev/null
+++ b/get-shit-done/workflows/ultraplan-phase.md
@@ -0,0 +1,189 @@
+# Ultraplan Phase Workflow [BETA]
+
+Offload GSD's plan phase to Claude Code's ultraplan cloud infrastructure.
+
+⚠ **BETA feature.** Ultraplan is in research preview and may change. This workflow is
+intentionally isolated from /gsd-plan-phase so upstream changes to ultraplan cannot
+affect the core planning pipeline.
+
+---
+
+
+
+Display the stage banner:
+
+```text
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+ GSD ► ULTRAPLAN PHASE ⚠ BETA
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+Ultraplan is in research preview (Claude Code v2.1.91+).
+Use /gsd-plan-phase for stable local planning.
+```
+
+
+
+---
+
+
+
+Check that the session is running inside Claude Code:
+
+```bash
+echo "$CLAUDE_CODE_VERSION"
+```
+
+If the output is empty or unset, display the following error and exit:
+
+```text
+╔══════════════════════════════════════════════════════════════╗
+║ RUNTIME ERROR ║
+╚══════════════════════════════════════════════════════════════╝
+
+/gsd-ultraplan-phase requires Claude Code.
+ultraplan is not available in this runtime.
+
+Use /gsd-plan-phase for local planning instead.
+```
+
+
+
+---
+
+
+
+Parse phase number from `$ARGUMENTS`. If no phase number is provided, detect the next
+unplanned phase from the roadmap (same logic as /gsd-plan-phase).
+
+Load GSD phase context:
+
+```bash
+INIT=$(gsd-sdk query init.plan-phase "$PHASE")
+if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
+```
+
+Parse JSON for: `phase_found`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`,
+`phase_dir`, `roadmap_path`, `requirements_path`, `research_path`, `planning_exists`.
+
+**If `planning_exists` is false:** Error and exit:
+
+```text
+No .planning directory found. Initialize the project first:
+
+/gsd-new-project
+```
+
+**If `phase_found` is false:** Error with the phase number provided and exit.
+
+Display detected phase:
+
+```text
+Phase {N}: {phase name}
+```
+
+
+
+---
+
+
+
+Build the ultraplan prompt from GSD context.
+
+1. Read the phase scope from ROADMAP.md — extract the goal, deliverables, and scope for
+ the target phase.
+
+2. Read REQUIREMENTS.md if it exists (`requirements_path` is not null) — extract a
+ concise summary (key requirements relevant to this phase, not the full document).
+
+3. Read RESEARCH.md if it exists (`research_path` is not null) — extract a concise
+ summary of technical findings. Including this reduces redundant cloud research.
+
+Construct the prompt:
+
+```text
+Plan phase {phase_number}: {phase_name}
+
+## Phase Scope (from ROADMAP.md)
+
+{phase scope block extracted from ROADMAP.md}
+
+## Requirements Context
+
+{requirements summary, or "No REQUIREMENTS.md found — infer from phase scope."}
+
+## Existing Research
+
+{research summary, or "No RESEARCH.md found — research from scratch."}
+
+## Output Format
+
+Produce a GSD PLAN.md with the following YAML frontmatter:
+
+---
+phase: "{padded_phase}-{phase_slug}"
+plan: "{padded_phase}-01"
+type: "feature"
+wave: 1
+depends_on: []
+files_modified: []
+autonomous: true
+must_haves:
+ truths: []
+ artifacts: []
+---
+
+Then a ## Plan section with numbered tasks. Each task should have:
+- A clear imperative title
+- Files to create or modify
+- Specific implementation steps
+
+Keep the plan focused and executable.
+```
+
+
+
+---
+
+
+
+Display the return-path instructions **before** triggering ultraplan so they are visible
+in the terminal scroll-back after ultraplan launches:
+
+```text
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+ WHEN THE PLAN IS READY — WHAT TO DO
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+When ◆ ultraplan ready appears in your terminal:
+
+ 1. Open the session link in your browser
+ 2. Review the plan — use inline comments and emoji reactions to give feedback
+ 3. Ask Claude to revise until you're satisfied
+ 4. Click "Approve plan and teleport back to terminal"
+ 5. At the terminal dialog, choose Cancel ← saves the plan to a file
+ 6. Note the file path Claude prints
+ 7. Run: /gsd-import --from
+
+/gsd-import will run conflict detection, convert to GSD format,
+validate via plan-checker, update ROADMAP.md, and commit.
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+Launching ultraplan for Phase {N}: {phase_name}...
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+```
+
+
+
+---
+
+
+
+Trigger ultraplan with the constructed prompt:
+
+```text
+/ultraplan {constructed prompt from build_prompt step}
+```
+
+Your terminal will show a `◇ ultraplan` status indicator while the remote session works.
+Use `/tasks` to open the detail view with the session link, agent activity, and a stop action.
+
+
diff --git a/tests/read-guard.test.cjs b/tests/read-guard.test.cjs
index 5fa54578..182fe011 100644
--- a/tests/read-guard.test.cjs
+++ b/tests/read-guard.test.cjs
@@ -28,7 +28,7 @@ const HOOK_PATH = path.join(__dirname, '..', 'hooks', 'gsd-read-guard.js');
*/
function runHook(payload, envOverrides = {}) {
const input = JSON.stringify(payload);
- // Sanitize CLAUDE_SESSION_ID so positive-path tests work inside Claude Code sessions
+ // Sanitize Claude Code env vars so positive-path tests work inside Claude Code sessions
const env = { ...process.env, CLAUDE_SESSION_ID: '', CLAUDECODE: '', ...envOverrides };
try {
const stdout = execFileSync(process.execPath, [HOOK_PATH], {
diff --git a/tests/ultraplan-phase.test.cjs b/tests/ultraplan-phase.test.cjs
new file mode 100644
index 00000000..660591e0
--- /dev/null
+++ b/tests/ultraplan-phase.test.cjs
@@ -0,0 +1,189 @@
+/**
+ * /gsd-ultraplan-phase [BETA] Tests
+ *
+ * Structural assertions for the ultraplan-phase command and workflow files.
+ * This command offloads GSD plan phase to Claude Code's ultraplan cloud infrastructure.
+ */
+
+'use strict';
+
+const { describe, test } = require('node:test');
+const assert = require('node:assert/strict');
+const fs = require('fs');
+const path = require('path');
+
+const CMD_PATH = path.join(__dirname, '..', 'commands', 'gsd', 'ultraplan-phase.md');
+const WF_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'ultraplan-phase.md');
+
+// ─── File Existence ────────────────────────────────────────────────────────────
+
+describe('ultraplan-phase file existence', () => {
+ test('command file exists', () => {
+ assert.ok(fs.existsSync(CMD_PATH), 'commands/gsd/ultraplan-phase.md should exist');
+ });
+
+ test('workflow file exists', () => {
+ assert.ok(fs.existsSync(WF_PATH), 'get-shit-done/workflows/ultraplan-phase.md should exist');
+ });
+});
+
+// ─── Command Frontmatter ───────────────────────────────────────────────────────
+
+describe('ultraplan-phase command frontmatter', () => {
+ const content = fs.readFileSync(CMD_PATH, 'utf-8');
+
+ test('has correct name field', () => {
+ assert.match(content, /^name:\s*gsd:ultraplan-phase$/m);
+ });
+
+ test('description marks feature as BETA', () => {
+ assert.match(content, /^description:.*\[BETA\]/m);
+ });
+
+ test('has argument-hint', () => {
+ assert.match(content, /^argument-hint:/m);
+ });
+});
+
+// ─── Command References ────────────────────────────────────────────────────────
+
+describe('ultraplan-phase command references', () => {
+ const content = fs.readFileSync(CMD_PATH, 'utf-8');
+
+ test('references the ultraplan-phase workflow', () => {
+ assert.ok(
+ content.includes('@~/.claude/get-shit-done/workflows/ultraplan-phase.md'),
+ 'command should reference ultraplan-phase workflow'
+ );
+ });
+
+ test('references ui-brand', () => {
+ assert.ok(content.includes('ui-brand'), 'command should reference ui-brand');
+ });
+});
+
+// ─── Workflow: Beta Marker ─────────────────────────────────────────────────────
+
+describe('ultraplan-phase workflow beta marker', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('workflow displays a BETA warning', () => {
+ assert.ok(content.includes('BETA') || content.includes('beta'), 'workflow should display a BETA warning');
+ });
+
+ test('workflow notes ultraplan is in research preview', () => {
+ assert.ok(content.includes('research preview') || content.includes('preview'), 'workflow should note ultraplan is in research preview');
+ });
+});
+
+// ─── Workflow: Runtime Gate ────────────────────────────────────────────────────
+
+describe('ultraplan-phase workflow runtime gate', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('checks CLAUDE_CODE_VERSION to detect Claude Code runtime', () => {
+ assert.ok(content.includes('CLAUDE_CODE_VERSION'), 'workflow must gate on CLAUDE_CODE_VERSION env var');
+ });
+
+ test('error message references /gsd-plan-phase as local alternative', () => {
+ assert.ok(
+ content.includes('gsd-plan-phase'),
+ 'error message should direct users to /gsd-plan-phase as the local alternative'
+ );
+ });
+});
+
+// ─── Workflow: Initialization ──────────────────────────────────────────────────
+
+describe('ultraplan-phase workflow initialization', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('loads GSD phase context via gsd-sdk query init.plan-phase', () => {
+ assert.ok(content.includes('gsd-sdk query init.plan-phase'), 'workflow must load phase context via gsd-sdk query init.plan-phase');
+ });
+
+ test('handles missing .planning directory', () => {
+ assert.ok(
+ content.includes('gsd-new-project') || content.includes('/gsd-new-project'),
+ 'workflow should direct user to /gsd-new-project when .planning is missing'
+ );
+ });
+});
+
+// ─── Workflow: Ultraplan Prompt ────────────────────────────────────────────────
+
+describe('ultraplan-phase workflow prompt construction', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('includes phase scope from ROADMAP in ultraplan prompt', () => {
+ assert.ok(
+ content.includes('ROADMAP') || content.includes('phase scope') || content.includes('phase_name'),
+ 'workflow should include phase scope from ROADMAP.md in the ultraplan prompt'
+ );
+ });
+
+ test('includes REQUIREMENTS context in ultraplan prompt', () => {
+ assert.ok(content.includes('REQUIREMENTS'), 'workflow should include requirements context in the ultraplan prompt');
+ });
+
+ test('includes existing RESEARCH when available', () => {
+ assert.ok(
+ content.includes('RESEARCH') || content.includes('research_path'),
+ 'workflow should include existing research in the ultraplan prompt'
+ );
+ });
+});
+
+// ─── Workflow: Ultraplan Trigger ───────────────────────────────────────────────
+
+describe('ultraplan-phase workflow ultraplan trigger', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('triggers /ultraplan command', () => {
+ assert.ok(content.includes('/ultraplan'), 'workflow must trigger /ultraplan');
+ });
+});
+
+// ─── Workflow: Return Path Instructions ───────────────────────────────────────
+
+describe('ultraplan-phase workflow return path', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('instructs user to choose Cancel to save plan to file', () => {
+ assert.ok(content.includes('Cancel'), 'workflow must instruct user to choose Cancel to save the plan to a file');
+ });
+
+ test('directs user to run /gsd-import --from after ultraplan completes', () => {
+ assert.ok(content.includes('gsd-import'), 'workflow must direct user to run /gsd-import --from with the saved file path');
+ });
+
+ test('mentions the --from flag for gsd-import', () => {
+ assert.ok(content.includes('--from'), 'workflow should reference /gsd-import --from ');
+ });
+
+ test('return-path instructions appear before the /ultraplan trigger', () => {
+ const ultraplanTriggerIndex = content.indexOf('/ultraplan');
+ const importIndex = content.indexOf('gsd-import');
+ assert.ok(
+ importIndex < ultraplanTriggerIndex,
+ 'return-path instructions (gsd-import) must appear before /ultraplan trigger so they are visible in scroll-back'
+ );
+ });
+});
+
+// ─── Workflow: Isolation from Core Pipeline ────────────────────────────────────
+
+describe('ultraplan-phase workflow isolation', () => {
+ const content = fs.readFileSync(WF_PATH, 'utf-8');
+
+ test('does NOT directly write PLAN.md files', () => {
+ assert.ok(
+ !content.includes('write PLAN.md') && !content.includes('Write(\'.planning'),
+ 'workflow must NOT directly write PLAN.md — delegates to /gsd-import --from'
+ );
+ });
+
+ test('does NOT reference ultrareview', () => {
+ assert.ok(!content.includes('ultrareview'), 'workflow must not reference ultrareview');
+ });
+});