@orkastery/cli 0.5.1 → 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 (260) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/agents/ork-master.md +2 -0
  3. package/adapters/claude-code/commands/master.md +8 -0
  4. package/adapters/claude-code/commands/ork.md +9 -0
  5. package/adapters/claude-code/mods/autoridade.json +56 -0
  6. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  8. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  9. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  10. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  11. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  12. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  13. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  16. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  17. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  18. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  19. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  20. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  21. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  25. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  27. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  28. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  29. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  30. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  33. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  34. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  35. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  36. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  37. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  38. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  44. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  45. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  46. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  47. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  48. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  49. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  52. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  53. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  54. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  55. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  56. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  57. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  59. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  60. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  61. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  62. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  63. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  64. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  67. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  68. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  69. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  70. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  71. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  72. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  77. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  78. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  79. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  80. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  81. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  82. package/adapters/codex/skills/ork/SKILL.md +18 -3
  83. package/adapters/hermes/README.md +1 -0
  84. package/adapters/hermes/bin/ork-network-status.sh +10 -0
  85. package/adapters/hermes/hermes.plugin.json +1 -0
  86. package/adapters/hermes/hitl-ingress/__init__.py +2 -2
  87. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +7 -6
  88. package/adapters/openclaw/README.md +26 -5
  89. package/adapters/openclaw/dist/hitl-ingress.js +2 -2
  90. package/adapters/openclaw/dist/index.js +46 -11
  91. package/adapters/openclaw/openclaw.plugin.json +5 -1
  92. package/adapters/openclaw/package.json +2 -2
  93. package/adapters/openclaw/src/hitl-ingress.ts +2 -2
  94. package/adapters/openclaw/src/index.ts +49 -11
  95. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  96. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  97. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  98. package/assets/docs-en/produto/README.md +14 -0
  99. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  100. package/assets/docs-en/roadmap/README.md +14 -0
  101. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  102. package/assets/orkmind_bridge.py +117 -9
  103. package/dist/adapters/claude-bg.js +116 -18
  104. package/dist/adapters/codex.js +14 -4
  105. package/dist/agents-md.js +24 -14
  106. package/dist/auditrun.js +22 -3
  107. package/dist/board.js +20 -17
  108. package/dist/branch-de-estado.js +88 -10
  109. package/dist/busca-semantica.js +52 -12
  110. package/dist/canarios-rm057.js +149 -0
  111. package/dist/canarios.js +2 -0
  112. package/dist/catalogo.js +33 -0
  113. package/dist/ci.js +21 -8
  114. package/dist/claims-conferir.js +342 -0
  115. package/dist/claims.js +41 -1
  116. package/dist/company-brain-client.js +36 -1
  117. package/dist/company-brain-context.js +158 -22
  118. package/dist/company-brain-journal.js +2 -1
  119. package/dist/company-brain-migration.js +36 -1
  120. package/dist/conducao-sentinela.js +388 -0
  121. package/dist/conducao-texto.js +12 -18
  122. package/dist/conducao.js +122 -30
  123. package/dist/conhecimento.js +490 -0
  124. package/dist/docs.js +70 -17
  125. package/dist/doctor-pulse-cron.js +349 -0
  126. package/dist/doctor-rede.js +150 -0
  127. package/dist/doctor.js +195 -111
  128. package/dist/entrega-pr.js +42 -29
  129. package/dist/escopo-escrita.js +10 -1
  130. package/dist/esgotamentos.js +181 -0
  131. package/dist/estado-thread.js +23 -1
  132. package/dist/experiencia-instalacao.js +45 -25
  133. package/dist/experiencia.js +12 -2
  134. package/dist/fabrica-batida.js +310 -0
  135. package/dist/fabrica-estado.js +52 -14
  136. package/dist/fabrica-publicar.js +9 -1
  137. package/dist/fechamento.js +20 -66
  138. package/dist/fila-pesada.js +444 -0
  139. package/dist/fix.js +3 -2
  140. package/dist/forja.js +31 -7
  141. package/dist/gates.js +3 -24
  142. package/dist/handoff.js +10 -6
  143. package/dist/hitl-contract.js +59 -4
  144. package/dist/hitl-curto.js +11 -6
  145. package/dist/hitl-gates.js +5 -0
  146. package/dist/hitl-local-receipt.js +2 -0
  147. package/dist/hitl-lote.js +5 -2
  148. package/dist/hitl-resumo.js +38 -3
  149. package/dist/hitl-tempo-parado.js +201 -0
  150. package/dist/hitl-texto-livre.js +5 -5
  151. package/dist/hitl.js +29 -33
  152. package/dist/horario.js +41 -7
  153. package/dist/hosts.js +104 -11
  154. package/dist/impedimento.js +299 -0
  155. package/dist/index.js +961 -542
  156. package/dist/indice-vetorial.js +87 -10
  157. package/dist/indice.js +9 -1
  158. package/dist/init.js +56 -43
  159. package/dist/instabilidade.js +144 -0
  160. package/dist/integracoes-locais.js +4 -0
  161. package/dist/intelligence-graph-cli.js +170 -16
  162. package/dist/intelligence-graph-contexto.js +254 -0
  163. package/dist/intelligence-graph-contract.js +2 -1
  164. package/dist/intelligence-graph-extract-md.js +56 -4
  165. package/dist/intelligence-graph-extract-ts.js +71 -3
  166. package/dist/intelligence-graph-parsers.js +6 -4
  167. package/dist/intelligence-graph-query.js +66 -19
  168. package/dist/leases.js +664 -87
  169. package/dist/ledger-stats.js +15 -1
  170. package/dist/ledger.js +18 -1
  171. package/dist/licoes.js +1 -0
  172. package/dist/liveness.js +6 -3
  173. package/dist/locale-ajuda.js +761 -0
  174. package/dist/locale-gerados.js +160 -0
  175. package/dist/locale-master.js +99 -0
  176. package/dist/locale-onboarding.js +92 -0
  177. package/dist/locale-phase.js +151 -0
  178. package/dist/locale-pulse.js +211 -0
  179. package/dist/locale-retry.js +385 -0
  180. package/dist/locale-roadmap.js +102 -0
  181. package/dist/locale-ship.js +494 -0
  182. package/dist/locale-thread.js +277 -0
  183. package/dist/locale-verify.js +125 -0
  184. package/dist/locale.js +714 -0
  185. package/dist/maestro-runtime.js +4 -1
  186. package/dist/manifest.js +149 -4
  187. package/dist/maquina.js +23 -4
  188. package/dist/master-digest.js +6 -1
  189. package/dist/master-nota.js +18 -11
  190. package/dist/master.js +145 -31
  191. package/dist/mcp-artifacts.js +43 -3
  192. package/dist/mcp-git.js +42 -8
  193. package/dist/mcp-grafo-worker.js +5 -3
  194. package/dist/mcp-grafo.js +55 -6
  195. package/dist/mcp-server.js +22 -3
  196. package/dist/mcp-ship.js +3 -1
  197. package/dist/mcp-verify.js +6 -1
  198. package/dist/memoria.js +48 -6
  199. package/dist/modos.js +3 -6
  200. package/dist/network-roadmap.js +196 -18
  201. package/dist/noctum-arco.js +911 -0
  202. package/dist/noctum-capacidade.js +141 -0
  203. package/dist/noctum-envelope.js +810 -0
  204. package/dist/noctum-execucao.js +304 -0
  205. package/dist/noctum-fila.js +280 -0
  206. package/dist/ocupacao.js +40 -5
  207. package/dist/onboarding.js +40 -21
  208. package/dist/orkmind.js +99 -7
  209. package/dist/orquestracao.js +24 -21
  210. package/dist/parado-no-condutor.js +219 -38
  211. package/dist/phase.js +160 -52
  212. package/dist/policies.js +56 -5
  213. package/dist/portfolio.js +8 -3
  214. package/dist/postura-local.js +234 -0
  215. package/dist/preflight.js +11 -10
  216. package/dist/procedencia.js +225 -0
  217. package/dist/projeto-alvo.js +132 -5
  218. package/dist/prompts.js +40 -1
  219. package/dist/prova-ativacao.js +75 -6
  220. package/dist/pulse-delivery.js +47 -4
  221. package/dist/pulse.js +98 -19
  222. package/dist/ratelimit.js +24 -6
  223. package/dist/recall.js +3 -1
  224. package/dist/redacao-saida.js +63 -0
  225. package/dist/rede-adesao.js +399 -0
  226. package/dist/rede-forja.js +289 -0
  227. package/dist/rede-projetos.js +239 -0
  228. package/dist/rede-status.js +337 -0
  229. package/dist/rede.js +980 -0
  230. package/dist/retry.js +291 -140
  231. package/dist/roadmap-reservas.js +20 -3
  232. package/dist/roadmap-status.js +150 -34
  233. package/dist/runtime-context.js +181 -3
  234. package/dist/runtime-profiles.js +22 -1
  235. package/dist/runtimes.js +2 -1
  236. package/dist/saida-segura.js +58 -0
  237. package/dist/session-events.js +7 -3
  238. package/dist/session-watcher-claude.js +120 -24
  239. package/dist/session-watcher.js +185 -33
  240. package/dist/sessoes-contas.js +187 -0
  241. package/dist/sessoes-inventario.js +6 -18
  242. package/dist/sessoes.js +83 -2
  243. package/dist/ship-publicar.js +800 -0
  244. package/dist/ship.js +157 -88
  245. package/dist/steal.js +77 -0
  246. package/dist/thread-close.js +3 -2
  247. package/dist/thread.js +299 -49
  248. package/dist/util.js +8 -1
  249. package/dist/verify.js +141 -52
  250. package/dist/vida-da-thread.js +254 -0
  251. package/dist/worktree-local.js +165 -0
  252. package/dist/worktree.js +25 -2
  253. package/dist/yaml.js +27 -8
  254. package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
  255. package/package.json +7 -3
  256. package/references/definition-of-done.md +1 -1
  257. package/schemas/code-artifact-graph.v1.schema.json +2 -1
  258. package/skills/README.md +1 -1
  259. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  260. package/skills/phases/master-metrics/SKILL.md +8 -3
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");
@@ -97,12 +101,19 @@ const modos_1 = require("./modos");
97
101
  const thread_1 = require("./thread");
