(
ctx: &PolicyLocalContext,
method: &str,
path: &str,
body: &[u8],
)
| 139 | } |
| 140 | |
| 141 | async fn route_request( |
| 142 | ctx: &PolicyLocalContext, |
| 143 | method: &str, |
| 144 | path: &str, |
| 145 | body: &[u8], |
| 146 | ) -> (u16, serde_json::Value) { |
| 147 | let (route, query) = path.split_once('?').map_or((path, ""), |(r, q)| (r, q)); |
| 148 | // Gate every route on the feature flag so the agent surface is fully off |
| 149 | // when the flag is off — including the diagnostic `current_policy` and |
| 150 | // `denials` routes. The skill is also not installed in that mode, so a |
| 151 | // disabled sandbox has no entry point into this API at all. |
| 152 | if !openshell_core::proposals::agent_proposals_enabled() { |
| 153 | return ( |
| 154 | 404, |
| 155 | serde_json::json!({ |
| 156 | "error": "feature_disabled", |
| 157 | "detail": "agent-driven policy proposals are not enabled in this sandbox; set the `agent_policy_proposals_enabled` setting to true to enable" |
| 158 | }), |
| 159 | ); |
| 160 | } |
| 161 | match (method, route) { |
| 162 | ("GET", ROUTE_POLICY_CURRENT) => current_policy_response(ctx).await, |
| 163 | ("GET", ROUTE_DENIALS) => recent_denials_response(ctx, query).await, |
| 164 | ("POST", ROUTE_PROPOSALS) => submit_proposal(ctx, body).await, |
| 165 | ("GET", path) if path.starts_with(ROUTE_PROPOSALS_PREFIX) => { |
| 166 | proposal_state_route(ctx, path, query).await |
| 167 | } |
| 168 | _ => ( |
| 169 | 404, |
| 170 | serde_json::json!({ |
| 171 | "error": "not_found", |
| 172 | "detail": format!("policy.local route not found: {method} {route}") |
| 173 | }), |
| 174 | ), |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | /// Parse `{chunk_id}` (status) or `{chunk_id}/wait` (long-poll) from the path |
| 179 | /// suffix and dispatch. Empty `chunk_id` or extra segments return 404 so a |
no test coverage detected