Doc touch
Skill pedroberaldo87/pedro-plugins/plugins/project-doc/skills/doc-touch
Marketplace privado de 17 plugins (skills, hooks e automações) pessoais para Claude Code.
npx -y skills add pedroberaldo87/pedro-plugins --skill doc-touchAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Atualização INCREMENTAL da documentação project-doc — mapeia o diff do trabalho recente pros docs afetados (via scope inverso) e re-projeta SÓ eles, sem re-mineração completa. Use quando o usuário diz "/doc-touch", "atualiza a doc do que eu mexi", "toca a doc", "atualiza a documentação disso que fizemos", ou após um ciclo de código quando a doc dos arquivos tocados precisa acompanhar. NÃO substitui o /project-doc FULL (mineração completa) — é o complemento frequente entre FULLs.
SKILL.md
10.7 KB, as published. Nobody here has run it
doc-touch — atualização incremental da doc
Irmã do /project-doc (mesmo plugin, mesma estrutura de doc, mesmos invariantes). O FULL minera tudo e re-projeta tudo; o touch atualiza só os docs cujo scope: intersecta o diff do trabalho recente. Mexeu → tocou a doc. O FULL vira evento raro.
Fluxo (5 passos)
1 · Grafo fresco + plano determinístico
graphify update "<root>" --force # AST, ZERO LLM, segundos, idempotente. Ausente → cria; fresco → no-op.
python3 plugins/project-doc/lib/pattern_check.py --project-root "<root>" --touch-plan --json
O touch documenta ⇒ é modo PESADO na regra do grafo (canônica: skills/project-doc/SKILL.md → Workflow Engine → Passo 0): doc nova nunca sai de grafo velho. Rode sem anunciar custo nem pedir confirmação — só informe o status. graphify não instalado ⇒ avise e siga (a re-projeção vem do diff, não do mapa; o touch não consome graph_map).
Devolve {changed, docs:{doc:{files, already_current}}, pending_docs, seam_review, unscoped_new, dead_scope, ledger_last_commit, last_full_age_days}. O changed = working tree ∪ staged ∪ ledger.last_commit..HEAD (mesma janela do backward-delta do journal, lida read-only). ⚠️ git diff não lista untracked — arquivo novo só entra no changed depois do git add.
Escalada touch → FULL: decida AQUI, antes de re-projetar nada. Quem chama o touch (o usuário, ou a /sovai) não tem como saber se o caso pede FULL — a informação nasce neste passo. Um sinal só, e ele é mecânico:
last_full_age_days > 30(ounull— ledger ausente/ilegível/SHA órfão, ou seja "não sei") ⇒ escale pro FULL. Em modo autônomo (/sovai, headless) escale e siga, sem perguntar: sugerir não serve pra quem não está lendo. Em modo interativo, diga o número e pergunte.- Caso contrário ⇒ touch, que é o caminho normal.
O campo existe porque o FULL é o único que avança ledger.last_commit (o touch é read-only nele), então a data desse commit é a data do último FULL.
⚠️ Não invente um segundo critério. unscoped_new e "arquivo fora do scope de todo doc" não servem de gatilho, e a tentação é real: o primeiro exige, por definição, que o arquivo esteja num diretório já coberto (então acusaria FULL a cada test_*.sh novo), e o segundo é alto num repo saudável (os scope: são seletivos de propósito — medido: 41 de 79 arquivos mudados neste repo, com o touch sendo claramente a escolha certa). Mecanizar "isso é estrutural?" produz heurística com cara de determinismo — o precedente do repo é o commits_after > 0 or edits_after >= 3, que era código e carimbava plano de 10 fases como executado.
Trabalhe sobre pending_docs, não sobre docs. docs lista tudo que o diff toca; pending_docs exclui os que já absorveram a mudança (doc mais novo que os arquivos). Sem isso o touch repetido vira no-op — enquanto o trabalho não é commitado, o git diff segue mostrando os mesmos arquivos. pending_docs vazio → reporte "nada a tocar" e pare.
2 · Re-projeção escopada, por doc
Para cada doc do plano (sequencial se ≤3; subagentes paralelos se mais): o agente recebe o doc atual + SÓ os arquivos mudados do scope + o diff deles (git diff <ledger_last_commit> -- <files> + working tree) e:
- Atualiza apenas as seções afetadas pelo diff; preserva o resto intocado (não reescreve, não "melhora").
- Obedece as Regras de escrita assertiva do SKILL grande (
skills/project-doc/SKILL.md→ Rules): nome/número/lista só por derivação mecânica no run; ponteiro = arquivo+símbolo; "ativa" exige evidência de wiring; costura citada existe nos dois lados. - Fato durável genuinamente NOVO que entrou na doc → anotar para o passo 4.
3 · Gate doc-lint (determinístico, antes do re-stamp)
python3 plugins/project-doc/lib/doc_lint.py --project-root "<root>" --docs <docs tocados> --json
FAIL → corrigir com a evidência que o próprio lint dá e re-rodar (máx 2 iterações; persiste → reportar FAIL, não silenciar). Falso-positivo legítimo (var dinâmica, config externa) → <!-- lint:ignore TOKEN --> ou .claude/.project-doc/lint-allow.txt, com justificativa no report.
4 · Journal
- Journal (disciplina do FULL, nunca relaxar):
journal.py adoptsó de fato durável genuinamente novo (nunca adopt do que já está vivo);journal.py invalidatesó contradição frontal com evidência arquivo:linha. - PROIBIDO rodar
journal.py update— avançarialedger.last_commite queimaria o backward-delta do próximo FULL. O ledger pertence ao FULL; o touch é read-only nele. - NÃO carimbe nada aqui. O carimbo é o passo 5, e ele vem depois do commit — pelo motivo do ovo-e-galinha abaixo.
5 · Report + o rito de DOIS commits (não é opcional)
Report curto primeiro: docs tocados (com o quê) · seam_review (costuras tocadas — verificar se o claim do OUTRO módulo mudou) · unscoped_new (arquivos novos em dirs cobertos — oferecer adicionar ao scope: do doc certo, ou ao verified-by: se for suíte de teste) · dead_scope (renames) · idade do último FULL (last_full_age_days, já decidida no passo 1 — aqui é só relatar o número).
Por que dois commits, e por que não dá pra ser um: o carimbo generated-commit: diz "esta doc vale pro estado do código no commit X". Quando código e doc entram no mesmo commit, X ainda não existe no momento de escrever o frontmatter — então o carimbo aponta pro commit anterior, a janela de staleness enxerga a mudança que a própria doc acabou de descrever, e o hook do SessionStart passa a gritar "⚠️ DEFASADA" sobre doc recém-nascida. Um doc não consegue citar o commit que o contém. Este repo pagou isso 3× (16211ae, b9028c3, 8d7a5a0) antes de virar comando.
PC="plugins/project-doc/lib/pattern_check.py"
# 1º commit — o CONTEÚDO (código, se houver, + os docs re-projetados + journal + grafo)
git add <arquivos tocados> .claude/docs/<tocados> .claude/.project-doc/findings.jsonl graphify-out/
git commit -m "..." # nunca `git add -A`
# 2º commit — o CARIMBO, apontando pro commit que acabou de nascer
python3 $PC --project-root . --restamp .claude/docs/<tocados>
git add .claude/docs/<tocados> && git commit -m "docs: re-stamp pro commit do conteúdo"
# confira: os dois medidores têm que concordar em `fresh`
python3 $PC --project-root . --project-staleness .
O --restamp faz o que antes era receita de sed pra lembrar: generated: = hoje, generated-commit: = HEAD, doc-sig: recomputada do corpo final e preservando a gen do doc-set (lida do marker do CLAUDE.md, não o CURRENT_GEN do código — o --sig cru bumpa a gen e viola o invariante "Gen NÃO bumpa"). Ele pula doc autoral (authored-by: human) e arquivo sem frontmatter, e falha sem escrever nada se não resolver o HEAD — carimbo pela metade é pior que carimbo velho. Passe só os docs que você re-projetou: carimbar doc que ninguém tocou escreveria generated: hoje sobre trabalho que não aconteceu.
Push seguro: git fetch antes, confirme fast-forward (git merge-base --is-ancestor origin/<branch> HEAD), nunca --force — o session-sync do bootstrap disputa esse push.
O que entra nos commits: só os artefatos de doc — docs tocados, findings.jsonl e graphify-out/ se existir (o .gitignore do projeto é quem exclui cache/ e os paths de máquina; o graph.json é versionado) — mais o código, se esta rodada mexeu em código. Nunca git add -A. O touch preserva o resto do doc, inclusive erro pré-existente: é complemento do FULL, não substituto.
Invariantes (não-negociáveis)
- Doc autoral é INTOCÁVEL. Arquivo com
authored-by: humanno frontmatter (quality-goals.md,constraints.md,context.md,solution-strategy.md,glossary.md,decisions/*.md— território do/start-doc) nunca é re-projetado, nunca ganhascope:, nunca é re-stampado. Se um aparecer no plano, pule e reporte. Hoje a proteção é indireta — oscope: []vazio o mantém fora dotouch-plan—, mas o passo 5 manda corrigirdead_scopee adotarunscoped_newnoscope:do doc certo: popular o scope de um autoral quebraria a trava para sempre e em silêncio. Antes de mexer noscope:de qualquer doc, cheque oauthored-by:. (Achado da revisão de 2026-07-26.) - Ativo novo exige linha de durabilidade (gen 3.8). Se
data-stores.mdestá entre os docs tocados, confira que todo depósito nele tem bloco correspondente emdurability.md— é a regra do check #24 do FULL, trazida pro touch porque senão um volume novo no compose entra no inventário e fica sem cobertura declarada até o próximo FULL (que pode demorar 30 dias). Sem bloco → escreva[TODO: sem cobertura declarada]e reporte. Silêncio sobre durabilidade é o que a gen 3.8 proíbe. - Gen NÃO bumpa. O touch não invalida docs antigas nem cria campo obrigatório (
generated-commit:é opcional — ausência não é violação). - Grafo em modo PESADO — o touch escreve doc, então garante o grafo fresco (
graphify update --force, passo 1), igual ao FULL. O que o touch NÃO faz é consumir o mapa: re-projeta do diff, semgraph_map.py/fan-out. Grafo e doc viajam juntos no commit. - Ledger read-only. Ver passo 4.
- Nunca re-projetar doc fora do plano. O touch-plan é o contrato; doc não mapeado não é tocado (nem "aproveitando que estou aqui").
- Secret: as mesmas regras do FULL (nomes SIM, valores NUNCA).
Output Protocol
**Touch 1/5:** grafo {criado | atualizado | já fresco | graphify ausente} · plano → {N} arquivos mudados → {M} doc(s) afetado(s) [+ costuras: {ids}] · último FULL há {D} dias → **{touch | ESCALEI PRO FULL}**
**Touch 2/5:** re-projeção → {doc}: {seções atualizadas}
**Touch 3/5:** doc-lint → {ok | X FAILs corrigidos | FAIL persistente: ...}
**Touch 4/5:** journal ({adopts} adoções, {invs} invalidações) · ledger intocado
**Touch 5/5:** conteúdo <hash1> + carimbo <hash2> ({M} doc(s) via --restamp) · staleness: por-doc {X} · agregado {Y} · último FULL há {N} dias{ — sugerir /project-doc se >30}