@orkastery/cli 0.5.3 → 0.6.0

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 (502) hide show
  1. package/adapters/README.md +18 -0
  2. package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
  3. package/adapters/claude-code/README.md +195 -5
  4. package/adapters/claude-code/agents/ork-check.md +1 -0
  5. package/adapters/claude-code/agents/ork-go.md +1 -0
  6. package/adapters/claude-code/agents/ork-goal.md +1 -0
  7. package/adapters/claude-code/agents/ork-master.md +1 -0
  8. package/adapters/claude-code/agents/ork-plan.md +1 -0
  9. package/adapters/claude-code/agents/ork-ship.md +1 -0
  10. package/adapters/claude-code/hooks/hooks.json +2 -1
  11. package/adapters/claude-code/hooks/ork-guard.js +15 -1
  12. package/adapters/claude-code/hooks/ork-resposta.js +91 -0
  13. package/adapters/claude-code/hooks/ork-sensor.js +18 -2
  14. package/adapters/claude-code/hooks/quota-signal.js +14 -0
  15. package/adapters/claude-code/mods/autoridade.json +56 -0
  16. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  17. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  18. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  19. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  20. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  21. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  22. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  23. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  24. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  25. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  26. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  27. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  28. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  29. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  30. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  31. package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
  32. package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
  33. package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
  34. package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
  35. package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
  36. package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
  37. package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
  38. package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
  39. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  40. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  41. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  42. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  43. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  44. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  45. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  46. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  47. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  48. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  49. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  50. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +121 -0
  51. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  52. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  53. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  54. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  55. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  56. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  57. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  58. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  59. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  60. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  61. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  62. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  63. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  64. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  65. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  66. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  67. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  68. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  69. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  70. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  71. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  72. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  73. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  74. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  75. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  76. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  77. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  78. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  79. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  80. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  81. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  82. package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
  83. package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
  84. package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
  85. package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
  86. package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
  87. package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
  88. package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
  89. package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
  90. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  91. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  92. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  93. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  94. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  95. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  96. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  97. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  98. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  99. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  100. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  101. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  102. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  103. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  104. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  105. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  106. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  107. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  108. package/adapters/codex/skills/ork/SKILL.md +2 -0
  109. package/adapters/hermes/README.md +64 -1
  110. package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
  111. package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
  112. package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
  113. package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
  114. package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
  115. package/adapters/hermes/hermes.plugin.json +4 -0
  116. package/adapters/hermes/hitl-ingress/__init__.py +101 -8
  117. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +3 -3
  118. package/adapters/openclaw/README.md +83 -10
  119. package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
  120. package/adapters/openclaw/dist/hitl-ingress.js +106 -9
  121. package/adapters/openclaw/dist/index.js +86 -0
  122. package/adapters/openclaw/openclaw.plugin.json +34 -4
  123. package/adapters/openclaw/package.json +2 -2
  124. package/adapters/openclaw/src/hitl-ingress.ts +103 -9
  125. package/adapters/openclaw/src/index.ts +94 -0
  126. package/assets/adapters-en/claude-code/README.md +403 -0
  127. package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
  128. package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
  129. package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
  130. package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
  131. package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
  132. package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
  133. package/assets/adapters-en/claude-code/commands/check.md +46 -0
  134. package/assets/adapters-en/claude-code/commands/go.md +46 -0
  135. package/assets/adapters-en/claude-code/commands/goal.md +55 -0
  136. package/assets/adapters-en/claude-code/commands/master.md +54 -0
  137. package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
  138. package/assets/adapters-en/claude-code/commands/ork.md +126 -0
  139. package/assets/adapters-en/claude-code/commands/plan.md +47 -0
  140. package/assets/adapters-en/claude-code/commands/ship.md +45 -0
  141. package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
  142. package/assets/adapters-en/hermes/README.md +273 -0
  143. package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
  144. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  145. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  146. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  147. package/assets/docs-en/produto/README.md +14 -0
  148. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  149. package/assets/docs-en/roadmap/README.md +14 -0
  150. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  151. package/assets/references-en/README.md +25 -0
  152. package/assets/references-en/code-review-axes.md +82 -0
  153. package/assets/references-en/definition-of-done.md +74 -0
  154. package/assets/references-en/performance-checklist.md +53 -0
  155. package/assets/references-en/security-checklist.md +101 -0
  156. package/assets/references-en/testing-patterns.md +51 -0
  157. package/assets/security-scan/defaults/.golangci.yml +2 -0
  158. package/assets/security-scan/defaults/eslint.config.mjs +11 -0
  159. package/assets/security-scan/defaults/gitleaks.toml +3 -0
  160. package/assets/security-scan/defaults/ruff.toml +1 -0
  161. package/assets/security-scan/tools-agil.json +87 -0
  162. package/assets/security-scan/tools.json +625 -0
  163. package/assets/skills-en/core/onboarding/SKILL.md +58 -0
  164. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
  165. package/assets/skills-en/core/thread-state/SKILL.md +88 -0
  166. package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
  167. package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
  168. package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
  169. package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
  170. package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
  171. package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
  172. package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
  173. package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
  174. package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
  175. package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
  176. package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
  177. package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
  178. package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
  179. package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
  180. package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
  181. package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
  182. package/dist/adapters/claude-bg.js +193 -15
  183. package/dist/adapters/codex-controller-worker.js +12 -5
  184. package/dist/adapters/codex-events.js +16 -4
  185. package/dist/adapters/codex.js +13 -2
  186. package/dist/agents-md.js +24 -15
  187. package/dist/atualizar-branch.js +245 -0
  188. package/dist/auditoria.js +13 -11
  189. package/dist/auditrun.js +68 -48
  190. package/dist/autorizacao-duravel.js +327 -0
  191. package/dist/board.js +98 -43
  192. package/dist/branch-de-estado.js +39 -9
  193. package/dist/busca-semantica.js +7 -5
  194. package/dist/catalogo.js +35 -1
  195. package/dist/changelog-reconciliacao.js +290 -0
  196. package/dist/check-agil.js +500 -0
  197. package/dist/check-modo.js +41 -0
  198. package/dist/check-paralelo.js +183 -0
  199. package/dist/ci.js +255 -46
  200. package/dist/ciclos.js +8 -6
  201. package/dist/claim-lint.js +12 -8
  202. package/dist/claims-conferir.js +350 -0
  203. package/dist/claims.js +13 -10
  204. package/dist/company-brain-client.js +45 -3
  205. package/dist/company-brain-journal.js +2 -1
  206. package/dist/company-brain-migration.js +47 -6
  207. package/dist/conducao-batida.js +759 -0
  208. package/dist/conducao-sentinela.js +405 -0
  209. package/dist/conducao-texto.js +12 -18
  210. package/dist/conducao.js +206 -59
  211. package/dist/conhecimento-consulta.js +270 -0
  212. package/dist/conhecimento.js +514 -0
  213. package/dist/conta-esgotada.js +127 -0
  214. package/dist/dado-privado.js +816 -0
  215. package/dist/decisao-autonoma.js +5 -4
  216. package/dist/demo.js +14 -12
  217. package/dist/dependencias-da-worktree.js +25 -0
  218. package/dist/divida.js +38 -36
  219. package/dist/docs.js +103 -82
  220. package/dist/doctor-forja.js +345 -0
  221. package/dist/doctor-pulse-cron.js +294 -27
  222. package/dist/doctor-rede.js +18 -17
  223. package/dist/doctor.js +278 -116
  224. package/dist/dsn-da-memoria.js +417 -0
  225. package/dist/entrega-por-mod.js +503 -0
  226. package/dist/entrega-pr.js +158 -57
  227. package/dist/escopo-escrita.js +10 -1
  228. package/dist/esgotamentos.js +13 -11
  229. package/dist/estado-thread.js +42 -17
  230. package/dist/evalrunner.js +35 -32
  231. package/dist/experiencia-instalacao.js +45 -25
  232. package/dist/fabrica-batida.js +323 -0
  233. package/dist/fabrica-estado.js +49 -16
  234. package/dist/fabrica-publicar.js +3 -1
  235. package/dist/fila-pesada.js +444 -0
  236. package/dist/fix.js +24 -21
  237. package/dist/forja/adaptador.js +6 -0
  238. package/dist/forja/ambiente-de-ci.js +27 -0
  239. package/dist/forja/api.js +256 -0
  240. package/dist/forja/cache.js +89 -0
  241. package/dist/forja/cli.js +60 -0
  242. package/dist/forja/contrato.js +9 -0
  243. package/dist/forja/endereco.js +43 -0
  244. package/dist/forja/estado.js +22 -0
  245. package/dist/forja/executor.js +73 -0
  246. package/dist/forja/github/ci.js +95 -0
  247. package/dist/forja/github/dono-da-rede.js +18 -0
  248. package/dist/forja/github/metadados.js +15 -0
  249. package/dist/forja/github/pedidos.js +200 -0
  250. package/dist/forja/gitlab/ci.js +141 -0
  251. package/dist/forja/gitlab/consultas.js +59 -0
  252. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  253. package/dist/forja/gitlab/metadados.js +15 -0
  254. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  255. package/dist/forja/gitlab/pedidos.js +141 -0
  256. package/dist/forja/produtor.js +32 -0
  257. package/dist/forja/registro.js +31 -0
  258. package/dist/forja/resolver.js +121 -0
  259. package/dist/forja/texto.js +13 -0
  260. package/dist/forja/versao.js +71 -0
  261. package/dist/forja.js +124 -81
  262. package/dist/gates.js +3 -28
  263. package/dist/handoff.js +33 -19
  264. package/dist/hitl-contract.js +46 -43
  265. package/dist/hitl-curto.js +37 -25
  266. package/dist/hitl-gates.js +13 -11
  267. package/dist/hitl-local-receipt.js +53 -0
  268. package/dist/hitl-local.js +11 -2
  269. package/dist/hitl-lock.js +5 -11
  270. package/dist/hitl-public-receipt.js +11 -0
  271. package/dist/hitl-resumo.js +72 -3
  272. package/dist/hitl-sessions.js +62 -9
  273. package/dist/hitl-tempo-parado.js +4 -4
  274. package/dist/hitl-texto-livre.js +7 -4
  275. package/dist/hitl.js +63 -64
  276. package/dist/horario.js +30 -7
  277. package/dist/hosts.js +155 -134
  278. package/dist/impedimento.js +108 -14
  279. package/dist/index.js +1421 -1019
  280. package/dist/indice-vetorial.js +14 -12
  281. package/dist/indice.js +7 -1
  282. package/dist/init.js +54 -49
  283. package/dist/instabilidade.js +144 -0
  284. package/dist/integracoes-locais.js +4 -0
  285. package/dist/intelligence-graph-cli.js +213 -88
  286. package/dist/intelligence-graph-contexto.js +56 -17
  287. package/dist/intelligence-graph-contract.js +2 -1
  288. package/dist/intelligence-graph-extract-md.js +56 -4
  289. package/dist/intelligence-graph-extract-ts.js +71 -3
  290. package/dist/intelligence-graph-query.js +96 -34
  291. package/dist/leases.js +19 -18
  292. package/dist/ledger-stats.js +17 -16
  293. package/dist/ledger.js +46 -2
  294. package/dist/licoes.js +12 -11
  295. package/dist/liveness.js +6 -3
  296. package/dist/locale-accounts.js +220 -0
  297. package/dist/locale-adapter.js +291 -0
  298. package/dist/locale-ajuda.js +833 -0
  299. package/dist/locale-audit.js +199 -0
  300. package/dist/locale-claims.js +213 -0
  301. package/dist/locale-conducao.js +138 -0
  302. package/dist/locale-conhecimento.js +181 -0
  303. package/dist/locale-decisao.js +205 -0
  304. package/dist/locale-docs.js +230 -0
  305. package/dist/locale-estado.js +101 -0
  306. package/dist/locale-forja.js +290 -0
  307. package/dist/locale-gerados.js +165 -0
  308. package/dist/locale-grafo.js +129 -0
  309. package/dist/locale-master.js +182 -0
  310. package/dist/locale-network.js +524 -0
  311. package/dist/locale-onboarding.js +92 -0
  312. package/dist/locale-operacao-restante.js +931 -0
  313. package/dist/locale-phase.js +151 -0
  314. package/dist/locale-projetos.js +100 -0
  315. package/dist/locale-prompts.js +194 -0
  316. package/dist/locale-pulse.js +349 -0
  317. package/dist/locale-reservas.js +87 -0
  318. package/dist/locale-retry.js +524 -0
  319. package/dist/locale-roadmap.js +102 -0
  320. package/dist/locale-security-scan.js +69 -0
  321. package/dist/locale-setup.js +192 -0
  322. package/dist/locale-ship.js +597 -0
  323. package/dist/locale-thread.js +421 -0
  324. package/dist/locale-verify.js +201 -0
  325. package/dist/locale-worktree.js +246 -0
  326. package/dist/locale.js +1258 -0
  327. package/dist/maestro-runtime.js +22 -3
  328. package/dist/manifest.js +415 -13
  329. package/dist/maquina-ociosa.js +211 -0
  330. package/dist/maquina.js +31 -7
  331. package/dist/master-digest.js +6 -1
  332. package/dist/master-nota-local.js +200 -0
  333. package/dist/master-nota.js +14 -8
  334. package/dist/master.js +139 -65
  335. package/dist/mcp-artifacts.js +11 -2
  336. package/dist/mcp-conhecimento.js +52 -0
  337. package/dist/mcp-experiencia.js +26 -5
  338. package/dist/mcp-git.js +23 -6
  339. package/dist/mcp-grafo.js +7 -4
  340. package/dist/mcp-install.js +73 -8
  341. package/dist/mcp-noctum.js +101 -0
  342. package/dist/mcp-server.js +90 -16
  343. package/dist/mcp-ship-transporte.js +977 -0
  344. package/dist/mcp-ship.js +71 -25
  345. package/dist/mcp-transportes.js +17 -0
  346. package/dist/mcp-verify.js +6 -1
  347. package/dist/memoria.js +63 -58
  348. package/dist/modos-migracao.js +8 -6
  349. package/dist/modos.js +20 -24
  350. package/dist/network-roadmap.js +90 -51
  351. package/dist/noctum-aceite.js +789 -0
  352. package/dist/noctum-arco.js +1418 -0
  353. package/dist/noctum-capacidade.js +141 -0
  354. package/dist/noctum-changelog.js +399 -0
  355. package/dist/noctum-cli.js +482 -0
  356. package/dist/noctum-coordenacao.js +1225 -0
  357. package/dist/noctum-entrega.js +1169 -0
  358. package/dist/noctum-envelope.js +1046 -0
  359. package/dist/noctum-execucao.js +376 -0
  360. package/dist/noctum-fechamento.js +405 -0
  361. package/dist/noctum-fila.js +314 -0
  362. package/dist/noctum-guarda.js +256 -0
  363. package/dist/noctum-integracao.js +507 -0
  364. package/dist/noctum-maquinas.js +383 -0
  365. package/dist/noctum-medicao.js +450 -0
  366. package/dist/noctum-modo.js +362 -0
  367. package/dist/noctum-pergunta-canal.js +96 -0
  368. package/dist/noctum-pergunta.js +115 -0
  369. package/dist/noctum-provas.js +838 -0
  370. package/dist/noctum-reconciliacao.js +591 -0
  371. package/dist/noctum-registro.js +215 -0
  372. package/dist/noctum-relatorio.js +827 -0
  373. package/dist/noctum-resposta.js +207 -0
  374. package/dist/noctum-sessoes-em-voo.js +93 -0
  375. package/dist/noctum-supervisao.js +649 -0
  376. package/dist/noctum-terminal.js +459 -0
  377. package/dist/noctum-transporte.js +655 -0
  378. package/dist/noctum-vigia.js +639 -0
  379. package/dist/ocupacao.js +32 -3
  380. package/dist/onboarding.js +56 -26
  381. package/dist/orkmind.js +48 -25
  382. package/dist/orquestracao.js +44 -47
  383. package/dist/parado-no-condutor.js +174 -127
  384. package/dist/phase.js +144 -63
  385. package/dist/policies.js +37 -4
  386. package/dist/portfolio.js +4 -2
  387. package/dist/postura-local.js +235 -0
  388. package/dist/preflight.js +11 -10
  389. package/dist/procedencia.js +220 -0
  390. package/dist/projeto-alvo.js +186 -24
  391. package/dist/prompts.js +140 -42
  392. package/dist/prova-minima.js +5 -6
  393. package/dist/pulse-cadencia.js +5 -4
  394. package/dist/pulse-consentimento.js +53 -1
  395. package/dist/pulse-delivery.js +151 -24
  396. package/dist/pulse-resposta.js +368 -4
  397. package/dist/pulse.js +188 -22
  398. package/dist/ratelimit.js +16 -6
  399. package/dist/recall.js +14 -13
  400. package/dist/redacao-saida.js +63 -0
  401. package/dist/rede-adesao.js +13 -8
  402. package/dist/rede-forja.js +108 -24
  403. package/dist/rede-status.js +66 -47
  404. package/dist/rede.js +86 -46
  405. package/dist/retomada-checkpoint.js +101 -0
  406. package/dist/retry.js +451 -212
  407. package/dist/roadmap-reservas.js +45 -28
  408. package/dist/roadmap-status.js +129 -33
  409. package/dist/runtime-ambiente.js +5 -0
  410. package/dist/runtime-context.js +284 -32
  411. package/dist/runtime-escada.js +423 -0
  412. package/dist/runtime-profiles.js +103 -46
  413. package/dist/runtimes.js +2 -1
  414. package/dist/saida-segura.js +3 -2
  415. package/dist/security-scan/agil.js +355 -0
  416. package/dist/security-scan/cli.js +76 -0
  417. package/dist/security-scan/compare.js +149 -0
  418. package/dist/security-scan/config.js +93 -0
  419. package/dist/security-scan/detect.js +97 -0
  420. package/dist/security-scan/executor.js +188 -0
  421. package/dist/security-scan/guard.js +180 -0
  422. package/dist/security-scan/imagem-de-lint.js +96 -0
  423. package/dist/security-scan/normalize/actionlint.js +12 -0
  424. package/dist/security-scan/normalize/eslint.js +12 -0
  425. package/dist/security-scan/normalize/gitleaks.js +13 -0
  426. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  427. package/dist/security-scan/normalize/govulncheck.js +36 -0
  428. package/dist/security-scan/normalize/index.js +25 -0
  429. package/dist/security-scan/normalize/npm-audit.js +30 -0
  430. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  431. package/dist/security-scan/normalize/oxlint.js +51 -0
  432. package/dist/security-scan/normalize/pip-audit.js +16 -0
  433. package/dist/security-scan/normalize/ruff.js +12 -0
  434. package/dist/security-scan/normalize/semgrep.js +20 -0
  435. package/dist/security-scan/normalize/trivy.js +33 -0
  436. package/dist/security-scan/normalize/util.js +204 -0
  437. package/dist/security-scan/normalize/zizmor.js +19 -0
  438. package/dist/security-scan/report.js +156 -0
  439. package/dist/security-scan/run.js +448 -0
  440. package/dist/security-scan/tools.js +62 -0
  441. package/dist/security-scan/trabalhador.js +74 -0
  442. package/dist/security-scan/types.js +15 -0
  443. package/dist/session-events.js +26 -5
  444. package/dist/session-watcher-claude.js +81 -20
  445. package/dist/session-watcher.js +340 -42
  446. package/dist/sessoes-contas.js +10 -1
  447. package/dist/sessoes-inventario.js +1 -1
  448. package/dist/sessoes.js +25 -23
  449. package/dist/setup.js +59 -58
  450. package/dist/ship-publicar.js +971 -0
  451. package/dist/ship.js +243 -97
  452. package/dist/steal.js +77 -0
  453. package/dist/superficie.js +14 -11
  454. package/dist/thread-close.js +12 -11
  455. package/dist/thread.js +274 -100
  456. package/dist/tokens.js +15 -11
  457. package/dist/trabalho-thread.js +297 -0
  458. package/dist/transporte-do-canal.js +189 -0
  459. package/dist/types.js +12 -1
  460. package/dist/util.js +13 -3
  461. package/dist/varredura-acoes.js +507 -0
  462. package/dist/verify.js +608 -76
  463. package/dist/vida-da-thread.js +254 -0
  464. package/dist/worktree-local.js +167 -0
  465. package/dist/worktree.js +99 -83
  466. package/dist/yaml.js +27 -8
  467. package/eval/casos/check-quality.json +77 -0
  468. package/eval/casos/security-auditor.json +148 -0
  469. package/eval/casos/security-remediation.json +161 -0
  470. package/eval/fixtures/security-scan/README.md +8 -0
  471. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  472. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  473. package/eval/fixtures/security-scan/go/README.md +4 -0
  474. package/eval/fixtures/security-scan/go/config.go +4 -0
  475. package/eval/fixtures/security-scan/go/go.mod +5 -0
  476. package/eval/fixtures/security-scan/go/go.sum +2 -0
  477. package/eval/fixtures/security-scan/go/main.go +31 -0
  478. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  479. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  480. package/eval/fixtures/security-scan/js/README.md +4 -0
  481. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  482. package/eval/fixtures/security-scan/js/package.json +10 -0
  483. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  484. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  485. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  486. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  487. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  488. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  489. package/eval/fixtures/security-scan/python/README.md +4 -0
  490. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  491. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  492. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  493. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  494. package/package.json +9 -4
  495. package/references/security-checklist.md +3 -3
  496. package/schemas/code-artifact-graph.v1.schema.json +2 -1
  497. package/skills/README.md +1 -0
  498. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  499. package/skills/phases/check-quality/SKILL.md +16 -0
  500. package/skills/phases/go-implementation/SKILL.md +6 -0
  501. package/skills/phases/security-remediation/SKILL.md +70 -0
  502. package/skills/reviewers/security-auditor/SKILL.md +25 -0
