arch-doctor
Diagnostica o setup desta máquina: hooks, regras de fronteira, o wrapper do build, o java, de qual .claude/ o projeto veio e se a stack do compose está rodando.
arch-doctor, seção a seção
As seções do próprio SKILL.md da skill, em trechos. Passe o mouse ou clique numa delas para ver quais regras do projeto, templates e arquivos de references/ ela cita. As seções também são chips: clique num para ir até ela.
## Diagnosis
!java "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/ArchHook.java" doctor 2>&1
## AI files
!find "${CLAUDE_PROJECT_DIR:-.}/.claude" -maxdepth 2 -type f | sort
Interpret the result above and tell the user, in two or three sentences, whether the setup is operational. If something is marked with ❌, give the concrete command that fixes it — don't describe the problem in general terms.
The Provenance line is the one exception to "give the command": when it lists files edited locally, say which ones and that an update would overwrite them. Don't offer to run the update — losing a hand-edited norm is the user's call, not a fix to apply.
Don't fix anything without the user asking.
## Why this is a manually-invoked skill
Form 2: the whole body is two shell injections plus how to read them, so it is a procedure (axis 5) fired by a person who wants a verdict (axis 2 — /arch-doctor). Form 1 was rejected because a diagnostic the model reaches on its own runs a JVM and a find on every session that mentions a hook; Form 3 was rejected because there is nothing to isolate — the output is the report, and it is what the user asked to see.
Runs on sonnet with effort: high: the report is computed, but naming the cause and the command that fixes it is judgment (@.claude/decisions/0080-procedural-skills-on-sonnet.md).
The name is not doctor: /doctor is a native command, and a skill folder with that name shadows it silently — @CLAUDE.md § Known pitfalls.
O que lê, escreve e recusa
O contrato da própria skill, do SKILL.md, no texto original.
Class
observer — the territory is skill_classes.observer in @.claude/schemas/extensions.json, and it is empty: this skill writes no file. It reports, and the fix is the user's call. ArchHook.java guard enforces it.
Reads
the output of ArchHook.java doctor (which folds in compose) and the listing of .claude/, both injected above. Nothing else: an injection that lied about the setup would be worse than no report.
Writes
nothing, ever. Leaves no audit report either — its class, observer in skill_classes of @.claude/schemas/extensions.json, declares audited: false, because an observer that records its own observation makes the trail mostly about reading it.
Fonte: SKILL.md § Contract, no nerviz e4cae27.
O que o guard faz com ela
observer é a classe da skill, e a lista à esquerda é o seu território. A fase abre quando a skill roda em um prompt próprio, e o ArchHook julga cada escrita contra essa lista. O texto à direita é o do próprio hook.
write_allow de arch-doctor
qualquer arquivo: o território é vazio
A recusa sai com código 2 e a mensagem volta para o modelo.
> /arch-doctor … UserPromptSubmit guard prompt exit 0 # phase opened: arch-doctor (class observer) # write_allow: [] — this class writes no file
PreToolUse Write(pom.xml) guard write exit 2 ❌ `arch-doctor` is class `observer` — pom.xml is outside its territory. write_allow: (nothing — this class writes no file) Put the content in the spec as a code block, or finish the run and invoke the skill that owns this path. If the path is legitimately this skill's, widen skill_classes.observer in .claude/schemas/extensions.json — retrying will not help.
Quem a chama
Não é um passo de uma cadeia. Ela começa em um prompt próprio, /arch-doctor, e o guard a trata como qualquer outra skill: a fase abre e vale o território da sua classe.