wendkeep 0.78.0 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.en.md +58 -3
  3. package/README.md +58 -3
  4. package/docs/en/commands/changes-and-verification.md +116 -1
  5. package/docs/en/commands/operating-profiles.md +49 -5
  6. package/docs/en/commands/sessions-and-import.md +6 -0
  7. package/docs/en/commands/verify.md +54 -0
  8. package/docs/en/commands/worktrees.md +39 -4
  9. package/docs/pt-BR/commands/changes-and-verification.md +115 -1
  10. package/docs/pt-BR/commands/operating-profiles.md +51 -5
  11. package/docs/pt-BR/commands/sessions-and-import.md +7 -0
  12. package/docs/pt-BR/commands/verify.md +53 -0
  13. package/docs/pt-BR/commands/worktrees.md +38 -3
  14. package/hooks/active-context-store.mjs +530 -2
  15. package/hooks/change-core.mjs +220 -123
  16. package/hooks/obsidian-common.mjs +175 -9
  17. package/hooks/session-stop.mjs +40 -1
  18. package/hooks/spec-core.mjs +93 -29
  19. package/package.json +2 -2
  20. package/packages/cli/src/index.mjs +7 -0
  21. package/packages/vault/src/memory-handoff.mjs +15 -0
  22. package/schema/artifact-manifest-v1.schema.json +35 -0
  23. package/schema/handoff-contract-v1.schema.json +37 -0
  24. package/schema/task-contract-v1.schema.json +57 -0
  25. package/schema/wendkeep.provenance-receipt-v2.schema.json +66 -0
  26. package/src/archive-operation-lock.mjs +235 -0
  27. package/src/change.mjs +1780 -79
  28. package/src/delivery.mjs +724 -67
  29. package/src/memory.mjs +2 -1
  30. package/src/provenance-gate.mjs +575 -0
  31. package/src/provenance-sources.mjs +547 -0
  32. package/src/receipt-ledger.mjs +841 -0
  33. package/src/release-provenance.mjs +48 -0
  34. package/src/task-contracts.mjs +510 -0
  35. package/src/task-leases.mjs +105 -0
  36. package/src/task.mjs +115 -0
  37. package/src/verify.mjs +32 -0
  38. package/src/worktree-cleanup.mjs +1733 -118
  39. package/src/worktree.mjs +94 -5
@@ -29,8 +29,11 @@ npx wendkeep change new <slug> [--simple|--guide] [--session <id>]
29
29
  npx wendkeep change status [slug] [--session <id>]
30
30
  npx wendkeep spec effective [--change <slug>] [--session <id>]
31
31
  npx wendkeep sensors list
32
+ npx wendkeep task list [--change <slug>] [--session <id>] [--json]
33
+ npx wendkeep task evaluate <task-id> [--change <slug>] [--session <id>] [--json]
32
34
  npx wendkeep verify [--deep] [--change <slug>] [--session <id>]
