mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 06:24:41 +01:00
* fix(make-pdf,design): real TOC page numbers and anchors; design models move to gpt-5.5 + gpt-image-2 (#2903, #2807) * ci: pin every action to a SHA, Scorecard, checksummed Bun, scoped Codex CLI in the CI image, macOS named-regressions job (#1948, #1706, #1997) * fix(cso,browse): Windows/macOS lease identity, retention skips bad runs, truthful 'not assessed' reports, env.kv false positive, Windows browse spawn fixes (#2894, #2912, #2048, #2637, #2805) * fix(outside-voice): one Codex model precedence for probe and dispatch, bounded timeouts with KILL escalation, probe cache identity, guarded mktemp, skills hidden in nested Codex (#2776, #2914, #2787, #2881, #2847) * feat(setup): install registry, ./setup --status, staged activation, per-scope migrations, host tiers and conformance kit, OpenCode/Hermes fixes, Copilot CLI (experimental), disabled_skills, slimmer CLAUDE.md (#1925, #2879, #2347, #2338, #2626, #2629, #2825, #2015, #393, #1206, #2096) Co-authored-by: Andrey Esipov <61357035+andrey-esipov@users.noreply.github.com> Co-authored-by: Matthew Williams <5863886+ridermw@users.noreply.github.com> Co-authored-by: Rocky Wu <92764750+lolisaigao1234@users.noreply.github.com> * fix(preamble): skills start in worktree-isolated Claude Code sessions — one literal skill-start line, context-recovery helper, no eval in skill blocks, $N token tripwire, honest plan-mode precedence (#2763, #2896, #2851) * fix(setup): per-install renders for renamed, vendored and custom-config installs, space-safe alias roots, per-host /cso launcher path (#1882, #2906) * test: free tests never write the real HOME (home-write tripwire), no orphaned browse daemons, symlinked-TMPDIR (macOS) fixes, gbrain-on-PATH isolation (#2895, #2816, #2829, #2841, #2982, #2911, #2909, #2908, #2910) * chore: integrate wave follow-ups — regenerate all hosts, README model docs, TODOS, touchfiles, duration seeds, Bun 1.3 telemetry test fix, replay fixtures pinned to their recorded bytes * v1.91.14.0: release metadata * test(browse): group-kill cleanup falls back to the leader when macOS returns EPERM for a live group * ci: Codex login steps run under bash (the CI container's default sh rejects pipefail) * fix: full-suite repairs — private state roots for 7 real-HOME writers, truthful home-guard attribution with --attribute-home, gstack-paths shim in ship-hook fixtures, Copilot in team-init probes, test-of-test detector, cookie review fixture pinned to the approved excerpt * fix(windows): LF for Dockerfiles, normalized home-guard exclusions, path.relative fixture containment, ship push test spawn timeouts * test(design-detect): widen the whole-scan budget test's timing margins so a loaded macOS runner can't time out the single-batch call * fix(evals): qa protocol names defined for the judge, async PTY judge so overlapping sessions keep their cleanup deadline, bws setup cases use the standard JUDGE_MS tier * test(pty): the non-blocking judge case is POSIX-only (its fake judge is a shebang script, like the PTY harness it covers) * test(evals): ship-coverage-audit names absolute skill paths, uses Read, and skips the Step 7 artifact nothing consumes (removes the mechanism behind 3 of 4 historical timeouts) * test: deflake terminal-agent concurrent startup (write the placeholder record before spawning, like the product) and qa-evidence resumed pipe (barrier on a full high-water mark instead of a sleep) * fix(design): daemon log stream handles open errors instead of crashing the daemon; shutdown test awaits the stubbed exit * test(evals): skillify checks the product's resolved state root (no GSTACK_HOME bypass), negative cases check every root; tpa shims live outside the agent's cwd and answer consistently * test(evals): coverage-audit detector splits parallel columns at │ rails and [+] groups; coverage prompts name absolute skill paths; TODOs from the gate eval census * fix(plan-eng-review): scope gate always sends the menu (no headless 'Scope pending' exit); PTY harness ends idle turn-ends and API-error panels promptly with a precise diagnostic * test(evals): one position-bound coverage-read rule credits read-only && chains (labels, context ranges, git displays in either order) and still rejects forged output * fix(ship): documentation section has one saved source inserted by cat (never retyped); spawned-marker evidence is the child output; refreshed codex/factory ship goldens * test(docsync): the byte-exact insert positive is POSIX-only (the bash-command observer refuses backslash paths by design) * test(evals): plan-design-with-ui focus-title rule accepts the comma-less 'dimensions or focus' wording (replayed on the captured CI run, negative controls kept) * fix(qa-callers): exploratory preflight says the scope/method Reads come after exploratory.md; design-review scan check credits an executed scan proven by one engine run over the changed files --------- Co-authored-by: Andrey Esipov <61357035+andrey-esipov@users.noreply.github.com> Co-authored-by: Matthew Williams <5863886+ridermw@users.noreply.github.com> Co-authored-by: Rocky Wu <92764750+lolisaigao1234@users.noreply.github.com>
325 lines
15 KiB
Cheetah
325 lines
15 KiB
Cheetah
---
|
|
name: codex
|
|
preamble-tier: 3
|
|
version: 1.0.0
|
|
description: |
|
|
OpenAI Codex CLI wrapper — three modes. Code review: independent diff review via
|
|
codex review with pass/fail gate. Challenge: adversarial mode that tries to break
|
|
your code. Consult: ask codex anything with session continuity for follow-ups.
|
|
The "200 IQ autistic developer" second opinion. Use when asked to "codex review",
|
|
"codex challenge", "ask codex", "second opinion", or "consult codex". (gstack)
|
|
voice-triggers:
|
|
- "code x"
|
|
- "code ex"
|
|
- "get another opinion"
|
|
triggers:
|
|
- codex review
|
|
- second opinion
|
|
- outside voice challenge
|
|
allowed-tools:
|
|
- Bash
|
|
- Read
|
|
- Write
|
|
- Glob
|
|
- Grep
|
|
- AskUserQuestion
|
|
---
|
|
|
|
{{PREAMBLE}}
|
|
|
|
{{BASE_BRANCH_DETECT}}
|
|
|
|
# /codex — Multi-AI Second Opinion
|
|
|
|
You are running the `/codex` skill. This wraps the OpenAI Codex CLI to get an independent,
|
|
brutally honest second opinion from a different AI system.
|
|
|
|
Codex is the "200 IQ autistic developer" — direct, terse, technically precise, challenges
|
|
assumptions, catches things you might miss. Present its output faithfully, not summarized.
|
|
|
|
---
|
|
|
|
{{SECTION_INDEX:codex}}
|
|
|
|
---
|
|
|
|
## Step 0.4: Check codex binary
|
|
|
|
```bash
|
|
CODEX_BIN=$(command -v codex || echo "")
|
|
[ -z "$CODEX_BIN" ] && echo "NOT_FOUND" || echo "FOUND: $CODEX_BIN"
|
|
```
|
|
|
|
If `NOT_FOUND`: stop and tell the user:
|
|
"Codex CLI not found. Install it: `npm install -g @openai/codex` or see https://github.com/openai/codex"
|
|
|
|
If `NOT_FOUND`, also log the event:
|
|
```bash
|
|
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
|
source ~/.claude/skills/gstack/bin/gstack-codex-probe 2>/dev/null && _gstack_codex_log_event "codex_cli_missing" 2>/dev/null || true
|
|
```
|
|
|
|
---
|
|
|
|
## Step 0.5: Auth probe + model probe + version check
|
|
|
|
Before building expensive prompts, verify Codex has valid auth, that the account
|
|
can actually USE gstack's selected model, AND the installed CLI version isn't in the
|
|
known-bad list. Sourcing `gstack-codex-probe` loads the shared helpers that both
|
|
`/codex` and `/autoplan` use.
|
|
|
|
Model order: a model the user names for this request, `GSTACK_CODEX_MODEL`, Codex
|
|
`config.toml` `model` (`review_model` first for `codex review`; honors `$CODEX_HOME`),
|
|
then `gpt-6-astra`. Each call prints `CODEX_MODEL: <model> (<kind>; source: ...)` first.
|
|
For a named model, pass it as the second argument of every `_gstack_codex_select_model`
|
|
call, and run `_gstack_codex_select_model exec '<model>'` before the probe below. An
|
|
invalid or unavailable choice stops with a repair message, never the default.
|
|
|
|
```bash
|
|
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
|
|
source ~/.claude/skills/gstack/bin/gstack-codex-probe
|
|
|
|
{{OUTSIDE_SELF_GUARD:codex}}
|
|
if ! _gstack_codex_auth_probe >/dev/null; then
|
|
_gstack_codex_log_event "codex_auth_failed"
|
|
echo "AUTH_FAILED"
|
|
else
|
|
_gstack_codex_model_probe # ~10s round trip on first run, cached 1h (#2477)
|
|
fi
|
|
_gstack_codex_version_check # warns if known-bad, non-blocking
|
|
```
|
|
|
|
If the runtime guard reports a harness mismatch, stop. Outside coverage is unavailable. Repair with `./setup --host codex`; do not silently substitute another provider or force a same-harness invocation.
|
|
|
|
If the output contains `AUTH_FAILED`, stop and tell the user:
|
|
"No Codex authentication found. Run `codex login` or set `$CODEX_API_KEY` / `$OPENAI_API_KEY`, then re-run this skill."
|
|
|
|
If the output contains `MODEL_UNUSABLE`, stop — the selected model (named with its
|
|
source on the `CODEX_MODEL:` line) is invalid or the account cannot use it. Relay the
|
|
probe's HINT lines and
|
|
follow the "Model not supported (HTTP 400)" recovery steps in
|
|
`## Error Handling` below. Running the modes anyway just burns four
|
|
invocations on the same 400 (#2477).
|
|
|
|
`MODEL_PROBE_INCONCLUSIVE` is non-blocking (timeout/transient network): pass
|
|
the warning through and continue.
|
|
|
|
If the version check printed a `WARN:` line, pass it through to the user verbatim
|
|
(non-blocking — Codex may still work, but the user should upgrade).
|
|
|
|
The probe multi-signal auth logic accepts: `$CODEX_API_KEY` set, `$OPENAI_API_KEY`
|
|
set, or `${CODEX_HOME:-~/.codex}/auth.json` exists. Avoids false-negatives for
|
|
env-auth users (CI, platform engineers) that file-only checks would reject.
|
|
|
|
---
|
|
|
|
## Step 0.6: Resolve portable roots
|
|
|
|
Before any mode runs, resolve `$PLAN_ROOT` (where plan files live) and `$TMP_ROOT`
|
|
(where ephemeral codex stderr / response captures land) via `bin/gstack-paths`.
|
|
This keeps the skill working whether installed as a Claude Code plugin
|
|
(`CLAUDE_PLANS_DIR` set), a global `~/.claude/skills/gstack/` install, or a CI
|
|
container where `HOME` may be unset and `/tmp` may be read-only.
|
|
|
|
```bash
|
|
GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ROOT); : "${GSTACK_STATE_ROOT:?gstack-paths failed; reinstall with ./setup or /gstack-upgrade}"
|
|
PLAN_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get PLAN_ROOT)
|
|
TMP_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get TMP_ROOT)
|
|
```
|
|
|
|
After this, every subsequent bash block in this skill uses `"$PLAN_ROOT"` and
|
|
`"$TMP_ROOT"` rather than hardcoded `~/.claude/plans` or `/tmp/codex-*`.
|
|
|
|
---
|
|
|
|
## Step 1: Detect mode
|
|
|
|
Parse the user's input to determine which mode to run:
|
|
|
|
1. `/codex review` or `/codex review <instructions>` — **Review mode** (Step 2A)
|
|
2. `/codex challenge` or `/codex challenge <focus>` — **Challenge mode** (Step 2B)
|
|
3. `/codex` with no arguments — **Auto-detect:**
|
|
- Check for a diff (with fallback if origin isn't available):
|
|
`git diff origin/<base> --stat 2>/dev/null | tail -1 || git diff <base> --stat 2>/dev/null | tail -1`
|
|
- If a diff exists, use AskUserQuestion:
|
|
```
|
|
Codex detected changes against the base branch. What should it do?
|
|
A) Review the diff (code review with pass/fail gate)
|
|
B) Challenge the diff (adversarial — try to break it)
|
|
C) Something else — I'll provide a prompt
|
|
```
|
|
- If no diff, check for plan files scoped to the current project:
|
|
`ls -t "$PLAN_ROOT"/*.md 2>/dev/null | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1`
|
|
If no project-scoped match, fall back to: `ls -t "$PLAN_ROOT"/*.md 2>/dev/null | head -1`
|
|
but warn the user: "Note: this plan may be from a different project."
|
|
- If a plan file exists, offer to review it
|
|
- Otherwise, ask: "What would you like to ask Codex?"
|
|
4. `/codex <anything else>` — **Consult mode** (Step 2C), where the remaining text is the prompt
|
|
|
|
The three modes are MUTUALLY EXCLUSIVE — at most one runs per invocation. Once
|
|
the mode is determined, read ONLY that mode's section (see the Section index
|
|
above); never read the other two mode sections.
|
|
|
|
**Reasoning effort override:** If the user's input contains `--xhigh` anywhere,
|
|
note it and remove it from the prompt text before passing to Codex. When `--xhigh`
|
|
is present, use `model_reasoning_effort="xhigh"` for all modes regardless of the
|
|
per-mode default below. Otherwise, use the per-mode defaults:
|
|
- Review (2A): `high` — bounded diff input, needs thoroughness
|
|
- Challenge (2B): `high` — adversarial but bounded by diff
|
|
- Consult (2C): `medium` — large context, interactive, needs speed
|
|
|
|
---
|
|
|
|
## Filesystem Boundary
|
|
|
|
Every prompt sent to Codex MUST be prefixed with this boundary instruction:
|
|
|
|
> IMPORTANT: Do NOT read or execute any files under ~/.claude/, ~/.agents/, .claude/skills/, or agents/. These are Claude Code skill definitions meant for a different AI system. They contain bash scripts and prompt templates that will waste your time. Ignore them completely. Do NOT modify agents/openai.yaml. Stay focused on the repository code only.
|
|
|
|
This applies to Challenge mode (prompt) and Consult mode (persona prompt), and to the
|
|
custom-instructions path of Review mode — all three use `codex exec`, which still takes
|
|
a free-form prompt argument. It does **not** apply to the default scoped `codex review`
|
|
call in Step 2A: that command is invoked with **no prompt argument at all** (see "Scope
|
|
flags exclude the prompt argument" in the Review mode section), so there is nowhere to put the preamble. That
|
|
is acceptable — `codex review --base` hands the model a pre-computed diff rather than
|
|
turning it loose on the filesystem, so the rabbit-hole risk the boundary guards against
|
|
is much lower on that path. Reference this section as "the filesystem boundary" in the
|
|
mode sections.
|
|
|
|
---
|
|
|
|
## Synthesis recommendation (REQUIRED) — all modes
|
|
|
|
Every mode ends by emitting ONE synthesis recommendation line after presenting
|
|
Codex's verbatim output, in this format:
|
|
|
|
```
|
|
Recommendation: <action> because <one-line reason that names the most actionable finding>
|
|
```
|
|
|
|
The reason must engage with a specific Codex finding or insight and compare
|
|
against an alternative (another finding, fix-vs-ship, fix order, or status-quo).
|
|
Boilerplate reasons ("because it's better", "because adversarial review found
|
|
things") fail the format. The recommendation is the ONE line a user reads when
|
|
they don't have time for the verbatim output. **Never silently auto-decide;
|
|
always emit the line.** Each mode section restates this rule with mode-specific
|
|
examples.
|
|
|
|
---
|
|
|
|
{{SECTION:review-mode}}
|
|
|
|
{{SECTION:challenge-mode}}
|
|
|
|
{{SECTION:consult-mode}}
|
|
|
|
{{PLAN_FILE_REVIEW_REPORT}}
|
|
|
|
{{EXIT_PLAN_MODE_GATE}}
|
|
|
|
---
|
|
|
|
## Model & Reasoning
|
|
|
|
**Model:** every Codex call passes the selection above via `{{CODEX_MODEL_CONFIG_FLAG}}`.
|
|
Native `codex review` selects with `review` and sets both `model` and `review_model`. The
|
|
flag also keeps installed skills out of Codex's context, so a review cannot become a
|
|
nested skill run.
|
|
|
|
**Reasoning effort (per-mode defaults):**
|
|
- **Review (2A):** `high` — bounded diff input, needs thoroughness but not max tokens
|
|
- **Challenge (2B):** `high` — adversarial but bounded by diff size
|
|
- **Consult (2C):** `medium` — large context (plans, codebase), interactive, needs speed
|
|
|
|
`xhigh` uses ~23x more tokens than `high` and causes 50+ minute hangs on large context
|
|
tasks (OpenAI issues #8545, #8402, #6931). Users can override with `--xhigh` flag
|
|
(e.g., `/codex review --xhigh`) when they want maximum reasoning and are willing to wait.
|
|
|
|
**Web search:** All codex commands pass `{{CODEX_WEB_SEARCH_FLAG}}` so `codex exec`
|
|
invocations can look up docs and APIs during review. This is OpenAI's cached index —
|
|
fast, no extra cost. Unlike the legacy `--enable`-based spelling (deprecated by
|
|
codex >=0.144), the `-c` form explicitly overrides any top-level
|
|
`web_search` setting in `~/.codex/config.toml`. Note: native `codex review` disables
|
|
web search regardless of configuration, so on the default Review path the flag is a
|
|
harmless no-op — only exec-based modes actually search.
|
|
|
|
If the user specifies a model (e.g., `/codex review -m gpt-5.6-sol` or
|
|
`/codex challenge --model gpt-daybreak-blue-latest`), translate it to the same config
|
|
form and replace the default model flag with `-c "model=\"<model>\""`. Native review
|
|
also requires `-c "review_model=\"<model>\""`; replace both model values together.
|
|
Review mode runs `codex review`, which REJECTS `-m` (`error: unexpected argument '-m' found`,
|
|
verified on 0.147.0), while `-c model=...` is accepted by both `codex review` and
|
|
`codex exec`.
|
|
|
|
---
|
|
|
|
## Cost Estimation
|
|
|
|
Parse token count from stderr. Codex prints `tokens used\nN` to stderr.
|
|
|
|
Display as: `Tokens: N`
|
|
|
|
If token count is not available, display: `Tokens: unknown`
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
- **Binary not found:** Detected in Step 0. Stop with install instructions.
|
|
- **Auth error:** Codex prints an auth error to stderr. Surface the error:
|
|
"Codex authentication failed. Run `codex login` in your terminal to authenticate via ChatGPT."
|
|
- **Timeout (Bash outer gate):** Every Bash gate sits ABOVE its inner wrapper (360s gate
|
|
over the 330s review wrapper; 600s gate, the tool maximum, over the 540s challenge/consult
|
|
wrappers), so
|
|
the wrapper's exit-124 path normally fires first with its explicit message. If the Bash
|
|
call itself times out anyway (wrapper unavailable AND codex hung), tell the user:
|
|
"Codex timed out. The prompt may be too large or the API may be slow. Try again or use a smaller scope."
|
|
- **Timeout (inner `timeout` wrapper, exit 124):** If the wrapper fires first (it TERMs Codex, then KILLs it after 10s), the skill's hang-detection block auto-logs a telemetry event + operational learning and prints: "Codex stalled past 9 minutes. Common causes: model API stall, long prompt, network issue. Try re-running. If persistent, split the prompt or check `~/.codex/logs/`." No extra action needed.
|
|
- **`the argument '[PROMPT]' cannot be used with '--base <BRANCH>'`:** a prompt argument
|
|
leaked into a scoped `codex review`. This fails instantly, before any API call, so it
|
|
looks like a hang-free "no output" — do not misread it as a model stall. Drop the
|
|
prompt: the scope flags (`--base`, `--commit`, `--uncommitted`) carry the scope on
|
|
their own. If the prompt was custom review instructions, run them through `codex exec`
|
|
instead (Step 2A, custom-instructions path). Do **not** fix it by removing `--base` and
|
|
keeping the prompt — that parses, but silently reviews the uncommitted working tree
|
|
instead of the branch diff.
|
|
- **Review says "no changes" on a branch that clearly has changes:** the scope flag is
|
|
missing or wrong. A prompt-only `codex review` defaults to uncommitted changes, so a
|
|
clean working tree reads as an empty review even when `<base>...HEAD` is large. Confirm
|
|
`--base <base>` is actually on the command line.
|
|
- **Model not supported (HTTP 400):** stderr shows
|
|
`The '<model>' model is not supported when using Codex with a ChatGPT account`
|
|
(a `status: 400` / `invalid_request_error` naming a model). This is a
|
|
model-entitlement problem, not an auth or network failure, and the auth probe
|
|
cannot catch it. Recovery, in order:
|
|
1. Read the `CODEX_MODEL:` line: it names the model and where it came from.
|
|
2. Fix that source: name another model for this request, update
|
|
`GSTACK_CODEX_MODEL`, or change `model` (or `review_model`) in the Codex
|
|
`config.toml`. With none of these set, gstack uses `gpt-6-astra`; set any of
|
|
them to a model the account can use.
|
|
3. If Codex printed `[notice.model_migrations]`, use that replacement model.
|
|
Never present this as a model stall or a PASS — it is a fail-closed gate result.
|
|
- **Empty response:** If `$TMPRESP` is empty or doesn't exist, tell the user:
|
|
"Codex returned no response. Check stderr for errors."
|
|
- **Session resume failure:** If resume fails, delete the session file and start fresh.
|
|
|
|
---
|
|
|
|
## Important Rules
|
|
|
|
- **Never modify files.** This skill is read-only. Codex runs in read-only sandbox mode.
|
|
- **Present output verbatim.** Do not truncate, summarize, or editorialize Codex's output
|
|
before showing it. Show it in full inside the CODEX SAYS block.
|
|
- **Add synthesis after, not instead of.** Any Claude commentary comes after the full output.
|
|
- **Bash gate above the wrapper.** Every Bash call to codex sets its `timeout`
|
|
parameter ABOVE the inner `_gstack_codex_timeout_wrapper` budget (Review:
|
|
`timeout: 360000` over the 330s wrapper; Challenge/Consult: `timeout: 600000`
|
|
over the 540s wrappers) so the wrapper fires first with a diagnosable exit 124.
|
|
- **No double-reviewing.** If the user already ran `/review`, Codex provides a second
|
|
independent opinion. Do not re-run Claude Code's own review.
|
|
- **Detect skill-file rabbit holes.** After receiving Codex output, scan for signs
|
|
that Codex got distracted by skill files: `gstack-config`, `gstack-update-check`,
|
|
`SKILL.md`, or `skills/gstack`. If any of these appear in the output, append a
|
|
warning: "Codex appears to have read gstack skill files instead of reviewing your
|
|
code. Consider retrying."
|