Prompt–Tool Surface Coherence
An agent should not be instructed to use tools that its current request cannot actually call, and a connected or newly activated tool provider should not silently disappear from the effective registry. Prompt–tool surface coherence treats declarations, guidance, registry reconciliation, authorization, deferred discovery and observability as related but distinct control-plane surfaces.
Page reviewed 4 Oct 2026 Source and review policy
Short answer
Section titled “Short answer”Prompt–tool surface coherence means that the model-facing instructions for a turn or session accurately describe the tools the model is actually allowed to call at that boundary. It is a harness correctness property, not merely a token optimization.
A modern agent host often has several independently evolving surfaces:
- a registry of tools the product knows about;
- the subset actually declared to the model for this request;
- system-prompt guidance and examples that name tools;
- permission or policy rules that may deny tools even if the host knows them;
- deferred tools that can be discovered or revealed later; and
- observability such as a context inspector that tells operators what the model received.
Dynamic plugin and MCP activation adds another requirement: a partial update must not be mistaken for the complete desired tool configuration, and concurrent discovery/activation must not expose an empty or half-rebuilt registry as durable session state.
If those surfaces drift, the harness can tell the model to prefer a tool that is not callable, hide guidance for a tool that is callable, or show operators a context view that does not match the actual request. Safety guidance creates a separate constraint: dangerous-action, permission and denial rules must not disappear merely because a tool is absent from the current declaration set.
Qwen Code PR #12145, merged on 18 September 2026 as 377a5753a73fb04977c629c835a9f8bbff42848b, is useful implementation evidence for prompt/declaration coherence. It changes Qwen’s base system prompt so selected tool-specific guidance and examples are assembled from the session’s declared tool set instead of only static tool-name constants and feature flags. That merge is an ancestor of stable Qwen Code v0.24.4, published 22 September 2026.
Hermes PRs #119900 and #119960, merged on 23 September 2026 as dbe2f6964d44d4d881144197fdf0aa2fd2aed0c1 and c07501ec411b5364e5b12b7258c25a6a4c758545, provide complementary current-main evidence for dynamic registry coherence. They fix two different ways an installed/connected plugin could report success while its MCP tools were missing from chats: subset reconciliation that removed another server’s tools, and concurrent forced rediscovery that let one go-live read an empty plugin manager. GitHub ancestry confirms both merges are included in stable v2026.9.24 / Hermes Agent v0.21.5 at tag commit f97608f1; they are Hermes implementation changes, not UHP, MCP, ACP or A2A wire changes.
Find the missing tool at the first inconsistent surface
Section titled “Find the missing tool at the first inconsistent surface”When Settings shows a connected provider but the model cannot call it, record three inventories for the same profile and request: transport connection, product registry and declared/revealed model tools. The Hermes subset-reconciliation fix demonstrates that the first can remain healthy while the second loses tools.
| First mismatch | Investigation |
|---|---|
| Connected but absent from registry | Delta-versus-authoritative reconciliation and activation locks |
| In registry but absent from request | Session refresh, deferred reveal or request snapshot |
| Declared but prompt says unavailable | Guidance assembled from another tool generation |
| Declared and described but invocation refused | Authorization, alias resolution or execution policy |
Capture the registry generation, provider/tool IDs, request ID and effective prompt/declaration digest. Avoid “fixing” a correct permission refusal by changing prompt wording or reconnecting repeatedly. Activating server B must not remove server A merely because A was omitted from a delta input.
The session-refresh race PR #119862 remains open and unmerged on 4 October 2026. The merged registry fixes are therefore not evidence that every existing chat refreshes atomically. A useful synthetic probe runs concurrent activation while a session snapshots its tools and checks for empty or partial inventories; it remains a proposed test here. See instruction provenance for retaining the snapshot actually supplied to the request.
The coherence boundary
Section titled “The coherence boundary”A useful decomposition is:
| Surface | Question it answers | Why it must remain distinct |
|---|---|---|
| Product tool registry | What tools can this harness implementation potentially provide? | Availability in the product does not mean the model received the tool this turn. |
| Declared tool set | What callable schemas were actually sent to the model? | This is the model’s immediate executable surface. |
| Prompt/tool guidance | What does the model believe it should call, prefer or avoid? | Stale prose can contradict the declared schemas. |
| Authorization policy | What calls may execute if proposed? | Permission is not equivalent to prompt visibility or tool declaration. |
| Deferred/reveal state | What may become callable later? | A session-start prompt can become stale after dynamic discovery. |
| Context/diagnostics view | What does an operator think the model saw? | Diagnostics must report the same snapshot used by the request, not a later registry state. |
The core invariant is simple:
Model-facing guidance about callable tools should be derived from, or checked against, the same effective tool surface that the model request uses.
That does not require every policy sentence to be conditional. In fact, some safety and authorization text should remain unconditional precisely because it constrains behavior beyond the currently declared tool list.
Dynamic activation: delta input is not authoritative inventory
Section titled “Dynamic activation: delta input is not authoritative inventory”Hermes PR #119900 exposes a different coherence failure at the registry layer. register_mcp_servers(servers) can be called with only the server being activated. The old reconciliation path treated that subset as if it were the profile’s complete MCP configuration. If server A was already connected and a later plugin activated server B, A was absent from {B}, so A’s tools were deregistered even though A’s connection stayed open and Settings still reported it as connected.
The merged fix separates delta input from authoritative inventory. A server explicitly present in the activation input is judged from that input. A connected server omitted from the subset is instead checked against the profile’s real MCP configuration and loses its tools only when it is actually absent, disabled, disconnected or routed differently.
That produces a reusable rule for dynamic harness registries:
A partial activation request must never be interpreted as proof that every omitted provider was deleted.
The rule applies beyond MCP. Plugin systems, connector managers, capability registries and hot-reload paths all need an explicit distinction between “these entries changed” and “this is the complete desired state.”
Connection state and callable-tool state are different
Section titled “Connection state and callable-tool state are different”PR #119900 also demonstrates why connection status alone is not a sufficient health signal. In the reproduced failure, NVIDIA App’s MCP connection remained open and the Plugins UI still said it was connected, but all 12 of its tools were missing from the profile tool registry after NVIDIA Broadcast went live. The chat therefore could not call the provider even though the transport-level status looked healthy.
For a dynamic tool provider, useful health evidence needs at least three independently observable layers:
- transport/provider state — is the server or connector connected?
- registry state — are its tool definitions present in the intended profile/runtime registry?
- request/session state — can the current chat/session actually discover or declare those tools?
A green transport indicator cannot substitute for the other two.
Concurrent activation needs an atomic visibility boundary
Section titled “Concurrent activation needs an atomic visibility boundary”Hermes PR #119960 covers a separate race. Plugin go-live performs forced rediscovery, reads the plugin’s MCP/skill declarations, connects servers and refreshes open chats. Forced rediscovery temporarily unloads the plugin manager before reloading it. Two installs can finish together, so one go-live could empty the manager while the other was reading it; the first operation then reported success with zero tools and zero skills until restart.
The merged implementation serializes each go-live with a process-wide _GO_LIVE_LOCK, protects discovery and the associated configuration reads with the plugin manager’s _discovery_lock, and carries the server configuration read under that lock into the later MCP connect step. The network connect deliberately stays outside the discovery lock so a slow server cannot block unrelated discovery readers for its timeout window.
That lock placement illustrates a broader lifecycle rule: serialize the state transition that defines what becomes visible, but do not hold a shared metadata/discovery lock across unbounded or network-bound work unless the design requires it. The activation transaction needs a consistent discovery snapshot; it does not need to freeze every reader while a remote endpoint connects.
Upstream’s live Windows harness reproduced the pre-fix concurrent failure in 13/13 simultaneous runs and 6/6 runs with the second install delayed by 100 ms. With PR #119960, the same harness reported 0/8 and 0/3 failures respectively, with both plugins ending with all expected tools and one skill each. The PR explicitly says a full cold Desktop onboarding run on that commit had not yet been observed, so those focused results should not be promoted into broader product certification.
One registry-to-session race remains open
Section titled “One registry-to-session race remains open”The merged changes do not make the entire activation pipeline atomic. Hermes PR #119862 remains open at this verification cutoff. It documents a separate registry-to-session snapshot race: reload.mcp can temporarily tear down the process-global MCP registry while plugin activation refreshes live session tool snapshots. A session snapshot taken in that window can persist with no MCP tools until a later reload.
That open issue is important evidence about boundary placement. Fixing connection-to-registry reconciliation and serializing concurrent plugin go-live do not automatically protect the later registry-to-session handoff. A complete dynamic tool lifecycle therefore needs consistency at every transition:
configured provider ↓connected provider ↓profile/runtime registry ↓session/request snapshot ↓model declaration + prompt guidanceEach arrow is a potential stale-snapshot, lost-update or partial-state boundary.
The Qwen failure mode
Section titled “The Qwen failure mode”Before PR #12145, Qwen’s base prompt described the tool surface from static ToolNames constants and configuration flags, while the request declarations came from ToolRegistry.getFunctionDeclarations().
Those two sources can diverge when a deployment:
- limits the eager tool set with
tools.eager; - denies an entire tool through permissions policy; or
- keeps a tool deferred behind ToolSearch.
The result is a correctness defect rather than just verbose prompting. The prompt can say, for example, “use this dedicated tool instead of a shell equivalent,” while the tool schema is absent from the request. The model then discovers the contradiction only after a failed call or an additional discovery round trip.
This failure pattern generalizes beyond Qwen. Any harness that independently generates prompt instructions and tool declarations can drift when plugins, permissions, feature flags, model modes, provider limits, MCP configuration or dynamic tool loading change one surface without updating the other.
Qwen’s session-start snapshot design
Section titled “Qwen’s session-start snapshot design”PR #12145 takes a deliberately bounded approach rather than rebuilding the prompt on every tool mutation.
At startChat, after the tool registry is warm and budget preloading has settled, Qwen snapshots the declared tool names onto Config. The main-session prompt builder receives that resolved set through an optional options object. Callers without a session snapshot retain the prior output, and an all-declared snapshot is required to render byte-identically to the old/default path.
The snapshot is important for diagnostics. Qwen’s /context path reads the same prompt-tool snapshot rather than recomputing from the live registry. If ToolSearch reveals another tool later, the live registry and the original system prompt may legitimately differ; /context should report what the prompt actually contains rather than silently rewriting history from newer registry state.
That gives Qwen a session-start coherence guarantee, not a claim of perfect dynamic coherence for every later reveal.
What gets gated — and what deliberately does not
Section titled “What gets gated — and what deliberately does not”The merged change narrows conditional rendering to two tool-bound prompt areas:
- lines in
## Using Your Tools; and - tool-call example blocks.
A line or example survives only when every tool it names is declared. This avoids partially retaining an instruction that still references an unavailable tool.
Several classes remain unconditional by design:
- security and dangerous-action guidance;
- permission/denial guidance;
- Core Mandates and general communication behavior;
- CodeModeOnly guidance, whose tools are reached through
tools.<name>insideexecrather than ordinary declared functions; and - documented residues such as some bare
read_fileprose plus the specialask_user_questionpolicy case.
This separation matters. Tool visibility and execution authorization are different controls. Removing a schema from a request does not make safety policy unnecessary, and leaving safety text visible does not make a denied tool callable.
Correctness first, tokens second
Section titled “Correctness first, tokens second”The PR explicitly corrects an earlier overstatement of the token savings. Its final measurements show:
| Declared set | Prompt reduction | Approx. tokens | Example blocks kept |
|---|---|---|---|
| Seven common file tools | 1,104 characters | ~276 | 7/7 |
read_file + run_shell_command | 4,327–5,069 characters | ~1,082–1,267 | 4/7 |
read_file only | 5,753–6,538 characters | ~1,438–1,634 | 3/7 |
| Default/all declared | 0 | 0 | unchanged |
The default session therefore gains no token saving from this change. The architectural value is that trimmed deployments stop receiving instructions for tools they do not have. Token reduction is a secondary benefit that appears only when the declared surface was already narrowed.
That distinction is useful when evaluating prompt optimization claims: first ask whether the change makes the effective control surface more truthful; only then count prompt bytes or tokens.
Dynamic reveals and prompt-cache trade-offs
Section titled “Dynamic reveals and prompt-cache trade-offs”Qwen intentionally does not regenerate the base system prompt after every mid-session ToolSearch reveal in this first step.
The reason is architectural: the system prefix participates in prompt caching. Rebuilding it whenever a deferred tool becomes resident would mutate the cached prefix repeatedly and couple prompt assembly to every registry mutation path. PR #12145 therefore freezes the prompt against the session-start declared snapshot and names per-reveal regeneration as follow-up work.
This leaves a documented boundary:
session start registry warm/preload ↓ declared-tool snapshot ─────► system prompt │ │ └──────────────────────────► /context view
later ToolSearch reveal ↓ live declared tools change ↓ original system prompt stays fixed in step 1That is not the same as saying the prompt remains fully coherent with every later tool mutation. It is a controlled trade-off: session-start truth and cache stability are guaranteed; dynamic reveal coherence remains a separate problem.
Validation should test both directions
Section titled “Validation should test both directions”A safe gate must detect both under-gating and over-gating.
Qwen’s PR reports automated checks that:
- bracket the expected reduction for representative narrow tool sets;
- strip the gated sections and require everything else to remain identical;
- withhold each of 66 tool names across four example formats and assert that undeclared names do not survive in the gated text, with the documented
ask_user_questionexception; - assert the inverse property that guidance for declared tools is retained;
- keep CodeModeOnly output identical with and without a snapshot;
- require the main prompt path to read the
Configsnapshot used by/context; and - preserve the existing 17 full-prompt snapshots, plus byte identity for an all-declared snapshot.
The PR is also explicit about what that evidence does not prove: no live session was run by the author for the submitted evidence, no provider-side before/after request measurement was demonstrated, and there is no model-behavior eval showing that tool recall improved. The repository verification brief leaves those checks for follow-up.
This is the right evidence boundary to preserve on a reference site: static/CI invariants can prove prompt assembly properties, but they do not automatically prove better model behavior or lower end-to-end cost.
Relation to permissions and execution finality
Section titled “Relation to permissions and execution finality”Prompt–tool coherence should not be confused with the execution contract documented in Tool-call execution finality.
A host still needs to answer, separately:
- whether the tool call is authorized;
- whether approval is required;
- which execution owns the call;
- how cancellation propagates;
- whether the call actually settled; and
- what terminal evidence is trustworthy.
A perfectly coherent prompt can still invoke an unsafe or poorly finalized tool implementation. Conversely, a strong permission layer can block an unauthorized call even if stale prompt text mistakenly encouraged it.
The reusable layering is:
provider/config state ↓connected providers ↓product tool registry ↓declared callable schemas ↓model-facing guidance ↓authorization / approval ↓execution ownership + lifecycle ↓terminal result / evidenceEach layer should consume the minimum truth it needs and should not silently substitute for another.
Relation to UHP, MCP and harness interoperability
Section titled “Relation to UHP, MCP and harness interoperability”This page describes harness-internal tool-surface integrity.
- UHP standardizes an external product/server/harness execution boundary. UHP
2026-09-12does not require a particular system-prompt renderer or certify that an upstream harness’s internal prompt names exactly the tools its model request declares. - MCP can supply tools to a host, but an MCP server being configured or connected does not prove every MCP tool is registered, declared to the model or preserved through a concurrent reload. Host policy, discovery, filtering and provider limits can still narrow the effective model-facing set.
- ACP/A2A operate at different interoperability boundaries; Qwen PR #12145 and Hermes PRs #119900/#119960 do not revise either protocol.
- Harness adapters can add another place for drift if an adapter filters, renames or emulates tools while the upstream harness still generates guidance from its own assumptions.
For interoperability testing, this suggests an additional implementation question beyond wire conformance:
When the effective tool surface changes through policy, installation, reconnection, reload or dynamic discovery, do the registry, session snapshot and model-facing context converge on the same intended capability set?
That is an implementation-quality question today, not a new UHP conformance class.
See Qwen Code, Hermes, Harness composition, Security and Lifecycle for the surrounding product, policy and execution boundaries.
Practical review checklist
Section titled “Practical review checklist”When reviewing an agent harness, verify:
- Authoritative inventory is explicit: can the system distinguish a complete desired tool/provider set from a partial activation delta?
- Connection and registration are separate: can a provider be connected while its tools are missing, and is that state detectable?
- Activation is serialized where required: can concurrent discovery or go-live expose a temporary empty manager/registry as success?
- Lock scope is bounded: are metadata/discovery locks released before slow network work when that work does not require the shared lock?
- Registry-to-session handoff is protected: can a live session snapshot the registry while another path has temporarily torn it down?
- Single effective source: can you identify the exact tool set sent to the model request?
- Prompt derivation: is tool-specific guidance generated or filtered from that effective set rather than a separate static catalogue?
- Multi-tool instructions: if one instruction names several tools, is it removed when any required tool is absent?
- Safety independence: do permission, denial and dangerous-action rules remain enforceable even when tool guidance is gated?
- Dynamic discovery: what happens when a tool is revealed, installed or disabled after the system prompt was built?
- Cache semantics: does refreshing tool guidance rewrite a cacheable system prefix, and is that trade-off intentional?
- Diagnostics parity: does
/context, debug output or telemetry show the prompt snapshot actually used by the request? - Inverse testing: do tests prove both that missing-tool guidance disappears and present-tool guidance remains?
- Default regression: does the common all-tools path remain unchanged when no narrowing is configured?
- Evidence boundary: are focused race/registry tests or prompt-size measurements being mistaken for broader product certification, model-quality gains or lower end-to-end cost?
Primary sources
Section titled “Primary sources”- Qwen Code PR #12145 — resident tool prompt assembly
- Qwen merge commit
377a5753 - Qwen design — Assembling the System Prompt from the Resident Tool Set
- Qwen verification brief
- Qwen issue #12032 — prompt/tool-surface mismatch
- Qwen Code v0.24.4
- Hermes PR #119900 — preserve already-connected MCP tools during subset activation
- Hermes merge
dbe2f696 - Hermes PR #119960 — serialize concurrent plugin go-live
- Hermes merge
c07501ec - Hermes PR #119862 — open registry-to-session refresh race
- Hermes Agent v0.21.5 / v2026.9.24
- Hermes v0.21.5 tag commit
f97608f1