@orkastery/cli 0.5.3 → 0.5.6

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 (212) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/mods/autoridade.json +56 -0
  3. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  4. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  5. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  6. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  8. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  9. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  10. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  11. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  12. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  13. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  16. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  17. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  18. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  19. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  20. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  21. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  25. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  26. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  27. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  28. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  29. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  30. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  33. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  34. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  35. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  36. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  37. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  38. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  44. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  45. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  46. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  47. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  48. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  49. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  52. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  53. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  54. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  55. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  56. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  57. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  59. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  60. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  61. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  62. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  63. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  64. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  67. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  68. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  69. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  70. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  71. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  72. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  77. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  78. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  79. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +1 -1
  80. package/adapters/openclaw/README.md +2 -1
  81. package/adapters/openclaw/openclaw.plugin.json +1 -1
  82. package/adapters/openclaw/package.json +1 -1
  83. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  84. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  85. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  86. package/assets/docs-en/produto/README.md +14 -0
  87. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  88. package/assets/docs-en/roadmap/README.md +14 -0
  89. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  90. package/dist/adapters/claude-bg.js +77 -13
  91. package/dist/adapters/codex.js +10 -1
  92. package/dist/agents-md.js +24 -15
  93. package/dist/auditrun.js +17 -2
  94. package/dist/board.js +4 -3
  95. package/dist/branch-de-estado.js +23 -1
  96. package/dist/catalogo.js +33 -0
  97. package/dist/ci.js +13 -7
  98. package/dist/claims-conferir.js +342 -0
  99. package/dist/claims.js +3 -1
  100. package/dist/company-brain-client.js +36 -1
  101. package/dist/company-brain-journal.js +2 -1
  102. package/dist/company-brain-migration.js +36 -1
  103. package/dist/conducao-sentinela.js +388 -0
  104. package/dist/conducao-texto.js +12 -18
  105. package/dist/conducao.js +122 -30
  106. package/dist/conhecimento.js +490 -0
  107. package/dist/docs.js +22 -8
  108. package/dist/doctor-pulse-cron.js +182 -27
  109. package/dist/doctor-rede.js +18 -17
  110. package/dist/doctor.js +115 -111
  111. package/dist/entrega-pr.js +22 -21
  112. package/dist/escopo-escrita.js +10 -1
  113. package/dist/estado-thread.js +23 -1
  114. package/dist/experiencia-instalacao.js +45 -25
  115. package/dist/fabrica-batida.js +310 -0
  116. package/dist/fabrica-estado.js +38 -8
  117. package/dist/fabrica-publicar.js +3 -1
  118. package/dist/fila-pesada.js +444 -0
  119. package/dist/fix.js +3 -2
  120. package/dist/forja.js +1 -1
  121. package/dist/gates.js +3 -28
  122. package/dist/handoff.js +10 -6
  123. package/dist/hitl-local-receipt.js +2 -0
  124. package/dist/hitl-resumo.js +29 -3
  125. package/dist/hitl-tempo-parado.js +4 -4
  126. package/dist/hitl.js +29 -33
  127. package/dist/horario.js +14 -7
  128. package/dist/hosts.js +52 -1
  129. package/dist/impedimento.js +108 -14
  130. package/dist/index.js +623 -521
  131. package/dist/indice.js +7 -1
  132. package/dist/init.js +43 -47
  133. package/dist/instabilidade.js +144 -0
  134. package/dist/integracoes-locais.js +2 -0
  135. package/dist/intelligence-graph-cli.js +92 -21
  136. package/dist/intelligence-graph-contexto.js +56 -17
  137. package/dist/intelligence-graph-contract.js +2 -1
  138. package/dist/intelligence-graph-extract-md.js +56 -4
  139. package/dist/intelligence-graph-extract-ts.js +71 -3
  140. package/dist/intelligence-graph-query.js +66 -19
  141. package/dist/ledger.js +15 -1
  142. package/dist/liveness.js +6 -3
  143. package/dist/locale-ajuda.js +761 -0
  144. package/dist/locale-gerados.js +160 -0
  145. package/dist/locale-master.js +99 -0
  146. package/dist/locale-onboarding.js +92 -0
  147. package/dist/locale-phase.js +151 -0
  148. package/dist/locale-pulse.js +211 -0
  149. package/dist/locale-retry.js +385 -0
  150. package/dist/locale-roadmap.js +102 -0
  151. package/dist/locale-ship.js +494 -0
  152. package/dist/locale-thread.js +277 -0
  153. package/dist/locale-verify.js +125 -0
  154. package/dist/locale.js +714 -0
  155. package/dist/manifest.js +129 -3
  156. package/dist/maquina.js +23 -4
  157. package/dist/master-digest.js +6 -1
  158. package/dist/master-nota.js +4 -6
  159. package/dist/master.js +21 -24
  160. package/dist/mcp-artifacts.js +11 -2
  161. package/dist/mcp-git.js +23 -6
  162. package/dist/mcp-grafo.js +7 -4
  163. package/dist/mcp-server.js +8 -2
  164. package/dist/mcp-ship.js +3 -1
  165. package/dist/mcp-verify.js +6 -1
  166. package/dist/modos.js +3 -6
  167. package/dist/network-roadmap.js +5 -2
  168. package/dist/noctum-arco.js +911 -0
  169. package/dist/noctum-capacidade.js +141 -0
  170. package/dist/noctum-envelope.js +810 -0
  171. package/dist/noctum-execucao.js +304 -0
  172. package/dist/noctum-fila.js +280 -0
  173. package/dist/ocupacao.js +29 -2
  174. package/dist/onboarding.js +40 -21
  175. package/dist/orkmind.js +9 -2
  176. package/dist/orquestracao.js +13 -12
  177. package/dist/parado-no-condutor.js +34 -9
  178. package/dist/phase.js +94 -39
  179. package/dist/policies.js +4 -4
  180. package/dist/portfolio.js +4 -2
  181. package/dist/postura-local.js +234 -0
  182. package/dist/preflight.js +11 -10
  183. package/dist/procedencia.js +225 -0
  184. package/dist/projeto-alvo.js +127 -4
  185. package/dist/prompts.js +6 -2
  186. package/dist/pulse-delivery.js +13 -2
  187. package/dist/pulse.js +52 -19
  188. package/dist/ratelimit.js +4 -2
  189. package/dist/redacao-saida.js +63 -0
  190. package/dist/rede-status.js +3 -2
  191. package/dist/retry.js +232 -148
  192. package/dist/roadmap-reservas.js +20 -3
  193. package/dist/roadmap-status.js +129 -33
  194. package/dist/runtime-context.js +181 -3
  195. package/dist/runtimes.js +2 -1
  196. package/dist/session-events.js +7 -3
  197. package/dist/session-watcher-claude.js +7 -1
  198. package/dist/session-watcher.js +185 -33
  199. package/dist/sessoes-contas.js +1 -1
  200. package/dist/ship-publicar.js +800 -0
  201. package/dist/ship.js +84 -81
  202. package/dist/steal.js +77 -0
  203. package/dist/thread-close.js +3 -2
  204. package/dist/thread.js +153 -82
  205. package/dist/util.js +8 -1
  206. package/dist/verify.js +141 -52
  207. package/dist/vida-da-thread.js +254 -0
  208. package/dist/worktree-local.js +165 -0
  209. package/dist/worktree.js +20 -0
  210. package/dist/yaml.js +27 -8
  211. package/package.json +1 -1
  212. package/schemas/code-artifact-graph.v1.schema.json +2 -1
package/dist/retry.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.POLITICA_DE_RETRY = exports.ESCADA_DE_ESFORCO = void 0;
36
+ exports.TETO_DO_PROMPT_GRAVADO = exports.POLITICA_DE_RETRY = exports.ESCADA_DE_ESFORCO = void 0;
37
37
  exports.proximoEsforco = proximoEsforco;
38
38
  exports.politicaDoMotivo = politicaDoMotivo;
39
39
  exports.podeReexecutar = podeReexecutar;
@@ -45,6 +45,8 @@ exports.estadoTerminalDeRetry = estadoTerminalDeRetry;
45
45
  exports.planejarRetry = planejarRetry;
46
46
  exports.escalarEsforco = escalarEsforco;
47
47
  exports.redespachar = redespachar;
48
+ exports.localizarPromptGravado = localizarPromptGravado;
49
+ exports.despachoParaRedespachar = despachoParaRedespachar;
48
50
  exports.playbookDaRetomada = playbookDaRetomada;
49
51
  exports.retomarPedido = retomarPedido;
50
52
  exports.retomarFila = retomarFila;
@@ -86,6 +88,8 @@ const runtimes_1 = require("./runtimes");
86
88
  const setup_1 = require("./setup");
87
89
  const gates_1 = require("./gates");
88
90
  const ledger_1 = require("./ledger");
91
+ const estado_thread_1 = require("./estado-thread");
92
+ const vida_da_thread_1 = require("./vida-da-thread");
89
93
  const phase_1 = require("./phase");
90
94
  const runtime_context_1 = require("./runtime-context");
91
95
  const slug_1 = require("./slug");