33
- npx wendkeep change archive <slug> [--session <id>]
35
+ npx wendkeep change archive <slug> [--json] [--session <id>]
36
+ npx wendkeep change archive recover <operation-id> --change <slug> [--spec-action rollback|resume] [--json]
34
37
  ```
35
38
 
36
39
  ## Opções e códigos de saída
@@ -47,6 +50,12 @@ npx wendkeep change archive <slug> [--session <id>]
47
50
  somente um contexto ativo inequívoco da worktree é aceito; ambiguidade retorna exit `2`.
48
51
  - `change relink [--apply]` e `change backlink [--apply]` reparam o grafo; dry-run é o padrão.
49
52
  - `change abandon <slug>` descarta sem ADR; `archive --force` exige decisão humana explícita.
53
+ - `task list/show/evaluate` projeta contratos read-only da autoria da change. `task claim/release`
54
+ controla owner/lease no active context causal.
55
+ - `change archive recover <operation-id> --change <slug> [--spec-action rollback|resume]` inspeciona
56
+ uma transação pendente por padrão; com `rollback` ou `resume`, converge somente a promoção de
57
+ specs preparada no journal, sob lock e validação. Não promove a change, não apaga o journal e não
58
+ inventa reconciliação.
50
59
  - `wendkeep spec list|show|effective|migrate|rebase` administra contratos vivos e deltas.
51
60
  - `wendkeep sensors list|add` administra provas executáveis.
52
61
  - Exit `0` indica comando concluído; os gates usam exit `1` para prova vermelha e exit `2` para
@@ -83,6 +92,111 @@ checkout provado. Se houver divergência, volte à worktree/sessão correta e ro
83
92
  `verify --deep` e `wk-verify` novamente. Campos, normalização textual/binária, códigos e recovery
84
93
  estão detalhados no [guia de verify](verify.md).
85
94
 
95
+ O gate comum reclassifica envelope, package e verdict como `verified`, `reported`,
96
+ `legacy-unbound`, `stale`, `conflict` ou `unproven`; somente `verified` permite archive. Um bloqueio
97
+ retorna `WENDKEEP_PROVENANCE_GATE_BLOCKED`: estabilize/recupere o contexto, rode `verify`, depois
98
+ `verify --deep` e obtenha novo passe `wk-verify`. `--force` pode dispensar somente tarefa aberta;
99
+ para proveniência, integridade, package e verdict ele **não** altera o resultado nem promove spec/ADR.
100
+ Os erros de ledger são `WENDKEEP_RECEIPT_LEDGER_BUSY`, `WENDKEEP_RECEIPT_LEDGER_CONFLICT`,
101
+ `WENDKEEP_RECEIPT_LEDGER_CORRUPT` e `WENDKEEP_RECEIPT_LEDGER_TRUNCATED`. No bloqueio, use a saída
102
+ `--json` sanitizada (`state`, `reasonCodes`, `diagnostics`, `repair.command`), execute o recovery
103
+ indicado e rode `npx --no-install wendkeep verify --deep --json`; preserve e recapture a prova, sem
104
+ editar ledger/checkpoint ou expor stderr, token, URL privada ou path do Vault.
105
+
106
+ ### Contrato pós-fix do archive
107
+
108
+ Antes da mutação, faça a recaptura final com `wendkeep verify --deep --change <slug>`. O package
109
+ e o verdict devem estar completos e canônicos, com binding do mesmo checkout, change, tarefas,
110
+ spec e sensores. O archive grava primeiro um receipt de autorização no ledger separado
111
+ `change-archive-receipts-v2`; só depois de validá-lo pode promover spec/ADR ou mover a change.
112
+ `change archive --json` expõe o resultado serializável com os campos `state`, `reason_codes`,
113
+ `diagnostics` e `repair`. Corrupção ou truncamento no ledger de prova ou no ledger de archive
114
+ bloqueia fechado antes de qualquer escrita. `--force` não bypassa proveniência nem integridade,
115
+ nem package/verdict, corrupção ou truncamento. O recovery exato é repetir
116
+ `wendkeep verify --deep --change <slug>` no checkout correto.
117
+
118
+ A mutação adquire o lock do runtime `.brain/runtime/change-archive-operation.lock` e abre uma
119
+ transação privada ASCII em `.brain/runtime/archive-transactions/<uuid>/{original,authorized}`.
120
+ Ela renomeia atomicamente a change viva para `original`, confere o digest e promove somente a
121
+ cópia `authorized`; o namespace público nunca é fonte de publicação. Em caso de falha de
122
+ selagem ou divergência `WENDKEEP_ARCHIVE_INPUT_CHANGED` antes da promoção, o snapshot
123
+ `authorized` é removido e `original` é restaurado sem promoção parcial. O archive bem-sucedido
124
+ mantém o journal `completed`; o finalizer pós-release valida os digests de `original` e do destino
125
+ publicado, mas retém `original` e a transação, sem cleanup destrutivo automático.
126
+
127
+ O lock do archive é um `directory lock`: o diretório canônico contém marker específico do token e
128
+ lease. A aquisição prepara um diretório irmão `.pending`, escreve owner/lease e publica por rename
129
+ atômico para o lock; não usa hardlink e reobserva colisões com no máximo 3 tentativas de topologia.
130
+ Owner vivo retorna `WENDKEEP_ARCHIVE_BUSY`; owner morto pode sofrer reap seguro sem apagar sucessor.
131
+ Estrutura/marker inválido retorna `WENDKEEP_ARCHIVE_LOCK_UNAVAILABLE`; perda de ownership retorna
132
+ `WENDKEEP_ARCHIVE_LOCK_OWNERSHIP_LOST`.
133
+
134
+ Cada operação mantém `archive-transaction.json` com as fases `prepared` → `isolated` → `copied` →
135
+ `sealed` → `published` → `promotion-prepared` → `promotion-applied` → `completed` ou
136
+ `recovery-required`. Um journal pending bloqueia novo archive do mesmo slug antes do gate. Em
137
+ colisão ou falha pós-publicação, `original` permanece retido e o estado é
138
+ `published-recovery-required`. Use a inspeção fail-closed e idempotente
139
+ `wendkeep change archive recover <operation-id> --change <slug> [--spec-action rollback|resume] [--json]`;
140
+ sem `--spec-action`, só retorna ações sanitizadas. `rollback` restaura before-images e `resume`
141
+ converge after-images de uma promoção `promotion-prepared`; ambos preservam o journal para nova
142
+ reconciliação.
143
+
144
+ A promoção multi-spec é uma unidade atômica: captura before-images/digests de todos os capabilities,
145
+ faz rollback de todos os alvos (incluindo estado/README) em falha antes ou depois da escrita e só
146
+ permite retry após a reconciliação do journal e nova verificação. O finalizer pós-release valida os
147
+ digests do original e do destino, mas retém o journal `completed` e `original`; sem cleanup
148
+ destrutivo automático. Os campos sanitizados
149
+ `operation_id` e `transaction_phase` acompanham o diagnóstico; `repair.command` aponta para
150
+ `wendkeep change archive recover <operation-id> --change <slug>` quando há operação identificada.
151
+ Texto e --json usam o mesmo diagnóstico sanitizado com code, operation, state, blocker, expected,
152
+ observed, recovery, reason_codes, diagnostics e repair.
153
+
154
+ ## Task Contracts, artifacts e handoffs
155
+
156
+ Task Contract v1 é uma projeção reconstruível cuja autoria permanece em `tarefas.md`, na spec
157
+ efetiva e no `artifacts.json` da change. O contrato não copia a spec nem infere requisito do chat.
158
+ Projeto, active context, HEAD e hashes de tarefas/spec/manifesto vinculam a projeção; divergência
159
+ resulta em `stale`.
160
+
161
+ ```markdown
162
+ - [ ] 2.3 gerar relatório [req:REP-1] [sensor:tests] [depends:2.2] [artifact:report]
163
+ - [ ] 9.1 revisar pacote deep e arquivar [req:REP-1] [phase:verify]
164
+ ```
165
+
166
+ ```powershell
167
+ npx wendkeep task list --session <id> [--change <slug>] [--json]
168
+ npx wendkeep task show 2.3 --session <id> [--json]
169
+ npx wendkeep task evaluate 2.3 --session <id> [--json]
170
+ npx wendkeep task claim 2.3 --session <id> [--lease-seconds 900] [--json]
171
+ npx wendkeep task release 2.3 --session <id> [--json]
172
+ ```
173
+
174
+ `list`, `show` e `evaluate` não escrevem. `claim` e `release` usam o lock atômico do
175
+ `SESSION_REGISTRY`, são escopados por repository/worktree/work session/change/task e recusam owner
176
+ concorrente. Lease expirada pode ser retomada; release por não-owner falha com
177
+ `TASK_LEASE_NOT_OWNER`.
178
+
179
+ Um manifesto de artifacts usa `schema_version: 1` e uma lista `artifacts`; cada entrada nomeada
180
+ pode ter tipo `name`, `path`, `glob` ou `file-count`. O fallback `fromFilesystem` é explícito, não
181
+ lê conteúdo, ignora `.git`, `.worktrees`, `node_modules` e `dist`, tem limites de tempo/quantidade
182
+ e falha fechado em path escape, symlink ou junction externo.
183
+
184
+ Checkbox é sinal autoral, não prova. `task evaluate` retorna `can_complete`, requisitos, sensores,
185
+ artifacts e dependências ausentes, além de `blocking_findings`. No active context causal, `verify`
186
+ pode gravar `evidencia.json`, mas não anuncia sucesso nem cria o pacote deep enquanto houver task
187
+ bloqueada na fase padrão `execute`; o diagnóstico fica em `task-evaluation.json`. Use
188
+ `[phase:verify]` somente para a tarefa de revisão/arquivo que necessariamente ocorre depois do
189
+ pacote deep: ela não integra o gate Execute → Verify, permanece bloqueada na avaliação individual
190
+ e ainda precisa ser concluída antes de `change archive`.
191
+
192
+ SessionStop vincula origem/destino, task, artifacts, Evidence Envelope, decisões, próximas ações,
193
+ blockers e hashes de HEAD/tarefas/spec. ASSURE exige Handoff Contract v1 verificado; nos demais
194
+ perfis ele é opcional. Handoffs históricos permanecem `legacy-reported`. Memória compartilhada,
195
+ brain injection e Observer consomem a mesma projeção sanitizada.
196
+
197
+ Schemas públicos: `schema/task-contract-v1.schema.json`,
198
+ `schema/artifact-manifest-v1.schema.json` e `schema/handoff-contract-v1.schema.json`.
199
+
86
200
  ## Cerca de escopo para ferramentas
87
201
 
88
202
  O `change-guard` também é projetado para o `PreToolUse` do Codex. Antes de uma mutação Git ou de
@@ -59,7 +59,7 @@ npx wendkeep flow finish <id> [--session <id>]
59
59
  npx wendkeep flow promote <id> [--change-slug <slug>] [--session <id>]
60
60
  npx wendkeep delivery start [id] --allow <capability> [--source-change <slug>] [--source-commit <sha>] [--session <id>]
61
61
  npx wendkeep delivery status [id] [--session <id>]
62
- npx wendkeep delivery finish [id] [--target <ref>] [--ci-url <url>] [--version <x.y.z>] [--npm-integrity <sha512>] [--release-url <url>] [--session <id>]
62
+ npx wendkeep delivery finish [id] [--target <remote>/<branch>] [--ci-url <url>] [--version <x.y.z>] [--npm-integrity <sha512>] [--release-url <url>] [--session <id>]
63
63
  npx wendkeep delivery abandon [id] --reason <texto> [--session <id>]
64
64
  ```