@@ -29,6 +29,7 @@ exports.motivoDoPedido = motivoDoPedido;
29
29
  /** D1: contrato de pedido, independente do host. Expiração nunca autoriza. */
30
30
  const modos_1 = require("./modos");
31
31
  const types_1 = require("./types");
32
+ const locale_1 = require("./locale");
32
33
  exports.CONTRATO_HITL = 'ork.hitl/v1';
33
34
  /**
34
35
  * D5: a lista FECHADA de atos que nao se desfazem. Ela mora no nucleo, congelada, e nao no
@@ -216,7 +217,7 @@ function validarComumV2(v) {
216
217
  if (!identificador(v.id) || !identificador(v.thread) || !types_1.FASES.includes(v.fase) ||
217
218
  !modos_1.MODOS_LEGADOS.includes(v.modo) || !iso(v.criadoEm) ||
218
219
  !['resumo', 'detalhada', 'profunda'].includes(v.profundidade)) {
219
- throw new Error('pedido HITL v2: identificação, modo, instante ou profundidade inválidos');
220
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoComumInvalido);
220
221
  }
221
222
  }
222
223
  /**
@@ -225,14 +226,15 @@ function validarComumV2(v) {
225
226
  * mandou os tres campos nao tinha como saber que o problema era o tamanho.
226
227
  */
