diff --git a/README.md b/README.md index d0e1441..32a7944 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ An interactive field kit compares common behavior skills such as `ponytail-lite`, `caveman`, `unlazy`, research, debugging, and review. The skill-forge workflow covers discovery, triggers, package anatomy, progressive instructions, structural validation, and behavioral iteration. +The hands-on lab provides a tiny starter project and copy-ready baseline and +skill-enabled prompts for a short side-by-side exercise. +An interactive model gearbox separates capability tier from reasoning effort +across OpenAI, Claude, and Gemini, and every featured skill links to a pinned +source with an approval-first installation prompt. ## Run locally @@ -33,6 +38,7 @@ npm run verify - `responsive.css` — interactive diagrams and Full HD-to-4K adaptations - `docs/references/` — bundled research sources and notes - `docs/operations-guide.md` — canonical SilverBullet operations and skills guide +- `hands-on/starter/` — dependency-free Tiny Tasks exercise - `GATES.md` — acceptance ledger for the project ## Publishing @@ -55,3 +61,5 @@ skill workflow, see [docs/operations-guide.md](docs/operations-guide.md). See [docs/references/README.md](docs/references/README.md) for official Claude, Codex, and Git documentation. The [additional reading path](docs/references/additional-reading.md) bundles 12 verified articles and guides, including Medium and practitioner sources. +See [model routing](docs/references/model-routing.md) for current provider controls +and [verified skill sources](docs/references/skill-sources.md) for commit-pinned provenance. diff --git a/app.js b/app.js index b17f13a..0f69dec 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,159 @@ const phases = { review: { model: { en: 'STRONG MODEL OR HUMAN', pt: 'MODELO FORTE OU HUMANO' }, title: { en: 'Reconnect result to intent', pt: 'Reconecte o resultado à intenção' }, copy: { en: 'Check the diff against the original brief, run the checks, then merge, request changes, or discard.', pt: 'Compare o diff com o brief original, execute as verificações e então faça merge, peça mudanças ou descarte.' }, code: { en: 'diff + checks → review → merge / iterate', pt: 'diff + verificações → revisar → merge / iterar' } } }; +const handsOnPrompts = { + en: { + basic: [ + 'Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript.', + '', + 'Add an All / Open / Done filter to Tiny Tasks.', + '', + 'Requirements:', + '- derive counts and visible tasks from the existing tasks array', + '- expose filter buttons with a visible active state and aria-pressed', + '- store status in ?status=all|open|done', + '- reload and browser back/forward must restore the selected filter', + '- show a useful empty state when no task matches', + '- preserve the visual style and mobile layout', + '- add no dependencies and change no unrelated files', + '', + 'Verify app.js syntax and exercise every filter plus URL navigation.', + 'Return changed files, checks run, results, and remaining risk.' + ].join('\n'), + skills: [ + 'Use $ponytail-lite and $webapp-testing.', + 'Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript.', + '', + 'Add an All / Open / Done filter to Tiny Tasks.', + '', + 'Apply $ponytail-lite: inspect first, reuse the current render flow, prefer native URL and button APIs, and avoid dependencies or abstractions.', + 'Apply $webapp-testing: verify all filters, aria-pressed, reload, browser back/forward, empty state, and one mobile viewport.', + '', + 'Acceptance:', + '- counts and visible tasks come from the existing tasks array', + '- ?status=all|open|done is the source of truth', + '- invalid status falls back safely to all', + '- style remains consistent; unrelated files remain untouched', + '', + 'Return the smallest working diff and concrete verification evidence.' + ].join('\n') + }, + pt: { + basic: [ + 'Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências.', + '', + 'Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks.', + '', + 'Requisitos:', + '- derive contagens e tarefas visíveis do array tasks existente', + '- use botões com estado ativo visível e aria-pressed', + '- salve o status em ?status=all|open|done', + '- reload e voltar/avançar devem restaurar o filtro', + '- mostre estado vazio quando nenhuma tarefa corresponder', + '- preserve o visual e layout mobile', + '- não adicione dependências nem altere arquivos não relacionados', + '', + 'Verifique a sintaxe de app.js e teste filtros e navegação por URL.', + 'Retorne arquivos alterados, checks, resultados e risco restante.' + ].join('\n'), + skills: [ + 'Use $ponytail-lite e $webapp-testing.', + 'Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências.', + '', + 'Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks.', + '', + 'Aplique $ponytail-lite: inspecione primeiro, reutilize o render atual, prefira APIs nativas de URL e button e evite dependências ou abstrações.', + 'Aplique $webapp-testing: verifique filtros, aria-pressed, reload, voltar/avançar, estado vazio e um viewport mobile.', + '', + 'Aceitação:', + '- contagens e tarefas visíveis vêm do array tasks existente', + '- ?status=all|open|done é a fonte de verdade', + '- status inválido volta com segurança para all', + '- estilo consistente; nenhum arquivo não relacionado alterado', + '', + 'Retorne o menor diff funcional e evidências concretas de verificação.' + ].join('\n') + } +}; + +const modelGuide = { + providers: { + openai: { + label: 'OpenAI', source: 'https://developers.openai.com/api/docs/guides/latest-model', + title: { en: 'Sol · Terra · Luna', pt: 'Sol · Terra · Luna' }, + copy: { en: 'GPT-5.6 separates capability tier from reasoning effort. Sol is flagship, Terra balances performance and cost, and Luna targets efficient high-volume work.', pt: 'O GPT-5.6 separa o nível de capacidade do esforço de raciocínio. Sol é flagship, Terra equilibra desempenho e custo, e Luna atende trabalho eficiente em alto volume.' }, + tiers: [ + ['STRONG', 'Sol', { en: 'orchestration + hard judgment', pt: 'orquestração + julgamento difícil' }], + ['BALANCED', 'Terra', { en: 'normal implementation', pt: 'implementação normal' }], + ['FAST', 'Luna', { en: 'bounded, high-volume work', pt: 'trabalho delimitado e volumoso' }] + ], + config: 'reasoning: { effort: "medium" }' + }, + claude: { + label: 'Claude', source: 'https://docs.anthropic.com/en/docs/claude-code/model-config', + title: { en: 'Opus · Sonnet · Haiku', pt: 'Opus · Sonnet · Haiku' }, + copy: { en: 'Claude Code exposes memorable aliases. Opus handles complex reasoning, Sonnet everyday coding, and Haiku simple fast work. The opusplan alias can plan with Opus and execute with Sonnet.', pt: 'Claude Code oferece aliases fáceis de lembrar. Opus cuida de raciocínio complexo, Sonnet do código cotidiano e Haiku de trabalho simples e rápido. O alias opusplan pode planejar com Opus e executar com Sonnet.' }, + tiers: [ + ['STRONG', 'Opus', { en: 'planning + architecture', pt: 'planejamento + arquitetura' }], + ['BALANCED', 'Sonnet', { en: 'everyday coding', pt: 'código cotidiano' }], + ['FAST', 'Haiku', { en: 'simple, fast tasks', pt: 'tarefas simples e rápidas' }] + ], + config: '/model opus · /model sonnet · /model haiku' + }, + gemini: { + label: 'Gemini', source: 'https://ai.google.dev/gemini-api/docs/thinking', + title: { en: 'Pro · Flash · Flash-Lite', pt: 'Pro · Flash · Flash-Lite' }, + copy: { en: 'Gemini uses model families rather than interchangeable aliases. Pro targets complex reasoning, Flash balances capability and throughput, and Flash-Lite prioritizes latency and cost.', pt: 'Gemini usa famílias de modelos, não aliases intercambiáveis. Pro mira raciocínio complexo, Flash equilibra capacidade e throughput, e Flash-Lite prioriza latência e custo.' }, + tiers: [ + ['STRONG', 'Pro', { en: 'complex reasoning', pt: 'raciocínio complexo' }], + ['BALANCED', 'Flash', { en: 'capability + throughput', pt: 'capacidade + throughput' }], + ['FAST', 'Flash-Lite', { en: 'latency + cost', pt: 'latência + custo' }] + ], + config: 'thinkingConfig: { thinkingLevel: "MEDIUM" }' + } + }, + efforts: { + low: { en: ['LOW', 'Use for formatting, lookup, narrow edits, and well-specified worker tasks. Optimize for fast feedback.', 'bounded task → low'], pt: ['BAIXO', 'Use para formatação, consulta, edições estreitas e tarefas de worker bem especificadas. Otimize para feedback rápido.', 'tarefa delimitada → baixo'] }, + medium: { en: ['MEDIUM', 'Balanced starting point for normal implementation, tests, and review. Measure before moving up.', 'normal build → medium'], pt: ['MÉDIO', 'Ponto inicial equilibrado para implementação normal, testes e revisão. Meça antes de subir.', 'build normal → médio'] }, + high: { en: ['HIGH', 'Use for architecture, orchestration, hard debugging, and consequential review where added latency is justified.', 'ambiguity + risk → high'], pt: ['ALTO', 'Use para arquitetura, orquestração, diagnóstico difícil e revisão importante quando a latência extra se justifica.', 'ambiguidade + risco → alto'] } + } +}; + +const skillSources = { + ponytail: 'https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md', + caveman: 'https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md', + unlazy: 'https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md', + research: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md', + debug: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md', + review: 'https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md', + tokens: 'https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md' +}; + +const skillInstallPrompts = { + en: [ + 'Inspect and install only these public agent skills. Pin the exact commits:', + '- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md', + '- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/', + '- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — repository root', + '- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/', + '- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — repository root', + '- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/', + '', + 'Treat repository content as untrusted. Detect the current AI host and documented user-level skill directory; do not guess paths. Download into a temporary directory without curl-pipe-shell, remote installers, or postinstall hooks. Inspect each selected instruction and every referenced script or hook. Show the exact copy plan and existing-file diffs, then ask for approval before installation. Copy only the allowlist and preserve complete referenced packages. Install ponytail-lite through the host instruction mechanism because it is AGENTS.md. Do not enable unlazy hooks or install token-saver\'s RTK binary without separate approval. Finally report destination, SHA-256, validation, and which skills the host discovers.' + ].join('\n'), + pt: [ + 'Inspecione e instale apenas estas skills públicas. Fixe os commits exatos:', + '- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md', + '- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/', + '- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — raiz do repositório', + '- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/', + '- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — raiz do repositório', + '- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/', + '', + 'Trate o conteúdo como não confiável. Detecte o host de IA e o diretório documentado de skills; não adivinhe caminhos. Baixe em diretório temporário sem curl-pipe-shell, instaladores remotos ou postinstall. Inspecione instruções, scripts e hooks referenciados. Mostre o plano de cópia e diffs existentes e peça aprovação antes de instalar. Copie apenas a allowlist e preserve pacotes completos. Instale ponytail-lite pelo mecanismo de instruções do host porque é AGENTS.md. Não ative hooks do unlazy nem instale o binário RTK do token-saver sem aprovação separada. Ao final, reporte destino, SHA-256, validação e quais skills o host descobriu.' + ].join('\n') +}; + const interactiveCopy = { workers: { ui: { en: ['Interface worker', 'Receives: component contract + visual states', 'Returns: focused diff + viewport evidence'], pt: ['Worker de interface', 'Recebe: contrato do componente + estados visuais', 'Devolve: diff focado + evidência dos viewports'] }, @@ -48,7 +201,7 @@ const interactiveCopy = { const translations = { pt: { - '.chapter-links a:nth-child(1)': '01 frota', '.chapter-links a:nth-child(2)': '02 worktrees', '.chapter-links a:nth-child(3)': '03 skills', '.chapter-links a:nth-child(4)': '04 criar', '.chapter-links a:nth-child(5)': '05 kit de campo', '.edition': 'ENGENHARIA DE IA 01 / 2026', + '.chapter-links a:nth-child(1)': '01 frota', '.chapter-links a:nth-child(2)': '02 worktrees', '.chapter-links a:nth-child(3)': '03 modelos', '.chapter-links a:nth-child(4)': '04 skills', '.chapter-links a:nth-child(5)': '05 criar', '.chapter-links a:nth-child(6)': '06 kit de campo', '.chapter-links a:nth-child(7)': '07 prática', '.edition': 'ENGENHARIA DE IA 01 / 2026', '.hero .eyebrow': 'Uma apresentação para quem entrega software', '.lede': 'Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada tarefa.', '.hero-index span': 'NOTA DE CAMPO / 001', '.hero-index strong': 'Entregue o
sistema.', '.hero-index small': 'Skills · agentes · worktrees · evidências', '.hero-stats div:nth-child(1) span': 'modelo forte
para ambiguidade', '.hero-stats div:nth-child(2) span': 'workers delimitados
em paralelo', '.hero-stats div:nth-child(3) span': 'iterações
com evidências', '.hero-stats p': 'Leia isto como um mapa de rota, não como uma receita de prompt.', '.thesis span': 'REGRA ZERO', '.thesis strong': 'Modelo forte para ambiguidade.
Modelo leve para trabalho delimitado.', '.fleet .section-label span:nth-child(1)': 'Uma pequena frota', '.fleet .section-label span:nth-child(2)': 'coordenação antes do paralelismo', '.captain span': 'ORQUESTRADOR', '.captain h2': 'Decide o que
precisa acontecer.', '.worker-card[data-worker="ui"] strong': 'Componentes e estados visuais', '.worker-card[data-worker="tests"] strong': 'Casos de aceitação', '.worker-card[data-worker="docs"] strong': 'Guia e exemplos', '.caption': 'O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados verificáveis. Ele não precisa digitar cada linha.', @@ -60,6 +213,11 @@ const translations = { }; Object.assign(translations.pt, { + '.model-gearbox .section-label span:nth-child(1)': 'Câmbio de modelos', '.model-gearbox .section-label span:nth-child(2)': 'nível de capacidade × esforço de raciocínio', + '.gearbox-intro .eyebrow': 'Dois controles separados', '.gearbox-intro h2': 'Escolha o motor.
Depois escolha a marcha.', + '.gearbox-intro > p': 'Um modelo mais forte muda o teto de capacidade. Mais esforço de raciocínio dá mais espaço para esse modelo trabalhar. Comece com a combinação mais leve que passa seus checks e mova um controle por vez.', + '.effort-rail > span': 'RACIOCÍNIO / PENSAMENTO', '[data-effort="low"] b': 'BAIXO', '[data-effort="low"] small': 'delimitado + rápido', '[data-effort="medium"] b': 'MÉDIO', '[data-effort="medium"] small': 'ponto inicial', '[data-effort="high"] b': 'ALTO', '[data-effort="high"] small': 'complexo + custoso', + '.gearbox-rule span': 'REGRA DE ROTEAMENTO', '.gearbox-rule strong': 'Use modelos fortes para ambiguidade e julgamento. Use modelos leves para execução delimitada. Aumente o esforço apenas quando a avaliação mostrar ganho.', '.skill-builder .section-label span:nth-child(1)': 'Criar uma skill', '.skill-builder .section-label span:nth-child(2)': 'atrito repetido → julgamento reutilizável', '.builder-intro .eyebrow': 'A forja de skills', @@ -72,7 +230,18 @@ Object.assign(translations.pt, { '[data-skill-step="validate"] span': 'Validar', '[data-skill-step="validate"] small': 'teste comportamento real', '.artifact-head span': 'SAÍDA / PACOTE DE SKILL', '.artifact-command span': 'VALIDAR', '.builder-loop > span': 'APÓS USO REAL', - '.builder-loop > div': 'observar falharefinar uma regraretestar comportamentomanter estreita' + '.builder-loop > div': 'observar falharefinar uma regraretestar comportamentomanter estreita', + '.install-skills header span': 'PACOTE DE INSTALAÇÃO', '.install-skills header strong': 'Peça ao seu agente para verificar, instalar e validar as skills.', + '.install-skills footer': 'Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.', + '.hands-on .section-label span:nth-child(1)': 'Prática', '.hands-on .section-label span:nth-child(2)': '10 minutos / uma feature ausente', + '.hands-intro .eyebrow': 'Laboratório Tiny Tasks', '.hands-intro h2': 'Mesma tarefa.
Melhor sistema operacional.', + '.hands-intro > div:last-child > p': 'Comece com um quadro estático propositalmente incompleto. Execute um prompt, restaure e execute a versão com skills. Compare tamanho do diff, evidências e complexidade desnecessária.', + '.starter-link': 'Abrir o projeto inicial →', '.exercise-brief > span': 'A FEATURE AUSENTE', + '.exercise-brief > strong': 'Adicione filtros Todos / Abertos / Concluídos que sobrevivem reload e navegação.', + '.exercise-brief > div': 'STACK HTML · CSS · JavaScript DEPENDÊNCIAS nenhuma ARQUIVOS 3', + '.prompt-card:first-child header strong': 'Bom prompt', '.prompt-card.enhanced header strong': 'Bom prompt + skills', + '.prompt-card:first-child footer': 'Contexto claro · restrições · aceitação · evidência', '.prompt-card.enhanced footer': 'Mesmo contrato · métodos explícitos · prova mais forte', + '.comparison-strip > span': 'COMPARE AS EXECUÇÕES', '.comparison-strip > div:nth-child(2)': '01 Arquivos alterados', '.comparison-strip > div:nth-child(3)': '02 Novas dependências', '.comparison-strip > div:nth-child(4)': '03 Checks executados', '.comparison-strip > div:nth-child(5)': '04 Evidências retornadas' }); const panel = document.querySelector('#phase-panel'); @@ -121,6 +290,23 @@ function renderRoute(id) { selectButtons('[data-route]', id, 'route'); } +function renderModelProvider(id) { + const item = modelGuide.providers[id]; + const language = currentLanguage; + const sourceLabel = language === 'pt' ? 'FONTE OFICIAL ↗' : 'OFFICIAL SOURCE ↗'; + const kindLabels = language === 'pt' ? { STRONG: 'FORTE', BALANCED: 'EQUILÍBRIO', FAST: 'RÁPIDO' } : {}; + const tiers = item.tiers.map(([kind, name, note]) => `
${kindLabels[kind] || kind}${name}${note[language]}
`).join(''); + document.querySelector('#provider-detail').innerHTML = `
${item.label}${sourceLabel}

