@orkastery/cli 0.5.3 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/mods/autoridade.json +56 -0
  3. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  4. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  5. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  6. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  8. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  9. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  10. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  11. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  12. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  13. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  16. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  17. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  18. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  19. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  20. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  21. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  25. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  26. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  27. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  28. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  29. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  30. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  33. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  34. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  35. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  36. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  37. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  38. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  44. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  45. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  46. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  47. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  48. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  49. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  52. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  53. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  54. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  55. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  56. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  57. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  59. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  60. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  61. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  62. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  63. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  64. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  67. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  68. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  69. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  70. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  71. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  72. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  77. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  78. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  79. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +1 -1
  80. package/adapters/openclaw/README.md +2 -1
  81. package/adapters/openclaw/openclaw.plugin.json +1 -1
  82. package/adapters/openclaw/package.json +1 -1
  83. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  84. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  85. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  86. package/assets/docs-en/produto/README.md +14 -0
  87. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  88. package/assets/docs-en/roadmap/README.md +14 -0
  89. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  90. package/dist/adapters/claude-bg.js +77 -13
  91. package/dist/adapters/codex.js +10 -1
  92. package/dist/agents-md.js +24 -15
  93. package/dist/auditrun.js +17 -2
  94. package/dist/board.js +4 -3
  95. package/dist/branch-de-estado.js +23 -1
  96. package/dist/catalogo.js +33 -0
  97. package/dist/ci.js +13 -7
  98. package/dist/claims-conferir.js +342 -0
  99. package/dist/claims.js +3 -1
  100. package/dist/company-brain-client.js +36 -1
  101. package/dist/company-brain-journal.js +2 -1
  102. package/dist/company-brain-migration.js +36 -1
  103. package/dist/conducao-sentinela.js +388 -0
  104. package/dist/conducao-texto.js +12 -18
  105. package/dist/conducao.js +122 -30
  106. package/dist/conhecimento.js +490 -0
  107. package/dist/docs.js +22 -8
  108. package/dist/doctor-pulse-cron.js +182 -27
  109. package/dist/doctor-rede.js +18 -17
  110. package/dist/doctor.js +115 -111
  111. package/dist/entrega-pr.js +22 -21
  112. package/dist/escopo-escrita.js +10 -1
  113. package/dist/estado-thread.js +23 -1
  114. package/dist/experiencia-instalacao.js +45 -25
  115. package/dist/fabrica-batida.js +310 -0
  116. package/dist/fabrica-estado.js +38 -8
  117. package/dist/fabrica-publicar.js +3 -1
  118. package/dist/fila-pesada.js +444 -0
  119. package/dist/fix.js +3 -2
  120. package/dist/forja.js +1 -1
  121. package/dist/gates.js +3 -28
  122. package/dist/handoff.js +10 -6
  123. package/dist/hitl-local-receipt.js +2 -0
  124. package/dist/hitl-resumo.js +29 -3
  125. package/dist/hitl-tempo-parado.js +4 -4
  126. package/dist/hitl.js +29 -33
  127. package/dist/horario.js +14 -7
  128. package/dist/hosts.js +52 -1
  129. package/dist/impedimento.js +108 -14
  130. package/dist/index.js +623 -521
  131. package/dist/indice.js +7 -1
  132. package/dist/init.js +43 -47
  133. package/dist/instabilidade.js +144 -0
  134. package/dist/integracoes-locais.js +2 -0
  135. package/dist/intelligence-graph-cli.js +92 -21
  136. package/dist/intelligence-graph-contexto.js +56 -17
  137. package/dist/intelligence-graph-contract.js +2 -1
  138. package/dist/intelligence-graph-extract-md.js +56 -4
  139. package/dist/intelligence-graph-extract-ts.js +71 -3
  140. package/dist/intelligence-graph-query.js +66 -19
  141. package/dist/ledger.js +15 -1
  142. package/dist/liveness.js +6 -3
  143. package/dist/locale-ajuda.js +761 -0
  144. package/dist/locale-gerados.js +160 -0
  145. package/dist/locale-master.js +99 -0
  146. package/dist/locale-onboarding.js +92 -0
  147. package/dist/locale-phase.js +151 -0
  148. package/dist/locale-pulse.js +211 -0
  149. package/dist/locale-retry.js +385 -0
  150. package/dist/locale-roadmap.js +102 -0
  151. package/dist/locale-ship.js +494 -0
  152. package/dist/locale-thread.js +277 -0
  153. package/dist/locale-verify.js +125 -0
  154. package/dist/locale.js +714 -0
  155. package/dist/manifest.js +129 -3
  156. package/dist/maquina.js +23 -4
  157. package/dist/master-digest.js +6 -1
  158. package/dist/master-nota.js +4 -6
  159. package/dist/master.js +21 -24
  160. package/dist/mcp-artifacts.js +11 -2
  161. package/dist/mcp-git.js +23 -6
  162. package/dist/mcp-grafo.js +7 -4
  163. package/dist/mcp-server.js +8 -2
  164. package/dist/mcp-ship.js +3 -1
  165. package/dist/mcp-verify.js +6 -1
  166. package/dist/modos.js +3 -6
  167. package/dist/network-roadmap.js +5 -2
  168. package/dist/noctum-arco.js +911 -0
  169. package/dist/noctum-capacidade.js +141 -0
  170. package/dist/noctum-envelope.js +810 -0
  171. package/dist/noctum-execucao.js +304 -0
  172. package/dist/noctum-fila.js +280 -0
  173. package/dist/ocupacao.js +29 -2
  174. package/dist/onboarding.js +40 -21
  175. package/dist/orkmind.js +9 -2
  176. package/dist/orquestracao.js +13 -12
  177. package/dist/parado-no-condutor.js +34 -9
  178. package/dist/phase.js +94 -39
  179. package/dist/policies.js +4 -4
  180. package/dist/portfolio.js +4 -2
  181. package/dist/postura-local.js +234 -0
  182. package/dist/preflight.js +11 -10
  183. package/dist/procedencia.js +225 -0
  184. package/dist/projeto-alvo.js +127 -4
  185. package/dist/prompts.js +6 -2
  186. package/dist/pulse-delivery.js +13 -2
  187. package/dist/pulse.js +52 -19
  188. package/dist/ratelimit.js +4 -2
  189. package/dist/redacao-saida.js +63 -0
  190. package/dist/rede-status.js +3 -2
  191. package/dist/retry.js +232 -148
  192. package/dist/roadmap-reservas.js +20 -3
  193. package/dist/roadmap-status.js +129 -33
  194. package/dist/runtime-context.js +181 -3
  195. package/dist/runtimes.js +2 -1
  196. package/dist/session-events.js +7 -3
  197. package/dist/session-watcher-claude.js +7 -1
  198. package/dist/session-watcher.js +185 -33
  199. package/dist/sessoes-contas.js +1 -1
  200. package/dist/ship-publicar.js +800 -0
  201. package/dist/ship.js +84 -81
  202. package/dist/steal.js +77 -0
  203. package/dist/thread-close.js +3 -2
  204. package/dist/thread.js +153 -82
  205. package/dist/util.js +8 -1
  206. package/dist/verify.js +141 -52
  207. package/dist/vida-da-thread.js +254 -0
  208. package/dist/worktree-local.js +165 -0
  209. package/dist/worktree.js +20 -0
  210. package/dist/yaml.js +27 -8
  211. package/package.json +1 -1
  212. package/schemas/code-artifact-graph.v1.schema.json +2 -1