227
228
  function problemaDaLinha(campo, v, teto) {
229
+ const m = (0, locale_1.msg)().decisao;
228
230
  if (typeof v !== 'string' || !v.trim())
229
- return { ausente: true, texto: `falta ${campo}` };
231
+ return { ausente: true, texto: m.linhaFalta(campo) };
230
232
  if (/[\r\n]/.test(v))
231
- return { ausente: false, texto: `${campo} tem quebra de linha; cada campo é uma linha só` };
233
+ return { ausente: false, texto: m.linhaQuebrada(campo) };
232
234
  if (/[\x00-\x08\x0b-\x1f\x7f]/.test(v))
233
- return { ausente: false, texto: `${campo} tem caractere de controle` };
235
+ return { ausente: false, texto: m.linhaControle(campo) };
234
236
  if (v.length > teto)
235
- return { ausente: false, texto: `${campo} tem ${v.length} caracteres; o teto é ${teto}` };
237
+ return { ausente: false, texto: m.linhaLonga(campo, v.length, teto) };
236
238
  return null;
237
239
  }
238
240
  /**
@@ -249,121 +251,121 @@ exports.CAMPOS_DA_DECISAO_NO_MCP = Object.freeze({
249
251
  });
250
252
  /** Troca o nome interno do campo, onde a recusa o cita, pelo nome da superficie. */
