@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/ship.js CHANGED
@@ -50,6 +50,8 @@ var __importStar = (this && this.__importStar) || (function () {
50
50
  };
51
51
  })();
52
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.MODOS_QUE_AUTORIZAM_PUSH = void 0;
54
+ exports.commitQueIncorporou = commitQueIncorporou;
53
55
  exports.autorizacaoDePush = autorizacaoDePush;
54
56
  exports.arvoreComBranch = arvoreComBranch;
55
57
  exports.prepararArvore = prepararArvore;
@@ -62,6 +64,7 @@ exports.ship = ship;
62
64
  exports.textoDoShip = textoDoShip;
63
65
  const fs = __importStar(require("node:fs"));
64
66
  const path = __importStar(require("node:path"));
67
+ const node_child_process_1 = require("node:child_process");
65
68
  const gates_1 = require("./gates");
66
69
  const leases_1 = require("./leases");
67
70
  const ledger_1 = require("./ledger");
@@ -76,6 +79,46 @@ const contrato_publico_1 = require("./contrato-publico");
76
79
  const prova_minima_1 = require("./prova-minima");
77
80
  const horario_1 = require("./horario");
78
81
  const fabrica_publicar_1 = require("./fabrica-publicar");
82
+ const branch_de_estado_1 = require("./branch-de-estado");
83
+ const locale_1 = require("./locale");
84
+ /**
85
+ * RM-037 (fatia 5, A1): o commit de primeiro pai da base que incorporou o `shaDe`: o merge que trouxe a branch, ou
86
+ * o proprio `shaDe` quando a base avancou por fast-forward ate ele. Com a branch ja incorporada, a ponta da base e
87
+ * outra coisa: no `ship_done` da ork-docsusuarios (27/09/2026), o unico do `ork ship` com `jaIncorporado` nos ledgers
88
+ * deste projeto, ela era o merge de outra thread. O que trouxe a branch e o commit mais velho do primeiro pai da base
89
+ * que descende do `shaDe`. GO-FIX (rodada 1 do CHECK): `--first-parent` junto com `--ancestry-path` so propaga a
90
+ * descendencia pelos commits de primeiro pai, e o merge do PR que recebeu "Update branch" no GitHub (o pai dele e um
91
+ * merge que descende do `shaDe`, nao o `shaDe`) sumia da lista; agora sao duas listas e a intersecao. `null` quando o
92
+ * git nao responde.
93
+ */
94
+ function commitQueIncorporou(raiz, shaDe, ponta, passos = []) {
95
+ if (shaDe === ponta)
96
+ return shaDe;
97
+ // `passos` recebe os comandos que de fato rodaram, na ordem: e a evidencia do ship (sugestao da conferencia da rodada 2).
98
+ const curto = (sha) => sha.slice(0, 8);
99
+ // As listas crescem com o historico entre a branch e a ponta: o buffer vai alem do 1 MiB padrao do spawnSync.
100
+ const listar = (args) => {
101
+ passos.push(`git ${args.map((a) => a.replace(/^([0-9a-f]{40,64})\.\.([0-9a-f]{40,64})$/, (_, x, y) => `${curto(x)}..${curto(y)}`)).join(' ')}`);
102
+ const r = (0, node_child_process_1.spawnSync)('git', args, { cwd: raiz, encoding: 'utf8', timeout: 120000, maxBuffer: 256 * 1024 * 1024 });
103
+ return r.status === 0 && !r.error ? r.stdout.split('\n').filter((l) => /^[0-9a-f]{40,64}$/.test(l)) : null;
104
+ };
105
+ const primeiroPai = listar(['rev-list', '--first-parent', `${shaDe}..${ponta}`]);
106
+ const descendentes = listar(['rev-list', '--ancestry-path', `${shaDe}..${ponta}`]);
107
+ if (!primeiroPai || !descendentes)
108
+ return null;
109
+ const doShaDe = new Set(descendentes);
110
+ // Do mais velho para o mais novo: o primeiro de primeiro pai que descende do `shaDe`.
111
+ const maisVelho = [...primeiroPai].reverse().find((c) => doShaDe.has(c));
112
+ if (!maisVelho)
113
+ return null;
114
+ // O primeiro pai dele e o proprio `shaDe`: a branch ja estava no primeiro pai da base (fast-forward). Sem a resposta
115
+ // do git, nada e gravado: devolver o mais velho poria no `mergeSha` o filho do `shaDe` (sugestao da rodada 2).
116
+ passos.push(`git rev-parse ${curto(maisVelho)}^1`);
117
+ const pai = (0, util_1.exec)('git', ['rev-parse', `${maisVelho}^1`], raiz);
118
+ if (!pai.ok)
119
+ return null;
120
+ return pai.stdout.trim() === shaDe ? shaDe : maisVelho;
121
+ }
79
122
  /** Os caminhos de contrato publico que a entrega traz sobre a base (diff desde o merge-base). */
