ADR-261: A configuration may exclude single tools
- Status
-
Accepted
- Date
-
2026-11-05
- Authors
-
Netresearch DTT GmbH
Context
An LLM configuration narrows the tools of its runs through
Allowed tool groups (ADR-043). The group is the
smallest unit it can name. To keep one tool from a configuration, an
administrator has to drop its whole group: a configuration that may use every
writing tool except delete_ loses all twenty-two tools of editing.
The global switch in the Tools module is no answer either, because it takes the
tool away from every configuration.
The tool gate (ADR-094) is the one place that decides whether a tool is offered and whether a call may run. A run resolves its skill allow-list once when it starts, stores it, and on resume intersects it with the list resolved then (ADR-038 item 5), so a change while the run waits can take a tool away but never add one. The group gate is read live on every decision instead.
Decision
- A field of single tools.
tx_gainsnrllm_ configuration excluded_, a comma list of tool names, edited as Excluded tools with a choice of the registered tools grouped by tool group. A stored name no tool carries any more stays listed under No longer registered, so it can be removed. Empty excludes nothing; every existing row keeps its tools.tools - It only narrows.
Toolrefuses an excluded tool with the new reasonCall Policy configuration(Excluded Tool). The check runs after the global state, the admin requirement, the skill allow-list and the group gate, so the reason is reported only when those let the tool through, and before the trust zone, so observe mode cannot offer an excluded tool. The field grants nothing: it is a deny list, and a name in it never reaches a path that adds a tool.Denial Reason:: CONFIGURATION_ EXCLUDED - Offer and execution. The same decision filters the tools offered to the
model and is asked again when a call is executed, and by the approval and
input submit gates of
Resume. A call the model sends to an excluded tool is refused like any call to a tool it was not offered.Coordinator - Stored with the run. The exclusions at run start ride the run's
SkillasTool Allow List excluded, so the queue, a suspended run and an approval carry them without a field of their own. The gate refuses the union of those and the configuration's live exclusions. An exclusion added while a run waits applies at once; one removed meanwhile still holds for that run. An intersection keeps the exclusions of both sides. The stored form writes the key only when there are exclusions, so the stored form of every other run is unchanged, and a run stored before reads back without exclusions and is held to the live list. A stored value that is not a list cannot say what it excluded and admits no tool, the skill load tool included.Tool Names - A tool registered later is not excluded. The field names tools, not a pattern or a group. A tool an extension or an MCP server adds later is offered until someone selects it.
- No exemption for the skill load tool. ADR-214 keeps
load_outside the skill allow-list and the group gate, because a skill declaringskill allowed-should not switch loading off. An exclusion names that very tool, so it applies totools: [] load_too.skill - Visible where tools are managed. The unavailable-tools list of
ADR-201 reports an excluded tool with its own reason. The
Tools module names, under each tool, the active configurations that exclude
it, and the governance tab of the overview module lists the excluded tools
per active configuration. Both read the field through
Tool, which decides nothing; the simulation on the same tab asks the gate itself.Exclusion Readout
Consequences
- An administrator can withhold one tool from one configuration without touching the others or the tool's group.
- A run resumed after its configuration dropped an exclusion stays without the tool. Starting a new run gives it back.
- The dashboard widget of tool denials shows a bar of its own for the new reason.
- Configuration presets do not carry the field. A preset import leaves it as it is.
Alternatives considered
- An allow-list of single tools. A configuration that names its tools would have to be edited whenever a tool is added, and a tool registered later would be refused by default. The ticket asks for the opposite: narrow by name, leave new tools alone.
- Reading the exclusions live only, like the group gate. Simpler, but a run waiting for an approval would get a tool back when its exclusion is removed, which the run never had at its start.
- A field of its own on every stored run. It would repeat the storage the skill allow-list already has, in the codec, the suspended state and the approval path, for the same "may only narrow on resume" rule.