98
102
  const tokens_1 = require("./tokens");
99
103
  const util_1 = require("./util");
104
+ const impedimento_1 = require("./impedimento");
100
105
  const worktree_1 = require("./worktree");
101
106
  const delegation_1 = require("./delegation");
102
107
  const gates_2 = require("./gates");
103
108
  const horario_1 = require("./horario");
104
109
  const conducao_1 = require("./conducao");
105
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;
106
117
  /**
107
118
  * Escada de esforco da 2a tentativa em diante.
108
119
  *
@@ -128,29 +139,25 @@ exports.POLITICA_DE_RETRY = {
128
139
  motivo: 'artifact.missing',
129
140
  acao: 'corrigir-dirigido',
130
141
  automatica: true,
131
- porque: 'o artefato exigido pela fase nao existe: a fase precisa de spec dirigida do que gravar, nao de repeticao cega do mesmo prompt',
132
- correcao: 'ork fix open <thread> abre a rodada com a spec exata',
142
+ ...TEXTOS_DA_POLITICA['artifact.missing'],
133
143
  },
134
144
  'claims.failed': {
135
145
  motivo: 'claims.failed',
136
146
  acao: 'corrigir-dirigido',
137
147
  automatica: true,
138
- 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',
139
- correcao: 'ork fix open <thread> e depois ork fix reverify <thread>',
148
+ ...TEXTOS_DA_POLITICA['claims.failed'],
140
149
  },
141
150
  'claims.unverifiable': {
142
151
  motivo: 'claims.unverifiable',
143
152
  acao: 'corrigir-dirigido',
144
153
  automatica: true,
145
- 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',
146
- correcao: 'ork claims verificar <thread> <claim> --comando "<comando>"',
154
+ ...TEXTOS_DA_POLITICA['claims.unverifiable'],
147
155
  },
148
156
  'policy.violation': {
149
157
  motivo: 'policy.violation',
150
158
  acao: 'escalar-humano',
151
159
  automatica: false,
152
- porque: 'policy com severidade block reprova em qualquer modo: reexecutar sozinho seria a maquina revogando a policy do manifesto',
153
- correcao: 'corrija a violacao no pedido/manifesto; policy block nao se resolve por repeticao',
160
+ ...TEXTOS_DA_POLITICA['policy.violation'],
154
161
  },
155
162
  'runtime.autoconferencia': {
156
163
  motivo: 'runtime.autoconferencia',
@@ -160,69 +167,66 @@ exports.POLITICA_DE_RETRY = {
160
167
  // decide em que runtime o CHECK roda e quem conduz a thread.
161
168
  acao: 'escalar-humano',
162
169
  automatica: false,
163
- 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',
164
- 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'],
171
+ },
172
+ // RM-056 (D1): o perfil pedido nao existe ou e de outro runtime. Quem corrige e quem pediu.
173
+ 'runtime.profile-invalid': {
174
+ motivo: 'runtime.profile-invalid',
175
+ acao: 'escalar-humano',
176
+ automatica: false,
177
+ ...TEXTOS_DA_POLITICA['runtime.profile-invalid'],
165
178
  },
166
179
  'cost.violation': {
167
180
  motivo: 'cost.violation',
168
181
  acao: 'sem-retry',
169
182
  automatica: false,
170
- porque: 'violacao de CUSTO nunca recebe retry automatico: cada reexecucao gastaria de novo pelo provider pago (subscription-only e regra de codigo, nao lembrete)',
171
- 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'],
172
184
  },
173
185
  'verify.regression': {
174
186
  motivo: 'verify.regression',
175
187
  acao: 'corrigir-dirigido',
176
188
  automatica: true,
177
- 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',
178
- correcao: 'ork fix open <thread> (a reexecucao seguinte e completa)',
189
+ ...TEXTOS_DA_POLITICA['verify.regression'],
179
190
  },
180
191
  'verify.failed': {
181
192
  motivo: 'verify.failed',
182
193
  acao: 'corrigir-dirigido',
183
194
  automatica: true,
184
- 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',
185
- correcao: 'ork fix open <thread>, ou ork verify <thread> --baseline antes do proximo GO',
195
+ ...TEXTOS_DA_POLITICA['verify.failed'],
186
196
  },
187
197
  'verify.timeout': {
188
198
  motivo: 'verify.timeout',
189
199
  acao: 'reexecutar',
190
200
  automatica: true,
191
- 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',
192
- 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'],
193
202
  },
194
203
  'verify.sem-veredito': {
195
204
  motivo: 'verify.sem-veredito',
196
205
  acao: 'reexecutar',
197
206
  automatica: true,
198
- 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',
199
- correcao: 'ork verify <thread> de novo, sem editar a worktree durante a rodada',
207
+ ...TEXTOS_DA_POLITICA['verify.sem-veredito'],
200
208
  },
201
209
  'ci.failed': {
202
210
  motivo: 'ci.failed',
203
211
  acao: 'escalar-humano',
204
212
  automatica: false,
205
- porque: 'o recibo pertence ao provedor e ao SHA candidato: repetir uma fase não cria nem altera legitimamente esse resultado',
206
- 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'],
207
214
  },
208
215
  'runtime.unavailable': {
209
216
  motivo: 'runtime.unavailable',
210
217
  acao: 'reexecutar',
211
218
  automatica: true,
212
- porque: 'falha de infraestrutura no despacho nao e falha de conteudo: o MESMO prompt, com o mesmo sha256, e redespachado sem alterar uma virgula',
213
- correcao: 'ork retry run <thread> redespacha o prompt ja gravado em disco',
219
+ ...TEXTOS_DA_POLITICA['runtime.unavailable'],
214
220
  },
215
221
  'runtime.silencio': {
216
222
  motivo: 'runtime.silencio', acao: 'reexecutar', automatica: true,
217
- porque: 'fase sem heartbeat: retomar o despacho original com hash conferido e limite de tentativas',
218
- correcao: 'ork retry run <thread> --motivo runtime.silencio',
223
+ ...TEXTOS_DA_POLITICA['runtime.silencio'],
219
224
  },
220
225
  'runtime.rate-limited': {
221
226
  motivo: 'runtime.rate-limited',
222
227
  acao: 'esperar-janela',
223
228
  automatica: true,
224
- 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',
225
- correcao: 'ork retry list mostra a fila; ork retry resume retoma o que ja liberou',
229
+ ...TEXTOS_DA_POLITICA['runtime.rate-limited'],
226
230
  },
227
231
  // I-33 (D5, D11): a falha e da CONTA. O perfil sai do rodizio e o MESMO prompt vai ao proximo
228
232
  // perfil ativo, depois ao runtime de fallback do bloco, e so por ultimo a fila duravel. A
@@ -232,15 +236,13 @@ exports.POLITICA_DE_RETRY = {
232
236
  motivo: 'runtime.quota-exhausted',
233
237
  acao: 'reexecutar',
234
238
  automatica: true,
235
- 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',
236
- correcao: 'ork accounts list mostra o perfil esgotado; ork retry run <thread> rotaciona o prompt ja gravado',
239
+ ...TEXTOS_DA_POLITICA['runtime.quota-exhausted'],
237
240
  },
238
241
  'runtime.auth-missing': {
239
242
  motivo: 'runtime.auth-missing',
240
243
  acao: 'reexecutar',
241
244
  automatica: true,
242
- 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',
243
- 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'],
244
246
  },
245
247
  // RM-037 (defeitosdeco D-6): o modelo e que falta, nao a conta. Repetir o mesmo modelo na mesma conta
246
248
  // so repete a recusa; o perfil continua no rodizio para os outros modelos.
@@ -248,22 +250,39 @@ exports.POLITICA_DE_RETRY = {
248
250
  motivo: 'runtime.model-unavailable',
249
251
  acao: 'reexecutar',
250
252
  automatica: true,
251
- 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',
252
- 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'],
254
+ },
255
+ // RM-055: so o dono destrava, no terminal. O retry nao repete o despacho as cegas: confere antes se o
256
+ // impedimento saiu (a confianca do diretorio tem prova local) e, sem prova, deixa o runtime decidir.
257
+ 'runtime.workspace-untrusted': {
258
+ motivo: 'runtime.workspace-untrusted',
259
+ acao: 'reexecutar',
260
+ automatica: true,
261
+ ...TEXTOS_DA_POLITICA['runtime.workspace-untrusted'],
262
+ },
263
+ 'runtime.consent-pending': {
264
+ motivo: 'runtime.consent-pending',
265
+ acao: 'reexecutar',
266
+ automatica: true,
267
+ ...TEXTOS_DA_POLITICA['runtime.consent-pending'],
253
268
  },
254
269
  'tree.blocked': {
255
270
  motivo: 'tree.blocked',
256
271
  acao: 'sincronizar-worktree',
257
272
  automatica: true,
258
- 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',
259
- correcao: 'ork worktree sync <thread> e so entao repetir o passo',
273
+ ...TEXTOS_DA_POLITICA['tree.blocked'],
274
+ },
275
+ 'lease.resume-unavailable': {
276
+ motivo: 'lease.resume-unavailable',
277
+ acao: 'escalar-humano',
278
+ automatica: false,
279
+ ...TEXTOS_DA_POLITICA['lease.resume-unavailable'],
260
280
  },
261
281
  'lease.busy': {
262
282
  motivo: 'lease.busy',
263
283
  acao: 'reexecutar',
264
284
  automatica: true,
265
- 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',
266
- correcao: 'ork lease list mostra a fila; a vez chega sem ninguem forcar',
285
+ ...TEXTOS_DA_POLITICA['lease.busy'],
267
286
  },
268
287
  // I-36 (T6): a vez chega quando a conducao atual terminar. Redespachar agora so recebe a mesma recusa,
269
288
  // e passar na frente de quem conduz e exatamente o incidente de 19/09/2026.
@@ -271,8 +290,7 @@ exports.POLITICA_DE_RETRY = {
271
290
  motivo: 'conducao.em-andamento',
272
291
  acao: 'esperar-janela',
273
292
  automatica: true,
274
- 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',
275
- 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'],
276
294
  },
277
295
  // I-41 (D10): formato e defeito de quem escreveu o pedido, e a spec dirigida conserta.
278
296
  // Escalar isto para o dono seria pedir que ele revise a sintaxe do robo.
@@ -280,15 +298,13 @@ exports.POLITICA_DE_RETRY = {
280
298
  motivo: 'hitl.formato',
281
299
  acao: 'corrigir-dirigido',
282
300
  automatica: true,
283
- 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',
284
- correcao: 'ork fix open <thread> abre a rodada com a spec exata do formato',
301
+ ...TEXTOS_DA_POLITICA['hitl.formato'],
285
302
  },
286
303
  'human.pending': {
287
304
  motivo: 'human.pending',
288
305
  acao: 'escalar-humano',
289
306
  automatica: false,
290
- porque: 'nao e reprovacao de verdade, e espera de autorizacao: automatizar a espera seria a maquina se autorizando',
291
- correcao: 'ork gate request <thread>',
307
+ ...TEXTOS_DA_POLITICA['human.pending'],
292
308
  },
293
309
  };
294
310
  /** A politica de um motivo tipado. */