80
123
  function contratosDaEntrega(raiz, shaPara, shaDe) {
81
124
  const base = (0, util_1.exec)('git', ['merge-base', shaPara, shaDe], raiz);
@@ -84,8 +127,8 @@ function contratosDaEntrega(raiz, shaPara, shaDe) {
84
127
  const diff = (0, util_1.exec)('git', ['diff', '--name-only', '--no-renames', base.stdout.trim(), shaDe], raiz);
85
128
  return diff.ok ? (0, contrato_publico_1.contratosTocados)(diff.stdout.split('\n').map((l) => l.trim()).filter(Boolean)) : [];
86
129
  }
87
- /** Modos em que a propria #TAG do pedido autoriza o push antecipadamente. */
88
- const MODOS_QUE_AUTORIZAM_PUSH = ['maestro', 'auto'];
130
+ /** Modos em que a propria #TAG do pedido autoriza o push antecipadamente (o `ork ship publicar` usa a mesma lista). */
131
+ exports.MODOS_QUE_AUTORIZAM_PUSH = ['maestro', 'auto'];
89
132
  /**
90
133
  * Quem autoriza o push desta thread.
91
134
  *
@@ -104,15 +147,15 @@ function autorizacaoDePush(raiz, thread, opcoes) {
104
147
  autorizado: true,
105
148
  tipo: 'humano-no-cli',
106
149
  por: opcoes.autorizarPush.trim(),
107
- razao: `pausa de push do modo ${tag} autorizada na linha de comando`,
150
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoNaLinha(tag)),
108
151
  };
109
152
  }
110
- if (MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
153
+ if (exports.MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
111
154
  return {
112
155
  autorizado: true,
113
156
  tipo: 'modo',
114
- por: `#TAG ${tag} no pedido do builder`,
115
- razao: `o modo ${tag} entrega dentro de um bloco sem pausa: a #TAG e a autorizacao previa`,
157
+ por: (0, locale_1.textoDoCatalogo)((m) => m.ship.porTag(tag)),
158
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoPeloModo(tag)),
116
159
  };
117
160
  }
118
161
  if (thread.modo === 'classic') {
@@ -121,8 +164,9 @@ function autorizacaoDePush(raiz, thread, opcoes) {
121
164
  return {
122
165
  autorizado: true,
123
166
  tipo: 'humano-antecipado',
124
- por: String(antecipada.autorizadoPor ?? 'humano'),
125
- razao: `autorizacao antecipada de push registrada no ledger em ${antecipada.ts}`,
167
+ por: antecipada.autorizadoPor !== undefined && antecipada.autorizadoPor !== null ? String(antecipada.autorizadoPor)
168
+ : (0, locale_1.textoDoCatalogo)((m) => m.ship.humano),
169
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoAntes(String(antecipada.ts))),
126
170
  };
127
171
  }
128
172
  }
@@ -130,8 +174,7 @@ function autorizacaoDePush(raiz, thread, opcoes) {
130
174
  autorizado: false,
131
175
  tipo: 'pendente',
132
176
  por: '',
133
- razao: `o modo ${tag} pausa no push e ainda nao ha autorizacao humana registrada. ` +
134
- `Autorize na entrega: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
177
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.semAutorizacao(tag, thread.id)),
135
178
  };
136
179
  }
137
180
  /** Diretorio temporario onde a arvore de merge e montada quando preciso. */
@@ -178,16 +221,16 @@ function prepararArvore(raiz, para) {
178
221
  const dona = arvoreComBranch(raiz, para);
179
222
  if (dona) {
180
223
  if (temAlteracaoNaoCommitada(dona)) {
181
- throw new Error(`a branch de destino "${para}" esta em check-out em ${dona} com alteracoes nao commitadas; ` +
182
- 'commite ou reverta la antes do ship');
224
+ throw new locale_1.ErroDoCatalogo((m) => m.ship.arvoreSuja(para, dona));
183
225
  }
184
226
  return { dir: dona, temporaria: false };
185
227
  }
186
228
  const dir = dirTemporarioDeShip(raiz, para);
187
229
  fs.mkdirSync(path.dirname(dir), { recursive: true });
188
- const r = (0, util_1.exec)('git', ['worktree', 'add', dir, para], raiz);
230
+ const r = (0, util_1.exec)('git', ['worktree', 'add', '--', dir, para], raiz);
189
231
  if (!r.ok) {
190
- throw new Error(`nao foi possivel montar a arvore de merge de "${para}": ${(r.stderr || r.stdout).trim()}`);
232
+ const erro = (r.stderr || r.stdout).trim();
233
+ throw new locale_1.ErroDoCatalogo((m) => m.ship.arvoreNaoMontada(para, erro));
191
234
  }
192
235
  return { dir, temporaria: true };
193
236
  }
@@ -211,18 +254,18 @@ function shaDaRef(dir, ref) {
211
254
  * codigo de saida do `git push` nao prova que o remoto ficou com o commit certo.
212
255
  */
213
256
  function shaNoRemoto(dir, remoto, branch) {
214
- const r = (0, util_1.exec)('git', ['ls-remote', remoto, `refs/heads/${branch}`], dir, 120000);
257
+ // RM-047: so nome de remoto chega ao git, e depois do `--` (nunca vira opcao nem transporte).
258
+ const r = (0, util_1.exec)('git', ['ls-remote', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship'), `refs/heads/${branch}`], dir, 120000);
215
259
  if (!r.ok)
216
260
  return null;
217
- const linha = r.stdout.split('\n').find((l) => l.trim() !== '');
218
- if (!linha)
219
- return null;
220
- const sha = linha.split(/\s+/)[0];
261
+ // RM-059 (S1 da revisao da ork-rm059pista): o padrao do ls-remote casa por sufixo; vale so a linha da ref exata.
262
+ const linha = r.stdout.split('\n').map((l) => l.trim().split(/\s+/)).find((partes) => partes[1] === `refs/heads/${branch}`);
263
+ const sha = linha?.[0] ?? '';
221
264
  return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
222
265
  }
223
266
  /** O remoto esta configurado neste repositorio? */
224
267
  function remotoConfigurado(dir, remoto) {
225
- return (0, util_1.exec)('git', ['remote', 'get-url', remoto], dir).ok;
268
+ return (0, util_1.exec)('git', ['remote', 'get-url', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship')], dir).ok;
226
269
  }
227
270
  function baseDoResultado(thread, de, opcoes) {
228
271
  return {
@@ -237,6 +280,7 @@ function baseDoResultado(thread, de, opcoes) {
237
280
  shaDe: '',
238
281
  shaParaAntes: '',
239
282
  mergeSha: null,
283
+ pontaDaBase: null,
240
284
  jaIncorporado: false,
241
285
  remoto: opcoes.remoto ?? 'origin',
242
286
  shaRemoto: null,
@@ -277,7 +321,9 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
277
321
  const entregas = (0, ledger_1.lerLedger)(dir)
278
322
  .filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && typeof e.mergeSha === 'string')
279
323
  .map((e) => ({ mergeSha: String(e.mergeSha), para: para ?? String(e.para ?? '') }))
280
- .filter((e) => e.para.length > 0);
324
+ // RM-047 (fronteira de confiança): o ledger pode vir do clone. Só sha hexadecimal e nome de branch
325
+ // chegam ao `git log`; qualquer outro valor viraria opção dele e é ignorado.
326
+ .filter((e) => e.para.length > 0 && (0, branch_de_estado_1.shaValido)(e.mergeSha) && (0, branch_de_estado_1.branchValida)(e.para));
281
327
  if (entregas.length === 0)
282
328
  return null;
283
329
  const perguntados = new Set();
@@ -287,7 +333,7 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
287
333
  continue;
288
334
  perguntados.add(intervalo);
289
335
  // O historico e append-only: o merge continua la, e o revert vem DEPOIS dele.
290
- const log = (0, util_1.exec)('git', ['log', '--format=%H%x1f%B%x1e', intervalo], raiz, 60000);
336
+ const log = (0, util_1.exec)('git', ['log', '--format=%H%x1f%B%x1e', '--end-of-options', intervalo], raiz, 60000);
291
337
  if (!log.ok)
292
338
  continue;
293
339
  for (const bruto of log.stdout.split('\x1e')) {
@@ -329,7 +375,10 @@ function ship(carregado, threadId, opcoes) {
329
375
  const dir = (0, thread_1.dirThread)(raiz, threadId);
330
376
  const de = opcoes.de ?? thread.base.branch;
331
377
  const para = opcoes.para;
332
- const remoto = opcoes.remoto ?? 'origin';
378
+ // RM-047: o `--remoto` vem da linha de comando. Antes de qualquer git (inclusive a leitura da reversao),
379
+ // so nome de remoto passa; o resto recusa com `ship.remoto-invalido`, e o ship nao entrega sem push provado
380
+ // por um remoto que nunca existiu.
381
+ const remoto = (0, branch_de_estado_1.exigirRemoto)(opcoes.remoto ?? 'origin', 'ship');
333
382
  const r = baseDoResultado(thread, de, opcoes);
334
383
  // I-43 (T7): antes de qualquer coisa, se a entrega ANTERIOR desta thread foi
335
384
  // revertida na base, isso vira `rollback_done`. E o insumo de maior peso do indice
@@ -366,7 +415,7 @@ function ship(carregado, threadId, opcoes) {
366
415
  const autorizacao = autorizacaoDePush(raiz, thread, opcoes);
367
416
  r.autorizacao = autorizacao;
368
417
  if (!autorizacao.autorizado) {
369
- return bloquear('human.pending', autorizacao.razao, `ork ship ${threadId} --para <branch> --autorizar-push <quem>`);
418
+ return bloquear('human.pending', autorizacao.razao, (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizeNaEntrega(threadId)));
370
419
  }
371
420
  // 2. Policies do manifesto que valem no gate `ship`. RM-008 (fatia 3): a branch da thread
372
421
  // atras da base e fato do git, calculado aqui (a ponta da base nao esta contida na branch).
@@ -417,20 +466,21 @@ function ship(carregado, threadId, opcoes) {
417
466
  return bloquear('policy.violation', bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; '), bloqueiam.map((v) => v.correcao).join('; '));
418
467
  }
419
468
  // 3. Verificacao independente: reexecuta claims e comandos no HEAD real da thread.
420
- const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify });
469
+ const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify,
470
+ conducao: { filaPesada: { ...opcoes.avisoDaFilaPesada, esperarMs: opcoes.esperarFilaPesadaMs } } });
421
471
  r.verificacao = verificacao;
422
472
  if (!verificacao.ok) {
423
473
  const motivo = verificacao.motivos.find((m) => m !== 'claims.unverifiable');
424
- return bloquear(motivo, `verificacao reprovou no HEAD ${verificacao.commit}: ${verificacao.motivos.join(', ')}`, 'rode `ork verify ' + threadId + '` e corrija antes de entregar');
474
+ return bloquear(motivo, (0, locale_1.textoDoCatalogo)((m) => m.ship.verificacaoReprovou(verificacao.commit, verificacao.motivos.join(', '))), (0, locale_1.textoDoCatalogo)((m) => m.ship.rodeVerify(threadId)));
425
475
  }
426
476
  // Referencias locais, resolvidas antes de tomar o lease.
427
477
  const shaDe = shaDaRef(raiz, `refs/heads/${de}`);
428
478
  const shaPara = shaDaRef(raiz, `refs/heads/${para}`);
429
479
  if (!shaDe) {
430
- return bloquear('artifact.missing', `branch de origem "${de}" nao existe neste repositorio`, `use --de <branch> ou crie a branch da thread`);
480
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.origemAusente(de)), (0, locale_1.textoDoCatalogo)((m) => m.ship.origemAusenteCorrecao));
431
481
  }
432
482
  if (!shaPara) {
433
- return bloquear('artifact.missing', `branch de destino "${para}" nao existe neste repositorio`, `crie a branch de destino ou informe outra em --para`);
483
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.destinoAusente(para)), (0, locale_1.textoDoCatalogo)((m) => m.ship.destinoAusenteCorrecao));
434
484
  }
435
485
  r.shaDe = shaDe;
436
486
  r.shaParaAntes = shaPara;
@@ -438,31 +488,37 @@ function ship(carregado, threadId, opcoes) {
438
488
  // por git direto. Ciclo sem PLAN nem CHECK nao entrega contrato publico.
439
489
  const tocados = (0, prova_minima_1.cicloSemCheck)(thread) ? contratosDaEntrega(raiz, shaPara, shaDe) : [];
440
490
  if (tocados.length > 0) {
441
- return bloquear('policy.violation', `contrato publico em ciclo sem PLAN nem CHECK: ${tocados.join(', ')}`, 'refaca a mudanca numa thread #Classic, #Maestro ou #Auto');
491
+ return bloquear('policy.violation', (0, locale_1.textoDoCatalogo)((m) => m.ship.contratoPublico(tocados.join(', '))), (0, locale_1.textoDoCatalogo)((m) => m.ship.contratoPublicoCorrecao));
442
492
  }
443
493
  // O recibo vem do provedor e pertence ao SHA exato da candidata. Teste local
444
494
  // verde ou status de outro commit não libera a entrega.
445
495
  const ci = (0, ci_1.consultarCi)(carregado, shaDe, remoto, opcoes.executorCi);
446
496
  r.ci = ci;
447
497
  if (!ci.ok) {
448
- return bloquear('ci.failed', `${ci.detail} (commit ${shaDe}, contexto ${ci.context})`, `publique a branch, aguarde o check ${ci.context} verde no GitHub e repita o SHIP`);
498
+ return bloquear('ci.failed', (0, locale_1.textoDoCatalogo)((m) => m.ship.ciReprovou((0, locale_1.remontar)(ci.detail), shaDe, ci.context)), (0, locale_1.textoDoCatalogo)((m) => m.ship.ciReprovouCorrecao(ci.context)));
449
499
  }
450
500
  // 4. Lease `main-tree`: so uma thread mergeia por vez.
451
501
  if (r.dryRun) {
452
- const ocupado = (0, leases_1.lerLease)(raiz, leases_1.LEASE_MAIN_TREE);
502
+ const ocupado = (0, leases_1.leasesColidentes)(raiz, leases_1.LEASE_MAIN_TREE)[0] ?? null;
453
503
  r.leaseOcupadoPor = ocupado;
454
504
  // O ensaio tambem responde ONDE o merge aconteceria e se aquela arvore esta limpa:
455
505
  // descobrir isso so na hora do merge real seria descobrir tarde demais.
456
506
  const dona = arvoreComBranch(raiz, para);
457
- const arvoreDoMerge = dona
458
- ? `${dona} (arvore que tem ${para} em check-out; ${temAlteracaoNaoCommitada(dona) ? 'SUJA, o ship reprovaria com tree.blocked' : 'limpa'})`
459
- : `worktree temporaria em ${path.join((0, manifest_1.dirEstado)(raiz), 'tmp')} (ninguem tem ${para} em check-out)`;
460
- r.detalhe = `arvore de merge: ${arvoreDoMerge}`;
507
+ const suja = dona ? temAlteracaoNaoCommitada(dona) : false;
508
+ const temporaria = path.join((0, manifest_1.dirEstado)(raiz), 'tmp');
509
+ const arvoreDoMerge = (m) => dona ? m.ship.arvoreDona(dona, para, suja) : m.ship.arvoreTemporaria(temporaria, para);
510
+ r.detalhe = (0, locale_1.textoDoCatalogo)((m) => m.ship.arvoreDeMerge(arvoreDoMerge(m)));
511
+ // Ensaio de 03/10 (R5): sem remoto (ou com --sem-push), o ensaio diz o mesmo que o ship real, e nao
512
+ // promete um push e uma prova que nao vao acontecer.
513
+ const semPushNoReal = opcoes.semPush || !remotoConfigurado(raiz, remoto)
514
+ ? (m) => opcoes.semPush ? m.ship.semPushPorFlag : m.ship.semRemoto(remoto) : null;
461
515
  r.passos = [
462
- `arvore de merge: ${arvoreDoMerge}`,
463
- `git merge --no-ff ${de} -m "<mensagem de ship>"`,
464
- `git push ${remoto} ${para}`,
465
- `git ls-remote ${remoto} refs/heads/${para} (prova do push)`,
516
+ r.detalhe,
517
+ (0, locale_1.textoDoCatalogo)((m) => m.ship.passoMerge(de)),
518
+ ...(semPushNoReal ? [(0, locale_1.textoDoCatalogo)((m) => m.ship.passoSemPush(semPushNoReal(m)))] : [
519
+ `git push ${remoto} ${para}`,
520
+ (0, locale_1.textoDoCatalogo)((m) => m.ship.passoProvaDoPush(remoto, para)),
521
+ ]),
466
522
  ];
467
523
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipIniciado, {
468
524
  de,
@@ -493,11 +549,9 @@ function ship(carregado, threadId, opcoes) {
493
549
  posicao: aquisicao.posicaoNaFila,
494
550
  naFrente: (0, leases_1.esperandoPor)(raiz, leases_1.LEASE_MAIN_TREE).length,
495
551
  bloqueadaPor: dono?.thread ?? '(desconhecida)',
496
- motivo: 'lease.busy',
552
+ motivo: aquisicao.motivo ?? 'lease.busy',
497
553
  });
498
- return bloquear('lease.busy', `lease ${leases_1.LEASE_MAIN_TREE} esta com a thread ${dono?.thread ?? '(desconhecida)'} ` +
499
- `desde ${dono?.adquiridoEm ?? '?'} (${dono?.motivo ?? 'sem motivo'}); ` +
500
- `esta thread entrou na merge queue na posicao ${aquisicao.posicaoNaFila}`, `espere a vez na fila (ork lease list), ou libere com: ork lease release ${leases_1.LEASE_MAIN_TREE} --forcar`);
554
+ return bloquear(aquisicao.motivo ?? 'lease.busy', aquisicao.falhaRetomada ? aquisicao.detalhe : (0, locale_1.textoDoCatalogo)((m) => m.ship.leaseComOutra(leases_1.LEASE_MAIN_TREE, dono?.thread ?? m.ship.desconhecida, dono?.adquiridoEm ?? '?', dono?.motivo ?? m.ship.semMotivo, aquisicao.posicaoNaFila)), aquisicao.correcao);
501
555
  }
502
556
  r.lease = aquisicao.lease;
503
557
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.leaseAdquirido, {
@@ -524,7 +578,7 @@ function ship(carregado, threadId, opcoes) {
524
578
  }
525
579
  catch (e) {
526
580
  // Arvore de destino indisponivel e reprovacao tipada, nao excecao vazando pelo CLI.
527
- return bloquear('tree.blocked', e.message, 'deixe a arvore da branch de destino limpa (ou libere a branch) e rode o ship de novo');
581
+ return bloquear('tree.blocked', e instanceof locale_1.ErroDoCatalogo ? (0, locale_1.textoDoCatalogo)(e.montar) : e.message, (0, locale_1.textoDoCatalogo)((m) => m.ship.arvoreCorrecao));
528
582
  }
529
583
  const passos = [];
530
584
  opcoes.revalidarGit?.('merge', arvore.dir);
@@ -532,6 +586,9 @@ function ship(carregado, threadId, opcoes) {
532
586
  const jaIncorporado = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, shaPara], raiz).ok;
533
587
  r.jaIncorporado = jaIncorporado;
534
588
  let mergeSha = shaPara;
589
+ // RM-037 (fatia 5, A1): a ponta que o push prova. Com o merge feito aqui, e ele; com a branch ja incorporada, a
590
+ // ponta de antes, que pode trazer outros merges depois do que entregou esta thread.
591
+ let pontaDaBase = shaPara;
535
592
  if (!jaIncorporado) {
536
593
  const mensagem = opcoes.mensagem ??
537
594
  `ship(${threadId}): merge de ${de} em ${para}\n\n` +
@@ -539,59 +596,68 @@ function ship(carregado, threadId, opcoes) {
539
596
  `modo: ${(0, modos_1.tagDoModo)(thread.modo)}\n` +
540
597
  `autorizado por: ${autorizacao.por} (${autorizacao.tipo})\n` +
541
598
  `verificado em: HEAD ${verificacao.commit}\n`;
542
- const merge = (0, util_1.exec)('git', ['merge', '--no-ff', de, '-m', mensagem], arvore.dir, 300000);
599
+ // RM-047: o merge e do sha verificado, e nao do nome que veio de `--de` (nome nunca vira opcao do git).
600
+ const merge = (0, util_1.exec)('git', ['merge', '--no-ff', '-m', mensagem, shaDe], arvore.dir, 300000);
543
601
  passos.push(`git merge --no-ff ${de}`);
544
602
  if (!merge.ok) {
545
603
  (0, util_1.exec)('git', ['merge', '--abort'], arvore.dir);
546
604
  r.passos = [...passos, 'git merge --abort'];
547
- return bloquear('artifact.missing', `merge de ${de} em ${para} falhou: ${(merge.stderr || merge.stdout).trim().slice(0, 400)}`, 'resolva o conflito na branch da thread e rode o ship de novo');
605
+ const erro = (merge.stderr || merge.stdout).trim().slice(0, 400);
606
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.mergeFalhou(de, para, erro)), (0, locale_1.textoDoCatalogo)((m) => m.ship.mergeFalhouCorrecao));
548
607
  }
549
608
  const novo = shaDaRef(arvore.dir, 'HEAD');
550
609
  if (!novo) {
551
- return bloquear('artifact.missing', 'nao foi possivel ler o HEAD apos o merge', 'confira o repositorio');
610
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.headIlegivel), (0, locale_1.textoDoCatalogo)((m) => m.ship.confiraRepositorio));
552
611
  }
553
612
  mergeSha = novo;
613
+ pontaDaBase = novo;
554
614
  // Verificacao independente do merge: a origem precisa ser ancestral do resultado.
555
615
  const incorporou = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, mergeSha], arvore.dir).ok;
556
616
  passos.push(`git merge-base --is-ancestor ${shaDe.slice(0, 8)} ${mergeSha.slice(0, 8)}`);
557
617
  if (!incorporou) {
558
- return bloquear('artifact.missing', `o commit de ${de} nao aparece como ancestral do merge ${mergeSha}`, 'nao empurre: investigue o estado do repositorio');
618
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.naoAncestral(de, mergeSha)), (0, locale_1.textoDoCatalogo)((m) => m.ship.naoEmpurre));
559
619
  }
