Files
documentation/scripts/strategy.test.mjs
T

42 lines
2.8 KiB
JavaScript

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {readFileSync, readdirSync} from 'node:fs';
const read = p => readFileSync(p, 'utf8');
const model = JSON.parse(read('research/ai-adoption/strategy-model.json'));
test('seven existing strategy pages and two stage overviews preserve canonical routes', () => {
assert.equal(model.pages.length, 7);
assert.deepEqual(readdirSync('docs/strategy').filter(p => p.endsWith('.mdx')).sort(),
[...model.pages.filter(p => p.id !== 'measurement').map(({id}) => `${id}.mdx`), 'stage-01-skills-adoption.mdx', 'stage-02-autonomous-agent.mdx', 'baseline.mdx'].sort());
for (const {id} of model.pages) {
const page = read(`docs/strategy/${id === 'measurement' ? 'measurement/index' : id}.mdx`);
assert(page.includes(`id: ${id === 'measurement' ? 'index' : id}`));
assert(page.includes('Target operating model'));
assert(!/## Sources|\[\d+\]|Internal evidence mapping/.test(page));
assert(read('sidebars/strategy.ts').includes(`'${id === 'measurement' ? 'measurement/index' : id}'`));
}
for (const teams of Object.values(model.organization)) for (const name of teams) {
assert(readdirSync('docs/organization/structure').some(file => read(`docs/organization/structure/${file}`).includes(name)));
assert(read('docs/strategy/target-operating-model.mdx').includes(name));
}
});
test('every metric has an actionable reader-facing contract', () => {
const manifest = JSON.parse(read('research/ai-adoption/measurement-migration.json'));
assert.equal(model.kpis.length,16);
for (const k of model.kpis) {
const section=read(`docs/strategy/${manifest.metrics.find(m => m.title === k.name).docId}.mdx`);
assert(section,k.name);
for (const field of ['Eligible population','Exclusions','Events and source','Owner / cadence','Missing evidence','Gaming and limits']) assert(section.includes(`| ${field} |`));
assert(section.includes(k.owner));
}
assert(read('docs/strategy/measurement/synthetic-example.mdx').includes('not a production ingestion system'));
});
test('diagram preserves independent release approval and no agent production authority', () => {
const d=JSON.parse(read('diagrams/ai-adoption-target.architecture.json'));
assert(d.meta.title.startsWith('TO-BE'));
assert.equal(d.components.filter(n=>n.id==='coordinator').length,1);
assert.deepEqual(d.connections.filter(e=>e.to==='release').map(e=>e.from),['approval']);
for (const [from,to] of [['registry','coordinator'],['registry','clients'],['clients','gates'],['gates','approval'],['release','audit'],['audit','people']]) assert(d.connections.some(e=>e.from===from&&e.to===to));
assert(!d.connections.some(e=>['clients','coordinator'].includes(e.from)&&['release','approval'].includes(e.to)));
assert(d.boundaries.some(b=>b.wraps.includes('gates')&&b.wraps.includes('release')));
});