import {test} from 'node:test'; import assert from 'node:assert/strict'; import {readFileSync} from 'node:fs'; const read = p => readFileSync(p, 'utf8'); const stages = ['Scope', 'Architecture', 'UI/UX', 'Planning', 'Delivery', 'UAT', 'Security', 'Releases']; test('Strategy opens at the autonomous lifecycle, with a matching direct landing story', () => { assert.match(read('sidebars/strategy.ts'), /strategySidebar: \['target-operating-model', 'index'/); assert.match(read('docs/strategy/target-operating-model.mdx'), /^sidebar_label: Target$/m); for (const id of ['index', 'target-operating-model']) { const page = read(`docs/strategy/${id}.mdx`); const primary = page.split('
')[0]; assert(primary.includes('name="strategy-target"')); assert(primary.includes('autonomous agent')); assert(primary.includes('direct, guide and review')); assert(primary.includes('Scope → Architecture → UI/UX → Planning → Delivery → UAT → Security → Releases → Scope')); assert(primary.includes('human-controlled code agent')); assert(primary.includes('TO-BE')); assert(!/only routes|People authorize|independent gates protect release/.test(primary)); } }); test('both target diagrams have eight stages, eight governed phases and eight human-controlled contributors', () => { for (const suffix of ['', '-mobile']) { const d = JSON.parse(read(`diagrams/strategy-target${suffix}.architecture.json`)); const ids = stages.map(label => d.components.find(n => n.label === label)?.id); assert(ids.every(Boolean)); assert.equal(new Set(ids).size, 8); const flow = d.connections.filter(e => ids.includes(e.from) && ids.includes(e.to)); assert.deepEqual(flow.map(e => [e.from, e.to]), ids.map((id, i) => [id, ids[(i + 1) % ids.length]])); assert.match(flow.at(-1).label, /Repeat/); assert(d.components.some(n => n.id === 'agent' && n.label === 'Autonomous agent' && n.sublabel === 'Human Controlled')); assert(!d.components.some(n => n.id === 'humans' || n.label === 'Humans')); assert(!d.connections.some(e => e.id === 'human-direction' || e.from === 'humans' || e.to === 'humans')); assert.equal(d.connections.length, 24); assert.deepEqual(d.connections.filter(e => e.from === 'agent').map(e => e.to), ids); const contributors = d.components.filter(n => n.id.startsWith('code-')); assert.equal(contributors.length, 8); assert(contributors.every(n => n.label === 'Code agent' && n.sublabel === 'Human-controlled')); for (const id of ids) { assert(d.connections.some(e => e.from === `code-${id}` && e.to === id && e.variant === 'dashed')); assert(d.connections.some(e => e.from === 'agent' && e.to === id && e.variant === 'security')); } assert.equal(d.components.length, 17); if (!suffix) { const center = n => n.pos.map((v, i) => v + n.size[i] / 2); const agent = center(d.components.find(n => n.id === 'agent')); const phaseCenters = ids.map(id => center(d.components.find(n => n.id === id))); for (const axis of [0, 1]) { const values = phaseCenters.map(c => c[axis]); assert.equal(agent[axis], (Math.min(...values) + Math.max(...values)) / 2); } for (const code of contributors) { const phase = d.components.find(n => n.id === code.id.slice(5)); const distance = n => Math.hypot(...center(n).map((v, i) => v - agent[i])); assert(distance(code) > distance(phase), `${code.id} is exterior`); } } } });