Attach Windows sandbox log to feedback reports (#24623)

## Why

Windows sandbox diagnostics are currently hard to recover from
`/feedback` even though they are often the most useful artifact when
debugging sandbox behavior. Now that sandbox logging uses daily rolling
files, feedback can safely include the current day's sandbox log without
uploading the old ever-growing legacy `sandbox.log`.

## What changed

- Add a `codex-windows-sandbox` helper that resolves the current daily
sandbox log from `codex_home`.
- When feedback is submitted with logs enabled on Windows, app-server
attaches today's sandbox log if it exists.
- Upload the attachment under the stable filename `windows-sandbox.log`,
independent of the dated on-disk filename.
- Keep existing raw `extra_log_files` behavior unchanged for rollout and
desktop log attachments.

## Verification

- `cargo fmt -p codex-app-server -p codex-windows-sandbox`
- `cargo test -p codex-windows-sandbox
current_log_file_path_for_codex_home_uses_sandbox_dir`
- `cargo test -p codex-app-server
windows_sandbox_log_attachment_uses_current_log`
- Manual CLI/TUI `/feedback` test confirmed Sentry received
`windows-sandbox.log`.
This commit is contained in:
iceweasel-oai authored and GitHub committed 2026-05-26 15:59:25 -07:00
1 parent 46391f7efa
commit 9826581e7b
12 files changed
+131 -1

No files matched your search

@@ -1,4 +1,6 @@
use super::*;
#[cfg(target_os = "windows")]
use codex_feedback::WINDOWS_SANDBOX_LOG_ATTACHMENT_FILENAME;
#[derive(Clone)]
pub(crate) struct FeedbackRequestProcessor {
@@ -186,6 +188,12 @@ impl FeedbackRequestProcessor {
)),
});
}
if let Some(sandbox_log_attachment) =
windows_sandbox_log_attachment(&self.config.codex_home)
&& seen_attachment_paths.insert(sandbox_log_attachment.path.clone())
{
attachment_paths.push(sandbox_log_attachment);
}
}
if let Some(extra_log_files) = extra_log_files {
for extra_log_file in extra_log_files {
@@ -264,3 +272,46 @@ impl FeedbackRequestProcessor {
fn auto_review_rollout_filename(thread_id: ThreadId) -> String {
format!("auto-review-rollout-{thread_id}.jsonl")
}
#[cfg(target_os = "windows")]
fn windows_sandbox_log_attachment(codex_home: &Path) -> Option<FeedbackAttachmentPath> {
let sandbox_log_path = codex_windows_sandbox::current_log_file_path_for_codex_home(codex_home);
sandbox_log_path
.is_file()
.then_some(FeedbackAttachmentPath {
path: sandbox_log_path,
attachment_filename_override: Some(WINDOWS_SANDBOX_LOG_ATTACHMENT_FILENAME.to_string()),
})
}
#[cfg(not(target_os = "windows"))]
fn windows_sandbox_log_attachment(_codex_home: &Path) -> Option<FeedbackAttachmentPath> {
None
}
#[cfg(all(test, target_os = "windows"))]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn windows_sandbox_log_attachment_uses_current_log() {
let codex_home = tempfile::tempdir().expect("create tempdir");
let sandbox_dir = codex_windows_sandbox::sandbox_dir(codex_home.path());
std::fs::create_dir_all(&sandbox_dir).expect("create sandbox dir");
let sandbox_log_path =
codex_windows_sandbox::current_log_file_path_for_codex_home(codex_home.path());
std::fs::write(&sandbox_log_path, "sandbox log").expect("write sandbox log");
let attachment = windows_sandbox_log_attachment(codex_home.path())
.map(|attachment| (attachment.path, attachment.attachment_filename_override));
assert_eq!(
attachment,
Some((
sandbox_log_path,
Some(WINDOWS_SANDBOX_LOG_ATTACHMENT_FILENAME.to_string())
))
);
}
}