Use ApiPathString in app-server filesystem permission paths (#28367)

## Why

Clients running an app-server on one OS and an exec-server on another OS
need to be able to pass sandbox config to app-server that refers to
resources on the executor's foreign OS.

## What

`AbsolutePathBuf` can't represent these paths and we don't want users to
be exposed to `PathUri` yet, so this moves the public app-server API to
be expressed in terms of `ApiPathString`.

Stacked on #28165.

- change app-server v2 filesystem permission paths, including legacy
read/write roots, to `ApiPathString`
- localize API paths through `PathUri` when converting into the current
native core permission types
- make path-bearing permission conversions fallible and surface
localization failures instead of silently treating malformed grants as
ordinary denials
- propagate conversion failures through app-server and TUI approval
handling
- regenerate the app-server JSON and TypeScript schemas
- leave migration TODOs on native-path conversions so they can be
removed once core permission paths use `PathUri`
This commit is contained in:
Adam Perry @ OpenAI
2026-06-15 19:25:54 -07:00
committed by GitHub
Unverified
parent d959664420
commit ecfe174d5f
34 changed files with 546 additions and 233 deletions
@@ -16,9 +16,9 @@ use ts_rs::TS;
///
/// When converting from [`PathUri`], "native" refers to the supplied
/// [`PathConvention`], which may be foreign to the operating system running
/// this process. The inner string is private so path-producing code must use
/// [`Self::from_abs_path`] or [`Self::from_path_uri`] instead of bypassing the
/// intended conversion boundary. Non-UTF-8 paths are converted to UTF-8
/// this process. The inner string is private so path-producing code must convert
/// from [`AbsolutePathBuf`] or use [`Self::from_path_uri`] instead of bypassing
/// the intended conversion boundary. Non-UTF-8 paths are converted to UTF-8
/// lossily because this API value is serialized as a JSON string.
///
/// Deserialization accepts any UTF-8 string without interpreting or validating
@@ -102,6 +102,12 @@ impl ApiPathString {
}
}
impl From<AbsolutePathBuf> for ApiPathString {
fn from(path: AbsolutePathBuf) -> Self {
Self::from_abs_path(&path)
}
}
fn parse_posix_path(path: &str) -> Option<PathUri> {
let path = path.strip_prefix('/')?;
if path.contains('\0') {