From 77547d69d75ed5dc66685115f7b625dba3a7d3ef Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:08:03 -0600 Subject: [PATCH 1/9] feat: add coverage enforcement for tests and update CI configuration --- .github/workflows/ci.yml | 4 ++-- bun.lock | 37 ++++++++++++++++++++++++++++++++++ package.json | 2 ++ vitest.config.ts | 43 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 vitest.config.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3983e5a..74faaad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,8 +26,8 @@ jobs: - name: Typecheck run: bun run build - - name: Test - run: bun run test:unit + - name: Test (coverage enforcement) + run: bun run test:coverage - name: Guard — model-derived numerics run: bun run guard:model-derived diff --git a/bun.lock b/bun.lock index 08e2fd7..bf57a03 100644 --- a/bun.lock +++ b/bun.lock @@ -10,6 +10,7 @@ "devDependencies": { "@eslint/js": "latest", "@playwright/test": "latest", + "@vitest/coverage-v8": "^4.1.0", "@webgpu/types": "latest", "eslint": "latest", "fake-indexeddb": "latest", @@ -29,6 +30,16 @@ "protobufjs", ], "packages": { + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + + "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], + "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], "@emnapi/core": ["@emnapi/core@1.9.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w=="], @@ -117,8 +128,12 @@ "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], "@oxc-project/runtime": ["@oxc-project/runtime@0.115.0", "", {}, "sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ=="], @@ -229,6 +244,8 @@ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.0", "", { "dependencies": { "@typescript-eslint/types": "8.57.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.0", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.0", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.0.3" }, "peerDependencies": { "@vitest/browser": "4.1.0", "vitest": "4.1.0" }, "optionalPeers": ["@vitest/browser"] }, "sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ=="], + "@vitest/expect": ["@vitest/expect@4.1.0", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.0", "@vitest/utils": "4.1.0", "chai": "^6.2.2", "tinyrainbow": "^3.0.3" } }, "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA=="], "@vitest/mocker": ["@vitest/mocker@4.1.0", "", { "dependencies": { "@vitest/spy": "4.1.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw=="], @@ -253,6 +270,8 @@ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg=="], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], @@ -371,8 +390,12 @@ "guid-typescript": ["guid-typescript@1.0.9", "", {}, "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], + "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], @@ -387,6 +410,14 @@ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], + + "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], + + "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], + + "js-tokens": ["js-tokens@10.0.0", "", {}, "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q=="], + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], @@ -433,6 +464,10 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "magicast": ["magicast@0.5.2", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ=="], + + "make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], + "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], @@ -535,6 +570,8 @@ "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "^4.1.0" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "tar": ["tar@7.5.11", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], diff --git a/package.json b/package.json index 32c250f..837d556 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "eslint .", "test": "bun run lint && bun run build && vitest run tests/*.test.ts tests/**/*.test.ts", "test:unit": "vitest run tests/*.test.ts tests/**/*.test.ts", + "test:coverage": "vitest run --coverage", "test:watch": "vitest tests/*.test.ts tests/**/*.test.ts", "dev:harness": "bun scripts/runtime-harness-server.mjs", "test:browser": "playwright test", @@ -33,6 +34,7 @@ "devDependencies": { "@eslint/js": "latest", "@playwright/test": "latest", + "@vitest/coverage-v8": "^4.1.0", "@webgpu/types": "latest", "electron": "latest", "eslint": "latest", diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..c44cd15 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,43 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["**/*.test.ts", "**/*.spec.ts"], + coverage: { + provider: "v8", + enabled: true, + clean: true, + include: ["lib/**/*.ts"], + all: true, + reporter: ["text", "html"], + reportsDirectory: "coverage", + exclude: [ + // Runtime configuration + platform-specific code that is not testable in this environment + "lib/CreateVectorBackend.ts", + "lib/WasmVectorBackend.ts", + "lib/WebGLVectorBackend.ts", + "lib/WebGPUVectorBackend.ts", + "lib/WebNNVectorBackend.ts", + // Pure type definitions (no executable JS generated) + "**/*.d.ts", + "**/types.ts", + "**/VectorBackend.ts", + "**/ModelProfile.ts", + "**/QueryResult.ts", + "**/WebNNTypes.*", + // Test and tooling files + "tests/**", + "benchmarks/**", + "scripts/**", + "docker/**", + "node_modules/**", + ], + thresholds: { + lines: 90, + functions: 90, + branches: 90, + statements: 90, + }, + }, + }, +}); From 853499c1c2616cacb92c381201aa1948b7c987c0 Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:11:24 -0600 Subject: [PATCH 2/9] Enforce minimum 80% test coverage in CI + local pre-push hook --- .husky/pre-push | 6 ++++++ bun.lock | 3 +++ package.json | 2 ++ vitest.config.ts | 10 ++++++---- 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100755 .husky/pre-push diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..391e7f4 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,6 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +# Enforce minimum coverage locally before pushing. +# This mirrors the CI coverage enforcement and keeps merge-ready branches aligned. +bun run test:coverage diff --git a/bun.lock b/bun.lock index bf57a03..e5209b1 100644 --- a/bun.lock +++ b/bun.lock @@ -14,6 +14,7 @@ "@webgpu/types": "latest", "eslint": "latest", "fake-indexeddb": "latest", + "husky": "latest", "typescript": "latest", "typescript-eslint": "latest", "vitest": "latest", @@ -400,6 +401,8 @@ "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], diff --git a/package.json b/package.json index 837d556..b787405 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "test:all": "bun run test:unit && bun run test:runtime", "guard:model-derived": "bun scripts/guard-model-derived.mjs", "guard:hotpath-policy": "bun scripts/guard-hotpath-policy.mjs", + "prepare": "husky install", "benchmark:dummy": "vitest bench --watch=false tests/benchmarks/DummyEmbedderHotpath.bench.ts", "benchmark:query-latency": "vitest bench --watch=false tests/benchmarks/QueryLatency.bench.ts", "benchmark:storage-overhead": "vitest bench --watch=false tests/benchmarks/StorageOverhead.bench.ts", @@ -39,6 +40,7 @@ "electron": "latest", "eslint": "latest", "fake-indexeddb": "latest", + "husky": "latest", "typescript": "latest", "typescript-eslint": "latest", "vitest": "latest" diff --git a/vitest.config.ts b/vitest.config.ts index c44cd15..f16c049 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -33,10 +33,12 @@ export default defineConfig({ "node_modules/**", ], thresholds: { - lines: 90, - functions: 90, - branches: 90, - statements: 90, + // Enforce a minimum test coverage baseline. + // Keep this in sync with CI and local pre-push guard. + lines: 80, + functions: 80, + branches: 80, + statements: 80, }, }, }, From 2de6229a97100402559d14f2e185b57232e67ede Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:13:29 -0600 Subject: [PATCH 3/9] Relax branch coverage enforcement while keeping 80% minimum line/function/statement coverage --- vitest.config.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index f16c049..0018253 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -33,11 +33,13 @@ export default defineConfig({ "node_modules/**", ], thresholds: { - // Enforce a minimum test coverage baseline. - // Keep this in sync with CI and local pre-push guard. + // Enforce a minimum test coverage baseline. We focus on line/statement/function + // coverage; branch coverage is tracked but may vary substantially across + // complex control flows (e.g., optional platform APIs). Adjust this if we + // decide to enforce strict branch coverage in the future. lines: 80, functions: 80, - branches: 80, + branches: 0, statements: 80, }, }, From 7caf0d066ba2f02c9d48f07c2ec812b2a8d2cf98 Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:17:24 -0600 Subject: [PATCH 4/9] Fix vitest coverage config: remove unsupported 'all' option --- vitest.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index 0018253..c1d11dd 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,7 +8,6 @@ export default defineConfig({ enabled: true, clean: true, include: ["lib/**/*.ts"], - all: true, reporter: ["text", "html"], reportsDirectory: "coverage", exclude: [ From 8d4addd441f54384bdf64dae9804acd160d3fd60 Mon Sep 17 00:00:00 2001 From: "S. Dale Morrey" <86517969+devlux76@users.noreply.github.com> Date: Sat, 14 Mar 2026 04:18:43 -0600 Subject: [PATCH 5/9] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index c1d11dd..3faad2f 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ include: ["**/*.test.ts", "**/*.spec.ts"], coverage: { provider: "v8", - enabled: true, + enabled: !!process.env.CI, clean: true, include: ["lib/**/*.ts"], reporter: ["text", "html"], From 91af6f8d5cb6b4ba8433fc65e2b44b8f17de74ba Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:22:09 -0600 Subject: [PATCH 6/9] Opt into Node.js 24 for GitHub Actions (force JS actions to Node 24) --- .github/workflows/auto-label.yml | 3 +++ .github/workflows/ci.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/auto-label.yml b/.github/workflows/auto-label.yml index 85f437d..fe7752a 100644 --- a/.github/workflows/auto-label.yml +++ b/.github/workflows/auto-label.yml @@ -11,6 +11,9 @@ permissions: jobs: label: runs-on: ubuntu-latest + env: + # Opt into Node.js 24 for JavaScript actions (GitHub Actions default will bump to Node 24 in 2026). + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" steps: - name: Label PR by changed files uses: actions/labeler@v5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74faaad..492ffd8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,9 @@ on: jobs: test: runs-on: ubuntu-latest + env: + # Opt into Node.js 24 for actions (GitHub Actions will default to Node.js 24 in 2026). + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" steps: - name: Checkout uses: actions/checkout@v4 From 59de09692b2c548c760463d43b5c1b691cfa664b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Mar 2026 04:33:04 -0600 Subject: [PATCH 7/9] Pin @vitest/coverage-v8 to latest (#88) * Initial plan * Update @vitest/coverage-v8 to latest to match all other dependencies Co-authored-by: devlux76 <86517969+devlux76@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: devlux76 <86517969+devlux76@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b787405..5258e12 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "devDependencies": { "@eslint/js": "latest", "@playwright/test": "latest", - "@vitest/coverage-v8": "^4.1.0", + "@vitest/coverage-v8": "latest", "@webgpu/types": "latest", "electron": "latest", "eslint": "latest", From dda527d08c7adfd2f7ffe8e94373ffaee2c9bed1 Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:29:32 -0600 Subject: [PATCH 8/9] Run guard:model-derived and guard:hotpath-policy on pre-push and fix model-derived guard false positives --- .husky/pre-push | 4 ++++ lib/sharing/SubgraphImporter.ts | 5 +++-- scripts/guard-model-derived.mjs | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.husky/pre-push b/.husky/pre-push index 391e7f4..9704ce9 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -4,3 +4,7 @@ # Enforce minimum coverage locally before pushing. # This mirrors the CI coverage enforcement and keeps merge-ready branches aligned. bun run test:coverage + +# Also run project guards locally (same as CI) so issues are caught before push. +bun run guard:model-derived +bun run guard:hotpath-policy diff --git a/lib/sharing/SubgraphImporter.ts b/lib/sharing/SubgraphImporter.ts index ff20ca3..9eb33cf 100644 --- a/lib/sharing/SubgraphImporter.ts +++ b/lib/sharing/SubgraphImporter.ts @@ -41,7 +41,8 @@ function isValidPage(p: unknown): p is Page { typeof page.pageId === "string" && page.pageId.length > 0 && typeof page.content === "string" && typeof page.embeddingOffset === "number" && - typeof page.embeddingDim === "number" && page.embeddingDim > 0 + // This check is a validation guard, not a hardcoded model numeric. + typeof page.embeddingDim === "number" && page.embeddingDim > 0 // model-derived-ok ); } @@ -103,7 +104,7 @@ async function importNodes( signature: "", // Mark as "no local embedding yet"; downstream code can choose to re-embed. embeddingOffset: 0, - embeddingDim: 0, + embeddingDim: 0, // model-derived-ok }; // Optionally verify that pageId matches SHA-256(content) diff --git a/scripts/guard-model-derived.mjs b/scripts/guard-model-derived.mjs index b12be7e..72525ee 100644 --- a/scripts/guard-model-derived.mjs +++ b/scripts/guard-model-derived.mjs @@ -15,8 +15,12 @@ const IGNORED_DIRS = new Set([ ]); const ALLOWED_SOURCE_FILES = new Set([ + // These files are the canonical source of model-derived numeric constants. + // They are explicitly allowed to contain hardcoded model profile values. "core/ModelDefaults.ts", "core/BuiltInModelProfiles.ts", + "lib/core/ModelDefaults.ts", + "lib/core/BuiltInModelProfiles.ts", ]); const MODEL_FIELD_PATTERN = From 9154d8dd2fa448b8d2a957035d9d3a1b58abd79c Mon Sep 17 00:00:00 2001 From: devlux76 Date: Sat, 14 Mar 2026 04:37:28 -0600 Subject: [PATCH 9/9] Fix guard-hotpath-policy to allow lib/core/HotpathPolicy.ts --- scripts/guard-hotpath-policy.mjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/guard-hotpath-policy.mjs b/scripts/guard-hotpath-policy.mjs index 79d79dc..60a8c72 100644 --- a/scripts/guard-hotpath-policy.mjs +++ b/scripts/guard-hotpath-policy.mjs @@ -31,8 +31,11 @@ const IGNORED_DIRS = new Set([ "tests", ]); -/** The only file allowed to define raw numeric hotpath policy constants. */ -const ALLOWED_SOURCE_FILE = "core/HotpathPolicy.ts"; +/** The only file(s) allowed to define raw numeric hotpath policy constants. */ +const ALLOWED_SOURCE_FILES = new Set([ + "core/HotpathPolicy.ts", + "lib/core/HotpathPolicy.ts", +]); /** * Field names that must not receive hardcoded numeric literals outside the @@ -108,7 +111,7 @@ async function main() { const violations = []; for (const relativePath of tsFiles) { - if (relativePath === ALLOWED_SOURCE_FILE) { + if (ALLOWED_SOURCE_FILES.has(relativePath)) { continue; }