@orkastery/cli 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/adapters/openclaw/openclaw.plugin.json +1 -1
  2. package/adapters/openclaw/package.json +1 -1
  3. package/dist/adapters/claude-bg.js +6 -6
  4. package/dist/adapters/grok-events.js +227 -0
  5. package/dist/adapters/grok-mcp-servidor.js +612 -0
  6. package/dist/adapters/grok-mcp.js +178 -0
  7. package/dist/adapters/grok.js +686 -0
  8. package/dist/agendador-cpu.js +92 -0
  9. package/dist/branch-de-estado.js +7 -2
  10. package/dist/check-agil.js +48 -20
  11. package/dist/check-paralelo.js +73 -18
  12. package/dist/conducao.js +5 -0
  13. package/dist/docs.js +9 -16
  14. package/dist/doctor-forja.js +1 -3
  15. package/dist/doctor.js +1 -1
  16. package/dist/entrega-pr.js +10 -10
  17. package/dist/fabrica-estado.js +20 -11
  18. package/dist/horario.js +4 -1
  19. package/dist/index.js +20 -10
  20. package/dist/integracoes-locais.js +2 -0
  21. package/dist/locale-accounts.js +11 -3
  22. package/dist/locale-ajuda.js +10 -6
  23. package/dist/locale-forja.js +2 -4
  24. package/dist/locale-operacao-restante.js +2 -2
  25. package/dist/locale-retry.js +40 -2
  26. package/dist/locale-ship.js +10 -2
  27. package/dist/manifest.js +6 -1
  28. package/dist/mcp-install.js +22 -12
  29. package/dist/mcp-server.js +42 -16
  30. package/dist/merge-da-entrega.js +85 -0
  31. package/dist/network-roadmap.js +18 -14
  32. package/dist/noctum-aceite.js +154 -14
  33. package/dist/noctum-cli.js +69 -12
  34. package/dist/noctum-entrega.js +55 -7
  35. package/dist/noctum-envelope.js +1 -1
  36. package/dist/noctum-execucao.js +5 -1
  37. package/dist/noctum-fechamento.js +18 -7
  38. package/dist/noctum-fila.js +6 -1
  39. package/dist/noctum-guarda.js +81 -4
  40. package/dist/noctum-maquinas.js +5 -1
  41. package/dist/noctum-modo.js +35 -7
  42. package/dist/noctum-reconciliacao.js +4 -1
  43. package/dist/noctum-rede.js +102 -0
  44. package/dist/noctum-relatorio.js +44 -10
  45. package/dist/noctum-retomada-rede.js +71 -0
  46. package/dist/noctum-vigia.js +49 -9
  47. package/dist/parado-no-condutor.js +14 -15
  48. package/dist/phase.js +43 -15
  49. package/dist/postura-local.js +7 -3
  50. package/dist/preflight.js +2 -1
  51. package/dist/ratelimit.js +1 -0
  52. package/dist/retry.js +103 -10
  53. package/dist/runtime-context.js +165 -45
  54. package/dist/runtime-escada.js +7 -1
  55. package/dist/runtime-profiles.js +27 -17
  56. package/dist/runtimes.js +42 -5
  57. package/dist/security-scan/agil.js +18 -7
  58. package/dist/security-scan/executor.js +8 -0
  59. package/dist/session-watcher-grok.js +425 -0
  60. package/dist/session-watcher.js +19 -4
  61. package/dist/sessoes-contas.js +33 -5
  62. package/dist/setup.js +11 -11
  63. package/dist/varredura-acoes.js +8 -15
  64. package/dist/verify.js +26 -10
  65. package/package.json +2 -2
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CARENCIA_DA_RETOMADA_MS = void 0;
4
+ exports.retomadaNaRede = retomadaNaRede;
5
+ const maquina_1 = require("./maquina");
6
+ const noctum_arco_1 = require("./noctum-arco");
7
+ const noctum_coordenacao_1 = require("./noctum-coordenacao");
8
+ const noctum_envelope_1 = require("./noctum-envelope");
9
+ /** O cancelamento exige duas carências de batida: uma partição de 15 min não transfere trabalho. */
10
+ exports.CARENCIA_DA_RETOMADA_MS = 2 * noctum_coordenacao_1.BATIDA_VENCIDA_MS;
11
+ const idadeDoSinal = (estado, maquina, quando) => {
12
+ const sinal = estado.sinais.get(maquina);
13
+ return sinal ? Date.parse(quando) - Date.parse(sinal) : Number.POSITIVE_INFINITY;
14
+ };
15
+ const canceladasDestaMaquina = (estado, maquina) => [...estado.ordens.values()].filter(o => o.maquina === maquina && o.estado === 'isolada' && !!o.cancelada)
16
+ .map(o => ({ ordem: o.ordem, trabalho: o.trabalho }));
17
+ /**
18
+ * Executa no máximo uma mudança de coordenação por chamada. Releituras e corridas continuam sob as trocas atômicas da N3;
19
+ * uma recusa tipada vira lacuna do tique, nunca estado vazio.
20
+ */
21
+ function retomadaNaRede(carregado, arco, opcoes = {}) {
22
+ const quando = opcoes.quando ?? new Date().toISOString();
23
+ const local = (0, noctum_arco_1.lerArco)(carregado.raiz, arco, quando);
24
+ if (!local?.conteudo || !(0, noctum_envelope_1.envelopeMultimaquina)(local.conteudo)) {
25
+ return { aplicavel: false, acoes: [], canceladasLocais: [], lacuna: null };
26
+ }
27
+ const eu = (0, maquina_1.nomeDaMaquina)(opcoes.maquina);
28
+ const acoes = [];
29
+ try {
30
+ let estado = (0, noctum_coordenacao_1.lerCoordenacao)(carregado, arco, { ...opcoes, quando });
31
+ const cessao = estado.autoridade ? estado.cessoes.get(estado.autoridade.geracao) : null;
32
+ if (estado.autoridade && estado.autoridade.maquina !== eu && cessao?.para === eu && local.situacao === 'vigente') {
33
+ (0, noctum_coordenacao_1.assumirAutoridade)(carregado, arco, { ...opcoes, quando });
34
+ acoes.push('autoridade-assumida-por-cessao');
35
+ estado = (0, noctum_coordenacao_1.lerCoordenacao)(carregado, arco, { ...opcoes, quando });
36
+ }
37
+ else if (estado.autoridade && estado.autoridade.maquina !== eu && local.situacao === 'vigente' &&
38
+ idadeDoSinal(estado, estado.autoridade.maquina, quando) > noctum_coordenacao_1.BATIDA_VENCIDA_MS) {
39
+ (0, noctum_coordenacao_1.assumirAutoridade)(carregado, arco, { ...opcoes, quando,
40
+ forcar: { motivo: 'noctum.retomada.autoridade-sem-sinal' } });
41
+ acoes.push('autoridade-tomada-sem-sinal');
42
+ estado = (0, noctum_coordenacao_1.lerCoordenacao)(carregado, arco, { ...opcoes, quando });
43
+ }
44
+ if (estado.autoridade?.maquina === eu && local.situacao === 'encerrado') {
45
+ const para = (estado.vigente.conteudo.maquinas ?? []).filter(m => m.nome !== eu)
46
+ .map(m => ({ nome: m.nome, em: estado.sinais.get(m.nome) ?? '' }))
47
+ .sort((a, b) => Date.parse(b.em || '1970-01-01') - Date.parse(a.em || '1970-01-01'))[0];
48
+ if (para && !estado.cessoes.has(estado.autoridade.geracao)) {
49
+ (0, noctum_coordenacao_1.cederAutoridade)(carregado, arco, para.nome, 'noctum.retomada.cessao-no-encerramento', { ...opcoes, quando });
50
+ acoes.push(`autoridade-cedida:${para.nome}`);
51
+ estado = (0, noctum_coordenacao_1.lerCoordenacao)(carregado, arco, { ...opcoes, quando });
52
+ }
53
+ }
54
+ else if (estado.autoridade?.maquina === eu && local.situacao === 'vigente') {
55
+ const presa = new Map((estado.vigente.conteudo.trabalhos ?? []).map(t => [t.id, t.maquina ?? null]));
56
+ const ordem = [...estado.ordens.values()].find(o => o.maquina !== eu && (0, noctum_coordenacao_1.ordemViva)(o) && !o.cancelada &&
57
+ presa.get(o.trabalho) !== o.maquina && idadeDoSinal(estado, o.maquina, quando) > exports.CARENCIA_DA_RETOMADA_MS);
58
+ if (ordem) {
59
+ (0, noctum_coordenacao_1.cancelarOrdem)(carregado, arco, ordem.ordem, 'noctum.retomada.maquina-sem-sinal', { ...opcoes, quando });
60
+ acoes.push(`ordem-cancelada:${ordem.ordem}`);
61
+ estado = (0, noctum_coordenacao_1.lerCoordenacao)(carregado, arco, { ...opcoes, quando });
62
+ }
63
+ }
64
+ return { aplicavel: true, acoes, canceladasLocais: canceladasDestaMaquina(estado, eu), lacuna: null };
65
+ }
66
+ catch (e) {
67
+ if (!(e instanceof noctum_envelope_1.RecusaDoArco))
68
+ throw e;
69
+ return { aplicavel: true, acoes, canceladasLocais: [], lacuna: { motivo: e.motivo, detalhe: e.message } };
70
+ }
71
+ }
@@ -76,6 +76,7 @@ const maquina_1 = require("./maquina");
76
76
  const noctum_arco_1 = require("./noctum-arco");
