@orkastery/cli 0.5.6 → 0.6.1

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 (396) hide show
  1. package/adapters/README.md +18 -0
  2. package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
  3. package/adapters/claude-code/README.md +37 -5
  4. package/adapters/claude-code/agents/ork-check.md +1 -0
  5. package/adapters/claude-code/agents/ork-go.md +1 -0
  6. package/adapters/claude-code/agents/ork-goal.md +1 -0
  7. package/adapters/claude-code/agents/ork-master.md +1 -0
  8. package/adapters/claude-code/agents/ork-plan.md +1 -0
  9. package/adapters/claude-code/agents/ork-ship.md +1 -0
  10. package/adapters/claude-code/hooks/hooks.json +2 -1
  11. package/adapters/claude-code/hooks/ork-guard.js +15 -1
  12. package/adapters/claude-code/hooks/ork-resposta.js +91 -0
  13. package/adapters/claude-code/hooks/ork-sensor.js +18 -2
  14. package/adapters/claude-code/hooks/quota-signal.js +14 -0
  15. package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
  16. package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
  17. package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
  18. package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
  19. package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
  20. package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
  21. package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
  22. package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
  23. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
  24. package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
  25. package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
  27. package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
  28. package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
  29. package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
  30. package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
  31. package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
  32. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
  33. package/adapters/codex/skills/ork/SKILL.md +2 -0
  34. package/adapters/hermes/README.md +64 -1
  35. package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
  36. package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
  37. package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
  38. package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
  39. package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
  40. package/adapters/hermes/hermes.plugin.json +4 -0
  41. package/adapters/hermes/hitl-ingress/__init__.py +101 -8
  42. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
  43. package/adapters/openclaw/README.md +81 -9
  44. package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
  45. package/adapters/openclaw/dist/hitl-ingress.js +106 -9
  46. package/adapters/openclaw/dist/index.js +86 -0
  47. package/adapters/openclaw/openclaw.plugin.json +34 -4
  48. package/adapters/openclaw/package.json +2 -2
  49. package/adapters/openclaw/src/hitl-ingress.ts +103 -9
  50. package/adapters/openclaw/src/index.ts +94 -0
  51. package/assets/adapters-en/claude-code/README.md +403 -0
  52. package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
  53. package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
  54. package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
  55. package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
  56. package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
  57. package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
  58. package/assets/adapters-en/claude-code/commands/check.md +46 -0
  59. package/assets/adapters-en/claude-code/commands/go.md +46 -0
  60. package/assets/adapters-en/claude-code/commands/goal.md +55 -0
  61. package/assets/adapters-en/claude-code/commands/master.md +54 -0
  62. package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
  63. package/assets/adapters-en/claude-code/commands/ork.md +126 -0
  64. package/assets/adapters-en/claude-code/commands/plan.md +47 -0
  65. package/assets/adapters-en/claude-code/commands/ship.md +45 -0
  66. package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
  67. package/assets/adapters-en/hermes/README.md +273 -0
  68. package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
  69. package/assets/references-en/README.md +25 -0
  70. package/assets/references-en/code-review-axes.md +82 -0
  71. package/assets/references-en/definition-of-done.md +74 -0
  72. package/assets/references-en/performance-checklist.md +53 -0
  73. package/assets/references-en/security-checklist.md +101 -0
  74. package/assets/references-en/testing-patterns.md +51 -0
  75. package/assets/security-scan/defaults/.golangci.yml +2 -0
  76. package/assets/security-scan/defaults/eslint.config.mjs +11 -0
  77. package/assets/security-scan/defaults/gitleaks.toml +3 -0
  78. package/assets/security-scan/defaults/ruff.toml +1 -0
  79. package/assets/security-scan/tools-agil.json +87 -0
  80. package/assets/security-scan/tools.json +625 -0
  81. package/assets/skills-en/core/onboarding/SKILL.md +58 -0
  82. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
  83. package/assets/skills-en/core/thread-state/SKILL.md +88 -0
  84. package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
  85. package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
  86. package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
  87. package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
  88. package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
  89. package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
  90. package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
  91. package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
  92. package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
  93. package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
  94. package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
  95. package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
  96. package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
  97. package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
  98. package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
  99. package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
  100. package/dist/adapters/claude-bg.js +123 -9
  101. package/dist/adapters/codex-controller-worker.js +12 -5
  102. package/dist/adapters/codex-events.js +16 -4
  103. package/dist/adapters/codex.js +3 -1
  104. package/dist/adapters/grok-events.js +227 -0
  105. package/dist/adapters/grok-mcp-servidor.js +612 -0
  106. package/dist/adapters/grok-mcp.js +178 -0
  107. package/dist/adapters/grok.js +686 -0
  108. package/dist/agendador-cpu.js +92 -0
  109. package/dist/atualizar-branch.js +245 -0
  110. package/dist/auditoria.js +13 -11
  111. package/dist/auditrun.js +51 -46
  112. package/dist/autorizacao-duravel.js +327 -0
  113. package/dist/board.js +94 -40
  114. package/dist/branch-de-estado.js +23 -10
  115. package/dist/busca-semantica.js +7 -5
  116. package/dist/catalogo.js +2 -1
  117. package/dist/changelog-reconciliacao.js +290 -0
  118. package/dist/check-agil.js +528 -0
  119. package/dist/check-modo.js +41 -0
  120. package/dist/check-paralelo.js +238 -0
  121. package/dist/ci.js +248 -45
  122. package/dist/ciclos.js +8 -6
  123. package/dist/claim-lint.js +12 -8
  124. package/dist/claims-conferir.js +47 -39
  125. package/dist/claims.js +10 -9
  126. package/dist/company-brain-client.js +10 -3
  127. package/dist/company-brain-migration.js +11 -5
  128. package/dist/conducao-batida.js +759 -0
  129. package/dist/conducao-sentinela.js +25 -8
  130. package/dist/conducao.js +89 -29
  131. package/dist/conhecimento-consulta.js +270 -0
  132. package/dist/conhecimento.js +111 -87
  133. package/dist/conta-esgotada.js +127 -0
  134. package/dist/dado-privado.js +816 -0
  135. package/dist/decisao-autonoma.js +5 -4
  136. package/dist/demo.js +14 -12
  137. package/dist/dependencias-da-worktree.js +25 -0
  138. package/dist/divida.js +38 -36
  139. package/dist/docs.js +89 -89
  140. package/dist/doctor-forja.js +343 -0
  141. package/dist/doctor-pulse-cron.js +113 -1
  142. package/dist/doctor.js +164 -6
  143. package/dist/dsn-da-memoria.js +417 -0
  144. package/dist/entrega-por-mod.js +503 -0
  145. package/dist/entrega-pr.js +154 -54
  146. package/dist/esgotamentos.js +13 -11
  147. package/dist/estado-thread.js +21 -18
  148. package/dist/evalrunner.js +35 -32
  149. package/dist/fabrica-batida.js +34 -21
  150. package/dist/fabrica-estado.js +33 -21
  151. package/dist/fix.js +21 -19
  152. package/dist/forja/adaptador.js +6 -0
  153. package/dist/forja/ambiente-de-ci.js +27 -0
  154. package/dist/forja/api.js +256 -0
  155. package/dist/forja/cache.js +89 -0
  156. package/dist/forja/cli.js +60 -0
  157. package/dist/forja/contrato.js +9 -0
  158. package/dist/forja/endereco.js +43 -0
  159. package/dist/forja/estado.js +22 -0
  160. package/dist/forja/executor.js +73 -0
  161. package/dist/forja/github/ci.js +95 -0
  162. package/dist/forja/github/dono-da-rede.js +18 -0
  163. package/dist/forja/github/metadados.js +15 -0
  164. package/dist/forja/github/pedidos.js +200 -0
  165. package/dist/forja/gitlab/ci.js +141 -0
  166. package/dist/forja/gitlab/consultas.js +59 -0
  167. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  168. package/dist/forja/gitlab/metadados.js +15 -0
  169. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  170. package/dist/forja/gitlab/pedidos.js +141 -0
  171. package/dist/forja/produtor.js +32 -0
  172. package/dist/forja/registro.js +31 -0
  173. package/dist/forja/resolver.js +121 -0
  174. package/dist/forja/texto.js +13 -0
  175. package/dist/forja/versao.js +71 -0
  176. package/dist/forja.js +123 -80
  177. package/dist/handoff.js +23 -13
  178. package/dist/hitl-contract.js +46 -43
  179. package/dist/hitl-curto.js +37 -25
  180. package/dist/hitl-gates.js +13 -11
  181. package/dist/hitl-local-receipt.js +51 -0
  182. package/dist/hitl-local.js +11 -2
  183. package/dist/hitl-lock.js +5 -11
  184. package/dist/hitl-public-receipt.js +11 -0
  185. package/dist/hitl-resumo.js +44 -1
  186. package/dist/hitl-sessions.js +62 -9
  187. package/dist/hitl-texto-livre.js +7 -4
  188. package/dist/hitl.js +34 -31
  189. package/dist/horario.js +20 -1
  190. package/dist/hosts.js +104 -134
  191. package/dist/index.js +864 -554
  192. package/dist/indice-vetorial.js +14 -12
  193. package/dist/init.js +11 -2
  194. package/dist/integracoes-locais.js +4 -0
  195. package/dist/intelligence-graph-cli.js +123 -69
  196. package/dist/intelligence-graph-query.js +37 -22
  197. package/dist/leases.js +19 -18
  198. package/dist/ledger-stats.js +17 -16
  199. package/dist/ledger.js +31 -1
  200. package/dist/licoes.js +12 -11
  201. package/dist/locale-accounts.js +228 -0
  202. package/dist/locale-adapter.js +291 -0
  203. package/dist/locale-ajuda.js +86 -10
  204. package/dist/locale-audit.js +199 -0
  205. package/dist/locale-claims.js +213 -0
  206. package/dist/locale-conducao.js +138 -0
  207. package/dist/locale-conhecimento.js +181 -0
  208. package/dist/locale-decisao.js +205 -0
  209. package/dist/locale-docs.js +230 -0
  210. package/dist/locale-estado.js +101 -0
  211. package/dist/locale-forja.js +288 -0
  212. package/dist/locale-gerados.js +5 -0
  213. package/dist/locale-grafo.js +129 -0
  214. package/dist/locale-master.js +83 -0
  215. package/dist/locale-network.js +524 -0
  216. package/dist/locale-operacao-restante.js +931 -0
  217. package/dist/locale-projetos.js +100 -0
  218. package/dist/locale-prompts.js +194 -0
  219. package/dist/locale-pulse.js +140 -2
  220. package/dist/locale-reservas.js +87 -0
  221. package/dist/locale-retry.js +183 -6
  222. package/dist/locale-security-scan.js +69 -0
  223. package/dist/locale-setup.js +192 -0
  224. package/dist/locale-ship.js +177 -66
  225. package/dist/locale-thread.js +149 -5
  226. package/dist/locale-verify.js +80 -4
  227. package/dist/locale-worktree.js +246 -0
  228. package/dist/locale.js +553 -9
  229. package/dist/maestro-runtime.js +22 -3
  230. package/dist/manifest.js +293 -12
  231. package/dist/maquina-ociosa.js +211 -0
  232. package/dist/maquina.js +10 -5
  233. package/dist/master-nota-local.js +200 -0
  234. package/dist/master-nota.js +10 -2
  235. package/dist/master.js +118 -41
  236. package/dist/mcp-conhecimento.js +52 -0
  237. package/dist/mcp-experiencia.js +26 -5
  238. package/dist/mcp-install.js +90 -15
  239. package/dist/mcp-noctum.js +101 -0
  240. package/dist/mcp-server.js +116 -22
  241. package/dist/mcp-ship-transporte.js +977 -0
  242. package/dist/mcp-ship.js +68 -24
  243. package/dist/mcp-transportes.js +17 -0
  244. package/dist/memoria.js +63 -58
  245. package/dist/merge-da-entrega.js +85 -0
  246. package/dist/modos-migracao.js +8 -6
  247. package/dist/modos.js +17 -18
  248. package/dist/network-roadmap.js +94 -54
  249. package/dist/noctum-aceite.js +929 -0
  250. package/dist/noctum-arco.js +540 -33
  251. package/dist/noctum-capacidade.js +3 -3
  252. package/dist/noctum-changelog.js +399 -0
  253. package/dist/noctum-cli.js +539 -0
  254. package/dist/noctum-coordenacao.js +1225 -0
  255. package/dist/noctum-entrega.js +1217 -0
  256. package/dist/noctum-envelope.js +253 -17
  257. package/dist/noctum-execucao.js +100 -24
  258. package/dist/noctum-fechamento.js +416 -0
  259. package/dist/noctum-fila.js +49 -10
  260. package/dist/noctum-guarda.js +333 -0
  261. package/dist/noctum-integracao.js +507 -0
  262. package/dist/noctum-maquinas.js +387 -0
  263. package/dist/noctum-medicao.js +450 -0
  264. package/dist/noctum-modo.js +390 -0
  265. package/dist/noctum-pergunta-canal.js +96 -0
  266. package/dist/noctum-pergunta.js +115 -0
  267. package/dist/noctum-provas.js +838 -0
  268. package/dist/noctum-reconciliacao.js +594 -0
  269. package/dist/noctum-rede.js +102 -0
  270. package/dist/noctum-registro.js +215 -0
  271. package/dist/noctum-relatorio.js +861 -0
  272. package/dist/noctum-resposta.js +207 -0
  273. package/dist/noctum-retomada-rede.js +71 -0
  274. package/dist/noctum-sessoes-em-voo.js +93 -0
  275. package/dist/noctum-supervisao.js +649 -0
  276. package/dist/noctum-terminal.js +459 -0
  277. package/dist/noctum-transporte.js +655 -0
  278. package/dist/noctum-vigia.js +679 -0
  279. package/dist/ocupacao.js +3 -1
  280. package/dist/onboarding.js +16 -5
  281. package/dist/orkmind.js +39 -23
  282. package/dist/orquestracao.js +31 -35
  283. package/dist/parado-no-condutor.js +160 -139
  284. package/dist/phase.js +96 -42
  285. package/dist/policies.js +33 -0
  286. package/dist/postura-local.js +11 -6
  287. package/dist/preflight.js +2 -1
  288. package/dist/procedencia.js +9 -14
  289. package/dist/projeto-alvo.js +59 -20
  290. package/dist/prompts.js +136 -42
  291. package/dist/prova-minima.js +5 -6
  292. package/dist/pulse-cadencia.js +5 -4
  293. package/dist/pulse-consentimento.js +53 -1
  294. package/dist/pulse-delivery.js +143 -27
  295. package/dist/pulse-resposta.js +368 -4
  296. package/dist/pulse.js +136 -3
  297. package/dist/ratelimit.js +13 -4
  298. package/dist/recall.js +14 -13
  299. package/dist/rede-adesao.js +13 -8
  300. package/dist/rede-forja.js +108 -24
  301. package/dist/rede-status.js +63 -45
  302. package/dist/rede.js +86 -46
  303. package/dist/retomada-checkpoint.js +101 -0
  304. package/dist/retry.js +326 -78
  305. package/dist/roadmap-reservas.js +32 -32
  306. package/dist/runtime-ambiente.js +5 -0
  307. package/dist/runtime-context.js +279 -85
  308. package/dist/runtime-escada.js +429 -0
  309. package/dist/runtime-profiles.js +130 -63
  310. package/dist/runtimes.js +42 -5
  311. package/dist/saida-segura.js +3 -2
  312. package/dist/security-scan/agil.js +366 -0
  313. package/dist/security-scan/cli.js +76 -0
  314. package/dist/security-scan/compare.js +149 -0
  315. package/dist/security-scan/config.js +93 -0
  316. package/dist/security-scan/detect.js +97 -0
  317. package/dist/security-scan/executor.js +196 -0
  318. package/dist/security-scan/guard.js +180 -0
  319. package/dist/security-scan/imagem-de-lint.js +96 -0
  320. package/dist/security-scan/normalize/actionlint.js +12 -0
  321. package/dist/security-scan/normalize/eslint.js +12 -0
  322. package/dist/security-scan/normalize/gitleaks.js +13 -0
  323. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  324. package/dist/security-scan/normalize/govulncheck.js +36 -0
  325. package/dist/security-scan/normalize/index.js +25 -0
  326. package/dist/security-scan/normalize/npm-audit.js +30 -0
  327. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  328. package/dist/security-scan/normalize/oxlint.js +51 -0
  329. package/dist/security-scan/normalize/pip-audit.js +16 -0
  330. package/dist/security-scan/normalize/ruff.js +12 -0
  331. package/dist/security-scan/normalize/semgrep.js +20 -0
  332. package/dist/security-scan/normalize/trivy.js +33 -0
  333. package/dist/security-scan/normalize/util.js +204 -0
  334. package/dist/security-scan/normalize/zizmor.js +19 -0
  335. package/dist/security-scan/report.js +156 -0
  336. package/dist/security-scan/run.js +448 -0
  337. package/dist/security-scan/tools.js +62 -0
  338. package/dist/security-scan/trabalhador.js +74 -0
  339. package/dist/security-scan/types.js +15 -0
  340. package/dist/session-events.js +19 -2
  341. package/dist/session-watcher-claude.js +74 -19
  342. package/dist/session-watcher-grok.js +425 -0
  343. package/dist/session-watcher.js +174 -13
  344. package/dist/sessoes-contas.js +42 -5
  345. package/dist/sessoes-inventario.js +1 -1
  346. package/dist/sessoes.js +25 -23
  347. package/dist/setup.js +67 -66
  348. package/dist/ship-publicar.js +263 -92
  349. package/dist/ship.js +160 -17
  350. package/dist/superficie.js +14 -11
  351. package/dist/thread-close.js +9 -9
  352. package/dist/thread.js +121 -18
  353. package/dist/tokens.js +15 -11
  354. package/dist/trabalho-thread.js +297 -0
  355. package/dist/transporte-do-canal.js +189 -0
  356. package/dist/types.js +12 -1
  357. package/dist/util.js +5 -2
  358. package/dist/varredura-acoes.js +500 -0
  359. package/dist/verify.js +491 -32
  360. package/dist/worktree-local.js +12 -10
  361. package/dist/worktree.js +81 -85
  362. package/eval/casos/check-quality.json +77 -0
  363. package/eval/casos/security-auditor.json +148 -0
  364. package/eval/casos/security-remediation.json +161 -0
  365. package/eval/fixtures/security-scan/README.md +8 -0
  366. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  367. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  368. package/eval/fixtures/security-scan/go/README.md +4 -0
  369. package/eval/fixtures/security-scan/go/config.go +4 -0
  370. package/eval/fixtures/security-scan/go/go.mod +5 -0
  371. package/eval/fixtures/security-scan/go/go.sum +2 -0
  372. package/eval/fixtures/security-scan/go/main.go +31 -0
  373. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  374. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  375. package/eval/fixtures/security-scan/js/README.md +4 -0
  376. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  377. package/eval/fixtures/security-scan/js/package.json +10 -0
  378. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  379. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  380. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  381. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  382. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  383. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  384. package/eval/fixtures/security-scan/python/README.md +4 -0
  385. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  386. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  387. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  388. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  389. package/package.json +10 -5
  390. package/references/security-checklist.md +3 -3
  391. package/skills/README.md +1 -0
  392. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  393. package/skills/phases/check-quality/SKILL.md +16 -0
  394. package/skills/phases/go-implementation/SKILL.md +6 -0
  395. package/skills/phases/security-remediation/SKILL.md +70 -0
  396. package/skills/reviewers/security-auditor/SKILL.md +25 -0
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.TETO_DO_PROMPT_GRAVADO = exports.POLITICA_DE_RETRY = exports.ESCADA_DE_ESFORCO = void 0;
36
+ exports.LIMITE_SEM_PROVA = 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;
@@ -55,6 +55,7 @@ exports.cancelarPedido = cancelarPedido;
55
55
  exports.alvosDeFallback = alvosDeFallback;