65
65
 
@@ -179,13 +179,38 @@ harness nativo da LLM.
179
179
  `contract_impact` e `operation_risk` são dimensões independentes. `delivery start` captura repo,
180
180
  branch/worktree, SHA, change de origem e capabilities em `.brain/runtime/deliveries/`; não cria
181
181
  pasta em `08-Mudanças`, delta, spec ou ADR.
182
- - `delivery finish` exige working tree limpa, comprova que o target contém o commit de origem e,
183
- para capability `publish`, exige CI, versão, integridade npm e GitHub Release. O receipt é
184
- append-only em `.brain/runtime/delivery-receipts.jsonl`. Se código/config precisar mudar, a
185
- delivery para com `WENDKEEP_DELIVERY_IMPLEMENTATION_REQUIRED` e o trabalho volta a implementation.
182
+ - Para as capabilities `git:merge` e `git:push`, `delivery finish` exige `--target
183
+ <remote>/<branch>` (por exemplo, `--target origin/main`). `delivery start` vincula o remote
184
+ `origin` ao `repository` esperado; `finish` resolve o destino com `git ls-remote` e bloqueia a
185
+ delivery antes dos adapters de proveniência se o target não puder ser resolvido ou o binding
186
+ divergir.
187
+ - `delivery finish` exige working tree limpa e rederiva source/target. Merge/push prova
188
+ ancestralidade; tag prova package/version e tag no target; `publish` consulta CI, NPM e GitHub
189
+ Release ligados ao mesmo commit, versão, integrity e notas. No modo offline, uma claim fica
190
+ `reported` e não vira `verified`; a conclusão bloqueia sem gravar receipt. Novos receipts formam
191
+ `.brain/runtime/delivery-receipts-v2.jsonl`, com hash chain e checkpoint; o v1 é somente
192
+ `legacy-unbound`. `WENDKEEP_PROVENANCE_GATE_BLOCKED` traz o recovery. Se código/config precisar
193
+ mudar, `WENDKEEP_DELIVERY_IMPLEMENTATION_REQUIRED` devolve o trabalho a implementation.
194
+ O gate usa a mesma taxonomia `verified`, `reported`, `legacy-unbound`, `stale`, `conflict` e
195
+ `unproven`. Os erros do ledger são `WENDKEEP_RECEIPT_LEDGER_BUSY`,
196
+ `WENDKEEP_RECEIPT_LEDGER_CONFLICT`, `WENDKEEP_RECEIPT_LEDGER_CORRUPT` e
197
+ `WENDKEEP_RECEIPT_LEDGER_TRUNCATED`; consulte `state`, `reasonCodes`, `diagnostics` e
198
+ `repair.command` sanitizados em `--json`, execute o recovery indicado e recapture a prova, sem editar
199
+ ledger/checkpoint ou expor stderr, tokens, URLs privadas e paths do Vault.
186
200
  - Em Vault multi-contexto, `active_contexts[].delivery_id` é a autoridade. `--session <id>` escolhe