77
77
  const noctum_envelope_1 = require("./noctum-envelope");
78
78
  const noctum_execucao_1 = require("./noctum-execucao");
79
+ const noctum_maquinas_1 = require("./noctum-maquinas");
79
80
  const noctum_entrega_1 = require("./noctum-entrega");
80
81
  const noctum_reconciliacao_1 = require("./noctum-reconciliacao");
81
82
  const noctum_supervisao_1 = require("./noctum-supervisao");
@@ -85,6 +86,7 @@ const claude_bg_1 = require("./adapters/claude-bg");
85
86
  const runtime_profiles_1 = require("./runtime-profiles");
86
87
  const sessoes_contas_1 = require("./sessoes-contas");
87
88
  const noctum_sessoes_em_voo_1 = require("./noctum-sessoes-em-voo");
89
+ const noctum_retomada_rede_1 = require("./noctum-retomada-rede");
88
90
  const thread_1 = require("./thread");
89
91
  const util_1 = require("./util");
90
92
  const ARQUIVO_DO_CONDUTOR = 'condutor.lock';
@@ -260,10 +262,24 @@ function passoConduzido(carregado, arco, quem, opcoes = {}) {
260
262
  (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: visao.parada.motivo, detalhe: visao.parada.detalhe }], quando);
261
263
  return { acao: 'parado', motivo: visao.parada.motivo, detalhe: visao.parada.detalhe };
262
264
  }
