Codex skills that call AskUserQuestion silently fail in Default mode
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Summary
gstack skills generated for Codex CLI still reference `AskUserQuestion` in their prompt bodies even though Codex strips that tool from the frontmatter and the Codex tool equivalent (`request_user_input`) is gated behind Plan mode. When a Codex user runs such a skill in Default mode (the default), the model either errors on an unknown tool or silently improvises an answer instead of asking the user.
## Reproduction
1. Clean Codex CLI install (v0.121.0 verified).
2. Install any gstack skill that includes `AskUserQuestion` in its prompt body. Easiest target is your own `/codex` skill at `codex/SKILL.md.tmpl:102-114`, which calls `AskUserQuestion` unconditionally for mode selection.
3. Launch Codex normally (Default mode) and invoke the skill.
4. Observe: the multiple-choice prompt does not appear. The model picks a default based on context.
Expected: either the question actually fires, or the skill fails loudly with a message pointing at `/plan`.
Actual: silent degradation. For `/codex` itself this is benign (the fallback picks "review"). For skills that collect user identity or preferences, it produces silently-wrong outputs downstream.
## Root cause
Two independent pieces, both verified against source:
**Codex side** (`openai/codex` at tag `rust-v0.121.0`):
- `codex-rs/protocol/src/config_types.rs:428-430`: `mode.allows_request_user_input()` returns true only for `ModeKind::Plan`.
- `codex-rs/tools/src/request_user_input_tool.rs:125-128`: the tool is registered unconditionally but the handler rejects calls in Default mode unless the `default_mode_request_user_input` feature flag is on (Stage: UnderDevelopment, default off).
**gstack side:**
- `hosts/codex.ts` declares `pathRewrites` but no `toolRewrites`. The optional `toolRewrites` field exists in the host-config interface (`scripts/host-config.ts:73`) but Codex's config doesn't populate it, so prompt text referring to `AskUserQuestion` passes through unchanged.
- `codex-helpers.ts:77-102` (`transformFrontmatter`) strips the `allowed-tools` list for non-Claude hosts. The model's schema for a Codex-generated skill does not contain `AskUserQuestion` at all.
- Generated Codex skills (e.g., `.agents/skills/gstack-checkpoint/SKILL.md:660`) literally say "If the skill says to use AskUserQuestion, do that". That tool isn't available to Codex in Default mode.
- `setup` (1011 lines) never touches `~/.codex/config.toml`. No feature flag gets enabled at install time.
- `bin/gstack-codex-probe` runs at skill invocation and handles auth, version checks, and timeout wrapping. It does not check Plan mode or tool availability.
- README, AGENTS.md, ARCHITECTURE.md, CHANGELOG.md: zero mentions of "Plan mode", "collaboration_modes", or `default_mode_request_user_input` in a Codex-integration context.
Net effect: the prompt instructs the model to call a tool that isn't in its schema, in a mode where the Codex equivalent wouldn't work anyway.
## Possible fixes (not mutually exclusive)
1. Add `toolRewrites: { AskUserQuestion: "request_user_input" }` to `hosts/codex.ts`. Apply it in the prompt-body transformer so Codex-generated skills reference the Codex tool name.
2. Document the Plan mode constraint in the Codex install path. A README block saying "after installing, type `/plan` in Codex before invoking gstack skills that need user input" would cover the common case.
3. Add a runtime fallback pattern to the Codex preamble: when the host signals no interactive tool is available, write a sentinel config file and halt with exit 2 rather than guessing values.
4. Apply the existing "auto-choose recommended option" pattern you use for OpenClaw spawned sessions (`SPAWNED_SESSION=true` branch in your generated Codex skills, e.g., `.agents/skills/gstack-checkpoint/SKILL.md:287`) to Codex Default mode as well. Gate it on a preamble probe that detects whether `request_user_input` is callable and sets a similar `INTERACTIVE_PROMPTS_AVAILABLE=false` flag the templates already respect. The machinery exists; only the Codex wiring is missing.
## How I found this
I'm building `resumasher` (https://github.com/earino/resumasher), a cross-host resume-tailoring skill for Claude Code, Codex CLI, and Gemini CLI. I hit this exact bug in my own skill. Codex in Default mode silently filled in user-identity answers I should have asked for. I looked at gstack expecting to copy your solution, and found you have the same gap.
I'm a big fan of gstack. `/office-hours`, `/plan-eng-review`, and `/devex-review` shaped resumasher's design substantially and I credit gstack in the README. Filing this as a contribution back rather than a complaint. Happy to turn it into a PR if the maintainers prefer.
## Environment
- gstack: latest `main` as of 2026-04-18
- Codex CLI: v0.121.0
- Claude Code: v2.1.114
- Gemini CLI: v0.38.2 (for contrast: Gemini's `ask_user` tool works in its default mode and does not have this issue)
Contributor guide
Assessment
This issue has not been assessed yet.