AUR-616: analistas com deliberação por ferramentas
Medido antes (base 4bd9bd9b)
toolsCapable (cmd/aurumcode/review_deliberation.go) devolvia falso sempre
que havia perfis aplicados, e prepareDeliberation imprimia "deliberation:
o provedor não chama ferramentas" nesse caso, com o provedor chamando
ferramentas. Em --base e --pr, runProfilePasses (cmd/aurumcode/
profiles.go) criava um review.Reviewer por perfil sem SetDeliberation:
nenhuma passada de analista era oferecida ferramenta, e nenhuma transcrição
dessas passadas chegava ao stderr ou à auditoria.
deliberation.Session tinha só os limites próprios (Limits): com N
passadas, N vezes max_rounds e N vezes max_cost_tokens.
review.mergeTranscripts (internal/review/batch_merge.go) somava rodadas e
tokens de entrada/saída dos lotes, mas não base_tokens nem cost_tokens,
repetia em requested a ferramenta pedida por mais de um lote e listava em
not_requested uma ferramenta que outro lote pediu.
scanOnRequest rodava o scanner de novo a cada pedido e anexava uma
segunda varredura às scans da sessão.
O que mudou
internal/deliberation: Budget (budget.go) é o teto de uma revisão
partilhado por várias sessões: max_rounds - 1 rodadas que pedem
ferramenta e max_cost_tokens tokens de deliberação, somados. Session.Shared
(session.go) faz a sessão sacar desse orçamento pelo sharedLedger
(ledger.go): a rodada oferece ferramentas só enquanto o orçamento tem
rodada com ferramenta; sem rodada, a sessão recebe a instrução de resposta
final de imediato; um modelo que ainda pede ferramenta estoura max_rounds
("rodadas com ferramenta somadas na revisao"); o custo de cada rodada é
somado no orçamento e estourá-lo é max_cost_tokens ("tokens de
deliberacao somados na revisao"). Sem Shared, o ownLedger reproduz as
condições anteriores byte a byte. Transcript.AttributeTo grava o
analista na transcrição e em cada Call (analyst); Merge (merge.go)
junta as transcrições das passadas de uma revisão: ferramentas oferecidas
uma vez, pedidas por alguma passada uma vez cada, as demais não pedidas,
somas de rodadas e tokens (base e custo inclusive), chamadas em ordem, e
analysts com uma entrada por passada atribuída (nome, rodadas, tokens de
custo, pedidas, desfecho, limite).
internal/review: Deliberation.Budget chega à sessão como Shared; os
lotes usam deliberation.Merge.
cmd/aurumcode: prepareDeliberation(orchestrator, reviewer, analysts)
decide uma vez por revisão (deliberationPlan: ferramentas, limites,
limite parcial e, com analistas, o Budget); sem deliberation.enabled e
com analistas imprime terminal.deliberation_off; sem provedor com
ferramentas imprime terminal.deliberation_no_tools com o nome do
provedor; toolsCapable deixou de existir. analystPasses
(profiles_deliberation.go) monta o revisor de cada analista com o mesmo
plano e o orçamento partilhado, avisa (terminal.deliberation_rounds_spent)
o analista que começa sem rodada com ferramenta, e atribui a transcrição;
runProfilePasses devolve o resultado fundido e a transcrição fundida
(também no erro, para a auditoria). reportDeliberation imprime uma
linha por analista (terminal.deliberation_analyst) e a chamada com o
analista (terminal.deliberation_analyst_call). scanOnRequest responde
com a varredura já feita quando o mesmo engine é pedido de novo.
internal/i18n/catalog.yml: as cinco chaves terminal.deliberation_*
em pt-BR e en.
docs/configuration.md: seção "Analistas com as mesmas ferramentas" e o
motivo nomeado no parágrafo de "nada é oferecido"; linha de
review.profiles.
Verificação
go test ./cmd/aurumcode -run AUR616 (AC-001..AC-004 pelo comando real,
com a fixture de ferramentas e os perfis embutidos seguranca,solid),
go test ./internal/deliberation -run AUR616 (orçamento partilhado e
Merge), go test ./internal/i18n -run AUR616.
tests/acceptance/AUR-616.sh all: AC-001..AC-004 e as mutações MUT-001
(nenhuma ferramenta com analistas, como antes) e MUT-002 (cada analista
com limites próprios), ambas rejeitadas por asserção.
Gate local com modelo real, com e sem --perfis seguranca,solid: com
perfis, as linhas deliberation: analista ... com rodadas > 0; sem perfis,
a saída anterior.
Limites
per_tool_timeout_seconds continua por execução de ferramenta; não há
teto de tempo somado por revisão.
O tutorial docs/tutorials/deliberacao.md (fora dos paths deste card) ainda
diz que com perfis nada é oferecido: corrigir no card seguinte.