187
201
  explicitamente a work session; sem ela, somente um active context inequívoco da worktree pode ser
188
202
  usado. Status, finish e abandon implícitos consultam esse binding, não um ponteiro global.
203
+ - Falhas de `delivery`, tanto em texto quanto em `delivery --json`, expõem o mesmo diagnóstico
204
+ PROV-8: `code` estável, `operation`, `state`, primeiro `blocker`, `expected`/`observed`
205
+ sanitizados e `recovery` objetivo. Stderr do Git, tokens, URLs privadas e caminhos privados não
206
+ são propagados.
207
+ - Receipts `delivery.completed` e `delivery.abandoned` vinculam `repository_id`, o `repository`
208
+ público no formato `owner/repo`, `worktree_id`, `work_session_id`, `change_slug` e `branch`.
209
+ O path privado da worktree nunca entra no receipt. Na finalização contextual, o receipt entra no
210
+ ledger e o `state` durável é gravado antes de limpar `active_contexts[].delivery_id`. Um retry
211
+ converge para o mesmo receipt quando o binding já está limpo ou ainda vinculado. Em
212
+ `delivery abandon`, o motivo livre vira `reason_digest`; o texto bruto não entra no ledger nem no
213
+ estado.
189
214
  - `CURRENT_DELIVERY` é somente uma projeção derivada: contém o ID quando existe um único contexto