263
- const r = (0, noctum_execucao_1.passoDoArco)(carregado, arco, { ...opcoes.passo, quando, maquina: opcoes.maquina ?? opcoes.passo?.maquina,
265
+ const opcoesDaN2 = { ...opcoes.passo, quando, maquina: opcoes.maquina ?? opcoes.passo?.maquina,
264
266
  ...(visao ? { perfis: () => visao.perfis } : {}),
265
267
  ...(conteudo && estado ? { alvos: (fase, runtime, modo) => (0, noctum_supervisao_1.alvosDaFase)(carregado, conteudo, estado, fase, runtime, modo) } : {}),
266
- supervisao: decisoesDaSupervisao(sup, estado) });
268
+ supervisao: decisoesDaSupervisao(sup, estado) };
269
+ let r;
270
+ if (estado?.conteudo && (0, noctum_envelope_1.envelopeMultimaquina)(estado.conteudo)) {
271
+ const daMaquina = (0, noctum_maquinas_1.passoDaMaquina)(carregado, arco, { ...opcoes.coordenacao, quando, maquina: opcoesDaN2.maquina,
272
+ consultarSessoes: opcoesDaN2.consultarSessoes ?? opcoes.consultarRuntime, n2: opcoesDaN2 });
273
+ if (daMaquina.acao === 'aguardar') {
274
+ r = { acao: 'aguardar', ate: cadencia, motivo: daMaquina.motivo, fila: null, detalhe: daMaquina.detalhe, maquina: daMaquina.relatorio };
275
+ }
276
+ else {
277
+ r = { ...daMaquina.passo, ...(daMaquina.acao === 'passo' ? { maquina: daMaquina.relatorio } : {}) };
278
+ }
279
+ }
280
+ else {
281
+ r = (0, noctum_execucao_1.passoDoArco)(carregado, arco, opcoesDaN2);
282
+ }
267
283
  gravarEstadoDoPasso(carregado, arco, quem, r, quando);
268
284
  // N1 do CHECK 2: a baseline do trabalho que falhou sem ser espera isola o trabalho, com a causa: os outros seguem, e o
269
285
  // tique e o relatório dizem por quê.
@@ -285,7 +301,7 @@ function passoConduzido(carregado, arco, quem, opcoes = {}) {
285
301
  try {
286
302
  const entrega = (opcoes.entregar ?? noctum_entrega_1.passoDaEntrega)(carregado, arco, { maquina: opcoes.maquina ?? opcoes.passo?.maquina,
287
303
  lerReservas: opcoes.passo?.lerReservas, consultarSessoes: opcoes.passo?.consultarSessoes, ...(visao ? { perfis: () => visao.perfis } : {}),
288
- ...opcoes.entrega, quando });
304
+ remoto: opcoes.coordenacao?.remoto, redeDaCoordenacao: opcoes.coordenacao?.rede, ...opcoes.entrega, quando });
289
305
  return { ...r, entrega };
290
306
  }
291
307
  catch (e) {
@@ -379,6 +395,7 @@ function vigiarArco(carregado, arco, opcoes = {}) {
379
395
  opcoes.depoisDeIniciar?.();
380
396
  const lacunas = [];
381
397
  const contagem = { reservas: 0, retomadas: 0, isolados: 0, contas: 0 };
398
+ let passoTerminal = null;
382
399
  if (sup.interrupcoesSeguidas >= parametros.interrupcoesQueParam && !sup.parada) {
383
400
  sup = (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: 'supervisor-falhou',
384
401
  detalhe: `${s.interrupcoesSeguidas} tiques do vigia interrompidos em série (o limite é ${parametros.interrupcoesQueParam})` }], quando);
@@ -386,9 +403,22 @@ function vigiarArco(carregado, arco, opcoes = {}) {
386
403
  const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
387
404
  const conteudo = v2(estado);
388
405
  if (conteudo) {
406
+ const retomada = (0, noctum_retomada_rede_1.retomadaNaRede)(carregado, arco, { ...opcoes.coordenacao, quando,
407
+ maquina: opcoes.maquina ?? opcoes.passo?.maquina });
408
+ if (retomada.lacuna)
409
+ lacunas.push(`retomada na rede: ${retomada.lacuna.motivo}: ${retomada.lacuna.detalhe}`);
410
+ if (estado.conteudo && (0, noctum_envelope_1.envelopeMultimaquina)(estado.conteudo) && estado.situacao !== 'vigente' && estado.situacao !== 'agendado') {
411
+ const daMaquina = (0, noctum_maquinas_1.passoDaMaquina)(carregado, arco, { ...opcoes.coordenacao, quando,
412
+ maquina: opcoes.maquina ?? opcoes.passo?.maquina, consultarSessoes: opcoes.passo?.consultarSessoes ?? opcoes.consultarRuntime,
413
+ n2: opcoes.passo });
414
+ passoTerminal = daMaquina.acao === 'aguardar'
415
+ ? { acao: 'aguardar', ate: new Date(Date.parse(quando) + parametros.cadenciaMs).toISOString(), motivo: daMaquina.motivo,
416
+ fila: null, detalhe: daMaquina.detalhe, maquina: daMaquina.relatorio }
417
+ : { ...daMaquina.passo, ...(daMaquina.acao === 'passo' ? { maquina: daMaquina.relatorio } : {}) };
418
+ }
389
419
  const store = (opcoes.lerStore ?? storePadrao(raiz))();
390
420
  aplicarContas(carregado, arco, conteudo, store, quando, contagem);
391
- reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem);
421
+ reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem, retomada.canceladasLocais);
392
422
  for (const d of (0, noctum_reconciliacao_1.decidirPedidos)(raiz, arco, (0, noctum_arco_1.lerArco)(raiz, arco, quando))) {
393
423
  (0, retry_1.cancelarPedido)(carregado, d.pedido, d.motivo);
394
424
  (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'pedido_tratado', pedido: d.pedido, thread: d.thread, acao: 'cancelado', motivo: d.motivo.slice(0, 200) }], quando);
