Merge branch 'refactor/task-translation-review-translation-review'
verify-and-publish / gate (push) Successful in 8m19s
verify-and-publish / publish (push) Has been skipped

Brings the i18n translation review into main:
- Five feat(i18n) commits translating the chapters collection
  (landing, summary, models, agents, skills).
- One feat(i18n) commit wiring audit-translations.mjs into
  pnpm run verify, with an 18-entry allowlist for intentional
  identicals (numeric card labels, product nouns, model-tier
  series names).

Together: 122 untranslated pt fields fixed (across 5 files), 18
intentional identicals documented, audit-translations now part of
the gate. English strings are byte-identical to origin/main. Recall
section in skills.json preserved byte-identical.

Reviewed-by: site owner (translation tone approved commit-by-commit).

Closes: chapters collection pt === en regression.
This commit is contained in:
Marcos Paulo
2026-09-07 04:58:08 -03:00
9 changed files with 396 additions and 151 deletions
@@ -0,0 +1,112 @@
{
"entries": [
{
"collection": "chapters",
"file": "agents.json",
"field": "sections.1.steps.0.label",
"reason": "Handoff step label (\"Brief\"); kept English by glossary convention."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.0.label",
"reason": "Numeric card label (\"01\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.1.label",
"reason": "Numeric card label (\"02\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.2.label",
"reason": "Numeric card label (\"03\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.2.title",
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.3.label",
"reason": "Numeric card label (\"04\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.4.label",
"reason": "Numeric card label (\"05\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "landing.json",
"field": "cards.5.label",
"reason": "Numeric card label (\"06\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.0.label",
"reason": "Numeric card label (\"01\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.1.label",
"reason": "Numeric card label (\"02\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.2.label",
"reason": "Numeric card label (\"03\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.2.title",
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.3.label",
"reason": "Numeric card label (\"04\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.4.label",
"reason": "Numeric card label (\"05\"); identical across locales by design."
},
{
"collection": "chapters",
"file": "summary.json",
"field": "cards.5.label",
"reason": "Numeric card label (\"06\"); identical across locales by design."
},
{
"collection": "providers",
"file": "claude.json",
"field": "title",
"reason": "Model-tier series name (\"Opus · Sonnet · Haiku\"); kept English as product name."
},
{
"collection": "providers",
"file": "gemini.json",
"field": "title",
"reason": "Model-tier series name (\"Pro · Flash · Flash-Lite\"); kept English as product name."
},
{
"collection": "providers",
"file": "openai.json",
"field": "title",
"reason": "Model-tier series name (\"Sol · Terra · Luna\"); kept English as product name."
}
]
}
+91 -26
View File
@@ -7,16 +7,25 @@
// node .agents/scripts/audit-translations.mjs # walks src/content
// node .agents/scripts/audit-translations.mjs src/content/ # explicit root
//
// Exits non-zero if any pair is identical. The output is grouped by
// collection, then by file, then by field path, so the report reads like
// Exits non-zero if any unallowed pair is identical. The output is grouped
// by collection, then by file, then by field path, so the report reads like
// a translation backlog rather than a wall of strings.
//
// This is the sibling of extract-strings.mjs: that one proves the
// migration moved every string; this one proves every string actually
// differs across locales.
//
// Allowlist: a sibling `.agents/scripts/audit-translations.allowlist.json`
// lists (collection, file, field) tuples that are intentionally identical
// across locales (numeric card labels, product nouns, model-tier series
// names, etc.). Entries in the allowlist are listed under "ALLOWED" in the
// output and do not affect the exit code. Adding to the allowlist is a
// deliberate edit + commit; future translators can see it and understand
// which identicals are intentional.
import { readFileSync, readdirSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
import { dirname, join, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = process.argv[2] ?? 'src/content';
@@ -69,9 +78,27 @@ const collectionOf = (file, root) => {
return parts.length >= 2 ? parts[0] : '(root)';
};
// Load the allowlist. The file lives next to this script and lists
// intentional identicals (numeric labels, product nouns, model-tier series
// names, etc.). Missing file is OK — the audit still runs.
const here = dirname(fileURLToPath(import.meta.url));
const allowlistPath = join(here, 'audit-translations.allowlist.json');
const allowlist = new Set();
const allowlistReasons = new Map();
if (existsSync(allowlistPath)) {
const { entries } = JSON.parse(readFileSync(allowlistPath, 'utf8'));
for (const { collection, file, field, reason } of entries) {
allowlist.add(`${collection}${file}${field}`);
allowlistReasons.set(`${collection}${file}${field}`, reason);
}
}
const groups = new Map();
const allowedGroups = new Map();
let totalLocalized = 0;
let totalIdentical = 0;
let totalReal = 0;
let totalAllowed = 0;
for (const file of files) {
let data;
@@ -84,40 +111,78 @@ for (const file of files) {
const pairs = collect(data);
if (pairs.length === 0) continue;
const offenders = pairs.filter(([, en, pt]) => same(en, pt));
if (offenders.length === 0) continue;
totalLocalized += pairs.length;
totalIdentical += offenders.length;
const collection = collectionOf(file, ROOT);
const filename = relative(ROOT, file);
// Allowlist entries key on the file's name within its collection
// (e.g. `landing.json`), so strip the collection prefix from
// `filename` when matching. The full relative path is still used
// for the report display.
const collectionFile = filename.startsWith(collection + '/')
? filename.slice(collection.length + 1)
: filename;
if (!groups.has(collection)) groups.set(collection, []);
groups.get(collection).push({ file: filename, pairs: offenders });
// Split identical pairs into real offenders (fail the gate) and
// allowlisted ones (listed under ALLOWED, do not affect exit code).
const real = [];
const allowed = [];
for (const [field, en, pt] of pairs) {
if (!same(en, pt)) continue;
const key = `${collection}${collectionFile}${field}`;
if (allowlist.has(key)) {
allowed.push([field, en, allowlistReasons.get(key)]);
} else {
real.push([field, en, null]);
}
}
if (groups.size === 0) {
totalLocalized += pairs.length;
if (real.length > 0) {
totalReal += real.length;
if (!groups.has(collection)) groups.set(collection, []);
groups.get(collection).push({ file: filename, pairs: real });
}
if (allowed.length > 0) {
totalAllowed += allowed.length;
if (!allowedGroups.has(collection)) allowedGroups.set(collection, []);
allowedGroups.get(collection).push({ file: filename, pairs: allowed });
}
}
const printGroup = (entries, label) => {
for (const [collection, list] of entries) {
console.log(`\n[${collection}]`);
for (const { file, pairs } of list) {
console.log(` ${file}`);
for (const [field, en, reason] of pairs) {
const sample = typeof en === 'string' ? JSON.stringify(en).slice(0, 80) : '<non-string>';
const suffix = reason ? ` [${label}: ${reason}]` : '';
console.log(` - ${field.padEnd(28)} ${sample}${suffix}`);
}
}
}
};
// Clean case: no identicals at all.
if (totalReal === 0 && totalAllowed === 0) {
console.log('OK: no identical en/pt pairs found under', ROOT);
process.exit(0);
}
// Print grouped report.
for (const [collection, entries] of groups) {
console.log(`\n[${collection}]`);
for (const { file, pairs } of entries) {
console.log(` ${file}`);
for (const [field, en, pt] of pairs) {
const sample = typeof en === 'string' ? JSON.stringify(en).slice(0, 80) : '<non-string>';
console.log(` - ${field.padEnd(28)} ${sample}`);
}
}
}
// Show allowed entries first, then real offenders (if any).
printGroup(allowedGroups, 'ALLOWED');
if (totalReal > 0) {
printGroup(groups, 'REAL');
console.log(
`\nFAIL: ${totalIdentical} identical localized field(s) across ${groups.size} collection(s) of ${ROOT}`,
`\nFAIL: ${totalReal} unallowed identical localized field(s) across ${groups.size} collection(s) of ${ROOT}`,
);
console.log(
'A `pt` identical to `en` is how a bilingual site becomes monolingual. Translate, then re-run.',
);
process.exit(1);
}
console.log(`\nOK: ${totalAllowed} identical field(s) found, all on the allowlist.`);
process.exit(0);
+1 -1
View File
@@ -9,7 +9,7 @@
"check": "astro check",
"lint": "eslint . --max-warnings=0 && stylelint --allow-empty-input 'src/**/*.css' --max-warnings=0",
"format": "prettier --write .",
"verify": "node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs",
"verify": "node .agents/scripts/audit-translations.mjs && node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs",
"gate": "./.agents/scripts/gate.sh",
"snapshot": "node .agents/scripts/snapshot-route.mjs",
"prepare": "husky"
+7 -5
View File
@@ -271,11 +271,13 @@ if (!allPages.every(([, page]) => page.includes('name="viewport"')))
throw new Error('a built route lacks a viewport declaration');
if (allPages.some(([, page]) => /<(script|link)[^>]+(src|href)="https?:[^\"]+"/i.test(page)))
throw new Error('a built route has an external runtime dependency');
if (
!read('package.json').includes(
'"verify": "node scripts/verify.mjs && node scripts/audit-ui.mjs && node .agents/scripts/check-tokens.mjs"',
)
)
// `pnpm run verify` may now prepend `node .agents/scripts/audit-translations.mjs &&`
// for fail-fast translation checks. Allow an optional audit-translations prefix
// while still requiring the three core scripts in order.
const verifyChain = read('package.json');
const verifyShape =
/\"verify\":\s*\"(?:node \.agents\/scripts\/audit-translations\.mjs && )?node scripts\/verify\.mjs && node scripts\/audit-ui\.mjs && node \.agents\/scripts\/check-tokens\.mjs\"/;
if (!verifyShape.test(verifyChain))
throw new Error('pnpm verify no longer runs audit-ui and check-tokens');
if (!read('.agents/scripts/gate.sh').includes('pnpm run verify'))
throw new Error('the gate no longer runs the output contract');
+23 -23
View File
@@ -2,57 +2,57 @@
"id": "agents",
"eyebrow": {
"en": "Subagent workflow",
"pt": "Subagent workflow"
"pt": "Fluxo de subagentes"
},
"title": {
"en": "One branch<br>per <em>hand.</em>",
"pt": "One branch<br>per <em>hand.</em>"
"pt": "Uma branch<br>por <em>mão.</em>"
},
"lede": {
"en": "Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent.",
"pt": "Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent."
"pt": "Agentes funcionam quando papéis, arquivos e evidências são delimitados. Um worktree dá a cada agente seu próprio checkout enquanto o orquestrador protege a intenção."
},
"cards": [
{
"label": {
"en": "FRAME",
"pt": "FRAME"
"pt": "ENQUADRAR"
},
"title": {
"en": "Orchestrator",
"pt": "Orchestrator"
"pt": "Orquestrador"
},
"copy": {
"en": "Owns scope, task graph, boundaries, and integration.",
"pt": "Owns scope, task graph, boundaries, and integration."
"pt": "Dono do escopo, do grafo de tarefas, das fronteiras e da integração."
}
},
{
"label": {
"en": "HAND OFF",
"pt": "HAND OFF"
"pt": "PASSAR"
},
"title": {
"en": "Worker",
"pt": "Worker"
"pt": "Agente"
},
"copy": {
"en": "Owns one coherent slice and one worktree.",
"pt": "Owns one coherent slice and one worktree."
"pt": "Dono de uma fatia coerente e de um worktree."
}
},
{
"label": {
"en": "PROVE",
"pt": "PROVE"
"pt": "COMPROVAR"
},
"title": {
"en": "Verifier",
"pt": "Verifier"
"pt": "Verificador"
},
"copy": {
"en": "Re-runs gates and reports remaining gaps.",
"pt": "Re-runs gates and reports remaining gaps."
"pt": "Roda gates novamente e reporta o que ainda falta."
}
}
],
@@ -60,29 +60,29 @@
{
"eyebrow": {
"en": "The tree",
"pt": "The tree"
"pt": "A árvore"
},
"title": {
"en": "Split at<br>the <em>seam.</em>",
"pt": "Split at<br>the <em>seam.</em>"
"pt": "Divida na<br><em>costura.</em>"
},
"panelLabel": {
"en": "MAIN / ORCHESTRATOR",
"pt": "MAIN / ORCHESTRATOR"
"pt": "MAIN / ORQUESTRADOR"
},
"panelCode": {
"en": "├── agent/ui → components + visual states\n├── agent/tests → acceptance + regressions\n└── agent/docs → guide + examples\n\nmerge after each leaf returns a diff and evidence",
"pt": "├── agent/ui → components + visual states\n├── agent/tests → acceptance + regressions\n└── agent/docs → guide + examples\n\nmerge after each leaf returns a diff and evidence"
"pt": "├── agent/ui → componentes + estados visuais\n├── agent/tests → aceitação + regressões\n└── agent/docs → guia + exemplos\n\nfaça merge depois que cada folha devolver um diff e evidências"
}
},
{
"eyebrow": {
"en": "Handoff",
"pt": "Handoff"
"pt": "Passagem"
},
"title": {
"en": "Context that<br>can <em>travel.</em>",
"pt": "Context that<br>can <em>travel.</em>"
"pt": "Contexto que<br>pode <em>viajar.</em>"
},
"steps": [
{
@@ -92,27 +92,27 @@
},
"copy": {
"en": "Goal, owned files, dependencies, non-goals, acceptance.",
"pt": "Goal, owned files, dependencies, non-goals, acceptance."
"pt": "Objetivo, arquivos sob sua posse, dependências, fora de escopo, aceitação."
}
},
{
"label": {
"en": "Isolation",
"pt": "Isolation"
"pt": "Isolamento"
},
"copy": {
"en": "One branch and worktree per independent change.",
"pt": "One branch and worktree per independent change."
"pt": "Uma branch e um worktree por mudança independente."
}
},
{
"label": {
"en": "Evidence",
"pt": "Evidence"
"pt": "Evidência"
},
"copy": {
"en": "Commands, result, changed files, screenshots, gaps.",
"pt": "Commands, result, changed files, screenshots, gaps."
"pt": "Comandos, resultado, arquivos alterados, capturas de tela, lacunas."
}
}
]
+29 -23
View File
@@ -1,83 +1,89 @@
{
"id": "landing",
"eyebrow": { "en": "The short route", "pt": "The short route" },
"title": { "en": "Ship the<br><em>system.</em>", "pt": "Ship the<br><em>system.</em>" },
"eyebrow": {
"en": "The short route",
"pt": "A rota curta"
},
"title": {
"en": "Ship the<br><em>system.</em>",
"pt": "Entregue o<br><em>sistema.</em>"
},
"lede": {
"en": "Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof.",
"pt": "Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof."
"pt": "Comece pelo mapa. Depois abra o capítulo que combina com a decisão à sua frente: modelo, agente, worktree, skill, regra ou prova."
},
"threadLabel": {
"en": "THE THREAD",
"pt": "THE THREAD"
"pt": "O FIO"
},
"threadText": {
"en": "Frame uncertainty → isolate execution → preserve judgment → verify the change.",
"pt": "Frame uncertainty → isolate execution → preserve judgment → verify the change."
"pt": "Enquadre a incerteza → isole a execução → preserve o julgamento → verifique a mudança."
},
"footer": {
"en": "The route map is now the default entry. The full guide remains available whenever you want the whole narrative.",
"pt": "The route map is now the default entry. The full guide remains available whenever you want the whole narrative."
"pt": "O mapa de rotas é agora a entrada padrão. O guia completo segue disponível sempre que você quiser a narrativa inteira."
},
"cards": [
{
"label": { "en": "01", "pt": "01" },
"title": { "en": "Models", "pt": "Models" },
"title": { "en": "Models", "pt": "Modelos" },
"copy": {
"en": "Capability and effort are separate knobs.",
"pt": "Capability and effort are separate knobs."
"pt": "Capacidade e esforço são controles separados."
},
"href": "models/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
},
{
"label": { "en": "02", "pt": "02" },
"title": { "en": "Agents & trees", "pt": "Agents & trees" },
"title": { "en": "Agents & trees", "pt": "Agentes e árvores" },
"copy": {
"en": "Bound roles, handoffs, and worktrees.",
"pt": "Bound roles, handoffs, and worktrees."
"pt": "Limite papéis, handoffs e worktrees."
},
"href": "agents/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
},
{
"label": { "en": "03", "pt": "03" },
"title": { "en": "Skills", "pt": "Skills" },
"copy": {
"en": "Capture repeatable decisions in small packages.",
"pt": "Capture repeatable decisions in small packages."
"pt": "Capture decisões repetíveis em pacotes pequenos."
},
"href": "skills/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
},
{
"label": { "en": "04", "pt": "04" },
"title": { "en": "Rules", "pt": "Rules" },
"title": { "en": "Rules", "pt": "Regras" },
"copy": {
"en": "Connect guidance to enforcement.",
"pt": "Connect guidance to enforcement."
"pt": "Conecte orientação a enforcement."
},
"href": "rules/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": { "en": "Open chapter →", "pt": "Abrir capítulo →" }
},
{
"label": { "en": "05", "pt": "05" },
"title": { "en": "Hands-on", "pt": "Hands-on" },
"title": { "en": "Hands-on", "pt": "Prática" },
"copy": {
"en": "Compare a strong prompt with skill-enabled work.",
"pt": "Compare a strong prompt with skill-enabled work."
"pt": "Compare um prompt forte com trabalho assistido por skills."
},
"href": "hands-on/starter/",
"cta": { "en": "Open lab →", "pt": "Open lab →" }
"cta": { "en": "Open lab →", "pt": "Abrir lab →" }
},
{
"label": { "en": "06", "pt": "06" },
"title": { "en": "Review desk", "pt": "Review desk" },
"title": { "en": "Review desk", "pt": "Mesa de revisão" },
"copy": {
"en": "Browse original packages, references, scripts, and improvements.",
"pt": "Browse original packages, references, scripts, and improvements."
"pt": "Explore pacotes originais, referências, scripts e melhorias."
},
"href": "skills-review/",
"cta": { "en": "Open desk →", "pt": "Open desk →" }
"cta": { "en": "Open desk →", "pt": "Abrir mesa →" }
}
]
}
+24 -24
View File
@@ -2,57 +2,57 @@
"id": "models",
"eyebrow": {
"en": "Model routing",
"pt": "Model routing"
"pt": "Roteamento de modelos"
},
"title": {
"en": "Choose the<br><em>engine.</em>",
"pt": "Choose the<br><em>engine.</em>"
"pt": "Escolha o<br><em>motor.</em>"
},
"lede": {
"en": "A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost.",
"pt": "A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost."
"pt": "Um modelo tem um teto de capacidade. O esforço controla quanto espaço ele ganha para raciocinar. Roteie por incerteza e custo de verificação."
},
"cards": [
{
"label": {
"en": "LOW",
"pt": "LOW"
"pt": "BAIXO"
},
"title": {
"en": "Bounded rhythm",
"pt": "Bounded rhythm"
"pt": "Ritmo delimitado"
},
"copy": {
"en": "Lookup, small edits, formatting, and transformations with clear checks.",
"pt": "Lookup, small edits, formatting, and transformations with clear checks."
"pt": "Consultas, edições pequenas, formatação e transformações com checagens claras."
}
},
{
"label": {
"en": "MEDIUM",
"pt": "MEDIUM"
"pt": "MÉDIO"
},
"title": {
"en": "Default work",
"pt": "Default work"
"pt": "Trabalho padrão"
},
"copy": {
"en": "Normal implementation where the contract is clear but context matters.",
"pt": "Normal implementation where the contract is clear but context matters."
"pt": "Implementação normal em que o contrato é claro, mas o contexto importa."
}
},
{
"label": {
"en": "HIGH",
"pt": "HIGH"
"pt": "ALTO"
},
"title": {
"en": "Ambiguity",
"pt": "Ambiguity"
"pt": "Ambiguidade"
},
"copy": {
"en": "Planning, architecture, security judgment, and hard failures.",
"pt": "Planning, architecture, security judgment, and hard failures."
"pt": "Planejamento, arquitetura, julgamento de segurança e falhas difíceis."
}
}
],
@@ -60,59 +60,59 @@
{
"eyebrow": {
"en": "Two knobs",
"pt": "Two knobs"
"pt": "Dois controles"
},
"title": {
"en": "Capability<br>× effort",
"pt": "Capability<br>× effort"
"pt": "Capacidade<br>× esforço"
},
"panelLabel": {
"en": "ROUTING RULE",
"pt": "ROUTING RULE"
"pt": "REGRA DE ROTEAMENTO"
},
"panelCode": {
"en": "strong model + high effort → frame ambiguity\nlight model + low effort → bounded execution\nraise one knob at a time → compare evidence",
"pt": "strong model + high effort → frame ambiguity\nlight model + low effort → bounded execution\nraise one knob at a time → compare evidence"
"pt": "modelo forte + esforço alto → enquadrar ambiguidade\nmodelo leve + esforço baixo → execução delimitada\nsuba um controle por vez → compare evidências"
}
},
{
"eyebrow": {
"en": "Sequence",
"pt": "Sequence"
"pt": "Sequência"
},
"title": {
"en": "Spend judgment<br>where it <em>compounds.</em>",
"pt": "Spend judgment<br>where it <em>compounds.</em>"
"pt": "Invista julgamento<br>onde ele <em>compensa.</em>"
},
"steps": [
{
"label": {
"en": "Plan",
"pt": "Plan"
"pt": "Planejar"
},
"copy": {
"en": "Strong model: scope, risks, acceptance, and worktree split.",
"pt": "Strong model: scope, risks, acceptance, and worktree split."
"pt": "Modelo forte: escopo, riscos, aceitação e divisão de worktrees."
}
},
{
"label": {
"en": "Build",
"pt": "Build"
"pt": "Construir"
},
"copy": {
"en": "Focused worker: smallest context and lightest model that can pass.",
"pt": "Focused worker: smallest context and lightest model that can pass."
"pt": "Worker focado: o menor contexto e o modelo mais leve que passa."
}
},
{
"label": {
"en": "Review",
"pt": "Review"
"pt": "Revisar"
},
"copy": {
"en": "Independent pass when missed issues cost more than the call.",
"pt": "Independent pass when missed issues cost more than the call."
"pt": "Revisão independente quando erros perdidos custam mais que a chamada."
}
}
]
+16 -16
View File
@@ -1,56 +1,56 @@
{
"id": "skills",
"eyebrow": { "en": "Reusable judgment", "pt": "Reusable judgment" },
"title": { "en": "Teach the<br><em>decision.</em>", "pt": "Teach the<br><em>decision.</em>" },
"eyebrow": { "en": "Reusable judgment", "pt": "Julgamento reutilizável" },
"title": { "en": "Teach the<br><em>decision.</em>", "pt": "Ensine a<br><em>decisão.</em>" },
"lede": {
"en": "A skill changes behavior. Keep the trigger precise, put the workflow in <code>SKILL.md</code>, and move conditional facts, scripts, and examples into focused files.",
"pt": "A skill changes behavior. Keep the trigger precise, put the workflow in <code>SKILL.md</code>, and move conditional facts, scripts, and examples into focused files."
"pt": "Uma skill muda comportamento. Mantenha o gatilho preciso, coloque o workflow em <code>SKILL.md</code> e mova fatos condicionais, scripts e exemplos para arquivos focados."
},
"sections": [
{
"eyebrow": { "en": "Package anatomy", "pt": "Package anatomy" },
"eyebrow": { "en": "Package anatomy", "pt": "Anatomia do pacote" },
"title": {
"en": "One job.<br>More than<br>one <em>file.</em>",
"pt": "One job.<br>More than<br>one <em>file.</em>"
"pt": "Um trabalho.<br>Mais que<br>um <em>arquivo.</em>"
},
"copy": {
"en": "Choose a file to see why it belongs in the package.",
"pt": "Choose a file to see why it belongs in the package."
"pt": "Escolha um arquivo para ver por que ele pertence ao pacote."
}
},
{
"eyebrow": { "en": "Create a skill", "pt": "Create a skill" },
"eyebrow": { "en": "Create a skill", "pt": "Crie uma skill" },
"title": {
"en": "Observe →<br>trigger →<br>validate",
"pt": "Observe →<br>trigger →<br>validate"
"pt": "Observe →<br>defina o gatilho →<br>valide"
},
"steps": [
{
"label": { "en": "Observe friction", "pt": "Observe friction" },
"label": { "en": "Observe friction", "pt": "Observe o atrito" },
"copy": {
"en": "Find a repeated decision or failure.",
"pt": "Find a repeated decision or failure."
"pt": "Encontre uma decisão ou falha repetida."
}
},
{
"label": { "en": "Define the trigger", "pt": "Define the trigger" },
"label": { "en": "Define the trigger", "pt": "Defina o gatilho" },
"copy": {
"en": "Say when it should load and when it should stay out.",
"pt": "Say when it should load and when it should stay out."
"pt": "Diga quando deve carregar e quando deve ficar de fora."
}
},
{
"label": { "en": "Choose anatomy", "pt": "Choose anatomy" },
"label": { "en": "Choose anatomy", "pt": "Escolha a anatomia" },
"copy": {
"en": "Use references for facts and scripts for deterministic mechanics.",
"pt": "Use references for facts and scripts for deterministic mechanics."
"pt": "Use referências para fatos e scripts para mecânicas determinísticas."
}
},
{
"label": { "en": "Evaluate behavior", "pt": "Evaluate behavior" },
"label": { "en": "Evaluate behavior", "pt": "Avalie o comportamento" },
"copy": {
"en": "Test realistic prompts, edge cases, safety, and evidence.",
"pt": "Test realistic prompts, edge cases, safety, and evidence."
"pt": "Teste prompts realistas, casos extremos, segurança e evidência."
}
}
]
+88 -28
View File
@@ -1,75 +1,135 @@
{
"id": "summary",
"eyebrow": { "en": "Start here", "pt": "Start here" },
"title": { "en": "Ship the<br><em>system.</em>", "pt": "Ship the<br><em>system.</em>" },
"eyebrow": {
"en": "Start here",
"pt": "Comece aqui"
},
"title": {
"en": "Ship the<br><em>system.</em>",
"pt": "Entregue o<br><em>sistema.</em>"
},
"lede": {
"en": "This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result.",
"pt": "This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result."
"pt": "Este guia transforma trabalho com IA em uma forma: enquadre o problema, escolha o modelo e o agente, isole mudanças, ensine decisões repetíveis e verifique o resultado."
},
"footer": {
"en": "Each chapter stands alone; the order follows a real task becoming a reliable change.",
"pt": "Each chapter stands alone; the order follows a real task becoming a reliable change."
"pt": "Cada capítulo se sustenta sozinho; a ordem segue uma tarefa real se tornando uma mudança confiável."
},
"cards": [
{
"label": { "en": "01", "pt": "01" },
"title": { "en": "Models", "pt": "Models" },
"label": {
"en": "01",
"pt": "01"
},
"title": {
"en": "Models",
"pt": "Modelos"
},
"copy": {
"en": "Capability and effort are separate knobs.",
"pt": "Capability and effort are separate knobs."
"pt": "Capacidade e esforço são controles separados."
},
"href": "../models/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": {
"en": "Open chapter →",
"pt": "Abrir capítulo →"
}
},
{
"label": { "en": "02", "pt": "02" },
"title": { "en": "Agents & trees", "pt": "Agents & trees" },
"label": {
"en": "02",
"pt": "02"
},
"title": {
"en": "Agents & trees",
"pt": "Agentes e árvores"
},
"copy": {
"en": "Bound roles, handoffs, and worktrees.",
"pt": "Bound roles, handoffs, and worktrees."
"pt": "Limite papéis, handoffs e worktrees."
},
"href": "../agents/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": {
"en": "Open chapter →",
"pt": "Abrir capítulo →"
}
},
{
"label": { "en": "03", "pt": "03" },
"title": { "en": "Skills", "pt": "Skills" },
"label": {
"en": "03",
"pt": "03"
},
"title": {
"en": "Skills",
"pt": "Skills"
},
"copy": {
"en": "Capture repeatable decisions.",
"pt": "Capture repeatable decisions."
"pt": "Capture decisões repetíveis."
},
"href": "../skills/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": {
"en": "Open chapter →",
"pt": "Abrir capítulo →"
}
},
{
"label": { "en": "04", "pt": "04" },
"title": { "en": "Rules", "pt": "Rules" },
"label": {
"en": "04",
"pt": "04"
},
"title": {
"en": "Rules",
"pt": "Regras"
},
"copy": {
"en": "Connect guidance to enforcement.",
"pt": "Connect guidance to enforcement."
"pt": "Conecte orientação a enforcement."
},
"href": "../rules/",
"cta": { "en": "Open chapter →", "pt": "Open chapter →" }
"cta": {
"en": "Open chapter →",
"pt": "Abrir capítulo →"
}
},
{
"label": { "en": "05", "pt": "05" },
"title": { "en": "Practice", "pt": "Practice" },
"label": {
"en": "05",
"pt": "05"
},
"title": {
"en": "Practice",
"pt": "Prática"
},
"copy": {
"en": "Compare prompts and skill-enabled runs.",
"pt": "Compare prompts and skill-enabled runs."
"pt": "Compare prompts e execuções com skills."
},
"href": "../hands-on/starter/",
"cta": { "en": "Open lab →", "pt": "Open lab →" }
"cta": {
"en": "Open lab →",
"pt": "Abrir lab →"
}
},
{
"label": { "en": "06", "pt": "06" },
"title": { "en": "Review desk", "pt": "Review desk" },
"label": {
"en": "06",
"pt": "06"
},
"title": {
"en": "Review desk",
"pt": "Mesa de revisão"
},
"copy": {
"en": "Browse original files and improved drafts.",
"pt": "Browse original files and improved drafts."
"pt": "Explore arquivos originais e rascunhos melhorados."
},
"href": "../skills-review/",
"cta": { "en": "Open desk →", "pt": "Open desk →" }
"cta": {
"en": "Open desk →",
"pt": "Abrir mesa →"
}
}
]
}