package/dist/ship.js CHANGED
@@ -50,6 +50,7 @@ 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;
53
54
  exports.commitQueIncorporou = commitQueIncorporou;
54
55
  exports.autorizacaoDePush = autorizacaoDePush;
55
56
  exports.arvoreComBranch = arvoreComBranch;
@@ -79,6 +80,7 @@ const prova_minima_1 = require("./prova-minima");
79
80
  const horario_1 = require("./horario");
80
81
  const fabrica_publicar_1 = require("./fabrica-publicar");
81
82
  const branch_de_estado_1 = require("./branch-de-estado");
83
+ const locale_1 = require("./locale");
82
84
  /**
83
85
  * RM-037 (fatia 5, A1): o commit de primeiro pai da base que incorporou o `shaDe`: o merge que trouxe a branch, ou
84
86
  * o proprio `shaDe` quando a base avancou por fast-forward ate ele. Com a branch ja incorporada, a ponta da base e
@@ -125,8 +127,8 @@ function contratosDaEntrega(raiz, shaPara, shaDe) {
125
127
  const diff = (0, util_1.exec)('git', ['diff', '--name-only', '--no-renames', base.stdout.trim(), shaDe], raiz);
126
128
  return diff.ok ? (0, contrato_publico_1.contratosTocados)(diff.stdout.split('\n').map((l) => l.trim()).filter(Boolean)) : [];
127
129
  }
128
- /** Modos em que a propria #TAG do pedido autoriza o push antecipadamente. */
129
- 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'];
130
132
  /**
131
133
  * Quem autoriza o push desta thread.
132
134
  *
@@ -145,15 +147,15 @@ function autorizacaoDePush(raiz, thread, opcoes) {
145
147
  autorizado: true,
146
148
  tipo: 'humano-no-cli',
147
149
  por: opcoes.autorizarPush.trim(),
148
- razao: `pausa de push do modo ${tag} autorizada na linha de comando`,
150
+ razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoNaLinha(tag)),
149
151
  };
150
152
  }
151
- if (MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
153
+ if (exports.MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
152
154
  return {
153
155
  autorizado: true,
154
156
  tipo: 'modo',
155
- por: `#TAG ${tag} no pedido do builder`,
156
- 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)),
157
159
  };
158
160
  }
159
161
  if (thread.modo === 'classic') {
@@ -162,8 +164,9 @@ function autorizacaoDePush(raiz, thread, opcoes) {
162
164
  return {
163
165
  autorizado: true,
164
166
  tipo: 'humano-antecipado',
165
- por: String(antecipada.autorizadoPor ?? 'humano'),
166
- 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))),
167
170
  };
168
171
  }
169
172
  }
@@ -171,8 +174,7 @@ function autorizacaoDePush(raiz, thread, opcoes) {
171
174
  autorizado: false,
172
175
  tipo: 'pendente',
173
176
  por: '',
174
- razao: `o modo ${tag} pausa no push e ainda nao ha autorizacao humana registrada. ` +
175
- `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)),
176
178
  };
177
179
  }
178
180
  /** Diretorio temporario onde a arvore de merge e montada quando preciso. */
