- classify->dpia->ros kjede-wiring: dpia/ros Task-templater far eksplisitte AI Act-klassifiserings- + DPIA-funn-felt (kjede-data agentene allerede branchet pa) - dpia-agent uutforbar "spor bruker" -> "marker vurderingen" (Hvis-ikke-klassifisert + Error Handling); speilet til ros-analysis-agent - adr-writer-agent: Write-verktoy fjernet, returnerer ADR-markdown til hovedkontekst (command er eneste skriver -- subagenter skriver aldri) - KB-sti-forankring (komprehensiv): 36 bare referanse-subdir-stier i 6 agenter + 2 commands fullkvalifisert med CLAUDE_PLUGIN_ROOT/skills/<skill>/references/ --- ogsa innen-skill kortformer, uresolverbare i installert modus - mekanisme: validate-plugin.sh Check 6d (bare-subdir-lint m/ hyphen-guard) + negativ-probe-test (beviser tenner) + RX-P2 wiring-regresjonstester Suite 859/859 exit 0. validate-plugin 250 PASS / 0 FAIL. 145 forankrede stier verifisert eksisterende (0 mangler).
65 lines
2.4 KiB
JavaScript
65 lines
2.4 KiB
JavaScript
// Wires the static plugin validator (tests/validate-plugin.sh) into the canonical
|
|
// node --test suite so its checks — including RX-P1 Check 6 (install-mode path &
|
|
// delegation safety) — are enforced on every suite run, not just manual invocation.
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { execFileSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { dirname, join } from 'node:path';
|
|
import { writeFileSync, rmSync } from 'node:fs';
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const pluginRoot = join(here, '..', '..'); // tests/kb-update -> plugin root
|
|
const script = join(pluginRoot, 'tests', 'validate-plugin.sh');
|
|
|
|
test('validate-plugin.sh passes (frontmatter, encoding, KB refs, plugin.json, install-mode Check 6)', () => {
|
|
let out;
|
|
try {
|
|
out = execFileSync('bash', [script], { encoding: 'utf8', cwd: pluginRoot });
|
|
} catch (err) {
|
|
assert.fail(
|
|
`validate-plugin.sh exited ${err.status}:\n${err.stdout || ''}${err.stderr || ''}`,
|
|
);
|
|
}
|
|
assert.match(out, /VALIDATION PASSED/);
|
|
assert.doesNotMatch(out, /VALIDATION FAILED/);
|
|
});
|
|
|
|
// RX-P2: prove Check 6d has teeth — an unanchored reference-subdir path must be caught.
|
|
// Without a negative probe, the positive test above only proves the plugin is currently
|
|
// clean, not that 6d actually fires.
|
|
test('validate-plugin.sh Check 6d catches an unanchored reference-subdir path (negative probe)', () => {
|
|
const probe = join(pluginRoot, 'agents', '__rx_p2_6d_probe__.md');
|
|
writeFileSync(
|
|
probe,
|
|
[
|
|
'---',
|
|
'name: rx-p2-6d-probe',
|
|
'description: temporary probe for the 6d negative test',
|
|
'model: opus',
|
|
'color: blue',
|
|
'tools: ["Read"]',
|
|
'---',
|
|
'',
|
|
'# Probe',
|
|
'',
|
|
'Load: `responsible-ai/ai-act-compliance-guide.md`',
|
|
'',
|
|
].join('\n'),
|
|
);
|
|
try {
|
|
let failed = false;
|
|
let out = '';
|
|
try {
|
|
out = execFileSync('bash', [script], { encoding: 'utf8', cwd: pluginRoot });
|
|
} catch (err) {
|
|
failed = true;
|
|
out = `${err.stdout || ''}${err.stderr || ''}`;
|
|
}
|
|
assert.ok(failed, 'validate-plugin.sh must exit non-zero when a bare reference-subdir path is present');
|
|
assert.match(out, /bare reference-subdir path/);
|
|
assert.match(out, /__rx_p2_6d_probe__\.md/);
|
|
} finally {
|
|
rmSync(probe, { force: true });
|
|
}
|
|
});
|