@@ -337,7 +353,8 @@ function ultimaReprovacao(raiz, threadId) {
337
353
  * planejou: planejar nao gasta janela nem toca no repositorio.
338
354
  */
339
355
  function tentativasFeitas(raiz, threadId, fase, motivo) {
340
- 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;
341
358
  }
342
359
  /** O bloco de loop desta fase pausa para o humano neste modo? */
343
360
  function blocoPausa(thread, fase) {
@@ -365,7 +382,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
365
382
  modo: thread.modo,
366
383
  fase: opcoes.fase ?? thread.faseAtual,
367
384
  motivo: null,
368
- detalhe: 'nenhum gate reprovado no ledger desta thread',
385
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.semReprovacao),
369
386
  politica: null,
370
387
  acao: 'sem-retry',
371
388
  tentativas: 0,
@@ -374,7 +391,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
374
391
  effortAnterior: effortBase,
375
392
  automatica: false,
376
393
  bloqueio: 'gate.sem-reprovacao',
377
- 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),
378
395
  };
379
396
  }
380
397
  const fase = opcoes.fase ?? (evento ? faseDoEvento(evento, thread) : thread.faseAtual);
@@ -397,7 +414,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
397
414
  effortAnterior: effortBase,
398
415
  automatica: false,
399
416
  bloqueio: 'politica.nao-automatica',