56
56
  exports.proximoAlvo = proximoAlvo;
57
57
  exports.producaoNoIntervalo = producaoNoIntervalo;
58
+ exports.recusasSemProvaSeguidas = recusasSemProvaSeguidas;
58
59
  exports.executarRetry = executarRetry;
59
60
  exports.textoDoPlano = textoDoPlano;
60
61
  exports.textoDoRetry = textoDoRetry;
@@ -90,12 +91,15 @@ const gates_1 = require("./gates");
90
91
  const ledger_1 = require("./ledger");
91
92
  const estado_thread_1 = require("./estado-thread");
92
93
  const vida_da_thread_1 = require("./vida-da-thread");
94
+ const runtime_escada_1 = require("./runtime-escada");
95
+ const claude_bg_2 = require("./adapters/claude-bg");
93
96
  const phase_1 = require("./phase");
94
97
  const runtime_context_1 = require("./runtime-context");
95
98
  const slug_1 = require("./slug");
96
99
  const policies_1 = require("./policies");
97
100
  const ratelimit_1 = require("./ratelimit");
98
101
  const session_watcher_claude_1 = require("./session-watcher-claude");
102
+ const session_watcher_grok_1 = require("./session-watcher-grok");
99
103
  const runtime_profiles_1 = require("./runtime-profiles");