@@ -104,6 +108,12 @@ const gates_2 = require("./gates");
104
108
  const horario_1 = require("./horario");
105
109
  const conducao_1 = require("./conducao");
106
110
  const conducao_texto_1 = require("./conducao-texto");
111
+ const procedencia_1 = require("./procedencia");
112
+ const postura_local_1 = require("./postura-local");
113
+ const locale_1 = require("./locale");
114
+ const locale_retry_1 = require("./locale-retry");
115
+ /** RM-061 (F2b, D3): `porque` e `correcao` de cada motivo tem a fonte no catalogo pt-BR; o `--json` nao muda. */
116
+ const TEXTOS_DA_POLITICA = locale_retry_1.RETRY_PT_BR.politica;
107
117
  /**
108
118
  * Escada de esforco da 2a tentativa em diante.
109
119
  *
@@ -129,29 +139,25 @@ exports.POLITICA_DE_RETRY = {
129
139
  motivo: 'artifact.missing',
130
140
  acao: 'corrigir-dirigido',
131
141
  automatica: true,
132
- porque: 'o artefato exigido pela fase nao existe: a fase precisa de spec dirigida do que gravar, nao de repeticao cega do mesmo prompt',
133
- correcao: 'ork fix open <thread> abre a rodada com a spec exata',
142
+ ...TEXTOS_DA_POLITICA['artifact.missing'],
134
143
  },
135
144
  'claims.failed': {
136
145
  motivo: 'claims.failed',
137
146
  acao: 'corrigir-dirigido',
138
147
  automatica: true,
139
- porque: 'a alegacao reprovou na reexecucao no HEAD real: reexecutar a fase igual reproduz a mesma mentira; o que resolve e GO-FIX com a claim e o comando exatos',
140
- correcao: 'ork fix open <thread> e depois ork fix reverify <thread>',
148
+ ...TEXTOS_DA_POLITICA['claims.failed'],
141
149
  },
142
150
  'claims.unverifiable': {
143
151
  motivo: 'claims.unverifiable',
144
152
  acao: 'corrigir-dirigido',
145
153
  automatica: true,
146
- porque: 'alegacao sem comando de verificacao vira correcao tipo A: anexar o comando (ou retirar a alegacao com motivo) e uma linha, nao um GO inteiro',
147
- correcao: 'ork claims verificar <thread> <claim> --comando "<comando>"',
154
+ ...TEXTOS_DA_POLITICA['claims.unverifiable'],
148
155
  },
149
156
  'policy.violation': {
150
157
  motivo: 'policy.violation',
151
158
  acao: 'escalar-humano',
152
159
  automatica: false,
153
- porque: 'policy com severidade block reprova em qualquer modo: reexecutar sozinho seria a maquina revogando a policy do manifesto',
154
- correcao: 'corrija a violacao no pedido/manifesto; policy block nao se resolve por repeticao',
160
+ ...TEXTOS_DA_POLITICA['policy.violation'],
155
161
  },
156
162
  'runtime.autoconferencia': {
157
163
  motivo: 'runtime.autoconferencia',
@@ -161,77 +167,66 @@ exports.POLITICA_DE_RETRY = {
161
167
  // decide em que runtime o CHECK roda e quem conduz a thread.
162
168
  acao: 'escalar-humano',
163
169
  automatica: false,
164
- porque: 'repetir o despacho no MESMO runtime daria o mesmo resultado: o que falta nao e tentativa, e um validador que nao seja quem executou. Escolher o outro runtime e decisao de conducao, nao retry',
165
- correcao: 'despache o CHECK em outro runtime (`ork phase run <thread> CHECK --runtime <outro>`), ou tire a exigencia de validacao cruzada da thread se ela nao se justifica',
170
+ ...TEXTOS_DA_POLITICA['runtime.autoconferencia'],
166
171
  },
167
172
  // RM-056 (D1): o perfil pedido nao existe ou e de outro runtime. Quem corrige e quem pediu.
168
173
  'runtime.profile-invalid': {
169
174
  motivo: 'runtime.profile-invalid',
170
175
  acao: 'escalar-humano',
171
176
  automatica: false,
172
- porque: 'o perfil foi pedido pelo dono (--perfil) e nao existe no store ou e de outro runtime: repetir o pedido daria a mesma recusa, e trocar de perfil sozinho desobedeceria o pedido',
173
- correcao: 'ork accounts list mostra os perfis de cada runtime; repita o despacho com um perfil do runtime certo ou sem --perfil',
177
+ ...TEXTOS_DA_POLITICA['runtime.profile-invalid'],
174
178
  },
175
179
  'cost.violation': {
176
180
  motivo: 'cost.violation',
177
181
  acao: 'sem-retry',
178
182
  automatica: false,
179
- porque: 'violacao de CUSTO nunca recebe retry automatico: cada reexecucao gastaria de novo pelo provider pago (subscription-only e regra de codigo, nao lembrete)',
180
- correcao: 'tire do ambiente a variavel que redireciona o despacho e rode a fase de novo a mao, com o gasto sob os olhos de um humano',
183
+ ...TEXTOS_DA_POLITICA['cost.violation'],
181
184
  },
182
185
  'verify.regression': {
183
186
  motivo: 'verify.regression',
184
187
  acao: 'corrigir-dirigido',
185
188
  automatica: true,
186
- porque: 'o comando passava na baseline e falha agora: o defeito e desta thread e tem alvo conhecido, entao ele vira spec de GO-FIX tipo B',
187
- correcao: 'ork fix open <thread> (a reexecucao seguinte e completa)',
189
+ ...TEXTOS_DA_POLITICA['verify.regression'],
188
190
  },
189
191
  'verify.failed': {
190
192
  motivo: 'verify.failed',
191
193
  acao: 'corrigir-dirigido',
192
194
  automatica: true,
193
- porque: 'o comando falha sem baseline para separar regressao de divida: a correcao dirigida conserta ou grava a baseline, mas nao chuta de quem e a culpa',
194
- correcao: 'ork fix open <thread>, ou ork verify <thread> --baseline antes do proximo GO',
195
+ ...TEXTOS_DA_POLITICA['verify.failed'],
195
196
  },
196
197
  'verify.timeout': {
197
198
  motivo: 'verify.timeout',
198
199
  acao: 'reexecutar',
199
200
  automatica: true,
200
- porque: 'o prazo estourou antes de o comando terminar: a prova nao chegou ao fim, e carga de maquina nao e defeito. A reexecucao e completa, e o limite de escalacao do manifesto impede repetir para sempre',
201
- correcao: 'ork verify <thread> de novo; se estourar sempre, suba verify.timeout_ms no manifesto ou divida o comando',
201
+ ...TEXTOS_DA_POLITICA['verify.timeout'],
202
202
  },
203
203
  'verify.sem-veredito': {
204
204
  motivo: 'verify.sem-veredito',
205
205
  acao: 'reexecutar',
206
206
  automatica: true,
207
- porque: 'um comando nao chegou a rodar ou o produto mudou no meio da rodada: nao ha veredito sobre ele, e a prova certa e rodar de novo, inteira',
208
- correcao: 'ork verify <thread> de novo, sem editar a worktree durante a rodada',
207
+ ...TEXTOS_DA_POLITICA['verify.sem-veredito'],
209
208
  },
210
209
  'ci.failed': {
211
210
  motivo: 'ci.failed',
212
211
  acao: 'escalar-humano',
213
212
  automatica: false,
214
- porque: 'o recibo pertence ao provedor e ao SHA candidato: repetir uma fase não cria nem altera legitimamente esse resultado',
215
- correcao: 'publique a candidata, aguarde o check obrigatório e repita o SHIP; se reprovou, corrija a causa registrada no runner',
213
+ ...TEXTOS_DA_POLITICA['ci.failed'],
216
214
  },
217
215
  'runtime.unavailable': {
218
216
  motivo: 'runtime.unavailable',
219
217
  acao: 'reexecutar',
220
218
  automatica: true,
221
- porque: 'falha de infraestrutura no despacho nao e falha de conteudo: o MESMO prompt, com o mesmo sha256, e redespachado sem alterar uma virgula',
222
- correcao: 'ork retry run <thread> redespacha o prompt ja gravado em disco',
219
+ ...TEXTOS_DA_POLITICA['runtime.unavailable'],
223
220
  },
224
221
  'runtime.silencio': {
225
222
  motivo: 'runtime.silencio', acao: 'reexecutar', automatica: true,
226
- porque: 'fase sem heartbeat: retomar o despacho original com hash conferido e limite de tentativas',
227
- correcao: 'ork retry run <thread> --motivo runtime.silencio',
223
+ ...TEXTOS_DA_POLITICA['runtime.silencio'],
228
224
  },
229
225
  'runtime.rate-limited': {
230
226
  motivo: 'runtime.rate-limited',
231
227
  acao: 'esperar-janela',
232
228
  automatica: true,
233
- porque: 'o limite de uso tem HORA de volta: a fase entra na fila duravel e e retomada na janela seguinte, sem humano no meio e sem gastar por fora da assinatura',
234
- correcao: 'ork retry list mostra a fila; ork retry resume retoma o que ja liberou',
229
+ ...TEXTOS_DA_POLITICA['runtime.rate-limited'],
235
230
  },
236
231
  // I-33 (D5, D11): a falha e da CONTA. O perfil sai do rodizio e o MESMO prompt vai ao proximo
237
232
  // perfil ativo, depois ao runtime de fallback do bloco, e so por ultimo a fila duravel. A
@@ -241,15 +236,13 @@ exports.POLITICA_DE_RETRY = {
241
236
  motivo: 'runtime.quota-exhausted',
242
237
  acao: 'reexecutar',
243
238
  automatica: true,
244
- porque: 'a cota ou os creditos da CONTA acabaram, nao a infraestrutura: o perfil sai do rodizio ate o prazo e o MESMO prompt, com o mesmo sha256, segue no proximo perfil, no runtime de fallback ou na fila ate o menor prazo',
245
- correcao: 'ork accounts list mostra o perfil esgotado; ork retry run <thread> rotaciona o prompt ja gravado',
239
+ ...TEXTOS_DA_POLITICA['runtime.quota-exhausted'],
246
240
  },
247
241
  'runtime.auth-missing': {
248
242
  motivo: 'runtime.auth-missing',
249
243
  acao: 'reexecutar',
250
244
  automatica: true,
251
- porque: 'a conta do runtime perdeu a autenticacao: o perfil nunca mais recebe despacho ate o login ser refeito pelo proprio CLI, e o MESMO prompt segue no proximo perfil ou no runtime de fallback',
252
- correcao: 'ork accounts check confere o login de cada perfil; ork retry run <thread> rotaciona o prompt ja gravado',
245
+ ...TEXTOS_DA_POLITICA['runtime.auth-missing'],
253
246
  },
254
247
  // RM-037 (defeitosdeco D-6): o modelo e que falta, nao a conta. Repetir o mesmo modelo na mesma conta
255
248
  // so repete a recusa; o perfil continua no rodizio para os outros modelos.
@@ -257,8 +250,7 @@ exports.POLITICA_DE_RETRY = {
257
250
  motivo: 'runtime.model-unavailable',
258
251
  acao: 'reexecutar',
259
252
  automatica: true,
260
- porque: 'o modelo pedido nao existe ou a conta nao tem acesso a ele: o MESMO prompt, com o mesmo sha256, segue no proximo perfil do mesmo runtime com o mesmo modelo e depois no fallback do bloco, nunca de novo no par que ja recusou',
261
- correcao: 'ork retry run <thread> troca o destino; sem destino, ork setup <modo> --bloco N --model <modelo acessivel> ou --fallback runtime:modelo',
253
+ ...TEXTOS_DA_POLITICA['runtime.model-unavailable'],
262
254
  },
263
255
  // RM-055: so o dono destrava, no terminal. O retry nao repete o despacho as cegas: confere antes se o
264
256
  // impedimento saiu (a confianca do diretorio tem prova local) e, sem prova, deixa o runtime decidir.
@@ -266,36 +258,31 @@ exports.POLITICA_DE_RETRY = {
266
258
  motivo: 'runtime.workspace-untrusted',
267
259
  acao: 'reexecutar',
268
260
  automatica: true,
269
- porque: 'o runtime recusou o diretorio da worktree antes de rodar qualquer coisa: depois que o dono aceita a confianca no terminal, o MESMO prompt, com o mesmo sha256, volta a mesma fase; enquanto a confianca nao aparece no .claude.json da conta, nada e despachado',
270
- correcao: 'o dono roda o comando da pausa (cd <worktree> && claude, aceita a confianca); ork retry run <thread> re-despacha o prompt ja gravado',
261
+ ...TEXTOS_DA_POLITICA['runtime.workspace-untrusted'],
271
262
  },
272
263
  'runtime.consent-pending': {
273
264
  motivo: 'runtime.consent-pending',
274
265
  acao: 'reexecutar',
275
266
  automatica: true,
276
- porque: 'o runtime espera o dono aceitar termos novos antes de rodar qualquer coisa: depois do aceite, o MESMO prompt, com o mesmo sha256, volta a mesma fase; se o runtime recusar de novo, a mesma pausa do dono volta',
277
- correcao: 'o dono abre o CLI do runtime e aceita os termos; ork retry run <thread> re-despacha o prompt ja gravado',
267
+ ...TEXTOS_DA_POLITICA['runtime.consent-pending'],
278
268
  },
279
269
  'tree.blocked': {
280
270
  motivo: 'tree.blocked',
281
271
  acao: 'sincronizar-worktree',
282
272
  automatica: true,
283
- porque: 'a arvore de destino andou por baixo da thread: rebasar a worktree contra a base e o passo que desbloqueia, e reexecutar antes disso so repete o conflito',
284
- correcao: 'ork worktree sync <thread> e so entao repetir o passo',
273
+ ...TEXTOS_DA_POLITICA['tree.blocked'],
285
274
  },
286
275
  'lease.resume-unavailable': {
287
276
  motivo: 'lease.resume-unavailable',
288
277
  acao: 'escalar-humano',
289
278
  automatica: false,
290
- porque: 'sem inode seguro, a remocao forcada exige avaliar a posse antes de retomar',
291
- correcao: 'ork lease release <nome> --forcar; depois repita a aquisicao',
279
+ ...TEXTOS_DA_POLITICA['lease.resume-unavailable'],
292
280
  },
293
281
  'lease.busy': {
294
282
  motivo: 'lease.busy',
295
283
  acao: 'reexecutar',
296
284
  automatica: true,
297
- porque: 'o lease e de outra thread e vai ser liberado: a fila ja serializa, entao a acao e tentar de novo quando chegar a vez, nunca furar a fila',
298
- correcao: 'ork lease list mostra a fila; a vez chega sem ninguem forcar',
285
+ ...TEXTOS_DA_POLITICA['lease.busy'],
299
286
  },
300
287
  // I-36 (T6): a vez chega quando a conducao atual terminar. Redespachar agora so recebe a mesma recusa,
301
288
  // e passar na frente de quem conduz e exatamente o incidente de 19/09/2026.
@@ -303,8 +290,7 @@ exports.POLITICA_DE_RETRY = {
303
290
  motivo: 'conducao.em-andamento',
304
291
  acao: 'esperar-janela',
305
292
  automatica: true,
306
- porque: 'outra conducao executa na mesma worktree agora: a vez chega quando ela terminar, e furar a fila e o incidente de 19/09/2026',
307
- correcao: 'ork conducao status <thread> mostra quem conduz; repita o pedido com --esperar <min> para seguir sozinho quando liberar',
293
+ ...TEXTOS_DA_POLITICA['conducao.em-andamento'],
308
294
  },
309
295
  // I-41 (D10): formato e defeito de quem escreveu o pedido, e a spec dirigida conserta.
310
296
  // Escalar isto para o dono seria pedir que ele revise a sintaxe do robo.
@@ -312,15 +298,13 @@ exports.POLITICA_DE_RETRY = {
312
298
  motivo: 'hitl.formato',
313
299
  acao: 'corrigir-dirigido',
314
300
  automatica: true,
315
- porque: 'o pedido HITL saiu fora do formato obrigatorio: quem errou foi o emissor, e a correcao e reemitir com alternativas rotuladas, consequencia por alternativa e exatamente uma recomendada com o porque',
316
- correcao: 'ork fix open <thread> abre a rodada com a spec exata do formato',
301
+ ...TEXTOS_DA_POLITICA['hitl.formato'],
317
302
  },
318
303
  'human.pending': {
319
304
  motivo: 'human.pending',
320
305
  acao: 'escalar-humano',
321
306
  automatica: false,
322
- porque: 'nao e reprovacao de verdade, e espera de autorizacao: automatizar a espera seria a maquina se autorizando',
323
- correcao: 'ork gate request <thread>',
307
+ ...TEXTOS_DA_POLITICA['human.pending'],
324
308
  },
325
309
  };
326
310
  /** A politica de um motivo tipado. */
