429b4e2e87
Two defects the order-sensitive rendered-text diff surfaced. Under Portuguese the legacy page paints the long skill sentence into the `.skills` eyebrow, above the heading, because its `.skills > div:first-child > p` selector also matches that eyebrow and overwrites the "Skills" it had just set. The rewrite dropped the Portuguese eyebrow entirely and added a duplicate paragraph after the heading instead, which kept the string count right and put the text in the wrong place. Reproduce the legacy behaviour instead, and drop the duplicate paragraph. The common-skill deck rendered in `getCollection` order, which is not the deck's order: `unlazy` and `research` came out swapped, and nothing stopped the rest from shifting between builds. Sort by the card number so the tabs stay 01..07 as the legacy page has them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1419 lines
58 KiB
TypeScript
1419 lines
58 KiB
TypeScript
---
|
||
// /full-guide/ — assembled from typed guide collections and the task 10 blocks.
|
||
// This route deliberately never imports the legacy full-guide HTML: task 20 removes
|
||
// that tree, and both locales must be present in the server-rendered document.
|
||
import { getCollection } from 'astro:content';
|
||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||
import FleetDiagram from '../components/blocks/FleetDiagram.astro';
|
||
import HandoffTable from '../components/blocks/HandoffTable.astro';
|
||
import PhasePanel from '../components/blocks/PhasePanel.astro';
|
||
import RouteTable from '../components/blocks/RouteTable.astro';
|
||
import SkillPackage from '../components/blocks/SkillPackage.astro';
|
||
import WorktreeMap from '../components/blocks/WorktreeMap.astro';
|
||
import CopyPrompt from '../components/islands/CopyPrompt.astro';
|
||
import GuideSelector from '../components/islands/GuideSelector.astro';
|
||
import LanguageToggle from '../components/islands/LanguageToggle.astro';
|
||
import ReadingProgress from '../components/islands/ReadingProgress.astro';
|
||
import '../../styles.css';
|
||
import '../../responsive.css';
|
||
import '../../full-guide/audit.css';
|
||
|
||
type Entry<T extends { id: string }> = { data: T };
|
||
const toRecord = <T extends { id: string }>(entries: Entry<T>[]) =>
|
||
Object.fromEntries(entries.map(({ data }) => [data.id, data]));
|
||
const [
|
||
phaseEntries,
|
||
workerEntries,
|
||
treeEntries,
|
||
routeEntries,
|
||
providerEntries,
|
||
effortEntries,
|
||
skillFileEntries,
|
||
workflowEntries,
|
||
commonSkillEntries,
|
||
promptEntries,
|
||
installEntries,
|
||
] = await Promise.all([
|
||
getCollection('phases'),
|
||
getCollection('workers'),
|
||
getCollection('trees'),
|
||
getCollection('routes'),
|
||
getCollection('providers'),
|
||
getCollection('efforts'),
|
||
getCollection('skillFiles'),
|
||
getCollection('skillWorkflow'),
|
||
getCollection('commonSkills'),
|
||
getCollection('handsOnPrompts'),
|
||
getCollection('skillInstallPrompts'),
|
||
]);
|
||
const phases = toRecord(phaseEntries);
|
||
const workers = toRecord(workerEntries);
|
||
const trees = toRecord(treeEntries);
|
||
const routes = toRecord(routeEntries);
|
||
const providers = toRecord(providerEntries);
|
||
const efforts = toRecord(effortEntries);
|
||
const skillFiles = toRecord(skillFileEntries);
|
||
const skillWorkflow = toRecord(workflowEntries);
|
||
const commonSkills = toRecord(commonSkillEntries);
|
||
const sortedCommonSkills = Object.values(commonSkills).sort((a, b) =>
|
||
a.number.localeCompare(b.number),
|
||
);
|
||
const handsOn = promptEntries.find(({ data }) => data.id === 'tiny-tasks')?.data;
|
||
const install = installEntries.find(({ data }) => data.id === 'install')?.data;
|
||
if (!handsOn || !install) throw new Error('full-guide content collections are incomplete');
|
||
|
||
// Selector chrome is page-specific, so it remains an inline bilingual constant.
|
||
const labels = {
|
||
context: { en: 'context: isolated', pt: 'contexto: isolado' },
|
||
owner: { en: 'OWNER', pt: 'RESPONSÁVEL' },
|
||
reasoningLoad: { en: 'REASONING LOAD', pt: 'CARGA DE RACIOCÍNIO' },
|
||
officialSource: { en: 'OFFICIAL SOURCE ↗', pt: 'FONTE OFICIAL ↗' },
|
||
skillFileHint: {
|
||
en: 'select another file to explore',
|
||
pt: 'clique em outro arquivo para explorar',
|
||
},
|
||
workflow: {
|
||
question: { en: 'QUESTION', pt: 'PERGUNTA' },
|
||
action: { en: 'ACTION', pt: 'AÇÃO' },
|
||
artifact: { en: 'ARTIFACT', pt: 'ARTEFATO' },
|
||
proof: { en: 'PROOF', pt: 'PROVA' },
|
||
},
|
||
commonSkill: {
|
||
whenToUse: { en: 'WHEN TO USE', pt: 'QUANDO USAR' },
|
||
example: { en: 'EXAMPLE', pt: 'EXEMPLO' },
|
||
watchOut: { en: 'WATCH OUT', pt: 'CUIDADO' },
|
||
source: { en: 'GITHUB SOURCE ↗', pt: 'FONTE NO GITHUB ↗' },
|
||
},
|
||
};
|
||
const builderSteps: Record<
|
||
string,
|
||
{ title: { en: string; pt: string }; tagline: { en: string; pt: string } }
|
||
> = {
|
||
observe: {
|
||
title: { en: 'Observe', pt: 'Observar' },
|
||
tagline: { en: 'find repeated friction', pt: 'encontre atrito repetido' },
|
||
},
|
||
trigger: {
|
||
title: { en: 'Define trigger', pt: 'Definir gatilho' },
|
||
tagline: { en: 'route precisely', pt: 'roteie com precisão' },
|
||
},
|
||
scaffold: {
|
||
title: { en: 'Choose anatomy', pt: 'Escolher anatomia' },
|
||
tagline: { en: 'only needed files', pt: 'apenas arquivos necessários' },
|
||
},
|
||
write: {
|
||
title: { en: 'Write guidance', pt: 'Escrever orientação' },
|
||
tagline: { en: 'decisions, not trivia', pt: 'decisões, não trivialidades' },
|
||
},
|
||
validate: {
|
||
title: { en: 'Validate', pt: 'Validar' },
|
||
tagline: { en: 'test real behavior', pt: 'teste comportamento real' },
|
||
},
|
||
};
|
||
const selectorData = {
|
||
phases,
|
||
workers,
|
||
trees,
|
||
routes,
|
||
providers,
|
||
efforts,
|
||
skillFiles,
|
||
skillWorkflow,
|
||
commonSkills,
|
||
labels,
|
||
};
|
||
const workerCards = [
|
||
{
|
||
id: 'ui',
|
||
label: 'UI',
|
||
strong: { en: 'Component and visual states', pt: 'Componentes e estados visuais' },
|
||
code: 'agent/ui',
|
||
},
|
||
{
|
||
id: 'tests',
|
||
label: 'TEST',
|
||
strong: { en: 'Acceptance cases', pt: 'Casos de aceitação' },
|
||
code: 'agent/tests',
|
||
},
|
||
{
|
||
id: 'docs',
|
||
label: 'DOCS',
|
||
strong: { en: 'Guide and examples', pt: 'Guia e exemplos' },
|
||
code: 'agent/docs',
|
||
},
|
||
];
|
||
const treeBranches = [
|
||
{
|
||
id: 'ui',
|
||
label: { en: 'UI AGENT', pt: 'AGENTE DE UI' },
|
||
strong: 'agent/ui',
|
||
small: { en: '3 files · working', pt: '3 arquivos · trabalhando' },
|
||
tone: 'ui',
|
||
},
|
||
{
|
||
id: 'tests',
|
||
label: { en: 'TEST AGENT', pt: 'AGENTE DE TESTES' },
|
||
strong: 'agent/tests',
|
||
small: { en: '8 checks · ready', pt: '8 verificações · pronto' },
|
||
tone: 'tests',
|
||
},
|
||
{
|
||
id: 'docs',
|
||
label: { en: 'DOCS AGENT', pt: 'AGENTE DE DOCS' },
|
||
strong: 'agent/docs',
|
||
small: { en: '2 pages · review', pt: '2 páginas · revisão' },
|
||
tone: 'docs',
|
||
},
|
||
];
|
||
const base = import.meta.env.BASE_URL;
|
||
---
|
||
|
||
<BaseLayout
|
||
title="AI For Dummies — Field Guide"
|
||
description="AI For Dummies: a field guide to skills, models, subagents, and worktrees."
|
||
>
|
||
<ReadingProgress />
|
||
<main id="full-guide">
|
||
<header class="topbar">
|
||
<a class="brand" href="#top"><span class="mark">A</span> field guide</a>
|
||
<nav class="chapter-links" aria-label="Chapter sections">
|
||
<a href="#fleet"
|
||
><span data-language-content="en">01 fleet</span><span data-language-content="pt" hidden
|
||
>01 frota</span
|
||
></a
|
||
><a href="#worktrees"
|
||
><span data-language-content="en">02 worktrees</span><span
|
||
data-language-content="pt"
|
||
hidden>02 worktrees</span
|
||
></a
|
||
><a href="#models"
|
||
><span data-language-content="en">03 models</span><span data-language-content="pt" hidden
|
||
>03 modelos</span
|
||
></a
|
||
><a href="#skills"
|
||
><span data-language-content="en">04 skills</span><span data-language-content="pt" hidden
|
||
>04 skills</span
|
||
></a
|
||
><a href="#create-skill"
|
||
><span data-language-content="en">05 create</span><span data-language-content="pt" hidden
|
||
>05 criar</span
|
||
></a
|
||
><a href="#field-kit"
|
||
><span data-language-content="en">06 field kit</span><span
|
||
data-language-content="pt"
|
||
hidden>06 kit de campo</span
|
||
></a
|
||
><a href="#hands-on"
|
||
><span data-language-content="en">07 hands-on</span><span
|
||
data-language-content="pt"
|
||
hidden>07 prática</span
|
||
></a
|
||
><a href="#verification">08 verify</a>
|
||
</nav>
|
||
<div class="topbar-tools">
|
||
<a class="skills-review-link" href={`${base}skills-review/`}>review submissions ↗</a
|
||
><LanguageToggle /><span class="edition"
|
||
><span data-language-content="en">AI ENGINEERING <i></i> 01 / 2026</span><span
|
||
data-language-content="pt"
|
||
hidden>ENGENHARIA DE IA <i></i> 01 / 2026</span
|
||
></span
|
||
>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="hero" id="top" data-language-content="en">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">A presentation for humans who ship</span><span
|
||
data-language-content="pt"
|
||
hidden>Uma apresentação para quem entrega software</span
|
||
>
|
||
</p><h1>
|
||
AI for<br /><em>dummies.</em>
|
||
</h1><p class="lede">
|
||
<span data-language-content="en"
|
||
>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.</span
|
||
>
|
||
<span data-language-content="pt" hidden
|
||
>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.</span
|
||
>
|
||
</p>
|
||
</div><aside class="hero-index">
|
||
<span
|
||
><span data-language-content="en">FIELD NOTE / 001</span><span
|
||
data-language-content="pt"
|
||
hidden>NOTA DE CAMPO / 001</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en">Ship the<br /><em>system.</em></span><span
|
||
data-language-content="pt"
|
||
hidden>Entregue o<br /><em>sistema.</em></span
|
||
></strong
|
||
><small
|
||
><span data-language-content="en">Skills · agents · worktrees · proof</span><span
|
||
data-language-content="pt"
|
||
hidden>Skills · agentes · worktrees · evidências</span
|
||
></small
|
||
>
|
||
</aside>
|
||
</section>
|
||
<section class="hero" id="top-pt" data-language-content="pt" hidden>
|
||
<div>
|
||
<p class="eyebrow">Uma apresentação para quem entrega software</p><h1>
|
||
AI for<br /><em>dummies.</em>
|
||
</h1><p class="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.
|
||
</p>
|
||
</div><aside class="hero-index">
|
||
<span>NOTA DE CAMPO / 001</span><strong>Entregue o<br /><em>sistema.</em></strong><small
|
||
>Skills · agentes · worktrees · evidências</small
|
||
>
|
||
</aside>
|
||
</section>
|
||
|
||
<section class="hero-stats" aria-label="Chapter summary" data-language-content="en">
|
||
<div>
|
||
<strong>01</strong><span
|
||
><span data-language-content="en">strong model<br />for ambiguity</span><span
|
||
data-language-content="pt"
|
||
hidden>modelo forte<br />para ambiguidade</span
|
||
></span
|
||
>
|
||
</div><div>
|
||
<strong>03</strong><span
|
||
><span data-language-content="en">bounded workers<br />in parallel</span><span
|
||
data-language-content="pt"
|
||
hidden>workers delimitados<br />em paralelo</span
|
||
></span
|
||
>
|
||
</div><div>
|
||
<strong>∞</strong><span
|
||
><span data-language-content="en">iterations<br />with evidence</span><span
|
||
data-language-content="pt"
|
||
hidden>iterações<br />com evidências</span
|
||
></span
|
||
>
|
||
</div><p>
|
||
<span data-language-content="en">Read this as a route map, not a prompt recipe.</span><span
|
||
data-language-content="pt"
|
||
hidden>Leia isto como um mapa de rota, não como uma receita de prompt.</span
|
||
>
|
||
</p>
|
||
</section>
|
||
<section class="hero-stats" aria-label="Resumo dos capítulos" data-language-content="pt" hidden>
|
||
<div><strong>01</strong><span>modelo forte<br />para ambiguidade</span></div><div>
|
||
<strong>03</strong><span>workers delimitados<br />em paralelo</span>
|
||
</div><div><strong>∞</strong><span>iterações<br />com evidências</span></div><p>
|
||
Leia isto como um mapa de rota, não como uma receita de prompt.
|
||
</p>
|
||
</section>
|
||
|
||
<section class="thesis" data-language-content="en">
|
||
<div>
|
||
<span
|
||
><span data-language-content="en">RULE ZERO</span><span data-language-content="pt" hidden
|
||
>REGRA ZERO</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en"
|
||
>Strong model for ambiguity.<br />Light model for bounded work.</span
|
||
><span data-language-content="pt" hidden
|
||
>Modelo forte para ambiguidade.<br />Modelo leve para trabalho delimitado.</span
|
||
></strong
|
||
>
|
||
</div><div class="signal" aria-hidden="true">
|
||
<b>THINK</b><i></i><i></i><i></i><b>MAKE</b>
|
||
</div>
|
||
</section>
|
||
<section class="thesis" data-language-content="pt" hidden>
|
||
<div>
|
||
<span>REGRA ZERO</span><strong
|
||
>Modelo forte para ambiguidade.<br />Modelo leve para trabalho delimitado.</strong
|
||
>
|
||
</div><div class="signal" aria-hidden="true">
|
||
<b>THINK</b><i></i><i></i><i></i><b>MAKE</b>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="fleet" id="fleet">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">A small fleet</span><span
|
||
data-language-content="pt"
|
||
hidden>Uma pequena frota</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">coordination before parallelism</span><span
|
||
data-language-content="pt"
|
||
hidden>coordenação antes do paralelismo</span
|
||
></span
|
||
>
|
||
</div><FleetDiagram
|
||
orchestrator={{
|
||
eyebrow: { en: 'ORCHESTRATOR', pt: 'ORQUESTRADOR' },
|
||
title: {
|
||
en: 'Decides what<br />needs to happen.',
|
||
pt: 'Decide o que<br />precisa acontecer.',
|
||
},
|
||
code: 'Opus / reasoning',
|
||
}}
|
||
workers={workerCards}
|
||
/><div class="worker-detail" id="worker-detail" aria-live="polite">
|
||
<span>{workers.ui.en[0]}</span><strong>{workers.ui.en[1]}</strong><small
|
||
>{workers.ui.en[2]}</small
|
||
>
|
||
</div><p class="caption">
|
||
<span data-language-content="en"
|
||
>The orchestrator preserves intent, writes small contracts, and gathers results that can
|
||
be verified. It does not need to type every line.</span
|
||
><span data-language-content="pt" hidden
|
||
>O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados
|
||
verificáveis. Ele não precisa digitar cada linha.</span
|
||
>
|
||
</p>
|
||
</section>
|
||
<section class="failure-map">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Why the boundary matters</span><span
|
||
data-language-content="pt"
|
||
hidden>Por que a fronteira importa</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">one vague task / three predictable failures</span><span
|
||
data-language-content="pt"
|
||
hidden>uma tarefa vaga / três falhas previsíveis</span
|
||
></span
|
||
>
|
||
</div><div class="failure-grid">
|
||
<article>
|
||
<span>01</span><strong
|
||
><span data-language-content="en">Context soup</span><span
|
||
data-language-content="pt"
|
||
hidden>Sopa de contexto</span
|
||
></strong
|
||
><p>
|
||
<span data-language-content="en"
|
||
>Every worker reads everything. Nobody knows which facts are load-bearing.</span
|
||
><span data-language-content="pt" hidden
|
||
>Cada worker lê tudo. Ninguém sabe quais fatos são essenciais.</span
|
||
>
|
||
</p>
|
||
</article><article>
|
||
<span>02</span><strong
|
||
><span data-language-content="en">Branch collision</span><span
|
||
data-language-content="pt"
|
||
hidden>Colisão de branches</span
|
||
></strong
|
||
><p>
|
||
<span data-language-content="en"
|
||
>Two agents touch the same checkout. The fastest path becomes conflict resolution.</span
|
||
><span data-language-content="pt" hidden
|
||
>Dois agentes usam o mesmo checkout. O caminho mais rápido vira resolução de
|
||
conflitos.</span
|
||
>
|
||
</p>
|
||
</article><article>
|
||
<span>03</span><strong
|
||
><span data-language-content="en">Confident drift</span><span
|
||
data-language-content="pt"
|
||
hidden>Desvio confiante</span
|
||
></strong
|
||
><p>
|
||
<span data-language-content="en"
|
||
>The diff is polished, but no one checks whether it solved the original problem.</span
|
||
><span data-language-content="pt" hidden
|
||
>O diff parece ótimo, mas ninguém verifica se resolveu o problema original.</span
|
||
>
|
||
</p>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="workflow" aria-labelledby="workflow-title">
|
||
<div class="copy">
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">The subagent loop</span><span
|
||
data-language-content="pt"
|
||
hidden>O ciclo de subagentes</span
|
||
>
|
||
</p><h2 id="workflow-title">
|
||
<span data-language-content="en">Click a phase.<br /><em>See the handoff.</em></span><span
|
||
data-language-content="pt"
|
||
hidden>Clique em uma fase.<br /><em>Veja a passagem.</em></span
|
||
>
|
||
</h2><!-- The legacy PT render paints this paragraph twice; preserve that output. -->
|
||
<p>
|
||
<span data-language-content="en"
|
||
>Delegation means moving one bounded task into a smaller context—not giving away
|
||
responsibility.</span
|
||
><span data-language-content="pt" hidden
|
||
>Delegar é mover uma tarefa delimitada para um contexto menor — não abrir mão da
|
||
responsabilidade.</span
|
||
>
|
||
</p>
|
||
</div><PhasePanel
|
||
phases={[
|
||
{
|
||
id: 'plan',
|
||
label: 'PLAN',
|
||
number: '01',
|
||
title: phases.plan.title.en,
|
||
body: phases.plan.copy.en,
|
||
meta: { deliverable: phases.plan.model.en, gate: labels.context.en },
|
||
evidence: phases.plan.code.en,
|
||
},
|
||
{
|
||
id: 'build',
|
||
label: 'BUILD',
|
||
number: '02',
|
||
title: phases.build.title.en,
|
||
body: phases.build.copy.en,
|
||
meta: { deliverable: phases.build.model.en, gate: labels.context.en },
|
||
evidence: phases.build.code.en,
|
||
},
|
||
{
|
||
id: 'review',
|
||
label: 'REVIEW',
|
||
number: '03',
|
||
title: phases.review.title.en,
|
||
body: phases.review.copy.en,
|
||
meta: { deliverable: phases.review.model.en, gate: labels.context.en },
|
||
evidence: phases.review.code.en,
|
||
},
|
||
]}
|
||
/>
|
||
</section>
|
||
<section class="handoff">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">What crosses contexts</span><span
|
||
data-language-content="pt"
|
||
hidden>O que atravessa contextos</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">brief → diff → evidence</span><span
|
||
data-language-content="pt"
|
||
hidden>brief → diff → evidência</span
|
||
></span
|
||
>
|
||
</div><HandoffTable
|
||
columns={[
|
||
{ en: 'Package', pt: 'Pacote' },
|
||
{ en: 'Contains', pt: 'Contém' },
|
||
{ en: 'Why it matters', pt: 'Por que importa' },
|
||
]}
|
||
rows={[
|
||
{
|
||
package: 'Brief',
|
||
contains: 'goal, files, boundaries',
|
||
why: 'stops the worker inventing the problem',
|
||
},
|
||
{
|
||
package: 'Worktree',
|
||
contains: 'branch and isolated checkout',
|
||
why: 'parallel edits do not collide',
|
||
},
|
||
{
|
||
package: 'Checks',
|
||
contains: 'tests, build, criteria',
|
||
why: 'turns “looks good” into evidence',
|
||
},
|
||
{
|
||
package: 'Diff',
|
||
contains: 'small, reviewable change',
|
||
why: 'integration and discard stay cheap',
|
||
},
|
||
]}
|
||
/>
|
||
</section>
|
||
|
||
<section class="worktrees" id="worktrees">
|
||
<div class="worktree-intro">
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">Git worktrees</span><span
|
||
data-language-content="pt"
|
||
hidden>Git worktrees</span
|
||
>
|
||
</p><h2>
|
||
<span data-language-content="en">One branch<br />per <em>hand.</em></span><span
|
||
data-language-content="pt"
|
||
hidden>Uma branch<br />por <em>mão.</em></span
|
||
>
|
||
</h2><p>
|
||
<span data-language-content="en"
|
||
>A worktree is another directory linked to the same repository. Each agent gets its own
|
||
checkout and index; history remains shared.</span
|
||
><span data-language-content="pt" hidden
|
||
>Um worktree é outro diretório ligado ao mesmo repositório. Cada agente recebe seu
|
||
próprio checkout e índice; o histórico continua compartilhado.</span
|
||
>
|
||
</p><p class="interaction-hint">
|
||
<span data-language-content="en"
|
||
>Select a node to inspect its checkout, owner, and next action.</span
|
||
><span data-language-content="pt" hidden
|
||
>Selecione um nó para inspecionar checkout, responsável e próxima ação.</span
|
||
>
|
||
</p>
|
||
</div><div class="tree-lab">
|
||
<div class="tree-toolbar">
|
||
<span
|
||
><span data-language-content="en">repository topology</span><span
|
||
data-language-content="pt"
|
||
hidden>topologia do repositório</span
|
||
></span
|
||
><span class="tree-live"
|
||
><span data-language-content="en"><i></i> 4 checkouts</span><span
|
||
data-language-content="pt"
|
||
hidden><i></i> 4 checkouts</span
|
||
></span
|
||
>
|
||
</div><WorktreeMap
|
||
branches={treeBranches}
|
||
rootLabel={{ en: 'ROOT', pt: 'RAIZ' }}
|
||
rootSmall={{ en: '● clean', pt: '● limpo' }}
|
||
/><article class="tree-detail" id="tree-detail" aria-live="polite">
|
||
<div><span>{labels.owner.en}</span><strong>{trees.main.owner.en}</strong></div><div>
|
||
<span>CHECKOUT</span><strong>{trees.main.path}</strong>
|
||
</div><p>{trees.main.note.en}</p><code>{trees.main.command}</code>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="routing">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">Model routing</span><span
|
||
data-language-content="pt"
|
||
hidden>Roteamento de modelos</span
|
||
>
|
||
</p><h2>
|
||
<span data-language-content="en"
|
||
>Do not pay for<br />reasoning where<br />you need <em>rhythm.</em></span
|
||
><span data-language-content="pt" hidden
|
||
>Não pague por<br />raciocínio onde precisa<br />de <em>ritmo.</em></span
|
||
>
|
||
</h2><p class="interaction-hint">
|
||
<span data-language-content="en">Choose a job to see why the model profile changes.</span
|
||
><span data-language-content="pt" hidden
|
||
>Escolha um trabalho para entender por que o perfil do modelo muda.</span
|
||
>
|
||
</p>
|
||
</div><div class="route-console">
|
||
<RouteTable
|
||
headWork={{ en: 'Work', pt: 'Trabalho' }}
|
||
headProfile={{ en: 'Profile', pt: 'Perfil' }}
|
||
headPromptShape={{ en: 'Prompt shape', pt: 'Formato do prompt' }}
|
||
routes={[
|
||
{
|
||
id: 'plan',
|
||
strong: { en: 'Plan', pt: 'Planejar' },
|
||
profile: 'strong / broad',
|
||
prompt: 'What changes? What can break?',
|
||
},
|
||
{
|
||
id: 'build',
|
||
strong: { en: 'Build', pt: 'Construir' },
|
||
profile: 'fast / focused',
|
||
prompt: 'Implement this slice. Run these checks.',
|
||
},
|
||
{
|
||
id: 'explore',
|
||
strong: { en: 'Explore', pt: 'Explorar' },
|
||
profile: 'read-only / light',
|
||
prompt: 'Find where this contract is used.',
|
||
},
|
||
{
|
||
id: 'review',
|
||
strong: { en: 'Review', pt: 'Revisar' },
|
||
profile: 'independent',
|
||
prompt: 'Does the diff satisfy the brief?',
|
||
},
|
||
]}
|
||
/><article class="route-detail" id="route-detail" aria-live="polite">
|
||
<div class="route-meter"><span style={`--score:${routes.plan.score}%`}></span></div><div>
|
||
<small>{labels.reasoningLoad.en} · {routes.plan.score}</small><strong
|
||
>{routes.plan.label.en}</strong
|
||
><p>{routes.plan.why.en}</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="model-gearbox" id="models">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Model gearbox</span><span
|
||
data-language-content="pt"
|
||
hidden>Câmbio de modelos</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">capability tier × thinking effort</span><span
|
||
data-language-content="pt"
|
||
hidden>nível de capacidade × esforço de raciocínio</span
|
||
></span
|
||
>
|
||
</div>
|
||
<div class="gearbox-intro">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">Two separate knobs</span><span
|
||
data-language-content="pt"
|
||
hidden>Dois controles separados</span
|
||
>
|
||
</p>
|
||
<h2>
|
||
<span data-language-content="en"
|
||
>Choose the engine.<br />Then choose the <em>gear.</em></span
|
||
><span data-language-content="pt" hidden
|
||
>Escolha o motor.<br />Depois escolha a <em>marcha.</em></span
|
||
>
|
||
</h2>
|
||
</div>
|
||
<p>
|
||
<span data-language-content="en"
|
||
>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.</span
|
||
><span data-language-content="pt" hidden
|
||
>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.</span
|
||
>
|
||
</p>
|
||
</div>
|
||
<div class="gearbox">
|
||
<div class="provider-tabs" role="tablist" aria-label="Model providers">
|
||
<button class="active" data-model-provider="openai" role="tab" aria-selected="true"
|
||
>OPENAI</button
|
||
><button data-model-provider="claude" role="tab" aria-selected="false">CLAUDE</button
|
||
><button data-model-provider="gemini" role="tab" aria-selected="false">GEMINI</button>
|
||
</div><article class="provider-detail" id="provider-detail" aria-live="polite">
|
||
<header>
|
||
<span>{providers.openai.label}</span><a
|
||
href={providers.openai.source}
|
||
target="_blank"
|
||
rel="noopener">{labels.officialSource.en}</a
|
||
>
|
||
</header><h3>{providers.openai.title.en}</h3><p>{providers.openai.copy.en}</p>
|
||
</article><div class="effort-rail" role="tablist" aria-label="Reasoning effort">
|
||
<span
|
||
><span data-language-content="en">REASONING / THINKING</span><span
|
||
data-language-content="pt"
|
||
hidden>RACIOCÍNIO / PENSAMENTO</span
|
||
></span
|
||
>
|
||
<button data-effort="low" role="tab" aria-selected="false"
|
||
><b
|
||
><span data-language-content="en">LOW</span><span data-language-content="pt" hidden
|
||
>BAIXO</span
|
||
></b
|
||
><small
|
||
><span data-language-content="en">bounded + fast</span><span
|
||
data-language-content="pt"
|
||
hidden>delimitado + rápido</span
|
||
></small
|
||
></button
|
||
><button class="active" data-effort="medium" role="tab" aria-selected="true"
|
||
><b
|
||
><span data-language-content="en">MEDIUM</span><span data-language-content="pt" hidden
|
||
>MÉDIO</span
|
||
></b
|
||
><small
|
||
><span data-language-content="en">default start</span><span
|
||
data-language-content="pt"
|
||
hidden>ponto inicial</span
|
||
></small
|
||
></button
|
||
><button data-effort="high" role="tab" aria-selected="false"
|
||
><b
|
||
><span data-language-content="en">HIGH</span><span data-language-content="pt" hidden
|
||
>ALTO</span
|
||
></b
|
||
><small
|
||
><span data-language-content="en">complex + costly</span><span
|
||
data-language-content="pt"
|
||
hidden>complexo + custoso</span
|
||
></small
|
||
></button
|
||
>
|
||
</div><article class="effort-detail" id="effort-detail" aria-live="polite">
|
||
<span>{efforts.medium.en[0]}</span><p>{efforts.medium.en[1]}</p><code
|
||
>{providers.openai.config}</code
|
||
>
|
||
</article>
|
||
</div>
|
||
<div class="gearbox-rule">
|
||
<span
|
||
><span data-language-content="en">ROUTING RULE</span><span
|
||
data-language-content="pt"
|
||
hidden>REGRA DE ROTEAMENTO</span
|
||
></span
|
||
>
|
||
<strong
|
||
><span data-language-content="en"
|
||
>Use strong models for ambiguity and judgment. Use lighter models for bounded execution.
|
||
Raise effort only when evaluation shows a gain.</span
|
||
><span data-language-content="pt" hidden
|
||
>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.</span
|
||
></strong
|
||
>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="skills" id="skills">
|
||
<div>
|
||
<p class="eyebrow">
|
||
{
|
||
/* Under Portuguese the legacy page paints the long skill sentence
|
||
here, not "Skills": its `.skills > div:first-child > p` selector
|
||
also matches this eyebrow and overwrites it. Reproduced on
|
||
purpose -- see .agents/rules/content-i18n.md. */
|
||
}
|
||
<span data-language-content="en">Skills</span><span data-language-content="pt" hidden
|
||
>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
|
||
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span
|
||
>
|
||
</p><h2>
|
||
<span data-language-content="en">Write the right way<br /><em>once.</em></span><span
|
||
data-language-content="pt"
|
||
hidden>Escreva do jeito certo<br /><em>uma vez.</em></span
|
||
>
|
||
</h2><p>
|
||
<span data-language-content="en"
|
||
>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.</span
|
||
>
|
||
<span data-language-content="pt" hidden
|
||
>Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências,
|
||
scripts e assets. Não é memória mágica e não substitui critérios de aceitação.</span
|
||
>
|
||
</p><div class="skill-principles">
|
||
<span data-language-content="en">01 / trigger clearly</span><span
|
||
data-language-content="pt"
|
||
hidden>01 / defina o gatilho</span
|
||
>
|
||
<span data-language-content="en">02 / load detail on demand</span><span
|
||
data-language-content="pt"
|
||
hidden>02 / carregue detalhes sob demanda</span
|
||
>
|
||
<span data-language-content="en">03 / return evidence</span><span
|
||
data-language-content="pt"
|
||
hidden>03 / devolva evidências</span
|
||
>
|
||
</div>
|
||
</div><div class="skill-explorer">
|
||
<SkillPackage
|
||
packageLabel={{ en: 'SKILL PACKAGE', pt: 'PACOTE DE SKILL' }}
|
||
files={[
|
||
{ id: 'skill', path: 'SKILL.md', small: 'procedure and limits' },
|
||
{ id: 'references', path: 'references/', small: 'facts to consult' },
|
||
{ id: 'scripts', path: 'scripts/', small: 'repeatable checks' },
|
||
{ id: 'assets', path: 'assets/', small: 'templates and examples' },
|
||
]}
|
||
/><article class="skill-detail" id="skill-detail" aria-live="polite">
|
||
<span>{skillFiles.skill.icon}</span><div>
|
||
<strong>{skillFiles.skill.title}</strong><p>{skillFiles.skill.en}</p><small
|
||
>{labels.skillFileHint.en}</small
|
||
>
|
||
</div>
|
||
</article>
|
||
</div><pre><code>name: review-ui · check focus, mobile, reduced motion · run verification · return evidence</code></pre>
|
||
</section>
|
||
|
||
<section class="skill-builder" id="create-skill">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Create a skill</span><span
|
||
data-language-content="pt"
|
||
hidden>Criar uma skill</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">repeatable pain → reusable judgment</span><span
|
||
data-language-content="pt"
|
||
hidden>atrito repetido → julgamento reutilizável</span
|
||
></span
|
||
>
|
||
</div><div class="builder-intro">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">The skill forge</span><span
|
||
data-language-content="pt"
|
||
hidden>A forja de skills</span
|
||
>
|
||
</p><h2>
|
||
<span data-language-content="en"
|
||
>Teach the decision.<br />Keep the context <em>light.</em></span
|
||
><span data-language-content="pt" hidden
|
||
>Ensine a decisão.<br />Mantenha o contexto <em>leve.</em></span
|
||
>
|
||
</h2>
|
||
</div><p>
|
||
<span data-language-content="en"
|
||
>Do not package everything you know. Capture the non-obvious choices that repeatedly
|
||
improve an outcome, then prove the skill changes behavior.</span
|
||
><span data-language-content="pt" hidden
|
||
>Não empacote tudo o que você sabe. Capture as escolhas não óbvias que melhoram
|
||
resultados repetidamente e prove que a skill muda o comportamento.</span
|
||
>
|
||
</p>
|
||
</div><div class="builder-workbench">
|
||
<nav class="builder-steps" role="tablist" aria-label="Skill creation workflow">
|
||
{
|
||
['observe', 'trigger', 'scaffold', 'write', 'validate'].map((id) => {
|
||
const step = skillWorkflow[id];
|
||
return (
|
||
<button
|
||
class:list={{ active: step.id === 'observe' }}
|
||
data-skill-step={step.id}
|
||
role="tab"
|
||
aria-selected={step.id === 'observe'}
|
||
>
|
||
<>
|
||
<b>{step.number}</b>
|
||
<>
|
||
<span>
|
||
<>
|
||
<span data-language-content="en">{builderSteps[step.id].title.en}</span>
|
||
<span data-language-content="pt" hidden>
|
||
{builderSteps[step.id].title.pt}
|
||
</span>
|
||
</>
|
||
</span>
|
||
<small>
|
||
<>
|
||
<span data-language-content="en">{builderSteps[step.id].tagline.en}</span>
|
||
<span data-language-content="pt" hidden>
|
||
{builderSteps[step.id].tagline.pt}
|
||
</span>
|
||
</>
|
||
</small>
|
||
</>
|
||
</>
|
||
</button>
|
||
);
|
||
})
|
||
}
|
||
</nav><article class="builder-detail" id="builder-detail" aria-live="polite">
|
||
<header>
|
||
<span>{skillWorkflow.observe.number}</span><small>{labels.workflow.question.en}</small>
|
||
</header><h3>{skillWorkflow.observe.title.en}</h3><blockquote>
|
||
{skillWorkflow.observe.question.en}
|
||
</blockquote><div class="builder-action">
|
||
<span>{labels.workflow.action.en}</span><p>{skillWorkflow.observe.action.en}</p>
|
||
</div><footer>
|
||
<div>
|
||
<span>{labels.workflow.artifact.en}</span><strong
|
||
>{skillWorkflow.observe.output.en}</strong
|
||
>
|
||
</div><div>
|
||
<span>{labels.workflow.proof.en}</span><strong
|
||
>{skillWorkflow.observe.proof.en}</strong
|
||
>
|
||
</div>
|
||
</footer>
|
||
</article><aside class="builder-artifact">
|
||
<div class="artifact-head">
|
||
<span
|
||
><span data-language-content="en">OUTPUT / SKILL PACKAGE</span><span
|
||
data-language-content="pt"
|
||
hidden>SAÍDA / PACOTE DE SKILL</span
|
||
></span
|
||
><i></i>
|
||
</div><pre
|
||
aria-label="Example skill structure"><code>review-ui/<br />├── SKILL.md<br />├── agents/<br />│ └── openai.yaml<br />├── references/<br />│ └── accessibility.md<br />└── scripts/<br /> └── verify.mjs</code></pre><div
|
||
class="artifact-command"
|
||
>
|
||
<span
|
||
><span data-language-content="en">VALIDATE</span><span
|
||
data-language-content="pt"
|
||
hidden>VALIDAR</span
|
||
></span
|
||
><code>quick_validate.py ./review-ui</code>
|
||
</div>
|
||
</aside>
|
||
</div><div class="builder-loop">
|
||
<span
|
||
><span data-language-content="en">AFTER REAL USE</span><span
|
||
data-language-content="pt"
|
||
hidden>APÓS USO REAL</span
|
||
></span
|
||
><div data-language-content="en">
|
||
<b>observe failure</b><i>→</i><b>sharpen one rule</b><i>→</i><b>retest behavior</b><i>→</i
|
||
><b>keep it narrow</b>
|
||
</div><div data-language-content="pt" hidden>
|
||
<b>observar falha</b><i>→</i><b>refinar uma regra</b><i>→</i><b>retestar comportamento</b
|
||
><i>→</i><b>manter estreita</b>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="skill-catalog" id="field-kit">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Common skills</span><span
|
||
data-language-content="pt"
|
||
hidden>Skills comuns</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">choose behavior before model</span><span
|
||
data-language-content="pt"
|
||
hidden>escolha o comportamento antes do modelo</span
|
||
></span
|
||
>
|
||
</div><div class="catalog-intro">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">The field kit</span><span
|
||
data-language-content="pt"
|
||
hidden>O kit de campo</span
|
||
>
|
||
</p>
|
||
<h2>
|
||
<span data-language-content="en"
|
||
>Different jobs.<br />Different <em>instincts.</em></span
|
||
><span data-language-content="pt" hidden
|
||
>Trabalhos diferentes.<br />Instintos <em>diferentes.</em></span
|
||
>
|
||
</h2>
|
||
</div>
|
||
<p>
|
||
<span data-language-content="en"
|
||
>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.</span
|
||
><span data-language-content="pt" hidden
|
||
>Uma skill muda como o agente aborda o trabalho. Algumas moldam a comunicação. Outras
|
||
impõem pesquisa, diagnóstico, revisão ou disciplina de conclusão. Selecione uma para
|
||
inspecionar sua regra operacional.</span
|
||
>
|
||
</p>
|
||
</div><div class="skill-deck">
|
||
<div class="skill-index" role="tablist" aria-label="Common agent skills">
|
||
{
|
||
/* getCollection's order is not the deck's order. Sort by the
|
||
card number so the tabs stay 01..07 as the legacy page has
|
||
them, instead of shifting between builds. */
|
||
sortedCommonSkills.map((skill) => (
|
||
<button
|
||
class:list={{ active: skill.id === 'ponytail' }}
|
||
data-common-skill={skill.id}
|
||
role="tab"
|
||
aria-selected={skill.id === 'ponytail'}
|
||
>
|
||
<>
|
||
{/* The button's two lines are `label` / `tagline`, not the
|
||
panel's `kind` / `use`. See src/content/config.ts. */}
|
||
<span>
|
||
<span data-language-content="en">{skill.label.en}</span>
|
||
<span data-language-content="pt" hidden>
|
||
{skill.label.pt}
|
||
</span>
|
||
</span>
|
||
<strong>{skill.title}</strong>
|
||
<small>
|
||
<span data-language-content="en">{skill.tagline.en}</span>
|
||
<span data-language-content="pt" hidden>
|
||
{skill.tagline.pt}
|
||
</span>
|
||
</small>
|
||
</>
|
||
</button>
|
||
))
|
||
}
|
||
</div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite">
|
||
<header>
|
||
<span>{commonSkills.ponytail.number}</span><small>{commonSkills.ponytail.kind.en}</small
|
||
>
|
||
</header><h3>{commonSkills.ponytail.title}</h3><blockquote>
|
||
{commonSkills.ponytail.rule.en}
|
||
</blockquote><div class="common-skill-notes">
|
||
<div>
|
||
<span>{labels.commonSkill.whenToUse.en}</span><p>{commonSkills.ponytail.use.en}</p>
|
||
</div><div>
|
||
<span>{labels.commonSkill.example.en}</span><p>{commonSkills.ponytail.example.en}</p>
|
||
</div><div>
|
||
<span>{labels.commonSkill.watchOut.en}</span><p>{commonSkills.ponytail.caution.en}</p>
|
||
</div>
|
||
</div><a
|
||
class="skill-source"
|
||
href={commonSkills.ponytail.source}
|
||
target="_blank"
|
||
rel="noopener">{labels.commonSkill.source.en}</a
|
||
>
|
||
</article>
|
||
</div><div class="skill-loadout">
|
||
<span data-language-content="en">ONE PRACTICAL LOADOUT</span><span
|
||
data-language-content="pt"
|
||
hidden>UM LOADOUT PRÁTICO</span
|
||
>
|
||
<div data-language-content="en">
|
||
<b>PLAN</b> unlazy <i>→</i>
|
||
<b>BUILD</b> ponytail-lite <i>→</i>
|
||
<b>DEBUG</b> diagnosing-bugs <i>→</i>
|
||
<b>REPORT</b> caveman
|
||
</div>
|
||
<div data-language-content="pt" hidden>
|
||
<b>PLANEJAR</b> unlazy <i>→</i>
|
||
<b>CONSTRUIR</b> ponytail-lite <i>→</i>
|
||
<b>DIAGNOSTICAR</b> diagnosing-bugs <i>→</i>
|
||
<b>REPORTAR</b> caveman
|
||
</div>
|
||
</div><article class="install-skills">
|
||
<header>
|
||
<div>
|
||
<span
|
||
><span data-language-content="en">INSTALL PACK</span><span
|
||
data-language-content="pt"
|
||
hidden>PACOTE DE INSTALAÇÃO</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en"
|
||
>Ask your coding agent to verify, install, and validate the skills.</span
|
||
><span data-language-content="pt" hidden
|
||
>Peça ao seu agente para verificar, instalar e validar as skills.</span
|
||
></strong
|
||
>
|
||
</div><CopyPrompt target="prompt-install-skills" />
|
||
</header><pre><code id="prompt-install-skills"><span data-language-content="en">{install.en}</span><span data-language-content="pt" hidden>{install.pt}</span></code></pre><footer
|
||
>
|
||
<span data-language-content="en"
|
||
>Review every source before installation. Existing local skills must be preserved.</span
|
||
><span data-language-content="pt" hidden
|
||
>Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.</span
|
||
>
|
||
</footer>
|
||
</article>
|
||
</section>
|
||
|
||
<section class="hands-on" id="hands-on">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Hands-on</span><span data-language-content="pt" hidden
|
||
>Prática</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">10 minutes / one missing feature</span><span
|
||
data-language-content="pt"
|
||
hidden>10 minutos / uma feature ausente</span
|
||
></span
|
||
>
|
||
</div><div class="hands-intro">
|
||
<div>
|
||
<p class="eyebrow">
|
||
<span data-language-content="en">Tiny Tasks lab</span><span
|
||
data-language-content="pt"
|
||
hidden>Laboratório Tiny Tasks</span
|
||
>
|
||
</p><h2>
|
||
<span data-language-content="en">Same task.<br />Better <em>operating system.</em></span
|
||
><span data-language-content="pt" hidden
|
||
>Mesma tarefa.<br />Melhor <em>sistema operacional.</em></span
|
||
>
|
||
</h2>
|
||
</div><div>
|
||
<p data-language-content="en">
|
||
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.
|
||
</p><p data-language-content="pt" hidden>
|
||
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.
|
||
</p><div class="starter-links">
|
||
<div class="starter-link-group">
|
||
<a href={`${base}hands-on/starter/`} class="starter-link"
|
||
><span data-language-content="en">Open the starter →</span><span
|
||
data-language-content="pt"
|
||
hidden>Abrir o projeto inicial →</span
|
||
></a
|
||
><a
|
||
href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/starter"
|
||
class="starter-link starter-link-source"
|
||
><span data-language-content="en">Clone from Gitea →</span><span
|
||
data-language-content="pt"
|
||
hidden>Abrir o projeto inicial →</span
|
||
></a
|
||
>
|
||
</div><div class="starter-link-group">
|
||
<a href={`${base}hands-on/rules/`} class="starter-link"
|
||
><span data-language-content="en">Open the rules lab →</span><span
|
||
data-language-content="pt"
|
||
hidden>Abrir o projeto inicial →</span
|
||
></a
|
||
><a
|
||
href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/pages/hands-on/rules"
|
||
class="starter-link starter-link-source"
|
||
><span data-language-content="en">Clone from Gitea →</span><span
|
||
data-language-content="pt"
|
||
hidden>Abrir o projeto inicial →</span
|
||
></a
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div><div class="exercise-brief">
|
||
<span
|
||
><span data-language-content="en">THE MISSING FEATURE</span><span
|
||
data-language-content="pt"
|
||
hidden>A FEATURE AUSENTE</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en"
|
||
>Add All / Open / Done filters that survive reload and browser navigation.</span
|
||
><span data-language-content="pt" hidden
|
||
>Adicione filtros Todos / Abertos / Concluídos que sobrevivem reload e navegação.</span
|
||
></strong
|
||
><div>
|
||
<span data-language-content="en"
|
||
><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</span
|
||
><span data-language-content="pt" hidden
|
||
><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDÊNCIAS</b> nenhuma <b>ARQUIVOS</b> 3</span
|
||
>
|
||
</div>
|
||
</div><div class="prompt-compare">
|
||
<article class="prompt-card">
|
||
<header>
|
||
<div>
|
||
<span>RUN A</span><strong
|
||
><span data-language-content="en">Good prompt</span><span
|
||
data-language-content="pt"
|
||
hidden>Bom prompt</span
|
||
></strong
|
||
>
|
||
</div><CopyPrompt target="prompt-basic" />
|
||
</header><pre><code id="prompt-basic"><span data-language-content="en">{handsOn.en.basic}</span><span data-language-content="pt" hidden>{handsOn.pt.basic}</span></code></pre><footer
|
||
>
|
||
<span data-language-content="en"
|
||
>Clear context · constraints · acceptance · evidence</span
|
||
><span data-language-content="pt" hidden
|
||
>Contexto claro · restrições · aceitação · evidência</span
|
||
>
|
||
</footer>
|
||
</article><article class="prompt-card enhanced">
|
||
<header>
|
||
<div>
|
||
<span>RUN B</span><strong
|
||
><span data-language-content="en">Good prompt + skills</span><span
|
||
data-language-content="pt"
|
||
hidden>Bom prompt + skills</span
|
||
></strong
|
||
>
|
||
</div><CopyPrompt target="prompt-skills" />
|
||
</header><pre><code id="prompt-skills"><span data-language-content="en">{handsOn.en.skills}</span><span data-language-content="pt" hidden>{handsOn.pt.skills}</span></code></pre><footer
|
||
>
|
||
<span data-language-content="en"
|
||
>Same contract · explicit working methods · stronger proof</span
|
||
><span data-language-content="pt" hidden
|
||
>Mesmo contrato · métodos explícitos · prova mais forte</span
|
||
>
|
||
</footer>
|
||
</article>
|
||
</div><div class="comparison-strip">
|
||
<span
|
||
><span data-language-content="en">COMPARE THE RUNS</span><span
|
||
data-language-content="pt"
|
||
hidden>COMPARE AS EXECUÇÕES</span
|
||
></span
|
||
><div>
|
||
<b>01</b>
|
||
<span data-language-content="en">Files changed</span><span
|
||
data-language-content="pt"
|
||
hidden>Arquivos alterados</span
|
||
>
|
||
</div><div>
|
||
<b>02</b>
|
||
<span data-language-content="en">New dependencies</span><span
|
||
data-language-content="pt"
|
||
hidden>Novas dependências</span
|
||
>
|
||
</div><div>
|
||
<b>03</b>
|
||
<span data-language-content="en">Checks actually run</span><span
|
||
data-language-content="pt"
|
||
hidden>Checks executados</span
|
||
>
|
||
</div><div>
|
||
<b>04</b>
|
||
<span data-language-content="en">Evidence returned</span><span
|
||
data-language-content="pt"
|
||
hidden>Evidências retornadas</span
|
||
>
|
||
</div>
|
||
</div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p>
|
||
</section>
|
||
|
||
<aside class="rule">
|
||
<span
|
||
><span data-language-content="en">THE HUMAN JOB</span><span
|
||
data-language-content="pt"
|
||
hidden>O PAPEL HUMANO</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en"
|
||
>The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</span
|
||
><span data-language-content="pt" hidden
|
||
>O agente pode ser autônomo na execução. Intenção, limites e evidências continuam sendo
|
||
seus.</span
|
||
></strong
|
||
>
|
||
</aside>
|
||
<aside class="callout">
|
||
<span
|
||
><span data-language-content="en">START HERE</span><span data-language-content="pt" hidden
|
||
>COMECE AQUI</span
|
||
></span
|
||
><strong
|
||
><span data-language-content="en"
|
||
>Begin with one agent and one skill. Add parallelism only when the tasks are truly
|
||
independent.</span
|
||
><span data-language-content="pt" hidden
|
||
>Comece com um agente e uma skill. Adicione paralelismo apenas quando as tarefas forem
|
||
realmente independentes.</span
|
||
></strong
|
||
>
|
||
</aside>
|
||
<section class="verification" id="verification">
|
||
<div class="section-label">
|
||
<span>Verification</span><span>run each gate separately</span>
|
||
</div><div class="verify-intro">
|
||
<div>
|
||
<p class="eyebrow">Checks become evidence</p><h2>
|
||
Three layers.<br />Run each one alone.
|
||
</h2>
|
||
</div><p>
|
||
Run a gate on its own line, print its exit code, attach the output. The result is the
|
||
deliverable.
|
||
</p>
|
||
</div><div class="verify-layers">
|
||
<article>
|
||
<span>01 · STATIC</span><h3>Lint and types</h3><p>
|
||
Format, lint, type-check. Fast and scoped to one file. Run on every save.
|
||
</p><code>pnpm lint; echo "lint=$?" pnpm typecheck; echo "typecheck=$?"</code>
|
||
</article><article>
|
||
<span>02 · BEHAVIOR</span><h3>Unit and contract</h3><p>
|
||
Tests that repeat. Run before claiming done.
|
||
</p><code>pnpm test; echo "test=$?" cd services/api && go test ./...</code>
|
||
</article><article>
|
||
<span>03 · INTEGRATION</span><h3>Real UI and API</h3><p>
|
||
Drive the actual UI, API, or browser. Slower and flakier — only this catches mobile
|
||
overflow and a missing 404.
|
||
</p><code>pnpm check:ui; echo "ui=$?" TURBO_FORCE=true pnpm e2e</code>
|
||
</article>
|
||
</div><div class="verify-antipatterns">
|
||
<span>FOUR WAYS A GREEN REPORT IS FALSE</span><div class="ap-grid">
|
||
<article>
|
||
<b>1</b><div>
|
||
<strong>Pipe a gate</strong><p>
|
||
tail, grep, or head hide the real exit code — a pipeline returns the last command's
|
||
status.
|
||
</p>
|
||
</div>
|
||
</article><article>
|
||
<b>2</b><div>
|
||
<strong>Swallow a rejection</strong><p>
|
||
A silent <code>{'.catch(() => {})'}</code> hides a panic, an upstream limit, or a partial
|
||
failure.
|
||
</p>
|
||
</div>
|
||
</article><article>
|
||
<b>3</b><div>
|
||
<strong>Trust the cache</strong><p>
|
||
Turbo caches results. A gate that "passes" may not have run — use <code
|
||
>TURBO_FORCE=true</code
|
||
>.
|
||
</p>
|
||
</div>
|
||
</article><article>
|
||
<b>4</b><div>
|
||
<strong>Skip the third layer</strong><p>
|
||
Lint and unit can both be green while the page breaks on mobile and the API never
|
||
returns 404.
|
||
</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div><article class="verify-cta">
|
||
<span>RUN IT YOURSELF · two labs, under 10 minutes each</span><div class="verify-cta-grid">
|
||
<a href={`${base}hands-on/starter/`} class="verify-card"
|
||
><strong>Path A · verification lab</strong><p>
|
||
Fill the four-row comparison strip on the starter. Run A naively, Run B with <code
|
||
>$gate-discipline</code
|
||
> and <code>$webapp-testing</code>.
|
||
</p><small>Open the starter →</small><small class="verify-card-source"
|
||
>Clone ↗ <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/starter</span
|
||
></small
|
||
></a
|
||
><a href={`${base}hands-on/rules/`} class="verify-card"
|
||
><strong>Path B · rules lab</strong><p>
|
||
Toggle every rule off, run the prompt. Toggle every rule on, run it again. Compare
|
||
diff size, gate invocations, and the names of checks the agent names back.
|
||
</p><small
|
||
><span data-language-content="en">Open the rules lab →</span><span
|
||
data-language-content="pt"
|
||
hidden>Open the rules lab →</span
|
||
></small
|
||
><small class="verify-card-source"
|
||
>Clone ↗ <span>git.marcospaulo.dev.br/.../src/branch/pages/hands-on/rules</span
|
||
></small
|
||
></a
|
||
>
|
||
</div>
|
||
</article>
|
||
</section>
|
||
<section class="sources">
|
||
<div class="section-label">
|
||
<span
|
||
><span data-language-content="en">Keep learning</span><span
|
||
data-language-content="pt"
|
||
hidden>Continue aprendendo</span
|
||
></span
|
||
><span
|
||
><span data-language-content="en">12 new readings + primary docs</span><span
|
||
data-language-content="pt"
|
||
hidden>12 novas leituras + documentação primária</span
|
||
></span
|
||
>
|
||
</div><p>
|
||
<span data-language-content="en"
|
||
>Go deeper with official documentation, production case studies, Medium, and practitioner
|
||
workflows. <a href={`${base}rules/`}>Rules and enforcement case study →</a>
|
||
<a href={`${base}skills-review/`}>Skills review desk →</a>
|
||
<a href={`${base}docs/references/README.md`}>Primary references →</a>
|
||
<a href={`${base}docs/references/additional-reading.md`}>12-part reading path →</a></span
|
||
>
|
||
<span data-language-content="pt" hidden
|
||
>Aprofunde com documentação oficial, casos de produção, Medium e fluxos de praticantes. <a
|
||
href={`${base}rules/`}>Estudo de caso sobre regras e enforcement →</a
|
||
>
|
||
<a href={`${base}docs/references/README.md`}>Referências primárias →</a>
|
||
<a href={`${base}docs/references/additional-reading.md`}>Trilha com 12 leituras →</a
|
||
></span
|
||
>
|
||
</p>
|
||
</section>
|
||
<!-- Legacy full-guide/index.html closes with this section after `.sources`.
|
||
Task 15d dropped it, and nothing caught that: verify.mjs reads the
|
||
legacy file, so its chapter-route assertion kept passing. It has no
|
||
`translations.pt` entry, so it is English-only on the live site too. -->
|
||
<section class="chapter-route">
|
||
<div class="section-label">
|
||
<span>Navigate by idea</span><span>short chapters / one system</span>
|
||
</div>
|
||
<p>
|
||
Prefer a focused chapter? Start with the <a href={`${base}summary/`}>route map</a>, then
|
||
jump directly to <a href={`${base}models/`}>models</a>, <a href={`${base}agents/`}
|
||
>agents and worktrees</a
|
||
>, <a href={`${base}skills/`}>skill creation</a>, <a href={`${base}rules/`}>rules</a>, or
|
||
the <a href={`${base}skills-review/`}>skills review desk</a>.
|
||
</p>
|
||
</section>
|
||
</main>
|
||
<GuideSelector rootSelector="#full-guide" data={selectorData} />
|
||
</BaseLayout>
|