@@ -219,8 +221,7 @@ function prepararArvore(raiz, para) {
219
221
  const dona = arvoreComBranch(raiz, para);
220
222
  if (dona) {
221
223
  if (temAlteracaoNaoCommitada(dona)) {
222
- throw new Error(`a branch de destino "${para}" esta em check-out em ${dona} com alteracoes nao commitadas; ` +
223
- 'commite ou reverta la antes do ship');
224
+ throw new locale_1.ErroDoCatalogo((m) => m.ship.arvoreSuja(para, dona));
224
225
  }
225
226
  return { dir: dona, temporaria: false };
226
227
  }
@@ -228,7 +229,8 @@ function prepararArvore(raiz, para) {
228
229
  fs.mkdirSync(path.dirname(dir), { recursive: true });
229
230
  const r = (0, util_1.exec)('git', ['worktree', 'add', '--', dir, para], raiz);
230
231
  if (!r.ok) {
231
- 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));
232
234
  }
233
235
  return { dir, temporaria: true };
234
236
  }
@@ -256,10 +258,9 @@ function shaNoRemoto(dir, remoto, branch) {
256
258
  const r = (0, util_1.exec)('git', ['ls-remote', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship'), `refs/heads/${branch}`], dir, 120000);
257
259
  if (!r.ok)
258
260
  return null;
259
- const linha = r.stdout.split('\n').find((l) => l.trim() !== '');
260
- if (!linha)
261
- return null;
262
- 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] ?? '';
263
264
  return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
264
265
  }
265
266
  /** O remoto esta configurado neste repositorio? */
@@ -320,7 +321,9 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
320
321
  const entregas = (0, ledger_1.lerLedger)(dir)
321
322
  .filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && typeof e.mergeSha === 'string')