@@ -369,7 +353,8 @@ function ultimaReprovacao(raiz, threadId) {
369
353
  * planejou: planejar nao gasta janela nem toca no repositorio.
370
354
  */
371
355
  function tentativasFeitas(raiz, threadId, fase, motivo) {
372
- return (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)).filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.retryTentado && e.fase === fase && e.motivo === motivo).length;
356
+ // RM-055 (continuacao, D2): a recusa pelo impedimento do dono fica no ledger com `conta: false` e nao conta.
357
+ return (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)).filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.retryTentado && e.fase === fase && e.motivo === motivo && e.conta !== false).length;
373
358
  }
374
359
  /** O bloco de loop desta fase pausa para o humano neste modo? */
375
360
  function blocoPausa(thread, fase) {
@@ -397,7 +382,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
397
382
  modo: thread.modo,
398
383
  fase: opcoes.fase ?? thread.faseAtual,
399
384
  motivo: null,
400
- detalhe: 'nenhum gate reprovado no ledger desta thread',
385
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.semReprovacao),
401
386
  politica: null,
402
387
  acao: 'sem-retry',
403
388
  tentativas: 0,
@@ -406,7 +391,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
406
391
  effortAnterior: effortBase,
407
392
  automatica: false,
408
393
  bloqueio: 'gate.sem-reprovacao',
