@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
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ORIGENS_DO_PROJETO = exports.FORA_DA_CONSULTA = exports.OFERTA_DA_REDE = exports.ErroDeProjeto = exports.PADRAO_DO_NOME_DE_PROJETO = exports.SAIDA_DE_PROJETO = exports.ENV_PROJETO_EXPLICITO = exports.ENV_PROJETO = exports.CONTRATO_CONSULTA = exports.CONTRATO_PROJETOS = void 0;
36
+ exports.ORIGENS_DO_PROJETO = exports.FORA_DA_CONSULTA = exports.OFERTA_DA_REDE = exports.ErroDeProjeto = exports.PADRAO_DO_NOME_DE_PROJETO = exports.AMBIENTE_SEM_PROJETO_HERDADO = exports.SAIDA_DE_PROJETO = exports.ENV_PROJETO_EXPLICITO = exports.ENV_PROJETO = exports.CONTRATO_CONSULTA = exports.CONTRATO_PROJETOS = void 0;
37
37
  exports.caminhoDoRegistro = caminhoDoRegistro;
38
38
  exports.lerRegistroDeProjetos = lerRegistroDeProjetos;
39
39
  exports.listarProjetos = listarProjetos;
@@ -51,7 +51,12 @@ exports.raizParaExibir = raizParaExibir;
51
51
  exports.outrosProjetosConhecidos = outrosProjetosConhecidos;
52
52
  exports.semRemoto = semRemoto;
53
53
  exports.consultaDoProjeto = consultaDoProjeto;
54
+ exports.linhaDoProjeto = linhaDoProjeto;
54
55
  exports.linhasDaConsulta = linhasDaConsulta;
56
+ exports.iniciarDeclaracaoDoProjeto = iniciarDeclaracaoDoProjeto;
57
+ exports.pedirDeclaracaoDoProjeto = pedirDeclaracaoDoProjeto;
58
+ exports.remotoParaExibir = remotoParaExibir;
59
+ exports.declaracaoQueFaltou = declaracaoQueFaltou;
55
60
  /**
56
61
  * RM-052: o projeto-alvo explicito.
57
62
  *
@@ -75,6 +80,7 @@ exports.linhasDaConsulta = linhasDaConsulta;
75
80
  const fs = __importStar(require("node:fs"));
76
81
  const os = __importStar(require("node:os"));
77
82
  const path = __importStar(require("node:path"));
83
+ const branch_de_estado_1 = require("./branch-de-estado");
78
84
  const estado_thread_1 = require("./estado-thread");
79
85
  const manifest_1 = require("./manifest");
80
86
  const maquina_1 = require("./maquina");
@@ -89,6 +95,18 @@ exports.ENV_PROJETO = 'ORK_PROJETO';
89
95
  exports.ENV_PROJETO_EXPLICITO = 'ORK_PROJETO_EXPLICITO';
90
96
  /** Codigo de saida da recusa de projeto-alvo no CLI (D3). */
91
97
  exports.SAIDA_DE_PROJETO = 4;
98
+ /**
99
+ * RM-052 (fatia 2, D2): o ambiente de quem o nucleo inicia ja dentro do projeto resolvido, a sessao
100
+ * despachada na worktree da thread e o filho `fabrica publicar`. O modo host e o `ORK_PROJETO` sao do
101
+ * gateway que pediu: herdados, recusavam todo `ork` da sessao com `projeto.escolha`, ou liam outro
102
+ * projeto. Valores neutros, e nao a ausencia das variaveis: o `claude --bg` entrega a sessao a um daemon
103
+ * que guarda o ambiente de quem o iniciou, e so o `env` do `--settings` vence o herdado. Com eles, o
104
+ * projeto da sessao e o do proprio cwd.
105
+ */
106
+ exports.AMBIENTE_SEM_PROJETO_HERDADO = Object.freeze({
107
+ [exports.ENV_PROJETO]: '',
108
+ [exports.ENV_PROJETO_EXPLICITO]: '0',
109
+ });
92
110
  const ARQUIVO = 'projetos.json';
93
111
  const TRAVA = 'projetos.json.lock';
94
112
  /** Nome ou abbrev de projeto: o mesmo alfabeto dos identificadores de thread, sem barra. */
@@ -198,7 +216,10 @@ function remotoSemCredencial(url) {
198
216
  }
199
217
  /** URL do remoto, sem credencial. `null` quando o projeto nao tem aquele remoto. */
