From baf79e125b596f2da32d3c33e422418128f20c2a Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Mon, 5 Oct 2026 18:16:57 +0000 Subject: [PATCH] fix: make Target canonical and place Roadmap second --- docs/strategy/index.mdx | 56 ------------------------ docs/strategy/roadmap.mdx | 2 +- docs/strategy/target-operating-model.mdx | 24 ++++++++++ docusaurus.config.ts | 1 + package.json | 1 + pnpm-lock.yaml | 51 +++++++++++++++++++++ research/ai-adoption/strategy-model.json | 5 --- scripts/browser/inline-controls.cjs | 4 +- scripts/browser/sdlc-cycle.cjs | 15 ++++++- scripts/sdlc-cycle.test.mjs | 6 +-- scripts/strategy-navigation.test.mjs | 19 ++++++++ scripts/strategy.test.mjs | 6 +-- scripts/verify.mjs | 3 ++ sidebars/strategy.ts | 2 +- src/pages/index.tsx | 2 +- 15 files changed, 125 insertions(+), 72 deletions(-) delete mode 100644 docs/strategy/index.mdx create mode 100644 scripts/strategy-navigation.test.mjs diff --git a/docs/strategy/index.mdx b/docs/strategy/index.mdx deleted file mode 100644 index b0b19e7..0000000 --- a/docs/strategy/index.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: index -title: AI adoption strategy -description: An autonomous SDLC cycle directed, guided and reviewed by humans, supported by governed skills. -slug: / -hide_table_of_contents: true ---- - -import ArchifyDiagram from '@site/src/components/ArchifyDiagram'; - -
- -**TO-BE · Target operating model — not installed controls or company results.** - -## Autonomous SDLC, human direction - - - -An autonomous agent executes and governs every phase. Humans direct, guide and review it; a separate human-controlled code agent contributes to each phase from outside the cycle. - -**Solid arrows:** lifecycle · **Dotted spokes:** execution and governance · **Dashed arrows:** contributions. - -**Scope → Architecture → UI/UX → Planning → Delivery → UAT → Security → Releases → Scope** - -Releases returns to Scope and the cycle repeats indefinitely. Governed skills and measured outcomes support the path toward this target; they are not a substitute for it. - -
-Strategy rationale and reading map - -**TO-BE · Target operating model.** Introduction depends on the [roadmap gates](./roadmap.mdx); these pages do not describe installed controls or measured company results. - -### Govern skills first, expand authority only with evidence - -Eldorado's target is to make AI-assisted work dependable across the organization: useful guidance, clear human ownership, controlled execution and measurable outcomes. The first investment is a governed skills system, not an autonomous replacement for the organization. A skill packages reusable working knowledge, prerequisites and verification steps. It helps an agent perform a task; it does not grant permission or guarantee that the work is correct. - -The target combines an autonomous agent executing and governing the SDLC with humans directing, guiding and reviewing it. Developer choice on local laptops remains a supporting option: Copilot, Claude Code and Cline can receive reviewed portable skill content through qualified adapters. Repository, CI and release controls support execution; detailed approval policies remain implementation decisions, not new roles established by this strategy. - -The strategy describes the intended operating model and the evidence required to introduce it. It does not establish that these controls are installed, that every client is supported, or that AI has improved Eldorado's performance. The current reference is the documented six-department organization. Rollout begins by validating actual clients, responsibilities, data boundaries and available evidence. - -Success means accepted outcomes with maintained quality, controlled risk and understood total cost. Faster activity without reliable outcomes is not success. More skill invocations, generated lines or tool subscriptions are not productivity targets. People remain accountable for product, customer, financial and personnel decisions. - -## Navigate the strategy - -- [Target operating model](./target-operating-model.mdx) — The autonomous SDLC cycle, with human direction, guidance and review. -- [Skills governance](./skills-governance.mdx) — Contract, lifecycle, decision rights, adapters, locking, exceptions. -- [Skills quality](./skills-quality.mdx) — Risk tiers, independent evaluation, repeated trials, adversarial conformance. -- [Skills adoption](./skills-adoption.mdx) — Workflow-led coaching, client choice, feedback, manual path. -- [Measurement](./measurement.mdx) — Full KPI contracts, minimal events, illustrative calculations, privacy and limits. -- [Skills maintenance](./skills-maintenance.mdx) — Review, drift, deprecation, rollback and incident handling. -- [Roadmap](./roadmap.mdx) — Evidence-gated phases, no promised dates or budgets. - -
- -**Next:** [Explore the autonomous SDLC cycle →](./target-operating-model.mdx) - -
diff --git a/docs/strategy/roadmap.mdx b/docs/strategy/roadmap.mdx index f716174..2496ad7 100644 --- a/docs/strategy/roadmap.mdx +++ b/docs/strategy/roadmap.mdx @@ -70,6 +70,6 @@ There are no invented launch dates, budgets, staffing commitments or guaranteed -**Next:** [Return to the strategy destination →](./index.mdx) +**Next:** [Return to the strategy destination →](./target-operating-model.mdx) diff --git a/docs/strategy/target-operating-model.mdx b/docs/strategy/target-operating-model.mdx index 11836a9..d490cf7 100644 --- a/docs/strategy/target-operating-model.mdx +++ b/docs/strategy/target-operating-model.mdx @@ -138,6 +138,30 @@ See the existing [organization structure](/organization/structure/), [department +
+Strategy rationale and reading map + +### Govern skills first, expand authority only with evidence + +Eldorado's target is to make AI-assisted work dependable across the organization: useful guidance, clear human ownership, controlled execution and measurable outcomes. The first investment is a governed skills system, not an autonomous replacement for the organization. A skill packages reusable working knowledge, prerequisites and verification steps. It helps an agent perform a task; it does not grant permission or guarantee that the work is correct. + +The target combines an autonomous agent executing and governing the SDLC with humans directing, guiding and reviewing it. Developer choice on local laptops remains a supporting option: Copilot, Claude Code and Cline can receive reviewed portable skill content through qualified adapters. Repository, CI and release controls support execution; detailed approval policies remain implementation decisions, not new roles established by this strategy. + +The strategy describes the intended operating model and the evidence required to introduce it. It does not establish that these controls are installed, that every client is supported, or that AI has improved Eldorado's performance. The current reference is the documented six-department organization. Rollout begins by validating actual clients, responsibilities, data boundaries and available evidence. + +Success means accepted outcomes with maintained quality, controlled risk and understood total cost. Faster activity without reliable outcomes is not success. More skill invocations, generated lines or tool subscriptions are not productivity targets. People remain accountable for product, customer, financial and personnel decisions. + +### Navigate the strategy + +- [Roadmap](./roadmap.mdx) — Evidence-gated phases, no promised dates or budgets. +- [Skills governance](./skills-governance.mdx) — Contract, lifecycle, decision rights, adapters, locking, exceptions. +- [Skills quality](./skills-quality.mdx) — Risk tiers, independent evaluation, repeated trials, adversarial conformance. +- [Skills adoption](./skills-adoption.mdx) — Workflow-led coaching, client choice, feedback, manual path. +- [Measurement](./measurement.mdx) — Full KPI contracts, minimal events, illustrative calculations, privacy and limits. +- [Skills maintenance](./skills-maintenance.mdx) — Review, drift, deprecation, rollback and incident handling. + +
+ **Next:** [Decide who owns and approves each skill →](./skills-governance.mdx) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 27386bd..82db6d6 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -18,6 +18,7 @@ const config: Config = { theme: {customCss: './src/css/custom.css'}, } satisfies Preset.Options]], plugins: [ + ['@docusaurus/plugin-client-redirects', {redirects: [{from: '/strategy/', to: '/strategy/target-operating-model/'}]}], ['@docusaurus/plugin-content-docs', {id: 'organization', path: 'docs/organization', routeBasePath: 'organization', sidebarPath: './sidebars/organization.ts'}], ['@docusaurus/plugin-content-docs', {id: 'strategy', path: 'docs/strategy', routeBasePath: 'strategy', sidebarPath: './sidebars/strategy.ts'}], ['@docusaurus/plugin-content-docs', {id: 'contribution', path: 'docs/contribution', routeBasePath: 'contribution', sidebarPath: './sidebars/contribution.ts'}], diff --git a/package.json b/package.json index b7a51f7..f180dfc 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@docusaurus/core": "3.10.2", + "@docusaurus/plugin-client-redirects": "3.10.2", "@docusaurus/preset-classic": "3.10.2", "@docusaurus/theme-common": "3.10.2", "@easyops-cn/docusaurus-search-local": "0.55.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a668fe8..e96ff24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@docusaurus/core': specifier: 3.10.2 version: 3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(debug@4.4.3)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3) + '@docusaurus/plugin-client-redirects': + specifier: 3.10.2 + version: 3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3) '@docusaurus/preset-classic': specifier: 3.10.2 version: 3.10.2(@algolia/client-search@5.59.0)(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(search-insights@2.17.3)(typescript@5.9.3) @@ -1115,6 +1118,13 @@ packages: react: '*' react-dom: '*' + '@docusaurus/plugin-client-redirects@3.10.2': + resolution: {integrity: sha512-z5I5ttCXw+8y2gHVZvqAMmUw4Rb0ZzKA5eCPk87SfM/jCKOTvE24yDpPAwwipvug96ij7mOwEHXWw8G4LlWdGA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + '@docusaurus/plugin-content-blog@3.10.2': resolution: {integrity: sha512-0cbEnNKf0InmLkhj/+nVRmqEnWEoOE8Mh+2x1qOXI0qYpCnphq4RXknVJ8BvybKRXqYVvbmdMfiJSup+k4tm5w==} engines: {node: '>=20.0'} @@ -6784,6 +6794,47 @@ snapshots: - uglify-js - webpack-cli + '@docusaurus/plugin-client-redirects@3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3)': + dependencies: + '@docusaurus/core': 3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(debug@4.4.3)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3) + '@docusaurus/logger': 3.10.2 + '@docusaurus/utils': 3.10.2(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.28))(html-minifier-terser@7.2.0)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@docusaurus/utils-common': 3.10.2(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.28))(html-minifier-terser@7.2.0)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@docusaurus/utils-validation': 3.10.2(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + eta: 2.2.0 + fs-extra: 11.4.1 + lodash: 4.18.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@minify-html/node' + - '@napi-rs/image' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - bufferutil + - clean-css + - cssnano + - csso + - debug + - esbuild + - html-minifier-terser + - imagemin + - lightningcss + - postcss + - sharp + - supports-color + - svgo + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + '@docusaurus/plugin-content-blog@3.10.2(@docusaurus/plugin-content-docs@3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3)': dependencies: '@docusaurus/core': 3.10.2(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.1))(debug@4.4.3)(postcss@8.5.28)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.9.3) diff --git a/research/ai-adoption/strategy-model.json b/research/ai-adoption/strategy-model.json index 2403518..4d799eb 100644 --- a/research/ai-adoption/strategy-model.json +++ b/research/ai-adoption/strategy-model.json @@ -28,11 +28,6 @@ ] }, "pages": [ - { - "id": "index", - "title": "AI adoption strategy", - "purpose": "Govern skills first; outcomes before activity; explicit target status." - }, { "id": "target-operating-model", "title": "Target operating model", diff --git a/scripts/browser/inline-controls.cjs b/scripts/browser/inline-controls.cjs index 1bf33b0..5d4f2e6 100644 --- a/scripts/browser/inline-controls.cjs +++ b/scripts/browser/inline-controls.cjs @@ -125,8 +125,10 @@ const fs = require('node:fs'); await page.screenshot({path:`${output}/${width}.png`, fullPage:true}); await frame.locator('#btn-theme').click(); await theme('dark'); // Exercise keyboard navigation without racing the portal's smooth scroll. - await page.locator('.strategy-content a[href$="/strategy/target-operating-model/"]').filter({visible:true}).focus(); + await page.locator('.strategy-content a[href$="/strategy/skills-governance/"]').filter({visible:true}).focus(); await page.keyboard.press('Enter'); + await page.waitForURL('**/strategy/skills-governance/'); + await page.goBack({waitUntil:'domcontentloaded'}); await page.waitForURL('**/strategy/target-operating-model/'); await page.getByRole('heading', {name:'Target operating model', exact:true, level:1}).waitFor(); const next = page.locator(`.archify-panel--story[data-diagram="strategy-target"] > .story-${width > 700 ? 'desktop' : 'mobile'}`); diff --git a/scripts/browser/sdlc-cycle.cjs b/scripts/browser/sdlc-cycle.cjs index e95691c..4f1a130 100644 --- a/scripts/browser/sdlc-cycle.cjs +++ b/scripts/browser/sdlc-cycle.cjs @@ -19,7 +19,20 @@ const fs = require('node:fs'); await page.waitForURL('**/strategy/target-operating-model/'); for (const route of ['target-operating-model/', '']) { await page.goto(`${base}/eldorado-v1/documentation/strategy/${route}`, {waitUntil:'networkidle'}); - if (width === 1440) assert.equal(await page.locator('.theme-doc-sidebar-menu .menu__link').first().innerText(), 'Target'); + await page.waitForURL('**/strategy/target-operating-model/'); + 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(), ['Target', 'Roadmap', 'Skills governance', 'Skills quality', 'Skills adoption', 'Measurement', 'Skills maintenance']); + 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:/^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/'); const iframe = page.locator(`.archify-panel--story > .story-${width > 700 ? 'desktop' : 'mobile'}`); await iframe.scrollIntoViewIfNeeded(); const frame = await (await iframe.elementHandle()).contentFrame(); diff --git a/scripts/sdlc-cycle.test.mjs b/scripts/sdlc-cycle.test.mjs index 724c14f..91665bd 100644 --- a/scripts/sdlc-cycle.test.mjs +++ b/scripts/sdlc-cycle.test.mjs @@ -4,10 +4,10 @@ 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'/); +test('Strategy opens at the canonical autonomous lifecycle', () => { + assert.match(read('sidebars/strategy.ts'), /strategySidebar: \['target-operating-model', 'roadmap'/); assert.match(read('docs/strategy/target-operating-model.mdx'), /^sidebar_label: Target$/m); - for (const id of ['index', 'target-operating-model']) { + for (const id of ['target-operating-model']) { const page = read(`docs/strategy/${id}.mdx`); const primary = page.split('
')[0]; assert(primary.includes('name="strategy-target"')); diff --git a/scripts/strategy-navigation.test.mjs b/scripts/strategy-navigation.test.mjs new file mode 100644 index 0000000..1757fc0 --- /dev/null +++ b/scripts/strategy-navigation.test.mjs @@ -0,0 +1,19 @@ +import {test} from 'node:test'; +import assert from 'node:assert/strict'; +import {readFileSync, existsSync} from 'node:fs'; +const read = p => readFileSync(p, 'utf8'); + +test('Strategy has one canonical Target, then Roadmap, without a landing menu duplicate', () => { + const sidebar = read('sidebars/strategy.ts').split('strategySidebar: [')[1].split(']')[0]; + const ids = [...sidebar.matchAll(/'([^']+)'/g)].map(match => match[1]); + assert.deepEqual(ids, ['target-operating-model', 'roadmap', 'skills-governance', 'skills-quality', 'skills-adoption', 'measurement', 'skills-maintenance']); + assert.equal(ids.filter(id => id === 'target-operating-model').length, 1); + 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'/); +}); + +test('old Strategy entry redirects to Target instead of maintaining a second document', () => { + assert(!existsSync('docs/strategy/index.mdx')); + assert.match(read('docusaurus.config.ts'), /'@docusaurus\/plugin-client-redirects'/); + assert.match(read('docusaurus.config.ts'), /from: '\/strategy\/', to: '\/strategy\/target-operating-model\/'/); +}); diff --git a/scripts/strategy.test.mjs b/scripts/strategy.test.mjs index 504481e..417b8cb 100644 --- a/scripts/strategy.test.mjs +++ b/scripts/strategy.test.mjs @@ -3,9 +3,9 @@ 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('eight fixed strategy pages preserve target boundary and separate evidence', () => { - assert.equal(model.pages.length, 8); - assert.equal(readdirSync('docs/strategy').length, 8); +test('seven canonical strategy pages preserve target boundary and separate evidence', () => { + assert.equal(model.pages.length, 7); + assert.equal(readdirSync('docs/strategy').length, 7); for (const {id} of model.pages) { const page = read(`docs/strategy/${id}.mdx`); assert(page.includes(`id: ${id}`)); diff --git a/scripts/verify.mjs b/scripts/verify.mjs index c65cbc3..5828f87 100644 --- a/scripts/verify.mjs +++ b/scripts/verify.mjs @@ -18,6 +18,9 @@ assert(workflow.includes("gitea.event_name == 'push' && gitea.ref == 'refs/heads if (process.argv.includes('--build')) { const model = JSON.parse(read('research/ai-adoption/strategy-model.json')); const indexes = readdirSync('build').filter(f => /^search-index.*\.json$/.test(f)).map(f => read(join('build',f))).join('\n'); + const redirect = read('build/strategy/index.html'); + 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'); for (const {id, title} of model.pages) { const route = `strategy/${id === 'index' ? '' : `${id}/`}index.html`; const page = read(join('build',route)); diff --git a/sidebars/strategy.ts b/sidebars/strategy.ts index eb26393..18c649d 100644 --- a/sidebars/strategy.ts +++ b/sidebars/strategy.ts @@ -1,2 +1,2 @@ import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; -export default {strategySidebar: ['target-operating-model', 'index', 'skills-governance', 'skills-quality', 'skills-adoption', 'measurement', 'skills-maintenance', 'roadmap']} satisfies SidebarsConfig; +export default {strategySidebar: ['target-operating-model', 'roadmap', 'skills-governance', 'skills-quality', 'skills-adoption', 'measurement', 'skills-maintenance']} satisfies SidebarsConfig; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8a73346..bbc0722 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -25,7 +25,7 @@ export default function Home(): React.ReactElement {

START HERE

A clear place to begin.

Foundation · v1
01 / ORGANIZATION

Organization

Explore the structure workspace and its first interactive diagram.

Explore structure - 02 / STRATEGY

Strategy

Shape the direction for an AI-powered Eldorado.

View the direction + 02 / STRATEGY

Strategy

Shape the direction for an AI-powered Eldorado.

View the direction 03 / CONTRIBUTION

Contribution

Contribute evidence, proposals, documentation, and diagrams.

Start contributing