409
- razao: 'nao ha o que repetir: o ledger da thread nao tem reprovacao tipada pendente',
394
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.nadaARepetir),
410
395
  };
411
396
  }
412
397
  const fase = opcoes.fase ?? (evento ? faseDoEvento(evento, thread) : thread.faseAtual);
@@ -429,7 +414,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
429
414
  effortAnterior: effortBase,
430
415
  automatica: false,
431
416
  bloqueio: 'politica.nao-automatica',
432
- razao: politica.porque,
417
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.politica[motivo].porque),
433
418
  };
434
419
  }
435
420
  // Limite de escalacao: pausa QUALQUER modo, inclusive #Auto.
@@ -448,8 +433,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
448
433
  effortAnterior: effortBase,
449
434
  automatica: false,
450
435
  bloqueio: 'escalacao.limite',
451
- razao: `${tentativas} tentativa(s) automatica(s) por ${motivo} em ${fase}, no limite de ${limite} ` +
452
- 'do manifesto: escalacao tipada pausa qualquer modo, inclusive #Auto',
436
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.limiteDeEscalacao(tentativas, motivo, fase, limite)),
453
437
  };
454
438
  }
455
439
  // Da 2a tentativa em diante o esforco sobe um degrau, quando o manifesto permite.
@@ -465,9 +449,10 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
465
449
  const autorizado = delegacao.permitida || (0, gates_2.aprovacoesHumanas)(raiz, threadId).some(e => e.fase === fase && e.autorizadoPor === opcoes.autorizadoPor);
466
450
  let bloqueio = null;
467
451
  let automatica = politica.automatica;
468
- let razao = politica.porque;
469
- if (delegacao.permitida && politica.automatica)
470
- razao += `; ${delegacao.razao}; delegado ${delegacao.delegado}; evidência ${delegacao.evidencia}`;
452
+ let razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.politica[motivo].porque);
453
+ if (delegacao.permitida && politica.automatica) {
454
+ razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.comDelegacao(m.retry.politica[motivo].porque, delegacao.razao, String(delegacao.delegado), String(delegacao.evidencia)));
455
+ }
471
456
  if (!politica.automatica) {
472
457
  automatica = false;
473
458
  bloqueio = 'politica.nao-automatica';
@@ -477,10 +462,8 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
477
462
  // a acao fica planejada e nao executada. `#Maestro` e `#Auto` nao caem neste ramo.
478
463
  automatica = false;
479
464
  bloqueio = 'modo.bloco-pausa';
480
- razao =
481
- `o bloco ${(0, thread_1.blocoDaThread)(thread, fase).fases.join('-')} pausa neste modo ` +
482
- `(${(0, thread_1.blocoDaThread)(thread, fase).pausaSobre}): a acao ${acao} espera autorizacao humana. ` +
483
- 'O modo afrouxa a pausa, nunca a verificacao.';
465
+ const bloco = (0, thread_1.blocoDaThread)(thread, fase);
466
+ razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.blocoPausa(bloco.fases.join('-'), m.thread.pausaSobre(bloco.pausaSobre), acao));
484
467
  }
485
468
  if (motivo === 'runtime.silencio') {
486
469
  const despacho = ultimoDespachoFalho(raiz, threadId, fase, true);
@@ -488,7 +471,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
488
471
  if (!prova || prova.sessionId !== despacho?.sessionId || !estadoTerminalDeRetry(prova.estado)) {
489
472
  automatica = false;
490
473
  bloqueio = 'politica.nao-automatica';
491
- razao = 'runtime.silencio exige prova terminal atual da mesma sessao; ausencia ou silencio nao provam morte';
474
+ razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.silencioSemProva);
492
475
  }
493
476
  }
494
477
  return {
@@ -534,24 +517,92 @@ function redespachar(carregado, thread, fase, promptRelativo, sha, opcoes = {})
534
517
  retida.devolver();
535
518
  }
536
519
  }
520
+ /**
521
+ * RM-063 (F3): onde esta o prompt gravado. O ledger guarda o caminho relativo a raiz de codigo de quem despachou:
522
+ * da worktree, ele sai `../../../.orkastery/threads/...` (a K7 de 12/10/2026), e lido do checkout principal aponta
523
+ * para fora do projeto. O arquivo certo e o que tem o MESMO sha256: absoluto, relativo a raiz de codigo, a raiz do
524
+ * estado ou a pasta de prompts da thread. Sem nenhum com o sha, vale o primeiro que existe (a recusa diz que o prompt
525
+ * mudou); sem nenhum arquivo comum dentro do projeto, `null` (a recusa diz que sumiu).
526
+ */
527
+ function localizarPromptGravado(raiz, threadId, promptPath, sha) {
528
+ const candidatos = path.isAbsolute(promptPath) ? [promptPath] : [path.join(raiz, promptPath)];
529
+ try {
530
+ candidatos.push(path.join((0, estado_thread_1.raizDoEstado)(raiz), promptPath));
531
+ }
532
+ catch { /* raiz sem estado legivel */ }
533
+ candidatos.push(path.join((0, thread_1.dirThread)(raiz, threadId), 'prompts', path.basename(promptPath)));
534
+ let thread = null;
535
+ try {
536
+ const t = (0, thread_1.lerThread)(raiz, threadId);
537
+ thread = { id: t.id, worktree: t.worktree };
538
+ }
539
+ catch {
540
+ thread = null;
541
+ }
542
+ // O ponteiro vem do estado: so arquivo comum, de tamanho de prompt, dentro do projeto ou da worktree da thread (RM-047).
543
+ const legivel = (c) => {
544
+ try {
545
+ const st = fs.lstatSync(c);
546
+ return st.isFile() && st.size <= exports.TETO_DO_PROMPT_GRAVADO && (0, procedencia_1.caminhoContidoOuNulo)(raiz, thread, c) !== null;
547
+ }
548
+ catch {
549
+ return false;
550
+ }
551
+ };
552
+ const existentes = [...new Set(candidatos.map((c) => path.resolve(c)))].filter(legivel);
553
+ for (const c of existentes) {
554
+ try {
555
+ if ((0, phase_1.hashDoPrompt)(fs.readFileSync(c, 'utf8')) === sha)
556
+ return c;
557
+ }
558
+ catch { /* ilegivel: tenta o proximo */ }
559
+ }
560
+ return existentes[0] ?? null;
561
+ }
562
+ /** Um prompt de fase tem dezenas de KB; acima disto o ponteiro do estado nao e um prompt gravado pelo ork. */
563
+ exports.TETO_DO_PROMPT_GRAVADO = 4 * 1024 * 1024;
564
+ /**
565
+ * RM-063 (F3): o despacho cujo prompt o `reexecutar` devolve ao runtime. Primeiro o despacho da sessao do gate (a
566
+ * sessao que morreu depois de despachada, como a K7 de 12/10/2026, nao deixa `phase_dispatch_failed`), depois o
567
+ * proprio gate quando ele carrega o prompt, e por fim a tentativa mais recente da fase com prompt gravado:
568
+ * `phase_dispatch_failed` ou `phase_prompt_recorded` (e o `phase_dispatch`, no silencio do runtime).
569
+ */
570
+ function despachoParaRedespachar(eventos, fase, gate, silencio = false) {
571
+ const comPrompt = (e) => !!e && typeof e.promptPath === 'string' && typeof e.promptSha256 === 'string';
572
+ if (gate && typeof gate.sessionId === 'string') {
573
+ const daSessao = eventos.filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.faseDespachada && e.sessionId === gate.sessionId).at(-1);
574
+ if (comPrompt(daSessao))
575
+ return daSessao;
576
+ }
577
+ if (comPrompt(gate))
578
+ return gate;
579
+ for (let i = eventos.length - 1; i >= 0; i--) {
580
+ const e = eventos[i];
581
+ if (e.fase !== fase || !comPrompt(e))
582
+ continue;
583
+ if (e.tipo === ledger_1.TIPOS_DE_EVENTO.despachoFalhou || e.tipo === ledger_1.TIPOS_DE_EVENTO.promptGravado ||
584
+ (silencio && e.tipo === ledger_1.TIPOS_DE_EVENTO.faseDespachada))
585
+ return e;
586
+ }
587
+ return null;
588
+ }
537
589
  function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes = {},
538
590
  /** A tomada que a primeira passada reteve para a baseline; com ela, esta e a repeticao. */