322
323
  .map((e) => ({ mergeSha: String(e.mergeSha), para: para ?? String(e.para ?? '') }))
323
- .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));
324
327
  if (entregas.length === 0)
325
328
  return null;
326
329
  const perguntados = new Set();
@@ -330,7 +333,7 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
330
333
  continue;
331
334
  perguntados.add(intervalo);
332
335
  // O historico e append-only: o merge continua la, e o revert vem DEPOIS dele.
333
- 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);
334
337
  if (!log.ok)
335
338
  continue;
336
339
  for (const bruto of log.stdout.split('\x1e')) {
@@ -412,7 +415,7 @@ function ship(carregado, threadId, opcoes) {
412
415
  const autorizacao = autorizacaoDePush(raiz, thread, opcoes);
413
416
  r.autorizacao = autorizacao;
414
417
  if (!autorizacao.autorizado) {
415
- 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)));
416
419
  }
417
420
  // 2. Policies do manifesto que valem no gate `ship`. RM-008 (fatia 3): a branch da thread
418
421
  // atras da base e fato do git, calculado aqui (a ponta da base nao esta contida na branch).
@@ -463,20 +466,21 @@ function ship(carregado, threadId, opcoes) {
463
466
  return bloquear('policy.violation', bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; '), bloqueiam.map((v) => v.correcao).join('; '));
464
467
  }
465
468
  // 3. Verificacao independente: reexecuta claims e comandos no HEAD real da thread.
466
- 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 } } });
467
471
  r.verificacao = verificacao;
468
472
  if (!verificacao.ok) {
469
473
  const motivo = verificacao.motivos.find((m) => m !== 'claims.unverifiable');
470
- 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)));
471
475
  }
472
476
  // Referencias locais, resolvidas antes de tomar o lease.
473
477
  const shaDe = shaDaRef(raiz, `refs/heads/${de}`);
474
478
  const shaPara = shaDaRef(raiz, `refs/heads/${para}`);
475
479
  if (!shaDe) {
476
- 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));
477
481
  }
478
482
  if (!shaPara) {
479
- 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));
480
484
  }
481
485
  r.shaDe = shaDe;
482
486
  r.shaParaAntes = shaPara;
@@ -484,14 +488,14 @@ function ship(carregado, threadId, opcoes) {
484
488
  // por git direto. Ciclo sem PLAN nem CHECK nao entrega contrato publico.
485
489
  const tocados = (0, prova_minima_1.cicloSemCheck)(thread) ? contratosDaEntrega(raiz, shaPara, shaDe) : [];
486
490
  if (tocados.length > 0) {
487
- 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));
488
492
  }
489
493
  // O recibo vem do provedor e pertence ao SHA exato da candidata. Teste local
490
494
  // verde ou status de outro commit não libera a entrega.
491
495
  const ci = (0, ci_1.consultarCi)(carregado, shaDe, remoto, opcoes.executorCi);
492
496
  r.ci = ci;
493
497
  if (!ci.ok) {
494
- 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)));
495
499
  }
496
500
  // 4. Lease `main-tree`: so uma thread mergeia por vez.
