Skip to content

Commit f67c04e

Browse files
DinahK-2SOCopilot
andauthored
Remove Copilot Yolo-off compatibility restriction (#849)
Copilot ACP now handles Yolo-off permission requests correctly. Remove the Copilot-specific prompt restriction so Yolo-off sessions use the standard permission flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e64c8b0 commit f67c04e

7 files changed

Lines changed: 62 additions & 370 deletions

File tree

doc/specs/Yolo-mode.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -166,20 +166,6 @@ through its normal interactive permission behavior. A failed disable or an
166166
unknown remote outcome retains fail-closed state until the Agent CLI stack is
167167
replaced.
168168

169-
GitHub Copilot CLI versions beginning with `1.0.81-1` have an upstream ACP
170-
regression that can report `allow_all=off` while executing tools without
171-
`session/request_permission`
172-
([github/copilot-cli#4537](https://github.com/github/copilot-cli/issues/4537)).
173-
The helper records the master-attested Copilot version and blocks every prompt
174-
producer when that exact session has acknowledged `allow_all=off` for the
175-
open-ended affected range. This includes a manual `/config` selection that
176-
differs from the global default. A missing or unsupported capability retains
177-
the provider's normal interactive path. Versions `1.0.81-0` and earlier retain
178-
the normal permission path. A session that acknowledges `allow_all=on` still
179-
permits prompts because the user selected the provider's unattended mode. A
180-
future version must pass the live denied-permission probe before the affected
181-
range is bounded.
182-
183169
Operations are serialized per session and fenced by lifecycle generation. A
184170
newer desired operation supersedes an older one; stale completions cannot
185171
commit state for a replaced or reused session ID.
@@ -217,7 +203,7 @@ option is not sufficient.
217203

218204
| Provider | Advertised contract | Enable | Restore |
219205
|---|---|---|---|
220-
| GitHub Copilot | `configOptions` ID `allow_all`, category `permissions`, Select values `on`/`off`; provider command `/allow_all` | `session/set_config_option(allow_all, on)` or the policy-gated provider command | Captured value, normally `off`; affected CLI versions are prompt-blocked because `off` is not trustworthy |
206+
| GitHub Copilot | `configOptions` ID `allow_all`, category `permissions`, Select values `on`/`off`; provider command `/allow_all` | `session/set_config_option(allow_all, on)` or the policy-gated provider command | Captured value, normally `off` |
221207
| Claude | `configOptions` ID `mode` with `bypassPermissions`; legacy mode fallback | `session/set_config_option(mode, bypassPermissions)` | Captured value, normally `default` |
222208
| Codex | `configOptions` ID `mode` with `agent-full-access`; legacy mode fallback | `session/set_config_option(mode, agent-full-access)` | Captured value, normally `agent` |
223209
| Gemini | ACP mode `yolo` | `session/set_mode(yolo)` | Captured mode, normally `default` |
@@ -263,9 +249,6 @@ defense in depth, not authorization. See `doc/security-model.md`.
263249
ACP session capability is implemented.
264250
- Gemini has no per-session WTA control because its current adapter advertises
265251
a mode but no corresponding config option.
266-
- Copilot CLI `1.0.81-1` and later block prompts whenever the exact session
267-
acknowledges `allow_all=off`, until the upstream ACP permission regression
268-
is fixed and a release passes the denied-permission probe.
269252
- Provider mode semantics and managed restrictions remain provider-owned.
270253
- WTA does not continuously poll for changes made by another actor; the next
271254
config update, reconciliation, or replacement session refreshes state.

tools/wta/src/protocol/acp/client.rs

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,13 +3154,9 @@ pub async fn run_acp_client_over_pipe(
31543154
.context("initialize over master pipe failed")
31553155
})?;
31563156
let wta_meta = crate::session_registry::extract_wta_meta(&mut init_resp.meta);
3157-
state.native_yolo.set_resolved_agent(
3158-
wta_meta.resolved_agent_id.as_deref(),
3159-
init_resp
3160-
.agent_info
3161-
.as_ref()
3162-
.map(|info| info.version.as_str()),
3163-
);
3157+
state
3158+
.native_yolo
3159+
.set_resolved_agent_id(wta_meta.resolved_agent_id.as_deref());
31643160
let cloud_catalog = crate::protocol::acp::model_select::cloud_catalog_from_wta_meta(&wta_meta);
31653161
if matches!(&agent_source, crate::agent_source::AgentSource::Host)
31663162
&& !cloud_catalog.models.is_empty()
@@ -5519,29 +5515,6 @@ async fn dispatch_prompt_body(
55195515
return;
55205516
}
55215517

5522-
if let Some(error) = client_task
5523-
.state
5524-
.native_yolo
5525-
.disabled_prompt_block_reason(&prompt_session_id)
5526-
{
5527-
tracing::error!(
5528-
target: "yolo",
5529-
session_id = %prompt_session_id_str,
5530-
error = %error,
5531-
"blocking prompt because the provider cannot attest disabled permissions"
5532-
);
5533-
let message = provider_permission_contract_blocked(&error);
5534-
let _ = event_tx_task.send(AppEvent::AgentError {
5535-
session_id: Some(prompt_session_id_str),
5536-
failure: AgentFailure::Protocol {
5537-
code: -32003,
5538-
message: message.clone(),
5539-
},
5540-
message,
5541-
});
5542-
return;
5543-
}
5544-
55455518
if client_task
55465519
.state
55475520
.yolo_state
@@ -5712,14 +5685,7 @@ async fn dispatch_prompt_body(
57125685
{
57135686
Some((provider_disable_pending(), "yolo_disable_pending"))
57145687
} else {
5715-
native_yolo
5716-
.disabled_prompt_block_reason(&guard_session_id)
5717-
.map(|error| {
5718-
(
5719-
provider_permission_contract_blocked(&error),
5720-
"permission_contract_blocked",
5721-
)
5722-
})
5688+
None
57235689
};
57245690
let should_send = !provider_command_blocked && yolo_safety_error.is_none();
57255691
if let Some(error) = yolo_safety_error {

0 commit comments

Comments
 (0)