diff --git a/docs/DOCUMENTATION_FITNESS.md b/docs/DOCUMENTATION_FITNESS.md new file mode 100644 index 0000000..69f6032 --- /dev/null +++ b/docs/DOCUMENTATION_FITNESS.md @@ -0,0 +1,276 @@ +# OriginWeave Documentation Fitness Assessment + +- **Assessment date:** 2026-08-11 +- **Assessment scope:** protected `main`, every current OriginWeave implementation lane relevant to canonical product truth, and durable product decisions that must be reconstructable without chat history +- **Assessment type:** semantic fitness, not file-presence inventory +- **Current verdict:** **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL** + +## 1. Verdict + +**DESIGN-SUFFICIENT** means the repository has a coherent product, technical, architecture, decision, diagram, data-model, security, testing, operability, protocol and release graph sufficient to implement and review OriginWeave without reconstructing product intent from chat history. + +**PROTECTED-MAIN-PARTIAL** means the design graph is sufficient, while protected `main` still lacks the canonical reconciliation and several active implementation slices. Active pull requests are implementation evidence only. Neither a green feature branch nor a Proposed ADR becomes shipped truth through documentation wording. + +File existence alone is never sufficient. An artifact can exist and still be stale, contradictory, overclaiming, underclaiming, or disconnected from executable evidence. + +## 2. Fitness matrix + +| Documentation family | Fitness | Current evidence / remaining boundary | +|---|---|---| +| PRD | **PRESENT-CURRENT on this branch / protected-main follow-up required** | Protected-main requirements remain distinct from active evidence. #37 is the bounded-HTTP replacement; #45→#46→#53→#55 narrows sensitive-handle authority without creating the trusted broker; #47→#50→#54 narrows resolution freshness through socket use; #40→#52→#57→#58 provides browser authority/semantic prerequisites; #43→#56→#59→#60→#61 plus #49 provide active MV3 compatibility evidence; #62/#63 prove extension-proposal isolation without widening Agent/secret approval authority; and #64/#65 plus #51→#66 add outcome, controlled-fixture and resource-measurement prerequisites without completing the real Chromium runtime. | +| TRD | **PRESENT-CURRENT on this branch / protected-main follow-up required** | One protected-main implementation state is kept separate from volatile active/non-shipped evidence. Value objects, fixtures, bounded Linux samplers and compatibility tests do not imply deployed services, Chromium process attribution, browser adapters or completed runtime paths. | +| Root Architecture | **PRESENT-CURRENT** | The Chromium compatibility kernel plus Rust authority-bearing control plane remains correct. #47/#50/#54 refine ADR 0004; #45/#46/#53/#55 refine ADR 0007; #40/#52/#57/#58 refine browser observation/action boundaries; #62/#63 exercise the existing extension/policy separation; #64/#65 and #51→#66 refine evidence/fixture/resource prerequisites; #43/#49/#56/#59/#60/#61 remain compatibility work under issue #27. None introduces a new trust domain, persistence owner or deployed component. | +| ADR index/lifecycle | **PRESENT-CURRENT on this branch** | Accepted ADRs remain distinct from Proposed decisions. ADR 0013 separates MV3 compatibility from Agent authority; ADR 0014 governs architecture-decision lifecycle. Their branch presence or later integration cannot silently promote them to Accepted. | +| Individual ADRs | **SUFFICIENT BY LIFECYCLE** | Existing Accepted and Proposed decisions cover current material trust boundaries. #62–#66 refine or test existing authority, evidence, fixture and resource boundaries and do not independently justify manufacturing a new ADR. | +| UML / control-flow diagrams | **PRESENT-CURRENT with one legitimate deferral** | Component, network authority, observation/action, delegated-task state, deployment, evidence, secret-fill, approval, resource-pressure/GPU fallback and hourly automation flows exist. `uml/extension-authority.md` closes the permission-vs-Agent-authority gap. Detailed real-Chromium adapter/input/post-condition/process-attribution UML remains deferred until issue #28 executable contracts stabilize. | +| Conceptual ERD/domain model | **PRESENT-CURRENT** | The ERD remains explicitly conceptual until a real persistence owner/schema exists. Current active #45–#66 value, policy, freshness, compatibility, fixture, evidence and resource slices add no OriginWeave-owned durable store. Manufacturing tables for in-memory state, value objects, browser fixtures or process samples would be false architecture. | +| Traceability | **PRESENT-CURRENT on this branch** | Uses explicit protected-main, active-PR, partial, accepted-architecture, planned, research-only, superseded and out-of-scope maturity vocabulary. Volatile exact-head evidence lives in the dated maturity appendix, now through #66. | +| Threat model / Security | **PRESENT-CURRENT with implementation follow-up** | Untrusted content, network, secret, provenance and extension risks are covered. #62/#63 prove extension proposal permission cannot replace Agent policy or R3 approval; #64 does not turn caller timestamps into trusted causality; #65's hostile page content remains a controlled untrusted fixture; #66 does not infer process ownership from caller-supplied PIDs. | +| Test strategy / quality gates | **PRESENT-CURRENT** | Exact owned production function/line/region/branch coverage, rustdoc and realistic boundary testing are explicit. Active work uses exact RED→GREEN evidence, pinned real Chromium where browser behavior is claimed, and fail-closed OS sampling contracts rather than source-text or self-reported claims alone. | +| Operability / incident response | **PRESENT-CURRENT** | Failure, readiness, quarantine, cleanup and recovery concepts exist. Current fixture/value/sampler lanes add no daemon/service or persistence owner, so new SLO/RPO/RTO claims would be fabricated. | +| API / protocol contracts | **PRESENT-CURRENT as target contracts** | #52 is an internal semantic-observation value API, #57 a bounded typed-query API, #58 an authority-bound action-target bridge, and #64 an outcome-evidence value boundary. None is a BiDi/CDP/WebMCP wire adapter, native browser input executor, trusted-clock source, business-risk classifier or post-condition observer. | +| Release / rollback / provenance | **PRESENT-CURRENT** | Release remains bound to one exact integrated protected head. Active stacks #40→#52→#57→#58, #47→#50→#54, #45→#46→#53→#55, #43→#56→#59→#60→#61 plus parallel #49, and #51→#66 preserve dependency order; #62/#63/#64/#65 are direct-main prerequisites. Predecessor-head success cannot satisfy a later head. | +| Data governance / privacy | **PRESENT-CURRENT architecture / PARTIAL runtime** | Purpose-bound policy/evidence foundations exist. #62/#63 prove that proposal authority cannot manufacture secret authority or approval, but authenticated workload identity, durable trusted-broker storage, protected-value resolution/fill, KMS, cross-process transactionality, compensation, retention and model-disclosure lifecycle remain open under issue #10. | +| Standards / doctoring | **PRESENT-CURRENT with continuous watch** | Primary browser/protocol/standards evidence and APA 7 references distinguish living/vendor/experimental material from final normative standards. Exact browser release evidence stays pinned to executable Chromium evidence rather than documentation alone. | + +## 3. Reconciliation findings + +### 3.1 HTTP lineage + +Protected-main PRD previously named historical PR #11 as active HTTP evidence. Current replacement work is PR #37, while protected main still does not ship the reconstructed bounded HTTP capability. + +**Resolution:** #37 is active/non-shipped implementation evidence, #11 is historical predecessor lineage, and integration before any of these branch repairs become protected-main truth remains mandatory. Old-head checks, reviews and mergeability never transfer. + +### 3.2 Sensitive-data authority and broker lifecycle + +Protected main contains purpose-bound sensitive-data policy/evidence governed by Accepted ADR 0007. The active dependency chain is #45 → #46 → #53 → #55: lifecycle evidence, authoritative in-process use reservation, first-revocation-wins state, then audience binding. + +The audience string accepted by the value/policy primitive is **not authentication**. A future trusted broker must derive audience from authenticated workload/service identity rather than caller-controlled input. One-process synchronization is not durable/cross-process atomicity. + +**Resolution:** these lanes may be `IMPLEMENTED_ON_ACTIVE_PR`; the complete broker remains Planned under issue #10. They do not justify a fictitious broker process, KMS path, database table, transaction manager, browser-fill adapter, new deployment topology or physical ERD entity. + +### 3.3 Manifest V3 compatibility + +Protected main already proves a pinned-Chromium baseline for service worker, content script, storage, DNR, tabs, windows, scripting, commands, side panel, bookmarks/history read behavior, restart persistence and repeatability. The active compatibility stack adds: + +- #43: controlled downloads; +- #49: per-trial ephemeral profile isolation; +- #56: bookmark create/read/delete cleanup; +- #59: history add/read/delete/absence verification; +- #60: trial-local unpacked-extension `1.0.0` → `1.0.1` update with explicit schema migration; and +- #61: real content-script isolated-world evidence in which the page main world retains a `page` sentinel while the content script independently retains an `extension` sentinel. + +#43/#49/#56/#59/#60/#61 are active compatibility evidence only. Chromium permission or browser compatibility success is not an OriginWeave Agent capability, policy grant, approval or protected-value authority. A successful fixture cannot become an OriginWeave Agent history grant, bookmark grant, download grant or arbitrary page-JavaScript bridge. + +The supported-capability matrix in `docs/doctoring/mv3-compatibility.md` separates `PROTECTED_MAIN`, `ACTIVE_PR`, `PLANNED`, security-gated and out-of-scope claims. Update migration is intentionally distinct from restart persistence, and isolated-world behavior is intentionally distinct from injection alone. + +**Resolution:** complete compatibility remains Planned under issue #27. Proposed ADR 0013 remains the authority separator. #59/#60/#61 are refinements of that decision, not new architecture decisions. + +### 3.4 Browser identifier authority + +Protected main contains session/context/document/node foundations under Accepted ADR 0010. Active #40 maps protocol-local identifiers into OriginWeave-owned authority and remains non-shipped. + +**Resolution:** protocol identifiers remain adapter-local, and detailed adapter sequence UML remains deferred until issue #28 stabilizes executable BiDi/CDP contracts. + +### 3.5 ADR discoverability and identifier allocation + +The earlier index omitted existing ADRs, and active #37 already reserves ADR identifiers 0011/0012. + +**Resolution:** the branch indexes every ADR by lifecycle, uses non-colliding 0013/0014 for new Proposed decisions, and treats collision-sensitive identifiers as reserved across protected main plus active work. + +### 3.6 Documentation contract parser + +The first fitness contract accepted only bare lifecycle metadata even though repository-valid ADRs can carry descriptive suffixes. + +**Resolution:** machine checks validate the leading supported lifecycle state and reject unknown states without rejecting valid suffixes. + +### 3.7 UML audit correction + +An early audit incorrectly called resource-pressure and hourly-automation views missing. + +**Resolution:** the existing resource-pressure/GPU fallback and hourly automation flows are recognized. Only the genuinely missing extension-permission-to-Agent-authority view was added. + +### 3.8 Resolution freshness authority + +Active #47 → #50 → #54 progressively binds approved resolution state to first-party network planning and rechecks freshness immediately before socket I/O under trusted monotonic time. + +**Resolution:** this refines Accepted ADR 0004 rather than introducing a resolver service, proxy/PAC authority, wall-clock authority, persistence owner or new deployed component. + +### 3.9 TLS revocation-material freshness + +Active #48 provides a bounded freshness primitive for already verified revocation material. + +**Resolution:** this is not OCSP/CRL acquisition, signature/path validation, cache operation or an unrevoked-certificate claim. No fictitious revocation-service topology is added. + +### 3.10 Browser task telemetry and process-set RSS + +Active #51 validates bounded RSS, observation-byte, action-latency and task-duration values and now samples one explicitly supplied Linux PID through strict `/proc//status` `VmRSS` parsing. Stacked #66 extends this to a bounded explicit process set: at most 256 unique nonzero caller-owned PIDs, checked aggregate addition, and fail-closed sampling when any member cannot be measured. + +**Resolution:** OS sampling is now real for caller-supplied Linux PIDs, but Chromium process discovery, same-task attribution, browser child-process/cgroup walking, GPU/VRAM, JS heap and cross-platform sampling remain unimplemented. A changing RSS value is runtime state, so correctness tests validate the sampling contract rather than assuming two sequential reads are byte-identical. + +### 3.11 Semantic observation authority + +Active #52 carries an OriginWeave-owned node handle, bounded semantic fields, typed advertised actions, provenance channels and bounded relationships. Every relationship must remain inside the same browser session, browsing context, canonical origin and document epoch. Self-parent/self-child relationships and duplicate child handles fail closed. The relationship graph remains descriptive evidence. + +**Resolution:** #52 is not a browser observation adapter. Accessibility, DOM, layout, WebMCP, structured-data and visual inputs remain untrusted observations and cannot mint capability. + +### 3.12 Typed semantic query authority + +Active #57 performs bounded exact role, accessible-name and required-typed-action matching only against already validated semantic observations. + +**Resolution:** semantic query success is descriptive selection, not CSS/XPath/raw-DOM authority, arbitrary JavaScript, browser I/O, action dispatch or policy approval. + +### 3.13 Authority-bound semantic node action target + +Active #58 accepts only an advertised `NodeActionKind`, carries the exact OriginWeave-owned node handle and revalidates session/context/origin/document epoch immediately before later use. + +**Resolution:** this remains descriptive execution input. A node advertising `Click` cannot determine business-risk classification: the same click could represent navigation, submit, purchase, delete, permission management or legal consent. Policy intent, approval, browser dispatch and verified success remain separate boundaries under issue #28. + +### 3.14 Controlled history mutation compatibility + +Active #59 creates one synthetic loopback history entry, requires exact readback, removes it in `finally` and proves its absence afterwards. + +**Resolution:** browser history compatibility is not an OriginWeave Agent history grant. No history values are exposed to a model and no human/default profile is used. + +### 3.15 Controlled extension update migration + +Active #60 copies the checked-in fixture into a trial-local directory, keeps one ephemeral profile and one extension path, transitions only `1.0.0` → `1.0.1`, observes the loaded version and requires schema state 1 → 2 migration. + +**Resolution:** this proves one deterministic unpacked-extension version transition. It does not establish Chrome Web Store updates, enterprise rollout, arbitrary downgrade or third-party migration safety. + +### 3.16 Content-script isolated-world compatibility + +Active #61 gives the page main world and the MV3 content script the same JavaScript global name with different values and requires the page to keep publishing `page` while the content script observes its own `extension` value. If the worlds collapse, the existing compatibility gate fails in real pinned Chromium. + +**Resolution:** this is a bounded compatibility proof, not a trusted page-content channel, arbitrary JavaScript bridge or Agent capability. + +### 3.17 Extension proposal authority and secret approval composition + +Active #62/#63 exercise two sides of one architectural separator. #62 first proves the exact extension/session/context `ProposeTypedAction` grant is present and then requires ordinary Agent policy to reject origin/capability/instruction/secret widening. #63 gives the Agent context its independent `FillSecret` capability and broker-handle delivery request, but still requires the ordinary high-risk result `RequireApproval(RiskClass::R3)`. + +**Resolution:** extension proposal permission can neither mint Agent capability/origin/secret authority nor manufacture approval. These are regression proofs over existing boundaries, not a secret broker, browser adapter, approval service or new trust domain. Proposed ADR 0013 already captures the relevant permission-vs-Agent-authority decision. + +### 3.18 Verified action-outcome ordering + +Active #64 makes a successful action-outcome value require existing verified provenance plus one caller-supplied monotonic dispatch timestamp and an observation timestamp that is not earlier. An earlier observation fails closed as `PostConditionPredatesDispatch`; equality is allowed for coarse monotonic clocks. + +**Resolution:** temporal ordering prevents packaging a pre-dispatch observation as later success evidence, but it does not prove trusted clock provenance, actual browser dispatch, target linkage, causal effect or that a real browser reached the declared state. #64 is not a browser dispatcher or post-condition observer. + +### 3.19 Controlled Agent Task fixture + +Active #65 supplies a deterministic synthetic local web fixture with a labelled semantic input, submit control, same-document post-condition and explicitly hidden/untrusted prompt-injection text. The fixture contains no credential collection surface and requires no live third-party site. + +**Resolution:** the fixture makes the future real Chromium vertical slice reproducible without turning a third-party site into a test dependency. It is not a browser adapter, semantic extractor, input dispatcher, policy engine, trusted clock, process-attribution source or proof of real Chromium execution. + +### 3.20 Bounded browser process-set resource evidence + +Active #51→#66 establishes two distinct layers: #51 owns single explicitly supplied Linux PID sampling and the bounded telemetry value boundary; #66 owns bounded duplicate-safe aggregation/sampling over an exact caller-owned PID set. #66's exact current contract rejects empty, zero-PID, duplicate, oversized and overflow states and fails closed if any member cannot be sampled. + +**Resolution:** aggregate resource measurement must not silently undercount a known caller-owned process set, but process membership remains an external attribution responsibility. The implementation does not discover Chromium PIDs, prove process ancestry/task ownership, walk cgroups, sample GPU/VRAM or create a durable telemetry store. + +## 4. Durable product decisions captured by the canonical graph + +1. OriginWeave is **Browse. Act. Prove.**: an enterprise agentic web runtime and provenance-native browser platform, not Selenium-style automation. +2. Chromium remains the compatibility kernel; Blink/V8 are not rewritten for differentiation. +3. Rust owns new authority-bearing control-plane semantics and remains independently reusable. +4. Human, Assist, Agent Task and Crawler modes have distinct authority/profile semantics; Agent Task does not ambiently inherit Human authority. +5. Page, extension, WebMCP and model content are untrusted observations, not goal/policy authority. +6. Structured observation precedes raw HTML or screenshot-only interpretation. +7. Typed actions and observed post-conditions replace arbitrary-script and command-return-as-success semantics. +8. Logical origin, destination, route/proxy, TCP peer, TLS identity and HTTP semantics are separate authorities. +9. Session/context/document epoch/node identity is separate from raw BiDi/CDP identifiers. +10. Manifest V3 permission is not an OriginWeave Agent capability; compatibility evidence and Agent-authority evidence are independent. +11. Raw secrets stay outside model-visible context; sensitive values use purpose-bound authority, opaque handles and trusted fill paths. +12. Browser correctness/human interaction outrank optional local-model throughput under pressure. +13. Provenance distinguishes source observation, model judgement, policy, approval, action and verified outcome. +14. WebDriver BiDi, CDP, WebMCP and MCP are versioned adapters, never the product authority model by themselves. +15. The first browser proof uses pinned stock Chromium before any broad fork. +16. High-risk actions remain approval-bound; Crawler Mode remains read-only and excludes CAPTCHA/block-evasion features. +17. Autonomous development uses OpenCode/NVIDIA NIM under deterministic gates and separate review/publication authority, never `COPILOT_GITHUB_TOKEN` as the development-model credential. +18. Documentation, checks, reviews, model judgements and operational evidence are separate evidence authorities. +19. Work-conserving maintenance continues to another safe lane rather than stopping on one merge, document, RCA, queued check or approval gap. +20. Collision-sensitive repository identifiers are reserved across protected main and active work before allocation. +21. In-memory sensitive-handle primitives may narrow replay/revocation risk without claiming the durable trusted broker exists. +22. A validated DNS answer is not sufficient socket authority indefinitely; resolution-to-socket use requires bounded trusted-monotonic freshness. +23. Revocation-material freshness, cryptographic validity, acquisition/cache operation and an unrevoked claim remain separate evidence authorities. +24. Browser telemetry values, OS process sampling and Chromium/task process attribution are separate maturity claims. +25. Semantic observation provenance and advertised node-local actions are descriptive evidence and never execution authority. +26. Semantic relationships remain bounded within exact session/context/origin/document authority. +27. Sensitive-handle audience must ultimately derive from authenticated workload/service identity. +28. Real browser compatibility fixtures may mutate and clean controlled synthetic state without creating Agent authority. +29. Semantic query success is neither selector authority nor permission to execute an advertised action. +30. Semantic action-target binding preserves exact node authority but remains separate from business-risk classification, policy approval, dispatch and observed success. +31. Update migration, restart persistence, injection and isolated-world behavior are separate compatibility claims and must retain distinct executable evidence. +32. Extension proposal authority never substitutes for Agent capability, origin/secret authority or independent high-risk approval. +33. Verified action-success evidence must not predate dispatch, while trusted clock provenance, browser dispatch, target linkage and causality remain separate authorities. +34. A controlled hostile page fixture is reproducible test infrastructure, not evidence that a real Chromium adapter exists. +35. Resource aggregation over known PIDs does not establish Chromium process discovery or task attribution. + +## 5. Architecture views legitimately deferred + +### 5.1 Extension authority — present + +`uml/extension-authority.md` captures: + +```text +Chromium MV3 permission +-> extension runtime +-> untrusted extension observation/message +-> OriginWeave extension policy/grant +-> Agent capability decision +-> typed action proposal +-> deterministic policy +``` + +Compatibility evidence cannot substitute for Agent-authority evidence, or vice versa. #62/#63 executable composition tests strengthen this existing view without changing its architecture. + +### 5.2 Network freshness sequence — reconcile after #47 → #50 → #54 integrates + +```text +resolver answer +-> destination policy + origin binding +-> fresh resolution approval +-> connection authorization at trusted monotonic use time +-> socket-use freshness recheck +-> exact socket candidate +-> observed TCP peer +-> TLS/HTTP authority layers +``` + +### 5.3 Real Chromium vertical slice — deferred until issue #28 stabilizes + +```text +isolated profile/context +-> BiDi/CDP adapter +-> OriginWeave registry +-> semantic observation +-> typed semantic query +-> authority-bound semantic action target +-> explicit business intent / deterministic policy +-> real browser input +-> observed post-condition +-> credential-safe evidence +-> teardown/recovery +``` + +#40/#52/#57/#58 make identifier/semantic/action-target authority concrete; #64 makes ordered verified outcome packaging concrete; #65 supplies a controlled hostile target application; and #51→#66 narrows resource measurement. None yet establishes the real Chromium transport/semantic extraction/native input/post-condition observer/trusted clock/process attribution chain. Freezing temporary protocol fields into authoritative UML before those executable contracts exist would create false architecture. + +### 5.4 Trusted sensitive-data broker — deferred until issue #10 establishes a real runtime boundary + +Protected-main policy/evidence plus #45→#46→#53→#55 and composition regressions #62/#63 do not justify inventing a broker process, durable database, KMS topology, authenticated service-identity mechanism or browser-fill adapter. Add physical ERD/component/transaction views only when executable ownership exists. + +## 6. Completion criteria + +The graph becomes **PROTECTED-MAIN-SUFFICIENT** only when: + +1. PRD/TRD implementation inventories agree with the exact protected-main crates/APIs/browser evidence; +2. no historical/superseded lineage is presented as current implementation evidence; +3. ADR indexes discover every protected-main ADR and match lifecycle metadata; +4. UML covers every implemented material authority flow, with planned diagrams clearly marked; +5. ERD/domain models distinguish conceptual, in-memory, persisted, adapter-owned and external state truthfully; +6. traceability maps each material requirement/Accepted decision to protected-main evidence, explicitly active-PR evidence or an open issue; +7. documentation tests catch stale status/index/link/ownership/identifier/maturity terminology; +8. security, test, operability, privacy and release docs agree on shipped-vs-planned boundaries; and +9. this documentation reconciliation itself reaches protected main through repository governance and is re-evaluated against whatever feature heads actually integrated. + +Until then, OriginWeave is **design-documented but not protected-main documentation-closed**. That finding must never be used as an excuse to stop unrelated safe implementation work. diff --git a/docs/PRD.md b/docs/PRD.md index 12e5b7f..40539a2 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -44,7 +44,7 @@ Every requirement uses **exactly one** status from this table. Implementation ev | **Proposed** | Product direction still requiring a dedicated reviewed decision or sufficient implementation evidence. | | **Open** | A decision or acceptance criterion is intentionally unresolved. | -Only `Implemented` may describe shipped behavior. An Accepted ADR is design authority, not implementation proof. +Only `Implemented` may describe shipped behavior. An Accepted ADR is design authority, not implementation proof. Active PR implementation evidence may be named in the evidence column, but it does not change a requirement to `Implemented` until the applicable behavior reaches protected `main`. ## 4. Problem statement @@ -84,10 +84,10 @@ The status applies to the **whole named product surface**, not to every implemen |---|---|---|---| | **OriginWeave Browser** | Chromium-compatible interactive distribution with governed agent entry points | Planned | No protected-main branded browser distribution yet | | **OriginWeave Runtime** | Headless/embedded governed web-task runtime | Planned | Rust authority kernels exist; browser integration remains incomplete | -| **OriginWeave Observe** | Structured observation from tools, structured data, network, accessibility, DOM/layout and visual fallback | Planned | Session/context/node-authority foundations are on protected main; semantic browser observation adapter is incomplete | -| **OriginWeave Capture** | Schema-bound extraction, crawler controls, downloads and WARC/PROV-oriented capture | Planned | Evidence foundations exist; complete capture runtime not shipped | +| **OriginWeave Observe** | Structured observation from tools, structured data, network, accessibility, DOM/layout and visual fallback | Planned | Session/context/node-authority foundations are on protected main; active PR #52 adds a bounded authority-bound semantic-observation value primitive with explicit evidence-channel provenance, but it is not a browser observation adapter and remains non-shipped | +| **OriginWeave Capture** | Schema-bound extraction, crawler controls, downloads and WARC/PROV-oriented capture | Planned | Evidence foundations and partial real-Chromium extension compatibility evidence exist; complete capture runtime is not shipped | | **OriginWeave Governor** | CPU, RAM, GPU, VRAM, admission and model/browser priority governance | Accepted architecture | Deterministic resource-budget and CPU-worker admission foundations are implemented; platform telemetry/scheduling adapters remain incomplete | -| **OriginWeave Policy** | Capability, origin, purpose, risk, crawler, approval and sensitive-data authority | Accepted architecture | Capability/origin/purpose/risk/crawler/approval foundations are implemented; purpose-bound sensitive-data policy is active work in PR #33 and the trusted broker remains planned | +| **OriginWeave Policy** | Capability, origin, purpose, risk, crawler, approval and sensitive-data authority | Accepted architecture | Capability/origin/purpose/risk/crawler/approval and purpose-bound sensitive-data policy foundations are implemented on protected main; trusted sensitive-data broker/storage/lifecycle remain planned under issue #10 | | **OriginWeave Evidence** | Credential-free evidence, provenance and task-trail contracts | Accepted architecture | Credential-free network evidence and purpose-bound sensitive-access receipts are implemented; complete Evidence Trail, WARC/PROV adapters and durable enterprise storage remain planned | | **OriginWeave Protocol** | Stable browser-agent protocol independent of one upstream automation standard | Planned | Contract documented; implementation pending | | **OriginWeave SDK** | Typed client libraries and adapters | Planned | Not a shipped product surface | @@ -163,7 +163,7 @@ planner identifies field + purpose + destination -> disclosure receipt records metadata without protected value ``` -The full journey is target architecture until the sensitive policy, trusted broker, browser-fill path, and post-condition/evidence path are all protected-main integrated. Implemented subcomponents do not make this whole sequence shipped. +The full journey is target architecture until the trusted broker, browser-fill path, and post-condition/evidence path are all protected-main integrated. The purpose-bound sensitive-data policy foundation and access-evidence primitives are already on protected main; those implemented subcomponents do not make the complete broker journey shipped. ### 8.4 Enterprise crawler @@ -183,7 +183,7 @@ public-crawl purpose | ID | Requirement | Status | Implementation evidence / note | |---|---|---|---| | PRD-COMP-001 | Chromium is the compatibility kernel; OriginWeave does not reimplement Blink or V8 | Accepted architecture | ADR 0001 | -| PRD-COMP-002 | Maintain a Manifest V3 compatibility matrix and representative extension test farm | Planned | Issue #27 / release-specific evidence required | +| PRD-COMP-002 | Maintain a Manifest V3 compatibility matrix and representative extension test farm | Planned | Partial protected-main pinned-Chromium evidence covers service worker, content script, storage, DNR, tabs, windows, scripting, commands, side panel, bookmarks, history, restart and repeatability; active PR #43 adds bounded real downloads evidence; issue #27 still owns the complete matrix/release acceptance | | PRD-COMP-003 | Chromium-specific integrations remain behind versioned adapters | Planned | Adapter strategy ADR 0107 | | PRD-COMP-004 | Headless runtime remains independently usable without the interactive browser UI | Planned | Modular architecture target | @@ -191,11 +191,11 @@ public-crawl purpose | ID | Requirement | Status | Implementation evidence / note | |---|---|---|---| -| PRD-OBS-001 | Autonomous observations can carry explicit browser-session, browsing-context, canonical-origin and document-epoch authority | Implemented | `ObservedNodeHandle`, `BrowserSessionId`, `BrowsingContextId` and `DocumentEpoch` on protected main via #17; real browser adapter remains planned | -| PRD-OBS-002 | Actionable semantic-node handles are invalidated by relevant document-epoch changes at the action linearization boundary | Accepted architecture | Core exact-authority validation exists; adapter lifecycle/mutation invalidation and atomic dispatch evidence remain planned | -| PRD-OBS-003 | Observation prefers typed/structured evidence before accessibility/DOM/layout and bounded visual fallback | Accepted architecture | ADR 0103 | +| PRD-OBS-001 | Autonomous observations can carry explicit browser-session, browsing-context, canonical-origin and document-epoch authority | Implemented | `ObservedNodeHandle`, `BrowserSessionId`, `BrowsingContextId` and `DocumentEpoch` are on protected main under Accepted ADR 0010; real browser adapter remains planned | +| PRD-OBS-002 | Actionable semantic-node handles are invalidated by relevant document-epoch changes at the action linearization boundary | Accepted architecture | Core exact-authority validation exists; adapter lifecycle/mutation invalidation and atomic dispatch evidence remain planned; active PR #40 owns the bounded protocol-ID registry and remains non-shipped evidence | +| PRD-OBS-003 | Observation prefers typed/structured evidence before accessibility/DOM/layout and bounded visual fallback | Accepted architecture | ADR 0103; active PR #52 adds a bounded `SemanticNodeObservation` value contract bound to `ObservedNodeHandle`, typed node-local action descriptors and explicit non-empty evidence-channel provenance. It is not a browser observation adapter and remains active/non-shipped evidence | | PRD-OBS-004 | Observation can use bounded incremental updates rather than full repeated snapshots | Planned | Adapter-specific design needed | -| PRD-OBS-005 | Source channel and trust/provenance remain explicit | Accepted architecture | Evidence model foundations exist | +| PRD-OBS-005 | Source channel and trust/provenance remain explicit | Accepted architecture | Evidence model foundations exist; active PR #52 fails closed when a semantic observation has no contributing evidence channel, while channel identity itself grants no execution authority | ### 9.3 Typed action execution @@ -215,8 +215,8 @@ public-crawl purpose | PRD-NET-002 | Resolution snapshots are bounded, origin-bound and fail closed on unapproved expansion | Implemented | `originweave-destination` | | PRD-NET-003 | Direct transport connects only to approved canonical sockets and verifies `peer_addr` | Implemented | `originweave-network` | | PRD-NET-004 | TLS authenticates service identity over the exact governed transport with explicit roots/time | Implemented | `originweave-tls` | -| PRD-NET-005 | Proxy/PAC route authority is explicit and never ambient | Implemented | Protected-main route-authority foundation from #20; PAC evaluation, proxy transport and CONNECT remain planned | -| PRD-NET-006 | Bounded HTTP semantics operate over authenticated governed transport | Planned | Active PR #11 is not shipped evidence | +| PRD-NET-005 | Proxy/PAC route authority is explicit and never ambient | Implemented | Protected-main route-authority foundation; PAC evaluation, proxy transport and CONNECT remain planned | +| PRD-NET-006 | Bounded HTTP semantics operate over authenticated governed transport | Planned | Current implementation evidence is active replacement PR #37; it is not protected-main truth. Historical PR #11 is predecessor lineage and must not be used as current implementation evidence | | PRD-NET-007 | Real Chromium navigation proves end-to-end consumption of every shipped authority layer | Planned | Issue #28 / release acceptance requirement | ### 9.5 Secret and sensitive-data authority @@ -224,8 +224,8 @@ public-crawl purpose | ID | Requirement | Status | Implementation evidence / note | |---|---|---|---| | PRD-DATA-001 | Raw secret values never enter model-visible context | Accepted architecture | ADR 0104; trusted browser/broker runtime path not fully shipped | -| PRD-DATA-002 | Sensitive disclosure binds tenant/task/field/purpose/destination/classification | Planned | Active replacement PR #33; no active-PR evidence counts as protected-main implementation | -| PRD-DATA-003 | Trusted broker owns expiry, revocation, atomic use reservation and resolution | Planned | Broker implementation pending under issue #10 | +| PRD-DATA-002 | Sensitive disclosure binds tenant/task/field/purpose/destination/classification | Implemented | Protected-main purpose-bound sensitive-data policy kernel governed by Accepted ADR 0007; this status does not claim broker/storage/value resolution | +| PRD-DATA-003 | Trusted broker owns expiry, revocation, atomic use reservation and resolution | Planned | Broker/storage/lifecycle implementation pending under issue #10 | | PRD-DATA-004 | Privacy controls use purpose-bound authorization, encryption, retention and audit rather than blanket masking | Accepted architecture | `DATA_GOVERNANCE.md` | | PRD-DATA-005 | Model disclosure additionally binds provider/model/region/retention policy | Planned | Requires orchestrator/provider integration | @@ -238,7 +238,7 @@ public-crawl purpose | PRD-EVD-003 | Evidence Trail links source, model judgement, policy, approval, action and verified outcome as distinct authorities | Planned | Conceptual ERD/provenance ADR; complete trail is not shipped | | PRD-EVD-004 | **Origin Map** provides buyer-visible provenance exploration | Proposed | UX/product-design work still required | | PRD-EVD-005 | WARC and PROV are separate interoperability/export adapters | Accepted architecture | ADR 0106 | -| PRD-EVD-006 | Sensitive-access evidence records authority without protected value | Implemented | Protected-main purpose-bound sensitive-access receipts via #31 | +| PRD-EVD-006 | Sensitive-access evidence records authority without protected value | Implemented | Protected-main purpose-bound sensitive-access receipts | ### 9.7 Resource governance @@ -246,7 +246,7 @@ public-crawl purpose |---|---|---|---| | PRD-RES-001 | Deterministic resource budgets produce cumulative mitigations | Implemented | `originweave-resource` foundations | | PRD-RES-002 | Browser/human correctness outranks optional model throughput | Accepted architecture | ADR 0105 | -| PRD-RES-003 | CPU worker saturation participates in deterministic new-work admission | Implemented | Protected-main `ResourceSnapshot`/`ResourceGovernor` CPU-worker admission via #30; platform worker telemetry/actuation remains adapter work | +| PRD-RES-003 | CPU worker saturation participates in deterministic new-work admission | Implemented | Protected-main `ResourceSnapshot`/`ResourceGovernor` CPU-worker admission; platform worker telemetry/actuation remains adapter work | | PRD-RES-004 | Platform adapters report bounded CPU/RAM/GPU/VRAM/network/storage telemetry | Planned | Platform integration required | | PRD-RES-005 | Constrained GPU systems shrink/offload/pause model work before sacrificing governed browser correctness | Accepted architecture | ADR 0105 | @@ -264,10 +264,10 @@ public-crawl purpose | ID | Requirement | Status | Implementation evidence / note | |---|---|---|---| -| PRD-EXT-001 | Manifest V3 remains the extension compatibility baseline | Accepted architecture | Official Chrome platform baseline | -| PRD-EXT-002 | Upstream extension APIs are preserved where possible | Accepted architecture | Chromium-kernel strategy | -| PRD-EXT-003 | Extension access to agent authority requires separate signed policy grant | Planned | Issue #27 / enterprise-runtime integration | -| PRD-EXT-004 | Compatibility tests cover install/update, worker lifecycle, scripts, storage, DNR, messaging, download, side panel and isolation | Planned | Issue #27 / release-specific suite | +| PRD-EXT-001 | Manifest V3 remains the extension compatibility baseline | Accepted architecture | Official Chrome platform baseline; real pinned-Chromium evidence exists on protected main | +| PRD-EXT-002 | Upstream extension APIs are preserved where possible | Accepted architecture | Chromium-kernel strategy; current protected-main compatibility lane exercises multiple real MV3 APIs | +| PRD-EXT-003 | Extension access to agent authority requires separate signed policy grant | Planned | Protected-main extension authority foundation exists, but the complete managed-extension/native-messaging/enterprise runtime contract remains open under issue #27; Proposed ADR 0013 does not itself make this shipped | +| PRD-EXT-004 | Compatibility tests cover install/update, worker lifecycle, scripts, storage, DNR, messaging, download, side panel and isolation | Planned | Protected-main suite already covers worker/content/storage/DNR/tabs/windows/scripting/commands/side panel/bookmarks/history/restart/repeatability; active PR #43 adds downloads; install/update/native messaging/enterprise isolation and release-wide matrix remain open under issue #27 | ### 9.10 Crawler and capture policy diff --git a/docs/README.md b/docs/README.md index fa62037..c7837bf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,9 +7,14 @@ - [Architecture](../ARCHITECTURE.md) - [Architecture Decision Record index](adr/README.md) - [UML and control-flow diagrams](uml/README.md) + - [Extension compatibility and Agent authority UML](uml/extension-authority.md) - [Conceptual ERD and durable domain model](erd/README.md) - [Data governance and privacy boundary](DATA_GOVERNANCE.md) - [Product and decision traceability](traceability/README.md) +- [Documentation fitness assessment](DOCUMENTATION_FITNESS.md) +- [Dated active-PR maturity evidence (2026-08-10)](evidence/2026-08-10-active-pr-maturity.md) +- [Active-PR maturity delta (2026-08-11)](evidence/2026-08-11-active-pr-maturity-delta.md) +- [Active-PR maturity closure (2026-08-11)](evidence/2026-08-11-active-pr-maturity-closure.md) - [Threat model](THREAT_MODEL.md) - [Product-wide test strategy](TEST_STRATEGY.md) - [Operability and incident-response baseline](OPERABILITY.md) @@ -17,11 +22,12 @@ - [Release and rollback contract](RELEASE_AND_ROLLBACK.md) - [Product roadmap](product-roadmap.md) - [Research and standards](doctoring.md) + - [Browser and Agent protocol standards evidence](doctoring/browser-agent-protocols.md) - [Current product-baseline standards addendum](doctoring/product-documentation-baseline.md) - [Quality gates](quality-gates.md) - [Security policy](../SECURITY.md) -The PRD/TRD/Architecture/ADR/UML/ERD/data-governance/traceability/security/operations/API/release set is the product-wide documentation graph. Feature-specific design specifications and plans below provide detailed implementation history but do not substitute for the product-wide baseline. Planned or conversation-derived capabilities must remain labelled Planned, Proposed, or Open until reviewed implementation evidence reaches protected `main`. +The PRD/TRD/Architecture/ADR/UML/ERD/data-governance/traceability/security/operations/API/release set is the product-wide documentation graph. The documentation-fitness assessment records where that graph is current, stale, partial, or intentionally proposed. Volatile exact heads, workflow results, stack state, and active-PR maturity belong in dated evidence appendices rather than timeless architecture claims. Feature-specific design specifications and plans below provide detailed implementation history but do not substitute for the product-wide baseline. Planned or conversation-derived capabilities must remain labelled Planned, Proposed, or Open until reviewed implementation evidence reaches protected `main`. ## Governance and maintenance @@ -42,7 +48,7 @@ The PRD/TRD/Architecture/ADR/UML/ERD/data-governance/traceability/security/opera - [TLS service-identity design](superpowers/specs/2026-08-06-tls-server-identity-design.md) - [TLS service-identity implementation plan](superpowers/plans/2026-08-06-tls-server-identity.md) -## Protected-main architecture decisions +## Accepted protected-main architecture decisions - [ADR 0001: Chromium compatibility kernel](adr/0001-chromium-compatibility-kernel.md) - [ADR 0002: Agent safety kernel](adr/0002-agent-safety-kernel.md) @@ -50,5 +56,33 @@ The PRD/TRD/Architecture/ADR/UML/ERD/data-governance/traceability/security/opera - [ADR 0004: Logical origin and resolved destination safety](adr/0004-resolved-destination-policy.md) - [ADR 0005: Exact direct TCP peer binding](adr/0005-direct-socket-binding.md) - [ADR 0006: TLS service identity over the verified peer](adr/0006-tls-server-identity.md) +- [ADR 0007: Purpose-bound sensitive-data authority](adr/0007-purpose-bound-sensitive-data-authority.md) +- [ADR 0008: Delegated-task TLS leaf-validity horizon](adr/0008-leaf-validity-horizon.md) +- [ADR 0010: Session/context-bound node authority](adr/0010-session-context-bound-node-authority.md) -See the [ADR index](adr/README.md) for status rules, required decision structure, and the rule that active-PR ADRs do not become Accepted merely because they exist on an unmerged branch. +## Proposed architecture decisions + +Proposed ADRs are reviewable architecture memory, not shipped behavior and not automatically Accepted because their files are present in a branch or later reach protected `main`. The provenance headings below distinguish the protected-main baseline from decisions introduced by this documentation reconciliation without changing either decision's lifecycle status. + +### Protected-main baseline proposed decisions + +- [ADR 0009: Hourly agent credential boundary](adr/0009-hourly-agent-credential-boundary.md) +- [ADR 0100: Rust control-plane boundary](adr/0100-rust-control-plane-boundary.md) +- [ADR 0101: Isolated execution/profile modes](adr/0101-isolated-execution-profile-modes.md) +- [ADR 0102: Typed actions over arbitrary JavaScript](adr/0102-typed-actions-and-arbitrary-js.md) +- [ADR 0103: Semantic observation and stale-node identity](adr/0103-semantic-observation-and-stale-node-identity.md) +- [ADR 0104: Prompt-injection and secret authority separation](adr/0104-prompt-injection-and-secret-authority.md) +- [ADR 0105: Resource governor priority](adr/0105-resource-governor-priority.md) +- [ADR 0106: Provenance evidence model](adr/0106-provenance-evidence-model.md) +- [ADR 0107: Browser protocol adapter strategy](adr/0107-browser-protocol-adapter-strategy.md) +- [ADR 0108: Crawler policy](adr/0108-crawler-policy.md) +- [ADR 0109: Hourly automation secret ordering and operational closure](adr/0109-hourly-automation-operational-closure.md) + +### Proposed decisions introduced by this documentation reconciliation + +- [ADR 0013: Manifest V3 compatibility and extension-to-Agent authority](adr/0013-manifest-v3-extension-authority.md) +- [ADR 0014: Architecture decision acceptance governance](adr/0014-architecture-decision-governance.md) + +The second group exists only on this documentation branch until the branch integrates. After integration, the heading remains useful historical provenance; it does not promote either ADR from Proposed to Accepted and it does not claim that the described runtime capability is implemented. + +See the [ADR index](adr/README.md) for status rules, required decision structure, supersession rules, and active feature ADRs. The index and each ADR's own status metadata must agree; a PR body, chat transcript, automation prompt, or stale issue reference cannot change ADR status. diff --git a/docs/TRD.md b/docs/TRD.md index 7330fec..3e80300 100644 --- a/docs/TRD.md +++ b/docs/TRD.md @@ -17,25 +17,28 @@ This TRD defines technical invariants for OriginWeave without describing planned - **Proposed** — a candidate design that still needs a dedicated reviewed decision or implementation proof. - **Open** — deliberately unresolved. -Pull-request code is not treated as Implemented until it reaches protected `main` and required acceptance evidence is re-established there. +Pull-request code is not treated as Implemented until it reaches protected `main` and required acceptance evidence is re-established there. Active-PR implementation may be recorded in a separate evidence note, but it never creates a composite implementation status. ## 2. Current protected-main implementation inventory -The current reusable Rust control plane is intentionally smaller than the final browser product. - -| Module | Current responsibility | Status | -|---|---|---| -| `originweave-core` | Canonical origin, typed actions, purpose/mode, capabilities, risk, secret-delivery and approval contracts. | **Implemented** | -| `originweave-policy` | Pure fail-closed action-policy evaluation. | **Implemented** | -| `originweave-destination` | Resolved-address classification, origin-bound snapshots, connection pinning, rebinding and redirect authority. | **Implemented** | -| `originweave-network` | Direct single-address TCP connection plan and exact operating-system peer verification. | **Implemented** | -| `originweave-tls` | WebPKI service identity over the already verified TCP stream. | **Implemented** | -| `originweave-resource` | Deterministic resource budgets and cumulative mitigation plans. | **Implemented** | -| `originweave-evidence` | Value-redacted network evidence and provenance foundations. | **Implemented** | -| Browser/session/observation/action adapters | Chromium/BiDi/CDP integration and node-lifetime enforcement. | **Planned / active development** | -| HTTP/proxy/PAC execution | Bounded HTTP and explicit route execution beyond pure foundations. | **Planned / active development** | -| Secret broker persistence/runtime | Atomic opaque-handle lifecycle and trusted fill. | **Planned / active development** | -| WARC/PROV persistence | Durable capture and provenance serialization. | **Planned** | +The current reusable Rust control plane is intentionally smaller than the final browser product. The status column describes protected `main` only; active PR evidence is kept in the final column. + +| Module / boundary | Current responsibility | Protected-main status | Active/non-shipped evidence | +|---|---|---|---| +| `originweave-core` | Canonical origin, typed actions, purpose/mode, capabilities, risk, secret-delivery, approval, session/context/document/node authority values. | **Implemented** | PR #40 builds a protocol-ID registry on top of these values; it is not protected-main truth | +| `originweave-policy` | Pure fail-closed action policy including purpose-bound sensitive-data authority. | **Implemented** | Trusted broker/runtime lifecycle remains separate planned work under issue #10 | +| `originweave-destination` | Resolved-address classification, origin-bound snapshots, route authority, connection pinning, rebinding and redirect authority. | **Implemented** | PAC evaluation/proxy transport/CONNECT are still Planned | +| `originweave-network` | Direct single-address TCP connection plan and exact operating-system peer verification. | **Implemented** | — | +| `originweave-tls` | WebPKI service identity over the already verified TCP stream. | **Implemented** | — | +| `originweave-resource` | Deterministic resource budgets, CPU-worker admission and cumulative mitigation plans. | **Implemented** | Platform telemetry/actuation remains Planned | +| `originweave-evidence` | Value-redacted network evidence, provenance foundations and sensitive-access evidence primitives. | **Implemented** | Complete durable Evidence Trail/WARC/PROV persistence remains Planned | +| Browser/session protocol registry | Bind raw BiDi/CDP identifiers to OriginWeave session/context/document authority. | **Planned** | Active PR #40; core lifetime value contracts are already Implemented under ADR 0010 | +| Semantic observation/action browser adapters | Chromium/BiDi/CDP observation, node lifecycle, typed input and post-condition verification. | **Planned** | Issue #28 | +| Bounded HTTP execution | HTTP/1.1 semantics over authenticated governed transport. | **Planned** | Active replacement PR #37; historical PR #11 is predecessor lineage, not current evidence | +| Proxy/PAC execution | Evaluate authorized route selection and perform governed proxy/CONNECT transport. | **Planned** | Protected-main route-authority value foundation already exists | +| Sensitive-data broker persistence/runtime | Atomic opaque-handle lifecycle, revocation/reservation, value resolution and trusted fill. | **Planned** | Protected-main policy/evidence foundations exist; issue #10 owns complete runtime lifecycle | +| Manifest V3 compatibility program | Real pinned-Chromium extension compatibility and release matrix. | **Planned** | Protected main already contains partial real-browser evidence; active PR #43 adds downloads evidence | +| WARC/PROV persistence | Durable capture and provenance serialization. | **Planned** | — | ## 3. Architectural invariants @@ -69,7 +72,7 @@ A **logical origin** is not a **resolved destination** decision. A resolved addr ### TRD-INV-003 — Untrusted page content -Browser content, rendered text, hidden text, comments, ads, WebMCP output, network bodies, downloads, and model-produced summaries are data. They cannot mutate system policy, expand capabilities, authorize destinations, reveal secrets, or redefine the user's goal. +Browser content, rendered text, hidden text, comments, ads, WebMCP output, network bodies, downloads, extension messages, and model-produced summaries are data. They cannot mutate system policy, expand capabilities, authorize destinations, reveal secrets, or redefine the user's goal. ### TRD-INV-004 — Secret separation @@ -87,23 +90,23 @@ A typed action may be attempted only after exact current authority is validated. ### Assist Mode -**Accepted architecture; Planned adapter path.** Reversible/read behavior may be automated. Irreversible or externally visible state changes re-enter the risk/approval pipeline. +**Accepted architecture.** Reversible/read behavior may be automated. Irreversible or externally visible state changes re-enter the risk/approval pipeline. The browser adapter path remains Planned. ### Agent Task Mode -**Accepted architecture; Planned adapter path.** Each delegated task receives an isolated or explicitly attached browser context, scoped capabilities, origins, secrets, policy and resource budgets. The unrestricted default human profile is not ambient task authority. +**Accepted architecture.** Each delegated task receives an isolated or explicitly attached browser context, scoped capabilities, origins, secrets, policy and resource budgets. The unrestricted default human profile is not ambient task authority. Complete browser adapter/session integration remains Planned. ### Crawler Mode -**Accepted architecture; policy foundation Implemented.** Crawler actions are read-only. Robots evidence, rate controls, purpose, privacy, retention and legal/contract policy are distinct checks. +**Accepted architecture.** The read-only crawler policy foundation is Implemented, while the complete crawler runtime is Planned. Robots evidence, rate controls, purpose, privacy, retention and legal/contract policy are distinct checks. ## 5. Identifier and lifetime contracts ### 5.1 Core identifiers -Durable identifiers introduced by adapters must be opaque and nonzero/nonempty. External browser identifiers are translated through scoped registries instead of becoming the core authority value directly. +Protected-main core contracts already define opaque browser-session, browsing-context, document-epoch and observed-node authority values governed by Accepted ADR 0010. External browser identifiers must be translated through scoped registries instead of becoming core authority directly. The protocol-ID registry is active PR #40 evidence until protected integration. -Planned browser-lifetime tuple: +Required browser-lifetime tuple: ```text browser_session_id @@ -117,7 +120,7 @@ An actionable node reference is valid only when every component matches the live ### 5.2 Document epochs -Navigation, document replacement, or another adapter-defined actionable-document lifetime change rotates `document_epoch`. A stale node reference must fail deterministically before input dispatch. +Navigation, document replacement, or another adapter-defined actionable-document lifetime change rotates `document_epoch`. A stale node reference must fail deterministically before input dispatch. Core exact-authority validation is Implemented; real browser lifecycle invalidation/linearized dispatch remains adapter work. ### 5.3 Idempotency @@ -145,7 +148,7 @@ The pure destination crate itself does no DNS lookup. ### 6.3 Route/proxy authority -**Accepted architecture; active development.** Direct routing is the default. Proxy and PAC-selected routes require explicit authority. A proxy is an intermediate authority and never replaces final-target authorization. Ambient environment proxy variables cannot silently change the governed route. +**Protected-main status: Implemented for route-authority foundations. Proxy/PAC execution: Planned.** Direct routing is the default. Proxy and PAC-selected routes require explicit authority. A proxy is an intermediate authority and never replaces final-target authorization. Ambient environment proxy variables cannot silently change the governed route. PAC evaluation, proxy transport and CONNECT require separate execution evidence before release claims. ### 6.4 Direct transport @@ -157,7 +160,9 @@ The pure destination crate itself does no DNS lookup. ### 6.6 HTTP semantics -**Accepted architecture; active development.** HTTP processing must consume an authenticated governed connection and define: +**Protected-main status: Planned.** Active replacement PR #37 implements bounded HTTP/1.1 semantics but remains non-shipped evidence until protected integration. Historical PR #11 is predecessor lineage and is not current implementation evidence. + +HTTP processing must consume an authenticated governed connection and define: - supported methods and caller-controlled fields; - syntax/framing rules; @@ -200,7 +205,7 @@ Raw HTML is not the default model payload. ## 8. Action architecture -Standard action vocabulary is **Accepted architecture / Planned runtime integration**: +The standard action vocabulary is **Accepted architecture**; complete real-browser runtime integration remains Planned: ```text navigate @@ -241,7 +246,7 @@ The adapter declares an observable post-condition contract, such as URL change, ### 9.1 Purpose-bound authority -**Active development.** Protected disclosure authority is represented as one value object/scoped record containing tenant, task, field, business purpose, canonical destination and data classification. Reclassification requires newly valid authority. +**Implemented policy foundation.** Protected disclosure authority binds tenant, task, field, business purpose, canonical destination and data classification under Accepted ADR 0007. This implementation does not imply that trusted value storage, opaque-handle resolution, revocation or browser fill are complete. ### 9.2 Opaque handle broker @@ -256,15 +261,17 @@ The adapter declares an observable post-condition contract, such as URL change, - value resolution/fill; - compensation/recovery after reserved-but-failed use. +Issue #10 owns the broader broker/storage/lifecycle completion. + ### 9.3 Evidence -Access/disclosure evidence records identifiers, scope, decision, approval reference, policy version and lifecycle times without carrying the protected value. +Protected-main evidence primitives can record purpose-bound sensitive-access authority without carrying the protected value. Complete broker-use receipts must remain aligned with the runtime lifecycle once that broker exists. ## 10. Resource-governor requirements ### 10.1 Deterministic kernel -**Implemented foundation.** `originweave-resource` validates budgets and produces a cumulative mitigation plan. It does not sample the operating system or directly schedule processes. +**Implemented.** `originweave-resource` validates budgets, includes CPU-worker admission state, and produces a cumulative mitigation plan. It does not sample the operating system or directly schedule processes. ### 10.2 Adapter telemetry @@ -276,7 +283,7 @@ Access/disclosure evidence records identifiers, scope, decision, approval refere ### 10.4 Constrained GPU -**Accepted architecture / Planned implementation.** Rendering and local model inference use phase scheduling where necessary. The mitigation ladder can shrink model batches, release inference caches, offload to CPU, pause the task and reject admission before foreground rendering is sacrificed. +**Accepted architecture.** Rendering and local model inference use phase scheduling where necessary. The implementation of platform GPU telemetry/scheduling remains Planned. The mitigation ladder can shrink model batches, release inference caches, offload to CPU, pause the task and reject admission before foreground rendering is sacrificed. ## 11. Evidence and provenance requirements @@ -310,7 +317,7 @@ Generic network evidence retains bounded names and canonical locators while valu ### WebDriver BiDi -**Planned.** WebDriver BiDi is an evolving W3C adapter contract. Its session/user-context/browsing-context identifiers are translated into OriginWeave-scoped internal identities. Protocol evolution is isolated behind versioned adapter tests. +**Planned.** WebDriver BiDi is an evolving W3C adapter contract. Its session/user-context/browsing-context identifiers are translated into OriginWeave-scoped internal identities. Core lifetime authority is already Implemented; active PR #40 is non-shipped registry implementation evidence. ### Chrome DevTools Protocol @@ -318,7 +325,7 @@ Generic network evidence retains bounded names and canonical locators while valu ### WebMCP -**Planned / experimental external dependency.** **WebMCP** can provide typed page tools. Tool schemas and outputs remain untrusted page-originated data and cannot grant OriginWeave authority. +**Planned.** **WebMCP** is an experimental external dependency that can provide typed page tools. Tool schemas and outputs remain untrusted page-originated data and cannot grant OriginWeave authority. ### Model Context Protocol @@ -330,9 +337,9 @@ Generic network evidence retains bounded names and canonical locators while valu ## 13. Manifest V3 extension requirements -**Accepted architecture / Planned compatibility program.** OriginWeave preserves Chromium's extension implementation rather than rebuilding Chrome APIs in Rust. Agent authority remains separate from ordinary extension permissions. A future signed policy registry controls which extensions may observe or propose agent actions. +The complete compatibility program is **Planned** under issue #27, while partial real-browser evidence exists on protected main. OriginWeave preserves Chromium's extension implementation rather than rebuilding Chrome APIs in Rust. Agent authority remains separate from ordinary extension permissions. Proposed ADR 0013 documents this separation but is not Accepted design authority until reviewed/integrated accordingly. -Compatibility acceptance includes installation/update, extension service-worker lifecycle, content scripts, storage, scripting, DNR, native messaging, downloads, side panel, restart persistence and explicit task-mode isolation. +Protected-main pinned-Chromium evidence currently exercises service-worker lifecycle, content scripts, storage, declarativeNetRequest, tabs, windows, scripting, commands, side panel, bookmarks, history, restart persistence and repeatability. Active PR #43 adds a bounded real `chrome.downloads` path and allowlisted download-stage failure evidence. Installation/update, native messaging, managed-extension/enterprise policy, broader isolation, Web Store and release-wide compatibility remain outside the current protected-main claim. ## 14. Prompt-injection and model boundary @@ -386,6 +393,7 @@ Long-running tasks and external model calls require cancellation semantics that - Node/action validation occurs immediately before execution to close stale-state races. - Sensitive-handle use becomes atomic in the trusted broker. - Migration/release/automation writer leases prevent competing repository writers. +- Repository-scoped collision-sensitive identifiers such as ADR numbers, migration IDs and protocol/schema versions are reserved across protected main plus active work before allocation. - Platform compute pools avoid avoidable oversubscription between Chromium, Rust and model runtimes. ## 17. Persistence and data naming @@ -407,7 +415,7 @@ network_exchange download_artifact ``` -The conceptual model is defined in [`erd/README.md`](erd/README.md). Adapters may use WARC/object storage/relational stores independently; cross-service application database access is not an integration contract. +The conceptual model is defined in [`erd/README.md`](erd/README.md). Adapters may use WARC/object storage/relational stores independently; cross-service application database access is not an integration contract. Conceptual ERD entities are not evidence that a physical relational schema exists. ## 18. Security and enterprise controls @@ -423,11 +431,15 @@ Product UI targets WCAG 2.2 AA / ISO/IEC 40500:2025-aligned evidence. Approval, ### Implemented kernels -Require deterministic unit/property/integration tests for canonicalization, classification, rebinding, redirects, direct peers, TLS identity, policy, resources and evidence. +Require deterministic unit/property/integration tests for canonicalization, classification, rebinding, redirects, route authority, direct peers, TLS identity, policy, session/node authority values, resources and evidence. ### Browser vertical slice -Requires real browser integration tests covering isolated contexts, stale nodes, iframes/shadow DOM where supported, origin changes, typed actions, post-conditions, crashes, cancellations and governed real network composition. +Requires real browser integration tests covering isolated contexts, protocol-ID registry binding, stale nodes, iframes/shadow DOM where supported, origin changes, typed actions, post-conditions, crashes, cancellations and governed real network composition. + +### Manifest V3 compatibility + +Maintain pinned real-Chromium evidence for every claimed extension surface, with restart/repeatability and bounded failure diagnostics. Compatibility evidence and Agent-authority evidence are independent: neither can substitute for the other. ### Security @@ -482,4 +494,4 @@ A material change to any of the following must update the authoritative document - enterprise privacy/security/tenancy contract; - release acceptance or rollback semantics. -If a decision is not implemented, the documentation must retain `Planned`, `Proposed`, or `Open` status rather than silently describe it as shipped. +If a decision is not implemented, the documentation must retain `Planned`, `Proposed`, or `Open` status rather than silently describe it as shipped. Active PR evidence remains explicitly non-shipped until protected integration and exact acceptance evidence exist. diff --git a/docs/adr/0013-manifest-v3-extension-authority.md b/docs/adr/0013-manifest-v3-extension-authority.md new file mode 100644 index 0000000..e620edf --- /dev/null +++ b/docs/adr/0013-manifest-v3-extension-authority.md @@ -0,0 +1,108 @@ +# ADR 0013: Manifest V3 compatibility and extension-to-Agent authority + +- **Status:** Proposed +- **Date:** 2026-08-10 +- **Supersedes:** None +- **Superseded by:** None + +## Context + +OriginWeave retains Chromium as its compatibility kernel rather than reimplementing Chrome's extension runtime. That creates two independent product questions: whether a declared Manifest V3 capability works on the pinned Chromium baseline, and whether an extension can influence an OriginWeave Agent Task only through explicit OriginWeave authority. + +Issue #27 requires both executable Manifest V3 compatibility evidence and explicit separation between Chromium extension permissions and OriginWeave Agent capabilities. Protected main contains partial pinned-Chromium compatibility evidence and extension-to-Agent authority foundations, but the full capability matrix, managed/native-messaging boundaries, release integration, and complete isolation acceptance remain open. + +This ADR makes that target architecture reviewable without claiming issue #27 is complete. Until protected-main governance accepts it, this ADR is Proposed design authority only. + +## Decision drivers + +- Preserve Chromium extension compatibility without creating a second OriginWeave plugin ecosystem. +- Prevent Chrome extension permissions from becoming ambient Agent Task authority. +- Keep Human Mode and delegated Agent Task profile semantics distinct. +- Bind compatibility claims to an exact Chromium revision and declared capability matrix. +- Keep extension-produced content and messages in the untrusted-observation domain. +- Keep protected secrets and sensitive values behind independent purpose-bound authority. +- Support managed extensions without granting arbitrary native-process or cross-origin capability. +- Allow safe rollback when a Chromium revision regresses a declared extension surface. + +## Assumptions and authority boundaries + +- Chromium owns Manifest V3 parsing, service workers, extension APIs, isolated worlds, and browser-managed extension policy. +- OriginWeave owns Agent Task isolation, extension-to-Agent grants, task/origin/action authority, secret/sensitive disclosure, approvals, evidence, and release claims. +- A Chromium extension permission authorizes the extension inside Chromium; it does not mint an OriginWeave capability. +- An OriginWeave `extension_grant` authorizes only the explicitly bound OriginWeave interaction; it does not emulate Chrome manifest permissions. +- Extension content, page mutations, messages, native-host output, and structured tool output remain untrusted observations unless independently authenticated through a separate trusted administrative channel. +- Compatibility evidence and Agent-authority-isolation evidence are separate evidence classes. Neither implies the other. + +## Options considered + +### Reimplement Chrome extensions as a Rust plugin system + +Rejected. It would create a second extension ecosystem and duplicate mature Chromium behavior. + +### Let extensions inherit Agent Task authority from Chrome permissions + +Rejected. Chrome permissions are not OriginWeave task/origin/action/approval grants and ambient inheritance creates confused-deputy, secret-disclosure, prompt-injection, and cross-origin escalation risk. + +### Disable extensions in every mode + +Rejected as a product-wide rule. Agent Task Mode defaults to no extensions or a managed allow-list, but Human Mode must retain normal compatible extension use and enterprises may require managed extensions. + +### Retain Chromium's extension plane and add explicit OriginWeave grants + +Selected. + +## Decision + +1. **Retain Chromium Manifest V3 as the compatibility plane.** OriginWeave does not create a competing Rust extension API for browser compatibility. +2. **Separate execution modes.** Human Mode may use the person's compatible extension set under browser/enterprise policy. Agent Task Mode defaults to no extensions or an explicit managed allow-list. Later attached-human-tab execution is labelled reduced-assurance when pre-existing extensions can influence page state. +3. **Require explicit OriginWeave extension authority.** Any extension-to-Agent interaction that can affect an Agent Task requires an `extension_grant` or equivalent typed decision bound at minimum to extension identity/version policy, session, applicable browsing context, capability, origin/resource scope, expiry, and task. +4. **Never translate Chrome permission into Agent capability.** `tabs`, `scripting`, `downloads`, `declarativeNetRequest`, host permissions, native messaging, or managed policy do not grant OriginWeave navigation, action, approval, secret, or sensitive-data authority. +5. **Keep extension output untrusted.** Extension messages and content enter the bounded observation/provenance path. They cannot alter the trusted goal, add tools, mint capabilities, approve high-risk actions, or weaken deterministic policy. +6. **Keep protected values brokered.** An extension does not receive raw credentials or sensitive values merely because it can inspect or modify a page. Independent secret/sensitive-data authority is rechecked immediately before trusted browser dispatch. +7. **Bound native messaging separately.** Native messaging is supported only behind an explicit host-managed allow-list, exact extension/host identity policy, process boundary, bounded I/O, and auditable lifecycle. It remains unsupported until that executable boundary exists. +8. **Publish exact compatibility evidence.** Public extension claims are bound to an exact Chromium revision/build and explicit Manifest V3 capability matrix. OriginWeave does not claim universal or `100% Chrome extension compatibility`. +9. **Separate Chrome-only services.** Web Store distribution, Google-account services, proprietary codecs/DRM, licensing, and other Chrome-only services are not implied by Manifest V3 compatibility. +10. **Gate releases by declared surfaces.** A declared supported capability that regresses blocks release or must be removed from the published matrix before release. Compatibility success never substitutes for Agent-authority-isolation evidence. + +## Consequences + +OriginWeave can preserve mature Chromium extension behavior while keeping its differentiating authority logic in reusable Rust modules. Buyers receive exact, falsifiable compatibility claims and separately reviewable security evidence. The cost is maintaining both a real-browser compatibility suite and independent authority-isolation tests, plus explicit managed-extension/native-host lifecycle work. + +## Failure and degraded behavior + +- A failed declared MV3 fixture makes that capability unsupported for the affected pinned release until fixed or removed from the published matrix. +- Invalid extension identity, grant scope, session/context binding, origin, expiry, or task fails closed. +- Attempts to widen task authority, inject a trusted instruction, resolve a secret, or synthesize approval are denied and recorded as bounded credential-free evidence. +- Missing native-host policy/process isolation keeps native messaging unsupported rather than falling back to ambient process execution. +- Attached human-tab sessions with unknown extensions are reduced-assurance and cannot inherit isolated-task release claims. + +## Security / privacy / governance impact + +The decision reduces confused-deputy and prompt-injection risk by keeping Chrome extension permissions outside OriginWeave policy. Secret and sensitive-data disclosure remain independently purpose-bound. Extension observations and compatibility diagnostics must not expose raw credentials, arbitrary local filesystem paths, unrestricted native-process output, or protected values in logs/evidence. Enterprise-managed extension policy is policy input, not a replacement for task authorization. + +## Tests and acceptance evidence + +Issue #27 acceptance requires pinned-Chromium evidence for the declared matrix and separate production authority tests, including service-worker/content-script lifecycle, declared APIs, restart/update persistence, Agent Task isolation without a grant, managed-grant success, denial of origin/action widening, untrusted-message handling, secret non-disclosure, exact build binding, repeated-run evidence, native-messaging denial until implemented, and release failure when a public capability regresses. + +Current active compatibility PRs are evidence only for their unchanged exact heads. They do not make this Proposed ADR Accepted or close issue #27. + +## Migration and rollback + +No persistent database migration is introduced. A release can roll back the Chromium baseline, disable a managed extension, revoke an `extension_grant`, or remove an unproven capability from the published matrix without widening authority. Rollback evidence must retain the exact Chromium/build/capability set that was tested. + +## Open follow-ups + +- Complete issue #27's compatibility matrix and production isolation acceptance. +- Define managed-extension identity/update semantics. +- Implement the native-messaging allow-list/process boundary before claiming support. +- Integrate the complete Agent Task browser vertical slice under issue #28. +- Reconcile PRD/TRD/traceability from protected-main evidence as compatibility slices integrate. +- Promote this ADR only through explicit protected-main governance. + +## Supersession / reversal conditions + +Supersede this ADR if Chromium adopts a materially different extension authority model, OriginWeave intentionally drops Chromium extension compatibility, or an accepted architecture provides safer equivalent compatibility without ambient Agent authority. A successor must retain explicit compatibility evidence and task-authority separation. + +## References + +Primary browser/extension/protocol evidence and APA 7 references are maintained in [`../doctoring/browser-agent-protocols.md`](../doctoring/browser-agent-protocols.md) and [`../doctoring.md`](../doctoring.md). Related decisions include ADR 0001, ADR 0002, ADR 0007, ADR 0010, ADR 0101, ADR 0104, and ADR 0107. \ No newline at end of file diff --git a/docs/adr/0014-architecture-decision-governance.md b/docs/adr/0014-architecture-decision-governance.md new file mode 100644 index 0000000..d550f84 --- /dev/null +++ b/docs/adr/0014-architecture-decision-governance.md @@ -0,0 +1,112 @@ +# ADR 0014: Architecture decision acceptance governance + +- **Status:** Proposed +- **Date:** 2026-08-10 +- **Supersedes:** None +- **Superseded by:** None + +## Context + +OriginWeave separates protected-main source, executable checks, formal review, documentation, release evidence, and runtime policy as distinct authorities. Architecture Decision Records need the same discipline: a Markdown file, issue, chat statement, automation prompt, model verdict, or PR body can propose a decision but cannot independently make it an Accepted governing decision. + +Current contributor authority comes from protected-main `AGENTS.md`, live GitHub policy, and any explicit operationally satisfiable CWL/OriginWeave governance rule. The current contract also describes a solo-maintainer condition: an otherwise impossible independent non-author approval rule is not manufactured when fewer than two eligible independent maintainers exist, while technical/security/coverage/rustdoc/findings/live-base/branch-protection gates remain mandatory. + +The ADR index previously repeated these binding details directly. An index should discover governance rather than create it. This ADR therefore records the proposed durable acceptance model and its reversal conditions. While Proposed, it does not override `AGENTS.md` or live GitHub policy. + +## Decision drivers + +- Prevent indexes, chat, model output, or stale PR evidence from silently changing architecture authority. +- Never synthesize, impersonate, self-submit, or fabricate approval that current policy requires. +- Avoid permanent solo-maintainer deadlock when an independent reviewer route does not operationally exist and GitHub does not require one. +- Keep exact-head technical evidence mandatory regardless of review topology. +- Make reviewer-provisioning gaps explicit and reversible. +- Keep ADR status machine-checkable without turning README prose into a hidden policy engine. + +## Assumptions and authority boundaries + +- Protected-main `AGENTS.md` and live GitHub rules are authoritative for contributor actions. +- This ADR remains Proposed until a protected-main revision explicitly records an Accepted lifecycle transition in this ADR's metadata and both canonical indexes. +- Merely merging a file that still says `Proposed` does not Accept it. +- Formal review and technical checks are separate evidence classes. +- A review counts only if the governing policy recognizes that reviewer identity and review state for the relevant exact head. +- Predecessor-head approval does not transfer across a changed head unless live policy explicitly defines that behavior. + +## Options considered + +### Define ADR acceptance only in the index README + +Rejected. The index should summarize and discover decisions, not define the binding algorithm that grants its own statuses. + +### Require non-author approval unconditionally + +Rejected. In a genuine solo-maintainer topology this creates an unsatisfiable governance deadlock and pressure to invent reviewer identities or weaken the rule. + +### Let the author or automation synthesize approval + +Rejected. Self-approval, impersonation, model verdicts, reactions, status checks, or fabricated identities cannot provide independent review evidence. + +### Bind acceptance to live protected-branch governance with a narrow solo-maintainer hold + +Selected. + +## Decision + +If Accepted, OriginWeave applies these durable ADR-governance rules: + +1. **Explicit protected-main lifecycle transition defines architecture acceptance.** A branch file, issue, chat statement, prompt, PR body, check, model verdict, or merge by itself does not create a governing Accepted ADR. An ADR becomes Accepted only when a protected-main revision explicitly changes that ADR's lifecycle metadata to `Accepted` and both `docs/README.md` and `docs/adr/README.md` mirror the same status. A Proposed ADR that merely reaches protected main remains Proposed. +2. **Live policy defines mandatory review evidence.** When current GitHub rules require counted approval, acceptance requires a formal `APPROVED` review from an eligible identity recognized by that policy on the applicable unchanged head. +3. **Repository-specific review requirements must be operationally satisfiable.** A stricter CWL/OriginWeave rule may require an eligible non-author reviewer only when a legitimate reviewer route exists. +4. **No synthetic approval.** Author approval, COMMENTED reviews, reactions, model verdicts, statuses, predecessor-head approvals, impersonated identities, and fabricated accounts never substitute for required counted approval. +5. **The solo-maintainer hold is narrow.** When fewer than two eligible independent maintainers exist and live GitHub policy does not independently require counted non-author approval, an otherwise impossible repository-level independent-review requirement is held. CI, security, SAST, exact owned-code coverage, rustdoc, unresolved findings/threads, live-base, mergeability, branch protection, release, and operational evidence remain mandatory. +6. **Reviewer provisioning is a first-class state.** If live policy requires independent approval but no eligible reviewer route exists, the PR is reviewer-provisioning-blocked. The remedy is legitimate reviewer/team/App provisioning or an authorized governance change, never self-approval or gate weakening. +7. **The hold reverses automatically.** Independent-review enforcement returns when two or more eligible independent maintainers exist, live GitHub policy requires it, or an Accepted successor defines another legitimate counted-review route. +8. **Indexes discover; they do not grant status.** `docs/README.md` and `docs/adr/README.md` must mirror each ADR's explicit lifecycle metadata and protected-main location. +9. **Design authority is not implementation evidence.** Even an Accepted ADR does not prove described behavior is implemented or released; protected-main code/tests/artifacts/configuration and claim-appropriate operational evidence establish that truth. + +## Consequences + +The repository can remain review-realistic without weakening technical gates, and maintainer-topology changes have explicit re-enablement semantics. The trade-off is that reviewer eligibility and live policy must be re-evaluated when governance changes; some otherwise-green work may legitimately remain blocked on reviewer provisioning. + +## Failure and degraded behavior + +- If live review requirements cannot be determined, do not infer permission to accept or merge; treat review authority as unresolved and continue non-conflicting work. +- If a required reviewer cannot be provisioned under current authority, classify the exact PR/head as reviewer-provisioning-blocked. +- If an ADR index and file disagree, the documentation contract fails until repaired. +- If an Accepted ADR describes behavior absent from protected-main implementation evidence, product docs must label that capability partial/planned rather than shipped. + +## Security / privacy / governance impact + +This is governance hardening. It prevents automation from manufacturing social proof, preserves branch/ruleset authority, and keeps model/check output non-authoritative for approval. It introduces no new secret or personal-data path. + +## Tests and acceptance evidence + +The documentation contract must prove that every ADR file is indexed exactly once in both canonical indexes, index status matches file metadata, Accepted and Proposed entries are not silently interchanged, superseded decisions retain discoverable successors where applicable, and active-PR ADRs are not presented as protected-main implementation evidence. README prose should point to `AGENTS.md`, live GitHub policy, and this ADR instead of independently redefining the acceptance algorithm. + +Operational acceptance for an actual merge additionally requires a current-authority probe of GitHub rules and reviewer eligibility whenever counted review matters; a documentation test cannot prove runtime reviewer eligibility. + +## Migration and rollback + +No database or runtime migration is introduced. On acceptance, duplicate binding review logic should be removed from ADR-index prose and replaced by concise references to `AGENTS.md`, live GitHub policy, and this ADR. A superseding governance change must update both indexes and contributor-governance documentation coherently. + +## Open follow-ups + +- Keep the machine-checkable ADR-index/status contract aligned with lifecycle and supersession states. +- Re-evaluate reviewer topology whenever maintainers, teams, Apps, or branch rules change. +- Keep scheduler prompts subordinate to protected-main `AGENTS.md` and live GitHub policy. +- Record any future organization-wide reviewer authority and its eligibility boundary in an Accepted successor before relying on it as repository-specific governance. + +## Supersession / reversal conditions + +Supersede this ADR if GitHub governance changes to a materially different review model, the organization adopts a managed independent-review service/team with explicit eligibility semantics, or OriginWeave changes its ADR lifecycle. A successor must retain the prohibitions on synthetic approval and on treating technical/model evidence as formal review authority. + +## References + +ContextualWisdomLab. (2026). *Agent development contract* [Repository specification]. *OriginWeave*. [`../../AGENTS.md`](../../AGENTS.md) + +ContextualWisdomLab. (2026). *OriginWeave architecture decision records* [Repository specification]. *OriginWeave*. [`README.md`](README.md) + +GitHub. (n.d.). *Approving a pull request with required reviews*. GitHub Docs. Retrieved August 10, 2026, from https://docs.github.com/en/pull-requests/how-tos/review-pull-requests/approving-a-pull-request-with-required-reviews + +GitHub. (n.d.). *About protected branches*. GitHub Docs. Retrieved August 10, 2026, from https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches + +Current repository settings remain mutable runtime policy and must be probed live; these references document GitHub review/protection semantics rather than freezing the repository's current configuration into this ADR. diff --git a/docs/adr/README.md b/docs/adr/README.md index 2838a12..416231b 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -1,22 +1,22 @@ # OriginWeave Architecture Decision Index -This directory contains durable architecture decisions for OriginWeave. A pull-request body, chat transcript, roadmap bullet, or implementation plan may motivate a decision but does not replace an ADR when the decision changes a governing product or authority boundary. +This directory contains durable architecture decisions for OriginWeave. A pull-request body, chat transcript, roadmap bullet, automation prompt, issue, or implementation plan may motivate a decision but does not replace an ADR when the decision changes a governing product or authority boundary. ## Status vocabulary - **Proposed** — under review; not binding and not a shipped claim. -- **Accepted** — governing design decision on protected `main`; acceptance does not by itself prove that every described capability is implemented. +- **Accepted** — governing design decision on protected `main`; acceptance does not itself prove that every described capability is implemented. - **Superseded** — replaced by a later Accepted ADR; retained for history. - **Deprecated** — still discoverable but no longer recommended for new work. - **Rejected** — evaluated and intentionally not adopted. -An ADR becomes Accepted only through normal protected-branch review and merge. Where live repository policy or explicit CWL/OriginWeave governance requires independent review, acceptance also requires a qualifying non-author formal `APPROVED` review on the unchanged exact head. COMMENTED reviews, check/status results, model verdicts, reactions, author approval, predecessor-head approval, or dismissed reviews never substitute for that requirement. Conversation-derived ideas remain Proposed/Open in PRD/TRD/traceability until the protected process is complete. +Current contributor/review authority is defined by protected-main [`../../AGENTS.md`](../../AGENTS.md) together with live GitHub repository policy. [ADR 0014](0014-architecture-decision-governance.md) records the proposed durable ADR-acceptance model, including reviewer eligibility, the solo-maintainer hold, re-enablement conditions, and the prohibition on synthetic approval. While ADR 0014 is Proposed, it does not override those live authorities. COMMENTED reviews, check/status results, model verdicts, reactions, author approval, predecessor-head approval, or dismissed reviews never substitute for a review that current policy actually requires. -An Accepted ADR is **design authority, not implementation evidence**. Protected-main source, executable tests, built/released artifacts, migrations/configuration, and protected-main operational evidence appropriate to the claim establish current implemented behavior. An ADR may intentionally describe an accepted target that is only partially implemented; the product documents must label that implementation status separately. +An Accepted ADR is **design authority, not implementation evidence**. Protected-main source, executable tests, built/released artifacts, migrations/configuration, and protected-main operational evidence appropriate to the claim establish current implemented behavior. An ADR may intentionally describe an accepted target that is only partially implemented; product documents must label implementation status separately. -## Current protected-main decisions +## Accepted protected-main decisions -| ADR | Decision | Protected-main status | Governs | +| ADR | Decision | Status | Governs | |---|---|---|---| | [0001](0001-chromium-compatibility-kernel.md) | Retain Chromium as the compatibility kernel | Accepted | Blink/V8/graphics/extensions boundary; Rust control-plane integration | | [0002](0002-agent-safety-kernel.md) | Agent safety kernel | Accepted | mode, capability, origin, risk, crawler, secret and approval policy | @@ -24,13 +24,19 @@ An Accepted ADR is **design authority, not implementation evidence**. Protected- | [0004](0004-resolved-destination-policy.md) | Logical origin and resolved destination safety | Accepted | SSRF/rebinding/special-purpose address and redirect authority | | [0005](0005-direct-socket-binding.md) | Exact direct TCP peer binding | Accepted | explicit socket authority and operating-system peer proof | | [0006](0006-tls-server-identity.md) | TLS service identity over the verified peer | Accepted | WebPKI identity, roots, time, ALPN and stream binding | +| [0007](0007-purpose-bound-sensitive-data-authority.md) | Purpose-bound sensitive-data authority | Accepted | tenant/task/field/purpose/destination/classification disclosure authority | +| [0008](0008-leaf-validity-horizon.md) | Delegated-task TLS leaf-validity horizon | Accepted | minimum certificate-validity horizon for bounded delegated tasks | +| [0010](0010-session-context-bound-node-authority.md) | Session/context-bound node authority | Accepted | browser-session, browsing-context, origin, document-epoch and stale-node authority | + +## Proposed architecture decisions -## Proposed target-architecture decisions in this change +Proposed ADR files are reviewable target architecture without becoming Accepted or shipped behavior. The provenance subsections distinguish files already present in the protected-main baseline from decisions introduced by this documentation reconciliation. Provenance never changes lifecycle: file presence on an active branch is not protected-main truth, and later integration does not itself promote a Proposed ADR to Accepted. -The following ADRs make the product-wide target architecture reviewable without promoting it to shipped behavior. They remain **Proposed** until their exact branch is reviewed and merged under protected-main policy. Existing feature PRs may independently carry lower-numbered Proposed ADRs; the `0100` range avoids claiming or conflicting with those active decisions. +### Protected-main baseline proposed decisions | ADR | Decision | Status | Governs | |---|---|---|---| +| [0009](0009-hourly-agent-credential-boundary.md) | Hourly agent credential boundary | Proposed | deterministic gates, NVIDIA credential materialization, local broker and publication separation | | [0100](0100-rust-control-plane-boundary.md) | Rust control-plane boundary | Proposed | Rust-owned product authority versus Chromium compatibility kernel | | [0101](0101-isolated-execution-profile-modes.md) | Isolated execution/profile modes | Proposed | Human, Assist, Agent Task and Crawler session/profile isolation | | [0102](0102-typed-actions-and-arbitrary-js.md) | Typed actions over arbitrary JavaScript authority | Proposed | action API, script escape hatches, risk/policy semantics | @@ -42,7 +48,29 @@ The following ADRs make the product-wide target architecture reviewable without | [0108](0108-crawler-policy.md) | Policy-bound crawler mode | Proposed | robots, rate/resource policy, read-only collection and no-evasion behavior | | [0109](0109-hourly-automation-operational-closure.md) | Hourly automation secret ordering and operational closure | Proposed | deterministic gates, model secret boundary, retries and protected-main proof | -Active feature PRs may contain additional Proposed ADRs. Those ADRs are not described as Accepted until their exact changes merge. When an ADR becomes protected-main architecture, update this index in the same protected change or an immediately coupled documentation repair. +### Proposed decisions introduced by documentation reconciliation + +| ADR | Decision | Status | Governs | +|---|---|---|---| +| [0013](0013-manifest-v3-extension-authority.md) | Manifest V3 compatibility and extension-to-Agent authority | Proposed | Chromium extension compatibility evidence, profile separation, extension grants, native-messaging boundary and release claims | +| [0014](0014-architecture-decision-governance.md) | Architecture decision acceptance governance | Proposed | ADR lifecycle authority, reviewer eligibility, solo-maintainer hold and re-enablement conditions | + +ADR 0013 and ADR 0014 exist only on this documentation branch until it integrates. After integration, this subsection remains historical provenance rather than an active-PR claim; both decisions remain Proposed until a later policy-compliant change explicitly changes their lifecycle. + +Other active feature PRs may contain additional Proposed ADRs. Those files are not part of this canonical documentation line until integrated or deliberately reconciled here. Historical PR checks, stale branch state, or chat decisions never transfer ADR acceptance across a changed head. + +## Index completeness rule + +Every numbered ADR file in the canonical documentation tree under review must be discoverable from this index with a status that agrees with the ADR's own lifecycle metadata. The protected-main subset must remain exact, while feature ADRs outside this canonical line belong in their owning PR's traceability until integration. When an ADR is added, accepted, superseded, deprecated, or rejected, update this index in the same protected change or an immediately coupled documentation reconciliation. + +The machine-checkable documentation contract should fail when: + +- a numbered ADR file in the canonical documentation tree is absent from this index; +- this index claims `Accepted` while the ADR metadata says `Proposed`, or the reverse; +- a superseded ADR lacks a discoverable successor; +- branch provenance is presented as lifecycle status or protected-main implementation evidence; +- an active-PR ADR is presented as protected-main implementation evidence; or +- a stale PR number, SHA, run ID, automation prompt, or conversation statement is used as timeless architecture authority. ## Decisions that require a dedicated ADR @@ -59,9 +87,10 @@ A new or superseding ADR is required when a change materially alters any of the 9. resource-governor priority, telemetry or GPU/CPU fallback semantics; 10. evidence/provenance identity, retention or persistence boundaries; 11. WebDriver BiDi, CDP, WebMCP, MCP or OriginWeave Protocol authority/version boundaries; -12. Manifest V3 extension-to-agent authorization; +12. Manifest V3 extension-to-agent authorization or compatibility evidence policy; 13. tenant, privacy, residency, audit, deployment or enterprise-control ownership; -14. release acceptance, rollback/recovery or protected-main operational-proof requirements. +14. hourly automation credential, writer, continuation or protected-main operational-proof authority; or +15. release acceptance, rollback/recovery or protected-main operational-proof requirements. ## Required ADR structure @@ -100,5 +129,6 @@ Material external standards or research belong in APA 7th format in [`../doctori - [`../uml/README.md`](../uml/README.md) visualizes component, sequence, state and deployment relationships. - [`../erd/README.md`](../erd/README.md) defines the conceptual durable domain model. - [`../traceability/README.md`](../traceability/README.md) maps requirements and decisions to implementation and evidence. +- [`../DOCUMENTATION_FITNESS.md`](../DOCUMENTATION_FITNESS.md) records semantic completeness and stale/current findings across the graph. -If these artifacts disagree about what is currently implemented, protected-main source, executable tests, built/released artifacts, configuration/migrations, and protected-main operational evidence appropriate to the claim define implementation truth. Accepted ADRs explain the governing design decision and expected boundary; they do not upgrade missing behavior into shipped behavior. The disagreement is a documentation or implementation defect that must be repaired rather than silently rationalized from conversation history. +If these artifacts disagree about current implementation, protected-main source, executable tests, built/released artifacts, configuration/migrations, and protected-main operational evidence appropriate to the claim define implementation truth. Accepted ADRs explain governing design decisions; they do not upgrade missing behavior into shipped behavior. The disagreement is a documentation or implementation defect that must be repaired rather than silently rationalized from conversation history. \ No newline at end of file diff --git a/docs/doctoring/browser-agent-protocols.md b/docs/doctoring/browser-agent-protocols.md new file mode 100644 index 0000000..5173a32 --- /dev/null +++ b/docs/doctoring/browser-agent-protocols.md @@ -0,0 +1,79 @@ +# Browser and Agent Protocol Standards Evidence + +- **Reviewed:** 2026-08-10 +- **Purpose:** primary-source evidence for OriginWeave browser compatibility and adapter boundaries +- **Canonical research index:** [`../doctoring.md`](../doctoring.md) + +This addendum complements the main doctoring record. The main record already carries the WebDriver BiDi, WARC/ISO 28500 and W3C PROV-O evidence. This addendum records the current primary sources for Manifest V3, Chrome DevTools Protocol, WebMCP and Model Context Protocol so product documentation does not rely on uncited protocol names. + +## WebDriver BiDi + +The W3C publication reviewed for this baseline is the 1 June 2026 **Working Draft**, not a Recommendation. OriginWeave therefore treats BiDi as a versioned browser-automation adapter rather than product-internal authority. Raw BiDi session/context/node identifiers do not become durable OriginWeave identities. + +Primary source: World Wide Web Consortium, *WebDriver BiDi*. + +## Chrome Manifest V3 + +Chrome's current manifest documentation identifies Manifest V3 as the current extension manifest format and the supported `manifest_version` value. OriginWeave therefore tests its declared extension compatibility against a pinned real Chromium/Chrome-for-Testing build and publishes evidence by exact capability. This is a compatibility target, not a claim of universal Chrome/Web Store/Google-service/codec/DRM equivalence. + +A Chrome extension permission remains separate from an OriginWeave Agent capability. Passing MV3 compatibility tests does not prove Agent-authority isolation, and a correct extension-grant kernel does not prove a real Chrome extension API works. + +Primary source: Chrome for Developers, *Manifest file format* and *Manifest Version*. + +## Chrome DevTools Protocol + +The official CDP documentation states that tip-of-tree changes frequently and provides no backward-compatibility guarantee for capabilities it introduces. OriginWeave therefore pins the Chromium/protocol evidence used by a release and keeps CDP behind an adapter. CDP is useful for Chromium-specific Network, Accessibility, DOMSnapshot, tracing and diagnostic surfaces; it is not the durable OriginWeave authority model. + +Primary source: Chrome DevTools Protocol, *Chrome DevTools Protocol—Latest (tip-of-tree)*. + +## WebMCP + +Chrome's 2026 WebMCP documentation describes WebMCP as an experimental/proposed structured-tool surface and its security guidance explicitly discusses indirect prompt injection and `untrustedContentHint`. The reviewed Chrome material is associated with an origin-trial / intent-to-experiment path. OriginWeave may prefer a valid structured WebMCP tool over lower-level scraping when present, but WebMCP remains optional and adapter-bound. + +WebMCP tool definitions, extension-produced content and tool outputs are untrusted observations. They cannot mint OriginWeave capabilities, alter the trusted task goal, resolve secrets, or approve high-risk actions. + +Primary sources: Chrome for Developers, *WebMCP*; *WebMCP tool security*; *Agent security considerations for WebMCP*. + +## Model Context Protocol + +The Model Context Protocol project released specification version `2026-07-28` on 28 July 2026. That release moved the protocol core toward stateless request/response operation and removed the earlier protocol-session assumptions described by previous releases. OriginWeave therefore keeps durable browser state in explicit OriginWeave application handles and exposes MCP only as a high-level adapter to the Rust runtime. MCP clients or servers do not connect models directly to Chromium/CDP authority. + +Primary sources: Model Context Protocol, *2026-07-28 Specification* and the maintainers' official release announcement. + +## Provenance standards + +The main [`docs/doctoring.md`](../doctoring.md) records the stable W3C PROV-O Recommendation and ISO 28500:2017 WARC format. OriginWeave treats both as interoperability/persistence adapters around its typed evidence identities. A WARC record, PROV statement, model judgement, check result or action log is evidence of its own class; none becomes authorization merely because it is captured in a provenance format. + +## Product consequences + +1. Version adapter contracts independently from OriginWeave session/context/action/evidence types. +2. Pin exact Chromium/CDP compatibility evidence at release time. +3. Keep WebDriver BiDi's Working Draft status visible in compatibility claims. +4. Keep WebMCP experimental/optional and propagate untrusted-content semantics. +5. Keep MCP browser state application-level rather than equating protocol transport/session metadata with browser authority. +6. Test Manifest V3 compatibility and extension-to-Agent authority isolation as separate evidence classes. +7. Treat WARC/PROV as provenance representations, not policy or truth escalation. + +## References — APA 7th + +Chrome DevTools Protocol. (n.d.). *Chrome DevTools Protocol—Latest (tip-of-tree)*. Retrieved August 10, 2026, from https://chromedevtools.github.io/devtools-protocol/tot/ + +Google Chrome Developers. (n.d.). *Manifest file format*. Chrome for Developers. Retrieved August 10, 2026, from https://developer.chrome.com/docs/extensions/reference/manifest + +Google Chrome Developers. (n.d.). *Manifest Version*. Chrome for Developers. Retrieved August 10, 2026, from https://developer.chrome.com/docs/extensions/reference/manifest/manifest-version + +Google Chrome Developers. (2026). *WebMCP*. Chrome for Developers. https://developer.chrome.com/docs/ai/webmcp + +Pagnucco, J., & Klepper, A. (2026, June 9). *Agent security considerations for WebMCP*. Chrome for Developers. https://developer.chrome.com/docs/agents/security + +Pagnucco, J., & Klepper, A. (2026, June 9). *WebMCP tool security*. Chrome for Developers. https://developer.chrome.com/docs/ai/webmcp/secure-tools + +Soria Parra, D., & Delimarsky, D. (2026, July 28). *The 2026-07-28 specification*. Model Context Protocol. https://blog.modelcontextprotocol.io/posts/2026-07-28/ + +Model Context Protocol. (2026). *Model Context Protocol specification (2026-07-28)*. https://modelcontextprotocol.io/specification/2026-07-28 + +World Wide Web Consortium. (2013). *PROV-O: The PROV ontology*. https://www.w3.org/TR/prov-o/ + +World Wide Web Consortium. (2026, June 1). *WebDriver BiDi* (W3C Working Draft). https://www.w3.org/TR/2026/WD-webdriver-bidi-20260601/ + +International Organization for Standardization. (2017). *Information and documentation—WARC file format* (ISO Standard No. 28500:2017). https://www.iso.org/standard/68004.html diff --git a/docs/doctoring/mv3-compatibility.md b/docs/doctoring/mv3-compatibility.md index 607a248..571c493 100644 --- a/docs/doctoring/mv3-compatibility.md +++ b/docs/doctoring/mv3-compatibility.md @@ -1,14 +1,54 @@ # Manifest V3 compatibility evidence baseline - **Status:** Active implementation evidence for issue #27 -- **Reviewed:** 2026-08-09 +- **Reviewed:** 2026-08-11 - **Pinned browser:** Chrome for Testing `150.0.7871.129`, Chromium revision `r1639810` -OriginWeave uses Chromium as its compatibility kernel, so browser-extension compatibility must be demonstrated with executable Chromium evidence rather than inferred from architecture alone. This first bounded lane exercises a controlled unpacked Manifest V3 extension against one exact Chrome for Testing build. It covers an extension service worker, content-script injection, `chrome.storage.local`, declarative network blocking, and one real WebDriver click/post-condition. It does **not claim 100% Chrome extension compatibility** and does not make claims about Chrome Web Store distribution, Google-only services, proprietary codecs, DRM, native messaging, enterprise policy, restart/update migration, or every Chrome extension API. +OriginWeave uses Chromium as its compatibility kernel, so browser-extension compatibility must be demonstrated with executable Chromium evidence rather than inferred from architecture alone. The protected-main lane exercises a controlled unpacked Manifest V3 extension against one exact Chrome for Testing build and proves service-worker, content-script, storage, declarative-network-request, tabs, windows, scripting, commands, side-panel, bookmarks/history read compatibility, restart persistence, repeatability, and one real WebDriver click/post-condition. Active stacked compatibility work adds downloads, bounded bookmark/history mutation, profile isolation, explicit extension update/version-migration evidence, and an exact content-script isolated-world check. OriginWeave does **not claim 100% Chrome extension compatibility**. -The checked-in fixture is intentionally local-only. Its host permission is limited to loopback HTTP used by the deterministic test server. It contains no remote code, user credential, model call, external content, native-messaging host, or production PII. Chrome permissions remain distinct from the explicit OriginWeave extension-to-Agent grant implemented in `originweave-core`. +The checked-in fixture is intentionally local-only. Its host permission is limited to loopback HTTP used by the deterministic test server. It contains no remote code, user credential, model call, external content, native-messaging host, or production PII. Chrome permissions remain distinct from the explicit OriginWeave extension-to-Agent grant implemented in `originweave-core`. Compatibility mutation tests create only controlled synthetic state inside the ephemeral test profile and must clean it up; successful API compatibility never grants the OriginWeave Agent ambient bookmarks/history/downloads authority. -The CI lane downloads the exact Chrome/ChromeDriver version from the official Chrome for Testing public bucket, records SHA-256 receipts for the downloaded archives, verifies the runtime-reported browser version, and emits bounded JSON compatibility evidence. A future release-quality compatibility matrix should additionally pin published artifact digests or equivalent immutable supply-chain identity when the upstream distribution exposes that identity in an authoritative machine-readable form. +## Supported-capability evidence matrix + +This matrix separates protected-main executable evidence from active, non-shipped evidence and from genuinely unproven surfaces. A row marked **ACTIVE_PR** is never a release claim; exact head/run provenance belongs in `docs/evidence/2026-08-10-active-pr-maturity.md` and must be refreshed when the branch changes. + +| Compatibility surface | Evidence maturity | Current evidence boundary | Known gap / non-claim | +|---|---|---|---| +| Manifest V3 unpacked extension load | **PROTECTED_MAIN** | Exact pinned Chromium fixture loads through the dedicated compatibility workflow. | No Chrome Web Store distribution or arbitrary third-party extension-install claim. | +| Service worker start/restart + event response | **PROTECTED_MAIN** | Worker startup count and message response are observed across a real browser restart. | Suspend timing and the full Chrome event catalog are not exhaustively covered. | +| Content-script injection | **PROTECTED_MAIN** | Controlled content script mutates bounded DOM evidence on loopback. | Injection alone does not prove JavaScript isolated-world semantics. | +| Content-script isolated-world separation | **ACTIVE_PR #61** | Page main-world and extension isolated-world JavaScript assign the same sentinel name to distinct values; compatibility reports ready only while the page still reads `page` and the content script reads `extension` in real pinned Chromium. | One deterministic fixture proof only; no arbitrary page-JavaScript bridge or Agent authority. | +| `chrome.storage.local` + restart persistence | **PROTECTED_MAIN** | State is initialized on the first browser pass and required to persist on restart. | No OriginWeave-owned durable application database is implied. | +| `declarativeNetRequest` | **PROTECTED_MAIN** | Controlled local rule blocks its fixture request in pinned Chromium. | No claim for every DNR rule/action combination. | +| `tabs`, `windows`, `scripting`, `commands`, `sidePanel` | **PROTECTED_MAIN** | Each declared API is exercised in real Chromium and required by the repeatability gate. | Chrome API permission does not become Agent capability. | +| Bookmarks read compatibility | **PROTECTED_MAIN** | Protected-main fixture exercises the declared bookmarks surface. | Ambient human-profile bookmark authority is not granted. | +| Bookmarks create/read/delete lifecycle | **ACTIVE_PR #56** | Controlled synthetic bookmark is created, read back, and removed in the ephemeral compatibility profile. | Compatibility only; no Agent bookmark capability. | +| History read compatibility | **PROTECTED_MAIN** | Protected-main fixture exercises bounded history search in the isolated profile. | No model-visible browsing-history content or default-profile access. | +| History add/read/delete lifecycle | **ACTIVE_PR #59** | Controlled synthetic loopback visit is added, exactly read back, deleted in `finally`, and required to be absent afterward. | Compatibility only; no Agent history capability. | +| Downloads | **ACTIVE_PR #43** | Controlled loopback payload is downloaded and validated through pinned Chromium. | No general download persistence, unsafe filename, or Agent filesystem authority claim. | +| Per-trial Agent Task profile isolation | **ACTIVE_PR #49** | Compatibility trials use isolated ephemeral profiles rather than ambient human state. | Full production Agent Task browser orchestration remains issue #28 work. | +| Extension update/version migration | **ACTIVE_PR #60** | Trial-local extension copy transitions `1.0.0` → `1.0.1` on the same ephemeral profile; versioned storage state is required to migrate and real pinned-Chromium evidence reports the update-migration surface. | No Chrome Web Store updater, enterprise deployment channel, arbitrary downgrade, or protected-main release claim. | +| Managed enterprise extension policy | **PLANNED** | No protected-main executable compatibility proof yet. | Do not infer managed-policy support from Chromium ancestry alone. | +| Native messaging | **PLANNED / SECURITY-GATED** | No compatibility claim. | Future support requires an explicit host-managed allow-list and process boundary. | +| Google-only services, proprietary codecs, DRM, Web Store licensing | **OUT_OF_SCOPE FOR COMPATIBILITY CLAIM** | Deliberately excluded from the open compatibility claim. | Chromium/API compatibility must not be conflated with Google service or licensing equivalence. | + +The release-quality capability matrix must remain coupled to executable evidence. Adding a row to documentation never creates support; declaring a new supported capability must first add a realistic regression test and pinned-Chromium proof. Conversely, if a declared protected-main capability regresses, the release gate must fail rather than silently downgrading the matrix. + +## History API primary evidence + +For history compatibility specifically, the current official Chrome Extensions API documents the `history` manifest permission and Promise-returning `chrome.history.addUrl`, `chrome.history.search`, and `chrome.history.deleteUrl` methods. This living vendor reference establishes API semantics only. OriginWeave release evidence continues to depend on the exact pinned Chromium fixture and exact-head CI result rather than inferring compatibility from documentation. + +## Update-migration evidence boundary + +Restart persistence and extension update migration are separate compatibility claims. A successful restart proves only that state survives a new browser process. The active update-migration lane additionally uses a trial-local copy of the checked-in fixture, preserves the same extension path and ephemeral profile across passes, changes only the controlled manifest version from `1.0.0` to `1.0.1`, observes `chrome.runtime.getManifest().version`, and requires the fixture schema marker to migrate from version 1 to version 2. The checked-in fixture is not rewritten by the test. This establishes one deterministic unpacked-extension version transition; it does not establish Chrome Web Store update behavior, enterprise rollout semantics, downgrade behavior, or arbitrary third-party extension migration safety. + +## Isolated-world evidence boundary + +Content-script injection and content-script JavaScript isolation are separate compatibility claims. Active PR #61 writes `window.originweaveWorldSentinel = "page"` in the fixture page's main world and repeatedly publishes that value through one controlled DOM attribute. The content script assigns the same global name to `"extension"` in its own execution world, waits a bounded interval, and only reports the existing compatibility surface ready when it simultaneously observes the page's published `page` value and its own `extension` value. If both scripts share one JavaScript global namespace, the page publisher changes to `extension` and real-browser compatibility fails. DOM sharing here is deliberate test evidence, not permission for arbitrary page content to become trusted instruction or Agent authority. + +## Supply-chain and repeatability evidence + +The CI lane downloads the exact Chrome/ChromeDriver version from the official Chrome for Testing public bucket, records SHA-256 receipts for the downloaded archives, verifies the runtime-reported browser version, and emits bounded JSON compatibility evidence. A future release-quality matrix should additionally pin published artifact digests or equivalent immutable supply-chain identity when the upstream distribution exposes that identity in an authoritative machine-readable form. ## Primary references — APA 7th @@ -20,6 +60,8 @@ Chrome for Developers. (2023, May 2). *The extension service worker lifecycle*. Chrome for Developers. (n.d.). *chrome.declarativeNetRequest*. Google. Retrieved August 9, 2026, from https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest +Chrome for Developers. (n.d.). *chrome.history*. Google. Retrieved August 11, 2026, from https://developer.chrome.com/docs/extensions/reference/api/history + Chrome for Developers. (n.d.). *Manifest file format*. Google. Retrieved August 9, 2026, from https://developer.chrome.com/docs/extensions/reference/manifest Bynens, M. (2023, June 12). *Chrome for Testing*. Chrome for Developers. https://developer.chrome.com/docs/automation-and-testing/chrome-for-testing diff --git a/docs/evidence/2026-08-10-active-pr-maturity.md b/docs/evidence/2026-08-10-active-pr-maturity.md new file mode 100644 index 0000000..71353dc --- /dev/null +++ b/docs/evidence/2026-08-10-active-pr-maturity.md @@ -0,0 +1,57 @@ +# Active pull-request maturity evidence series — opened 2026-08-10 + +- **Evidence series opened:** 2026-08-10 +- **Last refreshed:** 2026-08-11 +- **Filename semantics:** the date in this filename is the date this evidence series was opened; refresh provenance is recorded separately and is never backdated to match the filename. + +This dated appendix records volatile implementation evidence that must not be embedded as timeless architecture truth. Protected `main` remains the only shipped-code authority. Active pull requests are implementation evidence only until they integrate and protected-main acceptance is re-established. + +## Protected-main anchor + +- Protected `main`: `67af7c87589edc2039545af335c95064d9b8391c` +- Product status: pre-alpha +- Documentation verdict: **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL** + +## Active implementation evidence + +| PR | Scope | Maturity | Dependency / evidence boundary | +|---|---|---|---| +| #37 | Bounded HTTP/1.1 over authenticated governed transport | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `9becaaf61f10d854b20ebd2e04ccd3f57dee97fe` is mergeable and passes CI `31439440664`, Security Scan `31439440691`, SAST Semgrep `31439440663`, exact owned production coverage and CodeRabbit exact-head status. Protected main still reports HTTP as Planned. Historical #11 remains predecessor lineage until protected integration. | +| #40 | Browser protocol identifier → OriginWeave authority registry | **IMPLEMENTED_ON_ACTIVE_PR** | Current exact head `9e635e80e9813a1d2a9c408155d52221b76eeed3` is gate-clean across CI, Security Scan, SAST, Manifest V3 Compatibility and CodeRabbit; the real browser adapter remains Planned under #28. | +| #43 | Real pinned-Chromium Manifest V3 downloads compatibility | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `27ce89066ed1473dcd66eb26a2f91becf9df5424` is gate-clean; this proves one declared compatibility surface, not full extension compatibility or Agent authority. | +| #44 | Canonical documentation reconciliation | **IMPLEMENTED_ON_ACTIVE_PR** | This branch owns the documentation repair itself; its content does not become protected-main truth until integration. Current-head evidence must be read from the live PR because every reconciliation commit intentionally invalidates predecessor-head exactness. | +| #45 | Credential-free sensitive-handle lifecycle evidence | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `0f07fea031090c72a448fd9501b49d4dd7568419` is gate-clean; trusted broker/storage/value resolution remain Planned under #10. | +| #46 | In-process authoritative sensitive-handle use reservation | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `5f212cdfbf3c453472069973138fd9563cf7bff8` is gate-clean; no cross-process/database transactionality or protected-value resolution is claimed. | +| #47 | Bounded resolution freshness authority | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `6b5ed4dcea281b505f67db6180bb14c3bc95b392` is gate-clean. Its first-party consumer is now implemented on stacked #50, but neither capability is protected-main truth until dependency-ordered integration. | +| #48 | TLS revocation-material freshness primitive | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `9bbe12860436027a3b7cd5786775f1dacfbc835d` is gate-clean; no OCSP/CRL acquisition, signature validation, cache, or unrevoked claim is implemented. | +| #49 | Ephemeral Agent Task profile-isolation regression | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #43 at exact head `96a4e949d96b5794ef473ccf813987b8e69ea566`; CI is green but dependency-gated and not independently integrable before #43. | +| #50 | First-party network consumption of resolution freshness | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on exact #47 head `6b5ed4dcea281b505f67db6180bb14c3bc95b392`. Exact head `f8b43bc94444986ab23aa4ef3086e446a0b39295` structurally hides the untimed public network planner, migrates first-party TLS integration helpers through `FreshConnectionPlan`, and passes CI run `31408474576` including exact owned function/line/region/branch coverage; CodeRabbit exact-head status is success. Dependency order, not implementation incompleteness, keeps the PR Draft. | +| #51 | Browser-task runtime telemetry plus one-PID Linux RSS sampling | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `dab26e4e9652408fb67dc8eedf9fd1820e524805` validates browser/task telemetry and samples one explicitly supplied Linux PID through strict `/proc//status` `VmRSS` parsing. CI `31441792029`, production coverage job `93627900171`, Security Scan `31441792000`, SAST Semgrep `31441791982` and CodeRabbit exact-head status succeed. Chromium PID discovery, task attribution, process-set accounting, GPU/VRAM and cross-platform sampling remain separate responsibilities. | +| #52 | Bounded semantic-node observation and relationship value contract | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #40. Exact head `94fd284fe41746eeba9edc05d9753903b1c41ebf` adds at most 128 ordered child relationships, optional parent linkage, exact session/context/origin/document authority matching, self/duplicate rejection and stable credential-free errors. CI run `31428454410`, Manifest V3 Compatibility run `31428454350`, and CodeRabbit exact-head status succeed, including exact owned production function/line/region/branch coverage. The value contract still performs no browser I/O or action dispatch. | +| #53 | Authoritative in-process sensitive-handle revocation state | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #46 at exact head `86ce4bc1c11c270dc532593d673c42bd6f623d74`; CI and CodeRabbit are green. It adds typed first-revocation-wins state but no durable broker, cross-process transactionality, protected-value resolution, KMS, or persistence. | +| #54 | Recheck resolution freshness at socket use | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #50 at exact head `ec81031c537f2b662910c1ce78c7ae0e0bfc9c1e`; CI and CodeRabbit are green. `connect_at` revalidates freshness immediately before socket I/O and the compatibility path derives elapsed monotonic time; no resolver, DNS lookup, proxy/PAC or wall-clock authority is added. | +| #55 | Bind opaque sensitive-value handle use to a non-transferable audience | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on exact #53 head `86ce4bc1c11c270dc532593d673c42bd6f623d74`. Test-only head `95f0f1e418024f5dbe7aa613e5fd1e9d88a9417a` and CI run `31419991170` proved a real regression: audience binding had caused a revoked handle with later mismatched policy state to return `ScopeMismatch` instead of authoritative `Revoked`. Current exact head `8d3ccf0a3b99fd9789210dd9798b422431fab7d8` restores revocation precedence, retains audience binding, and adds a synchronized one-use concurrency regression. CI run `31421061134` passes repository contracts, rustfmt, locked workspace check, all workspace tests, strict Clippy, rustdoc and exact owned production function/line/region/branch coverage; CodeRabbit exact-head status is success. A future trusted broker must still derive the audience from authenticated workload/service identity. | +| #56 | Real pinned-Chromium bookmark mutation compatibility | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #43. Exact head `e1099e35ac000c7bf87ea75666cfdd928a386370` aligns the fixture and repository contracts with the bounded create → get → remove bookmark lifecycle; CI run `31427219564`, Manifest V3 Compatibility run `31427220684`, and CodeRabbit exact-head status all succeed. This is compatibility evidence only: it grants no OriginWeave Agent capability and does not complete issue #27's full extension matrix. | +| #57 | Typed semantic-node query over bounded observation evidence | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on exact #52 head `94fd284fe41746eeba9edc05d9753903b1c41ebf`. Test-only head `d0cd133f5be62fff99612d5b08aa4cf08ce2f29f` and CI run `31429065905` intentionally proved the missing public query boundary by failing compilation on absent `SemanticNodeQuery`/`SemanticNodeQueryError`. Current exact head `b4fa49953cbbb21c879a3340e264a6e132e41634` implements bounded exact role, accessible-name and typed-action selection against already validated `SemanticNodeObservation` values, with no CSS/XPath/raw DOM selector language, arbitrary JavaScript, browser I/O or action authority. CI run `31429995885`, Manifest V3 Compatibility run `31429997851`, and CodeRabbit exact-head status succeed. The PR remains Draft because #52/#40 are active prerequisites. | +| #58 | Authority-bound semantic-node action target | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #57. Current exact head `efe440c7a609cac187faacfa03a4df904a99386f` accepts only an advertised `NodeActionKind`, carries the exact OriginWeave-owned node handle, and delegates immediate-use session/context/origin/document-epoch validation to the browser authority boundary. CI run `31431277478`, Manifest V3 Compatibility run `31431277521`, and CodeRabbit exact-head status succeed. This remains descriptive execution input, not policy authorization, business-risk classification, browser I/O or action success. | +| #59 | Real pinned-Chromium history mutation compatibility | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #56. Test-only head `4b5f393a7420541723a07243b83cdaa7e28948de` and CI run `31432051381` established the intended repository-contract RED because controlled `history.addUrl`/`deleteUrl` lifecycle support was absent. Current exact head `b0d9c905fd7a50128eb1dde643b8a3a0f9cb1dc8` adds loopback-only add → exact readback → delete → absence verification. CI run `31432338572`, Manifest V3 Compatibility run `31432338759`, and CodeRabbit exact-head status succeed, including exact owned production function/line/region/branch coverage. Compatibility evidence only; no Agent history capability. | +| #60 | Real pinned-Chromium extension update/version migration | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #59. Test-only head `a60875f70f8412db27ff1025b75d7ad4b8ddc38e` and CI run `31433305976` established the intended RED because no trial-local extension copy, version transition, migration state, or update-migration evidence existed. Current exact head `e696e19c9eaf3dedb104a5de4bdbd7970abf90d4` uses an ephemeral extension copy and one profile across initial `1.0.0`/initialized → restart `1.0.0`/current → update `1.0.1`/migrated passes. CI run `31433968874`, Manifest V3 Compatibility run `31433968931`, and CodeRabbit exact-head status succeed; the real browser evidence reports 3/3 trials and the exact update-migration surface. This does not claim Chrome Web Store/enterprise update semantics or Agent authority. | +| #61 | Real pinned-Chromium content-script isolated-world separation | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on #60. Test-only head `e81cdbd9b31a62227698bd3d824fd901551061f0` and CI run `31434443638` established the intended RED because the fixture had no page-main/content-isolated sentinel contract. Current exact head `c1705ad9fd2d96e620b89bb6e7ea1235063dcb6a` requires the page to retain `window.originweaveWorldSentinel = "page"` while the content script independently retains the same-named global as `"extension"`; the existing content compatibility surface fails if the JavaScript worlds collapse. CI run `31434670642`, Manifest V3 Compatibility run `31434670629`, and CodeRabbit exact-head status succeed; real browser evidence reports 3/3 repeatability trials. Compatibility evidence only; no arbitrary page-JavaScript bridge or Agent authority. | +| #62 | Extension proposal → Agent policy isolation regression | **IMPLEMENTED_ON_ACTIVE_PR** | Ready PR based directly on protected main. Exact head `a57873b3688984711918be17aadd348ed9fb12a9` first proves the exact extension/session/context `ProposeTypedAction` grant is allowed, then proves ordinary Agent policy independently rejects an out-of-grant target origin, a missing core `Navigate` capability, `WebContent` as an untrusted instruction source, raw secret delivery and unexpected secret material. CI run `31436844685`, production coverage job `93612736291`, Security Scan run `31436844615`, SAST Semgrep run `31436844646`, and CodeRabbit exact-head status succeed. This adds no production API or real Chromium adapter and does not convert extension proposal authority into Agent action/origin authority; it also cannot manufacture secret authority. | +| #63 | Extension proposal → secret high-risk approval isolation | **IMPLEMENTED_ON_ACTIVE_PR** | Ready PR based directly on protected main at exact head `e83749acd1cf5a0b778ba38eb9d6ed5a9bd1e68f`. The exact extension grant allows `ProposeTypedAction`, while ordinary Agent policy still returns `RequireApproval(RiskClass::R3)` for broker-handle `FillSecret`. CI `31437994464`, Rust contracts job `93616406126`, production coverage job `93616406182`, Security Scan `31437994491`, SAST Semgrep `31437994454`, and CodeRabbit exact-head status succeed. This is composition evidence only: it adds no secret broker, protected value, authenticated workload identity, browser adapter or approval evidence. | +| #64 | Verified action post-condition evidence with dispatch ordering | **IMPLEMENTED_ON_ACTIVE_PR** | Ready PR based directly on protected main at exact head `2c45411ed9aa0eecca2d06c85659db9f4bb85e4d`. `VerifiedActionOutcomeEvidence` requires verified provenance and caller-supplied monotonic dispatch/observation timestamps; observations before dispatch fail as `PostConditionPredatesDispatch`. CI `31441848670`, production coverage job `93628017556`, Security Scan `31441848649`, SAST Semgrep `31441848615`, and CodeRabbit exact-head status succeed. It is not a browser dispatcher and does not prove trusted clock provenance, real browser dispatch, target linkage, causality or a reached browser condition. | +| #65 | Controlled hostile Agent Task fixture | **IMPLEMENTED_ON_ACTIVE_PR** | Ready PR based directly on protected main at exact head `0888fe3a6ef6da547a37fd075733cc73dc52b2ab`. Test-only head `d2580305f05aba93d10b5342ec1886d601c6752e` and CI `31445088008` established the intended missing-fixture RED. The current fixture provides a labelled semantic form, deterministic same-document state transition and explicitly hidden/untrusted prompt-injection text using synthetic local data only. CI `31445201739`, Rust contracts job `93637824750`, production coverage job `93637824824`, Security Scan `31445201774`, SAST Semgrep `31445201669`, and CodeRabbit exact-head status succeed. It is controlled test infrastructure, not a browser adapter or proof of real Chromium execution. | +| #66 | Bounded explicit browser process-set RSS aggregation/sampling | **IMPLEMENTED_ON_ACTIVE_PR** | Draft stacked on exact #51 head `dab26e4e9652408fb67dc8eedf9fd1820e524805`. A predecessor implementation test incorrectly required two sequential `/proc` RSS reads to be equal; current regression instead verifies the kernel sample's positive byte/unit contract without assuming RSS immutability. Exact head `986958ab8a29b3ca708c80e44df45e1ec5f9f868` accepts at most 256 unique nonzero caller-owned PIDs, rejects empty/duplicate/oversized sets and checked-add overflow, and fails closed if any sampled member is unavailable. CI `31446842334` passes repository contracts, formatting, workspace checks/tests, strict Clippy, rustdoc and exact owned production function/line/region/branch coverage; CodeRabbit exact-head status succeeds. It does not discover Chromium PIDs, prove same-task attribution, walk a process tree/cgroup, or measure GPU/VRAM. | + +## Historical lineage + +PR #11 is a historical HTTP predecessor, not current implementation authority. It may close as superseded only after #37 reaches protected main and unique-work preservation plus protected-main acceptance are revalidated. + +## Interpretation rules + +1. `IMPLEMENTED_ON_ACTIVE_PR` never means shipped. +2. A green active PR does not authorize release or change an ADR lifecycle state. +3. A Draft or stacked PR remains dependency-gated even if its own checks pass. +4. Exact heads and workflow run identifiers are volatile evidence and belong in dated appendices such as this one, not in timeless Architecture/PRD/TRD claims. +5. After an active PR integrates, canonical PRD/TRD/Architecture/UML/ERD/traceability must be re-evaluated from the new protected-main head before reclassifying the capability. +6. A formatting-only or metadata-only correction invalidates predecessor-head exactness: current-head checks must be rerun before a lane is called gate-clean. diff --git a/docs/evidence/2026-08-11-active-pr-maturity-closure.md b/docs/evidence/2026-08-11-active-pr-maturity-closure.md new file mode 100644 index 0000000..6609147 --- /dev/null +++ b/docs/evidence/2026-08-11-active-pr-maturity-closure.md @@ -0,0 +1,39 @@ +# Active pull-request maturity evidence — 2026-08-11 closure + +- **Protected-main anchor:** `67af7c87589edc2039545af335c95064d9b8391c` +- **Canonical documentation verdict:** **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL** +- **Scope:** exact-current reconciliation for PR #73 through PR #84 after their 2026-08-11 defect, review, policy-composition, browser-assurance, and sensitive-model authority corrections + +Protected `main` remains the only shipped-code authority. This appendix records volatile exact-head evidence for active work and must never be read as protected-main implementation or release evidence. + +## Exact-current active lanes + +| PR | Scope | Maturity | Exact evidence / authority boundary | +|---|---|---|---| +| #73 | Bounded Chromium root-plus-descendant RSS evidence in the controlled pinned-browser fixture | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `e5fabfd57387ec7d2db692961eda93c95cf8d886`, stacked on unchanged #72 head `1a7186085abe926c1d0e5b22c36760965d6e237b`, restores the focused optional-RSS regression and implements `_parse_linux_proc_status_optional_rss_bytes`. Absent or zero `VmRSS` remains representable as nonresident sampled evidence; one positive field becomes bounded bytes; duplicate, malformed, or overflowed evidence fails closed rather than being normalized to absence. CI run `31464241922` succeeds, including Rust contracts job `93693702956` with exact-head checkout and Production coverage job `93693703022`; Manifest V3 Compatibility run `31464241924` also succeeds on the exact head. The PR remains Draft because #72/#71/#70/#65 are active prerequisites. This is controlled Linux CI evidence, not product task/process attribution, cgroup authority, per-tab ownership, GPU/VRAM attribution, or cross-platform resource telemetry. | +| #74 | Separation of extension proposal-grant evaluation from ordinary Agent action policy | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `0d492564aa61c9094f1315ee4e234b46a1e63a6c` is based directly on protected main. A predecessor-head CodeRabbit review correctly identified that no production adapter currently converts an extension proposal into an `ActionRequest`; the former naming therefore implied a composition path that did not exist. The exact current head renames and documents the tests as independent boundaries: `evaluate_extension_access` may authorize the exact extension/session/context `ProposeTypedAction` grant while ordinary user-sourced requests remain independently fail-closed for cross-origin mutation, missing write authority, crawler mutation, execution-mode/purpose mismatch, robots evidence, non-delegable R5 consent, and Human mode. CI run `31464388199`, Security Scan run `31464388200`, and SAST Semgrep run `31464388210` all succeed on this exact head. The branch adds no extension-proposal adapter, action-source transformation, execution API, or new authority and therefore does not prove a real extension → Agent action composition path or close issue #27. | +| #75 | Exact sensitive-data provider/model/region/retention/training/reviewed-subprocessor/export route admission | **IMPLEMENTED_ON_ACTIVE_PR** | Exact current head `286f92aae9e298ab7dff1fd81c7850aabd5692ce`, stacked on unchanged #69 head `de79d85e6be5131036db119efab767f0eb76a816`, extends the existing model-route authority with an explicit export-policy dimension while preserving the complete tenant/task/field/purpose/destination/classification authority. The ordinary constructor defaults to `no-export`; callers may select another bounded export-policy token through `with_export_policy`, but matching route metadata still does not authorize protected-value disclosure or perform export. Test-only head `90bde2dba675be10abb34a5c2a8bf03bb34abcdf` established the intended RED in CI run `31474208345`, Rust contracts job `93724057066`: repository contracts and formatting passed before `cargo check` failed with E0599 because export-policy APIs did not exist. Production head `88b1fd46b6d2e83411682f97aa17de95aca90789` made the tests GREEN but strict Clippy correctly rejected two eight-argument constructors; the API was then narrowed to the builder-style export selector rather than weakening lint policy. The current head contains that correction, adjusted realistic regressions, and the truthful changelog entry. Exact-current CI run `31474904239` succeeds, including Rust contracts job `93726313815` and Production coverage job `93726313914` with exact owned production function/line/region/branch enforcement. The PR remains Draft because #69/#68/#55/#53/#46 are active prerequisites. Route admission is not raw-value disclosure, export execution, provider authentication, model invocation, real-region attestation, prompt/token-budget policy, output validation, fallback selection, persistence, or the complete trusted broker. | +| #76 | Production policy composition of extension proposal authority with ordinary typed-action policy | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `3d2fff3daa766e5e6d7f25e7727a18e01ff52a2e`, stacked on unchanged #74 head `0d492564aa61c9094f1315ee4e234b46a1e63a6c`, adds `evaluate_extension_action_proposal` and `ExtensionProposalDecision`. The helper constructs the exact extension/session/context `ProposeTypedAction` access request and, only after that grant succeeds, evaluates the caller-supplied `ActionRequest` unchanged through ordinary Agent policy. It therefore preserves instruction-source, capability, origin, secret-delivery, risk, approval, execution-mode, purpose, and crawler controls instead of minting them from extension transport. CI run `31472688287` succeeds, including Rust contracts job `93719296349` and exact Production coverage job `93719296436`. The PR remains Draft while #74 is active. This is a pure policy-composition prerequisite: it does not parse or authenticate extension messages, create trusted instruction provenance, execute Chromium actions, disclose secrets, verify post-conditions, persist policy, alter managed-extension configuration, or close issue #27. | +| #77 | Reviewed prompt/output-schema and token-budget policy composed after exact sensitive-model route admission | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `adb67f8de3e4828db14dfa0e2950b672b60709c5`, stacked on unchanged #75 head `286f92aae9e298ab7dff1fd81c7850aabd5692ce`, implements `ModelInvocationRequest`, `ModelInvocationScope`, `ModelInvocationDecision`, and `evaluate_model_invocation`. Exact route denial remains a distinct prerequisite; bounded prompt-contract/output-schema identifiers must match; requested and reviewed input/output token budgets must be nonzero; and requested budgets may not exceed reviewed maxima. Exact-head CI run `31477512549` succeeds. The PR remains Draft because #75 and the sensitive-handle prerequisites remain active. This metadata admission does not disclose a protected value, authenticate or invoke a provider, validate model output, enforce retention, isolate unrelated history, authorize fallback/export, or provide invocation-policy expiry. | +| #78 | Raw extension-message action proposals are forced into untrusted content provenance before ordinary Agent policy | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `3fd7d563d814a895e20d04fc6bd37371e548a875`, stacked on unchanged #76 head `3d2fff3daa766e5e6d7f25e7727a18e01ff52a2e`, implements `ExtensionMessageActionProposal` and `evaluate_extension_message_action_proposal`. The raw proposal type exposes no instruction-source selector; after exact extension/session/context proposal permission succeeds, production constructs the ordinary `ActionRequest` internally with `InstructionSource::WebContent`. Exact-head CI run `31477648663` succeeds. CodeRabbit's Draft skip is explicitly not review approval. The branch does not parse Chromium messages, establish transport sender authenticity beyond the existing grant tuple, execute browser input, resolve secrets, verify post-conditions, persist managed-extension policy, or close issue #27. | +| #79 | Exclusive freshness/expiry for reviewed sensitive-model invocation metadata | **IMPLEMENTED_ON_ACTIVE_PR** | Test-only head `eb7daf465f35b314b175a592cdb9d74962b64800`, stacked on exact #77 head `adb67f8de3e4828db14dfa0e2950b672b60709c5`, established the intended missing-boundary RED in CI run `31480649072`: repository contracts and formatting passed before Rust compilation failed because the production scope lacked `valid_until`, the evaluator lacked caller-supplied trusted time, and `InvocationExpired` did not exist. Production head `39ec1659541b10785fcd85a9531bdd8d823578e3` added a nonzero exclusive `valid_until`, caller-supplied `trusted_time`, and typed `InvocationExpired`; route denial remains first, malformed static invocation policy remains `InvocationPolicyMismatch`, and authorization requires `trusted_time < valid_until`. Exact current head `2ad7a2162b4842fe57f74f69f08b258f4f6a9c07` adds only the truthful changelog entry, and CI run `31481128812` is now completed successfully on that exact head. The policy function reads no wall clock and does not attest clock provenance; the trusted broker/orchestrator must supply time from the same authoritative domain that issued expiry. This remains metadata freshness only, not protected-value disclosure, provider invocation, output validation, unrelated-history isolation, retention enforcement, fallback/export execution, or complete issue #10 closure. | +| #80 | Origin-binding for node-state post-condition evidence | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `55b1421e25c5b68ca5f3b05fab37db8f4f1e22be`, stacked on unchanged #64 head `2c45411ed9aa0eecca2d06c85659db9f4bb85e4d`, retains canonical source origin in provenance and rejects `NodeStateChanged` evidence from an origin other than the governed action target with `PostConditionOriginMismatch`; canonical-equivalent origins remain accepted. CI run `31485218503` succeeds. The PR remains Draft while #64 is active. This does not prove browser dispatch, frame/node identity, trusted-clock provenance, a real post-condition observer, redirect authority, or network attribution. | +| #81 | Fail-closed unrelated-conversation-history metadata for sensitive model invocation | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `0ec604deb1c0293008560e0fcd4af7ccb65d93ad`, stacked on exact #79 head `2ad7a2162b4842fe57f74f69f08b258f4f6a9c07`, adds broker-derived `unrelated_history_items` to `ModelInvocationRequest`; only zero can be admitted after exact route admission and any positive count returns `UnrelatedConversationHistoryDenied`. CI run `31484982600` succeeds. The trusted broker must derive this fact from the bounded outgoing message set; a caller-provided zero is not proof of isolation. The branch does not inspect message payloads, classify relevance, disclose protected values, invoke a provider, validate output, enforce retention, or complete issue #10. | +| #82 | Explicit extension-ID + native-messaging-host allow-list authority | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `28593cf991cc552968da54b722a887252a3695e7` is directly based on protected main. It adds Chromium-compatible native-host-name validation, exact extension/host grants, typed missing-grant and identity-mismatch denial, and proves that native-messaging permission does not mint OriginWeave Agent capability. CI run `31484721598`, Manifest V3 Compatibility run `31484721575`, Security Scan run `31484721547`, and SAST Semgrep run `31484721542` all succeed. The PR is Ready for review but this scheduled actor cannot merge or self-approve it. The primitive does not launch/locate a native process, parse manifests/messages, communicate over stdio, expose secrets, or grant Agent actions. | +| #83 | Reduced-assurance classification for attached human tabs with known extension influence | **IMPLEMENTED_ON_ACTIVE_PR; exact-current CI pending** | The prior exact production head `231996f6db978c586207bd38596ebfc352dd54b2` implemented the narrow classifier but named the no-positive-evidence variant `NoExtensionInfluence`, which overstated the documented truth boundary. Test-only correction head `292736fc8a697292e4ec49224b4c43f673ac1de9` requires `NoKnownExtensionInfluence`; CI run `31489921146` observed the intended RED at the Rust workspace check while repository contracts and formatting passed. Exact current production head `f6d57f86e2cbea70144f3b7504bc929e20d60233` renames the public variant and explicitly documents that absence of known influence is not proof of extension absence or inability to interfere. Current CI run `31490346830` and Manifest V3 Compatibility run `31490346837` are queued and therefore are not counted as passing. The live base branch #82 has advanced to `28593cf991cc552968da54b722a887252a3695e7`; ancestry diverges from the older stack point because #82 added a coverage-only native-host test correction that #83 already contains content-equivalently, so dependency integration still requires fresh exact-base verification. This lane does not detect installed extensions, inspect managed policy, prove extension absence, attach to a browser, execute actions, or grant Agent authority. | +| #84 | Separate validated model-output and retention-policy admission | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `62f69cadbe0b4011fec67f9e482b04c4cacf181b`, stacked on unchanged #81 head `0ec604deb1c0293008560e0fcd4af7ccb65d93ad`, requires exact reviewed output-schema and retention-policy identifiers plus a trusted validation result before output authorization. Test-only head `32af45f2525f17fa1dbae50f59e4641999a50695` established the missing-API RED; a production attempt then exposed one uncovered identifier-validation branch, and the focused punctuation-only regression restored exact production branch coverage. Exact-head CI run `31487969844` succeeds, including Rust contracts job `93767614892` and Production coverage job `93767614791`. This is deterministic metadata policy only: it does not inspect output bytes, perform schema validation, authenticate/invoke a provider, persist output, enforce deletion/retention, authorize invocation, disclose protected values, select fallback, or attest validator identity. | + +## Documentation-fitness reconciliation + +The repository-wide documentation verdict remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. + +- **ADR:** no additional ADR is warranted by #73–#84. #73/#80 refine evidence integrity inside existing browser contracts. #74/#76/#78/#82/#83 refine Proposed ADR 0013's extension/Agent authority separation without creating a new trust domain, deployed component, persistence owner, or binding transport protocol. #75/#77/#79/#81/#84 make existing selective-model-disclosure architecture more executable while leaving the trusted broker, provider transport, authenticated runtime identities, validator, retention owner, storage, and clock authority outside these pure policy primitives. Proposed ADR 0013 remains Proposed and is not promoted by branch presence, tests, CI, or policy-helper implementation. +- **PRD/TRD/Architecture:** current contracts already require resource evidence to remain distinct from trusted attribution, browser/extension permission not to mint Agent capability/origin/approval/secret/execution authority, attached human-tab extension influence to reduce assurance without turning absence of known evidence into a high-assurance claim, and AI disclosure policy to bind route, prompt/schema/tokens, expiry, unrelated-history isolation, output validation and retention independently from protected-value disclosure. These active branches strengthen those boundaries without changing deployed topology. +- **UML:** existing extension-authority, sensitive-data/secret-fill, evidence, and product-wide authority views remain sufficient for the current material boundaries. No current branch adds a real Chromium extension transport/native-host adapter or a trusted sensitive-data broker/provider/validator/retention service. A detailed production adapter → semantic observation → typed policy/action → post-condition/recovery/resource sequence remains mandatory when that real browser-adapter composition boundary stabilizes. +- **ERD/data model:** none of #73–#84 introduces OriginWeave-owned durable persistence, ownership/cardinality changes, migrations, or rollback state. The conceptual ERD remains the truthful artifact; physical process-sample, extension-policy, native-host, assurance, model-route, invocation, output-policy, broker, provider, validator, retention, or clock tables would be invented architecture until a real persistence owner is accepted and implemented. +- **Security/test/release:** #73–#82 and #84 have exact-current GREEN evidence on the heads stated above. #83 has a realistic exact RED proving the uncertainty-safe API name was missing and a narrow production correction on current head `f6d57f86e2cbea70144f3b7504bc929e20d60233`; its current checks are pending and therefore are not passing evidence. None of these active branches is protected-main or release evidence, and no predecessor-head success transfers after a head or live base moves. +- **Traceability:** this appendix supersedes its earlier #79 pending-CI wording and extends exact-current non-shipped evidence through #84. If any recorded head or dependency moves, that evidence becomes historical immediately and must be refetched before use. + +## Truth boundary + +`IMPLEMENTED_ON_ACTIVE_PR` means the exact branch contains the stated behavior; it does not mean shipped, and a pending exact-head check is never treated as passing. A controlled Chromium runner is not the product browser adapter. A sampled Chromium process tree is not trusted whole-task ownership. An extension proposal or native-host grant is not an Agent action grant. A no-known-influence result is not proof that extensions are absent or unable to affect page state. A model-route, invocation, context-isolation, or output-policy admission decision is not authorization to disclose a protected value, execute an export, authenticate or invoke a provider, attest a region or clock, inspect/validate output bytes, retain/delete data, prove unrelated-history isolation, or authorize fallback. Protected-main maturity changes only after dependency-ordered integration and fresh protected-main acceptance. diff --git a/docs/evidence/2026-08-11-active-pr-maturity-delta.md b/docs/evidence/2026-08-11-active-pr-maturity-delta.md new file mode 100644 index 0000000..703cb6e --- /dev/null +++ b/docs/evidence/2026-08-11-active-pr-maturity-delta.md @@ -0,0 +1,57 @@ +# Active pull-request maturity evidence — 2026-08-11 delta + +- **Protected-main anchor:** `67af7c87589edc2039545af335c95064d9b8391c` +- **Canonical documentation verdict:** **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL** +- **Relationship to the existing series:** this file advances the dated evidence in [`2026-08-10-active-pr-maturity.md`](2026-08-10-active-pr-maturity.md) for active lanes opened after that appendix was refreshed through PR #66. It is volatile implementation evidence, not timeless architecture truth. + +Protected `main` remains the only shipped-code authority. Active pull requests, exact heads, CI runs, reviews, and coverage reports are evidence about non-shipped work until dependency-ordered integration and fresh protected-main acceptance are re-established. + +## Newly active implementation evidence + +| PR | Scope | Maturity | Exact evidence / authority boundary | +|---|---|---|---| +| #67 | Browser-task interruption and recovery evidence | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `9d9ebffee234ed4ab662dab7850bd08450ec365b` is stacked on unchanged #64 head `2c45411ed9aa0eecca2d06c85659db9f4bb85e4d`. CI run `31448465680` is successful, including exact owned production function/line/region/branch coverage. The value contract distinguishes an interruption proven before external effect from an effect that may have committed and requires browser-context closure, task-resource reclamation, and evidence finalization before `SafeToRetry`. It does **not** detect Chromium crashes, prove caller-supplied cleanup facts, reconcile external mutations, restart Chromium, dispatch a retry, persist checkpoints, or complete issue #28's real-browser vertical slice. | +| #68 | Identity-bound settlement of failed sensitive-handle reservations | **IMPLEMENTED_ON_ACTIVE_PR** | The lane is stacked on exact #55 head `8d3ccf0a3b99fd9789210dd9798b422431fab7d8`. Exact predecessor head `add3599bee784c58dfaa4275d17c477eaed781a9` passed repository contracts, formatting, workspace tests, strict Clippy and rustdoc but failed exact coverage at `branches=495/496`, `lines=3666/3667`, `regions=4575/4576`. The uncovered production `next_reservation_sequence == None` branch was synthetic/private-test-only, so the production design was replaced rather than weakening the gate. Exact head `17bc00790e75424afd97c8a73800d9b16c766300` replaced the finite sequence with an allocation-bound, non-copyable in-process reservation identity and passed CI `31451682170`. Current exact head `aa46d982b2bf786fe297744ac99f88b6c4c5f4cf` additionally proves a reservation token from one state instance cannot commit or compensate another identical-scope state. Fresh CI run `31451963178` succeeds: repository contracts, formatting, locked workspace/all-target checks, full tests, strict Clippy, rustdoc, and exact owned production function/line/region/branch coverage are green; CodeRabbit exact-head status is also success. The lane still provides no authenticated workload identity, protected-value resolution, durable/cross-process transaction, KMS, persistence, or proof that compensation is truthful. | +| #69 | Immediate pre-disclosure recheck of an exact tracked reservation | **IMPLEMENTED_ON_ACTIVE_PR** | This Draft is stacked on exact #68 head `aa46d982b2bf786fe297744ac99f88b6c4c5f4cf`. Test-only head `5a96d2931225e133768878c68d09e1a36b5ca0f6` established the intended missing-API RED. Production then exposed a real coverage defect in short-circuit recheck branches; focused malformed caller authority/audience cases were added, and two duplicate unreachable immutable-state checks were removed rather than manufacturing private-only coverage. Current exact head `de79d85e6be5131036db119efab767f0eb76a816` passes CI run `31453149013`, including exact owned production function/line/region/branch coverage, and CodeRabbit exact-head status is successful. The boundary rechecks the same still-outstanding reservation immediately before disclosure without consuming another use, but still trusts the future broker to supply authenticated workload audience, trusted time, exact current authority, transactional serialization and the protected-value disclosure boundary. | +| #70 | Controlled Agent Task execution on pinned stock Chromium | **IMPLEMENTED_ON_ACTIVE_PR** | This Draft is stacked on exact #65 head `0888fe3a6ef6da547a37fd075733cc73dc52b2ab`. Test-only head `197ce14a5e407d61ac35b38b45c0cd042dd6278c` established the intended missing-runner RED. Current exact head `f9917cdd8050c9fdf0aefa669f4d981af85479d6` passes CI run `31453647157` and pinned real-browser run `31453647201` against Chrome for Testing `150.0.7871.129` / revision `r1639810`. The controlled Agent Task completes `3/3` trials with real WebDriver clear/type/click operations, exact same-document post-condition verification, extensions disabled, and per-trial profile cleanup. This is reproducible browser execution evidence, not the product browser adapter: fixture CSS locators are test-harness locators, no semantic role/name query authority is claimed, and OriginWeave semantic observation/policy/node-handle composition remains incomplete. | +| #71 | Computed semantic role/name evidence before controlled browser action | **IMPLEMENTED_ON_ACTIVE_PR** | This Draft is stacked on unchanged exact #70 head `f9917cdd8050c9fdf0aefa669f4d981af85479d6`. Exact test-only head `977d2682dc191ca6b26b9de631a3642680abdbc0` produced the intended RED in CI run `31454219111`, Rust contracts job `93664601520`, because the runner had no `_get_element_semantics` boundary. Current exact head `5f1f972f3e9888faa44af184fd54a466d20b6ddb` adds the smallest bounded W3C WebDriver computed-role/computed-label verification before the controlled input and submit actions. CI run `31454448709` succeeds, including exact owned production function/line/region/branch coverage, and pinned real-browser run `31454448710` succeeds on Chrome for Testing `150.0.7871.129` / revision `r1639810`: all `3/3` Agent Task trials report browser-computed `textbox` / `Task text` and `button` / `Submit task` verification, exact post-condition and input echo, extensions disabled, and profile cleanup. CodeRabbit exact-head status is successful. CSS remains a controlled harness locator; this evidence does not itself implement semantic role/name search, a versioned product adapter, OriginWeave node registration/observation composition, policy dispatch, source provenance or real-site compatibility. | +| #72 | Controlled Agent Task runtime resource evidence | **IMPLEMENTED_ON_ACTIVE_PR** | This Draft is stacked on unchanged exact #71 head `5f1f972f3e9888faa44af184fd54a466d20b6ddb`. Exact test-only head `a9402a13c9ed429b8f3be2c623b994a0dfda3bb4` produced the intended RED in CI run `31454745237`, Rust contracts job `93666110420`, because strict Linux RSS parsing/sampling was absent. Current exact head `1a7186085abe926c1d0e5b22c36760965d6e237b` adds bounded `/proc//status` sampling for the ChromeDriver-issued browser PID, exact serialized semantic-observation bytes, monotonic action latency, and task duration. CI run `31454903615` succeeds, including exact owned production function/line/region/branch coverage, and pinned real-browser run `31454903620`, job `93666566904`, succeeds on Chrome for Testing `150.0.7871.129` / revision `r1639810`. All `3/3` trials pass with browser-process RSS `215326720`, `214568960`, and `213716992` bytes; semantic observation size `95` bytes each; action latency `133.282`, `130.186`, and `110.554` ms; and task duration `1144.545`, `957.991`, and `906.982` ms. Artifact ID `9087662526` has uploaded-artifact SHA-256 `a7f8ec5ae716ed723e9dd7ec84eeac3478c30fddd6eb7c9bf0d411f1a8990ee5`; CodeRabbit exact-head status is successful. The RSS metric intentionally covers only the ChromeDriver-reported browser process, not renderer/GPU/utility descendants or whole-task attribution; full trusted process-set composition remains pending the product adapter and #51/#66 contracts. | + +## Documentation-fitness reconciliation + +The addition of #67 through #72 does **not** require another ADR, a new deployed component, or a physical ERD entity at this stage. + +- **ADR:** #67 refines the existing evidence/recovery architecture. #68/#69 refine the in-process sensitive-handle lifecycle governed by Accepted ADR 0007. #70–#72 add executable compatibility/runtime evidence inside the already planned browser-adapter and resource-evidence boundaries. None changes a trust domain, persistence owner, deployment boundary, or binding protocol decision; existing ADR breadth remains sufficient. +- **PRD/TRD:** current requirements already distinguish post-condition evidence from browser dispatch, semantic observation from action authority, resource evidence from trusted process attribution, and purpose-bound sensitive policy from the future trusted broker. #67–#72 remain active/non-shipped evidence and must not be described as `Implemented` on protected main. +- **Architecture/UML:** #70 materially strengthens executable proof that stock pinned Chromium can perform the controlled task, #71 binds the controlled targets to browser-computed semantic evidence before action, and #72 adds measured resource evidence for that controlled browser execution. None creates the versioned WebDriver BiDi/CDP product adapter or composes the existing OriginWeave semantic-node/policy/evidence/resource primitives end to end. The current high-level authority diagrams remain truthful; a detailed adapter → semantic observation → typed policy/action → post-condition/recovery/resource-evidence sequence becomes mandatory when that production composition boundary stabilizes rather than while the evidence runner remains the execution owner. +- **ERD/data model:** #67 is an immutable evidence value, #68/#69 are explicitly in-process policy state, and #70–#72 are ephemeral CI/browser evidence. None creates an OriginWeave-owned durable persistence schema. The conceptual ERD remains the truthful artifact; manufacturing physical tables would overstate the implementation. +- **Security/privacy:** #67 quarantines ambiguous-effect/incomplete-cleanup states. #68/#69 preserve exact reservation identity and immediate pre-disclosure recheck without exposing protected values. #70 uses synthetic local data, disables extensions in the Agent Task profile, and proves profile cleanup. #71 is intentionally limited to bounded browser-computed role/name evidence and does not elevate page content into instruction or capability authority. #72 reads only bounded Linux process status for a ChromeDriver-issued PID and emits resource measurements without credentials or page values. +- **Test/release/traceability:** #67–#72 have fresh exact-head green evidence at this refresh. #71/#72 preserve their observed test-first RED before exact-head GREEN. No predecessor-head success transfers across any moved head, and none of these active lanes is release evidence for protected `main` yet. + +## Interpretation rules + +1. `IMPLEMENTED_ON_ACTIVE_PR` and `PARTIAL` never mean shipped. +2. Exact-head CI/coverage evidence becomes stale immediately when that head moves. +3. A stacked PR cannot be independently integrated before its exact prerequisite lineage. +4. An active implementation refinement does not manufacture a new ADR merely to mirror every PR; create or supersede an ADR only when the governing architecture decision changes. +5. In-memory identities, immutable evidence values, controlled fixtures, bounded samplers, and ephemeral compatibility/resource evidence do not justify physical ERD entities without a real durable ownership boundary. +6. A real browser test harness is not the same authority as the production browser adapter. Promote browser/runtime maturity only when the protected-main product path owns session/context/origin/document identity, semantic observation, typed policy/action dispatch, post-condition verification, recovery, and evidence composition. +7. A single ChromeDriver-reported browser PID is not equivalent to trusted Chromium process-set or task attribution. Whole-browser/task RSS claims require an adapter-owned process set and the existing bounded aggregation contracts. +8. After any of these lanes integrates, re-evaluate PRD/TRD/Architecture/UML/ERD/traceability from the new protected-main head before changing maturity claims. + +## Subsequent active lanes observed in this refresh + +| PR | Scope | Maturity | Exact evidence / authority boundary | +|---|---|---|---| +| #73 | Bounded Chromium root-plus-descendant RSS evidence in the controlled pinned-browser fixture | **PARTIAL** | This Draft remains stacked on unchanged exact #72 head `1a7186085abe926c1d0e5b22c36760965d6e237b`. Earlier exact head `cbf922fccc83782d3e114ed65afbeb6d84ef5ce6` repaired nondeterministic handling of a sampled descendant with no resident `VmRSS` and passed exact CI/coverage plus pinned-browser repeatability, but a subsequent integrity audit found a narrower fail-open ambiguity: `_snapshot_linux_process_evidence` currently catches the strict parser's `exactly one VmRSS` failure and converts it to `None`, so duplicate/ambiguous `VmRSS` records can be normalized to the same absence state as a legitimately nonresident process. Exact test-only head `015e4a5f79c0abee40c6807b481d3afce613c6c4` required a dedicated optional-RSS parser in which absent/zero `VmRSS` yields `None`, exactly one positive field yields bounded bytes, and duplicate/malformed evidence fails closed. CI run `31462156163`, Rust contracts job `93687687157`, checked out that exact test head and produced the intended RED at the missing helper boundary with `KeyError`. Current exact head `ef6f23365f225b825505a58556d6917aeef505a2` removes only the temporary RED probe so the prerequisite stack is not intentionally left failing: CI run `31462292887`, Rust contracts job `93688085184`, Production coverage job `93688085247`, and Manifest V3 Compatibility run `31462292914` are successful. Those green results do not erase the integrity finding. This lane remains **PARTIAL** and must stay Draft until the snapshot source distinguishes legitimate absent/nonresident RSS from duplicate/malformed evidence, the focused regression is restored, and the exact corrected head passes both repository and real-browser gates. It is still controlled Linux `/proc` evidence, not trusted product process ownership, cgroup/per-tab/task attribution, GPU/VRAM attribution, or cross-platform semantics. | +| #74 | Extension proposal permission cannot widen Agent mutation, execution-mode/purpose, crawler/robots, non-delegable-action, or Human-mode authority | **IMPLEMENTED_ON_ACTIVE_PR** | Exact head `ac8b27ee69229070c382ca2199eaf9ec8b1b12db` is based directly on protected main. CI run `31462551154` succeeds and SAST Semgrep run `31462551097` succeeds; Security Scan run `31462551096` is still non-terminal and is **not** counted as passing. Nine integration regressions first prove that the exact extension/session/context grant permits `ProposeTypedAction`, then prove ordinary Agent policy still denies cross-origin `Submit` as `CrossOriginMutation`, same-origin `Submit` without write authority as `OriginNotWritable`, Crawler/PublicCrawl mutation as `CrawlerMutation`, AgentTask/PublicCrawl as `ModePurposeMismatch`, crawler observations with disallowed/unknown/not-applicable robots evidence as `RobotsDisallowed`/`RobotsUnknown`/`RobotsNotApplicable`, R5 `LegalConsent` as `ForbiddenRisk`, and Human mode as `HumanModeNotAgentControlled`. GitHub reports the PR mergeable and no inline review threads are currently returned. This adds no production API or extension authority and does not claim a real Chromium extension adapter exists; exact-current security acceptance remains pending until every required gate is terminal-success. | + +## Reconciliation for #73 and #74 + +The canonical verdict remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. + +- **ADR:** neither lane creates a new governing decision. #73 refines controlled evidence inside the existing resource/browser-adapter direction; #74 verifies the already documented separation between extension proposal permission and Agent action/origin/risk/control authority. No new ADR number should be allocated solely to mirror either PR. +- **PRD/TRD/Architecture:** the current contracts already require browser resource evidence to remain distinct from trusted attribution and require extension access not to imply Agent capability/origin/risk/control authority. #73 is now **PARTIAL** because exact RED evidence demonstrates an unresolved snapshot-integrity ambiguity even though the restored branch is green. #74 remains `IMPLEMENTED_ON_ACTIVE_PR` test evidence, but exact-current security acceptance is not complete until all required security gates are terminal-success. Neither is protected-main implementation. +- **UML:** the existing extension-authority view remains sufficient for #74 because no new actor, trust boundary, or execution edge is introduced. #73 remains an ephemeral CI evidence path and does not justify presenting `/proc` process lineage as a product deployment/authority relationship. +- **ERD/data model:** neither lane introduces durable OriginWeave-owned persistence, ownership, cardinality, or migration semantics. The conceptual ERD remains the truthful current artifact. +- **Security/test/release:** #73 preserves both its earlier functional RED→GREEN chain and the newer exact RED proving the evidence-integrity gap; the current green restoration is not a substitute for the source correction. #74 strengthens policy-composition regression evidence without widening authority, while its current security gate set remains incomplete. Neither lane is protected-main release evidence. diff --git a/docs/traceability/README.md b/docs/traceability/README.md index 3d5a298..e30b9ed 100644 --- a/docs/traceability/README.md +++ b/docs/traceability/README.md @@ -1,12 +1,12 @@ # OriginWeave Product and Decision Traceability - **Status:** Proposed authoritative traceability baseline -- **Scope:** Product requirements, Accepted architecture, implemented kernels, planned adapters, conversation-derived decisions, standards, and verification evidence +- **Scope:** Product requirements, Accepted architecture, protected-main implementation, active-PR implementation, planned adapters, conversation-derived decisions, standards, and verification evidence This file prevents two opposite errors: 1. an implemented safety boundary becoming undiscoverable because it exists only in code/tests; and -2. a product-design conversation or pull-request proposal being presented as if it already shipped. +2. a product-design conversation, issue, or active pull request being presented as if it already shipped. ## 1. Evidence precedence @@ -15,81 +15,111 @@ For current behavior, use this precedence order: 1. exact protected-main code and executable tests; 2. Accepted ADRs governing that code; 3. current root `ARCHITECTURE.md` and authoritative PRD/TRD aligned to protected main; -4. roadmap and issue/PR plans; -5. conversation-derived product decisions and research notes. +4. active-PR code/tests as explicitly labeled non-shipped evidence; +5. roadmap and issue plans; +6. conversation-derived product decisions and research notes. -Lower layers may define future direction but cannot override current protected implementation or an Accepted ADR. +Lower layers may define future direction but cannot override current protected implementation or an Accepted ADR. Active-PR behavior is never protected-main truth. -## 2. Status vocabulary +### 1.1 Active freshness-authority dossiers -- **Implemented** — present on protected `main` with executable evidence. -- **Accepted architecture** — governing reviewed direction, though the complete runtime path may be unfinished. -- **Proposed** — candidate product/design decision requiring reviewed adoption. -- **Open** — intentionally unresolved. +Transient implementation evidence that materially tightens an existing authority boundary is kept in explicit active-PR traceability rather than silently changing protected-main maturity: -A change can move from Proposed -> Accepted architecture -> Implemented, but never skips evidence merely because the idea is compelling. +- [`resolution-freshness-authority.md`](resolution-freshness-authority.md) — PR #47 bounds the lifetime of validated destination-resolution authority; the direct socket consumer still must require that fresh authority before the overall DNS-rebinding/TOCTOU interval can be called implemented on protected main. +- [`tls-revocation-freshness-authority.md`](tls-revocation-freshness-authority.md) — PR #48 classifies independently verified revocation material for freshness only; it does not fetch or authenticate OCSP/CRL material and does not create an unrevoked-certificate claim. + +These dossiers are evidence indexes, not substitute ADRs. A new ADR is required only when a durable architecture/trust/deployment decision changes. + +## 2. Capability maturity vocabulary + +Capability maturity uses exactly one of these values: + +- **IMPLEMENTED_ON_PROTECTED_MAIN** — present on protected `main` with executable evidence. +- **IMPLEMENTED_ON_ACTIVE_PR** — implemented and testable on an active PR, but not shipped/protected-main truth. +- **PARTIAL** — material foundations are implemented, while a named runtime, lifecycle, integration, or acceptance boundary remains incomplete. +- **ACCEPTED_ARCHITECTURE** — governing reviewed direction; implementation may be incomplete. +- **PLANNED** — accepted product backlog or target architecture without current implementation evidence. +- **RESEARCH_ONLY** — exploratory evidence that does not define a product commitment. +- **SUPERSEDED** — replaced by later implementation or architecture authority. +- **OUT_OF_SCOPE** — intentionally excluded from the current product boundary. + +ADR lifecycle is separate and remains `Proposed`, `Accepted`, `Superseded`, `Deprecated`, or `Rejected`. An Accepted ADR is design authority, not implementation proof. ## 3. Product-level decision trace -| Product decision | Origin/status | Authoritative artifact | Protected implementation/evidence | +| Product decision | Capability maturity | Authoritative artifact | Protected-main / active-PR evidence boundary | |---|---|---|---| -| Chromium remains the compatibility kernel rather than rewriting Blink/V8 | Accepted architecture | ADR 0001; `ARCHITECTURE.md`; PRD-COMP-001 | Architecture/repository contract tests; Chromium adapter itself remains Planned | -| `Browse. Act. Prove.` provenance-native product identity | Accepted product framing | `README.md`; `docs/PRD.md`; roadmap | Evidence/provenance foundation implemented; full buyer Evidence Trail Planned | -| Human / Assist / Agent Task / Crawler execution modes | Accepted architecture | `ARCHITECTURE.md`; `docs/PRD.md`; ADR 0002 | Core mode/purpose and policy foundation implemented; browser-session integration Planned | -| Page content is data, never instruction authority | Implemented foundation | ADR 0002; `ARCHITECTURE.md`; `docs/TRD.md` | `originweave-core` + `originweave-policy` tests | -| Typed actions instead of default arbitrary JavaScript | Accepted architecture | PRD-ACT-001..004; ADR 0002 | Typed core/policy foundation implemented; full browser action adapter Planned | -| logical origin != resolved destination | Implemented | ADR 0004; TRD-INV-002 | `originweave-destination`; destination governance tests | -| resolved destination != TCP peer | Implemented | ADR 0005; TRD Section 6 | `originweave-network`; loopback/peer tests | -| TCP peer != TLS service identity | Implemented | ADR 0006; TRD Section 6 | `originweave-tls`; rustls integration tests | -| Proxy/PAC route authority must be explicit | Accepted architecture / active development | PRD-NET-005; TRD Section 6.3 | Protected-main direct-only boundary exists; complete proxy execution not yet shipped | -| HTTP semantics require an authenticated governed connection and resource bounds | Accepted architecture / active development | PRD-NET-006; TRD Section 6.6 | Not yet a protected-main product capability in this baseline | -| Node handles bind session/context/origin/document lifetime | Proposed/active development | PRD-OBS-001/002; TRD Section 5 | Not treated as shipped until protected integration | -| Raw secrets never enter model context | Accepted architecture / implemented policy foundation | PRD-DATA-001; ADR 0002; TRD Section 9 | Core secret-delivery policy implemented; trusted broker runtime Planned | -| Sensitive disclosure is purpose-bound and classification-bound | Proposed/active development | PRD-DATA-002; TRD Section 9 | Do not claim complete broker/service until protected integration | -| Evidence/provenance are product outputs, not debug leftovers | Accepted / foundation implemented | ADR 0003; PRD Section 9.6 | `originweave-evidence`; evidence governance tests | -| Human interaction outranks inference/background collection | Accepted architecture / foundation implemented | `ARCHITECTURE.md`; PRD-RES-002 | Deterministic resource mitigation foundation implemented; platform telemetry Planned | -| Structured observation precedes raw HTML/screenshot fallback | Accepted architecture | PRD-OBS-003; TRD Section 7 | Observation adapter Planned | -| WebDriver BiDi / CDP / WebMCP / MCP are adapters, not internal authority | Accepted architecture | PRD Section 9.8; TRD Section 12 | Adapter implementations Planned | -| Manifest V3 compatibility is preserved upstream where practical | Accepted architecture | ADR 0001; PRD Section 9.9 | Chromium compatibility program Planned | -| WARC/PROV-oriented durable evidence adapters | Accepted architecture / Planned | ADR 0003; PRD-EVD-005 | Source/provenance kernel foundation exists; persistence adapters Planned | -| Origin Map visualizes value/action provenance | **conversation-derived Proposed** product UX | PRD-EVD-004; this traceability record | No shipped UI claim | -| Browser / Runtime / Observe / Capture / Governor / Policy / Evidence / Protocol / SDK product surfaces | **conversation-derived Proposed product taxonomy**, aligned to existing architecture | PRD Section 6 | Some foundations exist under crates; named commercial surfaces are not all shipped artifacts | -| Constrained GPU phase scheduling for browser rendering vs local inference | **conversation-derived Accepted architecture direction**, implementation Planned | PRD-RES-005; TRD Section 10 | Deterministic resource plan exists; real GPU scheduler/telemetry Planned | -| Enterprise SSO/SCIM/residency/audit/procurement package | Planned | PRD Section 9.11; roadmap Phase 5 | Not shipped in pre-alpha baseline | +| Chromium remains the compatibility kernel rather than rewriting Blink/V8 | ACCEPTED_ARCHITECTURE | ADR 0001; `ARCHITECTURE.md`; PRD-COMP-001 | Architecture/repository contracts exist; complete branded browser distribution remains Planned | +| `Browse. Act. Prove.` provenance-native product identity | ACCEPTED_ARCHITECTURE | `README.md`; `docs/PRD.md`; roadmap | Evidence/provenance foundations exist; complete buyer Evidence Trail remains Planned | +| Human / Assist / Agent Task / Crawler execution modes | PARTIAL | `ARCHITECTURE.md`; `docs/PRD.md`; ADR 0002 | Core mode/purpose/policy foundations exist; browser-session/profile integration remains incomplete | +| Page content is data, never instruction authority | IMPLEMENTED_ON_PROTECTED_MAIN | ADR 0002; `ARCHITECTURE.md`; `docs/TRD.md` | `originweave-core` + `originweave-policy` tests | +| Typed actions instead of default arbitrary JavaScript | PARTIAL | PRD-ACT-001..004; ADR 0002 | Typed core/policy foundations are on main; complete browser action adapter remains Planned | +| logical origin != resolved destination | IMPLEMENTED_ON_PROTECTED_MAIN | ADR 0004; TRD-INV-002 | `originweave-destination`; destination governance tests | +| Bounded resolution freshness is explicit before destination authority is consumed | IMPLEMENTED_ON_ACTIVE_PR | ADR 0004; [`resolution-freshness-authority.md`](resolution-freshness-authority.md) | PR #47 implements the deterministic freshness primitive; protected-main socket planning can still bypass it, so the overall resolution-to-socket TOCTOU boundary remains PARTIAL | +| resolved destination != TCP peer | IMPLEMENTED_ON_PROTECTED_MAIN | ADR 0005; TRD Section 6 | `originweave-network`; loopback/peer tests | +| TCP peer != TLS service identity | IMPLEMENTED_ON_PROTECTED_MAIN | ADR 0006; TRD Section 6 | `originweave-tls`; rustls integration tests | +| Revocation-material freshness is separate from revocation authenticity/non-revocation | IMPLEMENTED_ON_ACTIVE_PR | ADR 0006/0008 boundary; [`tls-revocation-freshness-authority.md`](tls-revocation-freshness-authority.md) | PR #48 adds a freshness classifier only; protected main still records revocation as NotConfigured and makes no unrevoked claim | +| Proxy/PAC route authority must be explicit | PARTIAL | PRD-NET-005; TRD Section 6.3 | Protected-main direct-route authority exists; PAC evaluation/proxy transport/CONNECT remain incomplete | +| Bounded HTTP semantics require an authenticated governed connection and resource bounds | IMPLEMENTED_ON_ACTIVE_PR | PRD-NET-006; issue #9; active PR #37 | `originweave-http` replacement exists on active PR #37; historical PR #11 is SUPERSEDED implementation lineage and is not current evidence; no protected-main HTTP claim yet | +| Node handles bind session/context/origin/document lifetime | PARTIAL | ADR 0010; PRD-OBS-001/002; TRD Section 5 | Core opaque session/context/document/node authority is on protected main; active PR #40 owns the protocol-ID registry and remains non-shipped evidence | +| Semantic observations retain OriginWeave node authority and explicit source-channel provenance | IMPLEMENTED_ON_ACTIVE_PR | PRD-OBS-001/003/005; ADR 0010; structured-observation architecture | Active PR #52, stacked on #40, implements a bounded `SemanticNodeObservation` value primitive that rejects missing evidence-channel provenance. It is not a browser observation adapter; channels and advertised node actions are descriptive evidence and grant no execution authority | +| Raw secrets never enter model context | PARTIAL | PRD-DATA-001; ADR 0002; TRD Section 9 | Core secret-delivery policy exists; trusted broker/runtime completion remains Planned | +| Sensitive disclosure is purpose- and classification-bound | PARTIAL | ADR 0007; PRD-DATA-002; issue #10 | Purpose-bound policy/evidence foundations are on protected main; active PR #45 adds credential-free handle-lifecycle evidence and #46 adds bounded in-process authoritative use reservation, while trusted storage/revocation/value resolution/cross-process lifecycle/model-disclosure remain open | +| Evidence/provenance are product outputs, not debug leftovers | PARTIAL | ADR 0003; PRD Section 9.6 | `originweave-evidence` foundations exist; complete durable Evidence Trail/WARC/PROV adapters remain Planned | +| Human interaction outranks inference/background collection | PARTIAL | `ARCHITECTURE.md`; PRD-RES-002 | Deterministic resource mitigation/CPU-worker admission foundations exist; platform telemetry/actuation remain Planned | +| Structured observation precedes raw HTML/screenshot fallback | ACCEPTED_ARCHITECTURE | PRD-OBS-003; TRD Section 7 | Active PR #52 supplies a non-shipped bounded semantic value primitive; real browser observation and fallback adapters remain Planned | +| WebDriver BiDi / CDP / WebMCP / MCP are adapters, not internal authority | ACCEPTED_ARCHITECTURE | PRD Section 9.8; TRD Section 12 | Protocol adapter implementation remains Planned/active under issue #28; active PR #40 may not be called shipped | +| Manifest V3 compatibility is preserved upstream where practical | PARTIAL | ADR 0001; issue #27; Proposed ADR 0013 | Protected main has pinned real-Chromium compatibility evidence for service worker/content script/storage/DNR/tabs/windows/scripting/commands/side panel/bookmarks/history/restart/repeatability; active PR #43 adds real bounded downloads evidence; full issue #27 matrix remains incomplete | +| Extension permission does not imply OriginWeave Agent capability | PARTIAL | protected-main extension authority kernel; Proposed ADR 0013 | Core extension-to-Agent authority isolation exists on protected main; complete managed-extension/native-messaging/enterprise release policy remains incomplete | +| WARC/PROV-oriented durable evidence adapters | PLANNED | ADR 0003; PRD-EVD-005 | Source/provenance kernel foundation exists; persistence/export adapters remain Planned | +| Origin Map visualizes value/action provenance | PLANNED | PRD-EVD-004; this traceability record | No shipped UI claim | +| Browser / Runtime / Observe / Capture / Governor / Policy / Evidence / Protocol / SDK product surfaces | PARTIAL | PRD Section 6 | Some foundations exist under crates; named commercial surfaces are not all shipped artifacts | +| Constrained GPU phase scheduling for browser rendering vs local inference | PARTIAL | PRD-RES-005; TRD Section 10 | Deterministic resource plan exists; real GPU scheduler/telemetry remains Planned | +| Enterprise SSO/SCIM/residency/audit/procurement package | PLANNED | PRD Section 9.11; roadmap Phase 5 | Not shipped in pre-alpha baseline | ## 4. Requirement-to-module trace -| Requirement family | Current module(s) | Primary tests/docs | Implementation status | +| Requirement family | Current module(s) / lane | Primary tests/docs | Capability maturity | |---|---|---|---| -| Canonical origin / action / approval | `originweave-core` | crate tests; ADR 0002 | Implemented | -| Deterministic action policy | `originweave-policy` | policy/security-review tests | Implemented | -| Destination/rebinding/redirect | `originweave-destination` | destination tests; ADR 0004 | Implemented | -| Exact direct socket/peer | `originweave-network` | real loopback + error tests; ADR 0005 | Implemented | -| TLS identity | `originweave-tls` | real rustls integration; ADR 0006 | Implemented | -| Resource budgets/mitigations | `originweave-resource` | crate tests | Implemented foundation | -| Redacted evidence/provenance | `originweave-evidence` | crate tests; ADR 0003 | Implemented foundation | -| HTTP | future/active `originweave-http` work | dedicated design/tests/PR evidence | Planned until protected merge | -| Proxy/PAC | destination foundation + future adapter | roadmap/TRD | Planned/active | -| Session/observation/action | future crates/adapters | roadmap/TRD/UML | Planned/active | -| Secret broker | future bounded service/crate | PRD/TRD | Planned/active | -| BiDi/CDP/WebMCP/MCP | adapter crates | protocol compatibility tests required | Planned | -| WARC/PROV persistence | persistence adapters | doctoring + future conformance tests | Planned | +| Canonical origin / action / approval | `originweave-core` | crate tests; ADR 0002 | IMPLEMENTED_ON_PROTECTED_MAIN | +| Deterministic action policy | `originweave-policy` | policy/security-review tests | IMPLEMENTED_ON_PROTECTED_MAIN | +| Destination/rebinding/redirect | `originweave-destination` | destination tests; ADR 0004 | IMPLEMENTED_ON_PROTECTED_MAIN | +| Resolution freshness authority | active `originweave-destination` work in PR #47 | [`resolution-freshness-authority.md`](resolution-freshness-authority.md); active exact-head tests/coverage | IMPLEMENTED_ON_ACTIVE_PR | +| Exact direct socket/peer | `originweave-network` | real loopback + error tests; ADR 0005 | IMPLEMENTED_ON_PROTECTED_MAIN | +| TLS identity | `originweave-tls` | real rustls integration; ADR 0006 | IMPLEMENTED_ON_PROTECTED_MAIN | +| TLS revocation-material freshness | active `originweave-tls` work in PR #48 | [`tls-revocation-freshness-authority.md`](tls-revocation-freshness-authority.md); active exact-head tests/coverage | IMPLEMENTED_ON_ACTIVE_PR | +| Resource budgets/mitigations | `originweave-resource` | crate tests | PARTIAL | +| Redacted evidence/provenance | `originweave-evidence` | crate tests; ADR 0003 | PARTIAL | +| Bounded HTTP/1.1 | active `originweave-http` replacement in PR #37 | issue #9; active-PR unit/integration/coverage evidence | IMPLEMENTED_ON_ACTIVE_PR | +| Proxy/PAC | destination/route foundation + future adapter | roadmap/TRD | PARTIAL | +| Session/context/document/node authority | `originweave-core` authority values; active registry work in PR #40 | ADR 0010; roadmap/TRD/UML | PARTIAL | +| Semantic observation value authority/provenance | active `originweave-core` work in PR #52, stacked on #40 | `semantic_node_observation` tests; PRD-OBS-001/003/005; issue #28 | IMPLEMENTED_ON_ACTIVE_PR | +| Manifest V3 compatibility evidence | `scripts/ci/run_mv3_compatibility.py` + controlled MV3 fixture; active downloads lane #43 | issue #27; real-browser contracts | PARTIAL | +| Extension-to-Agent authority | protected-main core authority kernel + Proposed ADR 0013 | issue #27; extension authority UML | PARTIAL | +| Purpose-bound sensitive-data policy/evidence | `originweave-policy` + evidence foundations; active lifecycle/reservation work #45/#46 | ADR 0007; issue #10 | PARTIAL | +| Trusted sensitive-data broker/storage/lifecycle | future bounded service/crate | issue #10; PRD/TRD/data governance | PLANNED | +| BiDi/CDP/WebMCP/MCP | future/versioned adapter crates; registry prerequisite active in #40 | protocol compatibility tests required | PLANNED | +| WARC/PROV persistence | persistence/export adapters | doctoring + future conformance tests | PLANNED | ## 5. Requirement-to-ADR trace -| Requirement | Governing ADR | +| Requirement | Governing ADR / current decision boundary | |---|---| -| PRD-COMP-001, PRD-COMP-003 | ADR 0001 | -| PRD-ACT-001, PRD-ACT-005, PRD-CRAWL-001, trust-source boundary | ADR 0002 | -| PRD-EVD-001, PRD-EVD-002, PRD-EVD-005 | ADR 0003 | -| PRD-NET-001, PRD-NET-002, redirect/rebinding boundary | ADR 0004 | -| PRD-NET-003 | ADR 0005 | -| PRD-NET-004 | ADR 0006 | -| Session/context/document node binding | Proposed/active decision; index only after dedicated ADR reaches protected main | -| Proxy/PAC route execution | Proposed/active decision; protected-main index updates after merge | -| HTTP semantics | Proposed/active decision; protected-main index updates after merge | -| Sensitive-data broker lifecycle | Proposed/active decision; policy/evidence slices do not equal full broker acceptance | -| Enterprise deployment/privacy | Open ADR family before production release | +| PRD-COMP-001, Chromium compatibility kernel | ADR 0001 (Accepted) | +| PRD-ACT-001, PRD-ACT-005, PRD-CRAWL-001, trust-source boundary | ADR 0002 (Accepted) | +| PRD-EVD-001, PRD-EVD-002, PRD-EVD-005 | ADR 0003 (Accepted) | +| PRD-NET-001, PRD-NET-002, redirect/rebinding/freshness boundary | ADR 0004 (Accepted); active PR #47 tightens the existing boundary without creating a new deployed component or trust owner | +| PRD-NET-003 | ADR 0005 (Accepted) | +| PRD-NET-004 | ADR 0006 (Accepted); active PR #48 adds revocation-material freshness only and does not define a complete revocation architecture | +| Purpose-bound sensitive-data authority | ADR 0007 (Accepted); trusted broker/storage/lifecycle still issue #10 | +| TLS delegated-task leaf-validity horizon | ADR 0008 (Accepted) | +| Session/context/document/node binding | ADR 0010 (Accepted); active registry implementation #40 remains non-shipped | +| Semantic observation authority/provenance | Existing session/node authority plus structured-observation architecture; active PR #52 narrows the value contract without creating a new service, trust owner, persistence boundary, or external protocol and therefore does not justify a new ADR by itself | +| Manifest V3 compatibility + extension-to-Agent authority | ADR 0013 is Proposed on documentation PR #44; protected-main extension authority code does not auto-Accept the ADR | +| Architecture-decision acceptance governance | ADR 0014 is Proposed on documentation PR #44; protected-main AGENTS + live policy remain authoritative | +| HTTP semantics | active PR #37 contains its feature ADR lineage; it is active-PR evidence until protected merge and index reconciliation | +| Proxy/PAC route execution | current protected-main route authority + future dedicated execution decision as needed | +| Enterprise deployment/privacy | open ADR family before production release | ## 6. Standards-to-decision trace @@ -100,8 +130,8 @@ The canonical APA 7th bibliography is [`../doctoring.md`](../doctoring.md). This | WHATWG URL + Chromium canonicalizer | Browser-compatible origin identity and numeric-host rejection | | IANA special-purpose registries / RFC 6890 / RFC 8190 / RFC 9637 | Destination classification and fail-closed public-web policy | | RFC 9293 | Exact TCP endpoint/peer model | -| RFC 5280 / RFC 9525 / current TLS guidance | Certificate path and HTTPS service identity | -| RFC 9110 and related HTTP specifications | Redirect and bounded HTTP semantics | +| RFC 5280 / RFC 9525 / RFC 9325 | Certificate path, HTTPS service identity, and the separation between certificate validity and any future revocation policy | +| RFC 9110 / RFC 9112 / RFC 9530 | Bounded HTTP semantics, framing, redirect evidence and digest fields | | RFC 9309 | Crawler robots evidence, explicitly not access authorization | | W3C WebDriver BiDi | Versioned browser automation adapter, not core authority | | Chrome DevTools Protocol | Chromium-specific observation/diagnostic adapter | @@ -114,15 +144,17 @@ Material claims should update `docs/doctoring.md` with current primary evidence ## 7. Diagram-to-requirement trace -| Diagram | Requirements represented | +| Diagram | Requirements represented / maturity | |---|---| | UML component/bounded-context view | Product family, Chromium/Rust ownership, adapter boundaries | -| Network authority sequence | PRD-NET-001..007; TRD-INV-002 | -| Observation/action sequence | PRD-OBS, PRD-ACT, PRD-DATA, trust separation | +| Network authority sequence | PRD-NET-001..007; TRD-INV-002; HTTP remains active-PR until #37 integrates; resolution freshness remains an active lower-layer primitive until the socket consumer requires it | +| Observation/action sequence | PRD-OBS, PRD-ACT, PRD-DATA, trust separation; active #52 makes the bounded semantic-observation value/provenance contract explicit without establishing browser I/O or action dispatch | | Delegated-task state machine | session lifecycle, approval, resource pause, cancellation/recovery, post-condition truth | | Deployment topology | renderer trust, orchestrator/model/store boundaries | -| Evidence authority flow | PRD-EVD; separation of proposal/policy/approval/execution/outcome | -| Conceptual ERD | durable session/action/network/sensitive/resource/provenance identity | +| Evidence authority flow | PRD-EVD; proposal/policy/approval/execution/outcome separation | +| Extension authority sequence | MV3 compatibility plane vs explicit OriginWeave extension grant and Agent capability separation | +| Conceptual ERD | session/action/network/sensitive/resource/provenance identity; active freshness and semantic-value primitives introduce no physical persistence | +| Real Chromium vertical-slice sequence | PLANNED until issue #28 implementation stabilizes; active #40/#51/#52 are prerequisites, not proof of the real adapter flow; do not encode temporary adapter fields as shipped architecture | ## 8. Conversation-to-repository capture rule @@ -130,23 +162,29 @@ A **conversation-derived** decision is not binding merely because it was repeate If material and absent from GitHub: -1. record it as `Proposed` or `Open` in PRD/TRD/traceability; -2. create/supersede an ADR when it changes a governing architecture decision; +1. record it with explicit capability maturity in PRD/TRD/traceability; +2. create or supersede an ADR when it changes a governing architecture decision; 3. update UML/ERD when relationships or lifecycles change; 4. add standards/research to `docs/doctoring.md` when evidence is material; -5. add executable tests before calling production behavior Implemented; +5. add executable tests before calling production behavior `IMPLEMENTED_ON_PROTECTED_MAIN`; 6. update the protected-main ADR index only after review and merge. This rule intentionally prevents chat history from becoming a shadow architecture database. ## 9. Documentation drift checks -Repository contracts should fail when the canonical PRD/TRD/ADR index/UML/ERD/traceability files disappear or when core status/authority vocabulary is removed. More semantic checks should be added when a specific drift has caused a real defect; avoid brittle tests that duplicate prose without protecting a contract. +Repository contracts should fail when canonical PRD/TRD/ADR/UML/ERD/traceability artifacts disappear, lifecycle/index status diverges, an active PR is promoted to protected-main truth, or core maturity/authority vocabulary is removed. Active freshness dossiers must remain discoverable from this index so lower-layer primitives cannot silently become over-broad shipped claims. More semantic checks should be added when a specific drift has caused a real defect; avoid brittle tests that merely duplicate prose. ## 10. Open traceability work +- **Open:** active PR #47 must reach unchanged exact-head CI/security/100% coverage, then the first-party socket consumer must require the fresh resolution authority before the resolution-to-socket TOCTOU interval can become protected-main implemented evidence. +- **Open:** active PR #48 remains freshness classification only; define and review revocation-material acquisition/authenticity/cache/failure/composition before any protected-main revocation-enforcement or unrevoked claim. +- **Open:** after #37 integrates, move bounded HTTP from `IMPLEMENTED_ON_ACTIVE_PR` into protected-main evidence and close historical PR #11 only after unique-work preservation and protected-main verification are proven. +- **Open:** after #43 integrates, move bounded MV3 downloads from `IMPLEMENTED_ON_ACTIVE_PR` into the protected-main compatibility evidence inventory while issue #27 remains open for the complete matrix. +- **Open:** after #40 stabilizes/integrates, map its registry API and tests without presenting raw BiDi/CDP identifiers as durable authority. +- **Open:** after stacked #52 stabilizes/integrates behind #40, reclassify only its bounded semantic-observation value/provenance primitive; keep real browser observation I/O, action dispatch, mutation invalidation and post-condition evidence under issue #28 until implemented. +- **Open:** after #45/#46 integrate, reclassify their narrow lifecycle/reservation primitives while keeping durable trusted-broker storage/revocation/value-resolution/model-disclosure boundaries under issue #10 until implemented. - **Open:** attach concrete release profiles and quantitative benchmark thresholds after reproducible benchmark evidence exists. - **Open:** map every future public OriginWeave Protocol operation to risk/capability/authority and conformance tests. - **Open:** map enterprise controls to exact SOC 2/CSAP-oriented control evidence without claiming certification. - **Open:** add data-retention and residency lifecycle diagrams when persistence/tenant adapters become concrete. -- **Open:** after active feature PRs merge, update this matrix from `Proposed/active development` to the exact protected implementation and Accepted ADRs. diff --git a/docs/traceability/action-postcondition-evidence.md b/docs/traceability/action-postcondition-evidence.md new file mode 100644 index 0000000..23a6e76 --- /dev/null +++ b/docs/traceability/action-postcondition-evidence.md @@ -0,0 +1,116 @@ +# Action Post-Condition Evidence Traceability + +- **Documentation status:** Active-PR evidence dossier +- **Canonical owner:** PR #44 (`docs: reconcile architecture documentation fitness`) +- **Protected-main baseline:** `67af7c87589edc2039545af335c95064d9b8391c` +- **Capability maturity:** **PARTIAL** +- **Governing decisions:** Accepted ADR 0003 plus Proposed ADR 0106 preserve provenance-native evidence and separation of action execution from verification. + +## 1. Why this dossier exists + +OriginWeave's protected-main API contract already defines a durable product rule: returning from a browser command is not equivalent to successful action completion. A state-changing action becomes successful only after the declared or derived post-condition is observed and verified. Protected main also provides generic credential-safe provenance with explicit verification state, but that design rule was not yet represented by a reusable typed action-outcome evidence object. + +This dossier records the active implementation evidence that narrows that gap. It does not promote active pull requests to protected-main shipped truth and it does not claim that a real Chromium adapter already observes the post-condition after dispatch. + +## 2. Protected-main design and implementation boundary + +Protected `main` already provides: + +- typed `ActionKind` and immutable `ActionIntentDigest` values; +- canonical `Origin` authority values; +- credential-safe `ProvenanceRecord` with explicit `VerificationResult`; +- API/TRD requirements that state-changing success waits for an observed post-condition; and +- provenance architecture that keeps observation, policy, execution, and verification as distinct authorities. + +The generic value primitives are **IMPLEMENTED_ON_PROTECTED_MAIN**. The complete action dispatch → observation → independent verification → successful outcome chain remains **PARTIAL** because protected main does not yet contain the real Chromium runtime that composes them end to end. + +## 3. Active executable evidence + +### PR #64 — verified, temporally ordered post-condition becomes typed action-outcome evidence + +**Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR` + +Exact head `2c45411ed9aa0eecca2d06c85659db9f4bb85e4d` adds `VerifiedActionOutcomeEvidence` in the existing credential-safe evidence crate. It binds: + +1. the exact typed `ActionKind`; +2. canonical target `Origin`; +3. complete immutable `ActionIntentDigest`; +4. a bounded first-slice `PostConditionKind` (`UrlChanged`, `NodeStateChanged`, `DialogStateChanged`, or `NetworkMutationObserved`); +5. caller-supplied action-dispatch and post-condition-observation timestamps that must come from one monotonic clock domain; and +6. the exact `ProvenanceRecord` used as the post-condition proof. + +Construction fails closed unless the supplied provenance has `VerificationResult::Verified`. Both `Unverified` and `Rejected` observations are rejected as `PostConditionNotVerified`. An observation timestamp earlier than dispatch is rejected as `PostConditionPredatesDispatch`; equal ticks remain valid for coarse monotonic clocks. + +On this exact head, CI run `31441848670`, Security Scan run `31441848649`, SAST Semgrep run `31441848615`, exact owned production function/line/region/branch coverage, strict Clippy, rustdoc and CodeRabbit exact-head status are successful. GitHub reports the PR mergeable and Ready for review; no formal reviews or inline review threads are currently returned. + +### PR #65 — controlled hostile local workflow fixture + +**Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR` + +Test-only head `d2580305f05aba93d10b5342ec1886d601c6752e` was based directly on the protected-main baseline and intentionally required a checked-in `tests/fixtures/agent_task_basic/index.html` before that fixture existed. CI run `31445088008`, Rust contracts job `93637443229`, checked out that exact head and failed with three `FileNotFoundError` results for the missing fixture, establishing the intended fail-first boundary. + +Exact head `0888fe3a6ef6da547a37fd075733cc73dc52b2ab` adds the smallest controlled fixture satisfying the contract: a labelled semantic field, submit control, deterministic `idle` → `submitted` observable state change carrying only synthetic text, one explicitly hidden/untrusted prompt-injection marker, and no password/OTP/API-key/secret collection surface. + +On that unchanged exact head, CI run `31445201739` succeeds; Rust contracts job `93637824750` passes repository contracts, formatting, locked workspace check, full tests, strict Clippy and rustdoc; Production coverage job `93637824824` passes exact owned production function/line/region/branch enforcement; Security Scan run `31445201774`, SAST Semgrep run `31445201669` and CodeRabbit exact-head status succeed. GitHub reports the PR mergeable and Ready for review with no formal reviews or inline review threads currently returned. + +This remains controlled test infrastructure rather than browser-execution evidence. The fixture itself does not establish WebDriver BiDi/CDP transport, Chromium semantic extraction, policy dispatch, native input, post-condition provenance, profile teardown or process attribution. + +## 4. Non-transitive success semantics + +The intended first-slice chain is: + +```text +typed action intent +-> policy-authorized dispatch +-> real browser input/event +-> observed bounded post-condition +-> independently verified provenance +-> temporally ordered VerifiedActionOutcomeEvidence +``` + +The active PR implements only the final typed evidence boundary. The following implications are explicitly invalid: + +```text +command return -/> successful action completion +protocol acknowledgement -/> successful action completion +Unverified -/> successful action completion +Rejected -/> successful action completion +caller-supplied timestamp ordering -/> proof of trusted clock provenance +VerifiedActionOutcomeEvidence type existence -/> proof of real Chromium execution +controlled fixture success -/> proof of real Chromium execution +``` + +PR #64 now rejects a caller-supplied observation timestamp that predates caller-supplied dispatch time, but the type cannot independently prove the clock source, that a real browser actually dispatched the action, that the supplied provenance belongs to the claimed browser target/node, or that the observed state was caused by that action. PR #65 supplies deterministic hostile input and a post-condition target but no browser execution. Those claims remain the responsibility of the real adapter/runtime composition under issue #28. + +## 5. Active prerequisite graph for issue #28 + +The first real Chromium vertical slice remains distributed across bounded active prerequisites rather than one shipped runtime: + +- PR #40 — protocol/browser identifiers → OriginWeave session/context/origin/document/node authority; +- PR #52 — bounded semantic node observation with explicit source-channel provenance; +- PR #57 — typed semantic-node query contract; +- PR #58 — authority-bound semantic node action target; +- PR #49 — ephemeral compatibility-profile lifecycle regression stacked on #43; +- PR #51 — bounded browser-task telemetry plus one explicitly supplied Linux PID `VmRSS` sampler; Chromium process discovery/process-set attribution remains outside that slice; +- PR #64 — verified and caller-timestamp-ordered post-condition action-outcome evidence; and +- PR #65 — controlled hostile local Agent Task workflow fixture, gate-clean and Ready for review. + +These active PRs are non-shipped evidence. They do not themselves compose WebDriver BiDi/CDP transport, trusted Chromium process attribution, policy-authorized real input dispatch, causal post-condition observation, or deterministic end-to-end teardown/recovery into one protected-main runtime. + +## 6. Remaining issue #28 boundary + +This dossier does **not** close issue #28. Material remaining work includes: + +- pinned stock Chromium exercised as one reproducible end-to-end Agent Task runtime path, not only extension compatibility fixtures; +- isolated Agent Task profile/context lifecycle and cleanup in the production vertical path; +- versioned WebDriver BiDi adapter plus explicitly bounded CDP observation fallback where needed; +- real semantic observation feeding typed query and policy-authorized typed action; +- real browser input dispatch followed by post-dispatch observation of the declared condition; +- hostile/stale/cross-session/cross-context/cross-origin/prompt-injection/secret-leak/crash/oversize regressions; +- deterministic failure/recovery evidence and task teardown; +- Chromium process discovery/process-set attribution composed into resource telemetry; and +- protected-main integration plus fresh acceptance before any active-PR capability becomes shipped truth. + +## 7. Documentation fitness consequence + +The ADR/PRD/TRD/Architecture/UML/ERD graph remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. PR #64 narrows a typed evidence gap already governed by existing provenance/action-success decisions, while PR #65 supplies controlled test infrastructure for the eventual real-browser proof. Neither introduces a new trust domain, deployed component, persistence owner, database schema, or independent architecture decision, so a new ADR or physical ERD entity would overstate the implementation. Detailed real-Chromium dispatch/post-condition sequence diagrams should be reconciled when the executable adapter chain stabilizes rather than manufacturing as-built detail before that runtime exists. diff --git a/docs/traceability/extension-authority-security.md b/docs/traceability/extension-authority-security.md new file mode 100644 index 0000000..a36380a --- /dev/null +++ b/docs/traceability/extension-authority-security.md @@ -0,0 +1,85 @@ +# Extension-to-Agent Security Traceability + +- **Documentation status:** Active-PR evidence dossier +- **Canonical owner:** PR #44 (`docs: reconcile architecture documentation fitness`) +- **Protected-main baseline:** `67af7c87589edc2039545af335c95064d9b8391c` +- **Capability maturity:** **PARTIAL** +- **Governing decision:** Proposed ADR 0013 separates Manifest V3 compatibility from OriginWeave Agent authority. + +## 1. Why this dossier exists + +Manifest V3 compatibility and OriginWeave Agent authority are intentionally different evidence domains. A Chromium extension may possess Chrome permissions and may be explicitly granted a narrow OriginWeave extension capability without receiving Agent origin grants, Agent action capability, instruction trust, secret-delivery authority, approval, or protected-value access. + +This dossier records the current executable composition evidence for that separation. It does not promote active pull requests to protected-main shipped truth and it does not claim the trusted sensitive-data broker from issue #10 is complete. + +## 2. Protected-main authority + +Protected `main` already provides: + +- exact extension/session/context-scoped `ExtensionAgentGrant` evaluation; +- a distinction between `ObserveCurrentContext` and `ProposeTypedAction` extension capabilities; +- deterministic Agent policy evaluation for typed actions; +- fail-closed treatment of `InstructionSource::WebContent`; +- explicit Agent capability and readable/writable-origin gates; +- `FillSecret` policy that rejects raw secret delivery and requires `SecretDelivery::BrokerHandle`; and +- ordinary action-risk approval semantics that remain separate from extension permission. + +These foundations are **IMPLEMENTED_ON_PROTECTED_MAIN**. They do not by themselves prove every issue #27 cross-boundary composition case. + +## 3. Active executable evidence + +### PR #62 — proposal authority cannot widen Agent, instruction, or secret-material authority + +**Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR` + +Exact head `a57873b3688984711918be17aadd348ed9fb12a9` proves that, after an extension is genuinely allowed to `ProposeTypedAction`: + +1. a proposed navigation outside the Agent readable-origin grant is still denied; +2. proposal permission cannot supply the missing Agent `Navigate` capability; +3. extension-produced untrusted content remains rejected as instruction authority; +4. `FillSecret` with `SecretDelivery::RawValue` remains denied as `SecretBrokerRequired`; and +5. secret material attached to a non-secret action remains denied as `UnexpectedSecretMaterial`. + +The branch adds no production API and no extension runtime. It is compositional security evidence over protected-main authorities. + +### PR #63 — proposal authority cannot manufacture high-risk approval + +**Capability maturity:** `IMPLEMENTED_ON_ACTIVE_PR` + +Exact head `e83749acd1cf5a0b778ba38eb9d6ed5a9bd1e68f` deliberately keeps only the distinct approval-composition proof after duplicate regressions were removed in favor of PR #62 ownership. It proves that, after the same exact proposal grant is admitted and the Agent context independently possesses `FillSecret` plus exact readable/writable origin authority, broker-handle `FillSecret` still reaches the ordinary R3 approval boundary rather than becoming implicitly allowed. + +The exact head has successful CI, exact owned production coverage, Security Scan, SAST and CodeRabbit status and is Ready for review. It has no raw secret bytes and does not create approval evidence, a broker, browser-fill adapter, protected-value store, KMS path, authenticated workload identity, persistence owner, or release claim. + +## 4. Security interpretation + +The executable authority chain is intentionally non-transitive: + +```text +Chromium extension permission +-> explicit extension/session/context grant +-> permission to propose a typed action +-/> Agent capability +-/> Agent readable/writable origin +-/> trusted instruction source +-/> secret-delivery authority +-/> approval +-/> protected-value resolution +``` + +A future real extension adapter must preserve these separations. Chrome permissions and extension proposal grants are inputs to policy composition, never ambient authority that bypasses the deterministic Agent policy or the sensitive-data broker boundary. + +## 5. Remaining issue #27 / #10 boundary + +This dossier does **not** close issue #27 or issue #10. Remaining material work includes, among other accepted requirements: + +- real managed-extension allow-list and enterprise policy integration; +- native-messaging host boundary and process isolation; +- complete supported-capability release matrix and regression gate; +- authenticated workload/service identity for sensitive-data broker audience; +- protected-value resolution/fill outside model-visible context; +- durable transactional handle lifecycle, retention, encryption/KMS, deletion and audit-export controls; and +- protected-main integration plus fresh acceptance before any active-PR evidence becomes shipped truth. + +## 6. Documentation fitness consequence + +The existing ADR/PRD/TRD/Architecture/UML/ERD graph remains **DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL**. PRs #62 and #63 narrow distinct executable extension-authority evidence gaps without introducing a new trust domain, deployment component, persistence entity, database schema, or independent architecture decision. Proposed ADR 0013 remains Proposed until its own lifecycle authority changes. \ No newline at end of file diff --git a/docs/traceability/resolution-freshness-authority.md b/docs/traceability/resolution-freshness-authority.md new file mode 100644 index 0000000..edb91e4 --- /dev/null +++ b/docs/traceability/resolution-freshness-authority.md @@ -0,0 +1,99 @@ +# Resolution Freshness Authority Trace + +- **Documentation status:** Active-PR traceability +- **Protected-main capability status:** **PARTIAL** +- **Primitive implementation lane:** PR #47, `feat/resolution-freshness-authority-main` +- **First-party planning consumer lane:** PR #50, `feat/network-consume-resolution-freshness` +- **Socket-use freshness lane:** PR #54, `fix/network-resolution-freshness-at-use` +- **Governing existing decision boundary:** ADR 0004 and the protected-main destination/rebinding authority model +- **Buyer-visible gap:** bind the interval between a validated resolution answer and actual socket use so DNS-rebinding/TOCTOU exposure is explicit and fail-closed + +## Truth boundary + +Protected `main` already classifies, approves, pins, and non-expansively revalidates resolved destination addresses. It does **not** yet require a time-bounded resolution authority through the entire first-party direct-socket path. + +PR #47 exact head `6b5ed4dcea281b505f67db6180bb14c3bc95b392` contains the reusable production `FreshResolutionSnapshot` primitive and has terminal successful CI/security/SAST/exact-coverage evidence. That primitive is therefore **IMPLEMENTED_ON_ACTIVE_PR** evidence only; it is not protected-main truth. + +PR #50 exact head `f8b43bc94444986ab23aa4ef3086e446a0b39295` implements the dependent first-party planning boundary. It keeps the untimed `ConnectionPlan` internal to `originweave-network`, exposes `FreshConnectionPlan` as the ordinary direct-socket planner, requires a `FreshResolutionSnapshot` plus caller-supplied trusted monotonic current time, rejects expired authority at plan authorization, and migrates existing TLS integration helpers through that same fresh boundary. Exact-head CI run `31408474576` passes repository contracts, formatting, workspace check/tests, strict Clippy, rustdoc and exact owned production function/line/region/branch coverage; CodeRabbit exact-head status is success. + +PR #54 exact head `ec81031c537f2b662910c1ce78c7ae0e0bfc9c1e` closes a later plan-to-connect TOCTOU discovered after #50: freshness checked only when the plan was created could expire before socket I/O. The active lane retains the exact `FreshResolutionSnapshot` in the single-use plan, exposes `connect_at(current_time)` to re-run freshness immediately before socket use under the caller's trusted monotonic clock domain, and keeps the legacy `connect()` surface fail-closed by adding process-local monotonic elapsed time to the original authorization checkpoint before delegating to `connect_at`. CI run `31418337788` passes repository contracts, formatting, workspace checks/tests, strict Clippy, rustdoc and exact owned production function/line/region/branch coverage; CodeRabbit exact-head status is successful. + +PRs #47, #50 and #54 remain **IMPLEMENTED_ON_ACTIVE_PR**, not shipped. #50 remains dependency-gated on #47 and #54 remains dependency-gated on #50. The overall protected-main resolution-to-socket interval therefore remains **PARTIAL** until dependency-ordered integration and fresh protected-main acceptance prove the same authority chain without an untimed planning or delayed-use bypass. + +## Current exact-head RCA + +### PR #47 primitive + +The first production-complete PR #47 head reached all ordinary Rust contracts and security scans, but exact coverage failed at one compiler region while functions, lines, and branches were already complete. Coverage evidence localized the missing region to the generic `FreshResolutionSnapshot::revalidate` instantiation used with a one-address resolver answer: the success path for a one-address contraction was exercised, while the same monomorphized helper's error propagation for a one-address expansion had not been executed. + +That was a realistic DNS-rebinding case rather than an impossible instrumentation artifact. The branch added a focused one-address expansion regression requiring `ResolutionSetExpanded`, retained the two-address expansion case, and exact head `6b5ed4dcea281b505f67db6180bb14c3bc95b392` subsequently passed CI including exact production function/line/region/branch coverage, Security Scan, and SAST Semgrep. + +The freshness ceiling is executable active-PR evidence rather than an aspirational requirement. `crates/originweave-destination/src/resolution.rs` owns `MAX_RESOLUTION_VALIDITY: Duration = Duration::from_secs(30)`. `FreshResolutionSnapshot::approve` rejects `Duration::ZERO` and any interval above that constant with `DestinationError::InvalidResolutionValidity`; `crates/originweave-destination/tests/resolution_freshness.rs::fresh_resolution_rejects_invalid_or_overflowing_validity` verifies both the zero and greater-than-30-second boundaries plus approval-time overflow. This evidence remains active-PR-only until PR #47 integrates. + +### PR #50 planning consumer + +PR #50 began from exact PR #47 head `6b5ed4dcea281b505f67db6180bb14c3bc95b392` with a RED consumer contract requiring fresh resolution authority plus one trusted monotonic current time before direct socket planning. + +A first production repair added a public `FreshConnectionPlan` wrapper that authorized freshness and then delegated to the existing untimed `ConnectionPlan`. That implementation made the positive/expiry path available but did not close the buyer/security gap because the original public `ConnectionPlan::new(&ResolutionSnapshot, ...)` remained callable. Canonical review therefore rejected the parallel-wrapper design as insufficient rather than weakening the acceptance boundary. + +The corrected implementation removed `ConnectionPlan` from the public crate exports while retaining it as a private implementation detail. Exact-head CI run `31407686307` then failed at the intended first-party migration boundary: `cargo check --locked --workspace --all-targets` found exactly three TLS integration tests still importing the now-private stale planner (`handshake_deadline.rs`, `handshake_integration.rs`, and `validity_horizon_integration.rs`). That compile failure was useful evidence because it enumerated remaining first-party bypass consumers instead of hiding them behind a compatibility re-export. + +Those integration helpers were migrated to deterministic `FreshResolutionSnapshot` + `FreshConnectionPlan` fixtures with one explicit trusted monotonic clock domain. A later run `31408143459` found only missing end-of-file newlines under rustfmt; that formatting-only defect was corrected without changing the authority contract. Current exact head `f8b43bc94444986ab23aa4ef3086e446a0b39295` then passed CI run `31408474576` end to end, including exact owned function/line/region/branch coverage. + +The accepted remedy is therefore realized on the active branch: ordinary first-party direct planning cannot import the untimed planner, while the private implementation remains reusable only after `FreshConnectionPlan` performs freshness authorization. This proves the active planning implementation, but not freshness at a later delayed socket-use instant. + +### PR #54 socket-use consumer + +PR #54 follows #50 because a plan authorized within the resolution window could be retained until that window expired and then connected. The first failing boundary was therefore no longer public planner construction; it was the time between plan authorization and the exact operating-system connect operation. + +The accepted active-branch remedy keeps the admitted freshness snapshot with the non-cloneable single-use plan and revalidates it at the socket-use boundary. `connect_at(current_time)` is the explicit deterministic path and rejects both expiry and an authorization-time regression using the existing destination error taxonomy. The compatibility `connect()` path does not freeze the old authorization timestamp: it anchors a process-local monotonic `Instant` at plan construction, adds actual elapsed time to the admitted authorization time, and delegates to `connect_at`, so delayed legacy callers cannot replay stale authority indefinitely. + +The regression suite proves explicit success, deadline expiry, trusted-time regression, unchanged connection-parameter validation, and expiry of the compatibility path with a deliberately short real monotonic interval. Current exact head `ec81031c537f2b662910c1ce78c7ae0e0bfc9c1e` passes CI run `31418337788`. This remains active-PR evidence and does not add DNS lookup, a wall-clock authority, proxy/PAC, or a resolver service. + +## Deterministic authority contract + +The active stack proves one continuous destination-to-socket authority chain with all of the following properties: + +1. approval time is explicit and supplied from one trusted monotonic clock domain; +2. validity is non-zero and capped by the active implementation's repository-owned `MAX_RESOLUTION_VALIDITY` safety budget (30 seconds on PR #47 exact head), with shorter caller-selected intervals permitted; +3. the usable interval is half-open: `approved_at <= now < valid_until`; +4. use before approval, use at/after expiry, arithmetic overflow, unapproved addresses, and set expansion fail closed with typed errors; +5. the ordinary first-party socket planner no longer publicly accepts an untimed `ResolutionSnapshot` as sufficient authority on PR #50 exact head; +6. a single-use plan rechecks the retained freshness authority immediately before socket I/O on PR #54 rather than assuming plan-time admission remains fresh; +7. the compatibility socket path derives a new use time from monotonic elapsed duration and therefore cannot preserve stale plan-time authority indefinitely; +8. credential-free planning evidence records approval, expiry, and authorization times without introducing credentials, resolver internals, or protected values; +9. non-expanding revalidation may renew the bounded interval only while rerunning existing destination-policy validation against the newly supplied answer; and +10. the primitive and planning/use boundaries perform no DNS lookup, wall-clock read, ambient proxy selection, TLS policy mutation, HTTP, browser control, persistence, secret, or model call. + +## Architecture and ADR assessment + +The primitive and its first-party planning/socket consumers tighten the already Accepted destination/rebinding authority governed by ADR 0004. They do not introduce a new component, persistence owner, wire protocol, browser adapter, or trust domain. Therefore a new ADR, deployment component, or physical ERD object would be false precision at this stage. + +The durable network-authority sequence is now `resolver answer -> destination/origin validation -> fresh resolution approval -> trusted monotonic plan authorization -> socket-use freshness recheck -> exact socket candidate -> observed TCP peer -> TLS/HTTP authority`. That is a sequence refinement within the existing network-authority component graph, not a new topology. A new or superseding ADR becomes appropriate only if later integration changes ownership—for example, durable cross-process freshness state, a separate resolver service, a different trusted-clock owner, or a new externally versioned protocol. + +## Evidence progression + +| Evidence state | Allowed maturity claim | +|---|---| +| Test-only primitive/consumer head with unresolved production API | intentional RED contract only; not implementation evidence | +| Active PR #47 production primitive + unchanged exact-head CI/security/100% coverage | `IMPLEMENTED_ON_ACTIVE_PR` for the primitive; overall protected-main path remains `PARTIAL` | +| Active PR #50 adds a freshness wrapper while an ordinary untimed planner remains public | implementation progress only; bypass still makes the consumer incomplete | +| Active PR #50 hides the untimed planner and exact compile evidence finds stale first-party consumers | valid structural remedy with migration still incomplete | +| Active PR #50 exact head `f8b43bc...` migrates first-party consumers and passes exact CI/coverage | `IMPLEMENTED_ON_ACTIVE_PR` for planning; delayed socket-use freshness still requires #54 | +| Active PR #54 exact head `ec81031c...` rechecks freshness immediately before socket I/O and passes exact CI/coverage | `IMPLEMENTED_ON_ACTIVE_PR` for socket-use freshness; dependency-gated and non-shipped | +| PR #47 + #50 + #54 exact heads are individually gate-clean but none are on protected main | active-PR evidence only; no shipped claim | +| Protected-main primitive/planner, but delayed socket use can outlive freshness | `PARTIAL` | +| Protected-main direct socket path requires exact fresh authority and rechecks it at use, with tests proving pre-approval/expiry/rebinding/delay behavior | `IMPLEMENTED_ON_PROTECTED_MAIN` for the bounded resolution-to-socket interval | +| Browser/network adapter proves the same clock and authority chain under real navigation | additional integration/release evidence; not implied by lower-layer primitives | + +## Required follow-through + +- keep PR #47 as active/non-shipped evidence until repository governance integrates it; +- keep PR #50 Draft and dependency-gated while #47 remains active; do not transfer its green evidence to protected main; +- keep PR #54 Draft and dependency-gated while #50 remains active; do not transfer its green evidence to #50 or protected main; +- preserve the structural invariant that ordinary first-party direct planning cannot import an untimed `ConnectionPlan`; +- preserve the socket-use invariant that a delayed call cannot reuse plan-time freshness without a new trusted monotonic use-time check; +- keep PRD/TRD/traceability from calling the DNS-rebinding/TOCTOU interval closed while any prerequisite remains active; +- reconcile the existing network-authority UML with the stable durable freshness sequence without encoding temporary branch-only identifiers as timeless architecture; +- retain the existing conceptual ERD unless a real persistence owner is introduced; and +- after all three layers integrate, rerun protected-main operational/release acceptance before promoting capability maturity. diff --git a/docs/traceability/tls-revocation-freshness-authority.md b/docs/traceability/tls-revocation-freshness-authority.md new file mode 100644 index 0000000..a5bfb98 --- /dev/null +++ b/docs/traceability/tls-revocation-freshness-authority.md @@ -0,0 +1,53 @@ +# TLS Revocation-Material Freshness Authority Trace + +- **Documentation status:** Active-PR traceability +- **Protected-main capability status:** **PARTIAL** +- **Active implementation lane:** PR #48, `feat/tls-revocation-freshness-main` +- **Governing existing boundary:** protected-main TLS service-identity authority, ADR 0006, ADR 0008, and the revocation-distribution/freshness roadmap gap +- **Buyer-visible gap:** prevent stale independently verified revocation material from being treated as current authority while preserving the fact that OriginWeave does not yet make an unrevoked-certificate claim + +## Truth boundary + +Protected `main` authenticates the requested HTTPS service over the already verified TCP stream, but its TLS evidence records revocation as `NotConfigured`. It does not fetch, parse, validate, cache, or enforce OCSP/CRL material and it does not claim that a certificate is unrevoked. + +PR #48 adds a reusable **freshness primitive** for revocation material only. The primitive can classify independently verified material as usable inside its signed `thisUpdate` to `nextUpdate` interval. That active-PR implementation is not protected-main truth, and passing the freshness check does not prove signature validity, path validity, responder authority, non-revocation, successful distribution, or complete TLS authentication policy. + +The complete revocation path therefore remains **PARTIAL** until a separately reviewed adapter acquires and cryptographically verifies revocation material, composes freshness into the authentication decision, defines failure/cache/recovery semantics, and proves the resulting behavior on protected main. + +## Required deterministic authority + +The bounded primitive is expected to preserve these properties: + +1. a higher-layer adapter may construct `RevocationMaterialFreshness` only after independent cryptographic verification has supplied both signed `thisUpdate` and `nextUpdate`; because RFC 6960 permits an OCSP `SingleResponse` to omit `nextUpdate`, absence must fail closed in that adapter before construction and must never be converted into an invented timestamp; +2. the active PR #48 primitive deliberately accepts mandatory `u64` `this_update_unix_seconds` and `next_update_unix_seconds`, so a missing `nextUpdate` has no representable successful state in the primitive; any future parser/adapter must expose a typed missing-`nextUpdate` error or a separately reviewed bounded fallback contract before calling freshness approved; +3. the signed interval is non-empty and ordered; +4. the usable interval is half-open: `thisUpdate <= trusted_time < nextUpdate`; +5. trusted time before `thisUpdate` and at/after `nextUpdate` fails closed with typed bounded errors; +6. the primitive performs no OCSP/CRL fetch, DNS, socket connection, TLS handshake mutation, parsing, signature verification, cache operation, browser control, persistence, or model call; and +7. no evidence or documentation converts freshness into an `unrevoked` claim. + +## Architecture and ADR assessment + +The active primitive tightens an existing TLS evidence/policy concern without introducing a new deployed component, persistence owner, wire protocol, network path, or secret boundary. A new ADR is therefore not required merely because the helper type exists. + +A new or superseding ADR becomes appropriate if OriginWeave later chooses a concrete revocation architecture that changes trust ownership—for example, stapled OCSP versus independently fetched OCSP/CRL, cache authority and freshness policy, hard-fail versus explicitly bounded degraded behavior, responder/path validation ownership, or a separate revocation service. + +No new physical ERD object is justified by this active in-memory primitive. UML should change only when the executable TLS/revocation data or control path changes materially. + +## Evidence progression + +| Evidence state | Allowed maturity claim | +|---|---| +| Protected main records `RevocationStatus::NotConfigured` | `PARTIAL`; no revocation enforcement or unrevoked claim | +| Active PR freshness primitive with exact-head tests/coverage | `IMPLEMENTED_ON_ACTIVE_PR` for freshness classification only | +| Protected-main freshness primitive without verified material acquisition/composition | `PARTIAL` | +| Protected-main adapter verifies responder/material authenticity, requires or safely bounds missing `nextUpdate`, enforces freshness, cache/failure policy, and binds the result into TLS authentication | implementation evidence for the chosen bounded revocation policy | +| Protected-main integration/recovery/operational tests prove the complete path | required additional release evidence; not implied by the helper primitive | + +## Required follow-through + +- keep PRD/TRD/TLS evidence from implying revocation enforcement while protected main remains `NotConfigured`; +- define revocation-material acquisition, authenticity, missing-`nextUpdate`, cache, freshness, failure, privacy, and recovery semantics before calling the TLS revocation boundary implemented; +- require exact 100% owned production function/line/region/branch coverage and complete rustdoc on every changed head; +- add or supersede an ADR only when the concrete revocation architecture changes a durable trust or deployment decision; and +- retain the conceptual ERD unless executable persistence ownership actually appears. diff --git a/docs/uml/README.md b/docs/uml/README.md index 1d04ab0..1a985e2 100644 --- a/docs/uml/README.md +++ b/docs/uml/README.md @@ -6,6 +6,10 @@ These diagrams visualize governing boundaries; they do not imply that every planned adapter is already shipped. Labels use `implemented`, `active`, or `planned` where implementation status matters. +## Focused authority views + +- [Manifest V3 extension compatibility and Agent authority](extension-authority.md) + ## 1. Component and bounded-context view ```mermaid @@ -404,4 +408,4 @@ Update this pack when a protected change materially alters: - deployment boundaries; - evidence/provenance relationships. -A feature-specific ADR may include a more detailed sequence diagram, but this pack remains the product-wide view and must not require maintainers to reconstruct the complete system from scattered ADR diagrams. +A feature-specific ADR may include a more detailed sequence diagram, but this pack remains the product-wide view and must not require maintainers to reconstruct the complete system from scattered ADR diagrams. \ No newline at end of file diff --git a/docs/uml/extension-authority.md b/docs/uml/extension-authority.md new file mode 100644 index 0000000..e228e84 --- /dev/null +++ b/docs/uml/extension-authority.md @@ -0,0 +1,105 @@ +# Extension Compatibility and Agent Authority UML + +- **Status:** Protected-main architecture visualization with active compatibility work +- **Scope:** Chromium Manifest V3 compatibility plane versus OriginWeave Agent authority +- **Related:** [`README.md`](README.md), [`../PRD.md`](../PRD.md), [`../TRD.md`](../TRD.md), [`../THREAT_MODEL.md`](../THREAT_MODEL.md), issue #27 + +This diagram makes one security invariant visually explicit: + +> **A Chromium extension permission is not an OriginWeave Agent capability.** + +A compatible extension can use the Chromium APIs granted by its manifest and managed browser policy. It cannot thereby grant itself OriginWeave task authority, widen an Agent Task origin, resolve a protected secret, approve a high-risk action, or turn extension/page content into a trusted instruction. + +## Authority sequence + +```mermaid +sequenceDiagram + autonumber + participant Admin as Human / Enterprise Policy + participant Chrome as Chromium MV3 Runtime + participant Ext as Extension Worker / Content Script + participant Observe as OriginWeave Observation Adapter + participant Grant as OriginWeave Extension Grant Policy + participant Agent as Agent Task / Planner + participant Policy as Deterministic Action Policy + participant Broker as Secret / Sensitive Broker + participant Browser as Trusted Browser Adapter + participant Evidence as Evidence Trail + + Admin->>Chrome: install/enable extension under Chromium policy + Chrome-->>Ext: expose manifest-granted Chrome APIs + Note over Chrome,Ext: Chrome permission is compatibility authority only. + + Ext-->>Observe: extension message / page mutation / tool output + Observe-->>Agent: bounded untrusted observation + provenance + Note over Ext,Agent: Extension content cannot become trusted goal or policy. + + Admin->>Grant: issue explicit OriginWeave extension grant for bounded session/context/capability/origin + Ext->>Grant: request OriginWeave interaction + Grant->>Grant: verify extension identity, managed policy, session/context, capability, origin, expiry + + alt no valid OriginWeave grant + Grant-->>Ext: deny + Grant-->>Evidence: denial without sensitive value + else valid grant + Grant-->>Agent: bounded extension-originated proposal/evidence + Agent->>Policy: propose typed action under existing Agent Task authority + Policy->>Policy: revalidate task, action, risk, origin, approval and current browser authority + alt action requires secret/sensitive value + Policy->>Broker: authorize exact opaque handle use + Broker->>Broker: revalidate tenant/task/field/purpose/destination/expiry + Broker-->>Browser: minimum trusted value delivery + end + Policy-->>Browser: authorized typed action + Browser->>Browser: verify session/context/document epoch immediately before dispatch + Browser-->>Evidence: action result + observed post-condition + end +``` + +## Security state flow + +```mermaid +flowchart TD + manifest[Manifest V3 permissions] --> chromium[Chromium extension authority] + chromium --> extension[Extension runtime] + extension --> untrusted[Untrusted observation / message] + untrusted --> grant{Explicit OriginWeave extension grant?} + grant -- no --> deny[Deny Agent-control request] + grant -- yes --> scoped[Bind extension identity + session + context + origin + capability + expiry] + scoped --> proposal[Typed Agent action proposal] + proposal --> policy{Agent Task policy passes?} + policy -- no --> deny + policy -- yes --> approval{Risk-specific approval required?} + approval -- missing/invalid --> deny + approval -- no or valid --> execute[Trusted browser adapter executes] + execute --> verify{Observed post-condition matches?} + verify -- no --> fail[Fail / quarantine] + verify -- yes --> evidence[Credential-safe evidence] + + extension -. cannot mint .-> scoped + extension -. cannot approve .-> approval + extension -. cannot resolve .-> secret[Protected secret / sensitive value] + secret --> execute +``` + +## Compatibility evidence is separate from authority evidence + +```mermaid +flowchart LR + pinned[Pinned Chromium revision] --> fixture[Controlled MV3 fixture suite] + fixture --> compat[Compatibility evidence] + compat --> matrix[Published supported-capability matrix] + + policycode[OriginWeave extension policy] --> isolation[Agent-authority isolation evidence] + isolation --> release[Release acceptance] + matrix --> release + + compat -. does not prove .-> isolation + isolation -. does not prove .-> compat +``` + +The release claim requires both evidence classes. A passing `downloads`, `bookmarks`, `history`, storage, service-worker, DNR, or content-script compatibility test does not prove extension isolation. Conversely, a correct Rust extension-grant kernel does not prove that a real Chromium extension API works. + +## Maturity discipline + +Protected main already contains extension-to-Agent authority foundations and pinned-Chromium MV3 compatibility evidence for several surfaces. Issue #27 remains open because the complete declared capability matrix, remaining compatibility surfaces, managed/native-messaging boundaries and release integration are not yet complete. This diagram therefore represents a mixture of implemented foundations and accepted/planned product flow; it must not be read as a claim of full Chrome extension compatibility. diff --git a/tests/test_documentation_active_pr_evidence_contract.py b/tests/test_documentation_active_pr_evidence_contract.py new file mode 100644 index 0000000..d2a067e --- /dev/null +++ b/tests/test_documentation_active_pr_evidence_contract.py @@ -0,0 +1,196 @@ +"""Regression contracts for volatile active-PR evidence in canonical documentation.""" + +from pathlib import Path +import unittest + + +ROOT = Path(__file__).resolve().parents[1] +DOCS = ROOT / "docs" +FITNESS = DOCS / "DOCUMENTATION_FITNESS.md" +MATURITY = DOCS / "evidence" / "2026-08-10-active-pr-maturity.md" + + +def active_pr_row(text: str, pr_number: int) -> str: + """Return exactly one maturity row for an active pull request.""" + prefix = f"| #{pr_number} |" + rows = [line for line in text.splitlines() if line.startswith(prefix)] + if len(rows) != 1: + raise AssertionError( + f"expected exactly one active maturity row for PR #{pr_number}, got {len(rows)}" + ) + return rows[0] + + +class ActivePullRequestDocumentationContractTests(unittest.TestCase): + """Keep volatile implementation evidence separate from protected-main truth.""" + + @classmethod + def setUpClass(cls) -> None: + cls.fitness = FITNESS.read_text(encoding="utf-8") + cls.maturity = MATURITY.read_text(encoding="utf-8") + + def test_dependency_stacks_are_explicit_and_non_shipped(self) -> None: + """Current browser, network, sensitive and compatibility stacks stay active-only.""" + for pr_number in (52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66): + with self.subTest(pr_number=pr_number): + row = active_pr_row(self.maturity, pr_number) + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + for stack in ( + "#47 → #50 → #54", + "#45 → #46 → #53 → #55", + "#40→#52→#57→#58", + "#43→#56→#59→#60→#61", + "#51→#66", + ): + with self.subTest(stack=stack): + self.assertIn(stack, self.fitness) + + self.assertIn("#49", self.fitness) + + def test_semantic_relationship_evidence_stays_bounded_and_authority_scoped(self) -> None: + """PR #52 cannot turn relationship metadata into browser or execution authority.""" + row = active_pr_row(self.maturity, 52) + for marker in ("128", "relationship", "session/context/origin/document"): + with self.subTest(marker=marker): + self.assertIn(marker, row) + + for marker in ( + "same browser session, browsing context, canonical origin and document epoch", + "Self-parent/self-child relationships and duplicate child handles fail closed", + "relationship graph remains descriptive evidence", + "not a browser observation adapter", + ): + with self.subTest(marker=marker): + self.assertIn(marker, self.fitness) + + def test_typed_semantic_query_evidence_stays_descriptive_and_bounded(self) -> None: + """PR #57 cannot turn semantic matching into selector or execution authority.""" + row = active_pr_row(self.maturity, 57) + for marker in ( + "SemanticNodeQuery", + "role", + "accessible-name", + "typed-action", + "no CSS/XPath/raw DOM selector language", + "browser I/O or action authority", + ): + with self.subTest(marker=marker): + self.assertIn(marker, row) + + self.assertIn("Draft stacked on exact #52 head", row) + self.assertIn("CI run `31429995885`", row) + self.assertIn("CodeRabbit exact-head status succeed", row) + self.assertIn("remains Draft because #52/#40 are active prerequisites", row) + + def test_sensitive_audience_evidence_does_not_claim_authentication(self) -> None: + """An internal audience field is not authenticated workload/service identity.""" + row = active_pr_row(self.maturity, 55) + self.assertIn("authenticated workload/service identity", row) + self.assertIn( + "audience string accepted by the value/policy primitive is **not authentication**", + self.fitness, + ) + self.assertIn("new deployment topology or physical ERD entity", self.fitness) + + def test_mv3_mutation_and_isolation_are_compatibility_not_agent_authority(self) -> None: + """Real MV3 evidence must remain separate from OriginWeave capability grants.""" + bookmark_row = active_pr_row(self.maturity, 56) + for marker in ("create", "get", "remove", "compatibility evidence only"): + with self.subTest(marker=marker): + self.assertIn(marker, bookmark_row) + + for pr_number in (59, 60, 61): + with self.subTest(pr_number=pr_number): + row = active_pr_row(self.maturity, pr_number) + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + self.assertIn("Manifest V3 compatibility", self.fitness) + self.assertIn( + "Chromium permission or browser compatibility success is not an OriginWeave Agent capability", + self.fitness, + ) + self.assertIn( + "#43/#49/#56/#59/#60/#61 are active compatibility evidence only", + self.fitness, + ) + self.assertIn("Update migration is intentionally distinct from restart persistence", self.fitness) + self.assertIn("isolated-world behavior is intentionally distinct from injection alone", self.fitness) + + def test_extension_proposal_grant_does_not_become_agent_policy_authority(self) -> None: + """PR #62 must remain a policy-isolation regression, not a new action grant.""" + row = active_pr_row(self.maturity, 62) + for marker in ( + "ProposeTypedAction", + "out-of-grant target origin", + "missing core `Navigate` capability", + "untrusted instruction source", + "adds no production API or real Chromium adapter", + "does not convert extension proposal authority into Agent action/origin authority", + ): + with self.subTest(marker=marker): + self.assertIn(marker, row) + self.assertIn("CI run `31436844685`", row) + self.assertIn("Security Scan run `31436844615`", row) + self.assertIn("SAST Semgrep run `31436844646`", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + def test_latest_agent_task_and_secret_composition_evidence_remains_partial(self) -> None: + """Newest active slices must not be promoted into a complete browser or broker runtime.""" + secret_approval = active_pr_row(self.maturity, 63) + for marker in ( + "ProposeTypedAction", + "RequireApproval(RiskClass::R3)", + "no secret broker", + ): + with self.subTest(pr_number=63, marker=marker): + self.assertIn(marker, secret_approval) + + action_outcome = active_pr_row(self.maturity, 64) + for marker in ( + "PostConditionPredatesDispatch", + "monotonic", + "not a browser dispatcher", + ): + with self.subTest(pr_number=64, marker=marker): + self.assertIn(marker, action_outcome) + + controlled_fixture = active_pr_row(self.maturity, 65) + for marker in ( + "controlled", + "prompt-injection", + "not a browser adapter", + ): + with self.subTest(pr_number=65, marker=marker): + self.assertIn(marker, controlled_fixture) + + process_set = active_pr_row(self.maturity, 66) + for marker in ( + "process-set RSS", + "duplicate", + "does not discover Chromium PIDs", + ): + with self.subTest(pr_number=66, marker=marker): + self.assertIn(marker, process_set) + + for marker in ( + "#62/#63", + "#64", + "#65", + "#51→#66", + "real Chromium", + ): + with self.subTest(fitness_marker=marker): + self.assertIn(marker, self.fitness) + + def test_erd_stays_conceptual_without_persistence_owner(self) -> None: + """Active in-memory/value primitives must not manufacture a physical data model.""" + self.assertIn("Conceptual ERD/domain model", self.fitness) + self.assertIn("add no OriginWeave-owned durable store", self.fitness) + self.assertIn("false architecture", self.fitness) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_documentation_discoverability_followup.py b/tests/test_documentation_discoverability_followup.py new file mode 100644 index 0000000..67801c1 --- /dev/null +++ b/tests/test_documentation_discoverability_followup.py @@ -0,0 +1,43 @@ +"""Focused regression contracts for reviewed documentation discoverability gaps.""" + +from __future__ import annotations + +import pathlib +import unittest + +ROOT = pathlib.Path(__file__).resolve().parents[1] + + +class DocumentationDiscoverabilityFollowupTests(unittest.TestCase): + """Keep canonical diagrams and maturity vocabulary machine-discoverable.""" + + def test_extension_authority_view_is_indexed_mermaid(self) -> None: + """The extension authority view must exist, be indexed, and remain diagram-as-code.""" + uml_index = (ROOT / "docs" / "uml" / "README.md").read_text(encoding="utf-8") + authority_view = ROOT / "docs" / "uml" / "extension-authority.md" + + self.assertTrue(authority_view.is_file()) + self.assertIn("](extension-authority.md)", uml_index) + self.assertIn("```mermaid", authority_view.read_text(encoding="utf-8")) + + def test_traceability_keeps_complete_maturity_vocabulary(self) -> None: + """Every canonical capability maturity label must remain explicit.""" + traceability = (ROOT / "docs" / "traceability" / "README.md").read_text( + encoding="utf-8" + ) + for label in ( + "IMPLEMENTED_ON_PROTECTED_MAIN", + "IMPLEMENTED_ON_ACTIVE_PR", + "PARTIAL", + "ACCEPTED_ARCHITECTURE", + "PLANNED", + "RESEARCH_ONLY", + "SUPERSEDED", + "OUT_OF_SCOPE", + ): + with self.subTest(label=label): + self.assertIn(label, traceability) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_documentation_fitness_contract.py b/tests/test_documentation_fitness_contract.py new file mode 100644 index 0000000..33aefed --- /dev/null +++ b/tests/test_documentation_fitness_contract.py @@ -0,0 +1,265 @@ +"""Regression contracts for the authoritative OriginWeave documentation graph.""" + +from pathlib import Path +import re +import unittest + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +DOCS_ROOT = REPOSITORY_ROOT / "docs" +ADR_ROOT = DOCS_ROOT / "adr" +UML_ROOT = DOCS_ROOT / "uml" + +ADR_STATUSES = {"Proposed", "Accepted", "Superseded", "Deprecated", "Rejected"} + + +def _adr_files() -> set[str]: + """Return every numbered ADR Markdown file currently tracked by the repository.""" + return { + path.name + for path in ADR_ROOT.glob("[0-9][0-9][0-9][0-9]-*.md") + if path.is_file() + } + + +def _adr_file_status(path: Path) -> str: + """Read one ADR's explicit lifecycle status from its metadata header.""" + text = path.read_text(encoding="utf-8") + match = re.search( + r"(?im)^-\s+(?:\*\*Status:\*\*|\*\*Status\*\*:|Status:)\s*(\w+)(?:[;\s].*)?$", + text, + ) + if match is None: + raise AssertionError(f"ADR has no parseable status: {path.name}") + status = match.group(1) + if status not in ADR_STATUSES: + raise AssertionError(f"ADR has unsupported status {status!r}: {path.name}") + return status + + +def _insert_unique(mapping: dict[str, str], path: str, status: str, source: str) -> None: + """Insert one index target while rejecting duplicate or conflicting entries.""" + if path in mapping: + raise AssertionError(f"duplicate ADR index target {path!r} in {source}") + mapping[path] = status + + +def _parse_docs_index(text: str) -> dict[str, str]: + """Parse ADR links from the product documentation index by lifecycle section.""" + mapping: dict[str, str] = {} + current_status: str | None = None + for line in text.splitlines(): + if line.startswith("## "): + current_status = next( + (status for status in ADR_STATUSES if line.startswith(f"## {status}")), + None, + ) + continue + target = re.search(r"\(adr/(\d{4}[-\w]*\.md)\)", line) + if target is not None: + if current_status is None: + raise AssertionError( + f"ADR link {target.group(1)!r} is outside a lifecycle-status section" + ) + _insert_unique(mapping, target.group(1), current_status, "docs/README.md") + return mapping + + +def _parse_adr_index(text: str) -> dict[str, str]: + """Parse the dedicated ADR table into an exact target-to-status mapping.""" + mapping: dict[str, str] = {} + pattern = re.compile( + r"^\|\s*\[\d{4}\]\((\d{4}[-\w]*\.md)\)\s*\|[^|]*\|\s*" + r"(Proposed|Accepted|Superseded|Deprecated|Rejected)(?:[;\s][^|\r\n]*)?\s*\|", + re.MULTILINE, + ) + for path, status in pattern.findall(text): + _insert_unique(mapping, path, status, "docs/adr/README.md") + return mapping + + +def _active_pr_row(text: str, pr_number: int) -> str: + """Return one exact active-PR evidence row from the dated maturity appendix.""" + prefix = f"| #{pr_number} |" + rows = [line for line in text.splitlines() if line.startswith(prefix)] + if len(rows) != 1: + raise AssertionError(f"expected exactly one maturity row for PR #{pr_number}, got {len(rows)}") + return rows[0] + + +class DocumentationFitnessContractTests(unittest.TestCase): + """Keep architecture discovery and implementation-maturity metadata coherent.""" + + def test_documentation_index_links_fitness_assessment(self) -> None: + """The semantic fitness audit must remain discoverable from the docs index.""" + index = (DOCS_ROOT / "README.md").read_text(encoding="utf-8") + self.assertIn("[Documentation fitness assessment](DOCUMENTATION_FITNESS.md)", index) + self.assertTrue((DOCS_ROOT / "DOCUMENTATION_FITNESS.md").is_file()) + + def test_documentation_fitness_distinguishes_design_from_protected_main(self) -> None: + """A broad design pack must not be mislabeled as protected-main closure.""" + assessment = (DOCS_ROOT / "DOCUMENTATION_FITNESS.md").read_text(encoding="utf-8") + self.assertIn("DESIGN-SUFFICIENT", assessment) + self.assertIn("PROTECTED-MAIN-PARTIAL", assessment) + self.assertIn("File existence alone is never sufficient", assessment) + self.assertIn("HTTP lineage", assessment) + self.assertIn("Manifest V3 compatibility", assessment) + self.assertIn("Browser identifier authority", assessment) + self.assertIn("Semantic observation authority", assessment) + self.assertIn("integration before any of these branch repairs become protected-main truth", assessment) + + def test_every_adr_is_indexed_once_with_its_file_status(self) -> None: + """Both canonical indexes must exactly cover ADR files and their lifecycle status.""" + actual_files = _adr_files() + file_status = { + path: _adr_file_status(ADR_ROOT / path) + for path in sorted(actual_files) + } + docs_index = _parse_docs_index((DOCS_ROOT / "README.md").read_text(encoding="utf-8")) + adr_index = _parse_adr_index((ADR_ROOT / "README.md").read_text(encoding="utf-8")) + + self.assertEqual(set(docs_index), actual_files) + self.assertEqual(set(adr_index), actual_files) + self.assertEqual(docs_index, file_status) + self.assertEqual(adr_index, file_status) + + def test_adr_index_does_not_use_change_local_language_as_timeless_authority(self) -> None: + """The protected-main ADR index must not describe its ADRs as only `this change`.""" + adr_index = (ADR_ROOT / "README.md").read_text(encoding="utf-8") + self.assertNotIn("Proposed target-architecture decisions in this change", adr_index) + self.assertIn("Index completeness rule", adr_index) + + def test_proposed_adr_provenance_does_not_promote_branch_to_protected_main(self) -> None: + """Branch-only ADR presence must remain distinct from lifecycle and protected-main truth.""" + docs_index = (DOCS_ROOT / "README.md").read_text(encoding="utf-8") + adr_index = (ADR_ROOT / "README.md").read_text(encoding="utf-8") + + for text in (docs_index, adr_index): + with self.subTest(index="docs" if text is docs_index else "adr"): + self.assertIn("## Proposed architecture decisions", text) + self.assertIn("Protected-main baseline proposed decisions", text) + self.assertNotIn("## Proposed decisions retained on protected main", text) + + docs_branch = docs_index.split( + "### Proposed decisions introduced by this documentation reconciliation", 1 + )[1].split("\n## ", 1)[0] + adr_branch = adr_index.split( + "### Proposed decisions introduced by documentation reconciliation", 1 + )[1].split("\n## ", 1)[0] + for adr_path in ( + "0013-manifest-v3-extension-authority.md", + "0014-architecture-decision-governance.md", + ): + with self.subTest(adr=adr_path): + self.assertIn(adr_path, docs_branch) + self.assertIn(adr_path, adr_branch) + self.assertIn("exist only on this documentation branch until it integrates", adr_index) + + def test_current_replacement_lanes_are_not_promoted_to_protected_main(self) -> None: + """Each active implementation lane must carry its own exact non-shipped maturity mapping.""" + assessment = (DOCS_ROOT / "DOCUMENTATION_FITNESS.md").read_text(encoding="utf-8") + traceability = (DOCS_ROOT / "traceability" / "README.md").read_text(encoding="utf-8") + appendix = (DOCS_ROOT / "evidence" / "2026-08-10-active-pr-maturity.md").read_text( + encoding="utf-8" + ) + + for pr_number in (37, 40, 43, 52, 58, 59): + row = _active_pr_row(appendix, pr_number) + with self.subTest(pr_number=pr_number): + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + for marker in ("issue #10", "issue #27", "issue #28"): + with self.subTest(marker=marker): + self.assertTrue(marker in assessment or marker in traceability) + + self.assertIn("IMPLEMENTED_ON_ACTIVE_PR", traceability) + self.assertIn("IMPLEMENTED_ON_PROTECTED_MAIN", traceability) + self.assertIn("Active-PR behavior is never protected-main truth", traceability) + + def test_semantic_observation_lane_stays_non_shipped_and_provenance_bound(self) -> None: + """The semantic observation value object must stay active-only and distinct from browser I/O.""" + appendix = (DOCS_ROOT / "evidence" / "2026-08-10-active-pr-maturity.md").read_text( + encoding="utf-8" + ) + prd = (DOCS_ROOT / "PRD.md").read_text(encoding="utf-8") + row = _active_pr_row(appendix, 52) + + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertIn("semantic-node observation", row) + self.assertIn("no browser I/O or action dispatch", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + self.assertIn("active PR #52", prd) + self.assertIn("not a browser observation adapter", prd) + + def test_action_target_and_history_lanes_preserve_authority_boundaries(self) -> None: + """New active lanes must not turn descriptive or compatibility evidence into authority.""" + assessment = (DOCS_ROOT / "DOCUMENTATION_FITNESS.md").read_text(encoding="utf-8") + appendix = (DOCS_ROOT / "evidence" / "2026-08-10-active-pr-maturity.md").read_text( + encoding="utf-8" + ) + action_row = _active_pr_row(appendix, 58) + history_row = _active_pr_row(appendix, 59) + + self.assertIn("descriptive execution input, not policy authorization", action_row) + self.assertIn("no Agent history capability", history_row) + self.assertIn("business-risk classification", assessment) + self.assertIn("OriginWeave Agent history grant", assessment) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", action_row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", history_row) + + def test_active_pr_maturity_appendix_tracks_current_dependency_stacks(self) -> None: + """Volatile evidence must retain the current browser/network/sensitive stacks explicitly.""" + appendix = (DOCS_ROOT / "evidence" / "2026-08-10-active-pr-maturity.md").read_text( + encoding="utf-8" + ) + for marker in ("| #52 |", "| #53 |", "| #54 |", "| #55 |", "| #58 |", "| #59 |"): + with self.subTest(marker=marker): + self.assertIn(marker, appendix) + self.assertIn("authenticated workload/service identity", appendix) + self.assertIn( + "formatting-only or metadata-only correction invalidates predecessor-head exactness", + appendix, + ) + + def test_prd_does_not_restore_superseded_active_pr_claims(self) -> None: + """Historical feature branches must not reappear as the current implementation lane.""" + prd = (DOCS_ROOT / "PRD.md").read_text(encoding="utf-8") + self.assertNotIn("Active PR #11", prd) + self.assertNotIn("Active replacement PR #33", prd) + self.assertIn("active replacement PR #37", prd) + self.assertIn("Protected-main purpose-bound sensitive-data policy kernel", prd) + self.assertIn("active PR #43 adds", prd) + + def test_trd_uses_single_status_with_separate_active_pr_evidence(self) -> None: + """Implementation status must not be collapsed with active-development annotations.""" + trd = (DOCS_ROOT / "TRD.md").read_text(encoding="utf-8") + self.assertNotIn("**Planned / active development**", trd) + self.assertNotIn("**Accepted architecture; active development.**", trd) + self.assertIn("Protected-main status", trd) + self.assertIn("Active/non-shipped evidence", trd) + self.assertIn("Active replacement PR #37", trd) + self.assertIn("purpose-bound sensitive-data authority", trd) + + def test_extension_authority_uml_separates_compatibility_from_agent_authority(self) -> None: + """A Chrome permission must never be documented as an Agent capability.""" + diagram = (UML_ROOT / "extension-authority.md").read_text(encoding="utf-8") + self.assertIn("A Chromium extension permission is not an OriginWeave Agent capability", diagram) + self.assertIn("Compatibility evidence is separate from authority evidence", diagram) + self.assertIn("sequenceDiagram", diagram) + self.assertIn("OriginWeave Extension Grant Policy", diagram) + self.assertIn("cannot approve", diagram) + self.assertIn("cannot resolve", diagram) + + def test_fitness_audit_does_not_duplicate_existing_resource_or_hourly_uml(self) -> None: + """The audit must recognize existing product-wide resource and automation diagrams.""" + assessment = (DOCS_ROOT / "DOCUMENTATION_FITNESS.md").read_text(encoding="utf-8") + uml_index = (UML_ROOT / "README.md").read_text(encoding="utf-8") + self.assertIn("resource-pressure/GPU fallback", assessment) + self.assertIn("hourly automation flows", assessment) + self.assertIn("## 9. Resource-pressure and fallback flow", uml_index) + self.assertIn("## 10. Hourly product-development gate-to-model flow", uml_index) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_extension_authority_traceability_contract.py b/tests/test_extension_authority_traceability_contract.py new file mode 100644 index 0000000..3ca5c5c --- /dev/null +++ b/tests/test_extension_authority_traceability_contract.py @@ -0,0 +1,49 @@ +"""Regression contract for extension-to-Agent security traceability.""" + +from pathlib import Path +import unittest + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +TRACEABILITY = ( + REPOSITORY_ROOT / "docs" / "traceability" / "extension-authority-security.md" +) + + +class ExtensionAuthorityTraceabilityContractTests(unittest.TestCase): + """Keep compatibility, Agent authority, and secret authority as separate claims.""" + + def test_extension_security_dossier_preserves_maturity_boundaries(self) -> None: + """Active security proofs must never be promoted to protected-main shipped truth.""" + text = TRACEABILITY.read_text(encoding="utf-8") + semantic_text = text.replace("**", "") + + self.assertIn("DESIGN-SUFFICIENT / PROTECTED-MAIN-PARTIAL", semantic_text) + self.assertIn("IMPLEMENTED_ON_PROTECTED_MAIN", text) + self.assertIn("IMPLEMENTED_ON_ACTIVE_PR", text) + self.assertIn("PR #62", text) + self.assertIn("PR #63", text) + self.assertIn("Proposed ADR 0013", text) + self.assertIn("SecretBrokerRequired", text) + self.assertIn("UnexpectedSecretMaterial", text) + self.assertIn("R3 approval", text) + self.assertIn("does not close issue #27 or issue #10", semantic_text) + + def test_extension_proposal_authority_is_explicitly_non_transitive(self) -> None: + """The dossier must forbid proposal permission from becoming broader Agent authority.""" + text = TRACEABILITY.read_text(encoding="utf-8") + + for boundary in ( + "-/> Agent capability", + "-/> Agent readable/writable origin", + "-/> trusted instruction source", + "-/> secret-delivery authority", + "-/> approval", + "-/> protected-value resolution", + ): + with self.subTest(boundary=boundary): + self.assertIn(boundary, text) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_freshness_traceability_contract.py b/tests/test_freshness_traceability_contract.py new file mode 100644 index 0000000..a9e0e4f --- /dev/null +++ b/tests/test_freshness_traceability_contract.py @@ -0,0 +1,50 @@ +"""Regression contracts for bounded freshness-authority documentation.""" + +from __future__ import annotations + +import pathlib +import unittest + +ROOT = pathlib.Path(__file__).resolve().parents[1] +TRACEABILITY = ROOT / "docs" / "traceability" + + +class FreshnessTraceabilityContractTests(unittest.TestCase): + """Keep active freshness primitives discoverable without promoting them to shipped truth.""" + + def test_traceability_index_discovers_each_active_freshness_authority(self) -> None: + """Resolution and TLS freshness traces must be linked from the canonical index.""" + index = (TRACEABILITY / "README.md").read_text(encoding="utf-8") + for filename in ( + "resolution-freshness-authority.md", + "tls-revocation-freshness-authority.md", + ): + with self.subTest(filename=filename): + self.assertTrue((TRACEABILITY / filename).is_file()) + self.assertIn(f"]({filename})", index) + + def test_active_freshness_traces_preserve_protected_main_maturity(self) -> None: + """Active implementation evidence must remain explicitly non-shipped and partial overall.""" + for filename in ( + "resolution-freshness-authority.md", + "tls-revocation-freshness-authority.md", + ): + text = (TRACEABILITY / filename).read_text(encoding="utf-8") + with self.subTest(filename=filename): + self.assertIn("Active-PR traceability", text) + self.assertIn("Protected-main capability status:** **PARTIAL", text) + self.assertIn("IMPLEMENTED_ON_ACTIVE_PR", text) + self.assertIn("not protected-main truth", text) + + def test_resolution_trace_requires_socket_use_freshness_not_only_plan_time(self) -> None: + """The DNS freshness trace must retain the delayed-use boundary added by PR #54.""" + text = (TRACEABILITY / "resolution-freshness-authority.md").read_text(encoding="utf-8") + self.assertIn("Socket-use freshness lane:** PR #54", text) + self.assertIn("connect_at(current_time)", text) + self.assertIn("rechecks the retained freshness authority immediately before socket I/O", text) + self.assertIn("delayed call cannot reuse plan-time freshness", text) + self.assertIn("#47 + #50 + #54", text) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_mv3_supported_capability_matrix_contract.py b/tests/test_mv3_supported_capability_matrix_contract.py new file mode 100644 index 0000000..fcc24db --- /dev/null +++ b/tests/test_mv3_supported_capability_matrix_contract.py @@ -0,0 +1,97 @@ +"""Regression contract for the canonical MV3 supported-capability evidence matrix.""" + +from __future__ import annotations + +import pathlib +import unittest + +ROOT = pathlib.Path(__file__).resolve().parents[1] +DOCTORING = ROOT / "docs" / "doctoring" / "mv3-compatibility.md" +MATURITY = ROOT / "docs" / "evidence" / "2026-08-10-active-pr-maturity.md" + + +class ManifestV3SupportedCapabilityMatrixContractTests(unittest.TestCase): + """Keep compatibility claims executable, maturity-scoped, and authority-safe.""" + + @classmethod + def setUpClass(cls) -> None: + cls.doctoring = DOCTORING.read_text(encoding="utf-8") + cls.maturity = MATURITY.read_text(encoding="utf-8") + + def test_matrix_separates_protected_active_planned_and_out_of_scope(self) -> None: + """The matrix must never collapse active evidence into protected-main support.""" + + for marker in ( + "## Supported-capability evidence matrix", + "**PROTECTED_MAIN**", + "**ACTIVE_PR #43**", + "**ACTIVE_PR #56**", + "**ACTIVE_PR #59**", + "**ACTIVE_PR #60**", + "**ACTIVE_PR #61**", + "**PLANNED**", + "**PLANNED / SECURITY-GATED**", + "**OUT_OF_SCOPE FOR COMPATIBILITY CLAIM**", + ): + with self.subTest(marker=marker): + self.assertIn(marker, self.doctoring) + + def test_update_migration_is_not_documented_as_restart_only(self) -> None: + """Update compatibility requires a version transition plus migrated state.""" + + for marker in ( + "Restart persistence and extension update migration are separate compatibility claims", + "`1.0.0` to `1.0.1`", + "schema marker to migrate from version 1 to version 2", + "checked-in fixture is not rewritten", + ): + with self.subTest(marker=marker): + self.assertIn(marker, self.doctoring) + + row = next( + line for line in self.maturity.splitlines() if line.startswith("| #60 |") + ) + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertIn("e696e19c9eaf3dedb104a5de4bdbd7970abf90d4", row) + self.assertIn("CI run `31433968874`", row) + self.assertIn("Manifest V3 Compatibility run `31433968931`", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + def test_isolated_world_evidence_stays_active_only(self) -> None: + """Content-script isolation proof must not be promoted into protected-main support.""" + + for marker in ( + "Content-script injection | **PROTECTED_MAIN**", + "Content-script isolated-world separation | **ACTIVE_PR #61**", + "Content-script injection and content-script JavaScript isolation are separate compatibility claims", + "page publisher changes to `extension` and real-browser compatibility fails", + ): + with self.subTest(marker=marker): + self.assertIn(marker, self.doctoring) + + row = next( + line for line in self.maturity.splitlines() if line.startswith("| #61 |") + ) + self.assertIn("**IMPLEMENTED_ON_ACTIVE_PR**", row) + self.assertIn("c1705ad9fd2d96e620b89bb6e7ea1235063dcb6a", row) + self.assertIn("CI run `31434670642`", row) + self.assertIn("Manifest V3 Compatibility run `31434670629`", row) + self.assertIn("3/3 repeatability trials", row) + self.assertNotIn("IMPLEMENTED_ON_PROTECTED_MAIN", row) + + def test_compatibility_never_grants_agent_authority(self) -> None: + """Chrome API success must remain separate from OriginWeave Agent grants.""" + + for marker in ( + "Chrome API permission does not become Agent capability", + "no Agent bookmark capability", + "no Agent history capability", + "does not claim Chrome Web Store/enterprise update semantics or Agent authority", + "no arbitrary page-JavaScript bridge or Agent authority", + ): + with self.subTest(marker=marker): + self.assertTrue(marker in self.doctoring or marker in self.maturity) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_product_documentation_contract.py b/tests/test_product_documentation_contract.py index 66a67d5..1313189 100644 --- a/tests/test_product_documentation_contract.py +++ b/tests/test_product_documentation_contract.py @@ -14,9 +14,16 @@ class ProductDocumentationContractTests(unittest.TestCase): def test_authoritative_product_documentation_graph_exists(self) -> None: """Major product decisions must not require reconstructing chat or PR history.""" required_paths = { - "docs/PRD.md", "docs/TRD.md", "docs/adr/README.md", "docs/uml/README.md", - "docs/erd/README.md", "docs/traceability/README.md", "docs/THREAT_MODEL.md", - "docs/TEST_STRATEGY.md", "docs/OPERABILITY.md", "docs/API_CONTRACT.md", + "docs/PRD.md", + "docs/TRD.md", + "docs/adr/README.md", + "docs/uml/README.md", + "docs/erd/README.md", + "docs/traceability/README.md", + "docs/THREAT_MODEL.md", + "docs/TEST_STRATEGY.md", + "docs/OPERABILITY.md", + "docs/API_CONTRACT.md", "docs/RELEASE_AND_ROLLBACK.md", } missing = sorted(path for path in required_paths if not (ROOT / path).is_file()) @@ -25,110 +32,305 @@ def test_authoritative_product_documentation_graph_exists(self) -> None: def test_root_architecture_links_the_authoritative_product_graph(self) -> None: """Architecture readers must be able to reach requirements, decisions, diagrams, and data.""" architecture = (ROOT / "ARCHITECTURE.md").read_text(encoding="utf-8") - for link in ("docs/PRD.md", "docs/TRD.md", "docs/adr/README.md", "docs/uml/README.md", "docs/erd/README.md", "docs/traceability/README.md"): - with self.subTest(link=link): self.assertIn(link, architecture) + for link in ( + "docs/PRD.md", + "docs/TRD.md", + "docs/adr/README.md", + "docs/uml/README.md", + "docs/erd/README.md", + "docs/traceability/README.md", + ): + with self.subTest(link=link): + self.assertIn(link, architecture) def test_security_policy_links_the_product_threat_model(self) -> None: """Vulnerability reporters and operators must be able to find modeled trust boundaries.""" - self.assertIn("docs/THREAT_MODEL.md", (ROOT / "SECURITY.md").read_text(encoding="utf-8")) + self.assertIn( + "docs/THREAT_MODEL.md", + (ROOT / "SECURITY.md").read_text(encoding="utf-8"), + ) def test_agent_contract_is_work_conserving_instead_of_one_action_per_run(self) -> None: """Finishing one bounded slice must return maintenance to the live queue.""" contract = (ROOT / "AGENTS.md").read_text(encoding="utf-8") - for phrase in ("A completed action is an intermediate state", "one write-active slice at a time", "Mandatory exit sweep", "termination is prohibited", "blocks only that item"): - with self.subTest(phrase=phrase): self.assertIn(phrase, contract) + for phrase in ( + "A completed action is an intermediate state", + "one write-active slice at a time", + "Mandatory exit sweep", + "termination is prohibited", + "blocks only that item", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, contract) def test_prd_covers_product_family_modes_and_buyer_acceptance(self) -> None: """The PRD must describe the actual product family rather than one kernel slice.""" prd = (ROOT / "docs/PRD.md").read_text(encoding="utf-8") - for phrase in ("Browse. Act. Prove.", "Human Mode", "Assist Mode", "Agent Task Mode", "Crawler Mode", "OriginWeave Browser", "OriginWeave Runtime", "OriginWeave Observe", "OriginWeave Capture", "OriginWeave Governor", "OriginWeave Policy", "OriginWeave Evidence", "OriginWeave Protocol", "Non-goals", "Buyer-visible acceptance"): - with self.subTest(phrase=phrase): self.assertIn(phrase, prd) + for phrase in ( + "Browse. Act. Prove.", + "Human Mode", + "Assist Mode", + "Agent Task Mode", + "Crawler Mode", + "OriginWeave Browser", + "OriginWeave Runtime", + "OriginWeave Observe", + "OriginWeave Capture", + "OriginWeave Governor", + "OriginWeave Policy", + "OriginWeave Evidence", + "OriginWeave Protocol", + "Non-goals", + "Buyer-visible acceptance", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, prd) def test_trd_distinguishes_shipped_architecture_from_future_work(self) -> None: """Technical documentation must not silently describe planned work as shipped.""" trd = (ROOT / "docs/TRD.md").read_text(encoding="utf-8") - for phrase in ("Implemented", "Accepted architecture", "Planned", "logical origin", "resolved destination", "TCP peer", "TLS service identity", "WebDriver BiDi", "Chrome DevTools Protocol", "WebMCP", "Model Context Protocol", "NVIDIA_NIM_API_KEY", "COPILOT_GITHUB_TOKEN"): - with self.subTest(phrase=phrase): self.assertIn(phrase, trd) + for phrase in ( + "Implemented", + "Accepted architecture", + "Planned", + "logical origin", + "resolved destination", + "TCP peer", + "TLS service identity", + "WebDriver BiDi", + "Chrome DevTools Protocol", + "WebMCP", + "Model Context Protocol", + "NVIDIA_NIM_API_KEY", + "COPILOT_GITHUB_TOKEN", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, trd) def test_target_architecture_adr_set_is_detailed(self) -> None: """Product direction must be reconstructable from durable, reviewable decisions.""" required_adrs = { - "docs/adr/0001-chromium-compatibility-kernel.md": ("Chromium", "browser-engine rewrite"), - "docs/adr/0100-rust-control-plane-boundary.md": ("Rust control plane", "Chromium compatibility kernel"), - "docs/adr/0101-isolated-execution-profile-modes.md": ("Human", "Assist", "Agent Task", "Crawler"), - "docs/adr/0102-typed-actions-and-arbitrary-js.md": ("typed action", "arbitrary JavaScript"), - "docs/adr/0103-semantic-observation-and-stale-node-identity.md": ("WebMCP", "accessibility", "document epoch", "stale"), - "docs/adr/0104-prompt-injection-and-secret-authority.md": ("prompt injection", "opaque", "secret"), - "docs/adr/0105-resource-governor-priority.md": ("resource governor", "GPU", "browser", "model"), - "docs/adr/0106-provenance-evidence-model.md": ("WARC", "PROV", "evidence"), - "docs/adr/0107-browser-protocol-adapter-strategy.md": ("WebDriver BiDi", "Chrome DevTools Protocol", "WebMCP", "Model Context Protocol"), + "docs/adr/0001-chromium-compatibility-kernel.md": ( + "Chromium", + "browser-engine rewrite", + ), + "docs/adr/0100-rust-control-plane-boundary.md": ( + "Rust control plane", + "Chromium compatibility kernel", + ), + "docs/adr/0101-isolated-execution-profile-modes.md": ( + "Human", + "Assist", + "Agent Task", + "Crawler", + ), + "docs/adr/0102-typed-actions-and-arbitrary-js.md": ( + "typed action", + "arbitrary JavaScript", + ), + "docs/adr/0103-semantic-observation-and-stale-node-identity.md": ( + "WebMCP", + "accessibility", + "document epoch", + "stale", + ), + "docs/adr/0104-prompt-injection-and-secret-authority.md": ( + "prompt injection", + "opaque", + "secret", + ), + "docs/adr/0105-resource-governor-priority.md": ( + "resource governor", + "GPU", + "browser", + "model", + ), + "docs/adr/0106-provenance-evidence-model.md": ( + "WARC", + "PROV", + "evidence", + ), + "docs/adr/0107-browser-protocol-adapter-strategy.md": ( + "WebDriver BiDi", + "Chrome DevTools Protocol", + "WebMCP", + "Model Context Protocol", + ), "docs/adr/0108-crawler-policy.md": ("robots", "rate", "CAPTCHA"), - "docs/adr/0109-hourly-automation-operational-closure.md": ("NVIDIA_NIM_API_KEY", "protected-main", "open_pull_request"), + "docs/adr/0109-hourly-automation-operational-closure.md": ( + "NVIDIA_NIM_API_KEY", + "protected-main", + "open_pull_request", + ), } - sections = ("## Context", "## Options considered", "## Decision", "## Consequences", "## Failure and degraded behavior", "## Security / privacy / governance impact", "## Tests and acceptance evidence", "## Migration and rollback", "## Supersession / reversal conditions") + sections = ( + "## Context", + "## Options considered", + "## Decision", + "## Consequences", + "## Failure and degraded behavior", + "## Security / privacy / governance impact", + "## Tests and acceptance evidence", + "## Migration and rollback", + "## Supersession / reversal conditions", + ) fields = ("- Status:", "- Date:", "- Supersedes:", "- Superseded by:") for path, phrases in required_adrs.items(): with self.subTest(path=path): text = (ROOT / path).read_text(encoding="utf-8") - for field in fields: self.assertIn(field, text) - for section in sections: self.assertIn(section, text) - for phrase in phrases: self.assertIn(phrase, text) + for field in fields: + self.assertIn(field, text) + for section in sections: + self.assertIn(section, text) + for phrase in phrases: + self.assertIn(phrase, text) def test_stale_node_adr_defines_action_linearization_race(self) -> None: """A mutation between handle validation and dispatch must never produce a stale side effect.""" - adr = (ROOT / "docs/adr/0103-semantic-observation-and-stale-node-identity.md").read_text(encoding="utf-8") - for phrase in ("action linearization point", "side effect", "competing mutation", "re-observation"): - with self.subTest(phrase=phrase): self.assertIn(phrase, adr) + adr = ( + ROOT / "docs/adr/0103-semantic-observation-and-stale-node-identity.md" + ).read_text(encoding="utf-8") + for phrase in ( + "action linearization point", + "side effect", + "competing mutation", + "re-observation", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, adr) def test_hourly_automation_adr_requires_exit_sweep(self) -> None: """Automation closure must re-sweep all actionable lanes instead of stopping after one result.""" - adr = (ROOT / "docs/adr/0109-hourly-automation-operational-closure.md").read_text(encoding="utf-8") - for phrase in ("mandatory exit sweep", "open OriginWeave PRs and issues", "release state", "documentation", "product gaps", "safe actionable work remains"): - with self.subTest(phrase=phrase): self.assertIn(phrase, adr) + adr = ( + ROOT / "docs/adr/0109-hourly-automation-operational-closure.md" + ).read_text(encoding="utf-8") + for phrase in ( + "mandatory exit sweep", + "open OriginWeave PRs and issues", + "release state", + "documentation", + "product gaps", + "safe actionable work remains", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, adr) def test_uml_and_erd_are_diagram_as_code(self) -> None: """Architecture flows and the conceptual domain model must be reviewable in Git.""" uml = (ROOT / "docs/uml/README.md").read_text(encoding="utf-8") + authority_view = ROOT / "docs/uml/extension-authority.md" + self.assertTrue(authority_view.is_file()) + self.assertIn("](extension-authority.md)", uml) + self.assertIn("```mermaid", authority_view.read_text(encoding="utf-8")) + erd = (ROOT / "docs/erd/README.md").read_text(encoding="utf-8") - self.assertGreaterEqual(uml.count("```mermaid"), 8); self.assertIn("sequenceDiagram", uml); self.assertIn("stateDiagram-v2", uml) - for heading in ("Secret-fill sequence", "Read/write risk approval flow", "Resource-pressure and fallback flow", "Hourly product-development gate-to-model flow"): - with self.subTest(heading=heading): self.assertIn(heading, uml) + self.assertGreaterEqual(uml.count("```mermaid"), 8) + self.assertIn("sequenceDiagram", uml) + self.assertIn("stateDiagram-v2", uml) + for heading in ( + "Secret-fill sequence", + "Read/write risk approval flow", + "Resource-pressure and fallback flow", + "Hourly product-development gate-to-model flow", + ): + with self.subTest(heading=heading): + self.assertIn(heading, uml) self.assertIn("erDiagram", erd) - for entity in ("agent_session", "browser_profile", "page_snapshot", "semantic_node", "action_event", "policy_decision", "provenance_record", "resource_budget"): - with self.subTest(entity=entity): self.assertIn(entity, erd) + for entity in ( + "agent_session", + "browser_profile", + "page_snapshot", + "semantic_node", + "action_event", + "policy_decision", + "provenance_record", + "resource_budget", + ): + with self.subTest(entity=entity): + self.assertIn(entity, erd) def test_hourly_uml_fails_closed_before_secret_or_publication(self) -> None: """Denied credentials and failed validation must terminate before secret use or publication.""" uml = (ROOT / "docs/uml/README.md").read_text(encoding="utf-8") - for phrase in ("credential denied or broker unavailable", "stop without secret materialization", "validation failed", "fail closed without publication", "validation passed"): - with self.subTest(phrase=phrase): self.assertIn(phrase, uml) + for phrase in ( + "credential denied or broker unavailable", + "stop without secret materialization", + "validation failed", + "fail closed without publication", + "validation passed", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, uml) def test_operational_documents_preserve_fail_closed_product_boundaries(self) -> None: """Security, operations, APIs, tests, and rollback must agree on core authority boundaries.""" documents = { - "docs/THREAT_MODEL.md": ("renderer compromise", "prompt injection", "confused deputy", "cross-tenant"), - "docs/TEST_STRATEGY.md": ("true production boundary", "100%", "hostile", "protected-main"), + "docs/THREAT_MODEL.md": ( + "renderer compromise", + "prompt injection", + "confused deputy", + "cross-tenant", + ), + "docs/TEST_STRATEGY.md": ( + "true production boundary", + "100%", + "hostile", + "protected-main", + ), "docs/OPERABILITY.md": ("SLI", "SLO", "quarantine", "break-glass"), - "docs/API_CONTRACT.md": ("OriginWeave Protocol", "idempotency", "post-condition", "opaque"), - "docs/RELEASE_AND_ROLLBACK.md": ("SBOM", "provenance", "rollback", "protected main"), + "docs/API_CONTRACT.md": ( + "OriginWeave Protocol", + "idempotency", + "post-condition", + "opaque", + ), + "docs/RELEASE_AND_ROLLBACK.md": ( + "SBOM", + "provenance", + "rollback", + "protected main", + ), } for path, phrases in documents.items(): text = (ROOT / path).read_text(encoding="utf-8") for phrase in phrases: - with self.subTest(path=path, phrase=phrase): self.assertIn(phrase, text) + with self.subTest(path=path, phrase=phrase): + self.assertIn(phrase, text) def test_release_contract_never_bypasses_evidence_or_reproducibility(self) -> None: """Emergency release handling must preserve exact-head gates and reproducible artifacts.""" release = (ROOT / "docs/RELEASE_AND_ROLLBACK.md").read_text(encoding="utf-8") - for phrase in ("Emergency releases do not bypass required gates", "current-head checks", "complete coverage", "branch protection", "reproducible artifact", "nondeterministic signing"): - with self.subTest(phrase=phrase): self.assertIn(phrase, release) + for phrase in ( + "Emergency releases do not bypass required gates", + "current-head checks", + "complete coverage", + "branch protection", + "reproducible artifact", + "nondeterministic signing", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, release) self.assertNotIn("residual unrun evidence", release) def test_traceability_labels_conversation_derived_future_work(self) -> None: - """Conversation decisions must preserve implementation status instead of becoming claims.""" + """Conversation decisions must preserve canonical maturity instead of becoming shipped claims.""" traceability = (ROOT / "docs/traceability/README.md").read_text(encoding="utf-8") - for phrase in ("Implemented", "Accepted architecture", "Proposed", "Open", "conversation-derived", "docs/doctoring.md"): - with self.subTest(phrase=phrase): self.assertIn(phrase, traceability) + for phrase in ( + "IMPLEMENTED_ON_PROTECTED_MAIN", + "IMPLEMENTED_ON_ACTIVE_PR", + "PARTIAL", + "ACCEPTED_ARCHITECTURE", + "PLANNED", + "RESEARCH_ONLY", + "SUPERSEDED", + "OUT_OF_SCOPE", + "conversation-derived", + "docs/doctoring.md", + "Active-PR behavior is never protected-main truth", + ): + with self.subTest(phrase=phrase): + self.assertIn(phrase, traceability) -if __name__ == "__main__": unittest.main() +if __name__ == "__main__": + unittest.main()