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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ All notable changes to OriginWeave are documented in this file. The format follo

### Added

- Added fail-closed presentation-surface admission so an adapter cannot claim a
privacy profile while any required page-observable field remains ambient.

- Added a proposed privacy-preserving presentation-identity kernel with bounded screen, viewport, pixel ratio, processor, platform, language, reduced-motion, standardized named-UTC time-zone, and credential-free digest contracts; real Chromium application and anti-evasion claims remain explicitly unshipped.

- Refreshed the product and technical gap baseline with the 2026-08-24 live inventory: 158 open pull requests (44 ready, 114 draft), refreshed exact base/head evidence for the #208–#222 release, enterprise-approval, BAP, and WARC/PROV chains, the governance issue additions #212 and #215, and a required-check provider-failure record for the fail-closed Strix re-dispatches on #208/#218/#220.
Expand Down
78 changes: 71 additions & 7 deletions crates/originweave-fingerprint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,30 @@ pub enum PresentationError {
InvalidField,
/// Cross-field consistency failed (for example viewport exceeds screen).
InconsistentIdentity,
/// An adapter cannot override one required observable surface.
MissingSurface(PresentationSurface),
}

impl fmt::Display for PresentationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let message = match self {
Self::DegenerateSeed => "presentation seed must not be all zero",
Self::InvalidDigest => "digest must be sha256: plus 64 lowercase hex digits",
Self::InvalidField => "presentation field violates its bounded contract",
Self::InconsistentIdentity => "presentation fields contradict each other",
};
formatter.write_str(message)
match self {
Self::DegenerateSeed => formatter.write_str("presentation seed must not be all zero"),
Self::InvalidDigest => {
formatter.write_str("digest must be sha256: plus 64 lowercase hex digits")
}
Self::InvalidField => {
formatter.write_str("presentation field violates its bounded contract")
}
Self::InconsistentIdentity => {
formatter.write_str("presentation fields contradict each other")
}
Self::MissingSurface(surface) => {
write!(
formatter,
"adapter cannot override required {surface:?} surface"
)
}
}
}
}

Expand All @@ -55,6 +68,53 @@ impl Error for PresentationError {}
/// Domain-separation tag for derivation stream expansion.
const DERIVE_DOMAIN: &[u8] = b"originweave-presentation/v1";

/// A page-observable field that an adapter must override before admission.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PresentationSurface {
/// Screen dimensions and color depth.
Screen,
/// Viewport dimensions.
Viewport,
/// Device pixel ratio.
DevicePixelRatio,
/// Logical processor count.
HardwareConcurrency,
/// Named time-zone identity and offset behavior.
TimeZone,
/// Browser platform family.
Platform,
/// Ordered language preferences.
Languages,
/// Reduced-motion preference.
ReducedMotion,
}

const REQUIRED_PRESENTATION_SURFACES: [PresentationSurface; 8] = [
PresentationSurface::Screen,
PresentationSurface::Viewport,
PresentationSurface::DevicePixelRatio,
PresentationSurface::HardwareConcurrency,
PresentationSurface::TimeZone,
PresentationSurface::Platform,
PresentationSurface::Languages,
PresentationSurface::ReducedMotion,
];

/// Require an adapter to override every surface claimed by the profile.
///
/// The first missing surface is returned in stable contract order. Additional
/// or duplicate supported entries do not change admission.
pub fn require_presentation_surfaces(
supported: &[PresentationSurface],
) -> Result<(), PresentationError> {
for required in REQUIRED_PRESENTATION_SURFACES {
if !supported.contains(&required) {
return Err(PresentationError::MissingSurface(required));
}
}
Ok(())
}

/// Screen geometry with color depth as pages observe it.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScreenMetrics {
Expand Down Expand Up @@ -673,6 +733,10 @@ mod tests {
PresentationError::InconsistentIdentity.to_string(),
"presentation fields contradict each other"
);
assert_eq!(
PresentationError::MissingSurface(PresentationSurface::HardwareConcurrency).to_string(),
"adapter cannot override required HardwareConcurrency surface"
);
}

#[test]
Expand Down
38 changes: 38 additions & 0 deletions crates/originweave-fingerprint/tests/surface_admission.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use originweave_fingerprint::{
PresentationError, PresentationSurface, require_presentation_surfaces,
};

