feat(llm-security): v8 Phase 5 step 2 - commons-loader.mjs [skip-docs]

Thin, sync-read JSON artifact loader for the future vendored
llm-security-commons subtree, modeled on signature-scanner.mjs's
loadRules()/loadCustomRules() pair: process-cached, graceful-empty
fallback on any read/parse error, and policy-extensible via a
`commons.root` policy value (mirrors sig.custom_rules_path).

Unit-tested now against a local fixture — Phase 4 (commons repo
creation, gated on the operator creating the Forgejo remote) hasn't
run yet, so the default `shared/` vendor path doesn't exist in this
checkout. That "not vendored yet" case is itself asserted: the loader
must degrade to the caller's fallback, not crash.

Not wired to any consumer yet (that's Phase 5 step 4, table-by-table
behind the golden gate). No CLI/hook/scanner-visible behaviour exists
to document. Golden baseline unchanged; full suite 2063/2063 (2053 +
10 new).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QAYkRaBXT6tmWXTQAi1ZBg
This commit is contained in:
Kjell Tore Guttormsen 2026-08-09 14:06:37 +02:00
commit 69cad7c973
2 changed files with 208 additions and 0 deletions

View file

@ -0,0 +1,116 @@
// commons-loader.test.mjs — Tests for the vendored-commons JSON artifact loader
//
// v8 Phase 5 step 2: llm-security-commons doesn't exist yet (Phase 4 is
// blocked on the operator creating the Forgejo repo), so these tests drive
// the loader against a local fixture directory instead of a real vendored
// subtree — including the "commons isn't vendored yet" case, which must
// degrade gracefully rather than crash.
import { describe, it, beforeEach, afterEach } from 'node:test';
import assert from 'node:assert/strict';
import { writeFileSync, mkdirSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { loadArtifact, _resetCacheForTest } from '../../scanners/lib/commons-loader.mjs';
import { _resetCacheForTest as _resetPolicyCacheForTest } from '../../scanners/lib/policy-loader.mjs';
const TEST_ROOT = join(tmpdir(), `llm-security-commons-loader-test-${Date.now()}`);
const FIXTURE_COMMONS_ROOT = join(TEST_ROOT, 'fixture-commons');
const POLICY_DIR = join(TEST_ROOT, '.llm-security');
const POLICY_FILE = join(POLICY_DIR, 'policy.json');
function writeArtifact(relPath, data) {
const filePath = join(FIXTURE_COMMONS_ROOT, `${relPath}.json`);
mkdirSync(join(filePath, '..'), { recursive: true });
writeFileSync(filePath, JSON.stringify(data));
}
describe('commons-loader', () => {
beforeEach(() => {
_resetCacheForTest();
_resetPolicyCacheForTest();
mkdirSync(FIXTURE_COMMONS_ROOT, { recursive: true });
});
afterEach(() => {
_resetCacheForTest();
_resetPolicyCacheForTest();
try { rmSync(TEST_ROOT, { recursive: true }); } catch {}
});
it('loads and parses a valid artifact from an explicit commonsRoot', () => {
writeArtifact('lexicon/injection-lexicon', { version: '0.1.0', terms: ['ignore previous instructions'] });
const data = loadArtifact('lexicon/injection-lexicon', { commonsRoot: FIXTURE_COMMONS_ROOT, fallback: null });
assert.deepEqual(data, { version: '0.1.0', terms: ['ignore previous instructions'] });
});
it('returns the caller fallback when the artifact file is missing', () => {
const data = loadArtifact('lexicon/injection-lexicon', { commonsRoot: FIXTURE_COMMONS_ROOT, fallback: [] });
assert.deepEqual(data, []);
});
it('returns the caller fallback when the artifact JSON is invalid', () => {
const filePath = join(FIXTURE_COMMONS_ROOT, 'mapping', 'owasp-map.json');
mkdirSync(join(filePath, '..'), { recursive: true });
writeFileSync(filePath, 'not valid json!!!');
const data = loadArtifact('mapping/owasp-map', { commonsRoot: FIXTURE_COMMONS_ROOT, fallback: {} });
assert.deepEqual(data, {});
});
it('degrades gracefully when commons has not been vendored yet (no override, no policy)', () => {
// Phase 4 hasn't run in this repo checkout: the default `shared/` vendor
// path does not exist. The loader must not throw.
const data = loadArtifact('lexicon/injection-lexicon', { fallback: 'EMPTY' });
assert.equal(data, 'EMPTY');
});
it('caches a loaded artifact per resolved path', () => {
writeArtifact('calibration/calibration', { entropyFloor: 4.5 });
const first = loadArtifact('calibration/calibration', { commonsRoot: FIXTURE_COMMONS_ROOT });
writeArtifact('calibration/calibration', { entropyFloor: 9.9 }); // mutate after first read
const second = loadArtifact('calibration/calibration', { commonsRoot: FIXTURE_COMMONS_ROOT });
assert.equal(first, second); // same reference (cached)
assert.equal(second.entropyFloor, 4.5); // original value, not the mutation
});
it('caches a failed load too, so a fixed-but-unread file still returns the cached fallback', () => {
const first = loadArtifact('signatures/malware-signatures', { commonsRoot: FIXTURE_COMMONS_ROOT, fallback: [] });
writeArtifact('signatures/malware-signatures', { rules: [{ id: 'late-arrival' }] });
const second = loadArtifact('signatures/malware-signatures', { commonsRoot: FIXTURE_COMMONS_ROOT, fallback: [] });
assert.deepEqual(first, []);
assert.deepEqual(second, []);
});
it('resolves commonsRoot from the commons.root policy value when no explicit override is given', () => {
mkdirSync(POLICY_DIR, { recursive: true });
writeFileSync(POLICY_FILE, JSON.stringify({ commons: { root: FIXTURE_COMMONS_ROOT } }));
writeArtifact('codepoints/carriers', { zeroWidth: [''] });
const data = loadArtifact('codepoints/carriers', { targetPath: TEST_ROOT, fallback: null });
assert.deepEqual(data, { zeroWidth: [''] });
});
it('resolves a relative commons.root policy value against targetPath', () => {
mkdirSync(POLICY_DIR, { recursive: true });
writeFileSync(POLICY_FILE, JSON.stringify({ commons: { root: './fixture-commons' } }));
writeArtifact('lexicon/injection-lexicon', { version: '0.1.0', terms: [] });
const data = loadArtifact('lexicon/injection-lexicon', { targetPath: TEST_ROOT, fallback: null });
assert.deepEqual(data, { version: '0.1.0', terms: [] });
});
it('an explicit commonsRoot option takes precedence over the commons.root policy value', () => {
mkdirSync(POLICY_DIR, { recursive: true });
writeFileSync(POLICY_FILE, JSON.stringify({ commons: { root: join(TEST_ROOT, 'does-not-exist') } }));
writeArtifact('lexicon/injection-lexicon', { version: '0.1.0', terms: ['override-wins'] });
const data = loadArtifact('lexicon/injection-lexicon', {
targetPath: TEST_ROOT,
commonsRoot: FIXTURE_COMMONS_ROOT,
fallback: null,
});
assert.deepEqual(data, { version: '0.1.0', terms: ['override-wins'] });
});
it('defaults the fallback to null when the caller passes none', () => {
const data = loadArtifact('lexicon/injection-lexicon', { commonsRoot: FIXTURE_COMMONS_ROOT });
assert.equal(data, null);
});
});