497
501
  if (r.dryRun) {
@@ -500,20 +504,20 @@ function ship(carregado, threadId, opcoes) {
500
504
  // O ensaio tambem responde ONDE o merge aconteceria e se aquela arvore esta limpa:
501
505
  // descobrir isso so na hora do merge real seria descobrir tarde demais.
502
506
  const dona = arvoreComBranch(raiz, para);
503
- const arvoreDoMerge = dona
504
- ? `${dona} (arvore que tem ${para} em check-out; ${temAlteracaoNaoCommitada(dona) ? 'SUJA, o ship reprovaria com tree.blocked' : 'limpa'})`
505
- : `worktree temporaria em ${path.join((0, manifest_1.dirEstado)(raiz), 'tmp')} (ninguem tem ${para} em check-out)`;
506
- 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)));
507
511
  // Ensaio de 03/10 (R5): sem remoto (ou com --sem-push), o ensaio diz o mesmo que o ship real, e nao
508
512
  // promete um push e uma prova que nao vao acontecer.
509
- const semPushNoReal = opcoes.semPush ? 'push nao executado por --sem-push (merge local concluido)'
510
- : !remotoConfigurado(raiz, remoto) ? `remoto "${remoto}" nao configurado: merge local concluido, sem push a provar` : null;
513
+ const semPushNoReal = opcoes.semPush || !remotoConfigurado(raiz, remoto)
514
+ ? (m) => opcoes.semPush ? m.ship.semPushPorFlag : m.ship.semRemoto(remoto) : null;
511
515
  r.passos = [
512
- `arvore de merge: ${arvoreDoMerge}`,
513
- `git merge --no-ff ${de} -m "<mensagem de ship>"`,
514
- ...(semPushNoReal ? [`sem push: ${semPushNoReal}`] : [
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)))] : [
515
519
  `git push ${remoto} ${para}`,
516
- `git ls-remote ${remoto} refs/heads/${para} (prova do push)`,
520
+ (0, locale_1.textoDoCatalogo)((m) => m.ship.passoProvaDoPush(remoto, para)),
517
521
  ]),
518
522
  ];
519
523
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipIniciado, {
@@ -547,9 +551,7 @@ function ship(carregado, threadId, opcoes) {
547
551
  bloqueadaPor: dono?.thread ?? '(desconhecida)',
548
552
  motivo: aquisicao.motivo ?? 'lease.busy',
549
553
  });
550
- return bloquear(aquisicao.motivo ?? 'lease.busy', aquisicao.falhaRetomada ? aquisicao.detalhe : `lease ${leases_1.LEASE_MAIN_TREE} esta com a thread ${dono?.thread ?? '(desconhecida)'} ` +
551
- `desde ${dono?.adquiridoEm ?? '?'} (${dono?.motivo ?? 'sem motivo'}); ` +
552
- `esta thread entrou na merge queue na posicao ${aquisicao.posicaoNaFila}`, aquisicao.correcao);
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);
553
555
  }
554
556
  r.lease = aquisicao.lease;
555
557
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.leaseAdquirido, {
@@ -576,7 +578,7 @@ function ship(carregado, threadId, opcoes) {
576
578
  }
577
579
  catch (e) {
578
580
  // Arvore de destino indisponivel e reprovacao tipada, nao excecao vazando pelo CLI.
579
- 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));
580
582
  }
581
583
  const passos = [];
582
584
  opcoes.revalidarGit?.('merge', arvore.dir);
@@ -600,11 +602,12 @@ function ship(carregado, threadId, opcoes) {
600
602
  if (!merge.ok) {
601
603
  (0, util_1.exec)('git', ['merge', '--abort'], arvore.dir);
602
604
  r.passos = [...passos, 'git merge --abort'];
603
- 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));
604
607
  }
605
608
  const novo = shaDaRef(arvore.dir, 'HEAD');
606
609
  if (!novo) {
607
- 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));
608
611
  }
609
612
  mergeSha = novo;
610
613
  pontaDaBase = novo;
