Add local diagnostic ZIP exports to the app server (#55940)

## What changed

Add a save RPC that accepts the existing report options and an absolute `savePath` on the server host. Save the report, selected attachments, and a manifest without uploading, and return `savedPath`, `threadId`, and `promptHash`. Local exports remain available when uploads are disabled by configuration.

Publish archives atomically without replacing existing files. Bound uncompressed contents to 200 MiB and attachments to 128, preserve duplicate attachment names safely, and fail without publishing a partial ZIP when a selected file cannot be read. Honor `includeLogs` and omit automatic rollouts for untouched threads without materializing them.

Update protocol schemas and generated TypeScript and Python types.

## Testing

Add coverage for local-only saves, disabled uploads, path validation, overwrite protection, log consent, archive budgets, duplicate names, missing files, and rollout selection before materialization and after writer shutdown.

GitOrigin-RevId: 222c0fe7ab923904de9c8a9f12ad27f7a0104875
This commit is contained in:
viktor-oai
2026-10-21 16:43:30 +00:00
committed by copyberry
parent 430a16799d
commit a3b685331f
34 changed files with 1481 additions and 120 deletions
+12
View File
@@ -881,6 +881,18 @@ impl CodexThread {
self.rollout_path.clone()
}
/// Selects a local feedback rollout without materializing an untouched thread.
pub async fn feedback_rollout_path(&self) -> ThreadStoreResult<Option<PathBuf>> {
match self.session.live_thread() {
Some(thread) => thread.feedback_rollout_path().await.or_else(|error| {
// Shutdown can close or remove the writer before its thread leaves the manager.
// Retain the captured input; the archive reader still rejects missing files.
self.rollout_path().map(Some).ok_or(error)
}),
None => Ok(None),
}
}
/// Returns startup metadata without the one-time initial message replay.
pub fn startup_metadata(&self) -> &ThreadStartupMetadata {
&self.startup_metadata
+1 -1
View File
@@ -1182,7 +1182,7 @@ pub struct Config {
/// Voluntarily left as Optional because the default value might depend on the client.
pub analytics_enabled: Option<bool>,
/// When `false`, disables feedback collection across Codex product surfaces.
/// When `false`, disables feedback uploads and background Guardian review retention. Explicit local exports remain available.
/// Defaults to `true`.
pub feedback_enabled: bool,