Context
During PR #14439 re-review, Clio reported that test/playwright/unit/hooks/codexLaneStateStopHook.spec.mjs can read the real Codex prompt-context store when direct classification tests call classifyCodexStopPayload(fixture) without an explicit hook-store override. That makes two fixture tests depend on whether another live Codex session recently wrote codex-prompt-context.json.
This is a narrow leaf under #14420's Codex stop-hook prompt-visibility surface. It does not implement #14420 Defect B, Defect C, or the #14438 re-fire admission mechanism.
The Problem
.codex/hooks/codex-lane-state-stop.mjs computes its default prompt-context store from the module-level LOG_DIR. Direct unit tests import the module in-process, so calls that do not pass messages, last_user_message, or transcript_path can fall through to readPromptContext() and consume the real store.
That is correct for the live hook path, but wrong for pure fixture classification tests. A live prompt-context file can make a fixture that should produce promptSource=none classify as promptSource=prompt_context, changing a would-block result into an operator-dialogue allow.
The Architectural Reality
- Live hook behavior must continue to use the module-level default store.
- Spawned hook tests already isolate correctly by setting
NEO_AI_DAEMON_DIR.
- Pure classification tests need a test-owned
logDir seam so they can exercise the same prompt-context fallback deliberately without reading the user's real store.
- The owning files are
.codex/hooks/codex-lane-state-stop.mjs and test/playwright/unit/hooks/codexLaneStateStopHook.spec.mjs.
The Fix
Add an optional logDir option to the pure classification path:
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
extractPromptingText(input, {logDir}) |
Existing Codex prompt-context fallback and #14420 prompt-visibility isolation |
Use logDir when resolving codex-prompt-context.json for in-process classification |
Omitted logDir preserves live default store behavior |
JSDoc option entry |
Focused Codex hook spec |
classifyCodexStopPayload(input, {logDir}) |
Same |
Forward logDir into prompting-text extraction |
Omitted logDir preserves current behavior |
JSDoc option entry |
Pollution regression test |
codexLaneStateStopHook.spec.mjs direct fixture tests |
Unit-test isolation contract |
Direct no-prompt classification tests run against an empty temp store |
Spawned hook tests keep using NEO_AI_DAEMON_DIR |
Test helper name |
Focused and hook-directory unit runs |
Acceptance Criteria
Out of Scope
- #14420 Defect B operator-prompt visibility semantics.
- #14420 Defect C sunset terminal reconciliation.
- #14438 declining-yield re-fire admission.
- Any production policy change to no-hold / stop-hook admission.
Avoided Traps
- Do not remove the prompt-context fallback; live Codex
UserPromptSubmit to Stop continuity needs it.
- Do not make tests depend on deleting or mutating the user's real store.
- Do not close #14420 from this leaf; this fixes one test isolation defect only.
Related
#14420
#14439
Live latest-open sweep: checked latest 20 open issues at 2026-07-02T07:38:59Z; no equivalent found. Closest related ticket is #14440, but it is broader, not-code-ready, and about continuation-chain operator visibility rather than unit-test store isolation.
A2A in-flight sweep: checked latest 30 all-state mailbox messages at 2026-07-02T07:39Z; only overlapping claim was @neo-gpt's own [lane-claim] #14420 Codex stop-hook spec live-store isolation.
Origin Session ID: 8facbc96-c346-4633-9141-79a968ca1c5d
Retrieval Hint: "codexLaneStateStopHook NEO_AI_DAEMON_DIR promptSource live store isolation"
Context
During PR #14439 re-review, Clio reported that
test/playwright/unit/hooks/codexLaneStateStopHook.spec.mjscan read the real Codex prompt-context store when direct classification tests callclassifyCodexStopPayload(fixture)without an explicit hook-store override. That makes two fixture tests depend on whether another live Codex session recently wrotecodex-prompt-context.json.This is a narrow leaf under #14420's Codex stop-hook prompt-visibility surface. It does not implement #14420 Defect B, Defect C, or the #14438 re-fire admission mechanism.
The Problem
.codex/hooks/codex-lane-state-stop.mjscomputes its default prompt-context store from the module-levelLOG_DIR. Direct unit tests import the module in-process, so calls that do not passmessages,last_user_message, ortranscript_pathcan fall through toreadPromptContext()and consume the real store.That is correct for the live hook path, but wrong for pure fixture classification tests. A live prompt-context file can make a fixture that should produce
promptSource=noneclassify aspromptSource=prompt_context, changing a would-block result into an operator-dialogue allow.The Architectural Reality
NEO_AI_DAEMON_DIR.logDirseam so they can exercise the same prompt-context fallback deliberately without reading the user's real store..codex/hooks/codex-lane-state-stop.mjsandtest/playwright/unit/hooks/codexLaneStateStopHook.spec.mjs.The Fix
Add an optional
logDiroption to the pure classification path:extractPromptingText(input, {logDir})logDirwhen resolvingcodex-prompt-context.jsonfor in-process classificationlogDirpreserves live default store behaviorclassifyCodexStopPayload(input, {logDir})logDirinto prompting-text extractionlogDirpreserves current behaviorcodexLaneStateStopHook.spec.mjsdirect fixture testsNEO_AI_DAEMON_DIRAcceptance Criteria
promptSource=noneuses an explicit isolated prompt-context directory.Out of Scope
Avoided Traps
UserPromptSubmittoStopcontinuity needs it.Related
#14420 #14439
Live latest-open sweep: checked latest 20 open issues at 2026-07-02T07:38:59Z; no equivalent found. Closest related ticket is #14440, but it is broader, not-code-ready, and about continuation-chain operator visibility rather than unit-test store isolation.
A2A in-flight sweep: checked latest 30 all-state mailbox messages at 2026-07-02T07:39Z; only overlapping claim was @neo-gpt's own
[lane-claim] #14420 Codex stop-hook spec live-store isolation.Origin Session ID: 8facbc96-c346-4633-9141-79a968ca1c5d Retrieval Hint: "codexLaneStateStopHook NEO_AI_DAEMON_DIR promptSource live store isolation"