@orkastery/cli 0.5.1 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/agents/ork-master.md +2 -0
  3. package/adapters/claude-code/commands/master.md +8 -0
  4. package/adapters/claude-code/commands/ork.md +9 -0
  5. package/adapters/claude-code/mods/autoridade.json +56 -0
  6. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  8. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  9. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  10. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  11. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  12. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  13. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  16. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  17. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  18. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  19. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  20. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  21. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  25. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  27. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  28. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  29. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  30. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  33. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  34. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  35. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  36. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  37. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  38. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  44. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  45. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  46. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  47. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  48. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  49. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  52. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  53. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  54. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  55. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  56. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  57. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  59. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  60. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  61. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  62. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  63. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  64. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  67. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  68. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  69. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  70. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  71. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  72. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  77. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  78. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  79. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  80. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  81. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  82. package/adapters/codex/skills/ork/SKILL.md +18 -3
  83. package/adapters/hermes/README.md +1 -0
  84. package/adapters/hermes/bin/ork-network-status.sh +10 -0
  85. package/adapters/hermes/hermes.plugin.json +1 -0
  86. package/adapters/hermes/hitl-ingress/__init__.py +2 -2
  87. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +7 -6
  88. package/adapters/openclaw/README.md +26 -5
  89. package/adapters/openclaw/dist/hitl-ingress.js +2 -2
  90. package/adapters/openclaw/dist/index.js +46 -11
  91. package/adapters/openclaw/openclaw.plugin.json +5 -1
  92. package/adapters/openclaw/package.json +2 -2
  93. package/adapters/openclaw/src/hitl-ingress.ts +2 -2
  94. package/adapters/openclaw/src/index.ts +49 -11
  95. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  96. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  97. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  98. package/assets/docs-en/produto/README.md +14 -0
  99. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  100. package/assets/docs-en/roadmap/README.md +14 -0
  101. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  102. package/assets/orkmind_bridge.py +117 -9
  103. package/dist/adapters/claude-bg.js +116 -18
  104. package/dist/adapters/codex.js +14 -4
  105. package/dist/agents-md.js +24 -14
  106. package/dist/auditrun.js +22 -3
  107. package/dist/board.js +20 -17
  108. package/dist/branch-de-estado.js +88 -10
  109. package/dist/busca-semantica.js +52 -12
  110. package/dist/canarios-rm057.js +149 -0
  111. package/dist/canarios.js +2 -0
  112. package/dist/catalogo.js +33 -0
  113. package/dist/ci.js +21 -8
  114. package/dist/claims-conferir.js +342 -0
  115. package/dist/claims.js +41 -1
  116. package/dist/company-brain-client.js +36 -1
  117. package/dist/company-brain-context.js +158 -22
  118. package/dist/company-brain-journal.js +2 -1
  119. package/dist/company-brain-migration.js +36 -1
  120. package/dist/conducao-sentinela.js +388 -0
  121. package/dist/conducao-texto.js +12 -18
  122. package/dist/conducao.js +122 -30
  123. package/dist/conhecimento.js +490 -0
  124. package/dist/docs.js +70 -17
  125. package/dist/doctor-pulse-cron.js +349 -0
  126. package/dist/doctor-rede.js +150 -0
  127. package/dist/doctor.js +195 -111
  128. package/dist/entrega-pr.js +42 -29
  129. package/dist/escopo-escrita.js +10 -1
  130. package/dist/esgotamentos.js +181 -0
  131. package/dist/estado-thread.js +23 -1
  132. package/dist/experiencia-instalacao.js +45 -25
  133. package/dist/experiencia.js +12 -2
  134. package/dist/fabrica-batida.js +310 -0
  135. package/dist/fabrica-estado.js +52 -14
  136. package/dist/fabrica-publicar.js +9 -1
  137. package/dist/fechamento.js +20 -66
  138. package/dist/fila-pesada.js +444 -0
  139. package/dist/fix.js +3 -2
  140. package/dist/forja.js +31 -7
  141. package/dist/gates.js +3 -24
  142. package/dist/handoff.js +10 -6
  143. package/dist/hitl-contract.js +59 -4
  144. package/dist/hitl-curto.js +11 -6
  145. package/dist/hitl-gates.js +5 -0
  146. package/dist/hitl-local-receipt.js +2 -0
  147. package/dist/hitl-lote.js +5 -2
  148. package/dist/hitl-resumo.js +38 -3
  149. package/dist/hitl-tempo-parado.js +201 -0
  150. package/dist/hitl-texto-livre.js +5 -5
  151. package/dist/hitl.js +29 -33
  152. package/dist/horario.js +41 -7
  153. package/dist/hosts.js +104 -11
  154. package/dist/impedimento.js +299 -0
  155. package/dist/index.js +961 -542
  156. package/dist/indice-vetorial.js +87 -10
  157. package/dist/indice.js +9 -1
  158. package/dist/init.js +56 -43
  159. package/dist/instabilidade.js +144 -0
  160. package/dist/integracoes-locais.js +4 -0
  161. package/dist/intelligence-graph-cli.js +170 -16
  162. package/dist/intelligence-graph-contexto.js +254 -0
  163. package/dist/intelligence-graph-contract.js +2 -1
  164. package/dist/intelligence-graph-extract-md.js +56 -4
  165. package/dist/intelligence-graph-extract-ts.js +71 -3
  166. package/dist/intelligence-graph-parsers.js +6 -4
  167. package/dist/intelligence-graph-query.js +66 -19
  168. package/dist/leases.js +664 -87
  169. package/dist/ledger-stats.js +15 -1
  170. package/dist/ledger.js +18 -1
  171. package/dist/licoes.js +1 -0
  172. package/dist/liveness.js +6 -3
  173. package/dist/locale-ajuda.js +761 -0
  174. package/dist/locale-gerados.js +160 -0
  175. package/dist/locale-master.js +99 -0
  176. package/dist/locale-onboarding.js +92 -0
  177. package/dist/locale-phase.js +151 -0
  178. package/dist/locale-pulse.js +211 -0
  179. package/dist/locale-retry.js +385 -0
  180. package/dist/locale-roadmap.js +102 -0
  181. package/dist/locale-ship.js +494 -0
  182. package/dist/locale-thread.js +277 -0
  183. package/dist/locale-verify.js +125 -0
  184. package/dist/locale.js +714 -0
  185. package/dist/maestro-runtime.js +4 -1
  186. package/dist/manifest.js +149 -4
  187. package/dist/maquina.js +23 -4
  188. package/dist/master-digest.js +6 -1
  189. package/dist/master-nota.js +18 -11
  190. package/dist/master.js +145 -31
  191. package/dist/mcp-artifacts.js +43 -3
  192. package/dist/mcp-git.js +42 -8
  193. package/dist/mcp-grafo-worker.js +5 -3
  194. package/dist/mcp-grafo.js +55 -6
  195. package/dist/mcp-server.js +22 -3
  196. package/dist/mcp-ship.js +3 -1
  197. package/dist/mcp-verify.js +6 -1
  198. package/dist/memoria.js +48 -6
  199. package/dist/modos.js +3 -6
  200. package/dist/network-roadmap.js +196 -18
  201. package/dist/noctum-arco.js +911 -0
  202. package/dist/noctum-capacidade.js +141 -0
  203. package/dist/noctum-envelope.js +810 -0
  204. package/dist/noctum-execucao.js +304 -0
  205. package/dist/noctum-fila.js +280 -0
  206. package/dist/ocupacao.js +40 -5
  207. package/dist/onboarding.js +40 -21
  208. package/dist/orkmind.js +99 -7
  209. package/dist/orquestracao.js +24 -21
  210. package/dist/parado-no-condutor.js +219 -38
  211. package/dist/phase.js +160 -52
  212. package/dist/policies.js +56 -5
  213. package/dist/portfolio.js +8 -3
  214. package/dist/postura-local.js +234 -0
  215. package/dist/preflight.js +11 -10
  216. package/dist/procedencia.js +225 -0
  217. package/dist/projeto-alvo.js +132 -5
  218. package/dist/prompts.js +40 -1
  219. package/dist/prova-ativacao.js +75 -6
  220. package/dist/pulse-delivery.js +47 -4
  221. package/dist/pulse.js +98 -19
  222. package/dist/ratelimit.js +24 -6
  223. package/dist/recall.js +3 -1
  224. package/dist/redacao-saida.js +63 -0
  225. package/dist/rede-adesao.js +399 -0
  226. package/dist/rede-forja.js +289 -0
  227. package/dist/rede-projetos.js +239 -0
  228. package/dist/rede-status.js +337 -0
  229. package/dist/rede.js +980 -0
  230. package/dist/retry.js +291 -140
  231. package/dist/roadmap-reservas.js +20 -3
  232. package/dist/roadmap-status.js +150 -34
  233. package/dist/runtime-context.js +181 -3
  234. package/dist/runtime-profiles.js +22 -1
  235. package/dist/runtimes.js +2 -1
  236. package/dist/saida-segura.js +58 -0
  237. package/dist/session-events.js +7 -3
  238. package/dist/session-watcher-claude.js +120 -24
  239. package/dist/session-watcher.js +185 -33
  240. package/dist/sessoes-contas.js +187 -0
  241. package/dist/sessoes-inventario.js +6 -18
  242. package/dist/sessoes.js +83 -2
  243. package/dist/ship-publicar.js +800 -0
  244. package/dist/ship.js +157 -88
  245. package/dist/steal.js +77 -0
  246. package/dist/thread-close.js +3 -2
  247. package/dist/thread.js +299 -49
  248. package/dist/util.js +8 -1
  249. package/dist/verify.js +141 -52
  250. package/dist/vida-da-thread.js +254 -0
  251. package/dist/worktree-local.js +165 -0
  252. package/dist/worktree.js +25 -2
  253. package/dist/yaml.js +27 -8
  254. package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
  255. package/package.json +7 -3
  256. package/references/definition-of-done.md +1 -1
  257. package/schemas/code-artifact-graph.v1.schema.json +2 -1
  258. package/skills/README.md +1 -1
  259. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  260. package/skills/phases/master-metrics/SKILL.md +8 -3