400
- razao: politica.porque,
417
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.politica[motivo].porque),
401
418
  };
402
419
  }
403
420
  // Limite de escalacao: pausa QUALQUER modo, inclusive #Auto.
@@ -416,8 +433,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
416
433
  effortAnterior: effortBase,
417
434
  automatica: false,
418
435
  bloqueio: 'escalacao.limite',
419
- razao: `${tentativas} tentativa(s) automatica(s) por ${motivo} em ${fase}, no limite de ${limite} ` +
420
- 'do manifesto: escalacao tipada pausa qualquer modo, inclusive #Auto',
436
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.limiteDeEscalacao(tentativas, motivo, fase, limite)),
421
437
  };
422
438
  }
423
439
  // Da 2a tentativa em diante o esforco sobe um degrau, quando o manifesto permite.
@@ -433,9 +449,10 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
433
449
  const autorizado = delegacao.permitida || (0, gates_2.aprovacoesHumanas)(raiz, threadId).some(e => e.fase === fase && e.autorizadoPor === opcoes.autorizadoPor);
434
450
  let bloqueio = null;
435
451
  let automatica = politica.automatica;
436
- let razao = politica.porque;
437
- if (delegacao.permitida && politica.automatica)
438
- 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
+ }
439
456
  if (!politica.automatica) {
440
457
  automatica = false;
441
458
  bloqueio = 'politica.nao-automatica';
@@ -445,10 +462,8 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
445
462
  // a acao fica planejada e nao executada. `#Maestro` e `#Auto` nao caem neste ramo.
446
463
  automatica = false;
447
464
  bloqueio = 'modo.bloco-pausa';
448
- razao =
449
- `o bloco ${(0, thread_1.blocoDaThread)(thread, fase).fases.join('-')} pausa neste modo ` +
450
- `(${(0, thread_1.blocoDaThread)(thread, fase).pausaSobre}): a acao ${acao} espera autorizacao humana. ` +
451
- '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));
452
467
  }
453
468
  if (motivo === 'runtime.silencio') {
454
469
  const despacho = ultimoDespachoFalho(raiz, threadId, fase, true);
@@ -456,7 +471,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
456
471
  if (!prova || prova.sessionId !== despacho?.sessionId || !estadoTerminalDeRetry(prova.estado)) {
457
472
  automatica = false;
458
473
  bloqueio = 'politica.nao-automatica';
459
- 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);
460
475
  }
461
476
  }
462
477
  return {
@@ -502,24 +517,92 @@ function redespachar(carregado, thread, fase, promptRelativo, sha, opcoes = {})
502
517
  retida.devolver();
503
518
  }
