## Boundary Desk\:&#32;when the host can ask

Nia next hears that RPC is headless and concludes it cannot ask for approval\.&#32;That conclusion confuses a physical terminal with a semantic UI adapter\.

The wrapper asks its&#32;**extension runner**&#32;whether UI is available\.&#32;In the supplied runner\,&#32;`hasUI()`&#32;is implemented as a comparison against the built\-in no\-op UI context\.&#32;It is not a test for a keyboard\,&#32;TTY\,&#32;window\,&#32;or working client display\.

### Separate three questions

Ask these independently\:

1. What host mode is running\?
2. Which UI context was installed on the runner or tool context\?
3. Does that adapter actually support the requested selection operation\?

The SDK’s initial&#32;`hasUI`&#32;and&#32;`interactivePrompts`&#32;options\,&#32;the tool context’s UI state\,&#32;and&#32;`ExtensionRunner.hasUI()`&#32;serve related but distinct consumers\.&#32;A boolean from one is not proof of every capability in the others\.

| Host path | Source\-backed approval surface | Important limit |
| --- | ---: | --- |
| TUI | `ExtensionUiController`&#32;installs selector\-based UI\. | Component\/controller evidence is not physical key\-delivery proof\. |
| RPC | `runRpcMode()`&#32;installs&#32;`RpcExtensionUIContext`&#32;on extension initialization\;&#32;select uses RPC request\/response helpers\. | A connected client must handle the semantic request\.&#32;Native custom components and raw terminal input are not provided\. |
| ACP | `createAcpExtensionUiContext()`&#32;translates supported dialogs into form elicitations\. | Support depends on negotiated&#32;`elicitation.form`\;&#32;other methods remain stubbed\. |
| Default print\/JSON extension initialization | No UI context is supplied to the runner\. | A required approval fails closed\;&#32;automatically allowed calls need not prompt\. |

In&#32;`runRpcMode()`\,&#32;the optional&#32;`setToolUIContext`&#32;callback is called with the adapter and true when supplied\.&#32;`main.ts`&#32;supplies that callback for&#32;`rpc-ui`\,&#32;not ordinary&#32;`rpc`\.&#32;Nevertheless\,&#32;both use the RPC adapter in&#32;`initializeExtensions()`\,&#32;which is the runner UI consulted by this approval wrapper\.&#32;This is why the initial tool\-UI flag does not justify flattening ordinary RPC into no\-UI\.

### Read the two RPC cases

`boundary-rpc-approve`&#32;and&#32;`boundary-rpc-cancel`&#32;use the same exec\-tier fictional call in always\-ask mode\.&#32;Their&#32;`ui`&#32;value is&#32;`rpc`\.

**Prediction\:**&#32;what should a positive correlated response and a cancelled response do\?

**Recorded answer\:**&#32;each produced one select request through the real&#32;`requestRpcSelect()`&#32;helper and was answered through the real&#32;`dispatchRpcControlFrame()`&#32;helper\.&#32;The positive response produced one inert execution\.&#32;The cancelled response became&#32;`undefined`\,&#32;produced no execution\,&#32;and threw the user\-denial error\.&#32;Both left zero pending requests in the helper map\.

This is stronger than merely printing an expected frame\:&#32;the supplied verifier exercised the actual helper functions and wrapper\.&#32;It is narrower than launching a full RPC process or proving a real client rendered a dialog\.&#32;The runner itself was a structural adapter\,&#32;and the responses were supplied in\-process\.

The source also gives&#32;`RpcPendingExtensionRequests.rejectAll()`&#32;a disconnect failure path\.&#32;That is source\-backed here\,&#32;not an additional workbook disconnect scenario\.

### ACP requires capability\-specific language

The ACP adapter checks&#32;`clientCapabilities.elicitation.form`\.&#32;Without form support\,&#32;`select()`&#32;returns&#32;`undefined`\,&#32;`confirm()`&#32;returns false\,&#32;and editor\/input paths return their unavailable values\.

`AcpAgent.#configureExtensions()`&#32;still passes a distinct UI adapter to the extension runner\.&#32;As a result\,&#32;the runner can report&#32;`hasUI: true`&#32;even when a particular form operation is unavailable\.&#32;For a required generic tool approval\,&#32;that unavailable selection can be refused as a non\-Approve response rather than taking the runner’s literal no\-UI branch\.

This is not evidence that a person selected Deny\.&#32;It is an adapter capability boundary\.&#32;The supplied ACP setup also marks the tool UI available through its callback when form support is present\,&#32;and exposes extension mode as&#32;`rpc`\;&#32;neither means terminal components work\.

ACP plan\-proposal approval has its own control flow and capability fallback\.&#32;It is not the generic two\-choice tool gate\.&#32;Do not borrow its behavior or menu to explain a&#32;`tool_approval_requested`&#32;event\.

### No UI is a reason to stop\,&#32;not permission to skip

Compare&#32;`boundary-no-ui`&#32;with&#32;`dispatch-inspect-no-ui`\.&#32;Both have no UI\.&#32;The first needs a prompt and refuses\;&#32;the second is read\-tier at the applicable gates and returns without a prompt\.&#32;Absence of UI does not automatically deny all tools\,&#32;and it does not automatically approve a required prompt\.

The stock no\-UI error lists configuration\-widening possibilities\.&#32;This workbook does not recommend them as the generic repair\.&#32;First establish why a prompt is required\,&#32;whether the operation is still intended\,&#32;and whether the owning host has a supported approval surface\.&#32;On this route\,&#32;simply record the refusal and continue reading\.

**Paper checkpoint\:**&#32;is&#32;`hasUI: true`&#32;sufficient proof that a native panel or an ACP form can be used\?&#32;**Worked answer\:**&#32;no\.&#32;It can indicate only a non\-no\-op adapter\.&#32;Check the specific mode and negotiated operation capability\.

**Failure boundary\:**&#32;no physical terminal\,&#32;keyboard\,&#32;full RPC client process\,&#32;or ACP client flow was exercised by the new private scenarios\.&#32;Transport\-helper success does not upgrade itself into those claims\.

**Source anchors\:**&#32;`packages/coding-agent/src/extensibility/extensions/runner.ts`&#32;—&#32;`hasUI`\,&#32;`initialize`\;&#32;`packages/coding-agent/src/modes/rpc/rpc-mode.ts`&#32;—&#32;`runRpcMode`\,&#32;`requestRpcSelect`\,&#32;`requestRpcDialog`\,&#32;`dispatchRpcControlFrame`\,&#32;`RpcPendingExtensionRequests`\;&#32;`packages/coding-agent/src/modes/acp/acp-agent.ts`&#32;—&#32;`createAcpExtensionUiContext`\,&#32;`AcpAgent.#configureExtensions`\;&#32;`packages/coding-agent/src/modes/runtime-init.ts`&#32;—&#32;`initializeExtensions`\;&#32;`packages/coding-agent/src/modes/print-mode.ts`&#32;—&#32;`runPrintMode`\;&#32;`packages/coding-agent/src/main.ts`&#32;—&#32;`runRootCommand`\.