560
620
  }
561
621
  else {
562
- passos.push(`(nada a mergear: ${de} ja e ancestral de ${para})`);
622
+ // RM-037 (fatia 5, A1): o merge que trouxe a branch, e nao a ponta da base.
623
+ const incorporadoEm = commitQueIncorporou(raiz, shaDe, shaPara, passos);
624
+ if (!incorporadoEm) {
625
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPai(de, para)), (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPaiCorrecao));
626
+ }
627
+ mergeSha = incorporadoEm;
628
+ const incorporado = mergeSha.slice(0, 8);
629
+ passos.push((0, locale_1.textoDoCatalogo)((m) => m.ship.passoJaIncorporado(de, para, incorporado)));
563
630
  }
564
631
  r.mergeSha = mergeSha;
632
+ r.pontaDaBase = pontaDaBase;
565
633
  opcoes.revalidarGit?.('push', arvore.dir);
566
634
  // 6. Push PROVADO por ls-remote.
567
635
  const temRemoto = remotoConfigurado(arvore.dir, remoto);
568
636
  r.remoto = temRemoto ? remoto : null;
569
637
  if (opcoes.semPush || !temRemoto) {
570
638
  r.pushVerificado = false;
571
- r.detalhe = opcoes.semPush
572
- ? 'push nao executado por --sem-push (merge local concluido)'
573
- : `remoto "${remoto}" nao configurado: merge local concluido, sem push a provar`;
639
+ r.detalhe = (0, locale_1.textoDoCatalogo)((m) => opcoes.semPush ? m.ship.semPushPorFlag : m.ship.semRemoto(remoto));
574
640
  }