${item.title[language]}

${item.copy[language]}

${tiers}
`; + selectButtons('[data-model-provider]', id, 'modelProvider'); +} + +function renderEffort(id) { + const item = modelGuide.efforts[id][currentLanguage]; + const provider = modelGuide.providers[document.querySelector('[data-model-provider].active')?.dataset.modelProvider || 'openai']; + document.querySelector('#effort-detail').innerHTML = `${item[0]}

${item[1]}

${provider.config}`; + selectButtons('[data-effort]', id, 'effort'); +} + function renderSkillFile(id) { const item = interactiveCopy.skillFiles[id]; document.querySelector('#skill-detail').innerHTML = `${item.icon}
${item.title}

${item[currentLanguage]}

${currentLanguage === 'pt' ? 'clique em outro arquivo para explorar' : 'select another file to explore'}
`; @@ -143,17 +329,56 @@ function renderCommonSkill(id) { const labels = language === 'pt' ? ['QUANDO USAR', 'EXEMPLO', 'CUIDADO'] : ['WHEN TO USE', 'EXAMPLE', 'WATCH OUT']; - document.querySelector('#common-skill-detail').innerHTML = `
${item.number}${item.kind[language]}

${item.title}

${item.rule[language]}
${labels[0]}

${item.use[language]}