190
215
  ativo inequívoco com delivery e fica vazio com zero ou múltiplos contextos.
191
216
  `WENDKEEP_DELIVERY_CONTEXT_MISMATCH` indica que o ID explícito pertence a outro contexto; nenhum
@@ -274,6 +299,27 @@ continuam disponíveis e executam seus próprios contratos. Um FLOW concluído d
274
299
  consultável; um FLOW promovido passa a seguir o lifecycle normal de change. Uma delivery concluída
275
300
  deixa receipt sem gerar ADR; GUIDE compacto arquiva o resultado sem spec/design/ADR artificiais.
276
301
 
302
+ Para archive em GOVERN/ASSURE, o `directory lock` usa marker específico do token e lease: a
303
+ aquisição prepara um diretório irmão `.pending` e publica por rename atômico, sem hardlink, com no
304
+ máximo 3 tentativas de topologia. Owner vivo retorna `WENDKEEP_ARCHIVE_BUSY`, owner morto pode ser
305
+ reapado com segurança, marker inválido retorna `WENDKEEP_ARCHIVE_LOCK_UNAVAILABLE` e perda de
306
+ ownership retorna `WENDKEEP_ARCHIVE_LOCK_OWNERSHIP_LOST`. O journal `archive-transaction.json`
307
+ percorre `prepared` → `isolated` → `copied` → `sealed` → `published` → `promotion-prepared` →
308
+ `promotion-applied` → `completed` ou `recovery-required`; um journal pending bloqueia novo archive
309
+ do mesmo slug antes do gate.
310
+ `original` fica retido em collision/falha pós-publicação e `published-recovery-required` exige
311
+ inspeção. `operation_id` e `transaction_phase` aparecem apenas sanitizados. Use
312
+ `wendkeep change archive recover <operation-id> --change <slug> [--spec-action rollback|resume] [--json]`:
313
+ sem `--spec-action`, inspeção somente-leitura, fail-closed e idempotente, sem promoção, deleção ou
314
+ reconciliação inventada; `rollback` restaura before-images e `resume` converge after-images de
315
+ `promotion-prepared`, retendo o journal. Quando há operation ID, `repair.command` aponta para esse
316
+ recovery; não trate `command:null` como fluxo normal.
317
+
318
+ A promoção multi-spec é atômica, com before-images/digests, rollback dos alvos antes/depois da
319
+ escrita e retry somente após reconciliação e nova verificação. O finalizer pós-release valida os
320
+ digests do original e do destino publicado, mas o `completed` journal mantém o `original` retido;
321
+ sem cleanup destrutivo automático.
322
+
277
323
  ## Erros comuns e diagnóstico
