Repository navigation
Browser capability audit #3
Description
Activity
- addedwayfinder:researchEvidence gathering that unblocks a design decisionEvidence gathering that unblocks a design decision
on Sep 22, 2026 - added a parent issue
on Sep 22, 2026 Research checkpoint — this audit remains open.
An isolated Chrome for Testing 151.0.7922.34 run passed 15 assertions covering packaged MAIN-world injection before the parser, world isolation, DNR header changes, restricted debugger domains, response-stage text/HTML rewriting, explicit interception cleanup, and restricted-page rejection. The companion toolchain audit also observed a basic content-to-background round trip in Firefox 156.0.
These observations establish narrow platform behavior, not SDK conformance. Chrome debugger and Firefox response filtering require different implementations. Native DevTools coexistence still needs both attachment orders tested against the reference and official sample.
Remaining gates: browser support floors and failure semantics; Firefox filtering and MAIN-world timing; DevTools coexistence; permission and lifecycle transitions; broader interception failure cases. The report records concrete experiment protocols and their owner. Every supported SDK API/host/mode cell still needs a working example and executed behavior assertions.
Retained research context: local, unpushed branch
dvcol/research/browser-capabilities, commitd5c2799, reportdocs/research/browser-capabilities.md. The full research artifact remains local; no public artifact URL is claimed. This checkpoint is not a resolution or an implementation-complete claim.Resolution
The Browser capability audit establishes bounded native feasibility and a source-linked capability matrix. Remaining integration and lifecycle guarantees have named acceptance gates. The SDK and its conformance suite remain subsequent work.
The user-approved initial baseline is current stable Chromium and Firefox, advancing with stable releases. Official metadata retrieved on 2026-09-22 selected Chrome for Testing
153.0.8010.52and Firefox156.0.1. Both actual binaries reported those versions and ran in isolated macOS profiles. Cached Chrome 151 results remain historical. This audit adds no ESR, old-version, derivative-browser, mobile, Safari or untested operating-system guarantee. Record exact versions and rerun affected checks before advancing each release's support record. Google metadata, Mozilla metadata.Dated capability matrix
Capability and execution context Chromium evidence and constraints Firefox evidence and constraints SDK status and required follow-up Static content script in an isolated world Observed on 153.0.8010.52. Packaged script ran with messaging access and separate globals. Chrome lists only a subset of extension APIs in content scripts. Observed on 156.0.1: isolated globals separated from MAIN, runtime messaging completed with the event background. Supported native in both bounded fixtures; contribution lifecycle unresolved. Chrome content scripts, Mozilla execution worlds. document_startMAIN-world scriptObserved before the fixture's first parser script. Manifest worlddates to Chrome 111; programmatic MAIN dates to Chrome 95.Observed before the first parser script on 156.0.1, with runtime messaging absent in MAIN. Manifest worldis documented from Firefox 128.Supported native for pre-registered top-level scripts. Keep execution-world and timing capabilities separate. No result yet for strict CSP, frame variants or scripts registered after navigation. Manifest compatibility, Scripting compatibility. Dynamic registration and one-shot injection scriptingplus granted host access oractiveTab; dynamic registration from Chrome 96. Restrictedchrome://injection was rejected in the experiment.Scripting registration from Firefox 102. Host grants can change during use. Registration is not retroactive parser-time execution. Permission denial, revocation and navigation races unresolved. Chrome scripting, Mozilla host permissions. Same-origin, cross-origin and related frames Target selection can use frame/document identity. Each matching frame needs the relevant access. Compatibility data records an empty-iframe exception to document_start, includingmatch_about_blank; origin-fallback support starts at 128.Unresolved. Test blank, blob, sandboxed, same-process and out-of-process frames separately. Content-script compatibility, Chrome scripting. MV3 background execution Documented service worker. Global variables do not survive shutdown. An active debugger session keeps it alive from Chrome 118. Documented nonpersistent background scripts/event page; background.service_workeris unsupported.Browser-specific host entry points required. Recovery and state retention untested. Chrome lifecycle, Mozilla background manifest. Popup Documented packaged action popup. Closing it ends its document lifetime. Documented MV3 action.default_popup.Actual open/close, action routing and listener cleanup unresolved on both. Chrome popup, Mozilla action. Options document Documented options_pageoroptions_ui, with tab or embedded behavior.Documented options_uiwith browser-specific presentation.Rendering and persisted options round trip unresolved. Chrome options, Mozilla options. DevTools page, panel and DevTools sidebar Documented packaged devtools_page, which lives with the DevTools window and can create panels.Documented DevTools page, panels and inspected-window integration. Both hosts need real panel mounting and teardown tests. An extension DevTools panel is distinct from the Vite DevTools host. Chrome DevTools extensions, Mozilla DevTools extensions. Browser side panel/sidebar sidePanelfrom Chrome 114 MV3;open()from 116 requires user interaction and thesidePanelpermission.sidebarActionwithsidebar_actionmanifest entry; incompatible with Chrome's API.Separate adapters. Opening, tab switching and disposal unresolved. Chrome sidePanel, Mozilla sidebarAction. Messaging and ports Documented JSON serialization. A content script cannot directly access the privileged debugger namespace; observed here. Runtime message round trip observed on 156.0.1; structured-clone semantics documented. Supported native for basic messaging; ports/reconnection unresolved. Use an explicit portable wire codec. Raw browser objects and callbacks stay local. Disconnect/reconnect behavior unresolved. Chrome messaging, Mozilla sendMessage. Storage and change notifications Documented storagepermission; local/session/sync areas have different retention.storage.sessionclears on extension reload/update and browser restart.Documented asynchronous extension storage and change notifications. Storage APIs exist; shared-state consistency, revisions and restoration are separate SDK contracts. Chrome storage, Mozilla storage. Request observation webRequestplus host access. For subresources, access to request and initiator matters.Observed onBeforeRequestfor document and fetch traffic on 156.0.1; FirefoxactiveTabdoes not grant network interception.Firefox observation supported native in the fixture; Chromium observation unresolved. Observation and modification require distinct capabilities. Chrome webRequest, Mozilla incompatibilities. Request/response header modification DNR request and response header rules observed. Rule type and host grants determine authority. Normal MV3 extensions cannot use blocking webRequest; policy-installed extensions are an exception.Blocking webRequestis documented, including response filtering. Its permissions differ from Chromium.Chromium bounded success. Firefox semantics, conflicting rules and permission removal unresolved. Chrome DNR, Chrome webRequest, Mozilla response filtering. HTTP response body or HTML-byte transform DNR body transform unsupported. Debugger Fetchresponse-stage transformation observed for ASCII text and HTML on 153.0.8010.52.Observed text, HTML and three-chunk UTF-8 filtering on 156.0.1. MV3 needs webRequestFilterResponse,webRequest,webRequestBlockingand host access; missing filter permission rejected all three calls.Supported native for measured buffered transforms. Incremental output, compression, redirects, cancellation, cache and CSP outcomes unresolved. Debugger/Firefox implementations remain separate. DNR actions, Fetch schema, Mozilla filtering. Debugger commands and events Requires manifest debugger, which cannot be optional; transport exposes a restricted CDP domain set.Runtime.evaluatepassed;Browser.getVersionwas rejected. Flat child sessions date to Chrome 125.Chrome's debugger API is documented as unimplemented. Firefox native-CDP capability unsupported. Chromium command coverage, child sessions and CDB integration unresolved beyond the bounded native test. Chrome debugger, Mozilla incompatibilities. Debugger plus native DevTools Both orders passed on 153.0.8010.52 with a ready native Network frontend, extension evaluation 42, frontend evaluation 54, zero observed detach events, and response fulfillment in both active-Fetch cases. No equivalent extension debugger API. Supported native for these four measured cases. Breakpoints, cancellation, navigation, competing owners and other versions remain unresolved. Do not generalize from the bounded observation. Debugger detach reference, Google sample. Executable updates and HMR Packaged extension updates, unpacked development reloads and server UI HMR are different mechanisms. Companion audit records extension-page HMR on the current stable builds; its exact reload limits belong in the toolchain audit. Store policy requires self-contained code and rejects remote code execution as a generic update mechanism. Generic production replacement of privileged extension modules through a remote HMR server is unsupported as the default delivery contract. Other development contexts and watched-production-preview behavior remain unresolved. Chrome MV3 policy, Mozilla add-on policy. What was observed
On stable Chromium, the original native capability fixture passed fifteen assertions across eight groups: static MAIN before the first parser script, isolated globals and messaging access, DNR request/response headers, debugger evaluation, rejection of browser-level CDP through the extension transport, buffered text and HTML-byte transformation, explicit Fetch-disable/detach restoration, and rejection of chrome:// injection. These are native operation checks; the simultaneous Playwright controller is not the native DevTools evidence.
A separate headed-browser fixture exercised four real native Network frontend cases: extension first and frontend first, each without interception and with a response paused. It verified the native frontend document was ready and its own TargetManager contained the inspected fixture. After both clients attached, the frontend's existing RuntimeAgent evaluated
54and the extension debugger evaluated42. Both intercepted requests fulfilled as transformed-response, HTTP 200; no detach event was observed in these runs. The controller never autoattached or opened a CDP session to the inspected page. It controlled its own extension page and briefly inspected its own frontend document. This establishes the measured coexistence cases on153.0.8010.52, despite the earlier documentation/sample ambiguity. It does not guarantee breakpoint behavior, cancellation, navigation, other owners or future versions. Chrome debugger, CDP Target schema.On stable Firefox, packaged MAIN code ran before the fixture's first parser script, isolated globals stayed separate, isolated messaging reached the event background, and browser.debugger was absent. With the required permissions, filterResponseData transformed text, HTML, a pre-parser HTML script insertion, and UTF-8 input delivered in three chunks with multibyte characters split across chunks. This fixture buffers until onstop and writes once; it does not prove incremental downstream streaming. A second manifest lacking only webRequestFilterResponse rejected all three filtering calls with the browser's missing-permission error and delivered unchanged bodies. This is absent permission, not user refusal or revocation. Mozilla response filtering.
Contract consequences
Retain independently registered capabilities with browser-specific implementations. DNR cannot transform response bodies; Chromium can use its restricted debugger Fetch domain. Firefox can use response filtering but has no equivalent native extension debugger API. The remaining contribution must still run when a particular capability is unsupported. Raw browser namespaces, listeners and handles stay in their eligible local context; descriptors, target IDs and serializable results can cross RPC.
The semantic baseline distinguishes unsupported implementation, wrong execution context, missing permission, restricted target, disconnected backend, conflicting owner and stale target. Contribution and realm contract chooses concrete public names and serialization without collapsing these distinctions. The audit does not introduce SDK error types or availability watchers.
Build-time executable contributions remain packaged. Development page HMR, content reinjection, background restart, watched production preview and installed extension update need distinct lifecycle contracts. Production remote replacement of privileged extension code is not a generic supported delivery mechanism. Chrome debugger cannot be an optional runtime permission. Chrome permission exclusions, MV3 code policy.
Owned handoff and blocking acceptance gates
dvcolis accountable for these existing contract tickets:- Debugger and CDB contract: retain the four-case native evidence, then prove breakpoint, close/reopen, cancellation, navigation, owner conflict and optional CDB behavior. No CDB integration was exercised here.
- Injection and transform contract: gate streaming, compressed/binary/large responses, redirects, cache/service-worker paths, strict CSP, frame replacement and finite request deadlines on real evidence.
- State scope and recovery: observe actual background termination without inspection keepalive, next activation, durable state and pending-operation outcomes on both hosts. These transitions remain unrun.
- Permissions and trust: distinguish missing grants from real gesture-driven refusal, grant, host revocation and restoration. Only absent filtering permission was observed here.
- Renderer and surface contract: exercise actual popup, options, native DevTools panel and browser sidebar mounting/disposal. Extension documents alone do not establish native UI lifecycle.
- Live preview and reload contract: consume toolchain evidence and define each update mode's surviving state, listeners and ownership.
- Examples and API coverage contract: require every public SDK export/API/hook/feature to map to a runnable example and automated assertion on every supported host, including contributions, renderers, Devframe, DevTools, Chromium and Firefox. Unsupported, failure and lifecycle paths are required cases. No stub or compile-only example counts. Raw-exposure tests cover SDK access, ownership and disposal rather than retesting every vendor method.
The source-linked matrix explicitly leaves unobserved guarantees unresolved. The research Definition of Done permits high-risk claims to remain blocking investigations with named owners, so these gates do not require implementing the future SDK before research closure.
Retained executable evidence is on local, unpushed branch
dvcol/research/browser-capabilities, commit8ce8658, underdocs/research/. The source-linked findings above are the public resolution; no hosted artifact URL is claimed.- added a commit that references this issue
on Sep 23, 2026
Part of Design a portable contribution SDK and WebExtension runtime.
Question
Which browser capabilities can the generic extension SDK promise on Chromium and Firefox, under which permissions and lifecycle conditions, and what evidence establishes each promise? Produce a versioned capability matrix and executable experiment requirements that later contracts can use without assuming identical browser behavior.
Context and current behavior
The destination is a framework-neutral SDK with build-time contributions, shared JSON-rendered interfaces, and adapters for Devframe, DevTools, and browser extensions. Browser support must evolve by adding modules and adapters. A missing Firefox capability must not prevent the remaining extension from working.
The platforms differ materially. Chrome's declarativeNetRequest API covers request blocking, redirects, and header changes; it provides no response-body transform. Firefox exposes webRequest.filterResponseData. Chromium exposes a restricted CDP transport through chrome.debugger, while Mozilla documents that this debugger API is not implemented in Firefox.
Debugger coexistence remains unproven. Chrome's reference says opening DevTools terminates an extension debugging session, while Google's debugger sample opens DevTools before attaching. Neither reading establishes a reliable supported-version contract. The audit must test both orders.
Chrome and Firefox also differ in background execution and sidebar APIs. A shared TypeScript interface does not erase those differences.
Requirements and scope
Options and recommendation
A lowest-common-denominator API is simple but would discard Chromium debugging and Firefox response filtering. Separate unrelated SDKs preserve browser behavior but defeat contribution reuse. Recommend a common contribution contract with explicit, independently registered capabilities and browser-specific implementations. The capability catalogue should state semantic guarantees, not merely whether a property exists on
chromeorbrowser.An untested capability is unresolved. It cannot be promoted to supported from a type declaration or a mocked unit test. Version-specific exceptions belong in the matrix with a reproducible case and a date.
Proposed API or experiment
The following is illustrative pseudocode, not an approved public schema:
Build a small experiment extension with packaged scripts and deterministic HTTP fixtures. Repeat attachment before and after native DevTools, navigate during attachment, and exercise frame replacement and user cancellation. Repeat applicable experiments on Firefox. Record observed results, exact browser versions, API permissions, commands, and traces. Declare unsupported cases through the public contract and test those declarations automatically.
Scenarios and acceptance criteria
Testing raw browser exposure means verifying the SDK's local access, ownership, lifecycle, and failure behavior. It does not mean reproducing every browser vendor's API test suite.
Dependencies
None. This audit establishes platform facts needed by later decisions. It may inspect existing upstream code and documentation without waiting for a contract decision.
Definition of Ready
Definition of Done
Resolution record
Post the accepted matrix, experiment links, chosen browser floors, unresolved blockers, and resulting contract implications in the resolution comment. Link that comment from the parent map under this issue's title; keep detailed evidence here.