504
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
+ }
505
589
  function redespacharSobLock(carregado, thread, fase, promptRelativo, sha, opcoes = {},
506
590
  /** A tomada que a primeira passada reteve para a baseline; com ela, esta e a repeticao. */
507
591
  tomadaPrevia) {
508
592
  const { raiz, manifesto } = carregado;
509
- const absoluto = path.isAbsolute(promptRelativo)
510
- ? promptRelativo
511
- : path.join(raiz, promptRelativo);
593
+ const achado = localizarPromptGravado(raiz, thread.id, promptRelativo, sha);
594
+ const absoluto = achado ?? '';
512
595
  const slug = opcoes.slug ?? (0, phase_1.slugDaSessao)(thread, fase);
513
596
  const vazio = { slug, sessionId: null, verificada: false, sinal: null, comando: [] };
514
597
  const erroDeEstado = (0, phase_1.estadoParaDespacho)(raiz, thread, opcoes.dryRun);
515
598
  if (erroDeEstado)
516
599
  return { ...vazio, ok: false, motivo: 'tree.blocked', detalhe: erroDeEstado, dryRun: opcoes.dryRun === true };
517
- if (!fs.existsSync(absoluto)) {
600
+ if (!achado) {
518
601
  return {
519
602
  ...vazio,
520
603
  ok: false,
521
604
  motivo: 'artifact.missing',
522
- detalhe: `o prompt gravado sumiu do disco: ${promptRelativo}`,
605
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.promptSumiu(promptRelativo)),
523
606
  dryRun: opcoes.dryRun === true,
524
607
  };
525
608
  }
@@ -530,8 +613,7 @@ tomadaPrevia) {
530
613
  ...vazio,
531
614
  ok: false,
532
615
  motivo: 'artifact.missing',
533
- detalhe: `o prompt em ${promptRelativo} mudou desde o despacho original ` +
534
- `(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))),
535
617
  dryRun: opcoes.dryRun === true,
536
618
  };
537
619
  }
@@ -579,8 +661,9 @@ tomadaPrevia) {
579
661
  (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, ledger_1.TIPOS_DE_EVENTO.despachoIdempotente, { fase, promptSha256: sha, canal,
580
662
  sessionId: tomada.atual.sessao, origem: opcoes.origem ?? 'retry',
581
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);
582
665
  return { ...vazio, ok: true, sessionId: tomada.atual.sessao, motivo: null, dryRun: false,
583
- 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)) };
584
667
  }
585
668
  const recusa = (0, conducao_1.recusaDeConducao)(thread.id, tomada.atual, pedidoDeConducao);
586
669
  (0, conducao_1.registrarRecusa)(raiz, recusa);
@@ -589,7 +672,14 @@ tomadaPrevia) {
589
672
  conducao = tomada;
590
673
  }
591
674
  try {
592
- 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
+ }
593
683
  // Mesma resolucao do `ork phase run`: a retomada carimba no ledger o trio que ela de
594
684
  // fato despachou, inclusive quando o pedido da fila trazia um modelo proprio. O setup
595
685
  // do bloco (feature #setup) vale aqui tambem: a fase retomada abre no MESMO runtime
@@ -601,11 +691,20 @@ tomadaPrevia) {
601
691
  effort: opcoes.effort ?? undefined,
602
692
  }, doBloco);
603
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
+ }
604
703
  if (!opcoes.dryRun && (0, phase_1.baselineDoDespachoNecessaria)(carregado, thread.id, { fase, prompt: '', runtime, model, effort })) {
605
704
  // Na primeira passada a tomada fica retida para a baseline (o `finally` nao a solta); na repeticao, o
606
705
  // `finally` devolve o que a tomada consumiu (A-1 do CHECK 3).
607
706
  const pendente = { ...vazio, ok: false, motivo: 'runtime.unavailable', dryRun: false,
608
- 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)) };
609
708
  if (!tomadaPrevia && conducao) {
610
709
  pendente.retida = conducao;
611
710
  conducao = null;
@@ -621,8 +720,9 @@ tomadaPrevia) {
621
720
  contextoRuntime = (0, runtime_context_1.contextoDoProjeto)(raiz, runtime, cwd, thread.id);
622
721
  }
623
722
  catch (e) {
723
+ const erro = e.message;
624
724
  return { ...vazio, ok: false, motivo: 'runtime.unavailable',
625
- detalhe: `runtime.unavailable: ${e.message}`, dryRun: opcoes.dryRun === true };
725
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeIndisponivel(erro)), dryRun: opcoes.dryRun === true };
626
726
  }
627
727
  if (contextoRuntime)
628
728
  contextoRuntime.identidade = identidade;
@@ -668,7 +768,7 @@ tomadaPrevia) {
668
768
  sessionId: null,
669
769
  verificada: false,
670
770
  motivo: null,
671
- detalhe: 'ensaio (--dry-run): comando montado, nada despachado',
771
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.ensaioDoRedespacho),
672
772
  sinal: null,
673
773
  comando: resultado.comando,
674
774
  dryRun: true,
@@ -677,8 +777,19 @@ tomadaPrevia) {
677
777
  if (!resultado.ok || !resultado.sessionId) {
678
778
  (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, 'phase_dispatch_failed', { fase, runtime, slug, cwd,
679
779
  promptPath: absoluto, promptSha256: sha, controlador: resultado.controlador, model, effort,
680
- erro: resultado.erro ?? 'runtime.unavailable: sem sessionId', origem: 'retry', ...(perfil ? { perfil } : {}) });
780
+ erro: resultado.erro ?? 'runtime.unavailable: sem sessionId', stderr: (resultado.stderr ?? '').slice(0, 500),
781
+ origem: 'retry', ...(perfil ? { perfil } : {}) });
681
782
  const sinal = resultado.rateLimit ?? null;
783
+ // RM-055: o redespacho recusado pelo que so o dono resolve reabre a pausa dele, com o mesmo comando.
784
+ const impedimento = !resultado.falhaDeConta && !sinal
785
+ ? (0, impedimento_1.registrarImpedimentoDoDono)((0, thread_1.dirThread)(raiz, thread.id), thread, { fase, slug, runtime, cwd, origem: 'retry',
786
+ promptPath: absoluto, promptSha256: sha, perfil, saida: `${resultado.stderr ?? ''}\n${resultado.erro ?? ''}` })
787
+ : null;
788
+ if (impedimento) {
789
+ return { ok: false, slug, sessionId: null, verificada: false, motivo: impedimento.motivo,
790
+ detalhe: `${impedimento.motivo}: ${impedimento.trecho}`, sinal: null, falhaDeConta: null, perfil: perfil ?? null,
791
+ comando: resultado.comando, controlador: resultado.controlador, dryRun: false };
792
+ }
682
793
  // I-33 (D5): a conta recusou o redespacho; o perfil sai do rodizio aqui, onde a evidencia esta.
683
794
  if (resultado.falhaDeConta) {
684
795
  try {
@@ -693,7 +804,7 @@ tomadaPrevia) {
693
804
  verificada: false,
694
805
  // I-33 (D11b): falha de conta reconhecida na saida e o motivo mais especifico.
695
806
  motivo: resultado.falhaDeConta?.motivo ?? (sinal ? 'runtime.rate-limited' : 'runtime.unavailable'),
696
- detalhe: resultado.erro ?? 'sem sessionId na saida do runtime',
807
+ detalhe: resultado.erro ?? (0, locale_1.textoDoCatalogo)((m) => m.retry.semSessionId),
697
808
  sinal,
698
809
  falhaDeConta: resultado.falhaDeConta ?? null,
699
810
  perfil: perfil ?? null,
@@ -728,8 +839,7 @@ tomadaPrevia) {
728
839
  sessionId: resultado.sessionId,
729
840
  verificada: resultado.verificada,
730
841
  motivo: null,
731
- detalhe: `sessao ${resultado.sessionId} despachada com o mesmo prompt sha256 ${sha.slice(0, 12)}` +
732
- (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)),
733
843
  sinal: null,
734
844
  perfil: perfil ?? null,
735
845
  comando: resultado.comando,
@@ -1076,7 +1186,11 @@ function producaoNoIntervalo(raiz, thread, sessao, eventos) {
1076
1186
  // pelo shell nao passa pelo ledger, entao so o HEAD o revela.
1077
1187
  const registro = eventos.filter(e => e.tipo === 'session_sensor_registered' && e.sessionId === sessao.sessionId &&
1078
1188
  e.despachoEm === sessao.despachadaEm).at(-1);
1079
- 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' };
1080
1194
  const head = registro?.head;
1081
1195
  if (typeof head !== 'string' || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head))
1082
1196
  return { produziu: true, evidencia: 'HEAD da worktree no despacho desconhecido; producao nao descartada' };
@@ -1121,6 +1235,17 @@ function jaMarcado(raiz, perfil, falha, agoraMs = Date.now()) {
1121
1235
  ? atual.estado === 'esgotado' && atual.esgotadoAte !== null && Date.parse(atual.esgotadoAte) > agoraMs
1122
1236
  : atual.estado === 'sem-auth';
1123
1237
  }
1238
+ /**
1239
+ * RM-037 (fatia 5, aviso da rodada 1 do CHECK): a cota que o observador viu ao vivo (`runtime_quota_detected`, da mesma
1240
+ * sessao e do mesmo despacho, com o mesmo prazo dito) ja tirou o perfil do rodizio ate a hora da mensagem. Marcar de
1241
+ * novo aqui, depois dessa hora, pela janela padrao (A10), tiraria do rodizio uma conta que ja voltou.
1242
+ */
1243
+ function cotaJaVistaAoVivo(eventos, gate, falha) {
1244
+ if (falha.motivo !== 'runtime.quota-exhausted' || typeof gate?.sessionId !== 'string')
1245
+ return false;
1246
+ return eventos.some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.cotaVistaNaTranscricao && e.sessionId === gate.sessionId &&
1247
+ e.despachoEm === gate.despachoEm && (e.resetEm ?? null) === falha.resetEm);
1248
+ }
1124
1249
  function sinalDoGate(gate, motivo) {
1125
1250
  const f = gate?.falhaDeConta;
1126
1251
  return { motivo: motivo === 'runtime.auth-missing' ? 'runtime.auth-missing' : 'runtime.quota-exhausted',
@@ -1209,7 +1334,7 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1209
1334
  return vazio;
1210
1335
  }
1211
1336
  const acaoBase = plano.politica?.acao ?? plano.acao;
1212
- const registrarTentativa = (ok, detalhe) => {
1337
+ const registrarTentativa = (ok, detalhe, extra = {}) => {
1213
1338
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.retryTentado, {
1214
1339
  fase: plano.fase,
1215
1340
  motivo: plano.motivo,
@@ -1227,32 +1352,27 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1227
1352
  : `politica de retry do bloco B3 (bloco sem pausa no modo ${thread.modo})`,
1228
1353
  ok,
1229
1354
  detalhe,
1355
+ ...extra,
1230
1356
  });
1231
1357
  };
1232
1358
  // I-36 (T6): conducao em andamento nao e fila de rate limit. Nada e redespachado; o registro diz
1233
1359
  // quem conduz, e a vez chega quando essa conducao terminar.
1234
1360
  if (plano.motivo === 'conducao.em-andamento') {
1235
1361
  const atual = (0, conducao_1.conducaoDaThread)(raiz, threadId);
1236
- const detalhe = atual
1237
- ? `${(0, conducao_texto_1.linhaDeConducao)(atual)}; nada foi redespachado, a vez chega quando essa conducao terminar`
1238
- : '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);
1239
1363
  registrarTentativa(!atual, detalhe);
1240
1364
  return { ...vazio, executada: false, detalhe };
1241
1365
  }
1242
1366
  // `esperar-janela`: quem retoma e a fila, e ela ja esta gravada em disco.
1243
1367
  if (acaoBase === 'esperar-janela') {
1244
1368
  const fila = (0, ratelimit_1.lerFilaDeRetomada)(raiz).filter((p) => p.thread === threadId && p.estado === 'aguardando');
1245
- const detalhe = fila.length > 0
1246
- ? `${fila.length} pedido(s) na fila duravel; o proximo libera em ${fila[0].liberaEm}`
1247
- : '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);
1248
1370
  registrarTentativa(fila.length > 0, detalhe);
1249
1371
  return { ...vazio, executada: fila.length > 0, fila, detalhe };
1250
1372
  }
1251
1373
  if (acaoBase === 'sincronizar-worktree') {
1252
1374
  const sync = (0, worktree_1.sincronizarWorktree)(carregado, threadId, { dryRun: opcoes.dryRun });
1253
- const detalhe = sync.ok
1254
- ? `worktree sincronizada com a base (${sync.passos.join('; ')})`
1255
- : `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));
1256
1376
  registrarTentativa(sync.ok, detalhe);