539
591
  tomadaPrevia) {
540
592
  const { raiz, manifesto } = carregado;
541
- const absoluto = path.isAbsolute(promptRelativo)
542
- ? promptRelativo
543
- : path.join(raiz, promptRelativo);
593
+ const achado = localizarPromptGravado(raiz, thread.id, promptRelativo, sha);
594
+ const absoluto = achado ?? '';
544
595
  const slug = opcoes.slug ?? (0, phase_1.slugDaSessao)(thread, fase);
545
596
  const vazio = { slug, sessionId: null, verificada: false, sinal: null, comando: [] };
546
597
  const erroDeEstado = (0, phase_1.estadoParaDespacho)(raiz, thread, opcoes.dryRun);
547
598
  if (erroDeEstado)
548
599
  return { ...vazio, ok: false, motivo: 'tree.blocked', detalhe: erroDeEstado, dryRun: opcoes.dryRun === true };
549
- if (!fs.existsSync(absoluto)) {
600
+ if (!achado) {
550
601
  return {
551
602
  ...vazio,
552
603
  ok: false,
553
604
  motivo: 'artifact.missing',
554
- detalhe: `o prompt gravado sumiu do disco: ${promptRelativo}`,
605
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.promptSumiu(promptRelativo)),
555
606
  dryRun: opcoes.dryRun === true,
556
607
  };
557
608
  }
@@ -562,8 +613,7 @@ tomadaPrevia) {
562
613
  ...vazio,
563
614
  ok: false,
564
615
  motivo: 'artifact.missing',
565
- detalhe: `o prompt em ${promptRelativo} mudou desde o despacho original ` +
566
- `(sha256 ${shaAtual.slice(0, 12)} != ${sha.slice(0, 12)}): retomada e redespachar o MESMO texto`,
616
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.promptMudou(promptRelativo, shaAtual.slice(0, 12), sha.slice(0, 12))),
567
617
  dryRun: opcoes.dryRun === true,
568
618
  };
569
619
  }
@@ -611,8 +661,9 @@ tomadaPrevia) {
611
661
  (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, ledger_1.TIPOS_DE_EVENTO.despachoIdempotente, { fase, promptSha256: sha, canal,
612
662
  sessionId: tomada.atual.sessao, origem: opcoes.origem ?? 'retry',
613
663
  razao: 'mesma fase e mesmo prompt de quem ja conduz: a sessao em andamento atende a retomada, sem sessao nova' });
664
+ const sessao = String(tomada.atual.sessao).slice(0, 8);
614
665
  return { ...vazio, ok: true, sessionId: tomada.atual.sessao, motivo: null, dryRun: false,
615
- detalhe: `a sessao ${String(tomada.atual.sessao).slice(0, 8)} ja conduz a fase ${fase} com este prompt: nada foi redespachado` };
666
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.jaConduz(sessao, fase)) };
616
667
  }
617
668
  const recusa = (0, conducao_1.recusaDeConducao)(thread.id, tomada.atual, pedidoDeConducao);
618
669
  (0, conducao_1.registrarRecusa)(raiz, recusa);
@@ -621,7 +672,14 @@ tomadaPrevia) {
621
672
  conducao = tomada;
622
673
  }
623
674
  try {
624
- const cwd = opcoes.cwd ?? thread.worktree ?? raiz;
675
+ // RM-047 (P2): o cwd do pedido da fila ou da worktree da thread so vale como worktree registrada no git.
676
+ let cwd;
677
+ try {
678
+ cwd = opcoes.cwd !== undefined ? (0, procedencia_1.exigirCwdLocal)(raiz, thread.id, opcoes.cwd, 'fila') : (0, procedencia_1.diretorioDaThread)(raiz, thread);
679
+ }
680
+ catch (e) {
681
+ return { ...vazio, ok: false, motivo: 'tree.blocked', detalhe: e.message, dryRun: opcoes.dryRun === true };
682
+ }
625
683
  // Mesma resolucao do `ork phase run`: a retomada carimba no ledger o trio que ela de
626
684
  // fato despachou, inclusive quando o pedido da fila trazia um modelo proprio. O setup
627
685
  // do bloco (feature #setup) vale aqui tambem: a fase retomada abre no MESMO runtime
@@ -633,11 +691,20 @@ tomadaPrevia) {
633
691
  effort: opcoes.effort ?? undefined,
634
692
  }, doBloco);
635
693
  const rt = (0, runtimes_1.resolverRuntime)(runtime);
694
+ // RM-047 (P1): a retomada recusa o sandbox afrouxado sem a confirmacao local, como o `ork phase run`.
695
+ const erroDePostura = (0, postura_local_1.recusaDePostura)(raiz, manifesto, runtime);
696
+ if (erroDePostura) {
697
+ if (!opcoes.dryRun)
698
+ (0, gates_1.registrarGateBloqueado)((0, thread_1.dirThread)(raiz, thread.id), thread.id, { gate: 'phase.dispatch',
699
+ motivo: 'policy.violation', modo: thread.modo, detalhe: erroDePostura,
700
+ correcao: (0, postura_local_1.comandoDeConfirmacao)((0, postura_local_1.posturaAfrouxada)(manifesto) ?? ''), fase, slug, origem: opcoes.origem ?? 'retry' });
701
+ return { ...vazio, ok: false, motivo: 'policy.violation', detalhe: erroDePostura, dryRun: opcoes.dryRun === true };
702
+ }
636
703
  if (!opcoes.dryRun && (0, phase_1.baselineDoDespachoNecessaria)(carregado, thread.id, { fase, prompt: '', runtime, model, effort })) {
637
704
  // Na primeira passada a tomada fica retida para a baseline (o `finally` nao a solta); na repeticao, o
638
705
  // `finally` devolve o que a tomada consumiu (A-1 do CHECK 3).
639
706
  const pendente = { ...vazio, ok: false, motivo: 'runtime.unavailable', dryRun: false,
640
- detalhe: `baseline.pendente: o bloco com GO no ${runtime} precisa da baseline antes da retomada` };
707
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.baselinePendente(runtime)) };
641
708
  if (!tomadaPrevia && conducao) {
642
709
  pendente.retida = conducao;
643
710
  conducao = null;
@@ -653,8 +720,9 @@ tomadaPrevia) {
653
720
  contextoRuntime = (0, runtime_context_1.contextoDoProjeto)(raiz, runtime, cwd, thread.id);
654
721
  }
655
722
  catch (e) {
723
+ const erro = e.message;
656
724
  return { ...vazio, ok: false, motivo: 'runtime.unavailable',
657
- detalhe: `runtime.unavailable: ${e.message}`, dryRun: opcoes.dryRun === true };
725
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeIndisponivel(erro)), dryRun: opcoes.dryRun === true };
658
726
  }
659
727
  if (contextoRuntime)
660
728
  contextoRuntime.identidade = identidade;
@@ -700,7 +768,7 @@ tomadaPrevia) {
700
768
  sessionId: null,
701
769
  verificada: false,
702
770
  motivo: null,
703
- detalhe: 'ensaio (--dry-run): comando montado, nada despachado',
771
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.ensaioDoRedespacho),
704
772
  sinal: null,
705
773
  comando: resultado.comando,
706
774
  dryRun: true,
@@ -736,7 +804,7 @@ tomadaPrevia) {
736
804
  verificada: false,
737
805
  // I-33 (D11b): falha de conta reconhecida na saida e o motivo mais especifico.
738
806
  motivo: resultado.falhaDeConta?.motivo ?? (sinal ? 'runtime.rate-limited' : 'runtime.unavailable'),
739
- detalhe: resultado.erro ?? 'sem sessionId na saida do runtime',
807
+ detalhe: resultado.erro ?? (0, locale_1.textoDoCatalogo)((m) => m.retry.semSessionId),
740
808
  sinal,
741
809
  falhaDeConta: resultado.falhaDeConta ?? null,
742
810
  perfil: perfil ?? null,
@@ -771,8 +839,7 @@ tomadaPrevia) {
771
839
  sessionId: resultado.sessionId,
772
840
  verificada: resultado.verificada,
773
841
  motivo: null,
774
- detalhe: `sessao ${resultado.sessionId} despachada com o mesmo prompt sha256 ${sha.slice(0, 12)}` +
775
- (perfil ? ` no perfil ${perfil.id} (${runtime})` : ''),
842
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.redespachada(String(resultado.sessionId), sha.slice(0, 12), perfil ? perfil.id : null, runtime)),
776
843
  sinal: null,
777
844
  perfil: perfil ?? null,
778
845
  comando: resultado.comando,
@@ -1119,7 +1186,11 @@ function producaoNoIntervalo(raiz, thread, sessao, eventos) {
1119
1186
  // pelo shell nao passa pelo ledger, entao so o HEAD o revela.
1120
1187
  const registro = eventos.filter(e => e.tipo === 'session_sensor_registered' && e.sessionId === sessao.sessionId &&
1121
1188
  e.despachoEm === sessao.despachadaEm).at(-1);
1122
- const cwd = typeof registro?.cwd === 'string' ? registro.cwd : typeof despacho?.cwd === 'string' ? despacho.cwd : thread.worktree ?? raiz;
1189
+ const doLedger = typeof registro?.cwd === 'string' ? registro.cwd : typeof despacho?.cwd === 'string' ? despacho.cwd : null;
1190
+ // RM-047 (P2): git so roda em worktree registrada; cwd que nao vale e duvida, e duvida conta como producao.
1191
+ const cwd = doLedger !== null ? (0, procedencia_1.cwdLocalOuNulo)(raiz, thread.id, doLedger, 'ledger') : (0, procedencia_1.cwdLocalOuNulo)(raiz, thread.id, thread.worktree ?? raiz, 'thread');
1192
+ if (cwd === null)
1193
+ return { produziu: true, evidencia: 'cwd do despacho fora das worktrees registradas; producao nao descartada' };
1123
1194
  const head = registro?.head;
1124
1195
  if (typeof head !== 'string' || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head))
