Under load, a task's log names its subagents by thread id instead of by nickname — every line, for the whole turn:
[…] Starting subagent thr_2 via collaboration tool: wait.
[…] Subagent thr_2 reasoning: Questioned the retry strategy and the cache invalidation boundaries.
[…] Subagent thr_2: The design assumes retries are harmless, but they can duplicate side effects…
[…] Subagent thr_2 completed.
instead of design-challenger. The test task logs subagent reasoning and messages with a subagent prefix (tests/runtime.test.mjs:1486) catches it.
Why this is filed as a defect, not as a flaky test
The obvious "fix" — letting the test accept either form — would hide it. labelForThread() falling back to the id is a deliberate fallback for a name that has not arrived yet; here the name never arrives at all before the turn ends, so a real user on a loaded machine reads thread ids in their task log where the nickname belongs. The test is reporting something true.
Whether that is worth fixing is the open question. It is cosmetic — no job, turn or record is affected — but it degrades exactly when the log matters most.
Reproduction
The single test, under CPU contention (32 spinners on a 4-core box, load average ~36):
node --test --test-name-pattern "logs subagent reasoning" tests/runtime.test.mjs
Idle it passes every time. So it is pre-existing and independent of the broker and de-flake work in #10.
Where to look
describeStartedItem() in plugins/codex/scripts/lib/codex.mjs:342 builds the line from labelForThread(state, threadId) ?? threadId. The label is recorded when the child thread's thread/started notification arrives (plugins/codex/scripts/lib/codex.mjs:330), carrying name/agentNickname.
The likely cause is ordering between two delivery paths: the parent's collabAgentToolCall item and the child thread's thread/started reach the client separately — through the broker, a child thread's notifications depend on its subscription — so under contention the name can land after the turn has finished. If that is confirmed, the fix is about ordering, or about resolving the label lazily once it arrives, not about the log line itself.
Not urgent
Nothing is lost but readability, and the fallback keeps the log correct, just less legible. Filed so the failing test has a home and is not mistaken for noise.
Under load, a task's log names its subagents by thread id instead of by nickname — every line, for the whole turn:
instead of
design-challenger. The testtask logs subagent reasoning and messages with a subagent prefix(tests/runtime.test.mjs:1486) catches it.Why this is filed as a defect, not as a flaky test
The obvious "fix" — letting the test accept either form — would hide it.
labelForThread()falling back to the id is a deliberate fallback for a name that has not arrived yet; here the name never arrives at all before the turn ends, so a real user on a loaded machine reads thread ids in their task log where the nickname belongs. The test is reporting something true.Whether that is worth fixing is the open question. It is cosmetic — no job, turn or record is affected — but it degrades exactly when the log matters most.
Reproduction
The single test, under CPU contention (32 spinners on a 4-core box, load average ~36):
main(checked at commit 7f9aded, in a clean worktree)Idle it passes every time. So it is pre-existing and independent of the broker and de-flake work in #10.
Where to look
describeStartedItem()inplugins/codex/scripts/lib/codex.mjs:342builds the line fromlabelForThread(state, threadId) ?? threadId. The label is recorded when the child thread'sthread/startednotification arrives (plugins/codex/scripts/lib/codex.mjs:330), carryingname/agentNickname.The likely cause is ordering between two delivery paths: the parent's
collabAgentToolCallitem and the child thread'sthread/startedreach the client separately — through the broker, a child thread's notifications depend on its subscription — so under contention the name can land after the turn has finished. If that is confirmed, the fix is about ordering, or about resolving the label lazily once it arrives, not about the log line itself.Not urgent
Nothing is lost but readability, and the fallback keeps the log correct, just less legible. Filed so the failing test has a home and is not mistaken for noise.