1257
1377
  return { ...vazio, executada: sync.ok, sync, detalhe };
1258
1378
  }
@@ -1261,10 +1381,8 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1261
1381
  const reverify = opcoes.reverify && rodada.correcoes.length > 0
1262
1382
  ? (0, fix_1.reverificar)(carregado, threadId, { rodada: rodada.rodada })
1263
1383
  : null;
1264
- const detalhe = rodada.correcoes.length === 0
1265
- ? 'o CHECK passou no HEAD real: nao ha correcao a dirigir'
1266
- : `${rodada.correcoes.length} correcao(oes) na rodada ${rodada.rodada}` +
1267
- (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));
1268
1386
  registrarTentativa(rodada.correcoes.length > 0, detalhe);
1269
1387
  return { ...vazio, executada: rodada.correcoes.length > 0, rodada, reverify, detalhe };
1270
1388
  }
@@ -1274,14 +1392,41 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1274
1392
  if (plano.motivo === 'runtime.model-unavailable') {
1275
1393
  return trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registrarTentativa);
1276
1394
  }
1277
- // `reexecutar` e `escalar-esforco`: o MESMO prompt volta ao runtime.
1278
- 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');
1279
1401
  if (!falho || typeof falho.promptPath !== 'string' || typeof falho.promptSha256 !== 'string') {
1280
- const detalhe = `nao ha despacho falho registrado em ${plano.fase} com prompt gravado: ` +
1281
- `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));
1282
1403
  registrarTentativa(false, detalhe);
1283
1404
  return { ...vazio, detalhe };
1284
1405
  }
1406
+ // RM-055: o impedimento do dono com prova local (confianca do diretorio) so volta ao runtime depois de
1407
+ // resolvido. Sem a prova, nada e despachado e a tentativa nao conta: a pausa do dono continua aberta.
1408
+ if (plano.motivo && (0, impedimento_1.ehImpedimentoDoDono)(plano.motivo) && typeof falho.cwd === 'string') {
1409
+ const perfilFalho = perfilDoEvento(falho);
1410
+ const resolvido = (0, impedimento_1.impedimentoResolvido)(plano.motivo, { cwd: falho.cwd,
1411
+ runtime: typeof falho.runtime === 'string' ? falho.runtime : '', configDir: perfilFalho?.configDir ?? null });
1412
+ if (resolvido === false) {
1413
+ const motivo = plano.motivo, cwd = falho.cwd;
1414
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => m.retry.semConfianca(motivo, cwd, threadId));
1415
+ return { ...vazio, detalhe };
1416
+ }
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
+ }
1285
1430
  const redespacho = redespachar(carregado, thread, plano.fase, falho.promptPath, falho.promptSha256, {
1286
1431
  effort: plano.effort,
1287
1432
  runtime: typeof falho.runtime === 'string' ? falho.runtime : null,
@@ -1289,7 +1434,11 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1289
1434
  origem: 'retry.run',
1290
1435
  dryRun: opcoes.dryRun,
1291
1436
  });
1292
- 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 } : {});
1293
1442
  return {
1294
1443
  ...vazio,
1295
1444
  executada: redespacho.ok,
@@ -1322,7 +1471,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1322
1471
  return { ...vazio, detalhe: diagnostico };
1323
1472
  };
1324
1473
  if (!despacho || typeof despacho.promptPath !== 'string' || typeof despacho.promptSha256 !== 'string') {
1325
- 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));
1326
1475
  registrarTentativa(false, detalhe);
1327
1476
  return { ...vazio, detalhe };
1328
1477
  }
@@ -1334,14 +1483,14 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1334
1483
  : perfilDoEvento(despacho);
1335
1484
  }
1336
1485
  catch (e) {
1337
- 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)));
1338
1488
  }
1339
1489
  // D11 (c): sessao que morreu por cota depois de produzir nao e redespachada.
1340
1490
  if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
1341
1491
  const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
1342
1492
  if (producao.produziu) {
1343
- return escalar('producao parcial sob falha da conta', `producao parcial sob ${motivo === 'runtime.quota-exhausted' ? 'cota esgotada' : 'auth ausente'}: ${producao.evidencia}; ` +
1344
- '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))));
1345
1494
  }
1346
1495
  }
1347
1496
  const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, fase);
@@ -1349,7 +1498,8 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1349
1498
  const politica = (0, runtime_profiles_1.politicaDeRotacao)(manifesto);
1350
1499
  const falha = sinalDoGate(gate, motivo);
1351
1500
  // I-33 (D12): o observador ja marca o perfil no caminho terminal; remarcar empurraria o prazo a cada retry.
1352
- if (!opcoes.dryRun && perfil && !jaMarcado(raiz, perfil, falha)) {
1501
+ // RM-037 (fatia 5, aviso da rodada 1 do CHECK): a cota que ele viu ao vivo ja marcou ate a hora da mensagem.
1502
+ if (!opcoes.dryRun && perfil && !jaMarcado(raiz, perfil, falha) && !cotaJaVistaAoVivo(eventos, gate, falha)) {
1353
1503
  try {
1354
1504
  (0, ratelimit_1.marcarContaDaFalha)(carregado, perfil, falha);
1355
1505
  }
@@ -1398,8 +1548,8 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1398
1548
  if (ultimo.falhaDeConta?.motivo !== 'runtime.model-unavailable')
1399
1549
  falhaAtual = ultimo.falhaDeConta ?? falhaAtual;
1400
1550
  if (tentativas >= plano.limite) {
1401
- return escalar('limite de tentativas na rotacao', `${tentativas} tentativa(s) de rotacao por ${motivo} em ${fase}, no limite de ` +
1402
- `${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)));
1403
1553
  }
