@orkastery/cli 0.5.6 → 0.6.1
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.
- package/adapters/README.md +18 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
- package/adapters/claude-code/README.md +37 -5
- package/adapters/claude-code/agents/ork-check.md +1 -0
- package/adapters/claude-code/agents/ork-go.md +1 -0
- package/adapters/claude-code/agents/ork-goal.md +1 -0
- package/adapters/claude-code/agents/ork-master.md +1 -0
- package/adapters/claude-code/agents/ork-plan.md +1 -0
- package/adapters/claude-code/agents/ork-ship.md +1 -0
- package/adapters/claude-code/hooks/hooks.json +2 -1
- package/adapters/claude-code/hooks/ork-guard.js +15 -1
- package/adapters/claude-code/hooks/ork-resposta.js +91 -0
- package/adapters/claude-code/hooks/ork-sensor.js +18 -2
- package/adapters/claude-code/hooks/quota-signal.js +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
- package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
- package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
- package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
- package/adapters/codex/skills/ork/SKILL.md +2 -0
- package/adapters/hermes/README.md +64 -1
- package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
- package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
- package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
- package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
- package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
- package/adapters/hermes/hermes.plugin.json +4 -0
- package/adapters/hermes/hitl-ingress/__init__.py +101 -8
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
- package/adapters/openclaw/README.md +81 -9
- package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
- package/adapters/openclaw/dist/hitl-ingress.js +106 -9
- package/adapters/openclaw/dist/index.js +86 -0
- package/adapters/openclaw/openclaw.plugin.json +34 -4
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +103 -9
- package/adapters/openclaw/src/index.ts +94 -0
- package/assets/adapters-en/claude-code/README.md +403 -0
- package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
- package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
- package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
- package/assets/adapters-en/claude-code/commands/check.md +46 -0
- package/assets/adapters-en/claude-code/commands/go.md +46 -0
- package/assets/adapters-en/claude-code/commands/goal.md +55 -0
- package/assets/adapters-en/claude-code/commands/master.md +54 -0
- package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
- package/assets/adapters-en/claude-code/commands/ork.md +126 -0
- package/assets/adapters-en/claude-code/commands/plan.md +47 -0
- package/assets/adapters-en/claude-code/commands/ship.md +45 -0
- package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
- package/assets/adapters-en/hermes/README.md +273 -0
- package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
- package/assets/references-en/README.md +25 -0
- package/assets/references-en/code-review-axes.md +82 -0
- package/assets/references-en/definition-of-done.md +74 -0
- package/assets/references-en/performance-checklist.md +53 -0
- package/assets/references-en/security-checklist.md +101 -0
- package/assets/references-en/testing-patterns.md +51 -0
- package/assets/security-scan/defaults/.golangci.yml +2 -0
- package/assets/security-scan/defaults/eslint.config.mjs +11 -0
- package/assets/security-scan/defaults/gitleaks.toml +3 -0
- package/assets/security-scan/defaults/ruff.toml +1 -0
- package/assets/security-scan/tools-agil.json +87 -0
- package/assets/security-scan/tools.json +625 -0
- package/assets/skills-en/core/onboarding/SKILL.md +58 -0
- package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
- package/assets/skills-en/core/thread-state/SKILL.md +88 -0
- package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
- package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
- package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
- package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
- package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
- package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
- package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
- package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
- package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
- package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
- package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
- package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
- package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
- package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
- package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
- package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
- package/dist/adapters/claude-bg.js +123 -9
- package/dist/adapters/codex-controller-worker.js +12 -5
- package/dist/adapters/codex-events.js +16 -4
- package/dist/adapters/codex.js +3 -1
- package/dist/adapters/grok-events.js +227 -0
- package/dist/adapters/grok-mcp-servidor.js +612 -0
- package/dist/adapters/grok-mcp.js +178 -0
- package/dist/adapters/grok.js +686 -0
- package/dist/agendador-cpu.js +92 -0
- package/dist/atualizar-branch.js +245 -0
- package/dist/auditoria.js +13 -11
- package/dist/auditrun.js +51 -46
- package/dist/autorizacao-duravel.js +327 -0
- package/dist/board.js +94 -40
- package/dist/branch-de-estado.js +23 -10
- package/dist/busca-semantica.js +7 -5
- package/dist/catalogo.js +2 -1
- package/dist/changelog-reconciliacao.js +290 -0
- package/dist/check-agil.js +528 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +238 -0
- package/dist/ci.js +248 -45
- package/dist/ciclos.js +8 -6
- package/dist/claim-lint.js +12 -8
- package/dist/claims-conferir.js +47 -39
- package/dist/claims.js +10 -9
- package/dist/company-brain-client.js +10 -3
- package/dist/company-brain-migration.js +11 -5
- package/dist/conducao-batida.js +759 -0
- package/dist/conducao-sentinela.js +25 -8
- package/dist/conducao.js +89 -29
- package/dist/conhecimento-consulta.js +270 -0
- package/dist/conhecimento.js +111 -87
- package/dist/conta-esgotada.js +127 -0
- package/dist/dado-privado.js +816 -0
- package/dist/decisao-autonoma.js +5 -4
- package/dist/demo.js +14 -12
- package/dist/dependencias-da-worktree.js +25 -0
- package/dist/divida.js +38 -36
- package/dist/docs.js +89 -89
- package/dist/doctor-forja.js +343 -0
- package/dist/doctor-pulse-cron.js +113 -1
- package/dist/doctor.js +164 -6
- package/dist/dsn-da-memoria.js +417 -0
- package/dist/entrega-por-mod.js +503 -0
- package/dist/entrega-pr.js +154 -54
- package/dist/esgotamentos.js +13 -11
- package/dist/estado-thread.js +21 -18
- package/dist/evalrunner.js +35 -32
- package/dist/fabrica-batida.js +34 -21
- package/dist/fabrica-estado.js +33 -21
- package/dist/fix.js +21 -19
- package/dist/forja/adaptador.js +6 -0
- package/dist/forja/ambiente-de-ci.js +27 -0
- package/dist/forja/api.js +256 -0
- package/dist/forja/cache.js +89 -0
- package/dist/forja/cli.js +60 -0
- package/dist/forja/contrato.js +9 -0
- package/dist/forja/endereco.js +43 -0
- package/dist/forja/estado.js +22 -0
- package/dist/forja/executor.js +73 -0
- package/dist/forja/github/ci.js +95 -0
- package/dist/forja/github/dono-da-rede.js +18 -0
- package/dist/forja/github/metadados.js +15 -0
- package/dist/forja/github/pedidos.js +200 -0
- package/dist/forja/gitlab/ci.js +141 -0
- package/dist/forja/gitlab/consultas.js +59 -0
- package/dist/forja/gitlab/dono-da-rede.js +43 -0
- package/dist/forja/gitlab/metadados.js +15 -0
- package/dist/forja/gitlab/pedidos-abertos.js +158 -0
- package/dist/forja/gitlab/pedidos.js +141 -0
- package/dist/forja/produtor.js +32 -0
- package/dist/forja/registro.js +31 -0
- package/dist/forja/resolver.js +121 -0
- package/dist/forja/texto.js +13 -0
- package/dist/forja/versao.js +71 -0
- package/dist/forja.js +123 -80
- package/dist/handoff.js +23 -13
- package/dist/hitl-contract.js +46 -43
- package/dist/hitl-curto.js +37 -25
- package/dist/hitl-gates.js +13 -11
- package/dist/hitl-local-receipt.js +51 -0
- package/dist/hitl-local.js +11 -2
- package/dist/hitl-lock.js +5 -11
- package/dist/hitl-public-receipt.js +11 -0
- package/dist/hitl-resumo.js +44 -1
- package/dist/hitl-sessions.js +62 -9
- package/dist/hitl-texto-livre.js +7 -4
- package/dist/hitl.js +34 -31
- package/dist/horario.js +20 -1
- package/dist/hosts.js +104 -134
- package/dist/index.js +864 -554
- package/dist/indice-vetorial.js +14 -12
- package/dist/init.js +11 -2
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +123 -69
- package/dist/intelligence-graph-query.js +37 -22
- package/dist/leases.js +19 -18
- package/dist/ledger-stats.js +17 -16
- package/dist/ledger.js +31 -1
- package/dist/licoes.js +12 -11
- package/dist/locale-accounts.js +228 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +86 -10
- package/dist/locale-audit.js +199 -0
- package/dist/locale-claims.js +213 -0
- package/dist/locale-conducao.js +138 -0
- package/dist/locale-conhecimento.js +181 -0
- package/dist/locale-decisao.js +205 -0
- package/dist/locale-docs.js +230 -0
- package/dist/locale-estado.js +101 -0
- package/dist/locale-forja.js +288 -0
- package/dist/locale-gerados.js +5 -0
- package/dist/locale-grafo.js +129 -0
- package/dist/locale-master.js +83 -0
- package/dist/locale-network.js +524 -0
- package/dist/locale-operacao-restante.js +931 -0
- package/dist/locale-projetos.js +100 -0
- package/dist/locale-prompts.js +194 -0
- package/dist/locale-pulse.js +140 -2
- package/dist/locale-reservas.js +87 -0
- package/dist/locale-retry.js +183 -6
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +177 -66
- package/dist/locale-thread.js +149 -5
- package/dist/locale-verify.js +80 -4
- package/dist/locale-worktree.js +246 -0
- package/dist/locale.js +553 -9
- package/dist/maestro-runtime.js +22 -3
- package/dist/manifest.js +293 -12
- package/dist/maquina-ociosa.js +211 -0
- package/dist/maquina.js +10 -5
- package/dist/master-nota-local.js +200 -0
- package/dist/master-nota.js +10 -2
- package/dist/master.js +118 -41
- package/dist/mcp-conhecimento.js +52 -0
- package/dist/mcp-experiencia.js +26 -5
- package/dist/mcp-install.js +90 -15
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +116 -22
- package/dist/mcp-ship-transporte.js +977 -0
- package/dist/mcp-ship.js +68 -24
- package/dist/mcp-transportes.js +17 -0
- package/dist/memoria.js +63 -58
- package/dist/merge-da-entrega.js +85 -0
- package/dist/modos-migracao.js +8 -6
- package/dist/modos.js +17 -18
- package/dist/network-roadmap.js +94 -54
- package/dist/noctum-aceite.js +929 -0
- package/dist/noctum-arco.js +540 -33
- package/dist/noctum-capacidade.js +3 -3
- package/dist/noctum-changelog.js +399 -0
- package/dist/noctum-cli.js +539 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1217 -0
- package/dist/noctum-envelope.js +253 -17
- package/dist/noctum-execucao.js +100 -24
- package/dist/noctum-fechamento.js +416 -0
- package/dist/noctum-fila.js +49 -10
- package/dist/noctum-guarda.js +333 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +387 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +390 -0
- package/dist/noctum-pergunta-canal.js +96 -0
- package/dist/noctum-pergunta.js +115 -0
- package/dist/noctum-provas.js +838 -0
- package/dist/noctum-reconciliacao.js +594 -0
- package/dist/noctum-rede.js +102 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +861 -0
- package/dist/noctum-resposta.js +207 -0
- package/dist/noctum-retomada-rede.js +71 -0
- package/dist/noctum-sessoes-em-voo.js +93 -0
- package/dist/noctum-supervisao.js +649 -0
- package/dist/noctum-terminal.js +459 -0
- package/dist/noctum-transporte.js +655 -0
- package/dist/noctum-vigia.js +679 -0
- package/dist/ocupacao.js +3 -1
- package/dist/onboarding.js +16 -5
- package/dist/orkmind.js +39 -23
- package/dist/orquestracao.js +31 -35
- package/dist/parado-no-condutor.js +160 -139
- package/dist/phase.js +96 -42
- package/dist/policies.js +33 -0
- package/dist/postura-local.js +11 -6
- package/dist/preflight.js +2 -1
- package/dist/procedencia.js +9 -14
- package/dist/projeto-alvo.js +59 -20
- package/dist/prompts.js +136 -42
- package/dist/prova-minima.js +5 -6
- package/dist/pulse-cadencia.js +5 -4
- package/dist/pulse-consentimento.js +53 -1
- package/dist/pulse-delivery.js +143 -27
- package/dist/pulse-resposta.js +368 -4
- package/dist/pulse.js +136 -3
- package/dist/ratelimit.js +13 -4
- package/dist/recall.js +14 -13
- package/dist/rede-adesao.js +13 -8
- package/dist/rede-forja.js +108 -24
- package/dist/rede-status.js +63 -45
- package/dist/rede.js +86 -46
- package/dist/retomada-checkpoint.js +101 -0
- package/dist/retry.js +326 -78
- package/dist/roadmap-reservas.js +32 -32
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +279 -85
- package/dist/runtime-escada.js +429 -0
- package/dist/runtime-profiles.js +130 -63
- package/dist/runtimes.js +42 -5
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +366 -0
- package/dist/security-scan/cli.js +76 -0
- package/dist/security-scan/compare.js +149 -0
- package/dist/security-scan/config.js +93 -0
- package/dist/security-scan/detect.js +97 -0
- package/dist/security-scan/executor.js +196 -0
- package/dist/security-scan/guard.js +180 -0
- package/dist/security-scan/imagem-de-lint.js +96 -0
- package/dist/security-scan/normalize/actionlint.js +12 -0
- package/dist/security-scan/normalize/eslint.js +12 -0
- package/dist/security-scan/normalize/gitleaks.js +13 -0
- package/dist/security-scan/normalize/golangci-lint.js +13 -0
- package/dist/security-scan/normalize/govulncheck.js +36 -0
- package/dist/security-scan/normalize/index.js +25 -0
- package/dist/security-scan/normalize/npm-audit.js +30 -0
- package/dist/security-scan/normalize/osv-scanner.js +32 -0
- package/dist/security-scan/normalize/oxlint.js +51 -0
- package/dist/security-scan/normalize/pip-audit.js +16 -0
- package/dist/security-scan/normalize/ruff.js +12 -0
- package/dist/security-scan/normalize/semgrep.js +20 -0
- package/dist/security-scan/normalize/trivy.js +33 -0
- package/dist/security-scan/normalize/util.js +204 -0
- package/dist/security-scan/normalize/zizmor.js +19 -0
- package/dist/security-scan/report.js +156 -0
- package/dist/security-scan/run.js +448 -0
- package/dist/security-scan/tools.js +62 -0
- package/dist/security-scan/trabalhador.js +74 -0
- package/dist/security-scan/types.js +15 -0
- package/dist/session-events.js +19 -2
- package/dist/session-watcher-claude.js +74 -19
- package/dist/session-watcher-grok.js +425 -0
- package/dist/session-watcher.js +174 -13
- package/dist/sessoes-contas.js +42 -5
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +67 -66
- package/dist/ship-publicar.js +263 -92
- package/dist/ship.js +160 -17
- package/dist/superficie.js +14 -11
- package/dist/thread-close.js +9 -9
- package/dist/thread.js +121 -18
- package/dist/tokens.js +15 -11
- package/dist/trabalho-thread.js +297 -0
- package/dist/transporte-do-canal.js +189 -0
- package/dist/types.js +12 -1
- package/dist/util.js +5 -2
- package/dist/varredura-acoes.js +500 -0
- package/dist/verify.js +491 -32
- package/dist/worktree-local.js +12 -10
- package/dist/worktree.js +81 -85
- package/eval/casos/check-quality.json +77 -0
- package/eval/casos/security-auditor.json +148 -0
- package/eval/casos/security-remediation.json +161 -0
- package/eval/fixtures/security-scan/README.md +8 -0
- package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/go/Dockerfile +4 -0
- package/eval/fixtures/security-scan/go/README.md +4 -0
- package/eval/fixtures/security-scan/go/config.go +4 -0
- package/eval/fixtures/security-scan/go/go.mod +5 -0
- package/eval/fixtures/security-scan/go/go.sum +2 -0
- package/eval/fixtures/security-scan/go/main.go +31 -0
- package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/js/Dockerfile +3 -0
- package/eval/fixtures/security-scan/js/README.md +4 -0
- package/eval/fixtures/security-scan/js/package-lock.json +844 -0
- package/eval/fixtures/security-scan/js/package.json +10 -0
- package/eval/fixtures/security-scan/js/src/config.js +4 -0
- package/eval/fixtures/security-scan/js/src/server.js +17 -0
- package/eval/fixtures/security-scan/js/src/util.ts +4 -0
- package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
- package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/python/Dockerfile +3 -0
- package/eval/fixtures/security-scan/python/README.md +4 -0
- package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
- package/eval/fixtures/security-scan/python/app/config.py +2 -0
- package/eval/fixtures/security-scan/python/app/main.py +19 -0
- package/eval/fixtures/security-scan/python/requirements.txt +1 -0
- package/package.json +10 -5
- package/references/security-checklist.md +3 -3
- package/skills/README.md +1 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/check-quality/SKILL.md +16 -0
- package/skills/phases/go-implementation/SKILL.md +6 -0
- package/skills/phases/security-remediation/SKILL.md +70 -0
- package/skills/reviewers/security-auditor/SKILL.md +25 -0
package/dist/conhecimento.js
CHANGED
|
@@ -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.
|
|
48
|
-
* (D5); a
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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:
|
|
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',
|
|
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',
|
|
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',
|
|
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:
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
-
|
|
267
|
-
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
|
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,
|
|
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:
|
|
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:
|
|
319
|
+
return { motivo: t((l) => l.ledgerNaoAbriu(thread)) };
|
|
310
320
|
}
|
|
311
321
|
if (!st)
|
|
312
|
-
return { motivo:
|
|
313
|
-
|
|
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:
|
|
316
|
-
|
|
317
|
-
const completo = bytes.subarray(0,
|
|
318
|
-
if (!
|
|
319
|
-
return { motivo:
|
|
320
|
-
|
|
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
|
|
324
|
-
|
|
325
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
352
|
-
const tipo = TIPOS_DE_DECISAO.find((
|
|
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 :
|
|
355
|
-
return { codigo: 'referencia.nao-e-decisao', detalhe:
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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(
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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',
|
|
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
|
-
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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',
|
|
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(
|
|
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
|
+
}
|