* fix(#2479): drop the codex hook-trust bypass flag and its capability probe The /gsd-review codex lane emitted a hook-trust bypass flag via a capability-probed variable (#1115). Host-harness safety classifiers deny commands carrying the flag (23/33 sampled invocations), one denial citing the probe itself as intent, while flagless retries succeeded 32/32 — the flag only bypasses persisted hook trust, a first-run condition with no steady-state value. Remove both the flag and the probe per maintainer direction (no config key). #1115's diagnosability half — stderr to .err, folded into the lane on empty output — is untouched; its version-gate becomes vacuous with no flag to gate. The regression test inverts: the literal flag is now banned file-wide in review.md (covers continuation lines, carrier variables, and probes), alongside bans on the carrier variable and any codex help-grep probe shape. Fixes #2479 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(#2479): add changeset for PR #2536 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(#2479): changeset body in house format (bold lead) + post-rebase fixture regen Review round 2 Minor: wrap the changeset lead clause in the required **bold** span (reviewer-supplied text, applied verbatim). Rebased onto current next; golden-install-parity (19 runtimes) + size baseline regenerated — delta confined to review.md's hash/size. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
6ee4349272
commit
a40ee8a5e7
5
.changeset/tidy-rams-dart.md
Normal file
5
.changeset/tidy-rams-dart.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 2536
|
||||
---
|
||||
**`/gsd-review`'s codex lane no longer passes the hook-trust bypass flag or runs its capability probe** — host-harness safety classifiers denied invocations carrying them, and flagless invocations work in steady state. A genuine untrusted-hook failure still surfaces as a dropped lane with diagnosable stderr. (#2479)
|
||||
@@ -255,18 +255,20 @@ AGY_MODEL=$(gsd_run query config-get review.models.agy 2>/dev/null | jq -r '.' 2
|
||||
CLAUDE_EFFORT_ARGS=$(gsd_run query resolve-execution gsd-plan-checker --host claude 2>/dev/null | jq -r '.effort_argv_string // ""' 2>/dev/null || true)
|
||||
CODEX_EFFORT_ARGS=$(gsd_run query resolve-execution gsd-plan-checker --host codex 2>/dev/null | jq -r '.effort_argv_string // ""' 2>/dev/null || true)
|
||||
OPENCODE_EFFORT_ARGS=$(gsd_run query resolve-execution gsd-plan-checker --host opencode 2>/dev/null | jq -r '.effort_argv_string // ""' 2>/dev/null || true)
|
||||
|
||||
# #1115: `--dangerously-bypass-hook-trust` only exists on codex-cli >= 0.137.0.
|
||||
# Capability-probe it so older installs don't fail with "unexpected argument"
|
||||
# (which, with stderr suppressed, produced a silent empty review). The codex
|
||||
# invocation works fine without the flag on older versions.
|
||||
if codex exec --help 2>/dev/null | grep -q -- '--dangerously-bypass-hook-trust'; then
|
||||
CODEX_BYPASS_FLAG="--dangerously-bypass-hook-trust"
|
||||
else
|
||||
CODEX_BYPASS_FLAG=""
|
||||
fi
|
||||
```
|
||||
|
||||
**No hook-trust bypass (#2479):** the codex invocations below deliberately pass no
|
||||
hook-trust bypass flag and run no capability probe for one (#1115's former gate).
|
||||
That flag only bypasses *persisted* hook trust (a first-run condition) and flagless
|
||||
invocations work in steady state, while host-harness safety classifiers deny
|
||||
commands carrying it — and cited the probe itself as intent (#2479). An environment
|
||||
that genuinely hits an untrusted-hook prompt surfaces through the `.err` capture +
|
||||
empty-output guard below as a dropped lane with diagnosable stderr, not silent
|
||||
attrition. Do not reintroduce the flag (even spelled out in prose here — a
|
||||
regression test bans the literal file-wide) or the probe; the #1115 "unexpected
|
||||
argument" failure mode existed only because the flag was emitted, so with no flag
|
||||
there is nothing to version-gate.
|
||||
|
||||
**Reviewer instances (#1517, optional):** when instances are configured, each selected
|
||||
instance invokes its base `cli` with its own `model`/`agent` (opaque argv, never
|
||||
shell-interpolated). Exact invocation in `gsd-core/references/reviewer-instances.md`.
|
||||
@@ -315,18 +317,18 @@ fi
|
||||
|
||||
**Codex:**
|
||||
```bash
|
||||
# $CODEX_BYPASS_FLAG is capability-gated above (#1115). Capture stderr to a .err
|
||||
# file (not /dev/null) so a non-zero exit — e.g. a flag the installed codex-cli
|
||||
# does not support — is diagnosable instead of a silent empty review.
|
||||
# No hook-trust bypass flag — see the #2479 note above. Capture stderr to a .err
|
||||
# file (not /dev/null) so a non-zero exit — e.g. an untrusted-hook prompt on a
|
||||
# first run — is diagnosable instead of a silent empty review (#1115).
|
||||
# Capture the review via codex's own `-o/--output-last-message <FILE>` (only the
|
||||
# final agent message) and discard stdout (#1698): on some platforms (Windows)
|
||||
# codex writes process-teardown output to stdout *after* the final message, and a
|
||||
# stdout redirect would append that noise to a non-empty file — slipping past the
|
||||
# `[ ! -s … ]` empty-output guard as a silently polluted review.
|
||||
if [ -n "$CODEX_MODEL" ] && [ "$CODEX_MODEL" != "null" ]; then
|
||||
cat {run_dir}/gsd-review-prompt.md | codex exec --ephemeral $CODEX_BYPASS_FLAG --model "$CODEX_MODEL" $CODEX_EFFORT_ARGS --skip-git-repo-check -o {run_dir}/gsd-review-codex.md - 2>{run_dir}/gsd-review-codex.err >/dev/null
|
||||
cat {run_dir}/gsd-review-prompt.md | codex exec --ephemeral --model "$CODEX_MODEL" $CODEX_EFFORT_ARGS --skip-git-repo-check -o {run_dir}/gsd-review-codex.md - 2>{run_dir}/gsd-review-codex.err >/dev/null
|
||||
else
|
||||
cat {run_dir}/gsd-review-prompt.md | codex exec --ephemeral $CODEX_BYPASS_FLAG $CODEX_EFFORT_ARGS --skip-git-repo-check -o {run_dir}/gsd-review-codex.md - 2>{run_dir}/gsd-review-codex.err >/dev/null
|
||||
cat {run_dir}/gsd-review-prompt.md | codex exec --ephemeral $CODEX_EFFORT_ARGS --skip-git-repo-check -o {run_dir}/gsd-review-codex.md - 2>{run_dir}/gsd-review-codex.err >/dev/null
|
||||
fi
|
||||
if [ ! -s {run_dir}/gsd-review-codex.md ]; then
|
||||
echo "Codex review failed or returned empty output. stderr:" > {run_dir}/gsd-review-codex.md
|
||||
@@ -504,9 +506,9 @@ fi
|
||||
# #2176: grant the reviewer the repo under review. Without --add-dir, agy's
|
||||
# permission context never receives the cwd repo — the agent anchors on its own
|
||||
# ~/.gemini/antigravity-cli/scratch dir and reviews the plan text in isolation
|
||||
# (the exact failure the Review Instructions forbid). Capability-probed like the
|
||||
# Codex bypass flag so an older agy without --add-dir still runs; the prompt
|
||||
# anchor below keeps absolute-path reads possible on that fallback.
|
||||
# (the exact failure the Review Instructions forbid). Capability-probed so an
|
||||
# older agy without --add-dir still runs; the prompt anchor below keeps
|
||||
# absolute-path reads possible on that fallback.
|
||||
if agy --help 2>/dev/null | grep -q -- '--add-dir'; then
|
||||
set -- "$@" --add-dir "$_AGY_WS"
|
||||
fi
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "23b9eb0858a2535e",
|
||||
"gsd-core/workflows/remove-workspace.md": "1058d1d3160eb120",
|
||||
"gsd-core/workflows/resume-project.md": "98e2cf8908e73a52",
|
||||
"gsd-core/workflows/review.md": "73ea346aebf61b77",
|
||||
"gsd-core/workflows/review.md": "b6a91a893a94b56b",
|
||||
"gsd-core/workflows/scan.md": "46c5a73f6f682023",
|
||||
"gsd-core/workflows/secure-phase.md": "9564c529052d1d36",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "8effc8742d58a11a",
|
||||
"gsd-core/workflows/remove-workspace.md": "64b73daff58b9aec",
|
||||
"gsd-core/workflows/resume-project.md": "af9761bcec0f6fe9",
|
||||
"gsd-core/workflows/review.md": "7838e12644bf808a",
|
||||
"gsd-core/workflows/review.md": "145646378b6243ec",
|
||||
"gsd-core/workflows/scan.md": "686e787d3704db90",
|
||||
"gsd-core/workflows/secure-phase.md": "a7272ff8163a61ac",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "015cde237c75be39",
|
||||
"gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96",
|
||||
"gsd-core/workflows/review.md": "fa72c8f343102dba",
|
||||
"gsd-core/workflows/review.md": "4d4975c16d79515d",
|
||||
"gsd-core/workflows/scan.md": "a71e3009998cfc57",
|
||||
"gsd-core/workflows/secure-phase.md": "ba807b4862d7f3c9",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "e336350f8113a328",
|
||||
"gsd-core/workflows/remove-workspace.md": "79d3669cc9eb0b10",
|
||||
"gsd-core/workflows/resume-project.md": "e23981178fa37b3d",
|
||||
"gsd-core/workflows/review.md": "2a95ced731e6d14c",
|
||||
"gsd-core/workflows/review.md": "eb0a2e4e10bf92ab",
|
||||
"gsd-core/workflows/scan.md": "f0bd2f64f5530598",
|
||||
"gsd-core/workflows/secure-phase.md": "1a2e389991fc6263",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -407,7 +407,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "9ee0fddd11a0d9d4",
|
||||
"gsd-core/workflows/remove-workspace.md": "d0160c5d05bcb2bb",
|
||||
"gsd-core/workflows/resume-project.md": "9965f87eb278f7f8",
|
||||
"gsd-core/workflows/review.md": "9987e9fd8f7e5adb",
|
||||
"gsd-core/workflows/review.md": "b8108a114467fafe",
|
||||
"gsd-core/workflows/scan.md": "dcd6aac25ef39251",
|
||||
"gsd-core/workflows/secure-phase.md": "3ba89719288dd3f3",
|
||||
"gsd-core/workflows/session-report.md": "dd8fa011c9394075",
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "e262654e319d1bc4",
|
||||
"gsd-core/workflows/remove-workspace.md": "e7e5b5b1e0cc9d81",
|
||||
"gsd-core/workflows/resume-project.md": "40db7f350f5866d8",
|
||||
"gsd-core/workflows/review.md": "6aad3c5254932206",
|
||||
"gsd-core/workflows/review.md": "49d74c87b31abce8",
|
||||
"gsd-core/workflows/scan.md": "76aad4e70281c364",
|
||||
"gsd-core/workflows/secure-phase.md": "d60aa4053154e52f",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "0572a83d71650937",
|
||||
"gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96",
|
||||
"gsd-core/workflows/review.md": "f5972bbe92dc5f0c",
|
||||
"gsd-core/workflows/review.md": "837e0cba258335b5",
|
||||
"gsd-core/workflows/scan.md": "a71e3009998cfc57",
|
||||
"gsd-core/workflows/secure-phase.md": "b008216148d2afac",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "fce799aae3ab2715",
|
||||
"gsd-core/workflows/remove-workspace.md": "42029a7559f1d8fb",
|
||||
"gsd-core/workflows/resume-project.md": "a0443839f1f83c2d",
|
||||
"gsd-core/workflows/review.md": "b7aa706def0b93d6",
|
||||
"gsd-core/workflows/review.md": "0ba5a89b6b164971",
|
||||
"gsd-core/workflows/scan.md": "5c2370d6a8118b6c",
|
||||
"gsd-core/workflows/secure-phase.md": "c087131f1dd12901",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "f5dc82bb63e2efa4",
|
||||
"gsd-core/workflows/resume-project.md": "7f8dc986f0f35d96",
|
||||
"gsd-core/workflows/review.md": "c5c59f2bb70396ab",
|
||||
"gsd-core/workflows/review.md": "e86d4d7ac6b8a025",
|
||||
"gsd-core/workflows/scan.md": "c039d3e40d26b606",
|
||||
"gsd-core/workflows/secure-phase.md": "5a8fbf603d218100",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -329,7 +329,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -365,7 +365,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "dea4661e8f89596f",
|
||||
"gsd-core/workflows/remove-workspace.md": "21a8581add5f31ae",
|
||||
"gsd-core/workflows/resume-project.md": "ad9f06a10bab8cc0",
|
||||
"gsd-core/workflows/review.md": "486bc0f9ab4c24f4",
|
||||
"gsd-core/workflows/review.md": "65770618edc68d3f",
|
||||
"gsd-core/workflows/scan.md": "cbfb79df855e5e61",
|
||||
"gsd-core/workflows/secure-phase.md": "ef09f40dfd4d2424",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
2
tests/fixtures/golden-install-parity/pi.json
vendored
2
tests/fixtures/golden-install-parity/pi.json
vendored
@@ -268,7 +268,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "e8ae4fbbfac700f0",
|
||||
"gsd-core/workflows/remove-workspace.md": "ae520235f4d1f4a5",
|
||||
"gsd-core/workflows/resume-project.md": "7f20769f302e5427",
|
||||
"gsd-core/workflows/review.md": "3db704f47d7a5bde",
|
||||
"gsd-core/workflows/review.md": "0c0037cacbee532f",
|
||||
"gsd-core/workflows/scan.md": "b7efd0d381a3b8a5",
|
||||
"gsd-core/workflows/secure-phase.md": "f7bfa7175102af31",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "a46c2fe853bf4e86",
|
||||
"gsd-core/workflows/remove-workspace.md": "8ddc5f04f7c48d6c",
|
||||
"gsd-core/workflows/resume-project.md": "f242e4c8aba18ea2",
|
||||
"gsd-core/workflows/review.md": "b02dae5c743b1797",
|
||||
"gsd-core/workflows/review.md": "db77e672b2312bba",
|
||||
"gsd-core/workflows/scan.md": "3b14bcb51d3a4de8",
|
||||
"gsd-core/workflows/secure-phase.md": "267393d5b02b5334",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "e7a6af429b36e77b",
|
||||
"gsd-core/workflows/remove-workspace.md": "30ca05fe4a3efc25",
|
||||
"gsd-core/workflows/resume-project.md": "82cfe1b8cb17c085",
|
||||
"gsd-core/workflows/review.md": "f3fdf577dbc08f5f",
|
||||
"gsd-core/workflows/review.md": "8e345b36846e11e3",
|
||||
"gsd-core/workflows/scan.md": "4a910da5e34f2685",
|
||||
"gsd-core/workflows/secure-phase.md": "d5d811bc468ce7f2",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "f67860c795fb4bfe",
|
||||
"gsd-core/workflows/resume-project.md": "f28da1200e4545f4",
|
||||
"gsd-core/workflows/review.md": "ed04746925ea035f",
|
||||
"gsd-core/workflows/review.md": "cc0125d717a29c25",
|
||||
"gsd-core/workflows/scan.md": "e1c12d542e61720d",
|
||||
"gsd-core/workflows/secure-phase.md": "fda2361739e511ee",
|
||||
"gsd-core/workflows/session-report.md": "2e5b1205324ddefa",
|
||||
|
||||
@@ -259,15 +259,16 @@ const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
describe('enh-773: automated codex exec invocations include --ephemeral and --dangerously-bypass-hook-trust', () => {
|
||||
describe('enh-773: automated codex exec invocations include --ephemeral (hook-trust bypass dropped by #2479)', () => {
|
||||
const workflow = fs.readFileSync(
|
||||
path.join(process.cwd(), 'gsd-core', 'workflows', 'review.md'),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
// Extract codex exec INVOCATION lines from code fences. The #1115 capability
|
||||
// probe (`codex exec --help | grep …`) is not an automation invocation, so it
|
||||
// is excluded from the per-invocation flag assertions below.
|
||||
// Extract codex exec INVOCATION lines from code fences. A `codex exec --help`
|
||||
// capability probe would not be an automation invocation, so keep it excluded
|
||||
// from the per-invocation flag assertions below (#2479 asserts no such probe
|
||||
// exists at all).
|
||||
const codexExecLines = workflow
|
||||
.split(/\r?\n/)
|
||||
.filter((line) => line.includes('codex exec') && !line.includes('codex exec --help'));
|
||||
@@ -288,29 +289,29 @@ describe('enh-773: automated codex exec invocations include --ephemeral and --da
|
||||
}
|
||||
});
|
||||
|
||||
test('#1115: the hook-trust bypass is capability-gated, not passed unconditionally', () => {
|
||||
// --dangerously-bypass-hook-trust only exists on codex-cli >= 0.137.0. It must
|
||||
// be probed (`codex exec --help | grep`) and applied via $CODEX_BYPASS_FLAG so
|
||||
// older installs do not fail with "unexpected argument" (a silent empty review).
|
||||
test('#2479: no hook-trust bypass — flag and capability probe are both absent', () => {
|
||||
// The flag only bypasses *persisted* hook trust (a first-run condition) and
|
||||
// flagless invocations work in steady state, while host-harness safety
|
||||
// classifiers deny commands carrying it — and cited the probe itself as
|
||||
// intent. Inverts the former #1115 gating contract: instead of probe + gated
|
||||
// $CODEX_BYPASS_FLAG, the workflow must be free of the literal flag string
|
||||
// ANYWHERE in the file — not just on invocation lines — so a line
|
||||
// continuation, a renamed carrier variable, or a probe grepping for it are
|
||||
// all caught by the same assertion. (The #2479 prose note deliberately
|
||||
// describes the flag without spelling it out, keeping the file-wide ban
|
||||
// clean.)
|
||||
assert.ok(
|
||||
/codex exec --help[^\r\n]*grep[^\r\n]*--dangerously-bypass-hook-trust/.test(workflow),
|
||||
'review.md must capability-probe --dangerously-bypass-hook-trust via `codex exec --help | grep`'
|
||||
!workflow.includes('--dangerously-bypass-hook-trust'),
|
||||
'review.md must not contain --dangerously-bypass-hook-trust anywhere (#2479 — file-wide ban covers invocations, continuations, carrier variables, and probes)'
|
||||
);
|
||||
assert.ok(
|
||||
workflow.includes('CODEX_BYPASS_FLAG="--dangerously-bypass-hook-trust"'),
|
||||
'the probe must set CODEX_BYPASS_FLAG to the flag when the CLI supports it'
|
||||
!workflow.includes('CODEX_BYPASS_FLAG'),
|
||||
'review.md must not interpolate a $CODEX_BYPASS_FLAG variable (#2479)'
|
||||
);
|
||||
assert.ok(
|
||||
!/codex[^\r\n]*--help[^\r\n]*grep/.test(workflow),
|
||||
'review.md must not capability-probe codex flags via `codex --help | grep` (#2479 — the probe itself feeds harness safety classifiers)'
|
||||
);
|
||||
for (const line of codexExecLines) {
|
||||
assert.ok(
|
||||
line.includes('$CODEX_BYPASS_FLAG'),
|
||||
`codex exec invocation must apply the capability-gated $CODEX_BYPASS_FLAG, not an unconditional flag:\n ${line.trim()}`
|
||||
);
|
||||
// …and must NOT also pass the literal flag (that would reintroduce #1115).
|
||||
assert.ok(
|
||||
!line.includes('--dangerously-bypass-hook-trust'),
|
||||
`codex exec invocation must not pass the literal --dangerously-bypass-hook-trust (use the gated $CODEX_BYPASS_FLAG):\n ${line.trim()}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('#1115: codex review failures are surfaced, not silently swallowed', () => {
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"remove-phase.md": 8513,
|
||||
"remove-workspace.md": 7916,
|
||||
"resume-project.md": 17270,
|
||||
"review.md": 52646,
|
||||
"review.md": 52964,
|
||||
"scan.md": 8314,
|
||||
"secure-phase.md": 14627,
|
||||
"session-report.md": 4044,
|
||||
|
||||
Reference in New Issue
Block a user