diff --git a/crates/originweave-core/src/attached_tab_assurance.rs b/crates/originweave-core/src/attached_tab_assurance.rs new file mode 100644 index 000000000..4d2cd5954 --- /dev/null +++ b/crates/originweave-core/src/attached_tab_assurance.rs @@ -0,0 +1,50 @@ +/// 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 specific rule found no such reduction; it is not +/// proof of full trust, extension absence, inability to interfere, or high +/// assurance. +#[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/src/root.rs b/crates/originweave-core/src/root.rs index c47a136d4..12f4c1828 100644 --- a/crates/originweave-core/src/root.rs +++ b/crates/originweave-core/src/root.rs @@ -11,6 +11,9 @@ mod contracts; pub use contracts::*; +mod attached_tab_assurance; +pub use attached_tab_assurance::*; + /// Stateless MCP routing validation that maps only explicit tools to typed actions. pub mod mcp; /// Deterministic fail-closed release benchmark acceptance aggregation. 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 000000000..a9bb52cc6 --- /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 + ); +}