From 6346164b9ec272e3b2bf0333a7c780498697edd3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 12 Aug 2026 15:37:05 +0900 Subject: [PATCH 1/4] test(core): require runtime browser protocol kind binding --- .../tests/browser_protocol_use_validation.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/originweave-core/tests/browser_protocol_use_validation.rs b/crates/originweave-core/tests/browser_protocol_use_validation.rs index cf7c8ad0b..1bba239de 100644 --- a/crates/originweave-core/tests/browser_protocol_use_validation.rs +++ b/crates/originweave-core/tests/browser_protocol_use_validation.rs @@ -150,3 +150,24 @@ fn validation_errors_preserve_stable_typed_sources() { ); } } + +#[test] +fn runtime_protocol_kind_mismatch_precedes_revision_and_capability_checks() +-> Result<(), Box> { + let descriptor = descriptor()?; + + assert_eq!( + descriptor.validate_use( + ORIGINWEAVE_PROTOCOL_VERSION, + BrowserProtocolKind::ChromeDevToolsProtocol, + "runtime revision with spaces", + "browser/revision", + BrowserProtocolCapability::NetworkObservation, + ), + Err(BrowserProtocolUseValidationError::ProtocolKindMismatch { + descriptor_kind: BrowserProtocolKind::WebDriverBiDi, + runtime_kind: BrowserProtocolKind::ChromeDevToolsProtocol, + }) + ); + Ok(()) +} From de107ca6fa0de44d911fbfb52f7dc8f9a9fb8bca Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 12 Aug 2026 15:41:47 +0900 Subject: [PATCH 2/4] test(core): bind all validated uses to runtime protocol kind --- .../tests/browser_protocol_use_validation.rs | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/crates/originweave-core/tests/browser_protocol_use_validation.rs b/crates/originweave-core/tests/browser_protocol_use_validation.rs index 1bba239de..8994253ec 100644 --- a/crates/originweave-core/tests/browser_protocol_use_validation.rs +++ b/crates/originweave-core/tests/browser_protocol_use_validation.rs @@ -32,6 +32,7 @@ fn validated_use_binds_all_required_adapter_metadata() -> Result<(), Box Result<(), Box> { + let descriptor = descriptor()?; + + let error = descriptor.validate_use( + ORIGINWEAVE_PROTOCOL_VERSION, + BrowserProtocolKind::ChromeDevToolsProtocol, + "runtime revision with spaces", + "browser/revision", + BrowserProtocolCapability::NetworkObservation, + ); + + assert_eq!( + error, + Err(BrowserProtocolUseValidationError::ProtocolKindMismatch { + descriptor_kind: BrowserProtocolKind::WebDriverBiDi, + runtime_kind: BrowserProtocolKind::ChromeDevToolsProtocol, + }) + ); + let error = error.err().ok_or("expected protocol kind mismatch")?; + assert_eq!( + error.to_string(), + "runtime browser protocol kind does not match the pinned adapter kind" + ); + assert!(error.source().is_none()); + Ok(()) +} + #[test] fn runtime_revision_validation_precedes_capability_check() -> Result<(), Box> { let descriptor = descriptor()?; @@ -82,6 +113,7 @@ fn runtime_revision_validation_precedes_capability_check() -> Result<(), Box Result<(), Box Result<(), Box> { - let descriptor = descriptor()?; - - assert_eq!( - descriptor.validate_use( - ORIGINWEAVE_PROTOCOL_VERSION, - BrowserProtocolKind::ChromeDevToolsProtocol, - "runtime revision with spaces", - "browser/revision", - BrowserProtocolCapability::NetworkObservation, - ), - Err(BrowserProtocolUseValidationError::ProtocolKindMismatch { - descriptor_kind: BrowserProtocolKind::WebDriverBiDi, - runtime_kind: BrowserProtocolKind::ChromeDevToolsProtocol, - }) - ); - Ok(()) -} From 3294f2779e9e27f6bf17834841b9e64c178619aa Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 12 Aug 2026 15:43:00 +0900 Subject: [PATCH 3/4] feat(core): bind validated use to runtime protocol kind --- .../originweave-core/src/browser_protocol.rs | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/originweave-core/src/browser_protocol.rs b/crates/originweave-core/src/browser_protocol.rs index 369666ece..d4650ac30 100644 --- a/crates/originweave-core/src/browser_protocol.rs +++ b/crates/originweave-core/src/browser_protocol.rs @@ -293,21 +293,29 @@ impl BrowserProtocolAdapterDescriptor { /// Validate all adapter metadata prerequisites for one immediate browser operation. /// /// Validation is intentionally ordered and fail closed: the exact - /// OriginWeave Protocol generation is checked first, then the supplied - /// runtime protocol/browser revisions, then the required adapter - /// capability. Success returns a non-cloneable value that a later trusted - /// transport can consume as proof that these metadata prerequisites were - /// checked together. It is not browser or Agent authority and does not - /// authenticate the caller supplying runtime revision evidence. + /// OriginWeave Protocol generation is checked first, then the caller-supplied + /// runtime protocol family, then the supplied runtime protocol/browser + /// revisions, and finally the required adapter capability. Success returns + /// a non-cloneable value that a later trusted transport can consume as proof + /// that these metadata prerequisites were checked together. It is not + /// browser or Agent authority and does not authenticate or attest the caller + /// supplying runtime metadata. pub fn validate_use( &self, required_originweave_protocol_version: OriginWeaveProtocolVersion, + runtime_kind: BrowserProtocolKind, runtime_protocol_revision: &str, runtime_browser_revision: &str, required_capability: BrowserProtocolCapability, ) -> Result { self.require_originweave_protocol_version(required_originweave_protocol_version) .map_err(BrowserProtocolUseValidationError::ProtocolVersion)?; + if self.kind != runtime_kind { + return Err(BrowserProtocolUseValidationError::ProtocolKindMismatch { + descriptor_kind: self.kind, + runtime_kind, + }); + } self.require_runtime_revisions(runtime_protocol_revision, runtime_browser_revision) .map_err(BrowserProtocolUseValidationError::RuntimeRevision)?; self.require_capability(required_capability) @@ -484,6 +492,13 @@ impl std::error::Error for BrowserProtocolCapabilityRequirementError {} pub enum BrowserProtocolUseValidationError { /// The descriptor targets the wrong OriginWeave Protocol generation. ProtocolVersion(BrowserProtocolVersionRequirementError), + /// The runtime transport reports a different protocol family than the descriptor. + ProtocolKindMismatch { + /// Browser protocol family pinned by the adapter descriptor. + descriptor_kind: BrowserProtocolKind, + /// Browser protocol family reported by the runtime transport. + runtime_kind: BrowserProtocolKind, + }, /// The supplied runtime protocol or browser revision is invalid or has drifted. RuntimeRevision(BrowserProtocolRuntimeRequirementError), /// The descriptor does not explicitly declare the required capability. @@ -494,6 +509,8 @@ impl fmt::Display for BrowserProtocolUseValidationError { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::ProtocolVersion(error) => error.fmt(formatter), + Self::ProtocolKindMismatch { .. } => formatter + .write_str("runtime browser protocol kind does not match the pinned adapter kind"), Self::RuntimeRevision(error) => error.fmt(formatter), Self::Capability(error) => error.fmt(formatter), } @@ -504,6 +521,7 @@ impl std::error::Error for BrowserProtocolUseValidationError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::ProtocolVersion(error) => Some(error), + Self::ProtocolKindMismatch { .. } => None, Self::RuntimeRevision(error) => Some(error), Self::Capability(error) => Some(error), } From 9aed5ae21aca022f58253566c87e67be648675bd Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 12 Aug 2026 15:46:08 +0900 Subject: [PATCH 4/4] docs(changelog): record browser protocol use validation --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d197d67e..2241b0dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to OriginWeave are documented in this file. The format follo - Rust workspace for independently reusable core, policy, destination, network, TLS, resource, and evidence modules. - Versioned browser-protocol adapter metadata that distinguishes WebDriver BiDi from pinned CDP, binds bounded adapter/browser revision tokens to an explicit duplicate-free capability set, normalizes capability-set identity independently of caller ordering, and exposes typed fail-closed capability requirements without granting browser, action, network, or secret authority by protocol kind alone. - Canonical OriginWeave protocol-version parsing for exact `originweave/.` syntax, with typed fail-closed rejection of malformed, ambiguous, overflowed, or noncanonical serialized generations; parsing does not negotiate compatibility or grant adapter authority. +- Atomic browser-protocol use validation that requires the exact OriginWeave protocol generation, caller-supplied runtime protocol family, exact pinned runtime protocol/browser revisions, and an explicitly declared capability in deterministic fail-closed order before producing non-cloneable validation evidence; this metadata proof does not authenticate the adapter or grant browser/Agent authority. - Canonical HTTPS and loopback-origin boundary with case-normalized schemes and hosts, default-port normalization, IPv4/IPv6 handling, browser-special numeric-host rejection, and explicit malformed-input errors. - Typed browser actions, capabilities, risk classes, execution modes, robots decisions, secret-delivery contracts, immutable canonical action-intent digests, and intent-bound approval scopes. - Deterministic fail-closed policy evaluation for untrusted instructions, origin grants, crawler restrictions, execution-mode and purpose consistency, approvals, and brokered secrets.