Skip to content
Merged
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
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ The organization currently documents a **solo-maintainer** governance condition.
- Keep Blink, V8, Skia, Viz, Dawn, Chromium sandboxing, Site Isolation, and Manifest V3 compatibility upstream-aligned.
- Map browser presentation capabilities only when the protocol proves the complete canonical surface: width and height do not prove screen color depth, and one locale does not prove ordered languages.
- Keep browser command planning distinct from execution evidence: a typed command intent bound to a validated context has not been sent, acknowledged, or observed by a page.
- A reusable presentation planner must accept only the explicitly restorable fields, never a complete `PresentationProfile` whose omitted surfaces could be mistaken for applied.
- When a protocol capability remains discoverable but its unsafe reusable command is removed, update every source-contract assertion to require capability presence and command absence together.
- Marking a draft Ready can enqueue a new exact-head run; do not merge from an earlier green result until that new run is terminal and re-fetched.
- Do not assume browser/session teardown removed presentation overrides; model explicit cleanup for every override a presentation plan emits and require post-cleanup observation before reusing a browser boundary.
- Pin protocol provenance to the immutable dated W3C TR URI; a mutable latest page or lagging index must not silently redefine the capability contract.
- New product logic belongs in Rust control-plane modules behind narrow adapters.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to OriginWeave are documented in this file. The format follo

## [Unreleased]

- Made the reusable WebDriver BiDi presentation planner accept only viewport, DPR, and timezone inputs. It no longer accepts a complete presentation profile while leaving unsupported or lifecycle-unrestorable surfaces unapplied.
- Refreshed the product-gap queue to 126 open pull requests (54 ready, 72 draft) after #190, #188, #185, #192, #182, #184, #115, #181, #116, #117, #118, #183, #114, #127, #112, #109, #186, #110, #108, #111, #174, and #113 were merged into their immediate stacked prerequisites. PRs #147, #146, #145, #144, #143, #142, #141, #139, #136, #132, #129, and #128 moved to ready after exact-head checks and thread review; these are queue-consolidation results, not protected-main shipment.

### Fixed
Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ Additional constraints:
- Do not merge logical origin, destination authorization, direct TCP peer proof, TLS service identity, proxy routing, or HTTP resource policy into one ambient authority.
- Do not add hostname reconnect, proxy-environment inheritance, dangerous certificate-verifier hooks, Common Name fallback, TLS 0-RTT, key logging, or secret extraction to a production TLS path.
- Keep changes bounded to one product gap and preserve modular crate boundaries.
- For partial browser-emulation plans, require only the named restorable fields; do not accept a complete profile unless every requested surface has an explicit application witness.
- A discoverable protocol capability does not justify exposing an unsafe reusable command; contract tests must assert both facts.
- A Ready transition can replace an earlier green with a queued exact-head run; wait for its terminal result before merge.
- Never claim a test, benchmark, browser integration, TLS identity, GPU execution, release, or merge succeeded without current exact-head evidence.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

OriginWeave is a Chromium-compatible, Rust-first control plane for governed AI agents on the web. It is designed to let an agent observe, extract, and act without turning untrusted page content into authority, exposing secrets to a model, connecting to an unapproved network destination, accepting an unauthenticated web service, or losing the evidence required to explain what happened.

> Project status: pre-alpha. The current protected repository contains independently reusable safety, resolved-destination, direct TCP peer-binding, authenticated TLS service-identity, and bounded MCP `2026-07-28` stateless `tools/call` routing/policy foundations. Chromium, WebDriver BiDi, CDP, complete MCP, HTTP, proxy, WARC, and persistent provenance adapters are planned but not yet shipped. Active PR #170 implements only conservative `tools/list` discovery metadata on top of the protected-main MCP catalog; it remains non-shipped active-PR evidence and does not make the complete MCP adapter available.
> Project status: pre-alpha. The current protected repository contains independently reusable safety, resolved-destination, direct TCP peer-binding, authenticated TLS service-identity, and bounded MCP `2026-07-28` stateless `tools/call` routing/policy foundations. Live Chromium control, CDP, complete MCP, HTTP, proxy, WARC, and persistent provenance adapters are planned but not yet shipped. This active branch adds an `originweave-bidi` capability and command-planning boundary for a pinned standard revision; live WebDriver BiDi transport remains planned, and open-PR code is not protected-main shipment. Active PR #170 implements only conservative `tools/list` discovery metadata on top of the protected-main MCP catalog; it remains non-shipped active-PR evidence and does not make the complete MCP adapter available.

