feat(test): browser-app proof level for the consumer harness (#103 stage 3) - #212
Conversation
🦋 Changeset detectedLatest commit: 590b178 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f291f5a58
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Expose normalized MCP App descriptors from the same compiler preparation so browser pools can compile honest app evidence without reloading project configuration.
Compile every declared app in one production Rsbuild run and generate a bounded browser-worker registry with per-app target provenance.
Add a browser-safe public harness that drives sandboxed compiled HTML through the product bridge with bounded initialization, captured traffic, consent control, and proof-level provenance.
Adopt the browser harness in the public MCP App example and cover rendering, resource binding, consent approval and denial, accessibility, and fail-closed operations.
Give the real app-compilation test enough time under the full parallel suite and remove the redundant consent re-export import flagged by lint.
5f291f5 to
590b178
Compare
Closes the stage-3 slice of #103 — the browser harness, per #107 rev 2's cap and this issue's Test level 3. Scope was posted upfront in #103 (comment).
The
browser-appproof levelLabel, stamped into every result's provenance and printed in every failure:
agentBundleBrowserRstest()(agent-bundle/rstest) builds the browser pool configuration: onecompileTestManifestpass, then exactly onecompileMcpAppsinvocation per pool run — the production function already compiles every app in one Rsbuild instance with the self-contained-HTML invariants asserted post-build. The compiled HTML is embedded into a generated registry setup module (bounded by the bridge's ownMAX_APP_HTML_BYTES), so browser workers never touch the filesystem or a second compiler.agent-bundle/test/browser(new browser-safe subpath, nonode:imports in the emitted bundle) shipsmountBrowserApp: sandboxed iframe (srcdoc,allow-scripts allow-same-origin), postMessage wired to the product's owncreateMcpAppBridge— not a test reimplementation. Tests supply binding operations (callTool/readResource/closeBinding), host callbacks, and consent decisions (manual, scripted approve/deny, or a per-challenge function); the handle exposes the app document, both directions of bridge traffic, captured host callbacks, pending consent challenges, and the bridge publish surface. Every failure names the proof level, app identity, and compiled-output provenance.planCompiledMcpApps.Product changes (behavior-preserving)
compileMcpApps/planCompiledMcpAppsaccept a per-app target map alongside the existing single-targetform (existing callers unchanged).node:buffer/node:cryptofor web-platform equivalents (TextEncoder,atob/btoawith the same canonical-round-trip rejection,crypto.randomUUID), and the consent action digest moves to a leaf module (mcp-app-sandbox.tsre-exports it) so the browser bundle avoids the sandbox's Node imports.Example adoption
examples/mcp-appgains atests/browser-apppool (agentBundleBrowserRstest(), chrome via Playwright, 1440×900) with four acceptance tests against the real compiled status panel, which itself gained genuine resource-read and consent-gated refresh actions through the official@modelcontextprotocol/ext-appsSDK:-32001and never reaches the binding;-32000, never a fake success.Cost rules
Deferred (per the scope comment)
Gates (after rebase onto c158be5)
pnpm typecheck— pass.pnpm lint— 848 files, 0 errors/warnings.pnpm test:unit— 2186 passed, 5 skipped, 2 failed:scaffold-packed-matrix.e2e.test.tsfails identically on a cleanorigin/mainworktree atc158be5f5with npm 12.0.2 (npm pack --jsonnow returns an object;tests/support/shared-pack.ts:84expects the array form). Untouched by this branch; passes under npm 11.pnpm test:route-unit— 11 passed;pnpm test:projection— 22 passed.examples/mcp-appbrowser-app pool — 4 passed (real chrome, headless).proofLevelLabel('browser-app').pnpm --filter agent-bundle build—dist/test/browser.js+.d.tsemit with zeronode:imports.Changeset: minor (public surface grows).