diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e4bd39c..569bb0cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to OriginWeave are documented in this file. The format follo ### Added +- Explicit reduced-assurance classification for attached human tabs when trusted adapter evidence says an existing extension can influence page state; the narrow rule does not detect extensions, prove extension absence, grant Agent authority, or turn an unclassified context into high-assurance evidence. - Rust workspace for independently reusable core, policy, destination, network, TLS, resource, and evidence modules. - 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. diff --git a/crates/originweave-core/src/lib.rs b/crates/originweave-core/src/lib.rs index 75303407..de817f13 100644 --- a/crates/originweave-core/src/lib.rs +++ b/crates/originweave-core/src/lib.rs @@ -1181,3 +1181,53 @@ pub fn evaluate_native_messaging_access( } NativeMessagingAccessDecision::Allow } + +/// Browser control surface represented by assurance evidence. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BrowserAttachmentKind { + /// OriginWeave is attached to an existing person-controlled browser tab. + AttachedHumanTab, + /// OriginWeave operates in a task-isolated browser profile. + IsolatedProfile, +} + +/// Trusted adapter evidence about extension influence on page state. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExtensionInfluenceEvidence { + /// The trusted adapter established that an extension can influence page state. + CanInfluencePageState, + /// This bounded rule has no trusted evidence of extension influence. + /// Absence of known influence is not proof that extensions are absent or unable to interfere. + NoKnownExtensionInfluence, +} + +/// A specific reason that one browser context has reduced assurance. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ReducedAssuranceReason { + /// An attached human tab can be influenced by an existing browser extension. + AttachedTabExtensionInfluence, +} + +/// Classify the narrow attached-tab extension-influence assurance reduction. +/// +/// `None` means only that this rule did not identify this specific reduction. It +/// is not evidence of full trust, extension absence, or high assurance. A future +/// trusted Chromium adapter must supply the attachment and influence evidence and +/// evaluate any other applicable assurance rules separately. +#[must_use] +pub const fn classify_reduced_assurance( + attachment: BrowserAttachmentKind, + extension_influence: ExtensionInfluenceEvidence, +) -> Option { + if matches!( + (attachment, extension_influence), + ( + BrowserAttachmentKind::AttachedHumanTab, + ExtensionInfluenceEvidence::CanInfluencePageState + ) + ) { + Some(ReducedAssuranceReason::AttachedTabExtensionInfluence) + } else { + None + } +} diff --git a/crates/originweave-core/tests/attached_tab_assurance.rs b/crates/originweave-core/tests/attached_tab_assurance.rs new file mode 100644 index 00000000..a9bb52cc --- /dev/null +++ b/crates/originweave-core/tests/attached_tab_assurance.rs @@ -0,0 +1,37 @@ +use originweave_core::{ + BrowserAttachmentKind, ExtensionInfluenceEvidence, ReducedAssuranceReason, + classify_reduced_assurance, +}; + +#[test] +fn attached_human_tab_with_extension_influence_is_explicitly_reduced_assurance() { + assert_eq!( + classify_reduced_assurance( + BrowserAttachmentKind::AttachedHumanTab, + ExtensionInfluenceEvidence::CanInfluencePageState, + ), + Some(ReducedAssuranceReason::AttachedTabExtensionInfluence) + ); +} + +#[test] +fn attached_human_tab_without_known_extension_influence_has_no_extension_reduction() { + assert_eq!( + classify_reduced_assurance( + BrowserAttachmentKind::AttachedHumanTab, + ExtensionInfluenceEvidence::NoKnownExtensionInfluence, + ), + None + ); +} + +#[test] +fn isolated_profile_is_not_relabelled_by_attached_tab_rule() { + assert_eq!( + classify_reduced_assurance( + BrowserAttachmentKind::IsolatedProfile, + ExtensionInfluenceEvidence::CanInfluencePageState, + ), + None + ); +}