Skip to content

Commit 4dfdb7c

Browse files
garrytanclaude
andauthored
v1.57.2.0 feat: AskUserQuestion prose fallback when the tool fails at runtime (garrytan#1908)
* feat(auq): add gstack-session-kind + echo SESSION_KIND in preamble Classifies the session as spawned | headless | interactive from env markers (OPENCLAW_SESSION / GSTACK_HEADLESS / CONDUCTOR_* / CLAUDE_CODE_ENTRYPOINT / CI), defaulting to interactive. Echoed once at skill start alongside BRANCH/REPO_MODE so the AskUserQuestion-failure fallback can branch without a shell-out at failure time. Degrade-safe: empty/error => interactive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(auq): prose fallback when AskUserQuestion fails (interactive sessions) On a genuine AUQ failure (tool absent, or present-but-erroring like Conductor's flaky MCP returning '[Tool result missing due to internal error]'): retry once, then branch on SESSION_KIND — spawned auto-chooses, headless BLOCKs, interactive renders a prose decision brief the user answers by typing a letter. The prose fallback MUST surface the triad: a clear ELI10 of the issue, a per-choice Completeness score, and a recommendation+why (one paragraph per choice). Carves out the [plan-tune auto-decide] denial as NOT a failure, and qualifies the former 'tool_use, not prose' assertions so the rule isn't self-contradicting. Tests pin the triad, the SESSION_KIND branch, the OV2 collision guard, the always-loaded guarantee, and a cross-file invariant on the auto-decide prefix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(auq): default GSTACK_HEADLESS=1 in eval/E2E runners Headless harness runs classify as headless (BLOCK on AUQ failure rather than emit a prose question no one reads). SDK runner uses ambient mutation, not the Options.env object, to avoid breaking the SDK auth pipeline. Interactive-path suites opt out by overriding the env per-run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(auq): defensive PostToolUse error-fallback hook (OV3:B) When an AskUserQuestion call returns an error/missing result, this hook injects additionalContext reminding the model to run the prose fallback for the current SESSION_KIND. It does not render prose itself — it guarantees the reminder fires at the moment of failure instead of relying on the model recalling SESSION_KIND. Inert on success and inert if the platform never invokes PostToolUse on tool errors (unverified — could not force the Conductor MCP error in a harness; see the spike doc). The prompt-level fallback covers the case regardless. Decision logic is unit-tested deterministically; registered in setup beside the existing AUQ hooks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(auq): regenerate SKILL.md for all hosts + refresh ship goldens Regenerated from the resolver changes (gen:skill-docs --host all). Refreshes the byte-exact ship golden fixtures (claude/codex/factory). Spec prose tightened so the cross-cutting preamble addition stays under the 5% per-skill parity ceiling (investigate 4.8%) — guard unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(test): kebab testNames for section-loading E2Es to match TOUCHFILES keys The two section-loading E2E tests used display-form testNames ('/ship section-loading', '/plan-ceo-review section-loading') while every other E2E testName and their E2E_TOUCHFILES keys are kebab. The completeness gate does an exact `name in E2E_TOUCHFILES` check, so it failed (pre-existing on main); diff- based selection also couldn't match them. Align to ship-section-loading / plan-ceo-section-loading. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(test): make external-host freshness checks deterministic The parameterized host smoke + --host all freshness tests assumed an external `gen:skill-docs --host all` had run first (it never does in `bun test`), so which host reported STALE varied by sibling-test timing — flaky. Regenerate the gitignored external host dirs in a beforeAll so the --dry-run check is deterministic. It still catches non-deterministic generation (the real bug class for regenerated outputs); the tracked-claude freshness test runs earlier and is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(parity): headroom for AUQ cross-cutting addition on carved document-release Merging main brought the carve of document-release (smaller skeleton); the AUQ prose-fallback adds ~2KB to every skill's always-loaded preamble, landing document-release at ~5.9% over the pre-carve v1.53.0.0 baseline. Add a per-carve maxSizeRatio override (CARVE_GUARDS single source of truth) and bump only this skill to 1.08. All other skills keep the strict 1.05 ceiling. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(auq): harden error-fallback hook + harness per adversarial review Codex pre-landing review found three real issues: - The PostToolUse fallback hook shared source 'plan-tune-cathedral' with the question-log hook (same event+matcher); gstack-settings-hook replaces the entry, so it would have clobbered plan-tune capture. Give it its own 'auq-error-fallback' source (separate entry, both run); ALREADY_INSTALLED now requires both sources. - isErrorResponse triggered on any string containing 'internal error'/'is_error', so a real answer or a {"is_error": false} payload could fire the fallback after a successful question. Narrow it to the missing-result sentinel + boolean is_error. - The SDK runner mutated process.env.GSTACK_HEADLESS process-wide (leaked headless into later tests). Removed; GSTACK_HEADLESS=1 now lives in the eval package.json scripts, scoped to the invocation and inherited by the SDK child. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v1.57.2.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e722c5b commit 4dfdb7c

72 files changed

Lines changed: 2035 additions & 211 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,73 @@
11
# Changelog
22

3+
## [1.57.2.0] - 2026-06-08
4+
5+
## **When the question picker breaks mid-skill, gstack asks in plain text instead of stalling.**
6+
## **Every skill detects a dead AskUserQuestion and falls back to a full decision brief you answer by typing a letter.**
7+
8+
AskUserQuestion is how every gstack skill asks you to decide. When the host's question
9+
tool fails at runtime, which Conductor's MCP integration currently does intermittently,
10+
skills used to stall or hard-block. Now each skill detects the failure, works out
11+
whether a human is actually present, and if so re-renders the exact same decision as a
12+
text message: a plain-English explanation of the issue, a completeness score on each
13+
choice, and a recommendation with its reason, one paragraph per choice. You answer by
14+
typing a single letter. Headless eval runs still block cleanly (no human to answer);
15+
orchestrator sessions keep auto-choosing. This whole release was built and reviewed
16+
through that fallback, because the Conductor tool was down the entire session.
17+
18+
### The numbers that matter
19+
20+
No production benchmark for a reliability path like this. These are the behavior and
21+
coverage facts, verifiable with `bun test test/gstack-session-kind.test.ts
22+
test/resolver-ask-user-format.test.ts test/auq-error-fallback-hook.test.ts`.
23+
24+
| When AskUserQuestion fails | Before | After |
25+
|---|---|---|
26+
| Interactive session (human present) | stall / hard BLOCK | full prose decision brief, answer by letter |
27+
| Headless eval / CI | BLOCK | BLOCK (unchanged, correct) |
28+
| Orchestrator (OpenClaw) session | undefined | auto-choose recommended (contract kept) |
29+
| Session kinds detected | 0 | 3 (interactive / headless / spawned) |
30+
| New tests guarding the path | 0 | 34 |
31+
32+
The text brief is not a degraded stub. It carries the same three things the picker
33+
shows: a clear explanation of what is being decided, a `Completeness: X/10` on every
34+
choice, and a recommendation with the reason it wins.
35+
36+
### What this means for you
37+
38+
If your host's question tool flakes out, a skill no longer dies on you. You get the
39+
same decision to make, in text, and you reply with a letter. Nothing changes when the
40+
tool works normally. If you run gstack headless, those sessions still block on a needed
41+
question exactly as before, so eval determinism is intact.
42+
43+
### Itemized changes
44+
45+
#### Added
46+
- `gstack-session-kind` classifies each session as interactive, headless, or spawned,
47+
echoed as `SESSION_KIND` at skill start so any skill can branch on it.
48+
- Plain-text fallback for AskUserQuestion: on a tool failure in an interactive session,
49+
the skill renders the full decision brief (issue ELI10 + per-choice completeness +
50+
recommendation) as markdown you answer by typing a letter, then stops and waits.
51+
- A defensive hook that, when an AskUserQuestion call errors, reminds the agent to run
52+
the fallback for the current session kind.
53+
54+
#### Changed
55+
- AskUserQuestion is still sent as a normal tool call; the prose path applies only when
56+
the tool is unavailable or erroring, and never on a `[plan-tune auto-decide]` result.
57+
58+
#### Fixed
59+
- Section-loading tests use the canonical kebab test names, so the test-coverage gate
60+
matches them.
61+
- External-host doc-freshness checks are deterministic, no longer dependent on a prior
62+
full regeneration.
63+
64+
#### For contributors
65+
- The eval/E2E runners set `GSTACK_HEADLESS=1` so headless runs classify correctly;
66+
interactive-path suites opt out per-run.
67+
- Per-skill `maxSizeRatio` override in the carve-guards registry; `document-release`
68+
gets 1.08 headroom for the cross-cutting preamble addition while every other skill
69+
keeps the 1.05 ceiling.
70+
371
## [1.57.0.0] - 2026-06-07
472

573
## **Three more heavyweight skills load lighter, and every carved skill finally has a test that proves it loads.**

SKILL.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
4545
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
4646
REPO_MODE=${REPO_MODE:-unknown}
4747
echo "REPO_MODE: $REPO_MODE"
48+
_SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
49+
case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
50+
echo "SESSION_KIND: $_SESSION_KIND"
4851
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
4952
echo "LAKE_INTRO: $_LAKE_SEEN"
5053
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
@@ -124,7 +127,7 @@ In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`co
124127

125128
## Skill Invocation During Plan Mode
126129

127-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
130+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If AskUserQuestion is unavailable or a call fails, follow the AskUserQuestion Format failure fallback: `headless` → BLOCKED; `interactive` the prose fallback (also satisfies end-of-turn). At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
128131

129132
If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
130133

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.57.0.0
1+
1.57.2.0

autoplan/SKILL.md

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
5454
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
5555
REPO_MODE=${REPO_MODE:-unknown}
5656
echo "REPO_MODE: $REPO_MODE"
57+
_SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
58+
case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
59+
echo "SESSION_KIND: $_SESSION_KIND"
5760
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
5861
echo "LAKE_INTRO: $_LAKE_SEEN"
5962
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
@@ -133,7 +136,7 @@ In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`co
133136

134137
## Skill Invocation During Plan Mode
135138

136-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
139+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If AskUserQuestion is unavailable or a call fails, follow the AskUserQuestion Format failure fallback: `headless` → BLOCKED; `interactive` the prose fallback (also satisfies end-of-turn). At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
137140

138141
If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
139142

@@ -305,11 +308,31 @@ AI orchestrator (e.g., OpenClaw). In spawned sessions:
305308

306309
**Rule:** if any `mcp__*__AskUserQuestion` variant is in your tool list, prefer it. Hosts may disable native AUQ via `--disallowedTools AskUserQuestion` (Conductor does, by default) and route through their MCP variant; calling native there silently fails. Same questions/options shape; same decision-brief format applies.
307310

308-
**If no AskUserQuestion variant appears in your tool list, this skill is BLOCKED.** Stop, report `BLOCKED — AskUserQuestion unavailable`, and wait for the user. Do not write decisions to the plan file as a substitute, do not emit them as prose and stop, and do not silently auto-decide (only `/plan-tune` AUTO_DECIDE opt-ins authorize auto-picking).
311+
If AskUserQuestion is unavailable (no variant in your tool list) OR a call to it fails, do NOT silently auto-decide or write the decision to the plan file as a substitute. Follow the **failure fallback** below.
312+
313+
### When AskUserQuestion is unavailable or a call fails
314+
315+
Tell three outcomes apart:
316+
317+
1. **Auto-decide denial (NOT a failure).** The result contains `[plan-tune auto-decide] <id> → <option>` — the preference hook working as designed. Proceed with that option. Do NOT retry, do NOT fall back to prose.
318+
2. **Genuine failure** — no variant in your tool list, OR the variant is present but the call returns an error / missing result (MCP transport error, empty result, host bug — e.g. Conductor's MCP AskUserQuestion is flaky and returns `[Tool result missing due to internal error]`).
319+
- If it was present and **errored** (not absent), retry the SAME call **once** — but only if no answer could have surfaced (a missing-result error can arrive after the user already saw the question; retrying would double-prompt, so if it may have reached them, treat as pending, don't retry).
320+
- Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`):
321+
- `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED.
322+
- `headless``BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer).
323+
- `interactive`**prose fallback** (below).
324+
325+
**Prose fallback — render the decision brief as a markdown message, not a tool call.** Same information as the tool format below, different structure (paragraphs, not ✅/❌ bullets). It MUST surface this triad:
326+
327+
1. **A clear ELI10 of the issue itself** — plain English on what's being decided and why it matters (the question, not per-choice), naming the stakes. Lead with it.
328+
2. **Completeness scores per choice** — explicit `Completeness: X/10` on EACH choice (10 complete, 7 happy-path, 3 shortcut); use the kind-note when options differ in kind not coverage, but never silently drop the score.
329+
3. **The recommendation and why** — a `Recommendation: <choice> because <reason>` line plus the `(recommended)` marker on that choice.
330+
331+
Layout: a `D<N>` title + a one-line note that AskUserQuestion failed and to reply with a letter; the issue ELI10; the Recommendation line; then ONE paragraph per choice carrying its `(recommended)` marker, its `Completeness: X/10`, and 2-4 sentences of reasoning — never a bare bullet list; a closing `Net:` line. Split chains / 5+ options: one prose block per per-option call, in sequence. Then STOP and wait — the user's typed answer is the decision. In plan mode this satisfies end-of-turn like a tool call.
309332

310333
### Format
311334

312-
Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose.
335+
Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose — unless the documented failure fallback above applies (interactive session + the call is unavailable/erroring), in which case the prose fallback is the correct output.
313336

314337
```
315338
D<N> — <one-line question title>
@@ -389,7 +412,7 @@ Before calling AskUserQuestion, verify:
389412
- [ ] (recommended) label on one option (even for neutral-posture)
390413
- [ ] Dual-scale effort labels on effort-bearing options (human / CC)
391414
- [ ] Net line closes the decision
392-
- [ ] You are calling the tool, not writing prose
415+
- [ ] You are calling the tool, not writing prose — unless the documented failure fallback applies (then: prose with the mandatory triad — issue ELI10, per-choice Completeness, Recommendation + `(recommended)` — and a "reply with a letter" instruction, then STOP)
393416
- [ ] Non-ASCII characters (CJK / accents) written directly, NOT \u-escaped
394417
- [ ] If you had 5+ options, you split (or batched into ≤4-groups) — did NOT drop any
395418
- [ ] If you split, you checked dependencies between options before firing the chain

benchmark-models/SKILL.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
4848
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
4949
REPO_MODE=${REPO_MODE:-unknown}
5050
echo "REPO_MODE: $REPO_MODE"
51+
_SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
52+
case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
53+
echo "SESSION_KIND: $_SESSION_KIND"
5154
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
5255
echo "LAKE_INTRO: $_LAKE_SEEN"
5356
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
@@ -127,7 +130,7 @@ In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`co
127130

128131
## Skill Invocation During Plan Mode
129132

130-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
133+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If AskUserQuestion is unavailable or a call fails, follow the AskUserQuestion Format failure fallback: `headless` → BLOCKED; `interactive` the prose fallback (also satisfies end-of-turn). At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
131134

132135
If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
133136

benchmark/SKILL.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ echo "SKILL_PREFIX: $_SKILL_PREFIX"
4848
source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true
4949
REPO_MODE=${REPO_MODE:-unknown}
5050
echo "REPO_MODE: $REPO_MODE"
51+
_SESSION_KIND=$(~/.claude/skills/gstack/bin/gstack-session-kind 2>/dev/null || echo "interactive")
52+
case "$_SESSION_KIND" in spawned|headless|interactive) ;; *) _SESSION_KIND="interactive" ;; esac
53+
echo "SESSION_KIND: $_SESSION_KIND"
5154
_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")
5255
echo "LAKE_INTRO: $_LAKE_SEEN"
5356
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)
@@ -127,7 +130,7 @@ In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`co
127130

128131
## Skill Invocation During Plan Mode
129132

130-
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, the skill is BLOCKED — stop and report `BLOCKED — AskUserQuestion unavailable` per the AskUserQuestion Format rule. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
133+
If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If AskUserQuestion is unavailable or a call fails, follow the AskUserQuestion Format failure fallback: `headless` → BLOCKED; `interactive` the prose fallback (also satisfies end-of-turn). At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode.
131134

132135
If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?"
133136

0 commit comments

Comments
 (0)