${labels[1]}

${item.example[language]}

${labels[2]}

${item.caution[language]}

`; + const sourceLabel = language === 'pt' ? 'FONTE NO GITHUB ↗' : 'GITHUB SOURCE ↗'; + document.querySelector('#common-skill-detail').innerHTML = `
${item.number}${item.kind[language]}

${item.title}

${item.rule[language]}
${labels[0]}

${item.use[language]}

${labels[1]}

${item.example[language]}

${labels[2]}

${item.caution[language]}

${sourceLabel}`; selectButtons('[data-common-skill]', id, 'commonSkill'); } +function renderHandsOn() { + document.querySelector('#prompt-basic').textContent = handsOnPrompts[currentLanguage].basic; + document.querySelector('#prompt-skills').textContent = handsOnPrompts[currentLanguage].skills; + document.querySelector('#prompt-install-skills').textContent = skillInstallPrompts[currentLanguage]; + document.querySelectorAll('[data-copy-target] span').forEach((label) => { label.textContent = currentLanguage === 'pt' ? 'COPIAR' : 'COPY'; }); +} + +async function copyPrompt(button) { + const text = document.querySelector(`#${button.dataset.copyTarget}`).textContent; + let copied = false; + try { + await navigator.clipboard.writeText(text); + copied = true; + } catch (error) { + const helper = document.createElement('textarea'); + helper.value = text; + helper.setAttribute('readonly', ''); + helper.style.position = 'fixed'; + helper.style.opacity = '0'; + document.body.appendChild(helper); + helper.select(); + copied = document.execCommand('copy'); + helper.remove(); + } + const status = document.querySelector('#copy-status'); + status.textContent = copied + ? (currentLanguage === 'pt' ? 'Prompt copiado. Cole em uma nova sessão de agente.' : 'Prompt copied. Paste it into a fresh agent session.') + : (currentLanguage === 'pt' ? 'Não foi possível copiar. Selecione o texto manualmente.' : 'Copy unavailable. Select the text manually.'); + if (copied) { + button.classList.add('copied'); + button.querySelector('span').textContent = currentLanguage === 'pt' ? 'COPIADO' : 'COPIED'; + window.setTimeout(() => { button.classList.remove('copied'); button.querySelector('span').textContent = currentLanguage === 'pt' ? 'COPIAR' : 'COPY'; }, 1800); + } +} + function renderInteractive() { renderWorker(document.querySelector('[data-worker].active')?.dataset.worker || 'ui'); renderTree(document.querySelector('[data-tree].active')?.dataset.tree || 'main'); renderRoute(document.querySelector('[data-route].active')?.dataset.route || 'plan'); + renderModelProvider(document.querySelector('[data-model-provider].active')?.dataset.modelProvider || 'openai'); + renderEffort(document.querySelector('[data-effort].active')?.dataset.effort || 'medium'); renderSkillFile(document.querySelector('[data-skill-file].active')?.dataset.skillFile || 'skill'); renderSkillWorkflow(document.querySelector('[data-skill-step].active')?.dataset.skillStep || 'observe'); renderCommonSkill(document.querySelector('[data-common-skill].active')?.dataset.commonSkill || 'ponytail'); + renderHandsOn(); } function applyLanguage(language) { @@ -172,9 +397,12 @@ document.querySelectorAll('[data-lang]').forEach((button) => button.addEventList document.querySelectorAll('[data-worker]').forEach((button) => button.addEventListener('click', () => renderWorker(button.dataset.worker))); document.querySelectorAll('[data-tree]').forEach((button) => button.addEventListener('click', () => renderTree(button.dataset.tree))); document.querySelectorAll('[data-route]').forEach((button) => button.addEventListener('click', () => renderRoute(button.dataset.route))); +document.querySelectorAll('[data-model-provider]').forEach((button) => button.addEventListener('click', () => { renderModelProvider(button.dataset.modelProvider); renderEffort(document.querySelector('[data-effort].active')?.dataset.effort || 'medium'); })); +document.querySelectorAll('[data-effort]').forEach((button) => button.addEventListener('click', () => renderEffort(button.dataset.effort))); document.querySelectorAll('[data-skill-file]').forEach((button) => button.addEventListener('click', () => renderSkillFile(button.dataset.skillFile))); document.querySelectorAll('[data-skill-step]').forEach((button) => button.addEventListener('click', () => renderSkillWorkflow(button.dataset.skillStep))); document.querySelectorAll('[data-common-skill]').forEach((button) => button.addEventListener('click', () => renderCommonSkill(button.dataset.commonSkill))); +document.querySelectorAll('[data-copy-target]').forEach((button) => button.addEventListener('click', () => copyPrompt(button))); window.addEventListener('scroll', () => { const height = document.documentElement.scrollHeight - window.innerHeight; document.querySelector('.reading-progress span').style.width = `${height > 0 ? (window.scrollY / height) * 100 : 0}%`; }, { passive: true }); let savedLanguage = 'en'; diff --git a/docs/operations-guide.md b/docs/operations-guide.md index 9c6c939..20ec971 100644 --- a/docs/operations-guide.md +++ b/docs/operations-guide.md @@ -305,6 +305,82 @@ Useful compositions: - **Documentation with unstable facts:** `research` → writing → cited verification. - **Interactive presentation:** `frontend-design` → `webapp-testing` → responsive evidence. +## Model and effort routing + +Treat model tier and reasoning effort as separate controls: + +| Work shape | Capability tier | Effort baseline | +| :--- | :--- | :--- | +| Formatting, lookup, narrow edit | Luna / Haiku / Flash-Lite | Low or minimal where supported | +| Normal implementation and tests | Terra / Sonnet / Flash | Medium | +| Architecture, orchestration, hard debugging | Sol / Opus / Pro | High | + +For Claude Code, `/model opus`, `/model sonnet`, and `/model haiku` switch the +model alias; `opusplan` can use Opus while planning and Sonnet while executing. +Claude effort support depends on the active model. For OpenAI GPT-5.6, +`reasoning.effort` supports `none`, `low`, `medium`, `high`, `xhigh`, and `max`. +Gemini 3 uses model-specific `thinkingLevel` values, while Gemini 2.5 uses +`thinkingBudget`. Never assume one provider's control maps exactly to another. + +Start with the lightest configuration that passes representative checks. Move +one knob at a time and compare quality, latency, and cost. See +[model-routing.md](references/model-routing.md) for official source links and +copy-ready provider examples. + +## Installing the featured skills + +The field-kit cards link to commit-pinned public sources. The presentation also +includes a copy-ready installation request that tells the coding agent to: + +1. Detect the host's documented skill location. +2. Inspect downloaded instructions, scripts, hooks, and permissions first. +3. Show a source-to-destination plan and existing-file diffs. +4. Ask for approval before copying files. +5. Verify final paths, hashes, validation, and actual skill discovery. + +Important exceptions: `ponytail-lite` is published as `AGENTS.md`, not a +conventional skill package; `token-saver` expects a separate RTK binary; and +`unlazy` includes optional hooks. The prompt does not install binaries or enable +hooks without separate approval. See [skill-sources.md](references/skill-sources.md) +for exact commits, package paths, and confidence notes. + +## Hands-on lab + +The presentation includes a dependency-free starter at +`hands-on/starter/`. It renders a small task board but intentionally omits the +All / Open / Done filter. + +Run it from the repository root: + +```bash +python3 -m http.server 4173 +``` + +Open [http://localhost:4173/hands-on/starter/](http://localhost:4173/hands-on/starter/). +In a fresh coding-agent session, copy **Run A — Good prompt** from the +presentation. Record changed files, dependencies, checks, and evidence. Restore +the starter, then repeat with **Run B — Good prompt + skills**. + +The skill-enabled prompt invokes only two working methods: + +- `$ponytail-lite` keeps the implementation native and small; +- `$webapp-testing` verifies filters, URL state, history navigation, + accessibility state, empty state, and mobile layout. + +The goal is not to prove that a longer prompt is better. Both prompts define +the same task contract. Run B adds reusable operating discipline without +repeating those skill instructions inside the prompt. + +Compare: + +| Signal | Useful question | +| :--- | :--- | +| Files changed | Did the agent stay inside `hands-on/starter/`? | +| Dependencies | Did it add a library where native APIs were enough? | +| Verification | Did it actually exercise URL reload and browser history? | +| Evidence | Did the final response name checks and results? | +| Complexity | Is the solution proportionate to three tasks and three filters? | + ## Troubleshooting | Symptom | Check | Fix | diff --git a/docs/references/README.md b/docs/references/README.md index d5e0a2c..776007d 100644 --- a/docs/references/README.md +++ b/docs/references/README.md @@ -20,6 +20,12 @@ articles are context, not authority. ## Research and articles +- [Model routing and reasoning controls](model-routing.md) — official OpenAI, + Anthropic, and Google terminology, commands, compatibility caveats, and a + practical tier/effort baseline. +- [Verified skill sources](skill-sources.md) — pinned GitHub references, + package paths, local-match confidence, and an approval-first install prompt. + For a structured 12-part reading path—including Git and Anthropic documentation, OpenAI orchestration guidance, Medium, and Substack—see [additional-reading.md](additional-reading.md). diff --git a/docs/references/model-routing.md b/docs/references/model-routing.md new file mode 100644 index 0000000..eb4be8a --- /dev/null +++ b/docs/references/model-routing.md @@ -0,0 +1,96 @@ +# Model routing and reasoning controls + +Verified against first-party documentation on 2026-09-02. Model catalogs and aliases change; pin production model IDs and re-check the linked compatibility tables before rollout. + +## Two independent routing knobs + +1. **Model tier** chooses the capability, latency, and cost envelope. +2. **Effort / thinking control** changes how much reasoning work a supported model performs for one request. + +Do not assume that every effort value works with every model or product. Unsupported values may fail, be ignored, or be mapped to another level depending on the client. + +## OpenAI + +The current GPT-5.6 family exposes the **Sol**, **Terra**, and **Luna** model tiers. Its documented `reasoning.effort` values are `none`, `low`, `medium`, `high`, `xhigh`, and `max`. Availability remains model-specific, so select from the levels shown for the chosen model rather than treating the full list as universal. [OpenAI: latest model guide](https://developers.openai.com/api/docs/guides/latest-model) + +Use a lower-cost tier and low effort for bounded, mechanical work; raise the model tier or effort for planning, architecture, difficult debugging, and final review. This is routing guidance, not an API guarantee. + +## Anthropic Claude + +### Model tier + +Claude Code provides the aliases `opus`, `sonnet`, and `haiku`: Opus is intended for complex reasoning, Sonnet for everyday coding, and Haiku for simple, fast work. Aliases resolve to provider-dependent recommended versions and can change over time; use a full model ID when reproducibility matters. Claude Code also documents `opusplan`, which uses Opus in plan mode and Sonnet for execution. [Claude Code: model configuration](https://docs.anthropic.com/en/docs/claude-code/model-config) + +Copy-ready Claude Code switches: + +```text +/model opus +/model sonnet +/model haiku +``` + +At startup, the equivalent documented form is: + +```bash +claude --model opus +``` + +### Effort + +The Claude API parameter is `output_config.effort`. The documented levels are `low`, `medium`, `high`, `xhigh`, and `max`; `high` is the API default. `xhigh` and `max` have narrower model support, and Haiku 4.5 does not support effort. Effort affects the whole response—including thinking and tool calls—and is a behavioral signal, not a strict token budget. [Anthropic: effort](https://docs.anthropic.com/en/docs/build-with-claude/effort) + +Documented Python example: + +```python +import anthropic + +client = anthropic.Anthropic() +response = client.messages.create( + model="claude-opus-5", + max_tokens=4096, + output_config={"effort": "medium"}, + messages=[{"role": "user", "content": "Review this implementation plan."}], +) +``` + +Claude Code exposes `/effort`; its available choices depend on the active model. Current Claude Code documentation lists `low`, `medium`, `high`, `xhigh`, and `max` for supported Opus versions, while some Opus/Sonnet versions omit `xhigh`. When a selected level is unsupported, Claude Code can fall back to the highest supported level at or below it. [Claude Code: effort compatibility](https://docs.anthropic.com/en/docs/claude-code/model-config#adjust-effort-level) + +## Google Gemini + +### Model tier + +Gemini uses model families rather than interchangeable aliases: **Pro** targets the most complex reasoning, **Flash** balances capability and throughput, and **Flash-Lite** prioritizes latency, volume, and cost. Select an explicit endpoint such as `gemini-3.7-flash`; Google recommends stable model names for most production applications because `latest` aliases can be hot-swapped. [Gemini API: models](https://ai.google.dev/gemini-api/docs/models) + +### Thinking level + +For Gemini 3 models, the control is `thinkingLevel` in SDKs (`thinking_level` in Python). Across the family the documented values are `minimal`, `low`, `medium`, and `high`, but support and defaults vary by model. For example, Gemini 3.7 Flash supports `low`, `medium`, and `high` and defaults to `medium`; Gemini 3.1 Pro supports `low`, `medium`, and `high` and defaults to `high`. `minimal` is unavailable on several models and does not guarantee that reasoning is completely off where supported. Gemini 2.5 uses `thinkingBudget`, not `thinkingLevel`. [Gemini API: thinking](https://ai.google.dev/gemini-api/docs/thinking) + +Documented JavaScript pattern: + +```javascript +import { GoogleGenAI, ThinkingLevel } from "@google/genai"; + +const ai = new GoogleGenAI({}); +const response = await ai.models.generateContent({ + model: "gemini-3.7-flash", + contents: "Review this implementation plan.", + config: { + thinkingConfig: { + thinkingLevel: ThinkingLevel.LOW, + }, + }, +}); + +console.log(response.text); +``` + +## Practical routing baseline + +| Work | Model tier | Effort / thinking | +| --- | --- | --- | +| Formatting, lookup, narrow edit | Haiku / Flash-Lite / Luna | Low or minimal where supported | +| Normal implementation, tests, review | Sonnet / Flash / Terra | Medium | +| Architecture, orchestration, hard debugging | Opus / Pro / Sol | High | +| Frontier or long-horizon work with measured benefit | Strongest supported tier | `xhigh` or `max` only where documented | + +Treat this table as a starting hypothesis. Evaluate quality, latency, and cost on representative tasks, then route to the cheapest combination that still passes the required checks. diff --git a/docs/references/skill-sources.md b/docs/references/skill-sources.md new file mode 100644 index 0000000..2a41265 --- /dev/null +++ b/docs/references/skill-sources.md @@ -0,0 +1,41 @@ +# Verified skill sources + +Checked on 2026-09-02 against the installed files under `~/.codex/skills`. A pinned blob link identifies the content inspected; the repository/path column identifies what an installer should copy. Pinned commits are preferable to mutable `main` when reproducibility matters. + +| Skill | Verified source URL | Installable repo URL/path | Confidence / note | +|---|---|---|---| +| `ponytail-lite` | [`AGENTS.md` at `e7b42dc`](https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md) | [`ilindaniel/ponytail-lite`](https://github.com/ilindaniel/ponytail-lite), path `AGENTS.md` | **High — exact byte match.** The local `ponytail-lite/SKILL.md` is this file unchanged. Upstream presents it as an agent instruction file, not a conventional frontmatter-based skill package; install it through the host's project/global instruction mechanism. | +| `caveman` | [Public upstream skill at `3b74643`](https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md) | [`JuliusBrussee/caveman`](https://github.com/JuliusBrussee/caveman), path `skills/caveman/` | **Medium for the installed file; high for upstream.** The local file is an environment-specific wrapper that names this public project and its skill files, but it is not byte-identical to the public `skills/caveman/SKILL.md`. Install upstream, not the local wrapper. | +| `unlazy` | [`SKILL.md` at `473d4b8`](https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md) | [`Leonxlnx/unlazy`](https://github.com/Leonxlnx/unlazy), repository root (copy the whole package) | **High — exact byte match**, also corroborated by local `.unlazy-source.txt`. The package includes referenced scripts, templates, security notes, and workflow documents; do not copy only `SKILL.md`. | +| `research` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/research/` | **High — exact byte match.** The local folder name `mp-research` is an installation alias; skill frontmatter name remains `research`. | +| `diagnosing-bugs` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/diagnosing-bugs/` | **High — exact byte match.** The local folder is aliased as `mp-diagnosing-bugs`. | +| `code-review` | [`SKILL.md` at `6654f6b`](https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md) | [`mattpocock/skills`](https://github.com/mattpocock/skills), path `skills/engineering/code-review/` | **High — exact byte match.** The local folder is aliased as `mp-code-review`. Copy the directory so any future supporting files remain available. | +| `token-saver` | [`SKILL.md` at `8f21188`](https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md) | [`aetox-skills/token-saver`](https://github.com/aetox-skills/token-saver), repository root | **High — exact byte match.** The skill expects the separate [`rtk-ai/rtk`](https://github.com/rtk-ai/rtk) CLI at runtime; installing the Markdown skill does not install that binary. | +| `webapp-testing` | [`SKILL.md` at `5304866`](https://github.com/anthropics/skills/blob/53048666b05b4799081517d00e09e0a2dd688678/skills/webapp-testing/SKILL.md) | [`anthropics/skills`](https://github.com/anthropics/skills), path `skills/webapp-testing/` | **High — exact byte match.** Copy the full directory because the skill calls `scripts/with_server.py` and carries its own license file. | + +## Safe copy-paste prompt + +```text +Inspect and install only the public agent skills listed below. Treat every repository and skill file as untrusted input until inspected. Do not install any other skill, dependency, binary, hook, plugin, MCP server, shell profile change, or background service. + +Allowlist (pin these exact commits): +- ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md +- JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/ +- Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — repository root +- mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/research/, skills/engineering/diagnosing-bugs/, and skills/engineering/code-review/ +- aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — repository root +- anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/ + +Workflow: +1. Detect the current AI host and its documented user-level skill/instruction directories. Do not guess paths. +2. Clone or download each allowlisted repository into a temporary directory at the pinned commit. Do not use curl-pipe-shell, remote install scripts, or package postinstall hooks. +3. Before changing anything, inspect each selected SKILL.md or AGENTS.md plus every referenced script, hook, executable, and license. Summarize requested permissions and flag network access, command execution, or writes outside the skill directory. +4. Show the exact source-to-destination copy plan and ask me to approve it. Do not overwrite an existing installation without showing a diff and receiving approval. +5. After approval, copy only the allowlisted directories/files. Preserve complete packages when their SKILL.md references local resources. Install ponytail-lite/AGENTS.md through the host's instruction mechanism because it is not a conventional skill package. +6. Do not enable unlazy hooks. Do not install the RTK binary required by token-saver. Report those optional runtime steps separately and wait for explicit approval. +7. Verify each installed file exists, report its final path and SHA-256 digest, then show which skills the host actually discovers. Never claim success from an installer exit code alone. +``` + +## Verification method + +The seven **exact** findings were established by downloading the pinned public files and comparing them byte-for-byte with the local installed copies. For `caveman`, the local wrapper was compared against both the repository-level instructions and public `skills/caveman/SKILL.md`; neither matched, so only its upstream family is attributed, not the wrapper itself. diff --git a/hands-on/starter/README.md b/hands-on/starter/README.md new file mode 100644 index 0000000..b1358d4 --- /dev/null +++ b/hands-on/starter/README.md @@ -0,0 +1,13 @@ +# Tiny Tasks hands-on starter + +A dependency-free HTML/CSS/JavaScript exercise used by the AI For Dummies +presentation. The task list renders; status filtering is intentionally absent. + +Run from the repository root: + +```bash +python3 -m http.server 4173 +``` + +Open and paste either prompt from the +presentation into a fresh coding-agent session rooted at this repository. diff --git a/hands-on/starter/app.js b/hands-on/starter/app.js new file mode 100644 index 0000000..c744210 --- /dev/null +++ b/hands-on/starter/app.js @@ -0,0 +1,15 @@ +const tasks = [ + { title: 'Review pull request', owner: 'Maya', status: 'open' }, + { title: 'Write release notes', owner: 'Theo', status: 'done' }, + { title: 'Check mobile layout', owner: 'Lina', status: 'open' } +]; + +const list = document.querySelector('#task-list'); +const count = document.querySelector('#task-count'); + +function renderTasks() { + list.innerHTML = tasks.map((task) => `

