Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ All notable changes to OriginWeave are documented in this file. The format follo
### Added

- Controlled pinned-Chromium Agent Task success now binds the ChromeDriver browser root to its exact Linux `/proc/<pid>/stat` start-time identity, binds every still-live PID from the already sampled bounded Chromium root-plus-descendant set before shutdown, explicitly records descendants that already exited between the `/proc` lineage snapshot and identity capture, and fails closed unless every retained exact identity terminates after session/driver shutdown; root disappearance or identity change remains an error, PID reuse counts only as termination of the original identity, and this does not attest cgroup/task ownership, processes appearing only after the sample, or OS-wide orphan absence.
- The controlled forced-close Agent Task recovery probe now binds the ChromeDriver browser root and its already sampled bounded Chromium descendant set to exact Linux PID/start-time identities before forcing the disposable context closed, and successful recovery is accepted only after session/driver shutdown proves root and sampled-set termination under one shared bounded monotonic deadline; this remains bounded compatibility evidence and does not attest cgroup ownership, post-snapshot processes, cross-platform supervision, or OS-wide orphan absence.
- Controlled ordinary Agent Task teardown now observes the exact browser root and already sampled Chromium process set under one shared bounded monotonic deadline after session/driver shutdown, preserving separate root/process-set termination evidence and retaining `None` when no full process set was captured; this prevents sequential waiters from extending a nominal teardown budget while making no claim about cgroup ownership, post-snapshot processes, cross-platform supervision, or OS-wide orphan absence.
- Failed ordinary and forced-close Agent Task browser trials now retain credential-free temporary-profile cleanup evidence after bounded browser errors, and separate aggregate compatibility gates require cleanup proof from every trial rather than filtering unsuccessful trials out; this does not attest adversarial filesystem erasure, process termination, or arbitrary browser recovery.
- Failed Manifest V3 restart trials now retain credential-free temporary-profile cleanup evidence after bounded browser errors, including reviewed ChromeDriver process-teardown `TimeoutExpired` failures; successful trials record the same cleanup fact, and an aggregate compatibility gate requires teardown proof from every MV3 trial before repeatability acceptance without retaining exception messages or command paths; this does not attest adversarial filesystem erasure, browser-process termination, or cleanup outside the controlled temporary profile.
- Rust workspace for independently reusable core, policy, destination, network, TLS, resource, and evidence modules.
Expand Down
21 changes: 14 additions & 7 deletions scripts/ci/run_mv3_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -1428,15 +1428,22 @@ def _run_agent_task_browser_pass(

if browser_process_id is None or browser_process_start_time_ticks is None:
raise RuntimeError("Agent Task browser process identity was not captured")
browser_process_terminated = _wait_for_linux_process_identity_exit(
browser_process_id,
browser_process_start_time_ticks,
full_process_set_captured = chromium_process_identities is not None
teardown_identities = (
chromium_process_identities
if chromium_process_identities is not None
else ((browser_process_id, browser_process_start_time_ticks),)
)
chromium_process_set_terminated: bool | None = None
if chromium_process_identities is not None:
chromium_process_set_terminated = _wait_for_linux_process_identity_set_exit(
chromium_process_identities
browser_process_terminated, observed_process_set_terminated = (
_wait_for_linux_process_teardown(
browser_process_id,
browser_process_start_time_ticks,
teardown_identities,
)
)
chromium_process_set_terminated: bool | None = (
observed_process_set_terminated if full_process_set_captured else None
)
Comment thread
seonghobae marked this conversation as resolved.
if (
browser_failure_type is not None
or session_cleanup_failure_type is not None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ def test_browser_pass_retains_sampled_process_set_teardown_after_failure(self) -
end = runner.index("\ndef _run_agent_task_trial(", start)
browser_pass = runner[start:end]
for expected in (
"if chromium_process_identities is not None:",
"chromium_process_set_terminated = _wait_for_linux_process_identity_set_exit(",
"full_process_set_captured = chromium_process_identities is not None",
"_wait_for_linux_process_teardown(",
"observed_process_set_terminated if full_process_set_captured else None",
'failure_evidence["chromium_process_set_terminated"]',
):
with self.subTest(expected=expected):
Expand Down Expand Up @@ -91,4 +92,4 @@ def fail_before_process_set_capture(


if __name__ == "__main__":
unittest.main()
unittest.main()
37 changes: 37 additions & 0 deletions tests/test_agent_task_shared_teardown_deadline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Contract for one total post-shutdown teardown deadline in the ordinary Agent Task lane."""

from __future__ import annotations

import pathlib
import unittest

ROOT = pathlib.Path(__file__).resolve().parents[1]
RUNNER = ROOT / "scripts" / "ci" / "run_mv3_compatibility.py"


class AgentTaskSharedTeardownDeadlineContractTests(unittest.TestCase):
"""Prevent ordinary Agent Task teardown polling from multiplying the budget."""

def test_browser_pass_uses_only_the_combined_teardown_waiter(self) -> None:
"""Root and sampled-set evidence must share one timeout authority after shutdown."""

runner = RUNNER.read_text(encoding="utf-8")
start = runner.index("def _run_agent_task_browser_pass(")
end = runner.index("\ndef _run_agent_task_trial(", start)
browser_pass = runner[start:end]

self.assertIn("_wait_for_linux_process_teardown(", browser_pass)
self.assertNotIn("_wait_for_linux_process_identity_exit(", browser_pass)
self.assertNotIn("_wait_for_linux_process_identity_set_exit(", browser_pass)

shutdown = browser_pass.index("_terminate_owned_process_bounded(")
teardown_wait = browser_pass.index("_wait_for_linux_process_teardown(")
failure_return = browser_pass.index(
"or driver_cleanup_failure_type is not None"
)
self.assertLess(shutdown, teardown_wait)
self.assertLess(teardown_wait, failure_return)


if __name__ == "__main__":
unittest.main()
Loading