garrytan / garrytan/gstack

Codex skills that call AskUserQuestion silently fail in Default mode

Open
#1,066 1 comment 5 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.