This commit is contained in:
@@ -67,6 +67,8 @@ Always use the exact name from this list — do not fall back to 'general-purpos
|
||||
|
||||
<process>
|
||||
|
||||
**Compact Content Gate.** Read and follow `gsd-core/references/compact-content-gate.md` now — it states the `workflow.compact_content` check and the resolution rule this spine defers to. When it directs a Read, read `gsd-core/workflows/execute-phase/detail/elaboration.md` in full before continuing past this point; its content elaborates on two steps below (check_interactive_mode, cross_ai_delegation).
|
||||
|
||||
<step name="parse_args" priority="first">
|
||||
Parse `$ARGUMENTS` before loading any context:
|
||||
|
||||
@@ -211,7 +213,7 @@ if [ "$TDD_MODE" = "true" ]; then
|
||||
# literal grep hard-halts on a correct unpadded RED commit.
|
||||
PHASE_N=$((10#${PHASE_NUMBER}))
|
||||
PLAN_N=$((10#${PLAN_ID}))
|
||||
PLAN_SCOPE_RE="^[a-z]+\((0*${PHASE_N})-(0*${PLAN_N})\):"
|
||||
PLAN_SCOPE_RE="^[a-z]+\((0*${PHASE_N})-(0*${PLAN_N})\):" # TDD gate's own scope check
|
||||
TDD_MILESTONE_BASE=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
||||
RED_COMMIT=$(git log --oneline -E ${TDD_MILESTONE_BASE:+"$TDD_MILESTONE_BASE..HEAD"} --grep="${PLAN_SCOPE_RE}" -- "**/*.test.*" "**/*.spec.*" "tests/" | head -1)
|
||||
if [ -z "$RED_COMMIT" ]; then
|
||||
@@ -250,43 +252,7 @@ Write these answers inline before continuing. If a blocking anti-pattern cannot
|
||||
</step>
|
||||
|
||||
<step name="check_interactive_mode">
|
||||
**Parse `--interactive` flag from $ARGUMENTS.**
|
||||
|
||||
**If `--interactive` flag present:** Switch to interactive execution mode.
|
||||
|
||||
Interactive mode executes plans sequentially **inline** (no subagent spawning) with user
|
||||
checkpoints between tasks. The user can review, modify, or redirect work at any point.
|
||||
|
||||
**Interactive execution flow:**
|
||||
|
||||
1. Load plan inventory as normal (discover_and_group_plans)
|
||||
2. For each plan (sequentially, ignoring wave grouping):
|
||||
|
||||
a. **Present the plan to the user:**
|
||||
```
|
||||
## Plan {plan_id}: {plan_name}
|
||||
|
||||
Objective: {from plan file}
|
||||
Tasks: {task_count}
|
||||
|
||||
Options:
|
||||
- Execute (proceed with all tasks)
|
||||
- Review first (show task breakdown before starting)
|
||||
- Skip (move to next plan)
|
||||
- Stop (end execution, save progress)
|
||||
```
|
||||
|
||||
b. **If "Review first":** Read and display the full plan file. Ask again: Execute, Modify, Skip.
|
||||
|
||||
c. **If "Execute":** Read and follow `~/.claude/gsd-core/workflows/execute-plan.md` **inline**
|
||||
(do NOT spawn a subagent). Execute tasks one at a time.
|
||||
|
||||
d. **After each task:** Pause briefly. If the user intervenes (types anything), stop and address
|
||||
their feedback before continuing. Otherwise proceed to next task.
|
||||
|
||||
e. **After plan complete:** Show results, commit, create SUMMARY.md, then present next plan.
|
||||
|
||||
3. After all plans: proceed to verification (same as normal mode).
|
||||
**Parse `--interactive` flag from $ARGUMENTS.** If present, switch to interactive execution mode: plans run sequentially **inline** (no subagent spawning, ignoring wave grouping), reading `execute-plan.md` directly rather than dispatching `gsd-executor`. **Once per plan** (not per task), present a 4-option menu (execute / review-first / skip / stop) before starting that plan's tasks. Once executing, tasks run one at a time with only a brief pause after each — the agent stops mid-plan only if the user actually types something, it does not re-show the menu. After all plans, proceed to verification as normal. Full flow (the exact presentation format, the review-first sub-branch): `gsd-core/workflows/execute-phase/detail/elaboration.md` § 1.
|
||||
|
||||
**Skip to handle_branching step** (interactive plans execute inline after grouping).
|
||||
</step>
|
||||
@@ -422,74 +388,11 @@ Report:
|
||||
</step>
|
||||
|
||||
<step name="cross_ai_delegation">
|
||||
**Optional step 2.5 — Delegate plans to an external AI runtime.**
|
||||
**Optional step 2.5 — Delegate plans to an external AI runtime.** Runs after plan discovery, before wave execution. Activates when `--cross-ai` forces all incomplete plans, `--no-cross-ai` disables it entirely, or (default) a plan's `cross_ai: true` frontmatter agrees with the `workflow.cross_ai_execution` config. If no plan is marked, skip to execute_waves; if marked but `workflow.cross_ai_command` is unset, error and tell the user to set it.
|
||||
|
||||
This step runs after plan discovery and before normal wave execution. It identifies plans
|
||||
that should be delegated to an external AI command and executes them via stdin-based prompt
|
||||
delivery. Plans handled here are removed from the execute_waves plan list so the normal
|
||||
executor skips them.
|
||||
For each marked plan: build a self-contained prompt from the plan's `<objective>`/`<tasks>` plus PROJECT.md context, warn on a dirty working tree, then run the configured command **wrapped in `gsd_run run-with-timeout "${CROSS_AI_TIMEOUT}"` (config `workflow.cross_ai_timeout`, default 300s) — never run it unbounded** — with the prompt piped to **stdin, never shell-interpolated, to prevent injection**. On success (exit 0): validate the captured SUMMARY output is non-empty and structurally valid before writing it as the plan's SUMMARY.md, update STATE/ROADMAP, mark handled. On failure (non-zero exit, or the summary fails that validation): show the error, warn about possible partial edits, and offer **retry** / **skip** (falls back to the normal executor) / **abort**. Successfully handled plans are removed from execute_waves' list; skipped-to-fallback plans remain in it.
|
||||
|
||||
**Activation logic:**
|
||||
|
||||
1. If `CROSS_AI_DISABLED` is true (`--no-cross-ai` flag): skip this step entirely.
|
||||
2. If `CROSS_AI_FORCE` is true (`--cross-ai` flag): mark ALL incomplete plans for cross-AI execution.
|
||||
3. Otherwise: check each plan's frontmatter for `cross_ai: true` AND verify config
|
||||
`workflow.cross_ai_execution` is `true`. Plans matching both conditions are marked for cross-AI.
|
||||
|
||||
```bash
|
||||
CROSS_AI_ENABLED=$(gsd_run query config-get workflow.cross_ai_execution --raw 2>/dev/null || echo "false")
|
||||
CROSS_AI_CMD=$(gsd_run query config-get workflow.cross_ai_command --raw 2>/dev/null || echo "")
|
||||
CROSS_AI_TIMEOUT=$(gsd_run query config-get workflow.cross_ai_timeout --raw 2>/dev/null || echo "300")
|
||||
```
|
||||
|
||||
**If no plans are marked for cross-AI:** Skip to execute_waves.
|
||||
|
||||
**If plans are marked but `cross_ai_command` is empty:** Error — tell user to set
|
||||
`workflow.cross_ai_command` via `gsd_run query config-set workflow.cross_ai_command "<command>"`.
|
||||
|
||||
**For each cross-AI plan (sequentially):**
|
||||
|
||||
1. **Construct the task prompt** from the plan file:
|
||||
- Extract `<objective>` and `<tasks>` sections from the PLAN.md
|
||||
- Append PROJECT.md context (project name, description, tech stack)
|
||||
- Format as a self-contained execution prompt
|
||||
|
||||
2. **Check for dirty working tree before execution:**
|
||||
```bash
|
||||
if ! git diff --quiet HEAD 2>/dev/null; then
|
||||
echo "WARNING: dirty working tree detected — the external AI command may produce uncommitted changes that conflict with existing modifications"
|
||||
fi
|
||||
```
|
||||
|
||||
3. **Run the external command** from the project root, writing the prompt to stdin.
|
||||
Never shell-interpolate the prompt — always pipe via stdin to prevent injection:
|
||||
```bash
|
||||
echo "$TASK_PROMPT" | gsd_run run-with-timeout "${CROSS_AI_TIMEOUT}" -- ${CROSS_AI_CMD} > "$CANDIDATE_SUMMARY" 2>"$ERROR_LOG"
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
4. **Evaluate the result:**
|
||||
|
||||
**Success (exit 0 + valid summary):**
|
||||
- Read `$CANDIDATE_SUMMARY` and validate it contains meaningful content
|
||||
(not empty, has at least a heading and description — a valid SUMMARY.md structure)
|
||||
- Write it as the plan's SUMMARY.md file
|
||||
- Update STATE.md plan status to complete
|
||||
- Update ROADMAP.md progress
|
||||
- Mark plan as handled — skip it in execute_waves
|
||||
|
||||
**Failure (non-zero exit or invalid summary):**
|
||||
- Display the error output and exit code
|
||||
- Warn: "The external command may have left uncommitted changes or partial edits
|
||||
in the working tree. Review `git status` and `git diff` before proceeding."
|
||||
- Offer three choices:
|
||||
- **retry** — run the same plan through cross-AI again
|
||||
- **skip** — fall back to normal executor for this plan (re-add to execute_waves list)
|
||||
- **abort** — stop execution entirely, preserve state for resume
|
||||
|
||||
5. **After all cross-AI plans processed:** Remove successfully handled plans from the
|
||||
incomplete plan list so execute_waves skips them. Any skipped-to-fallback plans remain
|
||||
in the list for normal executor processing.
|
||||
Exact bash and per-branch wording: `gsd-core/workflows/execute-phase/detail/elaboration.md` § 2.
|
||||
</step>
|
||||
|
||||
<step name="execute_waves">
|
||||
@@ -1132,6 +1035,7 @@ When executor returns a checkpoint AND `AUTO_MODE` is `true`:
|
||||
- **decision** → Auto-spawn continuation agent with `{user_response}` = first option from checkpoint details. Log `⚡ Auto-selected: [option]`. **Except `blocking-human`.**
|
||||
- **human-action** → Present to user (existing behavior below). Auth gates cannot be automated.
|
||||
|
||||
<!-- gsd:protected -->
|
||||
**Carve-out — overrides all branches above.** If the returned `Gate:` is `blocking-human` (precondition-unmet, #3210), or its `<what-built>` mentions `Package verification required before install` or `Package install failed — human verification required`, never auto-approve or auto-select. Present to user (standard flow). Log `⛔ blocking-human gate — auto-mode suspended`.
|
||||
|
||||
**Standard flow (not auto-mode, human-action, or blocking-human):**
|
||||
|
||||
Reference in New Issue
Block a user