1125
1196
  return { produziu: true, evidencia: 'HEAD da worktree no despacho desconhecido; producao nao descartada' };
@@ -1263,7 +1334,7 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1263
1334
  return vazio;
1264
1335
  }
1265
1336
  const acaoBase = plano.politica?.acao ?? plano.acao;
1266
- const registrarTentativa = (ok, detalhe) => {
1337
+ const registrarTentativa = (ok, detalhe, extra = {}) => {
1267
1338
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.retryTentado, {
1268
1339
  fase: plano.fase,
1269
1340
  motivo: plano.motivo,
@@ -1281,32 +1352,27 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1281
1352
  : `politica de retry do bloco B3 (bloco sem pausa no modo ${thread.modo})`,
1282
1353
  ok,
1283
1354
  detalhe,
1355
+ ...extra,
1284
1356
  });
1285
1357
  };
1286
1358
  // I-36 (T6): conducao em andamento nao e fila de rate limit. Nada e redespachado; o registro diz
1287
1359
  // quem conduz, e a vez chega quando essa conducao terminar.
1288
1360
  if (plano.motivo === 'conducao.em-andamento') {
1289
1361
  const atual = (0, conducao_1.conducaoDaThread)(raiz, threadId);
1290
- const detalhe = atual
1291
- ? `${(0, conducao_texto_1.linhaDeConducao)(atual)}; nada foi redespachado, a vez chega quando essa conducao terminar`
1292
- : 'ninguem conduz a thread agora: o proximo pedido segue normalmente';
1362
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => atual ? m.retry.conduzidaAgora((0, conducao_texto_1.linhaDeConducao)(atual)) : m.retry.ninguemConduz);
1293
1363
  registrarTentativa(!atual, detalhe);
1294
1364
  return { ...vazio, executada: false, detalhe };
1295
1365
  }
1296
1366
  // `esperar-janela`: quem retoma e a fila, e ela ja esta gravada em disco.
1297
1367
  if (acaoBase === 'esperar-janela') {
1298
1368
  const fila = (0, ratelimit_1.lerFilaDeRetomada)(raiz).filter((p) => p.thread === threadId && p.estado === 'aguardando');
1299
- const detalhe = fila.length > 0
1300
- ? `${fila.length} pedido(s) na fila duravel; o proximo libera em ${fila[0].liberaEm}`
1301
- : 'nenhum pedido aguardando na fila para esta thread';
1369
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => fila.length > 0 ? m.retry.naFila(fila.length, fila[0].liberaEm) : m.retry.filaVazia);
1302
1370
  registrarTentativa(fila.length > 0, detalhe);
1303
1371
  return { ...vazio, executada: fila.length > 0, fila, detalhe };
1304
1372
  }
1305
1373
  if (acaoBase === 'sincronizar-worktree') {
1306
1374
  const sync = (0, worktree_1.sincronizarWorktree)(carregado, threadId, { dryRun: opcoes.dryRun });
1307
- const detalhe = sync.ok
1308
- ? `worktree sincronizada com a base (${sync.passos.join('; ')})`
1309
- : `sincronizacao nao concluiu: ${sync.detalhe}`;
1375
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => sync.ok ? m.retry.sincronizada(sync.passos.join('; ')) : m.retry.sincronizacaoFalhou(sync.detalhe));
1310
1376
  registrarTentativa(sync.ok, detalhe);
1311
1377
  return { ...vazio, executada: sync.ok, sync, detalhe };
1312
1378
  }
@@ -1315,10 +1381,8 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1315
1381
  const reverify = opcoes.reverify && rodada.correcoes.length > 0
1316
1382
  ? (0, fix_1.reverificar)(carregado, threadId, { rodada: rodada.rodada })
1317
1383
  : null;
1318
- const detalhe = rodada.correcoes.length === 0
1319
- ? 'o CHECK passou no HEAD real: nao ha correcao a dirigir'
1320
- : `${rodada.correcoes.length} correcao(oes) na rodada ${rodada.rodada}` +
1321
- (reverify ? `; CHECK-REVERIFY: ${reverify.veredito}` : '');
1384
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => rodada.correcoes.length === 0 ? m.retry.checkPassou
1385
+ : m.retry.correcoesNaRodada(rodada.correcoes.length, rodada.rodada, reverify ? m.retry.vereditos[reverify.veredito] ?? reverify.veredito : null));
1322
1386
  registrarTentativa(rodada.correcoes.length > 0, detalhe);
1323
1387
  return { ...vazio, executada: rodada.correcoes.length > 0, rodada, reverify, detalhe };
1324
1388
  }
@@ -1328,11 +1392,14 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1328
1392
  if (plano.motivo === 'runtime.model-unavailable') {
1329
1393
  return trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registrarTentativa);
1330
1394
  }
1331
- // `reexecutar` e `escalar-esforco`: o MESMO prompt volta ao runtime.
1332
- const falho = ultimoDespachoFalho(raiz, threadId, plano.fase, plano.motivo === 'runtime.silencio');
1395
+ // `reexecutar` e `escalar-esforco`: o MESMO prompt volta ao runtime. RM-063 (F3): o gate que o plano leu diz de que
1396
+ // despacho e o prompt; sem ele, a tentativa mais recente da fase com prompt gravado.
1397
+ const reprovacao = ultimaReprovacao(raiz, threadId);
1398
+ const gateDoPlano = reprovacao && reprovacao.motivo === plano.motivo && faseDoEvento(reprovacao, thread) === plano.fase
1399
+ ? reprovacao : null;
1400
+ const falho = despachoParaRedespachar((0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)), plano.fase, gateDoPlano, plano.motivo === 'runtime.silencio');
1333
1401
  if (!falho || typeof falho.promptPath !== 'string' || typeof falho.promptSha256 !== 'string') {
1334
- const detalhe = `nao ha despacho falho registrado em ${plano.fase} com prompt gravado: ` +
1335
- `rode a fase de novo com \`ork phase run ${threadId} ${plano.fase} --prompt "..."\``;
1402
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => m.retry.semDespachoFalho(plano.fase, threadId));
1336
1403
  registrarTentativa(false, detalhe);
1337
1404
  return { ...vazio, detalhe };
1338
1405
  }
@@ -1343,11 +1410,23 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1343
1410
  const resolvido = (0, impedimento_1.impedimentoResolvido)(plano.motivo, { cwd: falho.cwd,
1344
1411
  runtime: typeof falho.runtime === 'string' ? falho.runtime : '', configDir: perfilFalho?.configDir ?? null });
1345
1412
  if (resolvido === false) {
1346
- const detalhe = `${plano.motivo}: o runtime ainda nao confia em ${falho.cwd}; nada foi despachado. ` +
1347
- `Rode \`cd ${falho.cwd} && claude\`, aceite a confianca e repita \`ork retry run ${threadId}\``;
1413
+ const motivo = plano.motivo, cwd = falho.cwd;
1414
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => m.retry.semConfianca(motivo, cwd, threadId));
1348
1415
  return { ...vazio, detalhe };
1349
1416
  }
1350
1417
  }
1418
+ // RM-063 (F3, GO-FIX): antes de devolver o prompt ao runtime, a prova de que nenhuma sessao viva trabalha na thread. O
1419
+ // despacho que falhou depois de abrir a sessao (o `claude --bg` lento) e o adaptador que lanca deixariam duas sessoes
1420
+ // na mesma worktree. Sem a prova, nada e redespachado, e a tentativa nao conta.
1421
+ const ids = [falho.sessionId, gateDoPlano?.sessionId].filter((x) => typeof x === 'string' && !!x);
1422
+ const viva = (0, vida_da_thread_1.sessaoVivaNaThread)(raiz, thread, ids);
1423
+ if (!viva.respondeu || viva.sessionId) {
1424
+ const { sessionId: sessao, detalhe: falhaDaConsulta } = viva;
1425
+ const detalhe = sessao ? (0, locale_1.textoDoCatalogo)((m) => m.retry.sessaoAindaViva(sessao.slice(0, 8), threadId))
1426
+ : (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeSemProva(falhaDaConsulta ?? '', threadId));
1427
+ registrarTentativa(false, detalhe, { conta: false });
1428
+ return { ...vazio, detalhe };
1429
+ }
1351
1430
  const redespacho = redespachar(carregado, thread, plano.fase, falho.promptPath, falho.promptSha256, {
1352
1431
  effort: plano.effort,
1353
1432
  runtime: typeof falho.runtime === 'string' ? falho.runtime : null,
@@ -1355,7 +1434,11 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1355
1434
  origem: 'retry.run',
1356
1435
  dryRun: opcoes.dryRun,
1357
1436
  });