251
253
  function recusaNaSuperficie(mensagem, nomes) {
252
- return mensagem.replace(/(falta |: )(decidido|porque|comoMudar|custoDeReverter\.agora|custoDeReverter\.depois|criterio\.referencia)(?=\)| tem )/g, (_, antes, campo) => `${antes}${nomes[campo] ?? campo}`);
254
+ return mensagem.replace(/(falta |missing |: )(decidido|porque|comoMudar|custoDeReverter\.agora|custoDeReverter\.depois|criterio\.referencia)(?=\)| tem | has )/g, (_, antes, campo) => `${antes}${nomes[campo] ?? campo}`);
253
255
  }
254
256
  function validarDecidido(v) {
255
257
  for (const campo of exports.CAMPOS_DE_GATE) {
256
258
  if (v[campo] !== undefined)
257
- throw new Error(`pedido HITL v2: decisão informada não pode trazer ${campo}`);
259
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCampoDeGate(campo));
258
260
  }
259
261
  for (const campo of ['decidido', 'porque', 'comoMudar']) {
260
262
  const problema = problemaDaLinha(campo, v[campo], exports.TETOS_HITL_V2.campoDaDecisao);
261
263
  if (problema?.ausente)
262
- throw new Error(`pedido HITL v2: decisão informada exige o que foi decidido, o porquê e como mudar (${problema.texto})`);
264
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCamposObrigatorios(problema.texto));
263
265
  if (problema)
264
- throw new Error(`pedido HITL v2: decisão informada: ${problema.texto}`);
266
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCampoInvalido(problema.texto));
265
267
  }
266
268
  const custo = v.custoDeReverter;
267
269
  const problemasDoCusto = ['agora', 'depois']
268
270
  .map(lado => problemaDaLinha(`custoDeReverter.${lado}`, objeto(custo) ? custo[lado] : undefined, exports.TETOS_HITL_V2.custo));
269
271
  if (problemasDoCusto.some(p => p?.ausente)) {
270
- throw new Error('pedido HITL v2: custo de reverter exige agora e depois, os dois presentes');
272
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCustoObrigatorio);
271
273
  }
272
274
  const doCusto = problemasDoCusto.find(p => p !== null);
273
275
  if (doCusto)
274
- throw new Error(`pedido HITL v2: custo de reverter: ${doCusto.texto}`);
276
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCustoInvalido(doCusto.texto));
275
277
  const criterio = v.criterio;
276
278
  const daReferencia = objeto(criterio) ? problemaDaLinha('criterio.referencia', criterio.referencia, 300) : null;
277
279
  if (!objeto(criterio) || !['manifesto', 'ledger', 'medicao'].includes(criterio.tipo) || daReferencia?.ausente) {
278
- throw new Error('pedido HITL v2: decisão informada exige critério citado e resolvível');
280
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCriterioObrigatorio);
279
281
  }
280
282
  if (daReferencia)
281
- throw new Error(`pedido HITL v2: critério: ${daReferencia.texto}`);
283
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCriterioInvalido(daReferencia.texto));
282
284
  // R1, porta fechada: ato irreversivel nunca se qualifica como decisao informada.
283
285
  if (v.irreversivel === true)
284
- throw new Error('pedido HITL v2: ato irreversível nunca é decisão informada');
286
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivel);
285
287
  }
286
288
  function validarAlternativas(v) {
287
289
  const alternativas = v.alternativas;
288
290
  if (!Array.isArray(alternativas) || alternativas.length < 2 || alternativas.length > exports.LETRAS_DE_ALTERNATIVA.length) {
289
- throw new Error('pedido HITL v2: de 2 a 5 alternativas, rotuladas de a a e');
291
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativas);
290
292
  }
291
293
  let recomendadas = 0;
292
294
  alternativas.forEach((bruta, i) => {
293
295
  if (!objeto(bruta) || bruta.letra !== exports.LETRAS_DE_ALTERNATIVA[i]) {
294
- throw new Error('pedido HITL v2: de 2 a 5 alternativas, rotuladas de a a e');
296
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativas);
295
297
  }
296
298
  if (!linhaUnica(bruta.texto, exports.TETOS_HITL_V2.alternativaTexto))
297
- throw new Error('pedido HITL v2: alternativa sem texto');
299
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemTexto);
298
300
  if (!['aprovar', 'recusar', 'responder', 'esperar'].includes(bruta.acao)) {
299
- throw new Error('pedido HITL v2: alternativa sem ação explícita');
301
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemAcao);
300
302
  }
301
303
  if (!linhaUnica(bruta.consequencia, exports.TETOS_HITL_V2.consequencia)) {
302
- throw new Error('pedido HITL v2: alternativa sem consequência em uma linha');
304
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemConsequencia);
303
305
  }
304
306
  if (bruta.recomendada === undefined) {
305
307
  if (bruta.porque !== undefined)
306
- throw new Error('pedido HITL v2: só a alternativa recomendada diz o porquê');
308
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPorqueSoRecomendada);
307
309
  return;
308
310
  }
309
311
  if (bruta.recomendada !== true)
310
- throw new Error('pedido HITL v2: recomendada só aceita true ou ausência');
312
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRecomendadaBoolean);
311
313
  if (!linhaUnica(bruta.porque, exports.TETOS_HITL_V2.porque)) {
312
- throw new Error('pedido HITL v2: a alternativa recomendada precisa dizer o porquê em uma linha');
314
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRecomendadaSemPorque);
313
315
  }
314
316
  recomendadas++;
315
317
  });
316
318
  if (recomendadas !== 1)
317
- throw new Error('pedido HITL v2: exatamente uma alternativa é recomendada');
319
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoUmaRecomendada);
318
320
  }
319
321
  function validarPergunta(v) {
320
322
  if (!linhaUnica(v.pergunta, exports.TETOS_HITL_V2.pergunta)) {
321
- throw new Error('pedido HITL v2: a pergunta é uma frase, sem quebra de linha');
323
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPerguntaFrase);
322
324
  }
323
325
  if (!texto(v.motivo, 100))
324
- throw new Error('pedido HITL v2: motivo inválido');
326
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoMotivoInvalido);
325
327
  validarAlternativas(v);
326
328
  if (!Array.isArray(v.corpo) || v.corpo.length > exports.TETOS_HITL_V2.corpoLinhas ||
327
329
  v.corpo.some(l => !linhaUnica(l, exports.TETOS_HITL_V2.corpoLinha))) {
328
- throw new Error('pedido HITL v2: o corpo é lista de linhas, nunca prosa corrida');
330
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCorpoLinhas);
329
331
  }
330
332
  if (!['objetiva', 'aberta'].includes(v.tipoDeResposta))
331
- throw new Error('pedido HITL v2: tipo de resposta inválido');
333
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoTipoRespostaInvalido);
332
334
  if (!/^[0-9A-Za-z]{3,8}$/.test(String(v.codigo ?? '')))
333
- throw new Error('pedido HITL v2: código curto inválido');
335
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCodigoInvalido);
334
336
  const alvo = v.alvo;
335
337
  if (!objeto(alvo) || !(alvo.tipo === 'gate' && texto(alvo.sobre, 100) ||
336
338
  alvo.tipo === 'session' && identificador(alvo.sessionId) && ['claude-bg', 'codex'].includes(alvo.runtime))) {
337
- throw new Error('pedido HITL v2: alvo inválido');
339
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlvoInvalido);
338
340
  }
339
341
  const aceita = v.respostaAceita;
340
342
  if (!objeto(aceita) || !['opcao', 'texto'].includes(aceita.tipo) ||
341
343
  !Number.isInteger(aceita.maxCaracteres) || Number(aceita.maxCaracteres) < 1 || Number(aceita.maxCaracteres) > 4096) {
342
- throw new Error('pedido HITL v2: resposta aceita inválida');
344
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRespostaInvalida);
343
345
  }
344
346
  if (!iso(v.prazo) || Date.parse(v.prazo) <= Date.parse(v.criadoEm) ||
345
347
  !['esperar', 'escalar', 'seguir-recomendada'].includes(v.acaoPadraoAoExpirar)) {
346
- throw new Error('pedido HITL v2: prazo ou ação de expiração inválidos');
348
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPrazoInvalido);
347
349
  }
348
350
  if (v.dependenciaTecnica !== undefined) {
349
351
  const d = v.dependenciaTecnica;
350
352
  if (!objeto(d) || !linhaUnica(d.comando, exports.TETOS_HITL_V2.campoDaDecisao) || !linhaUnica(d.porque, exports.TETOS_HITL_V2.porque)) {
351
- throw new Error('pedido HITL v2: dependência técnica exige o comando exato e o porquê, uma linha cada');
353
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoDependenciaInvalida);
352
354
  }
