import { readFileSync } from 'node:fs'; const read = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf8'); const landingHtml = read('index.html'); const html = read('full-guide/index.html'); const js = read('app.js'); const refs = read('docs/references/README.md'); const additional = read('docs/references/additional-reading.md'); const starterHtml = read('hands-on/starter/index.html'); const starterJs = read('hands-on/starter/app.js'); const skillSources = read('docs/references/skill-sources.md'); const modelRouting = read('docs/references/model-routing.md'); const rulesHtml = read('rules/index.html'); const rulesJs = read('rules/app.js'); const rulesCss = read('rules/styles.css'); const reviewHtml = read('skills-review/index.html'); const reviewJs = read('skills-review/app.js'); const reviewFiles = read('skills-review/files.js'); const reviewLensCss = read('skills-review/change-lens.css'); const chaptersCss = read('chapters.css'); const summaryHtml = read('summary/index.html'); const modelsHtml = read('models/index.html'); const agentsHtml = read('agents/index.html'); const skillsHtml = read('skills/index.html'); const reviewCatalog = read('skills-review/catalog.js'); const reviewVoteJs = read('skills-review/vote.js'); const voteService = read('vote-service/main.go'); for (const url of [ 'https://code.claude.com/docs/en/sub-agents', 'https://code.claude.com/docs/en/skills', 'https://code.claude.com/docs/en/worktrees', 'https://git-scm.com/docs/git-worktree.html', 'https://developers.openai.com/codex/skills', ]) if (!refs.includes(url)) throw new Error(`missing reference ${url}`); console.log('content verification passed'); for (const token of [ 'data-phase="plan"', 'data-phase="build"', 'data-phase="review"', 'data-tree="main"', 'data-tree="ui"', 'data-worker="ui"', 'data-route="plan"', 'data-model-provider="openai"', 'data-model-provider="claude"', 'data-model-provider="gemini"', 'data-effort="low"', 'data-effort="medium"', 'data-effort="high"', 'data-skill-file="skill"', 'data-skill-step="observe"', 'data-skill-step="validate"', 'data-common-skill="ponytail"', 'data-common-skill="caveman"', 'data-common-skill="unlazy"', 'id="hands-on"', 'data-copy-target="prompt-install-skills"', 'data-copy-target="prompt-basic"', 'data-copy-target="prompt-skills"', 'hands-on/starter/', 'additional-reading.md', 'role="tablist"', ']+(src|href)="https?:[^"]+"/i)) throw new Error('external runtime dependency found'); console.log('standalone verification passed'); for (const token of [ 'id="pipeline"', 'id="skills"', 'id="examples"', 'data-stage="context"', 'data-stage="cli"', 'data-stage="commit"', 'data-stage="review"', 'gate-discipline', 'parallel-agents', 'repo-db', 'tech-debt', 'skill-writer', 'scripts/check-ui-contract.mjs', '.husky/pre-commit', '.pr-review.json', '.agents/skills', 'netcracker/interview', ]) if (!rulesHtml.includes(token)) throw new Error(`missing rules content ${token}`); console.log('rules content verification passed'); for (const token of [ 'const languageCopy', 'const stages', 'const skills', 'const prompts', 'renderStage', 'renderSkill', 'renderLanguage', 'copyPrompt', 'addEventListener', ]) if (!rulesJs.includes(token)) throw new Error(`missing rules interaction ${token}`); for (const token of [ 'data-lang="en"', 'data-lang="pt"', 'data-copy-prompt', 'aria-live="polite"', 'role="tablist"', ]) if (!rulesHtml.includes(token)) throw new Error(`missing rules control ${token}`); console.log('rules interaction verification passed'); if (!html.includes('href="../rules/"')) throw new Error('main presentation does not link to rules page'); if (!html.includes('href="../skills-review/"')) throw new Error('main presentation does not link to skills review page'); for (const token of ['../summary/', '../models/', '../agents/', '../skills/', 'chapter-route']) if (!html.includes(token)) throw new Error(`main presentation missing chapter route ${token}`); if (rulesHtml.includes('script src="http') || rulesHtml.includes('rel="stylesheet" href="http')) throw new Error('rules page has an external runtime dependency'); for (const token of [ '@media(min-width:2200px)', '@media(max-width:900px)', '@media(max-width:600px)', 'prefers-reduced-motion', ]) if (!rulesCss.includes(token)) throw new Error(`missing rules responsive contract ${token}`); console.log('rules standalone verification passed'); for (const token of [ 'id="catalog"', 'id="skill-filter"', 'id="skill-list"', 'id="detail"', 'Preview Markdown', 'styles.css?v=20260904-vote-widget', 'change-lens.css?v=20260904-vote-widget', 'app.js?v=20260904-vote-widget', '?author=Name&skill=skill-id&view=improved', 'SKILLS_REVIEW_VOTE_API', ]) if (!reviewHtml.includes(token)) throw new Error(`missing review page content ${token}`); for (const token of [ "from './catalog.js'", "from './files.js'", 'function renderList', 'function renderDetail', 'selectSkill', 'packageSummary', 'markdownHeadings', 'markdownToc', "document.addEventListener('keydown'", 'loadSelectedFile', 'schedulePackageSearch', 'fetchSource', 'packageSearchText', 'diffMarkup', 'diffRows', 'data-diff', "searchParams.set('compare'", 'markdownMarkup', 'data-render', 'preview-markdown', 'Preview Markdown', 'View source', 'FILE PREVIEW', "searchParams.set('render'", 'AUTHOR ·', 'SKILL ·', 'function selectFromUrl', 'function syncUrl', 'URLSearchParams', 'navigator.clipboard', 'document.execCommand', 'download', 'data-file', "searchParams.set('file'", ]) if (!reviewJs.includes(token)) throw new Error(`missing review interaction ${token}`); for (const token of [ 'ndo-repro', 'gfiber-logging', 'confluence-page', 'diagram-plantuml', 'page-reviewer', 'unslop', 'spanish-naturalizer', 'draft-mr', 'semantic-diff-review', 'reference.md', 'files =', ]) if (!`${reviewFiles}\n${read('skills-review/submitted-files.js')}`.includes(token)) throw new Error(`missing review file manifest ${token}`); if ( (reviewCatalog.match(/id:'/g) || []).length + (read('skills-review/submitted-catalog.js').match(/id:'/g) || []).length !== 24 ) throw new Error('review catalog does not cover all submissions'); if ( !reviewCatalog.includes('hardcoded password') || !reviewCatalog.includes('safety-redacted') || !reviewJs.includes('[REDACTED]') || !reviewJs.includes('[REDACTED LOCAL USER]') || !reviewJs.includes('[REDACTED USER]') ) throw new Error('review catalog does not record secret safety handling'); console.log('skills review verification passed'); for (const page of [summaryHtml, modelsHtml, agentsHtml, skillsHtml]) if (!page.includes('../chapters.css') || !page.includes('ROUTE MAP')) throw new Error('chapter page missing shared navigation'); for (const token of ['--ink', '@media(max-width:800px)', '@media(max-width:520px)']) if (!chaptersCss.includes(token)) throw new Error(`missing chapter responsive contract ${token}`); console.log('chapter route verification passed'); for (const token of [ 'The short route', 'full-guide/', 'models/', 'agents/', 'skills/', 'rules/', 'hands-on/starter/', 'skills-review/', ]) if (!landingHtml.includes(token)) throw new Error(`landing page missing ${token}`); if (landingHtml.includes('app.js')) throw new Error('landing page should remain a fast, static route map'); console.log('landing route verification passed'); for (const token of [ 'data-package-file="skill"', 'data-package-file="references"', 'data-package-file="scripts"', 'data-package-file="assets"', 'id="package-preview"', 'script src="app.js"', ]) if (!skillsHtml.includes(token)) throw new Error(`skills anatomy missing ${token}`); const skillsApp = read('skills/app.js'); const skillsCss = read('skills/styles.css'); for (const token of [ 'const packageFiles', 'function renderPackage', 'addEventListener', "renderPackage('skill')", ]) if (!skillsApp.includes(token)) throw new Error(`skills anatomy interaction missing ${token}`); for (const token of [ 'grid-template-columns:minmax(190px', 'overflow-wrap:anywhere', '@media(max-width:800px)', 'prefers-reduced-motion', ]) if (!skillsCss.includes(token)) throw new Error(`skills anatomy responsive contract missing ${token}`); console.log('skills anatomy verification passed'); console.log('presentation verification passed'); const legacyName = String.fromCharCode(80, 101, 100, 114, 111, 32, 65, 114, 97, 110, 104, 97); const legacyHandle = legacyName.toLowerCase().replace(' ', '.'); for (const path of [ 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/SKILL.md', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/envs.tsv', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/lib/env.sh', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/ndo-api.sh', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/ndo-ship.sh', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/reference/bom-Dockerfile_local.example', 'submitted-skills/Anonymous Operational Submission/skills/ndo-repro/reference/dockerfile-local.md', 'skill-reviews/improved/ndo-repro/SKILL.md', ]) { const source = read(path); if ( new RegExp( `${legacyName}|${legacyHandle}|https?:\\/\\/|git\\.netcracker\\.com|artifactorycn|managed\\.netcracker\\.cloud`, 'i', ).test(source) ) throw new Error(`operational submission privacy leak in ${path}`); } for (const source of [reviewCatalog, reviewFiles, reviewJs]) if (source.includes(legacyName) || source.includes(legacyName.replace(' ', '%20'))) throw new Error('operational submission identity remains in review desk source'); if ( !reviewFiles.includes('Anonymous%20Operational%20Submission') || !reviewJs.includes("entry.id === 'ndo-repro'") ) throw new Error('operational submission redaction contract missing'); console.log('review privacy verification passed'); for (const token of [ 'currentContent', 'unchangedDraft', 'state.preview = button.dataset.preview', 'state.file = available.find', 'loadSelectedFile', ]) if (!reviewJs.includes(token)) throw new Error(`review file-mode contract missing ${token}`); if (reviewJs.includes("state.preview = 'original'; syncUrl(); renderDetail(); loadSelectedFile();")) throw new Error('file selection still resets improved mode'); console.log('review file-mode verification passed'); for (const token of [ 'const changeRows', 'function lensMarkup', 'data-lens', 'CHANGE LENS', 'What changed — and why.', ]) if (!reviewJs.includes(token)) throw new Error(`review change-lens contract missing ${token}`); for (const token of [ '.change-lens', '.change-rows', '.skill-diff', '.diff-lines', '@media(max-width:620px)', 'prefers-reduced-motion', ]) if (!reviewLensCss.includes(token)) throw new Error(`review change-lens CSS missing ${token}`); console.log('review change-lens verification passed'); for (const token of [ '.markdown-preview', 'max-height:540px', '.markdown-table-wrap', '.markdown-frontmatter', '.markdown-toc', '.preview-title', '.preview-markdown', 'grid-template-columns:minmax(0,1fr)', 'height:120px', '-webkit-line-clamp:2', ]) if (!read('skills-review/styles.css').includes(token)) throw new Error(`review markdown preview contract missing ${token}`); console.log('review markdown preview verification passed'); for (const token of ["from './vote.js'", "renderVoteWidget($('#vote-widget'"]) if (!reviewJs.includes(token)) throw new Error(`review vote widget wiring missing ${token}`); for (const token of [ 'id="vote-widget"', 'function renderVoteWidget', 'X-Voter-Id', '/api/votes', 'Voting is offline', ]) if (!reviewVoteJs.includes(token) && !reviewJs.includes(token)) throw new Error(`review vote widget contract missing ${token}`); for (const token of ['.vote-widget', '.vote-buttons', '[aria-pressed="true"]']) if (!read('skills-review/styles.css').includes(token)) throw new Error(`review vote widget CSS missing ${token}`); if ( !voteService.includes('X-Forwarded-For') || (!voteService.includes('one active vote per skill') && !voteService.includes('at most one active vote')) ) throw new Error('vote-service missing IP-based one-vote-per-source contract'); console.log('review vote widget verification passed');