Motor Hermes supervisionado¶
Pipeline do PD Framework que implementa issues planejadas, faz revisão independente e prepara PRs para aprovação humana sem entregar credenciais externas ao agente.
Por que foi construído assim¶
O cron Hermes anterior concentrava planejamento, implementação, revisão, PR e tracking numa sessão longa. O novo motor divide o trabalho em três estágios independentes e usa ticks curtos para recovery. O worker executa como LocalService sem GitHub, Linear ou 1Password; um controller determinístico revalida evidências e executa somente efeitos externos allowlisted.
Essa separação reduz auto-revisão, torna handoffs obrigatórios e permite recuperar execução após timeout, reboot ou falha parcial sem adivinhar o estado.
Stack¶
| Camada | Tecnologia |
|---|---|
| Linguagem | Python |
| Runtime de agente | Hermes Agent com openai-codex |
| Isolamento de processo | Windows LocalService, Scheduled Tasks e Job Objects |
| Estado confiável | claims, fencing e manifests controller-only em ProgramData |
| Transporte de código | Git bundle + evidence importados em quarentena controller-only |
| Integrações externas | Linear e GitHub CLI somente no controller |
| Onde roda | máquina Windows dedicada ao Hermes |
Como funciona¶
flowchart TD
classDef component fill:#D1FAE5,stroke:#10B981,color:#111
classDef flow fill:#DBEAFE,stroke:#3B82F6,color:#111
classDef decision fill:#EDE9FE,stroke:#8B5CF6,color:#111
classDef core fill:#FEE2E2,stroke:#EF4444,color:#111
classDef warning fill:#FEF9C3,stroke:#EAB308,color:#111
subgraph SG_component["Componentes"]
controller["Controller determinístico"]
worker["Worker LocalService"]
launcher["Launcher + gates"]
end
class controller,worker,launcher component
subgraph SG_flow["Fluxo do processo"]
eligible["1. Issue elegível"]
impl["2. Implementation (22h)"]
quality["3. Quality (06h)"]
final["4. Finalization (10h)"]
end
class eligible,impl,quality,final flow
subgraph SG_decision["Decisões"]
tick["Tick */15"]
valid["Resultado válido?"]
publish["Sim: publicar handoff"]
human["Gate humano"]
end
class tick,valid,publish,human decision
title["Motor Hermes supervisionado"]
class title core
blocked["Não: falhar fechado"]
class blocked warning
title -->|"componentes"| controller
title -->|"entrada"| eligible
title -->|"supervisão"| tick
controller -->|"lança com spec"| worker
worker -->|"resultado + bundle"| launcher
eligible -->|"22h"| impl
impl -->|"handoff"| quality
quality -->|"PR draft"| final
tick -->|"run terminou"| valid
valid -->|"sim"| publish
valid -->|"não"| blocked
publish -->|"ready"| human Uma issue começa em Todo/Backlog, já planejada e com own:hermes, hermes:ready e hermes:planned. O implementation pode iniciar às 22h, entrega código e handoff sem abrir PR. O quality review pode iniciar às 06h, revisa/corrige e abre apenas PR draft. O finalizer pode iniciar às 10h, revalida tudo e converte o draft para ready for human.
Cada cron acorda a cada 15 minutos, mas fora da sua janela apenas reconcilia execução em andamento, coleta resultados, trata timeout/reboot e faz cleanup seguro. Um mutex global mantém somente um worker ativo entre os três estágios.
Decisões técnicas¶
- Controller e worker em trust domains diferentes: o worker não possui credenciais de publicação.
- Handoff persistido obrigatório: sem manifest/handoff válido, o próximo estágio não começa.
- Bundle em vez de Git privilegiado no repo do worker: metadata Git controlada pelo agente nunca é executada pelo controller.
- Fail-closed em toda fronteira: ACL, host fence, task, Job Object, plano, scope, diff, gates, PR e postconditions precisam bater.
- Aprovação humana: o motor nunca aprova ou mergeia PR.
Gotchas & armadilhas¶
- Tick não significa launch —
*/15supervisiona; launches são restritos a 22h/06h/10h. - Três labels são cumulativas — faltar uma delas torna a issue inelegível.
- Plano é contrato — precisa existir na main e declarar
## Escopo de arquivos. - Python do scheduler difere do shell — validar pywin32 no processo real
no_agent. - Cleanup é fail-closed — não remover run/repo até task e Job Object estarem comprovadamente ausentes.
Como operar¶
python _core/hermes_worker_bootstrap.py verify
python _core/hermes_supervised_pipeline.py smoke
python -m unittest _core.test_hermes_worker_isolation _core.test_hermes_supervised_pipeline _core.test_hermes_supervisor_adversarial _core.test_hermes_worker_bootstrap _core.test_hermes_stage_launcher _core.test_hermes_cron_entrypoints
Os jobs operacionais usam workdir C:\ProgramData\PD-Hermes-Control\pd-framework, no_agent=true e schedule */15 * * * *.
FAQ¶
Como uma issue entra no pipeline? Ela deve estar em Todo/Backlog, ter plano publicado em times/dev/context/plano-<ISSUE>.md e as labels own:hermes, hermes:ready e hermes:planned.
Ele implementa uma issue a cada 15 minutos? Não. O tick frequente serve para supervisão e recovery. Novo implementation só começa na janela das 22h.
Quem abre o PR? Somente o controller, depois do Quality Review, e sempre como draft.
Quem aprova e mergeia? Felipe. Worker e controller são tecnicamente impedidos de aprovar ou mergear.
AppContainer é obrigatório? Não neste host dedicado, por decisão explícita de risco. Continua como hardening opcional.