100
104
  const modos_1 = require("./modos");
101
105
  const thread_1 = require("./thread");
@@ -112,6 +116,7 @@ const procedencia_1 = require("./procedencia");
112
116
  const postura_local_1 = require("./postura-local");
113
117
  const locale_1 = require("./locale");
114
118
  const locale_retry_1 = require("./locale-retry");
119
+ const retomada_checkpoint_1 = require("./retomada-checkpoint");
115
120
  /** RM-061 (F2b, D3): `porque` e `correcao` de cada motivo tem a fonte no catalogo pt-BR; o `--json` nao muda. */
116
121
  const TEXTOS_DA_POLITICA = locale_retry_1.RETRY_PT_BR.politica;
117
122
  /**
@@ -228,10 +233,9 @@ exports.POLITICA_DE_RETRY = {
228
233
  automatica: true,
229
234
  ...TEXTOS_DA_POLITICA['runtime.rate-limited'],
230
235
  },
231
- // I-33 (D5, D11): a falha e da CONTA. O perfil sai do rodizio e o MESMO prompt vai ao proximo
232
- // perfil ativo, depois ao runtime de fallback do bloco, e so por ultimo a fila duravel. A
233
- // rotacao so redespacha quando a prova do `ork` confirma que o intervalo nao produziu nada;
234
- // producao parcial sob cota esgotada vira `human.pending`, nunca redespacho sobre a worktree.
236
+ // I-33 (D5, D11) + RM-064 T3: a falha e da CONTA. O perfil sai do rodizio e o pedido segue ao
237
+ // proximo perfil ativo, depois ao fallback e por ultimo a fila. Interrupcao no meio da fase leva
238
+ // checkpoint derivado do ledger/Git; o prompt original permanece gravado e referenciado.
235
239
  'runtime.quota-exhausted': {
236
240
  motivo: 'runtime.quota-exhausted',
237
241
  acao: 'reexecutar',
@@ -317,13 +321,15 @@ function podeReexecutar(motivo) {
317
321
  }
318
322
  /** Tabela de `ork retry policy`. */
319
323
  function tabelaDaPolitica() {
324
+ const m = (0, locale_1.msg)().retry;
325
+ const c = m.complementar;
320
326
  const linhas = Object.values(exports.POLITICA_DE_RETRY).map((p) => [
321
327
  p.motivo,
322
328
  p.acao,
323
- p.automatica ? 'sim' : 'nao',
324
- p.porque,
329
+ p.automatica ? c.sim : c.nao,
330
+ m.politica[p.motivo].porque,
325
331
  ]);
326
- return (0, util_1.tabela)(['MOTIVO TIPADO', 'ACAO DE RETRY', 'AUTOMATICA', 'POR QUE'], linhas);
332
+ return (0, util_1.tabela)([...c.colunasPolitica], linhas);
327
333
  }
328
334
  /** A fase a que um evento de gate reprovado se refere. */
329
335
  function faseDoEvento(evento, thread) {
@@ -353,8 +359,12 @@ function ultimaReprovacao(raiz, threadId) {
353
359
  * planejou: planejar nao gasta janela nem toca no repositorio.
354
360
  */
355
361
  function tentativasFeitas(raiz, threadId, fase, motivo) {
362
+ const eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId));
363
+ // RM-063 (F4): a escada de `runtime.unavailable` vale por episodio, e as tentativas dela tambem: o pedido novo da fase
364
+ // (`ork phase run`) recomeca a contagem.
365
+ const desde = motivo === 'runtime.unavailable' ? (0, runtime_escada_1.inicioDoEpisodio)(eventos, fase) : -1;
356
366
  // 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;
367
+ return eventos.filter((e, i) => i > desde && e.tipo === ledger_1.TIPOS_DE_EVENTO.retryTentado && e.fase === fase && e.motivo === motivo && e.conta !== false).length;
358
368
  }
359
369
  /** O bloco de loop desta fase pausa para o humano neste modo? */
360
370
  function blocoPausa(thread, fase) {
@@ -417,6 +427,17 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
417
427
  razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.politica[motivo].porque),
418
428
  };
419
429
  }
430
+ // RM-063 (F4): a escada de `runtime.unavailable` diz o proximo degrau do episodio; sem degrau, o dono e chamado.
431
+ const escada = motivo === 'runtime.unavailable' ? (0, runtime_escada_1.estadoDaEscada)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)), fase) : null;
432
+ const naEscada = escada ? { degrau: escada.proximo, tipo: escada.proximo ? runtime_escada_1.DEGRAUS_DA_ESCADA[escada.proximo - 1] : null,
433
+ consumidos: escada.consumidos.map((d) => ({ degrau: d.degrau, tipo: d.tipo, resultado: d.resultado, em: d.em })) } : null;
434
+ if (escada && escada.proximo === null) {
435
+ return {
436
+ thread: threadId, modo: thread.modo, fase, motivo, detalhe, politica, acao: 'escalar-humano', tentativas, limite,
437
+ effort: effortBase, effortAnterior: effortBase, automatica: false, bloqueio: 'escalacao.limite',
438
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.retry.escada.esgotada((0, runtime_escada_1.resumoDosDegraus)(escada.consumidos))), escada: naEscada,
439
+ };
440
+ }
420
441
  // Limite de escalacao: pausa QUALQUER modo, inclusive #Auto.
421
442
  if (tentativas >= limite) {
422
443
  return {
@@ -439,7 +460,8 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
439
460
  // Da 2a tentativa em diante o esforco sobe um degrau, quando o manifesto permite.
440
461
  // `tentativas` e quantas JA rodaram, entao a 1a tentativa (tentativas 0) sai no
441
462
  // esforco base do manifesto e so a partir da 2a a escada anda.
442
- const escala = manifesto.retry.escalar_esforco && tentativas >= 1;
463
+ // RM-063 (F4): runtime fora nao e prompt fraco. A escada de `runtime.unavailable` troca o destino, nunca o esforco.
464
+ const escala = manifesto.retry.escalar_esforco && tentativas >= 1 && !escada;
443
465
  const effortAnterior = escalarEsforco(effortBase, Math.max(0, tentativas - 1));
444
466
  const effort = escala ? escalarEsforco(effortBase, tentativas) : effortBase;
445
467
  const acao = escala ? 'escalar-esforco' : politica.acao;
@@ -450,6 +472,10 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
450
472
  let bloqueio = null;
451
473
  let automatica = politica.automatica;
452
474
  let razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.politica[motivo].porque);
475
+ // RM-063 (F4): o plano de `runtime.unavailable` diz o degrau da escada que a execucao sobe.
476
+ const degrau = escada?.proximo ?? null;
477
+ if (degrau)
478
+ razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.escada.proximo(degrau, m.retry.escada.degraus[runtime_escada_1.DEGRAUS_DA_ESCADA[degrau - 1]]));
453
479
  if (delegacao.permitida && politica.automatica) {
454
480
  razao = (0, locale_1.textoDoCatalogo)((m) => m.retry.comDelegacao(m.retry.politica[motivo].porque, delegacao.razao, String(delegacao.delegado), String(delegacao.evidencia)));
455
481
  }
@@ -476,7 +502,7 @@ function planejarRetry(carregado, threadId, opcoes = {}) {
476
502
  }
477
503
  return {
478
504
  thread: threadId, modo: thread.modo, fase, motivo, detalhe, politica, acao, tentativas,
479
- limite, effort, effortAnterior, automatica, bloqueio, razao,
505
+ limite, effort, effortAnterior, automatica, bloqueio, razao, ...(naEscada ? { escada: naEscada } : {}),
480
506
  };
481
507
  }
482
508
  /** O esforco depois de `n` escaladas a partir do esforco base do manifesto. */
@@ -606,8 +632,8 @@ tomadaPrevia) {
606
632
  dryRun: opcoes.dryRun === true,
607
633
  };
608
634
  }
609
- const prompt = fs.readFileSync(absoluto, 'utf8');
610
- const shaAtual = (0, phase_1.hashDoPrompt)(prompt);
635
+ const promptOriginal = fs.readFileSync(absoluto, 'utf8');
636
+ const shaAtual = (0, phase_1.hashDoPrompt)(promptOriginal);
611
637
  if (shaAtual !== sha) {
612
638
  return {
613
639
  ...vazio,
@@ -617,6 +643,10 @@ tomadaPrevia) {
617
643
  dryRun: opcoes.dryRun === true,
618
644
  };
619
645
  }
646
+ const retomada = opcoes.checkpoint ? (0, retomada_checkpoint_1.prepararPromptDeRetomada)(raiz, thread, fase, { prompt: promptOriginal, promptPath: absoluto, promptSha256: sha }, !opcoes.dryRun) : null;
647
+ const prompt = retomada?.prompt ?? promptOriginal;
648
+ const promptExecutadoPath = retomada?.promptPath ?? absoluto;
649
+ const promptExecutadoSha = retomada?.promptSha256 ?? sha;
620
650
  const violacoes = (0, policies_1.bloqueantes)((0, policies_1.avaliarPolicies)(manifesto, { gate: 'phase.dispatch', prompt }));
621
651
  if (violacoes.length > 0) {
622
652
  const motivo = (0, policies_1.motivoDominante)(violacoes);
@@ -630,7 +660,8 @@ tomadaPrevia) {
630
660
  fase,
631
661
  slug,
632
662
  origem: opcoes.origem ?? 'retry',
633
- evidencia: `prompt sha256 ${sha} (retomada recusada antes de despachar)`,
663
+ evidencia: `prompt sha256 ${promptExecutadoSha} (origem ${sha}; retomada recusada antes de despachar)`,
664
+ ...(opcoes.perfilPedido ? { perfilPedido: opcoes.perfilPedido } : {}),
634
665
  });
635
666
  return { ...vazio, ok: false, motivo, detalhe, dryRun: opcoes.dryRun === true };
