Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ All notable changes to OriginWeave are documented in this file. The format follo
- Real loopback rustls integration covering trusted DNS SAN, Common-Name fallback rejection, wrong-name and untrusted-root rejection, fixed-time expiry and not-yet-valid failures, exact IPv4 and IPv6 SANs, TLS 1.2/TLS 1.3, required and optional ALPN, and transport-origin binding.
- Cumulative interactive-first RAM, VRAM, batch, local-model, admission, pause, and compositor-pressure mitigation plans, including active-consumer reduction at exact hard limits.
- Real pinned-Chrome WebDriver evidence for the controlled Agent Task fixture: the CI lane uses an isolated profile, disables extensions, types and submits synthetic text, observes the same-document post-condition, and proves profile cleanup; this does not claim a shipped OriginWeave browser adapter.
- Active pinned-Chrome Agent Task evidence verifies browser-computed role/name for controlled input and submit targets before action; this remains test-harness semantic evidence and does not claim a product semantic observer or authority.
- Universally value-redacted network evidence with explicit path, metadata, and provenance bounds; ambiguous path rejection; validated source URLs; lowercase SHA-256 identifiers; and verification state.
- Rust 1.97.1 build contract, strict Clippy and rustdoc gates, and exact production function, line, region, and branch coverage enforcement.
- Hourly bounded OpenCode product-development workflow using `NVIDIA_NIM_API_KEY`, an unprivileged disposable workspace, loopback-only model broker, independently verified patches, and publication through a dedicated `OPENCODE_PR_TOKEN` that cannot review or merge.
Expand Down
4 changes: 2 additions & 2 deletions docs/DOCUMENTATION_FITNESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ Active #64 makes a successful action-outcome value require existing verified pro

### 3.19 Controlled Agent Task fixture

Active #65 supplies a deterministic synthetic local web fixture with a labelled semantic input, submit control, same-document post-condition and explicitly hidden/untrusted prompt-injection text. Active #70 executes that fixture through real WebDriver on pinned Chrome with an isolated profile, disabled extensions, synthetic input, same-document post-condition verification and profile cleanup. The fixture contains no credential collection surface and requires no live third-party site.
Active #65 supplies a deterministic synthetic local web fixture with a labelled semantic input, submit control, same-document post-condition and explicitly hidden/untrusted prompt-injection text. Active #70 executes that fixture through real WebDriver on pinned Chrome with an isolated profile, disabled extensions, synthetic input, same-document post-condition verification and profile cleanup. Active #71 verifies browser-computed role/name for the controlled input and submit button before action. The fixture contains no credential collection surface and requires no live third-party site.

**Resolution:** the #65/#70 lane makes controlled browser-level evidence reproducible without turning a third-party site into a test dependency. It is not a browser adapter, semantic extractor, OriginWeave input-dispatch authority, policy engine, trusted clock, process-attribution source or proof of the shipped product runtime.
**Resolution:** the #65/#70/#71 lane makes controlled browser-level and browser-computed role/name evidence reproducible without turning a third-party site into a test dependency. It is not a browser adapter, product semantic extractor, OriginWeave input-dispatch authority, policy engine, trusted clock, process-attribution source or proof of the shipped product runtime.

### 3.20 Bounded browser process-set resource evidence

Expand Down
5 changes: 5 additions & 0 deletions docs/TEST_STRATEGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ browser-level fixture execution only; it does not replace the OriginWeave
BiDi/CDP authority adapter, semantic node contract, policy dispatch or
protected-main runtime acceptance required by issue #28.

Active PR #71 additionally verifies browser-computed role/name for the
controlled input and submit target before the real WebDriver action. CSS remains
a fixture-harness locator; this does not establish OriginWeave node authority,
semantic provenance or policy dispatch.

### 3.5 Buyer acceptance

Versioned task packs measure repeatable product outcomes rather than one lucky agent run. The benchmark artifact records browser build, OriginWeave version, model/provider/reasoning configuration, seed where supported, policy profile, hardware profile and source fixtures.
Expand Down
17 changes: 13 additions & 4 deletions docs/traceability/action-postcondition-evidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ PR #70 reuses the existing pinned Chrome for Testing workflow and executes the #

This is real WebDriver evidence for a controlled local fixture, not a product browser adapter. It does not establish WebDriver BiDi/CDP authority translation, OriginWeave semantic observation or node handles, policy-authorized typed action dispatch, trusted browser-process attribution, or protected-main product runtime completion.

### PR #71 — browser-computed semantic role/name evidence before action

**Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR`

PR #71 extends the pinned-Chrome fixture lane by reading WebDriver's browser-computed role and accessible name for the controlled input and submit button before sending input or clicking. The exact expected values are `textbox` / `Task text` and `button` / `Submit task`; the repeatability gate requires both semantic checks in every successful trial.

This is bounded browser-computed evidence for a synthetic test target, not the OriginWeave semantic observation adapter. CSS locators remain test-harness selectors, and the lane does not create OriginWeave node handles, source-channel provenance, policy authority, or permission to execute page-advertised actions.

## 4. Non-transitive success semantics

The intended first-slice chain is:
Expand All @@ -88,7 +96,7 @@ VerifiedActionOutcomeEvidence type existence -/> proof of real Chromium executio
controlled fixture success -/> proof of an OriginWeave product browser runtime
```