@@ -407,7 +437,7 @@ function vigiarArco(carregado, arco, opcoes = {}) {
407
437
  sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
408
438
  // D5: com a trava do condutor livre, este tique conduz: a geração do vigia, com a prova, e um passo.
409
439
  let condutor = 'sem-passo';
410
- let passo = null;
440
+ let passo = passoTerminal;
411
441
  const vigente = (0, noctum_arco_1.lerArco)(raiz, arco, quando).situacao === 'vigente';
412
442
  if (!sup.parada && vigente && conteudo) {
413
443
  const fdCondutor = (0, fila_pesada_1.tentarTravaExclusiva)(path.join(dir, ARQUIVO_DO_CONDUTOR));
@@ -459,7 +489,7 @@ function vigiarArco(carregado, arco, opcoes = {}) {
459
489
  * com o instante da leitura; as reservas pendentes são decididas sobre o arco relido sob a trava (A3); e, com o arco
460
490
  * vigente e sem parada (A5), as sessões e as recusas repetidas. Com a trava ocupada, tudo fica para o tique seguinte.
461
491
  */
462
- function reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem) {
492
+ function reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem, ordensCanceladas = []) {
463
493
  const { raiz } = carregado;
464
494
  const noctum = path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'noctum');
465
495
  const fd = (0, fila_pesada_1.tentarTravaExclusiva)(path.join(noctum, 'despacho.lock'));
@@ -497,7 +527,7 @@ function reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, q
497
527
  }
498
528
  if (estado.situacao !== 'vigente' || sup.parada)
499
529
  return;
500
- aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar);
530
+ aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar, ordensCanceladas);
501
531
  // B4 do CHECK: o trabalho que o núcleo recusa seguidas vezes pelo mesmo tipo de motivo (a árvore, a policy, o erro
502
532
  // antes de lançar) não volta a noite toda: no teto, e com a série durando ao menos uma cadência, é isolado. O soluço
503
533
  // mais curto que a cadência (a conferência de login inconclusiva da A14, que o núcleo refaz a cada despacho) não isola.
@@ -528,7 +558,7 @@ function aplicarContas(carregado, arco, conteudo, store, quando, contagem) {
528
558
  * listagem nova; sem confirmação, a parada fica no log como não confirmada e nada é autorizado (no teto das tentativas, o
529
559
  * trabalho é isolado). Confirmada, ou já morta, a sessão vira `sessao_morta` no ledger da thread e a retomada é autorizada.
530
560
  */
531
- function aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar) {
561
+ function aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar, ordensCanceladas = []) {
532
562
  const { raiz } = carregado;
533
563
  const sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
534
564
  const parametros = sup.parametros;
@@ -547,7 +577,17 @@ function aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacu
547
577
  registrarMorte(raiz, p.thread, p, prova);
548
578
  return confirmada ? prova : null;
549
579
  };