636
667
  }
@@ -641,7 +672,7 @@ tomadaPrevia) {
641
672
  : (0, runtime_context_1.novaIdentidadeDeDespacho)(thread.id, fase);
642
673
  const canal = opcoes.canal ?? (0, conducao_1.canalDoProcesso)();
643
674
  const doBlocoDaConducao = (0, setup_1.limitesDoBloco)(manifesto, (0, setup_1.lerSetup)(raiz), thread.modo, fase);
644
- const pedidoDeConducao = { canal, correlacao: null, operacao: 'retry.run', fase, promptSha256: sha,
675
+ const pedidoDeConducao = { canal, correlacao: null, operacao: 'retry.run', fase, promptSha256: promptExecutadoSha,
645
676
  identidade: identidade.dispatchId, prazoMs: (0, phase_1.prazoDaSessao)(doBlocoDaConducao) };
646
677
  let conducao = null;
647
678
  if (tomadaPrevia) {
@@ -658,7 +689,7 @@ tomadaPrevia) {
658
689
  const tomada = (0, conducao_1.tomarConducao)(raiz, thread.id, pedidoDeConducao);
659
690
  if (!tomada.ok) {
660
691
  if (tomada.idempotente && tomada.atual) {
661
- (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, ledger_1.TIPOS_DE_EVENTO.despachoIdempotente, { fase, promptSha256: sha, canal,
692
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, ledger_1.TIPOS_DE_EVENTO.despachoIdempotente, { fase, promptSha256: promptExecutadoSha, canal,
662
693
  sessionId: tomada.atual.sessao, origem: opcoes.origem ?? 'retry',
663
694
  razao: 'mesma fase e mesmo prompt de quem ja conduz: a sessao em andamento atende a retomada, sem sessao nova' });
664
695
  const sessao = String(tomada.atual.sessao).slice(0, 8);
@@ -677,8 +708,9 @@ tomadaPrevia) {
677
708
  try {
678
709
  cwd = opcoes.cwd !== undefined ? (0, procedencia_1.exigirCwdLocal)(raiz, thread.id, opcoes.cwd, 'fila') : (0, procedencia_1.diretorioDaThread)(raiz, thread);
679
710
  }
711
+ // RM-061 (F3b, GO-FIX 1): o erro do catalogo fica registrado, e a impressao o remonta.
680
712
  catch (e) {
681
- return { ...vazio, ok: false, motivo: 'tree.blocked', detalhe: e.message, dryRun: opcoes.dryRun === true };
713
+ return { ...vazio, ok: false, motivo: 'tree.blocked', detalhe: (0, locale_1.textoDoErro)(e), dryRun: opcoes.dryRun === true };
682
714
  }
683
715
  // Mesma resolucao do `ork phase run`: a retomada carimba no ledger o trio que ela de
684
716
  // fato despachou, inclusive quando o pedido da fila trazia um modelo proprio. O setup
@@ -711,22 +743,27 @@ tomadaPrevia) {
711
743
  }
712
744
  return pendente;
713
745
  }
714
- // D14 (GO-FIX 2): a retomada claude-bg abre com a mesma colaboração e o mesmo contexto de
715
- // runtime do `ork phase run`; sem eles, o PLAN retomado saía sem negar Edit, Write e
716
- // NotebookEdit e sem a allowlist do núcleo. O ramo Codex não muda.
746
+ // RM-064 T8: toda retomada abre com o mesmo contexto de runtime do `ork phase run`.
747
+ // Sem ele, a escada que troca para Codex perde o MCP vinculado à thread e ao despacho.
717
748
  let contextoRuntime;
718
- if (runtime === 'claude-bg') {
719
- try {
720
- contextoRuntime = (0, runtime_context_1.contextoDoProjeto)(raiz, runtime, cwd, thread.id);
721
- }
722
- catch (e) {
723
- const erro = e.message;
724
- return { ...vazio, ok: false, motivo: 'runtime.unavailable',
725
- detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeIndisponivel(erro)), dryRun: opcoes.dryRun === true };
726
- }
727
- if (contextoRuntime)
728
- contextoRuntime.identidade = identidade;
749
+ try {
750
+ contextoRuntime = (0, runtime_context_1.contextoDoProjeto)(raiz, runtime, cwd, thread.id);
751
+ }
752
+ catch (e) {
753
+ const erro = e.message;
754
+ if (!opcoes.dryRun && opcoes.perfilPedido)
755
+ (0, gates_1.registrarGateBloqueado)((0, thread_1.dirThread)(raiz, thread.id), thread.id, {
756
+ gate: 'phase.dispatch', motivo: 'runtime.unavailable', modo: thread.modo,
757
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.perfilPedidoRecusado(opcoes.perfilPedido.id, opcoes.perfilPedido.runtime, 'runtime.unavailable', erro)),
758
+ correcao: (0, locale_1.textoDoCatalogo)((m) => m.retry.correcaoDoPerfilPedido(opcoes.perfilPedido.id, opcoes.perfilPedido.runtime, 'runtime.unavailable', thread.id)),
759
+ fase, slug, origem: opcoes.origem ?? 'retry', promptPath: promptExecutadoPath,
760
+ promptSha256: promptExecutadoSha, perfilPedido: opcoes.perfilPedido,
761
+ });
762
+ return { ...vazio, ok: false, motivo: 'runtime.unavailable',
763
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeIndisponivel(erro)), dryRun: opcoes.dryRun === true };
729
764
  }
765
+ if (contextoRuntime)
766
+ contextoRuntime.identidade = identidade;
730
767
  // I-33 (D4, D7): a retomada escolhe o perfil como o `ork phase run`, com o login conferido.
731
768
  let escolha;
732
769
  try {
@@ -739,12 +776,23 @@ tomadaPrevia) {
739
776
  if (escolha.erro) {
740
777
  const motivo = escolha.motivo ?? 'runtime.unavailable';
741
778
  const prazo = motivo === 'runtime.quota-exhausted' ? (0, runtime_profiles_1.prazoDoRuntime)((0, runtime_profiles_1.lerPerfisComContas)(raiz), runtime, (0, runtime_profiles_1.politicaDeRotacao)(manifesto)) : null;
742
- return { ...vazio, ok: false, motivo, detalhe: `${motivo}: ${escolha.erro}`, dryRun: opcoes.dryRun === true,
779
+ const detalhe = opcoes.perfilPedido
780
+ ? (0, locale_1.textoDoCatalogo)((m) => m.retry.perfilPedidoRecusado(opcoes.perfilPedido.id, opcoes.perfilPedido.runtime, motivo, escolha.erro))
781
+ : `${motivo}: ${escolha.erro}`;
782
+ if (!opcoes.dryRun && opcoes.perfilPedido)
783
+ (0, gates_1.registrarGateBloqueado)((0, thread_1.dirThread)(raiz, thread.id), thread.id, {
784
+ gate: 'phase.dispatch', motivo, modo: thread.modo, detalhe,
785
+ correcao: (0, locale_1.textoDoCatalogo)((m) => m.retry.correcaoDoPerfilPedido(opcoes.perfilPedido.id, opcoes.perfilPedido.runtime, motivo, thread.id)), fase, slug, origem: opcoes.origem ?? 'retry',
786
+ promptPath: promptExecutadoPath, promptSha256: promptExecutadoSha, perfilPedido: opcoes.perfilPedido,
787
+ });
788
+ return { ...vazio, ok: false, motivo, detalhe, dryRun: opcoes.dryRun === true,
743
789
  sinal: prazo ? { resetEm: prazo, fonte: 'iso', trecho: `menor esgotadoAte dos perfis ${runtime}` } : null };
744
790
  }
745
791
  const perfil = escolha.perfil ?? undefined;
746
- // I-33 (N1): o HEAD do GO codex sai antes do despacho, como no `ork phase run`.
747
- const headNoDespacho = fase === 'GO' && runtime === 'codex' && !opcoes.dryRun ? (0, session_watcher_claude_1.headDaWorktree)(cwd) : undefined;
792
+ // I-33 (N1): o HEAD do GO codex sai antes do despacho, como no `ork phase run`. RM-067: o grok tambem.
793
+ const headNoDespacho = fase === 'GO' && (runtime === 'codex' || runtime === 'grok') && !opcoes.dryRun ? (0, session_watcher_claude_1.headDaWorktree)(cwd) : undefined;
794
+ // RM-067 (D8): a base do artefato do grok tambem sai antes do redespacho, como no `ork phase run`.
795
+ const artefatoNoDespacho = runtime === 'grok' && !opcoes.dryRun ? (0, session_watcher_grok_1.baseDoArtefato)(raiz, thread.id, fase) : undefined;
748
796
  const resultado = rt.despachar({
749
797
  prompt,
750
798
  nome: slug,
@@ -754,10 +802,12 @@ tomadaPrevia) {
754
802
  dryRun: opcoes.dryRun,
755
803
  sandbox: manifesto.runtime.sandbox,
756
804
  logDir: path.join((0, thread_1.dirThread)(raiz, thread.id), 'sessoes'),
757
- vinculo: { thread: thread.id, fase, promptSha256: sha },
805
+ vinculo: { thread: thread.id, fase, promptSha256: promptExecutadoSha },
758
806
  ...(perfil ? { perfil } : {}),
759
807
  // RM-037 (defeito 2): o modo plano segue a mesma regra do `ork phase run`, pelo bloco.
760
- ...(runtime === 'claude-bg' ? { contextoRuntime, ...((0, phase_1.modoDaSessaoDoBloco)(thread, fase).plano ? { colaboracao: 'plan' } : {}) } : {}),
808
+ contextoRuntime,
809
+ // RM-067 (GO-FIX 1, A3): o grok tambem; no PLAN que fecha o bloco, ele roda em read-only.
810
+ ...((runtime === 'claude-bg' || runtime === 'grok') && (0, phase_1.modoDaSessaoDoBloco)(thread, fase).plano ? { colaboracao: 'plan' } : {}),
761
811
  // I-36 (D4): a sessao retomada herda a identidade do despacho e o canal, como no `ork phase run`.
762
812
  ambienteExtra: (0, conducao_1.ambienteDaConducao)(identidade.dispatchId, thread.id, canal),
763
813
  });
@@ -775,15 +825,21 @@ tomadaPrevia) {
775
825
  };
776
826
  }
777
827
  if (!resultado.ok || !resultado.sessionId) {
828
+ // RM-063 (F4, GO-FIX): o `claude --bg` lento diz o id e estoura o prazo com a sessao aberta. A falha guarda a sessao,
829
+ // como no `ork phase run`: e por ela que o retry e a escada provam que ninguem trabalha na worktree antes de outro
830
+ // destino.
831
+ const daSessao = resultado.sessionId ? { sessionId: resultado.sessionId } : {};
778
832
  (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, 'phase_dispatch_failed', { fase, runtime, slug, cwd,
779
- promptPath: absoluto, promptSha256: sha, controlador: resultado.controlador, model, effort,
833
+ promptPath: promptExecutadoPath, promptSha256: promptExecutadoSha,
834
+ ...(retomada ? { promptOriginalPath: absoluto, promptOriginalSha256: sha } : {}),
835
+ controlador: resultado.controlador, model, effort,
780
836
  erro: resultado.erro ?? 'runtime.unavailable: sem sessionId', stderr: (resultado.stderr ?? '').slice(0, 500),
781
- origem: 'retry', ...(perfil ? { perfil } : {}) });
837
+ origem: 'retry', ...(perfil ? { perfil } : {}), ...(opcoes.perfilPedido ? { perfilPedido: opcoes.perfilPedido } : {}), ...daSessao });
782
838
  const sinal = resultado.rateLimit ?? null;
783
839
  // RM-055: o redespacho recusado pelo que so o dono resolve reabre a pausa dele, com o mesmo comando.
784
840
  const impedimento = !resultado.falhaDeConta && !sinal
785
841
  ? (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 ?? ''}` })
842
+ promptPath: promptExecutadoPath, promptSha256: promptExecutadoSha, perfil, saida: `${resultado.stderr ?? ''}\n${resultado.erro ?? ''}` })
787
843
  : null;
788
844
  if (impedimento) {
789
845
  return { ok: false, slug, sessionId: null, verificada: false, motivo: impedimento.motivo,
@@ -800,7 +856,7 @@ tomadaPrevia) {
800
856
  return {
801
857
  ok: false,
802
858
  slug,
803
- sessionId: null,
859
+ sessionId: resultado.sessionId ?? null,
804
860
  verificada: false,
805
861
  // I-33 (D11b): falha de conta reconhecida na saida e o motivo mais especifico.
806
862
  motivo: resultado.falhaDeConta?.motivo ?? (sinal ? 'runtime.rate-limited' : 'runtime.unavailable'),
@@ -822,27 +878,33 @@ tomadaPrevia) {
822
878
  thread,
823
879
  fase,
824
880
  slug,
825
- promptPath: absoluto,
826
- promptSha256: sha,
881
+ promptPath: promptExecutadoPath,
882
+ promptSha256: promptExecutadoSha,
883
+ ...(retomada ? { promptOriginal: { path: absoluto, sha256: sha } } : {}),
827
884
  runtime,
828
885
  cwd,
829
886
  model,
830
887
  effort,
831
888
  origem: opcoes.origem ?? 'retry',
832
889
  ...(perfil ? { perfil } : {}),
890
+ ...(opcoes.perfilPedido ? { perfilPedido: opcoes.perfilPedido } : {}),
833
891
  ...(headNoDespacho !== undefined ? { headNoDespacho } : {}),
892
+ ...(artefatoNoDespacho !== undefined ? { artefatoNoDespacho } : {}),
834
893
  };
835
- (0, phase_1.concluirDespacho)(ctx, resultado.sessionId, resultado.verificada, resultado.comando, rt.fonteVerificacao, resultado.controlador);
894
+ // RM-067 (D14 da ork-grokbuild): o redespacho do grok leva os sensores do supervisor ao registro do watcher; o caminho
895
+ // do codex e do claude-bg segue sem eles, como antes.
896
+ (0, phase_1.concluirDespacho)(ctx, resultado.sessionId, resultado.verificada, resultado.comando, rt.fonteVerificacao, resultado.controlador, runtime === 'grok' ? { logPath: resultado.logPath, processoPath: resultado.processoPath, reciboPath: resultado.reciboPath } : undefined);
836
897
  return {
837
898
  ok: true,
838
899
  slug,
839
900
  sessionId: resultado.sessionId,
840
901
  verificada: resultado.verificada,
841
902
  motivo: null,
842
- detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.redespachada(String(resultado.sessionId), sha.slice(0, 12), perfil ? perfil.id : null, runtime)),
903
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.redespachada(String(resultado.sessionId), promptExecutadoSha.slice(0, 12), perfil ? perfil.id : null, runtime)),
843
904
  sinal: null,
844
905
  perfil: perfil ?? null,
845
906
  comando: resultado.comando,
907
+ controlador: resultado.controlador,
846
908
  dryRun: false,
847
909
  };
848
910
  }
@@ -895,6 +957,15 @@ function playbookDaRetomada(carregado, pedido, opcoes = {}) {
895
957
  function retomarPedido(carregado, pedidoOriginal, opcoes = {}) {
896
958
  const { raiz } = carregado;
897
959
  const quando = opcoes.quando ?? (0, util_1.agora)();
960
+ // RM-058 N4 (D17 da ork-rm058n4): o pedido do despacho de um arco #Noctum é retomado pelo vigia do arco, pelo passo dele
961
+ // (conferência do envelope e reserva). Aqui ele não é redespachado nem regravado, e o ledger da thread não muda.
962
+ const arco = (0, ratelimit_1.arcoDoPedido)(pedidoOriginal);
963
+ if (arco) {
964
+ return { pedido: pedidoOriginal, playbook: 'mesma-sessao', slug: pedidoOriginal.slug, despachada: false, sessionId: null, verificada: false,
965
+ motivo: null, dryRun: opcoes.dryRun === true,
966
+ detalhe: `o pedido ${pedidoOriginal.id} é do arco ${arco}: quem o retoma é o vigia do arco, com a conferência do envelope e a reserva; ` +
967
+ `nada foi despachado (sem o vigia, o dono tira o pedido da fila com ork retry cancel ${pedidoOriginal.id} --motivo "..." e retoma a fase à mão)` };
968
+ }
898
969
  const thread = (0, thread_1.lerThread)(raiz, pedidoOriginal.thread);
899
970
  const dir = (0, thread_1.dirThread)(raiz, thread.id);
900
971
  let pedido = pedidoOriginal;
@@ -969,10 +1040,12 @@ function retomarPedido(carregado, pedidoOriginal, opcoes = {}) {
969
1040
  slug,
970
1041
  runtime: alvo.runtime,
971
1042
  perfil: alvo.perfil ?? doPedido.perfil ?? null,
1043
+ ...(doPedido.perfilPedido ? { perfilPedido: doPedido.perfilPedido } : {}),
972
1044
  model: alvo.model,
973
1045
  effort: alvo.effort,
974
1046
  cwd: pedido.cwd,
975
1047
  origem: 'retry.rate-limit',
1048
+ checkpoint: doPedido.checkpoint === true,
976
1049
  dryRun: opcoes.dryRun,
977
1050
  });
978
1051
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.retryTentado, {
@@ -1078,13 +1151,18 @@ function retomarPedido(carregado, pedidoOriginal, opcoes = {}) {
1078
1151
  function alvoDaRetomada(carregado, thread, pedido) {
1079
1152
  const { raiz, manifesto } = carregado;
1080
1153
  const original = { runtime: pedido.runtime ?? null, model: pedido.model, effort: pedido.effort };
1154
+ if (pedido.perfilPedido)
1155
+ return { runtime: pedido.perfilPedido.runtime, perfil: pedido.perfilPedido.id,
1156
+ model: pedido.model, effort: pedido.effort, destino: true, runtimes: [pedido.perfilPedido.runtime], contas: false };
1081
1157
  if (pedido.motivo !== 'runtime.quota-exhausted' && pedido.motivo !== 'runtime.auth-missing')
1082
1158
  return { ...original, destino: true, runtimes: original.runtime ? [original.runtime] : [], contas: false };
1083
1159
  const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, pedido.fase);
1084
1160
  const principal = pedido.runtime ?? doBloco?.runtime ?? manifesto.runtime.adapter;
1085
1161
  const candidatos = [{ runtime: principal, model: pedido.model, effort: pedido.effort },
1086
1162
  ...alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter).filter(f => f.runtime !== principal)
1087
- .map(f => ({ runtime: f.runtime, model: f.model, effort: f.effort ?? pedido.effort }))];
1163
+ .map(f => ({ runtime: f.runtime, model: f.model, effort: f.effort ?? pedido.effort }))]
1164
+ // RM-067 (F4): a troca de conta do runtime principal vale tambem para o runtime sem host MCP (o grok).
1165
+ .filter(c => (0, runtime_context_1.capacidadeDaRotacao)(raiz, c.runtime, c.runtime === principal).capaz);
1088
1166
  const runtimes = candidatos.map(c => c.runtime);
1089
1167
  const store = (0, runtime_profiles_1.lerPerfisComContas)(raiz), politica = (0, runtime_profiles_1.politicaDeRotacao)(manifesto);
1090
1168
  for (const c of candidatos) {
@@ -1145,11 +1223,12 @@ function alvosDeFallback(bloco, principal) {
1145
1223
  function proximoAlvo(raiz, atual, fallback, excluir, politica, agoraMs = Date.now()) {
1146
1224
  const store = (0, runtime_profiles_1.lerPerfisComContas)(raiz, agoraMs);
1147
1225
  const perfis = [...excluir.perfis, ...(atual.perfil ? [atual.perfil.id] : [])];
1148
- const mesmo = (0, runtime_profiles_1.proximoPerfilDisponivel)(store, atual.runtime, politica, { excluir: perfis, agoraMs });
1226
+ const mesmo = (0, runtime_context_1.capacidadeDaRotacao)(raiz, atual.runtime, true).capaz
1227
+ ? (0, runtime_profiles_1.proximoPerfilDisponivel)(store, atual.runtime, politica, { excluir: perfis, agoraMs }) : null;
1149
1228
  if (mesmo)
1150
1229
  return { runtime: atual.runtime, perfil: (0, runtime_profiles_1.perfilDeDespacho)(mesmo), model: null, effort: null };
1151
1230
  for (const f of fallback) {
1152
- if (f.runtime === atual.runtime)
1231
+ if (f.runtime === atual.runtime || !(0, runtime_context_1.capacidadeDoRuntimeNoProjeto)(raiz, f.runtime).capaz)
1153
1232
  continue;
1154
1233
  if ((0, runtime_profiles_1.perfisDoRuntime)(store, f.runtime).length > 0) {
1155
1234
  const p = (0, runtime_profiles_1.proximoPerfilDisponivel)(store, f.runtime, politica, { excluir: perfis, agoraMs });
@@ -1220,6 +1299,41 @@ function despachoDaFalha(eventos, gate, fase) {
1220
1299
  function perfilDoEvento(e) {
1221
1300
  return e && e.perfil !== undefined && e.perfil !== null ? (0, runtime_profiles_1.validarPerfilDeDespacho)(e.perfil) : null;
1222
1301
  }
1302
+ /** O marcador distinto do destino efetivo: ausente em despacho sem `--perfil` e em rotacao interna. */
1303
+ function perfilPedidoDoEvento(e) {
1304
+ if (!e || e.perfilPedido === undefined || e.perfilPedido === null)
1305
+ return null;
1306
+ if (typeof e.perfilPedido !== 'object' || Array.isArray(e.perfilPedido))
1307
+ return null;
1308
+ const p = e.perfilPedido;
1309
+ if (typeof p.runtime !== 'string' || p.runtime.length === 0 || p.runtime.length > 64)
1310
+ return null;
1311
+ try {
1312
+ return { id: (0, runtime_profiles_1.validarIdDePerfil)(p.id), runtime: p.runtime };
1313
+ }
1314
+ catch {
1315
+ return null;
1316
+ }
1317
+ }
1318
+ /** Recupera o pedido do mesmo prompt; eventos antigos sem o campo preservam o comportamento anterior. */
1319
+ function perfilPedidoDoDespacho(eventos, fase, despacho, gate) {
1320
+ for (const e of [gate, despacho]) {
1321
+ const p = perfilPedidoDoEvento(e);
1322
+ if (p)
1323
+ return p;
1324
+ }
1325
+ const sha = typeof despacho?.promptSha256 === 'string' ? despacho.promptSha256
1326
+ : typeof gate?.promptSha256 === 'string' ? gate.promptSha256 : null;
1327
+ for (let i = eventos.length - 1; i >= 0; i--) {
1328
+ const e = eventos[i];
1329
+ if (e.fase !== fase || (sha !== null && e.promptSha256 !== sha))
1330
+ continue;
1331
+ const p = perfilPedidoDoEvento(e);
1332
+ if (p)
1333
+ return p;
1334
+ }
1335
+ return null;
1336
+ }
1223
1337
  /** O perfil ja esta fora do rodizio por esta falha (cota com prazo futuro, ou sem login)? */
1224
1338
  function jaMarcado(raiz, perfil, falha, agoraMs = Date.now()) {
1225
1339
  let atual;
@@ -1263,6 +1377,25 @@ function ultimoDespachoFalho(raiz, threadId, fase, silencio = false) {
1263
1377
  }
1264
1378
  return null;
1265
1379
  }
1380
+ /**
1381
+ * RM-063 (F4, GO-FIX): quantas recusas seguidas, no episodio da fase, sairam porque o runtime nao respondeu a prova de
1382
+ * vida (`semProva`). Uma tentativa que andou (contada, ou recusada com sessao viva) zera a conta.
1383
+ */
1384
+ function recusasSemProvaSeguidas(eventos, fase) {
1385
+ const desde = (0, runtime_escada_1.inicioDoEpisodio)(eventos, fase);
1386
+ let seguidas = 0;
1387
+ for (let i = eventos.length - 1; i > desde; i--) {
1388
+ const e = eventos[i];
1389
+ if (e.tipo !== ledger_1.TIPOS_DE_EVENTO.retryTentado || e.fase !== fase || e.motivo !== 'runtime.unavailable')
1390
+ continue;
1391
+ if (e.semProva !== true)
1392
+ break;
1393
+ seguidas += 1;
1394
+ }
1395
+ return seguidas;
1396
+ }
1397
+ /** Recusas seguidas sem resposta do runtime, no mesmo episodio, ate o dono ser chamado. */
1398
+ exports.LIMITE_SEM_PROVA = 3;
1266
1399
  /**
1267
1400
  * Executa a acao de retry do ultimo gate reprovado da thread.
1268
1401
  *
@@ -1308,6 +1441,28 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1308
1441
  razao: plano.razao,
1309
1442
  });
1310
1443
  if (!plano.automatica || plano.motivo === null) {
1444
+ // RM-063 (F4, GO-FIX, achado 9): a escada esgotada pelo plano (a sessao do ultimo degrau morreu depois) chama o dono
1445
+ // pela escada, com as alternativas e o comando que retoma com o mesmo prompt; a escalada generica so repetia o retry.
1446
+ if (plano.motivo === 'runtime.unavailable' && plano.escada && plano.escada.degrau === null && plano.fase && !opcoes.dryRun) {
1447
+ const eventos = (0, ledger_1.lerLedger)(dir);
1448
+ const ultimo = despachoParaRedespachar(eventos, plano.fase, null);
1449
+ if (ultimo && typeof ultimo.promptPath === 'string' && typeof ultimo.promptSha256 === 'string') {
1450
+ const origem = (0, runtime_escada_1.destinoDoEpisodio)(eventos, plano.fase);
1451
+ let perfil = null;
1452
+ try {
1453
+ perfil = perfilDoEvento(ultimo);
1454
+ }
1455
+ catch {
1456
+ perfil = null;
1457
+ }
1458
+ const despacho = { promptPath: localizarPromptGravado(raiz, threadId, ultimo.promptPath, ultimo.promptSha256) ?? ultimo.promptPath,
1459
+ promptSha256: ultimo.promptSha256, perfil: origem?.perfil ?? perfil,
1460
+ runtime: origem?.runtime ?? (typeof ultimo.runtime === 'string' ? ultimo.runtime : carregado.manifesto.runtime.adapter),
1461
+ model: origem?.model ?? null, effort: origem?.effort ?? null };
1462
+ const detalhe = (0, runtime_escada_1.escalarEscada)(carregado, thread, plano.fase, despacho, (0, runtime_escada_1.estadoDaEscada)(eventos, plano.fase).consumidos, plano.tentativas, plano.limite);
1463
+ return { ...vazio, detalhe };
1464
+ }
1465
+ }
1311
1466
  // Escalacao e custo viram gate humano explicito no ledger, nao silencio.
1312
1467
  if (plano.bloqueio === 'escalacao.limite' || plano.acao === 'sem-retry') {
1313
1468
  (0, gates_1.registrarGateBloqueado)(dir, threadId, {
@@ -1372,7 +1527,8 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1372
1527
  }
1373
1528
  if (acaoBase === 'sincronizar-worktree') {
1374
1529
  const sync = (0, worktree_1.sincronizarWorktree)(carregado, threadId, { dryRun: opcoes.dryRun });
1375
- const detalhe = (0, locale_1.textoDoCatalogo)((m) => sync.ok ? m.retry.sincronizada(sync.passos.join('; ')) : m.retry.sincronizacaoFalhou(sync.detalhe));
1530
+ // RM-061 (F3b): o detalhe da worktree tambem vem do catalogo; remontado aqui, ele segue o locale da impressao.
1531
+ const detalhe = (0, locale_1.textoDoCatalogo)((m) => sync.ok ? m.retry.sincronizada(sync.passos.join('; ')) : m.retry.sincronizacaoFalhou((0, locale_1.remontar)(sync.detalhe)));
1376
1532
  registrarTentativa(sync.ok, detalhe);
1377
1533
  return { ...vazio, executada: sync.ok, sync, detalhe };
1378
1534
  }
@@ -1386,7 +1542,29 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1386
1542
  registrarTentativa(rodada.correcoes.length > 0, detalhe);
1387
1543
  return { ...vazio, executada: rodada.correcoes.length > 0, rodada, reverify, detalhe };
1388
1544
  }
1545
+ const redespacharNoPerfilPedido = (falho, pedido) => {
1546
+ const r = redespachar(carregado, thread, plano.fase, String(falho.promptPath), String(falho.promptSha256), {
1547
+ runtime: pedido.runtime,
1548
+ perfil: pedido.id,
1549
+ perfilPedido: pedido,
1550
+ model: typeof falho.model === 'string' ? falho.model : null,
1551
+ effort: plano.effort ?? (typeof falho.effort === 'string' ? falho.effort : null),
1552
+ origem: 'retry.run',
1553
+ dryRun: opcoes.dryRun,
1554
+ });
1555
+ registrarTentativa(r.ok, r.detalhe, { perfilPedido: pedido, ...(!r.ok ? { conta: false } : {}) });
1556
+ return { ...vazio, executada: r.ok, redespacho: r, detalhe: r.detalhe };
1557
+ };
1389
1558
  if (plano.motivo === 'runtime.quota-exhausted' || plano.motivo === 'runtime.auth-missing') {
1559
+ const eventos = (0, ledger_1.lerLedger)(dir);
1560
+ const gate = ultimaReprovacao(raiz, threadId);
1561
+ const falho = despachoParaRedespachar(eventos, plano.fase, gate);
1562
+ const pedido = perfilPedidoDoDespacho(eventos, plano.fase, falho, gate);
1563
+ // Falha observada na propria conta continua na rotacao I-33 D5/RM-064 T3. A indisponibilidade
1564
+ // detectada antes de abrir a conta preserva o pedido do dono e nunca escolhe outra em silencio.
1565
+ if (pedido && gate?.falhaDeConta === undefined && falho && typeof falho.promptPath === 'string' &&
1566
+ typeof falho.promptSha256 === 'string')
1567
+ return redespacharNoPerfilPedido(falho, pedido);
1390
1568
  return rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTentativa);
1391
1569
  }
1392
1570
  if (plano.motivo === 'runtime.model-unavailable') {
@@ -1403,6 +1581,7 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1403
1581
  registrarTentativa(false, detalhe);
1404
1582
  return { ...vazio, detalhe };
1405
1583
  }
1584
+ const perfilPedidoDoRetry = perfilPedidoDoDespacho((0, ledger_1.lerLedger)(dir), plano.fase, falho, gateDoPlano);
1406
1585
  // RM-055: o impedimento do dono com prova local (confianca do diretorio) so volta ao runtime depois de
1407
1586
  // resolvido. Sem a prova, nada e despachado e a tentativa nao conta: a pausa do dono continua aberta.
1408
1587
  if (plano.motivo && (0, impedimento_1.ehImpedimentoDoDono)(plano.motivo) && typeof falho.cwd === 'string') {
@@ -1419,7 +1598,63 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1419
1598
  // despacho que falhou depois de abrir a sessao (o `claude --bg` lento) e o adaptador que lanca deixariam duas sessoes
1420
1599
  // na mesma worktree. Sem a prova, nada e redespachado, e a tentativa nao conta.
1421
1600
  const ids = [falho.sessionId, gateDoPlano?.sessionId].filter((x) => typeof x === 'string' && !!x);
1422
- const viva = (0, vida_da_thread_1.sessaoVivaNaThread)(raiz, thread, ids);
1601
+ const provar = (conhecidos) => (0, vida_da_thread_1.sessaoVivaNaThread)(raiz, thread, conhecidos);
1602
+ let viva = provar(ids);
1603
+ // RM-063 (F4): `runtime.unavailable` sobe a escada de recuperacao (reerguer o daemon, o fallback do bloco, outro perfil),
1604
+ // sempre com o mesmo prompt e o mesmo sha256. Ate aqui o retry so sabia repetir o destino que tinha acabado de falhar.
1605
+ if (plano.motivo === 'runtime.unavailable') {
1606
+ let perfilFalho = null;
1607
+ try {
1608
+ perfilFalho = perfilDoEvento(falho);
1609
+ }
1610
+ catch {
1611
+ perfilFalho = null;
1612
+ }
1613
+ // O destino de origem e o do pedido novo que abriu o episodio; o despacho do gate completa o que faltar.
1614
+ const origem = (0, runtime_escada_1.destinoDoEpisodio)((0, ledger_1.lerLedger)(dir), plano.fase);
1615
+ const perfilPedido = perfilPedidoDoDespacho((0, ledger_1.lerLedger)(dir), plano.fase, falho, gateDoPlano);
1616
+ const sha = falho.promptSha256;
1617
+ // GO-FIX (achado 10): o caminho do ledger e relativo a quem despachou; o absoluto e o que o dono roda de qualquer lugar.
1618
+ const promptPath = localizarPromptGravado(raiz, threadId, falho.promptPath, sha) ?? falho.promptPath;
1619
+ const despacho = { promptPath, promptSha256: sha, perfil: origem?.perfil ?? perfilFalho,
1620
+ runtime: origem?.runtime ?? (typeof falho.runtime === 'string' ? falho.runtime : carregado.manifesto.runtime.adapter),
1621
+ model: origem?.model ?? (typeof falho.model === 'string' ? falho.model : null),
1622
+ effort: origem?.effort ?? (typeof falho.effort === 'string' ? falho.effort : plano.effort) };
1623
+ // GO-FIX (a conferir da revisao): com o daemon travado, o proprio `claude agents` pode nao responder, e a prova de vida
1624
+ // segurava a escada para sempre. No claude-bg, o degrau 1 reergue o daemon antes (o `--keep-workers` deixa as sessoes
1625
+ // de pe) e a prova e refeita; sem resposta de novo, nada sai, e na terceira vez seguida no episodio o dono e chamado.
1626
+ let daemonJaReerguido = null;
1627
+ if (!viva.respondeu && despacho.runtime === 'claude-bg' && !opcoes.dryRun) {
1628
+ daemonJaReerguido = (0, runtime_escada_1.reerguerDaemon)(opcoes.daemon ?? claude_bg_2.DAEMON_DO_CLAUDE, despacho.perfil);
1629
+ viva = provar(ids);
1630
+ }
1631
+ if (!viva.respondeu || viva.sessionId) {
1632
+ const { sessionId: sessao, detalhe: falhaDaConsulta } = viva;
1633
+ const detalhe = sessao ? (0, locale_1.textoDoCatalogo)((m) => m.retry.sessaoAindaViva(sessao.slice(0, 8), threadId))
1634
+ : (0, locale_1.textoDoCatalogo)((m) => m.retry.runtimeSemProva(falhaDaConsulta ?? '', threadId));
1635
+ registrarTentativa(false, detalhe, { conta: false, ...(sessao ? {} : { semProva: true }),
1636
+ ...(daemonJaReerguido ? { daemon: daemonJaReerguido } : {}) });
1637
+ const seguidas = sessao ? 0 : recusasSemProvaSeguidas((0, ledger_1.lerLedger)(dir), plano.fase);
1638
+ if (seguidas >= exports.LIMITE_SEM_PROVA && !opcoes.dryRun) {
1639
+ const escada = (0, runtime_escada_1.estadoDaEscada)((0, ledger_1.lerLedger)(dir), plano.fase);
1640
+ const motivo = (0, locale_1.textoDoCatalogo)((m) => m.retry.escada.semResposta(seguidas, falhaDaConsulta ?? '-'));
1641
+ return { ...vazio, detalhe: (0, runtime_escada_1.escalarEscada)(carregado, thread, plano.fase, despacho, escada.consumidos, plano.tentativas, plano.limite, motivo) };
1642
+ }
1643
+ return { ...vazio, detalhe };
1644
+ }
1645
+ if (perfilPedido)
1646
+ return redespacharNoPerfilPedido(falho, perfilPedido);
1647
+ const saida = (0, runtime_escada_1.subirAEscada)({
1648
+ carregado, thread, fase: plano.fase, despacho,
1649
+ tentativas: plano.tentativas, limite: plano.limite, dryRun: opcoes.dryRun, daemon: opcoes.daemon, daemonJaReerguido,
1650
+ idsConhecidos: ids, provaDeVida: provar,
1651
+ redespachar: (d) => redespachar(carregado, thread, plano.fase, promptPath, sha, { runtime: d.runtime, perfil: d.perfil,
1652
+ model: d.model, effort: d.effort, origem: 'retry.escada', dryRun: opcoes.dryRun }),
1653
+ // RM-055 (D2): a recusa do runtime por um impedimento do dono nao gasta tentativa, tambem na escada.
1654
+ registrarTentativa: (ok, detalhe, extra = {}) => registrarTentativa(ok, detalhe, { ...extra, ...((0, impedimento_1.ehImpedimentoDoDono)(extra.motivoDoRedespacho) ? { conta: false } : {}) }),
1655
+ });
1656
+ return { ...vazio, executada: saida.executada, redespacho: saida.redespacho, detalhe: saida.detalhe };
1657
+ }
1423
1658
  if (!viva.respondeu || viva.sessionId) {
1424
1659
  const { sessionId: sessao, detalhe: falhaDaConsulta } = viva;
1425
1660
  const detalhe = sessao ? (0, locale_1.textoDoCatalogo)((m) => m.retry.sessaoAindaViva(sessao.slice(0, 8), threadId))
@@ -1429,8 +1664,9 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1429
1664
  }
1430
1665
  const redespacho = redespachar(carregado, thread, plano.fase, falho.promptPath, falho.promptSha256, {
1431
1666
  effort: plano.effort,
1432
- runtime: typeof falho.runtime === 'string' ? falho.runtime : null,
1667
+ runtime: perfilPedidoDoRetry?.runtime ?? (typeof falho.runtime === 'string' ? falho.runtime : null),
1433
1668
  model: typeof falho.model === 'string' ? falho.model : null,
1669
+ ...(perfilPedidoDoRetry ? { perfil: perfilPedidoDoRetry.id, perfilPedido: perfilPedidoDoRetry } : {}),
1434
1670
  origem: 'retry.run',
1435
1671
  dryRun: opcoes.dryRun,
1436
1672
  });
@@ -1447,11 +1683,10 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1447
1683
  };
1448
1684
  }
1449
1685
  /**
1450
- * D5 + D11: rotacao depois de falha da conta. Com sessao no gate (o observador classificou a
1451
- * morte), a prova do `ork` decide antes: producao parcial vira `human.pending` com diagnostico.
1452
- * Sem producao, o perfil sai do rodizio e o MESMO prompt segue no proximo destino; recusa da
1453
- * conta no redespacho (nada rodou) continua a rotacao na mesma chamada, dentro do limite de
1454
- * tentativas. Sem destino: fila ate o menor prazo, ou o humano quando nenhum prazo existe.
1686
+ * D5 + RM-064 T2/T3: rotação depois de falha da conta. Produção parcial sob cota segue com um
1687
+ * checkpoint derivado do ledger e do Git; sem produção, o prompt original segue no próximo
1688
+ * destino. Recusa da conta no redespacho continua a rotação dentro do limite de tentativas.
1689
+ * Sem destino: fila até o menor prazo, ou o humano quando nenhum prazo existe.
1455
1690
  */
1456
1691
  function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTentativa) {
1457
1692
  const { raiz, manifesto } = carregado;
@@ -1486,15 +1721,18 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1486
1721
  const erro = e.message;
1487
1722
  return escalar('perfil registrado invalido', (0, locale_1.textoDoCatalogo)((m) => m.retry.rotacaoRecusada(erro)));
1488
1723
  }
1489
- // D11 (c): sessao que morreu por cota depois de produzir nao e redespachada.
1724
+ // RM-064 T3: produção parcial sob cota é preservada no checkpoint; não é razão para recomeçar nem escalar.
1725
+ let checkpoint = false;
1490
1726
  if (typeof gate?.sessionId === 'string' && typeof gate.despachoEm === 'string') {
1491
1727
  const producao = producaoNoIntervalo(raiz, thread, { sessionId: gate.sessionId, fase, despachadaEm: gate.despachoEm }, eventos);
1492
- if (producao.produziu) {
1493
- return escalar('producao parcial sob falha da conta', (0, locale_1.textoDoCatalogo)((m) => m.retry.producaoParcialConta(motivo === 'runtime.quota-exhausted', String(producao.evidencia))));
1494
- }
1728
+ checkpoint = motivo === 'runtime.quota-exhausted' &&
1729
+ (producao.produziu || gate?.origem === 'account.quota-exhausted');
1495
1730
  }
1731
+ const promptOriginalPath = typeof despacho.promptOriginalPath === 'string' ? despacho.promptOriginalPath : despacho.promptPath;
1732
+ const promptOriginalSha = typeof despacho.promptOriginalSha256 === 'string' ? despacho.promptOriginalSha256 : despacho.promptSha256;
1496
1733
  const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, fase);
1497
- const fallback = alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter);
1734
+ const fallback = alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter)
1735
+ .filter(f => (0, runtime_context_1.capacidadeDoRuntimeNoProjeto)(raiz, f.runtime).capaz);
1498
1736
  const politica = (0, runtime_profiles_1.politicaDeRotacao)(manifesto);
1499
1737
  const falha = sinalDoGate(gate, motivo);
1500
1738
  // I-33 (D12): o observador ja marca o perfil no caminho terminal; remarcar empurraria o prazo a cada retry.
@@ -1516,7 +1754,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1516
1754
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.perfilRotacionado, { fase, motivo: falhaAtual.motivo, origem: 'retry.rotacao',
1517
1755
  de: { runtime: atual.runtime, perfil: atual.perfil?.id ?? null },
1518
1756
  para: para ? { runtime: para.runtime, perfil: para.perfil?.id ?? null } : null,
1519
- evidencia: falhaAtual.trecho, razao, promptSha256: despacho.promptSha256, modo: thread.modo,
1757
+ evidencia: falhaAtual.trecho, razao, promptSha256: promptOriginalSha, modo: thread.modo,
1520
1758
  autorizadoPor: `politica de retry da I-33 (D5), bloco sem pausa ou delegado no modo ${thread.modo}` });
1521
1759
  };
1522
1760
  for (;;) {
@@ -1525,11 +1763,11 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1525
1763
  break;
1526
1764
  emitir(alvo, alvo.runtime === atual.runtime ? 'proximo perfil ativo do mesmo runtime' : 'fallback de runtime pela ordem do bloco');
1527
1765
  const mudouRuntime = alvo.runtime !== runtime;
1528
- ultimo = redespachar(carregado, thread, fase, despacho.promptPath, despacho.promptSha256, {
1766
+ ultimo = redespachar(carregado, thread, fase, promptOriginalPath, promptOriginalSha, {
1529
1767
  runtime: alvo.runtime, perfil: alvo.perfil?.id ?? null,
1530
1768
  model: mudouRuntime ? alvo.model : typeof despacho.model === 'string' ? despacho.model : null,
1531
1769
  effort: mudouRuntime ? alvo.effort ?? (typeof despacho.effort === 'string' ? despacho.effort : null) : plano.effort,
1532
- origem: 'retry.rotacao', dryRun: opcoes.dryRun,
1770
+ origem: 'retry.rotacao', checkpoint, dryRun: opcoes.dryRun,
1533
1771
  });
1534
1772
  registrarTentativa(ultimo.ok, ultimo.detalhe);
1535
1773
  tentativas += 1;
@@ -1565,14 +1803,16 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1565
1803
  emitir(null, `nenhum perfil ativo em ${runtimes.join(', ')}: fila duravel ate ${liberaEm}`);
1566
1804
  if (opcoes.dryRun)
1567
1805
  return { ...vazio, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.entrariaNaFila(liberaEm)) };
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),
1569
- promptPath: despacho.promptPath, promptSha256: despacho.promptSha256,
1806
+ let pedido = (0, ratelimit_1.enfileirar)(carregado, { thread: thread.id, fase, slug: typeof despacho.slug === 'string' ? despacho.slug : (0, phase_1.slugDaSessao)(thread, fase),
1807
+ promptPath: promptOriginalPath, promptSha256: promptOriginalSha,
1570
1808
  cwd: typeof despacho.cwd === 'string' ? despacho.cwd : thread.worktree ?? raiz,
1571
1809
  model: typeof despacho.model === 'string' ? despacho.model : null, effort: typeof despacho.effort === 'string' ? despacho.effort : null,
1572
1810
  sinal: { resetEm: prazo, fonte: prazo ? 'iso' : 'sem-horario', trecho: falhaAtual.trecho },
1573
1811
  detalhe: `${falhaAtual.motivo}: nenhum perfil ativo em ${runtimes.join(', ')}`, runtime, perfil: null, motivo: falhaAtual.motivo });
1812
+ if (checkpoint)
1813
+ pedido = (0, ratelimit_1.gravarPedido)(raiz, { ...pedido, checkpoint: true });
1574
1814
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.rateLimitEnfileirado, { fase, slug: pedido.slug, pedido: pedido.id, liberaEm: pedido.liberaEm,
1575
- janelaEstimada: pedido.janelaEstimada, motivo: falhaAtual.motivo, promptSha256: despacho.promptSha256,
1815
+ janelaEstimada: pedido.janelaEstimada, motivo: falhaAtual.motivo, promptSha256: promptOriginalSha, checkpoint,
1576
1816
  correcao: `ork retry resume (ou aguarde ate ${pedido.liberaEm})` });
1577
1817
  registrarTentativa(true, `fila duravel: pedido ${pedido.id} libera em ${pedido.liberaEm}`);
1578
1818
  return { ...vazio, executada: true, fila: [pedido], redespacho: ultimo, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.retry.pedidoAte(pedido.id, pedido.liberaEm)) };
@@ -1625,14 +1865,16 @@ function destinosQueRecusaramOModelo(eventos, fase) {
1625
1865
  */
1626
1866
  function proximoDestinoDoModelo(raiz, runtime, model, fallback, recusados) {
1627
1867
  const store = (0, runtime_profiles_1.lerPerfisComContas)(raiz);
1628
- const utilizavel = (p) => !['desativado', 'provider-pago', 'sem-auth'].includes(p.estado) && (0, runtime_profiles_1.perfilDisponivel)(p);
1629
- const mesmo = (0, runtime_profiles_1.perfisDoRuntime)(store, runtime).find(p => utilizavel(p) && !recusados.has(chaveDoModelo(runtime, p.id, model)));
1868
+ const mesmo = (0, runtime_context_1.capacidadeDaRotacao)(raiz, runtime, true).capaz
1869
+ ? (0, runtime_profiles_1.perfisDisponiveis)(store, runtime).find(p => !recusados.has(chaveDoModelo(runtime, p.id, model))) : null;
1630
1870
  if (mesmo)
1631
1871
  return { runtime, perfil: (0, runtime_profiles_1.perfilDeDespacho)(mesmo), model, effort: null };
1632
1872
  for (const f of fallback) {
1873
+ if (!(0, runtime_context_1.capacidadeDoRuntimeNoProjeto)(raiz, f.runtime).capaz)
1874
+ continue;
1633
1875
  const perfis = (0, runtime_profiles_1.perfisDoRuntime)(store, f.runtime);
1634
1876
  if (perfis.length) {
1635
- const p = perfis.find(x => utilizavel(x) && !recusados.has(chaveDoModelo(f.runtime, x.id, f.model)));
1877
+ const p = (0, runtime_profiles_1.perfisDisponiveis)(store, f.runtime).find(x => !recusados.has(chaveDoModelo(f.runtime, x.id, f.model)));
1636
1878
  if (p)
1637
1879
  return { runtime: f.runtime, perfil: (0, runtime_profiles_1.perfilDeDespacho)(p), model: f.model, effort: f.effort ?? null };
1638
1880
  continue;
@@ -1697,7 +1939,8 @@ function trocarDestinoDoModelo(carregado, thread, plano, opcoes, vazio, registra
1697
1939
  }
1698
1940
  const recusados = new Set([...destinosQueRecusaramOModelo(eventos, fase), chaveDoModelo(runtime, perfil?.id ?? null, model)]);
1699
1941
  const doBloco = (0, setup_1.configDoBloco)((0, setup_1.lerSetup)(raiz), thread.modo, fase);
1700
- const fallback = alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter);
1942
+ const fallback = alvosDeFallback(doBloco, doBloco?.runtime ?? manifesto.runtime.adapter)
1943
+ .filter(f => (0, runtime_context_1.capacidadeDoRuntimeNoProjeto)(raiz, f.runtime).capaz);
1701
1944
  let atual = { runtime, perfil, model };
1702
1945
  let tentativas = plano.tentativas;
1703
1946
  for (;;) {
@@ -1753,6 +1996,10 @@ function textoDoPlano(p) {
1753
1996
  linhas.push(m.tentativas(p.tentativas, p.limite));
1754
1997
  linhas.push(m.esforco(p.effort, p.effort !== p.effortAnterior ? p.effortAnterior : null));
1755
1998
  linhas.push(m.automatica(p.automatica));
1999
+ // RM-063 (F4): o degrau da escada de `runtime.unavailable`, ou o fim dela.
2000
+ const escada = p.escada;
2001
+ if (escada)
2002
+ linhas.push(escada.degrau && escada.tipo ? m.escada.noPlano(escada.degrau, m.escada.degraus[escada.tipo]) : m.escada.noPlanoEsgotada);
1756
2003
  if (p.bloqueio)
1757
2004
  linhas.push(m.bloqueio(p.bloqueio));
1758
2005
  linhas.push(m.razao((0, locale_1.remontar)(p.razao)));
@@ -1791,19 +2038,20 @@ function textoDoRetry(r) {
1791
2038
  }
1792
2039
  /** Texto de `ork retry resume`. */
1793
2040
  function textoDaRetomada(rs) {
2041
+ const m = (0, locale_1.msg)().retry.complementar;
1794
2042
  if (rs.length === 0) {
1795
- return 'Nenhum pedido da fila de rate limit com a janela liberada agora.';
2043
+ return m.retomadaVazia;
1796
2044
  }
1797
2045
  const linhas = [];
1798
2046
  for (const r of rs) {
1799
- linhas.push(`${r.pedido.id} thread ${r.pedido.thread} fase ${r.pedido.fase}`);
1800
- linhas.push(` playbook ${r.playbook}`);
1801
- linhas.push(` slug ${r.slug}`);
1802
- linhas.push(` retomada ${r.despachada ? `sim (sessao ${r.sessionId})` : 'nao'}`);
2047
+ linhas.push(m.retomadaCabecalho(r.pedido.id, r.pedido.thread, r.pedido.fase));
2048
+ linhas.push(m.playbook(r.playbook));
2049
+ linhas.push(m.slug(r.slug));
2050
+ linhas.push(m.retomada(r.despachada, r.sessionId));
1803
2051
  if (r.motivo)
1804
- linhas.push(` motivo ${r.motivo}`);
1805
- linhas.push(` detalhe ${(0, horario_1.localizarTexto)(r.detalhe)}`);
1806
- linhas.push(` estado ${r.pedido.estado}`);
2052
+ linhas.push(m.motivoRetomada(r.motivo));
2053
+ linhas.push(m.detalhe((0, horario_1.localizarTexto)(r.detalhe)));
2054
+ linhas.push(m.estado(m.estados[r.pedido.estado] ?? r.pedido.estado));
1807
2055
  }
1808
2056
  if (rs.some((r) => (0, horario_1.localizarTexto)(r.detalhe) !== r.detalhe))
1809
2057
  linhas.push((0, horario_1.legendaDoFuso)());