@@ -612,17 +615,18 @@ function ship(carregado, threadId, opcoes) {
612
615
  const incorporou = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, mergeSha], arvore.dir).ok;
613
616
  passos.push(`git merge-base --is-ancestor ${shaDe.slice(0, 8)} ${mergeSha.slice(0, 8)}`);
614
617
  if (!incorporou) {
615
- 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));
616
619
  }
617
620
  }
618
621
  else {
619
622
  // RM-037 (fatia 5, A1): o merge que trouxe a branch, e nao a ponta da base.
620
623
  const incorporadoEm = commitQueIncorporou(raiz, shaDe, shaPara, passos);
621
624
  if (!incorporadoEm) {
622
- return bloquear('artifact.missing', `${de} ja e ancestral de ${para}, mas o git nao achou o commit de primeiro pai que o incorporou`, 'confira o repositorio: o ship_done precisa do merge que entregou a thread');
625
+ return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPai(de, para)), (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPaiCorrecao));
623
626
  }
624
627
  mergeSha = incorporadoEm;
625
- passos.push(`(nada a mergear: ${de} ja e ancestral de ${para}, incorporado em ${mergeSha.slice(0, 8)})`);
628
+ const incorporado = mergeSha.slice(0, 8);
629
+ passos.push((0, locale_1.textoDoCatalogo)((m) => m.ship.passoJaIncorporado(de, para, incorporado)));
626
630
  }
627
631
  r.mergeSha = mergeSha;
628
632
  r.pontaDaBase = pontaDaBase;
@@ -632,9 +636,7 @@ function ship(carregado, threadId, opcoes) {
632
636
  r.remoto = temRemoto ? remoto : null;
633
637
  if (opcoes.semPush || !temRemoto) {
634
638
  r.pushVerificado = false;
635
- r.detalhe = opcoes.semPush
636
- ? 'push nao executado por --sem-push (merge local concluido)'
637
- : `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));
638
640
  }
639
641
  else {
640
642
  const existeNoRemoto = shaNoRemoto(arvore.dir, remoto, para) !== null;
@@ -645,7 +647,8 @@ function ship(carregado, threadId, opcoes) {
645
647
  passos.push(`git ${argsPush.join(' ')}`);
646
648
  if (!push.ok) {
647
649
  r.passos = passos;
648
- 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));
649
652
  }
650
653
  // A prova: o sha que o REMOTO devolve tem que ser o mesmo do destino local.
651
654
  const shaRemoto = shaNoRemoto(arvore.dir, remoto, para);
@@ -654,8 +657,7 @@ function ship(carregado, threadId, opcoes) {
654
657
  r.pushVerificado = shaRemoto !== null && shaRemoto === pontaDaBase;
655
658
  if (!r.pushVerificado) {
656
659
  r.passos = passos;
657
- return bloquear('runtime.unavailable', `ls-remote devolveu ${shaRemoto ?? '(nada)'} e o destino local esta em ${pontaDaBase}: ` +
658
- '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));
659
661
  }
660
662
  }
661
663
  r.passos = passos;
@@ -717,74 +719,75 @@ function ship(carregado, threadId, opcoes) {
717
719
  });
718
720
  }
719
721
  }
720
- /** 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
+ */
721
726
  function textoDoShip(r) {
727
+ const m = (0, locale_1.msg)().ship;
722
728
  const linhas = [];
723
729
  // I-35: horários no fuso do dono, sem rótulo por linha; o fuso é dito uma vez, no fim.
724
730
  let comHorario = false;
725
731
  const local = (texto) => {
726
- const localizado = (0, horario_1.localizarTexto)(texto);
727
- if (localizado !== texto)
732
+ const remontado = (0, locale_1.remontar)(texto);
733
+ const localizado = (0, horario_1.localizarTexto)(remontado);
734
+ if (localizado !== remontado)
728
735
  comHorario = true;
729
736
  return localizado;
730
737
  };
731
738
  const fechar = () => (comHorario ? [...linhas, (0, horario_1.legendaDoFuso)()] : linhas).join('\n');
732
- const cabecalho = r.dryRun ? 'ork ship (--dry-run, nada foi executado)' : 'ork ship';
733
- linhas.push(`${cabecalho}: thread ${r.thread}`);
734
- linhas.push(` de ${r.de}${r.shaDe ? ` @ ${r.shaDe.slice(0, 8)}` : ''}`);
735
- linhas.push(` para ${r.para}${r.shaParaAntes ? ` @ ${r.shaParaAntes.slice(0, 8)}` : ''}`);
736
- linhas.push(` autorizacao ${r.autorizacao.autorizado ? `AUTORIZADO por ${r.autorizacao.por} (${r.autorizacao.tipo})` : 'AGUARDANDO AUTORIZACAO HUMANA'}`);
737
- 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)));
738
745
  if (r.verificacao) {
739
746
  const v = r.verificacao;
740
- linhas.push(` verificacao ${v.ok ? 'passou' : 'REPROVOU'} no HEAD ${(0, util_1.shaCurto)(v.commit)} ` +
741
- `(${v.claims.filter((c) => c.verificado).length}/${v.claims.length} claims, ` +
742
- `${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));
743
748
  }
744
749
  if (r.ci) {
745
- 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);
746
751
  }