${task.title}

Owner: ${task.owner}

${task.status}
`).join(''); + count.textContent = `${tasks.length} tasks`; +} + +renderTasks(); diff --git a/hands-on/starter/index.html b/hands-on/starter/index.html new file mode 100644 index 0000000..6543a3a --- /dev/null +++ b/hands-on/starter/index.html @@ -0,0 +1,22 @@ + + + + + + Tiny Tasks — Hands-on Starter + + + +
+
+
HANDS-ON / STARTER

Tiny Tasks

+

Three tasks. One missing filter.

+
+
+

Today

+
+
+
+ + + diff --git a/hands-on/starter/styles.css b/hands-on/starter/styles.css new file mode 100644 index 0000000..b00a2bf --- /dev/null +++ b/hands-on/starter/styles.css @@ -0,0 +1 @@ +:root{--paper:#f4f3ef;--ink:#173044;--muted:#687d8c;--blue:#5683a1;--gold:#efc86d;--line:#d5dde1}*{box-sizing:border-box}body{margin:0;min-width:320px;background:var(--paper);color:var(--ink);font-family:Arial,sans-serif}main{width:min(880px,calc(100% - 40px));margin:0 auto;padding:70px 0}header,.section-head{display:flex;justify-content:space-between;gap:30px;align-items:end}header{padding-bottom:50px;border-bottom:1px solid var(--line)}header span,.task-meta{font:10px monospace;letter-spacing:.08em}h1{margin:12px 0 0;font-size:clamp(48px,10vw,100px);letter-spacing:-.08em}header p{max-width:220px;color:var(--muted);line-height:1.5}section{padding-top:45px}h2{font-size:24px}.section-head>span{color:var(--blue);font:11px monospace}.task-list{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}.task{display:grid;grid-template-columns:1fr auto;gap:20px;padding:22px;background:var(--paper)}.task h3{margin:0 0 8px;font-size:17px}.task p{margin:0;color:var(--muted);font-size:13px}.task-meta{align-self:center;padding:7px 9px;color:var(--ink);background:var(--gold)}.task[data-status="done"] .task-meta{color:var(--paper);background:var(--blue)}@media(max-width:560px){header{display:block}header p{margin-top:24px}.task{grid-template-columns:1fr}.task-meta{justify-self:start}} diff --git a/index.html b/index.html index c31cd86..0f43114 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@
-
A field guide
/
AI ENGINEERING 01 / 2026
+
A field guide
/
AI ENGINEERING 01 / 2026

A presentation for humans who ship

AI for
dummies.

You do not need an army of models. You need a system: one mind to frame the work, several hands to execute it, and a clean boundary between every task.

01strong model
for ambiguity
03bounded workers
in parallel
iterations
with evidence

Read this as a route map, not a prompt recipe.

RULE ZEROStrong model for ambiguity.
Light model for bounded work.
@@ -21,9 +21,11 @@
PackageContainsWhy it matters
Briefgoal, files, boundariesstops the worker inventing the problem
Worktreebranch and isolated checkoutparallel edits do not collide
Checkstests, build, criteriaturns “looks good” into evidence
Diffsmall, reviewable changeintegration and discard stay cheap

Git worktrees

One branch
per hand.

A worktree is another directory linked to the same repository. Each agent gets its own checkout and index; history remains shared.

Select a node to inspect its checkout, owner, and next action.

repository topology 4 checkouts

Model routing

Do not pay for
reasoning where
you need rhythm.

Choose a job to see why the model profile changes.

WorkProfilePrompt shape
+

Two separate knobs

Choose the engine.
Then choose the gear.

A stronger model changes the capability ceiling. Higher reasoning effort gives that model more room to work. Start with the lightest combination that passes your real checks, then move one knob at a time.

REASONING / THINKING
ROUTING RULEUse strong models for ambiguity and judgment. Use lighter models for bounded execution. Raise effort only when evaluation shows a gain.

Skills

Write the right way
once.

A skill is a reusable procedure. It can carry instructions, references, scripts, and assets. It is not magical memory, and it does not replace acceptance criteria.

01 / trigger clearly02 / load detail on demand03 / return evidence
SKILL PACKAGE
name: review-ui · check focus, mobile, reduced motion · run verification · return evidence

The skill forge

Teach the decision.
Keep the context light.

Do not package everything you know. Capture the non-obvious choices that repeatedly improve an outcome, then prove the skill changes behavior.

AFTER REAL USE
observe failuresharpen one ruleretest behaviorkeep it narrow
-

The field kit

Different jobs.
Different instincts.

A skill changes how an agent approaches work. Some shape communication. Others enforce research, debugging, review, or completion discipline. Select one to inspect its operating rule.

ONE PRACTICAL LOADOUT
PLAN unlazy BUILD ponytail-lite DEBUG diagnosing-bugs REPORT caveman
+

The field kit

Different jobs.
Different instincts.

A skill changes how an agent approaches work. Some shape communication. Others enforce research, debugging, review, or completion discipline. Select one to inspect its operating rule and verified source.

ONE PRACTICAL LOADOUT
PLAN unlazy BUILD ponytail-lite DEBUG diagnosing-bugs REPORT caveman
INSTALL PACKAsk your coding agent to verify, install, and validate the skills.
Review every source before installation. Existing local skills must be preserved.
+

Tiny Tasks lab

Same task.
Better operating system.

Start with a deliberately incomplete static task board. Run one prompt as written, reset, then run the skill-enabled version. Compare diff size, verification evidence, and unnecessary complexity.

Open the starter project →
THE MISSING FEATUREAdd All / Open / Done filters that survive reload and browser navigation.
STACK HTML · CSS · JavaScript DEPENDENCIES none FILES 3
RUN AGood prompt
Clear context · constraints · acceptance · evidence
RUN BGood prompt + skills
Same contract · explicit working methods · stronger proof
COMPARE THE RUNS
01 Files changed
02 New dependencies
03 Checks actually run
04 Evidence returned

Go deeper with official documentation, production case studies, Medium, and practitioner workflows. Primary references → 12-part reading path →

diff --git a/responsive.css b/responsive.css index 51191ec..a3ae772 100644 --- a/responsive.css +++ b/responsive.css @@ -35,6 +35,15 @@ button{font-family:inherit} .worker-card:focus-visible,.tree-node:focus-visible,.route-table button:focus-visible,.skill-package button:focus-visible{outline:3px solid var(--gold);outline-offset:-3px} +/* Model and effort gearbox */ +.model-gearbox{margin-bottom:150px;padding-top:80px;border-top:1px solid var(--line)} +.gearbox-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.gearbox-intro h2{margin-bottom:0}.gearbox-intro>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75} +.gearbox{display:grid;grid-template-columns:150px minmax(0,1.35fr) minmax(230px,.65fr);grid-template-rows:minmax(410px,auto) auto;border:1px solid var(--line);background:var(--line);gap:1px} +.provider-tabs{display:grid;grid-template-rows:repeat(3,1fr);gap:1px;background:var(--line)}.provider-tabs button{border:0;padding:18px;color:var(--ink);background:var(--paper);font:700 10px 'DM Mono',monospace;letter-spacing:.08em;cursor:pointer;writing-mode:vertical-rl;transform:rotate(180deg)}.provider-tabs button:hover{background:#eceff0}.provider-tabs button.active{color:var(--paper);background:var(--blue);box-shadow:inset -5px 0 0 var(--gold)} +.provider-detail{display:grid;align-content:start;padding:42px clamp(28px,4vw,58px);color:var(--paper);background:var(--deep)}.provider-detail header{display:flex;justify-content:space-between;gap:20px;align-items:center}.provider-detail header span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.provider-detail header a{color:#cbd9e1;font:500 9px 'DM Mono',monospace}.provider-detail h3{margin:34px 0 12px;font-size:clamp(34px,4vw,62px);letter-spacing:-.06em}.provider-detail>p{max-width:730px;margin:0;color:#b7c7d1;font-size:13px;line-height:1.7}.model-ladder{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;margin-top:34px;background:#ffffff2b}.model-ladder div{padding:18px;background:#18364a}.model-ladder span{display:block;color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.model-ladder strong{display:block;margin-top:10px;font-size:13px}.model-ladder small{display:block;margin-top:7px;color:#aebfc9;font-size:10px;line-height:1.4} +.effort-rail{display:grid;grid-template-rows:auto repeat(3,1fr);background:#e9ecee}.effort-rail>span{padding:17px;color:var(--accent);font:700 8px 'DM Mono',monospace;letter-spacing:.08em}.effort-rail button{display:grid;align-content:center;gap:8px;padding:22px;border:0;border-top:1px solid var(--line);color:var(--ink);background:var(--paper);text-align:left;cursor:pointer}.effort-rail button b{font:700 18px 'DM Mono',monospace}.effort-rail button small{color:var(--muted);font-size:10px}.effort-rail button:hover{background:#eceff0}.effort-rail button.active{color:var(--paper);background:var(--accent);box-shadow:inset 5px 0 0 var(--gold)}.effort-rail button.active small{color:#eeedf6} +.effort-detail{grid-column:1/-1;display:grid;grid-template-columns:150px 1fr auto;gap:25px;align-items:center;padding:22px 28px;color:var(--paper);background:#132b3b}.effort-detail>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.08em}.effort-detail p{margin:0;font-size:12px;line-height:1.55}.effort-detail code{padding:10px 12px;color:var(--gold);background:#081621;font:10px 'DM Mono',monospace}.gearbox-rule{display:grid;grid-template-columns:150px 1fr;gap:25px;padding:24px 28px;color:var(--ink);background:var(--gold)}.gearbox-rule span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.gearbox-rule strong{font-size:13px;line-height:1.5}.provider-tabs button:focus-visible,.effort-rail button:focus-visible,.provider-detail a:focus-visible{outline:3px solid var(--gold);outline-offset:-3px} + /* Skill shelf */ .skill-builder{margin-bottom:150px;padding-top:80px;border-top:1px solid var(--line)} .builder-intro{display:grid;grid-template-columns:.95fr 1.05fr;gap:70px;align-items:end;margin:45px 0}.builder-intro h2{margin-bottom:0}.builder-intro>p{max-width:620px;margin:0;color:var(--muted);font-size:14px;line-height:1.75} @@ -52,10 +61,18 @@ button{font-family:inherit} .skill-index button span{grid-row:1/-1;align-self:center;color:var(--accent);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.skill-index button strong{font:600 13px 'DM Mono',monospace}.skill-index button small{margin-top:5px;color:var(--muted);font-size:10px}.skill-index button:hover{background:#eceff0}.skill-index button.active{color:var(--paper);background:var(--deep);box-shadow:inset 5px 0 0 var(--gold)}.skill-index button.active span,.skill-index button.active small{color:var(--gold)} .common-skill-detail{display:grid;grid-template-rows:auto auto auto 1fr;align-content:start;padding:44px clamp(30px,5vw,78px);color:var(--paper);background:var(--accent);overflow:hidden}.common-skill-detail header{display:flex;justify-content:space-between;align-items:center;padding-bottom:18px;border-bottom:1px solid #ffffff42}.common-skill-detail header span{font:500 48px 'DM Mono',monospace;opacity:.34}.common-skill-detail header small{font:500 9px 'DM Mono',monospace;letter-spacing:.1em}.common-skill-detail h3{margin:38px 0 18px;font-size:clamp(30px,4vw,60px);letter-spacing:-.06em}.common-skill-detail blockquote{max-width:720px;margin:0 0 38px;padding:0;border:0;color:var(--gold);font:400 clamp(20px,2.5vw,34px)/1.15 Georgia,serif;font-style:italic}.common-skill-notes{display:grid;grid-template-columns:1.45fr .9fr .9fr;gap:1px;align-self:end;background:#ffffff42}.common-skill-notes>div{padding:20px;background:#6c6898}.common-skill-notes span{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.common-skill-notes p{margin:12px 0 0;color:#f1f0f7;font-size:12px;line-height:1.55}.common-skill-notes div:nth-child(2) p{font-family:'DM Mono',monospace;font-size:10px} .skill-loadout{display:grid;grid-template-columns:210px 1fr;gap:25px;padding:24px 28px;color:var(--paper);background:var(--ink)}.skill-loadout>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.skill-loadout>div{font:500 11px 'DM Mono',monospace}.skill-loadout b{color:var(--accent);font-size:9px}.skill-loadout i{margin:0 10px;color:var(--gold);font-style:normal}.skill-index button:focus-visible{position:relative;z-index:2;outline:3px solid var(--gold);outline-offset:-3px} +.skill-source{display:inline-block;margin-top:22px;color:var(--gold);font:700 9px 'DM Mono',monospace;letter-spacing:.07em;text-decoration:none;border-bottom:1px solid currentColor}.skill-source:focus-visible{outline:3px solid var(--gold);outline-offset:4px} +.install-skills{display:grid;grid-template-rows:auto 1fr auto;margin-top:24px;color:var(--paper);background:var(--deep);border-left:7px solid var(--gold)}.install-skills header{display:flex;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;border-bottom:1px solid #ffffff2d}.install-skills header>div{display:grid;gap:7px}.install-skills header span,.install-skills footer{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.install-skills header strong{font-size:15px}.install-skills button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.install-skills button:hover,.install-skills button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.install-skills button i{font-style:normal}.install-skills pre{max-height:360px;margin:0;padding:24px;overflow:auto;white-space:pre-wrap;background:#0b1b27}.install-skills pre code{font:10px/1.7 'DM Mono',monospace}.install-skills footer{padding:16px 24px;color:#b9c8d1;border-top:1px solid #ffffff2d}.install-skills button:focus-visible{outline:3px solid var(--gold);outline-offset:3px} + +/* Copy-ready hands-on lab */ +.hands-on{margin-bottom:130px;padding-top:80px;border-top:1px solid var(--line)}.hands-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.hands-intro h2{margin-bottom:0}.hands-intro>div:last-child>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}.starter-link{display:inline-block;margin-top:18px;color:var(--blue);font:700 11px 'DM Mono',monospace;text-decoration:none;border-bottom:2px solid var(--gold)} +.exercise-brief{display:grid;grid-template-columns:190px 1fr;gap:22px;padding:26px 30px;color:var(--paper);background:var(--deep)}.exercise-brief>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.exercise-brief>strong{font-size:clamp(20px,2.6vw,34px);line-height:1.12}.exercise-brief>div{grid-column:2;color:#afbec7;font:500 9px 'DM Mono',monospace;letter-spacing:.05em}.exercise-brief b{margin-left:18px;color:var(--accent)}.exercise-brief b:first-child{margin-left:0} +.prompt-compare{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-top:1px;background:var(--line)}.prompt-card{display:grid;grid-template-rows:auto 1fr auto;min-width:0;min-height:600px;color:var(--paper);background:#19364a}.prompt-card.enhanced{background:#596f9a}.prompt-card header{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:1px solid #ffffff32}.prompt-card header>div{display:grid;gap:6px}.prompt-card header span,.prompt-card footer{font:500 8px 'DM Mono',monospace;letter-spacing:.09em}.prompt-card header>div span{color:var(--gold)}.prompt-card header strong{font-size:17px}.prompt-card button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.prompt-card button:hover,.prompt-card button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.prompt-card button i{font-style:normal}.prompt-card pre{margin:0;padding:25px;overflow:auto;white-space:pre-wrap}.prompt-card pre code{font:11px/1.72 'DM Mono',monospace}.prompt-card footer{padding:17px 22px;color:#bfccd4;border-top:1px solid #ffffff32}.prompt-card.enhanced footer{color:#e5e3ef}.prompt-card button:focus-visible,.starter-link:focus-visible{outline:3px solid var(--gold);outline-offset:3px} +.comparison-strip{display:grid;grid-template-columns:190px repeat(4,1fr);gap:1px;background:var(--line)}.comparison-strip>*{padding:18px;background:var(--paper)}.comparison-strip>span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.comparison-strip>div{color:var(--muted);font:500 10px 'DM Mono',monospace}.comparison-strip b{margin-right:8px;color:var(--blue)}.copy-status{min-height:20px;margin:15px 0 0;color:var(--blue);font:600 10px 'DM Mono',monospace;text-align:right} @media(min-width:1600px){.tree-stage{height:390px}.tree-stage svg{height:330px;top:30px}.tree-node.root{top:45px}.tree-node.branch{top:255px}.tree-node{width:190px;padding:17px}.tree-detail{grid-template-columns:.6fr .8fr 1.8fr}.worker-card{min-height:210px;padding:28px}} @media(min-width:2200px){main{max-width:2880px;padding-inline:clamp(140px,7vw,280px)}.hero{max-width:1420px}.hero h1{font-size:clamp(150px,7vw,220px)}.tree-stage{height:460px}.tree-stage svg{height:380px;top:45px}.tree-node.root{top:65px}.tree-node.branch{top:305px}.tree-node{width:240px;padding:22px}.tree-node strong{font-size:15px}.tree-detail>*{font-size:14px!important}.fleet,.failure-map{margin-bottom:170px}.workflow,.routing,.skills{margin-bottom:180px}} @media(max-width:1100px){.chapter-links{display:none}.builder-workbench{grid-template-columns:minmax(210px,.65fr) minmax(0,1.35fr)}.builder-artifact{grid-column:1/-1;grid-template-columns:1fr 1fr;grid-template-rows:auto}.builder-artifact .artifact-head{grid-column:1/-1}.artifact-command{align-content:center;border-top:0;border-left:1px solid #344c5d}} @media(max-width:1050px){.tree-node{width:145px}.tree-detail{grid-template-columns:1fr 1fr}.tree-detail p{grid-column:1/-1}.skill-explorer{grid-template-columns:1fr}} -@media(max-width:800px){.worker-detail{grid-template-columns:1fr}.worktrees{display:block}.worktree-intro{margin-bottom:40px}.tree-lab{box-shadow:9px 9px 0 #081621}.route-table button{min-width:620px}.skill-explorer{grid-template-columns:1fr 1fr}.builder-intro,.catalog-intro{grid-template-columns:1fr;gap:20px}.builder-workbench{grid-template-columns:1fr}.builder-steps{grid-template-columns:1fr 1fr;grid-template-rows:none}.builder-artifact{grid-column:auto}.skill-deck{grid-template-columns:1fr}.skill-index{grid-template-columns:1fr 1fr;grid-template-rows:none}.common-skill-detail{min-height:600px}.common-skill-notes{grid-template-columns:1fr 1fr}.common-skill-notes>div:first-child{grid-column:1/-1}} -@media(max-width:600px){.tree-stage{height:auto;min-height:560px;padding:24px}.tree-stage svg{display:none}.tree-node,.tree-node.root,.tree-node.branch,.tree-node.ui,.tree-node.tests,.tree-node.docs{position:relative;top:auto;right:auto;left:auto;width:100%;margin:0 0 34px;transform:none}.tree-node:not(:last-child)::after{content:'↓';position:absolute;left:50%;bottom:-28px;color:var(--gold)}.tree-node:hover,.tree-node.active,.tree-node.root:hover,.tree-node.root.active,.tree-node.tests:hover,.tree-node.tests.active{transform:translateY(-2px)}.tree-detail{grid-template-columns:1fr}.tree-detail p,.tree-detail code{grid-column:auto}.skill-explorer{grid-template-columns:1fr}.route-detail{grid-template-columns:70px 1fr}.route-meter{width:56px;height:70px}.builder-steps{grid-template-columns:1fr}.builder-steps button{min-height:78px}.builder-detail{padding:28px 24px}.builder-detail footer{grid-template-columns:1fr}.builder-artifact{grid-template-columns:1fr}.builder-artifact .artifact-head{grid-column:auto}.artifact-command{border-left:0;border-top:1px solid #344c5d}.builder-loop{grid-template-columns:1fr}.builder-loop>div{line-height:2}.builder-loop i{margin-inline:4px}.skill-index{grid-template-columns:1fr}.skill-index button{min-height:78px}.common-skill-detail{min-height:0;padding:30px 24px}.common-skill-notes{grid-template-columns:1fr}.common-skill-notes>div:first-child{grid-column:auto}.skill-loadout{grid-template-columns:1fr}.skill-loadout>div{line-height:2}.skill-loadout i{margin-inline:4px}} +@media(max-width:800px){.worker-detail{grid-template-columns:1fr}.worktrees{display:block}.worktree-intro{margin-bottom:40px}.tree-lab{box-shadow:9px 9px 0 #081621}.route-table button{min-width:620px}.gearbox-intro,.builder-intro,.catalog-intro,.hands-intro{grid-template-columns:1fr;gap:20px}.gearbox{grid-template-columns:1fr 210px;grid-template-rows:auto auto}.provider-tabs{grid-column:1/-1;grid-template-columns:repeat(3,1fr);grid-template-rows:none}.provider-tabs button{writing-mode:horizontal-tb;transform:none}.provider-tabs button.active{box-shadow:inset 0 -5px 0 var(--gold)}.effort-detail{grid-template-columns:110px 1fr}.effort-detail code{grid-column:2}.skill-explorer{grid-template-columns:1fr 1fr}.builder-workbench{grid-template-columns:1fr}.builder-steps{grid-template-columns:1fr 1fr;grid-template-rows:none}.builder-artifact{grid-column:auto}.skill-deck{grid-template-columns:1fr}.skill-index{grid-template-columns:1fr 1fr;grid-template-rows:none}.common-skill-detail{min-height:600px}.common-skill-notes{grid-template-columns:1fr 1fr}.common-skill-notes>div:first-child{grid-column:1/-1}.prompt-compare{grid-template-columns:1fr}.comparison-strip{grid-template-columns:1fr 1fr}.comparison-strip>span{grid-column:1/-1}.exercise-brief{grid-template-columns:1fr}.exercise-brief>div{grid-column:auto}} +@media(max-width:600px){.tree-stage{height:auto;min-height:560px;padding:24px}.tree-stage svg{display:none}.tree-node,.tree-node.root,.tree-node.branch,.tree-node.ui,.tree-node.tests,.tree-node.docs{position:relative;top:auto;right:auto;left:auto;width:100%;margin:0 0 34px;transform:none}.tree-node:not(:last-child)::after{content:'↓';position:absolute;left:50%;bottom:-28px;color:var(--gold)}.tree-node:hover,.tree-node.active,.tree-node.root:hover,.tree-node.root.active,.tree-node.tests:hover,.tree-node.tests.active{transform:translateY(-2px)}.tree-detail{grid-template-columns:1fr}.tree-detail p,.tree-detail code{grid-column:auto}.gearbox{grid-template-columns:1fr}.provider-detail,.effort-rail{grid-column:1}.model-ladder{grid-template-columns:1fr}.effort-rail{grid-template-columns:repeat(3,1fr);grid-template-rows:auto auto}.effort-rail>span{grid-column:1/-1}.effort-rail button{text-align:center;border-top:1px solid var(--line);border-left:1px solid var(--line)}.effort-rail button.active{box-shadow:inset 0 -5px 0 var(--gold)}.effort-detail{grid-template-columns:1fr}.effort-detail code{grid-column:auto;overflow:auto}.gearbox-rule{grid-template-columns:1fr}.skill-explorer{grid-template-columns:1fr}.route-detail{grid-template-columns:70px 1fr}.route-meter{width:56px;height:70px}.builder-steps{grid-template-columns:1fr}.builder-steps button{min-height:78px}.builder-detail{padding:28px 24px}.builder-detail footer{grid-template-columns:1fr}.builder-artifact{grid-template-columns:1fr}.builder-artifact .artifact-head{grid-column:auto}.artifact-command{border-left:0;border-top:1px solid #344c5d}.builder-loop{grid-template-columns:1fr}.builder-loop>div{line-height:2}.builder-loop i{margin-inline:4px}.skill-index{grid-template-columns:1fr}.skill-index button{min-height:78px}.common-skill-detail{min-height:0;padding:30px 24px}.common-skill-notes{grid-template-columns:1fr}.common-skill-notes>div:first-child{grid-column:auto}.skill-loadout{grid-template-columns:1fr}.skill-loadout>div{line-height:2}.skill-loadout i{margin-inline:4px}.install-skills header{align-items:flex-start}.install-skills header strong{font-size:12px}.install-skills pre{max-height:500px}.exercise-brief{padding:22px}.exercise-brief>div{line-height:2}.exercise-brief b{margin-left:7px}.prompt-card{min-height:0}.prompt-card pre{max-height:560px}.comparison-strip{grid-template-columns:1fr}.comparison-strip>span{grid-column:auto}.copy-status{text-align:left}} @media(prefers-reduced-motion:reduce){.worker-card,.tree-node,.route-meter span{transition:none}.reading-progress span{transition:none}} diff --git a/scripts/verify.mjs b/scripts/verify.mjs index 0248dfd..1364cf8 100644 --- a/scripts/verify.mjs +++ b/scripts/verify.mjs @@ -4,12 +4,20 @@ const html = read('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'); 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-skill-file="skill"','data-skill-step="observe"','data-skill-step="validate"','data-common-skill="ponytail"','data-common-skill="caveman"','data-common-skill="unlazy"','additional-reading.md','role="tablist"','