Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/packed-deleted-source-proof.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
'agent-bundle': minor
---

Add the `packed-deleted-source` consumer proof level to `agent-bundle/test`.

`removeProjectSource` removes conventional project inputs and returns a frozen
receipt, while `openPackedMcpServer({ deletedSource })` verifies every receipt
path is still absent immediately before spawn and upgrades its provenance only
then.

The repository's single packed harness journey now builds once, removes the
fixture source and configuration, spawns once, asserts every route, and proves
the generated server serves its self-contained embedded MCP App resource.
Packed test and release scripts also accept both npm 11's array and npm 12's
package-keyed object forms of `npm pack --json`.
12 changes: 8 additions & 4 deletions packages/agent-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ is never a receipt for another.
| `mcp-in-memory` | `openInMemoryMcpServer`, `invokeMcpTool`, `readMcpResource`, `getMcpPrompt`, `listMcpSurface` | the real generated MCP server's protocol contract, over the SDK's in-memory transport |
| `cli-dispatch` | `invokeCli`, `cliJson` | an argv vector resolved and run through the routed CLI's own shell, in-process |
| `packed-stdio` | `openPackedMcpServer` | a built artifact's generated entry running as a real process over stdio |
| `packed-deleted-source` | `removeProjectSource`, `openPackedMcpServer({ deletedSource })` | the packed stdio process still runs after project source and configuration are removed and verified absent |