747
752
  linhas.push(...(0, policies_1.linhasDeAviso)(r.violacoes ?? []));
748
753
  if (r.leaseOcupadoPor) {
749
754
  comHorario = true;
750
- 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)));
751
756
  }
752
757
  else if (r.lease) {
753
- 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));
754
759
  }
755
760
  else if (r.dryRun) {
756
- linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} livre`);
761
+ linhas.push(m.leaseLivre(leases_1.LEASE_MAIN_TREE));
757
762
  }
758
763
  if (r.bloqueado) {
759
764
  linhas.push('');
760
- linhas.push(`BLOQUEADO. motivo tipado: ${r.motivo}`);
761
- linhas.push(` detalhe ${local(r.detalhe)}`);
762
- 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)));
763
768
  return fechar();
764
769
  }
765
770
  if (r.dryRun) {
766
771
  linhas.push('');
767
- linhas.push('Passos que o ship real executaria, nesta ordem:');
772
+ linhas.push(m.passosDoEnsaio);
768
773
  for (const p of r.passos)
769
- linhas.push(` ${p}`);
774
+ linhas.push(` ${(0, locale_1.remontar)(p)}`);
770
775
  return fechar();
771
776
  }
772
777
  linhas.push('');
773
- linhas.push(r.jaIncorporado
774
- ? `Nada a mergear: ${r.de} ja estava em ${r.para}, incorporado em ${r.mergeSha}.`
775
- : `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)));
776
779
  if (r.pushVerificado) {
777
- linhas.push(`Push PROVADO: ls-remote de ${r.remoto}/${r.para} devolveu ${r.shaRemoto}`);
778
- linhas.push(` e o destino local esta no mesmo sha: ${r.pontaDaBase ?? 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)));
779
782
  }
780
783
  else {
781
- linhas.push(`Push nao provado: ${local(r.detalhe) || 'sem remoto configurado'}`);
784
+ linhas.push(m.pushNaoProvado(local(r.detalhe) || m.semRemotoConfigurado));
782
785
  }
783
786
  linhas.push('');
784
- linhas.push('Evidencia (comandos executados):');
787
+ linhas.push(m.evidencia);
785
788
  for (const p of r.passos)
786
- linhas.push(` ${p}`);
789
+ linhas.push(` ${(0, locale_1.remontar)(p)}`);
787
790
  linhas.push('');
788
- linhas.push(`Ledger: ork phase list ${r.thread} (evento ship_done)`);
791
+ linhas.push(m.ledger(r.thread));
789
792
  return fechar();
790
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) {