575
641
  else {
576
642
  const existeNoRemoto = shaNoRemoto(arvore.dir, remoto, para) !== null;
577
643
  const argsPush = existeNoRemoto
578
- ? ['push', remoto, `${para}:refs/heads/${para}`]
579
- : ['push', '-u', remoto, `${para}:refs/heads/${para}`];
644
+ ? ['push', '--', remoto, `refs/heads/${para}:refs/heads/${para}`]
645
+ : ['push', '-u', '--', remoto, `refs/heads/${para}:refs/heads/${para}`];
580
646
  const push = (0, util_1.exec)('git', argsPush, arvore.dir, 300000);
581
647
  passos.push(`git ${argsPush.join(' ')}`);
582
648
  if (!push.ok) {
583
649
  r.passos = passos;
584
- return bloquear('runtime.unavailable', `push para ${remoto}/${para} falhou: ${(push.stderr || push.stdout).trim().slice(0, 400)}`, 'resolva o acesso ao remoto e rode o ship de novo (o merge local ja aconteceu)');
650
+ const erro = (push.stderr || push.stdout).trim().slice(0, 400);
651
+ return bloquear('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => m.ship.pushFalhou(remoto, para, erro)), (0, locale_1.textoDoCatalogo)((m) => m.ship.pushFalhouCorrecao));
585
652
  }
586
653
  // A prova: o sha que o REMOTO devolve tem que ser o mesmo do destino local.
587
654
  const shaRemoto = shaNoRemoto(arvore.dir, remoto, para);
588
655
  passos.push(`git ls-remote ${remoto} refs/heads/${para}`);
589
656
  r.shaRemoto = shaRemoto;
590
- r.pushVerificado = shaRemoto !== null && shaRemoto === mergeSha;
657
+ r.pushVerificado = shaRemoto !== null && shaRemoto === pontaDaBase;
591
658
  if (!r.pushVerificado) {
592
659
  r.passos = passos;
593
- return bloquear('runtime.unavailable', `ls-remote devolveu ${shaRemoto ?? '(nada)'} e o destino local esta em ${mergeSha}: ` +
594
- 'o push nao ficou provado', 'rode o ship de novo e confira o remoto');
660
+ return bloquear('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => m.ship.pushSemProva(shaRemoto, pontaDaBase)), (0, locale_1.textoDoCatalogo)((m) => m.ship.pushSemProvaCorrecao));
595
661
  }
596
662
  }
597
663
  r.passos = passos;
@@ -609,6 +675,8 @@ function ship(carregado, threadId, opcoes) {
609
675
  shaDe,
610
676
  shaParaAntes: shaPara,
611
677
  mergeSha,
678
+ // RM-037 (fatia 5, A1): a ponta da base vai em campo proprio; o `mergeSha` e o merge que entregou a thread.
679
+ pontaDaBase,
612
680
  jaIncorporado,
613
681
  remoto: r.remoto,
614
682
  shaRemoto: r.shaRemoto,
@@ -651,74 +719,75 @@ function ship(carregado, threadId, opcoes) {
651
719
  });
652
720
  }
653
721
  }