353
355
  }
354
356
  if (typeof v.irreversivel !== 'boolean')
355
- throw new Error('pedido HITL v2: irreversível precisa ser declarado');
357
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivelAusente);
356
358
  if (v.irreversivel) {
357
359
  if (!exports.ATOS_IRREVERSIVEIS.includes(String(v.ato))) {
358
- throw new Error('pedido HITL v2: ato irreversível precisa nomear um da lista congelada');
360
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAtoIrreversivelInvalido);
359
361
  }
360
362
  // D5, primeira das quatro barreiras: a combinacao nao chega a existir.
361
363
  if (v.acaoPadraoAoExpirar === 'seguir-recomendada') {
362
- throw new Error('pedido HITL v2: ato irreversível nunca avança por expiração');
364
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivelExpira);
363
365
  }
364
366
  }
365
367
  else if (v.ato !== undefined) {
366
- throw new Error('pedido HITL v2: só pedido irreversível nomeia ato');
368
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAtoSoIrreversivel);
367
369
  }
368
370
  }
369
371
  // ---------------------------------------------------------------------------
@@ -396,33 +398,33 @@ exports.SelecaoRecusada = SelecaoRecusada;
396
398
  */
397
399
  function exigirSelecaoDeConducao(pedido) {
398
400
  if (!ehV2(pedido)) {
399
- throw new SelecaoRecusada('hitl.selecao.versao', 'o pedido de condução do ork sai em ork.hitl/v2, com alternativas declaradas');
401
+ throw new SelecaoRecusada('hitl.selecao.versao', (0, locale_1.msg)().decisao.selecaoVersao);
400
402
  }
401
403
  if (pedido.classe === 'decidido')
402
404
  return;
403
405
  const n = pedido.alternativas.length;
404
406
  if (n < exports.MINIMO_DE_ALTERNATIVAS_DE_CONDUCAO || n > exports.MAXIMO_DE_ALTERNATIVAS_DE_CONDUCAO) {
405
- throw new SelecaoRecusada('hitl.selecao.fora-da-faixa', `de ${exports.MINIMO_DE_ALTERNATIVAS_DE_CONDUCAO} a ${exports.MAXIMO_DE_ALTERNATIVAS_DE_CONDUCAO} alternativas, este traz ${n}`);
407
+ throw new SelecaoRecusada('hitl.selecao.fora-da-faixa', (0, locale_1.msg)().decisao.selecaoFaixa(exports.MINIMO_DE_ALTERNATIVAS_DE_CONDUCAO, exports.MAXIMO_DE_ALTERNATIVAS_DE_CONDUCAO, n));
406
408
  }
407
409
  const recomendadas = pedido.alternativas.filter(a => a.recomendada).length;
408
410
  if (recomendadas !== 1) {
409
- throw new SelecaoRecusada('hitl.selecao.recomendada', `exatamente uma alternativa com o selo Recomendação, este traz ${recomendadas}`);
411
+ throw new SelecaoRecusada('hitl.selecao.recomendada', (0, locale_1.msg)().decisao.selecaoRecomendada(recomendadas));
410
412
  }
411
413
  const pedeTexto = pedido.tipoDeResposta === 'aberta' || pedido.respostaAceita.tipo === 'texto';
412
414
  if (pedeTexto && !pedido.dependenciaTecnica) {
413
- throw new SelecaoRecusada('hitl.selecao.texto-livre', 'resposta em texto só com dependência técnica tipada: o comando exato que o dono roda no terminal e o porquê');
415
+ throw new SelecaoRecusada('hitl.selecao.texto-livre', (0, locale_1.msg)().decisao.selecaoTextoLivre);
414
416
  }
415
417
  }
416
418
  /** Valida `ork.hitl/v2`. Nunca aceita um v1: quem julga v1 e o validador congelado. */
417
419
  function validarPedidoHitlV2(v) {
418
420
  if (!objeto(v) || v.contrato !== exports.CONTRATO_HITL_V2)
419
- throw new Error('pedido HITL v2: contrato inválido');
421
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoDesconhecido);
420
422
  validarComumV2(v);
421
423
  if (v.classe === 'decidido')
422
424
  return validarDecidido(v);
423
425
  if (v.classe === 'pergunta')
424
426
  return validarPergunta(v);
425
- throw new Error('pedido HITL v2: classe precisa ser decidido ou pergunta');
427
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoClasseInvalida);
426
428
  }
427
429
  /**
428
430
  * O leitor das duas versoes. Despacha por contrato: v1 pelo validador congelado, v2 pelo novo.
@@ -473,7 +475,8 @@ function classificarDecisao(sinais) {
473
475
  * `hitl.formato` para tudo tornaria o motivo tao generico quanto a string que ele substitui.
474
476
  */
475
477
  function motivoDaRecusaDeFormato(erro) {
476
- const mensagem = erro instanceof Error ? erro.message : String(erro);
478
+ // RM-061 F3c: a recusa do catalogo e classificada pelo texto pt-BR, a fonte, em qualquer lingua de quem a leu.
479
+ const mensagem = erro instanceof locale_1.ErroDoCatalogo ? erro.montar((0, locale_1.msg)('pt-BR')) : erro instanceof Error ? erro.message : String(erro);
477
480
  return mensagem.startsWith('pedido HITL v2: ') && !mensagem.includes('contrato inválido')
478
481
  ? 'hitl.formato' : null;
479
482
  }
@@ -36,6 +36,7 @@ exports.desdeDoPedido = desdeDoPedido;
36
36
  const hitl_1 = require("./hitl");
37
37
  const hitl_contract_1 = require("./hitl-contract");
38
38
  const horario_1 = require("./horario");
39
+ const locale_1 = require("./locale");
39
40
  exports.CONTRATO_PEDIDO_CURTO = 'ork.hitl-curto/v1';
40
41
  /** RM-057: o selo que o dono procura na lista, igual em todo canal. */
41
42
  exports.SELO_DA_RECOMENDADA = 'Recomendação';
@@ -60,7 +61,7 @@ const linha = (texto, teto = TETO_DA_LINHA) => {
60
61
  function entradaDoPedido(pedido, desde) {
61
62
  (0, hitl_contract_1.validarPedidoHitl)(pedido);
62
63
  if (!(0, hitl_contract_1.ehV2)(pedido) || pedido.classe !== 'pergunta') {
63
- throw new Error('pedido curto: só uma pergunta ork.hitl/v2 tem alternativas declaradas');
64
+ throw new Error((0, locale_1.msg)().decisao.curto.soPergunta);
64
65
  }
65
66
  const alvo = (0, hitl_contract_1.alvoDoPedido)(pedido);
66
67
  return {
@@ -74,32 +75,34 @@ function entradaDoPedido(pedido, desde) {
74
75
  }
75
76
  /** O que acontece sem resposta, em meia linha. Expirar nunca autoriza. */
76
77
  function semResposta(e, agora) {
77
- const ate = e.prazo ? ` até ${(0, horario_1.formatarHora)(e.prazo, { agora })}` : '';
78
+ const m = (0, locale_1.msg)().decisao.curto;
79
+ const ate = e.prazo ? m.ate((0, horario_1.formatarHora)(e.prazo, { agora })) : '';
78
80
  if (e.expiracao === 'seguir-recomendada')
79
- return `Sem resposta${ate}, sigo com a recomendada.`;
81
+ return m.semRespostaRecomendada(ate);
80
82
  if (e.expiracao === 'escalar')
81
- return `Sem resposta${ate}, o pedido é escalado.`;
82
- return e.alvo?.tipo === 'session' ? 'Sem resposta, a sessão continua parada.' : 'Sem resposta, nada avança.';
83
+ return m.semRespostaEscala(ate);
84
+ return e.alvo?.tipo === 'session' ? m.semRespostaSessao : m.semRespostaGate;
83
85
  }
84
86
  /**
85
87
  * Monta o pedido curto. Recusa, em vez de cortar em silencio, o que o contrato nao aceita: menos
86
88
  * de duas alternativas, mais de cinco, ou recomendada diferente de exatamente uma.
87
89
  */
88
90
  function montarPedidoCurto(e, opcoes) {
91
+ const m = (0, locale_1.msg)().decisao.curto;
89
92
  if (e.alternativas.length < 2 || e.alternativas.length > 5)
90
- throw new Error('pedido curto: de 2 a 5 alternativas');
93
+ throw new Error(m.alternativas);
91
94
  if (e.alternativas.filter(a => a.recomendada).length !== 1)
92
- throw new Error('pedido curto: exatamente uma alternativa é recomendada');
95
+ throw new Error(m.umaRecomendada);
93
96
  const onde = e.alvo?.tipo === 'session'
94
- ? `A sessão ${e.alvo.sessionId.slice(0, 8)} está parada esperando você`
95
- : `${e.fase ? `A fase ${e.fase}` : 'A thread'} está parada esperando você`;
96
- const desde = e.desde ? ` desde ${(0, horario_1.formatarDesde)(e.desde, { agora: opcoes.quando })}` : '';
97
+ ? m.sessaoParada(e.alvo.sessionId.slice(0, 8))
98
+ : m.faseParada(e.fase);
99
+ const desde = e.desde ? m.desde((0, horario_1.formatarDesde)(e.desde, { agora: opcoes.quando })) : '';
97
100
  return {
98
101
  contrato: exports.CONTRATO_PEDIDO_CURTO,
99
- titulo: linha([e.thread, e.fase].filter(Boolean).join(' · ') || 'sem thread'),
102
+ titulo: linha(e.titulo ?? ([e.thread, e.fase].filter(Boolean).join(' · ') || m.semThread)),
100
103
  pergunta: linha(e.pergunta),
101
- trava: linha(`${onde}${desde}. ${semResposta(e, opcoes.quando)}`),
102
- ...(e.ato ? { semVolta: `Sem volta depois de feito: ${exports.TEXTO_DO_ATO[e.ato]}.` } : {}),
104
+ trava: linha(e.trava ?? `${onde}${desde}. ${semResposta(e, opcoes.quando)}`),
105
+ ...(e.ato ? { semVolta: m.semVolta(m.atos[e.ato]) } : {}),
103
106
  corpo: (e.corpo ?? []).slice(0, exports.TETO_DE_LINHAS_DO_CORPO).map(l => linha(l)).filter(Boolean),
104
107
  alternativas: e.alternativas.map(a => ({ chave: a.chave, texto: linha(a.texto, 140), consequencia: linha(a.consequencia, 140),
105
108
  ...(a.recomendada ? { recomendada: { porque: linha(a.recomendada.porque, 140) } } : {}) })),
@@ -109,43 +112,52 @@ function montarPedidoCurto(e, opcoes) {
109
112
  /** A ultima linha: exatamente o que digitar, sem identificador longo. */
110
113
  function linhaDeResposta(p, canal) {
111
114
  const r = p.responder, recomendada = p.alternativas.find(a => a.recomendada).chave;
115
+ const m = (0, locale_1.msg)().decisao.curto;
112
116
  if (r.tipo === 'numero')
113
117
  return null;
114
118
  if (r.tipo === 'texto')
115
- return `${canal === 'telegram' ? '↩️ ' : ''}Responda escrevendo o texto; ele é enviado como está.`;
119
+ return `${canal === 'telegram' ? '↩️ ' : ''}${m.respostaTexto}`;
116
120
  if (r.tipo === 'terminal')
117
- return `${canal === 'telegram' ? '↩️ ' : 'Responder: '}feito o comando, ${recomendada}) é \`${r.comando}\`.`;
121
+ return `${canal === 'telegram' ? '↩️ ' : `${m.responder}: `}${m.respostaTerminal(recomendada, r.comando)}`;
118
122
  if (r.tipo === 'dialogo')
119
- return `${canal === 'telegram' ? '↩️ ' : ''}Responda selecionando a opção no diálogo; digitar a letra também vale.`;
123
+ return `${canal === 'telegram' ? '↩️ ' : ''}${m.respostaDialogo}`;
124
+ if (r.tipo === 'letras') {
125
+ // RM-057: as letras reais da pergunta, nunca uma linha para copiar; o detalhe fica a um pedido de distancia.
126
+ const letras = m.listaDeLetras(p.alternativas.map(a => a.chave));
127
+ return canal === 'telegram' ? `↩️ ${m.respostaLetras(letras, r.codigo)}` : `${m.responder}: ${m.respostaLetrasHost(letras, r.codigo)}`;
128
+ }
120
129
  return canal === 'telegram'
121
- ? `↩️ Responda: ${r.codigo} ${recomendada} (ou outra letra). Evidências: ${r.codigo} detalhes.`
122
- : `Responda pelo Telegram: ${r.codigo} ${recomendada} (ou outra letra); aqui, pelo diálogo do host. Evidências: ${r.codigo} detalhes.`;
130
+ ? m.respostaTelegram(r.codigo, recomendada)
131
+ : m.respostaHost(r.codigo, recomendada);
123
132
  }
124
133
  /**
125
134
  * O texto do pedido no canal. Telegram e terminal dizem a mesma coisa com marcadores diferentes;
126
135
  * nenhum dos dois passa de `TETO_DE_LINHAS_DO_PEDIDO` linhas.
127
136
  */
128
137
  function textoDoPedidoCurto(p, canal) {
138
+ const m = (0, locale_1.msg)().decisao.curto;
129
139
  if (p.contrato !== exports.CONTRATO_PEDIDO_CURTO)
130
- throw new Error('pedido curto: contrato inválido');
140
+ throw new Error(m.contratoInvalido);
131
141
  const tg = canal === 'telegram';
132
142
  const numero = p.responder.tipo === 'numero' ? `${p.responder.numero}. ` : '';
143
+ // RM-057 (resposta curta): a pergunta servida sozinha leva o numero do lote, para "1a" tambem valer.
144
+ const servida = p.responder.tipo === 'letras' && p.responder.numero ? `${p.responder.numero}. ` : '';
133
145
  const linhas = [
134
- `${tg && !numero ? '🔔 ' : ''}${numero}${tg || numero ? '' : 'Orkastery · '}${p.titulo}`,
135
- `${tg ? '❓ ' : 'Pergunta: '}${p.pergunta}`,
136
- `${tg ? '⏳ ' : 'Situação: '}${p.trava}`,
146
+ `${tg && !numero ? '🔔 ' : ''}${numero || servida}${tg || numero ? '' : 'Orkastery · '}${p.titulo}`,
147
+ `${tg ? '❓ ' : `${m.pergunta}: `}${p.pergunta}`,
148
+ `${tg ? '⏳ ' : `${m.situacao}: `}${p.trava}`,
137
149
  ...(p.semVolta ? [`${tg ? '🔒 ' : '! '}${p.semVolta}`] : []),
138
150
  ...p.corpo.map(l => `${tg ? '• ' : '- '}${l}`),
139
151
  ...p.alternativas.flatMap(a => [
140
- `${a.chave}) ${a.texto}${a.recomendada ? (tg ? ` ✅ ${exports.SELO_DA_RECOMENDADA}` : ` [${exports.SELO_DA_RECOMENDADA}]`) : ''}: ${a.consequencia}`,
141
- ...(a.recomendada ? [` porquê: ${a.recomendada.porque}`] : []),
152
+ `${a.chave}) ${a.texto}${a.recomendada ? (tg ? ` ✅ ${m.selo}` : ` [${m.selo}]`) : ''}: ${a.consequencia}`,
153
+ ...(a.recomendada ? [` ${m.porque}: ${a.recomendada.porque}`] : []),
142
154
  ]),
143
155
  ];
144
156
  const resposta = linhaDeResposta(p, canal);
145
157
  if (resposta)
146
158
  linhas.push(resposta);
147
159
  if (linhas.length > exports.TETO_DE_LINHAS_DO_PEDIDO)
148
- throw new Error('pedido curto: acima do teto de linhas');
160
+ throw new Error(m.acimaDoTeto);
149
161
  return linhas.join('\n');
150
162
  }
151
163
  /**
@@ -78,6 +78,7 @@ const memoria_humana_1 = require("./memoria-humana");
78
78
  const hitl_canais_1 = require("./hitl-canais");
79
79
  const hitl_native_1 = require("./hitl-native");
80
80
  const modos_1 = require("./modos");
81
+ const locale_1 = require("./locale");
81
82
  /**
82
83
  * D12: o canal entra no corpo assinado, e é isso que o torna recibo em vez de rótulo.
83
84
  * Hermes e OpenClaw compartilham transporte, mas usam chaves próprias e identidades
@@ -170,8 +171,9 @@ function autenticarResposta(thread, pedido, r, quando = new Date().toISOString()
170
171
  */
171
172
  function resolverCriterio(raiz, pedido) {
172
173
  const { tipo, referencia } = pedido.criterio;
174
+ const m = (0, locale_1.msg)().decisao;
173
175
  if (tipo === 'medicao') {
174
- return { resolve: true, detalhe: 'comando citado; quem executa e reprova é o CHECK' };
176
+ return { resolve: true, detalhe: m.criterioMedicao };
175
177
  }
176
178
  if (tipo === 'manifesto') {
177
179
  let alvo;
@@ -179,19 +181,19 @@ function resolverCriterio(raiz, pedido) {
179
181
  alvo = (0, manifest_1.exigirManifesto)(raiz).manifesto;
180
182
  }
181
183
  catch {
182
- return { resolve: false, detalhe: 'manifesto do projeto não pôde ser lido' };
184
+ return { resolve: false, detalhe: m.criterioManifestoIlegivel };
183
185
  }
184
186
  for (const parte of referencia.split('.')) {
185
187
  if (!alvo || typeof alvo !== 'object' || !(parte in alvo)) {
186
- return { resolve: false, detalhe: `o manifesto não tem a chave ${referencia}` };
188
+ return { resolve: false, detalhe: m.criterioManifestoSemChave(referencia) };
187
189
  }
188
190
  alvo = alvo[parte];
189
191
  }
190
192
  const vazio = alvo === undefined || alvo === null || alvo === '' ||
191
193
  (Array.isArray(alvo) && alvo.length === 0);
192
194
  return vazio
193
- ? { resolve: false, detalhe: `a chave ${referencia} existe mas está vazia` }
194
- : { resolve: true, detalhe: `chave ${referencia} lida do manifesto` };
195
+ ? { resolve: false, detalhe: m.criterioManifestoVazio(referencia) }
196
+ : { resolve: true, detalhe: m.criterioManifestoLido(referencia) };
195
197
  }
196
198
  // `ledger`: `<thread>#evento:<n>` (1-based) ou o `eventId` do proprio evento.
197
199
  const comIndice = /^([a-zA-Z0-9][a-zA-Z0-9._-]{0,79})#evento:(\d+)$/.exec(referencia);
@@ -201,17 +203,17 @@ function resolverCriterio(raiz, pedido) {
201
203
  eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, thread));
202
204
  }
203
205
  catch {
204
- return { resolve: false, detalhe: `a thread ${thread} não tem ledger legível` };
206
+ return { resolve: false, detalhe: m.criterioLedgerIlegivel(thread) };
205
207
  }
206
208
  if (comIndice) {
207
209
  const n = Number(comIndice[2]);
208
210
  return n >= 1 && n <= eventos.length
209
- ? { resolve: true, detalhe: `evento ${n} de ${thread}` }
210
- : { resolve: false, detalhe: `${thread} não tem evento ${n}` };
211
+ ? { resolve: true, detalhe: m.criterioEvento(n, thread) }
212
+ : { resolve: false, detalhe: m.criterioEventoAusente(n, thread) };
211
213
  }
212
214
  return eventos.some(e => e.eventId === referencia)
213
- ? { resolve: true, detalhe: `evento ${referencia} de ${thread}` }
214
- : { resolve: false, detalhe: `nenhum evento de ${thread} tem esse identificador` };
215
+ ? { resolve: true, detalhe: m.criterioEvento(referencia, thread) }
216
+ : { resolve: false, detalhe: m.criterioEventoAusente(referencia, thread) };
215
217
  }
216
218
  function registrarPedidoHitl(raiz, pedido) {
217
219
  (0, hitl_contract_1.validarPedidoHitl)(pedido);
@@ -224,7 +226,7 @@ function registrarPedidoHitl(raiz, pedido) {
224
226
  if ((0, hitl_contract_1.ehV2)(pedido) && pedido.classe === 'decidido') {
225
227
  const { resolve, detalhe } = resolverCriterio(raiz, pedido);
226
228
  if (!resolve)
227
- throw new Error(`decisão informada: critério não resolve (${detalhe})`);
229
+ throw new locale_1.ErroDoCatalogo((m) => m.decisao.criterioNaoResolve(detalhe));
228
230
  }
229
231
  return comLockHitl(raiz, pedido.thread, () => {
230
232
  const t = (0, thread_1.lerThread)(raiz, pedido.thread), dir = (0, thread_1.dirThread)(raiz, t.id);
@@ -33,7 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.IDENTIDADE_DA_NOTA_NATIVA = exports.CONTRATO_RECIBO_DA_NOTA = void 0;
37
+ exports.chaveLocal = chaveLocal;
36
38
  exports.gravarEvidenciaLocal = gravarEvidenciaLocal;
39
+ exports.gravarEvidenciaLocalNota = gravarEvidenciaLocalNota;
40
+ exports.conferirReciboLocalNota = conferirReciboLocalNota;
37
41
  exports.gravarEvidenciaLocalSessao = gravarEvidenciaLocalSessao;
38
42
  exports.validarEvidenciaLocalSessao = validarEvidenciaLocalSessao;
39
43
  exports.validarEvidenciaLocal = validarEvidenciaLocal;
@@ -46,6 +50,16 @@ const thread_1 = require("./thread");
46
50
  const ledger_1 = require("./ledger");
47
51
  const hitl_contract_1 = require("./hitl-contract");
48
52
  const hitl_local_atestado_1 = require("./hitl-local-atestado");
53
+ /**
54
+ * RM-059 (T8.1, D3 e D12 da thread ork-rm059ritual): o recibo da nota do MASTER pelo dialogo nativo. Mesmo cofre e mesma
55
+ * chave do gate; guarda o hash do porque, nunca o texto (o texto vai ao MASTER log da thread).
56
+ */
57
+ exports.CONTRATO_RECIBO_DA_NOTA = 'ork.hitl-local-master-note/v1';
58
+ /**
59
+ * RM-059 (D12 da thread ork-rm059ritual): o `avaliadoPor` da nota pelo dialogo nativo. O host da conexao fica no
60
+ * `canal` e no recibo; a identidade e uma so, aceita pelo `autoriaHumana` de qualquer versao do `ork`.
61
+ */
62
+ exports.IDENTIDADE_DA_NOTA_NATIVA = 'dono (dialogo nativo)';
49
63
  const sha = (v) => (0, node_crypto_1.createHash)('sha256').update(v).digest('hex');
50
64
  const uid = () => {
51
65
  const atual = process.getuid?.();
@@ -70,6 +84,7 @@ function diretorioPrivado(file) {
70
84
  }
71
85
  return validarDiretorio(file, 0o700);
72
86
  }
87
+ /** RM-058 (N1): exportada só para o arco #Noctum derivar a subchave dele (`noctum-arco.ts`). */
73
88
  function chaveLocal(raiz, criar) {
74
89
  const estado = path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery');
75
90
  const stEstado = fs.lstatSync(estado);
@@ -220,6 +235,44 @@ function gravarEvidenciaLocal(atestado, veredito) {
220
235
  recebidoEm: atestado.recebidoEm, ...veredito };
221
236
  return gravarRecibo(atestado.raiz, atestado.thread, nomeDoRecibo(atestado), dados);
222
237
  }
238
+ /** RM-059 (T8.1): grava o recibo assinado da nota; o nome sai da conexao e da solicitacao, como no gate. */
239
+ function gravarEvidenciaLocalNota(raiz, dados) {
240
+ const completos = { contrato: exports.CONTRATO_RECIBO_DA_NOTA, ...dados };
241
+ return gravarRecibo(raiz, dados.thread, sha(JSON.stringify([dados.connectionId, dados.requestId])) + '.json', completos);
242
+ }
243
+ /**
244
+ * RM-059 (T8.1, D12): confere o recibo da nota contra a prova do `preflightMaster` (escrita: sem ele a identidade da
245
+ * nota nativa nao se grava) ou contra um `master_done` ja gravado (auditoria: a prova do caminho, que nao decide se a
246
+ * nota vale). Recibo ausente, adulterado, de outra thread, de outra conexao, de outro host ou com outra nota nao confere.
247
+ */
248
+ function conferirReciboLocalNota(raiz, thread, campos) {
249
+ try {
250
+ if (campos.por !== exports.IDENTIDADE_DA_NOTA_NATIVA || campos.origem !== 'mcp-local' ||
251
+ (campos.canal !== 'claude-code' && campos.canal !== 'codex'))
252
+ return false;
253
+ const host = campos.canal;
254
+ const pedidoId = campos.notaPedida?.pedidoId;
255
+ if (campos.contratoResposta !== exports.CONTRATO_RECIBO_DA_NOTA || typeof pedidoId !== 'string' ||
256
+ typeof campos.conexao !== 'string' || typeof campos.solicitacao !== 'string' || typeof campos.recebidoEm !== 'string' ||
257
+ !Number.isInteger(campos.score) || typeof campos.justificativa !== 'string' || typeof campos.evidencia !== 'string' ||
258
+ !/^[a-f0-9]{64}$/.test(String(campos.evidenciaSha256 ?? '')) || !/^[a-f0-9]{64}$/.test(String(campos.recibo ?? '')))
259
+ return false;
260
+ const nome = sha(JSON.stringify([campos.conexao, campos.solicitacao])) + '.json';
261
+ if (campos.evidencia !== referencia(thread, nome))
262
+ return false;
263
+ const lido = lerRecibo(raiz, thread, nome);
264
+ const esperado = { contrato: exports.CONTRATO_RECIBO_DA_NOTA, thread, pedidoId, host,
265
+ connectionId: campos.conexao, requestId: campos.solicitacao, recebidoEm: campos.recebidoEm,
266
+ score: campos.score, justificativaSha256: sha(campos.justificativa) };
267
+ const sig = assinatura(chaveLocal(raiz, false), esperado);
268
+ return JSON.stringify(lido.dados) === JSON.stringify(esperado) &&
269
+ (0, node_crypto_1.timingSafeEqual)(Buffer.from(lido.assinatura, 'hex'), Buffer.from(sig, 'hex')) &&
270
+ campos.evidenciaSha256 === sha(lido.bytes) && campos.recibo === sha(lido.assinatura);
271
+ }
272
+ catch {
273
+ return false;
274
+ }
275
+ }
223
276
  function gravarEvidenciaLocalSessao(atestado, entrega) {
224
277
  const dados = { contrato: 'ork.hitl-local-session/v1', thread: atestado.thread,
225
278
  pedidoId: atestado.pedidoId, contexto: atestado.contexto, pedidoSha256: atestado.pedidoSha256,
@@ -23,7 +23,9 @@ const idValido = (s) => typeof s === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,7
23
23
  /** O callback é fornecido pelo servidor, nunca pelos argumentos de tools/call. */
24
24
  function criarIngressoLocal(raiz, origem, elicitar,
25
25
  /** Vinculo do adapter para resposta de SESSAO, fornecido pelo servidor. E o mesmo ponto
26
- * de injecao que `responderSessao` ja tem; ausente, vale o controle nativo do runtime. */
26
+ * de injecao que `responderSessao` ja tem; ausente, vale o controle nativo do runtime.
27
+ * RM-059 (F9): a `caixa` de saida do servidor do dono, por onde a resposta a uma sessao
28
+ * `claude-bg` sai para o Mensageiro de Sessoes; sem ela, essa resposta e recusada antes do dialogo. */
27
29
  opcoes = {}) {
28
30
  if (!['claude-code', 'codex'].includes(origem.host) || !idValido(origem.connectionId))
29
31
  throw new Error('hitl.local.origem-invalida');
@@ -64,6 +66,13 @@ opcoes = {}) {
64
66
  throw new Error('hitl.local.pedido-antigo');
65
67
  if ((0, hitl_contract_1.estadoDoPedido)(pedido) !== 'aberto')
66
68
  throw new Error('hitl.local.pedido-expirado');
69
+ // RM-059 (F9, D4): a resposta que nao vai sair (sessao claude-bg sem Mensageiro vivo) recusa antes do dialogo,
70
+ // para o dono nao digitar uma resposta que ficaria sem quem a leve. Com o envio ja reservado, vale a recusa de
71
+ // sempre (`hitl.channel.delivery-uncertain`), logo abaixo.
72
+ const emEnvio = eventos.some(e => e.tipo === 'session_answer_sending' && e.pedidoId === pedidoId);
73
+ const impedimento = alvo === 'session' && !emEnvio ? (0, hitl_sessions_1.impedimentoDaEntrega)(raiz, threadId, pedido, opcoes.controle, opcoes.caixa) : null;
74
+ if (impedimento)
75
+ throw new Error(impedimento);
67
76
  const pedidoSha256 = (0, hitl_local_atestado_1.hashPedidoLocal)(pedido), requestId = (0, node_crypto_1.randomUUID)(), controller = new AbortController();
68
77
  let liberarReserva;
69
78
  (0, hitl_gates_1.comLockHitl)(raiz, threadId, () => {
@@ -117,7 +126,7 @@ opcoes = {}) {
117
126
  try {
118
127
  return alvo === 'gate'
119
128
  ? (0, hitl_gates_1.responderGateLocal)(raiz, threadId, pedidoId, token)
120
- : (0, hitl_sessions_1.responderSessaoLocal)(raiz, threadId, pedidoId, token, opcoes.controle);
129
+ : (0, hitl_sessions_1.responderSessaoLocal)(raiz, threadId, pedidoId, token, opcoes.controle, opcoes.caixa);
121
130
  }
122
131
  finally {
123
132
  (0, hitl_local_atestado_1.descartarAtestadoLocal)(token);
package/dist/hitl-lock.js CHANGED
@@ -85,16 +85,10 @@ function comLockInspecionavel(dir, operacao, executar) {
85
85
  throw new Error('runtime.unavailable: lock HITL exige flock Linux');
86
86
  // Mesmo inode/nome do protocolo legado: writer wx antigo também recusa enquanto existir.
87
87
  const file = path.join(dir, '.hitl.lock');
88
- let fd, criado = false;
89
- try {
90
- fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_NOFOLLOW, 0o600);
91
- criado = true;
92
- }
93
- catch (e) {
94
- if (e.code !== 'EEXIST')
95
- throw e;
96
- fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_NOFOLLOW);
97
- }
88
+ // `O_EXCL` abria uma janela no primeiro uso: o criador já tinha publicado o inode, mas ainda não o havia travado
89
+ // nem inicializado; um concorrente podia abrir o arquivo vazio e classificá-lo como legado. Todos abrem o mesmo
90
+ // inode e só interpretam os bytes depois do `flock`, que serializa criação, recuperação e uso normal.
91
+ const fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_CREAT | fs.constants.O_NOFOLLOW, 0o600);
98
92
  try {
99
93
  const st = fs.fstatSync(fd);
100
94
  if (!st.isFile() || st.uid !== process.getuid?.() || st.mode & 0o077 || st.nlink !== 1)
@@ -108,7 +102,7 @@ function comLockInspecionavel(dir, operacao, executar) {
108
102
  throw new Error('HITL lock mudou durante aquisição');
109
103
  let anterior = null;
110
104
  const raw = fs.readFileSync(fd, 'utf8');
111
- if (!criado) {
105
+ if (raw !== '') {
112
106
  let v;
113
107
  try {
114
108
  v = JSON.parse(raw);
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ENV_HITL_VERIFIERS = void 0;
37
37
  exports.publicHitlVerifiers = publicHitlVerifiers;
38
+ exports.canVerifyPublicReceipt = canVerifyPublicReceipt;
38
39
  exports.publicReceiptAuthority = publicReceiptAuthority;
39
40
  exports.publicBindingMatches = publicBindingMatches;
40
41
  exports.signPublicReceipt = signPublicReceipt;
@@ -108,6 +109,16 @@ function publicHitlVerifiers(env = process.env) {
108
109
  }
109
110
  return Object.keys(verifiers).length ? JSON.stringify({ schema: 'ork.hitl-verifiers/v1', verifiers }) : undefined;
110
111
  }
112
+ /** O processo consegue reconferir este slot com a chave local ou com o material público herdado, sem expor nenhum dos dois. */
113
+ function canVerifyPublicReceipt(canal, native, env = process.env) {
114
+ try {
115
+ const bundle = publicHitlVerifiers(env);
116
+ return !!bundleSchema.parse(JSON.parse(bundle ?? '{}')).verifiers[slotFor(canal, native)];
117
+ }
118
+ catch {
119
+ return false;
120
+ }
121
+ }
111
122
  function publicReceiptAuthority(canal, native) {
112
123
  return inherited(process.env)[slotFor(canal, native)];
113
124
  }