Skip Guardian reviews in Full Access (#42147)

## Why

Full Access already combines `approvalPolicy: "never"` with unrestricted
permissions, so confirmation-only actions do not require a model review.

## What changed

- Detect Full Access consistently across the thread and every selected
  environment. Pending, failed, or restricted environments are not treated as
  Full Access.
- Approve confirmation-only Guardian and MCP requests without synchronous
  review, sampler prewarming, or background scoring. Cancellation, explicit
  denials, and forms that require user input keep their existing behavior.
- Re-evaluate the active permission state on each turn so an existing thread
  can enter or leave Full Access safely.

## Testing

Added coverage for switching approval modes, strict sensitive MCP
confirmations, failed and pending environments, and suppression of Guardian
requests and background-scoring connections.

GitOrigin-RevId: 089ab4296dde473b8e33ab8324be79c5446c46f6
This commit is contained in:
jif authored and copyberry committed 2026-09-01 22:16:54 +00:00
1 parent cd8bd62c6e
commit e576993911
14 files changed
+295 -22

No files matched your search

+24
View File
@@ -726,6 +726,30 @@ async fn review_guardian_mcp_elicitation(
};
let step_settings = turn_context.current_settings.load_full();
// Full Access skips inference, not the active-turn and cancellation checks.
if turn_context.environments.has_full_access(
turn_context.approval_policy(),
&turn_context
.config
.permissions
.effective_permission_profile(),
) && matches!(
&request.elicitation,
Elicitation::Mcp(rmcp::model::ElicitRequestParams::FormElicitationParams {
requested_schema, ..
}) if requested_schema.properties.is_empty()
) {
let decision = if cancellation_token.is_cancelled() {
ReviewDecision::Abort
} else {
ReviewDecision::Approved
};
return Ok(Some(mcp_elicitation_response_from_guardian_decision(
decision,
turn_context.model_info(),
)));
}
// The invocation identifies the tool event, but a nested elicitation can
// review a different action and connector than the enclosing JavaScript.
let originating_call_id = if is_node_repl_backed_server(&request.server_name)