654
- /** Texto de `ork ship` para o CLI. */
722
+ /**
723
+ * Texto de `ork ship` para o CLI. A razao, o detalhe, a correcao e os passos que o ship montou pelo catalogo
724
+ * vieram em pt-BR (como o ledger os guarda) e saem remontados no locale ativo (G2 da F2b).
725
+ */
655
726
  function textoDoShip(r) {
727
+ const m = (0, locale_1.msg)().ship;
656
728
  const linhas = [];
657
729
  // I-35: horários no fuso do dono, sem rótulo por linha; o fuso é dito uma vez, no fim.
658
730
  let comHorario = false;
659
731
  const local = (texto) => {
660
- const localizado = (0, horario_1.localizarTexto)(texto);
661
- if (localizado !== texto)
732
+ const remontado = (0, locale_1.remontar)(texto);
733
+ const localizado = (0, horario_1.localizarTexto)(remontado);
734
+ if (localizado !== remontado)
662
735
  comHorario = true;
663
736
  return localizado;
664
737
  };
665
738
  const fechar = () => (comHorario ? [...linhas, (0, horario_1.legendaDoFuso)()] : linhas).join('\n');
666
- const cabecalho = r.dryRun ? 'ork ship (--dry-run, nada foi executado)' : 'ork ship';
667
- linhas.push(`${cabecalho}: thread ${r.thread}`);
668
- linhas.push(` de ${r.de}${r.shaDe ? ` @ ${r.shaDe.slice(0, 8)}` : ''}`);
669
- linhas.push(` para ${r.para}${r.shaParaAntes ? ` @ ${r.shaParaAntes.slice(0, 8)}` : ''}`);
670
- linhas.push(` autorizacao ${r.autorizacao.autorizado ? `AUTORIZADO por ${r.autorizacao.por} (${r.autorizacao.tipo})` : 'AGUARDANDO AUTORIZACAO HUMANA'}`);
671
- linhas.push(` ${local(r.autorizacao.razao)}`);
739
+ linhas.push(m.cabecalho(r.dryRun, r.thread));
740
+ linhas.push(m.de(r.de, r.shaDe ? r.shaDe.slice(0, 8) : ''));
741
+ linhas.push(m.para(r.para, r.shaParaAntes ? r.shaParaAntes.slice(0, 8) : ''));
742
+ linhas.push(r.autorizacao.autorizado
743
+ ? m.autorizado((0, locale_1.remontar)(r.autorizacao.por), m.tiposDeAutorizacao[r.autorizacao.tipo] ?? r.autorizacao.tipo) : m.aguardandoAutorizacao);
744
+ linhas.push(m.razao(local(r.autorizacao.razao)));
672
745
  if (r.verificacao) {
673
746
  const v = r.verificacao;
674
- linhas.push(` verificacao ${v.ok ? 'passou' : 'REPROVOU'} no HEAD ${(0, util_1.shaCurto)(v.commit)} ` +
675
- `(${v.claims.filter((c) => c.verificado).length}/${v.claims.length} claims, ` +
676
- `${v.comandos.filter((c) => c.ok).length}/${v.comandos.length} comandos)`);
747
+ linhas.push(m.verificacao(v.ok, (0, util_1.shaCurto)(v.commit), v.claims.filter((c) => c.verificado).length, v.claims.length, v.comandos.filter((c) => c.ok).length, v.comandos.length));
677
748
  }
678
749
  if (r.ci) {
679
- linhas.push(` ci ${r.ci.required ? `${r.ci.state.toUpperCase()} ${r.ci.context} em ${r.ci.sha.slice(0, 8)}` : 'não exigido'}`);
750
+ linhas.push(r.ci.required ? m.ciExigido(r.ci.state.toUpperCase(), r.ci.context, r.ci.sha.slice(0, 8)) : m.ciNaoExigido);
680
751
  }
681
752
  linhas.push(...(0, policies_1.linhasDeAviso)(r.violacoes ?? []));
682
753
  if (r.leaseOcupadoPor) {
683
754
  comHorario = true;
684
- linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} OCUPADO pela thread ${r.leaseOcupadoPor.thread} (desde ${(0, horario_1.formatarDataHora)(r.leaseOcupadoPor.adquiridoEm)})`);
755
+ linhas.push(m.leaseOcupado(leases_1.LEASE_MAIN_TREE, r.leaseOcupadoPor.thread, (0, horario_1.formatarDataHora)(r.leaseOcupadoPor.adquiridoEm)));
685
756
  }
686
757
  else if (r.lease) {
687
- linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} tomado por ${r.thread} e liberado ao fim`);
758
+ linhas.push(m.leaseTomado(leases_1.LEASE_MAIN_TREE, r.thread));
688
759
  }
