diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 420d4385..89af2f6d 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ { "name": "ralph-specum", "description": "Spec-driven development with research, requirements, design, tasks, autonomous execution, and epic triage. Fresh context per task.", - "version": "4.9.1", + "version": "4.10.0", "author": { "name": "tzachbon" }, @@ -29,7 +29,7 @@ { "name": "ralph-speckit", "description": "Spec-driven development using GitHub spec-kit methodology. Constitution-first approach with specify, plan, tasks, and implement phases.", - "version": "0.5.2", + "version": "0.5.3", "author": { "name": "tzachbon" }, diff --git a/plugins/ralph-speckit/.claude-plugin/plugin.json b/plugins/ralph-speckit/.claude-plugin/plugin.json index 98890417..7ee2a8b9 100644 --- a/plugins/ralph-speckit/.claude-plugin/plugin.json +++ b/plugins/ralph-speckit/.claude-plugin/plugin.json @@ -1,10 +1,17 @@ { "name": "ralph-speckit", - "version": "0.5.2", + "version": "0.5.3", "description": "Spec-driven development using GitHub spec-kit methodology. Constitution-first approach with specify, plan, tasks, and implement phases.", "author": { "name": "tzachbon" }, "license": "MIT", - "keywords": ["ralph", "speckit", "spec-driven", "constitution", "specify", "plan", "tasks", "implement"] + "keywords": ["ralph", "speckit", "spec-driven", "constitution", "specify", "plan", "tasks", "implement"], + "hooks": [ + { + "event": "PreToolUse", + "matcher": "AskUserQuestion", + "command": "hooks/scripts/quick-mode-guard.sh" + } + ] } diff --git a/plugins/ralph-speckit/commands/start.md b/plugins/ralph-speckit/commands/start.md index 8dd7f207..14af2427 100644 --- a/plugins/ralph-speckit/commands/start.md +++ b/plugins/ralph-speckit/commands/start.md @@ -30,10 +30,22 @@ If CONSTITUTION_MISSING: From `$ARGUMENTS`, extract: - **feature-name**: Required, kebab-case name for the feature - **goal**: Optional description of what the feature should accomplish +- **--quick**: Optional flag. Run all planning phases (research, requirements, design, tasks) but STOP before implementation. Presents the plan and awaits approval. +- **--auto**: Optional flag. Full end-to-end autonomous execution. Skips interactive prompts and runs all phases including implementation without stopping. Examples: - `/speckit:start user-auth` - Create feature named user-auth - `/speckit:start user-auth Add OAuth2 support` - Create with goal +- `/speckit:start user-auth Add OAuth2 support --quick` - Plan only, no implementation +- `/speckit:start user-auth Add OAuth2 support --auto` - Full autonomous execution + +Mutual exclusivity check: if both `--quick` and `--auto` are present in `$ARGUMENTS`: +1. Output: "Error: --quick and --auto are mutually exclusive. Use one or the other." +2. STOP - do not create any feature directory or continue + +Parse flags (strip from goal text after extraction): +- `quickMode`: set to `true` if `--quick` is present, `false` otherwise +- `autoMode`: set to `true` if `--auto` is present, `false` otherwise If no feature-name provided: 1. Output: "Usage: /speckit:start [goal]" @@ -143,16 +155,48 @@ Write `.specify/specs/$FEATURE_ID-$feature-name/.speckit-state.json`: "maxTaskIterations": 5, "globalIteration": 1, "maxGlobalIterations": 100, - "awaitingApproval": false + "awaitingApproval": false, + "quickMode": false, + "autoMode": false } ``` +Set fields based on parsed flags: +- If `quickMode` is `true`: set `"quickMode": true` in the state file +- If `autoMode` is `true`: set `"autoMode": true` in the state file + ## Update Current Feature Pointer ```bash echo "$FEATURE_ID-$feature-name" > .specify/.current-feature ``` +## Autonomous Mode Routing + +After state init and writing `.current-feature`, check flags: + +If neither `quickMode` nor `autoMode` is set: continue to normal interactive flow (output feature created message, suggest next step). + +If `quickMode=true` or `autoMode=true`: +1. Verify `.specify/.current-feature` was written (guards depend on it). +2. Skip all interactive prompts. +3. Run all spec phases sequentially, delegating to each subagent with the directive: "Autonomous Mode: skip all questions, make reasonable decisions based on the goal and constitution." + - Phase 1: Research (delegate to research-analyst agent) + - Phase 2: Requirements (delegate to product-manager agent) + - Phase 3: Design (delegate to architect-reviewer agent) + - Phase 4: Tasks (delegate to task-planner agent) +4. After tasks phase completes, compute totalTasks (count `- [ ]` checkboxes in tasks.md) and update state with shared execution bootstrap fields: + ```json + { "phase": "execution", "taskIndex": 0, "totalTasks": } + ``` + Then branch by mode: + - If `quickMode=true`: + - Also set `awaitingApproval: true` in state file + - Output: "Plan complete for '$FEATURE_ID-$feature-name'. Review the spec in .specify/specs/$FEATURE_ID-$feature-name/ and run /speckit:implement to start execution." + - STOP - do not proceed to implementation + - If `autoMode=true`: + - Transition directly to implementation (continue to execution loop) + ## Initialize Progress File Create `.specify/specs/$FEATURE_ID-$feature-name/.progress.md`: diff --git a/plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh b/plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh new file mode 100755 index 00000000..d4fc771d --- /dev/null +++ b/plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# PreToolUse hook: Block AskUserQuestion in autonomous modes (quickMode or autoMode) +set -euo pipefail + +INPUT=$(cat) + +command -v jq >/dev/null 2>&1 || exit 0 + +CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true) +[ -z "$CWD" ] && exit 0 + +# Find the current feature's state file +CURRENT_FEATURE_FILE="$CWD/.specify/.current-feature" +[ ! -f "$CURRENT_FEATURE_FILE" ] && exit 0 + +FEATURE_NAME=$(cat "$CURRENT_FEATURE_FILE" 2>/dev/null | tr -d '[:space:]') +[ -z "$FEATURE_NAME" ] && exit 0 + +# Try .speckit-state.json first, then .ralph-state.json for compatibility +STATE_FILE="" +for candidate in "$CWD/.specify/specs/$FEATURE_NAME/.speckit-state.json" "$CWD/.specify/specs/"*"-$FEATURE_NAME/.speckit-state.json"; do + if [ -f "$candidate" ]; then + STATE_FILE="$candidate" + break + fi +done +[ -z "$STATE_FILE" ] && exit 0 + +QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") +AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") + +if [ "$QUICK_MODE" != "true" ] && [ "$AUTO_MODE" != "true" ]; then + exit 0 +fi + +# Autonomous mode is active — block AskUserQuestion +jq -n '{ + "hookSpecificOutput": { + "permissionDecision": "deny" + }, + "systemMessage": "Autonomous mode active: do NOT ask the user any questions. Make opinionated decisions autonomously. Choose the simplest, most conventional approach." +}' diff --git a/plugins/ralph-speckit/hooks/scripts/stop-watcher.sh b/plugins/ralph-speckit/hooks/scripts/stop-watcher.sh index 9704e7c4..1455e8ae 100755 --- a/plugins/ralph-speckit/hooks/scripts/stop-watcher.sh +++ b/plugins/ralph-speckit/hooks/scripts/stop-watcher.sh @@ -109,6 +109,8 @@ PHASE=$(jq -r '.phase // "unknown"' "$STATE_FILE" 2>/dev/null || echo "unknown") TASK_INDEX=$(jq -r '.taskIndex // 0' "$STATE_FILE" 2>/dev/null || echo "0") TOTAL_TASKS=$(jq -r '.totalTasks // 0' "$STATE_FILE" 2>/dev/null || echo "0") TASK_ITERATION=$(jq -r '.taskIteration // 1' "$STATE_FILE" 2>/dev/null || echo "1") +QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") +AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") # Check global iteration limit GLOBAL_ITERATION=$(jq -r '.globalIteration // 1' "$STATE_FILE" 2>/dev/null || echo "1") @@ -120,6 +122,16 @@ if [ "$GLOBAL_ITERATION" -ge "$MAX_GLOBAL" ]; then exit 0 fi +# Autonomous mode planning guard: block stops during non-execution phases +if { [ "$QUICK_MODE" = "true" ] || [ "$AUTO_MODE" = "true" ]; } && [ "$PHASE" != "execution" ]; then + STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false") + if [ "$STOP_HOOK_ACTIVE" = "true" ]; then exit 0; fi + REASON="Autonomous mode active — continue spec phase: $PHASE for $FEATURE_NAME." + MSG="Ralph-speckit autonomous mode: continue $PHASE phase" + jq -n --arg reason "$REASON" --arg msg "$MSG" '{"decision": "block", "reason": $reason, "systemMessage": $msg}' + exit 0 +fi + # Log current state if [ "$PHASE" = "execution" ]; then echo "[ralph-speckit] Session stopped during feature: $FEATURE_NAME | Task: $((TASK_INDEX + 1))/$TOTAL_TASKS | Attempt: $TASK_ITERATION" >&2 @@ -127,6 +139,12 @@ fi # Loop control: output continuation prompt if more tasks remain if [ "$PHASE" = "execution" ] && [ "$TASK_INDEX" -lt "$TOTAL_TASKS" ]; then + AWAITING=$(jq -r '.awaitingApproval // false' "$STATE_FILE" 2>/dev/null || echo "false") + if [ "$AWAITING" = "true" ]; then + echo "[ralph-speckit] awaitingApproval=true, allowing stop for user gate" >&2 + exit 0 + fi + # Read recovery mode for prompt customization RECOVERY_MODE=$(jq -r '.recoveryMode // false' "$STATE_FILE" 2>/dev/null || echo "false") MAX_TASK_ITER=$(jq -r '.maxTaskIterations // 5' "$STATE_FILE" 2>/dev/null || echo "5") diff --git a/plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md b/plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md index 292577ae..f11be6f2 100644 --- a/plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md +++ b/plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md @@ -20,7 +20,7 @@ Use this for the `start` and `new` entrypoints. ## Action -1. Parse explicit name, goal, `--quick`, commit flags, optional specs root, and optional `--tasks-size fine|coarse`. +1. Parse explicit name, goal, `--quick`, `--auto`, commit flags, optional specs root, and optional `--tasks-size fine|coarse`. If both `--quick` and `--auto` are present: Respond "Error: --quick and --auto are mutually exclusive. Use one or the other." STOP. 2. Resolve the target by explicit path, exact name, or `.current-spec`. 3. If the same name exists in multiple configured roots, stop and require a full path. 4. Check active epic context from `specs/.current-epic` when no explicit spec was chosen. @@ -40,15 +40,18 @@ Use this for the `start` and `new` entrypoints. - `commitSpec: settings auto_commit_spec or true` - `relatedSpecs: []` - `awaitingApproval: true` when the run will stop after setup and wait for explicit direction - - `awaitingApproval: false` when quick mode or explicit autonomy will continue without pausing - - preserve or set `quickMode` + - `awaitingApproval: false` when `--auto` will continue without pausing + - `quickMode: true, autoMode: false` when `--quick` was supplied + - `quickMode: false, autoMode: true` when `--auto` was supplied + - preserve or set `quickMode` and `autoMode` - preserve or set `granularity` when `--tasks-size` was supplied - preserve or set `epicName` when starting from an epic suggestion 8. Update `.current-spec`. 9. Write `.progress.md` with goal, current phase, next step, blockers, learnings, and skill discovery results when used. 10. On resume, prefer `tasks.md` and present files over stale state when they disagree. -11. In quick mode, generate missing artifacts in order, skip normal approval pauses, and continue into implementation in the same run. -12. **Without quick mode or explicit autonomy: STOP HERE after setup. Do NOT proceed to research. Wait for the user to explicitly ask to continue.** This is non-negotiable. +11. With `--quick`: generate all artifacts (research, requirements, design, tasks) autonomously in order, skip normal approval pauses, then set `awaitingApproval: true`. Output a summary listing each generated artifact with a one-sentence description, then end with exactly one explicit choice prompt: "Approve plan and run implement" or "Request changes". STOP. +12. With `--auto`: generate all artifacts autonomously in order, skip normal approval pauses, and continue directly into implementation without stopping. +13. **Without `--quick` or `--auto`: STOP HERE after setup. Do NOT proceed to research. Wait for the user to explicitly ask to continue.** This is non-negotiable. ## Branch Isolation @@ -61,4 +64,4 @@ Use this for the `start` and `new` entrypoints. - End with exactly one explicit choice prompt: - `request changes` - `continue to research` -- Do not run research until the user explicitly asks to continue or explicitly asked for quick or autonomous flow. +- Do not run research until the user explicitly asks to continue or explicitly asked for `--quick` or `--auto` flow. diff --git a/plugins/ralph-specum-codex/skills/ralph-specum/SKILL.md b/plugins/ralph-specum-codex/skills/ralph-specum/SKILL.md index afecdf54..ee137c17 100644 --- a/plugins/ralph-specum-codex/skills/ralph-specum/SKILL.md +++ b/plugins/ralph-specum-codex/skills/ralph-specum/SKILL.md @@ -56,13 +56,13 @@ If the corresponding helper skill is installed and the user invoked it explicitl 4. Keep `.current-spec` in the default specs root. 5. Merge state fields. Do not replace the whole state object. 6. Preserve `source`, `name`, `basePath`, `phase`, `taskIndex`, `totalTasks`, `taskIteration`, `maxTaskIterations`, `globalIteration`, `maxGlobalIterations`, `commitSpec`, and `relatedSpecs`. -7. Also preserve newer state fields when present, especially `awaitingApproval`, `quickMode`, `granularity`, `epicName`, `discoveredSkills`, and native task sync metadata. +7. Also preserve newer state fields when present, especially `awaitingApproval`, `quickMode`, `autoMode`, `granularity`, `epicName`, `discoveredSkills`, and native task sync metadata. 8. Write `.progress.md` after every phase and after every implementation attempt. 9. Honor approval checkpoints between phases unless quick mode is active. 10. Honor the `Commit` line in tasks during implementation unless the user explicitly disables task commits. 11. Use branch creation or worktree creation when the user asks for branch isolation or the repo policy requires it. -12. Enter quick mode only when the user explicitly asks Ralph to be autonomous, do it quickly, or continue without pauses. -13. In quick mode, generate missing artifacts, default task granularity to `fine` when unset, and continue into implementation in the same session. +12. `--quick` and `--auto` are mutually exclusive. `--quick` means plan-only: generate all artifacts autonomously, then stop with `awaitingApproval: true` before implementation. `--auto` means full autonomous: generate all artifacts and continue directly into implementation without stopping. +13. In `--auto` mode, generate missing artifacts, default task granularity to `fine` when unset, and continue into implementation in the same session. In `--quick` mode, do the same but stop before implementation. ## Stop Enforcement diff --git a/plugins/ralph-specum/.claude-plugin/plugin.json b/plugins/ralph-specum/.claude-plugin/plugin.json index 9affe412..815f2e5d 100644 --- a/plugins/ralph-specum/.claude-plugin/plugin.json +++ b/plugins/ralph-specum/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ralph-specum", - "version": "4.9.1", + "version": "4.10.0", "description": "Spec-driven development with task-by-task execution. Research, requirements, design, tasks, autonomous implementation, and epic triage for multi-spec feature decomposition.", "author": { "name": "tzachbon" diff --git a/plugins/ralph-specum/commands/start.md b/plugins/ralph-specum/commands/start.md index 2edef4c7..767f5f8c 100644 --- a/plugins/ralph-specum/commands/start.md +++ b/plugins/ralph-specum/commands/start.md @@ -1,6 +1,6 @@ --- description: Smart entry point that detects if you need a new spec or should resume existing -argument-hint: [name] [goal] [--fresh] [--quick] [--commit-spec] [--no-commit-spec] [--specs-dir ] [--tasks-size fine|coarse] +argument-hint: [name] [goal] [--fresh] [--quick] [--auto] [--commit-spec] [--no-commit-spec] [--specs-dir ] [--tasks-size fine|coarse] allowed-tools: "*" --- @@ -37,8 +37,12 @@ Read `${CLAUDE_PLUGIN_ROOT}/references/intent-classification.md` and follow the ### Quick Mode Check +If both `--quick` and `--auto` flags are detected in $ARGUMENTS, output: "Error: --quick and --auto are mutually exclusive. Use one or the other." and STOP immediately before creating any files. + If `--quick` flag detected in $ARGUMENTS, skip to **Step 5: Quick Mode Flow**. +If `--auto` flag detected in $ARGUMENTS, skip to **Step 5: Quick Mode Flow**. + ## Step 3: Scan Existing Specs Read `${CLAUDE_PLUGIN_ROOT}/references/spec-scanner.md` and follow the scanning algorithm and index hint logic. @@ -135,7 +139,7 @@ Continuing... "phase": "research", "taskIndex": 0, "totalTasks": 0, "taskIteration": 1, "maxTaskIterations": 5, "globalIteration": 1, "maxGlobalIterations": 100, - "commitSpec": true, "quickMode": false, + "commitSpec": true, "quickMode": false, "autoMode": false, "discoveredSkills": [] } ``` @@ -254,7 +258,7 @@ End response immediately. Read `${CLAUDE_PLUGIN_ROOT}/references/quick-mode.md` and follow the full quick mode execution sequence. -**Summary**: Validates input, infers name, creates spec directory, initializes state with quickMode=true, then runs all phases sequentially (research, requirements, design, tasks) delegating to subagents with Quick Mode Directive. Each artifact gets a review loop (max 3 iterations). After all artifacts generated, transitions to execution and invokes spec-executor for task 1. +**Summary**: Validates input, infers name, creates spec directory, initializes state with quickMode=true or autoMode=true, then runs all phases sequentially (research, requirements, design, tasks) delegating to subagents with Autonomous Mode Directive. Each artifact gets a review loop (max 3 iterations). After all artifacts generated: `--quick` sets awaitingApproval=true and stops before implementation; `--auto` transitions to execution and invokes spec-executor for task 1. **IMPORTANT**: Each phase MUST be tracked as a native Claude task via `TaskCreate` / `TaskUpdate`. Create a task at phase start (with `activeForm` for spinner text), mark it completed when the phase finishes. This provides visible progress in the UI. See quick-mode.md steps 11-15 for the exact pattern. @@ -304,7 +308,7 @@ After ANY subagent returns in normal mode (no `--quick` flag): **The user must explicitly run the next command.** This gives them time to review artifacts. -Exception: `--quick` mode runs all phases without stopping. +Exception: `--quick` or `--auto` mode runs all phases without stopping. ## Quick Mode Execution (Stop-Hook) diff --git a/plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh b/plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh index d219bb83..e02b0d92 100755 --- a/plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh +++ b/plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh @@ -32,16 +32,17 @@ if [ ! -f "$STATE_FILE" ]; then exit 0 fi -# Check quickMode flag +# Check quickMode and autoMode flags QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") -if [ "$QUICK_MODE" != "true" ]; then +AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") +if [ "$QUICK_MODE" != "true" ] && [ "$AUTO_MODE" != "true" ]; then exit 0 fi -# Quick mode is active — block AskUserQuestion +# Autonomous mode is active — block AskUserQuestion jq -n '{ "hookSpecificOutput": { "permissionDecision": "deny" }, - "systemMessage": "Quick mode active: do NOT ask the user any questions. Make opinionated decisions autonomously. Choose the simplest, most conventional approach." + "systemMessage": "Autonomous mode active: do NOT ask the user any questions. Make opinionated decisions autonomously. Choose the simplest, most conventional approach." }' diff --git a/plugins/ralph-specum/hooks/scripts/stop-watcher.sh b/plugins/ralph-specum/hooks/scripts/stop-watcher.sh index 2fa9430a..5ba86608 100755 --- a/plugins/ralph-specum/hooks/scripts/stop-watcher.sh +++ b/plugins/ralph-specum/hooks/scripts/stop-watcher.sh @@ -144,8 +144,14 @@ TASK_INDEX=$(jq -r '.taskIndex // 0' "$STATE_FILE" 2>/dev/null || echo "0") TOTAL_TASKS=$(jq -r '.totalTasks // 0' "$STATE_FILE" 2>/dev/null || echo "0") TASK_ITERATION=$(jq -r '.taskIteration // 1' "$STATE_FILE" 2>/dev/null || echo "1") QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") +AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") NATIVE_SYNC=$(jq -r '.nativeSyncEnabled // true' "$STATE_FILE" 2>/dev/null || echo "true") +AUTONOMOUS_MODE="false" +if [ "$QUICK_MODE" = "true" ] || [ "$AUTO_MODE" = "true" ]; then + AUTONOMOUS_MODE="true" +fi + # Check global iteration limit GLOBAL_ITERATION=$(jq -r '.globalIteration // 1' "$STATE_FILE" 2>/dev/null || echo "1") MAX_GLOBAL=$(jq -r '.maxGlobalIterations // 100' "$STATE_FILE" 2>/dev/null || echo "100") @@ -156,25 +162,25 @@ if [ "$GLOBAL_ITERATION" -ge "$MAX_GLOBAL" ]; then exit 0 fi -# Quick mode guard: block stop during ANY phase when quickMode is active -if [ "$QUICK_MODE" = "true" ] && [ "$PHASE" != "execution" ]; then +# Autonomous mode guard: block stop during ANY phase when quickMode or autoMode is active +if [ "$AUTONOMOUS_MODE" = "true" ] && [ "$PHASE" != "execution" ]; then STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false") if [ "$STOP_HOOK_ACTIVE" = "true" ]; then - echo "[ralph-specum] stop_hook_active=true in quick mode, allowing stop to prevent loop" >&2 + echo "[ralph-specum] stop_hook_active=true in autonomous mode, allowing stop to prevent loop" >&2 exit 0 fi REASON=$(cat <**: Create spec in specified directory (must be in configured specs_dirs array) - **--tasks-size **: Task granularity level for task generation +- **--auto**: Run all phases including implementation autonomously, full end-to-end ### Commit Spec Flag Logic ```text +0. If both --quick and --auto in $ARGUMENTS -> Error: '--quick and --auto are mutually exclusive. Use one or the other.' STOP before creating any files. 1. Check if --no-commit-spec in $ARGUMENTS -> commitSpec = false 2. Else if --commit-spec in $ARGUMENTS -> commitSpec = true 3. Else if --quick in $ARGUMENTS -> commitSpec = false (quick mode default) +3b. Else if --auto in $ARGUMENTS -> commitSpec = false (auto mode default) 4. Else -> commitSpec = true (normal mode default) ``` @@ -38,6 +41,9 @@ From `$ARGUMENTS`, extract: - `/ralph-specum:start my-feature --quick` -> Quick mode using existing plan.md - `/ralph-specum:start my-feature "Add logging" --tasks-size coarse` -> Coarse granularity (10-20 tasks) - `/ralph-specum:start my-feature --quick --tasks-size fine` -> Quick mode with fine granularity +- `/ralph-specum:start "Build auth with JWT" --auto` -> Auto mode with goal string +- `/ralph-specum:start my-feature "Add logging" --auto` -> Auto mode with name+goal +- `/ralph-specum:start my-feature ./plan.md --auto` -> Auto mode with file input ## Detection Logic (Normal Mode) @@ -252,3 +258,5 @@ For fix goals: run reproduction command, document BEFORE state in .progress.md. | No name + no active spec | Ask for name and goal, new flow | | --quick with goal/file | Quick mode flow (skip interactive phases) | | --quick with zero args | Error: "Quick mode requires a goal or plan file" | +| --auto with goal/file | Auto mode flow (full autonomous) | +| Both --quick and --auto | Error: mutually exclusive | diff --git a/plugins/ralph-specum/references/quick-mode.md b/plugins/ralph-specum/references/quick-mode.md index 8f973423..c166624d 100644 --- a/plugins/ralph-specum/references/quick-mode.md +++ b/plugins/ralph-specum/references/quick-mode.md @@ -4,6 +4,10 @@ This reference contains the full quick mode flow triggered by the `--quick` flag, including input detection, validation, execution sequence, review loops, and rollback. +## Mode Selector + +This reference is used for both --quick (plan-only) and --auto (full autonomous) flows. The flows are identical through the Tasks Phase. They diverge at the Transition to Execution step. + ## Quick Mode Input Detection Parse arguments before `--quick` flag and classify input type: @@ -68,11 +72,16 @@ Validation Sequence: 4. Create spec directory: mkdir -p "$basePath" 4a. Ensure gitignore entries exist (.current-spec, .progress.md) 5. Write .ralph-state.json: - { source: "plan", name, basePath, phase: "research", + For --quick: { source: "plan", name, basePath, phase: "research", + taskIndex: 0, totalTasks: 0, taskIteration: 1, + maxTaskIterations: 5, globalIteration: 1, + maxGlobalIterations: 100, commitSpec: $commitSpec, + quickMode: true, autoMode: false, discoveredSkills: [] } + For --auto: { source: "plan", name, basePath, phase: "research", taskIndex: 0, totalTasks: 0, taskIteration: 1, maxTaskIterations: 5, globalIteration: 1, maxGlobalIterations: 100, commitSpec: $commitSpec, - quickMode: true, discoveredSkills: [] } + quickMode: false, autoMode: true, discoveredSkills: [] } 6. Write .progress.md with original goal 7. Update .current-spec (bare name or full path) 8. Update Spec Index: ./plugins/ralph-specum/hooks/scripts/update-spec-index.sh --quiet @@ -117,7 +126,9 @@ Validation Sequence: - Count total tasks (number of `- [ ]` checkboxes) - Update state: phase="execution", totalTasks=, taskIndex=0 - If commitSpec: stage, commit, push spec files -17. Invoke spec-executor for task 1 + - **--quick path**: set awaitingApproval: true in state, output "Plan complete for '$name'. All 4 artifacts generated. Run /ralph-specum:implement to execute, or review the spec files first.", then STOP. Do NOT invoke spec-executor. + - **--auto path**: continue to step 17 (count tasks, transition to execution, invoke spec-executor for task 1). +17. [--auto only] Invoke spec-executor for task 1 ``` ## Step 9: Skill Discovery Pass 1 @@ -182,13 +193,13 @@ Re-scan skills with enriched context after research completes: ``` If no new skills match: `- No new skills matched` -## Quick Mode Directive +## Autonomous Mode Directive Each agent delegation in steps 11-15 includes this directive in the Task prompt: ```text -Quick Mode Context: -Running in quick mode with no user feedback. You MUST: +Autonomous Mode Context: +Running in autonomous mode with no user feedback. You MUST: - Make strong, opinionated decisions instead of deferring to user - Choose the simplest, most conventional approach - Be more critical of your own output diff --git a/plugins/ralph-specum/skills/smart-ralph/SKILL.md b/plugins/ralph-specum/skills/smart-ralph/SKILL.md index ddc7a968..8196faab 100644 --- a/plugins/ralph-specum/skills/smart-ralph/SKILL.md +++ b/plugins/ralph-specum/skills/smart-ralph/SKILL.md @@ -15,7 +15,8 @@ All Ralph commands support these standard arguments: | Argument | Short | Description | Default | |----------|-------|-------------|---------| -| `--quick` | `-q` | Skip interactive phases, auto-generate artifacts, start execution immediately | false | +| `--quick` | `-q` | Run all planning phases autonomously (research, requirements, design, tasks), then stop before implementation | false | +| `--auto` | `-a` | Run all phases including implementation autonomously, no stopping | false | | `--commit` | `-c` | Commit and push spec/feature files after generation | true (normal), false (quick) | | `--no-commit` | | Explicitly disable committing files | - | | `--max-task-iterations` | `-m` | Max retries per failed task before stopping | 5 | @@ -23,6 +24,8 @@ All Ralph commands support these standard arguments: Argument precedence: `--no-commit` > `--commit` > mode default. +`--quick` and `--auto` are mutually exclusive. + ## Execution Modes ### Normal Mode (Interactive) @@ -32,7 +35,17 @@ Argument precedence: `--no-commit` > `--commit` > mode default. - Each phase sets `awaitingApproval: true` - Commits spec files by default -### Quick Mode (`--quick`) +### Plan-Only Mode (`--quick`) + +- Skip all interactive prompts, interviews, and approval pauses +- Run the same phase agents (research, requirements, design, tasks) sequentially +- Agents receive a "be more opinionated" directive since there is no user feedback +- spec-reviewer validates each artifact (max 3 iterations) +- Stop after all planning phases complete, before implementation +- Do NOT commit by default (use `--commit` to override) +- Still delegate to subagents (delegation is mandatory) + +### Full Autonomous Mode (`--auto`) - Skip all interactive prompts, interviews, and approval pauses - Run the same phase agents (research, requirements, design, tasks) sequentially @@ -82,7 +95,7 @@ All Ralph plugins follow consistent branch strategy: 1. Check current branch before starting 2. If on default branch (main/master): prompt for branch strategy 3. If on feature branch: offer to continue or create new -4. Quick mode: auto-create branch, no prompts +4. Quick or auto mode: auto-create branch, no prompts ## Coordinator Behavior diff --git a/specs/add-auto-flag/.progress.md b/specs/add-auto-flag/.progress.md new file mode 100644 index 00000000..e5972056 --- /dev/null +++ b/specs/add-auto-flag/.progress.md @@ -0,0 +1,74 @@ +# Progress: add-auto-flag + +## Goal +Redefine `--quick` flag to only run planning phases (research, requirements, design, tasks) without implementation, and add new `--auto` flag for full end-to-end autonomous execution. Apply changes across all plugins. + +## Interview Format +- Version: 1.0 + +## Intent Classification +- Type: MID_SIZED +- Confidence: medium (2 keywords matched) +- Min questions: 3 +- Max questions: 7 +- Keywords matched: small change, add + +## Interview Responses + +### Goal Interview (from start.md) +- **--quick new behavior**: Run all planning phases (research, requirements, design, tasks) but STOP before implementation. Present the plan and ask if user wants to continue. +- **--auto new behavior**: Full end-to-end autonomous execution. Skip interview, run all phases + implementation without stopping. This is what current --quick does, plus it never stops. +- **Interview in --auto**: Skipped (same as current --quick) +- **Flag exclusivity**: --quick and --auto are mutually exclusive. Using both is an error. +- **Scope**: All 3 plugins (ralph-specum, ralph-speckit, ralph-specum-codex) +- **Chosen approach**: A (Skill-first) -- Update smart-ralph skill first, then update each plugin's commands +- **Spec location**: ./specs/ (default) + +## Skill Discovery +- **smart-ralph** (plugins/ralph-specum/skills/smart-ralph/SKILL.md): matched (reason: directly defines --quick flag and execution modes) +- **Command Development** (.agents/skills/Command Development/SKILL.md): matched but invocation failed +- **interview-framework** (plugins/ralph-specum/skills/interview-framework/SKILL.md): no match +- **communication-style** (plugins/ralph-specum/skills/communication-style/SKILL.md): no match +- **reality-verification** (plugins/ralph-specum/skills/reality-verification/SKILL.md): no match +- **spec-workflow** (plugins/ralph-specum/skills/spec-workflow/SKILL.md): no match +- **Hook Development** (.agents/skills/Hook Development/SKILL.md): no match +- **MCP Integration** (.agents/skills/MCP Integration/SKILL.md): no match +- **Plugin Settings** (.agents/skills/Plugin Settings/SKILL.md): no match +- **Plugin Structure** (.agents/skills/Plugin Structure/SKILL.md): no match +- **Skill Development** (.agents/skills/Skill Development/SKILL.md): no match + +## Completed Tasks +- [x] 1.1 Update smart-ralph SKILL.md with --auto definition +- [x] 1.2 Update intent-classification.md with --auto parsing +- [x] 1.3 Update quick-mode.md to branch on --quick vs --auto +- [x] 1.5 Update commands/start.md (ralph-specum) +- [x] 1.6 Update stop-watcher.sh (ralph-specum) +- [x] 1.7 Update quick-mode-guard.sh (ralph-specum) +- [x] 1.11 Create quick-mode-guard.sh (ralph-speckit) and register hook - cde7755 +- [x] 1.13 Update ralph-specum-codex skills + +## Current Task +Awaiting next task + +## Learnings + +- `quickMode` field currently means "full autonomous" in ralph-specum. Renaming its semantics (not the field name) requires updating stop-watcher.sh, quick-mode-guard.sh, and quick-mode.md references. The field name stays `quickMode` but its meaning flips to plan-only. +- `autoMode` is a net-new field. State files without it must treat it as `false` to avoid breaking existing runs. +- ralph-speckit has zero quick mode infrastructure (no guard hook, no quickMode in state, no stop-watcher logic). Both flags need to be built from scratch there. +- ralph-specum-codex uses intent detection rather than flag parsing. The change is isolated to skill files; no shell hooks to update. +- Spec-reviewer loop behavior: assumed to stay active for both flags (open question Q1 in requirements). +- Mutual exclusivity check must happen at argument parse time, before any spec files or state are created. +- "Plan-only" stop point: stop-watcher should set `awaitingApproval: true` after tasks phase completes when `quickMode` is set, which prevents auto-continuation into implementation. +- Design decision: `awaitingApproval: true` for --quick is set by the coordinator (start.md / quick-mode.md step 16), not by the stop-watcher. The stop-watcher already exits 0 when awaitingApproval=true; no stop-watcher change needed for the plan-only stop. +- ralph-speckit stop-watcher currently has no `awaitingApproval` check in its execution loop section — this is a gap that must be fixed as part of this spec. +- ralph-specum-codex stop-watcher only fires during `phase=execution` and already checks `awaitingApproval`; no changes needed there. +- `commitSpec` defaults to `true` for both --quick and --auto (requirements matrix), unlike the old --quick which defaulted to false. This is a intentional behavior change. +- The planning phase guard in stop-watcher (lines 159-184) checks `quickMode` only. Adding `autoMode` to this guard is the only stop-watcher change needed for ralph-specum — merge both into a single `AUTONOMOUS_MODE` variable. +- ralph-speckit `.claude-plugin/plugin.json` must be updated to register the new PreToolUse hook; without this registration the guard script will never fire. +- Task planning order: SKILL.md first (foundation), then intent-classification.md + quick-mode.md (parallel), then start.md (both plugins), then hooks (parallel per plugin), then codex skills, then version bumps. +- ralph-speckit plugin.json currently has no `hooks` array at all. Task 1.11 adds it fresh. +- Tasks 1.6 and 1.7 (ralph-specum hooks) can run in parallel -- zero file overlap. +- Tasks 1.10 and 1.11 (ralph-speckit stop-watcher + guard creation) can run in parallel -- different files. +- Tasks 1.2 and 1.3 (intent-classification + quick-mode) can run in parallel -- different files. +- Version bump targets: ralph-specum 4.9.1 -> 4.10.0 (minor), ralph-speckit 0.5.2 -> 0.5.3 (patch). +- ralph-specum-codex has no `.claude-plugin/plugin.json` found in the worktree; skip version bump for that plugin or verify path before task 1.14. diff --git a/specs/add-auto-flag/tasks.md b/specs/add-auto-flag/tasks.md new file mode 100644 index 00000000..2b591aab --- /dev/null +++ b/specs/add-auto-flag/tasks.md @@ -0,0 +1,311 @@ +# Tasks: add-auto-flag + +## Phase 1: Make It Work + +Focus: Apply all file edits in dependency order. Skill-first (SKILL.md), then command layer, then hooks. + +--- + +- [x] 1.1 Update smart-ralph SKILL.md with --auto definition + - **Files**: `plugins/ralph-specum/skills/smart-ralph/SKILL.md` + - **Do**: + 1. Replace the `--quick` row description to: "Run all planning phases autonomously (research, requirements, design, tasks), then stop before implementation" + 2. Add `--auto` row: "Run all phases including implementation autonomously, no stopping" + 3. Add mutual-exclusivity note: "--quick and --auto are mutually exclusive" + 4. Rename "Quick Mode" execution modes section to "Plan-Only Mode (--quick)" and add "Full Autonomous Mode (--auto)" section with the old Quick Mode description + 5. In Branch Management section: update "Quick mode: auto-create branch" to "Quick or auto mode: auto-create branch, no prompts" + - **Done when**: SKILL.md defines both flags, documents mutual exclusivity, and no longer equates --quick with full autonomous execution + - **Verify**: `grep -n "\-\-auto" plugins/ralph-specum/skills/smart-ralph/SKILL.md | grep -q "auto" && grep -n "mutually exclusive" plugins/ralph-specum/skills/smart-ralph/SKILL.md | grep -q "mutually" && echo PASS` + - **Commit**: `feat(ralph-specum): document --auto flag and redefine --quick in smart-ralph skill` + - _Requirements: FR-8, AC-4.1, AC-4.2, AC-4.3_ + - _Design: ralph-specum section 6_ + +--- + +- [x] 1.2 [P] Update intent-classification.md with --auto parsing + - **Files**: `plugins/ralph-specum/references/intent-classification.md` + - **Do**: + 1. Add `--auto` row to the Argument Parsing table + 2. Prepend mutual-exclusivity rule to the Commit Spec Flag Logic section: "If both --quick and --auto in $ARGUMENTS -> Error: --quick and --auto are mutually exclusive. Use one or the other." + 3. Add `--auto with goal/file -> Auto mode flow (full autonomous)` to the Routing Summary table + 4. Add `Both --quick and --auto -> Error: mutually exclusive` to the Routing Summary table + 5. Add --auto to the examples list + - **Done when**: intent-classification.md documents --auto parsing, mutual-exclusivity rule appears before commitSpec logic, routing table covers all four flag combinations + - **Verify**: `grep -n "\-\-auto" plugins/ralph-specum/references/intent-classification.md | grep -q "auto" && grep -n "mutually exclusive" plugins/ralph-specum/references/intent-classification.md | grep -q "mutually" && echo PASS` + - **Commit**: `feat(ralph-specum): add --auto to intent-classification reference` + - _Requirements: FR-4, AC-3.1_ + - _Design: ralph-specum section 5_ + +- [x] 1.3 [P] Update quick-mode.md to branch on --quick vs --auto + - **Files**: `plugins/ralph-specum/references/quick-mode.md` + - **Do**: + 1. Add "Mode Selector" section at top: "This reference is used for both --quick (plan-only) and --auto (full autonomous) flows. The flows are identical through the Tasks Phase. They diverge at the Transition to Execution step." + 2. In the state-write step (step 5): branch on mode -- `--quick: { quickMode: true, autoMode: false, ... }` / `--auto: { quickMode: false, autoMode: true, ... }` + 3. In the Transition to Execution step (step 16): add fork. --quick path: set `awaitingApproval: true`, output "Plan complete for '$name'. Run /ralph-specum:implement to execute, or review tasks.md first.", STOP. --auto path: existing behavior (count tasks, transition to execution, invoke spec-executor). + 4. Rename "Quick Mode Directive" header to "Autonomous Mode Directive" + - **Done when**: quick-mode.md has a Mode Selector section, step 16 forks by flag, --quick path sets awaitingApproval and stops without invoking spec-executor + - **Verify**: `grep -n "Mode Selector" plugins/ralph-specum/references/quick-mode.md | grep -q "Mode" && grep -n "awaitingApproval" plugins/ralph-specum/references/quick-mode.md | grep -q "awaitingApproval" && grep -n "Autonomous Mode Directive" plugins/ralph-specum/references/quick-mode.md | grep -q "Autonomous" && echo PASS` + - **Commit**: `feat(ralph-specum): split quick-mode.md into --quick (plan-only) and --auto (full autonomous) paths` + - _Requirements: FR-1, FR-5, AC-1.3, AC-1.5_ + - _Design: ralph-specum section 2_ + +--- + +- [ ] 1.4 [VERIFY] Quality checkpoint + - **Do**: Verify the three files edited so far have no obvious broken references + - **Verify**: `grep -rn "autoMode" plugins/ralph-specum/skills/smart-ralph/SKILL.md plugins/ralph-specum/references/intent-classification.md plugins/ralph-specum/references/quick-mode.md | grep -q "autoMode" && echo PASS` + - **Done when**: All three files mention autoMode + - **Commit**: none + +--- + +- [x] 1.5 Update commands/start.md (ralph-specum) + - **Files**: `plugins/ralph-specum/commands/start.md` + - **Do**: + 1. Add `--auto` to the argument-hint line alongside existing flags + 2. In Step 2 (Quick Mode Check): expand to detect both flags. Add mutual-exclusivity check first: if both present, output error and STOP before creating any files. Then route --quick to Step 5 Quick Mode Flow (plan-only), --auto to Step 5 Auto Mode Flow (full autonomous). + 3. In state initialization template: add `"autoMode": false` field alongside existing `"quickMode": false` + 4. Update Step 5 summary line to distinguish plan-only (--quick) from full autonomous (--auto) + 5. Update the "Stop After Each Subagent" exception note from `--quick` to `--quick or --auto` + - **Done when**: start.md argument-hint includes --auto, mutual-exclusivity check precedes flag routing, state template includes autoMode field + - **Verify**: `grep -n "\-\-auto" plugins/ralph-specum/commands/start.md | grep -q "auto" && grep -n "autoMode" plugins/ralph-specum/commands/start.md | grep -q "autoMode" && grep -n "mutually exclusive" plugins/ralph-specum/commands/start.md | grep -q "mutually" && echo PASS` + - **Commit**: `feat(ralph-specum): add --auto flag parsing and mutual-exclusivity check to start.md` + - _Requirements: FR-2, FR-3, AC-2.1, AC-3.1, AC-3.2_ + - _Design: ralph-specum section 1_ + +--- + +- [x] 1.6 [P] Update stop-watcher.sh (ralph-specum) + - **Files**: `plugins/ralph-specum/hooks/scripts/stop-watcher.sh` + - **Do**: + 1. After the existing `QUICK_MODE` read (line ~146), add: `AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false")` + 2. In the quick mode guard block (lines ~159-184): replace the `if [ "$QUICK_MODE" = "true" ]` condition with a merged AUTONOMOUS_MODE variable: + ```bash + AUTONOMOUS_MODE="false" + if [ "$QUICK_MODE" = "true" ] || [ "$AUTO_MODE" = "true" ]; then + AUTONOMOUS_MODE="true" + fi + ``` + Then use `if [ "$AUTONOMOUS_MODE" = "true" ] && [ "$PHASE" != "execution" ]` + 3. Update the REASON string: replace "Quick mode active" with "Autonomous mode active" + 4. Update the jq `--arg msg` string: replace "quick mode" with "autonomous mode" + - **Done when**: stop-watcher reads autoMode, planning guard blocks when either quickMode or autoMode is true, log messages say "autonomous mode" + - **Verify**: `grep -n "AUTO_MODE" plugins/ralph-specum/hooks/scripts/stop-watcher.sh | grep -q "AUTO_MODE" && grep -n "AUTONOMOUS_MODE" plugins/ralph-specum/hooks/scripts/stop-watcher.sh | grep -q "AUTONOMOUS_MODE" && echo PASS` + - **Commit**: `feat(ralph-specum): extend stop-watcher planning guard to cover --auto flag` + - _Requirements: FR-5, FR-6, AC-1.7, AC-2.7_ + - _Design: ralph-specum section 3_ + +- [x] 1.7 [P] Update quick-mode-guard.sh (ralph-specum) + - **Files**: `plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh` + - **Do**: + 1. After the existing `QUICK_MODE` read line, add: `AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false")` + 2. Replace the `if [ "$QUICK_MODE" != "true" ]` guard with: `if [ "$QUICK_MODE" != "true" ] && [ "$AUTO_MODE" != "true" ]; then exit 0; fi` + 3. Update the systemMessage to: "Autonomous mode active: do NOT ask the user any questions. Make opinionated decisions autonomously. Choose the simplest, most conventional approach." + - **Done when**: guard blocks AskUserQuestion when either quickMode or autoMode is true; passes through when both are false + - **Verify**: `grep -n "AUTO_MODE" plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh | grep -q "AUTO_MODE" && grep -n "Autonomous mode" plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh | grep -q "Autonomous" && echo PASS` + - **Commit**: `feat(ralph-specum): extend quick-mode-guard to block AskUserQuestion in --auto mode` + - _Requirements: FR-7, AC-1.6, AC-2.6_ + - _Design: ralph-specum section 4_ + +--- + +- [ ] 1.8 [VERIFY] Quality checkpoint: ralph-specum changes consistent + - **Do**: Verify all ralph-specum files reference autoMode consistently + - **Verify**: `grep -rn "autoMode" plugins/ralph-specum/commands/start.md plugins/ralph-specum/hooks/scripts/stop-watcher.sh plugins/ralph-specum/hooks/scripts/quick-mode-guard.sh | wc -l | xargs -I{} sh -c '[ {} -ge 4 ] && echo PASS || echo FAIL'` + - **Done when**: At least 4 autoMode references across the three hook/command files + - **Commit**: none + +--- + +- [x] 1.9 Update commands/start.md (ralph-speckit) + - **Files**: `plugins/ralph-speckit/commands/start.md` + - **Do**: + 1. After the Parse Arguments section, add a "Flag Parsing" block: detect --quick (plan-only) and --auto (full autonomous). Add mutual-exclusivity check: if both present, output "Error: --quick and --auto are mutually exclusive. Use one or the other." and STOP before creating any feature directory. + 2. In the Initialize State File block: add `"quickMode": false` and `"autoMode": false` fields. Set `quickMode: true` when --quick detected; set `autoMode: true` when --auto detected. + 3. After state init, add post-init routing: if quickMode=true or autoMode=true, skip interactive prompts and run all spec phases sequentially. If quickMode=true after tasks phase: set awaitingApproval=true, output completion message, STOP. If autoMode=true: transition to execution. + - **Done when**: start.md has flag parsing with mutual-exclusivity check, state init includes both fields, post-init routing block handles both autonomous modes + - **Verify**: `grep -n "quickMode" plugins/ralph-speckit/commands/start.md | grep -q "quickMode" && grep -n "autoMode" plugins/ralph-speckit/commands/start.md | grep -q "autoMode" && grep -n "mutually exclusive" plugins/ralph-speckit/commands/start.md | grep -q "mutually" && echo PASS` + - **Commit**: `feat(ralph-speckit): add --quick and --auto flag parsing to start.md` + - _Requirements: FR-9, AC-5.1, AC-5.2_ + - _Design: ralph-speckit section 1_ + +--- + +- [ ] 1.10 [P] Update stop-watcher.sh (ralph-speckit) + - **Files**: `plugins/ralph-speckit/hooks/scripts/stop-watcher.sh` + - **Do**: + 1. After the existing state reads (PHASE, TASK_INDEX, etc.), add reads for both flags: + ```bash + QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") + AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") + ``` + 2. After the global iteration check, add a planning phase guard block (mirrors ralph-specum pattern): + ```bash + if { [ "$QUICK_MODE" = "true" ] || [ "$AUTO_MODE" = "true" ]; } && [ "$PHASE" != "execution" ]; then + STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false") + if [ "$STOP_HOOK_ACTIVE" = "true" ]; then exit 0; fi + jq -n --arg reason "Autonomous mode active — continue spec phase: $PHASE for $FEATURE_NAME." \ + --arg msg "Ralph-speckit autonomous mode: continue $PHASE phase" \ + '{"decision": "block", "reason": $reason, "systemMessage": $msg}' + exit 0 + fi + ``` + 3. In the execution loop block (line ~129), add an `awaitingApproval` check before the continuation prompt: + ```bash + AWAITING=$(jq -r '.awaitingApproval // false' "$STATE_FILE" 2>/dev/null || echo "false") + if [ "$AWAITING" = "true" ]; then + echo "[ralph-speckit] awaitingApproval=true, allowing stop for user gate" >&2 + exit 0 + fi + ``` + - **Done when**: stop-watcher reads quickMode and autoMode, blocks during planning phases for either autonomous mode, and checks awaitingApproval before continuing execution loop + - **Verify**: `grep -n "QUICK_MODE\|AUTO_MODE\|awaitingApproval" plugins/ralph-speckit/hooks/scripts/stop-watcher.sh | wc -l | xargs -I{} sh -c '[ {} -ge 3 ] && echo PASS || echo FAIL'` + - **Commit**: `feat(ralph-speckit): add autonomous mode planning guard and awaitingApproval check to stop-watcher` + - _Requirements: FR-9, AC-5.3, AC-5.4_ + - _Design: ralph-speckit section 2_ + +- [x] 1.11 [P] Create quick-mode-guard.sh (ralph-speckit) and register hook + - **Files**: `plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh` (new), `plugins/ralph-speckit/.claude-plugin/plugin.json` + - **Do**: + 1. Create `plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh` mirroring the ralph-specum guard but using `.speckit-state.json` and `.specify/specs/$FEATURE_NAME/` path: + ```bash + #!/usr/bin/env bash + # PreToolUse hook: Block AskUserQuestion in autonomous modes (quickMode or autoMode) + set -euo pipefail + INPUT=$(cat) + command -v jq >/dev/null 2>&1 || exit 0 + CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true) + [ -z "$CWD" ] && exit 0 + CURRENT_FEATURE_FILE="$CWD/.specify/.current-feature" + [ ! -f "$CURRENT_FEATURE_FILE" ] && exit 0 + FEATURE_NAME=$(cat "$CURRENT_FEATURE_FILE" 2>/dev/null | tr -d '[:space:]') + [ -z "$FEATURE_NAME" ] && exit 0 + STATE_FILE="$CWD/.specify/specs/$FEATURE_NAME/.speckit-state.json" + [ ! -f "$STATE_FILE" ] && exit 0 + QUICK_MODE=$(jq -r '.quickMode // false' "$STATE_FILE" 2>/dev/null || echo "false") + AUTO_MODE=$(jq -r '.autoMode // false' "$STATE_FILE" 2>/dev/null || echo "false") + if [ "$QUICK_MODE" != "true" ] && [ "$AUTO_MODE" != "true" ]; then exit 0; fi + jq -n '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "Autonomous mode active: do NOT ask the user any questions. Make opinionated decisions autonomously."}' + ``` + 2. Make the new script executable: `chmod +x plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh` + 3. In `plugins/ralph-speckit/.claude-plugin/plugin.json`, add a `hooks` array with the new entry: + ```json + "hooks": [ + { + "event": "PreToolUse", + "matcher": "AskUserQuestion", + "command": "hooks/scripts/quick-mode-guard.sh" + } + ] + ``` + 4. Bump ralph-speckit version in plugin.json (patch: 0.5.2 -> 0.5.3) + - **Done when**: guard script exists, is executable, plugin.json registers it as a PreToolUse hook + - **Verify**: `[ -x plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh ] && grep -q "AskUserQuestion" plugins/ralph-speckit/.claude-plugin/plugin.json && echo PASS` + - **Commit**: `feat(ralph-speckit): add AskUserQuestion guard for autonomous modes` + - _Requirements: FR-9, AC-5.5_ + - _Design: ralph-speckit sections 3 and 4_ + +--- + +- [ ] 1.12 [VERIFY] Quality checkpoint: ralph-speckit changes consistent + - **Do**: Verify speckit state file, hook, and plugin.json are all coherent + - **Verify**: `grep -rn "autoMode\|quickMode" plugins/ralph-speckit/commands/start.md plugins/ralph-speckit/hooks/scripts/stop-watcher.sh plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh | grep -q "autoMode" && echo PASS` + - **Done when**: autoMode appears in all three speckit files + - **Commit**: none + +--- + +- [x] 1.13 [P] Update ralph-specum-codex skills + - **Files**: `plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md`, `plugins/ralph-specum-codex/skills/ralph-specum/SKILL.md` + - **Do**: + 1. In `ralph-specum-start/SKILL.md` Step 1 (parse): add `--auto` to the flag list. Add mutual-exclusivity check: "If both --quick and --auto present: Respond 'Error: --quick and --auto are mutually exclusive. Use one or the other.' STOP." + 2. In `ralph-specum-start/SKILL.md` Step 7 (state initialization): add `autoMode` field. Set `quickMode: true, autoMode: false` for --quick; `quickMode: false, autoMode: true` for --auto. + 3. In `ralph-specum-start/SKILL.md` Step 11 (quick mode behavior): split into two cases. --quick: generate all artifacts autonomously, then set awaitingApproval: true, output "Plan complete. Run /ralph-specum:implement to execute.", STOP. --auto: generate all artifacts autonomously then continue into implementation without stopping (current --quick behavior). + 4. In `ralph-specum/SKILL.md` Core Rules section: update rule 12 to distinguish --quick (plan-only) from --auto (full autonomous) and note mutual exclusivity. Update rule 7 to add `autoMode` to the preserve list alongside `quickMode`. + - **Done when**: ralph-specum-start/SKILL.md handles both flags with mutual-exclusivity check and split step 11; ralph-specum/SKILL.md rules 7 and 12 reference autoMode + - **Verify**: `grep -rn "autoMode\|mutually exclusive" plugins/ralph-specum-codex/skills/ | wc -l | xargs -I{} sh -c '[ {} -ge 4 ] && echo PASS || echo FAIL'` + - **Commit**: `feat(ralph-specum-codex): add --auto flag and split --quick/--auto behavior in skills` + - _Requirements: FR-10, AC-6.1, AC-6.2, AC-6.3, AC-6.4_ + - _Design: ralph-specum-codex sections 1 and 2_ + +--- + +- [ ] 1.14 Bump plugin versions in marketplace.json + - **Files**: `.claude-plugin/marketplace.json`, `plugins/ralph-specum/.claude-plugin/plugin.json` + - **Do**: + 1. Bump ralph-specum version: 4.9.1 -> 4.10.0 (minor: new --auto feature) in `plugins/ralph-specum/.claude-plugin/plugin.json` + 2. Update ralph-specum entry in `.claude-plugin/marketplace.json` to match: 4.9.1 -> 4.10.0 + 3. Update ralph-speckit entry in `.claude-plugin/marketplace.json` to match plugin.json: 0.5.2 -> 0.5.3 + 4. If ralph-specum-codex has an entry in marketplace.json, bump its version too (patch) + - **Done when**: ralph-specum is 4.10.0 in both files, ralph-speckit is 0.5.3 in both files + - **Verify**: `grep -A2 '"ralph-specum"' .claude-plugin/marketplace.json | grep -q "4.10.0" && grep -A2 '"ralph-speckit"' .claude-plugin/marketplace.json | grep -q "0.5.3" && echo PASS` + - **Commit**: `chore: bump ralph-specum to 4.10.0 and ralph-speckit to 0.5.3 for --auto flag` + - _Design: Implementation Steps 13_ + +--- + +## Phase 2: Verification + +- [ ] V4 [VERIFY] Full AC checklist + - **Do**: + 1. AC-1.1/2.1: `grep -rn "\-\-auto\|\-\-quick" plugins/ralph-specum/commands/start.md plugins/ralph-speckit/commands/start.md plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md | grep -q "auto" && echo AC-1.1-2.1-PASS` + 2. AC-3.1/3.3: `grep -rn "mutually exclusive" plugins/ralph-specum/commands/start.md plugins/ralph-speckit/commands/start.md plugins/ralph-specum-codex/skills/ralph-specum-start/SKILL.md | wc -l | xargs -I{} sh -c '[ {} -ge 3 ] && echo AC-3.1-3.3-PASS || echo AC-3.1-3.3-FAIL'` + 3. AC-1.4/2.4: `grep -rn "autoMode" plugins/ralph-specum/commands/start.md plugins/ralph-specum/references/quick-mode.md | grep -q "autoMode" && echo AC-1.4-2.4-PASS` + 4. AC-5.5: `[ -x plugins/ralph-speckit/hooks/scripts/quick-mode-guard.sh ] && grep -q "AskUserQuestion" plugins/ralph-speckit/.claude-plugin/plugin.json && echo AC-5.5-PASS` + 5. AC-4.1/4.2/4.3: `grep -n "mutually exclusive\|--auto\|--quick" plugins/ralph-specum/skills/smart-ralph/SKILL.md | wc -l | xargs -I{} sh -c '[ {} -ge 3 ] && echo AC-4-PASS || echo AC-4-FAIL'` + - **Verify**: All 5 checks above print PASS + - **Done when**: Every AC outputs PASS + - **Commit**: none + +- [ ] V5 [VERIFY] No broken cross-references + - **Do**: + 1. Verify quick-mode.md is still referenced correctly from start.md: `grep -n "quick-mode" plugins/ralph-specum/commands/start.md | grep -q "quick-mode" && echo PASS` + 2. Verify stop-watcher.sh in ralph-specum still references QUICK_MODE for backward compat: `grep -n "QUICK_MODE" plugins/ralph-specum/hooks/scripts/stop-watcher.sh | grep -q "QUICK_MODE" && echo PASS` + 3. Verify ralph-speckit plugin.json is valid JSON: `jq . plugins/ralph-speckit/.claude-plugin/plugin.json > /dev/null && echo PASS` + 4. Verify ralph-specum plugin.json is valid JSON: `jq . plugins/ralph-specum/.claude-plugin/plugin.json > /dev/null && echo PASS` + - **Verify**: All 4 checks print PASS + - **Done when**: No broken references, all JSON files parse cleanly + - **Commit**: none + +## Phase 3: PR + +- [ ] 3.1 Create PR + - **Do**: + 1. Verify branch: `git branch --show-current` + 2. Push: `git push -u origin $(git branch --show-current)` + 3. Create PR: `gh pr create --title "feat: add --auto flag, redefine --quick as plan-only" --body "$(cat <<'EOF' +## Summary + +- Redefines \`--quick\` as plan-only mode: runs all 4 planning phases autonomously then stops before implementation +- Adds \`--auto\` as full autonomous mode (what \`--quick\` currently does) +- Applies both flags across ralph-specum, ralph-speckit, and ralph-specum-codex +- \`--quick\` and \`--auto\` are mutually exclusive; combining them errors immediately + +## Migration + +Existing \`--quick\` users: replace with \`--auto\` to restore the old behavior. + +## Files changed + +- ralph-specum: start.md, quick-mode.md, intent-classification.md, stop-watcher.sh, quick-mode-guard.sh, smart-ralph SKILL.md +- ralph-speckit: start.md, stop-watcher.sh, quick-mode-guard.sh (new), plugin.json +- ralph-specum-codex: ralph-specum-start/SKILL.md, ralph-specum/SKILL.md +- marketplace.json, plugin.json (version bumps) +EOF +)"` + - **Verify**: `gh pr view --json url | jq -r .url` + - **Done when**: PR created, URL returned + - **Commit**: none + +- [ ] 3.2 [VERIFY] CI passes + - **Do**: `gh pr checks --watch` + - **Verify**: All checks green + - **Done when**: No failing checks + - **Commit**: none (fix and push if checks fail) + +## Notes + +- **Backward compat**: Old state files without `autoMode` field work fine. All reads use `jq -r '.autoMode // false'`. +- **Key asymmetry**: `--quick` sets `awaitingApproval: true` after tasks phase (coordinator does this, not stop-watcher). Stop-watcher already exits 0 when awaitingApproval=true, so no stop-watcher change is needed for the plan-only stop behavior. +- **ralph-specum-codex**: No shell hooks to modify. Intent detection only. +- **ralph-speckit plugin.json**: Currently has no `hooks` array at all. Task 1.11 adds it fresh. diff --git a/tests/codex-platform.bats b/tests/codex-platform.bats index 7e0ee1eb..aaf977d0 100644 --- a/tests/codex-platform.bats +++ b/tests/codex-platform.bats @@ -279,7 +279,7 @@ for skill, tokens in expected.items(): assert_python ' pairs = { - "start": ["quick mode", "granularity", ".current-epic", "awaitingApproval"], + "start": ["--quick", "granularity", ".current-epic", "awaitingApproval"], "triage": ["specs/_epics", ".current-epic", ".epic-state.json", "dependencies"], "research": ["brainstorming", "research.md", "verification tooling"], "requirements": ["brainstorming", "requirements.md", "awaitingApproval"], diff --git a/tests/interview-framework.bats b/tests/interview-framework.bats index d07db162..f3ee0d87 100644 --- a/tests/interview-framework.bats +++ b/tests/interview-framework.bats @@ -61,11 +61,11 @@ GOAL_INTERVIEW="plugins/ralph-specum/references/goal-interview.md" grep -q "skills/interview-framework/SKILL.md" "$GOAL_INTERVIEW" } -@test "plugin.json version is 4.9.1" { - grep -q '"version": "4.9.1"' "plugins/ralph-specum/.claude-plugin/plugin.json" +@test "plugin.json version is 4.10.0" { + grep -q '"version": "4.10.0"' "plugins/ralph-specum/.claude-plugin/plugin.json" } -@test "marketplace.json ralph-specum version is 4.9.1" { +@test "marketplace.json ralph-specum version is 4.10.0" { version=$(jq -r '.plugins[] | select(.name == "ralph-specum") | .version' ".claude-plugin/marketplace.json") - [ "$version" = "4.9.1" ] + [ "$version" = "4.10.0" ] }