diff --git a/.gitignore b/.gitignore
index 09c32cc46..9677048fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -90,3 +90,4 @@ bun.lock
.direnv/
.envrc
.serena/
+repowise.db
diff --git a/gsd-orchestrator/SKILL.md b/gsd-orchestrator/SKILL.md
deleted file mode 100644
index 1475301ab..000000000
--- a/gsd-orchestrator/SKILL.md
+++ /dev/null
@@ -1,215 +0,0 @@
----
-name: sf-orchestrator
-description: >
- Build software products autonomously via SF headless mode. Handles the full
- lifecycle: write a spec, launch a build, poll for completion, handle blockers,
- track costs, and verify the result. Use when asked to "build something",
- "create a project", "run sf", "check build status", or any task that
- requires autonomous software development via subprocess.
-metadata:
- openclaw:
- requires:
- bins: [sf]
- install:
- kind: node
- package: sf-run
- bins: [sf]
----
-
-
-You are an autonomous agent that builds software by orchestrating SF as a subprocess.
-SF is a headless CLI that plans, codes, tests, and ships software from a spec.
-You control it via shell commands, exit codes, and JSON output — no SDK, no RPC.
-
-
-
-SF headless is a subprocess you launch and monitor. Think of it like a junior developer
-you hand a spec to:
-
-1. You write the spec (what to build)
-2. You launch the build (`sf headless ... new-milestone --context spec.md --auto`)
-3. You wait for it to finish (exit code tells you the outcome)
-4. You check the result (query state, inspect files, verify deliverables)
-5. If blocked, you intervene (steer, supply answers, or escalate)
-
-The subprocess handles all planning, coding, testing, and git commits internally.
-You never write application code yourself — SF does that.
-
-
-
-- **Flags before command.** `sf headless [--flags] [command] [args]`. Flags after the command are ignored.
-- **Redirect stderr.** JSON output goes to stdout. Progress goes to stderr. Always `2>/dev/null` when parsing JSON.
-- **Check exit codes.** 0=success, 1=error, 10=blocked (needs you), 11=cancelled.
-- **Use `query` to poll.** Instant (~50ms), no LLM cost. Use it between steps, not `auto` for status.
-- **Budget awareness.** Track `cost.total` from query results. Set limits before launching long runs.
-- **One project directory per build.** Each SF project needs its own directory with a `.sf/` folder.
-
-
-
-Route based on what you need to do:
-
-**Build something from scratch:**
-Read `workflows/build-from-spec.md` — write spec, init directory, launch, monitor, verify.
-
-**Check on a running or completed build:**
-Read `workflows/monitor-and-poll.md` — query state, interpret phases, handle blockers.
-
-**Execute with fine-grained control:**
-Read `workflows/step-by-step.md` — run one unit at a time with decision points.
-
-**Understand the JSON output:**
-Read `references/json-result.md` — field reference for HeadlessJsonResult.
-
-**Pre-supply answers or secrets:**
-Read `references/answer-injection.md` — answer file schema and injection mechanism.
-
-**Look up a specific command:**
-Read `references/commands.md` — full command reference with flags and examples.
-
-
-
-
-**Launch a full build (spec to working code):**
-```bash
-mkdir -p /tmp/my-project && cd /tmp/my-project && git init
-cat > spec.md << 'EOF'
-# Your Product Spec Here
-Build a ...
-EOF
-sf headless --output-format json --context spec.md new-milestone --auto 2>/dev/null
-```
-
-**Check project state (instant, free):**
-```bash
-cd /path/to/project
-sf headless query | jq '{phase: .state.phase, progress: .state.progress, cost: .cost.total}'
-```
-
-**Resume work on an existing project:**
-```bash
-cd /path/to/project
-sf headless --output-format json auto 2>/dev/null
-```
-
-**Run one step at a time:**
-```bash
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-echo "$RESULT" | jq '{status: .status, phase: .phase, cost: .cost.total}'
-```
-
-
-
-
-| Code | Meaning | Your action |
-|------|---------|-------------|
-| `0` | Success | Check deliverables, verify output, report completion |
-| `1` | Error or timeout | Inspect stderr, check `.sf/STATE.md`, retry or escalate |
-| `10` | Blocked | Query state for blocker details, steer around it or escalate to human |
-| `11` | Cancelled | Process was interrupted — resume with `--resume ` or restart |
-
-
-
-SF creates and manages all state in `.sf/`:
-```
-.sf/
- PROJECT.md # What this project is
- REQUIREMENTS.md # Capability contract
- DECISIONS.md # Architectural decisions (append-only)
- KNOWLEDGE.md # Persistent project knowledge (patterns, rules, lessons)
- STATE.md # Current phase and next action
- milestones/
- M001-xxxxx/
- M001-xxxxx-CONTEXT.md # Scope, constraints, assumptions
- M001-xxxxx-ROADMAP.md # Slices with checkboxes
- M001-xxxxx-SUMMARY.md # Completion summary
- slices/S01/
- S01-PLAN.md # Tasks
- S01-SUMMARY.md # Slice summary
- tasks/
- T01-PLAN.md # Individual task spec
- T01-SUMMARY.md # Task completion summary
-```
-
-State is derived from files on disk — checkboxes in ROADMAP.md and PLAN.md are the source of truth for completion. You never need to edit these files. SF manages them. But you can read them to understand progress.
-
-
-
-| Flag | Description |
-|------|-------------|
-| `--output-format ` | `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) |
-| `--json` | Alias for `--output-format stream-json` — JSONL event stream to stdout |
-| `--bare` | Skip CLAUDE.md, AGENTS.md, user settings, user skills. Use for CI/ecosystem runs. |
-| `--resume ` | Resume a prior headless session by its session ID |
-| `--timeout N` | Overall timeout in ms (default: 300000, use 0 to disable) |
-| `--model ID` | Override LLM model |
-| `--supervised` | Forward interactive UI requests to orchestrator via stdout/stdin |
-| `--response-timeout N` | Timeout (ms) for orchestrator response in supervised mode (default: 30000) |
-| `--answers ` | Pre-supply answers and secrets from JSON file |
-| `--events ` | Filter JSONL to specific event types (comma-separated, implies `--json`) |
-| `--verbose` | Show tool calls in progress output |
-| `--context ` | Spec file path for `new-milestone` (use `-` for stdin) |
-| `--context-text ` | Inline spec text for `new-milestone` |
-| `--auto` | Chain into auto-mode after `new-milestone` |
-
-
-
-Pre-supply answers and secrets for fully autonomous runs:
-
-```bash
-sf headless --answers answers.json --output-format json auto 2>/dev/null
-```
-
-```json
-{
- "questions": { "question_id": "selected_option" },
- "secrets": { "API_KEY": "sk-..." },
- "defaults": { "strategy": "first_option" }
-}
-```
-
-- **questions** — question ID to answer (string for single-select, string[] for multi-select)
-- **secrets** — env var to value, injected into child process environment
-- **defaults.strategy** — `"first_option"` (default) or `"cancel"` for unmatched questions
-
-See `references/answer-injection.md` for the full mechanism.
-
-
-
-For real-time monitoring, use JSONL event streaming:
-
-```bash
-sf headless --json auto 2>/dev/null | while read -r line; do
- TYPE=$(echo "$line" | jq -r '.type')
- case "$TYPE" in
- tool_execution_start) echo "Tool: $(echo "$line" | jq -r '.toolName')" ;;
- extension_ui_request) echo "SF: $(echo "$line" | jq -r '.message // .title // empty')" ;;
- agent_end) echo "Session ended" ;;
- esac
-done
-```
-
-Filter to specific events: `--events agent_end,execution_complete,extension_ui_request`
-
-Available types: `agent_start`, `agent_end`, `tool_execution_start`, `tool_execution_end`,
-`tool_execution_update`, `extension_ui_request`, `message_start`, `message_end`,
-`message_update`, `turn_start`, `turn_end`, `cost_update`, `execution_complete`.
-
-
-
-| Command | Purpose |
-|---------|---------|
-| `auto` | Run all queued units until milestone complete or blocked (default) |
-| `next` | Run exactly one unit, then exit |
-| `query` | Instant JSON snapshot — state, next dispatch, costs (no LLM, ~50ms) |
-| `new-milestone` | Create milestone from spec file |
-| `dispatch ` | Force specific phase (research, plan, execute, complete, reassess, uat, replan) |
-| `stop` / `pause` | Control auto-mode |
-| `steer ` | Hard-steer plan mid-execution |
-| `skip` / `undo` | Unit control |
-| `queue` | Queue/reorder milestones |
-| `history` | View execution history |
-| `doctor` | Health check + auto-fix |
-| `knowledge ` | Add persistent project knowledge |
-
-See `references/commands.md` for the complete reference.
-
diff --git a/gsd-orchestrator/references/answer-injection.md b/gsd-orchestrator/references/answer-injection.md
deleted file mode 100644
index 8032350bd..000000000
--- a/gsd-orchestrator/references/answer-injection.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Answer Injection
-
-Pre-supply answers and secrets to eliminate interactive prompts during headless execution.
-
-## Usage
-
-```bash
-sf headless --answers answers.json auto
-sf headless --answers answers.json new-milestone --context spec.md --auto
-```
-
-The `--answers` flag takes a path to a JSON file containing pre-supplied answers and secrets.
-
-## Answer File Schema
-
-```json
-{
- "questions": {
- "question_id": "selected_option_label",
- "multi_select_question": ["option_a", "option_b"]
- },
- "secrets": {
- "API_KEY": "sk-...",
- "DATABASE_URL": "postgres://..."
- },
- "defaults": {
- "strategy": "first_option"
- }
-}
-```
-
-### Fields
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `questions` | `Record` | Map question ID → answer. String for single-select, string array for multi-select. |
-| `secrets` | `Record` | Map env var name → value. Injected into child process environment variables. |
-| `defaults.strategy` | `"first_option" \| "cancel"` | Fallback for unmatched questions. Default: `"first_option"`. |
-
-## How Secrets Work
-
-Secrets are injected as environment variables into the SF child process:
-
-1. The orchestrator passes the answer file via `--answers`
-2. SF reads the file and sets secret values as env vars in the child process
-3. When `secure_env_collect` runs inside the agent, it finds the keys already in `process.env`
-4. The tool skips the interactive prompt and reports the keys as "already configured"
-
-Secrets are never logged or included in event streams.
-
-## How Question Matching Works
-
-Two-phase correlation:
-
-1. **Observe** — SF monitors `tool_execution_start` events for `ask_user_questions` to extract question metadata (ID, options, allowMultiple)
-2. **Match** — Subsequent `extension_ui_request` events are correlated to the metadata and responded to with the pre-supplied answer
-
-Handles out-of-order events (extension_ui_request can arrive before tool_execution_start) via a deferred processing queue with 500ms timeout.
-
-## Coexistence with `--supervised`
-
-Both `--answers` and `--supervised` can be active simultaneously. Priority order:
-
-1. Answer injector tries first
-2. If no answer found, supervised mode forwards to the orchestrator
-3. If no orchestrator response within `--response-timeout`, the auto-responder kicks in
-
-## Without Answer Injection
-
-Headless mode has built-in auto-responders for all prompt types:
-
-| Prompt Type | Default Behavior |
-|-------------|-----------------|
-| Select | Picks first option |
-| Confirm | Auto-confirms |
-| Input | Empty string |
-| Editor | Returns prefill or empty |
-
-Answer injection overrides these defaults with specific answers when precision matters.
-
-## Diagnostics
-
-The injector tracks statistics printed in the session summary:
-
-| Stat | Description |
-|------|-------------|
-| `questionsAnswered` | Questions resolved from the answer file |
-| `questionsDefaulted` | Questions handled by the default strategy |
-| `secretsProvided` | Number of secrets injected |
-
-Unused question IDs and secret keys are warned about at exit.
-
-## Example: Orchestrator with Answers
-
-```bash
-# Create answer file
-cat > answers.json << 'EOF'
-{
- "questions": {
- "test_framework": "vitest",
- "package_manager": "pnpm"
- },
- "secrets": {
- "OPENAI_API_KEY": "sk-...",
- "DATABASE_URL": "postgres://localhost:5432/mydb"
- },
- "defaults": {
- "strategy": "first_option"
- }
-}
-EOF
-
-# Run with pre-supplied answers
-sf headless --answers answers.json --output-format json auto 2>/dev/null
-
-# Parse result
-RESULT=$(sf headless --answers answers.json --output-format json next 2>/dev/null)
-echo "$RESULT" | jq '{status: .status, cost: .cost.total}'
-```
diff --git a/gsd-orchestrator/references/commands.md b/gsd-orchestrator/references/commands.md
deleted file mode 100644
index a92b6e294..000000000
--- a/gsd-orchestrator/references/commands.md
+++ /dev/null
@@ -1,210 +0,0 @@
-# SF Commands Reference
-
-All commands run as subprocesses via `sf headless [flags] [command] [args...]`.
-
-## Global Flags
-
-These flags apply to any `sf headless` invocation:
-
-| Flag | Description |
-|------|-------------|
-| `--output-format ` | `text` (default), `json` (structured result), `stream-json` (JSONL) |
-| `--json` | Alias for `--output-format stream-json` |
-| `--bare` | Minimal context: skip CLAUDE.md, AGENTS.md, user settings, user skills |
-| `--resume ` | Resume a prior headless session by ID |
-| `--timeout N` | Overall timeout in ms (default: 300000) |
-| `--model ID` | Override LLM model |
-| `--supervised` | Forward interactive UI requests to orchestrator via stdout/stdin |
-| `--response-timeout N` | Timeout for orchestrator response in supervised mode (default: 30000ms) |
-| `--answers ` | Pre-supply answers and secrets from JSON file |
-| `--events ` | Filter JSONL output to specific event types (comma-separated, implies `--json`) |
-| `--verbose` | Show tool calls in progress output |
-
-## Exit Codes
-
-| Code | Meaning | When |
-|------|---------|------|
-| `0` | Success | Unit/milestone completed normally |
-| `1` | Error or timeout | Runtime error, LLM failure, or `--timeout` exceeded |
-| `10` | Blocked | Execution hit a blocker requiring human intervention |
-| `11` | Cancelled | User or orchestrator cancelled the operation |
-
-## Workflow Commands
-
-### `auto` (default)
-
-Autonomous mode — loop through all pending units until milestone complete or blocked.
-
-```bash
-sf headless --output-format json auto
-```
-
-### `next`
-
-Step mode — execute exactly one unit (task/slice/milestone step), then exit. Recommended for orchestrators that need decision points between steps.
-
-```bash
-sf headless --output-format json next
-```
-
-### `new-milestone`
-
-Create a milestone from a specification document.
-
-```bash
-sf headless new-milestone --context spec.md
-sf headless new-milestone --context spec.md --auto
-sf headless new-milestone --context-text "Build a REST API" --auto
-cat spec.md | sf headless new-milestone --context - --auto
-```
-
-Extra flags:
-- `--context ` — path to spec/PRD file (use `-` for stdin)
-- `--context-text ` — inline specification text
-- `--auto` — start auto-mode after milestone creation
-
-### `dispatch `
-
-Force-route to a specific phase, bypassing normal state-machine routing.
-
-```bash
-sf headless dispatch research
-sf headless dispatch plan
-sf headless dispatch execute
-sf headless dispatch complete
-sf headless dispatch reassess
-sf headless dispatch uat
-sf headless dispatch replan
-```
-
-### `discuss`
-
-Start guided milestone/slice discussion.
-
-```bash
-sf headless discuss
-```
-
-### `stop`
-
-Stop auto-mode gracefully.
-
-```bash
-sf headless stop
-```
-
-### `pause`
-
-Pause auto-mode (preserves state, resumable).
-
-```bash
-sf headless pause
-```
-
-## State Inspection
-
-### `query`
-
-**Instant JSON snapshot** — state, next dispatch, parallel costs. No LLM, ~50ms. The recommended way for orchestrators to inspect state.
-
-```bash
-sf headless query
-sf headless query | jq '.state.phase'
-sf headless query | jq '.next'
-sf headless query | jq '.cost.total'
-```
-
-### `status`
-
-Progress dashboard (TUI overlay — useful interactively, not for parsing).
-
-```bash
-sf headless status
-```
-
-### `history`
-
-Execution history. Supports `--cost`, `--phase`, `--model`, and `limit` arguments.
-
-```bash
-sf headless history
-```
-
-## Unit Control
-
-### `skip`
-
-Prevent a unit from auto-mode dispatch.
-
-```bash
-sf headless skip
-```
-
-### `undo`
-
-Revert last completed unit. Use `--force` to bypass confirmation.
-
-```bash
-sf headless undo
-sf headless undo --force
-```
-
-### `steer `
-
-Hard-steer plan documents during execution. Useful for mid-course corrections.
-
-```bash
-sf headless steer "Skip the blocked dependency, use mock instead"
-```
-
-### `queue`
-
-Queue and reorder future milestones.
-
-```bash
-sf headless queue
-```
-
-## Configuration & Health
-
-### `doctor`
-
-Runtime health checks with auto-fix.
-
-```bash
-sf headless doctor
-```
-
-### `prefs`
-
-Manage preferences (global/project/status/wizard/setup).
-
-```bash
-sf headless prefs
-```
-
-### `knowledge `
-
-Add persistent project knowledge.
-
-```bash
-sf headless knowledge "Always use UTC timestamps in API responses"
-```
-
-## Phases
-
-SF workflows progress through these phases:
-
-```
-pre-planning → needs-discussion → discussing → researching → planning →
-executing → verifying → summarizing → advancing → validating-milestone →
-completing-milestone → complete
-```
-
-Special phases: `paused`, `blocked`, `replanning-slice`
-
-## Hierarchy
-
-- **Milestone**: Shippable version (4–10 slices, 1–4 weeks)
-- **Slice**: One demoable vertical capability (1–7 tasks, 1–3 days)
-- **Task**: One context-window-sized unit of work (one session)
diff --git a/gsd-orchestrator/references/json-result.md b/gsd-orchestrator/references/json-result.md
deleted file mode 100644
index 04adf33ce..000000000
--- a/gsd-orchestrator/references/json-result.md
+++ /dev/null
@@ -1,162 +0,0 @@
-# HeadlessJsonResult Reference
-
-When using `--output-format json`, SF collects events silently and emits a single `HeadlessJsonResult` JSON object to stdout at process exit. This is the structured result for orchestrator decision-making.
-
-## Obtaining the Result
-
-```bash
-# Capture the JSON result
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-EXIT=$?
-
-# Parse fields with jq
-echo "$RESULT" | jq '.status'
-echo "$RESULT" | jq '.cost.total'
-echo "$RESULT" | jq '.nextAction'
-```
-
-**Important:** Progress text goes to stderr. The JSON result goes to stdout. Redirect stderr to `/dev/null` when parsing stdout.
-
-## Field Reference
-
-### Top-Level Fields
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `status` | `"success" \| "error" \| "blocked" \| "cancelled" \| "timeout"` | Final session status. Maps directly to exit codes. |
-| `exitCode` | `number` | Process exit code: `0` (success), `1` (error/timeout), `10` (blocked), `11` (cancelled). |
-| `sessionId` | `string \| undefined` | Session identifier. Pass to `--resume ` to continue this session. |
-| `duration` | `number` | Session wall-clock duration in milliseconds. |
-| `cost` | `CostObject` | Token usage and cost breakdown. See below. |
-| `toolCalls` | `number` | Total number of tool calls made during the session. |
-| `events` | `number` | Total number of events processed during the session. |
-| `milestone` | `string \| undefined` | Active milestone ID (e.g. `"M001"`). |
-| `phase` | `string \| undefined` | Current SF phase at session end (e.g. `"executing"`, `"blocked"`, `"complete"`). |
-| `nextAction` | `string \| undefined` | Recommended next action from the state machine (e.g. `"dispatch"`, `"complete"`). |
-| `artifacts` | `string[] \| undefined` | Paths to artifacts created or modified during the session. |
-| `commits` | `string[] \| undefined` | Git commit SHAs created during the session. |
-
-### Status → Exit Code Mapping
-
-| Status | Exit Code | Constant | Meaning |
-|--------|-----------|----------|---------|
-| `success` | `0` | `EXIT_SUCCESS` | Unit or milestone completed successfully |
-| `error` | `1` | `EXIT_ERROR` | Runtime error or LLM failure |
-| `timeout` | `1` | `EXIT_ERROR` | `--timeout` deadline exceeded |
-| `blocked` | `10` | `EXIT_BLOCKED` | Execution blocked — needs human intervention |
-| `cancelled` | `11` | `EXIT_CANCELLED` | Cancelled by user or orchestrator |
-
-### Cost Object
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `cost.total` | `number` | Total cost in USD for the session. |
-| `cost.input_tokens` | `number` | Number of input tokens consumed. |
-| `cost.output_tokens` | `number` | Number of output tokens generated. |
-| `cost.cache_read_tokens` | `number` | Number of tokens served from prompt cache. |
-| `cost.cache_write_tokens` | `number` | Number of tokens written to prompt cache. |
-
-## Parsing Patterns
-
-### Decision-Making After Each Step
-
-```bash
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-EXIT=$?
-
-case $EXIT in
- 0)
- PHASE=$(echo "$RESULT" | jq -r '.phase')
- NEXT=$(echo "$RESULT" | jq -r '.nextAction')
- echo "Success — phase: $PHASE, next: $NEXT"
- ;;
- 1)
- STATUS=$(echo "$RESULT" | jq -r '.status')
- echo "Failed — status: $STATUS"
- ;;
- 10)
- echo "Blocked — needs intervention"
- sf headless query | jq '.state'
- ;;
- 11)
- echo "Cancelled"
- ;;
-esac
-```
-
-### Cost Tracking
-
-```bash
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-
-COST=$(echo "$RESULT" | jq -r '.cost.total')
-INPUT=$(echo "$RESULT" | jq -r '.cost.input_tokens')
-OUTPUT=$(echo "$RESULT" | jq -r '.cost.output_tokens')
-
-echo "Cost: \$$COST (${INPUT} in / ${OUTPUT} out)"
-```
-
-### Session Resumption
-
-```bash
-# First run — capture session ID
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-SESSION_ID=$(echo "$RESULT" | jq -r '.sessionId')
-
-# Resume the same session later
-sf headless --resume "$SESSION_ID" --output-format json next 2>/dev/null
-```
-
-### Artifact Collection
-
-```bash
-RESULT=$(sf headless --output-format json auto 2>/dev/null)
-
-# List files created/modified
-echo "$RESULT" | jq -r '.artifacts[]?'
-
-# List commits made
-echo "$RESULT" | jq -r '.commits[]?'
-```
-
-## Example Result
-
-```json
-{
- "status": "success",
- "exitCode": 0,
- "sessionId": "abc123def456",
- "duration": 45200,
- "cost": {
- "total": 0.42,
- "input_tokens": 15000,
- "output_tokens": 3500,
- "cache_read_tokens": 8000,
- "cache_write_tokens": 2000
- },
- "toolCalls": 12,
- "events": 87,
- "milestone": "M001",
- "phase": "executing",
- "nextAction": "dispatch",
- "artifacts": [
- ".sf/milestones/M001/slices/S01/tasks/T01-SUMMARY.md"
- ],
- "commits": [
- "a1b2c3d"
- ]
-}
-```
-
-## Combined with `query` for Full Picture
-
-The `HeadlessJsonResult` captures what happened during a session. Use `query` for the current project state:
-
-```bash
-# What happened in this step?
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-echo "$RESULT" | jq '{status, cost: .cost.total, phase}'
-
-# What's the overall project state now?
-sf headless query | jq '{phase: .state.phase, progress: .state.progress, totalCost: .cost.total}'
-```
diff --git a/gsd-orchestrator/templates/spec.md b/gsd-orchestrator/templates/spec.md
deleted file mode 100644
index 441880f39..000000000
--- a/gsd-orchestrator/templates/spec.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# [Product Name]
-
-## What
-[One paragraph: what this product does. Be concrete — "A CLI tool that converts CSV files to JSON" not "A data transformation solution".]
-
-## Requirements
-- [User can DO something specific and observable]
-- [User can DO another specific thing]
-- [System DOES something automatically]
-- [Error case: system handles X gracefully]
-
-## Technical Constraints
-- Language: [Node.js / Python / Go / Rust / etc.]
-- Framework: [Express / FastAPI / none / etc.]
-- External dependencies: [list APIs, databases, services]
-- Environment: [Node >= 22 / Python 3.12+ / etc.]
-
-## Out of Scope
-- [Explicit exclusion 1 — prevents scope creep]
-- [Explicit exclusion 2]
diff --git a/gsd-orchestrator/workflows/build-from-spec.md b/gsd-orchestrator/workflows/build-from-spec.md
deleted file mode 100644
index 9552fa7b0..000000000
--- a/gsd-orchestrator/workflows/build-from-spec.md
+++ /dev/null
@@ -1,184 +0,0 @@
-# Build From Spec
-
-End-to-end workflow: take a product idea or specification, produce working software.
-
-## Prerequisites
-
-- `sf` CLI installed (`npm install -g sf-run`)
-- A directory for the project (can be empty)
-- Git initialized in the directory
-
-## Process
-
-### Step 1: Prepare the project directory
-
-```bash
-PROJECT_DIR="/tmp/my-project-name"
-mkdir -p "$PROJECT_DIR"
-cd "$PROJECT_DIR"
-git init 2>/dev/null # SF needs a git repo
-```
-
-### Step 2: Write the spec file
-
-Write a spec file that describes what to build. More detail = better results.
-
-```bash
-cat > spec.md << 'SPEC'
-# Product Name
-
-## What
-[Concrete description of what to build]
-
-## Requirements
-- [Specific, testable requirement 1]
-- [Specific, testable requirement 2]
-- [Specific, testable requirement 3]
-
-## Technical Constraints
-- [Language, framework, or platform requirements]
-- [External services or APIs involved]
-- [Performance or security requirements]
-
-## Out of Scope
-- [Things explicitly NOT included]
-SPEC
-```
-
-**Spec quality matters.** Vague specs produce vague results. Include:
-- What the user can DO when it's done (not what code to write)
-- Technical constraints (language, framework, Node version)
-- What's out of scope (prevents scope creep)
-
-### Step 3: Launch the build
-
-**Fire-and-forget (simplest — SF does everything):**
-```bash
-cd "$PROJECT_DIR"
-RESULT=$(sf headless --output-format json --timeout 0 --context spec.md new-milestone --auto 2>/dev/null)
-EXIT=$?
-```
-
-`--timeout 0` disables the timeout for long builds. `--auto` chains milestone creation into execution.
-
-**With budget limit:**
-```bash
-# Use step-by-step mode with budget checks instead of auto
-# See workflows/step-by-step.md
-```
-
-**For CI or ecosystem runs (no user config):**
-```bash
-RESULT=$(sf headless --bare --output-format json --timeout 0 --context spec.md new-milestone --auto 2>/dev/null)
-EXIT=$?
-```
-
-### Step 4: Handle the result
-
-```bash
-case $EXIT in
- 0)
- # Success — verify deliverables
- STATUS=$(echo "$RESULT" | jq -r '.status')
- COST=$(echo "$RESULT" | jq -r '.cost.total')
- COMMITS=$(echo "$RESULT" | jq -r '.commits | length')
- echo "Build complete: $STATUS, cost: \$$COST, commits: $COMMITS"
-
- # Inspect what was built
- sf headless query | jq '.state.progress'
-
- # Check the actual files
- ls -la "$PROJECT_DIR"
- ;;
- 1)
- # Error — inspect and decide
- echo "Build failed"
- echo "$RESULT" | jq '{status: .status, phase: .phase}'
-
- # Check state for details
- sf headless query | jq '.state'
- ;;
- 10)
- # Blocked — needs intervention
- echo "Build blocked — needs human input"
- sf headless query | jq '{phase: .state.phase, blockers: .state.blockers}'
-
- # Options: steer, supply answers, or escalate
- # See workflows/monitor-and-poll.md for blocker handling
- ;;
- 11)
- echo "Build was cancelled"
- ;;
-esac
-```
-
-### Step 5: Verify deliverables
-
-After a successful build, verify the output:
-
-```bash
-cd "$PROJECT_DIR"
-
-# Check project state
-sf headless query | jq '{
- phase: .state.phase,
- progress: .state.progress,
- cost: .cost.total
-}'
-
-# Check git log for what was built
-git log --oneline
-
-# Run the project's own tests if they exist
-[ -f package.json ] && npm test 2>/dev/null
-[ -f Makefile ] && make test 2>/dev/null
-```
-
-## Complete Example
-
-```bash
-# 1. Setup
-mkdir -p /tmp/todo-api && cd /tmp/todo-api && git init
-
-# 2. Write spec
-cat > spec.md << 'SPEC'
-# Todo API
-
-Build a REST API for managing todo items using Node.js and Express.
-
-## Requirements
-- GET /todos — list all todos
-- POST /todos — create a todo (title, completed)
-- PUT /todos/:id — update a todo
-- DELETE /todos/:id — delete a todo
-- Todos stored in-memory (no database)
-- Input validation with descriptive error messages
-- Health check endpoint at GET /health
-
-## Technical Constraints
-- Node.js with ESM modules
-- Express framework
-- No external database — in-memory array
-- Port configurable via PORT env var (default 3000)
-
-## Out of Scope
-- Authentication
-- Persistent storage
-- Frontend
-SPEC
-
-# 3. Launch
-RESULT=$(sf headless --output-format json --timeout 0 --context spec.md new-milestone --auto 2>/dev/null)
-EXIT=$?
-
-# 4. Report
-if [ $EXIT -eq 0 ]; then
- COST=$(echo "$RESULT" | jq -r '.cost.total')
- echo "Build complete (\$$COST)"
- echo "Files created:"
- find . -not -path './.sf/*' -not -path './.git/*' -type f
-else
- echo "Build failed (exit $EXIT)"
- echo "$RESULT" | jq .
-fi
-```
diff --git a/gsd-orchestrator/workflows/monitor-and-poll.md b/gsd-orchestrator/workflows/monitor-and-poll.md
deleted file mode 100644
index ffff137e4..000000000
--- a/gsd-orchestrator/workflows/monitor-and-poll.md
+++ /dev/null
@@ -1,187 +0,0 @@
-# Monitor and Poll
-
-Check status of a SF project, handle blockers, track costs, and decide next actions.
-
-## Checking Project State
-
-The `query` command is your primary monitoring tool. It's instant (~50ms), costs nothing (no LLM), and returns the full project snapshot.
-
-```bash
-cd /path/to/project
-sf headless query
-```
-
-### Key fields to inspect
-
-```bash
-# Overall status
-sf headless query | jq '{
- phase: .state.phase,
- milestone: .state.activeMilestone.id,
- slice: .state.activeSlice.id,
- task: .state.activeTask.id,
- progress: .state.progress,
- cost: .cost.total
-}'
-
-# What should happen next
-sf headless query | jq '.next'
-# Returns: { "action": "dispatch", "unitType": "execute-task", "unitId": "M001/S01/T01" }
-
-# Is it done?
-sf headless query | jq '.state.phase'
-# "complete" = done, "blocked" = needs you, anything else = in progress
-```
-
-### Phase meanings
-
-| Phase | Meaning | Your action |
-|-------|---------|-------------|
-| `pre-planning` | Milestone exists, no slices planned yet | Run `auto` or `next` |
-| `needs-discussion` | Ambiguities need resolution | Supply answers or run with defaults |
-| `discussing` | Discussion in progress | Wait |
-| `researching` | Codebase/library research | Wait |
-| `planning` | Creating task plans | Wait |
-| `executing` | Writing code | Wait |
-| `verifying` | Checking must-haves | Wait |
-| `summarizing` | Recording what happened | Wait |
-| `advancing` | Moving to next task/slice | Wait |
-| `evaluating-gates` | Quality checks before execution | Wait or run `next` |
-| `validating-milestone` | Final milestone checks | Wait |
-| `completing-milestone` | Archiving and cleanup | Wait |
-| `complete` | Done | Verify deliverables |
-| `blocked` | Needs human input | Handle blocker (see below) |
-| `paused` | Explicitly paused | Resume with `auto` |
-
-## Handling Blockers
-
-When exit code is `10` or phase is `blocked`:
-
-```bash
-# 1. Understand the blocker
-sf headless query | jq '{phase: .state.phase, blockers: .state.blockers, nextAction: .state.nextAction}'
-
-# 2. Option A: Steer around it
-sf headless steer "Skip the database dependency, use in-memory storage instead"
-
-# 3. Option B: Supply pre-built answers
-cat > fix.json << 'EOF'
-{
- "questions": { "blocked_question_id": "workaround_option" },
- "defaults": { "strategy": "first_option" }
-}
-EOF
-sf headless --answers fix.json auto
-
-# 4. Option C: Force a specific phase
-sf headless dispatch replan
-
-# 5. Option D: Escalate to user
-echo "SF build blocked. Phase: $(sf headless query | jq -r '.state.phase')"
-echo "Manual intervention required."
-```
-
-## Cost Tracking
-
-```bash
-# Current cumulative cost
-sf headless query | jq '.cost.total'
-
-# Per-worker breakdown
-sf headless query | jq '.cost.workers'
-
-# After a step (from HeadlessJsonResult)
-RESULT=$(sf headless --output-format json next 2>/dev/null)
-echo "$RESULT" | jq '.cost'
-```
-
-### Budget enforcement pattern
-
-```bash
-MAX_BUDGET=15.00
-
-check_budget() {
- TOTAL=$(sf headless query | jq -r '.cost.total')
- OVER=$(echo "$TOTAL > $MAX_BUDGET" | bc -l)
- if [ "$OVER" = "1" ]; then
- echo "Budget exceeded: \$$TOTAL > \$$MAX_BUDGET"
- sf headless stop
- return 1
- fi
- return 0
-}
-```
-
-## Poll-and-React Loop
-
-For agents that need to periodically check on a build:
-
-```bash
-cd /path/to/project
-
-poll_project() {
- STATE=$(sf headless query 2>/dev/null)
- if [ -z "$STATE" ]; then
- echo "NO_PROJECT"
- return
- fi
-
- PHASE=$(echo "$STATE" | jq -r '.state.phase')
- COST=$(echo "$STATE" | jq -r '.cost.total')
- PROGRESS=$(echo "$STATE" | jq -r '"\(.state.progress.milestones.done)/\(.state.progress.milestones.total) milestones, \(.state.progress.tasks.done)/\(.state.progress.tasks.total) tasks"')
-
- case "$PHASE" in
- complete)
- echo "COMPLETE cost=\$$COST progress=$PROGRESS"
- ;;
- blocked)
- BLOCKER=$(echo "$STATE" | jq -r '.state.nextAction // "unknown"')
- echo "BLOCKED reason=$BLOCKER cost=\$$COST"
- ;;
- *)
- NEXT=$(echo "$STATE" | jq -r '.next.action // "none"')
- echo "IN_PROGRESS phase=$PHASE next=$NEXT cost=\$$COST progress=$PROGRESS"
- ;;
- esac
-}
-```
-
-## Resuming Work
-
-If a build was interrupted or you need to continue:
-
-```bash
-cd /path/to/project
-
-# Check current state
-sf headless query | jq '.state.phase'
-
-# Resume from where it left off
-sf headless --output-format json auto 2>/dev/null
-
-# Or resume a specific session
-sf headless --resume "$SESSION_ID" --output-format json auto 2>/dev/null
-```
-
-## Reading Build Artifacts
-
-After completion, inspect what SF produced:
-
-```bash
-cd /path/to/project
-
-# Project summary
-cat .sf/PROJECT.md
-
-# What was decided
-cat .sf/DECISIONS.md
-
-# Requirements and their validation status
-cat .sf/REQUIREMENTS.md
-
-# Milestone summary
-cat .sf/milestones/M001-*/M001-*-SUMMARY.md 2>/dev/null
-
-# Git history (SF commits per-slice)
-git log --oneline
-```
diff --git a/gsd-orchestrator/workflows/step-by-step.md b/gsd-orchestrator/workflows/step-by-step.md
deleted file mode 100644
index b9f9eb1e6..000000000
--- a/gsd-orchestrator/workflows/step-by-step.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Step-by-Step Execution
-
-Run SF one unit at a time with decision points between steps. Use this when you need
-control over execution — budget enforcement, progress reporting, conditional logic,
-or the ability to steer mid-build.
-
-## When to use this vs `auto`
-
-| Approach | Use when |
-|----------|----------|
-| `auto` | You trust the build, just want the result |
-| `next` loop | You need budget checks, progress updates, or intervention points |
-
-## Core Loop
-
-```bash
-cd /path/to/project
-MAX_BUDGET=20.00
-TOTAL_COST=0
-
-while true; do
- # Run one unit
- RESULT=$(sf headless --output-format json next 2>/dev/null)
- EXIT=$?
-
- # Parse result
- STATUS=$(echo "$RESULT" | jq -r '.status')
- STEP_COST=$(echo "$RESULT" | jq -r '.cost.total')
- PHASE=$(echo "$RESULT" | jq -r '.phase // empty')
- SESSION_ID=$(echo "$RESULT" | jq -r '.sessionId // empty')
-
- # Handle exit codes
- case $EXIT in
- 0) ;; # success — continue
- 1)
- echo "Step failed: $STATUS"
- break
- ;;
- 10)
- echo "Blocked — needs intervention"
- sf headless query | jq '.state'
- break
- ;;
- 11)
- echo "Cancelled"
- break
- ;;
- esac
-
- # Check if milestone complete
- CURRENT_PHASE=$(sf headless query | jq -r '.state.phase')
- if [ "$CURRENT_PHASE" = "complete" ]; then
- TOTAL_COST=$(sf headless query | jq -r '.cost.total')
- echo "Milestone complete. Total cost: \$$TOTAL_COST"
- break
- fi
-
- # Budget check
- TOTAL_COST=$(sf headless query | jq -r '.cost.total')
- OVER=$(echo "$TOTAL_COST > $MAX_BUDGET" | bc -l)
- if [ "$OVER" = "1" ]; then
- echo "Budget limit (\$$MAX_BUDGET) exceeded at \$$TOTAL_COST"
- sf headless stop
- break
- fi
-
- # Progress report
- PROGRESS=$(sf headless query | jq -r '"\(.state.progress.tasks.done)/\(.state.progress.tasks.total) tasks"')
- echo "Step done ($STATUS). Phase: $CURRENT_PHASE, Progress: $PROGRESS, Cost: \$$TOTAL_COST"
-done
-```
-
-## Step-by-Step with Spec Creation
-
-Complete flow from idea to working code with full control:
-
-```bash
-# 1. Setup
-PROJECT_DIR="/tmp/my-project"
-mkdir -p "$PROJECT_DIR" && cd "$PROJECT_DIR" && git init 2>/dev/null
-
-# 2. Write spec
-cat > spec.md << 'SPEC'
-[Your spec here]
-SPEC
-
-# 3. Create the milestone (planning only, no execution)
-RESULT=$(sf headless --output-format json --context spec.md new-milestone 2>/dev/null)
-EXIT=$?
-
-if [ $EXIT -ne 0 ]; then
- echo "Milestone creation failed"
- echo "$RESULT" | jq .
- exit 1
-fi
-
-echo "Milestone created. Starting execution..."
-
-# 4. Execute step-by-step
-STEP=0
-while true; do
- STEP=$((STEP + 1))
- RESULT=$(sf headless --output-format json next 2>/dev/null)
- EXIT=$?
-
- [ $EXIT -ne 0 ] && break
-
- PHASE=$(sf headless query | jq -r '.state.phase')
- COST=$(sf headless query | jq -r '.cost.total')
-
- echo "Step $STEP complete. Phase: $PHASE, Cost: \$$COST"
-
- [ "$PHASE" = "complete" ] && break
-done
-
-echo "Build finished in $STEP steps"
-```
-
-## Intervention Patterns
-
-### Steer mid-execution
-
-If you detect the build going in the wrong direction:
-
-```bash
-# Check what's happening
-sf headless query | jq '{phase: .state.phase, task: .state.activeTask}'
-
-# Redirect
-sf headless steer "Use SQLite instead of PostgreSQL for storage"
-
-# Continue
-sf headless --output-format json next 2>/dev/null
-```
-
-### Skip a stuck unit
-
-```bash
-sf headless skip
-sf headless --output-format json next 2>/dev/null
-```
-
-### Undo last completed unit
-
-```bash
-sf headless undo --force
-sf headless --output-format json next 2>/dev/null
-```
-
-### Force a specific phase
-
-```bash
-sf headless dispatch replan # Re-plan the current slice
-sf headless dispatch execute # Skip to execution
-sf headless dispatch uat # Jump to user acceptance testing
-```
diff --git a/package.json b/package.json
index e98abc56f..2e96166e0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
- "name": "sf-run",
+ "name": "singularity-forge",
"version": "2.75.0",
- "description": "sf-run — Singularity Forge runtime core",
+ "description": "Singularity Forge runtime core",
"license": "MIT",
"repository": {
"type": "git",
diff --git a/packages/pi-ai/src/providers/anthropic-vertex.ts b/packages/pi-ai/src/providers/anthropic-vertex.ts
index e32d916e7..bad3595db 100644
--- a/packages/pi-ai/src/providers/anthropic-vertex.ts
+++ b/packages/pi-ai/src/providers/anthropic-vertex.ts
@@ -10,7 +10,7 @@ import type {
StreamFunction,
} from "../types.js";
import { AssistantMessageEventStream } from "../utils/event-stream.js";
-import { adjustMaxTokensForThinking, buildBaseOptions } from "./simple-options.js";
+import { adjustMaxTokensForThinking, buildBaseOptions, isAutoReasoning, resolveReasoningLevel } from "./simple-options.js";
import {
type AnthropicOptions,
mapThinkingLevelToEffort,
@@ -105,8 +105,17 @@ export const streamSimpleAnthropicVertex: StreamFunction<"anthropic-vertex", Sim
return streamAnthropicVertex(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);
}
+ if (isAutoReasoning(options.reasoning) && (supportsAdaptiveThinking(model.id) || model.capabilities?.thinkingNoBudget)) {
+ return streamAnthropicVertex(model, context, {
+ ...base,
+ thinkingEnabled: true,
+ } satisfies AnthropicOptions);
+ }
+
+ const effectiveReasoning = resolveReasoningLevel(model, options.reasoning)!;
+
if (supportsAdaptiveThinking(model.id)) {
- const effort = mapThinkingLevelToEffort(options.reasoning, model.id);
+ const effort = mapThinkingLevelToEffort(effectiveReasoning, model.id);
return streamAnthropicVertex(model, context, {
...base,
thinkingEnabled: true,
@@ -117,7 +126,7 @@ export const streamSimpleAnthropicVertex: StreamFunction<"anthropic-vertex", Sim
const adjusted = adjustMaxTokensForThinking(
base.maxTokens || 0,
model.maxTokens,
- options.reasoning,
+ effectiveReasoning,
options.thinkingBudgets,
);
diff --git a/repowise.db b/repowise.db
deleted file mode 100644
index df702d28f..000000000
Binary files a/repowise.db and /dev/null differ
diff --git a/src/cli.ts b/src/cli.ts
index 36c019a34..5ac9eef6b 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -798,7 +798,7 @@ if (!process.stdin.isTTY || !process.stdout.isTTY) {
// Welcome screen — shown on every fresh interactive session before TUI takes over.
// Skip when the first-run banner was already printed in loader.ts (prevents double banner).
-if (!process.env.SF_FIRST_RUN_BANNER && !process.env.SF_FIRST_RUN_BANNER) {
+if (!process.env.SF_FIRST_RUN_BANNER) {
const { printWelcomeScreen } = await import('./welcome-screen.js')
let remoteChannel: string | undefined
try {
diff --git a/src/resources/extensions/claude-code-cli/stream-adapter.ts b/src/resources/extensions/claude-code-cli/stream-adapter.ts
index 211902f8b..fd02b1989 100644
--- a/src/resources/extensions/claude-code-cli/stream-adapter.ts
+++ b/src/resources/extensions/claude-code-cli/stream-adapter.ts
@@ -13,6 +13,7 @@ import type {
AssistantMessageEventStream,
Context,
Model,
+ RequestedThinkingLevel,
SimpleStreamOptions,
ThinkingLevel,
ToolCall,
@@ -730,9 +731,12 @@ export function buildSdkOptions(
modelId: string,
prompt: string,
overrides?: { permissionMode?: "bypassPermissions" | "acceptEdits" | "default" | "plan" },
- extraOptions: Record & { reasoning?: ThinkingLevel } = {},
+ extraOptions: Record & { reasoning?: RequestedThinkingLevel } = {},
): Record {
- const { reasoning, ...sdkExtraOptions } = extraOptions;
+ const { reasoning: requestedReasoning, ...sdkExtraOptions } = extraOptions;
+ // "auto" → let Claude's adaptive thinking pick effort itself (no explicit level)
+ const reasoning: ThinkingLevel | undefined = requestedReasoning === "auto" ? undefined : requestedReasoning;
+ const autoReasoning = requestedReasoning === "auto";
const mcpServers = buildWorkflowMcpServers();
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
const disallowedTools = ["AskUserQuestion"];
@@ -760,8 +764,9 @@ export function buildSdkOptions(
// Bug B: SDK requires thinking:{type:"adaptive"} alongside effort for adaptive thinking to activate.
// Bug C: SDK requires thinking:{type:"disabled"} to actually stop adaptive thinking when reasoning is off;
// omitting the field leaves the SDK in its adaptive default (or persisted session state).
+ // "auto": request adaptive thinking with no explicit effort (SDK picks).
const thinkingConfig = supportsAdaptive
- ? effort
+ ? effort || autoReasoning
? { thinking: { type: "adaptive" } }
: { thinking: { type: "disabled" } }
: undefined;
diff --git a/src/resources/extensions/sf/metrics.ts b/src/resources/extensions/sf/metrics.ts
index 2849fc141..c622e7fdd 100644
--- a/src/resources/extensions/sf/metrics.ts
+++ b/src/resources/extensions/sf/metrics.ts
@@ -68,7 +68,7 @@ async function recordUnitOutcome(unit: UnitMetrics): Promise {
unitType: unit.type,
unitId: unit.id,
succeeded: true, // metrics.json entry implies completion
- retries: 0, // TODO: extract from session entries if possible
+ // retries omitted — UnitMetrics does not track retry count; defaults to 0 in outcome-recorder
escalated: !!unit.modelDowngraded,
verification_passed: null,
blocker_discovered: false,
diff --git a/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md b/src/resources/skills/create-skill/references/sf-skill-ecosystem.md
similarity index 100%
rename from src/resources/skills/create-skill/references/gsd-skill-ecosystem.md
rename to src/resources/skills/create-skill/references/sf-skill-ecosystem.md
diff --git a/src/tests/gsd-web-launcher-contract.test.ts b/src/tests/sf-web-launcher-contract.test.ts
similarity index 100%
rename from src/tests/gsd-web-launcher-contract.test.ts
rename to src/tests/sf-web-launcher-contract.test.ts