550
- for (const d of (0, noctum_reconciliacao_1.decidirSessoes)(raiz, arco, conteudo, (0, noctum_arco_1.lerArco)(raiz, arco, quando), sup, leitura, quando)) {
580
+ const cancelados = new Set(ordensCanceladas.map(o => o.trabalho));
581
+ for (const s of (0, noctum_sessoes_em_voo_1.sessoesEmVooDoArco)(raiz, (0, noctum_arco_1.lerArco)(raiz, arco, quando)).filter(s => cancelados.has(s.trabalho))) {
582
+ if (!s.sessionId || !s.thread) {
583
+ lacunas.push(`trabalho ${s.trabalho}: a ordem foi cancelada, mas a sessão em voo não está identificada`);
584
+ continue;
585
+ }
586
+ const prova = pararEConferir({ sessionId: s.sessionId, runtime: s.runtime, perfil: s.conta, thread: s.thread }, 'ordem-cancelada', s.trabalho);
587
+ if (!prova)
588
+ lacunas.push(`${s.thread}: a parada da sessão ${s.sessionId} da ordem cancelada não foi confirmada pelo runtime`);
589
+ }
590
+ for (const d of (0, noctum_reconciliacao_1.decidirSessoes)(raiz, arco, conteudo, (0, noctum_arco_1.lerArco)(raiz, arco, quando), sup, leitura, quando, cancelados)) {
551
591
  if (d.acao === 'aguardar') {
552
592
  lacunas.push(`${d.thread}: ${d.detalhe}`);
553
593
  continue;
@@ -102,6 +102,7 @@ const session_watcher_claude_1 = require("./session-watcher-claude");
102
102
  const thread_1 = require("./thread");
103
103
  const util_1 = require("./util");
104
104
  const worktree_1 = require("./worktree");
105
+ const merge_da_entrega_1 = require("./merge-da-entrega");
105
106
  exports.CONTRATO_PRS = 'ork.prs-abertos/v1';
106
107
  /** D4: duas batidas do pulse. Abaixo disto o condutor pode estar agindo. */
107
108
  exports.LIMIAR_PARADO_NO_CONDUTOR_MIN = 30;
@@ -783,20 +784,19 @@ function refsLocais(raiz, remoto) {
783
784
  }
784
785
  return mapa;
785
786
  }
786
- /** Os merges `ship(<thread>)` da base numa leitura so, do mais novo para o mais velho (fica o mais novo). */
787
- function mergesNaBase(raiz, baseRef) {
787
+ /** Os merges das entregas da base numa leitura so, do mais novo para o mais velho (fica o mais novo). */
788
+ function mergesNaBase(raiz, baseRef, base, threads) {
788
789
  const mapa = new Map();
789
790
  if (!baseRef)
790
791
  return mapa;
791
- // Regex basica do git: o `(` e literal. A ref vem qualificada do `for-each-ref`.
792
- const r = git(raiz, ['log', baseRef, '--first-parent', '--format=%H%x09%cI%x09%s', '--grep=^ship(']);
793
- if (!r.ok)
794
- return mapa;
795
- for (const linha of r.stdout.split('\n')) {
796
- const [sha, em, assunto] = linha.split('\t');
797
- const m = /^ship\(([A-Za-z0-9._-]+)\)/.exec(assunto ?? '');
798
- if (m && sha && SHA.test(sha) && !mapa.has(m[1]))
799
- mapa.set(m[1], { sha, em: instante(em) });
792
+ const reconhecidos = (0, merge_da_entrega_1.mergesDasEntregasNaBase)(raiz, baseRef, base, threads.map((t) => ({
793
+ thread: t.id,
794
+ branch: (0, merge_da_entrega_1.branchRegistradaDaEntrega)(raiz, t.id) ?? (0, worktree_1.branchDaWorktree)(t),
795
+ })));
796
+ for (const t of threads) {
797
+ const merge = reconhecidos.get(t.id)?.[0];
798
+ if (merge)
799
+ mapa.set(t.id, { sha: merge.mergeSha, em: merge.em });
800
800
  }
801
801
  return mapa;
802
802
  }
@@ -857,7 +857,6 @@ function entregasDoProjeto(carregado, opcoes) {
857
857
  const refs = refsLocais(raiz, remoto);
858
858
  // A copia do remoto vem primeiro: a base local desta maquina pode estar parada (o merge e pelo GitHub).
859
859
  const baseRef = [`refs/remotes/${remoto}/${baseBranch}`, `refs/heads/${baseBranch}`].find((r) => refs.has(r)) ?? null;
860
- const merges = mergesNaBase(raiz, baseRef);
861
860
  const sessoes = opcoes.sessoes ?? [];
862
861
  const threads = [];
863
862
  for (const id of (0, thread_1.listarIds)(raiz)) {
@@ -866,6 +865,7 @@ function entregasDoProjeto(carregado, opcoes) {
866
865
  }
867
866
  catch { /* thread ilegivel fica de fora */ }
868
867
  }
868
+ const merges = mergesNaBase(raiz, baseRef, baseBranch, threads);
869
869
  const fatos = threads.filter((t) => t.status !== 'fechada').map((t) => {
870
870
  let eventos = [];
871
871
  try {
@@ -1007,11 +1007,10 @@ function entregasDoProjeto(carregado, opcoes) {
1007
1007
  desde = f.merge.em ?? fimEm;
1008
1008
  peloGit = true;
1009
1009
  passo = `registrar a entrega do merge ${f.merge.sha.slice(0, 7)} (ork ship registrar-pr ${t.id})`;
1010
- evidencia.push(`git log: merge ship(${t.id}) ${f.merge.sha.slice(0, 7)} na base, sem ship_done no ledger`);
1010
+ evidencia.push(`git log: merge da entrega de ${t.id} ${f.merge.sha.slice(0, 7)} na base, sem ship_done no ledger`);
1011
1011
  }
1012
1012
  else if (!aberto && daBranch.mesclado && !f.entregueNaPonta && (daBranch.mesclado.mescladoEm ?? fimEm)) {
1013
- // N4 do CHECK (rodada 2): PR mesclado sem o assunto ship(<thread>); o `registrar-pr` nao o acha sozinho. Com o
1014
- // merge ship(<thread>) ainda sem registro na base (squash), o `registrar-pr` acha.
1013
+ // N4 do CHECK (rodada 2): PR mesclado sem assunto ou branch reconhecivel; o `registrar-pr` nao o acha sozinho.
1015
1014
  caso = 'sem-registro';
1016
1015
  desde = daBranch.mesclado.mescladoEm ?? fimEm;
1017
1016
  passo = f.merge && !f.mergeRegistrado ? `registrar a entrega do merge ${f.merge.sha.slice(0, 7)} (ork ship registrar-pr ${t.id})`
package/dist/phase.js CHANGED
@@ -73,6 +73,7 @@ const board_1 = require("./board");
73
73
  const verify_1 = require("./verify");
74
74
  const session_watcher_1 = require("./session-watcher");
75
75
  const session_watcher_claude_1 = require("./session-watcher-claude");
76
+ const session_watcher_grok_1 = require("./session-watcher-grok");
76
77
  const manifest_1 = require("./manifest");
77
78
  const mcp_grafo_1 = require("./mcp-grafo");
78
79
  const runtimes_1 = require("./runtimes");
@@ -84,6 +85,7 @@ const ratelimit_1 = require("./ratelimit");
84
85
  const impedimento_1 = require("./impedimento");
85
86
  const claude_bg_1 = require("./adapters/claude-bg");
86
87
  const codex_1 = require("./adapters/codex");
88
+ const grok_1 = require("./adapters/grok");
87
89
  const memoria_1 = require("./memoria");
88
90
  const prompts_1 = require("./prompts");
89
91
  const slug_1 = require("./slug");
@@ -183,8 +185,9 @@ function perfilParaDespacho(carregado, thread, fase, runtime, opcoes) {
183
185
  const escolha = escolherPerfil(raiz, runtime, { perfil: opcoes.perfil, excluir, politica, carga });
184
186
  if (escolha.erro || !escolha.perfil || opcoes.dryRun)
185
187
  return escolha;
188
+ // RM-067 (F3): o grok nao tem conferencia de login sem ler a credencial; o despacho prova o login (semConferencia).
186
189
  const auth = runtime === 'claude-bg' ? (0, claude_bg_1.conferirAuth)(escolha.perfil) : runtime === 'codex' ? (0, codex_1.conferirAuth)(escolha.perfil)
187
- : { ok: false, detalhe: `runtime ${runtime} sem conferencia de login` };
190
+ : runtime === 'grok' ? (0, grok_1.conferirAuth)(escolha.perfil) : { ok: false, detalhe: `runtime ${runtime} sem conferencia de login` };
188
191
  if (auth.ok)
189
192
  return escolha;
190
193
  let motivo, razao;
@@ -477,6 +480,7 @@ function dadosDoDespacho(ctx, comando) {
477
480
  ...(ctx.identidade ? { identidade: ctx.identidade } : {}),
478
481
  // I-33 (D4): so identidade e diretorio do perfil; o store guarda o resto e nada e segredo.
479
482
  ...(ctx.perfil ? { perfil: ctx.perfil } : {}),
483
+ ...(ctx.perfilPedido ? { perfilPedido: ctx.perfilPedido } : {}),
480
484
  comando: comandoMascarado(comando, ctx.promptSha256),
481
485
  };
482
486
  }
@@ -554,7 +558,7 @@ sensores) {
554
558
  vincularConducaoDaSessao(ctx, sessionId);
555
559
  // I-51 (RM-047): as outras maquinas veem a fase nova; so com a fabrica compartilhada.
556
560
  (0, fabrica_publicar_1.publicarEmSegundoPlano)(ctx.raiz);
557
- if (ctx.runtime === 'codex' || ctx.runtime === 'claude-bg')
561
+ if (ctx.runtime === 'codex' || ctx.runtime === 'claude-bg' || ctx.runtime === 'grok')
558
562
  registrarObservacao(ctx, sessao, dir, controlador, sensores);
559
563
  return sessao;
560
564
  }
@@ -590,9 +594,14 @@ function registrarObservacao(ctx, sessao, dir, controlador, sensores) {
590
594
  // I-34: claude-bg observa pela fonte nativa; no PLAN o registro guarda o sha de base do artefato.
591
595
  // I-33 (N1): o GO codex registra o HEAD do despacho, como a fonte claude-bg; ele revela commit pelo shell no checkpoint.
592
596
  const head = ctx.runtime === 'codex' && ctx.fase === 'GO' ? { head: ctx.headNoDespacho ?? null } : {};
593
- const fonte = ctx.runtime === 'claude-bg' ? (0, session_watcher_claude_1.fonteClaudeDoDespacho)(ctx.raiz, ctx.thread.id, ctx.fase, ctx.cwd)
594
- : sensores?.logPath ? { logPath: sensores.logPath, processoPath: sensores.processoPath, reciboPath: sensores.reciboPath, ...head }
595
- : controlador ? { controlador, cwd: ctx.cwd, ...head } : null;
597
+ // RM-067 (F2, D8): o grok observa o stream e os recibos do supervisor; o HEAD do GO vem de antes do despacho.
598
+ // RM-067 (F3): a pasta da sessao mora na casa do perfil do despacho; sem perfil, na do processo.
599
+ const fonte = ctx.runtime === 'grok' ? (sensores?.logPath && sensores.processoPath && sensores.reciboPath
600
+ ? (0, session_watcher_grok_1.fonteGrokDoDespacho)(ctx.raiz, ctx.thread.id, ctx.fase, ctx.cwd, { logPath: sensores.logPath, processoPath: sensores.processoPath, reciboPath: sensores.reciboPath }, ctx.perfil ? (0, runtime_profiles_1.diretorioDoPerfil)(ctx.perfil) : (0, grok_1.casaDoGrok)(), { head: ctx.headNoDespacho, ...(ctx.artefatoNoDespacho !== undefined ? { artefato: ctx.artefatoNoDespacho } : {}) })
601
+ : null)
602
+ : ctx.runtime === 'claude-bg' ? (0, session_watcher_claude_1.fonteClaudeDoDespacho)(ctx.raiz, ctx.thread.id, ctx.fase, ctx.cwd)
603
+ : sensores?.logPath ? { logPath: sensores.logPath, processoPath: sensores.processoPath, reciboPath: sensores.reciboPath, ...head }
604
+ : controlador ? { controlador, cwd: ctx.cwd, ...head } : null;
596
605
  if (!fonte)
597
606
  return;
598
607
  (0, session_watcher_1.prepararFonteWatcher)(ctx.raiz, sessao.sessionId, fonte);
@@ -904,6 +913,9 @@ tomadaPrevia) {
904
913
  }
905
914
  }
906
915
  const cwd = (0, procedencia_1.diretorioDaThread)(raiz, thread);
916
+ // O pedido explicito precisa sobreviver mesmo quando o despacho para antes de escolher ou abrir a conta.
917
+ // `perfil` continua sendo o destino efetivo; misturar os dois quebraria a rotacao por falha da propria conta.
918
+ const perfilPedido = opcoes.perfil !== undefined ? { id: opcoes.perfil, runtime } : undefined;
907
919
  // RM-063 (F3): o prompt vai ao disco e ao ledger, com o sha256, ANTES do contexto do runtime e do adaptador. No
908
920
  // incidente de 12/10/2026 a fase morreu no despacho e o `ork retry run` saiu com "nao ha despacho falho registrado
909
921
  // em GO com prompt gravado"; daqui em diante, toda tentativa deixa o prompt que o retry redespacha sem pedir o texto.
@@ -911,7 +923,8 @@ tomadaPrevia) {
911
923
  const promptNoLedger = { promptPath: path.relative(raiz, promptPath), promptSha256: sha };
912
924
  if (!opcoes.dryRun) {
913
925
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.promptGravado, { fase, slug, modo: thread.modo, runtime, model, effort, cwd,
914
- ...promptNoLedger, origem: 'phase.run', canal, ...(opcoes.correlacao ? { correlacao: opcoes.correlacao } : {}), identidade });
926
+ ...promptNoLedger, origem: 'phase.run', canal, ...(opcoes.correlacao ? { correlacao: opcoes.correlacao } : {}), identidade,
927
+ ...(perfilPedido ? { perfilPedido } : {}) });
915
928
  }
916
929
  const correcaoDoRetry = `ork retry run ${thread.id} redespacha o mesmo prompt (sha256 ${sha.slice(0, 12)})`;
917
930
  let contextoRuntime;
@@ -921,7 +934,8 @@ tomadaPrevia) {
921
934
  catch (e) {
922
935
  const erro = `runtime.unavailable: ${e.message}`;
923
936
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: 'runtime.unavailable',
924
- modo: thread.modo, detalhe: erro, fase, slug, ...(opcoes.dryRun ? {} : { ...promptNoLedger, correcao: correcaoDoRetry }) });
937
+ modo: thread.modo, detalhe: erro, fase, slug, ...(opcoes.dryRun ? {} : { ...promptNoLedger, correcao: correcaoDoRetry }),
938
+ ...(perfilPedido ? { perfilPedido } : {}) });
925
939
  return { thread, slug, promptPath, promptSha256: sha, comando: [], sessionId: null,
926
940
  verificada: false, pausaAoFim: (0, thread_1.pausaNaThread)(thread, fase), dryRun: opcoes.dryRun === true,
927
941
  runtime, model, effort, bloqueado: true, motivo: 'runtime.unavailable', violacoes, erro };
@@ -940,16 +954,20 @@ tomadaPrevia) {
940
954
  }