1404
1554
  }
1405
1555
  // Sem destino: a fila so faz sentido quando algum perfil tem prazo para voltar. Sem perfil (ambiente do
@@ -1409,13 +1559,12 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1409
1559
  const prazo = (0, runtime_profiles_1.prazoDaFila)((0, runtime_profiles_1.lerPerfisComContas)(raiz), runtimes, politica) ?? dito;
1410
1560
  if (!prazo && falhaAtual.motivo === 'runtime.auth-missing') {
1411
1561
  emitir(null, 'nenhum perfil com login em nenhum runtime da ordem de fallback');
1412
- return escalar('auth ausente sem alternativa', 'nenhum perfil com login conferido em nenhum runtime da ordem de fallback: ' +
1413
- '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));
1414
1563
  }
1415
1564
  const liberaEm = prazo ?? new Date(Date.now() + (0, ratelimit_1.janelaPadraoMs)(manifesto)).toISOString();
1416
1565
  emitir(null, `nenhum perfil ativo em ${runtimes.join(', ')}: fila duravel ate ${liberaEm}`);
1417
1566
  if (opcoes.dryRun)
1418
- return { ...vazio, detalhe: `ensaio: entraria na fila duravel ate ${liberaEm}` };
1567
+ return { ...vazio, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.entrariaNaFila(liberaEm)) };
1419
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),
1420
1569
  promptPath: despacho.promptPath, promptSha256: despacho.promptSha256,
1421
1570
  cwd: typeof despacho.cwd === 'string' ? despacho.cwd : thread.worktree ?? raiz,
@@ -1426,7 +1575,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1426
1575
  janelaEstimada: pedido.janelaEstimada, motivo: falhaAtual.motivo, promptSha256: despacho.promptSha256,
1427
1576
  correcao: `ork retry resume (ou aguarde ate ${pedido.liberaEm})` });
1428
1577
  registrarTentativa(true, `fila duravel: pedido ${pedido.id} libera em ${pedido.liberaEm}`);
1429
- 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)) };
1430
1579
  }
1431
1580
  /** RM-037 (defeitosdeco D-6): chave de um destino (runtime, perfil, modelo) que recusou o modelo. */