200
218
  function remotoDoProjeto(raiz, remoto = 'origin') {
201
- const r = (0, util_1.exec)('git', ['remote', 'get-url', remoto], raiz, 5000);
219
+ // RM-047: o nome vem do manifesto; fora do formato de remoto, nada vai ao git.
220
+ if (!(0, branch_de_estado_1.remotoValido)(remoto))
221
+ return null;
222
+ const r = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], raiz, 5000);
202
223
  const url = r.ok ? r.stdout.trim() : '';
203
224
  return url ? remotoSemCredencial(url) : null;
204
225
  }
@@ -528,6 +549,10 @@ exports.ORIGENS_DO_PROJETO = Object.freeze({
528
549
  * e nao revela os demais).
529
550
  */
530
551
  function consultaDoProjeto(carregado, opcoes) {
552
+ // Fatia 2 (D3): o comando monta o proprio cabecalho DO ALVO; a linha generica do fim nao se repete.
553
+ // A consulta de outro projeto (sugestao A3 do CHECK) nao apaga a declaracao pedida.
554
+ if (declaracao && mesmaRaiz(carregado.raiz, declaracao.alvo.raiz))
555
+ declaracao.feita = true;
531
556
  const alvo = projetoAlvoAtual();
532
557
  const origem = opcoes.origem ?? (alvo && path.resolve(alvo.raiz) === path.resolve(carregado.raiz) ? alvo.origem : 'cwd');
533
558
  const outros = opcoes.outrosProjetos === false ? 0 : outrosProjetosConhecidos(carregado.raiz);
@@ -536,16 +561,118 @@ function consultaDoProjeto(carregado, opcoes) {
536
561
  return {
537
562
  contrato: exports.CONTRATO_CONSULTA,
538
563
  projeto: { nome: carregado.manifesto.project.name, abbrev: carregado.manifesto.project.abbrev,
539
- raiz: raizParaExibir(carregado.raiz), remoto, origem },
564
+ raiz: raizParaExibir(carregado.raiz), remoto: remotoParaExibir(remoto), origem },
540
565
  lido: [...opcoes.lido],
541
566
  naoLido: [...opcoes.naoLido, ...(outros > 0 ? [`outros projetos desta máquina: ${outros} (ork projetos)`] : [])],
542
567
  };
543
568
  }
569
+ /** A linha do projeto consultado: a primeira do cabecalho e a que a declaracao da fatia 2 escreve. */
570
+ function linhaDoProjeto(p) {
571
+ return `Projeto consultado: ${p.nome} (${p.abbrev || '-'}) · ${p.raiz} · ${p.remoto ?? 'sem remoto'} · ${exports.ORIGENS_DO_PROJETO[p.origem]}`;
572
+ }
544
573
  /** As duas linhas do cabecalho em texto: o projeto consultado e o que nao foi lido. */
545
574
  function linhasDaConsulta(c) {
546
- const p = c.projeto;
547
575
  return [
548
- `Projeto consultado: ${p.nome} (${p.abbrev || '-'}) · ${p.raiz} · ${p.remoto ?? 'sem remoto'} · ${exports.ORIGENS_DO_PROJETO[p.origem]}`,
576
+ linhaDoProjeto(c.projeto),
549
577
  `Não lido: ${c.naoLido.length ? c.naoLido.join(' · ') : 'nada fora do projeto consultado'}`,
550
578
  ];
551
579
  }
580
+ // ---------------------------------------------------------------------------
581
+ // A declaracao do projeto consultado (fatia 2, D3).
582
+ // ---------------------------------------------------------------------------
583
+ /**
584
+ * Na fatia 1, so maestro, board, fabrica e roadmap status diziam qual projeto leram; dez das catorze
585
+ * tools de projeto do OpenClaw respondiam sem nomea-lo, e com um so projeto conhecido a resposta era a
586
+ * dele, sem aviso. Agora todo comando que le um projeto que o leitor nao tem como adivinhar termina com
587
+ * a linha `Projeto consultado: ...` no stderr: o OpenClaw junta stdout e stderr no texto da tool, e o
588
+ * JSON do stdout continua inteiro para quem o consome.
589
+ */
590
+ let declaracao = null;
591
+ /** Zera o pedido de declaracao do processo (os testes chamam `main` em serie no mesmo processo). */
592
+ function iniciarDeclaracaoDoProjeto() {
593
+ declaracao = null;
594
+ }
595
+ /**
596
+ * Pede a linha para o comando que vai ler `alvo`, so quando o leitor nao sabe qual projeto foi lido:
597
+ * no host (`ORK_PROJETO_EXPLICITO=1`), cuja resposta vai a um canal de conversa, ou quando o projeto nao
598
+ * e o do diretorio atual. No terminal, dentro do proprio projeto, nada muda (BR-030-02).
599
+ */
600
+ function pedirDeclaracaoDoProjeto(alvo, entrada = {}) {
601
+ declaracao = null;
602
+ if (!alvo)
603
+ return;
604
+ const ambiente = entrada.ambiente ?? process.env;
605
+ const host = (ambiente[exports.ENV_PROJETO_EXPLICITO] ?? '').trim() === '1';
606
+ if (!host && raizDoDiretorio(entrada.cwd ?? process.cwd()) === alvo.raiz)
607
+ return;
608
+ declaracao = { alvo, feita: false };
609
+ }
610
+ /** As duas raizes sao a mesma copia (caminho real; o resolvido quando o disco nao responde). */
611
+ function mesmaRaiz(a, b) {
612
+ const real = (p) => { try {
613
+ return fs.realpathSync(p);
614
+ }
615
+ catch {
616
+ return path.resolve(p);
617
+ } };
618
+ return real(a) === real(b);
619
+ }
620
+ /**
621
+ * Fatia 2 (sugestao S1 do CHECK): o remoto que vai a um canal de conversa. Ele ja chega sem usuario e
622
+ * senha (`remotoSemCredencial`); aqui sai tambem o que vem depois de `?` ou `#` na URL (token em query,
623
+ * como `?private_token=`), o caminho local mostra `~` no lugar da pasta da conta (D8) e o remoto que
624
+ * ainda parecer segredo sai omitido. So a exibicao muda: o registro guarda o remoto como sempre.
625
+ */
626
+ function remotoParaExibir(remoto) {
627
+ if (remoto === null)
628
+ return null;
629
+ let exibido = remoto;
630
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(exibido)) {
631
+ try {
632
+ const u = new URL(exibido);
633
+ u.search = '';
634
+ u.hash = '';
635
+ exibido = u.toString();
636
+ }
637
+ catch {
638
+ exibido = exibido.replace(/[?#].*$/, '');
639
+ }
640
+ }
641
+ else if (path.isAbsolute(exibido))
642
+ exibido = raizParaExibir(exibido);
643
+ return (0, policies_1.procurarSegredos)(exibido).length ? 'remoto omitido (parece carregar segredo)' : exibido;
644
+ }
645
+ /** A raiz do manifesto que o diretorio enxerga subindo, com caminho real; `null` fora de projeto. */
646
+ function raizDoDiretorio(cwd) {
647
+ const achada = (0, util_1.subirAte)(path.resolve(cwd), manifest_1.NOME_MANIFESTO) ?? (0, util_1.subirAte)(path.resolve(cwd), manifest_1.NOME_MANIFESTO_LEGADO);
648
+ if (!achada)
649
+ return null;
650
+ try {
651
+ return fs.realpathSync(achada);
652
+ }
653
+ catch {
654
+ return null;
655
+ }
656
+ }
657
+ /**
658
+ * A linha que faltou, e consome o pedido: `null` sem pedido, ou quando o comando montou o proprio
659
+ * cabecalho (`consultaDoProjeto`).
660
+ */
661
+ function declaracaoQueFaltou() {
662
+ const d = declaracao;
663
+ declaracao = null;
664
+ if (!d || d.feita)
665
+ return null;
666
+ let carregado;
667
+ try {
668
+ carregado = (0, manifest_1.carregarManifesto)(d.alvo.raiz);
669
+ }
670
+ catch {
671
+ return null;
672
+ }
673
+ if (!carregado)
674
+ return null;
675
+ const m = carregado.manifesto;
676
+ return linhaDoProjeto({ nome: m.project.name, abbrev: m.project.abbrev, raiz: raizParaExibir(carregado.raiz),
677
+ remoto: remotoParaExibir(remotoDoProjeto(carregado.raiz, m.fabrica?.remoto ?? 'origin')), origem: d.alvo.origem });
678
+ }
package/dist/prompts.js CHANGED
@@ -49,11 +49,13 @@ var __importStar = (this && this.__importStar) || (function () {
49
49
  };
50
50
  })();
51
51
  Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
52
+ exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
53
+ exports.pedidoComDicaDoGrafo = pedidoComDicaDoGrafo;
53
54
  exports.dirDeTemplates = dirDeTemplates;
54
55
  exports.variaveisUsadas = variaveisUsadas;
55
56
  exports.renderizar = renderizar;
56
57
  exports.parseTemplate = parseTemplate;
58
+ exports.procurarHitlEmTextoLivre = procurarHitlEmTextoLivre;
57
59
  exports.lintTemplate = lintTemplate;
58
60
  exports.carregarTemplatesDe = carregarTemplatesDe;
59
61
  exports.carregarTemplates = carregarTemplates;
@@ -69,6 +71,19 @@ const policies_1 = require("./policies");
69
71
  const types_1 = require("./types");
70
72
  /** Limite duro de um template, o mesmo do manifesto: prosa longa nao vira prompt. */
71
73
  exports.LIMITE_TEMPLATE_BYTES = 16384;
74
+ /**
75
+ * KG5 fatia 2: dica opt-in no pedido; desligada preserva o texto byte a byte. Fatia 5: a dica diz o que
76
+ * a marca `arvore: modificada` quer dizer na aresta.
77
+ */
78
+ function pedidoComDicaDoGrafo(pedido, thread, ligado) {
79
+ if (!ligado)
80
+ return pedido;
81
+ return pedido.trimEnd() + '\n\n## Contexto do grafo (opcional)\n'
82
+ + `Consulte ork_grafo_contexto {threadId: "${thread}"} ou ork grafo contexto ${thread} --json para o pacote da thread com evidencias e teto em bytes.\n`
83
+ + 'As tools ork_grafo_vizinhos, ork_grafo_chamadores, ork_grafo_importadores e ork_grafo_caminho permitem aprofundar. '
84
+ + 'Sem indice do HEAD, rode ork grafo indexar. O grafo e parcial e descreve o HEAD; '
85
+ + 'aresta com arvore: modificada vem de fonte que mudou depois dele: confira o arquivo antes de usar.\n';
86
+ }
72
87
  /** Onde um projeto guarda os templates que sobrescrevem os embutidos. */
73
88
  function dirDeTemplates(raiz) {
74
89
  return path.join(raiz, 'prompts');
@@ -170,6 +185,27 @@ exports.CONTRATO_DE_FASE = {
170
185
  variavelObrigatoria: 'pedido',
171
186
  validaFases: true,
172
187
  };
188
+ /**
189
+ * RM-057: os jeitos de um template pedir ao dono texto livre ou texto colado. Lista fechada, como o
190
+ * vocabulario do pulse: acrescentar um padrao e decisao de contrato, com teste. Casa sobre a linha
191
+ * em minusculas e sem acento.
192
+ */
193
+ exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = Object.freeze([
194
+ { oQue: 'que o dono cole texto', padrao: /\b(cole|colar|colem)\b[^.\n]{0,60}\b(texto|aqui|mensagem|pedido|resposta|saida|conteudo)\b/ },
195
+ { oQue: 'que o dono cole texto', padrao: /\bpaste\b/ },
196
+ { oQue: 'confirmacao em texto livre', padrao: /\b(responda|digite|escreva|confirme|responder|digitar|escrever)\b[^.\n]{0,40}(\bconfirmo\b|texto livre|\bem texto\b)/ },
197
+ { oQue: 'confirmacao em texto livre', padrao: /\b(peca|peco|pedir|solicite|solicitar)\b[^.\n]{0,30}\bconfirmacao\b[^.\n]{0,20}\b(por escrito|em texto|textual)\b/ },
198
+ ]);
199
+ function procurarHitlEmTextoLivre(corpo) {
200
+ const achados = [];
201
+ corpo.split('\n').forEach((bruta, i) => {
202
+ const linha = bruta.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
203
+ const casou = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE.find(p => p.padrao.test(linha));
204
+ if (casou)
205
+ achados.push({ linha: i + 1, oQue: casou.oQue });
206
+ });
207
+ return achados;
208
+ }
173
209
  /**
174
210
  * Lint de um template. Devolve os problemas; lista vazia quer dizer aprovado.
175
211
  *
@@ -231,6 +267,9 @@ function lintTemplate(t, contrato = exports.CONTRATO_DE_FASE) {
231
267
  if (bytes > exports.LIMITE_TEMPLATE_BYTES) {
232
268
  erro('tamanho', `${bytes} bytes acima do limite de ${exports.LIMITE_TEMPLATE_BYTES}`);
233
269
  }
270
+ for (const achado of procurarHitlEmTextoLivre(t.corpo)) {
271
+ erro('hitl-texto-livre', `linha ${achado.linha} pede ${achado.oQue}; HITL de conducao e selecao de 3 a 5 alternativas com uma Recomendacao (RM-057)`);
272
+ }
234
273
  if (t.bruto.includes('—')) {
235
274
  aviso('idioma', 'o template usa travessao longo (U+2014); o padrao do projeto e hifen ou virgula');
236
275
  }
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ENTRADAS = exports.HOSTS_DA_PROVA = void 0;
37
37
  exports.transcriptDoClaude = transcriptDoClaude;
38
38
  exports.transcriptDoOpenclaw = transcriptDoOpenclaw;
39
+ exports.transcriptDoCodex = transcriptDoCodex;
39
40
  exports.extrairSnapshot = extrairSnapshot;
40
41
  exports.conferirProva = conferirProva;
41
42
  exports.redigir = redigir;
@@ -44,7 +45,7 @@ exports.redigirObjeto = redigirObjeto;
44
45
  * RM-032: conferência da prova de ativação por host, sem host.
45
46
  *
46
47
  * O roteiro `core/scripts/prova-ativacao.cjs` abre uma sessão nova e não interativa no host
47
- * (Claude Code ou OpenClaw), diz `orkastery maestro` e entrega aqui o transcript. Esta
48
+ * (Claude Code, OpenClaw ou Codex), diz `orkastery maestro` e entrega aqui o transcript. Esta
48
49
  * conferência olha só o que é determinístico: qual ferramenta o modelo chamou, o resultado que
49
50
  * ela devolveu (contra o contrato da entrada) e o projeto lido. Da resposta final em texto
50
51
  * livre, exige apenas que cite o projeto e não repita o incidente de 29/09 ("roadmap vazio").
@@ -52,20 +53,31 @@ exports.redigirObjeto = redigirObjeto;
52
53
  const fs = __importStar(require("node:fs"));
53
54
  const path = __importStar(require("node:path"));
54
55
  const maestro_contract_1 = require("./maestro-contract");
55
- exports.HOSTS_DA_PROVA = ['claude-code', 'openclaw'];
56
+ exports.HOSTS_DA_PROVA = ['claude-code', 'openclaw', 'codex'];
56
57
  /**
57
58
  * As entradas da frase em cada host. No Claude, a tool MCP do servidor `orkastery` fixado no
58
59
  * projeto (MAESTRO_HOST_SURFACES em hosts.ts). No OpenClaw 0.5.0 (RM-054, fatia 2), a frase sem
59
60
  * projeto vai a `ork_network_roadmap`, a única tool da extensão no perfil `coding`; com projeto
60
- * nomeado, a `ork_maestro`. `ork maestro` pelo shell do host é desvio: o CLI resolve o projeto
61
- * pelo diretório atual, a classe de erro do incidente.
61
+ * nomeado, a `ork_maestro`. No Codex (B11), a tool `ork_maestro` do servidor `orkastery` que o
62
+ * `ork mcp install --host codex` grava no projeto; o nome segue o padrão `mcp__<servidor>__<tool>`.
63
+ * `ork maestro` pelo shell do host é desvio: o CLI resolve o projeto pelo diretório atual, a classe
64
+ * de erro do incidente.
62
65
  */
63
66
  exports.ENTRADAS = {
64
67
  'claude-code': [{ ferramenta: 'mcp__orkastery__ork_maestro', contrato: 'maestro' }],
65
68
  openclaw: [{ ferramenta: 'ork_network_roadmap', contrato: 'rede' }, { ferramenta: 'ork_maestro', contrato: 'maestro' }],
69
+ codex: [{ ferramenta: 'mcp__orkastery__ork_maestro', contrato: 'maestro' }],
66
70
  };
67
- const SHELL_DO_HOST = { 'claude-code': 'Bash', openclaw: 'exec' };
68
- const ORK_MAESTRO_NO_SHELL = /(^|[\s;&|(/])ork(\s+(--projeto|--project|-p)(\s+|=)\S+)?\s+maestro\b/;
71
+ const SHELL_DO_HOST = { 'claude-code': 'Bash', openclaw: 'exec', codex: 'command_execution' };
72
+ // B11: o shell do Codex chega embrulhado (`bash -lc 'ork maestro'`), então aspas também abrem o comando.
73
+ // Suspeitas da revisão de 03/10: o mesmo CLI roda também pelo caminho do binário (`$(which ork)`), pelo
74
+ // node (`core/dist/index.js`), pelo npx (`@orkastery/cli`) e com o projeto entre aspas. É desvio a
75
+ // invocação do ork cujo subcomando, depois só de opções (com valor, até entre aspas), é `maestro`;
76
+ // `maestro` dentro do argumento de outro subcomando não é.
77
+ const INVOCACAO_DO_ORK = String.raw `(?:(?:^|[^\w.@-])ork|@orkastery\/cli(?:@[\w.-]+)?|\bdist\/index\.js)(?![\w.-])[)\x60]?`;
78
+ const VALOR = String.raw `(?:"[^"]*"|'[^']*'|[^\s"'-][^\s"']*)`;
79
+ const OPCOES = String.raw `(?:\s+-[\w-]*(?:=(?:"[^"]*"|'[^']*'|[^\s"']+))?(?:\s+${VALOR})?)*`;
80
+ const ORK_MAESTRO_NO_SHELL = new RegExp(String.raw `${INVOCACAO_DO_ORK}${OPCOES}\s+maestro(?![\w.-])`);
69
81
  function linhasJson(texto) {
70
82
  const eventos = [];
71
83
  for (const linha of texto.split('\n')) {
@@ -172,6 +184,63 @@ function transcriptDoOpenclaw(eventsJsonl, agenteJson) {
172
184
  const textos = (agente.payloads ?? []).map(p => p?.text).filter((t) => typeof t === 'string');
173
185
  return { ferramentasExpostas, chamadas, respostaFinal: textos.length ? textos.join('\n') : null };
174
186
  }
187
+ /**
188
+ * Eventos do `codex exec --json` (B11): `item.started`/`item.completed` com `mcp_tool_call` (servidor,
189
+ * tool, argumentos, resultado, erro), `command_execution` (o shell do host) e `agent_message` (a
190
+ * resposta). O `codex exec` não lista as ferramentas expostas ao modelo: quem chama passa as do
191
+ * `tools/list` do mesmo servidor MCP que a sessão recebeu, já com o nome `mcp__<servidor>__<tool>`.
192
+ */
193
+ function transcriptDoCodex(eventosJsonl, ferramentasExpostas) {
194
+ const porItem = new Map();
195
+ const chamadas = [];
196
+ const mensagens = [];
197
+ for (const e of linhasJson(eventosJsonl)) {
198
+ if (e.type !== 'item.started' && e.type !== 'item.completed')
199
+ continue;
200
+ const item = (e.item ?? {});
201
+ const id = typeof item.id === 'string' ? item.id : null;
202
+ if (item.type === 'agent_message') {
203
+ if (e.type === 'item.completed' && typeof item.text === 'string')
204
+ mensagens.push(item.text);
205
+ continue;
206
+ }
207
+ let ferramenta, argumentos, resultado = null, erro = false;
208
+ if (item.type === 'mcp_tool_call' && typeof item.server === 'string' && typeof item.tool === 'string') {
209
+ ferramenta = `mcp__${item.server}__${item.tool}`;
210
+ argumentos = item.arguments ?? null;
211
+ const r = item.result;
212
+ resultado = typeof r === 'string' ? r : textoDoConteudo(r?.content);
213
+ const falha = item.error;
214
+ erro = !!falha || item.status === 'failed';
215
+ if (erro && resultado === null)
216
+ resultado = typeof falha === 'string' ? falha : typeof falha?.message === 'string' ? falha.message : 'falhou';
217
+ }
218
+ else if (item.type === 'command_execution' && typeof item.command === 'string') {
219
+ ferramenta = 'command_execution';
220
+ argumentos = { command: item.command };
221
+ resultado = typeof item.aggregated_output === 'string' ? item.aggregated_output : null;
222
+ erro = item.status === 'failed' || (typeof item.exit_code === 'number' && item.exit_code !== 0);
223
+ }
224
+ else
225
+ continue;
226
+ const tipo = classificar('codex', ferramenta, argumentos);
227
+ if (!tipo)
228
+ continue;
229
+ const anterior = id ? porItem.get(id) : undefined;
230
+ if (anterior) {
231
+ // `item.completed` do mesmo item fecha a chamada aberta no `item.started`.
232
+ if (e.type === 'item.completed')
233
+ Object.assign(anterior, { argumentos, resultado, erro });
234
+ continue;
235
+ }
236
+ const chamada = { ferramenta, ...tipo, argumentos, resultado: e.type === 'item.completed' ? resultado : null,
237
+ erro: e.type === 'item.completed' ? erro : false };
238
+ if (id)
239
+ porItem.set(id, chamada);
240
+ chamadas.push(chamada);
241
+ }
242
+ return { ferramentasExpostas, chamadas, respostaFinal: mensagens.length ? mensagens.at(-1) : null };
243
+ }
175
244
  /** O primeiro objeto `ork.maestro-snapshot/v1` do texto (o host pode juntar stderr ao stdout). */
176
245
  function extrairSnapshot(texto) {
177
246
  const inicio = texto.indexOf('{"schema":"ork.maestro-snapshot/v1"');
@@ -38,6 +38,7 @@ exports.assinaturaPulse = assinaturaPulse;
38
38
  exports.assinaturaDoResumo = assinaturaDoResumo;
39
39
  exports.mensagemPulse = mensagemPulse;
40
40
  exports.varrerPulse = varrerPulse;
41
+ exports.varrerEDepoisPublicarNaRede = varrerEDepoisPublicarNaRede;
41
42
  exports.enviarPayloadHost = enviarPayloadHost;
42
43
  const manifest_1 = require("./manifest");
43
44
  const write_activation_1 = require("./write-activation");
@@ -49,6 +50,7 @@ const node_crypto_1 = require("node:crypto");
49
50
  const node_child_process_1 = require("node:child_process");
50
51
  const pulse_1 = require("./pulse");
51
52
  const estado_thread_1 = require("./estado-thread");
53
+ const procedencia_1 = require("./procedencia");
52
54
  const hitl_1 = require("./hitl");
53
55
  const horario_1 = require("./horario");
54
56
  const hitl_resumo_1 = require("./hitl-resumo");
@@ -59,6 +61,8 @@ const hitl_contract_1 = require("./hitl-contract");
59
61
  const monitor_lock_1 = require("./monitor-lock");
60
62
  const fabrica_estado_1 = require("./fabrica-estado");
61
63
  const maquina_1 = require("./maquina");
64
+ const rede_1 = require("./rede");
65
+ const rede_adesao_1 = require("./rede-adesao");
62
66
  const pulse_cadencia_1 = require("./pulse-cadencia");
63
67
  // O lock dos monitores mudou de modulo (I-41, GO-FIX 1); quem o importava daqui continua importando.
64
68
  var monitor_lock_2 = require("./monitor-lock");
@@ -209,6 +213,12 @@ function varrerPulse(opcoes) {
209
213
  const servidas = (0, pulse_resposta_1.threadsComPerguntaViva)(raiz, quando, dir);
210
214
  const jaServida = (i) => !!i.thread && servidas.has(i.thread);
211
215
  novas = itens.filter(i => vistas[i.id] !== assinaturaPulse(i) && !jaServida(i)).length;
216
+ // RM-055 (continuacao, D3): o impedimento que so o dono destrava vai no resumo com o comando de cada um,
217
+ // e o que ele ainda nao viu sai na hora, como pergunta nova: esperar a janela da cadencia deixava a
218
+ // fase parada sem ele saber. O ja avisado nao volta a tocar sozinho.
219
+ const impedimentos = itens.filter(i => i.impedimento && i.thread).map(i => ({ thread: i.thread, fase: i.fase,
220
+ comando: i.impedimento.comando, retry: i.impedimento.retry }));
221
+ const impedimentoNovo = itens.some(i => i.impedimento && vistas[i.id] !== assinaturaPulse(i) && !jaServida(i));
212
222
  for (const i of itens)
213
223
  if (jaServida(i))
214
224
  vistas[i.id] = assinaturaPulse(i);
@@ -217,6 +227,9 @@ function varrerPulse(opcoes) {
217
227
  if (opcoes.enviar)
218
228
  entregue = opcoes.enviar(mensagem);
219
229
  else {
230
+ // RM-047 (P2): o executavel do transporte so sai do arquivo local, nunca de um versionado no git.
231
+ if (!opcoes.transporte)
232
+ (0, procedencia_1.exigirHostLocal)(raiz, path.join(dir, 'pulse-host.json'));
220
233
  const config = opcoes.transporte ?? JSON.parse(fs.readFileSync(path.join(dir, 'pulse-host.json'), 'utf8'));
221
234
  if (typeof config.executavel !== 'string' || !config.executavel || !Array.isArray(config.argumentos) ||
222
235
  !config.argumentos.every(a => typeof a === 'string') || !config.argumentos.some(a => a.includes('{{mensagem}}'))) {
@@ -248,12 +261,15 @@ function varrerPulse(opcoes) {
248
261
  // cadencia do dono, e a novidade que esperou continua nao vista ate sair.
249
262
  const noPrazo = !opcoes.comCadencia || (0, pulse_cadencia_1.janelaAberta)(cadencia, (0, pulse_cadencia_1.lerUltimoResumo)(opcoes.raiz, dir), quando);
250
263
  const informacaoNova = novas > 0 || decisoesNovas.length > 0 || paradosNovos.length > 0;
251
- const adiada = !conjuntoNovo && !esperaNovaFora && informacaoNova && !noPrazo;
252
- if (conjuntoNovo || esperaNovaFora || (noPrazo && informacaoNova)) {
264
+ const adiada = !conjuntoNovo && !esperaNovaFora && !impedimentoNovo && informacaoNova && !noPrazo;
265
+ if (conjuntoNovo || esperaNovaFora || impedimentoNovo || (noPrazo && informacaoNova)) {
253
266
  const guardadas = anterior ? fila.candidatos.filter(c => anterior.candidatos.some(a => a.thread === c.thread)).length : 0;
254
267
  const resumo = (0, hitl_resumo_1.resumirHitl)(itens, { quando, janelaMin, prontas: fila.candidatos.length, acumuladas: guardadas,
255
268
  consertos: fila.consertos, atoDoItem: i => fila.atos.get(`${i.thread}|${i.fase}`),
256
- decisoes: decisoesNovas, acimaDoLimiar: pulse.acimaDoLimiar ?? [], outrasMaquinas: outras, paradosNoCondutor: parados });
269
+ decisoes: decisoesNovas, acimaDoLimiar: pulse.acimaDoLimiar ?? [], outrasMaquinas: outras, paradosNoCondutor: parados,
270
+ impedimentosDoDono: impedimentos,
271
+ // RM-057 (fatia 3): a linha so acompanha o resumo que ja sai; nao e novidade nem fura a cadencia.
272
+ ...(pulse.hitlDeConducao ? { hitlDeConducao: pulse.hitlDeConducao } : {}) });
257
273
  // Pedir licenca para mandar zero perguntas era o defeito: sem pergunta, nao ha codigo.
258
274
  // I-50: cadencia curta nao encurta o prazo do dono para responder ao resumo (minimo de 60 min).
259
275
  const consentimento = fila.candidatos.length ? (0, monitor_lock_1.comLockDaConversa)(dir, () => (0, pulse_consentimento_1.abrirConsentimento)(raiz, { quando,
@@ -287,6 +303,22 @@ function varrerPulse(opcoes) {
287
303
  trava.liberar();
288
304
  }
289
305
  }
306
+ /**
307
+ * RM-053: a entrega ao dono vem primeiro, e a rede depois, mesmo quando a varredura falha. M4 do
308
+ * CHECK 1: antes da entrega, uma forja lenta atrasava o HITL em minutos. S13 da revisao 2: sem o
309
+ * `finally`, uma excecao na varredura suprimia tambem a batida da rede.
310
+ */
311
+ function varrerEDepoisPublicarNaRede(varrer, publicar) {
312
+ try {
313
+ return varrer();
314
+ }
315
+ finally {
316
+ try {
317
+ publicar();
318
+ }
319
+ catch { /* a rede registra a propria falha no rede.log */ }
320
+ }
321
+ }
290
322
  if (require.main === module) {
291
323
  try {
292
324
  const raiz = process.argv[2] ?? process.cwd();
@@ -317,7 +349,18 @@ if (require.main === module) {
317
349
  }
318
350
  const outrasMaquinas = compartilhada
319
351
  ? () => (0, fabrica_estado_1.resumoDasOutrasMaquinas)((0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto, semRemoto: true }), (0, maquina_1.nomeDaMaquina)()) : undefined;
320
- const r = varrerPulse({ raiz, escopo, comCadencia: true, outrasMaquinas });
352
+ // RM-053 (D9): depois da entrega ao dono, a mesma batida publica o retrato desta maquina na rede da
353
+ // pessoa (so membro, uma tentativa a cada 14 min, retrato igual so de hora em hora).
354
+ const r = varrerEDepoisPublicarNaRede(() => varrerPulse({ raiz, escopo, comCadencia: true, outrasMaquinas }), () => {
355
+ try {
356
+ const rede = (0, rede_1.publicarRedeNaBatida)({ diretorio: carregado.raiz });
357
+ if (rede)
358
+ (0, rede_adesao_1.registrarNaRede)({ ...rede, origem: 'pulse' });
359
+ }
360
+ catch (e) {
361
+ (0, rede_adesao_1.registrarNaRede)({ acao: 'falhou', origem: 'pulse', erro: e.message });
362
+ }
363
+ });
321
364
  console.log(JSON.stringify(r));
322
365
  process.exitCode = r.code;
323
366
  }