@orkastery/cli 0.5.6 → 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 (385) 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 +37 -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/ork-mensageiro/.claude-plugin/plugin.json +14 -0
  16. package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
  17. package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
  18. package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
  19. package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
  20. package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
  21. package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
  22. package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
  23. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
  24. package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
  25. package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
  27. package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
  28. package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
  29. package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
  30. package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
  31. package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
  32. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
  33. package/adapters/codex/skills/ork/SKILL.md +2 -0
  34. package/adapters/hermes/README.md +64 -1
  35. package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
  36. package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
  37. package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
  38. package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
  39. package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
  40. package/adapters/hermes/hermes.plugin.json +4 -0
  41. package/adapters/hermes/hitl-ingress/__init__.py +101 -8
  42. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
  43. package/adapters/openclaw/README.md +81 -9
  44. package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
  45. package/adapters/openclaw/dist/hitl-ingress.js +106 -9
  46. package/adapters/openclaw/dist/index.js +86 -0
  47. package/adapters/openclaw/openclaw.plugin.json +34 -4
  48. package/adapters/openclaw/package.json +2 -2
  49. package/adapters/openclaw/src/hitl-ingress.ts +103 -9
  50. package/adapters/openclaw/src/index.ts +94 -0
  51. package/assets/adapters-en/claude-code/README.md +403 -0
  52. package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
  53. package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
  54. package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
  55. package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
  56. package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
  57. package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
  58. package/assets/adapters-en/claude-code/commands/check.md +46 -0
  59. package/assets/adapters-en/claude-code/commands/go.md +46 -0
  60. package/assets/adapters-en/claude-code/commands/goal.md +55 -0
  61. package/assets/adapters-en/claude-code/commands/master.md +54 -0
  62. package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
  63. package/assets/adapters-en/claude-code/commands/ork.md +126 -0
  64. package/assets/adapters-en/claude-code/commands/plan.md +47 -0
  65. package/assets/adapters-en/claude-code/commands/ship.md +45 -0
  66. package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
  67. package/assets/adapters-en/hermes/README.md +273 -0
  68. package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
  69. package/assets/references-en/README.md +25 -0
  70. package/assets/references-en/code-review-axes.md +82 -0
  71. package/assets/references-en/definition-of-done.md +74 -0
  72. package/assets/references-en/performance-checklist.md +53 -0
  73. package/assets/references-en/security-checklist.md +101 -0
  74. package/assets/references-en/testing-patterns.md +51 -0
  75. package/assets/security-scan/defaults/.golangci.yml +2 -0
  76. package/assets/security-scan/defaults/eslint.config.mjs +11 -0
  77. package/assets/security-scan/defaults/gitleaks.toml +3 -0
  78. package/assets/security-scan/defaults/ruff.toml +1 -0
  79. package/assets/security-scan/tools-agil.json +87 -0
  80. package/assets/security-scan/tools.json +625 -0
  81. package/assets/skills-en/core/onboarding/SKILL.md +58 -0
  82. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
  83. package/assets/skills-en/core/thread-state/SKILL.md +88 -0
  84. package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
  85. package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
  86. package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
  87. package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
  88. package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
  89. package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
  90. package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
  91. package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
  92. package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
  93. package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
  94. package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
  95. package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
  96. package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
  97. package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
  98. package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
  99. package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
  100. package/dist/adapters/claude-bg.js +118 -4
  101. package/dist/adapters/codex-controller-worker.js +12 -5
  102. package/dist/adapters/codex-events.js +16 -4
  103. package/dist/adapters/codex.js +3 -1
  104. package/dist/atualizar-branch.js +245 -0
  105. package/dist/auditoria.js +13 -11
  106. package/dist/auditrun.js +51 -46
  107. package/dist/autorizacao-duravel.js +327 -0
  108. package/dist/board.js +94 -40
  109. package/dist/branch-de-estado.js +16 -8
  110. package/dist/busca-semantica.js +7 -5
  111. package/dist/catalogo.js +2 -1
  112. package/dist/changelog-reconciliacao.js +290 -0
  113. package/dist/check-agil.js +500 -0
  114. package/dist/check-modo.js +41 -0
  115. package/dist/check-paralelo.js +183 -0
  116. package/dist/ci.js +248 -45
  117. package/dist/ciclos.js +8 -6
  118. package/dist/claim-lint.js +12 -8
  119. package/dist/claims-conferir.js +47 -39
  120. package/dist/claims.js +10 -9
  121. package/dist/company-brain-client.js +10 -3
  122. package/dist/company-brain-migration.js +11 -5
  123. package/dist/conducao-batida.js +759 -0
  124. package/dist/conducao-sentinela.js +25 -8
  125. package/dist/conducao.js +84 -29
  126. package/dist/conhecimento-consulta.js +270 -0
  127. package/dist/conhecimento.js +111 -87
  128. package/dist/conta-esgotada.js +127 -0
  129. package/dist/dado-privado.js +816 -0
  130. package/dist/decisao-autonoma.js +5 -4
  131. package/dist/demo.js +14 -12
  132. package/dist/dependencias-da-worktree.js +25 -0
  133. package/dist/divida.js +38 -36
  134. package/dist/docs.js +81 -74
  135. package/dist/doctor-forja.js +345 -0
  136. package/dist/doctor-pulse-cron.js +113 -1
  137. package/dist/doctor.js +164 -6
  138. package/dist/dsn-da-memoria.js +417 -0
  139. package/dist/entrega-por-mod.js +503 -0
  140. package/dist/entrega-pr.js +143 -43
  141. package/dist/esgotamentos.js +13 -11
  142. package/dist/estado-thread.js +21 -18
  143. package/dist/evalrunner.js +35 -32
  144. package/dist/fabrica-batida.js +34 -21
  145. package/dist/fabrica-estado.js +13 -10
  146. package/dist/fix.js +21 -19
  147. package/dist/forja/adaptador.js +6 -0
  148. package/dist/forja/ambiente-de-ci.js +27 -0
  149. package/dist/forja/api.js +256 -0
  150. package/dist/forja/cache.js +89 -0
  151. package/dist/forja/cli.js +60 -0
  152. package/dist/forja/contrato.js +9 -0
  153. package/dist/forja/endereco.js +43 -0
  154. package/dist/forja/estado.js +22 -0
  155. package/dist/forja/executor.js +73 -0
  156. package/dist/forja/github/ci.js +95 -0
  157. package/dist/forja/github/dono-da-rede.js +18 -0
  158. package/dist/forja/github/metadados.js +15 -0
  159. package/dist/forja/github/pedidos.js +200 -0
  160. package/dist/forja/gitlab/ci.js +141 -0
  161. package/dist/forja/gitlab/consultas.js +59 -0
  162. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  163. package/dist/forja/gitlab/metadados.js +15 -0
  164. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  165. package/dist/forja/gitlab/pedidos.js +141 -0
  166. package/dist/forja/produtor.js +32 -0
  167. package/dist/forja/registro.js +31 -0
  168. package/dist/forja/resolver.js +121 -0
  169. package/dist/forja/texto.js +13 -0
  170. package/dist/forja/versao.js +71 -0
  171. package/dist/forja.js +123 -80
  172. package/dist/handoff.js +23 -13
  173. package/dist/hitl-contract.js +46 -43
  174. package/dist/hitl-curto.js +37 -25
  175. package/dist/hitl-gates.js +13 -11
  176. package/dist/hitl-local-receipt.js +51 -0
  177. package/dist/hitl-local.js +11 -2
  178. package/dist/hitl-lock.js +5 -11
  179. package/dist/hitl-public-receipt.js +11 -0
  180. package/dist/hitl-resumo.js +44 -1
  181. package/dist/hitl-sessions.js +62 -9
  182. package/dist/hitl-texto-livre.js +7 -4
  183. package/dist/hitl.js +34 -31
  184. package/dist/horario.js +16 -0
  185. package/dist/hosts.js +104 -134
  186. package/dist/index.js +848 -548
  187. package/dist/indice-vetorial.js +14 -12
  188. package/dist/init.js +11 -2
  189. package/dist/integracoes-locais.js +2 -0
  190. package/dist/intelligence-graph-cli.js +123 -69
  191. package/dist/intelligence-graph-query.js +37 -22
  192. package/dist/leases.js +19 -18
  193. package/dist/ledger-stats.js +17 -16
  194. package/dist/ledger.js +31 -1
  195. package/dist/licoes.js +12 -11
  196. package/dist/locale-accounts.js +220 -0
  197. package/dist/locale-adapter.js +291 -0
  198. package/dist/locale-ajuda.js +76 -4
  199. package/dist/locale-audit.js +199 -0
  200. package/dist/locale-claims.js +213 -0
  201. package/dist/locale-conducao.js +138 -0
  202. package/dist/locale-conhecimento.js +181 -0
  203. package/dist/locale-decisao.js +205 -0
  204. package/dist/locale-docs.js +230 -0
  205. package/dist/locale-estado.js +101 -0
  206. package/dist/locale-forja.js +290 -0
  207. package/dist/locale-gerados.js +5 -0
  208. package/dist/locale-grafo.js +129 -0
  209. package/dist/locale-master.js +83 -0
  210. package/dist/locale-network.js +524 -0
  211. package/dist/locale-operacao-restante.js +931 -0
  212. package/dist/locale-projetos.js +100 -0
  213. package/dist/locale-prompts.js +194 -0
  214. package/dist/locale-pulse.js +140 -2
  215. package/dist/locale-reservas.js +87 -0
  216. package/dist/locale-retry.js +145 -6
  217. package/dist/locale-security-scan.js +69 -0
  218. package/dist/locale-setup.js +192 -0
  219. package/dist/locale-ship.js +169 -66
  220. package/dist/locale-thread.js +149 -5
  221. package/dist/locale-verify.js +80 -4
  222. package/dist/locale-worktree.js +246 -0
  223. package/dist/locale.js +553 -9
  224. package/dist/maestro-runtime.js +22 -3
  225. package/dist/manifest.js +287 -11
  226. package/dist/maquina-ociosa.js +211 -0
  227. package/dist/maquina.js +10 -5
  228. package/dist/master-nota-local.js +200 -0
  229. package/dist/master-nota.js +10 -2
  230. package/dist/master.js +118 -41
  231. package/dist/mcp-conhecimento.js +52 -0
  232. package/dist/mcp-experiencia.js +26 -5
  233. package/dist/mcp-install.js +73 -8
  234. package/dist/mcp-noctum.js +101 -0
  235. package/dist/mcp-server.js +82 -14
  236. package/dist/mcp-ship-transporte.js +977 -0
  237. package/dist/mcp-ship.js +68 -24
  238. package/dist/mcp-transportes.js +17 -0
  239. package/dist/memoria.js +63 -58
  240. package/dist/modos-migracao.js +8 -6
  241. package/dist/modos.js +17 -18
  242. package/dist/network-roadmap.js +85 -49
  243. package/dist/noctum-aceite.js +789 -0
  244. package/dist/noctum-arco.js +540 -33
  245. package/dist/noctum-capacidade.js +3 -3
  246. package/dist/noctum-changelog.js +399 -0
  247. package/dist/noctum-cli.js +482 -0
  248. package/dist/noctum-coordenacao.js +1225 -0
  249. package/dist/noctum-entrega.js +1169 -0
  250. package/dist/noctum-envelope.js +252 -16
  251. package/dist/noctum-execucao.js +95 -23
  252. package/dist/noctum-fechamento.js +405 -0
  253. package/dist/noctum-fila.js +43 -9
  254. package/dist/noctum-guarda.js +256 -0
  255. package/dist/noctum-integracao.js +507 -0
  256. package/dist/noctum-maquinas.js +383 -0
  257. package/dist/noctum-medicao.js +450 -0
  258. package/dist/noctum-modo.js +362 -0
  259. package/dist/noctum-pergunta-canal.js +96 -0
  260. package/dist/noctum-pergunta.js +115 -0
  261. package/dist/noctum-provas.js +838 -0
  262. package/dist/noctum-reconciliacao.js +591 -0
  263. package/dist/noctum-registro.js +215 -0
  264. package/dist/noctum-relatorio.js +827 -0
  265. package/dist/noctum-resposta.js +207 -0
  266. package/dist/noctum-sessoes-em-voo.js +93 -0
  267. package/dist/noctum-supervisao.js +649 -0
  268. package/dist/noctum-terminal.js +459 -0
  269. package/dist/noctum-transporte.js +655 -0
  270. package/dist/noctum-vigia.js +639 -0
  271. package/dist/ocupacao.js +3 -1
  272. package/dist/onboarding.js +16 -5
  273. package/dist/orkmind.js +39 -23
  274. package/dist/orquestracao.js +31 -35
  275. package/dist/parado-no-condutor.js +146 -124
  276. package/dist/phase.js +53 -27
  277. package/dist/policies.js +33 -0
  278. package/dist/postura-local.js +4 -3
  279. package/dist/procedencia.js +9 -14
  280. package/dist/projeto-alvo.js +59 -20
  281. package/dist/prompts.js +136 -42
  282. package/dist/prova-minima.js +5 -6
  283. package/dist/pulse-cadencia.js +5 -4
  284. package/dist/pulse-consentimento.js +53 -1
  285. package/dist/pulse-delivery.js +143 -27
  286. package/dist/pulse-resposta.js +368 -4
  287. package/dist/pulse.js +136 -3
  288. package/dist/ratelimit.js +12 -4
  289. package/dist/recall.js +14 -13
  290. package/dist/rede-adesao.js +13 -8
  291. package/dist/rede-forja.js +108 -24
  292. package/dist/rede-status.js +63 -45
  293. package/dist/rede.js +86 -46
  294. package/dist/retomada-checkpoint.js +101 -0
  295. package/dist/retry.js +228 -73
  296. package/dist/roadmap-reservas.js +32 -32
  297. package/dist/runtime-ambiente.js +5 -0
  298. package/dist/runtime-context.js +117 -43
  299. package/dist/runtime-escada.js +423 -0
  300. package/dist/runtime-profiles.js +103 -46
  301. package/dist/saida-segura.js +3 -2
  302. package/dist/security-scan/agil.js +355 -0
  303. package/dist/security-scan/cli.js +76 -0
  304. package/dist/security-scan/compare.js +149 -0
  305. package/dist/security-scan/config.js +93 -0
  306. package/dist/security-scan/detect.js +97 -0
  307. package/dist/security-scan/executor.js +188 -0
  308. package/dist/security-scan/guard.js +180 -0
  309. package/dist/security-scan/imagem-de-lint.js +96 -0
  310. package/dist/security-scan/normalize/actionlint.js +12 -0
  311. package/dist/security-scan/normalize/eslint.js +12 -0
  312. package/dist/security-scan/normalize/gitleaks.js +13 -0
  313. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  314. package/dist/security-scan/normalize/govulncheck.js +36 -0
  315. package/dist/security-scan/normalize/index.js +25 -0
  316. package/dist/security-scan/normalize/npm-audit.js +30 -0
  317. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  318. package/dist/security-scan/normalize/oxlint.js +51 -0
  319. package/dist/security-scan/normalize/pip-audit.js +16 -0
  320. package/dist/security-scan/normalize/ruff.js +12 -0
  321. package/dist/security-scan/normalize/semgrep.js +20 -0
  322. package/dist/security-scan/normalize/trivy.js +33 -0
  323. package/dist/security-scan/normalize/util.js +204 -0
  324. package/dist/security-scan/normalize/zizmor.js +19 -0
  325. package/dist/security-scan/report.js +156 -0
  326. package/dist/security-scan/run.js +448 -0
  327. package/dist/security-scan/tools.js +62 -0
  328. package/dist/security-scan/trabalhador.js +74 -0
  329. package/dist/security-scan/types.js +15 -0
  330. package/dist/session-events.js +19 -2
  331. package/dist/session-watcher-claude.js +74 -19
  332. package/dist/session-watcher.js +156 -10
  333. package/dist/sessoes-contas.js +9 -0
  334. package/dist/sessoes-inventario.js +1 -1
  335. package/dist/sessoes.js +25 -23
  336. package/dist/setup.js +59 -58
  337. package/dist/ship-publicar.js +263 -92
  338. package/dist/ship.js +160 -17
  339. package/dist/superficie.js +14 -11
  340. package/dist/thread-close.js +9 -9
  341. package/dist/thread.js +121 -18
  342. package/dist/tokens.js +15 -11
  343. package/dist/trabalho-thread.js +297 -0
  344. package/dist/transporte-do-canal.js +189 -0
  345. package/dist/types.js +12 -1
  346. package/dist/util.js +5 -2
  347. package/dist/varredura-acoes.js +507 -0
  348. package/dist/verify.js +472 -29
  349. package/dist/worktree-local.js +12 -10
  350. package/dist/worktree.js +81 -85
  351. package/eval/casos/check-quality.json +77 -0
  352. package/eval/casos/security-auditor.json +148 -0
  353. package/eval/casos/security-remediation.json +161 -0
  354. package/eval/fixtures/security-scan/README.md +8 -0
  355. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  356. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  357. package/eval/fixtures/security-scan/go/README.md +4 -0
  358. package/eval/fixtures/security-scan/go/config.go +4 -0
  359. package/eval/fixtures/security-scan/go/go.mod +5 -0
  360. package/eval/fixtures/security-scan/go/go.sum +2 -0
  361. package/eval/fixtures/security-scan/go/main.go +31 -0
  362. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  363. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  364. package/eval/fixtures/security-scan/js/README.md +4 -0
  365. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  366. package/eval/fixtures/security-scan/js/package.json +10 -0
  367. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  368. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  369. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  370. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  371. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  372. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  373. package/eval/fixtures/security-scan/python/README.md +4 -0
  374. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  375. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  376. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  377. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  378. package/package.json +9 -4
  379. package/references/security-checklist.md +3 -3
  380. package/skills/README.md +1 -0
  381. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  382. package/skills/phases/check-quality/SKILL.md +16 -0
  383. package/skills/phases/go-implementation/SKILL.md +6 -0
  384. package/skills/phases/security-remediation/SKILL.md +70 -0
  385. package/skills/reviewers/security-auditor/SKILL.md +25 -0
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.LIMITES_DO_CONHECIMENTO = exports.REFERENCIA_DE_DECISAO = exports.NOME_DE_COLECAO = exports.ID_DE_DOCUMENTO = exports.CONTRATO_CONHECIMENTO = void 0;
36
+ exports.compararLacunas = exports.detalheDoConhecimento = exports.LIMITES_DO_CONHECIMENTO = exports.REFERENCIA_DE_DECISAO = exports.NOME_DE_COLECAO = exports.ID_DE_DOCUMENTO = exports.CONTRATO_CONHECIMENTO = void 0;
37
+ exports.lacunaDoConhecimento = lacunaDoConhecimento;
37
38
  exports.lerConhecimento = lerConhecimento;
