* feat(execute-phase): classify quota/rate-limit failures across runtimes (#3095) Dispatched executor subagents that die from provider quota or rate-limit errors currently look identical to a crashed agent to the orchestrator — so step 7's recovery prompt offers "retry now" when the right action is "wait for reset and resume". This adds a runtime-agnostic classifier and wires execute-phase step 7 to it. - `agent.classify-failure` SDK query returns `{class: 'quota-exceeded' | 'classify-handoff-bug' | 'unknown-failure', sentinel?, retryAfterSeconds?}`. Sentinels cover Claude Code (`usage limit`, `429`), Copilot CLI (`rate_limit`, `user_weekly_rate_limited`), Codex (`usage_limit_reached`, `too many requests`), and Gemini (`RESOURCE_EXHAUSTED`, `exceeded your`). - `execute-phase.md` step 7 now branches on the class. Quota-exceeded presents a wait-for-reset prompt and points at the safe-resume gate landing in #3212 instead of re-dispatching a fresh executor. - `docs/research/provider-rate-limit-signals.md` records the proactive (header / SDK event) signals each provider exposes and the upstream Claude Code / Copilot / Codex issues blocking hook-side detection — the forward path once host runtimes surface them. Resume-from-partial-worktree and context-load metrics from the original report are deliberately out of scope; they overlap #3212's `state.verify-against-disk` work already in flight. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(execute): render quota retry hint and refresh alias artifacts * fix(workflow): restore slash namespace and execute-phase size budget --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1005,46 +1005,46 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
||||
---
|
||||
```
|
||||
|
||||
- Bad: "Wave 2 complete. Proceeding to Wave 3."
|
||||
- Good: "Terrain system complete — 3 biome types, height-based texturing, physics collision meshes. Vehicle physics (Wave 3) can now reference ground surfaces."
|
||||
|
||||
7. **Handle failures:**
|
||||
|
||||
**Known Claude Code bug (classifyHandoffIfNeeded):** If an agent reports "failed" with error containing `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a GSD or agent issue. The error fires in the completion handler AFTER all tool calls finish. In this case: run the same spot-checks as step 5 (SUMMARY.md exists, git commits present, no Self-Check: FAILED). If spot-checks PASS → treat as **successful**. If spot-checks FAIL → treat as real failure below.
|
||||
|
||||
For real failures: report which plan failed → ask "Continue?" or "Stop?" → if continue, dependent plans may also fail. If stop, partial completion report.
|
||||
**Step 7.0 — classify before branching (#3095):**
|
||||
```bash
|
||||
CLASS_JSON=$(gsd-sdk query agent.classify-failure -- "$AGENT_RETURN_BODY")
|
||||
CLASS=$(echo "$CLASS_JSON" | jq -r '.class')
|
||||
SENTINEL=$(echo "$CLASS_JSON" | jq -r '.sentinel // empty')
|
||||
RETRY_AFTER=$(echo "$CLASS_JSON" | jq -r '.retryAfterSeconds // empty')
|
||||
if [ -n "$RETRY_AFTER" ]; then RETRY_HINT=" Provider hinted retry-after: ${RETRY_AFTER}s"; else RETRY_HINT=""; fi
|
||||
```
|
||||
One classifier branch handles sentinels across Claude/Copilot/Codex/Gemini. Reference: `docs/research/provider-rate-limit-signals.md`.
|
||||
**Step 7.1 — `class == "quota-exceeded"`:**
|
||||
Do not offer "retry now". Run step-5 spot-check first; if SUMMARY.md is missing but commits exist, route to safe-resume (`state.verify-against-disk`) instead of immediate redispatch.
|
||||
```text
|
||||
⚠ Plan {plan_id} terminated by provider quota / rate limit
|
||||
Runtime sentinel: {SENTINEL}
|
||||
{RETRY_HINT}
|
||||
Partial commits on worktree branch: {N}
|
||||
SUMMARY.md present: {yes|no}
|
||||
1. Wait for quota reset, then resume (recommended)
|
||||
2. Switch to a different runtime / model and resume
|
||||
3. Abort phase and report partial state
|
||||
```
|
||||
Re-run `/gsd:execute-phase` after quota reset for Option 1.
|
||||
**Step 7.2 — `class == "classify-handoff-bug"`:**
|
||||
If error contains `classifyHandoffIfNeeded is not defined`, treat as Claude runtime bug. Run the same step-5 spot-checks; PASS => treat as success, FAIL => fall through.
|
||||
**Step 7.3 — `class == "unknown-failure"`:**
|
||||
Report failed plan and ask Continue/Stop; continuing may cascade into dependent plan failures.
|
||||
|
||||
7b. **Pre-wave dependency check (waves 2+ only):**
|
||||
|
||||
Before spawning wave N+1, for each plan in the upcoming wave:
|
||||
```bash
|
||||
gsd-sdk query verify.key-links {phase_dir}/{plan}-PLAN.md
|
||||
```
|
||||
|
||||
If any key-link from a PRIOR wave's artifact fails verification:
|
||||
|
||||
## Cross-Plan Wiring Gap
|
||||
|
||||
| Plan | Link | From | Expected Pattern | Status |
|
||||
|------|------|------|-----------------|--------|
|
||||
| {plan} | {via} | {from} | {pattern} | NOT FOUND |
|
||||
|
||||
Wave {N} artifacts may not be properly wired. Options:
|
||||
1. Investigate and fix before continuing
|
||||
2. Continue (may cause cascading failures in wave {N+1})
|
||||
|
||||
Key-links referencing files in the CURRENT (upcoming) wave are skipped.
|
||||
|
||||
Before wave N+1, run `gsd-sdk query verify.key-links {phase_dir}/{plan}-PLAN.md` for each upcoming plan.
|
||||
If any PRIOR-wave artifact link fails, present:
|
||||
- `## Cross-Plan Wiring Gap` with plan/link/from/pattern rows
|
||||
- Options: investigate+fix before continue, or continue with cascade risk
|
||||
Skip key-links that reference files in the CURRENT (upcoming) wave.
|
||||
8. **Execute checkpoint plans between waves** — see `<checkpoint_handling>`.
|
||||
|
||||
9. **Proceed to next wave.**
|
||||
</step>
|
||||
|
||||
<step name="checkpoint_handling">
|
||||
Plans with `autonomous: false` require user interaction.
|
||||
|
||||
**Auto-mode checkpoint handling:**
|
||||
|
||||
Read auto-advance config (chain flag OR user preference — same boolean as `check.auto-mode`):
|
||||
```bash
|
||||
AUTO_MODE=$(gsd-sdk query check auto-mode --pick active 2>/dev/null || echo "false")
|
||||
@@ -1785,6 +1785,7 @@ For 1M+ context models, consider:
|
||||
</context_efficiency>
|
||||
|
||||
<failure_handling>
|
||||
- **Quota / rate-limit (any runtime — #3095):** Agent return body contains a sentinel like `usage limit`, `rate limit`, `429`, `too many requests`, `RESOURCE_EXHAUSTED`, `usage_limit_reached`. Route via `gsd-sdk query agent.classify-failure` → `class: "quota-exceeded"`. Do not offer retry-now; the right action is wait-for-reset and resume.
|
||||
- **classifyHandoffIfNeeded false failure:** Agent reports "failed" but error is `classifyHandoffIfNeeded is not defined` → Claude Code bug, not GSD. Spot-check (SUMMARY exists, commits present) → if pass, treat as success
|
||||
- **Agent fails mid-plan:** Missing SUMMARY.md → report, ask user how to proceed
|
||||
- **Dependency chain breaks:** Wave 1 fails → Wave 2 dependents likely fail → user chooses attempt or skip
|
||||
|
||||
Reference in New Issue
Block a user