package/dist/ocupacao.js CHANGED
@@ -21,13 +21,14 @@
21
21
  * `slot_released` no ledger da thread devolvida.
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.EVENTOS_QUE_DESTRAVAM = exports.PAUSA_PREVISTA = void 0;
24
+ exports.CARENCIA_DO_TURNO_ENCERRADO_MIN = exports.EVENTOS_QUE_DESTRAVAM = exports.PAUSA_PREVISTA = void 0;
25
25
  exports.ehAprovacaoHumana = ehAprovacaoHumana;
26
26
  exports.ehPausaPrevista = ehPausaPrevista;
27
27
  exports.faseTemPausaPrevista = faseTemPausaPrevista;
28
28
  exports.sessaoLivreDaVaga = sessaoLivreDaVaga;
29
29
  exports.avaliarOcupacao = avaliarOcupacao;
30
30
  const ledger_1 = require("./ledger");
31
+ const impedimento_1 = require("./impedimento");
31
32
  const sessoes_adopt_1 = require("./sessoes-adopt");
32
33
  /** Estado que o `ork phase run` grava quando o bloco despachado pausa ao fim. */
33
34
  exports.PAUSA_PREVISTA = 'prevista ao fim do bloco';
@@ -89,7 +90,9 @@ function ultimaAtividadeEm(eventos) {
89
90
  * `human.pending` sem destravamento, ou sessao bloqueada no runtime), e a que o pulse declarou em silencio
90
91
  * (`runtime.silencio`). A pausa PREVISTA ao fim do bloco nao entra: ela e gravada no proprio
91
92
  * despacho e a sessao roda ate o fim do bloco. O impedimento de verify tambem nao: a sessao corrige e
92
- * verifica de novo. Somente leitura.
93
+ * verifica de novo. RM-058 N2 (D8): a quarta e a sessao com o turno encerrado pelo ledger (`turno-encerrado`), passada
94
+ * a carencia.
95
+ * Somente leitura.
93
96
  */
94
97
  function sessaoLivreDaVaga(doLedger, desde, agora, staleMin,
95
98
  /** A-3 do CHECK 4: o bloqueio no runtime e por sessao; o de outra sessao (a sucedida) nao libera esta. */
@@ -115,8 +118,33 @@ sessionId) {
115
118
  (!sessionId || e.sessionId === sessionId)).at(-1);
116
119
  if (bloqueio?.tipo === 'sessao_bloqueada')
117
120
  return 'human.pending';
121
+ if (sessionId && turnoEncerrado(eventos, sessionId, desde, agora))
122
+ return 'turno-encerrado';
118
123
  return null;
119
124
  }