941
955
  if (escolha.erro) {
942
956
  const motivo = escolha.motivo ?? 'runtime.unavailable';
943
- const erro = `${motivo}: ${escolha.erro}`;
957
+ const erro = perfilPedido
958
+ ? (0, locale_1.textoDoCatalogo)((m) => m.retry.perfilPedidoRecusado(perfilPedido.id, perfilPedido.runtime, motivo, escolha.erro))
959
+ : `${motivo}: ${escolha.erro}`;
944
960
  if (!opcoes.dryRun) {
945
961
  const semPerfil = { identidade, raiz, thread, fase, slug, promptPath, promptSha256: sha, runtime, cwd, model, effort,
946
- origem: 'phase.run', canal, correlacao: opcoes.correlacao ?? null };
962
+ origem: 'phase.run', canal, correlacao: opcoes.correlacao ?? null, ...(perfilPedido ? { perfilPedido } : {}) };
947
963
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.despachoFalhou, { ...dadosDoDespacho(semPerfil, []), erro });
948
964
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo, modo: thread.modo, detalhe: erro,
949
- correcao: motivo === 'cost.violation'
950
- ? 'refaca o login do perfil pela assinatura (claude auth login --claudeai ou codex login com ChatGPT) e rode ork accounts check; perfil de provider pago nunca despacha'
951
- : 'ork accounts list mostra o estado de cada perfil; ork retry run segue pela ordem de fallback ou pela fila',
952
- fase, slug, runtime, origem: 'phase.run' });
965
+ correcao: perfilPedido
966
+ ? (0, locale_1.textoDoCatalogo)((m) => m.retry.correcaoDoPerfilPedido(perfilPedido.id, perfilPedido.runtime, motivo, thread.id))
967
+ : motivo === 'cost.violation'
968
+ ? 'refaca o login do perfil pela assinatura (claude auth login --claudeai ou codex login com ChatGPT) e rode ork accounts check; perfil de provider pago nunca despacha'
969
+ : 'ork accounts list mostra o estado de cada perfil; ork retry run segue pela ordem de fallback ou pela fila',
970
+ fase, slug, runtime, origem: 'phase.run', ...promptNoLedger, ...(perfilPedido ? { perfilPedido } : {}) });
953
971
  }
