O que a casca ao redor do modelo realmente oferece — loop, context window, skills, hooks, slash commands, sub-agents, memória, MCP — e onde termina o que é genuinamente nativo antes de qualquer framework externo entrar em cima.
Doze seções. Cada uma numera um mecanismo que a Anthropic de fato expõe — não o que qualquer framework coloca em cima. A Parte 2 entra nisso.
— e por que Claude Code, a CLI que você usa todo dia, não é o modelo. É a casca que permite o modelo operar.
Antes de qualquer coisa, uma confissão de método: o termo "harness" não é completamente padronizado na literatura de ML. A Anthropic usa ele bastante nos posts de engenharia — especialmente no Effective harnesses for long-running agents e no mais recente Harness design for long-running application development — para se referir ao conjunto do que cerca o modelo durante execução: a loop principal, o system prompt, as tools disponíveis, como o context window é gerenciado, e a lógica que decide quando compactar, resetar, ou passar trabalho pra outro agente.
Uma analogia útil, admitidamente imperfeita: harness é o cockpit do piloto. O piloto (o modelo — Opus, Sonnet, Haiku) é o que toma decisões; o cockpit é tudo ao redor que converte essas decisões em controle da aeronave: manche (tools), tela de instrumentos (context), rádio (stdout/stderr), piloto automático (compaction), ejetor de emergência (context reset). Trocar o piloto sem mexer no cockpit — você tem um piloto melhor; trocar o cockpit sem mexer no piloto — você ainda tem o mesmo piloto, só que com mais ou menos alavancas.
Dito isso, o Claude Code — a CLI que roda no seu terminal, que está interpretando este texto neste instante — é um harness específico, opinado, construído pela Anthropic em cima dos modelos Claude. Ele expõe um conjunto finito de mecanismos para você moldar o comportamento. Essa Parte 1 inventaria esses mecanismos, um por um, com evidência (arquivo:linha quando possível) e sem fingir certeza onde não temos.
Quando você lê “harness” em posts da Anthropic, geralmente é sobre o
design (decisões de arquitetura — planner/generator/evaluator,
context resets, sprints). Quando você lê “harness” em contexto de CLI,
é sobre o runtime — o binário claude
executando o loop. Os dois usos se sobrepõem, mas não são idênticos.
Nesta apresentação uso “harness” mais no sentido de runtime, com
referências pontuais ao uso no sentido de design.
Combinando a leitura dos posts de engenharia e a observação direta do comportamento do Claude Code, um harness tem cinco peças. Se alguma delas não existir, você ainda tem um chatbot — não um agente.
Inferência minha, vale explicitar: a Anthropic raramente usa essa lista de cinco itens com essa exata taxonomia. É como eu condensei, a partir dos artigos. (Veja §02 pra context management, §05 pra sub-agents, §06 pra hooks — cada uma dessas peças tem camadas que o harness do Claude Code expande.)
— o recurso mais escasso do harness, e o que toda decisão de design tenta preservar.
O context window é o cérebro de curto prazo do modelo. Todo token que
entra ali — system prompt, histórico, tool results, file reads,
CLAUDE.md — consome orçamento. Os modelos Opus 4.7 atingem
1 milhão de tokens (o badge do rodapé mostra isso: Opus 4.7 (1M context));
modelos anteriores tipicamente 200k. Mas capacidade não é gratuita.
Isso é o que a Anthropic chama de context rot
— a decadência atencional que ocorre à medida que a janela se enche. A causa
é arquitetural: transformers criam n² relações par-a-par entre
tokens; quando n cresce, a atenção fica diluída e o modelo perde capacidade
de recuperar a informação certa no momento certo.
(Fonte: raw-anthropic-context-engineering.md:28–36.)
O harness nativo combina três estratégias (a Anthropic documenta todas em effective-context-engineering-for-ai-agents):
Grep a abrir 50 arquivos: cada arquivo aberto
é tokens que depois vão pesar.
raw-anthropic-context-engineering.md:94 —
“we implement this by passing the message history to the model to
summarize and compress the most critical details. The model preserves
architectural decisions, unresolved bugs, and implementation details
while discarding redundant tool outputs.”
Essa linha descreve o que é, literalmente, auto-compaction no Claude Code.
O harness monta o contexto em camadas. A ordem típica (inferência a partir do que observo e do que a Anthropic documenta):
Quando compaction ocorre, o item 6 é o que é resumido primeiro; itens 1–5 são mantidos integrais porque mudam as regras do jogo. Isso é inferência minha sobre o comportamento observado — a Anthropic não publica uma tabela de precedência pública.
Termo usado no post de harness design. Alguns modelos, ao sentir a janela
se aproximando do limite, começam a "embrulhar" trabalho prematuramente
— resumos apressados, encerramentos que não eram pedidos. Sonnet 4.5
exibia isso fortemente (é mencionado em raw-anthropic-harness-design.md:26).
Opus 4.6 e superiores mitigaram. É um efeito emergente: não há um
sinal formal "contexto cheio" — o modelo estima e age.
— as macros do usuário. Uma pasta, um arquivo .md,
e um prefixo /.
Slash commands são o mecanismo mais simples que o Claude Code oferece
para o usuário empacotar prompts reutilizáveis. A definição vive em
.claude/commands/<nome>.md
— dois escopos: projeto (/Users/italo/italo_gustavo/.claude/commands/)
e user-global (/Users/italo/.claude/commands/).
Subpastas criam namespaces: .claude/commands/AIOX/init.md
vira /AIOX:init.
Arquivo Markdown com frontmatter YAML opcional. O corpo do arquivo
é o prompt que será injetado na conversa quando o usuário invocar.
Exemplo real do seu codebase, em /Users/italo/italo_gustavo/.claude/commands/greet.md:
# greet Generate contextual agent greeting using GreetingBuilder infrastructure. --- ## What This Command Does When activated, this command: 1. Loads the GreetingBuilder module from `.aiox-core/development/scripts/greeting-builder.js` 2. Extracts agent definition from the calling agent (name, icon, persona_profile, commands) 3. Analyzes conversation history to detect session type (new/existing/workflow) 4. Generates intelligent greeting based on: ...
Esse arquivo não "faz" nada sozinho. Quando o usuário digita
/greet, o harness lê o arquivo e injeta
seu conteúdo como se fosse a próxima mensagem do usuário (ou algo equivalente —
o comportamento exato varia).
Slash commands só carregam quando o usuário digita /nome.
Eles não são descobertos pelo modelo autonomamente.
Isso é fundamental: o modelo não "vê" a lista de comandos disponíveis
a menos que o harness decida mostrar (normalmente no UI — uma lista de
autocomplete). O modelo só conhece o prompt depois que o usuário invocou.
Listando /Users/italo/.claude/commands/
(user-global) e /Users/italo/italo_gustavo/.claude/commands/
(projeto), existem hoje:
| escopo | comando | arquivo |
|---|---|---|
| user | /greet | ~/.claude/commands/greet.md |
| user | /mega-brain | ~/.claude/commands/mega-brain.md (20.4 KB) |
| user | /sync-repos | ~/.claude/commands/sync-repos.md |
| user | /system-architect | ~/.claude/commands/system-architect.md (10.4 KB) |
| projeto | /AIOX:init | .claude/commands/AIOX/init.md |
| projeto | /AIOX:help | .claude/commands/AIOX/help.md (16.2 KB) |
| nativo | /init | Claude Code built-in — gera CLAUDE.md |
O comando nativo /init é um bom exemplo de referência:
a Anthropic embute alguns slash commands no próprio binário — não ficam em
arquivos, mas se comportam identicamente ao usuário. /help,
/clear, /compact,
/model, /login entram nessa
categoria. A documentação diz textualmente: não invoque skills para essas CLI
built-ins.
/deploy disponível, o modelo só
sabe disso se você (ou a UI) mencionar. Contraste com Skills (§04),
que se "anunciam" via descrição no frontmatter.
/mega-brain no seu caso)
injeta o arquivo inteiro no contexto toda vez que invocado. Se for complexo,
considere transformá-lo em Skill — a Skill tem carregamento lazy (§04).
.md. Scripts, templates ou assets
ficam fora — você os referencia por path, mas eles não "vêm junto" com
o comando. Skills podem empacotar tudo isso.
— o equivalente a plugins. Uma pasta, um SKILL.md,
e — aí a diferença — o modelo as descobre sozinho.
Skills são a evolução de slash commands quando você precisa de três coisas que slash commands não dão bem: auto-descoberta (o modelo saber quando chamar), lazy loading (não gastar tokens com skills que não são ativadas), e empacotamento (trazer scripts, templates, assets junto).
Cada skill vive em uma pasta com um arquivo SKILL.md
na raiz. O frontmatter YAML é agora obrigatório (diferente de slash
commands): contém pelo menos name e
description. A description é o que o modelo lê
— é o pitch que faz a skill se auto-anunciar.
--- name: graphify description: any input (code, docs, papers, images) → knowledge graph → clustered communities → HTML + JSON + audit report trigger: /graphify --- # /graphify Turn any folder of files into a navigable knowledge graph with community detection, an honest audit trail, and three outputs: interactive HTML, GraphRAG-ready JSON, and a plain-language GRAPH_REPORT.md. ## Prerequisites ... ## Workflow ... ## Examples ...
Acima: cabeçalho real de /Users/italo/.claude/skills/graphify/SKILL.md
(arquivo completo: 55.6 KB, 1336 linhas). O frontmatter tem 3 campos; o
corpo é o conteúdo substantivo que só é carregado se a skill for ativada.
A description do frontmatter não é enfeite —
é o único sinal que o modelo usa para decidir ativar a skill. Escreva como
se fosse um elevator pitch para outro LLM: nome do problema, inputs,
outputs, condições de gatilho. Descrições vagas matam a skill — o modelo
nunca vai chamar algo que não entende quando usar.
<system-reminder>
blocks. O modelo, ao ler o prompt do usuário, compara com as descrições
e decide se deve chamar alguma. Frameworks mais antigos te obrigavam a
declarar explicitamente qual plugin usar; Skills inverteu: descreva bem
o quando, o modelo decide.
SKILL.md — que pode ter dezenas de KB —
só carrega quando a skill é ativada. Antes disso,
só nome + descrição ocupam tokens. Contraste com slash commands: o
conteúdo do comando entra inteiro toda invocação.
A pasta da skill pode conter além do SKILL.md:
LICENSE.txt, README.md (não entram no contexto do modelo — ficam no filesystem)
Exemplo: a skill graphify embute scripts Python
que extraem, detectam comunidades e renderizam o grafo. O
SKILL.md diz "rode
python scripts/extract.py com esses args" — e o
modelo usa o Bash tool.
Listando /Users/italo/.claude/skills/ (user-global)
e /Users/italo/italo_gustavo/.claude/skills/ (projeto):
| escopo | skill | origem |
|---|---|---|
| user | graphify | symlink para .agents/skills/frontend-design (Anthropic oficial) |
| user | frontend-design | symlink para skill oficial da Anthropic — plugins/frontend-design |
| user | knowledge-dream | customizada |
| user | elx-audit | customizada |
| user | eloquent-best-practices etc. | symlinks para skills Laravel (oficiais 3rd-party) |
| projeto | cli-router | customizada |
| projeto | tech-research | customizada |
| projeto | deep-strategic-planning | customizada |
| projeto | doc-rot | customizada |
O post de engenharia da Anthropic
Harness design for long-running application development
referencia explicitamente a frontend-design skill em
github.com/anthropics/claude-code/blob/main/plugins/frontend-design/skills/frontend-design/SKILL.md
(citado em raw-anthropic-harness-design.md:12 e :100).
É uma das primeiras skills publicadas pela Anthropic como referência.
Quando o usuário diz algo como "Cria um grafo desses papers", o modelo compara com as descriptions em memória e pode:
/graphify (recomendação verbal)— o jeito nativo de paralelizar e isolar trabalho. Contextos novos para cada tarefa, resultados que voltam condensados.
Quando o Claude Code precisa fazer algo que vai consumir muito contexto
— pesquisa em dezenas de arquivos, implementação de múltiplas features —
ele tem a opção de delegar para sub-agents.
A Agent tool aceita um subagent_type e um
prompt, e spawna um novo agente com janela de
contexto própria.
general-purpose (investigação ampla),
Explore (read-only, mapeamento de codebase),
Plan (decomposição de trabalho em steps).
Projetos podem definir tipos adicionais.
isolation: "worktree", o harness cria
um git worktree novo, checkout em branch
isolado, e o sub-agent opera lá. Commits do sub-agent não colidem com
commits do parent. (Esse é justamente o worktree em
que este texto está sendo gerado — veja o path:
/Users/italo/italo_gustavo/.claude/worktrees/agent-a9bee114.)
Parent combina os resumos e toma decisões. Nenhum sub-agent tem memória de outro. É deliberado: quanto maior a isolação, menor o contaminação cruzada.
Todo sub-agent paga o custo de aquecer o contexto: system prompt completo + tool schemas + CLAUDE.md + rules carregam do zero. Isso é frequentemente 10–40k tokens "de graça" antes do trabalho começar. Portanto: sub-agents para tarefas grandes o suficiente que o warmup não seja o principal custo. Tarefa pequena = fazer inline.
parallel-subagent-isolation.md cobre exatamente
isso — é uma rule criada depois de um incidente real.)
— o único lugar onde você injeta lógica imperativa no harness. O modelo pede algo, o hook decide se passa.
Hooks são scripts externos (shell, Node, Python) que o harness executa em pontos específicos do loop. Essa é a ponte entre o modelo (declarativo, textual) e o mundo determinístico (código). Se você precisa garantir que algo sempre aconteça — independente do modelo "lembrar" — hooks são o mecanismo.
Hooks são declarados em settings.json, no campo
hooks, estruturado por evento. Veja o
seu ~/.claude/settings.json:
"hooks": {
"SessionStart": [
{ "hooks": [ { "type": "command", "command": "~/.claude/hooks/kill-orphan-mcps.sh" } ] }
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "~/.claude/hooks/rtk-rewrite.sh" },
{ "type": "command", "command": "~/.claude/hooks/port-check.sh" }
]
},
{
"matcher": "WebFetch",
"hooks": [
{ "type": "command", "command": "~/.claude/hooks/jina-webfetch-router.cjs" }
]
}
],
"Stop": [...]
}
| Evento | Quando dispara | Matcher opcional |
|---|---|---|
PreToolUse |
Antes do harness executar qualquer tool call do modelo | Nome da tool (ex: Bash, WebFetch) |
PostToolUse |
Depois da tool executar (mesmo se falhou) | Nome da tool |
UserPromptSubmit |
Quando o usuário envia uma mensagem | — |
SessionStart |
No início da sessão | — |
Stop |
Quando a sessão termina normalmente | — |
StopFailure |
Quando a sessão termina por erro | — |
PreCompact |
Antes de auto-compaction rodar (pode capturar estado) | — |
A Anthropic publica a lista oficial em
docs.claude.com/en/docs/claude-code/hooks. A tabela
acima reflete o conjunto que observo usado hoje na prática — pode haver
outros eventos introduzidos em versões recentes. Inferência: a lista
cresce com o tempo, então confirmar a doc antes de escrever hook novo.
O harness executa o hook e passa o contexto via stdin em JSON. O hook responde via stdout em JSON, e exit code. Semântica típica:
| Exit | Sinônimo | Efeito |
|---|---|---|
0 | OK | Tool executa normalmente (ou conforme permissionDecision) |
2 | Block (legado) | Tool call bloqueada; stderr vira o "motivo" |
| outros | Erro | Normalmente logado, tool prossegue (comportamento varia) |
A forma moderna — que a própria doc recomenda desde 2025 — é usar exit 0 sempre e retornar no stdout um JSON como:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "WebFetch auto-summarises content; use Jina Reader for full/raw text..."
}
}
permissionDecision aceita: "allow",
"deny", (ou omitir, deixando o fluxo default).
Quando deny retorna, o harness
mostra a permissionDecisionReason para o modelo —
que então tem chance de reagir (ex: trocar de estratégia, explicar ao usuário).
/Users/italo/.claude/hooks/jina-webfetch-router.cjs:95–105
implementa exatamente o padrão moderno:
function emit(permissionDecision, permissionDecisionReason) {
process.stdout.write(
JSON.stringify({
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision,
permissionDecisionReason,
},
})
);
process.exit(0);
}
Três hooks do seu setup pessoal ilustram tipos comuns:
jina-webfetch-router.cjs
(PreToolUse, matcher WebFetch) — intercepta toda WebFetch call, nega por
padrão, diz ao modelo pra usar curl r.jina.ai
em vez disso. Allowlist para localhost/privados. Bypass via env
CLAUDE_WEBFETCH_ALLOW=1.
port-check.sh
(PreToolUse, matcher Bash) — detecta padrões de server-start em comandos
Bash, verifica se a porta está em LISTEN, bloqueia se colidir. Criado
depois de um incidente em 16/04/2026 — está documentado na rule
port-availability.md.
kill-orphan-mcps.sh
(SessionStart + Stop) — housekeeping. Ao iniciar, mata processos MCP
órfãos. Ao parar, idem. Ciclo de vida limpo.
Memory/preferences/instruções no CLAUDE.md pedem ao modelo — e o modelo tenta lembrar, mas nem sempre consegue em sessão longa. Hooks executam, independentemente. Se algo precisa acontecer 100% das vezes (bloquear push pra main, rodar testes antes de commit, rotear WebFetch) → hook. Se é uma preferência flexível → instrução no CLAUDE.md.
— o ponto único onde você configura o harness. Tudo que o Claude Code "lembra" sem perguntar mora aqui.
Três arquivos, três escopos, uma regra de precedência:
| arquivo | escopo | commitado? | precedência |
|---|---|---|---|
~/.claude/settings.json |
user | não (home) | baixa |
<proj>/.claude/settings.json |
projeto | sim | média |
<proj>/.claude/settings.local.json |
projeto — local | não (gitignored) | alta |
Local override projeto override user. Isso é importante: você pode ter
defaultMode: "bypassPermissions" no user global
(pra conveniência pessoal), mas um projeto específico pode forçar
defaultMode: "default" no settings comitado —
o projeto vence.
| campo | função |
|---|---|
permissions | allow/deny lists e defaultMode |
hooks | Array por evento — ver §06 |
env | Variáveis de ambiente injetadas na sessão |
statusLine | Comando para gerar a linha de status da CLI |
enabledPlugins | Plugins oficiais ativos |
autoUpdatesChannel | "latest" / "stable" |
alwaysThinkingEnabled | Ativa extended thinking por default |
effortLevel | "low" … "xhigh" — esforço do modelo |
autoMemoryEnabled | Liga o memory system automático (§08) |
{
"permissions": {
"deny": [],
"defaultMode": "bypassPermissions"
},
"env": {
"CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING": "1",
"CLAUDE_CODE_EFFORT_LEVEL": "max",
"MAX_THINKING_TOKENS": "64000"
},
"hooks": { ... },
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
},
"alwaysThinkingEnabled": true,
"effortLevel": "xhigh",
"autoMemoryEnabled": true
}
/Users/italo/.claude/settings.json — arquivo completo
tem 95 linhas.
O settings.json do projeto é commitado.
Nunca coloque API keys, tokens, credenciais ali. Use
settings.local.json (gitignored por padrão)
ou variáveis de ambiente do shell. Se precisar que o harness injete um
env var, declare em settings.local.json.
CLAUDE.md.claude/rules/*.md.mcp.json ou no settings, dependendo da versão— o caderno de anotações que o agente carrega entre sessões. Não é o histórico; é o que ele escolheu guardar.
Memory é uma feature relativamente recente do Claude Code. A ideia vem
direto de Effective context engineering for AI agents
(seção Structured note-taking,
raw-anthropic-context-engineering.md:100–110):
dar ao agente um filesystem persistente onde ele registra o que descobriu,
para que futuras sessões possam recuperar sem releer tudo.
Nativamente, a Anthropic organiza memória por projeto, em
~/.claude/projects/<slug-do-projeto>/memory/.
O slug é derivado do path absoluto do projeto (trocando / por -).
No seu caso:
/Users/italo/.claude/projects/-Users-italo-italo-gustavo/memory/ ├── MEMORY.md ← index ├── feedback_aiox_agents_opus.md ← uma entrada └── feedback_git_remote_policy.md ← outra entrada
MEMORY.md é o index: lista de itens com
link para o arquivo detalhado + um resumo de uma linha. O modelo lê o index;
se um item for relevante, abre o arquivo referenciado. Exemplo real do
seu projeto:
- [All AIOX agents must use Opus](feedback_aiox_agents_opus.md) — CTO directive 2026-04-15: every squad agent (registry model, agent .md model_tier) defaults to Opus, not Haiku/Sonnet - [Git push policy — private only](feedback_git_remote_policy.md) — always push to `private` (contatoitalo/aiox-business), never to origin/italo_gustavo upstream
/Users/italo/.claude/projects/-Users-italo-italo-gustavo/memory/MEMORY.md:1–2
A Anthropic menciona convenções para os prefixos dos arquivos. Pelo que observo e o que a doc sugere:
| prefixo | tipo | exemplo |
|---|---|---|
user_ | Fatos sobre o usuário | user_prefers_portuguese.md |
feedback_ | Correções/direções dadas pelo usuário | feedback_git_remote_policy.md |
project_ | Fatos sobre o projeto/codebase | project_uses_monorepo.md |
reference_ | Pedaços de doc que o modelo quer lembrar | reference_aiox_constitution.md |
Inferência: a doc oficial lista esses tipos, mas convenções de nomeação evoluíram. O que importa é que o MEMORY.md linke cada um com um resumo claro — o modelo toma decisões a partir do index, não dos arquivos individuais.
Quando autoMemoryEnabled: true está setado
em settings.json (seu caso), o harness:
MEMORY.md no contexto inicialmemory/ ao longo da sessãoAmbos carregam no contexto inicial. A diferença: CLAUDE.md é editado por humano (regras, instruções, contexto de projeto que você escreveu); memory é editado pelo agente (aprendizados acumulados). É a separação entre "o que te digo" (CLAUDE.md) e "o que descobri" (memory).
Sem memória, cada sessão começa do zero. Toda correção que você dá ("não use whisper, use VibeVoice", "sempre commit em branch do worktree") é esquecida. Memory transforma o agente de uma amnesic tool em algo que acumula aprendizado. É pequeno em disk — uns kilobytes — mas grande em comportamento ao longo de semanas.
— o jeito padrão de o Claude falar com o resto do mundo. Não é uma feature; é um protocolo.
Model Context Protocol é a padronização que a Anthropic publicou em 2025 para o problema "como um LLM fala com sistemas externos de forma interoperável". Antes do MCP, cada framework tinha seu jeito (ChatGPT plugins, LangChain tools, bespoke integrations). MCP virou o USB-C: um protocolo de client/server sobre JSON-RPC que qualquer runtime pode implementar.
Do ponto de vista do Claude Code, MCP significa duas coisas:
node
ou python — que implementam o protocolo).
mcp__<servidor>__<tool>. O modelo chama
como chamaria qualquer tool. Ex:
mcp__chrome-devtools__take_screenshot.
Na sessão presente temos vários servidores MCP disponíveis. A lista completa vem via system-reminder, mas destaco alguns:
| servidor | tools expostas | uso típico |
|---|---|---|
chrome-devtools |
navigate_page, take_screenshot, evaluate_script… |
Inspecionar páginas, debuggar UI, Lighthouse |
langfuse |
createChatPrompt, listPrompts… |
Gestão de prompts versionados |
jira |
jira_get, jira_post… |
Automação de tickets |
tailwindcss |
get_tailwind_utilities, search_tailwind_docs… |
Doc/componentes Tailwind |
xcodebuild |
build_sim, test_sim, screenshot… |
Desenvolvimento iOS/macOS |
codex |
codex, codex-reply |
Executar OpenAI Codex como sub-agent |
MCP servers são configurados via CLI (claude mcp add …)
ou em arquivo. O Claude Code lê .mcp.json no projeto,
e ~/.claude.json no user global. Cada servidor declara:
tipo de transport (stdio, HTTP SSE), comando pra spawn, env vars, e a
lista de tools é descoberta pelo próprio Claude via handshake
do protocolo.
Esta sessão tem um bloco de MCP Server Instructions (veja o system-reminder do xcodebuild no início da conversa). É o próprio servidor MCP injetando instruções de uso no system prompt do Claude. Essa injeção é parte do protocolo. O Claude lê e ajusta comportamento — ex: "prefira XcodeBuildMCP tools a shell commands para tasks Apple".
Sem MCP, cada integração externa demanda modificar o próprio Claude Code (ou um wrapper). Com MCP:
Inferência técnica: embora MCP seja um protocolo aberto, quanto da
implementação client interna do Claude Code seja realmente pública/extensível
é menos claro. A spec do protocolo está em
modelcontextprotocol.io.
— quatro perfis de "o quão autônomo o agente opera". Trocar de modo muda o fluxo, não o modelo.
O harness tem quatro modos de permissão. O modo controla como o Claude Code lida com cada tool call potencialmente arriscada (Bash, Edit, Write, Delete). Você pode trocar no meio da sessão via UI ou CLI.
| modo | comportamento | quando usar |
|---|---|---|
default |
Pergunta ao usuário antes de cada tool call "arriscada". Allowlist em settings é respeitada. | Primeira sessão em projeto novo, ou quando você quer control review. |
acceptEdits |
Aceita automaticamente Edits/Writes em arquivos do projeto. Outras tools ainda pedem confirmação. | Refatoração em andamento, quando você sabe que quer mudanças em arquivos. |
plan |
Modelo só planeja — descreve o que faria, sem chamar tools que modificam estado. | Discussão de arquitetura, investigação preliminar antes de implementar. |
bypassPermissions |
Aceita tudo sem perguntar (respeitando denylist). | Quando você confia no agente e quer fluxo ininterrupto. Seu user settings usa este modo por default. |
bypassPermissions significa que o agente
pode rodar qualquer Bash sem perguntar. Em projeto que você não
conhece bem — ou em projeto com dados sensíveis — isso vira risco real.
Prefira default ou acceptEdits
até ter confiança operacional.
Independente do modo, permissions.allow e
permissions.deny em settings.json
dão controle por padrão de tool call. Exemplo real do seu
settings.local.json:
{
"permissions": {
"allow": [
"Bash(mkdir -p .claude/commands/Support/agents)",
"Bash(cp squads/aiox-support-squad/agents/*.md .claude/commands/Support/agents/)",
"Bash(rtk ls *)"
]
}
}
/Users/italo/italo_gustavo/.claude/settings.local.json:1–10
Com esses allows, mesmo em modo default o
Claude não precisa pedir permissão para esses comandos específicos.
É a forma certa de reduzir interrupção sem desligar permissions
completamente.
— a forma nativa de mostrar progresso. Pequena, simples, boa no que faz.
O Claude Code expõe uma tool — historicamente chamada
TodoWrite — que o agente usa para manter uma
lista de tarefas visível no UI do usuário. Não é uma feature sofisticada;
é um buffer JSON com três campos por item: content,
status, activeForm.
A mecânica é simbiótica: o agente, ao receber uma tarefa complexa,
decompõe em 3–7 itens, marca cada um como
in_progress enquanto trabalha, e
completed ao terminar. O usuário vê isso no UI
como checklist ao vivo. É ao mesmo tempo ferramenta do agente e
telemetria do usuário.
Duas razões, ambas mencionadas em Effective context engineering for AI agents:
A todo list não persiste entre sessões (ou não deveria — o comportamento varia por versão). É um estado da sessão ativa. Se você precisa rastrear progresso de algo que dura mais de uma sessão, use memory (§08) ou arquivos de estado dentro do projeto.
Em documentos recentes, a Anthropic também se refere a esse mecanismo como "TaskCreate/TaskUpdate/TaskList" — provavelmente uma evolução de API (mudança de nome sem mudança conceitual). Inferência: depende da versão do Claude Code.
— e por que frameworks de agentes existem em cima disso.
Recapitulando o que o harness da Anthropic, sozinho, oferece:
Note o padrão: são primitivos. Peças pequenas, bem definidas, que compõem. Nenhuma delas, isolada, é um "framework de agentes". Juntas, dão o que a Anthropic chama em Building Effective Agents de augmented LLM: modelo + tools + memory + retrieval. Composição em vez de framework.
Vale notar os vazios — não porque sejam defeitos, mas porque explicam onde frameworks emergem:
raw-anthropic-building-effective-agents.md:176–180
explicita os três princípios da Anthropic para design de agentes:
maintain simplicity in your agent's design; prioritize transparency
by explicitly showing the agent's planning steps; carefully craft
your agent-computer interface (ACI). A escolha de oferecer
primitivos em vez de frameworks é consistente com esse princípio.
É exatamente nesse vazio deliberado — agents-com-persona, workflows, delegação, metodologia de dev — que frameworks como AIOX se instalam. Eles não substituem o harness; eles compõem em cima dele. Usam skills para empacotar agents, slash commands para comandos de persona, hooks para impor regras, memory para persistir governança, sub-agents para paralelizar trabalho.
Na Parte 2 investigaremos como esse empilhamento funciona — o que é genuinamente novo no framework, o que é reembalagem de primitivos nativos, e o que é atrito contra o harness. É aí que fica interessante.
Fim da Parte 1.
A Parte 2 começa onde esta termina — examinando o que o AIOX adiciona por cima,
e o custo/benefício de cada camada.
Esta Parte 1 apoiou-se em três fontes primárias da Anthropic e em observação direta do setup do usuário. Linhas citadas ao longo do texto:
raw-anthropic-harness-design.md:12 — referência à frontend-design skill oficialraw-anthropic-harness-design.md:24–26 — context anxiety e context resetsraw-anthropic-harness-design.md:65 — Agent SDK + automatic compactionraw-anthropic-harness-design.md:100 — frontend-design usado como skill na planner agentraw-anthropic-harness-design.md:122 — "find the simplest solution possible"raw-anthropic-context-engineering.md:28–36 — context rot + n² attentionraw-anthropic-context-engineering.md:72–80 — just-in-time retrieval e CLAUDE.mdraw-anthropic-context-engineering.md:90–98 — compaction em Claude Coderaw-anthropic-context-engineering.md:100–110 — structured note-taking, memory toolraw-anthropic-context-engineering.md:112–117 — sub-agent architecturesraw-anthropic-building-effective-agents.md:16–20 — workflows vs agentsraw-anthropic-building-effective-agents.md:48–58 — augmented LLM building blockraw-anthropic-building-effective-agents.md:176–180 — três princípios de design~/.claude/settings.json:11–78 — hooks, env, permissions do usuário~/.claude/hooks/jina-webfetch-router.cjs:95–105 — protocolo moderno de permissionDecision~/.claude/commands/greet.md:1–25 — formato de slash command~/.claude/skills/graphify/SKILL.md:1–5 — frontmatter de skill~/.claude/projects/-Users-italo-italo-gustavo/memory/MEMORY.md:1–2 — formato de MEMORY.md index./.claude/settings.local.json:1–10 — permissions.allow exemplo