689
760
  else if (r.dryRun) {
690
- linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} livre`);
761
+ linhas.push(m.leaseLivre(leases_1.LEASE_MAIN_TREE));
691
762
  }
692
763
  if (r.bloqueado) {
693
764
  linhas.push('');
694
- linhas.push(`BLOQUEADO. motivo tipado: ${r.motivo}`);
695
- linhas.push(` detalhe ${local(r.detalhe)}`);
696
- linhas.push(` correcao ${r.correcao}`);
765
+ linhas.push(m.bloqueado(String(r.motivo)));
766
+ linhas.push(m.detalhe(local(r.detalhe)));
767
+ linhas.push(m.correcao((0, locale_1.remontar)(r.correcao)));
697
768
  return fechar();
698
769
  }
699
770
  if (r.dryRun) {
700
771
  linhas.push('');
701
- linhas.push('Passos que o ship real executaria, nesta ordem:');
772
+ linhas.push(m.passosDoEnsaio);
702
773
  for (const p of r.passos)
703
- linhas.push(` ${p}`);
774
+ linhas.push(` ${(0, locale_1.remontar)(p)}`);
704
775
  return fechar();
705
776
  }
706
777
  linhas.push('');
707
- linhas.push(r.jaIncorporado
708
- ? `Nada a mergear: ${r.de} ja estava em ${r.para}.`
709
- : `Merge --no-ff concluido: ${r.mergeSha}`);
778
+ linhas.push(r.jaIncorporado ? m.nadaAMergear(r.de, r.para, String(r.mergeSha)) : m.mergeConcluido(String(r.mergeSha)));
710
779
  if (r.pushVerificado) {
711
- linhas.push(`Push PROVADO: ls-remote de ${r.remoto}/${r.para} devolveu ${r.shaRemoto}`);
712
- linhas.push(` e o destino local esta no mesmo sha: ${r.mergeSha}`);
780
+ linhas.push(m.pushProvado(String(r.remoto), r.para, String(r.shaRemoto)));
781
+ linhas.push(m.mesmoSha(r.pontaDaBase ?? String(r.mergeSha)));
713
782
  }
714
783
  else {
715
- linhas.push(`Push nao provado: ${local(r.detalhe) || 'sem remoto configurado'}`);
784
+ linhas.push(m.pushNaoProvado(local(r.detalhe) || m.semRemotoConfigurado));
716
785
  }
717
786
  linhas.push('');
718
- linhas.push('Evidencia (comandos executados):');
787
+ linhas.push(m.evidencia);
719
788
  for (const p of r.passos)
720
- linhas.push(` ${p}`);
789
+ linhas.push(` ${(0, locale_1.remontar)(p)}`);
721
790
  linhas.push('');
722
- linhas.push(`Ledger: ork phase list ${r.thread} (evento ship_done)`);
791
+ linhas.push(m.ledger(r.thread));
723
792
  return fechar();
724
793
  }
package/dist/steal.js ADDED
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * RM-037 (fatia 6): o steal da CPU durante o `ork verify`, medido em `/proc/stat`.
4
+ *
5
+ * Em 23 e 24/09/2026 a VPS perdeu de 67% a 92% da CPU para o hipervisor (sar), e a mesma suite que
6
+ * leva 3,4 min com CPU livre levou de 24 a 30 min. Teste que mede relogio reprova nessa hora sem que
7
+ * o codigo tenha mudado. O verify passa a medir o steal na janela de cada comando e da rodada e a
8
+ * gravar a medida no `verify_run`; a reprovacao de teste com relogio sob steal acima de 40% vira
9
+ * `verify.timeout` (o retry reexecuta), nunca regressao.
10
+ *
11
+ * A linha agregada `cpu` do `/proc/stat` traz, em jiffies desde o boot: user, nice, system, idle,
12
+ * iowait, irq, softirq, steal, guest e guest_nice. guest e guest_nice ja estao contados em user e
13
+ * nice, entao o total da janela soma so os oito primeiros.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.lerProcStat = exports.FONTE_STEAL = exports.LIMIAR_STEAL_PCT = void 0;
17
+ exports.amostraDoProcStat = amostraDoProcStat;
18
+ exports.stealDaJanela = stealDaJanela;
19
+ exports.abrirJanela = abrirJanela;
20
+ exports.reprovacaoSoDeRelogio = reprovacaoSoDeRelogio;
21
+ exports.stealAlto = stealAlto;
22
+ const node_fs_1 = require("node:fs");
23
+ /** Limiar da recomendada da RM-037: acima dele, o relogio do teste nao julga o codigo. */
24
+ exports.LIMIAR_STEAL_PCT = 40;
25
+ exports.FONTE_STEAL = '/proc/stat';
26
+ const lerProcStat = () => {
27
+ try {
28
+ return (0, node_fs_1.readFileSync)(exports.FONTE_STEAL, 'utf8');
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ };
34
+ exports.lerProcStat = lerProcStat;
35
+ /** A linha `cpu ` (agregada) do `/proc/stat`. Kernel antigo, sem a coluna de steal, nao tem medida. */
36
+ function amostraDoProcStat(conteudo) {
37
+ if (!conteudo)
38
+ return null;
39
+ const linha = conteudo.split('\n').find((l) => /^cpu\s/.test(l));
40
+ if (!linha)
41
+ return null;
42
+ const campos = linha.trim().split(/\s+/).slice(1).map(Number);
43
+ if (campos.length < 8 || campos.slice(0, 8).some((n) => !Number.isFinite(n) || n < 0))
44
+ return null;
45
+ const total = campos.slice(0, 8).reduce((s, n) => s + n, 0);
46
+ return { steal: campos[7], total };
47
+ }
48
+ /** Steal da janela entre duas amostras, em porcentagem com uma casa. Janela vazia nao tem medida. */
49
+ function stealDaJanela(inicio, fim) {
50
+ if (!inicio || !fim)
51
+ return null;
52
+ const total = fim.total - inicio.total;
53
+ const steal = fim.steal - inicio.steal;
54
+ if (total <= 0 || steal < 0)
55
+ return null;
56
+ return Math.round((steal / total) * 1000) / 10;
57
+ }
58
+ /** Abre a janela agora; `fechar()` devolve o steal dela (ou `null` sem medida). */
59
+ function abrirJanela(leitor = exports.lerProcStat) {
60
+ const inicio = amostraDoProcStat(leitor());
61
+ return { fechar: () => stealDaJanela(inicio, amostraDoProcStat(leitor())) };
62
+ }
63
+ /**
64
+ * A reprovacao do comando e so de teste com relogio? Todo teste que caiu precisa ser de relogio:
65
+ * pela assinatura de prazo do runner (estouro do teste ou cancelado pelo pai que estourou) ou pelo
66
+ * registro de instabilidade. Comando sem teste nomeado (build, tsc, script) nunca entra.
67
+ */
68
+ function reprovacaoSoDeRelogio(falhas, registro = new Set()) {
69
+ if (!falhas || falhas.length === 0)
70
+ return null;
71
+ const todas = falhas.every((f) => f.relogio || registro.has(f.nome));
72
+ return todas ? falhas.map((f) => f.nome) : null;
73
+ }
74
+ /** Steal acima do limiar? A medida ausente nunca atenua nada. */
75
+ function stealAlto(pct) {
76
+ return typeof pct === 'number' && pct > exports.LIMIAR_STEAL_PCT;
77
+ }
@@ -48,6 +48,7 @@ const estado_thread_1 = require("./estado-thread");
48
48
  const util_1 = require("./util");
49
49
  const fabrica_publicar_1 = require("./fabrica-publicar");
50
50
  const fechamento_1 = require("./fechamento");
51
+ const locale_1 = require("./locale");
51
52
  function validarArtefato(raiz, arquivo, sha256) {
52
53
  if (!/^[a-f0-9]{64}$/.test(sha256))
53
54
  throw new Error('sha256 inválido');
@@ -80,10 +81,10 @@ function provaDeEntrega(raiz, id) {
80
81
  function exigirEntrega(raiz, id) {
81
82
  const t = (0, thread_1.lerThread)(raiz, id);
82
83
  if (t.fechamentoAdmin)
83
- throw new Error('thread encerrada administrativamente não pode receber MASTER');
84
+ throw new locale_1.ErroDoCatalogo((m) => m.master.encerradaAdmin);
84
85
  const prova = provaDeEntrega(raiz, id);
85
86
  if (!prova)
86
- throw new Error('MASTER exige entrega: ship_done ou artefato existente com hash verificado');
87
+ throw new locale_1.ErroDoCatalogo((m) => m.master.exigeEntrega);
87
88
  return prova;
88
89
  }
89
90
  function registrarArtefato(raiz, id, arquivo, sha256, por) {