docs: rewrite gsd-orchestrator skill as agent-oriented playbook (#2889)

Restructure from flat documentation reference into proper agent-oriented
skill with XML structure, mental model, routing to workflows, and restored
reference content (KNOWLEDGE.md, flags, event streaming, answer injection,
command table).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
TÂCHES 2026-03-27 15:22:48 -06:00 committed by GitHub
parent da7f5793be
commit 3e0b2b7c6b

View file

@ -1,13 +1,11 @@
---
name: gsd-orchestrator
description: >
Orchestrate GSD (Get Shit Done) projects via subprocess execution.
Use when an agent needs to create milestones from specs, execute software
development workflows, monitor task progress, poll status, handle blockers,
or track costs. Triggers on requests to "run gsd", "create milestone",
"execute project", "check gsd status", "orchestrate development",
"run headless workflow", or any programmatic interaction with the GSD
project management system.
Build software products autonomously via GSD 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 gsd", "check build status", or any task that
requires autonomous software development via subprocess.
metadata:
openclaw:
requires:
@ -18,267 +16,166 @@ metadata:
bins: [gsd]
---
# GSD Orchestrator
<objective>
You are an autonomous agent that builds software by orchestrating GSD as a subprocess.
GSD 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.
</objective>
Run GSD commands as subprocesses via `gsd headless`. No SDK, no RPC — just shell exec, exit codes, and JSON on stdout.
<mental_model>
GSD headless is a subprocess you launch and monitor. Think of it like a junior developer
you hand a spec to:
## Quick Start
1. You write the spec (what to build)
2. You launch the build (`gsd 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 — GSD does that.
</mental_model>
<critical_rules>
- **Flags before command.** `gsd 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 GSD project needs its own directory with a `.gsd/` folder.
</critical_rules>
<routing>
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.
</routing>
<quick_reference>
**Launch a full build (spec to working code):**
```bash
# Install GSD globally
npm install -g gsd-pi
# Verify installation
gsd --version
# Create a milestone from a spec and execute it
gsd headless --output-format json new-milestone --context spec.md --auto
mkdir -p /tmp/my-project && cd /tmp/my-project && git init
cat > spec.md << 'EOF'
# Your Product Spec Here
Build a ...
EOF
gsd headless --output-format json --context spec.md new-milestone --auto 2>/dev/null
```
## Command Syntax
**Check project state (instant, free):**
```bash
gsd headless [flags] [command] [args...]
cd /path/to/project
gsd headless query | jq '{phase: .state.phase, progress: .state.progress, cost: .cost.total}'
```
Default command is `auto` (run all queued units).
**Resume work on an existing project:**
```bash
cd /path/to/project
gsd headless --output-format json auto 2>/dev/null
```
### Flags
**Run one step at a time:**
```bash
RESULT=$(gsd headless --output-format json next 2>/dev/null)
echo "$RESULT" | jq '{status: .status, phase: .phase, cost: .cost.total}'
```
</quick_reference>
<exit_codes>
| Code | Meaning | Your action |
|------|---------|-------------|
| `0` | Success | Check deliverables, verify output, report completion |
| `1` | Error or timeout | Inspect stderr, check `.gsd/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 <sessionId>` or restart |
</exit_codes>
<project_structure>
GSD creates and manages all state in `.gsd/`:
```
.gsd/
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. GSD manages them. But you can read them to understand progress.
</project_structure>
<flags>
| Flag | Description |
|------|-------------|
| `--output-format <fmt>` | Output format: `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) |
| `--output-format <fmt>` | `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) |
| `--json` | Alias for `--output-format stream-json` — JSONL event stream to stdout |
| `--bare` | Minimal context: skip CLAUDE.md, AGENTS.md, user settings, user skills. Use for CI/ecosystem runs. |
| `--bare` | Skip CLAUDE.md, AGENTS.md, user settings, user skills. Use for CI/ecosystem runs. |
| `--resume <id>` | Resume a prior headless session by its session ID |
| `--timeout N` | Overall timeout in ms (default: 300000) |
| `--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 <path>` | Pre-supply answers and secrets from JSON file |
| `--events <types>` | Filter JSONL output to specific event types (comma-separated, implies `--json`) |
| `--events <types>` | Filter JSONL to specific event types (comma-separated, implies `--json`) |
| `--verbose` | Show tool calls in progress output |
| `--context <path>` | Spec file path for `new-milestone` (use `-` for stdin) |
| `--context-text <text>` | Inline spec text for `new-milestone` |
| `--auto` | Chain into auto-mode after `new-milestone` |
</flags>
### Exit Codes
| Code | Meaning | Constant |
|------|---------|----------|
| `0` | Success — unit/milestone completed | `EXIT_SUCCESS` |
| `1` | Error or timeout | `EXIT_ERROR` |
| `10` | Blocked — needs human intervention | `EXIT_BLOCKED` |
| `11` | Cancelled by user or orchestrator | `EXIT_CANCELLED` |
These codes are stable and suitable for CI pipelines and orchestrator logic.
### Output Formats
| Format | Behavior |
|--------|----------|
| `text` | Human-readable progress on stderr. Default. |
| `json` | Collect events silently. Emit a single `HeadlessJsonResult` JSON object to stdout at exit. |
| `stream-json` | Stream JSONL events to stdout in real time (same as `--json`). |
Use `--output-format json` when you need a structured result for decision-making. See [references/json-result.md](references/json-result.md) for the full field reference.
## Core Workflows
### 1. Create + Execute a Milestone (end-to-end)
<answer_injection>
Pre-supply answers and secrets for fully autonomous runs:
```bash
gsd headless --output-format json new-milestone --context spec.md --auto
gsd headless --answers answers.json --output-format json auto 2>/dev/null
```
Reads a spec file, bootstraps `.gsd/`, creates the milestone, then chains into auto-mode executing all phases (discuss → research → plan → execute → summarize → complete). The JSON result is emitted on stdout at exit.
Extra flags for `new-milestone`:
- `--context <path>` — path to spec/PRD file (use `-` for stdin)
- `--context-text <text>` — inline specification text
- `--auto` — start auto-mode after milestone creation
- `--verbose` — show tool calls in progress output
```bash
# From stdin
cat spec.md | gsd headless --output-format json new-milestone --context - --auto
# Inline text
gsd headless new-milestone --context-text "Build a REST API for user management" --auto
```
### 2. Run All Queued Work
```bash
gsd headless --output-format json auto
```
Loop through all pending units until milestone complete or blocked.
### 3. Run One Unit (step-by-step)
```bash
gsd headless --output-format json next
```
Execute exactly one unit (task/slice/milestone step), then exit. This is the recommended pattern for orchestrators that need control between steps.
### 4. Instant State Snapshot (no LLM)
```bash
gsd headless query
```
Returns a single JSON object with the full project snapshot — no LLM session, instant (~50ms). **This is the recommended way for orchestrators to inspect state.**
```json
{
"state": {
"phase": "executing",
"activeMilestone": { "id": "M001", "title": "..." },
"activeSlice": { "id": "S01", "title": "..." },
"progress": { "completed": 3, "total": 7 },
"registry": [...]
},
"next": { "action": "dispatch", "unitType": "execute-task", "unitId": "M001/S01/T01" },
"cost": { "workers": [{ "milestoneId": "M001", "cost": 1.50 }], "total": 1.50 }
"questions": { "question_id": "selected_option" },
"secrets": { "API_KEY": "sk-..." },
"defaults": { "strategy": "first_option" }
}
```
### 5. Dispatch Specific Phase
- **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
```bash
gsd headless dispatch research|plan|execute|complete|reassess|uat|replan
```
See `references/answer-injection.md` for the full mechanism.
</answer_injection>
Force-route to a specific phase, bypassing normal state-machine routing.
### 6. Resume a Session
```bash
gsd headless --resume <session-id> auto
```
Resume a prior headless session. The session ID is available in the `HeadlessJsonResult.sessionId` field from a previous `--output-format json` run.
## Orchestrator Patterns
### Parse the Structured JSON Result
When using `--output-format json`, the process emits a single `HeadlessJsonResult` on stdout at exit. Parse it for decision-making:
```bash
RESULT=$(gsd headless --output-format json next 2>/dev/null)
EXIT=$?
STATUS=$(echo "$RESULT" | jq -r '.status')
COST=$(echo "$RESULT" | jq -r '.cost.total')
PHASE=$(echo "$RESULT" | jq -r '.phase')
NEXT=$(echo "$RESULT" | jq -r '.nextAction')
SESSION_ID=$(echo "$RESULT" | jq -r '.sessionId')
echo "Status: $STATUS, Cost: \$${COST}, Phase: $PHASE, Next: $NEXT"
```
See [references/json-result.md](references/json-result.md) for the full field reference.
### Blocker Detection and Handling
Exit code `10` means the execution hit a blocker requiring human intervention:
```bash
gsd headless --output-format json next 2>/dev/null
EXIT=$?
if [ $EXIT -eq 10 ]; then
# Inspect the blocker
BLOCKER=$(gsd headless query | jq '.state.phase')
echo "Blocked: $BLOCKER"
# Option 1: Use --supervised mode to handle interactively
gsd headless --supervised auto
# Option 2: Pre-supply answers to resolve the blocker
gsd headless --answers blocker-answers.json auto
# Option 3: Steer the plan to work around it
gsd headless steer "Skip the blocked dependency, use mock instead"
fi
```
### Cost Tracking and Budget Enforcement
```bash
MAX_BUDGET=10.00
RESULT=$(gsd headless --output-format json next 2>/dev/null)
COST=$(echo "$RESULT" | jq -r '.cost.total')
# Check cumulative cost via query (includes all workers)
TOTAL_COST=$(gsd headless query | jq -r '.cost.total')
if (( $(echo "$TOTAL_COST > $MAX_BUDGET" | bc -l) )); then
echo "Budget exceeded: \$$TOTAL_COST > \$$MAX_BUDGET"
gsd headless stop
exit 1
fi
```
### Step-by-Step with Monitoring
The recommended pattern for full control. Run one unit at a time, inspect state between steps:
```bash
while true; do
RESULT=$(gsd headless --output-format json next 2>/dev/null)
EXIT=$?
STATUS=$(echo "$RESULT" | jq -r '.status')
COST=$(echo "$RESULT" | jq -r '.cost.total')
echo "Exit: $EXIT, Status: $STATUS, Cost: \$$COST"
# Handle terminal states
[ $EXIT -eq 0 ] || break
# Check if milestone is complete
PHASE=$(gsd headless query | jq -r '.state.phase')
[ "$PHASE" = "complete" ] && echo "Milestone complete" && break
# Budget check
TOTAL=$(gsd headless query | jq -r '.cost.total')
if (( $(echo "$TOTAL > 20.00" | bc -l) )); then
echo "Budget limit reached"
break
fi
done
```
### Poll-and-React Loop
Lightweight pattern using only the instant `query` command:
```bash
PHASE=$(gsd headless query | jq -r '.state.phase')
NEXT_ACTION=$(gsd headless query | jq -r '.next.action')
case "$PHASE" in
complete) echo "Done" ;;
blocked) echo "Needs intervention — exit code 10" ;;
*) [ "$NEXT_ACTION" = "dispatch" ] && gsd headless next ;;
esac
```
### CI/Ecosystem Mode
Use `--bare` to skip user-specific configuration for deterministic CI runs:
```bash
gsd headless --bare --output-format json auto 2>/dev/null
```
This skips CLAUDE.md, AGENTS.md, user settings, and user skills. Bundled GSD extensions and `.gsd/` state are still loaded (they're required for GSD to function).
### JSONL Event Stream
Use `--json` (or `--output-format stream-json`) for real-time events:
<event_streaming>
For real-time monitoring, use JSONL event streaming:
```bash
gsd headless --json auto 2>/dev/null | while read -r line; do
@ -291,84 +188,28 @@ gsd headless --json auto 2>/dev/null | while read -r line; do
done
```
### Filtered Event Stream
Filter to specific events: `--events agent_end,execution_complete,extension_ui_request`
Use `--events` to receive only specific event types:
```bash
# Only phase-relevant events
gsd headless --events agent_end,extension_ui_request auto 2>/dev/null
# Only tool execution events
gsd headless --events tool_execution_start,tool_execution_end auto
```
Available event 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`.
## Answer Injection
Pre-supply answers and secrets for fully autonomous headless runs:
```bash
gsd headless --answers answers.json auto
```
Answer file schema:
```json
{
"questions": { "question_id": "selected_option" },
"secrets": { "API_KEY": "sk-..." },
"defaults": { "strategy": "first_option" }
}
```
- **questions** — question ID → answer (string for single-select, string[] for multi-select)
- **secrets** — env var → value, injected into child process environment
- **defaults.strategy**`"first_option"` (default) or `"cancel"` for unmatched questions
See [references/answer-injection.md](references/answer-injection.md) for the full mechanism.
## GSD Project Structure
All state lives in `.gsd/` as markdown files (version-controllable):
```
.gsd/
PROJECT.md
REQUIREMENTS.md
DECISIONS.md
KNOWLEDGE.md
STATE.md
milestones/
M001/
M001-CONTEXT.md # Requirements, scope, decisions
M001-ROADMAP.md # Slices with tasks, dependencies, checkboxes
M001-SUMMARY.md # Completion summary
slices/
S01/
S01-PLAN.md # Task list
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.
## All Commands
See [references/commands.md](references/commands.md) for the complete reference.
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`.
</event_streaming>
<all_commands>
| Command | Purpose |
|---------|---------|
| `auto` | Run all queued units (default) |
| `next` | Run one unit |
| `query` | Instant JSON snapshot — state, next dispatch, costs (no LLM) |
| `new-milestone` | Create milestone from spec |
| `dispatch <phase>` | Force specific phase |
| `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 <phase>` | Force specific phase (research, plan, execute, complete, reassess, uat, replan) |
| `stop` / `pause` | Control auto-mode |
| `steer <desc>` | Hard-steer plan mid-execution |
| `skip` / `undo` | Unit control |
| `queue` | Queue/reorder milestones |
| `history` | View execution history |
| `doctor` | Health check + auto-fix |
| `knowledge <rule>` | Add persistent project knowledge |
See `references/commands.md` for the complete reference.
</all_commands>