Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
499049eff3 | ||
|
|
46bb8b2b48 |
No files matched your search
@@ -21,7 +21,7 @@ export const slides = [
|
||||
"id": "starting-point",
|
||||
"title": "We are not starting from “no AI”.",
|
||||
"minutes": 2,
|
||||
"body": "<div class=\"facts\"><div><strong>≈80 → ≈100</strong><span>engineers, by year end</span></div><div><strong>>10</strong><span>teams</span></div><div><strong>Already using AI</strong><span>uneven depth and quality</span></div></div><div class=\"contrast\"><p><b>Assignment facts</b><br>Solo architect → CTO<br>No formal authority over teams</p><p><b>Unknown until discovery</b><br>Stack, tools, process, baselines<br>Capacity and actual bottlenecks</p></div>",
|
||||
"body": "<div class=\"facts\"><div><strong>≈80 → ≈100</strong><span>engineers, by year end</span></div><div><strong>>10</strong><span>teams</span></div><div><strong>Already using AI</strong><span>uneven depth and quality</span></div></div><div class=\"contrast\"><p>Solo architect → CTO<br>No formal authority over teams</p><p>Stack, tools, process, baselines<br>Capacity and actual bottlenecks</p></div>",
|
||||
"notes": "These headcount and usage facts are from the assignment, not independent research. The comparison is existing AI-assisted practice, never an invented no-AI baseline. Delivery is a starting hypothesis, not a finding. The documented departmental model is not evidence of actual assignment staffing. Ask about stack and tool/data restrictions in discovery; do not assume familiar clients are in use. Every timeline and proposed allocation in this deck remains subject to agreement.",
|
||||
"sources": [
|
||||
"PDF: Context; question 1; final assumptions instruction",
|
||||
@@ -63,7 +63,7 @@ export const slides = [
|
||||
"id": "contributors",
|
||||
"title": "People contribute throughout the cycle.",
|
||||
"minutes": 1,
|
||||
"body": `<p class="diagram-intro">Eight separate AI Agents, each human-controlled.</p>` + contributionsFigure + `<div class="rail">Dashed ⇢ contribution from outside the cycle.</div>`,
|
||||
"body": `<p class="diagram-intro">Eight separate AI Agents, each human-controlled.</p>` + contributionsFigure + `<p class="small">AI Agent = Claude, Cline, ChatGPT or a similar tool, used under human control.</p><div class="rail">Dashed ⇢ contribution from outside the cycle.</div>`,
|
||||
"notes": "Keep the previous cycle in mind: these eight pairs are its contribution layer, not a second lifecycle or eight central coordinators. Each separate human-controlled AI Agent contributes to its corresponding phase from outside the cycle. The central autonomous agent remains connected to every phase, executing and governing under human direction. Splitting the original topology into two presentation-sized views preserves all eight lifecycle arrows, eight governance spokes and eight contribution arrows without miniaturizing seventeen nodes. Laptop client choice and adapters are implementation options, not a promise of installed support. Human review, product and risk decisions remain necessary.",
|
||||
"sources": [
|
||||
"target-operating-model"
|
||||
@@ -90,7 +90,7 @@ export const slides = [
|
||||
"id": "learning-loop",
|
||||
"title": "Connected skills. A repeating learning loop.",
|
||||
"minutes": 2,
|
||||
"body": "<div class=\"learning-loop\"><span>Understand work</span><i>→</i><span>Measure + baseline</span><i>→</i><span>Engineer topology</span><i>↓</i><span>Reassess</span><i>←</i><span>Collect results</span><i>←</i><span>Use in real work</span></div><div class=\"rail\">↻ Repeat within each phase. Not six global rollout stages.</div><p class=\"statement\">Triggers → skills → handoffs → acceptance.</p><p class=\"small\">Relationships and cooperation—not merely a catalogue.</p>",
|
||||
"body": "<div class=\"learning-loop\"><span>Understand work</span><i>→</i><span>Measure + baseline</span><i>↓</i><span>Engineer topology</span><i>→</i><span>Use in real work</span><i>↓</i><span>Collect results</span><i>→</i><span>Reassess</span></div><div class=\"rail\">↻ Repeat within each phase. Not six global rollout stages.</div><p class=\"statement\">Triggers → skills → handoffs → acceptance.</p><p class=\"small\">Relationships and cooperation—not merely a catalogue.</p>",
|
||||
"notes": "Within every adopted phase repeat the loop: understand the current situation, select relevant metrics and baseline, engineer connected skills, use them in real work, collect outcomes/friction/feedback, then reassess and repeat. Topology defines what exists, how skills relate, when each triggers and how they cooperate. In Delivery trace codebase principles through system logic, tests, builds/packaging and deployment before designing that topology. A code-change skill may hand an exact patch and regression evidence to independent review; its trigger is an eligible change, not an ambient right to act. Governance and Measurement support the whole loop. Qualify revisions before use, and reconsider simpler interventions whenever the evidence says they fit better.",
|
||||
"sources": [
|
||||
"roadmap",
|
||||
|
||||
@@ -85,15 +85,24 @@ html.print-pdf .toolbar{display:none}html.print-pdf .reveal.deck{top:0;height:10
|
||||
.deck .journey small,.deck .horizon small{display:block;font-size:17px;color:#805b00;font-weight:900;letter-spacing:.04em;margin-bottom:14px}
|
||||
.deck .journey b{font-size:31px;display:block;margin-bottom:20px}
|
||||
.deck .journey span{font-size:25px}.deck .journey i{font-style:normal}
|
||||
.deck .learning-loop{display:grid;grid-template-columns:1fr 40px 1fr 40px 1fr;align-items:center;gap:12px;margin:32px 0 22px}
|
||||
.deck .learning-loop span{border:2px solid #14131a;padding:22px 10px;font-size:27px;text-align:center}
|
||||
.deck .learning-loop i{font-style:normal;text-align:center}.deck .learning-loop i:nth-child(6){grid-column:5}
|
||||
.deck .learning-loop{display:grid;grid-template-columns:1fr 28px 1fr 28px 1fr 28px 1fr;align-items:center;gap:0 8px;margin:22px 0}
|
||||
.deck #learning-loop .statement{margin:16px 0 0}.deck #learning-loop .small{margin-top:12px}
|
||||
.deck .learning-loop span{border:2px solid #14131a;padding:8px;font-size:27px;text-align:center}
|
||||
.deck .learning-loop i{font-style:normal;text-align:center;line-height:1}
|
||||
.deck .learning-loop>:nth-child(1){grid-area:1/1}.deck .learning-loop>:nth-child(2){grid-area:1/2}.deck .learning-loop>:nth-child(3){grid-area:1/3}
|
||||
.deck .learning-loop>:nth-child(4){grid-area:2/3}
|
||||
.deck .learning-loop>:nth-child(5){grid-area:3/3}.deck .learning-loop>:nth-child(6){grid-area:3/4}.deck .learning-loop>:nth-child(7){grid-area:3/5}
|
||||
.deck .learning-loop>:nth-child(8){grid-area:4/5}
|
||||
.deck .learning-loop>:nth-child(9){grid-area:5/5}.deck .learning-loop>:nth-child(10){grid-area:5/6}.deck .learning-loop>:nth-child(11){grid-area:5/7}
|
||||
.deck .horizon{margin:35px 0;border-left:5px solid #ffc950;padding-left:25px}
|
||||
.deck .horizon b{font-size:32px;display:block}.deck .horizon .near{background:#e9e9ec;padding:22px;margin-top:28px}
|
||||
.deck .horizon span{display:block;font-size:25px;margin-top:14px}
|
||||
.portrait .deck .target-cycle.wide{display:none}.portrait .deck .target-cycle.phone{display:block;height:540px}
|
||||
.portrait .deck #target h2{font-size:40px}
|
||||
.portrait .deck #target .small{font-size:24px;margin-top:20px}
|
||||
.portrait .deck #contributors .small{margin:12px 0}
|
||||
.portrait .deck #contributors .contribution-grid{gap:6px;margin:14px 0}
|
||||
.portrait .deck #contributors .contribution-grid>div{padding:4px 8px}
|
||||
.portrait .deck .contribution-grid{grid-template-columns:1fr 1fr;gap:12px;margin:24px 0}
|
||||
.portrait .deck .contribution-grid>div{padding:8px;flex-direction:column;justify-content:center;gap:0;font-size:27px}
|
||||
.portrait .deck .contribution-grid i{transform:rotate(90deg)}.portrait .deck .contribution-grid b{text-align:center}
|
||||
@@ -101,6 +110,6 @@ html.print-pdf .toolbar{display:none}html.print-pdf .reveal.deck{top:0;height:10
|
||||
.portrait .deck .journey>div{width:100%;padding:12px 0;border-top-width:4px}
|
||||
.portrait .deck .journey b{font-size:29px;margin-bottom:8px}.portrait .deck .journey small{margin-bottom:8px}
|
||||
.portrait .deck .journey i{transform:rotate(90deg);line-height:1}
|
||||
.portrait .deck .learning-loop{grid-template-columns:1fr 28px 1fr 28px 1fr;gap:6px;margin:30px 0}
|
||||
.portrait .deck .learning-loop span{font-size:24px;padding:20px 4px}
|
||||
.portrait .deck .learning-loop{grid-template-columns:1fr 16px 1fr 16px 1fr 16px 1fr;gap:0 3px;margin:30px 0}
|
||||
.portrait .deck .learning-loop span{font-size:24px;padding:14px 2px}
|
||||
.portrait .deck .horizon b{font-size:32px}
|
||||
@@ -1,4 +1,5 @@
|
||||
const {chromium}=require('playwright');
|
||||
const staircaseFits=require('./presentation-staircase.cjs');
|
||||
const assert=require('node:assert/strict');const fs=require('node:fs');
|
||||
(async()=>{
|
||||
const base=process.argv[2]||'http://127.0.0.1:43853';const root=base+'/eldorado-v1/documentation/';
|
||||
@@ -22,7 +23,8 @@ const assert=require('node:assert/strict');const fs=require('node:fs');
|
||||
for(let i=0;i<23;i++){
|
||||
assert.equal(await f.evaluate(()=>Reveal.getIndices().h),i);visited.push(await f.evaluate(()=>Reveal.getCurrentSlide().id));
|
||||
const bad=await f.evaluate(()=>{const r=Reveal.getCurrentSlide().getBoundingClientRect();return [...Reveal.getCurrentSlide().querySelectorAll('svg,text,.journey,.learning-loop,.contribution-grid,h1,h2,p,li,table,.flow,.roles,.timeline')].filter(e=>!e.closest('.notes')&&e.getBoundingClientRect().width>0).filter(e=>{const b=e.getBoundingClientRect();return b.bottom>r.bottom+1||b.right>r.right+1||b.left<r.left-1}).map(e=>e.textContent)});assert.deepEqual(bad,[]);
|
||||
if(i===4)assert(await f.evaluate(()=>[...document.querySelectorAll('#contributors .contribution-grid>div')].every(e=>{const a=e.querySelector('span').getBoundingClientRect(), arrow=e.querySelector('i').getBoundingClientRect(), b=e.querySelector('b').getBoundingClientRect();return a.bottom<=arrow.top+2&&arrow.bottom<=b.top+2&&Math.abs((a.left+a.right-b.left-b.right)/2)<2&&getComputedStyle(e.querySelector('i')).transform==='matrix(0, 1, -1, 0, 0, 0)'})),'contribution arrows must point down to their own phase');
|
||||
if(i===6)assert(await f.evaluate(staircaseFits),'staircase aligns each arrow with its intended steps');
|
||||
if(i===4)assert(await f.evaluate(()=>[...document.querySelectorAll('#contributors .contribution-grid>div')].every(e=>{const a=e.querySelector('span').getBoundingClientRect(), arrow=e.querySelector('i').getBoundingClientRect(), b=e.querySelector('b').getBoundingClientRect();return a.bottom<=arrow.top+2&&arrow.bottom<=b.top+2&&Math.abs((a.left+a.right-b.left-b.right)/2)<2&&getComputedStyle(e.querySelector('i')).transform==='matrix(0, 1, -1, 0, 0, 0)'})),'contribution arrows must point down to their own phase');
|
||||
await iframe.screenshot({path:`${out}/${viewport.width}-${i+1}.png`});
|
||||
if(i<22)await p.keyboard.press('ArrowRight');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Browser-side geometry contract, shared by standalone and embedded acceptance.
|
||||
module.exports = function staircaseFits() {
|
||||
const els=[...document.querySelectorAll('#learning-loop .learning-loop>*')];
|
||||
const b=els.map(e=>e.getBoundingClientRect());
|
||||
const center=r=>({x:(r.left+r.right)/2,y:(r.top+r.bottom)/2});
|
||||
const close=(a,b)=>Math.abs(a-b)<2;
|
||||
return [[0,1,2],[4,5,6],[8,9,10]].every(([a,arrow,c])=>
|
||||
close(center(b[a]).y,center(b[c]).y)&&close(center(b[a]).y,center(b[arrow]).y)&&
|
||||
b[a].right<=b[arrow].left+2&&b[arrow].right<=b[c].left+2
|
||||
)&&[[2,3,4],[6,7,8]].every(([a,arrow,c])=>
|
||||
close(center(b[a]).x,center(b[c]).x)&&close(center(b[a]).x,center(b[arrow]).x)&&
|
||||
b[a].bottom<=b[arrow].top+2&&b[arrow].bottom<=b[c].top+2
|
||||
)&&els.filter(e=>e.tagName==='SPAN').every(e=>e.scrollWidth<=e.clientWidth+1);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
const {chromium}=require('playwright');
|
||||
const staircaseFits=require('./presentation-staircase.cjs');
|
||||
const fs=require('node:fs'); const assert=require('node:assert/strict');
|
||||
(async()=>{
|
||||
const base=process.argv[2]||'http://127.0.0.1:4179'; const root='/eldorado-v1/documentation/';const url=base+root+'presentations/less-prompting-more-shipping/';
|
||||
@@ -20,7 +21,8 @@ const fs=require('node:fs'); const assert=require('node:assert/strict');
|
||||
const slide=Reveal.getCurrentSlide(),r=slide.getBoundingClientRect();
|
||||
return [...slide.querySelectorAll('svg,text,.journey,.learning-loop,.contribution-grid,h1,h2,p,li,td,th,.rail,.gate,.facts,.flow,.roles,.timeline,.capacity,.measure-list,.contrast,.comparison,.choices,.ledger')].filter(e=>!e.closest('.notes')&&e.getBoundingClientRect().width>0).filter(e=>{const b=e.getBoundingClientRect();return b.bottom>r.bottom+1||b.right>r.right+1||b.left<r.left-1||b.top<r.top-1}).map(e=>e.textContent.slice(0,60));
|
||||
});
|
||||
if(i===4)assert(await page.evaluate(()=>[...document.querySelectorAll('#contributors .contribution-grid>div')].every(e=>{const a=e.querySelector('span').getBoundingClientRect(), arrow=e.querySelector('i').getBoundingClientRect(), b=e.querySelector('b').getBoundingClientRect();return a.bottom<=arrow.top+2&&arrow.bottom<=b.top+2&&Math.abs((a.left+a.right-b.left-b.right)/2)<2&&getComputedStyle(e.querySelector('i')).transform==='matrix(0, 1, -1, 0, 0, 0)'})),'contribution arrows must point down to their own phase');
|
||||
if(i===6)assert(await page.evaluate(staircaseFits),'staircase aligns each arrow with its intended steps');
|
||||
if(i===4)assert(await page.evaluate(()=>[...document.querySelectorAll('#contributors .contribution-grid>div')].every(e=>{const a=e.querySelector('span').getBoundingClientRect(), arrow=e.querySelector('i').getBoundingClientRect(), b=e.querySelector('b').getBoundingClientRect();return a.bottom<=arrow.top+2&&arrow.bottom<=b.top+2&&Math.abs((a.left+a.right-b.left-b.right)/2)<2&&getComputedStyle(e.querySelector('i')).transform==='matrix(0, 1, -1, 0, 0, 0)'})),'contribution arrows must point down to their own phase');
|
||||
bounds.push({slide:i+1,overflow:bad});
|
||||
await page.screenshot({path:`${out}/${viewport.width}-slide-${String(i+1).padStart(2,'0')}.png`});
|
||||
}
|
||||
|
||||
@@ -14,6 +14,26 @@ test('deck preserves assignment coverage, 35+15 timing and traceable notes',()=>
|
||||
for(const id of ['experiment']) assert.match(slides.find(s=>s.id===id).body,/fictional/i);
|
||||
assert.match(slides.find(s=>s.id==='qualification').notes,/separately authorizes/);
|
||||
});
|
||||
test('starting point keeps content without the two removed headings',()=>{
|
||||
const body=slides.find(s=>s.id==='starting-point').body;
|
||||
assert.doesNotMatch(body,/Assignment facts|Unknown until discovery/);
|
||||
for(const text of ['Solo architect → CTO','No formal authority over teams','Stack, tools, process, baselines','Capacity and actual bottlenecks'])assert(body.includes(text));
|
||||
assert.doesNotMatch(body,/<p><br>/);
|
||||
});
|
||||
test('contributors explains human-controlled AI tools below the diagram',()=>{
|
||||
const body=slides.find(s=>s.id==='contributors').body;
|
||||
const definition='AI Agent = Claude, Cline, ChatGPT or a similar tool, used under human control.';
|
||||
assert(body.includes(definition));
|
||||
assert(body.indexOf(definition)>body.indexOf('contribution-grid'));
|
||||
assert(body.includes('Dashed ⇢ contribution from outside the cycle.'));
|
||||
});
|
||||
test('learning loop staircase preserves the original semantic sequence',()=>{
|
||||
const body=slides.find(s=>s.id==='learning-loop').body;
|
||||
const loop=body.split('</div>')[0];
|
||||
assert.deepEqual([...loop.matchAll(/<span>(.*?)<\/span>/g)].map(m=>m[1]),['Understand work','Measure + baseline','Engineer topology','Use in real work','Collect results','Reassess']);
|
||||
assert.deepEqual([...loop.matchAll(/<i>(.*?)<\/i>/g)].map(m=>m[1]),['→','↓','→','↓','→']);
|
||||
assert(body.includes('↻ Repeat within each phase.'));
|
||||
});
|
||||
test('build emits local pinned Reveal assets, stable IDs and no production CDN',()=>{
|
||||
execFileSync(process.execPath,['scripts/build-presentations.mjs']);
|
||||
const dir='static/presentations/less-prompting-more-shipping'; const html=read(`${dir}/index.html`);
|
||||
|
||||
Reference in new issue
Block a user