@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
@@ -0,0 +1,639 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.passageira = exports.PAUSA_DEPOIS_DA_RECUSA_MS = void 0;
37
+ exports.recusasSeguidas = recusasSeguidas;
38
+ exports.passoConduzido = passoConduzido;
39
+ exports.vigiarArco = vigiarArco;
40
+ exports.conduzirArco = conduzirArco;
41
+ /**
42
+ * RM-058, fatia N4 (D3 a D6, D15 e D19 da ork-rm058n4): o condutor e o vigia do arco, numa máquina.
43
+ *
44
+ * O condutor (`conduzirArco`) é o laço que chama o passo do arco na cadência que a fila pede; o vigia (`vigiarArco`) é um
45
+ * tique, chamado a cada 5 min (D3 do dono) por quem liga o modo (cron, serviço ou o transporte), independente do condutor
46
+ * e do runtime que ele observa: lê só o disco, o kernel e a listagem do runtime, e nunca espera nenhum deles (a baseline
47
+ * que um despacho pede nunca roda dentro do tique: ela fica para o condutor).
48
+ *
49
+ * A prova de vida é a trava do kernel (D3): o condutor segura `condutor.lock` pela vida inteira, e o vigia segura
50
+ * `vigia.lock` durante o tique. Trava livre prova que o dono anterior não existe mais. Com a trava do condutor livre, o
51
+ * vigia assume a condução (D5): grava a geração dele, lida sob a trava do log, com essa prova, e dá um passo por tique; o
52
+ * condutor que volta toma uma geração nova, e o que perdeu a geração sai sem despachar (D4). Sem tique do vigia dentro do
53
+ * limite, o condutor não despacha nada novo (D6); o tique que ficou aberto quando o vigia morreu é registrado pelo
54
+ * seguinte, e tiques interrompidos em série no limite param o arco.
55
+ *
56
+ * A reconciliação das reservas e das sessões roda com a trava de despacho na mão (nenhum passo no meio), e a listagem do
57
+ * runtime é lida sob ela, com o instante da leitura: a sessão despachada depois não morre por ausência (B3 do CHECK). Toda
58
+ * recuperação passa pelo passo da N2 (D8): o vigia reconcilia (`noctum-reconciliacao.ts`) e autoriza; o passo despacha
59
+ * com a trava de despacho, a conferência do envelope sob o lock do arco, a reserva e a capacidade. Com o arco revogado,
60
+ * expirado ou parado, o vigia só fecha a contabilidade do que estava em voo: não para sessão nem autoriza retomada. Nenhuma
61
+ * linha nova vai ao log do arco além do desfecho das reservas: o envelope não é renovado, emendado nem prorrogado por nada
62
+ * aqui, e o despacho só sai por conta do envelope (D13 e D14).
63
+ *
64
+ * Nada aqui liga o modo (D19): nenhum comando, ferramenta ou gateway chama o vigia ou o condutor nesta fatia. RM-058,
65
+ * integração (ork-rm058integra): o tique do arco chama o vigia (D7), o `ork noctum conduzir` roda o condutor (D9), e o passo
66
+ * supervisionado chama a entrega da N5 depois do despacho, sob a mesma geração (D8); no tique do vigia, nada espera a fila
67
+ * pesada, e o verify do SHA e o da atualização ficam para o condutor.
68
+ */
69
+ const fs = __importStar(require("node:fs"));
70
+ const path = __importStar(require("node:path"));
71
+ const node_crypto_1 = require("node:crypto");
72
+ const fila_pesada_1 = require("./fila-pesada");
73
+ const horario_1 = require("./horario");
74
+ const ledger_1 = require("./ledger");
75
+ const maquina_1 = require("./maquina");
76
+ const noctum_arco_1 = require("./noctum-arco");
77
+ const noctum_envelope_1 = require("./noctum-envelope");
78
+ const noctum_execucao_1 = require("./noctum-execucao");
79
+ const noctum_entrega_1 = require("./noctum-entrega");
80
+ const noctum_reconciliacao_1 = require("./noctum-reconciliacao");
81
+ const noctum_supervisao_1 = require("./noctum-supervisao");
82
+ const estado_thread_1 = require("./estado-thread");
83
+ const retry_1 = require("./retry");
84
+ const claude_bg_1 = require("./adapters/claude-bg");
85
+ const runtime_profiles_1 = require("./runtime-profiles");
86
+ const sessoes_contas_1 = require("./sessoes-contas");
87
+ const noctum_sessoes_em_voo_1 = require("./noctum-sessoes-em-voo");
88
+ const thread_1 = require("./thread");
89
+ const util_1 = require("./util");
90
+ const ARQUIVO_DO_CONDUTOR = 'condutor.lock';
91
+ const ID_DE_SESSAO = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i;
92
+ const ARQUIVO_DO_VIGIA = 'vigia.lock';
93
+ function quemSou(papel, opcoes) {
94
+ return { papel, instancia: opcoes.instancia ?? (0, node_crypto_1.randomUUID)(), pid: process.pid, maquina: (0, maquina_1.nomeDaMaquina)(opcoes.maquina) };
95
+ }
96
+ /** A leitura padrão do runtime: todas as contas, com as paradas, e o prazo da RM-063 por conta. */
97
+ function runtimePadrao(raiz, staleMin) {
98
+ return () => (0, sessoes_contas_1.consultarContas)(raiz, { todas: true, staleMin, prazoMs: 30_000 });
99
+ }
100
+ function storePadrao(raiz) {
101
+ return () => { try {
102
+ return (0, runtime_profiles_1.lerPerfisComContas)(raiz);
103
+ }
104
+ catch {
105
+ return null;
106
+ } };
107
+ }
108
+ /**
109
+ * A parada padrão (D12): `claude stop` com o ambiente do perfil da sessão, sem shell e com prazo. O codex só para pelo
110
+ * controller vinculado, que o vigia não infere: sem ele, a parada não é confirmada e o trabalho segue para o teto.
111
+ */
112
+ function pararPadrao(raiz) {
113
+ return (s) => {
114
+ if (s.runtime !== 'claude-bg')
115
+ return { ok: false, detalhe: `o vigia só para sessão claude-bg; ${s.runtime} exige o controller vinculado` };
116
+ // O id vem do ledger: só um UUID vai à linha de comando do runtime.
117
+ if (!ID_DE_SESSAO.test(s.sessionId))
118
+ return { ok: false, detalhe: 'id de sessão fora do formato: nada foi parado' };
119
+ try {
120
+ const p = s.perfil ? (0, runtime_profiles_1.lerPerfis)(raiz).perfis.find(x => x.id === s.perfil) : undefined;
121
+ if (s.perfil && !p)
122
+ return { ok: false, detalhe: `o perfil ${s.perfil} não está no store` };
123
+ const r = (0, util_1.exec)('claude', ['stop', s.sessionId], undefined, 15_000, (0, claude_bg_1.ambienteDoPerfil)(p ? (0, runtime_profiles_1.perfilDeDespacho)(p) : null));
124
+ return { ok: r.ok, detalhe: r.ok ? 'claude stop aceito' : `claude stop saiu ${r.code}` };
125
+ }
126
+ catch (e) {
127
+ return { ok: false, detalhe: e.message.slice(0, 160) };
128
+ }
129
+ };
130
+ }
131
+ /**
132
+ * B1 do CHECK: as retomadas autorizadas que nenhuma reserva do arco atendeu ainda, a mais nova de cada trabalho; a fila
133
+ * as trata como despacháveis na fase delas.
134
+ */
135
+ function decisoesDaSupervisao(sup, estado) {
136
+ const retomadas = new Map();
137
+ for (const trabalho of new Set(sup.retomadas.map(r => r.trabalho))) {
138
+ const r = estado ? (0, noctum_reconciliacao_1.retomadaPendente)(sup, estado, trabalho) : null;
139
+ if (r)
140
+ retomadas.set(trabalho, { fase: r.fase, tentativa: r.tentativa, motivo: r.motivo });
141
+ }
142
+ return { isolados: new Map([...sup.isolados].map(([t, i]) => [t, `${i.motivo}: ${i.detalhe}`])), retomadas };
143
+ }
144
+ const v2 = (estado) => estado?.conteudo && (0, noctum_envelope_1.envelopeComTrabalhos)(estado.conteudo) ? estado.conteudo : null;
145
+ /** Depois de uma recusa, o condutor não volta na hora ao mesmo candidato (B4 do CHECK). */
146
+ exports.PAUSA_DEPOIS_DA_RECUSA_MS = 60_000;
147
+ /**
148
+ * As recusas do núcleo que dependem da conta, da vaga, da condução ou da baseline, a do orçamento esgotado na reserva do
149
+ * arco, e as que o próprio vigia gravou: passam, e não contam para isolar o trabalho. As outras (a árvore bloqueada, a
150
+ * policy, o runtime indisponível no portão, o erro de contexto da thread, o erro antes de lançar) contam (RA2 da rodada 3:
151
+ * o runtime indisponível não passa sozinho). No arco entre máquinas (A1 da rodada 3 da ork-rm058n3), a vaga global ocupada,
152
+ * o ramo de coordenação sem leitura e a corrida perdida por ele também passam, como a vaga local.
153
+ */
154
+ const RECUSAS_PASSAGEIRAS = ['runtime.quota-exhausted', 'runtime.auth-missing', 'runtime.rate-limited', 'concurrency.limite',
155
+ 'conducao.em-andamento', 'baseline.pendente', 'noctum.orcamento.esgotado',
156
+ 'noctum.coordenacao.vaga-global', 'noctum.coordenacao.sem-remoto', 'noctum.coordenacao.concorrencia'];
157
+ const passageira = (motivo) => !motivo || RECUSAS_PASSAGEIRAS.includes(motivo) || motivo.startsWith('noctum.reconciliacao.');
158
+ exports.passageira = passageira;
159
+ /**
160
+ * As recusas seguidas do trabalho, das mais novas para trás, que não passam (B4 do CHECK), e o instante da reserva da
161
+ * primeira delas: a série precisa durar uma cadência para isolar (aviso da rodada 4).
162
+ */
163
+ function recusasSeguidas(estado, trabalho) {
164
+ let n = 0, motivo = null, desde = null;
165
+ for (const d of estado.despachos.filter(x => x.trabalho === trabalho).sort((a, b) => b.seq - a.seq)) {
166
+ if (d.desfecho !== 'recusado' || (0, exports.passageira)(d.motivo))
167
+ break;
168
+ n += 1;
169
+ motivo ??= d.motivo;
170
+ desde = d.reservadoEm;
171
+ }
172
+ return { n, motivo, desde };
173
+ }
174
+ /** O vigia não roda a baseline dentro do tique (A6 do CHECK): ela fica para o condutor, e o passo espera por ela. */
175
+ function baselineFicaParaOCondutor(_carregado, thread) {
176
+ throw new fila_pesada_1.ErroDaFilaPesada({ contrato: 'ork.fila-pesada-recusa/v1', motivo: 'fila-pesada.ocupada', operacao: 'verify.baseline', thread,
177
+ slots: 0, esperouMs: 0, ocupantes: [], texto: `o vigia não roda a baseline da thread ${thread} dentro do tique: ela fica para o condutor do arco` });
178
+ }
179
+ /**
180
+ * RM-058, integração (T4, D8): o vigia também não roda o verify do SHA nem o da atualização no tique; a entrega espera o
181
+ * condutor com o mesmo motivo da baseline. O MASTER por omissão, a reconciliação, a publicação e a integração com as provas
182
+ * prontas seguem no tique.
183
+ */
184
+ function verifyFicaParaOCondutor(_carregado, thread) {
185
+ throw new fila_pesada_1.ErroDaFilaPesada({ contrato: 'ork.fila-pesada-recusa/v1', motivo: 'fila-pesada.ocupada', operacao: 'verify', thread,
186
+ slots: 0, esperouMs: 0, ocupantes: [], texto: `o vigia não roda o verify da thread ${thread} dentro do tique: ele fica para o condutor do arco` });
187
+ }
188
+ /** A entrega fez um efeito (ou tentou um de resultado incerto)? A espera, o bloqueio e o nada não contam. */
189
+ const fezEfeito = (e) => !!e && e.acao !== 'aguardar' && e.acao !== 'bloqueado' && e.acao !== 'nada';
190
+ /** A instância ainda tem a geração do arco? O vigia, pela geração de qualquer vigia; o condutor, pela dele (D4). */
191
+ function daGeracaoDe(sup, quem) {
192
+ return quem.papel === 'vigia' ? sup.geracao?.quem.papel === 'vigia' : sup.geracao?.quem.instancia === quem.instancia;
193
+ }
194
+ /** O log público da supervisão nunca recebe o texto livre devolvido pelo adaptador ou pelo runtime. */
195
+ function detalheSeguroDaRecusa(motivo) {
196
+ if (motivo === 'noctum.origem.sem-prova') {
197
+ return 'a prova do dono não pode ser reconferida neste processo: falta a chave ou o verificador público do canal';
198
+ }
199
+ if (motivo === 'noctum.efeito.sem-autorizacao')
200
+ return 'o envelope não tem autorização vigente do dono';
201
+ if (motivo.startsWith('noctum.envelope.'))
202
+ return 'o núcleo recusou o envelope do arco';
203
+ return `o núcleo recusou o passo antes do despacho (${motivo})`;
204
+ }
205
+ /** Registra só a transição da espera ou da recusa; repetição do mesmo motivo não cresce o log a cada cadência. */
206
+ function gravarEstadoDoPasso(carregado, arco, quem, resultado, quando) {
207
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => {
208
+ if (resultado.acao === 'aguardar') {
209
+ if (s.espera?.motivo === resultado.motivo)
210
+ return [];
211
+ return [{ tipo: 'passo_em_espera', papel: quem.papel, motivo: resultado.motivo,
212
+ ocupantes: resultado.ocupantes ?? [] }];
213
+ }
214
+ if (resultado.acao === 'recusado') {
215
+ if (s.recusaDoPasso?.motivo === resultado.motivo)
216
+ return [];
217
+ return [{ tipo: 'passo_recusado', papel: quem.papel, trabalho: resultado.trabalho, motivo: resultado.motivo,
218
+ detalhe: detalheSeguroDaRecusa(resultado.motivo) }];
219
+ }
220
+ if ((s.espera || s.recusaDoPasso) && ['despachou', 'encerrar'].includes(resultado.acao)) {
221
+ return [{ tipo: 'passo_retomado', papel: quem.papel }];
222
+ }
223
+ return [];
224
+ }, quando);
225
+ }
226
+ /**
227
+ * Um passo do arco com a supervisão (D5, D6, D13 a D15): para o arco parado, sai da geração vencida, espera o vigia
228
+ * ausente (só o condutor exige: o vigia que dá o passo está presente), e chama o passo da N2 com as contas e os alvos do
229
+ * arco e as decisões da supervisão. A recusa de ambiente fica no log e, repetida, para o arco; a parada pelo teto do arco
230
+ * ou pela violação de custo também.
231
+ */
232
+ function passoConduzido(carregado, arco, quem, opcoes = {}) {
233
+ const { raiz } = carregado;
234
+ const quando = opcoes.quando ?? new Date().toISOString();
235
+ const agora = Date.parse(quando);
236
+ const parametros = (0, noctum_supervisao_1.parametrosDoArco)(carregado, arco, quando);
237
+ const sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
238
+ if (sup.parada)
239
+ return { acao: 'parado', motivo: sup.parada.motivo, detalhe: sup.parada.detalhe };
240
+ if (!daGeracaoDe(sup, quem)) {
241
+ return { acao: 'geracao-vencida', detalhe: `a geração ${sup.geracao?.numero ?? 0} é de ${sup.geracao?.quem.papel ?? 'ninguém'} ` +
242
+ `${sup.geracao?.quem.instancia ?? ''}; esta instância não despacha mais` };
243
+ }
244
+ const cadencia = new Date(agora + parametros.cadenciaMs).toISOString();
245
+ if (quem.papel === 'condutor') {
246
+ const vigia = sup.batidas.vigia;
247
+ if (!vigia || agora - Date.parse(vigia.em) > parametros.vigiaAusenteMs) {
248
+ const espera = { acao: 'aguardar', ate: cadencia, motivo: 'vigia-ausente', fila: null,
249
+ detalhe: vigia ? `o último tique do vigia foi em ${(0, horario_1.formatarDataHora)(vigia.em)}, há mais de ${Math.round(parametros.vigiaAusenteMs / 60000)} min: ` +
250
+ 'nada novo sai sem supervisão' : 'o vigia ainda não deu nenhum tique neste arco: nada novo sai sem supervisão' };
251
+ gravarEstadoDoPasso(carregado, arco, quem, espera, quando);
252
+ return espera;
253
+ }
254
+ }
255
+ const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
256
+ const conteudo = v2(estado);
257
+ const store = (opcoes.lerStore ?? storePadrao(raiz))();
258
+ const visao = conteudo && estado ? (0, noctum_supervisao_1.contasDoArco)(conteudo, estado, sup, store, quando) : null;
259
+ if (visao?.parada) {
260
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: visao.parada.motivo, detalhe: visao.parada.detalhe }], quando);
261
+ return { acao: 'parado', motivo: visao.parada.motivo, detalhe: visao.parada.detalhe };
262
+ }
263
+ const r = (0, noctum_execucao_1.passoDoArco)(carregado, arco, { ...opcoes.passo, quando, maquina: opcoes.maquina ?? opcoes.passo?.maquina,
264
+ ...(visao ? { perfis: () => visao.perfis } : {}),
265
+ ...(conteudo && estado ? { alvos: (fase, runtime, modo) => (0, noctum_supervisao_1.alvosDaFase)(carregado, conteudo, estado, fase, runtime, modo) } : {}),
266
+ supervisao: decisoesDaSupervisao(sup, estado) });
267
+ gravarEstadoDoPasso(carregado, arco, quem, r, quando);
268
+ // N1 do CHECK 2: a baseline do trabalho que falhou sem ser espera isola o trabalho, com a causa: os outros seguem, e o
269
+ // tique e o relatório dizem por quê.
270
+ if (r.acao === 'recusado' && r.motivo === noctum_execucao_1.MOTIVO_DA_BASELINE_FALHA)
271
+ isolar(carregado, arco, r.trabalho, r.thread, 'baseline-falhou', r.detalhe, quando);
272
+ if (r.acao === 'recusado' && (0, noctum_reconciliacao_1.recusaDeAmbiente)(r.detalhe)) {
273
+ const depois = (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'recusa_de_ambiente', trabalho: r.trabalho, thread: r.thread,
274
+ detalhe: r.detalhe.slice(0, 300) }], quando);
275
+ const parada = (0, noctum_reconciliacao_1.paradaPorAmbiente)(depois, (0, noctum_arco_1.lerArco)(raiz, arco, quando));
276
+ if (parada)
277
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: parada.motivo, detalhe: parada.detalhe }], quando);
278
+ }
279
+ // RM-058, integração (T4, D8): a entrega depois do despacho, no máximo um efeito, relida a supervisão: com a parada ou a
280
+ // geração que outro tomou entre os dois, nada é entregue por esta instância. Roda também no passo que encerra: a fila
281
+ // vazia ainda deve o MASTER por omissão da última entrega do arco.
282
+ const relida = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
283
+ if (relida.parada || !daGeracaoDe(relida, quem))
284
+ return r;
285
+ try {
286
+ const entrega = (opcoes.entregar ?? noctum_entrega_1.passoDaEntrega)(carregado, arco, { maquina: opcoes.maquina ?? opcoes.passo?.maquina,
287
+ lerReservas: opcoes.passo?.lerReservas, consultarSessoes: opcoes.passo?.consultarSessoes, ...(visao ? { perfis: () => visao.perfis } : {}),
288
+ ...opcoes.entrega, quando });
289
+ return { ...r, entrega };
290
+ }
291
+ catch (e) {
292
+ return { ...r, entrega: null, falhaDaEntrega: (e instanceof Error ? e.message : String(e)).split('\n')[0].slice(0, 200) };
293
+ }
294
+ }
295
+ /**
296
+ * M1 do CHECK 3: sob a parada pelo teto, cada sessão do arco em voo que o runtime prova morta, passada a carência desde a
297
+ * última atividade dela, vira `sessao_morta`, seja qual for o trabalho (isolado, com as retomadas esgotadas ou na fase da
298
+ * entrega): a decisão de retomar não importa com o arco parado.
299
+ */
300
+ function registrarMortesSobAParada(raiz, estado, leitura, parametros, quando) {
301
+ for (const s of (0, noctum_sessoes_em_voo_1.sessoesEmVooDoArco)(raiz, estado)) {
302
+ if (!s.sessionId || !s.thread)
303
+ continue;
304
+ let eventos;
305
+ try {
306
+ eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, s.thread));
307
+ }
308
+ catch {
309
+ continue;
310
+ }
311
+ const despacho = eventos.filter(e => e.tipo === 'phase_dispatch' && e.sessionId === s.sessionId).at(-1);
312
+ if (!despacho)
313
+ continue;
314
+ const p = (0, noctum_reconciliacao_1.provaDaSessao)(leitura, s.sessionId, s.conta, s.runtime, despacho.ts, parametros.ausenciaMinimaMs);
315
+ const ultimaAtividade = Math.max(...eventos.filter(e => e.sessionId === s.sessionId).map(e => Date.parse(e.ts)).filter(Number.isFinite));
316
+ if (p.estado !== 'morta' || Date.parse(quando) - ultimaAtividade < parametros.carenciaMs)
317
+ continue;
318
+ registrarMorte(raiz, s.thread, { sessionId: s.sessionId, runtime: s.runtime, perfil: s.conta }, `a sessão ${s.sessionId} acabou sem resultado com o arco parado pelo teto: ${p.detalhe}`);
319
+ }
320
+ }
321
+ /** Grava `sessao_morta` no ledger da thread, uma vez por sessão: é o que solta a condução e a vaga (D10). */
322
+ function registrarMorte(raiz, thread, m, prova) {
323
+ const dir = (0, thread_1.dirThread)(raiz, thread);
324
+ let eventos = [];
325
+ try {
326
+ eventos = (0, ledger_1.lerLedger)(dir);
327
+ }
328
+ catch {
329
+ return;
330
+ }
331
+ if (eventos.some(e => e.tipo === 'sessao_morta' && e.sessionId === m.sessionId))
332
+ return;
333
+ // A fase da sessão é a do despacho dela (ou da falha que disse o id).
334
+ const daSessao = [...eventos].reverse().find(e => (e.tipo === 'phase_dispatch' || e.tipo === 'phase_dispatch_failed') && e.sessionId === m.sessionId);
335
+ (0, ledger_1.registrar)(dir, thread, 'sessao_morta', { fase: typeof daSessao?.fase === 'string' ? daSessao.fase : null, sessionId: m.sessionId,
336
+ runtime: m.runtime, ...(m.perfil ? { perfilId: m.perfil } : {}), origem: 'noctum.vigia', evidencia: prova.slice(0, 300),
337
+ razao: 'o vigia do arco provou o fim da sessão pelo runtime: solta a condução e a vaga para a retomada pelo passo do arco' });
338
+ }
339
+ /** Isola o trabalho uma vez (S1 do CHECK): o primeiro isolamento vale, e o tique seguinte não o regrava. */
340
+ function isolar(carregado, arco, trabalho, thread, motivo, detalhe, quando) {
341
+ let gravou = false;
342
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => {
343
+ if (s.isolados.has(trabalho))
344
+ return [];
345
+ gravou = true;
346
+ return [{ tipo: 'isolado', trabalho, thread, motivo, detalhe: detalhe.slice(0, 300) }];
347
+ }, quando);
348
+ return gravou;
349
+ }
350
+ /**
351
+ * Um tique do vigia (D3 a D6). Com a trava do vigia: registra o tique anterior que ficou aberto, observa as contas, e com
352
+ * a trava de despacho na mão (nenhum passo no meio) lê o runtime e reconcilia as reservas pendentes e as sessões; tira da
353
+ * fila durável os pedidos do arco já atendidos, relê os efeitos incertos, aplica as paradas e, com a trava do condutor
354
+ * livre e o arco vigente, assume a condução e dá um passo. A exceção do passo vira lacuna do tique; a de antes dele (disco,
355
+ * log adulterado) sobe, o tique fica aberto e o seguinte o registra como interrompido.
356
+ */
357
+ function vigiarArco(carregado, arco, opcoes = {}) {
358
+ const { raiz } = carregado;
359
+ if (!(0, fila_pesada_1.kernelDisponivel)())
360
+ return { acao: 'sem-kernel', detalhe: 'o vigia exige /usr/bin/flock: sem a trava do kernel, nada prova a vida de ninguém' };
361
+ if (!(0, noctum_arco_1.lerArco)(raiz, arco))
362
+ return { acao: 'sem-arco', detalhe: `o arco ${arco} não tem proposta` };
363
+ const dir = (0, noctum_supervisao_1.dirDaSupervisao)(raiz, arco);
364
+ const fdVigia = (0, fila_pesada_1.tentarTravaExclusiva)(path.join(dir, ARQUIVO_DO_VIGIA));
365
+ if (fdVigia === null)
366
+ return { acao: 'outro-vigia', detalhe: 'outro vigia deste arco está no meio de um tique' };
367
+ try {
368
+ const quando = opcoes.quando ?? new Date().toISOString();
369
+ const quem = quemSou('vigia', opcoes);
370
+ const parametros = (0, noctum_supervisao_1.parametrosDoArco)(carregado, arco, quando);
371
+ // S6 do CHECK: com a trava do vigia na mão, todo tique aberto é de um vigia que morreu, até de uma instância de mesmo nome.
372
+ let interrompido = null;
373
+ let sup = (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => {
374
+ interrompido = s.tiqueAberto?.quem.instancia ?? null;
375
+ return [...(s.tiqueAberto ? [{ tipo: 'vigia_interrompido', interrompido: s.tiqueAberto.quem.instancia,
376
+ prova: `a trava do vigia estava livre: a instância ${s.tiqueAberto.quem.instancia} (pid ${s.tiqueAberto.quem.pid}) não a segura mais` }] : []),
377
+ { tipo: 'tique_iniciado', quem }];
378
+ }, quando);
379
+ opcoes.depoisDeIniciar?.();
380
+ const lacunas = [];
381
+ const contagem = { reservas: 0, retomadas: 0, isolados: 0, contas: 0 };
382
+ if (sup.interrupcoesSeguidas >= parametros.interrupcoesQueParam && !sup.parada) {
383
+ sup = (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: 'supervisor-falhou',
384
+ detalhe: `${s.interrupcoesSeguidas} tiques do vigia interrompidos em série (o limite é ${parametros.interrupcoesQueParam})` }], quando);
385
+ }
386
+ const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
387
+ const conteudo = v2(estado);
388
+ if (conteudo) {
389
+ const store = (opcoes.lerStore ?? storePadrao(raiz))();
390
+ aplicarContas(carregado, arco, conteudo, store, quando, contagem);
391
+ reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem);
392
+ for (const d of (0, noctum_reconciliacao_1.decidirPedidos)(raiz, arco, (0, noctum_arco_1.lerArco)(raiz, arco, quando))) {
393
+ (0, retry_1.cancelarPedido)(carregado, d.pedido, d.motivo);
394
+ (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'pedido_tratado', pedido: d.pedido, thread: d.thread, acao: 'cancelado', motivo: d.motivo.slice(0, 200) }], quando);
395
+ }
396
+ for (const id of (0, noctum_reconciliacao_1.efeitosAbertos)((0, noctum_supervisao_1.lerSupervisao)(raiz, arco))) {
397
+ const r = (0, noctum_reconciliacao_1.reconciliarEfeito)(carregado, arco, id, { lerRemoto: opcoes.lerRemoto, quando });
398
+ if (r.isolado)
399
+ contagem.isolados += 1;
400
+ if (r.desfecho === 'sem-leitura')
401
+ lacunas.push(`efeito ${id}: ${r.prova}`);
402
+ }
403
+ const ambiente = (0, noctum_reconciliacao_1.paradaPorAmbiente)((0, noctum_supervisao_1.lerSupervisao)(raiz, arco), (0, noctum_arco_1.lerArco)(raiz, arco, quando));
404
+ if (ambiente)
405
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', ...ambiente }], quando);
406
+ }
407
+ sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
408
+ // D5: com a trava do condutor livre, este tique conduz: a geração do vigia, com a prova, e um passo.
409
+ let condutor = 'sem-passo';
410
+ let passo = null;
411
+ const vigente = (0, noctum_arco_1.lerArco)(raiz, arco, quando).situacao === 'vigente';
412
+ if (!sup.parada && vigente && conteudo) {
413
+ const fdCondutor = (0, fila_pesada_1.tentarTravaExclusiva)(path.join(dir, ARQUIVO_DO_CONDUTOR));
414
+ if (fdCondutor === null) {
415
+ condutor = 'vivo';
416
+ const batida = sup.batidas.condutor;
417
+ if (!batida || Date.parse(quando) - Date.parse(batida.em) > 3 * parametros.cadenciaMs) {
418
+ lacunas.push(`o condutor segura a trava sem batida desde ${batida ? (0, horario_1.formatarDataHora)(batida.em) : 'nunca'}: vivo, sem prova de ausência, ele não é substituído`);
419
+ }
420
+ }
421
+ else {
422
+ try {
423
+ // A4 do CHECK: a geração é lida sob a trava do log, depois de tomar a trava do condutor.
424
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.geracao?.quem.papel === 'vigia' ? [] : [{ tipo: 'conducao_assumida',
425
+ geracao: (s.geracao?.numero ?? 0) + 1, quem,
426
+ prova: s.geracao ? `a trava do condutor estava livre: a geração ${s.geracao.numero} (${s.geracao.quem.papel} ${s.geracao.quem.instancia}, ` +
427
+ `pid ${s.geracao.quem.pid}) não a segura mais` : 'a trava do condutor estava livre: primeira condução do arco' }], quando);
428
+ condutor = 'assumido';
429
+ try {
430
+ passo = passoConduzido(carregado, arco, quem, { ...opcoes, quando,
431
+ passo: { ...opcoes.passo, gravarBaseline: (k, thread) => baselineFicaParaOCondutor(k, thread) },
432
+ // RM-058, integração (T4, D8): no tique, nada espera a fila pesada nem a trava de despacho, e o verify fica para o condutor.
433
+ entrega: { ...opcoes.entrega, esperarMs: 0, verificar: (k, thread) => verifyFicaParaOCondutor(k, thread) } });
434
+ if (passo.falhaDaEntrega)
435
+ lacunas.push(`a entrega lançou: ${passo.falhaDaEntrega}`);
436
+ }
437
+ catch (e) {
438
+ // S7 do CHECK: o passo que lança (o adaptador do runtime, por exemplo) é lacuna do tique, e não queda do vigia.
439
+ lacunas.push(`o passo lançou: ${(e instanceof Error ? e.message : String(e)).slice(0, 200)}`);
440
+ }
441
+ }
442
+ finally {
443
+ fs.closeSync(fdCondutor);
444
+ }
445
+ }
446
+ }
447
+ const resumo = `reservas ${contagem.reservas}, retomadas ${contagem.retomadas}, isolados ${contagem.isolados}, contas ${contagem.contas}, ` +
448
+ `condutor ${condutor}${passo ? `, passo ${passo.acao}` : ''}`;
449
+ sup = (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'tique_concluido', quem, resumo }], quando);
450
+ return { acao: 'tique', instancia: quem.instancia, situacao: (0, noctum_arco_1.lerArco)(raiz, arco, quando).situacao, interrompido,
451
+ ...contagem, parada: sup.parada?.motivo ?? null, condutor, passo, lacunas };
452
+ }
453
+ finally {
454
+ fs.closeSync(fdVigia);
455
+ }
456
+ }
457
+ /**
458
+ * D7 e D10 a D12, com a trava de despacho na mão (nenhum passo no meio, B3 do CHECK): a listagem do runtime é lida sob ela,
459
+ * com o instante da leitura; as reservas pendentes são decididas sobre o arco relido sob a trava (A3); e, com o arco
460
+ * vigente e sem parada (A5), as sessões e as recusas repetidas. Com a trava ocupada, tudo fica para o tique seguinte.
461
+ */
462
+ function reconciliarSobATravaDeDespacho(carregado, arco, conteudo, parametros, quando, opcoes, lacunas, contagem) {
463
+ const { raiz } = carregado;
464
+ const noctum = path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'noctum');
465
+ const fd = (0, fila_pesada_1.tentarTravaExclusiva)(path.join(noctum, 'despacho.lock'));
466
+ if (fd === null) {
467
+ lacunas.push('um passo segura a trava de despacho: reservas e sessões ficam para o próximo tique');
468
+ return;
469
+ }
470
+ try {
471
+ const consultar = opcoes.consultarRuntime ?? runtimePadrao(raiz, carregado.manifesto.concurrency.stale_after_min);
472
+ const leitura = { ...consultar(), lidaEm: quando };
473
+ lacunas.push(...leitura.fontes.filter(f => !f.ok || f.ausente).map(f => `${f.origem}: ${f.ok ? 'ausente' : f.detalhe}`));
474
+ for (const d of (0, noctum_reconciliacao_1.decidirReservas)(raiz, arco, conteudo, (0, noctum_arco_1.lerArco)(raiz, arco, quando), leitura, parametros, quando)) {
475
+ if (d.acao === 'concluir') {
476
+ (0, noctum_arco_1.concluirDespacho)(raiz, arco, d.seq, { thread: d.thread ?? '', sessionId: d.sessionId, idempotente: d.idempotente }, quando);
477
+ if (d.morta && d.thread)
478
+ registrarMorte(raiz, d.thread, d.morta, d.prova);
479
+ contagem.reservas += 1;
480
+ }
481
+ else if (d.acao === 'devolver') {
482
+ (0, noctum_arco_1.concluirDespacho)(raiz, arco, d.seq, { motivo: d.motivo }, quando);
483
+ contagem.reservas += 1;
484
+ }
485
+ else if (d.acao === 'aguardar')
486
+ lacunas.push(`reserva ${d.seq} do trabalho ${d.trabalho}: ${d.prova}`);
487
+ if (d.isolamento && isolar(carregado, arco, d.trabalho, d.thread, d.isolamento.motivo, d.isolamento.detalhe, quando))
488
+ contagem.isolados += 1;
489
+ }
490
+ const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
491
+ const sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
492
+ // N2 do CHECK 2: com a parada pelo teto, o arco espera as sessões admitidas. A que o runtime prova morta sem resultado no
493
+ // ledger vira `sessao_morta`, sem retomada nem parada, e o fechamento pelo teto não fica preso a ela até a hora.
494
+ if (estado.situacao === 'vigente' && sup.parada?.motivo === 'teto-do-arco') {
495
+ registrarMortesSobAParada(raiz, estado, leitura, sup.parametros, quando);
496
+ return;
497
+ }
498
+ if (estado.situacao !== 'vigente' || sup.parada)
499
+ return;
500
+ aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar);
501
+ // B4 do CHECK: o trabalho que o núcleo recusa seguidas vezes pelo mesmo tipo de motivo (a árvore, a policy, o erro
502
+ // antes de lançar) não volta a noite toda: no teto, e com a série durando ao menos uma cadência, é isolado. O soluço
503
+ // mais curto que a cadência (a conferência de login inconclusiva da A14, que o núcleo refaz a cada despacho) não isola.
504
+ const depois = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
505
+ for (const t of conteudo.trabalhos) {
506
+ const r = recusasSeguidas(depois, t.id);
507
+ if (r.n >= parametros.tetoDeRetomadas && r.desde !== null && Date.parse(quando) - Date.parse(r.desde) >= parametros.cadenciaMs &&
508
+ isolar(carregado, arco, t.id, null, r.motivo === 'noctum.despacho.erro' ? 'erro-repetido' : 'recusas-repetidas', `${r.n} despachos seguidos recusados pelo núcleo (${String(r.motivo)}): o dono decide`, quando))
509
+ contagem.isolados += 1;
510
+ }
511
+ }
512
+ finally {
513
+ fs.closeSync(fd);
514
+ }
515
+ }
516
+ /** D13 e D15: as contas que os despachos do arco e o store provaram fora, e a parada por custo. */
517
+ function aplicarContas(carregado, arco, conteudo, store, quando, contagem) {
518
+ const { raiz } = carregado;
519
+ const o = (0, noctum_supervisao_1.observarContas)(raiz, arco, conteudo, (0, noctum_arco_1.lerArco)(raiz, arco, quando), (0, noctum_supervisao_1.lerSupervisao)(raiz, arco), store, quando);
520
+ if (o.eventos.length)
521
+ (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, o.eventos, quando);
522
+ if (o.parada)
523
+ (0, noctum_supervisao_1.gravarComEstado)(carregado, arco, (s) => s.parada ? [] : [{ tipo: 'parada', motivo: o.parada.motivo, detalhe: o.parada.detalhe }], quando);
524
+ contagem.contas += o.eventos.length;
525
+ }
526
+ /**
527
+ * D10 a D12 e D16: aplica as decisões das sessões. A sessão viva é parada pelo controle do runtime e conferida numa
528
+ * listagem nova; sem confirmação, a parada fica no log como não confirmada e nada é autorizado (no teto das tentativas, o
529
+ * trabalho é isolado). Confirmada, ou já morta, a sessão vira `sessao_morta` no ledger da thread e a retomada é autorizada.
530
+ */
531
+ function aplicarSessoes(carregado, arco, conteudo, leitura, quando, opcoes, lacunas, contagem, consultar) {
532
+ const { raiz } = carregado;
533
+ const sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
534
+ const parametros = sup.parametros;
535
+ const parar = opcoes.pararSessao ?? pararPadrao(raiz);
536
+ /** Para a sessão e confere numa listagem nova: a prova, ou `null` quando o runtime não confirmou. */
537
+ const pararEConferir = (p, motivo, trabalho) => {
538
+ const pedido = parar(p);
539
+ // A listagem nova depois do pedido: aqui a sessão já existia antes, e a ausência na listagem completa prova o fim.
540
+ const listagem = consultar();
541
+ const depois = (0, noctum_reconciliacao_1.listagemCompleta)(listagem) || listagem.sessoes.some(x => x.sessionId === p.sessionId)
542
+ ? (0, noctum_reconciliacao_1.provaDaSessao)(listagem, p.sessionId, p.perfil, p.runtime) : { estado: 'desconhecida', detalhe: 'a listagem depois da parada não veio completa' };
543
+ const confirmada = pedido.ok && depois.estado === 'morta';
544
+ const prova = `${pedido.detalhe}; depois: ${depois.detalhe}`;
545
+ (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'sessao_parada', trabalho, thread: p.thread, sessionId: p.sessionId, motivo, confirmada, prova }], quando);
546
+ if (confirmada)
547
+ registrarMorte(raiz, p.thread, p, prova);
548
+ return confirmada ? prova : null;
549
+ };
550
+ for (const d of (0, noctum_reconciliacao_1.decidirSessoes)(raiz, arco, conteudo, (0, noctum_arco_1.lerArco)(raiz, arco, quando), sup, leitura, quando)) {
551
+ if (d.acao === 'aguardar') {
552
+ lacunas.push(`${d.thread}: ${d.detalhe}`);
553
+ continue;
554
+ }
555
+ if (d.acao === 'isolar') {
556
+ if (d.parar)
557
+ pararEConferir(d.parar, d.motivo === 'sem-primeiro-turno' ? 'sem-primeiro-turno' : 'sem-avanco', d.trabalho);
558
+ if (isolar(carregado, arco, d.trabalho, d.thread, d.motivo, d.detalhe, quando))
559
+ contagem.isolados += 1;
560
+ continue;
561
+ }
562
+ let prova = null;
563
+ if (d.parar) {
564
+ prova = pararEConferir(d.parar, d.motivo, d.trabalho);
565
+ if (!prova) {
566
+ const falhas = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco).sessoesParadas.filter(x => x.sessionId === d.parar.sessionId && !x.confirmada).length;
567
+ if (falhas >= parametros.tetoDeRetomadas) {
568
+ if (isolar(carregado, arco, d.trabalho, d.thread, 'sessao-presa', `a sessão ${d.parar.sessionId} não parou pelo controle do runtime em ${falhas} tentativa(s): o dono a encerra`, quando))
569
+ contagem.isolados += 1;
570
+ }
571
+ else
572
+ lacunas.push(`${d.thread}: a parada da sessão ${d.parar.sessionId} não foi confirmada pelo runtime`);
573
+ continue;
574
+ }
575
+ }
576
+ if (d.morta)
577
+ registrarMorte(raiz, d.thread, d.morta, d.prova);
578
+ (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'retomada_autorizada', trabalho: d.trabalho, thread: d.thread, fase: d.fase, tentativa: d.tentativa,
579
+ motivo: d.motivo, sessao: d.sessao, prova: (prova ? `${d.prova}; parada confirmada: ${prova}` : d.prova).slice(0, 400),
580
+ aposReserva: d.aposReserva }], quando);
581
+ contagem.retomadas += 1;
582
+ }
583
+ }
584
+ /**
585
+ * O condutor do arco (D4 e D6): segura a trava do condutor pela vida inteira, grava a geração nova (lida sob a trava do
586
+ * log) com a prova, bate a cada passo e chama o passo supervisionado na cadência que a fila pede, nunca além da cadência;
587
+ * depois de uma recusa, espera `PAUSA_DEPOIS_DA_RECUSA_MS` (B4 do CHECK), ou a cadência inteira na recusa que passa. Sai
588
+ * quando o arco encerra (a fila vazia, com a entrega sem efeito no passo) ou para, quando perde a geração, ou no fim dos
589
+ * passos que lhe deram (os testes). `dormir` é dependência.
590
+ */
591
+ function conduzirArco(carregado, arco, opcoes = {}) {
592
+ const { raiz } = carregado;
593
+ if (!(0, fila_pesada_1.kernelDisponivel)())
594
+ return { acao: 'sem-kernel', detalhe: 'o condutor exige /usr/bin/flock' };
595
+ if (!(0, noctum_arco_1.lerArco)(raiz, arco))
596
+ return { acao: 'sem-arco', detalhe: `o arco ${arco} não tem proposta` };
597
+ const fd = (0, fila_pesada_1.tentarTravaExclusiva)(path.join((0, noctum_supervisao_1.dirDaSupervisao)(raiz, arco), ARQUIVO_DO_CONDUTOR));
598
+ if (fd === null)
599
+ return { acao: 'outro-condutor', detalhe: 'outro processo conduz este arco agora (ou o vigia está no passo dele)' };
600
+ const dormir = opcoes.dormir ?? ((ms) => { if (ms > 0)
601
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, Math.ceil(ms)); });
602
+ try {
603
+ const relogio = opcoes.relogio ?? (() => new Date().toISOString());
604
+ const quem = quemSou('condutor', opcoes);
605
+ const parametros = (0, noctum_supervisao_1.parametrosDoArco)(carregado, arco, relogio());
606
+ const geracao = (0, noctum_supervisao_1.assumirConducao)(carregado, arco, quem, (anterior) => anterior
607
+ ? `a trava do condutor estava livre: a geração ${anterior.numero} (${anterior.quem.papel} ${anterior.quem.instancia}) não a segura mais`
608
+ : 'a trava do condutor estava livre: primeira condução do arco', relogio());
609
+ let ultimo = null, passos = 0;
610
+ for (; passos < (opcoes.maxPassos ?? Number.POSITIVE_INFINITY); passos++) {
611
+ const quando = relogio();
612
+ (0, noctum_supervisao_1.gravarNaSupervisao)(carregado, arco, [{ tipo: 'batida', quem, geracao }], quando);
613
+ ultimo = passoConduzido(carregado, arco, quem, { ...opcoes, quando });
614
+ // RM-058, integração (D8): a fila vazia só tira o condutor quando a entrega também não fez efeito no passo.
615
+ if ((ultimo.acao === 'encerrar' && !fezEfeito(ultimo.entrega)) || ultimo.acao === 'parado' || ultimo.acao === 'geracao-vencida') {
616
+ passos += 1;
617
+ break;
618
+ }
619
+ // A recusa que passa (a conta, a vaga, a condução, o orçamento esgotado na reserva) espera a cadência, que é quando
620
+ // o vigia relê as contas; a que conta (a árvore, a policy) volta depois da pausa, e repetida isola o trabalho (RA2 da
621
+ // rodada 3).
622
+ // A5 do CHECK: o passo que acabou de gravar a baseline volta já; o `ate` dele é o relógio depois da suíte, e medir a
623
+ // espera do começo da iteração faria o condutor dormir a cadência inteira antes de despachar.
624
+ const doPasso = ultimo.acao === 'aguardar' ? (ultimo.motivo === 'baseline-gravada' ? Date.parse(quando) : Date.parse(ultimo.ate))
625
+ : ultimo.acao === 'recusado' ? Date.parse(quando) + ((0, exports.passageira)(ultimo.motivo) ? parametros.cadenciaMs : exports.PAUSA_DEPOIS_DA_RECUSA_MS)
626
+ : Date.parse(quando);
627
+ // RM-058, integração (D8): o menor `ate` do despacho e da entrega; a entrega que fez um efeito volta já, e a que não tem
628
+ // nada a entregar (ou bloqueou) não adianta o laço.
629
+ const e = ultimo.entrega;
630
+ const daEntrega = !e ? Number.POSITIVE_INFINITY : e.acao === 'aguardar' ? Date.parse(e.ate)
631
+ : e.acao === 'nada' || e.acao === 'bloqueado' ? Number.POSITIVE_INFINITY : Date.parse(quando);
632
+ dormir(Math.max(0, Math.min(Math.min(doPasso, daEntrega) - Date.parse(quando), parametros.cadenciaMs)));
633
+ }
634
+ return { acao: 'saiu', instancia: quem.instancia, geracao, passos, ultimo };
635
+ }
636
+ finally {
637
+ fs.closeSync(fd);
638
+ }
639
+ }