feat(test): packed deleted-source proof level for the consumer harness (#103 stage 4) - #225
Conversation
#103 stage 4) The artifact-harness stage: removeProjectSource returns a verified removal receipt, openPackedMcpServer({ deletedSource }) re-verifies absence before spawn and only then upgrades provenance to packed-deleted-source, and the repository's single packed journey now deletes the consumer's source after its one build and proves the generated server still serves every route plus its embedded MCP App resource. Pack scripts accept npm 12's package-keyed `npm pack --json` output alongside npm 11's array form.
🦋 Changeset detectedLatest commit: ee6e6e9 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: 4046b94d17
ℹ️ 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".
| export const openPackedMcpServer = async ( | ||
| options: PackedMcpSessionOptions, | ||
| ): Promise<PackedMcpSession> => { | ||
| if (options.deletedSource !== undefined) await verifyDeletedSourceReceipt(options.deletedSource); |
There was a problem hiding this comment.
Bind deletion receipts to the launched project
When a harness manages multiple consumer projects, a genuine receipt returned for project A can be passed while launching project B's entry with its source still intact. verifyDeletedSourceReceipt checks only that A's recorded paths are absent; it never relates receipt.projectRoot to options.entry or cwd, yet the session is upgraded to packed-deleted-source. This can therefore record false self-contained-artifact evidence, so validate that the launched artifact belongs to the project represented by the receipt before assigning the stronger proof level.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in ee6e6e9. openPackedMcpServer now verifies the session binding before the receipt and before anything loads or spawns: the resolved entry must be a strict descendant of receipt.projectRoot, and any explicit cwd must be that root or a descendant. Mismatches fail closed with deleted-source-unverified, naming the receipt root and the offending entry/cwd. Two regression tests cover the cross-project entry and the in-project-entry/foreign-cwd cases; both reject before spawn (the dummy entries never exist). The packed journey re-passed — its entry and cwd bind to the receipt's root.
A receipt from project A could upgrade a session spawning project B's entry (B's source intact) to packed-deleted-source. The entry must now be a descendant of the receipt's project root and any explicit cwd must stay inside it, verified fail-closed before the SDK loads or anything spawns.
Closes the stage-4 slice of #103 — the artifact harness: packed/deleted-source proof, including the packed App proof stage 3 (#212) explicitly deferred here.
New proof level (label is load-bearing)
It is
packed-stdiomade strictly stronger, never a substitute claim: without a verified removal receipt,openPackedMcpServerprovenance stays byte-for-bytepacked-stdio.Delivered
removeProjectSource(agent-bundle/test): removes the consumer's conventional source inputs (src+ rootagent-bundle.config.*, plus caller-named extras), fail-closed — refuses a missing root, a vacuous deletion (absence observed without a deletion is not evidence), any path escaping the project root, and any path that survives removal. Returns a frozen, sorted, project-relative receipt.openPackedMcpServer({ deletedSource }): re-verifies every receipt path is absent immediately before spawn (newdeleted-source-unverifiederror code; failure text prints the full proof-level label) and only then stampspacked-deleted-source+sourceRemovedinto provenance.packed-stdio-projection.test.ts: one shared tarball set, one install, oneagent-bundle build, one verified source removal, one spawned server — every prior route assertion plus:listResourcescarriesui://harness/panelattext/html;profile=mcp-app, andreadResourcereturns the artifact-embedded HTML containing the fixture marker, an inline<script, and no externalscript/linkreferences (the build's own self-containment regex, re-checked on the wire with the source tree gone). The App HTML is served from the entry's inline registry (agent-bundle/mcp-appsvirtual module) — the deleted source can play no part.npm pack --jsonreturns a package-keyed object on npm 12 (array on ≤11);run-packed-tests.mjs,tests/support/shared-pack.ts, andaudit-packed-release.mjsnow accept both forms and fail loudly on anything else. This is the pre-existing breakage the stage-3 landing comment documented; without it the packed gate cannot run under npm 12.0.2 at all.route-harnesspanel App gains a guarded, minification-surviving DOM marker so the wire assertion checks real compiled content.browser-app). Docs: proof-level tables inagent-bundle/testand the README; minor changeset.Cost rules held (#107: one build + one pack per pool, one PR-gate packed journey)
No new build, no new pack, no new spawn. The one journey gained a source
rmand per-session App assertions — deletion and reads, not processes. The deleted-source proof rides the same single spawn all prior assertions use.Gates (all on the rebased tree over
101e70bf7)pnpm typecheck— passpnpm lint— pass (860 files, 0 errors/warnings)pnpm test:unit— full unit pool pass; scoped harness files 34/34pnpm test:packed packages/agent-bundle/tests/packed-stdio-projection.test.ts— pass (1/1), re-run after rebasing over feat(install): make host bundles directly installable #195's install-surface changes