954
972
  return { thread, slug, promptPath, promptSha256: sha, comando: [], sessionId: null,
955
973
  verificada: false, pausaAoFim: (0, thread_1.pausaNaThread)(thread, fase), dryRun: opcoes.dryRun === true,
@@ -986,8 +1004,10 @@ tomadaPrevia) {
986
1004
  const claimsSchema = fase === 'GO' && runtime === 'codex'
987
1005
  ? schemaDeClaimsDoPacote()
988
1006
  : undefined;
989
- // I-33 (N1): lido antes de a sessao existir; depois dela, um commit rapido ja estaria no HEAD.
990
- const headNoDespacho = fase === 'GO' && runtime === 'codex' && !opcoes.dryRun ? (0, session_watcher_claude_1.headDaWorktree)(cwd) : undefined;
1007
+ // I-33 (N1): lido antes de a sessao existir; depois dela, um commit rapido ja estaria no HEAD. RM-067: o grok tambem.
1008
+ const headNoDespacho = fase === 'GO' && (runtime === 'codex' || runtime === 'grok') && !opcoes.dryRun ? (0, session_watcher_claude_1.headDaWorktree)(cwd) : undefined;
1009
+ // RM-067 (D8): a base do artefato do grok tambem sai antes do despacho, que espera a pasta da sessao.
1010
+ const artefatoNoDespacho = runtime === 'grok' && !opcoes.dryRun ? (0, session_watcher_grok_1.baseDoArtefato)(raiz, thread.id, fase) : undefined;
991
1011
  const pedidoAoRuntime = {
992
1012
  prompt,
993
1013
  nome: slug,
@@ -1028,7 +1048,9 @@ tomadaPrevia) {
1028
1048
  effort,
1029
1049
  origem: 'phase.run',
1030
1050
  ...(perfil ? { perfil } : {}),
1051
+ ...(perfilPedido ? { perfilPedido } : {}),
1031
1052
  ...(headNoDespacho !== undefined ? { headNoDespacho } : {}),
1053
+ ...(artefatoNoDespacho !== undefined ? { artefatoNoDespacho } : {}),
1032
1054
  };
1033
1055
  let resultado;
1034
1056
  try {
@@ -1042,6 +1064,7 @@ tomadaPrevia) {
1042
1064
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.despachoFalhou, { ...dadosDoDespacho(ctx, []), erro });
1043
1065
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: 'runtime.unavailable', modo: thread.modo,
1044
1066
  detalhe: erro, correcao: correcaoDoRetry, fase, slug, runtime, origem: 'phase.run', ...promptNoLedger,
1067
+ ...(perfilPedido ? { perfilPedido } : {}),
1045
1068
  evidencia: 'excecao real do runtime adapter no despacho, nao relato do agente' });
1046
1069
  }
1047
1070
  throw e;
@@ -1091,6 +1114,7 @@ tomadaPrevia) {
1091
1114
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: falha.motivo, modo: thread.modo, detalhe: erro,
1092
1115
  correcao: 'ork retry run rotaciona para o proximo perfil, para o runtime de fallback ou para a fila', fase, slug,
1093
1116
  runtime, origem: 'phase.run', falhaDeConta: falha, ...(perfil ? { perfil } : {}),
1117
+ ...(perfilPedido ? { perfilPedido } : {}),
1094
1118
  evidencia: 'saida real do runtime adapter no despacho, nao relato do agente' });
