From 3032a34b4346520ab6042e8ad68ce96bdc932310 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sun, 6 Sep 2026 04:24:07 +0000 Subject: [PATCH 1/3] fix: report package evidence sidecar paths --- .../src/build/compile-evidence.ts | 20 ++++++++++--------- .../agent-bundle/src/build/pack-inventory.ts | 1 + packages/agent-bundle/tests/prepack.test.ts | 9 +++++++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/agent-bundle/src/build/compile-evidence.ts b/packages/agent-bundle/src/build/compile-evidence.ts index a6eab60f3..55f0bd171 100644 --- a/packages/agent-bundle/src/build/compile-evidence.ts +++ b/packages/agent-bundle/src/build/compile-evidence.ts @@ -309,8 +309,8 @@ export const parseCompileEvidenceRecord = (bytes: string): CompileEvidenceRecord /** MCP App views are the only compiled HTML documents (`mcp-apps/.html`). */ const isViewAsset = (path: string): boolean => path.endsWith('.html'); -const evidenceDiagnostic = (message: string): Diagnostic => - artifactDiagnostic('AB6039', `Compile evidence ${message}`, compileEvidenceFileName); +const evidenceDiagnostic = (message: string, evidencePath: string): Diagnostic => + artifactDiagnostic('AB6039', `Compile evidence ${message}`, evidencePath); /** * Checks a parsed record against the artifact's file table: every compiled @@ -322,10 +322,12 @@ const evidenceDiagnostic = (message: string): Diagnostic => export const compileEvidenceDiagnostics = ( record: CompileEvidenceRecord, files: ReadonlyMap, + evidencePath: string = compileEvidenceFileName, ): readonly Diagnostic[] => { const diagnostics: Diagnostic[] = []; + const reportEvidence = (message: string): Diagnostic => evidenceDiagnostic(message, evidencePath); if (record.policy.name !== externalPolicy.name || record.policy.revision !== externalPolicy.revision) { - diagnostics.push(evidenceDiagnostic( + diagnostics.push(reportEvidence( `was judged under policy ${record.policy.name}@${String(record.policy.revision)}; ` + `this validator applies ${externalPolicy.name}@${String(externalPolicy.revision)}.`, )); @@ -334,18 +336,18 @@ export const compileEvidenceDiagnostics = ( const compiled = new Set([...files].filter(([, file]) => file.kind === 'bundle').map(([path]) => path)); for (const path of compiled) { const asset = recorded.get(path); - if (asset === undefined) diagnostics.push(evidenceDiagnostic(`does not cover compiled file ${JSON.stringify(path)}.`)); - else if (asset.sha256 !== files.get(path)!.sha256) diagnostics.push(evidenceDiagnostic(`for ${JSON.stringify(path)} describes different bytes.`)); + if (asset === undefined) diagnostics.push(reportEvidence(`does not cover compiled file ${JSON.stringify(path)}.`)); + else if (asset.sha256 !== files.get(path)!.sha256) diagnostics.push(reportEvidence(`for ${JSON.stringify(path)} describes different bytes.`)); } // A view (an HTML document) inlines every module it loads; only node bundles may load a sibling, and only another node bundle. const nodeBundles = new Set([...compiled].filter((path) => !isViewAsset(path))); for (const asset of record.assets) { if (!compiled.has(asset.path)) { - diagnostics.push(evidenceDiagnostic(`names ${JSON.stringify(asset.path)}, which the file table does not list as a compiled file.`)); + diagnostics.push(reportEvidence(`names ${JSON.stringify(asset.path)}, which the file table does not list as a compiled file.`)); } for (const external of asset.externals) { if (isViewAsset(asset.path)) { - diagnostics.push(evidenceDiagnostic( + diagnostics.push(reportEvidence( `for ${JSON.stringify(asset.path)} records ${JSON.stringify(external.request)} as an external; a view inlines every module it loads.`, )); continue; @@ -355,14 +357,14 @@ export const compileEvidenceDiagnostics = ( switch (external.kind) { case 'builtin': if (judged !== 'builtin') { - diagnostics.push(evidenceDiagnostic( + diagnostics.push(reportEvidence( `for ${JSON.stringify(asset.path)} records ${JSON.stringify(external.request)} as a built-in; it is not one.`, )); } break; case 'artifact-relative': if (judged !== 'artifact-relative' || external.target !== posix.join(posix.dirname(asset.path), external.request)) { - diagnostics.push(evidenceDiagnostic( + diagnostics.push(reportEvidence( `for ${JSON.stringify(asset.path)} records sibling ${JSON.stringify(external.request)}, which the artifact does not contain.`, )); } diff --git a/packages/agent-bundle/src/build/pack-inventory.ts b/packages/agent-bundle/src/build/pack-inventory.ts index 2d28d9528..cfe829f1e 100644 --- a/packages/agent-bundle/src/build/pack-inventory.ts +++ b/packages/agent-bundle/src/build/pack-inventory.ts @@ -287,6 +287,7 @@ export const packInventoryDiagnostics = async (options: { new Map(options.packageBuild.files .filter((file) => file.kind === 'bundle' && !artifactPaths.has(file.path)) .map((file) => [file.path, { kind: file.kind, sha256: file.sha256 }])), + packageCompileEvidenceFileName, )); } catch (error) { diagnostics.push(diagnostic( diff --git a/packages/agent-bundle/tests/prepack.test.ts b/packages/agent-bundle/tests/prepack.test.ts index 7e8288d1e..c376c6e6c 100644 --- a/packages/agent-bundle/tests/prepack.test.ts +++ b/packages/agent-bundle/tests/prepack.test.ts @@ -191,8 +191,13 @@ it('reports package-only compile evidence drift as AB6039', async () => { const path = join(projectRoot, 'dist', packageCompileEvidenceFileName); const original = await readFile(path, 'utf8'); try { - await writeFile(path, '{"assets":[]}\n'); - expect(await diagnostics()).toContainEqual(expect.objectContaining({ code: 'AB6039' })); + const evidence = JSON.parse(original) as { policy: { revision: number } }; + evidence.policy.revision += 1; + await writeFile(path, `${JSON.stringify(evidence)}\n`); + expect(await diagnostics()).toContainEqual(expect.objectContaining({ + code: 'AB6039', + generatedPath: packageCompileEvidenceFileName, + })); } finally { await writeFile(path, original); } From cdc4d831f40880d1e799d8746203918bf3840a18 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sun, 6 Sep 2026 04:24:35 +0000 Subject: [PATCH 2/3] docs: record package evidence diagnostic fix --- .changeset/report-package-evidence-path.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/report-package-evidence-path.md diff --git a/.changeset/report-package-evidence-path.md b/.changeset/report-package-evidence-path.md new file mode 100644 index 000000000..36b85c1cd --- /dev/null +++ b/.changeset/report-package-evidence-path.md @@ -0,0 +1,5 @@ +--- +"agent-bundle": patch +--- + +Report package-only compile-evidence failures against `agent-bundle.package-compile-evidence.json` (#672). From bc157af83dd81239b5c08fe394495bdb1620bb96 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sun, 6 Sep 2026 04:28:19 +0000 Subject: [PATCH 3/3] docs: name package evidence diagnostic --- .changeset/report-package-evidence-path.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/report-package-evidence-path.md b/.changeset/report-package-evidence-path.md index 36b85c1cd..25240d33d 100644 --- a/.changeset/report-package-evidence-path.md +++ b/.changeset/report-package-evidence-path.md @@ -2,4 +2,4 @@ "agent-bundle": patch --- -Report package-only compile-evidence failures against `agent-bundle.package-compile-evidence.json` (#672). +Report `AB6039` package-only compile-evidence failures against `agent-bundle.package-compile-evidence.json` (#672).