Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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 @@ -1448,15 +1448,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