A resumed round runs with the agent it was started with

What was seen

On the control instance on 2026-10-02 (17:09–19:21Z) and 2026-10-03 (09:44–10:17Z), review, triage and bug threads under Hosting/Triage/_Thread/… ended rounds with this message:

Selected agent 'pr-reviewer' was not found among the available agents ([Agent/Assistant, Agent/Researcher,
Agent/TrainingSim, Agent/Tutor, Agent/Worker, Agent/ExecutiveAssistant, Agent/LogTriage, Agent/NotificationTriage,
Agent/EmailRouter, Agent/PullRequestWriter, Agent/DescriptionWriter, Agent/NodeInitializer, Agent/ThreadNamer]).

The same message appeared for triage and bug-triage, each written as a Completed response cell.

Why

A resume carries no selection. Both resume entries, DispatchAfterClaim and the interrupted-round recovery in ThreadSubmission, build a RoundDispatch with AgentName, ModelName, Harness and ContextPath all null. ThreadExecution.ExecuteMessageAsync then recovered the agent, model and harness from the response cell, but it lost two things.

Lost Because Registry row that went with it
The agent's install path (Essentials/Agent/bug-triage) The cell stamps the SHORT name (bug-triage) AgentPickerProjection.PinnedAgentQuery. This is the only row that reaches an agent outside the context's own layers, which is how a Hosting/Triage thread reaches Essentials/Agent (Plugins#2566)
The context (Hosting/Triage/pull-request/…) It was never recovered The space layer {space}/Agent. This is how Hosting/Agent/pr-reviewer and Hosting/Agent/triage are found

What remained was the platform namespace Agent, which is exactly the roster the message printed. Waiting longer cannot help, because no later catalog emission adds a row that the query never asked for.

What a resume recovers now

ThreadExecution.RecoverResumeSelection reads the response cell and the thread node:

A value the request already carries always wins. The cell and the thread node are read together, each bounded by 5 s. The thread read is an own-node read: the hub running the resume is the thread hub, already active. If it fails anyway, the resume falls back to the cell alone, is never blocked, and logs a warning (Resume: could not read thread node …). That way a roll on which resumed rounds degrade shows up in Loki before the rounds end. ResumeSelectionRecoveryTest (MeshWeaver.AI.Test) pins each branch.

Not established