1358
- registrarTentativa(redespacho.ok, redespacho.detalhe);
1437
+ // RM-055 (continuacao, D2): o runtime recusou o redespacho por um motivo que so o dono resolve. Nada rodou
1438
+ // e a espera do dono voltou com o mesmo comando: a recusa fica no ledger, mas nao gasta tentativa nem sobe
1439
+ // esforco. Contada, a quarta chamada escalava e o retry nunca mais re-despachava, nem depois do aceite.
1440
+ const recusaDoDono = !redespacho.ok && (0, impedimento_1.ehImpedimentoDoDono)(redespacho.motivo);
1441
+ registrarTentativa(redespacho.ok, redespacho.detalhe, recusaDoDono ? { conta: false } : {});
1359
1442
  return {
1360
1443
  ...vazio,
1361
1444
  executada: redespacho.ok,
@@ -1388,7 +1471,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1388
1471
  return { ...vazio, detalhe: diagnostico };
1389
1472
  };
1390
1473
  if (!despacho || typeof despacho.promptPath !== 'string' || typeof despacho.promptSha256 !== 'string') {
1391
- const detalhe = `nao ha despacho com prompt gravado para ${motivo} em ${fase}: rode a fase de novo com ork phase run`;
1474
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => m.retry.semDespachoComPrompt(motivo, fase));
1392
1475
  registrarTentativa(false, detalhe);
1393
1476
  return { ...vazio, detalhe };
1394
1477
  }
@@ -1400,14 +1483,14 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1400
1483
  : perfilDoEvento(despacho);
1401
1484
  }
1402
1485
  catch (e) {
1403
- return escalar('perfil registrado invalido', `rotacao recusada: ${e.message}`);
1486
+ const erro = e.message;
1487
+ return escalar('perfil registrado invalido', (0, locale_1.textoDoCatalogo)((m) => m.retry.rotacaoRecusada(erro)));
1404
1488
  }
1405
1489
  // D11 (c): sessao que morreu por cota depois de produzir nao e redespachada.
1406
1490
  if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
1407
1491
  const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
1408
1492
  if (producao.produziu) {
1409
- return escalar('producao parcial sob falha da conta', `producao parcial sob ${motivo === 'runtime.quota-exhausted' ? 'cota esgotada' : 'auth ausente'}: ${producao.evidencia}; ` +
1410
- 'a sessao nao e redespachada sobre a worktree alterada e a fase nao conclui sem o humano');
1493
+ return escalar('producao parcial sob falha da conta', (0, locale_1.textoDoCatalogo)((m) => m.retry.producaoParcialConta(motivo === 'runtime.quota-exhausted', String(producao.evidencia))));
1411
1494
  }
1412
1495
  }
1413
1496
  const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, fase);
@@ -1465,8 +1548,8 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1465
1548
  if (ultimo.falhaDeConta?.motivo !== 'runtime.model-unavailable')
1466
1549
  falhaAtual = ultimo.falhaDeConta ?? falhaAtual;
1467
1550
  if (tentativas >= plano.limite) {
1468
- return escalar('limite de tentativas na rotacao', `${tentativas} tentativa(s) de rotacao por ${motivo} em ${fase}, no limite de ` +
1469
- `${plano.limite} do manifesto: escalacao tipada pausa qualquer modo`);
1551
+ const feitas = tentativas;
1552
+ return escalar('limite de tentativas na rotacao', (0, locale_1.textoDoCatalogo)((m) => m.retry.limiteDaRotacao(feitas, motivo, fase, plano.limite)));
1470
1553
  }
1471
1554
  }
1472
1555
  // Sem destino: a fila so faz sentido quando algum perfil tem prazo para voltar. Sem perfil (ambiente do
@@ -1476,13 +1559,12 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1476
1559
  const prazo = (0, runtime_profiles_1.prazoDaFila)((0, runtime_profiles_1.lerPerfisComContas)(raiz), runtimes, politica) ?? dito;
1477
1560
  if (!prazo && falhaAtual.motivo === 'runtime.auth-missing') {
1478
1561
  emitir(null, 'nenhum perfil com login em nenhum runtime da ordem de fallback');
1479
- return escalar('auth ausente sem alternativa', 'nenhum perfil com login conferido em nenhum runtime da ordem de fallback: ' +
1480
- 'refaca o login com ork accounts add ou ork accounts check antes de retomar');
1562
+ return escalar('auth ausente sem alternativa', (0, locale_1.textoDoCatalogo)((m) => m.retry.semLogin));
1481
1563
  }
1482
1564
  const liberaEm = prazo ?? new Date(Date.now() + (0, ratelimit_1.janelaPadraoMs)(manifesto)).toISOString();
1483
1565
  emitir(null, `nenhum perfil ativo em ${runtimes.join(', ')}: fila duravel ate ${liberaEm}`);
1484
1566
  if (opcoes.dryRun)
1485
- return { ...vazio, detalhe: `ensaio: entraria na fila duravel ate ${liberaEm}` };
1567
+ return { ...vazio, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.entrariaNaFila(liberaEm)) };
1486
1568
  const pedido = (0, ratelimit_1.enfileirar)(carregado, { thread: thread.id, fase, slug: typeof despacho.slug === 'string' ? despacho.slug : (0, phase_1.slugDaSessao)(thread, fase),
1487
1569
  promptPath: despacho.promptPath, promptSha256: despacho.promptSha256,
1488
1570
  cwd: typeof despacho.cwd === 'string' ? despacho.cwd : thread.worktree ?? raiz,
@@ -1493,7 +1575,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1493
1575
  janelaEstimada: pedido.janelaEstimada, motivo: falhaAtual.motivo, promptSha256: despacho.promptSha256,
1494
1576
  correcao: `ork retry resume (ou aguarde ate ${pedido.liberaEm})` });
1495
1577
  registrarTentativa(true, `fila duravel: pedido ${pedido.id} libera em ${pedido.liberaEm}`);
1496
- return { ...vazio, executada: true, fila: [pedido], redespacho: ultimo, detalhe: `pedido ${pedido.id} na fila ate ${pedido.liberaEm}` };
1578
+ return { ...vazio, executada: true, fila: [pedido], redespacho: ultimo, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.pedidoAte(pedido.id, pedido.liberaEm)) };
1497
1579
  }
1498
1580
  /** RM-037 (defeitosdeco D-6): chave de um destino (runtime, perfil, modelo) que recusou o modelo. */
