Merge published Strategy horizons into homepage embed candidate
Build and publish Eldorado documentation / build (pull_request) Successful in 46s
Build and publish Eldorado documentation / build (pull_request) Successful in 46s
This commit is contained in:
commit
4e94ad24fd
46 files changed
+600
-303
No files matched your search
@@ -13,11 +13,11 @@ test('PDF assignment and audit matrix map to actual page evidence',()=>{
|
||||
for(const p of matrix.verification_sources)assert(read(p));
|
||||
assert.equal(35+15,50);
|
||||
});
|
||||
test('main reading path does not promise skills rollout or autonomous destination',()=>{
|
||||
const main=read('docs/strategy/target-operating-model.mdx').split('<details>')[0];
|
||||
test('six-month reading path does not promise skills rollout or autonomous delivery',()=>{
|
||||
const main=read('docs/strategy/six-months-target.mdx').split('<details>')[0];
|
||||
assert(main.indexOf('strategy-six-months')<main.indexOf('Choose the smallest intervention'));
|
||||
for(const stale of ['The first investment is a governed skills system','An autonomous agent executes and governs every phase','foundation for Stage 2'])assert(!main.includes(stale));
|
||||
const roadmap=read('docs/strategy/roadmap.mdx');
|
||||
const roadmap=read('docs/strategy/six-months-roadmap.mdx');
|
||||
for(const month of [1,2,3,4,5,6]){
|
||||
const block=roadmap.split(`**Month ${month} — `)[1].split('\n\n')[0];
|
||||
for(const word of ['Output:','Dependency:'])assert(block.includes(word),`${month}: ${word}`);
|
||||
@@ -53,7 +53,7 @@ test('first-revision recovery and diagram decisions cannot disappear',()=>{
|
||||
test('target caption is inside SVG, expands canvas and fails closed',()=>{
|
||||
const svg='<svg role="img" viewBox="0 0 1200 1000"><g data-node-id="agent"/></svg>';
|
||||
const out=targetCaption(svg);
|
||||
for(const term of ['Proposed optional target','Solid: lifecycle','Dotted: execution','Dashed: human-controlled'])assert(out.includes(term));
|
||||
for(const term of ['Long-term Target','Solid: lifecycle','Dotted: execution','Dashed: human-controlled'])assert(out.includes(term));
|
||||
assert(out.includes('viewBox="0 0 1200 1130"'));
|
||||
assert(out.indexOf('eldorado-target-caption')<out.indexOf('</svg>'));
|
||||
assert.equal((out.match(/data-node-id=/g)||[]).length,1);
|
||||
|
||||
@@ -3,6 +3,6 @@ const fs=require('node:fs');const assert=require('node:assert/strict');
|
||||
(async()=>{
|
||||
const base=process.argv[2]||'http://127.0.0.1:4173';const out=`.cache/journey-${process.argv[3]||'candidate'}`;fs.mkdirSync(out,{recursive:true});
|
||||
const b=await chromium.launch({executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE,args:['--no-sandbox']});const results=[];
|
||||
const steps=[['target-operating-model','roadmap'],['roadmap','stage-01-skills-adoption'],['stage-01-skills-adoption','baseline'],['baseline','measurement'],['measurement','skills-quality'],['skills-quality','skills-governance'],['skills-governance','skills-quality'],['skills-quality','skills-adoption'],['skills-adoption','skills-maintenance'],['skills-maintenance','skills-quality'],['skills-quality','measurement/validated-task-success'],['measurement/validated-task-success','skills-quality'],['skills-maintenance','stage-02-autonomous-agent'],['stage-02-autonomous-agent','stage-01-skills-adoption']];
|
||||
const steps=[['target-operating-model','roadmap'],['roadmap','six-months-target'],['six-months-target','six-months-roadmap'],['six-months-roadmap','stage-02-autonomous-agent'],['six-months-roadmap','stage-01-skills-adoption'],['stage-01-skills-adoption','baseline'],['baseline','measurement'],['measurement','skills-quality'],['skills-quality','skills-governance'],['skills-governance','skills-quality'],['skills-quality','skills-adoption'],['skills-adoption','skills-maintenance'],['skills-maintenance','skills-quality'],['skills-quality','measurement/validated-task-success'],['measurement/validated-task-success','skills-quality'],['skills-maintenance','stage-02-autonomous-agent'],['stage-02-autonomous-agent','stage-01-skills-adoption']];
|
||||
try{for(const width of [1440,390]){const p=await b.newPage({viewport:{width,height:900}});for(const [from,to]of steps){await p.goto(`${base}/eldorado-v1/documentation/strategy/${from}/`,{waitUntil:'networkidle'});const href=`/eldorado-v1/documentation/strategy/${to}/`;const link=p.locator(`article a[href="${href}"]`).filter({visible:true}).first();assert(await link.count(),`${from} → ${to}`);await link.scrollIntoViewIfNeeded();await p.waitForLoadState('networkidle');await link.click();await p.waitForURL(`${base}${href}`);await p.locator('article h1').waitFor();results.push({width,from,to,clicked:true});fs.writeFileSync(`${out}/results.json`,JSON.stringify(results,null,2))}await p.close()}console.log(`PASS ${results.length} real reader handoffs and feedback links`)}finally{await b.close()}
|
||||
})().catch(e=>{console.error(e);process.exitCode=1});
|
||||
@@ -13,8 +13,6 @@ const fs = require('node:fs');
|
||||
const page = await context.newPage();
|
||||
await page.goto(`${base}/eldorado-v1/documentation/strategy/`, {waitUntil: 'networkidle'});
|
||||
await page.addStyleTag({content:'html {scroll-behavior:auto !important;}'});
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const panel = page.locator('.archify-panel--story[data-diagram="strategy-target"]');
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
@@ -140,9 +138,7 @@ const fs = require('node:fs');
|
||||
await page.waitForURL('**/strategy/roadmap/');
|
||||
await page.goBack({waitUntil:'domcontentloaded'});
|
||||
await page.waitForURL('**/strategy/target-operating-model/');
|
||||
await page.getByRole('heading', {name:'First six months as AI Architect', exact:true, level:1}).waitFor();
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await page.getByRole('heading', {name:'Target', exact:true, level:1}).waitFor();
|
||||
const next = page.locator(`.archify-panel--story[data-diagram="strategy-target"] > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await next.scrollIntoViewIfNeeded();
|
||||
await (await (await next.elementHandle()).contentFrame()).waitForFunction(() => document.documentElement.dataset.theme === 'dark');
|
||||
|
||||
@@ -26,7 +26,7 @@ const views = {
|
||||
const ids=views[name];
|
||||
geometry.cards.sort((a,b)=>ids.indexOf(a.id)-ids.indexOf(b.id));
|
||||
assert.deepEqual(geometry.cards.map(n => n.id), ids);
|
||||
assert.deepEqual(geometry.cards.map(n => n.number), ids.length === 6 ? ids.map((_,i)=>`Step ${i+1}`) : name === 'strategy-roadmap' ? ['Proposed M1–4','Proposed M5–6'] : ['First','If justified']);
|
||||
assert.deepEqual(geometry.cards.map(n => n.number), ids.length === 6 ? ids.map((_,i)=>`Step ${i+1}`) : name === 'strategy-roadmap' ? ['Stage 1','Stage 2'] : ['First','If justified']);
|
||||
assert.equal(geometry.edges.length,ids.length===6?6:1);
|
||||
if(ids.length===6) assert(geometry.edges.some(e=>e.id==='repeat'));
|
||||
for(const edge of geometry.edges) assert(edge.box.left>=0 && edge.box.right<=geometry.width+1 && edge.box.top>=0 && edge.box.bottom<=geometry.height+1, `clipped edge ${name} ${edge.id}`);
|
||||
@@ -63,7 +63,7 @@ const views = {
|
||||
if(await frame.locator('html').getAttribute('data-theme')!==theme) {
|
||||
await frame.locator('#btn-theme').focus(); await page.keyboard.press('Enter');
|
||||
}
|
||||
await page.waitForFunction(t=>document.documentElement.dataset.theme===t,theme);
|
||||
await page.waitForFunction(t=>document.documentElement?.dataset.theme===t,theme);
|
||||
const inline=await inspect(frame,name,width<1100);
|
||||
await frame.locator('#btn-preset').focus();await page.keyboard.press('Enter');
|
||||
await frame.locator('[data-preset-value="blueprint"]').focus();await page.keyboard.press('Enter');
|
||||
@@ -93,7 +93,7 @@ const views = {
|
||||
const close=panel.getByRole('button',{name:'Close full-screen diagram',exact:true});await close.waitFor({state:'visible'});
|
||||
const fullIframe=panel.locator('dialog iframe');
|
||||
const fullscreen=await (await fullIframe.elementHandle()).contentFrame();
|
||||
await fullscreen.waitForFunction(t=>document.documentElement.dataset.theme===t,theme);
|
||||
await fullscreen.waitForFunction(t=>document.documentElement?.dataset.theme===t,theme);
|
||||
const expanded=await inspect(fullscreen,name,width<1000);
|
||||
await page.screenshot({path:`${output}/${width}-${theme}-${name}-fullscreen.png`});
|
||||
await close.focus();await page.keyboard.press('Escape');
|
||||
|
||||
@@ -61,14 +61,14 @@ const fs = require('node:fs');
|
||||
assert.equal(response.status(), 200);
|
||||
assert.equal(await page.locator('h1').innerText(), 'Roadmap');
|
||||
const headings = page.locator('.strategy-content > h2');
|
||||
assert.deepEqual((await headings.allTextContents()).map(s => s.replace(/\u200b/g, '')), ['Six months, two investment decisions','Delivery first, replication only if earned','Keep one learning loop','Solo capacity and influence']);
|
||||
assert.deepEqual((await headings.allTextContents()).map(s => s.replace(/\u200b/g, '')), ['Two stages toward the long-term Target','Stage 1: Delivery first','Improve within each phase','Delivery in practice']);
|
||||
const text = await page.locator('.strategy-content').innerText();
|
||||
for (const marker of ['Humans direct, guide and review throughout', 'Delivery keeps improving', 'system-logic source', 'baseline', 'Target operating model']) assert(text.includes(marker), marker);
|
||||
assert(!text.includes('Supporting gate evidence and hold conditions\n\nThese are'));
|
||||
if (width < 700) await page.getByRole('button', {name:'Toggle navigation bar'}).click();
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
assert.deepEqual((await menu.allTextContents()).slice(0,2), ['Six-month strategy','Roadmap']);
|
||||
assert.deepEqual((await menu.allTextContents()).slice(0,2), ['Target','Roadmap']);
|
||||
if (width < 700) await page.getByRole('button', {name:'Close navigation bar'}).click();
|
||||
const panel = page.locator('.archify-panel--story').first();
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
@@ -125,7 +125,7 @@ const fs = require('node:fs');
|
||||
const [download] = await Promise.all([page.waitForEvent('download'), frame.locator('[data-format="svg"]').click()]);
|
||||
assert.equal(await download.failure(), null);
|
||||
await download.saveAs(`${output}/${width}.svg`);
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('Learn and test'));
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('Adopt skills'));
|
||||
assert(fs.readFileSync(`${output}/${width}.svg`, 'utf8').includes('eldorado-roadmap-typography'));
|
||||
for (const id of ['skills','autonomy']) {
|
||||
await frame.locator(`svg[role="img"] [data-node-id="${id}"]`).screenshot({path:`${output}/${width}-${id}-card.png`});
|
||||
|
||||
@@ -23,18 +23,16 @@ const fs = require('node:fs');
|
||||
if (width < 700) await page.getByRole('button', {name:'Toggle navigation bar'}).click();
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
assert.deepEqual(await menu.allTextContents(), ['Six-month strategy', 'Roadmap', 'One bounded experiment', 'Beyond six months']);
|
||||
assert.deepEqual(await menu.allTextContents(), ['Target', 'Roadmap', '6 Months Target', '6 Months Roadmap', 'Beyond 6 Months']);
|
||||
assert((await menu.nth(0).getAttribute('href')).endsWith('/strategy/target-operating-model/'));
|
||||
assert((await menu.nth(1).getAttribute('href')).endsWith('/strategy/roadmap/'));
|
||||
assert.equal(await menu.filter({hasText:/^Six-month strategy$/}).count(), 1);
|
||||
assert.equal(await menu.filter({hasText:/^Target$/}).count(), 1);
|
||||
await page.screenshot({path:`${output}/${width}-${route ? 'target' : 'landing'}-navigation.png`,fullPage:true,animations:'disabled'});
|
||||
await menu.nth(1).click();
|
||||
await page.waitForURL('**/strategy/roadmap/');
|
||||
await page.getByRole('heading', {level:1,name:'Roadmap',exact:true}).waitFor();
|
||||
await page.goBack({waitUntil:'domcontentloaded'});
|
||||
await page.waitForURL('**/strategy/target-operating-model/');
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const iframe = page.locator(`[data-diagram="strategy-target"] > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
const frame = await (await iframe.elementHandle()).contentFrame();
|
||||
|
||||
@@ -46,7 +46,7 @@ const fs = require('node:fs');
|
||||
await page.waitForURL(`${base}/eldorado-v1/documentation/strategy/measurement/supported-bundle-coverage/`);
|
||||
await page.getByRole('heading', {level:1, name:'Supported bundle coverage', exact:true}).waitFor();
|
||||
assert((await page.locator('article').innerText()).includes('Supported bundle coverage'));
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'One bounded experiment'}).getAttribute('href'), '/eldorado-v1/documentation/strategy/stage-01-skills-adoption/');
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'6 Months Roadmap'}).getAttribute('href'), '/eldorado-v1/documentation/strategy/six-months-roadmap/');
|
||||
assert((await page.locator('.breadcrumbs').innerText()).includes('Measurement'));
|
||||
await open();
|
||||
await menu.getByRole('link', {name:'Supported bundle coverage', exact:true}).waitFor({state:'visible'});
|
||||
|
||||
@@ -28,7 +28,7 @@ const fs = require('node:fs');
|
||||
const menu = page.locator('.theme-doc-sidebar-menu .menu__link').filter({visible:true});
|
||||
await menu.first().waitFor({state:'visible'});
|
||||
const metrics = JSON.parse(fs.readFileSync('research/ai-adoption/measurement-migration.json','utf8')).metrics;
|
||||
assert.deepEqual(await menu.allTextContents(), ['Six-month strategy','Roadmap','One bounded experiment','Measurement',...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example','Baseline','Governance','Quality','Adoption','Maintenance','Beyond six months']);
|
||||
assert.deepEqual(await menu.allTextContents(), ['Target','Roadmap','6 Months Target','6 Months Roadmap','Skills lifecycle reference','Measurement',...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example','Baseline','Governance','Quality','Adoption','Maintenance','Beyond 6 Months']);
|
||||
if (width < 700) await page.getByRole('button', {name:'Close navigation bar'}).click();
|
||||
const panel = page.locator('.archify-panel--story');
|
||||
const iframe = panel.locator(width > 700 ? '.story-desktop' : '.story-mobile');
|
||||
|
||||
@@ -9,7 +9,7 @@ const assert=require('node:assert/strict');
|
||||
for(const topic of ['six-months','measurement','baseline','governance','quality','adoption','maintenance','stage01','stage02']) for(const width of [1440,1024,390,320]) {
|
||||
console.log(`Checking ${topic} at ${width}px`);
|
||||
const page=await browser.newPage({viewport:{width,height:900},colorScheme:'light'});const errors=[];page.on('pageerror',e=>errors.push(e.message));
|
||||
const route=topic==='six-months'?'target-operating-model':topic==='stage01'?'stage-01-skills-adoption':topic==='stage02'?'stage-02-autonomous-agent':['measurement','baseline'].includes(topic)?topic:`skills-${topic}`;
|
||||
const route=topic==='six-months'?'six-months-roadmap':topic==='stage01'?'stage-01-skills-adoption':topic==='stage02'?'stage-02-autonomous-agent':['measurement','baseline'].includes(topic)?topic:`skills-${topic}`;
|
||||
assert.equal((await page.goto(`${base}/eldorado-v1/documentation/strategy/${route}/`,{waitUntil:'networkidle'})).status(),200);
|
||||
const panel=page.locator('.archify-panel--skills');assert.equal(await panel.count(),1);
|
||||
const iframe=panel.locator(width>1100?'.story-desktop':'.story-mobile');await iframe.scrollIntoViewIfNeeded();
|
||||
|
||||
@@ -6,14 +6,14 @@ const fs = require('node:fs');
|
||||
const output = `.cache/strategy-navigation-${process.argv[3] || 'local'}`;
|
||||
fs.mkdirSync(output, {recursive:true});
|
||||
const prefix = '/eldorado-v1/documentation/strategy/';
|
||||
const first = 'One bounded experiment';
|
||||
const second = 'Beyond six months';
|
||||
const topics = ['Measurement','Baseline','Governance','Quality','Adoption','Maintenance'];
|
||||
const first = '6 Months Roadmap';
|
||||
const second = 'Beyond 6 Months';
|
||||
const topics = ['Skills lifecycle reference','Measurement','Baseline','Governance','Quality','Adoption','Maintenance'];
|
||||
const metrics = JSON.parse(fs.readFileSync('research/ai-adoption/measurement-migration.json','utf8')).metrics;
|
||||
const childIds = [...metrics.map(m => m.docId),'measurement/collection-and-safeguards','measurement/synthetic-example'];
|
||||
const childTitles = [...metrics.map(m => m.title),'Collection and safeguards','Run the synthetic measurement example'];
|
||||
const ids = ['target-operating-model','roadmap','stage-01-skills-adoption','measurement',...childIds,'baseline','skills-governance','skills-quality','skills-adoption','skills-maintenance','stage-02-autonomous-agent'];
|
||||
const titles = ['First six months as AI Architect','Roadmap',first,'Measuring real output',...childTitles,'Baseline','Skills governance','Skills quality','Skills adoption','Skills maintenance',second];
|
||||
const ids = ['target-operating-model','roadmap','six-months-target','six-months-roadmap','stage-01-skills-adoption','measurement',...childIds,'baseline','skills-governance','skills-quality','skills-adoption','skills-maintenance','stage-02-autonomous-agent'];
|
||||
const titles = ['Target','Roadmap','6 Months Target',first,'Skills lifecycle reference','Measuring real output',...childTitles,'Baseline','Skills governance','Skills quality','Skills adoption','Skills maintenance',second];
|
||||
const browser = await chromium.launch({headless:true, executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE, args:['--no-sandbox']});
|
||||
const results = [];
|
||||
try {
|
||||
@@ -35,26 +35,26 @@ const fs = require('node:fs');
|
||||
assert.equal((await page.goto(`${base}${prefix}roadmap/`, {waitUntil:'networkidle'})).status(), 200);
|
||||
let menu = await openMenu();
|
||||
const visibleLabels = () => menu.locator('.menu__link').filter({visible:true}).allTextContents();
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap','6 Months Target',first,second]);
|
||||
const category = menu.locator('.theme-doc-sidebar-item-category').filter({has:page.getByRole('link', {name:first, exact:true})});
|
||||
const caret = category.locator(':scope > .menu__list-item-collapsible > button.menu__caret');
|
||||
await caret.click();
|
||||
await category.getByRole('link', {name:'Governance', exact:true}).waitFor({state:'visible'});
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,...topics,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap','6 Months Target',first,...topics,second]);
|
||||
assert.deepEqual(await category.locator('ul .menu__link').filter({visible:true}).allTextContents(), topics);
|
||||
const measurement = category.locator('.theme-doc-sidebar-item-category').filter({has:page.getByRole('link', {name:'Measurement', exact:true})});
|
||||
const reference = measurement.locator(':scope > .menu__list-item-collapsible > button.menu__caret');
|
||||
await reference.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await category.getByRole('link', {name:'Validated task success', exact:true}).waitFor({state:'visible'});
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,topics[0],...childTitles,...topics.slice(1),second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap','6 Months Target',first,...topics.slice(0,2),...childTitles,...topics.slice(2),second]);
|
||||
await reference.click();
|
||||
await page.screenshot({path:`${output}/${width}-expanded.png`, animations:'disabled'});
|
||||
await caret.click();
|
||||
await category.getByRole('link', {name:'Governance', exact:true}).waitFor({state:'hidden'});
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,second]);
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap','6 Months Target',first,second]);
|
||||
await menu.getByRole('link', {name:first, exact:true}).click();
|
||||
await page.waitForURL(`${base}${prefix}stage-01-skills-adoption/`);
|
||||
await page.waitForURL(`${base}${prefix}six-months-roadmap/`);
|
||||
await page.getByRole('heading', {level:1, name:first, exact:true}).waitFor();
|
||||
assert.equal(await page.locator('h1').innerText(), first);
|
||||
assert((await page.locator('article').innerText()).includes('Delivery first'));
|
||||
@@ -71,11 +71,11 @@ const fs = require('node:fs');
|
||||
else assert.equal(await prev.count(), 0);
|
||||
if (index < ids.length-1) assert.equal(await next.getAttribute('href'), `${prefix}${id === 'measurement' ? 'baseline' : ids[index+1]}/`);
|
||||
else assert.equal(await next.count(), 0);
|
||||
if (index >= 3 && index < ids.length - 1) {
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:first}).getAttribute('href'), `${prefix}stage-01-skills-adoption/`);
|
||||
if (index >= 4 && index < ids.length - 1) {
|
||||
assert.equal(await page.locator('.breadcrumbs a').filter({hasText:first}).getAttribute('href'), `${prefix}six-months-roadmap/`);
|
||||
menu = await openMenu();
|
||||
const expectedTopics = id === 'measurement' || id.startsWith('measurement/') ? [topics[0],...childTitles,...topics.slice(1)] : topics;
|
||||
assert.deepEqual(await visibleLabels(), ['Six-month strategy','Roadmap',first,...expectedTopics,second]);
|
||||
const expectedTopics = id === 'measurement' || id.startsWith('measurement/') ? [...topics.slice(0,2),...childTitles,...topics.slice(2)] : topics;
|
||||
assert.deepEqual(await visibleLabels(), ['Target','Roadmap','6 Months Target',first,...expectedTopics,second]);
|
||||
if (id.startsWith('measurement/')) assert.equal(await page.locator('.breadcrumbs a').filter({hasText:'Measurement'}).getAttribute('href'), `${prefix}measurement/`);
|
||||
await closeMenu();
|
||||
}
|
||||
|
||||
@@ -132,8 +132,6 @@ function inspectTypography({mobile}) {
|
||||
const page = await browser.newPage({viewport:{width,height:1000}});
|
||||
await page.goto(`${base}/eldorado-v1/documentation/strategy/target-operating-model/`,{waitUntil:'networkidle'});
|
||||
await page.addStyleTag({content:'html {scroll-behavior:auto !important;}'});
|
||||
await page.getByText('Conditional long-term Target operating model — not the six-month promise',{exact:true}).focus();
|
||||
await page.keyboard.press('Enter');
|
||||
const panel = page.locator('[data-diagram="strategy-target"]');
|
||||
const iframe = panel.locator(`:scope > .story-${width > 700 ? 'desktop' : 'mobile'}`);
|
||||
await iframe.scrollIntoViewIfNeeded();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {mkdir,copyFile,writeFile} from 'node:fs/promises';
|
||||
import {mkdir,copyFile,writeFile,readFile} from 'node:fs/promises';
|
||||
import {createHash} from 'node:crypto';
|
||||
import {slides} from '../presentations/less-prompting-more-shipping/slides.mjs';
|
||||
const root='presentations/less-prompting-more-shipping';
|
||||
const out=`static/${root}`;
|
||||
@@ -13,5 +14,9 @@ await writeFile(`${out}/index.html`,`<!doctype html><html lang="en"><head><meta
|
||||
<div class="reveal deck"><div class="slides">${slides.map((s,i)=>`<section id="${s.id}" class="${s.kind}" data-timing="${s.minutes*60}" ${s.kind==='dark'?'data-background-color="#1f1f29"':''}><p class="eyebrow">ELDORADO / ${i===17?'DISCUSSION':i===18?'REFERENCE':'AI STRATEGY'}</p><${i?'h2':'h1'}>${s.title}</${i?'h2':'h1'}>${s.body}<aside class="notes"><p><strong>${s.minutes} minutes.</strong> ${esc(s.notes)}</p><p>Sources: ${esc(s.sources.join('; '))}.</p></aside></section>`).join('\n')}</div></div>
|
||||
<script src="./assets/reveal.js"></script><script src="./assets/notes.js"></script><script src="./runtime.js"></script></body></html>`);
|
||||
await copyFile(`${root}/runtime.js`,`${out}/runtime.js`);
|
||||
await writeFile(`${out}/source-map.json`,JSON.stringify({version:'1.0.0',strategyRevision:'fcaa84f3bf9058f4ede0a097d16d0e3571590a6b',assignment:'AI_Architect_Test_Task.pdf',talkMinutes:slides.slice(0,17).reduce((a,s)=>a+s.minutes,0),discussionMinutes:15,slides:slides.map(({id,title,minutes,sources},i)=>({number:i+1,id,title,minutes,sources}))},null,2));
|
||||
const sourceDocuments = await Promise.all([...new Set(slides.flatMap(s=>s.sources).filter(s=>!s.startsWith('PDF:')))].sort().map(async id=>{
|
||||
const path=`docs/strategy/${id==='measurement'?'measurement/index':id}.mdx`;
|
||||
return {id,path,route:`/strategy/${id}/`,sha256:createHash('sha256').update(await readFile(path)).digest('hex')};
|
||||
}));
|
||||
await writeFile(`${out}/source-map.json`,JSON.stringify({version:'1.0.1',strategyRevision:'same-build; exact source hashes below; deployed revision in ../../revision.txt',strategyOrigins:{longTerm:'88a43757762114a506f57ed4b44484306cae1aaa',assignment:'fcaa84f3bf9058f4ede0a097d16d0e3571590a6b',horizonCorrection:'1557813737941901572'},sourceDocuments,assignment:'AI_Architect_Test_Task.pdf',talkMinutes:slides.slice(0,17).reduce((a,s)=>a+s.minutes,0),discussionMinutes:15,slides:slides.map(({id,title,minutes,sources},i)=>({number:i+1,id,title,minutes,sources:[...new Set(sources)]}))},null,2));
|
||||
console.log(`Built ${slides.length} local Reveal.js slides at ${out}`);
|
||||
@@ -7,9 +7,9 @@ const coverage=JSON.parse(read('research/ai-adoption/strategy-coverage.json')).r
|
||||
|
||||
test('connected Strategy covers every canonical route and reader handoff',()=>{
|
||||
const files=readdirSync('docs/strategy',{recursive:true}).filter(p=>p.endsWith('.mdx')).map(p=>'docs/strategy/'+p).sort();
|
||||
assert.equal(coverage.length,28);
|
||||
assert.equal(coverage.length,30);
|
||||
assert.deepEqual(coverage.map(r=>r.source).sort(),files);
|
||||
assert.equal(new Set(coverage.map(r=>r.route)).size,28);
|
||||
assert.equal(new Set(coverage.map(r=>r.route)).size,30);
|
||||
for(const r of coverage){
|
||||
for(const k of ['question','inputs','action_or_decision','output','next_or_feedback','review'])assert(r[k],`${r.source}: ${k}`);
|
||||
const page=read(r.source);assert(!/roadmap gates|Evidence-gated phases/.test(page),r.source);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {readFileSync} from 'node:fs';
|
||||
import {createHash} from 'node:crypto';
|
||||
import {execFileSync} from 'node:child_process';
|
||||
import {slides} from '../presentations/less-prompting-more-shipping/slides.mjs';
|
||||
const read=p=>readFileSync(p,'utf8');
|
||||
@@ -24,4 +25,11 @@ test('build emits local pinned Reveal assets, stable IDs and no production CDN',
|
||||
assert.match(read(`${dir}/runtime.js`),/hash:!embedded/);
|
||||
assert.equal(JSON.parse(read('package.json')).dependencies['reveal.js'],'5.2.1');
|
||||
assert.match(read('src/components/PresentationEmbed/index.tsx'),/Open presentation/);
|
||||
const map=JSON.parse(read(`${dir}/source-map.json`));
|
||||
assert.equal(map.version,'1.0.1');
|
||||
assert.match(map.strategyRevision,/same-build/);
|
||||
for(const doc of map.sourceDocuments) assert.equal(doc.sha256,createHash('sha256').update(read(doc.path)).digest('hex'),doc.path);
|
||||
for(const id of ['target-operating-model','roadmap','six-months-target','six-months-roadmap','stage-02-autonomous-agent']) assert(map.sourceDocuments.some(d=>d.id===id),id);
|
||||
assert(slides.find(s=>s.id==='beyond').notes.includes('long-term destination remains human-directed'));
|
||||
for(const id of ['months-one-two','months-three-four','months-five-six','capacity','experiment','inconclusive','stop']) assert(slides.find(s=>s.id===id).sources.includes('six-months-roadmap'),id);
|
||||
});
|
||||
@@ -30,7 +30,7 @@ export function roadmapViewer(html, spec) {
|
||||
return `<text x="${x+24}" y="${y+top}" font-size="${size}" class="${cls}" ${attrs}>${lines.map((line,i) => `<tspan x="${x+24}" dy="${i ? 34 : 0}">${escape(line)}</tspan>`).join('')}</text>`;
|
||||
};
|
||||
if (!node.sublabel || node.tag || /Output:|Exit:|\n/.test(node.sublabel)) throw new Error(`Roadmap content contract drift: ${node.id}`);
|
||||
const number = spec.nodes.length === 6 ? `Step ${index+1}` : spec.nodes[0].id === 'skills' ? ['Proposed M1–4','Proposed M5–6'][index] : index === 0 ? 'First' : 'If justified';
|
||||
const number = spec.nodes.length === 6 ? `Step ${index+1}` : spec.nodes[0].id === 'skills' ? ['Stage 1','Stage 2'][index] : index === 0 ? 'First' : 'If justified';
|
||||
const content = text(number, 40, 26, 't-primary', 'data-stage-number="" font-weight="700"')
|
||||
+ text(node.label, 88, 30, 't-primary', 'data-node-label="" font-weight="700"')
|
||||
+ text(node.sublabel, 160, 26, 't-muted');
|
||||
|
||||
@@ -12,8 +12,8 @@ test('Roadmap has three visual levels and preserves human direction and Delivery
|
||||
const page = read('docs/strategy/roadmap.mdx');
|
||||
const visible = page.split('<details>')[0];
|
||||
assert.deepEqual([...visible.matchAll(/<ArchifyDiagram name="([^"]+)"/g)].map(m => m[1]), Object.keys(views));
|
||||
assert.deepEqual([...visible.matchAll(/^## (.+)$/gm)].map(m => m[1]), ['Six months, two investment decisions', 'Delivery first, replication only if earned', 'Keep one learning loop', 'Solo capacity and influence']);
|
||||
for (const marker of ['Humans direct, guide and review throughout', 'current', 'AI-assisted practice', 'One active live pilot at a time', 'Month 1', 'Month 2', 'Month 3', 'Month 4', 'Month 5', 'Month 6', 'Delivery keeps improving', 'what skills exist, how they relate, when they are used and how they work together', 'codebase structure', 'existing principles', 'system-logic source', 'tests', 'builds and packaging', 'deployments', 'retain/change/hold/stop', './measurement/index.mdx', './target-operating-model.mdx']) assert(visible.includes(marker), marker);
|
||||
assert.deepEqual([...visible.matchAll(/^## (.+)$/gm)].map(m => m[1]), ['Two stages toward the long-term Target', 'Stage 1: Delivery first', 'Improve within each phase', 'Delivery in practice']);
|
||||
for (const marker of ['Humans direct, guide and review throughout', 'standardizes skills', 'foundation for Stage 2', 'future Autonomous Agent', 'not deployed autonomy', 'order is not yet decided', 'Delivery keeps improving', 'not as six global roadmap stages', 'what skills exist, how they relate, when they are used and how they work together', 'codebase structure', 'existing principles', 'system-logic source', 'tests', 'builds and packaging', 'deployments', 'practices, tooling, controls and problems', 'metrics/KPIs and a baseline', 'friction and feedback', './measurement/index.mdx', './target-operating-model.mdx']) assert(visible.includes(marker), marker);
|
||||
for (const marker of ['revocation','exact-artifact approvals','idempotency','human takeover','sensitive decisions','security findings','reproducible baseline']) assert(page.includes(marker), marker);
|
||||
assert(!/## [1-5]\.|Prepare foundations|Sustain and improve/.test(page));
|
||||
});
|
||||
|
||||
@@ -4,21 +4,15 @@ 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 assignment and retains autonomy only as a conditional reference', () => {
|
||||
assert.match(read('sidebars/strategy.ts'), /strategySidebar:\s*\[\s*'target-operating-model',\s*'roadmap'/);
|
||||
assert.match(read('docs/strategy/target-operating-model.mdx'), /^sidebar_label: Six-month strategy$/m);
|
||||
for (const id of ['target-operating-model']) {
|
||||
const page = read(`docs/strategy/${id}.mdx`);
|
||||
const primary = page.split('<details>')[0];
|
||||
assert(primary.includes('name="strategy-six-months"'));
|
||||
assert(!primary.includes('name="strategy-target"'));
|
||||
assert(page.includes('Conditional long-term Target operating model'));
|
||||
assert(page.includes('Scope → Architecture → UI/UX → Planning → Delivery → UAT → Security → Releases → Scope'));
|
||||
assert(page.includes('human-controlled AI Agent'));
|
||||
assert(!/code[ -]agent/i.test(page));
|
||||
assert(primary.includes('Proposed strategy'));
|
||||
assert(!/only routes|People authorize|independent gates protect release/.test(primary));
|
||||
}
|
||||
test('Strategy opens at the long-term Target and separates the six-month contribution', () => {
|
||||
const page=read('docs/strategy/target-operating-model.mdx');
|
||||
const primary=page.split('<details>')[0];
|
||||
assert.match(page, /^title: Target$/m);
|
||||
assert.match(page, /^sidebar_label: Target$/m);
|
||||
assert(primary.includes('name="strategy-target"'));
|
||||
assert(!primary.includes('name="strategy-six-months"'));
|
||||
for(const marker of ['not a six-month commitment or present authorization','Scope → Architecture → UI/UX → Planning → Delivery → UAT → Security → Releases → Scope','human-controlled AI Agent','Humans direct, guide and review','./six-months-target.mdx','./six-months-roadmap.mdx']) assert(primary.includes(marker),marker);
|
||||
assert(!page.includes('conditional long-term option'));
|
||||
});
|
||||
|
||||
test('both target diagrams have eight stages, eight governed phases and eight human-controlled contributors', () => {
|
||||
|
||||
@@ -10,10 +10,11 @@ test('Strategy has Target, Roadmap, a linked Skills Adoption category and Autono
|
||||
const sandbox = {exports:{}};
|
||||
runInNewContext(compiled, sandbox);
|
||||
const sidebar = JSON.parse(JSON.stringify(sandbox.exports.default.strategySidebar));
|
||||
assert.deepEqual(sidebar, ['target-operating-model', 'roadmap', {
|
||||
type:'category', label:'One bounded experiment',
|
||||
link:{type:'doc', id:'stage-01-skills-adoption'}, collapsed:true,
|
||||
assert.deepEqual(sidebar, ['target-operating-model', 'roadmap', 'six-months-target', {
|
||||
type:'category', label:'6 Months Roadmap',
|
||||
link:{type:'doc', id:'six-months-roadmap'}, collapsed:true,
|
||||
items:[
|
||||
'stage-01-skills-adoption',
|
||||
{type:'category', label:'Measurement', collapsed:true, link:{type:'doc', id:'measurement/index'}, items:[
|
||||
...JSON.parse(read('research/ai-adoption/measurement-migration.json')).metrics.map(m => m.docId),
|
||||
'measurement/collection-and-safeguards','measurement/synthetic-example',
|
||||
@@ -26,7 +27,7 @@ test('Strategy has Target, Roadmap, a linked Skills Adoption category and Autono
|
||||
|
||||
],
|
||||
}, 'stage-02-autonomous-agent']);
|
||||
assert.match(read('docs/strategy/target-operating-model.mdx'), /^sidebar_label: Six-month strategy$/m);
|
||||
assert.match(read('docs/strategy/target-operating-model.mdx'), /^sidebar_label: Target$/m);
|
||||
assert.match(read('docusaurus.config.ts'), /type: 'docSidebar', docsPluginId: 'strategy', sidebarId: 'strategySidebar', label: 'Strategy'/);
|
||||
});
|
||||
|
||||
@@ -34,8 +35,8 @@ test('stage overviews explain the foundation and future without replacing topic
|
||||
const first = read('docs/strategy/stage-01-skills-adoption.mdx');
|
||||
const second = read('docs/strategy/stage-02-autonomous-agent.mdx');
|
||||
for (const [id, title, page] of [
|
||||
['stage-01-skills-adoption', 'One bounded experiment', first],
|
||||
['stage-02-autonomous-agent', 'Beyond six months', second],
|
||||
['stage-01-skills-adoption', 'Skills lifecycle reference', first],
|
||||
['stage-02-autonomous-agent', 'Beyond 6 Months', second],
|
||||
]) {
|
||||
assert(page.includes(`id: ${id}\ntitle: ${title}`));
|
||||
for (const link of ['./roadmap.mdx', './target-operating-model.mdx']) assert(page.includes(link));
|
||||
|
||||
@@ -6,7 +6,7 @@ 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());
|
||||
[...model.pages.filter(p => p.id !== 'measurement').map(({id}) => `${id}.mdx`), 'stage-01-skills-adoption.mdx', 'stage-02-autonomous-agent.mdx', 'baseline.mdx', 'six-months-target.mdx', 'six-months-roadmap.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}`));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Caption the retained optional target without changing its native topology.
|
||||
// Caption the long-term target without changing its native topology.
|
||||
// Text lives inside the SVG so standalone exports retain proposal/line semantics.
|
||||
export function targetCaption(html) {
|
||||
const roots = [...html.matchAll(/<svg\b[^>]*role="img"[^>]*>/g)];
|
||||
@@ -8,7 +8,7 @@ export function targetCaption(html) {
|
||||
if (!match) throw new Error('Target caption requires viewBox');
|
||||
const [x,y,w,h] = match[1].trim().split(/\s+/).map(Number);
|
||||
const size = Math.min(26, w / 30);
|
||||
const lines = ['Proposed optional target — not a six-month commitment',
|
||||
const lines = ['Long-term Target — not a six-month commitment',
|
||||
'Solid: lifecycle · Dotted: execution / governance', 'Dashed: human-controlled contributions'];
|
||||
const extra = size * 5;
|
||||
const caption = `<g id="eldorado-target-caption" aria-label="Proposed target legend">${lines.map((line,i) => `<text x="${x+20}" y="${y+h+size*(1.2+i*1.3)}" font-family="Arial, sans-serif" font-size="${size}" style="font-size:${size}px!important" class="t-primary">${line}</text>`).join('')}</g>`;
|
||||
|
||||
+5
-3
@@ -27,15 +27,17 @@ if (process.argv.includes('--build')) {
|
||||
assert(redirect.includes('/eldorado-v1/documentation/strategy/target-operating-model/'));
|
||||
assert(redirect.includes('window.location.href') && redirect.includes('http-equiv="refresh"') && !redirect.includes('archify-panel'), 'Landing must redirect, not duplicate Target');
|
||||
const strategyPages = [...model.pages,
|
||||
{id:'stage-01-skills-adoption', title:'One bounded experiment'},
|
||||
{id:'six-months-target', title:'6 Months Target'},
|
||||
{id:'six-months-roadmap', title:'6 Months Roadmap'},
|
||||
{id:'stage-01-skills-adoption', title:'Skills lifecycle reference'},
|
||||
{id:'baseline', title:'Baseline'},
|
||||
{id:'stage-02-autonomous-agent', title:'Beyond six months'},
|
||||
{id:'stage-02-autonomous-agent', title:'Beyond 6 Months'},
|
||||
];
|
||||
for (const {id, title} of strategyPages) {
|
||||
const route = `strategy/${id === 'index' ? '' : `${id}/`}index.html`;
|
||||
const page = read(join('build',route));
|
||||
assert(page.includes(title), route);
|
||||
if (!id.startsWith('stage-')) assert(page.includes('Target operating model'), route);
|
||||
if (!id.startsWith('stage-') && !id.startsWith('six-months-')) assert(page.includes('Target operating model'), route);
|
||||
assert(indexes.includes(title), `Missing indexed Strategy page: ${id}`);
|
||||
for (const match of page.matchAll(/href="(\/eldorado-v1\/documentation\/[^"?#]*)/g)) {
|
||||
const local = decodeURIComponent(match[1].replace('/eldorado-v1/documentation/',''));
|
||||
|
||||
Reference in new issue
Block a user