Environment
- agmsg:
v1.1.13
- Host: Codex
- Delivery mode:
monitor
- OS: Linux
- Codex bridge: app-server based
Symptom
The Codex bridge does not trigger an inbox notification even when unread messages exist.
The bridge log repeatedly contains errors like these:
codex-bridge: watch-once failed with exit 1: agmsg watch: skipping pairs held by other sessions: <team>/<agent>(<owner-id>)
watch-once: no available subscription for project=<project> type=codex name=* team=*
codex-bridge: stopping after 3 consecutive watch-once failure(s)
Investigation
armWatch() in the Codex bridge starts watch-once.sh with the following information:
<project> codex --timeout <seconds> --interval <seconds> --pair <team><TAB><agent>
The command does not include the owner ID used to identify the actas lock owner.
At the same time, watch-once.sh calls agmsg_subscription_pairs() as follows:
agmsg_subscription_pairs "$PROJECT_PATH" "$AGENT_TYPE" "" "$ACTIVE_NAME"
The third argument is the owner ID, but it is always an empty string.
agmsg_subscription_pairs() uses this value to check actas locks.
When the value does not match the lock owner, the identity is excluded as other:<owner>.
Therefore, when a lock exists for the bridge's own identity, notification delivery stops through this sequence:
Start watch-once without an owner ID
↓
The value does not match the existing lock owner
↓
Exclude the identity from the subscription set
↓
No available subscription
↓
watch-once exits with status 1
↓
The bridge stops after three consecutive failures
Difference between 1.1.12 and 1.1.13
armWatch() in v1.1.12 and v1.1.13 both omit the owner ID when starting watch-once.sh.
Therefore, the missing owner ID cannot be attributed solely to the 1.1.13 release commit.
However, 1.1.13 also includes changes related to seating roles from app-server loaded threads, recording the armed thread in the role session, and resolving the app-server endpoint.
When the bridge reconnects after these changes while old actas locks or role-session records remain, the missing owner ID can surface as a notification failure.
Proposed fix
The following changes appear to be needed:
- Add
--owner-id <instance_id> to watch-once.sh.
- Pass that value as the third argument to
agmsg_subscription_pairs().
- Resolve the instance ID associated with the Codex bridge and include it in the
armWatch() spawn command.
- If the owner ID cannot be resolved, fail closed and log the reason instead of treating an existing lock as owned by the bridge.
- Add self-tests for the three cases: owner ID missing, owner ID matching, and owner ID not matching.
The Codex thread ID and the actas lock owner ID are different identifiers.
Passing the thread ID as a substitute is not sufficient to perform the lock ownership check correctly.
Additional information
No direct edits were made to the database or team data during this investigation.
When delivery succeeds, the bridge log records wakeup and started turn, and the unread message is passed to the current Codex thread.
Environment
v1.1.13monitorSymptom
The Codex bridge does not trigger an inbox notification even when unread messages exist.
The bridge log repeatedly contains errors like these:
Investigation
armWatch()in the Codex bridge startswatch-once.shwith the following information:The command does not include the owner ID used to identify the actas lock owner.
At the same time,
watch-once.shcallsagmsg_subscription_pairs()as follows:The third argument is the owner ID, but it is always an empty string.
agmsg_subscription_pairs()uses this value to check actas locks.When the value does not match the lock owner, the identity is excluded as
other:<owner>.Therefore, when a lock exists for the bridge's own identity, notification delivery stops through this sequence:
Difference between 1.1.12 and 1.1.13
armWatch()inv1.1.12andv1.1.13both omit the owner ID when startingwatch-once.sh.Therefore, the missing owner ID cannot be attributed solely to the 1.1.13 release commit.
However, 1.1.13 also includes changes related to seating roles from app-server loaded threads, recording the armed thread in the role session, and resolving the app-server endpoint.
When the bridge reconnects after these changes while old actas locks or role-session records remain, the missing owner ID can surface as a notification failure.
Proposed fix
The following changes appear to be needed:
--owner-id <instance_id>towatch-once.sh.agmsg_subscription_pairs().armWatch()spawn command.The Codex thread ID and the actas lock owner ID are different identifiers.
Passing the thread ID as a substitute is not sufficient to perform the lock ownership check correctly.
Additional information
No direct edits were made to the database or team data during this investigation.
When delivery succeeds, the bridge log records
wakeupandstarted turn, and the unread message is passed to the current Codex thread.