Skip to content

fix(sandbox): bound web E2E evidence and service logs - #1287

Merged
seonghobae merged 13 commits into
codex/pr931-bounded-subprocess-core-20260824from
codex/pr931-sandboxed-web-e2e-main-20260824
Aug 24, 2026
Merged

fix(sandbox): bound web E2E evidence and service logs#1287
seonghobae merged 13 commits into
codex/pr931-bounded-subprocess-core-20260824from
codex/pr931-sandboxed-web-e2e-main-20260824

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Recreated from the preserved #1282 work after its deleted stacked base was merged into #1280. This layer adds bounded backend/frontend service capture, bounded E2E output, readiness URL validation, stable launch errors, cleanup evidence, and regression coverage.\n\nStack: #1280 -> this PR. Local evidence on the merge-result tree: 59 focused tests passed; full suite 1,478 passed, 1 skipped, 16 subtests; interrogate 100%; compileall and git diff --check passed.


Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 522a2e2c-9421-4ee5-9c50-42b9530e1afd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae merged commit 39e30cb into codex/pr931-bounded-subprocess-core-20260824 Aug 24, 2026
7 of 13 checks passed
@seonghobae
seonghobae deleted the codex/pr931-sandboxed-web-e2e-main-20260824 branch August 24, 2026 03:05

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

Comment on lines +494 to +503
if _services_output_limited(services):
output_limited = True
if exit_code == 0:
exit_code = bounded_subprocess.OUTPUT_LIMIT_EXIT_CODE
if not service_limit_reported:
print(
"sandboxed-web-e2e: service output exceeded "
f"{args.service_log_limit_bytes} bytes",
file=sys.stderr,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Late-overflow exit-code precedence holds

In main's finally, a late service overflow raises the code to 123 only when exit_code == 0 (scripts/ci/sandboxed_web_e2e.py:496), so a nonzero E2E, readiness, or timeout result stays authoritative while output_limited still records the overflow. Consistent with the documented contract and the tests.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@@ -135,41 +237,59 @@ def wait_for_url(url: str, timeout: int, service: Service) -> bool:
return False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: 5xx readiness responses re-poll without backoff

A 5xx response in wait_for_url neither returns ready nor sleeps, so it re-polls immediately until the deadline (scripts/ci/sandboxed_web_e2e.py:231-236). Each pass still issues a real 2-second request, so it is not a tight spin. Pre-existing behavior; the PR only added the overflow guard to this loop.

(Refers to this code)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +210 to 217
def service_output_limited(service: Service) -> bool:
"""Return whether one service exceeded its declared combined log budget."""
if service.capture is not None:
return service.capture.output_limited
return (
service.log_path.exists()
and service.log_path.stat().st_size > service.log_limit_bytes
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Service log file materializes only at stream close

The bounded service log is written only when the stream closes (_write_destination in the drain thread, scripts/ci/bounded_subprocess.py:222-234), so it is absent while the service runs. Overflow detection uses in-memory capture.output_limited and tail_text runs after stop_service joins the capture, so the read ordering is sound.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +433 to +472
except CommandExecutableNotFoundError:
print(
"sandboxed-web-e2e: install each executable or correct command PATH",
file=sys.stderr,
)
exit_code = sandboxed_verify.COMMAND_NOT_FOUND_EXIT_CODE
except CommandNotExecutableError:
print(
"sandboxed-web-e2e: select executable files or correct their permissions",
file=sys.stderr,
)
exit_code = sandboxed_verify.COMMAND_NOT_EXECUTABLE_EXIT_CODE
except bounded_subprocess.OutputLimitUnsupportedError:
output_limit_unsupported = True
print(
"sandboxed-web-e2e: bounded child output is unavailable on this platform",
file=sys.stderr,
)
exit_code = bounded_subprocess.OUTPUT_LIMIT_EXIT_CODE
except sandboxed_verify.RepositoryPathBoundaryError:
path_boundary_rejected = True
copied_repo = Path("(not-created)")
print(
"sandboxed-web-e2e: repository path boundary rejected",
file=sys.stderr,
)
exit_code = sandboxed_verify.PATH_BOUNDARY_EXIT_CODE
except sandboxed_verify.RepositoryRootError:
copied_repo = Path("(not-created)")
print(
"sandboxed-web-e2e: repository root is not a directory",
file=sys.stderr,
)
exit_code = 1
except RuntimeError:
print(
"sandboxed-web-e2e: bounded output capture failed",
file=sys.stderr,
)
exit_code = bounded_subprocess.OUTPUT_LIMIT_EXIT_CODE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: RuntimeError handler ordering is safe

The specific CommandExecutableNotFoundError, CommandNotExecutableError, and OutputLimitUnsupportedError handlers (all RuntimeError subclasses) precede the catch-all except RuntimeError at scripts/ci/sandboxed_web_e2e.py:467, so each maps to its intended exit code and the catch-all only absorbs the generic missing-pipe/capture failures as 123.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant