Skip to content

test(browser): execute controlled Agent Task on pinned Chrome - #70

Open
seonghobae wants to merge 17 commits into
test/agent-task-controlled-fixturefrom
test/agent-task-pinned-chrome-execution
Open

test(browser): execute controlled Agent Task on pinned Chrome#70
seonghobae wants to merge 17 commits into
test/agent-task-controlled-fixturefrom
test/agent-task-pinned-chrome-execution

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Partial implementation of #28, stacked on PR #65.

Buyer-visible boundary

PR #65 provides the controlled Agent Task fixture. This lane proves pinned stock Chromium can execute the bounded clear/type/click/post-condition workflow without leaving the authorized fixture document, while preserving isolated-profile cleanup and bounded repeatability evidence.

Fresh stack state

Protected main is b05d5acca82b9d916ada2c8e82f59f92a89817e1. Live prerequisite #65 is 93a85c1464ab73ed7386367dc78fbad9c4f2f107.

The prior child was behind that moved prerequisite, so #70 was reconstructed non-destructively from the exact current #65 tree while preserving its six unique Agent Task/MV3 files. Current exact head is 4930ab764eb63c524c4129196bd2acb6188c1c02. Fresh comparison against #65 reports merge base exactly 93a85c1464ab73ed7386367dc78fbad9c4f2f107, 14 ahead / 0 behind, with only the intended child files changed. No predecessor evidence transfers.

TDD boundary

The runner uses pinned Chrome WebDriver clear/type/click operations against the controlled fixture, verifies submitted state and synthetic echo, requires the loaded URL to remain unchanged, emits bounded credential-free repeatability evidence, and proves temporary-profile cleanup. A prior security regression that reflected page-controlled data-state text into diagnostics was repaired to a constant failure message; no catch-all suppression or authority weakening was introduced.

Exact-current evidence

On unchanged exact head 4930ab764eb63c524c4129196bd2acb6188c1c02:

  • CI 32935787043: success.
  • Rust contracts 98076633184: success, including repository contracts, formatting, workspace/all-target check, full tests, strict Clippy, and rustdoc under Rust 1.97.1.
  • Production coverage 98076633012: success.
  • Owned production coverage: functions 433/433, lines 3675/3675, regions 4580/4580, branches 512/512 — 100% on all four dimensions.
  • Coverage artifact 9594817668, digest sha256:75aa3efbb13fa9f2cc4877eace0d1e564f08cd412002da8c9b74c1feb9bb8496.
  • Manifest V3 Compatibility 32935787063: success.
  • Pinned-Chrome job 98076633056: success.
  • MV3 artifact 9594787798, digest sha256:e1fa350ff31fd076900c5d2a63bd2bdb75bfd6882be87d27eaabf21f2fde6bd1.
  • Chrome/ChromeDriver 150.0.7871.129, Chromium revision r1639810.
  • Agent Task repeatability: 3/3 trials; every trial reports post_condition, input_echo_verified, url_unchanged, extensions_disabled, and profile_cleaned true.
  • Formal review inventory contains one Devin automated COMMENTED review and no qualifying independent approval; inline review inventory is empty.

No same-head SAST or Security Scan success is claimed because the reconstructed head currently exposes CI and Manifest V3 evidence only.

Truth / authority boundary

This is executable controlled-browser evidence, not the complete OriginWeave browser runtime. It does not prove full origin authorization, BiDi/CDP product-adapter semantics, semantic node-handle composition, policy dispatch, provenance, trusted process attribution, secret brokerage, persistence, or closure of #28. #65 remains active, so this child is dependency-bound. Protected-main AGENTS.md remains authoritative; this scheduled actor does not merge, self-approve, force-push, alter workflows/rulesets, add secrets, weaken checks, tag, release, or publish.

@coderabbitai

coderabbitai Bot commented Aug 11, 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: 65d04328-7ef9-49da-a357-26bcd20463b7

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 marked this pull request as ready for review August 21, 2026 01:44

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 4 new potential issues.

Open in Devin Review

Comment thread scripts/ci/run_mv3_compatibility.py Outdated
Comment on lines +758 to +766
agent_task_surfaces_complete = all(
trial.get("post_condition") is True
and trial.get("input_echo_verified") is True
and trial.get("url_unchanged") is True
and trial.get("extensions_disabled") is True
and trial.get("profile_cleaned") is True
for trial in agent_task_trials
if trial.get("passed") is True
)

@devin-ai-integration devin-ai-integration Bot Aug 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Agent Task surface gate is largely redundant

