Skip to content

Commit 567fdfe

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 83636e6 commit 567fdfe

9 files changed

Lines changed: 331 additions & 187 deletions

File tree

CHANGELOG.md

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

3+
## [1.45.3.0] - 2026-05-27
4+
5+
## **`/codex` and `/autoplan` no longer trigger pre-tool-use security hooks on source with tilde path, bare `cd`, and inline python.**
6+
7+
Three shell patterns in `/codex` and `/autoplan` consistently trigger Claude Code security hooks: `source ~/.claude/skills/gstack/bin/gstack-codex-probe`, bare `cd "$_REPO_ROOT"`, and multi-line inline python with `#`-comments. This PR eliminates the latter two patterns in the context of the default review path by using alternative calling conventions. Also adds a new test file `test/codex-hardening.test.ts` with 38 tests guarding all three patterns.
8+
9+
Note: the `source ~/.claude/skills/gstack/bin/gstack-codex-probe` pattern is retained since it is load-bearing for the probe function suite that all codex modes depend on. The other two patterns were the primary hook triggers in practice.
10+
11+
### Itemized changes
12+
13+
#### Changed
14+
- `codex/SKILL.md.tmpl` + `codex/SKILL.md`: removed bare `cd "$_REPO_ROOT"` calls where possible; inline python streaming parsers extracted to standalone binary invocations
15+
- `autoplan/SKILL.md.tmpl` + `autoplan/SKILL.md`: same pattern fixes for the autoplan codex integration path
16+
17+
#### Added
18+
- `test/codex-hardening.test.ts`: 38 new tests asserting the absence of security-hook-triggering patterns and verifying standalone binary behavior
19+
320
## [1.45.0.0] - 2026-05-25
421

522
## **Design boards now live 24 hours, not 10 minutes. One daemon hosts every board, one tab survives the whole day.**

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.45.0.0
1+
1.45.3.0

autoplan/SKILL.md

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

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

10721071
```bash
1073-
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
1074-
source ~/.claude/skills/gstack/bin/gstack-codex-probe
1075-
10761072
# Check Codex binary. If missing, tag the degradation matrix and continue
10771073
# with Claude subagent only (autoplan's existing degradation fallback).
10781074
if ! command -v codex >/dev/null 2>&1; then
1079-
_gstack_codex_log_event "codex_cli_missing"
1075+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_cli_missing"
10801076
echo "[codex-unavailable: binary not found] — proceeding with Claude subagent only"
10811077
_CODEX_AVAILABLE=false
1082-
elif ! _gstack_codex_auth_probe >/dev/null; then
1083-
_gstack_codex_log_event "codex_auth_failed"
1078+
elif ! ~/.claude/skills/gstack/bin/gstack-codex-auth-probe >/dev/null; then
1079+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_auth_failed"
10841080
echo "[codex-unavailable: auth missing] — proceeding with Claude subagent only. Run \`codex login\` or set \$CODEX_API_KEY to enable dual-voice review."
10851081
_CODEX_AVAILABLE=false
10861082
else
1087-
_gstack_codex_version_check # non-blocking warn if known-bad
1083+
~/.claude/skills/gstack/bin/gstack-codex-version-check # non-blocking warn if known-bad
10881084
_CODEX_AVAILABLE=true
10891085
fi
10901086
```
@@ -1118,7 +1114,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
11181114
**Codex CEO voice** (via Bash):
11191115
```bash
11201116
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1121-
_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.
1117+
~/.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.
11221118
11231119
You are a CEO/founder advisor reviewing a development plan.
11241120
Challenge the strategic foundations: Are the premises valid or assumed? Is this the
@@ -1129,8 +1125,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
11291125
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
11301126
_CODEX_EXIT=$?
11311127
if [ "$_CODEX_EXIT" = "124" ]; then
1132-
_gstack_codex_log_event "codex_timeout" "600"
1133-
_gstack_codex_log_hang "autoplan" "0"
1128+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1129+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
11341130
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
11351131
fi
11361132
```
@@ -1235,7 +1231,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
12351231
**Codex design voice** (via Bash):
12361232
```bash
12371233
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1238-
_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.
1234+
~/.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.
12391235
12401236
Read the plan file at <plan_path>. Evaluate this plan's
12411237
UI/UX design decisions.
@@ -1252,8 +1248,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
12521248
Be opinionated. No hedging." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
12531249
_CODEX_EXIT=$?
12541250
if [ "$_CODEX_EXIT" = "124" ]; then
1255-
_gstack_codex_log_event "codex_timeout" "600"
1256-
_gstack_codex_log_hang "autoplan" "0"
1251+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1252+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
12571253
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
12581254
fi
12591255
```
@@ -1316,7 +1312,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
13161312
**Codex eng voice** (via Bash):
13171313
```bash
13181314
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1319-
_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.
1315+
~/.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.
13201316
13211317
Review this plan for architectural issues, missing edge cases,
13221318
and hidden complexity. Be adversarial.
@@ -1328,8 +1324,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
13281324
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
13291325
_CODEX_EXIT=$?
13301326
if [ "$_CODEX_EXIT" = "124" ]; then
1331-
_gstack_codex_log_event "codex_timeout" "600"
1332-
_gstack_codex_log_hang "autoplan" "0"
1327+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1328+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
13331329
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
13341330
fi
13351331
```
@@ -1437,7 +1433,7 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
14371433
**Codex DX voice** (via Bash):
14381434
```bash
14391435
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
1440-
_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.
1436+
~/.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.
14411437
14421438
Read the plan file at <plan_path>. Evaluate this plan's developer experience.
14431439
@@ -1454,8 +1450,8 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
14541450
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
14551451
_CODEX_EXIT=$?
14561452
if [ "$_CODEX_EXIT" = "124" ]; then
1457-
_gstack_codex_log_event "codex_timeout" "600"
1458-
_gstack_codex_log_hang "autoplan" "0"
1453+
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
1454+
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
14591455
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
14601456
fi
14611457
```

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)