1499
1581
  function chaveDoModelo(runtime, perfil, model) {
@@ -1561,10 +1643,10 @@ function proximoDestinoDoModelo(raiz, runtime, model, fallback, recusados) {
1561
1643
  return null;
1562
1644
  }
1563
1645
  /** D-6: a correcao exata quando nenhum destino tem o modelo: o bloco do setup que conduz a fase. */
1564
- function correcaoDoModelo(thread, fase) {
1646
+ function correcaoDoModelo(thread, fase, m = (0, locale_1.msg)()) {
1565
1647
  const indice = modos_1.MODOS[thread.modo]?.blocos.findIndex(b => b.fases.includes(fase)) ?? -1;
1566
1648
  const bloco = indice >= 0 ? String(indice + 1) : 'N';
1567
- return `ork setup ${thread.modo} --bloco ${bloco} --model <modelo acessivel>, ou declare no mesmo bloco --fallback runtime:modelo`;
1649
+ return m.retry.correcaoDoModelo(thread.modo, bloco);
1568
1650
  }
1569
1651
  /**
1570
1652
  * RM-037 (defeitosdeco D-6): troca de destino depois de `runtime.model-unavailable`. O modelo pedido nao
@@ -1591,13 +1673,12 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1591
1673
  return { ...vazio, detalhe: diagnostico };
1592
1674
  };
1593
1675
  if (!despacho || typeof despacho.promptPath !== 'string' || typeof despacho.promptSha256 !== 'string') {
1594
- const detalhe = `nao ha despacho com prompt gravado para ${motivo} em ${fase}: rode a fase de novo com ork phase run`;
1676
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => m.retry.semDespachoComPrompt(motivo, fase));
1595
1677
  registrarTentativa(false, detalhe);
1596
1678
  return { ...vazio, detalhe };
1597
1679
  }
1598
1680
  const runtime = typeof despacho.runtime === 'string' ? despacho.runtime : manifesto.runtime.adapter;
1599
1681
  const model = typeof despacho.model === 'string' ? despacho.model : null;
1600
- const rotulo = model ?? '(padrao do runtime)';
1601
1682
  let perfil;
1602
1683
  try {
1603
1684
  perfil = typeof gate?.sessionId === 'string'
@@ -1605,13 +1686,13 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1605
1686
  : perfilDoEvento(despacho);
1606
1687
  }
1607
1688
  catch (e) {
1608
- return escalar('perfil registrado invalido', `troca de destino recusada: ${e.message}`);
1689
+ const erro = e.message;
1690
+ return escalar('perfil registrado invalido', (0, locale_1.textoDoCatalogo)((m) => m.retry.trocaRecusada(erro)));
1609
1691
  }
1610
1692
  if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
1611
1693
  const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
1612
1694
  if (producao.produziu) {
1613
- return escalar('producao parcial com modelo inacessivel', `producao parcial com o modelo ${rotulo} inacessivel: ${producao.evidencia}; ` +
1614
- 'a sessao nao e redespachada sobre a worktree alterada e a fase nao conclui sem o humano');
1695
+ return escalar('producao parcial com modelo inacessivel', (0, locale_1.textoDoCatalogo)((m) => m.retry.producaoParcialModelo(model ?? m.retry.padraoDoRuntime, String(producao.evidencia))));
1615
1696
  }
1616
1697
  }
1617
1698
  const recusados = new Set([...destinosQueRecusaramOModelo(eventos, fase), chaveDoModelo(runtime, perfil?.id ?? null, model)]);
@@ -1637,8 +1718,7 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1637
1718
  origem: 'retry.modelo', dryRun: opcoes.dryRun,
1638
1719
  });
1639
1720
  if (opcoes.dryRun)
1640
- return { ...vazio, redespacho: r, detalhe: `ensaio: o mesmo prompt iria a ${alvo.runtime}` +
1641
- `${alvo.perfil ? ` (perfil ${alvo.perfil.id})` : ''} com o modelo ${alvo.model ?? '(padrao do runtime)'}; ${r.detalhe}` };
1721
+ return { ...vazio, redespacho: r, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.ensaioDoModelo(alvo.runtime, alvo.perfil ? alvo.perfil.id : null, alvo.model ?? m.retry.padraoDoRuntime, (0, locale_1.remontar)(r.detalhe))) };
1642
1722
  registrarTentativa(r.ok, r.detalhe);
1643
1723
  tentativas += 1;
1644
1724
  if (r.ok)
@@ -1649,58 +1729,62 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1649
1729
  recusados.add(chaveDoModelo(alvo.runtime, alvo.perfil?.id ?? null, alvo.model));
1650
1730
  atual = { runtime: alvo.runtime, perfil: alvo.perfil, model: alvo.model };
1651
1731
  if (tentativas >= plano.limite) {
1652
- return escalar('limite de tentativas na troca de modelo', `${tentativas} tentativa(s) de troca por ${motivo} em ${fase}, no limite de ` +
1653
- `${plano.limite} do manifesto: escalacao tipada pausa qualquer modo`);
1732
+ const feitas = tentativas;
1733
+ return escalar('limite de tentativas na troca de modelo', (0, locale_1.textoDoCatalogo)((m) => m.retry.limiteDaTroca(feitas, motivo, fase, plano.limite)));
1654
1734
  }
1655
1735
  }
1656
1736
  const tentados = [...recusados].map(k => { const [rt, p, m] = k.split('|'); return `${rt}${p ? `/${p}` : ''}:${m || '(padrao)'}`; });
1657
- return escalar('modelo inacessivel sem outro destino', `o modelo ${rotulo} nao esta acessivel em ${tentados.join(', ')} e o bloco ` +
1658
- `nao tem outro destino: ${correcaoDoModelo(thread, fase)}`);
1737
+ return escalar('modelo inacessivel sem outro destino', (0, locale_1.textoDoCatalogo)((m) => m.retry.modeloSemDestino(model ?? m.retry.padraoDoRuntime, tentados.join(', '), correcaoDoModelo(thread, fase, m))));
1659
1738
  }
1660
1739
  /** Texto de `ork retry plan`. */
1661
1740
  function textoDoPlano(p) {
1741
+ // RM-061 (F2b, G2): a razao e o detalhe que este processo montou saem remontados no locale; o detalhe lido
1742
+ // do ledger (gravado por outro processo) e a politica pelo motivo saem como o catalogo os traz.
1743
+ const m = (0, locale_1.msg)().retry;
1662
1744
  const linhas = [];
1663
- linhas.push(`Plano de retry da thread ${p.thread}`);
1664
- linhas.push(` modo ${p.modo}`);
1665
- linhas.push(` fase ${p.fase ?? '(nenhuma)'}`);
1666
- linhas.push(` motivo tipado ${p.motivo ?? '(nenhuma reprovacao pendente)'}`);
1745
+ linhas.push(m.titulo(p.thread));
1746
+ linhas.push(m.modo(p.modo));
1747
+ linhas.push(m.fase(p.fase));
1748
+ linhas.push(m.motivo(p.motivo));
1749
+ const detalhe = (0, locale_1.remontar)(p.detalhe);
1667
1750
  if (p.detalhe)
1668
- linhas.push(` detalhe ${(0, horario_1.localizarTexto)(p.detalhe)}`);
1669
- linhas.push(` acao ${p.acao}`);
1670
- linhas.push(` tentativas ${p.tentativas} de ${p.limite} antes da escalacao`);
1671
- linhas.push(` esforco ${p.effort}${p.effort !== p.effortAnterior ? ` (escalado de ${p.effortAnterior})` : ''}`);
1672
- linhas.push(` automatica ${p.automatica ? 'sim' : 'nao'}`);
1751
+ linhas.push(m.detalhe((0, horario_1.localizarTexto)(detalhe)));
1752
+ linhas.push(m.acao(p.acao));
1753
+ linhas.push(m.tentativas(p.tentativas, p.limite));
1754
+ linhas.push(m.esforco(p.effort, p.effort !== p.effortAnterior ? p.effortAnterior : null));
1755
+ linhas.push(m.automatica(p.automatica));
1673
1756
  if (p.bloqueio)
1674
- linhas.push(` bloqueio ${p.bloqueio}`);
1675
- linhas.push(` razao ${p.razao}`);
1757
+ linhas.push(m.bloqueio(p.bloqueio));
1758
+ linhas.push(m.razao((0, locale_1.remontar)(p.razao)));
1676
1759
  if (p.politica && !p.automatica)
1677
- linhas.push(` correcao ${p.politica.correcao}`);
1678
- if (p.detalhe && (0, horario_1.localizarTexto)(p.detalhe) !== p.detalhe)
1760
+ linhas.push(m.correcao(p.motivo ? m.politica[p.motivo].correcao : p.politica.correcao));
1761
+ if (p.detalhe && (0, horario_1.localizarTexto)(detalhe) !== detalhe)
1679
1762
  linhas.push((0, horario_1.legendaDoFuso)());
1680
1763
  return linhas.join('\n');
1681
1764
  }
1682
1765
  /** Texto de `ork retry run`. */
1683
1766
  function textoDoRetry(r) {
1767
+ const m = (0, locale_1.msg)().retry;
1684
1768
  const plano = textoDoPlano(r.plano);
1685
1769
  const linhas = [plano, ''];
1686
- linhas.push(`Execucao: ${r.executada ? 'acao executada' : 'nada executado'}`);
1687
- linhas.push(` ${(0, horario_1.localizarTexto)(r.detalhe)}`);
1770
+ const detalhe = (0, locale_1.remontar)(r.detalhe);
1771
+ linhas.push(m.execucao(r.executada));
1772
+ linhas.push(m.linhaDoDetalhe((0, horario_1.localizarTexto)(detalhe)));
1688
1773
  if (r.rodada && r.rodada.correcoes.length > 0) {
1689
1774
  linhas.push('');
1690
- linhas.push(`GO-FIX rodada ${r.rodada.rodada}: ` +
1691
- r.rodada.correcoes.map((c) => `${c.id} (tipo ${c.tipo}, ${c.origem})`).join(', '));
1775
+ linhas.push(m.rodada(r.rodada.rodada, r.rodada.correcoes.map((c) => m.correcaoDaRodada(c.id, c.tipo, c.origem)).join(', ')));
1692
1776
  }
1693
1777
  if (r.reverify) {
1694
- linhas.push(`CHECK-REVERIFY: ${r.reverify.veredito} (cobertura ${r.reverify.cobertura})`);
1778
+ linhas.push(m.reverify(m.vereditos[r.reverify.veredito] ?? r.reverify.veredito, m.coberturas[r.reverify.cobertura] ?? r.reverify.cobertura));
1695
1779
  }
1696
1780
  if (r.fila.length > 0) {
1697
1781
  linhas.push('');
1698
- linhas.push('Fila de rate limit desta thread:');
1782
+ linhas.push(m.fila);
1699
1783
  for (const p of r.fila) {
1700
- linhas.push(` ${p.id} ${p.fase} libera em ${(0, horario_1.formatarDataHora)(p.liberaEm)}${p.janelaEstimada ? ' (janela estimada)' : ''}`);
1784
+ linhas.push(m.pedidoNaFila(p.id, p.fase, (0, horario_1.formatarDataHora)(p.liberaEm), p.janelaEstimada));
1701
1785
  }
1702
1786
  }
1703
- if ((r.fila.length > 0 || (0, horario_1.localizarTexto)(r.detalhe) !== r.detalhe) && !plano.includes((0, horario_1.legendaDoFuso)())) {
1787
+ if ((r.fila.length > 0 || (0, horario_1.localizarTexto)(detalhe) !== detalhe) && !plano.includes((0, horario_1.legendaDoFuso)())) {
1704
1788
  linhas.push((0, horario_1.legendaDoFuso)());
1705
1789
  }
1706
1790
  return linhas.join('\n');