fix(activity): stabilize codex and opencode states#6
fix(activity): stabilize codex and opencode states#6integrate-your-mind wants to merge 42 commits into
Conversation
Ensure codex in-flight ends within 2.5s of completion, pick active JSONL per process, and make opencode message completion authoritative. Remove wheel passive listener warnings and align docs/tests.
Start the server on the next available port during dev and ignore stale OpenCode status events when determining in-flight state.
1 similar comment
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee9f28dc13
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Tail Codex JSONL incrementally when log growth exceeds MAX_READ_BYTES and surface catch-up via TailState.needsCatchUp. - Apply shouldParseJsonLine() before JSON.parse to skip noisy delta lines while still recording ingest time. - Add integration coverage for needsCatchUp behavior.
|
Review comment fixes pushed (4 commits):\n\n- fix(codex): ignore token_count for pending-end markers (65b2b43)\n- fix(setup): merge required codex notifications (c98983c)\n- fix(ui): avoid spatial cell-key wrapping (2d1c9bd)\n- test(ui): filter live TUI demo lane by match query (c5d17d9)\n\nBuild gate:\n- npm run build: ✓ built in 360ms\n\nTest gate:\n- npm run test:unit: # pass 171 # fail 0\n- npm run test:integration: # pass 71 # fail 0\n\nUI gate:\n- npm run test:ui: 19 passed (6.2s), 2 skipped (env-gated demos)\n\nEvidence gate (flicker):\n- tmp/flicker-summary.json (intervalMs=250 durationMs=120000 windowMs=10000 totalFlickerCount=0)\n- tmp/flicker-summary.transitions.jsonl\n\nDemo video gate (live TUI):\n- Playwright raw: test-results/ui-codexTuiLiveDemo.pw.ts--c9c35--active---idle-30s-capture-/video.webm\n- Trimmed 30s mp4: tmp/codexTuiLiveDemo-30s.mp4 |
|
CI fix: npm test now works in bash (GitHub Actions) without relying on ** globstar.\n\n- Commit: cf91d42 fix(test): make npm test portable across shells\n- Added scripts/run-node-tests.js and updated package.json test scripts.\n\nLocal verification (summary lines):\n- npm run build: ✓ built in 331ms\n- npm test: unit # pass 171 # fail 0; integration # pass 71 # fail 0\n\nGitHub Actions:\n- build check now passing (run 21740671370). |
|
Follow-up fix for latest Devin inline review comment (
Build gate:
Test gate:
|
| const expireInFlight = () => { | ||
| if (!state.inFlight) return; | ||
| if (!Number.isFinite(inflightTimeoutMs) || inflightTimeoutMs <= 0) return; | ||
| if (process.env.CODEX_TEST_HOOKS === "1") { | ||
| "TEST_HOOK_EXPIRE_CHECK"; | ||
| } | ||
| if (!state.inFlight && !state.pendingEndAt) return; | ||
| if (!Number.isFinite(inflightTimeoutMs) || inflightTimeoutMs <= 0) return; |
There was a problem hiding this comment.
🔴 Codex tail expiration can get stuck when turnOpen/openCallIds are set but state.inFlight is false
Codex tail state can become permanently inFlight (via summarizeTail) because expireInFlight() returns early unless state.inFlight or pendingEndAt is set.
Root Cause & Impact
expireInFlight() starts with:
if (!state.inFlight && !state.pendingEndAt) return;(/home/ubuntu/repos/repo-ab792c74ddf9424a89ed9851e3e65943/src/codexLogs.ts:852-857)
But summarizeTail() treats a session as in-flight if any of these are true: turnOpen, openCallCount > 0, reviewMode, or pendingEndAt (/home/ubuntu/repos/repo-ab792c74ddf9424a89ed9851e3e65943/src/codexLogs.ts:1506-1511).
There are code paths that set turnOpen and/or openCallIds/openItemCount even when canSignal is false (so state.inFlight may remain false):
- Turn/thread start sets
state.turnOpen = trueunconditionally, and only setsstate.inFlight = trueinside theif (canSignal)block (/home/ubuntu/repos/repo-ab792c74ddf9424a89ed9851e3e65943/src/codexLogs.ts:1115-1123). - Tool-call start adds to
openCallIds/ incrementsopenItemCountunconditionally, and only setsstate.inFlight = trueinside theif (canSignal)block (/home/ubuntu/repos/repo-ab792c74ddf9424a89ed9851e3e65943/src/codexLogs.ts:1237-1256).
If canSignal is false (e.g., timestamp considered stale by CONSENSUS_CODEX_SIGNAL_MAX_AGE_MS, or file is stale and keepStale is false), the state can end up with turnOpen=true or openCallCount>0 while state.inFlight=false and pendingEndAt unset. In that case:
summarizeTail()reportsinFlight=true(becauseturnOpen/openCallCountcontributes).expireInFlight()never runs and never clearsturnOpen/open-call tracking.
Actual: agent can stay incorrectly active indefinitely.
Expected: stale/unsignalable events should not create sticky turnOpen/open-call state, or expiration should still run when these markers are set.
Prompt for agents
In src/codexLogs.ts, make expireInFlight() consider all fields that contribute to summarizeTail().inFlight, not just state.inFlight/pendingEndAt.
Concretely:
1) In updateTailLegacy(), change the early return in expireInFlight() (currently: if (!state.inFlight && !state.pendingEndAt) return;) so it also runs when state.turnOpen is true, state.reviewMode is true, or openCallCount > 0.
2) Alternatively (or additionally), prevent turnOpen/open-call tracking from being set when canSignal is false (stale/unsignalable events). For example:
- In the isTurnStart/isResponseStart branches and tool-call start branches, gate state.turnOpen mutation and openCallIds/openItemCount mutations behind canSignal.
3) Add/adjust a unit/integration test demonstrating the stuck-active case: write a stale-timestamp turn.started or tool-call event that sets turnOpen/openCallCount while canSignal=false, then verify a later updateTail call can clear/expire the in-flight summary.
Was this helpful? React with 👍 or 👎 to provide feedback.
Backlog triage statusThis remains the canonical activity-stability branch and should merge before #26 and before rebasing #29, but it is not merge-ready yet. Cleared during triage
Live blocker
Required fix:
The current head has no attached combined status checks, and there is no approving review. Returning this PR to draft until the blocker is fixed and the focused test passes. |
Summary
Testing