278
324
 
279
325
  - Perfil desconhecido: use exatamente `OFF`, `FLOW`, `GUIDE`, `GOVERN` ou `ASSURE`.
@@ -141,3 +141,10 @@ confirmada de um lock ocupado ou de um caminho que foi pulado, sem reabrir a ses
141
141
 
142
142
  Leia [Perfis de Operação](operating-profiles.md), [importação retroativa](retroactive-import.md),
143
143
  [custos e observabilidade](costs-and-observability.md) e [notas](notes-and-knowledge.md).
144
+ # Handoff Contract v1
145
+
146
+ Em active context causal, o SessionStop projeta um handoff tipado com task, artifacts, Evidence
147
+ Envelope, decisões, próximas ações, blockers e hashes de HEAD/tarefas/spec. ASSURE bloqueia a
148
+ publicação quando esse contrato verificado não pode ser produzido; outros perfis preservam o
149
+ fallback opcional. Handoffs históricos continuam `legacy-reported`. Veja
150
+ [Changes e verificação](changes-and-verification.md).
@@ -91,6 +91,44 @@ no verdict.
91
91
  Evidência v1 continua legível como `legacy-unbound`, nunca como autoridade equivalente. Rode
92
92
  `wendkeep change status <slug>` para ver `bound`, `stale` ou `context-mismatch`.
93
93
 
94
+ O gate de proveniência normaliza a visão legada numa taxonomia única: `verified` quando toda prova
95
+ obrigatória está fresca e vinculada; `reported` para claim registrada sem observação autoritativa;
96
+ `legacy-unbound` para v1; `stale` para um snapshot anterior; `conflict` para identidade/conteúdo
97
+ incompatível; e `unproven` para prova ausente ou insuficiente. A precedência é `conflict` > `stale`
98
+ > `legacy-unbound` > `unproven` > `reported` > `verified`, e somente `verified` fecha o gate.
99
+
100
+ Para o archive pós-fix, o passe final é `wendkeep verify --deep --change <slug>`. Ele deve deixar
101
+ package e verdict completos e canônicos, ligados ao mesmo checkout, change, tarefas, spec e
102
+ sensores. O archive grava o receipt de autorização antes da mutação no ledger separado
103
+ `change-archive-receipts-v2`. Sua saída `change archive --json` é serializável e expõe `state`,
104
+ `reason_codes`, `diagnostics` e `repair`; corrupção ou truncamento de ledger bloqueia fechado.
105
+ `--force` não bypassa proveniência ou integridade. O recovery exato é repetir
106
+ `wendkeep verify --deep --change <slug>` depois de estabilizar o contexto.
107
+
108
+ O archive usa um `directory lock` com marker específico do token e lease. A aquisição prepara um
109
+ diretório irmão `.pending` e publica-o por rename atômico, sem hardlink, com no máximo 3 tentativas
110
+ de topologia. Owner vivo produz `WENDKEEP_ARCHIVE_BUSY`; owner morto só é reapado com observação
111
+ segura; marker/estrutura inválida produz `WENDKEEP_ARCHIVE_LOCK_UNAVAILABLE`; perda de ownership
112
+ produz `WENDKEEP_ARCHIVE_LOCK_OWNERSHIP_LOST`. O manifest `archive-transaction.json` registra
113
+ `prepared` → `isolated` → `copied` → `sealed` → `published` → `promotion-prepared` →
114
+ `promotion-applied` → `completed` ou `recovery-required`. Um journal pending bloqueia novo archive
115
+ do mesmo slug antes do gate. Em
116
+ collision ou falha pós-publicação, `original` é retido e o estado
117
+ `published-recovery-required` bloqueia retry destrutivo. `operation_id` e `transaction_phase` são
118
+ campos sanitizados. Inspecione com
119
+ `wendkeep change archive recover <operation-id> --change <slug> [--spec-action rollback|resume] [--json]`:
120
+ sem `--spec-action`, é somente-leitura, fail-closed e idempotente, sem promoção, deleção ou
121
+ reconciliação inventada. `rollback` restaura before-images e `resume` converge after-images de uma
122
+ promoção `promotion-prepared`, mantendo o journal para reconciliação. Quando há operation ID,
123
+ `repair.command` aponta para `wendkeep change archive recover <operation-id> --change <slug>`; não
124
+ trate `command:null` como fluxo normal.
125
+
126
+ A promoção multi-spec é uma unidade atômica: captura before-images/digests de todos os capabilities,
127
+ faz rollback de todos os alvos (incluindo estado/README) em falha antes ou depois da escrita e só
128
+ permite retry após reconciliação do journal e nova verificação. O finalizador pós-release valida os
129
+ digests do original e do destino, mas o `completed` journal mantém o `original` retido; sem cleanup
130
+ destrutivo automático. Falha mantém `published-recovery-required`.
131
+
94
132
  ## Erros comuns e diagnóstico