const COMPLETE_SURFACES: [PresentationSurface; 8] = [
PresentationSurface::Screen,
PresentationSurface::Viewport,
PresentationSurface::DevicePixelRatio,
PresentationSurface::HardwareConcurrency,
PresentationSurface::TimeZone,
PresentationSurface::Platform,
PresentationSurface::Languages,
PresentationSurface::ReducedMotion,
];

#[test]
fn incomplete_adapter_support_fails_on_the_first_missing_surface() {
let supported = COMPLETE_SURFACES
.into_iter()
.filter(|surface| *surface != PresentationSurface::HardwareConcurrency)
.collect::<Vec<_>>();

assert_eq!(
require_presentation_surfaces(&supported),
Err(PresentationError::MissingSurface(
PresentationSurface::HardwareConcurrency
))
);
}

#[test]
fn complete_adapter_support_is_order_and_duplicate_independent() {
let mut supported = COMPLETE_SURFACES.to_vec();
supported.reverse();
supported.push(PresentationSurface::Screen);

assert_eq!(require_presentation_surfaces(&supported), Ok(()));
}
6 changes: 6 additions & 0 deletions docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ surface before page script, preserve the actual engine/platform family, and
prove no ambient host fallback. This privacy boundary grants no CAPTCHA,
bot-management, or access-control bypass authority.

**Implemented kernel contract; adapter planned.** The kernel admits an adapter
only when it declares every required observable surface and returns the first
missing surface deterministically. Admission is a capability gate, not proof
that BiDi/CDP applied the values; pinned pre-navigation Chromium evidence
remains release-critical.

## 7. Observation architecture

Observation order is an **Accepted architecture** requirement:
Expand Down
13 changes: 10 additions & 3 deletions docs/adr/0110-privacy-preserving-presentation-identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ remain explicitly ambient and unreleased. The seed, if used for lifecycle
selection, is trusted control-plane material and never enters page, model, log,
or evidence context.

Before launch, an adapter must pass the kernel's deterministic surface
admission check. Missing screen, viewport, pixel ratio, hardware concurrency,
time zone, platform, language, or reduced-motion support returns the first
missing surface and blocks the claimed profile. Ordering, duplicates, and
unsupported protocol claims cannot relax this boundary.

OriginWeave does not use presentation identity to solve CAPTCHA, impersonate a
target person or device, rotate residential routes, defeat bot-management, or
circumvent access controls. Such a challenge is recorded as blocked/degraded.
Expand Down Expand Up @@ -81,9 +87,10 @@ extension, secret, or action authority.

Unit and integration tests cover deterministic derivation, independent seed
results, enumerated construction, cross-field consistency, standardized UTC
identity, canonical digest validation, and malformed input rejection. Browser
acceptance remains blocked on pinned real-Chromium pre-script injection and
host-fallback evidence.
identity, canonical digest validation, malformed input rejection, complete
surface admission, and exact missing-surface evidence. Browser acceptance
remains blocked on pinned real-Chromium pre-script injection and host-fallback
evidence.

## Migration and rollback

Expand Down
13 changes: 13 additions & 0 deletions docs/doctoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ before page script and prove that no ambient host value leaks. Camoufox is
reviewed only as implementation precedent for native-layer consistency, not as
policy authority for anti-detect, CAPTCHA, or access-control circumvention.

The 25 August 2026 WebDriver BiDi Editor's Draft exposes locale, media, screen,
user-agent, viewport, and time-zone emulation commands, but it does not define a
hardware-concurrency override. Chromium's tip-of-tree DevTools Protocol exposes
`Emulation.setHardwareConcurrencyOverride` as Experimental and warns that
tip-of-tree commands can change without notice. OriginWeave therefore records
required presentation surfaces in a protocol-neutral Rust admission contract;
a later pinned Chromium adapter must capability-negotiate every surface and
fail closed before claiming a complete profile.

### Extension-to-Agent grant origin binding

RFC 6454 defines a web origin as the scheme, host, and port tuple that browsers use to isolate authority. An OriginWeave `extension_grant` that is bound only to extension identity, session, and browsing context would remain valid after the same context navigates to another origin. OriginWeave therefore requires the grant and the request to carry the same canonical origin. A host change or a non-default port change is a different origin and cannot reuse the grant. This is grant-scope isolation only; it does not install an extension, parse Chrome messages, or mint Agent capabilities from Manifest V3 permissions.
Expand Down Expand Up @@ -135,6 +144,8 @@ Bonica, R., Cotton, M., Haberman, B., & Vegoda, L. (2017). *Updates to the speci

