From e2f9dd84b04930bd7f08e29129c16be3eb974022 Mon Sep 17 00:00:00 2001 From: davion-knight <298846663+davion-knight@users.noreply.github.com> Date: Sun, 5 Jul 2026 10:59:28 -0500 Subject: [PATCH] feat(enrichment): categorize the full binary inventory as assets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit categorizeFile only recognized a narrow hand-listed set of binary extensions (png/jpg/jpeg/gif/webp/pdf/zip/gz/zst) as the `asset` category, so every other binary the shared inventory already knows — mp4, mov, webm, woff2, wasm, node, safetensors, gguf, onnx, and the rest — fell through to `source`, mislabeling a media/font/model-weight change as a source change. Delegate the check to the shared binary-extension inventory (`BINARY_EXT_RE` from analyzers/binary-extensions, the same source asset-weight and provenance use) instead of a duplicated list, matching the #3252 unification. `.svg` is text (deliberately not in the binary inventory) but is still an asset for categorization, so it is kept explicitly. Purely additive — only binaries that were previously `source` become `asset`; no other category changes. --- review-enrichment/src/analysis-context.ts | 10 +++--- .../test/analysis-context.test.ts | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/review-enrichment/src/analysis-context.ts b/review-enrichment/src/analysis-context.ts index 752ef5beec..f874c4f95b 100644 --- a/review-enrichment/src/analysis-context.ts +++ b/review-enrichment/src/analysis-context.ts @@ -19,6 +19,7 @@ import { } from "./external-fetch.js"; import { isWorkflowPath } from "./workflow-path.js"; import { isSupportedLockfile } from "./lockfile-path.js"; +import { BINARY_EXT_RE } from "./analyzers/binary-extensions.js"; type ChangedFile = NonNullable[number]; @@ -448,11 +449,10 @@ function categorizeFile(path: string): FileCategory { ) { return { path, extension, category: "docs" }; } - if ( - [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".pdf", ".zip", ".gz", ".zst"].includes( - extension, - ) - ) { + // Binary assets — delegate to the shared binary-extension inventory (used by asset-weight/provenance) so any + // media/font/archive/model-weight blob categorizes as an asset instead of falling through to `source`. + // `.svg` is text, so it is not in BINARY_EXT_RE, but categorization still treats it as an asset. + if (BINARY_EXT_RE.test(path) || extension === ".svg") { return { path, extension, category: "asset" }; } if (extension) return { path, extension, category: "source" }; diff --git a/review-enrichment/test/analysis-context.test.ts b/review-enrichment/test/analysis-context.test.ts index 29a43aef33..b8553c9910 100644 --- a/review-enrichment/test/analysis-context.test.ts +++ b/review-enrichment/test/analysis-context.test.ts @@ -570,6 +570,39 @@ test("createAnalysisContext classifies long-form doc extensions as docs", () => ); }); +test("createAnalysisContext categorizes shared binary inventory entries as assets", () => { + const context = createAnalysisContext({ + repoFullName: "JSONbored/gittensory", + prNumber: 3359, + files: [ + // A legacy image extension that was already an asset before this change. + { path: "ui/logo.png", patch: null, status: "added" }, + // Binaries beyond the original narrow image/archive list — now recognized via the shared inventory. + { path: "media/demo.mp4", patch: null, status: "added" }, + { path: "fonts/Inter.woff2", patch: null, status: "added" }, + { path: "vendor/lib.wasm", patch: null, status: "added" }, + { path: "models/llama.safetensors", patch: null, status: "added" }, + // .svg is text but still an asset for categorization (kept explicitly). + { path: "icons/logo.svg", patch: "@@ -1,0 +1,1 @@\n+" }, + // A real source file is unaffected. + { path: "src/index.ts", patch: "@@ -1,0 +1,1 @@\n+export {};" }, + ], + }); + + assert.deepEqual( + context.fileCategories.map((file) => [file.path, file.category]), + [ + ["ui/logo.png", "asset"], + ["media/demo.mp4", "asset"], + ["fonts/Inter.woff2", "asset"], + ["vendor/lib.wasm", "asset"], + ["models/llama.safetensors", "asset"], + ["icons/logo.svg", "asset"], + ["src/index.ts", "source"], + ], + ); +}); + test("createAnalysisContext classifies lockfile paths case-insensitively", () => { const context = createAnalysisContext({ repoFullName: "JSONbored/gittensory",