PR #64 now rejects a caller-supplied observation timestamp that predates caller-supplied dispatch time, but the type cannot independently prove the clock source, that a real browser actually dispatched the action, that the supplied provenance belongs to the claimed browser target/node, or that the observed state was caused by that action. PR #70 proves real Chromium execution against the controlled fixture, but its test-harness CSS locators and direct WebDriver calls are not the OriginWeave adapter/runtime composition required under issue #28.
PR #64 now rejects a caller-supplied observation timestamp that predates caller-supplied dispatch time, but the type cannot independently prove the clock source, that a real browser actually dispatched the action, that the supplied provenance belongs to the claimed browser target/node, or that the observed state was caused by that action. PR #70 proves real Chromium execution against the controlled fixture and PR #71 adds browser-computed role/name evidence, but their test-harness CSS locators and direct WebDriver calls are not the OriginWeave adapter/runtime composition required under issue #28.

## 5. Active prerequisite graph for issue #28

Expand All @@ -102,9 +110,10 @@ The first real Chromium vertical slice remains distributed across bounded active
- PR #51 — bounded browser-task telemetry plus one explicitly supplied Linux PID `VmRSS` sampler; Chromium process discovery/process-set attribution remains outside that slice;
- PR #64 — verified and caller-timestamp-ordered post-condition action-outcome evidence; and
- PR #65 — controlled hostile local Agent Task workflow fixture; and
- PR #70 — real WebDriver execution of that fixture on pinned Chrome, without claiming a product browser adapter.
- PR #70 — real WebDriver execution of that fixture on pinned Chrome, without claiming a product browser adapter; and
- PR #71 — browser-computed role/name evidence before controlled action, without claiming a product semantic observer.

These active PRs are non-shipped evidence. PR #70 proves a bounded browser-level fixture flow, but the active set does not itself compose WebDriver BiDi/CDP transport, OriginWeave authority translation, trusted Chromium process attribution, policy-authorized real input dispatch, causal post-condition observation, or deterministic end-to-end teardown/recovery into one protected-main runtime.
These active PRs are non-shipped evidence. PR #70/#71 prove bounded browser-level and semantic evidence, but the active set does not itself compose WebDriver BiDi/CDP transport, OriginWeave authority translation, trusted Chromium process attribution, policy-authorized real input dispatch, causal post-condition observation, or deterministic end-to-end teardown/recovery into one protected-main runtime.

## 6. Remaining issue #28 boundary

Expand All @@ -122,4 +131,4 @@ This dossier does **not** close issue #28. Material remaining work includes:

## 7. Documentation fitness consequence

The ADR/PRD/TRD/Architecture/UML/ERD graph remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. PR #64 narrows a typed evidence gap, PR #65 supplies the controlled fixture, and PR #70 supplies real WebDriver evidence for that fixture. Neither introduces a new trust domain, deployed component, persistence owner, database schema, or independent architecture decision, so a new ADR or physical ERD entity would overstate the implementation. Detailed real-Chromium dispatch/post-condition sequence diagrams should be reconciled when the executable adapter chain stabilizes rather than manufacturing as-built detail before that runtime exists.
The ADR/PRD/TRD/Architecture/UML/ERD graph remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. PR #64 narrows a typed evidence gap, PR #65 supplies the controlled fixture, and PR #70/#71 supply real WebDriver and browser-computed semantic evidence for that fixture. Neither introduces a new trust domain, deployed component, persistence owner, database schema, or independent architecture decision, so a new ADR or physical ERD entity would overstate the implementation. Detailed real-Chromium dispatch/post-condition sequence diagrams should be reconciled when the executable adapter chain stabilizes rather than manufacturing as-built detail before that runtime exists.
53 changes: 49 additions & 4 deletions scripts/ci/run_mv3_compatibility.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
content-script, storage, declarative-net-request, tabs, windows, scripting,
commands, side-panel, bookmarks, history, real browser-click, and
restart-persistence behavior. It also executes the controlled Agent Task fixture
with extensions disabled in a fresh profile, performs real WebDriver input and
click operations, verifies the observable post-condition, and proves profile
cleanup without treating page content as instruction or authority.
with extensions disabled in a fresh profile, verifies browser-computed role/name
for the controlled action targets, performs real WebDriver input and click
operations, verifies the observable post-condition, and proves profile cleanup
without treating page content as instruction or authority.
"""

from __future__ import annotations
Expand Down Expand Up @@ -179,6 +180,28 @@ def _element_command_path(session_id: str, element_id: str, suffix: str) -> str:
return _webdriver_path(session_id, f"/element/{safe_element}{suffix}")


def _get_element_semantics(
driver_port: int,
session_id: str,
element_id: str,
) -> tuple[str, str]:
"""Read one controlled element's browser-computed role and accessible name."""