125
+ /**
126
+ * RM-058 N2 (A8 do CHECK da ork-rm058n2): a carencia do turno encerrado. O Stop do Claude Code dispara a cada fim de
127
+ * turno, e a sessao que espera uma tarefa em segundo plano volta sozinha quando ela acaba; nesse intervalo a vaga
128
+ * continua dela. Sem atividade da sessao por toda a carencia, o turno acabou de vez e a vaga sai.
129
+ */
130
+ exports.CARENCIA_DO_TURNO_ENCERRADO_MIN = 15;
131
+ /**
132
+ * RM-058 N2 (D8 da ork-rm058n2): a sessao cujo turno o ledger prova encerrado (o Stop correlacionado e nenhuma
133
+ * atividade dela depois, ha pelo menos `CARENCIA_DO_TURNO_ENCERRADO_MIN`) nao trabalha mais, mesmo com o lease de pe:
134
+ * e a mesma leitura do pulse (P7). Em 12/10/2026 o `runtime_stop` sem `phase_result` (sessao parada com `claude stop`
135
+ * antes do resultado) prendia a vaga ate a thread fechar. A sessao que volta a trabalhar tem atividade depois do Stop
136
+ * e volta a ocupar.
137
+ */
138
+ function turnoEncerrado(eventos, sessionId, desde, agora) {
139
+ const despacho = [...eventos].reverse().find((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.faseDespachada && e.sessionId === sessionId);
140
+ if (!despacho)
141
+ return false;
142
+ // Carregado na hora: `parado-no-condutor` importa este modulo, e o import no topo fecharia um ciclo de modulos.
143
+ const { fimDoTurno } = require('./parado-no-condutor');
144
+ const fim = fimDoTurno(eventos, despacho);
145
+ return !!fim && fim.tipo !== 'outro' && fim.sessionId === sessionId && Date.parse(fim.em) >= Date.parse(desde) &&
146
+ minutos(fim.em, agora) >= exports.CARENCIA_DO_TURNO_ENCERRADO_MIN;
147
+ }
120
148
  /** A thread tem pausa humana ABERTA? Mesmas tres fontes do monitor, resumidas. */
121
149
  function pausaHumanaAberta(thread, eventos) {
122
150
  if (thread.status === 'pausada' && faseTemPausaPrevista(thread)) {
@@ -126,7 +154,8 @@ function pausaHumanaAberta(thread, eventos) {
126
154
  for (let i = 0; i < eventos.length; i++) {
127
155
  const e = eventos[i];
128
156
  const prevista = ehPausaPrevista(e);
129
- const escalada = e.tipo === ledger_1.TIPOS_DE_EVENTO.gateBloqueado && e.motivo === 'human.pending';
157
+ // RM-055: o impedimento do despacho que so o dono resolve tambem e pausa humana: nao ocupa vaga.
158
+ const escalada = (0, impedimento_1.ehEsperaDoDono)(e, ledger_1.TIPOS_DE_EVENTO.gateBloqueado);
130
159
  if (!prevista && !escalada)
131
160
  continue;
132
161
  const iFase = indiceDaFase(e.fase);
@@ -143,11 +172,16 @@ function pausaHumanaAberta(thread, eventos) {
143
172
  });
144
173
  if (resolvida)
145
174
  continue;
175
+ // Ensaio de 03/10/2026 (RM-049): a escalada traz a correcao gravada no gate (no impedimento do dono,
176
+ // o comando dele e o `ork retry run`); o board a mostra, em vez de um `ork gate request` que o
177
+ // modo sem pausa prevista recusa.
178
+ const correcao = escalada && typeof e.correcao === 'string' && e.correcao !== '' ? e.correcao : undefined;
146
179
  return {
147
180
  desdeEm: e.ts,
148
181
  evidencia: prevista
149
182
  ? `ledger ${ledger_1.TIPOS_DE_EVENTO.pausaHumana} (${exports.PAUSA_PREVISTA}) em ${e.ts}`
150
- : `ledger ${ledger_1.TIPOS_DE_EVENTO.gateBloqueado} (human.pending) em ${e.ts}`,
183
+ : `ledger ${ledger_1.TIPOS_DE_EVENTO.gateBloqueado} (${String(e.motivo)}) em ${e.ts}`,
184
+ ...(correcao ? { correcao } : {}),
151
185
  };
152
186
  }
153
187
  return null;
@@ -162,7 +196,7 @@ function impedimentoAberto(eventos) {
162
196
  continue;
163
197
  const motivo = e.motivo;
164
198
  // `human.pending` ja e pausa humana; `claims.unverifiable` avisa mas nao bloqueia.
165
- if (motivo === 'human.pending' || motivo === 'claims.unverifiable')
199
+ if (motivo === 'human.pending' || motivo === 'claims.unverifiable' || (0, impedimento_1.ehImpedimentoDoDono)(motivo))
166
200
  continue;
167
201
  const resolvido = eventos
168
202
  .slice(i + 1)
@@ -248,6 +282,7 @@ function avaliarOcupacao(thread, doLedger, opcoes) {
248
282
  detalhe: `pausa humana aberta ha ${minutos(pausa.desdeEm, opcoes.agora)} min: ` +
249
283
  'esperar veredito humano nao ocupa vaga da maquina',
250
284
  evidencia: pausa.evidencia,
285
+ ...(pausa.correcao ? { correcao: pausa.correcao } : {}),
251
286
  };
252
287
  }
253
288
  if (registro)
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ETAPAS_ONBOARDING = exports.PAUTA_ONBOARDING = exports.ONDE_FICAM_OS_SEGREDOS = exports.CONTRATO_ONBOARDING = void 0;
36
+ exports.PAUTA_ONBOARDING = exports.ETAPAS_ONBOARDING = exports.ONDE_FICAM_OS_SEGREDOS = exports.CONTRATO_ONBOARDING = void 0;
37
+ exports.perguntaDaEtapa = perguntaDaEtapa;
37
38
  exports.caminhoOnboarding = caminhoOnboarding;
38
39
  exports.validarConteudo = validarConteudo;
39
40
  exports.jsonCanonico = jsonCanonico;
@@ -42,6 +43,7 @@ exports.lerOnboarding = lerOnboarding;
42
43
  exports.gravarEtapa = gravarEtapa;
43
44
  exports.resetarOnboarding = resetarOnboarding;
44
45
  exports.textoDaPauta = textoDaPauta;
46
+ exports.validarPedidoDeEtapa = validarPedidoDeEtapa;
45
47
  /** Entrevista determinística; hosts conduzem a conversa a partir desta pauta. */
46
48
  const fs = __importStar(require("node:fs"));
47
49
  const path = __importStar(require("node:path"));
@@ -53,24 +55,28 @@ const policies_1 = require("./policies");
53
55
  const horario_1 = require("./horario");
54
56
  const experiencia_1 = require("./experiencia");
55
57
  const yaml_1 = require("./yaml");
58
+ const locale_1 = require("./locale");
56
59
  exports.CONTRATO_ONBOARDING = 'ork.onboarding/v1';
57
60
  /**
58
61
  * Fatia 2 do ensaio da 0.5.0 (P5): onde ficam os segredos, para quem usa o Hermes e para quem nao
59
62
  * usa. Perguntas, erro e ajuda leem daqui; as docs e os hosts repetem a frase, conferida por teste.
60
63
  */
61
- exports.ONDE_FICAM_OS_SEGREDOS = 'no ambiente do processo ou no cofre do host (no Hermes, ~/.hermes/.env)';
62
- exports.PAUTA_ONBOARDING = [
63
- { etapa: 'maestro', pergunta: `Quem conduz o projeto, quais são seus objetivos e preferências, e em qual fuso horário o Orkastery deve mostrar horários? Informe o fuso como nome IANA, ex.: {"fuso":"${horario_1.FUSO_DE_BRASILIA}"}; ele orienta ${horario_1.CHAVE_DO_FUSO} no manifesto, sem editá-lo. Preferências em {"owner":{...}} gravam owner no manifesto.` },
64
- { etapa: 'credenciais', pergunta: `Quais provedores públicos e nomes de variáveis em env serão usados? Segredos ficam ${exports.ONDE_FICAM_OS_SEGREDOS}; nunca informe valores.` },
65
- { etapa: 'bancos', pergunta: `Quais bancos públicos e nomes de variáveis em env configuram as conexões? Nunca informe DSN ou senha; valores ficam ${exports.ONDE_FICAM_OS_SEGREDOS}.` },
66
- { etapa: 'memoria', pergunta: 'Deseja OrkMind? Informe {"modo":"orkmind"} ou {"modo":"files"}; a escolha orienta memory.mode no manifesto, sem editá-lo.' },
67
- { etapa: 'produtos', pergunta: 'Quais produtos e repositórios públicos pertencem ao projeto?' },
68
- { etapa: 'topologia', pergunta: 'Como se distribuem ambientes e serviços? Informe identificadores públicos.' },
69
- { etapa: 'arquitetura', pergunta: 'Quais decisões e restrições de arquitetura devem orientar o trabalho?' },
70
- { etapa: 'skills', pergunta: 'Quais capacidades e skills serão necessárias?' },
71
- { etapa: 'auditores', pergunta: 'Quais auditorias e cadências são desejadas?' },
72
- ];
73
- exports.ETAPAS_ONBOARDING = exports.PAUTA_ONBOARDING.map(p => p.etapa);
64
+ exports.ONDE_FICAM_OS_SEGREDOS = (0, locale_1.msg)('pt-BR').onboarding.segredos;
65
+ /** RM-061 (F2a): as etapas, na ordem da entrevista; a pergunta de cada uma sai do catalogo. */
66
+ exports.ETAPAS_ONBOARDING = ['maestro', 'credenciais', 'bancos', 'memoria', 'produtos', 'topologia', 'arquitetura', 'skills', 'auditores'];
67
+ /** A pergunta da etapa no locale pedido (ou no ativo, que so os comandos cobertos trocam). */
68
+ function perguntaDaEtapa(etapa, locale) {
69
+ const m = (0, locale_1.msg)(locale).onboarding, p = m.perguntas;
70
+ if (etapa === 'maestro')
71
+ return p.maestro(horario_1.FUSO_DE_BRASILIA, horario_1.CHAVE_DO_FUSO);
72
+ if (etapa === 'credenciais')
73
+ return p.credenciais(m.segredos);
74
+ if (etapa === 'bancos')
75
+ return p.bancos(m.segredos);
76
+ return p[etapa];
77
+ }
78
+ /** A pauta em pt-BR, como dado (testes e docs a leem); o texto do CLI usa `perguntaDaEtapa`. */
79
+ exports.PAUTA_ONBOARDING = exports.ETAPAS_ONBOARDING.map((etapa) => ({ etapa, pergunta: perguntaDaEtapa(etapa, 'pt-BR') }));
74
80
  function caminhoOnboarding(raiz) {
75
81
  return (0, project_state_1.stateFile)(raiz, 'onboarding.json');
76
82
  }
@@ -79,7 +85,7 @@ function objeto(v) {
79
85
  [Object.prototype, null].includes(Object.getPrototypeOf(v));
80
86
  }
81
87
  /** Recusa antes de persistir. Diagnósticos nunca incluem a entrada recebida. */
82
- function invalido() { throw new Error(`onboarding.input.invalid: use JSON público e referências de variáveis; segredos ficam ${exports.ONDE_FICAM_OS_SEGREDOS}`); }
88
+ function invalido() { throw new Error((0, locale_1.msg)().onboarding.entradaInvalida((0, locale_1.msg)().onboarding.segredos)); }
83
89
  function textoSeguro(v) {
84
90
  return !(0, policies_1.procurarSegredos)(v).length &&
85
91
  !/[a-z][a-z0-9+.-]*:\/\/[^\s/]*@/i.test(v) &&
@@ -405,10 +411,23 @@ function resetarOnboarding(raiz, nome, por = 'owner') {
405
411
  });
406
412
  }
407
413
  function textoDaPauta(estado = onboardingPadrao(), owner = {}) {
408
- const p = (0, experiencia_1.resolverExperiencia)(owner);
409
- return ['Onboarding do projeto (' + exports.CONTRATO_ONBOARDING + ')',
410
- `Experiência recomendada: ${p.language}, ${p.timezone}, resposta ${p.depth}. Ativar com esses valores, configurar ou desativar?`,
411
- 'Registre a escolha em maestro com {"owner":{"language":"' + p.language + '","timezone":"' + p.timezone + '","depth":"' + p.depth + '","experience":true}}; use experience:false para desativar. Consulta não registra resposta.',
412
- ...exports.PAUTA_ONBOARDING.map(({ etapa, pergunta }) => `${estado.etapas[etapa] ? '[respondida]' : '[pendente]'} ${etapa}: ${pergunta}`),
413
- 'Responda com ork onboarding set <etapa> --conteudo <JSON> --por <quem>.'].join('\n');
414
+ const p = (0, experiencia_1.resolverExperiencia)(owner), m = (0, locale_1.msg)().onboarding;
415
+ return [m.titulo(exports.CONTRATO_ONBOARDING),
416
+ m.recomendada(p.language, p.timezone, p.depth),
417
+ m.registre(p.language, p.timezone, p.depth),
418
+ ...exports.ETAPAS_ONBOARDING.map((etapa) => `${estado.etapas[etapa] ? m.respondida : m.pendente} ${etapa}: ${perguntaDaEtapa(etapa)}`),
419
+ m.responda].join('\n');
420
+ }
421
+ /**
422
+ * RM-061 (F2a): a mesma recusa que `gravarEtapa` e `resetarOnboarding` dariam, antes de gravar: o CLI a
423
+ * chama no locale do comando e grava depois em `comLocale('pt-BR')`, entao a recusa de uso sai na
424
+ * lingua do texto e o dado gravado nao muda.
425
+ */
426
+ function validarPedidoDeEtapa(nome, conteudo, por) {
427
+ exigirAutor(por);
428
+ if (nome !== undefined) {
429
+ const etapa = exigirEtapa(nome);
430
+ if (conteudo !== undefined)
431
+ validarConteudo(etapa, conteudo);
432
+ }
414
433
  }
package/dist/orkmind.js CHANGED
@@ -54,7 +54,8 @@ var __importStar = (this && this.__importStar) || (function () {
54
54
  };
55
55
  })();
56
56
  Object.defineProperty(exports, "__esModule", { value: true });
57
- exports.DriverEmMemoria = exports.DriverCliOrkMind = exports.LIMITE_CONSULTA_MAXIMO = exports.LIMITE_CONSULTA_PADRAO = exports.CODIGOS_DE_EMBEDDING = exports.MODELO_DE_EMBEDDING = exports.EMBED_MAX_CARACTERES = exports.EMBED_MAX_TEXTOS = exports.ESQUEMA_ORKMIND = exports.DIMENSOES = exports.COLECOES_DE_GOVERNANCA = exports.COLECOES_DO_ORK = void 0;
57
+ exports.DriverEmMemoria = exports.DriverCliOrkMind = exports.LIMITE_CONSULTA_MAXIMO = exports.LIMITE_CONSULTA_PADRAO = exports.CODIGOS_DE_EMBEDDING = exports.MODELO_DE_EMBEDDING = exports.EMBED_MAX_CARACTERES = exports.EMBED_MAX_TEXTOS = exports.ESQUEMA_ORKMIND = exports.DIMENSOES = exports.COLECOES_DE_GOVERNANCA = exports.LIMITE_TIMEOUT_DO_UNIVERSO_MS = exports.TIMEOUT_DO_UNIVERSO_MS = exports.COLECOES_DO_ORK = void 0;
58
+ exports.pertenceAoUniverso = pertenceAoUniverso;
58
59
  exports.enderecoDeMemoria = enderecoDeMemoria;
59
60
  exports.lerEndereco = lerEndereco;
60
61
  exports.violacoesDeGovernanca = violacoesDeGovernanca;
@@ -82,6 +83,7 @@ const fs = __importStar(require("node:fs"));
82
83
  const node_child_process_1 = require("node:child_process");
83
84
  const node_crypto_1 = require("node:crypto");
84
85
  const node_util_1 = require("node:util");
86
+ const node_perf_hooks_1 = require("node:perf_hooks");
85
87
  /** As colecoes do OrkMind que o `ork` grava (guia: docs/guias/memoria-e-handoff.md). */
86
88
  exports.COLECOES_DO_ORK = [
87
89
  'decision',
@@ -90,6 +92,31 @@ exports.COLECOES_DO_ORK = [
90
92
  'learning',
91
93
  'roadmap',
92
94
  ];
95
+ /** Cinco leituras governadas e a contagem, num unico subprocesso. */
96
+ exports.TIMEOUT_DO_UNIVERSO_MS = 90_000;
97
+ exports.LIMITE_TIMEOUT_DO_UNIVERSO_MS = 86_400_000;
98
+ /** Configuracao direta tambem tem prazo finito: zero no spawnSync significaria sem limite. */
99
+ function prazoDoUniversoMs(prazo) {
100
+ return typeof prazo === 'number' && Number.isSafeInteger(prazo) && prazo > 0 && prazo <= exports.LIMITE_TIMEOUT_DO_UNIVERSO_MS
101
+ ? prazo : exports.TIMEOUT_DO_UNIVERSO_MS;
102
+ }
103
+ /**
104
+ * RM-038: a fronteira do universo da busca vista do `ork`: colecao do ork e o tenant como item
105
+ * de `project`, sem injection_risk e ainda ativa. Reconferida antes de qualquer embed,
106
+ * mesmo quando a ponte ou outro driver devolve uma entrada que a biblioteca deveria recusar.
107
+ */
108
+ function pertenceAoUniverso(e, tenant, agora = Date.now()) {
109
+ // A biblioteca trata datas sem fuso como UTC. Data invalida nunca vira entrada ativa.
110
+ const expira = e.expires_at == null ? null : Date.parse(/(?:Z|[+-]\d{2}:?\d{2})$/i.test(e.expires_at) ? e.expires_at : `${e.expires_at}Z`);
111
+ return exports.COLECOES_DO_ORK.includes(e.collection) && Array.isArray(e.tags.project) &&
112
+ e.tags.project.includes(tenant) && e.injection_risk !== true && (expira === null || expira > agora);
113
+ }
114
+ /** RM-038: contagem de fora da busca bem formada (tres inteiros nao negativos, nada mais). */
115
+ function foraDaBuscaValida(x) {
116
+ const campos = ['injecao', 'expiradas', 'outrasColecoes'];
117
+ return !!x && typeof x === 'object' && !Array.isArray(x) && Object.keys(x).length === campos.length &&
118
+ campos.every(k => Number.isInteger(x[k]) && Number(x[k]) >= 0);
119
+ }
93
120
  /**
94
121
  * Colecoes de governanca dura do OrkMind: entrada aqui vira REGRA do ecossistema.
95
122
  * O agente pode gravar (o B6 grava as policies do manifesto), mas nunca como `mandatory`
@@ -313,6 +340,10 @@ function entradaDoJson(bruto) {
313
340
  const o = bruto;
314
341
  if (typeof o.id !== 'string' || typeof o.content !== 'string')
315
342
  return null;
343
+ if (o.injection_risk !== undefined && typeof o.injection_risk !== 'boolean')
344
+ return null;
345
+ if (o.expires_at !== undefined && o.expires_at !== null && typeof o.expires_at !== 'string')
346
+ return null;
316
347
  const tags = {};
317
348
  if (o.tags && typeof o.tags === 'object' && !Array.isArray(o.tags)) {
318
349
  for (const [k, v] of Object.entries(o.tags)) {
@@ -340,6 +371,8 @@ function entradaDoJson(bruto) {
340
371
  author_id: typeof o.author_id === 'string' ? o.author_id : null,
341
372
  visibility: typeof o.visibility === 'string' ? o.visibility : undefined,
342
373
  protected: typeof o.protected === 'boolean' ? o.protected : undefined,
374
+ injection_risk: o.injection_risk,
375
+ expires_at: o.expires_at,
343
376
  criadaEm: typeof o.created_at === 'string' ? o.created_at : '',
344
377
  };
345
378
  }
@@ -360,8 +393,12 @@ class DriverCliOrkMind {
360
393
  }
361
394
  python() {
362
395
  const cli = this.config.cli;
363
- const candidatos = cli.includes(path.sep) ? [path.resolve(cli)] :
364
- (process.env.PATH ?? '').split(path.delimiter).map(p => path.join(p, cli));
396
+ // RM-047 (fronteira de confiança): caminho relativo resolveria no diretório atual, que é o clone, e
397
+ // entrada relativa do PATH também. Só caminho absoluto ou nome procurado em entrada absoluta do PATH.
398
+ if (cli.includes(path.sep) && !path.isAbsolute(cli))
399
+ throw new Error('cli.ausente: memory.cli relativo recusado');
400
+ const candidatos = path.isAbsolute(cli) ? [cli] :
401
+ (process.env.PATH ?? '').split(path.delimiter).filter(p => path.isAbsolute(p)).map(p => path.join(p, cli));
365
402
  const executavel = candidatos.find(p => {
366
403
  try {
367
404
  fs.accessSync(p, fs.constants.X_OK);
@@ -377,6 +414,9 @@ class DriverCliOrkMind {
377
414
  const match = /^#!(\S+)(?:\s+(\S+))?\s*$/.exec(linha);
378
415
  if (!match)
379
416
  throw new Error('memory.transport.interpreter: shebang nao suportado');
417
+ // RM-047: interpretador relativo resolveria no diretório atual (o clone).
418
+ if (!path.isAbsolute(match[1]))
419
+ throw new Error('memory.transport.interpreter: shebang nao suportado');
380
420
  return match[2] ? [match[1], match[2]] : [match[1]];
381
421
  }
382
422
  /** Valor da chave de embedding no ambiente do `ork`; nunca guardado no driver. */
@@ -440,7 +480,7 @@ class DriverCliOrkMind {
440
480
  code = JSON.parse(r.stdout)?.error;
441
481
  }
442
482
  catch { /* nenhum detalhe do filho */ }
443
- throw new Error(['memory.schema.absent', 'memory.legacy.provenance-collision', 'memory.prospective.marker-invalid', 'memory.native.schema-mismatch', 'memory.query.invalid', 'memory.query.window-saturated', 'memory.query.scope-violation', 'memory.health.invalid', 'memory.fts.invalid', ...exports.CODIGOS_DE_EMBEDDING].includes(code) ? code : 'memory.transport.failed');
483
+ throw new Error(['memory.schema.absent', 'memory.legacy.provenance-collision', 'memory.prospective.marker-invalid', 'memory.native.schema-mismatch', 'memory.query.invalid', 'memory.query.window-saturated', 'memory.query.scope-violation', 'memory.health.invalid', 'memory.fts.invalid', 'memory.universo.invalid', ...exports.CODIGOS_DE_EMBEDDING].includes(code) ? code : 'memory.transport.failed');
444
484
  }
445
485
  let json;
446
486
  try {
@@ -555,6 +595,31 @@ class DriverCliOrkMind {
555
595
  }
556
596
  return r.ids;
557
597
  }
598
+ /**
599
+ * RM-038: o universo da busca numa chamada. A ponte filtra o tenant na origem e confere o
600
+ * predicado; o `ork` confere de novo cada entrada e recusa a alheia, nunca a descarta.
601
+ */
602
+ universo(tenant) {
603
+ if (!textoDeConsulta(tenant, 128) || tenant.trim() === '')
604
+ throw new Error('memory.universo.invalid');
605
+ const agora = Date.now();
606
+ const inicio = node_perf_hooks_1.performance.now();
607
+ const r = this.rodar({ op: 'universo', tenant }, prazoDoUniversoMs(this.config.universoTimeoutMs));
608
+ if (!objetoDeConsulta(r) || !Array.isArray(r.entradas) || !(r.foraDaBusca === null || foraDaBuscaValida(r.foraDaBusca))) {
609
+ throw new Error('memory.transport.universo');
610
+ }
611
+ const entradas = r.entradas.map(d => {
612
+ const e = entradaDoJson(d);
613
+ if (!e)
614
+ throw new Error('memory.transport.universo');
615
+ if (!pertenceAoUniverso(e, tenant, agora))
616
+ throw new Error('memory.query.scope-violation');
617
+ return e;
618
+ });
619
+ const fora = r.foraDaBusca;
620
+ return { entradas, foraDaBusca: fora === null ? null : { injecao: fora.injecao, expiradas: fora.expiradas, outrasColecoes: fora.outrasColecoes },
621
+ latenciaMs: node_perf_hooks_1.performance.now() - inicio };
622
+ }
558
623
  submeterHandoff(pedido) {
559
624
  try {
560
625
  const r = this.rodar({ op: 'handoff', pedido });
@@ -671,6 +736,8 @@ class DriverEmMemoria {
671
736
  embedding = { primario: true, fallback: true };
672
737
  /** Pedidos de embedding recebidos, para as assercoes de custo (chamadas ao provider). */
673
738
  pedidosDeEmbedding = [];
739
+ /** RM-038: o que a governanca da biblioteca tiraria da leitura (injection_risk, expirada), por id. */
740
+ foraDaBuscaMarcadas = new Map();
674
741
  constructor(entradas = []) {
675
742
  for (const e of entradas)
676
743
  this.entradas.push(e);
@@ -750,7 +817,31 @@ class DriverEmMemoria {
750
817
  exportar(colecao) {
751
818
  if (!this.ligado)
752
819
  throw new Error('memory.transport.unavailable');
753
- return this.entradas.filter((e) => e.collection === colecao);
820
+ // Como o search_by_tags governado: o que a governanca tira nao sai pela leitura por tag.
821
+ return this.entradas.filter((e) => e.collection === colecao && !this.foraDaBuscaMarcadas.has(e.id));
822
+ }
823
+ /** So para os testes: a entrada passa a contar como tirada pela governanca da biblioteca. */
824
+ marcarForaDaBusca(id, motivo) {
825
+ this.foraDaBuscaMarcadas.set(id, motivo);
826
+ }
827
+ /** RM-038: o mesmo predicado do universo para o dublê inteiro (universo e FTS). */
828
+ naBusca(e, tenant) {
829
+ return pertenceAoUniverso(e, tenant) && !this.foraDaBuscaMarcadas.has(e.id);
830
+ }
831
+ /** RM-038: dublê da operacao `universo` da ponte, com a contagem de fora da busca. */
832
+ universo(tenant) {
833
+ if (!textoDeConsulta(tenant, 128) || tenant.trim() === '')
834
+ throw new Error('memory.universo.invalid');
835
+ if (!this.ligado)
836
+ throw new Error('memory.transport.unavailable');
837
+ const foraDaBusca = { injecao: 0, expiradas: 0, outrasColecoes: 0 };
838
+ for (const e of this.entradas.filter(x => (x.tags.project ?? []).includes(tenant))) {
839
+ if (!exports.COLECOES_DO_ORK.includes(e.collection))
840
+ foraDaBusca.outrasColecoes += 1;
841
+ else if (this.foraDaBuscaMarcadas.has(e.id))
842
+ foraDaBusca[this.foraDaBuscaMarcadas.get(e.id)] += 1;
843
+ }
844
+ return { entradas: this.entradas.filter(e => this.naBusca(e, tenant)), foraDaBusca };
754
845
  }
755
846
  consultar(consulta) {
756
847
  const q = validarConsultaDelimitada(consulta);
@@ -802,7 +893,7 @@ class DriverEmMemoria {
802
893
  this.pedidosDeEmbedding.push(p);
803
894
  return { alvo: p.alvo, modelo: p.modelo, dim: p.dim, vetores: p.textos.map(t => vetorDeDuble(t, p.dim)) };
804
895
  }
805
- /** Dublê de FTS: todas as palavras da consulta no conteudo, sem stemming, com tenant obrigatorio. */
896
+ /** Dublê de FTS: todas as palavras da consulta no conteudo, sem stemming, dentro do universo da busca. */
806
897
  buscarTexto(tenant, texto) {
807
898
  if (!textoDeConsulta(tenant, 128) || !textoDeBuscaValido(texto))
808
899
  throw new Error('memory.fts.invalid');
@@ -811,7 +902,7 @@ class DriverEmMemoria {
811
902
  const palavras = (t) => t.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().match(/[a-z0-9]+/g) ?? [];
812
903
  const consulta = palavras(texto);
813
904
  return this.entradas
814
- .filter(e => exports.COLECOES_DO_ORK.includes(e.collection) && (e.tags.project ?? []).includes(tenant))
905
+ .filter(e => this.naBusca(e, tenant))
815
906
  .map(e => ({ id: e.id, conteudo: palavras(e.content) }))
816
907
  .filter(e => consulta.every(p => e.conteudo.includes(p)))
817
908
  .map(e => ({ id: e.id, peso: e.conteudo.filter(p => consulta.includes(p)).length }))
@@ -838,6 +929,7 @@ function configDoManifesto(manifesto) {
838
929
  variavel,
839
930
  dsn: variavel ? (process.env[variavel] ?? '') : '',
840
931
  timeoutMs: manifesto.memory.timeout_ms || 15000,
932
+ universoTimeoutMs: prazoDoUniversoMs(manifesto.memory.universo_timeout_ms),
841
933
  tenant: manifesto.memory.tenant || manifesto.project.name,
842
934
  // Lido direto do bloco: este modulo carrega sem o parser do manifesto (memory-native-schema).
843
935
  variavelDaChaveDeEmbedding: manifesto.memory.embedding?.provider === 'openrouter' ? manifesto.memory.embedding.api_key_env : '',
@@ -69,16 +69,18 @@ const adapter = __importStar(require("./adapters/claude-bg"));
69
69
  const board_1 = require("./board");
70
70
  const gates_1 = require("./gates");
71
71
  const ledger_1 = require("./ledger");
72
+ const leases_1 = require("./leases");
72
73
  const modos_1 = require("./modos");
73
74
  const ocupacao_1 = require("./ocupacao");
74
75
  const ratelimit_1 = require("./ratelimit");
75
- const hitl_1 = require("./hitl");
76
+ const impedimento_1 = require("./impedimento");
76
77
  const thread_1 = require("./thread");
77
78
  const util_1 = require("./util");
78
79
  const horario_1 = require("./horario");
79
80
  Object.defineProperty(exports, "duracaoCurta", { enumerable: true, get: function () { return horario_1.duracaoCurta; } });
80
81
  const conducao_1 = require("./conducao");
81
82
  const conducao_texto_1 = require("./conducao-texto");
83
+ const locale_1 = require("./locale");
82
84
  /** Limite de atencao padrao, em minutos: parada mais velha que isso e destacada. */
83
85
  exports.ATENCAO_PADRAO_MIN = 30;
84
86
  /** Minutos inteiros entre dois carimbos ISO (nunca negativo). */
@@ -167,16 +169,17 @@ function pausasAbertas(thread, eventos, estados, quando) {
167
169
  fase,
168
170
  bloco: blocoDaFase(thread, fase).bloco,
169
171
  pausaSobre: sobre,
170
- detalhe: sessaoViva === true
171
- ? `a sessao ${sessionId.slice(0, 8)} do bloco ainda esta trabalhando no runtime: a pausa chega quando ela terminar`
172
+ // RM-061 (F2b, G2): a parada nasce em pt-BR (o --json do monitor) e o pulse a remonta no locale.
173
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => sessaoViva === true
174
+ ? m.pulse.pausaTrabalhando(sessionId.slice(0, 8))
172
175
  : sessaoEstado === 'blocked'
173
- ? `a sessao ${sessionId.slice(0, 8)} do bloco esta BLOQUEADA no runtime esperando acao humana (prompt, permissao ou credencial): veja \`ork sessions hitl\``
174
- : `bloco fechado em ${fase ?? '?'}: espera o veredito humano sobre ${sobre || 'a pausa do bloco'}`,
176
+ ? m.pulse.pausaBloqueada(sessionId.slice(0, 8))
177
+ : m.pulse.blocoFechado(fase ?? '?', sobre ? m.thread.pausaSobre(sobre) : m.pulse.aPausaDoBloco)),
175
178
  evidencia: `ledger ${ledger_1.TIPOS_DE_EVENTO.pausaHumana} (${ocupacao_1.PAUSA_PREVISTA})` +
176
179
  `${sessionId ? `, sessao ${sessionId.slice(0, 8)}` : ''}` +
177
180
  `${sessaoEstado ? ` em state=${sessaoEstado}` : ''}`,
178
181
  correcao: sessaoEstado === 'blocked'
179
- ? `ork sessions logs ${sessionId.slice(0, 8)} para ver o que a sessao pede, e claude attach ${sessionId} para responder`
182
+ ? (0, locale_1.textoDoCatalogo)((m) => m.pulse.responderSessao(sessionId.slice(0, 8), sessionId))
180
183
  : comandoDeAprovacao(thread.id, sobre),
181
184
  desdeEm: e.ts,
182
185
  sessaoViva,
@@ -188,7 +191,8 @@ function pausasAbertas(thread, eventos, estados, quando) {
188
191
  // ESCALADA do bloco B3 (limite de tentativas estourado), que pausa qualquer modo,
189
192
  // inclusive `#Auto` -- que por definicao nao tem pausa prevista no ledger.
190
193
  eventos.forEach((e, i) => {
191
- if (e.tipo !== ledger_1.TIPOS_DE_EVENTO.gateBloqueado || e.motivo !== 'human.pending')
194
+ // RM-055: o impedimento do despacho que so o dono resolve tambem e espera dele.
195
+ if (!(0, impedimento_1.ehEsperaDoDono)(e, ledger_1.TIPOS_DE_EVENTO.gateBloqueado))
192
196
  return;
193
197
  const resolvido = eventos
194
198
  .slice(i + 1)
@@ -200,15 +204,17 @@ function pausasAbertas(thread, eventos, estados, quando) {
200
204
  if (porFase.has(chave))
201
205
  return;
202
206
  const { bloco, pausaSobre } = blocoDaFase(thread, fase);
207
+ const imp = (0, impedimento_1.ehImpedimentoDoDono)(e.motivo) ? (0, impedimento_1.impedimentoDoEvento)(e) : null;
203
208
  porFase.set(chave, parada({
204
209
  natureza: 'pausa-humana',
205
- motivo: 'human.pending',
210
+ motivo: imp ? e.motivo : 'human.pending',
206
211
  fase,
207
212
  bloco,
208
- pausaSobre: pausaSobre || 'autorizacao da retomada',
213
+ pausaSobre: imp ? `rodar \`${imp.comando}\` no terminal` : pausaSobre || 'autorizacao da retomada',
214
+ ...(imp ? { impedimento: imp } : {}),
209
215
  detalhe: typeof e.detalhe === 'string' && e.detalhe !== ''
210
216
  ? e.detalhe
211
- : gates_1.DESCRICAO_DO_MOTIVO['human.pending'],
217
+ : (0, locale_1.textoDoCatalogo)((m) => m.pulse.motivos['human.pending']),
212
218
  evidencia: `ledger ${ledger_1.TIPOS_DE_EVENTO.gateBloqueado} (gate ${String(e.gate ?? '?')})`,
213
219
  correcao: typeof e.correcao === 'string' && e.correcao !== ''
214
220
  ? e.correcao
@@ -229,7 +235,7 @@ function pausasAbertas(thread, eventos, estados, quando) {
229
235
  fase: thread.faseAtual,
230
236
  bloco,
231
237
  pausaSobre: pausaSobre || 'veredito do bloco',
232
- detalhe: `thread carimbada como pausada na fase ${thread.faseAtual}`,
238
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.pulse.threadPausada(thread.faseAtual)),
233
239
  evidencia: 'thread.json (status: pausada)',
234
240
  correcao: comandoDeAprovacao(thread.id, pausaSobre),
235
241
  desdeEm: thread.atualizadaEm,
@@ -254,9 +260,9 @@ function impedimentosAbertos(item, eventos, raizDoProjeto, quando) {
254
260
  fase: thread.faseAtual,
255
261
  bloco: blocoDaFase(thread, thread.faseAtual).bloco,
256
262
  pausaSobre: '',
257
- detalhe: `na fila de ${p.nome}, atras da thread ${p.bloqueadaPor} (colide com ${p.colidiuCom})`,
263
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.pulse.naFilaDoLease(p.nome, p.bloqueadaPor, p.colidiuCom)),
258
264
  evidencia: `.orkastery/leases/fila.json (${p.tipo})`,
259
- correcao: `espere a thread ${p.bloqueadaPor} liberar (ork lease release ${p.colidiuCom} --thread ${p.bloqueadaPor}), ou reduza a regiao pedida`,
265
+ correcao: (0, locale_1.textoDoCatalogo)((m) => m.pulse.espereOLease(p.bloqueadaPor, (0, leases_1.argumentoDeLease)(p.colidiuCom), (0, leases_1.argumentoDeLease)(p.bloqueadaPor))),
260
266
  desdeEm: p.desdeEm,
261
267
  sessaoViva: null,
262
268
  fonte: 'fila-de-lease',
@@ -273,8 +279,7 @@ function impedimentosAbertos(item, eventos, raizDoProjeto, quando) {
273
279
  fase: p.fase,
274
280
  bloco: blocoDaFase(thread, p.fase).bloco,
275
281
  pausaSobre: '',
276
- detalhe: `pedido ${p.id} na fila de rate limit, libera ${(0, ratelimit_1.faltaPara)(p, quando)} ` +
277
- `(${p.liberaEm}, ${p.janelaEstimada ? 'janela estimada' : 'hora dita pelo runtime'})`,
282
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.pulse.naFilaDeRateLimit(p.id, (0, ratelimit_1.faltaPara)(p, quando), p.liberaEm, p.janelaEstimada)),
278
283
  evidencia: `.orkastery/retry/fila.jsonl (${p.id}, ${p.sinal.fonte})`,
279
284
  correcao: `ork retry resume --id ${p.id}`,
280
285
  desdeEm: p.criadoEm,
@@ -288,7 +293,7 @@ function impedimentosAbertos(item, eventos, raizDoProjeto, quando) {
288
293
  if (e.tipo !== ledger_1.TIPOS_DE_EVENTO.gateBloqueado && e.tipo !== 'phase_wait')
289
294
  return;
290
295
  const motivo = e.motivo;
291
- if (motivo === 'human.pending' || motivo === 'claims.unverifiable')
296
+ if (motivo === 'human.pending' || motivo === 'claims.unverifiable' || (0, impedimento_1.ehImpedimentoDoDono)(motivo))
292
297
  return;
293
298
  if (!(motivo in gates_1.DESCRICAO_DO_MOTIVO))
294
299
  return;
@@ -310,7 +315,7 @@ function impedimentosAbertos(item, eventos, raizDoProjeto, quando) {
310
315
  pausaSobre: '',
311
316
  detalhe: typeof e.detalhe === 'string' && e.detalhe !== ''
312
317
  ? e.detalhe
313
- : gates_1.DESCRICAO_DO_MOTIVO[motivo],
318
+ : (0, locale_1.textoDoCatalogo)((m) => m.pulse.motivos[motivo]),
314
319
  evidencia: `ledger ${e.tipo} (gate ${String(e.gate ?? '?')})`,
315
320
  correcao: typeof e.correcao === 'string' && e.correcao !== ''
316
321
  ? e.correcao
@@ -372,10 +377,8 @@ function montarMonitor(carregado, opcoes = {}) {
372
377
  }
373
378
  else if (opcoes.semRuntime !== true) {
374
379
  if (adapter.disponivel()) {
375
- estados = new Map(adapter
376
- .listarSessoes()
377
- .filter((s) => !!s.sessionId)
378
- .map((s) => [s.sessionId, (0, hitl_1.estadoBruto)(s)]));
380
+ // RM-056 (D7): todas as contas, a mesma consulta do escalonador.
381
+ estados = (0, board_1.estadosDeSessao)(carregado.raiz, carregado.manifesto.concurrency.stale_after_min);
379
382
  runtimeDetalhe = '';
380
383
  }
381
384
  else {