Cao, Y., Li, S., & Wijmans, E. (2017). (Cross-)browser fingerprinting via OS and hardware level features. *Proceedings of the Network and Distributed System Security Symposium*. https://doi.org/10.14722/ndss.2017.23152

Chrome DevTools Protocol. (2026). *Emulation domain*. https://chromedevtools.github.io/devtools-protocol/tot/Emulation/

Chromium Authors. (n.d.). *Proxy support in Chrome* [Source documentation]. Chromium. https://chromium.googlesource.com/chromium/src/+/a3e71ebfa307d8760eb68b777e2998a869940092/net/docs/proxy.md

Chromium Authors. (2026). *URL canonicalizer unit tests* [Source code]. Chromium. https://chromium.googlesource.com/chromium/src/+/446d05d21720f0b3505ec21057b3e9f909784262/url/url_canon_unittest.cc
Expand Down Expand Up @@ -207,6 +218,8 @@ World Wide Web Consortium. (2025, September 25). *Mitigating browser fingerprint

World Wide Web Consortium. (2026, June 1). *WebDriver BiDi* (W3C Working Draft). https://www.w3.org/TR/2026/WD-webdriver-bidi-20260601/

World Wide Web Consortium. (2026, August 25). *WebDriver BiDi* [Editor's Draft]. https://w3c.github.io/webdriver-bidi/

Xu, J., Sun, Q., Schwendeman, P., Nielsen, S., Cetin, E., & Tang, Y. (2025). *TRINITY: An evolved LLM coordinator* [Preprint]. arXiv. https://doi.org/10.48550/arXiv.2512.04695

Zhou, S., Xu, F. F., Zhu, H., Zhou, X., Lo, R., Sridhar, A., Cheng, X., Ou, T., Bisk, Y., Fried, D., Alon, U., & Neubig, G. (2023). *WebArena: A realistic web environment for building autonomous agents*. arXiv. https://doi.org/10.48550/arXiv.2307.13854
2 changes: 1 addition & 1 deletion docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ The hourly product-development loop is operational infrastructure, not proof tha
| Priority | Buyer-visible outcome | Protected-main status | Completion issue and acceptance evidence |
|---|---|---|---|
| P0 | A bounded task observes a real Chromium page, performs one typed action, verifies the post-condition, and emits provenance | **Open / Phase 1** | #28; repeated real Chromium E2E with isolated context, exact session/node authority, typed dispatch, post-condition, crash cleanup, and protected-main checks |
| P1 | A governed browser session minimizes ambient host fingerprint leakage without impersonating a target or bypassing site controls | **Local kernel only; browser integration open** | Proposed ADR 0110 and local `originweave-fingerprint` evidence; acceptance requires a pinned real-Chromium test across UA/client hints/platform/locale/named timezone/screen/DPR/hardware/graphics/fonts/media, pre-script application, lifecycle stability, digest binding, no host fallback, and explicit challenge non-circumvention |
| P1 | A governed browser session minimizes ambient host fingerprint leakage without impersonating a target or bypassing site controls | **Local kernel and surface-admission evidence only; browser integration open** | Proposed ADR 0110 and active stacked `originweave-fingerprint` evidence now fail closed when an adapter omits a required profile surface; acceptance still requires a pinned real-Chromium test across UA/client hints/platform/locale/named timezone/screen/DPR/hardware/graphics/fonts/media, pre-script application, lifecycle stability, digest binding, no host fallback, and explicit challenge non-circumvention |
| P0 | Navigation consumes approved origin, resolution, route, TCP peer, TLS identity, bounded HTTP, redirect, MIME, and download policy | **Partial foundation** | #9 plus #28; real browser-network adapter proves the governed path is consumed end to end |
| P1 | Existing Chromium extensions remain compatible while Agent authority stays separate | **Partial active-PR evidence** | #27; exact supported-build/platform compatibility matrix, managed allow-list, native-host isolation, repeatability, and release binding |
| P1 | Authorized work can use necessary PII without ambient exposure | **Policy foundation; runtime open** | #10; opaque broker, exact field/purpose/destination/model policy, atomic use/revocation, retention/deletion, and value-free telemetry |
Expand Down
Loading