38
39
  /**
39
40
  * RM-026 K7 (fatia 1): conhecimento escrito, no contrato `ork.conhecimento/v1`.
@@ -44,14 +45,17 @@ exports.lerConhecimento = lerConhecimento;
44
45
  *
45
46
  * Só leitura. Documento inválido ou referência que não confere vira lacuna tipada, nunca resposta (D4). A pasta
46
47
  * vem com o repositório e segue a fronteira da RM-047 (D6): relativa, dentro da raiz pelo caminho real, sem
47
- * seguir link e sem executar nada. Nesta fatia a decisão confere no ledger canônico e o id do Brain só pela forma
48
- * (D5); a CLI, as tools MCP e a conferência pelo Brain chegam nas fatias 2 e 3. Contrato:
48
+ * seguir link e sem executar nada. O leitor confere a decisão no ledger canônico e o id do Brain só pela forma
49
+ * (D5); a conferência por `get` mora na consulta (`conhecimento-consulta.ts`, fatia 2), a porta pública da CLI e das
50
+ * tools MCP. O detalhe das lacunas sai pelo catálogo (família `conhecimento`). Contrato:
49
51
  * docs/referencia/contratos/conhecimento-rm026.md.
50
52
  */
51
53
  const fs = __importStar(require("node:fs"));
