Codex Desktop memory consolidation background jobs re-fire historical Stop/PermissionRequest hook events, causing spurious notifications (no actual task running)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Environment
- Codex Desktop (Windows Store build
OpenAI.Codex 26.901.6511.0), Windows 11 - Codex CLI
0.153.4(app-server instances) config.tomlhas[features] hooks=true, with[[hooks.Stop]]and[[hooks.PermissionRequest]]pointing to a custom notification script (codex-notify.py) that POSTs to Feishu[features] memories=true,goals=true
Symptom
On 2026-09-08 16:44–16:47 Asia/Shanghai, the notification script received and forwarded a burst of six events for tasks that had actually completed days earlier. The affected session was last active on 2026-09-05, and no corresponding turn was running at the time:
- 3×
PermissionRequestformcp__officecli__officecliviewcommands on files from the 2026-09-05 session - 2×
Stopevents whoselast_assistant_messagecontained content from the 2026-09-05 session - 1×
Stopevent whosecwdbasename wasappand whoselast_assistant_messagewas{"exclude":[]}
Reproduction / observed sequence
The issue was observed when background memory jobs ran while another thread was active:
- A thread from 2026-09-05 had no new user-facing turns and remained inactive.
- On 2026-09-08 around 16:43, memory background jobs
memory_stage1andmemory_consolidate_globalran. - During the same interval, historical content from the 2026-09-05 rollout was replayed, including a spurious continuation that immediately produced
task_complete. - The configured
StopandPermissionRequesthooks fired, and the notification script forwarded six events to Feishu, even though no task was running and no approval was pending for the affected thread.
I do not currently have a minimal deterministic reproduction outside this observed sequence.
Evidence that these were not real task events
thread_history_1.sqlitethread_turns: the affected threads had zero turns started after 2026-09-05. The only real turns running in the 16:00–17:10 window belonged to two other threads: one from 2026-09-08 and one from 2026-09-06 that resumed.state_5.sqlitethreads: the affected thread (id prefix01a0714b...) hadupdated_at_ms/recency_at_msstuck at 2026-09-05; it was never touched that day.queue_1.sqlitequeued_items: there were 0 rows when the threePermissionRequestnotifications fired, so no approval was actually pending.logs_2.sqlite: thecodex_core::hook_runtimetarget's last log entry was 2026-09-07 09:27. There were no hook-runtime logs on 2026-09-08 around 16:44–16:47, yet the notification script demonstrably ran; the Feishu messages include the script'sapp_idand exact template output.- Desktop logs (
AppData/Local/Codex/Logs) had no writes after 14:24 that day.
Timing correlation
The memories_1.sqlite jobs table shows memory_stage1 and memory_consolidate_global background jobs running from 16:43:03 to 16:49:27, with worker_id corresponding to the active 2026-09-08 thread. This exactly brackets the spurious notification window (16:44:30–16:47:30).
The 16:43 thread also shows a spurious continuation rollout that replayed an old user message and produced an immediate task_complete.
Hypothesis
Codex Desktop's background memory consolidation (memory_stage1 / memory_consolidate_global) may read or replay historical rollouts to summarize them. During that replay, it may re-dispatch hook events (Stop, PermissionRequest) recorded in old rollouts as if they were new events, causing configured hooks to fire for long-finished tasks. The spurious PermissionRequest events also never appear in the approval queue.
Expected behavior
Background memory jobs should not re-trigger Stop or PermissionRequest hook events for historical turns. Only live user-facing turns should fire these hooks.
Additional notes
The issue appears to be specific to the interaction between Desktop memory consolidation and configured hooks. The evidence above is from local SQLite databases, logs, and the notification payloads observed during the 2026-09-08 window.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the memory_stage1 and memory_consolidate_global jobs and how they process historical rollouts relative to live user-facing turns. Compare their behavior with the codex_core::hook_runtime logs, hook events, and approval queue evidence in the named SQLite databases. Done means historical memory work no longer fires Stop or PermissionRequest hooks or creates spurious task activity.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- ai, backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100