Skip to content

feat(test): browser-app proof level for the consumer harness (#103 stage 3) - #212

Merged
ScriptedAlchemy merged 7 commits into
mainfrom
wave5/103-s3
Sep 1, 2026
Merged

feat(test): browser-app proof level for the consumer harness (#103 stage 3)#212
ScriptedAlchemy merged 7 commits into
mainfrom
wave5/103-s3

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

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-app proof level

Label, stamped into every result's provenance and printed in every failure:

browser-app (MCP App HTML compiled through the production Rsbuild profile, mounted in a real browser page over the product bridge; NOT host embedding, packed-artifact, or Workbench evidence)

  • agentBundleBrowserRstest() (agent-bundle/rstest) builds the browser pool configuration: one compileTestManifest pass, then exactly one compileMcpApps invocation 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 own MAX_APP_HTML_BYTES), so browser workers never touch the filesystem or a second compiler.
  • agent-bundle/test/browser (new browser-safe subpath, no node: imports in the emitted bundle) ships mountBrowserApp: sandboxed iframe (srcdoc, allow-scripts allow-same-origin), postMessage wired to the product's own createMcpAppBridge — 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.
  • Test manifest now carries collision-checked MCP App descriptors from the same compiler pass (the slot stage 2 explicitly reserved), with the same identity/dedup rules and error text as planCompiledMcpApps.

Product changes (behavior-preserving)

  • compileMcpApps/planCompiledMcpApps accept a per-app target map alongside the existing single-target form (existing callers unchanged).
  • The bridge and binding-service modules drop node:buffer/node:crypto for web-platform equivalents (TextEncoder, atob/btoa with the same canonical-round-trip rejection, crypto.randomUUID), and the consent action digest moves to a leaf module (mcp-app-sandbox.ts re-exports it) so the browser bundle avoids the sandbox's Node imports.

Example adoption

examples/mcp-app gains a tests/browser-app pool (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-apps SDK:

  1. mount + initialize handshake + accessible presentation (landmark, labeled checks list, aria-live outcome);
  2. resource read round-trip from the running App through binding operations;
  3. consent: a tool call held for consent, approval resumes the exact pending operation once, denial fails closed with -32001 and never reaches the binding;
  4. unavailable binding operation fails closed with -32000, never a fake success.

Cost rules

  • Packed pool untouched: no new build, no new pack, no new spawn.
  • The browser pool adds exactly one production Rsbuild compile per run, shared by every test.
  • The harness unit test compiles the fixture project's app once, in the unit pool, with no pack.

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.ts fails identically on a clean origin/main worktree at c158be5f5 with npm 12.0.2 (npm pack --json now returns an object; tests/support/shared-pack.ts:84 expects the array form). Untouched by this branch; passes under npm 11.
  • pnpm test:route-unit — 11 passed; pnpm test:projection — 22 passed.
  • examples/mcp-app browser-app pool — 4 passed (real chrome, headless).
  • New harness tests — 30 passed, including a pin that the browser registry's label copy never drifts from proofLevelLabel('browser-app').
  • pnpm --filter agent-bundle builddist/test/browser.js + .d.ts emit with zero node: imports.

Changeset: minor (public surface grows).

@changeset-bot

changeset-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 590b178

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Minor

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T21:31:10.852245Z 5f291f5 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 1, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@212
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@212
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@212

commit: 590b178

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread packages/agent-bundle/src/test/browser.ts
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant