fix: run the stop-gate review as an ephemeral, untracked, read-only one-shot#385
fix: run the stop-gate review as an ephemeral, untracked, read-only one-shot#385joelmdev wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Codex stop-time review gate execution path so the stop-gate “one-shot” review runs as an ephemeral, untracked, read-only task, preventing orphaned persisted threads and job-catalog churn while keeping the hook’s stdout contract intact.
Changes:
- Teach
executeTaskRunto honorrequest.persistThread(defaulting totrue) and avoid generating a persistent thread name when persistence is disabled. - Route stop-gate marker prompts through a foreground, untracked one-shot path in
handleTaskthat forcespersistThread: falseand omitswrite(read-only). - Update the stop-hook end-to-end test to assert the thread is ephemeral and that no “Codex Stop Gate Review” job appears in the catalog/status output.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/runtime.test.mjs | Adds assertions that stop-gate runs produce an ephemeral thread and do not create catalog jobs/status entries. |
| plugins/codex/scripts/codex-companion.mjs | Implements persistThread support in task execution and adds an early stop-gate one-shot execution path that bypasses tracked jobs and forces read-only. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5406e18692
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| resumeLast | ||
| }); | ||
|
|
||
| if (!resumeLast && String(prompt ?? "").includes(STOP_REVIEW_TASK_MARKER)) { |
There was a problem hiding this comment.
Gate only internal stop-review invocations
Any normal /codex:task prompt or --prompt-file that contains this marker sentence now takes the stop-gate path before --background or --write are honored. For example, asking Codex to edit or discuss plugins/codex/prompts/stop-review-gate.md with --write would be run as an untracked ephemeral read-only one-shot instead of a write-capable task, so the requested edits cannot be made and the job cannot be resumed or inspected. Consider keying this branch off an internal flag/env from stop-review-gate-hook.mjs rather than user-controlled prompt text alone.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in 4acaf32. Routing no longer reads the prompt: stop-review-gate-hook.mjs now passes an explicit --stop-gate flag, and handleTask keys the ephemeral/untracked/read-only branch off that flag instead of the marker sentence. So a normal /codex:task (or --prompt-file) whose text happens to contain the marker — e.g. editing prompts/stop-review-gate.md with --write — now runs as a normal write-capable, tracked, resumable task. Added a regression test asserting exactly that. Thanks for the catch!
…ne-shot
When the stop-time review gate is enabled, the Stop hook runs
`codex-companion.mjs task` every turn. That path forced
`persistThread: true` (persisting the thread as an on-disk rollout) and
registered a tracked "Codex Stop Gate Review" job in the companion
catalog (state.json + jobs/<id>.{json,log}).
But the stop-gate review is a one-shot: the hook consumes its result
inline (parsing ALLOW:/BLOCK: from stdout) and never resumes or inspects
it via /codex:status, /codex:result, or --resume-last. So every turn
orphaned a Codex rollout on disk and churned the 50-job catalog cap with
stop-gate noise, pushing out real tasks and reviews.
stop-review-gate-hook.mjs now marks its invocation with an explicit
`--stop-gate` flag, and handleTask routes on that flag (not
user-controlled prompt text) through an ephemeral, untracked, read-only
path: the check runs before the --background branch (so a backgrounded
run can't create a tracked job), passes persistThread: false (ephemeral
thread, no rollout, no thread name), and omits write so the review can
never select a writable sandbox. executeTaskRun now honors
request.persistThread (default true). The stdout contract is unchanged;
normal /codex:task runs are unaffected, even when their prompt text
happens to contain the stop-gate marker sentence.
5406e18 to
4acaf32
Compare
Problem
When the stop-time review gate is enabled, the
Stophook runscodex-companion.mjs taskon every turn. Thetaskpath always setpersistThread: true(persisting the thread as an on-disk rollout) and registered a tracked job in the companion catalog (state.json+jobs/<id>.{json,log}).But the stop-gate review is a one-shot: the hook consumes its result inline (parsing
ALLOW:/BLOCK:from stdout) and never resumes or inspects it via/codex:status,/codex:result, or--resume-last. So every turn leaves behind:On a busy machine this accumulates into hundreds of orphaned rollouts and a catalog dominated by stop-gate noise.
Fix
Route the stop-gate one-shot (already recognized via
STOP_REVIEW_TASK_MARKER) through an ephemeral, untracked, read-only path inhandleTask:executeTaskRunnow honorsrequest.persistThread(defaulttrue), so the stop-gate passespersistThread: false→ the thread startsephemeral: true(no rollout) with no persistent thread name.runForegroundCommand/runTrackedJob, so no job record or log file is written. The same JSON payload is still printed to stdout, so the hook contract (and the gate's ALLOW/BLOCK behavior) is unchanged.--backgroundbranch, so a backgrounded marker prompt can't create a tracked job either.write, so the review can never select aworkspace-writesandbox regardless of CLI flags — it is always read-only.Normal
/codex:taskruns are unaffected (persistThreaddefaults totrue).Tests
Updated the stop-hook end-to-end test to assert the new contract: the review still runs and blocks on findings, the review thread is
ephemeral, and no "Codex Stop Gate Review" job is added to the catalog.