Severity: High · Confidence: High (adversarially verified) · Plugin: a2a_fleet
Summary
When a stored OpenCode session_id is dead, oc_receiver retries with _invoke(None) but never clears the stale entry from the session map. If the remint itself fails (timeout / CLI error / no parseable sessionID), the stale id stays on disk and every subsequent turn re-hits session-not-found and burns a full timeout before reminting — an infinite dead-session loop.
This is the exact failure mode PR #79 fixed for codex_receiver via clear_thread_id_for_context. oc_receiver lacks both the clear call and an equivalent clear_session_id_for_context function — a genuine parity gap.
Evidence
templates/oc_receiver.py:419-431 — remint branch calls _invoke(None) with no clear of the stale session_id.
_invoke only persists a new id when parsed_session_id is truthy (oc_receiver.py:405-406). So on successful remint it self-heals after one bad turn; on failed remint the stale id is never removed → infinite loop.
- Contrast
templates/codex_receiver.py:539-544 — calls clear_thread_id_for_context(context_id, session_map_path) before _invoke(None), guaranteeing the bad id is gone regardless of remint outcome.
- Minor adjacent gap:
oc_receiver.py:399 calls get_session_id_for_context(context_id) without threading session_map_path (codex captures it locally) — testability/override inconsistency.
Fix
Add clear_session_id_for_context(context_id, session_map_path) to oc_receiver.py (parallel to codex) and call it before _invoke(None) in the remint path. Thread session_map_path through the session-map calls like codex does.
Found via codegraph audit of custom plugins; adversarially re-verified before filing.
Severity: High · Confidence: High (adversarially verified) · Plugin: a2a_fleet
Summary
When a stored OpenCode
session_idis dead,oc_receiverretries with_invoke(None)but never clears the stale entry from the session map. If the remint itself fails (timeout / CLI error / no parseable sessionID), the stale id stays on disk and every subsequent turn re-hits session-not-found and burns a full timeout before reminting — an infinite dead-session loop.This is the exact failure mode PR #79 fixed for
codex_receiverviaclear_thread_id_for_context.oc_receiverlacks both the clear call and an equivalentclear_session_id_for_contextfunction — a genuine parity gap.Evidence
templates/oc_receiver.py:419-431— remint branch calls_invoke(None)with no clear of the stalesession_id._invokeonly persists a new id whenparsed_session_idis truthy (oc_receiver.py:405-406). So on successful remint it self-heals after one bad turn; on failed remint the stale id is never removed → infinite loop.templates/codex_receiver.py:539-544— callsclear_thread_id_for_context(context_id, session_map_path)before_invoke(None), guaranteeing the bad id is gone regardless of remint outcome.oc_receiver.py:399callsget_session_id_for_context(context_id)without threadingsession_map_path(codex captures it locally) — testability/override inconsistency.Fix
Add
clear_session_id_for_context(context_id, session_map_path)tooc_receiver.py(parallel to codex) and call it before_invoke(None)in the remint path. Threadsession_map_paththrough the session-map calls like codex does.Found via codegraph audit of custom plugins; adversarially re-verified before filing.