From dd81e4c8e827e9d2763173a3351e01889d15c20b Mon Sep 17 00:00:00 2001 From: garrytan Date: Mon, 26 Oct 2026 07:44:20 +0000 Subject: [PATCH] fix: keep destructive options pending in the unattended AUQ fallback (GSTA-91) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 8 +- autoplan/SKILL.md | 2 +- canary/SKILL.md | 2 +- codex/SKILL.md | 2 +- context-restore/SKILL.md | 2 +- context-save/SKILL.md | 2 +- design-consultation/SKILL.md | 2 +- design-html/SKILL.md | 2 +- design-review/SKILL.md | 2 +- design-shotgun/SKILL.md | 2 +- devex-review/SKILL.md | 2 +- document-generate/SKILL.md | 2 +- document-release/SKILL.md | 2 +- eval-plan/SKILL.md | 2 +- health/SKILL.md | 2 +- investigate/SKILL.md | 2 +- ios-clean/SKILL.md | 2 +- ios-design-review/SKILL.md | 2 +- ios-fix/SKILL.md | 2 +- ios-qa/SKILL.md | 2 +- ios-sync/SKILL.md | 2 +- land-and-deploy/SKILL.md | 2 +- landing-report/SKILL.md | 2 +- learn/SKILL.md | 2 +- office-hours/SKILL.md | 2 +- pair-agent/SKILL.md | 2 +- plan-ceo-review/SKILL.md | 2 +- plan-design-review/SKILL.md | 2 +- plan-devex-review/SKILL.md | 2 +- plan-eng-review/SKILL.md | 2 +- plan-tune/SKILL.md | 2 +- qa-only/SKILL.md | 2 +- qa/SKILL.md | 2 +- retro/SKILL.md | 2 +- review/SKILL.md | 2 +- .../preamble/generate-ask-user-format.ts | 2 +- setup-deploy/SKILL.md | 2 +- setup-gbrain/SKILL.md | 2 +- ship/SKILL.md | 2 +- skillify/SKILL.md | 2 +- spec/SKILL.md | 2 +- sync-gbrain/SKILL.md | 2 +- test-audit/SKILL.md | 2 +- test/fixtures/golden/agy-ship-SKILL.md | 2 +- test/fixtures/golden/claude-ship-SKILL.md | 2 +- test/fixtures/golden/codex-ship-SKILL.md | 2 +- test/fixtures/golden/factory-ship-SKILL.md | 2 +- test/fixtures/skill-md-size-allowlist.json | 178 +++++++++--------- test/resolver-ask-user-format.test.ts | 13 ++ 49 files changed, 152 insertions(+), 139 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f250555c..7677af044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,18 +6,18 @@ ### Fixed - **Claims Need Evidence kernel** (`scripts/resolvers/preamble/generate-evidence-directive.ts`): the evidence-kind bullet ended with "Reuse rules: Step 16." That step exists only in /ship, so in every other skill the pointer led nowhere. It's gone. /ship's Step 16 still states its own reuse rule ("Reuse a check when its inputs match"), and every tier's DONE line still asks you to name reuse. -- **AskUserQuestion Tool resolution** (`generate-ask-user-format.ts`): "per its Unattended session block" read like a section of the skill, but the block is runtime output. Item 1 now names the `unattended-session` block that gstack-skill-start prints, which is the id on its `GSTACK_INSTRUCTION_BEGIN` line. The failure fallback's `unattended` branch dropped its repeat of that pointer, because item 1 already states the rule. +- **AskUserQuestion Tool resolution** (`generate-ask-user-format.ts`): "per its Unattended session block" read like a section of the skill, but the block is runtime output. Item 1 now names the `unattended-session` block that gstack-skill-start prints, which is the id on its `GSTACK_INSTRUCTION_BEGIN` line. The failure fallback's `unattended` branch dropped its repeat of that pointer and now lists destructive or irreversible options as pending gate items itself, as the printed block does; the pointer had been its only route to that carve-out. - **AskUserQuestion fallback hook** (`hosts/claude/hooks/auq-error-fallback-hook.ts`): its unattended directive ended with "GSTACK_RESULT status=gate_pending (Unattended session block).", the same section-style pointer to runtime output. The parenthetical is gone. - **Reality rows, eng/ceo branch** (`scripts/resolvers/plan-reality.ts`): the Completion Summary row and plan-eng-review's checklist ask for the `PLAN_REALITY` line, but the operative block never said where that line comes from. It now says `gstack-plan-reality check` prints it. ### Tests - `test/honesty-kernel.test.ts` no longer requires the Step 16 pointer. It now rejects any `Step ` cross-reference in the kernel, which every skill renders. -- `test/resolver-ask-user-format.test.ts` checks across files that the unattended pointer names `unattended-session` and that gstack-skill-start really emits a block with that id, so renaming either side fails the test. `test/auq-error-fallback-hook.test.ts` asserts the hook's unattended directive no longer says "Unattended session block". +- `test/resolver-ask-user-format.test.ts` checks across files that the unattended pointer names `unattended-session` and that gstack-skill-start really emits a block with that id, so renaming either side fails the test. It also checks that the failure fallback's `unattended` branch names destructive or irreversible options as pending. `test/auq-error-fallback-hook.test.ts` asserts the hook's unattended directive no longer says "Unattended session block". - `test/plan-reality.test.ts` checks that the reality-rows block, generated for each of the eng, ceo and devex phases, says its `gstack-plan-reality check` line prints `PLAN_REALITY`. -- Every changed SKILL.md shrank, so 89 pins in `test/fixtures/skill-md-size-allowlist.json` were lowered to their new exact sizes (a ratchet: nothing grew). The /ship goldens were regenerated. +- 89 pins in `test/fixtures/skill-md-size-allowlist.json` were moved to their new exact sizes. 78 went down by 3 characters. The 11 non-Claude plan-eng-review pins went up by 21: the unattended failure-fallback branch regains the destructive/irreversible carve-out that the removed pointer used to supply (about 21 chars). The /ship goldens were regenerated. ### Gate integrity -- No threshold, rubric, trial count, case kind or judge prompt changed. The size pins only went down. +- No threshold, rubric, trial count, case kind or judge prompt changed. 78 size pins went down; 11 went up by 21 characters for the restored carve-out above. ## [1.91.230.0] - 2026-10-26 diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index 6cc16635b..0cf7ecb51 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -89,7 +89,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/canary/SKILL.md b/canary/SKILL.md index aefe3f611..bbbcbbf8a 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -74,7 +74,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/codex/SKILL.md b/codex/SKILL.md index 2bc3ff097..74b2b1b1a 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -75,7 +75,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/context-restore/SKILL.md b/context-restore/SKILL.md index 26824f063..35a9e3fa0 100644 --- a/context-restore/SKILL.md +++ b/context-restore/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/context-save/SKILL.md b/context-save/SKILL.md index d9b172e68..0d6db894a 100644 --- a/context-save/SKILL.md +++ b/context-save/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index ba2b59adb..c865aaf52 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -100,7 +100,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/design-html/SKILL.md b/design-html/SKILL.md index 7af8c0b2d..48d8e752c 100644 --- a/design-html/SKILL.md +++ b/design-html/SKILL.md @@ -77,7 +77,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/design-review/SKILL.md b/design-review/SKILL.md index be0bdf944..56019a2d9 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -77,7 +77,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/design-shotgun/SKILL.md b/design-shotgun/SKILL.md index ea5156a48..9dd010ac0 100644 --- a/design-shotgun/SKILL.md +++ b/design-shotgun/SKILL.md @@ -94,7 +94,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/devex-review/SKILL.md b/devex-review/SKILL.md index 8a0acbdfa..bfaecabf2 100644 --- a/devex-review/SKILL.md +++ b/devex-review/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/document-generate/SKILL.md b/document-generate/SKILL.md index c57587344..fc1b388d9 100644 --- a/document-generate/SKILL.md +++ b/document-generate/SKILL.md @@ -80,7 +80,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/document-release/SKILL.md b/document-release/SKILL.md index c6e98d651..83899e1b0 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/eval-plan/SKILL.md b/eval-plan/SKILL.md index dd397d040..0ecc2584f 100644 --- a/eval-plan/SKILL.md +++ b/eval-plan/SKILL.md @@ -79,7 +79,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/health/SKILL.md b/health/SKILL.md index 21e8f9b07..3e3171ce3 100644 --- a/health/SKILL.md +++ b/health/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/investigate/SKILL.md b/investigate/SKILL.md index ac8e1cd41..a9622bd42 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -118,7 +118,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ios-clean/SKILL.md b/ios-clean/SKILL.md index 50830f450..7ecdd4198 100644 --- a/ios-clean/SKILL.md +++ b/ios-clean/SKILL.md @@ -75,7 +75,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ios-design-review/SKILL.md b/ios-design-review/SKILL.md index 06d3a601e..58a4e51db 100644 --- a/ios-design-review/SKILL.md +++ b/ios-design-review/SKILL.md @@ -74,7 +74,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ios-fix/SKILL.md b/ios-fix/SKILL.md index d363f49fe..8d5bfe1a7 100644 --- a/ios-fix/SKILL.md +++ b/ios-fix/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ios-qa/SKILL.md b/ios-qa/SKILL.md index cd86c0016..35f27c740 100644 --- a/ios-qa/SKILL.md +++ b/ios-qa/SKILL.md @@ -79,7 +79,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ios-sync/SKILL.md b/ios-sync/SKILL.md index 572fc94aa..c787c07af 100644 --- a/ios-sync/SKILL.md +++ b/ios-sync/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index b291f87cc..31d94ead1 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -74,7 +74,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/landing-report/SKILL.md b/landing-report/SKILL.md index 962fa5ad6..e210102d4 100644 --- a/landing-report/SKILL.md +++ b/landing-report/SKILL.md @@ -75,7 +75,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/learn/SKILL.md b/learn/SKILL.md index b4a089999..76f5e4f65 100644 --- a/learn/SKILL.md +++ b/learn/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index fd788d326..ae2ca60eb 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -104,7 +104,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/pair-agent/SKILL.md b/pair-agent/SKILL.md index 92cd8df0b..caef74585 100644 --- a/pair-agent/SKILL.md +++ b/pair-agent/SKILL.md @@ -73,7 +73,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index daef71504..94e9ea942 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -106,7 +106,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index 5e61b86dd..0ae4ef3ff 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -108,7 +108,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/plan-devex-review/SKILL.md b/plan-devex-review/SKILL.md index 4b785e7b0..840938ced 100644 --- a/plan-devex-review/SKILL.md +++ b/plan-devex-review/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index 2d322a7df..7ff5eee77 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -122,7 +122,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → follow Tool resolution item 1: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/plan-tune/SKILL.md b/plan-tune/SKILL.md index 933afa4e7..773247c94 100644 --- a/plan-tune/SKILL.md +++ b/plan-tune/SKILL.md @@ -80,7 +80,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index 33e82d17c..06c181f3d 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -74,7 +74,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/qa/SKILL.md b/qa/SKILL.md index a1a7ce5e1..a46e4cf47 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -77,7 +77,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/retro/SKILL.md b/retro/SKILL.md index b060ebf37..3a943336b 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -94,7 +94,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/review/SKILL.md b/review/SKILL.md index 3f5033916..0dad552e6 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -79,7 +79,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/scripts/resolvers/preamble/generate-ask-user-format.ts b/scripts/resolvers/preamble/generate-ask-user-format.ts index 00d200256..119e23735 100644 --- a/scripts/resolvers/preamble/generate-ask-user-format.ts +++ b/scripts/resolvers/preamble/generate-ask-user-format.ts @@ -26,7 +26,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on \`SESSION_KIND\` (echoed by the preamble; empty/absent ⇒ \`interactive\`): - \`spawned\` → ${ctx.skillName === 'plan-eng-review' ? 'follow Tool resolution item 1' : 'defer to the **Spawned session** block'}: auto-choose the recommended option. Never prose, never BLOCKED. - - \`unattended\` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - \`unattended\` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - \`headless\` → \`BLOCKED — AskUserQuestion unavailable\`; stop and wait (no human can answer). - \`interactive\` → **prose fallback** (below). diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index 572394168..5d22b95c9 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/setup-gbrain/SKILL.md b/setup-gbrain/SKILL.md index f7221dcc0..f4939bb9e 100644 --- a/setup-gbrain/SKILL.md +++ b/setup-gbrain/SKILL.md @@ -78,7 +78,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/ship/SKILL.md b/ship/SKILL.md index 0c903f6c8..700543437 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -79,7 +79,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/skillify/SKILL.md b/skillify/SKILL.md index 6e1faa9c2..db46fa454 100644 --- a/skillify/SKILL.md +++ b/skillify/SKILL.md @@ -74,7 +74,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/spec/SKILL.md b/spec/SKILL.md index bb4011268..bdb42740d 100644 --- a/spec/SKILL.md +++ b/spec/SKILL.md @@ -77,7 +77,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index 04cb63560..89371e902 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -77,7 +77,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test-audit/SKILL.md b/test-audit/SKILL.md index abd71b6b9..652a74f23 100644 --- a/test-audit/SKILL.md +++ b/test-audit/SKILL.md @@ -76,7 +76,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test/fixtures/golden/agy-ship-SKILL.md b/test/fixtures/golden/agy-ship-SKILL.md index 6fe27b18d..0d2c9ade5 100644 --- a/test/fixtures/golden/agy-ship-SKILL.md +++ b/test/fixtures/golden/agy-ship-SKILL.md @@ -63,7 +63,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index 0c903f6c8..700543437 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -79,7 +79,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index 3b2bea869..e86d1bbfe 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -61,7 +61,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index 611e4d96d..342bef043 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -63,7 +63,7 @@ Tell these apart: - If it was present and **errored** (not absent), retry the SAME call **once** — only if no answer could have surfaced (a missing-result error can arrive after the user saw the question; retrying would double-prompt, so if it may have reached them, treat it as pending and don't retry). - Then branch on `SESSION_KIND` (echoed by the preamble; empty/absent ⇒ `interactive`): - `spawned` → defer to the **Spawned session** block: auto-choose the recommended option. Never prose, never BLOCKED. - - `unattended` → auto-choose the recommended option; a consent, unrecommended question or approval gate becomes a pending gate item. + - `unattended` → auto-choose the recommended option; a consent, destructive or irreversible option, unrecommended question or approval gate becomes a pending gate item. - `headless` → `BLOCKED — AskUserQuestion unavailable`; stop and wait (no human can answer). - `interactive` → **prose fallback** (below). diff --git a/test/fixtures/skill-md-size-allowlist.json b/test/fixtures/skill-md-size-allowlist.json index 803cdd9fe..9bdbe7fe6 100644 --- a/test/fixtures/skill-md-size-allowlist.json +++ b/test/fixtures/skill-md-size-allowlist.json @@ -2,94 +2,94 @@ "_comment": "Generated SKILL.md files over the limit, pinned at their exact character count (#3199). test/skill-md-size-guard.test.ts fails when a pinned skill grows past its pin or shrinks below it: lower the pin when a skill shrinks and delete it once the skill is within the limit. Raising a pin is an owner decision. The shared-preamble hoist that would retire most pins is deferred: owner Garry, revisit 2026-11-15.", "limit": 100000, "pins": { - "agy/gstack-autoplan": 130465, - "agy/gstack-design-consultation": 108145, - "agy/gstack-design-review": 143489, - "agy/gstack-land-and-deploy": 117683, - "agy/gstack-plan-design-review": 139974, - "agy/gstack-plan-devex-review": 135721, - "agy/gstack-plan-eng-review": 152567, - "agy/gstack-review": 124143, - "claude/design-review": 136492, - "codex/gstack-autoplan": 130589, - "codex/gstack-design-consultation": 109413, - "codex/gstack-design-review": 144989, - "codex/gstack-land-and-deploy": 122233, - "codex/gstack-office-hours": 102269, - "codex/gstack-plan-design-review": 142427, - "codex/gstack-plan-devex-review": 138610, - "codex/gstack-plan-eng-review": 155113, - "codex/gstack-review": 125047, - "copilot/gstack-autoplan": 131598, - "copilot/gstack-codex": 100196, - "copilot/gstack-design-consultation": 109497, - "copilot/gstack-design-review": 144794, - "copilot/gstack-land-and-deploy": 118938, - "copilot/gstack-office-hours": 100425, - "copilot/gstack-plan-design-review": 140845, - "copilot/gstack-plan-devex-review": 136873, - "copilot/gstack-plan-eng-review": 153292, - "copilot/gstack-review": 125414, - "cursor/gstack-autoplan": 129239, - "cursor/gstack-design-consultation": 107183, - "cursor/gstack-design-review": 142468, - "cursor/gstack-land-and-deploy": 116606, - "cursor/gstack-plan-design-review": 138929, - "cursor/gstack-plan-devex-review": 134552, - "cursor/gstack-plan-eng-review": 151421, - "cursor/gstack-review": 140675, - "factory/gstack-autoplan": 131523, - "factory/gstack-codex": 100616, - "factory/gstack-design-consultation": 108631, - "factory/gstack-design-review": 144258, - "factory/gstack-land-and-deploy": 120778, - "factory/gstack-office-hours": 101304, - "factory/gstack-plan-design-review": 141710, - "factory/gstack-plan-devex-review": 137921, - "factory/gstack-plan-eng-review": 154535, - "factory/gstack-review": 144454, - "gbrain/gstack-autoplan": 129776, - "gbrain/gstack-design-review": 132803, - "gbrain/gstack-land-and-deploy": 117128, - "gbrain/gstack-plan-design-review": 127816, - "gbrain/gstack-plan-devex-review": 115090, - "gbrain/gstack-plan-eng-review": 134153, - "hermes/gstack-autoplan": 129866, - "hermes/gstack-design-review": 132910, - "hermes/gstack-land-and-deploy": 117230, - "hermes/gstack-plan-design-review": 127925, - "hermes/gstack-plan-devex-review": 115176, - "hermes/gstack-plan-eng-review": 134238, - "kiro/gstack-autoplan": 129001, - "kiro/gstack-design-consultation": 107025, - "kiro/gstack-design-review": 142282, - "kiro/gstack-land-and-deploy": 116494, - "kiro/gstack-plan-design-review": 138769, - "kiro/gstack-plan-devex-review": 134392, - "kiro/gstack-plan-eng-review": 151271, - "kiro/gstack-review": 140487, - "openclaw/gstack-autoplan": 129481, - "openclaw/gstack-design-review": 131608, - "openclaw/gstack-land-and-deploy": 116718, - "openclaw/gstack-plan-design-review": 126667, - "openclaw/gstack-plan-devex-review": 113929, - "openclaw/gstack-plan-eng-review": 132550, - "opencode/gstack-autoplan": 131601, - "opencode/gstack-design-consultation": 109318, - "opencode/gstack-design-review": 144666, - "opencode/gstack-land-and-deploy": 118723, - "opencode/gstack-office-hours": 100259, - "opencode/gstack-plan-design-review": 140699, - "opencode/gstack-plan-devex-review": 136773, - "opencode/gstack-plan-eng-review": 153173, - "opencode/gstack-review": 142910, - "slate/gstack-autoplan": 129120, - "slate/gstack-design-consultation": 107104, - "slate/gstack-design-review": 142375, - "slate/gstack-land-and-deploy": 116550, - "slate/gstack-plan-design-review": 138849, - "slate/gstack-plan-devex-review": 134472, - "slate/gstack-plan-eng-review": 151346, - "slate/gstack-review": 140581 + "agy/gstack-autoplan": 130501, + "agy/gstack-design-consultation": 108181, + "agy/gstack-design-review": 143525, + "agy/gstack-land-and-deploy": 117719, + "agy/gstack-plan-design-review": 140010, + "agy/gstack-plan-devex-review": 135757, + "agy/gstack-plan-eng-review": 152603, + "agy/gstack-review": 124179, + "claude/design-review": 136528, + "codex/gstack-autoplan": 130625, + "codex/gstack-design-consultation": 109449, + "codex/gstack-design-review": 145025, + "codex/gstack-land-and-deploy": 122269, + "codex/gstack-office-hours": 102305, + "codex/gstack-plan-design-review": 142463, + "codex/gstack-plan-devex-review": 138646, + "codex/gstack-plan-eng-review": 155149, + "codex/gstack-review": 125083, + "copilot/gstack-autoplan": 131634, + "copilot/gstack-codex": 100232, + "copilot/gstack-design-consultation": 109533, + "copilot/gstack-design-review": 144830, + "copilot/gstack-land-and-deploy": 118974, + "copilot/gstack-office-hours": 100461, + "copilot/gstack-plan-design-review": 140881, + "copilot/gstack-plan-devex-review": 136909, + "copilot/gstack-plan-eng-review": 153328, + "copilot/gstack-review": 125450, + "cursor/gstack-autoplan": 129275, + "cursor/gstack-design-consultation": 107219, + "cursor/gstack-design-review": 142504, + "cursor/gstack-land-and-deploy": 116642, + "cursor/gstack-plan-design-review": 138965, + "cursor/gstack-plan-devex-review": 134588, + "cursor/gstack-plan-eng-review": 151457, + "cursor/gstack-review": 140711, + "factory/gstack-autoplan": 131559, + "factory/gstack-codex": 100652, + "factory/gstack-design-consultation": 108667, + "factory/gstack-design-review": 144294, + "factory/gstack-land-and-deploy": 120814, + "factory/gstack-office-hours": 101340, + "factory/gstack-plan-design-review": 141746, + "factory/gstack-plan-devex-review": 137957, + "factory/gstack-plan-eng-review": 154571, + "factory/gstack-review": 144490, + "gbrain/gstack-autoplan": 129812, + "gbrain/gstack-design-review": 132839, + "gbrain/gstack-land-and-deploy": 117164, + "gbrain/gstack-plan-design-review": 127852, + "gbrain/gstack-plan-devex-review": 115126, + "gbrain/gstack-plan-eng-review": 134189, + "hermes/gstack-autoplan": 129902, + "hermes/gstack-design-review": 132946, + "hermes/gstack-land-and-deploy": 117266, + "hermes/gstack-plan-design-review": 127961, + "hermes/gstack-plan-devex-review": 115212, + "hermes/gstack-plan-eng-review": 134274, + "kiro/gstack-autoplan": 129037, + "kiro/gstack-design-consultation": 107061, + "kiro/gstack-design-review": 142318, + "kiro/gstack-land-and-deploy": 116530, + "kiro/gstack-plan-design-review": 138805, + "kiro/gstack-plan-devex-review": 134428, + "kiro/gstack-plan-eng-review": 151307, + "kiro/gstack-review": 140523, + "openclaw/gstack-autoplan": 129517, + "openclaw/gstack-design-review": 131644, + "openclaw/gstack-land-and-deploy": 116754, + "openclaw/gstack-plan-design-review": 126703, + "openclaw/gstack-plan-devex-review": 113965, + "openclaw/gstack-plan-eng-review": 132586, + "opencode/gstack-autoplan": 131637, + "opencode/gstack-design-consultation": 109354, + "opencode/gstack-design-review": 144702, + "opencode/gstack-land-and-deploy": 118759, + "opencode/gstack-office-hours": 100295, + "opencode/gstack-plan-design-review": 140735, + "opencode/gstack-plan-devex-review": 136809, + "opencode/gstack-plan-eng-review": 153209, + "opencode/gstack-review": 142946, + "slate/gstack-autoplan": 129156, + "slate/gstack-design-consultation": 107140, + "slate/gstack-design-review": 142411, + "slate/gstack-land-and-deploy": 116586, + "slate/gstack-plan-design-review": 138885, + "slate/gstack-plan-devex-review": 134508, + "slate/gstack-plan-eng-review": 151382, + "slate/gstack-review": 140617 } } diff --git a/test/resolver-ask-user-format.test.ts b/test/resolver-ask-user-format.test.ts index 8196adff7..b41f7c8be 100644 --- a/test/resolver-ask-user-format.test.ts +++ b/test/resolver-ask-user-format.test.ts @@ -208,6 +208,19 @@ describe('generateAskUserFormat — runtime-failure prose fallback', () => { expect(out).toMatch(/empty\/absent[\s\S]{0,40}interactive/i); }); + test('unattended branch keeps destructive or irreversible options pending, like the printed block', () => { + for (const skillName of ['test-skill', 'plan-eng-review']) { + const fallback = generateAskUserFormat({ ...makeCtx(), skillName }) + .split('### When AskUserQuestion is unavailable or a call fails')[1] ?? ''; + const unattended = fallback.split('\n').find(line => line.trim().startsWith('- `unattended`')) ?? ''; + expect(unattended, `${skillName}: failure fallback must branch on unattended`).not.toBe(''); + expectMentions(unattended, [ + ['destructive', 'irreversible', 'pending gate item'], + ['consent', 'unrecommended question', 'approval gate', 'pending gate item'], + ], `${skillName} unattended fallback branch`); + } + }); + // The mandatory triad the user explicitly required for the plain-text output. test('prose fallback mandates the triad: issue ELI10', () => { expect(out).toContain('ELI10');