52
54
  const path = __importStar(require("node:path"));
55
+ const node_buffer_1 = require("node:buffer");
53
56
  const company_brain_journal_1 = require("./company-brain-journal");
54
57
  const docs_1 = require("./docs");
58
+ const locale_1 = require("./locale");
55
59
  const portfolio_1 = require("./portfolio");
56
60
  const saida_segura_1 = require("./saida-segura");
57
61
  const thread_1 = require("./thread");
@@ -76,14 +80,21 @@ const reservada = (segmento) => PASTAS_RESERVADAS.includes(segmento.toLowerCase(
76
80
  const INVISIVEIS = new RegExp(saida_segura_1.INVISIVEL.source, 'gu');
77
81
  exports.LIMITES_DO_CONHECIMENTO = Object.freeze({
78
82
  entradas: 5000, profundidade: 8, bytesPorDocumento: 1024 * 1024, bytesDoFrontmatter: 16 * 1024,
79
- bytesNoTotal: 32 * 1024 * 1024, bytesDoLedger: 16 * 1024 * 1024,
83
+ bytesNoTotal: 32 * 1024 * 1024, bytesDoLedger: 16 * 1024 * 1024, bytesDosLedgers: 64 * 1024 * 1024,
84
+ getsDoBrain: 100, msDaConferencia: 60 * 1000,
80
85
  });
81
86
  const comparar = (a, b) => a < b ? -1 : a > b ? 1 : 0;
82
87
  const ehMapa = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
83
88
  /** Texto que veio do repositório, pronto para a resposta: numa linha, sem invisível e, com teto, cortado sem partir caractere. */
84
89
  const limpo = (v, teto = Infinity) => Array.from((0, saida_segura_1.emUmaLinha)(v)).slice(0, teto).join('');
85
90
  const relativo = (raizReal, abs) => path.relative(raizReal, abs).split(path.sep).join('/');
86
- const LINK = 'link simbólico não é seguido; o documento é o arquivo versionado';
91
+ /**
92
+ * O detalhe de uma lacuna, pelo catálogo (D13 da fatia 2): nasce no locale ativo, o pt-BR do `--json` e do MCP, e a
93
+ * impressão do comando coberto o remonta no locale dela.
94
+ */
95
+ const detalheDoConhecimento = (montar) => (0, locale_1.textoDoCatalogo)((m) => montar(m.conhecimento.lacunas));
96
+ exports.detalheDoConhecimento = detalheDoConhecimento;
97
+ const t = exports.detalheDoConhecimento;
87
98
  /** `stat` que nunca lança: a pasta que some ou não abre vale como ausente. */
88
99
  const statOuNulo = (p) => { try {
89
100
  return fs.statSync(p, { throwIfNoEntry: false }) ?? null;
@@ -91,10 +102,15 @@ const statOuNulo = (p) => { try {
91
102
  catch {
92
103
  return null;
93
104
  } };
94
- function lacuna(codigo, detalhe, onde = {}) {
105
+ /** Uma lacuna, com a referência como escrita, numa linha e cortada (a mesma regra no leitor e na consulta). */
106
+ function lacunaDoConhecimento(codigo, detalhe, onde = {}) {
95
107
  return { codigo, arquivo: onde.arquivo ?? null, documento: onde.documento ?? null,
96
108
  referencia: typeof onde.referencia === 'string' ? limpo(onde.referencia, 200) : null, detalhe };
97
109
  }
110
+ const lacuna = lacunaDoConhecimento;
111
+ /** A ordem estável das lacunas: por arquivo, código e referência. */
112
+ const compararLacunas = (a, b) => comparar(a.arquivo ?? '', b.arquivo ?? '') || comparar(a.codigo, b.codigo) || comparar(a.referencia ?? '', b.referencia ?? '');
113
+ exports.compararLacunas = compararLacunas;
98
114
  /**
99
115
  * D6: a pasta declarada, pelo caminho real. A forma recusa antes de tocar o disco (vazia, absoluta, `..`, `\`,
100
116
  * invisível, a própria raiz, `.git` e `.orkastery`); o caminho real, com os links resolvidos, precisa ficar dentro
@@ -104,8 +120,7 @@ function pastaDoConhecimento(raiz, dir) {
104
120
  const segmentos = dir.split('/').filter((s) => s !== '' && s !== '.');
105
121
  if (path.isAbsolute(dir) || dir.includes('\\') || saida_segura_1.INVISIVEL.test(dir) || !segmentos.length || segmentos.includes('..') ||
106
122
  reservada(segmentos[0])) {
107
- return lacuna('conhecimento.dir-invalido', 'conhecimento.dir precisa ser uma pasta relativa à raiz, sem "..", ' +
108
- 'fora de .git e .orkastery, como docs/conhecimento; nada foi lido');
123
+ return lacuna('conhecimento.dir-invalido', t((l) => l.dirForma));
109
124
  }
110
125
  let raizReal, real;
111
126
  try {
@@ -113,19 +128,17 @@ function pastaDoConhecimento(raiz, dir) {
113
128
  real = fs.realpathSync(path.join(raizReal, ...segmentos));
114
129
  }
115
130
  catch {
116
- return lacuna('conhecimento.dir-ausente', 'a pasta de conhecimento.dir não existe ou não abre');
131
+ return lacuna('conhecimento.dir-ausente', t((l) => l.dirNaoAbre));
117
132
  }
118
133
  const rel = path.relative(raizReal, real);
119
134
  if (rel === '..' || rel.startsWith('..' + path.sep) || path.isAbsolute(rel)) {
120
- return lacuna('conhecimento.dir-fora-da-raiz', 'pelo caminho real (links resolvidos), conhecimento.dir sai da raiz ' +
121
- 'do projeto; o manifesto vem com o repositório e não escolhe caminho fora dela; nada foi lido');
135
+ return lacuna('conhecimento.dir-fora-da-raiz', t((l) => l.dirForaDaRaiz));
122
136
  }
123
137
  if (rel === '' || reservada(rel.split(path.sep)[0]) || saida_segura_1.INVISIVEL.test(rel)) {
124
- return lacuna('conhecimento.dir-invalido', 'pelo caminho real, conhecimento.dir é a própria raiz, cai em .git ou ' +
125
- '.orkastery, ou tem caractere invisível; nada foi lido');
138
+ return lacuna('conhecimento.dir-invalido', t((l) => l.dirReal));
126
139
  }
127
140
  if (!statOuNulo(real)?.isDirectory())
128
- return lacuna('conhecimento.dir-ausente', 'conhecimento.dir não é uma pasta');
141
+ return lacuna('conhecimento.dir-ausente', t((l) => l.dirNaoEPasta));
129
142
  return { real, raizReal };
130
143
  }
131
144
  /**
@@ -148,7 +161,7 @@ function varrer(real, raizReal, limites, lacunas) {
148
161
  realDaPasta = null;
149
162
  }
150
163
  if (realDaPasta !== atual.abs) {
151
- lacunas.push(lacuna('documento.link', LINK, { arquivo: relativo(raizReal, atual.abs) }));
164
+ lacunas.push(lacuna('documento.link', t((l) => l.link), { arquivo: relativo(raizReal, atual.abs) }));
152
165
  continue;
153
166
  }
154
167
  let nomes;
@@ -156,17 +169,17 @@ function varrer(real, raizReal, limites, lacunas) {
156
169
  nomes = fs.readdirSync(atual.abs, { encoding: 'buffer' }).sort(Buffer.compare);
157
170
  }
158
171
  catch {
159
- lacunas.push(lacuna('documento.nao-regular', 'a pasta não abriu para leitura; o que está nela não foi lido', { arquivo: relativo(raizReal, atual.abs) }));
172
+ lacunas.push(lacuna('documento.nao-regular', t((l) => l.pastaNaoAbriu), { arquivo: relativo(raizReal, atual.abs) }));
160
173
  continue;
161
174
  }
162
175
  for (const bruto of nomes) {
163
176
  if (bruto[0] === 0x2e)
164
177
  continue;
165
178
  if (++entradas > limites.entradas)
166
- return { teto: `a pasta passa de ${limites.entradas} entradas` };
179
+ return { teto: t((l) => l.limiteEntradas(limites.entradas)) };
167
180
  const nome = bruto.toString('utf8');
168
181
  if (!Buffer.from(nome, 'utf8').equals(bruto) || saida_segura_1.INVISIVEL.test(nome)) {
169
- lacunas.push(lacuna('documento.nome-invalido', 'nome fora de UTF-8 ou com caractere invisível; não foi lido', { arquivo: relativo(raizReal, path.join(atual.abs, nome.replace(INVISIVEIS, '?'))) }));
182
+ lacunas.push(lacuna('documento.nome-invalido', t((l) => l.nomeInvalido), { arquivo: relativo(raizReal, path.join(atual.abs, nome.replace(INVISIVEIS, '?'))) }));
170
183
  continue;
171
184
  }
172
185
  const abs = path.join(atual.abs, nome), arquivo = relativo(raizReal, abs);
@@ -175,25 +188,25 @@ function varrer(real, raizReal, limites, lacunas) {
175
188
  st = fs.lstatSync(abs, { throwIfNoEntry: false });
176
189
  }
177
190
  catch {
178
- lacunas.push(lacuna('documento.nao-regular', 'a entrada não abriu para leitura; não foi lida', { arquivo }));
191
+ lacunas.push(lacuna('documento.nao-regular', t((l) => l.entradaNaoAbriu), { arquivo }));
179
192
  continue;
180
193
  }
181
194
  if (!st)
182
195
  continue;
183
196
  if (st.isSymbolicLink()) {
184
- lacunas.push(lacuna('documento.link', LINK, { arquivo }));
197
+ lacunas.push(lacuna('documento.link', t((l) => l.link), { arquivo }));
185
198
  continue;
186
199
  }
187
200
  if (st.isDirectory()) {
188
201
  if (atual.profundidade + 1 > limites.profundidade)
189
- return { teto: `a pasta passa de ${limites.profundidade} níveis` };
202
+ return { teto: t((l) => l.limiteNiveis(limites.profundidade)) };
190
203
  pilha.push({ abs, profundidade: atual.profundidade + 1 });
191
204
  continue;
192
205
  }
193
206
  if (!(0, docs_1.ehPaginaDeDocs)(nome))
194
207
  continue;
195
208
  if (!st.isFile()) {
196
- lacunas.push(lacuna('documento.nao-regular', 'não é arquivo comum; não foi lido', { arquivo }));
209
+ lacunas.push(lacuna('documento.nao-regular', t((l) => l.naoRegular), { arquivo }));
197
210
  continue;
198
211
  }
199
212
  candidatos.push({ abs, arquivo, st });
@@ -254,50 +267,47 @@ function lista(v) {
254
267
  /** D2 e D3: o frontmatter vale inteiro ou devolve a lacuna do primeiro problema, com o id quando ele já vale. */
255
268
  function validarFrontmatter(dados, arquivo) {
256
269
  if (!ehMapa(dados))
257
- return lacuna('documento.frontmatter-invalido', 'o frontmatter precisa ser um mapa de chaves', { arquivo });
270
+ return lacuna('documento.frontmatter-invalido', t((l) => l.frontmatterNaoEMapa), { arquivo });
258
271
  const id = typeof dados.id === 'string' && exports.ID_DE_DOCUMENTO.test(dados.id) ? dados.id : null;
259
- if (!id) {
260
- return lacuna('documento.id-invalido', 'id precisa ser doc- seguido de 3 a 48 letras minúsculas, números ou hífens, ' +
261
- 'começando por letra ou número', { arquivo });
262
- }
272
+ if (!id)
273
+ return lacuna('documento.id-invalido', t((l) => l.idInvalido), { arquivo });
263
274
  const onde = { arquivo, documento: id };
264
275
  const estranhas = Object.keys(dados).filter((k) => !CHAVES_DO_DOCUMENTO.includes(k));
265
276
  if (estranhas.length) {
266
- return lacuna('documento.chave-desconhecida', `chave fora do contrato: ${estranhas.map((k) => JSON.stringify(limpo(k, 40))).join(', ')} ` +
267
- `(o frontmatter tem só ${CHAVES_DO_DOCUMENTO.join(', ')})`, onde);
277
+ const chaves = estranhas.map((k) => JSON.stringify(limpo(k, 40))).join(', ');
278
+ return lacuna('documento.chave-desconhecida', t((l) => l.chaveDesconhecida(chaves, CHAVES_DO_DOCUMENTO.join(', '))), onde);
268
279
  }
269
280
  const titulo = typeof dados.titulo === 'string' ? dados.titulo.trim() : '';
270
281
  if (!titulo || titulo.length > LIMITE_DO_TITULO || saida_segura_1.INVISIVEL.test(titulo)) {
271
- return lacuna('documento.titulo-invalido', `titulo precisa ser texto de 1 a ${LIMITE_DO_TITULO} caracteres, ` +
272
- 'sem caractere de controle', onde);
282
+ return lacuna('documento.titulo-invalido', t((l) => l.tituloInvalido(LIMITE_DO_TITULO)), onde);
273
283
  }
274
284
  const colecoes = lista(dados.colecoes);
275
285
  if (!colecoes || !colecoes.length || colecoes.length > COLECOES_POR_DOCUMENTO ||
276
286
  colecoes.some((c) => !exports.NOME_DE_COLECAO.test(c)) || new Set(colecoes).size !== colecoes.length) {
277
- return lacuna('documento.colecoes-invalidas', `colecoes precisa listar de 1 a ${COLECOES_POR_DOCUMENTO} nomes ` +
278
- 'de 1 a 48 letras minúsculas, números ou hífens, sem repetir', onde);
287
+ return lacuna('documento.colecoes-invalidas', t((l) => l.colecoesInvalidas(COLECOES_POR_DOCUMENTO)), onde);
279
288
  }
280
289
  const refs = dados.referencias ?? null;
281
290
  const brain = ehMapa(refs) ? lista(refs.brain) : [], decisoes = ehMapa(refs) ? lista(refs.decisoes) : [];
282
291
  if ((refs !== null && !ehMapa(refs)) || (ehMapa(refs) && Object.keys(refs).some((k) => !CHAVES_DAS_REFERENCIAS.includes(k))) ||
283
292
  !brain || brain.length > REFERENCIAS_POR_LISTA || !decisoes || decisoes.length > REFERENCIAS_POR_LISTA) {
284
- return lacuna('documento.referencias-invalidas', 'referencias é um mapa só com brain e decisoes, cada uma uma lista ' +
285
- `de até ${REFERENCIAS_POR_LISTA} textos`, onde);
293
+ return lacuna('documento.referencias-invalidas', t((l) => l.referenciasInvalidas(REFERENCIAS_POR_LISTA)), onde);
286
294
  }
287
295
  return { id, titulo, colecoes: [...colecoes].sort(comparar), brain: [...new Set(brain)], decisoes: [...new Set(decisoes)] };
288
296
  }
289
297
  /**
290
298
  * As linhas citadas do ledger canônico de uma thread (D5). O ledger é lido como a captura do Brain o lê
291
299
  * (`readCycle`): só linhas completas, em UTF-8 exato, para o sha256 da linha ser o `source_hash` dela no Brain.
292
- * Cada ledger é lido uma vez, e só as linhas citadas ficam na memória.
300
+ * Cada ledger é lido uma vez, até a maior linha citada, e só as linhas citadas viram texto (fatia 2: a leitura não parte
301
+ * o ledger inteiro em linhas). `completas` é exato quando alguma linha citada passa do fim, o único caso em que ele é
302
+ * dito. O `orcamento` é o que resta do teto de bytes dos ledgers da leitura.
293
303
  */
294
- function linhasCitadas(raiz, thread, citadas, teto) {
304
+ function linhasCitadas(raiz, thread, citadas, limites, orcamento) {
295
305
  let arquivo;
296
306
  try {
297
307
  arquivo = path.join((0, thread_1.dirThread)(raiz, thread), 'ledger.jsonl');
298
308
  }
299
309
  catch {
300
- return { motivo: 'a pasta da thread no estado do projeto é link ou fica fora da regra de id' };
310
+ return { motivo: t((l) => l.ledgerLinkOuId) };
301
311
  }
302
312
  let st;
303
313
  try {
@@ -306,36 +316,46 @@ function linhasCitadas(raiz, thread, citadas, teto) {
306
316
  catch (e) {
307
317
  // A pasta da thread que é arquivo comum dá ENOTDIR: a thread não tem ledger, e nada lança.
308
318
  if (e.code !== 'ENOTDIR')
309
- return { motivo: `o ledger da thread ${thread} não abriu para leitura` };
319
+ return { motivo: t((l) => l.ledgerNaoAbriu(thread)) };
310
320
  }
311
321
  if (!st)
312
- return { motivo: `a thread ${thread} não tem ledger neste projeto` };
313
- const bytes = lerArquivo(arquivo, st, teto, true);
322
+ return { motivo: t((l) => l.semLedger(thread)) };
323
+ if (st.size > orcamento.restante)
324
+ return { motivo: t((l) => l.ledgersDemais(limites.bytesDosLedgers / 1024 / 1024)) };
325
+ const bytes = lerArquivo(arquivo, st, limites.bytesDoLedger, true);
314
326
  if (!Buffer.isBuffer(bytes))
315
- return { motivo: `o ledger da thread ${thread} não é arquivo comum de até ${teto / 1024 / 1024} MiB` };
316
- const fim = bytes.lastIndexOf(10) + 1;
317
- const completo = bytes.subarray(0, fim).toString('utf8');
318
- if (!Buffer.from(completo, 'utf8').equals(bytes.subarray(0, fim)))
319
- return { motivo: `o ledger da thread ${thread} não é UTF-8` };
320
- const todas = completo.split('\n').slice(0, -1);
321
- const linhas = new Map();
327
+ return { motivo: t((l) => l.ledgerNaoRegular(thread, limites.bytesDoLedger / 1024 / 1024)) };
328
+ orcamento.restante -= bytes.length;
329
+ const completo = bytes.subarray(0, bytes.lastIndexOf(10) + 1);
330
+ if (!(0, node_buffer_1.isUtf8)(completo))
331
+ return { motivo: t((l) => l.ledgerNaoUtf8(thread)) };
332
+ let maior = 0;
322
333
  for (const n of citadas)
323
- if (n <= todas.length)
324
- linhas.set(n, todas[n - 1]);
325
- return { linhas, completas: todas.length };
334
+ if (n > maior)
335
+ maior = n;
336
+ const linhas = new Map();
337
+ let inicio = 0, n = 0;
338
+ while (inicio < completo.length && n < maior) {
339
+ const fimDaLinha = completo.indexOf(10, inicio);
340
+ n++;
341
+ if (citadas.has(n))
342
+ linhas.set(n, completo.subarray(inicio, fimDaLinha).toString('utf8'));
343
+ inicio = fimDaLinha + 1;
344
+ }
345
+ return { linhas, completas: n };
326
346
  }
327
347
  /** D5: a referência `thread#linha` confere quando a linha completa existe, é da thread e é uma decisão. */
328
348
  function conferirDecisao(ref, ledgers) {
329
349
  const m = exports.REFERENCIA_DE_DECISAO.exec(ref);
330
350
  if (!m)
331
- return { codigo: 'referencia.invalida', detalhe: 'decisão é <thread>#<linha>, com o id da thread e a linha do ledger a partir de 1' };
351
+ return { codigo: 'referencia.invalida', detalhe: t((l) => l.decisaoForma) };
332
352
  const thread = m[1], linha = Number(m[2]);
333
353
  const ledger = ledgers.get(thread);
334
354
  if ('motivo' in ledger)
335
355
  return { codigo: 'referencia.decisao-ausente', detalhe: ledger.motivo };
336
356
  const bruta = ledger.linhas.get(linha);
337
357
  if (bruta === undefined) {
338
- return { codigo: 'referencia.decisao-ausente', detalhe: `o ledger da thread ${thread} tem ${ledger.completas} linha(s) completa(s)` };
358
+ return { codigo: 'referencia.decisao-ausente', detalhe: t((l) => l.linhasCompletas(thread, ledger.completas)) };
339
359
  }
340
360
  let evento = null;
341
361
  try {
@@ -344,15 +364,14 @@ function conferirDecisao(ref, ledgers) {
344
364
  evento = lido;
345
365
  }
346
366
  catch { /* linha que não é JSON não é decisão */ }
347
- const onde = `a linha ${linha} do ledger da thread ${thread}`;
348
367
  if (!evento)
349
- return { codigo: 'referencia.nao-e-decisao', detalhe: `${onde} não é um evento JSON` };
368
+ return { codigo: 'referencia.nao-e-decisao', detalhe: t((l) => l.naoEJson(linha, thread)) };
350
369
  if (evento.thread !== thread)
351
- return { codigo: 'referencia.nao-e-decisao', detalhe: `${onde} é de outra thread` };
352
- const tipo = TIPOS_DE_DECISAO.find((t) => t === evento?.tipo);
370
+ return { codigo: 'referencia.nao-e-decisao', detalhe: t((l) => l.outraThread(linha, thread)) };
371
+ const tipo = TIPOS_DE_DECISAO.find((x) => x === evento?.tipo);
353
372
  if (!tipo) {
354
- const visto = typeof evento.tipo === 'string' && /^[a-z_]{1,40}$/.test(evento.tipo) ? evento.tipo : 'sem tipo conhecido';
355
- return { codigo: 'referencia.nao-e-decisao', detalhe: `${onde} é ${visto}, não decisão (${TIPOS_DE_DECISAO.join(', ')})` };
373
+ const visto = typeof evento.tipo === 'string' && /^[a-z_]{1,40}$/.test(evento.tipo) ? evento.tipo : null;
374
+ return { codigo: 'referencia.nao-e-decisao', detalhe: t((l) => l.naoEDecisao(linha, thread, visto, TIPOS_DE_DECISAO.join(', '))) };
356
375
  }
357
376
  return { ref, thread, linha, tipo, fonte: `threads/${thread}/ledger.jsonl#L${linha}`, sha256: (0, company_brain_journal_1.bytesHash)(bruta) };
358
377
  }
@@ -360,16 +379,16 @@ function conferirDecisao(ref, ledgers) {
360
379
  * Lê o conhecimento declarado no manifesto: documentos válidos, coleções e lacunas, tudo em ordem estável.
361
380
  * Nunca lança por causa do conteúdo do repositório; o que não vale vira lacuna tipada.
362
381
  */
363
- function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
382
+ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO, opcoes = {}) {
364
383
  const declarado = c.manifesto.conhecimento?.dir ?? null;
365
384
  const dir = declarado === null ? null : limpo(declarado);
366
385
  const so = (l) => ({ contrato: exports.CONTRATO_CONHECIMENTO, dir, documentos: [], colecoes: [], lacunas: [l] });
367
386
  if (declarado === null)
368
- return so(lacuna('conhecimento.nao-declarado', 'o orkastery.yaml não declara conhecimento.dir'));
387
+ return so(lacuna('conhecimento.nao-declarado', t((l) => l.naoDeclarado)));
369
388
  const pasta = pastaDoConhecimento(c.raiz, declarado);
370
389
  if ('codigo' in pasta)
371
390
  return so(pasta);
372
- const teto = (detalhe) => so(lacuna('conhecimento.limite', `${detalhe}; nenhum documento foi devolvido`));
391
+ const teto = (detalhe) => so(lacuna('conhecimento.limite', detalhe));
373
392
  const lacunas = [];
374
393
  const candidatos = varrer(pasta.real, pasta.raizReal, limites, lacunas);
375
394
  if (!Array.isArray(candidatos))
@@ -381,35 +400,35 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
381
400
  for (const { abs, arquivo, st } of candidatos) {
382
401
  const bytes = lerArquivo(abs, st, limites.bytesPorDocumento);
383
402
  if (bytes === 'link') {
384
- lacunas.push(lacuna('documento.link', LINK, { arquivo }));
403
+ lacunas.push(lacuna('documento.link', t((l) => l.link), { arquivo }));
385
404
  continue;
386
405
  }
387
406
  if (bytes === 'nao-regular') {
388
- lacunas.push(lacuna('documento.nao-regular', 'não abriu como arquivo comum, ou mudou durante a leitura', { arquivo }));
407
+ lacunas.push(lacuna('documento.nao-regular', t((l) => l.naoAbriuComoArquivo), { arquivo }));
389
408
  continue;
390
409
  }
391
410
  if (bytes === 'grande') {
392
- lacunas.push(lacuna('documento.grande-demais', `o documento passa de ${limites.bytesPorDocumento / 1024} KiB`, { arquivo }));
411
+ lacunas.push(lacuna('documento.grande-demais', t((l) => l.grandeDemais(limites.bytesPorDocumento / 1024)), { arquivo }));
393
412
  continue;
394
413
  }
395
414
  total += bytes.length;
396
415
  if (total > limites.bytesNoTotal)
397
- return teto(`os documentos passam de ${limites.bytesNoTotal / 1024 / 1024} MiB no total`);
416
+ return teto(t((l) => l.limiteTotal(limites.bytesNoTotal / 1024 / 1024)));
398
417
  let texto;
399
418
  try {
400
419
  texto = decodificador.decode(bytes);
401
420
  }
402
421
  catch {
403
- lacunas.push(lacuna('documento.codificacao', 'o arquivo não é UTF-8', { arquivo }));
422
+ lacunas.push(lacuna('documento.codificacao', t((l) => l.codificacao), { arquivo }));
404
423
  continue;
405
424
  }
406
- const { bruto } = (0, docs_1.separarFrontmatter)(texto);
425
+ const { bruto, corpo } = (0, docs_1.separarFrontmatter)(texto);
407
426
  if (bruto === null) {
408
- lacunas.push(lacuna('documento.sem-frontmatter', 'o arquivo não começa com o frontmatter entre duas linhas ---', { arquivo }));
427
+ lacunas.push(lacuna('documento.sem-frontmatter', t((l) => l.semFrontmatter), { arquivo }));
409
428
  continue;
410
429
  }
411
430
  if (Buffer.byteLength(bruto, 'utf8') > limites.bytesDoFrontmatter) {
412
- lacunas.push(lacuna('documento.frontmatter-invalido', `o frontmatter passa de ${limites.bytesDoFrontmatter / 1024} KiB`, { arquivo }));
431
+ lacunas.push(lacuna('documento.frontmatter-invalido', t((l) => l.frontmatterGrande(limites.bytesDoFrontmatter / 1024)), { arquivo }));
413
432
  continue;
414
433
  }
415
434
  let dados;
@@ -418,7 +437,8 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
418
437
  dados = (0, yaml_1.lerYaml)('---\n' + bruto, { estrito: true });
419
438
  }
420
439
  catch (e) {
421
- lacunas.push(lacuna('documento.frontmatter-invalido', limpo(e.message, 200), { arquivo }));
440
+ const erro = limpo(e.message, 200);
441
+ lacunas.push(lacuna('documento.frontmatter-invalido', t((l) => l.frontmatterYaml(erro)), { arquivo }));
422
442
  continue;
423
443
  }
424
444
  // D4: o id na forma certa conta para a regra do repetido mesmo quando o resto do documento não vale.
@@ -430,28 +450,33 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
430
450
  lacunas.push(v);
431
451
  continue;
432
452
  }
433
- validos.push({ ...v, arquivo, bytes: bytes.length, sha256: (0, company_brain_journal_1.bytesHash)(bytes) });
453
+ validos.push({ ...v, arquivo, bytes: bytes.length, sha256: (0, company_brain_journal_1.bytesHash)(bytes), ...(v.id === opcoes.corpoDe ? { corpo } : {}) });
434
454
  }
435
455
  // D4: id repetido não escolhe arquivo; todos os documentos com ele saem da resposta, também quando a outra
436
456
  // cópia não vale por outro motivo (ela já tem a lacuna dela).
437
457
  const unicos = validos.filter((v) => {
438
458
  const vezes = declarados.get(v.id);
439
459
  if (vezes > 1) {
440
- lacunas.push(lacuna('documento.id-repetido', `o id aparece em ${vezes} arquivos; nenhum deles vale até sobrar um`, { arquivo: v.arquivo, documento: v.id }));
460
+ lacunas.push(lacuna('documento.id-repetido', t((l) => l.idRepetido(vezes)), { arquivo: v.arquivo, documento: v.id }));
441
461
  }
442
462
  return vezes === 1;
443
463
  });
444
- // D5: cada ledger citado é lido uma vez, com as linhas que os documentos válidos pedem.
464
+ // D5: cada ledger citado é lido uma vez, com as linhas que os documentos válidos pedem, em ordem de thread e até o
465
+ // teto de bytes da leitura. Fatia 2: só os documentos cujas decisões a consulta mostra (`decisoesDe`).
466
+ const decisoesDe = opcoes.decisoesDe ?? 'todos';
467
+ const confere = (id) => decisoesDe === 'todos' || decisoesDe === id;
445
468
  const citadas = new Map();
446
469
  for (const v of unicos)
447
- for (const ref of v.decisoes) {
448
- const m = exports.REFERENCIA_DE_DECISAO.exec(ref);
449
- if (m)
450
- citadas.set(m[1], (citadas.get(m[1]) ?? new Set()).add(Number(m[2])));
451
- }
452
- const ledgers = new Map();
453
- for (const [thread, linhas] of citadas)
454
- ledgers.set(thread, linhasCitadas(c.raiz, thread, linhas, limites.bytesDoLedger));
470
+ if (confere(v.id))
471
+ for (const ref of v.decisoes) {
472
+ const m = exports.REFERENCIA_DE_DECISAO.exec(ref);
473
+ if (m)
474
+ citadas.set(m[1], (citadas.get(m[1]) ?? new Set()).add(Number(m[2])));
475
+ }
476
+ const ledgers = new Map(), orcamento = { restante: limites.bytesDosLedgers };
477
+ for (const thread of [...citadas.keys()].sort(comparar)) {
478
+ ledgers.set(thread, linhasCitadas(c.raiz, thread, citadas.get(thread), limites, orcamento));
479
+ }
455
480
  const documentos = [];
456
481
  for (const v of unicos) {
457
482
  const onde = { arquivo: v.arquivo, documento: v.id };
@@ -460,9 +485,9 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
460
485
  if (portfolio_1.ID_DE_ENTIDADE.test(referencia))
461
486
  brain.push(referencia);
462
487
  else
463
- lacunas.push(lacuna('referencia.invalida', 'id do Brain é prod-, proj- ou init-, na regra dos ids do portfólio', { ...onde, referencia }));
488
+ lacunas.push(lacuna('referencia.invalida', t((l) => l.brainForma), { ...onde, referencia }));
464
489
  }
465
- for (const referencia of v.decisoes) {
490
+ for (const referencia of confere(v.id) ? v.decisoes : []) {
466
491
  const r = conferirDecisao(referencia, ledgers);
467
492
  if ('codigo' in r)
468
493
  lacunas.push(lacuna(r.codigo, r.detalhe, { ...onde, referencia }));
@@ -471,7 +496,7 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
471
496
  }
472
497
  documentos.push({ id: v.id, titulo: v.titulo, colecoes: v.colecoes,
473
498
  referencias: { brain: brain.sort(comparar), decisoes: decisoes.sort((a, b) => comparar(a.thread, b.thread) || a.linha - b.linha) },
474
- arquivo: v.arquivo, bytes: v.bytes, sha256: v.sha256 });
499
+ arquivo: v.arquivo, bytes: v.bytes, sha256: v.sha256, ...(v.corpo !== undefined ? { corpo: v.corpo } : {}) });
475
500
  }
476
501
  const colecoes = new Map();
477
502
  for (const d of documentos)
@@ -484,7 +509,6 @@ function lerConhecimento(c, limites = exports.LIMITES_DO_CONHECIMENTO) {
484
509
  contrato: exports.CONTRATO_CONHECIMENTO, dir,
485
510
  documentos: documentos.sort((a, b) => comparar(a.id, b.id)),
486
511
  colecoes: [...colecoes].map(([nome, ids]) => ({ nome, documentos: ids.sort(comparar) })).sort((a, b) => comparar(a.nome, b.nome)),
487
- lacunas: lacunas.sort((a, b) => comparar(a.arquivo ?? '', b.arquivo ?? '') || comparar(a.codigo, b.codigo) ||
488
- comparar(a.referencia ?? '', b.referencia ?? '')),
512
+ lacunas: lacunas.sort(exports.compararLacunas),
489
513
  };
490
514
  }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reconciliarContaEsgotada = reconciliarContaEsgotada;
4
+ /** RM-064 T1/T2: uma cota esgotada pertence à conta, não só à sessão que a revelou. */
5
+ const node_crypto_1 = require("node:crypto");
6
+ const claude_bg_1 = require("./adapters/claude-bg");
7
+ const hitl_sessions_1 = require("./hitl-sessions");
8
+ const ledger_1 = require("./ledger");
9
+ const projeto_alvo_1 = require("./projeto-alvo");
10
+ const runtime_profiles_1 = require("./runtime-profiles");
11
+ const session_events_1 = require("./session-events");
12
+ const sessoes_inventario_1 = require("./sessoes-inventario");
13
+ const thread_1 = require("./thread");
14
+ const sha = (v) => (0, node_crypto_1.createHash)('sha256').update(JSON.stringify(v)).digest('hex');
15
+ const padrao = {
16
+ inventario: (raiz) => (0, sessoes_inventario_1.inventariarSessoes)(raiz, { global: true, todas: true, prazoMs: 30_000 }),
17
+ projetos: (raiz) => [...new Set([raiz, ...(0, projeto_alvo_1.listarProjetos)().filter((p) => p.presente).map((p) => p.raiz)])],
18
+ parar: (sessionId, id, perfil, vinculo) => {
19
+ if (perfil.runtime === 'codex') {
20
+ if (!vinculo)
21
+ return { ok: false, detalhe: 'vínculo canônico do controller ausente' };
22
+ try {
23
+ const ctl = (0, hitl_sessions_1.controleNativo)('codex', vinculo.raiz, vinculo.thread, sessionId);
24
+ const consulta = ctl.consultar();
25
+ const candidatas = consulta.sessoes.filter((s) => s.sessionId === sessionId && s.runtime === 'codex');
26
+ if (!consulta.ok || candidatas.length !== 1)
27
+ return { ok: false, detalhe: 'controller codex não confirmou identidade única' };
28
+ return { ok: ctl.parar(candidatas[0]), detalhe: 'controller codex vinculado recebeu interrupção' };
29
+ }
30
+ catch (e) {
31
+ return { ok: false, detalhe: e.message };
32
+ }
33
+ }
34
+ const r = (0, claude_bg_1.pararAchada)({ sessionId, ...(id ? { id } : {}) }, (0, claude_bg_1.ambienteDoPerfil)(perfil));
35
+ return { ok: r.ok, detalhe: r.texto || (r.ok ? 'runtime confirmou a parada' : 'runtime recusou a parada') };
36
+ },
37
+ };
38
+ function vinculosDaConta(projetos, sessionId, conta) {
39
+ const vinculos = [], falhas = [];
40
+ for (const raiz of projetos) {
41
+ let ids;
42
+ try {
43
+ ids = (0, thread_1.listarIds)(raiz);
44
+ }
45
+ catch (e) {
46
+ falhas.push(`projeto não lido: ${e.message}`);
47
+ continue;
48
+ }
49
+ for (const id of ids) {
50
+ try {
51
+ const thread = (0, thread_1.lerThread)(raiz, id);
52
+ const sessao = thread.sessoes.find((s) => s.sessionId === sessionId && s.origem !== 'adocao');
53
+ if (!sessao?.despachadaEm)
54
+ continue;
55
+ const eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, id));
56
+ const perfil = (0, runtime_profiles_1.perfilDoRegistro)(eventos, { sessionId, despachadaEm: sessao.despachadaEm });
57
+ if (!perfil || (0, runtime_profiles_1.chaveDaConta)(perfil) !== conta)
58
+ continue;
59
+ vinculos.push({ raiz, thread: id, fase: sessao.fase, despachoEm: sessao.despachadaEm });
60
+ }
61
+ catch (e) {
62
+ falhas.push(`vínculo ${id} não confirmado: ${e.message}`);
63
+ }
64
+ }
65
+ }
66
+ return { vinculos: vinculos.filter((v, i, a) => a.findIndex((x) => x.raiz === v.raiz && x.thread === v.thread) === i), falhas };
67
+ }
68
+ /**
69
+ * Para cada sessão viva da mesma conta: prova o vínculo pelo ledger, pede a parada uma vez e só
70
+ * então grava o terminal que libera a condução. Consulta incompleta nunca vira falso sucesso.
71
+ */
72
+ function reconciliarContaEsgotada(entrada, deps = padrao) {
73
+ const agoraMs = entrada.agoraMs ?? Date.now();
74
+ const contaBruta = (0, runtime_profiles_1.chaveDaConta)(entrada.perfil), conta = sha(contaBruta);
75
+ const episodio = sha([conta, entrada.erroEm, entrada.esgotadoAte]);
76
+ const inv = deps.inventario(entrada.raiz);
77
+ const projetos = deps.projetos(entrada.raiz);
78
+ const falhas = inv.fontes.filter((f) => !f.ok).map((f) => f.detalhe);
79
+ const sessoes = [];
80
+ const candidatas = inv.sessoes.filter((s) => s.runtime === entrada.perfil.runtime && s.perfil === entrada.perfil.id && s.viva);
81
+ for (const sessao of candidatas) {
82
+ const achados = vinculosDaConta(projetos, sessao.sessionId, contaBruta);
83
+ falhas.push(...achados.falhas);
84
+ if (achados.vinculos.length === 0)
85
+ continue;
86
+ const pendentes = achados.vinculos.filter((v) => !(0, ledger_1.lerLedger)((0, thread_1.dirThread)(v.raiz, v.thread)).some((e) => e.tipo === 'phase_result' && e.quotaEpisodeId === episodio && e.sessionId === sessao.sessionId));
87
+ for (const v of achados.vinculos.filter((x) => !pendentes.includes(x))) {
88
+ sessoes.push({ ...v, sessionId: sessao.sessionId, parada: true, registrada: false, detalhe: 'episódio já reconciliado' });
89
+ }
90
+ if (pendentes.length === 0)
91
+ continue;
92
+ const paradaUnica = sessao.runtime === 'claude-bg'
93
+ ? deps.parar(sessao.sessionId, sessao.id, entrada.perfil) : null;
94
+ for (const v of pendentes) {
95
+ const parada = paradaUnica ?? deps.parar(sessao.sessionId, sessao.id, entrada.perfil, v);
96
+ const dir = (0, thread_1.dirThread)(v.raiz, v.thread);
97
+ if (!parada.ok || !(0, ledger_1.threadPresente)(dir)) {
98
+ sessoes.push({ ...v, sessionId: sessao.sessionId, parada: parada.ok, registrada: false, detalhe: parada.detalhe });
99
+ continue;
100
+ }
101
+ let registrada = false;
102
+ (0, session_events_1.comLockDeSessao)(dir, () => {
103
+ const atuais = (0, ledger_1.lerLedger)(dir);
104
+ if (atuais.some((e) => e.tipo === 'phase_result' && e.quotaEpisodeId === episodio && e.sessionId === sessao.sessionId))
105
+ return;
106
+ const dados = { fase: v.fase, sessionId: sessao.sessionId, despachoEm: v.despachoEm, runtime: sessao.runtime,
107
+ motivo: 'runtime.quota-exhausted', quotaEpisodeId: episodio, conta, resetEm: entrada.falha.resetEm,
108
+ esgotadoAte: entrada.esgotadoAte, observadoEm: new Date(agoraMs).toISOString(), origem: 'account.quota-exhausted',
109
+ perfil: { id: entrada.perfil.id, runtime: entrada.perfil.runtime },
110
+ falhaDeConta: { motivo: entrada.falha.motivo, resetEm: entrada.falha.resetEm,
111
+ fonte: entrada.falha.fonte, trecho: entrada.falha.trecho },
112
+ evidencia: 'vínculo da sessão, conta do despacho e parada confirmados pelo núcleo' };
113
+ (0, ledger_1.registrarSeExiste)(dir, v.thread, 'runtime_account_exhausted', dados);
114
+ (0, ledger_1.registrarSeExiste)(dir, v.thread, ledger_1.TIPOS_DE_EVENTO.gateBloqueado, { ...dados, gate: 'phase.dispatch',
115
+ modo: (0, thread_1.lerThread)(v.raiz, v.thread).modo, detalhe: 'a conta do despacho esgotou; retomar no próximo destino capaz',
116
+ correcao: `ork retry run ${v.thread}` });
117
+ (0, ledger_1.registrarSeExiste)(dir, v.thread, 'phase_result', { ...dados, sensorResultId: `quota:${episodio}:${sessao.sessionId}`,
118
+ classificacao: 'gate_blocked', ok: false, estado: 'bloqueada', paradaConfirmada: true });
119
+ registrada = true;
120
+ });
121
+ sessoes.push({ ...v, sessionId: sessao.sessionId, parada: true, registrada,
122
+ detalhe: registrada ? 'sessão parada e condução liberada' : 'episódio já reconciliado' });
123
+ }
124
+ }
125
+ return { conta, episodio, completo: inv.ok && falhas.length === 0 && sessoes.every((s) => s.parada && (s.registrada || s.detalhe.includes('já'))),
126
+ sessoes, falhas };
127
+ }