role = _json_request(
driver_port,
"GET",
_element_command_path(session_id, element_id, "/computedrole"),
).get("value")
label = _json_request(
driver_port,
"GET",
_element_command_path(session_id, element_id, "/computedlabel"),
).get("value")
if not isinstance(role, str) or not isinstance(label, str):
raise RuntimeError("WebDriver returned malformed element semantics")
return role, label
Comment thread
seonghobae marked this conversation as resolved.


def _wait_for_extension_evidence(
driver_port: int,
session_id: str,
Expand Down Expand Up @@ -538,6 +561,13 @@ def _run_agent_task_browser_pass(
f"Agent Task initial URL mismatch: expected {fixture_url!r}, got {initial_url!r}"
)
input_element = _find_element(driver_port, session_id, "#task-text")
input_role, input_name = _get_element_semantics(
driver_port,
session_id,
input_element,
)
if input_role != "textbox" or input_name != "Task text":
raise RuntimeError("Agent Task input semantic evidence mismatch")
_json_request(
driver_port,
"POST",
Expand All @@ -555,6 +585,13 @@ def _run_agent_task_browser_pass(
session_id,
"#agent-task-form button[type=submit]",
)
submit_role, submit_name = _get_element_semantics(
driver_port,
session_id,
submit_element,
)
if submit_role != "button" or submit_name != "Submit task":
raise RuntimeError("Agent Task submit semantic evidence mismatch")
Comment thread
seonghobae marked this conversation as resolved.
_json_request(
driver_port,
"POST",
Expand Down Expand Up @@ -588,6 +625,8 @@ def _run_agent_task_browser_pass(
"post_condition": True,
"input_echo_verified": True,
"url_unchanged": url_unchanged,
"input_semantics_verified": True,
"submit_semantics_verified": True,
"extensions_disabled": True,
"duration_ms": round((time.monotonic() - started) * 1000),
}
Expand Down Expand Up @@ -635,13 +674,17 @@ def _run_agent_task_trial(
"post_condition": result["post_condition"],
"input_echo_verified": result["input_echo_verified"],
"url_unchanged": result["url_unchanged"],
"input_semantics_verified": result["input_semantics_verified"],
"submit_semantics_verified": result["submit_semantics_verified"],
"extensions_disabled": result["extensions_disabled"],
"profile_cleaned": profile_cleaned,
"duration_ms": round((time.monotonic() - trial_started) * 1000),
}


def _start_fixture_server(directory: pathlib.Path) -> tuple[http.server.ThreadingHTTPServer, threading.Thread]:
def _start_fixture_server(
directory: pathlib.Path,
) -> tuple[http.server.ThreadingHTTPServer, threading.Thread]:
"""Start one loopback-only static fixture server for a bounded browser lane."""

server = http.server.ThreadingHTTPServer(
Expand Down Expand Up @@ -759,6 +802,8 @@ def main() -> int:
trial.get("post_condition") is True
and trial.get("input_echo_verified") is True
and trial.get("url_unchanged") is True
and trial.get("input_semantics_verified") is True
and trial.get("submit_semantics_verified") is True
and trial.get("extensions_disabled") is True
and trial.get("profile_cleaned") is True
for trial in agent_task_trials
Expand Down
23 changes: 23 additions & 0 deletions tests/test_agent_task_pinned_chrome_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ def test_agent_task_submission_preserves_the_loaded_url(self) -> None:
self.assertIn(expected, runner)
self.assertIn("Agent Task URL changed during submission", runner)

def test_agent_task_observes_computed_role_and_name_before_action(self) -> None:
"""Real-browser evidence must bind the controlled targets to semantic role/name."""

namespace = runpy.run_path(str(RUNNER), run_name="agent_task_semantics_contract")
runner = RUNNER.read_text(encoding="utf-8")
self.assertIn("_get_element_semantics", namespace)
for expected in (
'"/computedrole"',
'"/computedlabel"',
'"textbox"',
'"Task text"',
'"button"',
'"Submit task"',
'"input_semantics_verified"',
'"submit_semantics_verified"',
):
with self.subTest(expected=expected):
self.assertIn(expected, runner)

def test_agent_task_fixture_runs_under_the_existing_pinned_chrome_job(self) -> None:
"""No floating browser or second workflow may be introduced for this slice."""

Expand All @@ -123,6 +142,10 @@ def test_documentation_separates_active_browser_evidence_from_product_runtime(se
self.assertIn("not a product browser adapter", traceability)
self.assertIn("pinned Chrome", fitness)
self.assertIn("not a browser adapter", fitness)
self.assertIn("browser-computed role/name", changelog)
self.assertIn("PR #71", traceability)
self.assertIn("computed role/name", traceability)
self.assertIn("computed role/name", fitness)
Comment thread
seonghobae marked this conversation as resolved.


if __name__ == "__main__":
Expand Down
Loading