95
133
 
96
134
  - `no change`: isso é exit 2 e estado ocioso válido; crie/use uma change ou não rode verify.
@@ -103,6 +141,13 @@ Evidência v1 continua legível como `legacy-unbound`, nunca como autoridade equ
103
141
  checkout e repita. A evidência anterior não foi substituída.
104
142
  - `legacy-unbound`, `stale` ou `context-mismatch`: volte à worktree/sessão correta, recupere o
105
143
  contexto se necessário e rode `verify` + `verify --deep` novamente.
144
+ - `WENDKEEP_PROVENANCE_GATE_BLOCKED`: leia `state`, `reasonCodes` e `repair`; não reutilize uma
145
+ prova de outra branch/worktree/sessão. Rode o comando indicado e recapture o envelope.
146
+ - Os erros `WENDKEEP_RECEIPT_LEDGER_BUSY`, `WENDKEEP_RECEIPT_LEDGER_CONFLICT`,
147
+ `WENDKEEP_RECEIPT_LEDGER_CORRUPT` e `WENDKEEP_RECEIPT_LEDGER_TRUNCATED` exigem preservar o
148
+ ledger/checkpoint e executar o recovery objetivo em `repair.command` (ou
149
+ `npx --no-install wendkeep verify --deep --json` para uma prova fresca); a saída textual/JSON
150
+ permanece sanitizada e não contém stderr bruto, tokens, URLs privadas ou paths do Vault.
106
151
  - Mutantes sobreviventes: fortaleça o teste discriminante; após três rodadas, revise manualmente.
107
152
 
108
153
  ## Próximos passos
@@ -110,3 +155,11 @@ Evidência v1 continua legível como `legacy-unbound`, nunca como autoridade equ
110
155
  Volte ao [ciclo de changes](changes-and-verification.md) para archive, confira os
111
156
  [Perfis de Operação](operating-profiles.md) ou consulte
112
157
  [manutenção](maintenance-and-diagnostics.md) quando não houver change.
158
+ # Gate de Task Contract
159
+
160
+ Depois de executar sensores e gravar o Evidence Envelope atual, `verify` avalia os Task Contracts
161
+ do active context causal. Checkbox aberta, requisito/sensor/artifact ausente, dependência aberta ou
162
+ binding stale bloqueia exit `1`, preserva `evidencia.json`, grava `task-evaluation.json` e não cria
163
+ o pacote deep. Tasks explicitamente autoradas com `[phase:verify]` ficam fora apenas desta
164
+ transição porque dependem do pacote deep; continuam abertas para o gate de archive. Veja
165
+ [Changes e verificação](changes-and-verification.md).
@@ -58,6 +58,31 @@ interrompido/failed e uma recuperação objetiva.
58
58
  head comprovado; divergência ou rede indisponível bloqueia. Branch já ausente é sucesso idempotente.
59
59
  `--open-main` abre a worktree principal somente depois da conclusão.
60
60
 
