@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
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessoesEmVooDoArco = exports.CONTRATO_FECHAMENTO = void 0;
|
|
4
|
+
exports.condicaoDeFechamento = condicaoDeFechamento;
|
|
5
|
+
exports.trabalhosDoArco = trabalhosDoArco;
|
|
6
|
+
exports.lerFechamento = lerFechamento;
|
|
7
|
+
exports.fecharSeDevido = fecharSeDevido;
|
|
8
|
+
exports.textoDaParada = textoDaParada;
|
|
9
|
+
/**
|
|
10
|
+
* RM-058, fatia N6 (D2, D6 e D8 da ork-rm058n6): o fechamento do arco por hora, por custo e por fila vazia.
|
|
11
|
+
*
|
|
12
|
+
* A tabela "Condição / Comportamento / Estado deixado para retomar" da página manda:
|
|
13
|
+
*
|
|
14
|
+
* - hora final, ou envelope expirado ou revogado: parar admissões e efeitos novos e encerrar as sessões em voo de modo
|
|
15
|
+
* controlado, deixando checkpoints, motivos de interrupção e as operações em voo para reconciliar;
|
|
16
|
+
* - fila vazia confirmada: encerrar cedo, sem abrir escopo novo, com o retrato das fontes e dos itens concluídos;
|
|
17
|
+
* - teto do arco: parar globalmente, sem retry nem troca de conta para contornar, com o consumo, as reservas em voo e a
|
|
18
|
+
* reconciliação pendente identificados.
|
|
19
|
+
*
|
|
20
|
+
* O teto em `sessoes` conta cada sessão na reserva: alcançado, nenhuma reserva nova passa (`noctum.orcamento.esgotado`, em
|
|
21
|
+
* qualquer conta), e o arco fecha quando a última sessão admitida acaba, porque pará-las não protege o teto, só joga
|
|
22
|
+
* trabalho fora (a hora final para as que passarem do fim). Em unidade contínua, o consumo segue enquanto a sessão roda:
|
|
23
|
+
* a leitura que alcança o teto fecha o arco e para as sessões em voo.
|
|
24
|
+
*
|
|
25
|
+
* As condições valem nesta ordem: revogado, hora, a parada da supervisão da N4 (RM-058, integração, D7 da
|
|
26
|
+
* ork-rm058integra; a parada pelo teto do arco fica com a regra do custo e, sem sessão admitida em voo e com o consumo
|
|
27
|
+
* abaixo do teto, fecha pela supervisão: N2 do CHECK 2), custo, fila vazia (D8). Revogado, hora, a parada e o teto em sessões não dependem da fila nem da
|
|
28
|
+
* medição, e nenhuma falha delas segura esse fechamento. Com uma condição, o fechamento grava primeiro o
|
|
29
|
+
* `encerrado` no log do arco (`encerrarArco`): dali em diante nenhuma reserva de despacho nem efeito passa, e nenhuma
|
|
30
|
+
* reserva devolvida reabre o arco. Só depois vêm o retrato do fechamento e o pedido de parada de cada sessão em voo, no
|
|
31
|
+
* registro próprio da N6 (`fechamento.jsonl`). A parada é pedida uma vez por sessão, pelo controle da conta dela (o
|
|
32
|
+
* `pararSessao` do núcleo no claude-bg); o codex fica `sem-controle`, porque parar uma sessão dele exige o controller
|
|
33
|
+
* vinculado (limite da N4). A reserva pendente para pelo id que a falha do runtime disse no ledger da thread, quando
|
|
34
|
+
* disse; sem ele, não há o que parar. No tique seguinte, a listagem do runtime confirma a parada, ou a deixa
|
|
35
|
+
* `nao-confirmada`. O retrato é gravado uma vez; se o processo cair entre o `encerrado` e o registro, o tique seguinte o
|
|
36
|
+
* grava.
|
|
37
|
+
*
|
|
38
|
+
* Subteto de conta ou runtime esgotado não fecha o arco: a reserva por aquela conta ou runtime é recusada, e trocar para
|
|
39
|
+
* outra conta admitida é da N4. Consumo com lacuna também não fecha por custo (o teto não se prova alcançado); a admissão
|
|
40
|
+
* já recusa por falta de medida.
|
|
41
|
+
*
|
|
42
|
+
* Interfaces para as fatias que correm em paralelo (D6): a parada (`parar`) e a listagem das sessões (`listarSessoes`)
|
|
43
|
+
* são injetáveis; a N4 pluga o controle dela aí. Nada aqui despacha.
|
|
44
|
+
*/
|
|
45
|
+
const horario_1 = require("./horario");
|
|
46
|
+
const ledger_1 = require("./ledger");
|
|
47
|
+
const master_1 = require("./master");
|
|
48
|
+
const noctum_arco_1 = require("./noctum-arco");
|
|
49
|
+
const noctum_envelope_1 = require("./noctum-envelope");
|
|
50
|
+
const noctum_fila_1 = require("./noctum-fila");
|
|
51
|
+
const noctum_rede_1 = require("./noctum-rede");
|
|
52
|
+
const noctum_medicao_1 = require("./noctum-medicao");
|
|
53
|
+
const noctum_registro_1 = require("./noctum-registro");
|
|
54
|
+
const noctum_supervisao_1 = require("./noctum-supervisao");
|
|
55
|
+
const noctum_sessoes_em_voo_1 = require("./noctum-sessoes-em-voo");
|
|
56
|
+
Object.defineProperty(exports, "sessoesEmVooDoArco", { enumerable: true, get: function () { return noctum_sessoes_em_voo_1.sessoesEmVooDoArco; } });
|
|
57
|
+
const sessoes_contas_1 = require("./sessoes-contas");
|
|
58
|
+
const sessoes_1 = require("./sessoes");
|
|
59
|
+
const thread_1 = require("./thread");
|
|
60
|
+
const util_1 = require("./util");
|
|
61
|
+
exports.CONTRATO_FECHAMENTO = 'ork.noctum-fechamento/v1';
|
|
62
|
+
/**
|
|
63
|
+
* A condição de fechamento no instante dado, pura, na ordem da D8. `null` quando o arco segue (ou nunca foi autorizado).
|
|
64
|
+
* O custo só fecha com o teto do arco provado alcançado: em `sessoes`, pelas reservas não recusadas e sem sessão admitida
|
|
65
|
+
* em voo (`emVoo`, as sessões e reservas pendentes que ainda podem rodar); em outra unidade, pelo consumo medido sem
|
|
66
|
+
* lacuna. A parada pelo teto do arco espera as sessões admitidas e, sem nenhuma em voo, fecha pelo custo com o consumo no
|
|
67
|
+
* teto, ou pela supervisão abaixo dele (a reserva devolvida, a emenda que subiu o teto depois da parada).
|
|
68
|
+
*/
|
|
69
|
+
function condicaoDeFechamento(estado, fila, medicao, quando, emVoo = 0, parada = null) {
|
|
70
|
+
if (!estado || !estado.autorizadoPor || !estado.conteudo)
|
|
71
|
+
return null;
|
|
72
|
+
if (estado.encerramento)
|
|
73
|
+
return { motivo: estado.encerramento.motivo, detalhe: estado.encerramento.detalhe };
|
|
74
|
+
if (estado.situacao === 'revogado')
|
|
75
|
+
return { motivo: 'revogado', detalhe: 'o dono revogou o arco pelo ingresso autenticado' };
|
|
76
|
+
const fim = estado.conteudo.janela.fim;
|
|
77
|
+
if (Date.parse(quando) >= Date.parse(fim)) {
|
|
78
|
+
return { motivo: 'hora', detalhe: `o fim do envelope chegou (${(0, horario_1.formatarDataHora)(fim, { fuso: estado.conteudo.janela.fuso, locale: 'pt-BR' })}, ` +
|
|
79
|
+
`${estado.conteudo.janela.fuso}); nada o prorroga` };
|
|
80
|
+
}
|
|
81
|
+
// RM-058, integração (D7): a supervisão parou o arco (o vigia nunca encerra; quem encerra é o fechamento, por ela). A
|
|
82
|
+
// parada pelo teto do arco em sessões é a regra do custo logo abaixo: as sessões admitidas terminam, e o arco fecha
|
|
83
|
+
// quando a última acaba (A1 do CHECK); fechar por ela pediria a parada de trabalho já contado no teto.
|
|
84
|
+
if (parada && parada.motivo !== 'teto-do-arco')
|
|
85
|
+
return { motivo: 'supervisao', detalhe: `a supervisão parou o arco (${parada.motivo}): ${parada.detalhe}` };
|
|
86
|
+
const teto = estado.conteudo.orcamento.arco;
|
|
87
|
+
if (teto.unidade === 'sessoes') {
|
|
88
|
+
// Cada sessão admitida já está contada no teto: o arco fecha quando a última acaba, não por cima dela.
|
|
89
|
+
if (estado.consumo.arco >= teto.valor && emVoo === 0) {
|
|
90
|
+
return { motivo: 'custo', detalhe: `o teto do arco é de ${teto.valor} sessoes e ${estado.consumo.arco} foram reservadas; nenhuma segue em voo` };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (medicao) {
|
|
94
|
+
const c = (0, noctum_medicao_1.consumoDoEscopoNaUnidade)(medicao, 'arco', teto.unidade);
|
|
95
|
+
if (c.valor !== null && Number.isFinite(c.valor) && c.valor >= teto.valor) {
|
|
96
|
+
return { motivo: 'custo', detalhe: `o teto do arco é de ${teto.valor} ${teto.unidade} e o consumo medido é ${(0, noctum_medicao_1.textoDoConsumo)(c)}` };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// N2 do CHECK 2: a parada pelo teto segue terminal com o consumo abaixo dele (a reserva devolvida, a emenda que subiu o teto
|
|
100
|
+
// depois da parada): sem sessão admitida em voo, o arco fecha pela supervisão, em vez de ficar parado e aberto até a hora.
|
|
101
|
+
if (parada && emVoo === 0) {
|
|
102
|
+
return { motivo: 'supervisao', detalhe: `a supervisão parou o arco (${parada.motivo}): ${parada.detalhe}; nenhuma sessão admitida segue em voo` };
|
|
103
|
+
}
|
|
104
|
+
if (estado.situacao === 'agendado')
|
|
105
|
+
return null;
|
|
106
|
+
if (fila?.situacao === 'vazia' && fila.decisao.acao === 'encerrar' && fila.decisao.motivo === 'fila-vazia') {
|
|
107
|
+
// A entrega registrada (`ship_done`) pode vir sem a prova do push; o relatório diz qual tem prova.
|
|
108
|
+
return { motivo: 'fila-vazia', detalhe: 'todo trabalho do envelope tem a entrega registrada (ship_done), fechou sem entrega ou depende ' +
|
|
109
|
+
'de um que fechou sem entrega; nada sobra para este arco' };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* RM-058, integração (T4, D8): as threads que este arco entregou (o `ship_done` da entrega dele, com o arco na evidência) e
|
|
115
|
+
* cujo MASTER por omissão a entrega dele ainda faz, como em `noctum-entrega.ts`: o envelope `v2`, o trabalho sem isolamento,
|
|
116
|
+
* a thread aberta e sem MASTER ratificado. A thread que não se lê não segura o fechamento: a fila já a mostra.
|
|
117
|
+
*/
|
|
118
|
+
function mastersDevidos(raiz, estado, fila, sup) {
|
|
119
|
+
const devidos = [];
|
|
120
|
+
for (const t of fila.trabalhos) {
|
|
121
|
+
if (t.estado !== 'entregue' || !t.thread || sup.isolados.has(t.id))
|
|
122
|
+
continue;
|
|
123
|
+
try {
|
|
124
|
+
const doArco = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, t.thread)).some(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido &&
|
|
125
|
+
e.evidencia?.arco === estado.arco);
|
|
126
|
+
if (doArco && (0, thread_1.lerThread)(raiz, t.thread).status !== 'fechada' && !(0, master_1.masterRatificado)(raiz, t.thread))
|
|
127
|
+
devidos.push(t.thread);
|
|
128
|
+
}
|
|
129
|
+
catch { /* a leitura que falhou não prende o arco aberto */ }
|
|
130
|
+
}
|
|
131
|
+
return devidos;
|
|
132
|
+
}
|
|
133
|
+
const gitDoDisco = (cwd, args) => {
|
|
134
|
+
const r = (0, util_1.exec)('git', ['-C', cwd, ...args], undefined, 15_000);
|
|
135
|
+
return r.ok ? r.stdout.trim() : null;
|
|
136
|
+
};
|
|
137
|
+
/** As sessões vivas pelo `claude agents` e pelos rollouts de todas as contas que o `ork` conhece. */
|
|
138
|
+
function sessoesDoRuntime(raiz) {
|
|
139
|
+
try {
|
|
140
|
+
const l = (0, sessoes_contas_1.consultarContas)(raiz);
|
|
141
|
+
return { lidas: l.fontes.every(f => f.ok), vivas: new Set(l.sessoes.filter(s => s.viva && !(0, sessoes_contas_1.encerradaNaLista)(s)).map(s => s.sessionId)) };
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return { lidas: false, vivas: new Set() };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** O controle de produção: o claude-bg para pela conta dele; o codex não tem controle sem o controller vinculado. */
|
|
148
|
+
function pararPeloNucleo(raiz) {
|
|
149
|
+
return (s) => {
|
|
150
|
+
if (!s.sessionId)
|
|
151
|
+
return { ok: false, detalhe: 'sem id de sessão' };
|
|
152
|
+
const r = (0, sessoes_1.pararSessao)(s.sessionId, raiz);
|
|
153
|
+
return { ok: r.codigo === 0, detalhe: r.texto.slice(0, 300) };
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function trabalhosNaRetomada(raiz, fila, git) {
|
|
157
|
+
return (fila?.trabalhos ?? []).map(t => {
|
|
158
|
+
let branch = null, ponta = null, arvoreLimpa = null;
|
|
159
|
+
if (t.thread) {
|
|
160
|
+
let wt = null;
|
|
161
|
+
try {
|
|
162
|
+
wt = (0, thread_1.lerThread)(raiz, t.thread).worktree ?? null;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
wt = null;
|
|
166
|
+
}
|
|
167
|
+
if (wt) {
|
|
168
|
+
branch = git(wt, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
169
|
+
ponta = git(wt, ['rev-parse', 'HEAD']);
|
|
170
|
+
const status = git(wt, ['status', '--porcelain']);
|
|
171
|
+
arvoreLimpa = status === null ? null : status.length === 0;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { id: t.id, item: t.item, thread: t.thread, estado: t.estado, fase: t.fase, motivo: t.motivo, detalhe: t.detalhe,
|
|
175
|
+
entregueEm: t.entregueEm, branch, ponta, arvoreLimpa };
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function instrucaoDeRetomada(arco, trabalhos, reservas, emVoo) {
|
|
179
|
+
const linhas = [`O arco ${arco} não reabre: o trabalho que sobrou volta num arco novo, com envelope vigente proposto por ` +
|
|
180
|
+
'`ork noctum propor` e autorizado pelo dono por ingresso autenticado.'];
|
|
181
|
+
if (reservas.length) {
|
|
182
|
+
linhas.push(`As reservas pendentes (${reservas.map(r => r.seq).join(', ')}) precisam ser reconciliadas antes do primeiro despacho do arco ` +
|
|
183
|
+
'novo, pela N4 ou pelo dono: o runtime pode ter aberto a sessão, e nada deve ser despachado por cima dela.');
|
|
184
|
+
}
|
|
185
|
+
for (const t of trabalhos.filter(x => x.thread && x.estado !== 'entregue' && x.estado !== 'encerrado-sem-entrega')) {
|
|
186
|
+
linhas.push(`A thread ${t.thread} (${t.id}) retoma pelo passo do arco novo${t.fase ? `, na fase ${t.fase}` : ''}, pela prova mais adiantada` +
|
|
187
|
+
`${t.arvoreLimpa === false ? '; a árvore tem mudanças não commitadas, que a sessão seguinte confere' : ''}.`);
|
|
188
|
+
}
|
|
189
|
+
if (emVoo.some(s => s.runtime === 'codex' && s.sessionId)) {
|
|
190
|
+
linhas.push('A sessão do codex em voo não tem controle de parada sem o controller vinculado: confira-a antes do arco novo.');
|
|
191
|
+
}
|
|
192
|
+
linhas.push('Commit, push ou merge de resultado incerto nunca se repete às cegas: quem retoma reconcilia antes de agir.');
|
|
193
|
+
return linhas;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* A classificação de cada trabalho como se o arco estivesse vigente. `montarFila` não classifica nada num arco expirado,
|
|
197
|
+
* revogado ou encerrado (nada é candidato), e o retrato do fechamento e o relatório precisam saber onde cada trabalho
|
|
198
|
+
* parou justamente nesses arcos. A decisão desta fila não vale para despachar: só a classificação é lida.
|
|
199
|
+
*/
|
|
200
|
+
function trabalhosDoArco(fatos) {
|
|
201
|
+
const e = fatos.estado;
|
|
202
|
+
if (!e || !e.conteudo || !e.autorizadoPor || e.situacao === 'vigente')
|
|
203
|
+
return (0, noctum_fila_1.montarFila)(fatos);
|
|
204
|
+
return (0, noctum_fila_1.montarFila)({ ...fatos, estado: { ...e, situacao: 'vigente' } });
|
|
205
|
+
}
|
|
206
|
+
/** O retrato gravado e as paradas e conferências do registro do fechamento. */
|
|
207
|
+
function lerFechamento(raiz, arco) {
|
|
208
|
+
const linhas = (0, noctum_registro_1.lerRegistro)(raiz, arco, 'fechamento');
|
|
209
|
+
const fechado = linhas.find(l => l.evento.tipo === 'fechado')?.evento;
|
|
210
|
+
return {
|
|
211
|
+
retrato: fechado?.tipo === 'fechado' ? fechado.retrato : null,
|
|
212
|
+
paradas: linhas.filter(l => l.evento.tipo === 'parada_pedida').map(l => l.evento.parada),
|
|
213
|
+
conferencias: linhas.filter(l => l.evento.tipo === 'parada_conferida').map(l => l.evento.conferencia),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/** O retrato do fechamento: o consumo, a fila e o estado de retomada, lidos no instante dado e gravados uma vez. */
|
|
217
|
+
function gravarRetrato(carregado, arco, estado, encerramento, quando, o) {
|
|
218
|
+
const { raiz } = carregado;
|
|
219
|
+
let trabalhosDaFila = null;
|
|
220
|
+
try {
|
|
221
|
+
const rede = estado.conteudo && (0, noctum_envelope_1.envelopeMultimaquina)(estado.conteudo)
|
|
222
|
+
? o.projecaoDaRede ?? (0, noctum_rede_1.lerRede)(carregado, arco, { quando, maquina: o.maquina, remoto: o.remoto, rede: o.redeDaCoordenacao }) : null;
|
|
223
|
+
const coordenacao = rede ? (0, noctum_rede_1.coordenacaoDaFila)(rede) : null;
|
|
224
|
+
trabalhosDaFila = rede?.lacuna ? null : trabalhosDoArco((0, noctum_fila_1.fatosDaFila)(carregado, arco, { quando, maquina: o.maquina, lerReservas: o.lerReservas, ...(coordenacao ? { coordenacao } : {}) }));
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
if (!(e instanceof noctum_envelope_1.RecusaDoArco))
|
|
228
|
+
throw e;
|
|
229
|
+
}
|
|
230
|
+
let consumo;
|
|
231
|
+
try {
|
|
232
|
+
const medicao = o.medir(raiz, estado, quando);
|
|
233
|
+
consumo = Object.fromEntries(noctum_envelope_1.UNIDADES.map(u => [u, (0, noctum_medicao_1.consumoDoEscopoNaUnidade)(medicao, 'arco', u)]));
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
const lacuna = `a medição falhou no fechamento (${e.message.slice(0, 200)})`;
|
|
237
|
+
consumo = Object.fromEntries(noctum_envelope_1.UNIDADES.map(u => [u, { unidade: u, valor: null, lacunas: [lacuna], parcial: false, tetoSuperior: false,
|
|
238
|
+
sessoes: 0 }]));
|
|
239
|
+
}
|
|
240
|
+
const emVoo = (0, noctum_sessoes_em_voo_1.sessoesEmVooDoArco)(raiz, estado);
|
|
241
|
+
const trabalhos = trabalhosNaRetomada(raiz, trabalhosDaFila, o.git);
|
|
242
|
+
const reservasEmVoo = estado.despachos.filter(d => d.desfecho === 'pendente')
|
|
243
|
+
.map(d => ({ seq: d.seq, trabalho: d.trabalho, thread: d.threadDespachada ?? d.thread }));
|
|
244
|
+
const ditaNaFalha = new Map(emVoo.filter(s => s.daReservaPendente && s.sessionId).map(s => [s.seq, s.sessionId]));
|
|
245
|
+
const retrato = {
|
|
246
|
+
contrato: exports.CONTRATO_FECHAMENTO, arco, motivo: encerramento.motivo, detalhe: encerramento.detalhe, em: encerramento.em,
|
|
247
|
+
versao: encerramento.versao, envelopeSha256: encerramento.envelopeSha256, consumo,
|
|
248
|
+
// A situação da fila como se o arco seguisse: a do arco encerrado é sempre vazia, e não diz onde o trabalho parou.
|
|
249
|
+
fila: { situacao: trabalhosDaFila?.situacao ?? null,
|
|
250
|
+
lacunas: trabalhosDaFila ? trabalhosDaFila.lacunas : ['a fila do arco não pôde ser lida no fechamento'], lida: !!trabalhosDaFila },
|
|
251
|
+
retomada: { trabalhos, reservasEmVoo,
|
|
252
|
+
reconciliacaoPendente: [...reservasEmVoo.map(r => ditaNaFalha.has(r.seq)
|
|
253
|
+
? `reserva ${r.seq} (${r.trabalho}): pendente, com a sessão ${ditaNaFalha.get(r.seq)} dita na falha do runtime`
|
|
254
|
+
: `reserva ${r.seq} (${r.trabalho}): pendente, sem id de sessão`),
|
|
255
|
+
...emVoo.filter(s => s.sessionId && !s.daReservaPendente).map(s => `sessão ${s.sessionId} (${s.trabalho}): em voo no fechamento`)],
|
|
256
|
+
instrucao: instrucaoDeRetomada(arco, trabalhos, reservasEmVoo, emVoo) },
|
|
257
|
+
};
|
|
258
|
+
(0, noctum_registro_1.comRegistro)(raiz, arco, 'fechamento', (linhas, anexar) => {
|
|
259
|
+
if (!linhas.some(l => l.evento.tipo === 'fechado'))
|
|
260
|
+
anexar({ tipo: 'fechado', retrato }, quando);
|
|
261
|
+
}, { esperarMs: 5_000 });
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Fecha o arco se alguma condição vale, e confirma as paradas pendentes de um arco já fechado. Idempotente: o segundo
|
|
265
|
+
* chamado não grava outro retrato nem pede a mesma parada de novo. Lança só o erro que não é recusa tipada do arco.
|
|
266
|
+
*/
|
|
267
|
+
function fecharSeDevido(carregado, arco, opcoes = {}) {
|
|
268
|
+
const quando = opcoes.quando ?? new Date().toISOString();
|
|
269
|
+
const { raiz } = carregado;
|
|
270
|
+
const nada = (detalhe) => ({ fechado: false, agora: false, motivo: null, detalhe, retrato: null, paradas: [], conferencias: [] });
|
|
271
|
+
let estado;
|
|
272
|
+
try {
|
|
273
|
+
estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
|
|
274
|
+
}
|
|
275
|
+
catch (e) {
|
|
276
|
+
if (e instanceof noctum_envelope_1.RecusaDoArco)
|
|
277
|
+
return nada(e.message);
|
|
278
|
+
throw e;
|
|
279
|
+
}
|
|
280
|
+
if (!estado)
|
|
281
|
+
return nada(`o arco ${arco} não tem proposta`);
|
|
282
|
+
if (!estado.autorizadoPor || !estado.conteudo)
|
|
283
|
+
return nada(`o arco ${arco} nunca foi autorizado pelo dono`);
|
|
284
|
+
const medir = opcoes.medir ?? ((r, e, q) => (0, noctum_medicao_1.medirArco)(r, e, { quando: q }));
|
|
285
|
+
const git = opcoes.git ?? gitDoDisco;
|
|
286
|
+
const parar = opcoes.parar ?? pararPeloNucleo(raiz);
|
|
287
|
+
const listar = opcoes.listarSessoes ?? (() => sessoesDoRuntime(raiz));
|
|
288
|
+
let agora = false;
|
|
289
|
+
if (!estado.encerramento) {
|
|
290
|
+
const emVooAgora = (0, noctum_sessoes_em_voo_1.sessoesEmVooDoArco)(raiz, estado).length;
|
|
291
|
+
const multimaquina = (0, noctum_envelope_1.envelopeMultimaquina)(estado.conteudo);
|
|
292
|
+
const rede = multimaquina
|
|
293
|
+
? opcoes.projecaoDaRede ?? (0, noctum_rede_1.lerRede)(carregado, arco, { quando, maquina: opcoes.maquina, remoto: opcoes.remoto, rede: opcoes.redeDaCoordenacao })
|
|
294
|
+
: null;
|
|
295
|
+
// Com rede íntegra, o teto em sessões é global. Sem leitura, o consumo local ainda pode provar sozinho que o teto caiu.
|
|
296
|
+
const estadoDoCusto = rede && !rede.lacuna
|
|
297
|
+
? { ...estado, consumo: { ...estado.consumo, arco: rede.consumo.arco } }
|
|
298
|
+
: estado;
|
|
299
|
+
// RM-058, integração (D7): a parada da supervisão; o log dela que não se lê não segura o fechamento pelas outras condições.
|
|
300
|
+
let sup = null;
|
|
301
|
+
try {
|
|
302
|
+
sup = (0, noctum_supervisao_1.lerSupervisao)(raiz, arco);
|
|
303
|
+
}
|
|
304
|
+
catch (e) {
|
|
305
|
+
if (!(e instanceof noctum_supervisao_1.RecusaDaSupervisao))
|
|
306
|
+
throw e;
|
|
307
|
+
}
|
|
308
|
+
const parada = sup?.parada ?? null;
|
|
309
|
+
// Revogado, hora, a parada e o teto em sessões vêm primeiro e sem a fila nem a medição: nenhuma falha delas segura esse fechamento.
|
|
310
|
+
let condicao = condicaoDeFechamento(estadoDoCusto, null, null, quando, emVooAgora, parada);
|
|
311
|
+
let falhaDaMedicao = '';
|
|
312
|
+
if (!condicao) {
|
|
313
|
+
let fila = null;
|
|
314
|
+
try {
|
|
315
|
+
const coordenacao = rede ? (0, noctum_rede_1.coordenacaoDaFila)(rede) : null;
|
|
316
|
+
fila = rede?.lacuna ? null : (0, noctum_fila_1.montarFila)((0, noctum_fila_1.fatosDaFila)(carregado, arco, { quando, maquina: opcoes.maquina, lerReservas: opcoes.lerReservas, ...(coordenacao ? { coordenacao } : {}) }));
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
if (!(e instanceof noctum_envelope_1.RecusaDoArco))
|
|
320
|
+
throw e;
|
|
321
|
+
}
|
|
322
|
+
let medicao = null;
|
|
323
|
+
if (estado.conteudo.orcamento.arco.unidade !== 'sessoes' && !rede?.lacuna) {
|
|
324
|
+
// A medição que falha não prova o teto alcançado: o custo não fecha, e a fila vazia ainda pode fechar.
|
|
325
|
+
try {
|
|
326
|
+
medicao = medir(raiz, estado, quando);
|
|
327
|
+
}
|
|
328
|
+
catch (e) {
|
|
329
|
+
falhaDaMedicao = `; a medição falhou (${e.message.slice(0, 200)})`;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
condicao = condicaoDeFechamento(estadoDoCusto, fila, medicao, quando, emVooAgora, parada);
|
|
333
|
+
// RM-058, integração (T4, D8): a fila vazia não fecha o arco por cima do MASTER por omissão que a entrega dele ainda
|
|
334
|
+
// deve; o passo seguinte o faz, e o fechamento vem depois. A hora, a parada e o teto fecharam antes, sem esperar.
|
|
335
|
+
const devidos = condicao?.motivo === 'fila-vazia' && fila && sup ? mastersDevidos(raiz, estado, fila, sup) : [];
|
|
336
|
+
if (devidos.length) {
|
|
337
|
+
return nada(`o arco segue: a fila está vazia, mas a entrega do arco ainda faz o MASTER por omissão de ${devidos.join(', ')}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (!condicao)
|
|
341
|
+
return nada(`o arco segue: nenhuma condição de fechamento vale agora${falhaDaMedicao}`);
|
|
342
|
+
// O terminal primeiro: daqui em diante nenhum despacho nem efeito passa.
|
|
343
|
+
estado = (0, noctum_arco_1.encerrarArco)(raiz, arco, condicao, quando);
|
|
344
|
+
agora = true;
|
|
345
|
+
}
|
|
346
|
+
const encerramento = estado.encerramento;
|
|
347
|
+
// O retrato do fechamento, uma vez: se o processo caiu entre o encerrado e o registro, o tique seguinte o grava.
|
|
348
|
+
if (!lerFechamento(raiz, arco).retrato)
|
|
349
|
+
gravarRetrato(carregado, arco, estado, encerramento, quando, { ...opcoes, medir, git });
|
|
350
|
+
// Pede a parada de cada sessão em voo uma vez, e confere as pedidas antes; tudo sob a trava do registro do fechamento.
|
|
351
|
+
const atual = (0, noctum_arco_1.lerArco)(raiz, arco, quando) ?? estado;
|
|
352
|
+
const emVoo = (0, noctum_sessoes_em_voo_1.sessoesEmVooDoArco)(raiz, atual);
|
|
353
|
+
const novas = [], conferidas = [];
|
|
354
|
+
(0, noctum_registro_1.comRegistro)(raiz, arco, 'fechamento', (linhas, anexar) => {
|
|
355
|
+
const pedidas = linhas.filter(l => l.evento.tipo === 'parada_pedida').map(l => l.evento.parada);
|
|
356
|
+
const jaConferidas = new Set(linhas.filter(l => l.evento.tipo === 'parada_conferida')
|
|
357
|
+
.map(l => l.evento.conferencia.sessionId));
|
|
358
|
+
const aConferir = pedidas.filter(p => p.resultado === 'pedida' && p.sessionId && !jaConferidas.has(p.sessionId));
|
|
359
|
+
if (aConferir.length && !agora) {
|
|
360
|
+
const lista = listar();
|
|
361
|
+
if (lista.lidas) {
|
|
362
|
+
for (const p of aConferir) {
|
|
363
|
+
const conferencia = { sessionId: p.sessionId, confirmada: !lista.vivas.has(p.sessionId),
|
|
364
|
+
detalhe: lista.vivas.has(p.sessionId) ? 'a sessão segue viva na listagem do runtime depois do pedido de parada'
|
|
365
|
+
: 'a sessão não aparece viva na listagem do runtime' };
|
|
366
|
+
anexar({ tipo: 'parada_conferida', conferencia }, quando);
|
|
367
|
+
conferidas.push(conferencia);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const chave = (s) => s.sessionId ?? `reserva:${s.seq}`;
|
|
372
|
+
const jaPedidas = new Set(pedidas.map(chave));
|
|
373
|
+
for (const s of emVoo.filter(x => !jaPedidas.has(chave(x)))) {
|
|
374
|
+
let resultado, detalhe;
|
|
375
|
+
if (!s.sessionId) {
|
|
376
|
+
resultado = 'sem-id';
|
|
377
|
+
detalhe = 'reserva pendente: a sessão pode ter aberto sem id, e não há o que parar';
|
|
378
|
+
}
|
|
379
|
+
else if (s.runtime !== 'claude-bg') {
|
|
380
|
+
resultado = 'sem-controle';
|
|
381
|
+
detalhe = 'parar a sessão do codex exige o controller vinculado';
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
let r;
|
|
385
|
+
try {
|
|
386
|
+
r = parar(s);
|
|
387
|
+
}
|
|
388
|
+
catch (e) {
|
|
389
|
+
r = { ok: false, detalhe: e.message.slice(0, 300) };
|
|
390
|
+
}
|
|
391
|
+
resultado = r.ok ? 'pedida' : 'falhou';
|
|
392
|
+
detalhe = r.detalhe || (r.ok ? 'o runtime aceitou o pedido de parada' : 'o runtime não aceitou o pedido de parada');
|
|
393
|
+
}
|
|
394
|
+
const parada = { seq: s.seq, sessionId: s.sessionId, trabalho: s.trabalho, thread: s.thread, runtime: s.runtime,
|
|
395
|
+
conta: s.conta, resultado, detalhe };
|
|
396
|
+
anexar({ tipo: 'parada_pedida', parada }, quando);
|
|
397
|
+
novas.push(parada);
|
|
398
|
+
}
|
|
399
|
+
}, { esperarMs: 5_000 });
|
|
400
|
+
const registro = lerFechamento(raiz, arco);
|
|
401
|
+
return { fechado: true, agora, motivo: encerramento.motivo, detalhe: encerramento.detalhe, retrato: registro.retrato,
|
|
402
|
+
paradas: registro.paradas, conferencias: registro.conferencias };
|
|
403
|
+
}
|
|
404
|
+
/** O que cada desfecho da parada quer dizer para o dono, sem o código. */
|
|
405
|
+
const PARADA_EM_TEXTO = Object.freeze({
|
|
406
|
+
'sem-id': () => 'reserva pendente sem id de sessão, nada a parar; reconciliar antes do arco novo',
|
|
407
|
+
'sem-controle': (p) => `sem controle de parada no ${p.runtime}; conferir a sessão antes do arco novo`,
|
|
408
|
+
falhou: (p) => `o pedido de parada falhou (${p.detalhe})`,
|
|
409
|
+
});
|
|
410
|
+
/** Uma linha por parada, para o retrato e o relatório. */
|
|
411
|
+
function textoDaParada(p, conferencias) {
|
|
412
|
+
const c = p.sessionId ? conferencias.find(x => x.sessionId === p.sessionId) : undefined;
|
|
413
|
+
const situacao = p.resultado !== 'pedida' ? PARADA_EM_TEXTO[p.resultado](p) : !c ? 'parada pedida, sem conferência ainda'
|
|
414
|
+
: c.confirmada ? 'parada confirmada' : 'parada não confirmada';
|
|
415
|
+
return `${p.sessionId ?? `reserva ${p.seq}`} (${p.trabalho}, ${p.runtime}): ${situacao}`;
|
|
416
|
+
}
|
package/dist/noctum-fila.js
CHANGED
|
@@ -22,6 +22,11 @@ exports.fatosDaFila = fatosDaFila;
|
|
|
22
22
|
* id) deixa o trabalho na fila, e o despacho seguinte sai por outra conta. Fechar o arco e o relatório são da N6.
|
|
23
23
|
*
|
|
24
24
|
* `fatosDaFila` relê o disco a cada chamada; `montarFila` é pura sobre os fatos e o instante. Nada aqui despacha nem grava.
|
|
25
|
+
*
|
|
26
|
+
* RM-058, fatia N4 (D8 e D21 da ork-rm058n4): a fila respeita, quando vem, o que a supervisão do arco decidiu. O trabalho
|
|
27
|
+
* isolado não sai sozinho neste arco; o trabalho bloqueado para a N4 sem reserva pendente (a falha com id antes do primeiro
|
|
28
|
+
* despacho, o passo de retomar, o fim de turno sem resultado e o que ficou sem passo depois da sessão morta) volta à fila
|
|
29
|
+
* na fase da retomada que o vigia autorizou. A reserva pendente nunca é sobreposta. Sem a supervisão, nada muda.
|
|
25
30
|
*/
|
|
26
31
|
const roadmap_reservas_1 = require("./roadmap-reservas");
|
|
27
32
|
const branch_de_estado_1 = require("./branch-de-estado");
|
|
@@ -69,6 +74,16 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
69
74
|
const base = { id: t.id, item: t.item, prioridade: t.prioridade, posicao, thread: null, fase: null,
|
|
70
75
|
motivo: null, entregueEm: null };
|
|
71
76
|
const bloqueado = (motivo, detalhe) => ({ ...base, estado: 'bloqueado', motivo, detalhe });
|
|
77
|
+
// N3: a entrega em outra máquina do arco vale aqui, até sem thread nesta raiz.
|
|
78
|
+
const naRede = fatos.coordenacao?.entregues.get(t.id);
|
|
79
|
+
if (naRede)
|
|
80
|
+
return { ...base, thread: f?.threads[0]?.id ?? null, estado: 'entregue', entregueEm: naRede, detalhe: 'entregue em outra máquina do arco' };
|
|
81
|
+
if (fatos.coordenacao?.encerrados?.has(t.id)) {
|
|
82
|
+
return { ...base, thread: f?.threads[0]?.id ?? null, estado: 'encerrado-sem-entrega', detalhe: 'encerrado sem entrega em outra máquina do arco' };
|
|
83
|
+
}
|
|
84
|
+
if ((0, noctum_envelope_1.envelopeMultimaquina)(estado.conteudo) && fatos.coordenacao?.emOutraMaquina?.has(t.id)) {
|
|
85
|
+
return bloqueado('em-outra-maquina', 'o trabalho tem ordem viva em outra máquina do arco');
|
|
86
|
+
}
|
|
72
87
|
if (!f)
|
|
73
88
|
return bloqueado('thread-ilegivel', 'o trabalho não foi lido');
|
|
74
89
|
if (f.ilegivel)
|
|
@@ -86,6 +101,10 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
86
101
|
return { ...base, estado: 'entregue', entregueEm: f.entregueEm, detalhe: `ship_done da thread ${th.id}` };
|
|
87
102
|
if (th && th.status === 'fechada')
|
|
88
103
|
return { ...base, estado: 'encerrado-sem-entrega', detalhe: `a thread ${th.id} fechou sem ship_done` };
|
|
104
|
+
// RM-058 N4 (D16): o trabalho isolado pela supervisão não sai sozinho neste arco, nem com uma sessão de fora rodando nele.
|
|
105
|
+
const isolado = fatos.supervisao?.isolados.get(t.id);
|
|
106
|
+
if (isolado !== undefined)
|
|
107
|
+
return bloqueado('isolado', isolado);
|
|
89
108
|
if (th && f.passo?.conduzida)
|
|
90
109
|
return { ...base, estado: 'em-curso', detalhe: `a thread ${th.id} está sendo conduzida agora` };
|
|
91
110
|
const mortas = t.dependeDe.filter(d => semSaida.has(d));
|
|
@@ -95,6 +114,9 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
95
114
|
const faltam = t.dependeDe.filter(d => !entregues.has(d));
|
|
96
115
|
if (faltam.length)
|
|
97
116
|
return bloqueado('dependencia', `depende de ${faltam.join(', ')}, ainda não entregue(s)`);
|
|
117
|
+
if (fatos.coordenacao && !fatos.coordenacao.trabalhos.has(t.id)) {
|
|
118
|
+
return bloqueado('sem-ordem', 'o trabalho não tem ordem aceita desta máquina no ramo de coordenação do arco');
|
|
119
|
+
}
|
|
98
120
|
if (fatos.reservas.leitura === 'sem-copia')
|
|
99
121
|
return bloqueado('reserva-sem-leitura', 'esta máquina não tem cópia da branch de reservas');
|
|
100
122
|
const reserva = fatos.reservas.porItem.get(t.item);
|
|
@@ -113,6 +135,12 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
113
135
|
if (erros >= exports.ERROS_SEGUIDOS_QUE_BLOQUEIAM) {
|
|
114
136
|
return bloqueado('erro-repetido', `os ${erros} últimos despachos falharam no núcleo antes de lançar; quem decide é a N4 ou o dono`);
|
|
115
137
|
}
|
|
138
|
+
// RM-058 N4 (D8): o bloqueio que a N2 deixou para a N4 vira a retomada que o vigia autorizou, na fase dela.
|
|
139
|
+
const retomada = fatos.supervisao?.retomadas.get(t.id);
|
|
140
|
+
const paraAN4 = (motivo, detalhe) => retomada
|
|
141
|
+
? { ...base, estado: 'despachavel', fase: retomada.fase,
|
|
142
|
+
detalhe: `retomada autorizada pela supervisão (tentativa ${retomada.tentativa}, ${retomada.motivo}) no lugar de: ${detalhe}` }
|
|
143
|
+
: bloqueado(motivo, detalhe);
|
|
116
144
|
if (!th) {
|
|
117
145
|
// A4 do CHECK: abrir a thread num projeto que não deixa criar #Auto falharia toda noite; o arco nem tenta.
|
|
118
146
|
if (!fatos.modosPermitidos.includes('auto'))
|
|
@@ -128,7 +156,7 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
128
156
|
if (!f.despachada) {
|
|
129
157
|
// B1 da rodada 2: a falha disse o id da sessão, que pode estar aberta; despachar de novo abriria outra.
|
|
130
158
|
if (f.despachoFalho)
|
|
131
|
-
return
|
|
159
|
+
return paraAN4('retomada', `o despacho da thread ${th.id} falhou depois de o runtime dizer o id da sessão; a retomada é da N4`);
|
|
132
160
|
return { ...base, estado: 'despachavel', fase: th.faseAtual, detalhe: `a thread ${th.id} nunca foi despachada` };
|
|
133
161
|
}
|
|
134
162
|
const passo = f.passo;
|
|
@@ -138,12 +166,12 @@ function classificar(t, posicao, f, fatos, entregues, semSaida, estado) {
|
|
|
138
166
|
return { ...base, estado: 'despachavel', fase: passo.fase, detalhe: passo.porque };
|
|
139
167
|
}
|
|
140
168
|
if (passo?.acao === 'retomar')
|
|
141
|
-
return
|
|
169
|
+
return paraAN4('retomada', `${passo.porque}; a retomada é da N4`);
|
|
142
170
|
if (f.espera?.tipo === 'stop-sem-resultado')
|
|
143
|
-
return
|
|
171
|
+
return paraAN4('fim-de-turno-sem-resultado', 'o turno acabou sem o resultado da fase; quem decide é a N4');
|
|
144
172
|
if (f.espera?.tipo === 'concluida')
|
|
145
173
|
return { ...base, estado: 'aguardando-entrega', detalhe: `${passo?.porque ?? 'fase concluída'}; a entrega é da N5` };
|
|
146
|
-
return
|
|
174
|
+
return paraAN4('sem-passo', passo?.porque ?? 'nenhum passo do condutor para a thread');
|
|
147
175
|
}
|
|
148
176
|
/** O último progresso do arco: a autorização, um despacho ou uma entrega. O backoff conta a partir dele. */
|
|
149
177
|
function ultimoProgresso(estado, trabalhos) {
|
|
@@ -165,20 +193,28 @@ function montarFila(fatos) {
|
|
|
165
193
|
return vazia('fonte-indisponivel', { acao: 'aguardar', motivo: 'sem-autorizacao', ate: daqui(exports.CADENCIA_MS) }, ['o arco não tem envelope autorizado']);
|
|
166
194
|
}
|
|
167
195
|
const conteudo = estado.conteudo;
|
|
168
|
-
|
|
196
|
+
// RM-058 N6: o arco encerrado (hora, custo ou fila vazia) também acabou: nada é candidato.
|
|
197
|
+
if (estado.situacao === 'revogado' || estado.situacao === 'expirado' || estado.situacao === 'encerrado') {
|
|
169
198
|
return vazia('vazia', { acao: 'encerrar', motivo: 'arco-encerrado' });
|
|
199
|
+
}
|
|
170
200
|
if (estado.situacao === 'agendado')
|
|
171
201
|
return vazia('bloqueada', { acao: 'aguardar', motivo: 'agendado', ate: conteudo.janela.inicio });
|
|
172
202
|
if (!(0, noctum_envelope_1.envelopeComTrabalhos)(conteudo)) {
|
|
173
203
|
return vazia('fonte-indisponivel', { acao: 'aguardar', motivo: 'fonte-indisponivel', ate: daqui(exports.CADENCIA_MS, conteudo.janela.fim) }, ['o envelope vigente é v1, sem lista de trabalhos']);
|
|
174
204
|
}
|
|
175
|
-
// Primeiro quem já foi entregue, para as dependências; depois cada trabalho.
|
|
205
|
+
// Primeiro quem já foi entregue, para as dependências (aqui ou, no arco entre máquinas, em outra); depois cada trabalho.
|
|
176
206
|
const entregues = new Set(conteudo.trabalhos.filter(t => {
|
|
177
207
|
const f = fatos.porTrabalho.get(t.id);
|
|
178
|
-
return !!f && f.threads.length === 1 && !!f.entregueEm && f.threads[0].roadmap === t.item;
|
|
208
|
+
return fatos.coordenacao?.entregues.has(t.id) || (!!f && f.threads.length === 1 && !!f.entregueEm && f.threads[0].roadmap === t.item);
|
|
179
209
|
}).map(t => t.id));
|
|
180
|
-
// S7 do CHECK: quem fechou sem entrega nunca mais entrega neste arco, nem quem depende dele, de qualquer distância.
|
|
210
|
+
// S7 do CHECK: quem fechou sem entrega nunca mais entrega neste arco, nem quem depende dele, de qualquer distância. No arco
|
|
211
|
+
// entre máquinas (B1 e S1 da rodada 3 da ork-rm058n3), a rede decide antes da thread local: o entregue lá nunca fica sem
|
|
212
|
+
// saída por uma thread antiga fechada aqui, e o encerrado lá fica sem saída aqui também.
|
|
181
213
|
const semSaida = new Set(conteudo.trabalhos.filter(t => {
|
|
214
|
+
if (fatos.coordenacao?.entregues.has(t.id))
|
|
215
|
+
return false;
|
|
216
|
+
if (fatos.coordenacao?.encerrados?.has(t.id))
|
|
217
|
+
return true;
|
|
182
218
|
const f = fatos.porTrabalho.get(t.id);
|
|
183
219
|
return !!f && f.threads.length === 1 && !f.entregueEm && f.threads[0].status === 'fechada' && f.threads[0].roadmap === t.item;
|
|
184
220
|
}).map(t => t.id));
|
|
@@ -220,7 +256,8 @@ function fatosDaFila(carregado, arco, opcoes = {}) {
|
|
|
220
256
|
? { leitura: 'sem-copia', reservas: [] }
|
|
221
257
|
: { leitura: 'copia-local', reservas: (0, roadmap_reservas_1.reservasLocais)(raiz) }))();
|
|
222
258
|
const fatos = { arco, quando, maquina, estado, porTrabalho: new Map(), threadsIlegiveis: [],
|
|
223
|
-
modosPermitidos: carregado.manifesto.conduction.allowed_modes,
|
|
259
|
+
modosPermitidos: carregado.manifesto.conduction.allowed_modes, ...(opcoes.coordenacao ? { coordenacao: opcoes.coordenacao } : {}),
|
|
260
|
+
...(opcoes.supervisao ? { supervisao: opcoes.supervisao } : {}),
|
|
224
261
|
reservas: { leitura: lidas.leitura, porItem: new Map(lidas.reservas.map(r => [r.item, { maquina: r.maquina, thread: r.thread }])) } };
|
|
225
262
|
if (!estado?.conteudo || !(0, noctum_envelope_1.envelopeComTrabalhos)(estado.conteudo))
|
|
226
263
|
return fatos;
|
|
@@ -244,7 +281,9 @@ function fatosDaFila(carregado, arco, opcoes = {}) {
|
|
|
244
281
|
}
|
|
245
282
|
else {
|
|
246
283
|
const alvo = (0, noctum_envelope_1.shaDoPedido)(t.pedido);
|
|
247
|
-
|
|
284
|
+
const ordem = opcoes.coordenacao?.ordens?.get(t.id);
|
|
285
|
+
casam = threads.filter(x => x.roadmap === t.item && x.pedido?.sha256 === alvo &&
|
|
286
|
+
(!ordem || x.assunto.endsWith(`o${ordem.numero}`)));
|
|
248
287
|
// Sem casar e com thread ilegível, ela pode ser a do trabalho: abrir outra duplicaria a thread.
|
|
249
288
|
if (!casam.length && fatos.threadsIlegiveis.length)
|
|
250
289
|
ilegivel = fatos.threadsIlegiveis[0];
|