## Why OriginWeave

Expand Down Expand Up @@ -37,6 +37,7 @@ The repository is organized as independently consumable Rust crates:
- `originweave-destination`: address classification, explicit destination policy, origin-bound DNS snapshots, connection pinning, rebinding detection, and redirect reauthorization.
- `originweave-network`: direct-only, single-use TCP connection plans that bind an approved canonical address to the exact operating-system peer and emit credential-free evidence.
- `originweave-tls`: single-use WebPKI handshakes over an existing verified TCP stream, with RFC 9525 DNS/IP identity, explicit roots and time, TLS 1.2/1.3, bounded ALPN and certificate evidence, and no reconnect or verifier bypass.
- `originweave-bidi`: active-branch, version-pinned capability and command-planning boundary for validated reusable viewport/DPR and timezone intents. It performs no live protocol transport and does not turn command construction into acknowledgement or page-observed evidence.
- `originweave-resource`: task-level RAM, VRAM, thread, and frame-time budgets with cumulative mitigation plans.
- `originweave-evidence`: universally value-redacted network evidence and source-bound provenance records.

Expand Down Expand Up @@ -111,4 +112,4 @@ Read [AGENTS.md](AGENTS.md), [CONTRIBUTING.md](CONTRIBUTING.md), and [SECURITY.m

## License

Apache License 2.0. See [LICENSE](LICENSE).
Apache License 2.0. See [LICENSE](LICENSE).
87 changes: 39 additions & 48 deletions crates/originweave-bidi/src/presentation_capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::{error::Error, fmt};

use originweave_fingerprint::{
PresentationError, PresentationProfile, PresentationSurface, require_presentation_surfaces,
DevicePixelRatio, PresentationError, PresentationSurface, PresentationTimeZone, ViewportBounds,
require_presentation_surfaces,
};

const MAX_BROWSING_CONTEXT_BYTES: usize = 256;
Expand Down Expand Up @@ -48,35 +49,27 @@ impl WebDriverBidiBrowsingContext {
///
/// These values are inputs to a later transport owner. Constructing them does not send a command,
/// prove an acknowledgement, establish Browser Session ownership, or establish page-observed state.
#[derive(Debug, Clone, PartialEq)]
/// Presentation payloads retain the validated fingerprint value objects so a transport adapter cannot
/// bypass their bounds by constructing raw viewport, DPR, or time-zone values. This reusable-boundary
/// enum deliberately exposes no media-feature mutation command because this crate has no ownership or
/// snapshot witness that would make such mutation reversibly safe.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WebDriverBidiPresentationCommand {
/// Set viewport dimensions and device-pixel ratio together.
SetViewport {
/// Exact target browsing context.
context: WebDriverBidiBrowsingContext,
/// CSS-pixel viewport width.
width: u32,
/// CSS-pixel viewport height.
height: u32,
/// Positive device-pixel ratio.
device_pixel_ratio: f64,
/// Validated viewport bounds from the presentation-identity kernel.
viewport: ViewportBounds,
/// Validated quantized device-pixel ratio from the presentation-identity kernel.
device_pixel_ratio: DevicePixelRatio,
},
/// Set the named time zone.
SetTimezone {
/// Exact target browsing context.
context: WebDriverBidiBrowsingContext,
/// IANA time-zone identifier.
timezone: String,
},
/// Set the reduced-motion media feature.
///
/// The pinned standard can express this command, but it is intentionally excluded from the
/// reusable default plan because standard media cleanup cannot selectively restore prior state.
SetReducedMotion {
/// Exact target browsing context.
context: WebDriverBidiBrowsingContext,
/// Whether `prefers-reduced-motion` is `reduce`.
reduce: bool,
/// Validated presentation time-zone identity.
timezone: PresentationTimeZone,
},
/// Restore the implementation-defined viewport and remove the device-pixel-ratio override.
ResetViewport {
Expand All @@ -93,26 +86,29 @@ pub enum WebDriverBidiPresentationCommand {
/// Plan the reversible standard-BiDi presentation commands safe for a reusable browsing context.
///
/// Viewport/device-pixel-ratio and time-zone state each have a non-destructive nullable reset in the
/// pinned Working Draft. Reduced motion remains an expressible protocol capability, but the default
/// reusable plan does not install it because `features: null` clears the complete media-feature
/// configuration rather than restoring only OriginWeave's prior `prefers-reduced-motion` value.
/// A Browser Session owner must first bind media mutation to a genuinely disposable lifecycle or a
/// complete snapshot/restore path before constructing and sending `SetReducedMotion`.
/// pinned Working Draft. Reduced motion remains an expressible protocol capability, but this reusable
/// planning boundary neither installs nor exposes a media-mutation command because `features: null`
/// clears the complete media-feature configuration rather than restoring only OriginWeave's prior
/// `prefers-reduced-motion` value. The explicit arguments make this a partial-plan API: it cannot be
/// mistaken for application of a complete [`originweave_fingerprint::PresentationProfile`]. A later
/// Browser Session-owned adapter may introduce reduced-motion application only after it can prove a
/// genuinely disposable lifecycle or a complete snapshot/restore path.
#[must_use]
pub fn plan_standard_presentation_commands(
context: &WebDriverBidiBrowsingContext,
profile: &PresentationProfile,
viewport: &ViewportBounds,
device_pixel_ratio: DevicePixelRatio,
timezone: PresentationTimeZone,
) -> [WebDriverBidiPresentationCommand; 2] {
[
WebDriverBidiPresentationCommand::SetViewport {
context: context.clone(),
width: profile.viewport().width(),
height: profile.viewport().height(),
device_pixel_ratio: profile.device_pixel_ratio().value(),
viewport: *viewport,
device_pixel_ratio,
},
WebDriverBidiPresentationCommand::SetTimezone {
context: context.clone(),
timezone: profile.timezone().iana_name().to_owned(),
timezone,
},
]
}
Expand Down Expand Up @@ -161,8 +157,9 @@ const WEBDRIVER_BIDI_PRESENTATION_SURFACES: [PresentationSurface; 4] = [
///
/// Complete screen and ordered-language surfaces, hardware concurrency, and the
/// Chromium platform/User-Agent Client Hints surface are intentionally absent.
/// Reduced motion is listed as protocol capability even though reusable default application leaves
/// media state untouched until a Browser Session owner supplies a restorable lifecycle.
/// Reduced motion is listed as protocol capability even though reusable application leaves media
/// state untouched until a Browser Session owner supplies a restorable lifecycle and corresponding
/// command authority.
#[must_use]
pub const fn webdriver_bidi_presentation_surfaces() -> &'static [PresentationSurface] {
&WEBDRIVER_BIDI_PRESENTATION_SURFACES
Expand Down Expand Up @@ -246,30 +243,24 @@ mod tests {
assert_eq!(context.as_str(), "context-17");

assert_eq!(
plan_standard_presentation_commands(&context, &profile),
plan_standard_presentation_commands(
&context,
profile.viewport(),
profile.device_pixel_ratio(),
profile.timezone(),
),
[
WebDriverBidiPresentationCommand::SetViewport {
context: context.clone(),
width: 1440,
height: 900,
device_pixel_ratio: 2.0,
viewport: *profile.viewport(),
device_pixel_ratio: profile.device_pixel_ratio(),
},
WebDriverBidiPresentationCommand::SetTimezone {
context: context.clone(),
timezone: "UTC".to_owned(),
context,
timezone: profile.timezone(),
},
]
);
assert_eq!(
WebDriverBidiPresentationCommand::SetReducedMotion {
context: context.clone(),
reduce: profile.reduced_motion(),
},
WebDriverBidiPresentationCommand::SetReducedMotion {
context,
reduce: true,
}
);
}

#[test]
Expand Down
9 changes: 8 additions & 1 deletion docs/product-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,17 @@ Delivered document-node authority foundation:
- deterministic rejection of cross-session, cross-context, cross-origin, or stale-document node reuse before a future browser adapter performs an action;
- reusable core contracts without Chromium, WebDriver, selector, script-execution, network, storage, or secret dependencies.

Active-branch WebDriver BiDi foundation:

- a version-pinned capability and command-planning boundary in `originweave-bidi` for the 3 September 2026 W3C Working Draft;
- fail-closed distinction between the complete canonical presentation profile and the standard surfaces BiDi can express;
- reusable viewport/DPR and timezone intents built only from validated presentation value objects;
- no live protocol transport, acknowledgement, page-observed application, Browser Session ownership, or cleanup proof is claimed by the planning boundary.

Remaining vertical-slice work:

- launch and terminate ephemeral Chromium user contexts;
- WebDriver BiDi adapter behind a versioned interface;
- live WebDriver BiDi transport that consumes the version-pinned capability and command-planning boundary, including serialization, request/response correlation, page-observed post-conditions, and cleanup observation;
- session-scoped translation from external protocol identifiers to collision-free internal browser-session, browsing-context, document-epoch, and node identities;
- navigation and accessibility-tree observation;
- typed `navigate`, `observe`, `query`, and `click` actions;
Expand Down
6 changes: 6 additions & 0 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This is a dated delivery baseline, not a substitute for the PRD, TRD, roadmap, architecture decisions, or live GitHub state. It keeps buyer-visible gaps, current issues, active pull-request evidence, and commercial completion tracks in one discoverable place. Protected `main` is the implementation boundary: code in an open pull request is not shipped behavior.

## Live continuity note: 2026-09-09

- Protected `main` was re-fetched at `87c4daa1830bac5a5228b6036752ad5633232085`. Issue #292 remains open; its buyer-visible acceptance is still pinned Chromium application followed by page-observed and post-cleanup evidence.
- Draft #293 (`476a8e09aa1aa7ab2e87cf7452a8ecfca47bf9c1`) is only the versioned standard-BiDi capability boundary. Its reusable command API previously accepted a complete profile despite planning only viewport/DPR and timezone. The active successor makes that partiality explicit at the type boundary; it is not Chromium runtime evidence or protected-main behavior.
- The next executable owner path remains the existing pinned-Chrome Agent Task lane, not a second browser runner: apply admitted overrides before navigation, read the controlled fixture's declared observations through bounded DOM endpoints, then prove explicit reset or owned-boundary destruction. Command acknowledgement and session teardown alone remain non-passing.

## Observed snapshot: 2026-08-26

### Protected-main truth
Expand Down
14 changes: 14 additions & 0 deletions tests/test_bidi_media_authority_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from pathlib import Path


SOURCE = Path("crates/originweave-bidi/src/presentation_capabilities.rs")


def test_reduced_motion_capability_does_not_mint_unowned_command() -> None:
source = SOURCE.read_text(encoding="utf-8")
command_enum = source.split("pub enum WebDriverBidiPresentationCommand {", 1)[1].split(
"/// Plan the reversible standard-BiDi presentation commands", 1
)[0]

assert "PresentationSurface::ReducedMotion" in source
assert "SetReducedMotion" not in command_enum
Loading
Loading