1432
1581
  function chaveDoModelo(runtime, perfil, model) {
@@ -1494,10 +1643,10 @@ function proximoDestinoDoModelo(raiz, runtime, model, fallback, recusados) {
1494
1643
  return null;
1495
1644
  }
1496
1645
  /** D-6: a correcao exata quando nenhum destino tem o modelo: o bloco do setup que conduz a fase. */
1497
- function correcaoDoModelo(thread, fase) {
1646
+ function correcaoDoModelo(thread, fase, m = (0, locale_1.msg)()) {
1498
1647
  const indice = modos_1.MODOS[thread.modo]?.blocos.findIndex(b => b.fases.includes(fase)) ?? -1;
1499
1648
  const bloco = indice >= 0 ? String(indice + 1) : 'N';
1500
- 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);
1501
1650
  }
1502
1651
  /**
1503
1652
  * RM-037 (defeitosdeco D-6): troca de destino depois de `runtime.model-unavailable`. O modelo pedido nao
@@ -1524,13 +1673,12 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1524
1673
  return { ...vazio, detalhe: diagnostico };
1525
1674
  };
1526
1675
  if (!despacho || typeof despacho.promptPath !== 'string' || typeof despacho.promptSha256 !== 'string') {
1527
- 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));
1528
1677
  registrarTentativa(false, detalhe);
1529
1678
  return { ...vazio, detalhe };
1530
1679
  }
1531
1680
  const runtime = typeof despacho.runtime === 'string' ? despacho.runtime : manifesto.runtime.adapter;
1532
1681
  const model = typeof despacho.model === 'string' ? despacho.model : null;
1533
- const rotulo = model ?? '(padrao do runtime)';
1534
1682
  let perfil;
1535
1683
  try {
1536
1684
  perfil = typeof gate?.sessionId === 'string'
@@ -1538,13 +1686,13 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1538
1686
  : perfilDoEvento(despacho);
1539
1687
  }
1540
1688
  catch (e) {
1541
- 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)));
1542
1691
  }
1543
1692
  if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
1544
1693
  const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
1545
1694
  if (producao.produziu) {
1546
- return escalar('producao parcial com modelo inacessivel', `producao parcial com o modelo ${rotulo} inacessivel: ${producao.evidencia}; ` +
1547
- '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))));
1548
1696
  }
1549
1697
  }
1550
1698
  const recusados = new Set([...destinosQueRecusaramOModelo(eventos, fase), chaveDoModelo(runtime, perfil?.id ?? null, model)]);
@@ -1570,8 +1718,7 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1570
1718
  origem: 'retry.modelo', dryRun: opcoes.dryRun,
1571
1719
  });
1572
1720
  if (opcoes.dryRun)
1573
- return { ...vazio, redespacho: r, detalhe: `ensaio: o mesmo prompt iria a ${alvo.runtime}` +
1574
- `${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))) };
1575
1722
  registrarTentativa(r.ok, r.detalhe);
1576
1723
  tentativas += 1;
1577
1724
  if (r.ok)
@@ -1582,58 +1729,62 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1582
1729
  recusados.add(chaveDoModelo(alvo.runtime, alvo.perfil?.id ?? null, alvo.model));
1583
1730
  atual = { runtime: alvo.runtime, perfil: alvo.perfil, model: alvo.model };
1584
1731
  if (tentativas >= plano.limite) {
1585
- return escalar('limite de tentativas na troca de modelo', `${tentativas} tentativa(s) de troca por ${motivo} em ${fase}, no limite de ` +
1586
- `${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)));
1587
1734
  }
1588
1735
  }
1589
1736
  const tentados = [...recusados].map(k => { const [rt, p, m] = k.split('|'); return `${rt}${p ? `/${p}` : ''}:${m || '(padrao)'}`; });
1590
- return escalar('modelo inacessivel sem outro destino', `o modelo ${rotulo} nao esta acessivel em ${tentados.join(', ')} e o bloco ` +
1591
- `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))));
1592
1738
  }
1593
1739
  /** Texto de `ork retry plan`. */
1594
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;
1595
1744
  const linhas = [];
1596
- linhas.push(`Plano de retry da thread ${p.thread}`);
1597
- linhas.push(` modo ${p.modo}`);
1598
- linhas.push(` fase ${p.fase ?? '(nenhuma)'}`);
1599
- 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);
1600
1750
  if (p.detalhe)
1601
- linhas.push(` detalhe ${(0, horario_1.localizarTexto)(p.detalhe)}`);
1602
- linhas.push(` acao ${p.acao}`);
1603
- linhas.push(` tentativas ${p.tentativas} de ${p.limite} antes da escalacao`);
1604
- linhas.push(` esforco ${p.effort}${p.effort !== p.effortAnterior ? ` (escalado de ${p.effortAnterior})` : ''}`);
1605
- 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));
1606
1756
  if (p.bloqueio)
1607
- linhas.push(` bloqueio ${p.bloqueio}`);
1608
- linhas.push(` razao ${p.razao}`);
1757
+ linhas.push(m.bloqueio(p.bloqueio));
1758
+ linhas.push(m.razao((0, locale_1.remontar)(p.razao)));
1609
1759
  if (p.politica && !p.automatica)
1610
- linhas.push(` correcao ${p.politica.correcao}`);
1611
- 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)
1612
1762
  linhas.push((0, horario_1.legendaDoFuso)());
1613
1763
  return linhas.join('\n');
1614
1764
  }
1615
1765
  /** Texto de `ork retry run`. */
1616
1766
  function textoDoRetry(r) {
1767
+ const m = (0, locale_1.msg)().retry;
1617
1768
  const plano = textoDoPlano(r.plano);
1618
1769
  const linhas = [plano, ''];
1619
- linhas.push(`Execucao: ${r.executada ? 'acao executada' : 'nada executado'}`);
1620
- 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)));
1621
1773
  if (r.rodada && r.rodada.correcoes.length > 0) {
1622
1774
  linhas.push('');
1623
- linhas.push(`GO-FIX rodada ${r.rodada.rodada}: ` +
1624
- 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(', ')));
1625
1776
  }
1626
1777
  if (r.reverify) {
1627
- 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));
1628
1779
  }
1629
1780
  if (r.fila.length > 0) {
1630
1781
  linhas.push('');
1631
- linhas.push('Fila de rate limit desta thread:');
1782
+ linhas.push(m.fila);
1632
1783
  for (const p of r.fila) {
1633
- 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));
1634
1785
  }
1635
1786
  }
1636
- 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)())) {
1637
1788
  linhas.push((0, horario_1.legendaDoFuso)());
1638
1789
  }
1639
1790
  return linhas.join('\n');