# Leppy Loop para DeepSeek Harness [English](README.md) Leppy Loop é um bundle Cordis externo e nativo que executa uma checklist Markdown rastreada com um processo e uma sessão novos do DeepSeek Harness por linha de worker. O controller é dono da sincronização Git, worktree isolada, transições da checklist, closure, gates, recuperação durável e leases de processo. Workers comuns mandam no repositório isolado inteiro: `paths=` é contexto, não bloqueio; comandos locais e Git são permitidos; arquivos gerados ou ignored nunca travam adoção. Só a checklist controladora e publicação remota ficam fora da autoridade do worker. A versão `0.3.54` é fixada no DeepSeek Harness `0.1.1-rc.2`, commit [`b150a551b8d465e31e418e1b2eaf5e79bbb7d28e`](https://github.com/deepseek-ai/deepseek-harness/commit/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e). Ela registra o comando Host, uma tool durável de controller sempre descobrível, a skill model-only `leppy-loop-operator`, sem colisão com o comando humano, e cards Web sem patch do Harness. ## Instalação Requer Node `22.19+`, Git e pnpm `10.28.1`. O DeepSeek Harness repassa a gestão de plugins ao `pnpm` encontrado no `PATH`; pnpm 11 exige aprovação separada de builds nativos e não é uma combinação de instalação afirmada para `0.3.54`. Configure a credencial do provedor selecionado na página Models do Harness, gere o pacote e instale no profile usado pelo Web host. Os workers reutilizam automaticamente o provedor, o perfil do modelo e a credencial selecionados; `DEEPSEEK_API_KEY` não é necessária quando outro provedor está ativo: ```sh pnpm install --frozen-lockfile pnpm gate pnpm pack npx @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add ./leppy-loop-deepseek-0.3.54.tgz ``` Reinicie o processo `dsh web` existente depois de alterar o profile. Refresh do navegador não compõe um plugin Host recém-instalado. Um tarball publicado no GitHub Release pode substituir o path do `.tgz` local; não há afirmação de publicação em registry de plugins. ## Uso rápido Abra uma sessão Web no repositório e autorize um lifecycle com linguagem humana comum — nunca paths, base, run ID, fingerprint, scope, ciclos ou flags de repair: ```text /leppy-loop /leppy-loop conclua a adoção de capabilities e abra um PR /leppy-loop rode somente local; não publique /leppy-loop status /leppy-loop parar ``` O slash command retorna depois de criar um permit de lifecycle e enfileirar um turno curto da IA. O mesmo permit conduz até dezesseis transições sequenciais de um único run/sessão/repositório: a IA pode retomar falhas recuperáveis, escolher repair limitado, reconciliar publicação e reagir ao fim do background sem pedir comandos separados por fase. Depois de consumir as dezesseis, só uma nova invocação humana direta pode anexar um próximo epoch com consumo zero para esse run exato, após settlement de job, lock do repositório e lease assinado; o modelo não consegue resetar. Só uma transição fica em voo. Depois de preso ao run, o permit usa marker HMAC obrigatório, recibos encadeados e head monotônico autenticado: admissão persiste antes do job, downgrade local-only antes do ack do slash e revogação de Stop antes do kill. Após restart do Host ele reidrata; anchors high-water append-only do Host sob `DSH_HOME` recusam rollback coordenado de head/prefixo local, authority moderna corrompida entra em quarentena, `run.json` mutável nunca concede autoridade e transição consumida não volta após crash. O permit ainda expira em 24 horas, não cruza sessão/repo/run e nunca autoriza ampliar scope, merge ou deploy. Linguagem explícita `não publique`/somente local impede publicação durante a implementação. Depois da conclusão o Leppy pergunta uma vez; resposta humana afirmativa assina uma renovação de publicação para o mesmo run que permite apenas push da branch do controller e criação/reconciliação do PR, nunca merge ou deploy. A tool global `leppy_loop_control` recebe checklist/base/run/recovery/publicação técnicos enquanto a superfície humana permanece simples. Todo turno de resolver de um run existente começa com `status` read-only; somente quando ele não retorna job vivo uma transição pode seguir. O status devolve checklist e base autenticadas exatas, e `continue` deriva ambas controller-side quando omitidas, sem obrigar o modelo a repeti-las ou adivinhá-las. O `preflight` read-only valida scopes canônicos e base antes de criar worktree. A tool prende o permit ao primeiro run uma única vez, valida cada continuação contra o controller HMAC vivo, usa orçamento cumulativo e transfere cada transição para `ctx.jobs` preso ao owner. `status` nunca confia em job lembrado e só expõe controller durável à sessão assinada: estado `running` sem job Host do owner vira `orphaned`, sem ID inventado. Fingerprints de gate, identidade do controller/checklist, recibos e ciclos limitados permanecem controller-side; workers mutáveis mandam no restante do repositório isolado e continuam sem publicação remota. A política padrão `adaptive` usa `gpt-5.6-terra` com esforço `high` nas tarefas comuns do OpenAI Codex e muda para `gpt-5.6-sol` com esforço `low` nas closures e na recuperação de uma tarefa parada. Falhas terminais de disponibilidade do SDK recebem até três workers frescos de recuperação no mesmo job do controller; somente indisponibilidade repetida após esse limite para com recibo. Conclusão no-op limpa fecha a checklist diretamente, enquanto trabalho sujo em qualquer parte do repositório isolado é adotado pelo controller sem retry cerimonial ou commit manual. Metadados `model=`/`effort=` na linha e opções CLI `--model`/`--effort` têm prioridade. Use `--worker-policy selected`, `terra-high` ou `sol-low` para escolher outro comportamento global. O limite padrão de transcript é 8192 KiB e pode ser alterado com `--worker-transcript-limit-kb`. Os recibos de retomada incluem `--recover-run ` para evitar ambiguidade quando ainda existem runs antigos com falha. A retomada autenticada exata resolve e valida o controller na worktree preservada do run, portanto o checkout fonte pode ter mudado de branch, removido a checklist ou conter alterações sujas não relacionadas; runs novos continuam exigindo checkout fonte limpo e checklist tracked. Um gate de fase local que falha reabre automaticamente a closure adjacente por até três ciclos de reparo restrito pela IA. Se o mesmo gate continuar falhando — ou não houver closure reparável — o controller commita o receipt não-zero como evidência consultiva e avança no mesmo job, sem girar transições de recovery. Resume comum adota evidência de gate presa ao HMAC depois de crash do controller sem reexecutá-lo. Controllers stalled antigos reexecutam o mesmo gate exatamente uma vez, com repair desativado, para criar evidência atual; worktree suja/movida e evidência autenticada ausente, malformada, forjada ou divergente falham fechadas. Caches Svelte de validação, na raiz ou aninhados, entram automaticamente em quarentena presa ao HMAC e voltam byte a byte depois do gate ou de um crash; churn de manifest não exige cerimônia e não apaga WIP ignored. Retry ou repair explícito continuam disponíveis no mesmo permit quando escolhidos deliberadamente. Quando o gate provar que a closure original omitiu artefatos gerados ou dependências necessárias, uma pessoa pode adicionar scopes existentes na worktree com `--repair-path `; as adições são validadas, persistidas, registradas e concedidas somente ao worker de reparo reaberto. Comandos na raiz podem omitir `cwd` ou usar `cwd="."`, enquanto a validação do commit continua limitada ao scope efetivo. Uma invocação direta de reparo encadeia por padrão até três ciclos de closure nova/gate, entregando cada novo recibo vermelho ao worker seguinte; `--repair-cycles <1..8>` altera esse limite rígido. O processo para imediatamente em sucesso, falha do worker, estado sujo, fingerprint alterado, cancelamento ou esgotamento, sem loop infinito. O resolver autônomo deve relatar stall/falha e parar; nunca pode editar a worktree preservada, delegar reparo, publicar ou integrar por fora do controller. Um ID exato também pode continuar um run seletivo já concluído na próxima linha aberta do branch/worktree preservado; runs concluídos nunca são escolhidos implicitamente. Em tarefas e closures comuns, `LEPPY_OUTCOME`, validação e cerimônia Git são telemetria consultiva. Report ausente ou malformado vira evidência em prosa; `blocked`/`failed` comum não interrompe a adoção sem `disposition: "implementation-impossible"` explícito. Limites de falha de tool encerram apenas o turno problemático; o controller preserva trabalho seguro e pode lançar workers frescos limitados. Falhas de gate de fase local continuam visíveis como evidência consultiva após reparo limitado; conflitos e gate final de publicação, authority, checklist e índice Git não mesclado continuam estritos. O controller reconcilia trabalho comum pelo estado Git que ele próprio observa antes de interpretar cerimônia do modelo. Ele recusa apenas índice não mesclado ou drift de branch/checklist, faz stage do WIP do repositório inteiro e cria, amenda ou consolida um commit convencional. Estado ignored/gerado não participa da adoção; candidatos legados pending ou interrompidos são adotados diretamente sem verifier detached. No Windows, a validação direta do Playwright não consegue criar os named pipes internos de libuv dentro do token `WRITE_RESTRICTED` do Harness. O Leppy registra `LEPPY_WINDOWS_NAMED_PIPE_UNAVAILABLE` depois da primeira chamada autenticada a `playwright`, sem repetir nem esconder o argv. A falha permanece visível como evidência consultiva; o controller comum pode adotar trabalho repo-wide sem verifier detached. WSL2 + bubblewrap continua sendo executor opt-in sem fallback Host não confinado. Configure um `.leppy-loop.json` tracked e portátil ou um `.leppy-loop.local.json` local do Host e não commitado, que tem precedência. O preflight de source clean admite somente esse arquivo privado untracked exato e limitado; qualquer outro WIP ainda bloqueia o início: ```json { "validationExecutor": { "kind": "wsl2", "distribution": "Ubuntu", "envFile": ".env", "envAllowlist": ["E2E_BACKEND_URL", "E2E_SYSTEM_KEY", "E2E_TENANT_URI"], "envPrefixes": ["PUBLIC_"], "envAliases": { "BACKEND_URL": "E2E_BACKEND_URL" }, "prepareScripts": ["prepare"], "seedPaths": ["src/reflector/backup.json", "src/reflector/controllers", "src/reflector/enums.ts", "src/reflector/fields.ts", "src/reflector/mocked-params.svelte.ts"], "webServerTimeoutMs": 600000, "playwrightConfig": "playwright.config.ts" } } ``` O config só nomeia variáveis; nunca contém seus valores. O arquivo de ambiente precisa resolver fisicamente para um único arquivo regular privado dentro do `repoRoot` exato e ter no máximo 64 KiB. O executor arquiva o OID autenticado do commit pendente e prova root/HEAD exatos do candidato; não monta a worktree Windows. `seedPaths` opcional aceita somente baselines Host-generated ignorados por autoridade `.gitignore` tracked e untracked nas duas roots; copia um snapshot estável preso a handles antes de extrair o archive, negando topologia symlink no destino, links, hardlinks, arquivos especiais, escapes, mais de 10.000 arquivos ou 256 MiB e emite receipt SHA-256. O install sempre usa `npm ci --ignore-scripts`; entradas canônicas do registry no lock, identidades dos pacotes, edges das dependências e launcher direto do Playwright são autenticados antes da árvore virar read-only — exceto mounts privados exatos de cache Vite — e antes de qualquer `prepareScripts` ou `prepareBins` explicitamente nomeado. `webServerTimeoutMs`, limitado a 180000–900000, exige o path exato `playwrightConfig` e cria um wrapper privado sem supor TypeScript nem editar o candidato. O `wslpath` da distribuição selecionada resolve o staging sem supor `/mnt/`. Dentro do WSL a cápsula mascara mounts do Host, homes, estado mutável da distro e WSL interop, oferece só workspace/home/temp/cache privados, autentica a tabela live de mounts e expõe somente um runtime mínimo read-only da distro (`/usr`, libs do toolchain e `/etc`) com submounts WSL mascarados e roda ali npm, web server, workers do Playwright e Chromium. `wsl.exe`, a distribuição declarada, Node/npm Linux, `findmnt` e `bubblewrap` são pré-requisitos explícitos. A rede continua compartilhada conforme o non-goal existente. `pnpm gate` roda automaticamente a fronteira real de Chromium/isolamento/cancelamento em Hosts Windows de release com WSL2; CI não-Windows registra skip explícito de plataforma. Use `pnpm test:wsl-capsule` para rodar só essa fronteira. O source da integração continua fora do tarball publicado. Até a versão 0.3.49 o controller registrava snapshot HMAC de paths ignored antes do worker; a 0.3.50 não invoca mais essa maquinaria para workers mutáveis. Depois que o worker termina, ele classifica o delta inteiro antes de mutar: WIP ignored preexistente e inalterado é preservado; WIP alterado, removido ou substituído falha fechado sem mover nada; promoção para tracked continua sujeita à validação normal de scope do candidate; e somente folhas de arquivo regular ausentes no baseline podem ser renomeadas atomicamente para quarentena privada. A referência da transação entra no active state autenticado antes do primeiro move. Recuperação de crash revalida todos os pares source/destination, raiz e parents físicos privados, link count, fingerprint e same-device antes de mover qualquer entry. Tentativas legadas sem snapshot só recuperam quando vale o digest vazio canônico ou quando uma busca limitada encontra um subconjunto exato dos fingerprints atuais cujo SHA-256 coincide com o digest autenticado do baseline não vazio. Somente uma identidade autenticada de tarefa/tentativa/baseline ativa pode usar a bridge anti-thrash. Antes do job da bridge iniciar, terminal normalizado e identidade completa da tentativa entram numa admissão HMAC `prepared`, idempotente e sob lock. A preparação prende o digest do request normalizado e o epoch/transição lifecycle alvo, então falhas antes do job repetem sem worker e um receipt já no último slot do budget é reutilizado sem incremento; o runner a exige e promove atomicamente para `consumed` antes da reconciliação, após o que replay é negado. A migração final, somente de baseline, pode incluir todos os paths untracked comuns atuais na prova exata do subconjunto histórico, mas nunca trata paths comuns não provados como output aceitável do worker: efeitos fora do scope são descartados pelo controller antes da adoção. O classificador de regras da base usa um Git dir isolado sem excludes mutáveis/globais, e um único budget de conteúdo cobre todas as classes de candidatos. A falha no-match exata do predecessor prova no máximo 39 fingerprints e pode receber uma migração única de quatro adições/100.000 candidatos; o terminal canônico dela pode receber uma migração adicional ciente de promoção, que só amplia os candidatos com paths exatos adicionados ao Git desde a base autenticada do active attempt e que continuam ignored. Esse terminal pode receber uma migração base-ignore para paths untracked comuns atuais comprovadamente ignored por blobs `.gitignore` regulares e byte-exact da base autenticada. O terminal base-ignore recebe uma migração final para paths newly tracked que eram ignored por essas regras da base mas não são mais ignored hoje; a detecção de rename é desligada para manter destinations exatos como candidatos Added. Regras symlink/gitlink, atributos que transformam checkout, bytes de path não canônicos e separadores ambíguos por plataforma falham fechado. Snapshots mais largos mantêm três adições/10.000 candidatos. A entrada é limitada a 128 KiB UTF-8 e a serialização/hash cumulativos a 512 MiB; conteúdo candidato e de quarentena tem limite independente de 512 MiB por fase em streaming. Qualquer mismatch ou limite falha fechado antes de receipt ou move. Antes de liberar um worker, o próprio controller materializa uma árvore npm utilizável. Primeiro ele prefere um `node_modules` da fonte equivalente e estruturalmente atual como fronteira explícita de estado local confiável. Se essa cópia não existir, um único lock npm sem workspaces, com pacotes presos a origens HTTPS sem credenciais e digests de integridade suportados, pode ser instalado pelo `npm-cli.js` do próprio Host em staging privado; filhos `inBundle` só são aceitos por uma cadeia recursiva de declarações explícitas que termina nesse tarball com integridade. Esse `npm ci` usa config/cache isolados, ambiente allowlisted, sem lifecycle scripts/audit/funding, cancelamento da árvore de processos e quotas vivas de arquivos/bytes/profundidade. Os dois caminhos recusam pacotes, shims ou payloads ocultos inesperados, links externos e hardlinks, validam a árvore completa e normalmente publicam sem substituir ou apagar target. Para uma condição autenticada `ENOTCACHED` ou módulo ausente, o runner sob lock do repositório pode mover atomicamente um target inválido para quarentena, materializar o lock exato da worktree, publicar e validar uma nova árvore física e então descartar a quarentena. Uma transação durável presa à identidade só adota a fase `published`, gravada após validação; fases anteriores de crash/falha preservam a quarentena original, removem apenas target comprovadamente pertencente ao controller e repetem sem jamais restaurar por cima, apagar ou substituir uma corrida não pertencente ao controller. Receipt de transação pendente é retomado sob o lock do repositório antes de liberar worker, e erros de setup preservam evidência. Árvores de dependência ausentes, inválidas ou interrompidas são reparadas automaticamente sem outra transição de lifecycle autorizada por digest. Workers mutáveis podem executar qualquer argv local direto dentro do sandbox da worktree autenticada; workers de verificação/publicação continuam estreitos. A resolução antepõe o `node_modules/.bin` da raiz e usa o subprocess service do Host com ambiente limpo. Workers mutáveis podem usar gerenciadores de pacote, frontends dinâmicos, mutação de dependências, geradores, Git local e caches quando julgarem útil. Fora disso, o worker chama ferramentas já materializadas pelo nome simples. Por compatibilidade com runs criados até 0.3.49, se uma falha `npx` anterior autenticada deixou `.npm-cache` físico, totalmente untracked e fora do scope da tarefa, o controller sob lock pode mover o diretório — sem apagar seus bytes — para uma transação de quarentena autenticada por HMAC e presa à identidade antes de retomar o WIP preservado. Esse caminho de compatibilidade aceita somente receipts antigos assinados; nenhum worker 0.3.54 cria baseline ou transação de quarentena de cache. Cache tracked, staged, linkado, ambíguo, recriado ou com identidade alterada falha fechado; estado de artefato em outro filesystem é recusado antes de existir receipt. Toda fase de receipt é reconciliada antes de liberar worker e um crash retoma a mesma transação. Durante um run Web, cada row selecionada mantém um card durável. `Running`, attempt por tarefa e elapsed time ficam em elementos separados que não encolhem; somente a label longa sofre ellipsis, e o resultado terminal fecha o mesmo card. Rows sequenciais e subtarefas substitutas criadas por um split durável começam em `Attempt 1`; recovery explícito da mesma row inalterada avança seu ordinal local. A identidade global separada continua cumulativa em leases, recibos, eventos e recovery limitado. O controller geral possui card de background com status, timer e botão Stop. `/leppy-loop status` mostra primeiro o job ativo exato preso ao owner; estado durável `running` sem esse job é `orphaned`, nunca um `leppy-loop-*` chutado. Sem job ativo, mostra o controller autenticado mais recente mesmo quando a parada ocorreu na publicação. Stalls resolvidos preservam o detalhe acionável limitado em vez de virar uma falha genérica. Timers locais não gravam eventos por segundo nem consomem tokens. A publicação primeiro deriva um único repositório GitHub de URLs fetch/push coincidentes e reconcilia um PR OPEN ou MERGED exato, do mesmo owner, antes de rebase, gate ou push; para MERGED pode fazer fetch somente leitura para provar que o merge commit ainda está na base viva solicitada. Sem PR, faz prune e consulta refs remotas vivas em vez de confiar em tracking branch stale. Base configurada apagada falha fechada; a IA pode fornecer uma branch substituta técnica dentro do mesmo lifecycle, nunca outro remote, aceita somente quando um target anterior durável está incorporado nela. A reconciliação de PR OPEN ou MERGED aplica a mesma regra de base/ancestralidade e só conclui depois que o controller reexecuta o gate final estrito; receipt consultivo local nunca basta. Fetch, `ls-remote` e push usam as URLs literais validadas em vez de alias remoto mutável. Branch do controller já enviada só é atualizada com `force-with-lease` preso ao OID observado; base, remote head, worktree limpa e HEAD validado pelo gate são conferidos imediatamente antes do push e o remote head é verificado depois. A busca por PR repete antes do create para absorver corrida. Se o rebase por OID exato parar em conflitos, no máximo três workers frescos recebem somente read/write/delete nos arquivos não mesclados exatos, sem commit ou exec. O controller congela HEAD e index, recusa drift/edição fora de scope, faz stage dos conflitos, pula replay vazio com segurança e repete o gate final. Reconciliar PR exato já existente não faz mutação remota e permite fechar o estado durável depois de abertura/merge manual. Workers não fazem push nem usam `gh`; Leppy nunca faz merge ou deploy. Instale e autentique o GitHub CLI (`gh auth status`) antes de permitir publicação. ## Contrato da checklist ```md ## Fase API - [ ] Criar `src/api.ts` | Done: GET /health responde 200 | model=deepseek-v4-pro | effort=high - [ ] Documentar endpoint | Done: README descreve /health | paths=README.md - [?] Closure: revisar a fase | paths=src,README.md - [~] Gate: testes focais ``` - `[ ]`: tarefa comum aberta. - `[?]`: closure aberta. - `[~]`: gate do controller aberto. - `[x]`: linha concluída de qualquer tipo. Tarefa comum exige `Done:` não vazio. Metadados opcionais `paths=` e paths em crase fornecem apenas contexto não vinculante; hints malformados ainda falham no preflight, mas ausência de paths ou scope de teste é aceita. O formato canônico com pipes é preferido, mas continua compatível com continuações Markdown indentadas e as formas históricas `[closure]`/`[gate]`, `Paths:`, `Paths EXATOS:`, `Paths permitidos:` e `Done:` multiline. Um checkpoint `[?] [human]` ou `[?] [human/live]` nunca inicia worker: o run para com o worktree preservado até um humano marcar a row e recuperar o ID exato. A capability conveniente de commit stageia mudanças comuns do repositório inteiro; arquivos ignored continuam fora do stage salvo quando o worker os escolhe explicitamente via Git local. `--task-match` é substring literal. Paths passam por `realpath`; traversal, absoluto e symlink/junction escapando do repositório são recusados. O worker nunca pode ler ou editar a checklist controladora. Um `.leppy-loop.json` rastreado na raiz pode fornecer `customInstructions` string, anexada às instruções `AGENTS.md`/`CLAUDE.md` aplicáveis. Shapes inválidos falham fechados; o arquivo tem limite de 64 KiB e a string, 32 KiB. Dry-run expõe todos os diagnósticos de lint na ferramenta do modelo e no texto do comando direto. ## Semântica O checkout e a checklist rastreada precisam estar limpos. O controller faz no máximo um fetch, resolve `--sync-branch`, cria uma branch `leppy-loop/-` e uma worktree irmã. Não sincroniza de novo durante o loop. Cada tarefa ou closure recebe um processo/sessão efêmero com autoridade sobre a worktree isolada inteira. Formato do report, validação, `paths=`, ignored state e commit manual são consultivos; o controller reconcilia o trabalho e marca a linha, salvo `implementation-impossible` explícito. Gate roda o comando opaco sem worker e, quando falha, reabre automaticamente a closure adjacente para reparo limitado antes de repetir o mesmo fingerprint. Depois do limite, o controller prende o receipt ao estado HMAC e avança com evidência consultiva; estado ignored/gerado de gate local é irrestrito, enquanto publicação sempre reexecuta seu gate final estrito. Defaults: sync 120 s, worker 30 min, 64 inicializações, output final 192 KiB e transcript 8 MiB. Provider/model/effort vêm da seleção atual do Harness e são validados no catálogo real. Outcomes de runtime sem decisão da IA recebem até três workers frescos; fallback configurado tem prioridade na primeira recuperação de indisponibilidade. ## Recuperação Estado durável fica fora da worktree: `run.json`, PID do runner, eventos JSONL, outputs, transcripts, recibos, resumos de diff, instrução de retomada, prova de ownership e leases HMAC. Há um lock por `git-common-dir`. Timeout, limite ou Ctrl+C preserva WIP e a mesma linha. Retome com `--recover-existing-wip`. O controller só adota um único run autenticado correspondente. Só encerra uma árvore quando lease, PID e identidade de início ainda coincidem; nunca busca ou mata por nome. ## Segurança e limitações É isolamento prático: worker mutável manda na worktree inteira, exceto a checklist controladora. `leppy_exec` aceita qualquer argv local direto sob `workspace-write`, incluindo Git, PowerShell, gerenciadores de pacote e geradores. Push, publicação, deploy e mutação remota de PR continuam exclusivos do controller. A chave vem do serviço de credenciais e subprocessos de ferramenta recebem ambiente scrubbed; logs/eventos são redigidos. `leppy_commit` continua como conveniência para criar um commit conventional; Git local geral também é permitido, e o controller adota WIP do repositório inteiro e normaliza a estrutura automaticamente. O sandbox oficial não confina rede. Um script malicioso já presente no repositório pode usar rede durante um teste permitido. Não use em repositório não confiável. Push, PR, release, publicação e deploy nunca são automáticos. Leppy difere de Ralph porque a checklist tipada é a máquina de estados controlada: uma linha por sessão, repositório isolado sob autoridade do worker, adoção Git, closure e gate explícitos. O contexto independente aumenta o custo porque conversa/cache não é compartilhada. Para todos os flags, eventos, troubleshooting, API e desenvolvimento, veja o [README em inglês](README.md), [ARCHITECTURE.md](ARCHITECTURE.md) e [THREAT_MODEL.md](THREAT_MODEL.md). ## Licença Apache-2.0.