Send initialized notification after initialize handshake (fix codex 0.130 wedge — internal#659 P1#1) #48
Reference in New Issue
Block a user
Delete Branch "fix/send-initialized-notification"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Send the
initializednotification (JSON-RPC, no id) after theinitializehandshake response, before any further request. The codex app-server protocol requires this — without it, codex-cli 0.130 silently wedges every subsequent request.Root cause
Per
codex-rs/app-server/README.mdandcodex-rs/app-server-protocol/schema/json/ClientNotification.json, the only client→server notification defined isinitialized, and it is mandatory after the initialize response and before any further method invocation. Ourapp_server.pywas missing this entirely —grep -E 'initialized|notify' app_server.pyreturned zero matches before this patch.codex-cli 0.72.x (against which
executor.pywas originally verified — see line ~187 comment dated 2026-05-02) was permissive. codex-cli 0.130.0 (current runtime image pin) is strict.Production evidence — 2026-05-24
Both codex agents in agents-team prod (CR2
4e817f43-a0b7-4c44-9fcb-d6b2e7d4dda1and Researcher712b5600-d397-4749-adac-cd6ee574afea) exhibited the wedge:Registered with platform: 200✓POST / HTTP/1.1 200 OKon every inbound delegation ✓cron_run+a2a_receiverecorded inactivity_logs✓agent_logentries produced: 0 for the entire session ✗Pattern survived
docker restart+ full re-provision (POST /workspaces/:id/restart). Both restart modes preserved the symptom because neither sentinitialized.Fix
app_server.py: addnotify(method, params=None)public method that writes a JSON-RPC notification (noid) through the existing_write_messagepath. Updateinitialize()to callawait self.notify("initialized")after the response.tests/mock_app_server.py: record incoming notification methods in a module list; expose them via a test-onlyget_received_notificationsRPC.tests/test_app_server.py: two new tests asserting (1)initializedis sent afterinitialize, (2)notify()produces a no-id JSON-RPC message.12/12 tests pass locally including the two new ones. No changes to executor.py — the fix is fully contained in the JSON-RPC client primitive.
Test plan
pytest tests/test_app_server.py -x -q— 12/12 passagent_logcount > 0 within one cron tickRelated
🤖 Generated with Claude Code
The codex app-server protocol requires clients to send an `initialized` notification (no id, JSON-RPC) after receiving the `initialize` response and BEFORE issuing any further request. The contract is documented in codex-rs/app-server/README.md and codex-rs/app-server-protocol/schema/ json/ClientNotification.json (only client→server notification defined). Without this notification, codex-cli 0.130.0 (current production image) silently wedges every subsequent request — thread/start, turn/start — with no agent_log output. Reproduced live 2026-05-24 against agents-team prod CR2 (4e817f43…) and Researcher (712b5600…): both received POST / 200 OK but produced zero agent_log activity for the entire session. codex-cli 0.72.x was permissive about a missing initialized; 0.130.0 is strict. The executor.py comment dating verification to 2026-05-02 against 0.72.0 was effectively a regression vector when the runtime-image pin advanced past 0.72. Fix is two parts: - app_server.py: add notify() method (JSON-RPC notification, no id), and call notify('initialized') at end of initialize() after the response lands. - mock_app_server.py: record received notifications + expose them via a get_received_notifications test-only RPC. - test_app_server.py: two new tests asserting (1) initialized is sent after initialize, (2) notify() produces a no-id JSON-RPC message. Root cause tracking: internal#659 P1#1. This is the smallest sufficient fix; the broader codex template restart-safety work tracked separately under that issue. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>APPROVE.
Protocol-compliance fix: client now sends the required
initializednotification per codex-rs/app-server protocol contract (ClientNotification.json defines only this notification, README marks it mandatory after initialize response).Root-caused live against agents-team prod CR2 + Researcher (workspaces 4e817f43..., 712b5600...) — both received POST / 200 OK but produced zero agent_log; codex-cli 0.130 strictly rejects post-initialize requests when the notification is missing. 0.72.x (against which executor.py was verified) was permissive.
Review points checked:
069a206hardened it by recording in main()s read loop before _handle dispatch.Resolves internal#659 P1#1.