```ts
import { cliJson, expectEvents, invokeCli, invokeMcpTool } from 'agent-bundle/test';
Expand All @@ -296,10 +297,13 @@ turn a passing render red — while a missing frame, a reordering, or a regresse
ordinal still fails; `toHaveMonotonicSequence`, `toCompleteOnce`,
`toHaveProgress`, and `toHaveNoErrors` cover the rest of the contract.

Only `packed-stdio` is process evidence, and it is deliberately expensive: pack
once, install once, spawn once, and iterate every per-route assertion inside
that one session. Browser-App surfaces and deleted-source artifact proofs are
later stages; nothing here stands in for them.
Only `packed-stdio` and its strictly stronger `packed-deleted-source` upgrade
are process evidence, and they are deliberately expensive: pack once, install
once, build once, remove and verify source once, spawn once, and iterate every
per-route assertion inside that one session. The deleted-source journey also
reads the embedded MCP App resource from the generated server; it does not
prove native-host install or dispatch, or an install mode that copies the
artifact elsewhere.

## Evaluation

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// A browser App surface. The route-unit level refuses to render it by name;
// nothing in the Node test bundle ever imports this module.
// nothing in the Node test bundle ever imports this module, and the guard
// keeps its observable marker inert anywhere without a browser document.
export const config = { resourceUri: 'ui://harness/panel' };

if (typeof document !== 'undefined') {
const marker = document.createElement('span');
marker.textContent = 'route-harness panel';
document.body.append(marker);
}

export default function Panel() {
return null;
}
1 change: 1 addition & 0 deletions packages/agent-bundle/src/test/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { RenderedRouteProvenance } from './types.ts';
export type AgentTestErrorCode =
| 'assertion-failed'
| 'command-not-found'
| 'deleted-source-unverified'
| 'invalid-input'
| 'invalid-route-module'
| 'manifest-unavailable'
Expand Down
18 changes: 13 additions & 5 deletions packages/agent-bundle/src/test/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* `agent-bundle/test` — the consumer test harness helpers.
*
* Four Node proof levels ship here, and the browser-safe fifth level ships
* Five Node proof levels ship here, and the browser-safe sixth level ships
* from `agent-bundle/test/browser`. Each helper names the level it supplies,
* stamps it into its provenance, and prints it in every failure:
*
Expand All @@ -11,15 +11,18 @@
* | `mcp-in-memory` | `openInMemoryMcpServer`, `invokeMcpTool`, `readMcpResource`, `getMcpPrompt`, `listMcpSurface` | the real generated MCP server's protocol contract, over the SDK's in-memory transport |
* | `cli-dispatch` | `invokeCli`, `cliJson` | a compiled CLI command dispatched through the routed CLI's own shell, in this process |
* | `packed-stdio` | `openPackedMcpServer` | a built artifact's generated entry running as a real process over stdio |
* | `packed-deleted-source` | `removeProjectSource`, `openPackedMcpServer` | the packed stdio process still runs after project source and configuration are removed and verified absent |
* | `browser-app` | `mountBrowserApp` (`agent-bundle/test/browser`) | production-compiled MCP App HTML mounted over the product bridge in a real browser page |
*
* A pass at one level is never a receipt for another. Deleted-source artifact
* proof is a later stage; nothing here stands in for it.
* A pass at one level is never a receipt for another. The `deletedSource`
* option upgrades `openPackedMcpServer` provenance only after every path in a
* non-empty removal receipt is verified absent immediately before spawn.
*/
export {
BROWSER_APP_PROOF_LEVEL,
CLI_DISPATCH_PROOF_LEVEL,
MCP_IN_MEMORY_PROOF_LEVEL,
PACKED_DELETED_SOURCE_PROOF_LEVEL,
PACKED_STDIO_PROOF_LEVEL,
ROUTE_UNIT_PROOF_LEVEL,
compileTestManifest,
Expand Down Expand Up @@ -75,8 +78,13 @@ export type {
} from './mcp.ts';
export { cliJson, invokeCli } from './cli.ts';
export type { CliDispatchProvenance, CliInvocation, InvokeCliOptions } from './cli.ts';
export { openPackedMcpServer } from './packed.ts';
export type { PackedMcpProvenance, PackedMcpSession, PackedMcpSessionOptions } from './packed.ts';
export { openPackedMcpServer, removeProjectSource } from './packed.ts';
export type {
DeletedSourceReceipt,
PackedMcpProvenance,
PackedMcpSession,
PackedMcpSessionOptions,
} from './packed.ts';
export type {
AgentRouteModule,
AgentRouteModuleLoader,
Expand Down
18 changes: 14 additions & 4 deletions packages/agent-bundle/src/test/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,28 @@ import type {
* - `packed-stdio` installs the packed release tarball into a clean consumer,
* spawns the generated stdio entry as a real process, and drives it with a
* real MCP client. This is the only level here that is process evidence.
* - `packed-deleted-source` carries the `packed-stdio` proof after project
* source and configuration have been removed and verified absent. It proves
* that the generated entry is self-contained; it does not prove native-host
* install or dispatch, or an install mode that copies the artifact elsewhere.
*
* - `browser-app` compiles MCP App HTML through the production Rsbuild
* profile and mounts it over the product bridge in a real browser page. It
* does not prove host embedding, a packed artifact, or Workbench behavior.
*
* Deleted-source artifact evidence is a later stage; nothing here stands in
* for it.
*/
export type AgentTestProofLevel = 'route-unit' | 'mcp-in-memory' | 'cli-dispatch' | 'packed-stdio' | 'browser-app';
export type AgentTestProofLevel =
| 'route-unit'
| 'mcp-in-memory'
| 'cli-dispatch'
| 'packed-stdio'
| 'packed-deleted-source'
| 'browser-app';

export const ROUTE_UNIT_PROOF_LEVEL = 'route-unit' as const;
export const MCP_IN_MEMORY_PROOF_LEVEL = 'mcp-in-memory' as const;
export const CLI_DISPATCH_PROOF_LEVEL = 'cli-dispatch' as const;
export const PACKED_STDIO_PROOF_LEVEL = 'packed-stdio' as const;
export const PACKED_DELETED_SOURCE_PROOF_LEVEL = 'packed-deleted-source' as const;
export const BROWSER_APP_PROOF_LEVEL = 'browser-app' as const;

/**
Expand All @@ -60,6 +68,8 @@ export const proofLevelLabel = (level: AgentTestProofLevel): string => {
return 'cli-dispatch (argv dispatched through the routed CLI shell in-process; NOT a spawned binary)';
case 'packed-stdio':
return 'packed-stdio (packed tarball installed into a clean consumer, generated stdio entry spawned as a real process)';
case 'packed-deleted-source':
return 'packed-deleted-source (packed tarball installed into a clean consumer, artifact built, project source removed and verified absent, generated stdio entry spawned as a real process; self-contained-artifact evidence)';
case 'browser-app':
return '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)';
default: {
Expand Down
Loading
Loading