1095
1119
  return { thread, slug, promptPath, promptSha256: sha, comando: resultado.comando, controlador: resultado.controlador,
1096
1120
  sessionId: null, verificada: false, pausaAoFim, dryRun: false, runtime, model, effort, bloqueado: false,
@@ -1122,6 +1146,9 @@ tomadaPrevia) {
1122
1146
  detalhe: erro,
1123
1147
  // RM-058 N4 (D17 da ork-rm058n4): o pedido do despacho do arco é do vigia do arco, e o `ork retry resume` não o retoma.
1124
1148
  ...(opcoes.correlacao ? { correlacao: opcoes.correlacao } : {}),
1149
+ // RM-067 (GO-FIX 1, A1): o pedido do grok volta pelo grok, com o modelo dele; o dos outros runtimes segue como antes.
1150
+ ...(runtime === 'grok' ? { runtime } : {}),
1151
+ ...(perfilPedido ? { runtime, perfil: perfilPedido.id, perfilPedido } : {}),
1125
1152
  });
1126
1153
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.rateLimitEnfileirado, {
1127
1154
  fase,
@@ -1167,6 +1194,7 @@ tomadaPrevia) {
1167
1194
  // a registrava: o `ork retry plan` nao a via e a fase ficava parada sem ninguem saber.
1168
1195
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: 'runtime.unavailable', modo: thread.modo,
1169
1196
  detalhe: erro, correcao: correcaoDoRetry, fase, slug, runtime, origem: 'phase.run', ...promptNoLedger, ...daSessao,
1197
+ ...(perfilPedido ? { perfilPedido } : {}),
1170
1198
  evidencia: 'saida real do runtime adapter no despacho, nao relato do agente' });
1171
1199
  return {
1172
1200
  thread,
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.POSTURAS_QUE_AFROUXAM = exports.ARQUIVO_POSTURA_LOCAL = exports.CONTRATO_POSTURA_LOCAL = void 0;
36
+ exports.RUNTIMES_COM_POSTURA = exports.POSTURAS_QUE_AFROUXAM = exports.ARQUIVO_POSTURA_LOCAL = exports.CONTRATO_POSTURA_LOCAL = void 0;
37
37
  exports.pastaPrivadaDaPostura = pastaPrivadaDaPostura;
38
38
  exports.caminhoDaPosturaLocal = caminhoDaPosturaLocal;
39
39
  exports.posturaAfrouxada = posturaAfrouxada;
@@ -154,13 +154,17 @@ function lerPosturaLocal(raiz) {
154
154
  return { postura: null, motivo: 'a confirmação local é de outro checkout' };
155
155
  return { postura: o, motivo: null };
156
156
  }
157
+ /**
158
+ * Os runtimes que recebem a postura de sandbox do manifesto: o Codex e, desde a F4 da RM-067, o `grok`, em que a postura
159
+ * mais frouxa vira o perfil `off` (sem sandbox). O `claude-bg` não recebe a postura.
160
+ */
161
+ exports.RUNTIMES_COM_POSTURA = ['codex', 'grok'];
157
162
  /**
158
163
  * A recusa do despacho: `null` quando a postura do manifesto vale nesta máquina (não afrouxa, ou
159
164
  * foi confirmada localmente com o mesmo valor); senão o erro tipado com o comando que confirma.
160
- * Só o Codex recebe a postura de sandbox do manifesto.
161
165
  */
162
166
  function recusaDePostura(raiz, manifesto, runtime) {
163
- if (runtime !== 'codex')
167
+ if (!exports.RUNTIMES_COM_POSTURA.includes(runtime))
164
168
  return null;
165
169
  const postura = posturaAfrouxada(manifesto);
166
170
  if (!postura)
package/dist/preflight.js CHANGED
@@ -46,6 +46,7 @@ const manifest_1 = require("./manifest");
46
46
  const estado_thread_1 = require("./estado-thread");
47
47
  const claude_bg_1 = require("./adapters/claude-bg");
48
48
  const codex_1 = require("./adapters/codex");
49
+ const grok_1 = require("./adapters/grok");
49
50
  const runtime_profiles_1 = require("./runtime-profiles");
50
51
  const modos_1 = require("./modos");
51
52
  const setup_1 = require("./setup");
@@ -57,7 +58,7 @@ const runtime_ambiente_1 = require("./runtime-ambiente");
57
58
  const slug_1 = require("./slug");
58
59
  const util_1 = require("./util");
59
60
  const horario_1 = require("./horario");
60
- const authPadrao = (p) => p.runtime === 'claude-bg' ? (0, claude_bg_1.conferirAuth)(p) : (0, codex_1.conferirAuth)(p);
61
+ const authPadrao = (p) => p.runtime === 'claude-bg' ? (0, claude_bg_1.conferirAuth)(p) : p.runtime === 'grok' ? (0, grok_1.conferirAuth)(p) : (0, codex_1.conferirAuth)(p);
61
62
  const sensoresPadrao = {
62
63
  runtime: nome => !!(0, runtimes_1.resolverRuntime)(nome).disponivel(),
63
64
  sandboxCodex: () => (0, codex_2.sondarSandbox)().ok,
package/dist/ratelimit.js CHANGED
@@ -142,6 +142,7 @@ function enfileirar(carregado, novo, agoraMs = Date.now()) {
142
142
  detalhe: novo.detalhe,
143
143
  ...(novo.runtime !== undefined ? { runtime: novo.runtime } : {}),
144
144
  ...(novo.perfil !== undefined ? { perfil: novo.perfil } : {}),
145
+ ...(novo.perfilPedido ? { perfilPedido: novo.perfilPedido } : {}),
145
146
  ...(novo.motivo !== undefined ? { motivo: novo.motivo } : {}),
146
147
  ...(novo.correlacao ? { correlacao: novo.correlacao } : {}),
147
148
  };