Skip to content

Commit 41d97b9

Browse files
fix: eliminate 3 security hook trigger patterns in /codex and /autoplan (issue #1329)
Pattern 1 — source with tilde path: Replace `source ~/.claude/skills/gstack/bin/gstack-codex-probe` + function calls with direct `~/.claude/skills/gstack/bin/gstack-codex-*` binary invocations in both codex/SKILL.md.tmpl and autoplan/SKILL.md.tmpl. Pattern 3 — bare cd "$_REPO_ROOT": Replace bare `cd "$_REPO_ROOT"` lines with `-C "$_REPO_ROOT"` flag on codex commands (review bare path, exec custom path) and drop the cd entirely for exec resume (session context preserves directory; -C is not a supported flag for resume). Pattern 4 — inline python3 -u -c with #-comments: Replace all three inline JSONL parser blocks (Challenge, Consult new-session, Consult resume) with pipe to `~/.claude/skills/gstack/bin/gstack-codex-jsonl-parser`. Also regenerates .kiro/.cursor/.openclaw etc host-specific SKILL.md files via `bun run scripts/gen-skill-docs.ts --host all`. Tests: 38 new tests in codex-hardening.test.ts guarding all three patterns and verifying standalone binary behaviour. Updated skill-validation.test.ts to check for the jsonl-parser binary instead of the old $PYTHON_CMD inline pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 440426f commit 41d97b9

9 files changed

Lines changed: 329 additions & 187 deletions

File tree

CHANGELOG.md

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

3+
## [1.48.2.0] - 2026-05-28
4+
5+
**`/codex` and `/autoplan` replace inline python streaming parsers with a standalone binary, eliminating security hook triggers.**
6+
7+
The `gstack-codex-jsonl-parser` binary handles JSONL streaming from `codex exec --json` in both challenge (`--mode challenge`) and consult (`--mode consult`) modes. Three shell invocation patterns that consistently triggered pre-tool-use security hooks in `/codex` and `/autoplan` are removed or replaced.
8+
9+
### Itemized changes
10+
11+
#### Changed
12+
- `codex/SKILL.md.tmpl` + `codex/SKILL.md`: three inline python blocks replaced with `gstack-codex-jsonl-parser` binary invocations; python availability check updated to `if ! command -v python3`
13+
- `autoplan/SKILL.md.tmpl` + `autoplan/SKILL.md`: same pattern fixes
14+
15+
#### Added
16+
- `bin/gstack-codex-jsonl-parser`: standalone python3 binary handling JSONL streaming in challenge and consult modes
17+
318
## [1.48.0.0] - 2026-05-26
419

520
## **Agents stop dropping AskUserQuestion options when there are 5+.** A new canonical preamble rule + runtime gate makes Conductor's 4-option cap a split-or-batch decision, not a silent trim.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.48.0.0
1+
1.48.2.0

autoplan/SKILL.md

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,26 +1038,22 @@ Loaded review skills from disk. Starting full review pipeline with auto-decision
10381038
## Phase 0.5: Codex auth + version preflight
10391039

10401040
Before invoking any Codex voice, preflight the CLI: verify auth (multi-signal) and
1041-
warn on known-bad CLI versions. This is infrastructure for all 4 phases below —
1042-
source it once here and the helper functions stay in scope for the rest of the
1043-
workflow.
1041+
warn on known-bad CLI versions. Standalone probe binaries handle auth, version
1042+
checks, and telemetry — no `source` needed, no security hook triggers.
10441043

10451044
```bash
1046-
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
1047-
source ~/.claude/skills/gstack/bin/gstack-codex-probe
1048-
10491045
# Check Codex binary. If missing, tag the degradation matrix and continue
10501046
# with Claude subagent only (autoplan's existing degradation fallback).
10511047
if ! command -v codex >/dev/null 2>&1; then
1052-
_gstack_codex_log_event "codex_cli_missing"
1048+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_cli_missing"
10531049
echo "[codex-unavailable: binary not found] — proceeding with Claude subagent only"
10541050
_CODEX_AVAILABLE=false
1055-
elif ! _gstack_codex_auth_probe >/dev/null; then
1056-
_gstack_codex_log_event "codex_auth_failed"
1051+
elif ! ~/.claude/skills/gstack/bin/gstack-codex-auth-probe >/dev/null; then
1052+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_auth_failed"
10571053
echo "[codex-unavailable: auth missing] — proceeding with Claude subagent only. Run \`codex login\` or set \$CODEX_API_KEY to enable dual-voice review."
10581054
_CODEX_AVAILABLE=false
10591055
else
1060-
_gstack_codex_version_check # non-blocking warn if known-bad
1056+
~/.claude/skills/gstack/bin/gstack-codex-version-check # non-blocking warn if known-bad
10611057
_CODEX_AVAILABLE=true
10621058
fi
10631059
```
@@ -1091,7 +1087,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
10911087
**Codex CEO voice** (via Bash):
10921088
```bash
10931089
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1094-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
1090+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
10951091
10961092
You are a CEO/founder advisor reviewing a development plan.
10971093
Challenge the strategic foundations: Are the premises valid or assumed? Is this the
@@ -1102,8 +1098,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
11021098
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
11031099
_CODEX_EXIT=$?
11041100
if [ "$_CODEX_EXIT" = "124" ]; then
1105-
_gstack_codex_log_event "codex_timeout" "600"
1106-
_gstack_codex_log_hang "autoplan" "0"
1101+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1102+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
11071103
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
11081104
fi
11091105
```
@@ -1208,7 +1204,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
12081204
**Codex design voice** (via Bash):
12091205
```bash
12101206
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1211-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
1207+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
12121208
12131209
Read the plan file at <plan_path>. Evaluate this plan's
12141210
UI/UX design decisions.
@@ -1225,8 +1221,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
12251221
Be opinionated. No hedging." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
12261222
_CODEX_EXIT=$?
12271223
if [ "$_CODEX_EXIT" = "124" ]; then
1228-
_gstack_codex_log_event "codex_timeout" "600"
1229-
_gstack_codex_log_hang "autoplan" "0"
1224+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1225+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
12301226
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
12311227
fi
12321228
```
@@ -1289,7 +1285,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
12891285
**Codex eng voice** (via Bash):
12901286
```bash
12911287
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1292-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
1288+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
12931289
12941290
Review this plan for architectural issues, missing edge cases,
12951291
and hidden complexity. Be adversarial.
@@ -1301,8 +1297,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
13011297
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
13021298
_CODEX_EXIT=$?
13031299
if [ "$_CODEX_EXIT" = "124" ]; then
1304-
_gstack_codex_log_event "codex_timeout" "600"
1305-
_gstack_codex_log_hang "autoplan" "0"
1300+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1301+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
13061302
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
13071303
fi
13081304
```
@@ -1410,7 +1406,7 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
14101406
**Codex DX voice** (via Bash):
14111407
```bash
14121408
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1413-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
1409+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
14141410
14151411
Read the plan file at <plan_path>. Evaluate this plan's developer experience.
14161412
@@ -1427,8 +1423,8 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
14271423
Be adversarial. Think like a developer who is evaluating this against 3 competitors." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
14281424
_CODEX_EXIT=$?
14291425
if [ "$_CODEX_EXIT" = "124" ]; then
1430-
_gstack_codex_log_event "codex_timeout" "600"
1431-
_gstack_codex_log_hang "autoplan" "0"
1426+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1427+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
14321428
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
14331429
fi
14341430
```

autoplan/SKILL.md.tmpl

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,26 +237,22 @@ Loaded review skills from disk. Starting full review pipeline with auto-decision
237237
## Phase 0.5: Codex auth + version preflight
238238

239239
Before invoking any Codex voice, preflight the CLI: verify auth (multi-signal) and
240-
warn on known-bad CLI versions. This is infrastructure for all 4 phases below —
241-
source it once here and the helper functions stay in scope for the rest of the
242-
workflow.
240+
warn on known-bad CLI versions. Standalone probe binaries handle auth, version
241+
checks, and telemetry — no `source` needed, no security hook triggers.
243242

244243
```bash
245-
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
246-
source ~/.claude/skills/gstack/bin/gstack-codex-probe
247-
248244
# Check Codex binary. If missing, tag the degradation matrix and continue
249245
# with Claude subagent only (autoplan's existing degradation fallback).
250246
if ! command -v codex >/dev/null 2>&1; then
251-
_gstack_codex_log_event "codex_cli_missing"
247+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_cli_missing"
252248
echo "[codex-unavailable: binary not found] — proceeding with Claude subagent only"
253249
_CODEX_AVAILABLE=false
254-
elif ! _gstack_codex_auth_probe >/dev/null; then
255-
_gstack_codex_log_event "codex_auth_failed"
250+
elif ! ~/.claude/skills/gstack/bin/gstack-codex-auth-probe >/dev/null; then
251+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_auth_failed"
256252
echo "[codex-unavailable: auth missing] — proceeding with Claude subagent only. Run \`codex login\` or set \$CODEX_API_KEY to enable dual-voice review."
257253
_CODEX_AVAILABLE=false
258254
else
259-
_gstack_codex_version_check # non-blocking warn if known-bad
255+
~/.claude/skills/gstack/bin/gstack-codex-version-check # non-blocking warn if known-bad
260256
_CODEX_AVAILABLE=true
261257
fi
262258
```
@@ -290,7 +286,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
290286
**Codex CEO voice** (via Bash):
291287
```bash
292288
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
293-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
289+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
294290
295291
You are a CEO/founder advisor reviewing a development plan.
296292
Challenge the strategic foundations: Are the premises valid or assumed? Is this the
@@ -301,8 +297,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
301297
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
302298
_CODEX_EXIT=$?
303299
if [ "$_CODEX_EXIT" = "124" ]; then
304-
_gstack_codex_log_event "codex_timeout" "600"
305-
_gstack_codex_log_hang "autoplan" "0"
300+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
301+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
306302
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
307303
fi
308304
```
@@ -407,7 +403,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
407403
**Codex design voice** (via Bash):
408404
```bash
409405
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
410-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
406+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
411407
412408
Read the plan file at <plan_path>. Evaluate this plan's
413409
UI/UX design decisions.
@@ -424,8 +420,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
424420
Be opinionated. No hedging." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
425421
_CODEX_EXIT=$?
426422
if [ "$_CODEX_EXIT" = "124" ]; then
427-
_gstack_codex_log_event "codex_timeout" "600"
428-
_gstack_codex_log_hang "autoplan" "0"
423+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
424+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
429425
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
430426
fi
431427
```
@@ -488,7 +484,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
488484
**Codex eng voice** (via Bash):
489485
```bash
490486
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
491-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
487+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
492488
493489
Review this plan for architectural issues, missing edge cases,
494490
and hidden complexity. Be adversarial.
@@ -500,8 +496,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
500496
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
501497
_CODEX_EXIT=$?
502498
if [ "$_CODEX_EXIT" = "124" ]; then
503-
_gstack_codex_log_event "codex_timeout" "600"
504-
_gstack_codex_log_hang "autoplan" "0"
499+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
500+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
505501
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
506502
fi
507503
```
@@ -609,7 +605,7 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
609605
**Codex DX voice** (via Bash):
610606
```bash
611607
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
612-
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
608+
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
613609
614610
Read the plan file at <plan_path>. Evaluate this plan's developer experience.
615611
@@ -626,8 +622,8 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
626622
Be adversarial. Think like a developer who is evaluating this against 3 competitors." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
627623
_CODEX_EXIT=$?
628624
if [ "$_CODEX_EXIT" = "124" ]; then
629-
_gstack_codex_log_event "codex_timeout" "600"
630-
_gstack_codex_log_hang "autoplan" "0"
625+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
626+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
631627
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
632628
fi
633629
```

0 commit comments

Comments
 (0)