61
+ ### Cleanup pós-fix: retomada crash-safe
62
+
63
+ A operação de cleanup é **crash-safe** e retomável antes do receipt, depois do receipt e antes do
64
+ finalize, e depois do finalize: um crash em qualquer fronteira preserva operation/state e permite
65
+ repetir a mesma prova sem duplicar remoção ou receipt. O subject de cada operação inclui todos os
66
+ active contexts, actor, pr, head e merge. O PR canônico é a autoridade resolvida pelo adapter
67
+ GitHub; texto fornecido pelo chamador não substitui essa autoridade.
68
+
69
+ O HEAD é rederivado antes do finalize, a partir do checkout, e comparado ao head/merge comprovado. O reason
70
+ fica sanitizado e recebe digest para auditoria, sem armazenar path privado, token ou stderr.
71
+ Checkpoint ausente ou inválido é WENDKEEP_RECEIPT_LEDGER_TRUNCATED. Receipt v1 continua
72
+ legacy-unbound e nunca autoriza cleanup.
73
+
74
+ Texto e --json expõem sempre operation, state, blocker, recovery e os códigos estáveis
75
+ WENDKEEP_WORKTREE_CLEANUP_BUSY, WENDKEEP_RECEIPT_LEDGER_CORRUPT e
76
+ WENDKEEP_RECEIPT_LEDGER_TRUNCATED; a recuperação retoma a reserva ou indica o reparo objetivo.
77
+
78
+ O gate comum classifica a operação de cleanup e bloqueia antes da mutação, inclusive em finish,
79
+ remove e cleanup --apply. Depois do append, o receipt é classificado pelo mesmo gate antes do
80
+ finalize; falha de proveniência não finaliza nem marca sucesso. Um estado cleaned sem receipt v2
81
+ fica bloqueado como unproven; um receipt v1 não autoriza e permanece legacy-unbound.
82
+
83
+ Texto e --json de bloqueio mantêm o diagnóstico equivalente e sanitizado: code, operation, state,
84
+ blocker, expected, observed, recovery, reason_codes, diagnostics e repair.
85
+
61
86
  ## Cleanup, remove e prune
62
87
 
63
88
  `cleanup --merged` e `prune` são dry-run por padrão. `--dry-run` apenas torna essa intenção
@@ -70,9 +95,19 @@ mas mantém todo o preflight e preserva as branches local e remota.
70
95
 
71
96
  O registry fica no Git common-dir, em `wendkeep/worktrees-v1.json`, sob lock multiprocesso. Ele
72
97
  guarda identidade do repositório/worktree, binding canônico, PR e estado transitório de cleanup;
73
- `.wendkeep.json` permanece inalterado. Receipts ficam em
74
- `wendkeep/worktree-cleanup-receipts-v1.jsonl`. `.worktrees/` entra no ignore versionado e no exclude
75
- privado. A saída JSON de `list`/`status` não expõe path nem conteúdo do Vault.
98
+ `.wendkeep.json` permanece inalterado. Novos receipts ficam em
99
+ `wendkeep/worktree-cleanup-receipts-v2.jsonl`: cada linha inclui `previous_hash` e `receipt_hash`, e
100
+ um checkpoint separado fixa a sequência/hash/tamanho validado. O v1 permanece legível como
101
+ `legacy-unbound`, sem append ou reescrita silenciosa. `WENDKEEP_RECEIPT_LEDGER_CORRUPT` indica
102
+ adulteração/JSON parcial; `WENDKEEP_RECEIPT_LEDGER_TRUNCATED` indica cauda removida. Ambos bloqueiam
103
+ antes da remoção e exigem diagnosticar o store, nunca inventar receipt. `.worktrees/` entra no
104
+ ignore versionado e no exclude privado; JSON de `list`/`status` não expõe path/conteúdo do Vault.
105
+ O gate de cleanup usa `verified`, `reported`, `legacy-unbound`, `stale`, `conflict` e `unproven`;
106
+ `WENDKEEP_PROVENANCE_GATE_BLOCKED` e os códigos `WENDKEEP_RECEIPT_LEDGER_BUSY`,
107
+ `WENDKEEP_RECEIPT_LEDGER_CONFLICT`, `WENDKEEP_RECEIPT_LEDGER_CORRUPT` e
108
+ `WENDKEEP_RECEIPT_LEDGER_TRUNCATED` falham fechados. O recovery objetivo lê o JSON sanitizado de
109
+ `worktree status <slug> --json`, executa `repair.command` quando presente e recaptura a prova; não
110
+ edite ledger/checkpoint nem exponha stderr, tokens, URLs privadas ou paths do Vault.
76
111
 
77
112
  `create` é idempotente quando slug, path e branch já correspondem. Colisões falham fechadas.
78
113
  Falhas depois da reserva ficam como `failed`; rode `worktree status <slug>` e siga `recovery`.