_agent_task_surfaces_complete requires five boolean fields true, but _run_agent_task_browser_pass raises before returning unless all are satisfied, so any passed trial already carries them true. The gate is effectively equivalent to the successful-trial count check that precedes it.

Open in Devin Review

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

Comment thread scripts/ci/run_mv3_compatibility.py
Comment thread scripts/ci/run_mv3_compatibility.py Outdated
Comment on lines +547 to +552
_json_request(
driver_port,
"POST",
_element_command_path(session_id, input_element, "/value"),
{"text": AGENT_TASK_INPUT_VALUE, "value": list(AGENT_TASK_INPUT_VALUE)},
)

@devin-ai-integration devin-ai-integration Bot Aug 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Send Keys payload includes both W3C 'text' and legacy 'value' keys

The element /value request at run_mv3_compatibility.py sends {"text": AGENT_TASK_INPUT_VALUE, "value": list(AGENT_TASK_INPUT_VALUE)}. W3C WebDriver Element Send Keys uses text; the extra legacy value array is ignored by modern ChromeDriver in W3C mode and is harmless. The preceding /clear ensures the pre-populated input default (synthetic order 42) is removed before typing, so the subsequent text != AGENT_TASK_INPUT_VALUE check would fail closed if clear were ineffective — no false positive risk here.

Open in Devin Review

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

devin-ai-integration[bot]

This comment was marked as resolved.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

Open in Devin Review

Comment on lines +213 to +226
def _cleanup_browser_session_preserving_primary(
driver_port: int,
session_id: str,
primary_error: BaseException | None,
) -> None:
"""Fail closed on expected cleanup errors while retaining an earlier causal failure."""

try:
_cleanup_browser_session(driver_port, session_id)
except (OSError, ValueError, RuntimeError, json.JSONDecodeError) as cleanup_error:
bounded_error = BrowserSessionCleanupError(cleanup_error)
if primary_error is None:
raise bounded_error from cleanup_error
raise bounded_error from primary_error

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Cleanup wrapper only normalizes a fixed exception tuple

_cleanup_browser_session_preserving_primary catches only (OSError, ValueError, RuntimeError, json.JSONDecodeError). http.client.HTTPException subclasses (e.g. IncompleteRead) are none of these and would propagate uncaught, escaping the same narrow tuple caught in the main trial loop. Consistent with the existing pattern, so not a regression, but a malformed DELETE response would crash the runner rather than mark a failed trial.

Open in Devin Review

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

Comment on lines 412 to +427
finally:
if session_id is not None:
with contextlib.suppress(Exception):
_json_request(
primary_error = sys.exc_info()[1]
try:
if session_id is not None:
_cleanup_browser_session_preserving_primary(
driver_port,
"DELETE",
_webdriver_path(session_id, ""),
{},
session_id,
primary_error,
)
driver.terminate()
try:
driver.wait(timeout=5)
except subprocess.TimeoutExpired:
driver.kill()
driver.wait(timeout=5)
finally:
driver.terminate()
try:
driver.wait(timeout=5)
except subprocess.TimeoutExpired:
driver.kill()
driver.wait(timeout=5)

@devin-ai-integration devin-ai-integration Bot Aug 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Cleanup failures now fail the trial (behavior change)

Both browser-pass finalizers read sys.exc_info()[1] to chain cleanup errors onto the causal failure. This replaces the old contextlib.suppress(Exception), which silently discarded cleanup errors. A WebDriver session or profile cleanup failure now converts an otherwise passing trial into a failed one — fail-closed, and the tests exercise the chaining paths directly.

Open in Devin Review

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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

Open in Devin Review

"duration_ms": round((time.monotonic() - started) * 1000),
}
finally:
primary_error = sys.exc_info()[1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: sys.exc_info() primary-error detection is context-fragile

The three finally blocks read primary_error from sys.exc_info()[1]. This is correct only because no caller invokes these functions from inside an active except block. A future caller doing so would surface a stale outer exception and mis-chain the cleanup error. Correct as currently called.

Open in Devin Review

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

Comment on lines +501 to +504
def _cleanup_agent_task_browser_session(driver_port: int, session_id: str) -> None:
"""Delete one Agent Task WebDriver session without suppressing cleanup failures."""

_cleanup_browser_session(driver_port, session_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Cleanup wrapper tested but never used in production

_cleanup_agent_task_browser_session is only exercised by a test; the real Agent Task pass cleans up via _cleanup_browser_session_preserving_primary. The test guards a function that is not on the executed cleanup path.

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