From 3dbce8a9862b6332ee897703780af7b2eb3f4135 Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 25 Aug 2026 16:52:04 -0500 Subject: [PATCH] fix(runnerd): send structured Codex permission profiles --- .../runner-core/src/bin/fake-codex-app-server.rs | 16 +++++++++++++++- .../crates/runner-core/src/codex_provider.rs | 8 ++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/bin/fake-codex-app-server.rs b/packages/paperclip-runner/runner/crates/runner-core/src/bin/fake-codex-app-server.rs index 6119c454d8c..84dce39d0d3 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/bin/fake-codex-app-server.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/bin/fake-codex-app-server.rs @@ -86,9 +86,16 @@ fn run() -> Result<(), Box> { } let config = request.pointer("/params/config").and_then(Value::as_object); planning_thread = request - .pointer("/params/permissions") + .pointer("/params/permissions/id") .and_then(Value::as_str) == Some("paperclip-runner-workspace-read-only"); + if request + .pointer("/params/permissions/type") + .and_then(Value::as_str) + != Some("profile") + { + return Err(format!("{method} omitted a structured permission profile").into()); + } if config .and_then(|value| value.get("skills.include_instructions")) .and_then(Value::as_bool) @@ -134,6 +141,13 @@ fn run() -> Result<(), Box> { }))?; } "turn/start" => { + if request + .pointer("/params/permissions/type") + .and_then(Value::as_str) + != Some("profile") + { + return Err("turn/start omitted a structured permission profile".into()); + } if planning_thread { let collaboration_mode = request.pointer("/params/collaborationMode"); if collaboration_mode diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs b/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs index 98becf5f1f4..5fc409ece45 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs @@ -1203,9 +1203,9 @@ impl CodexProvider { )); } let permission_profile = if config.collaboration_mode == "plan" { - "paperclip-runner-workspace-read-only" + json!({"type": "profile", "id": "paperclip-runner-workspace-read-only"}) } else { - "paperclip-runner-workspace-only" + json!({"type": "profile", "id": "paperclip-runner-workspace-only"}) }; let opened = if let Some(thread_id) = resume_thread_id { provider.request( @@ -1318,9 +1318,9 @@ impl CodexProvider { pub fn start_turn(&mut self, message: &str, cwd: &str) -> Result { let thread_id = self.thread_id.clone(); let permission_profile = if self.collaboration_mode == "plan" { - "paperclip-runner-workspace-read-only" + json!({"type": "profile", "id": "paperclip-runner-workspace-read-only"}) } else { - "paperclip-runner-workspace-only" + json!({"type": "profile", "id": "paperclip-runner-workspace-only"}) }; let mut params = json!({ "threadId": thread_id,