@orkastery/cli 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/README.md +18 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
- package/adapters/claude-code/README.md +195 -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/autoridade.json +56 -0
- package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
- package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
- package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
- package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
- package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
- package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
- package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
- package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
- package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -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-mesa/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
- package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
- package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +121 -0
- package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
- package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
- package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
- package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
- package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
- package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
- package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
- package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
- package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
- package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
- package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
- package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
- package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
- 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/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
- package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
- package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
- package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
- package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
- package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
- package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
- package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
- 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 +3 -3
- package/adapters/openclaw/README.md +83 -10
- 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/docs-en/markdownlint-cli2.jsonc +22 -0
- package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
- package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
- package/assets/docs-en/produto/README.md +14 -0
- package/assets/docs-en/produto/_modelo-feature.md +62 -0
- package/assets/docs-en/roadmap/README.md +14 -0
- package/assets/docs-en/roadmap/_modelo-item.md +75 -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 +193 -15
- package/dist/adapters/codex-controller-worker.js +12 -5
- package/dist/adapters/codex-events.js +16 -4
- package/dist/adapters/codex.js +13 -2
- package/dist/agents-md.js +24 -15
- package/dist/atualizar-branch.js +245 -0
- package/dist/auditoria.js +13 -11
- package/dist/auditrun.js +68 -48
- package/dist/autorizacao-duravel.js +327 -0
- package/dist/board.js +98 -43
- package/dist/branch-de-estado.js +39 -9
- package/dist/busca-semantica.js +7 -5
- package/dist/catalogo.js +35 -1
- package/dist/changelog-reconciliacao.js +290 -0
- package/dist/check-agil.js +500 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +183 -0
- package/dist/ci.js +255 -46
- package/dist/ciclos.js +8 -6
- package/dist/claim-lint.js +12 -8
- package/dist/claims-conferir.js +350 -0
- package/dist/claims.js +13 -10
- package/dist/company-brain-client.js +45 -3
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +47 -6
- package/dist/conducao-batida.js +759 -0
- package/dist/conducao-sentinela.js +405 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +206 -59
- package/dist/conhecimento-consulta.js +270 -0
- package/dist/conhecimento.js +514 -0
- 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 +103 -82
- package/dist/doctor-forja.js +345 -0
- package/dist/doctor-pulse-cron.js +294 -27
- package/dist/doctor-rede.js +18 -17
- package/dist/doctor.js +278 -116
- package/dist/dsn-da-memoria.js +417 -0
- package/dist/entrega-por-mod.js +503 -0
- package/dist/entrega-pr.js +158 -57
- package/dist/escopo-escrita.js +10 -1
- package/dist/esgotamentos.js +13 -11
- package/dist/estado-thread.js +42 -17
- package/dist/evalrunner.js +35 -32
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/fabrica-batida.js +323 -0
- package/dist/fabrica-estado.js +49 -16
- package/dist/fabrica-publicar.js +3 -1
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +24 -21
- 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 +124 -81
- package/dist/gates.js +3 -28
- package/dist/handoff.js +33 -19
- 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 +53 -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 +72 -3
- package/dist/hitl-sessions.js +62 -9
- package/dist/hitl-tempo-parado.js +4 -4
- package/dist/hitl-texto-livre.js +7 -4
- package/dist/hitl.js +63 -64
- package/dist/horario.js +30 -7
- package/dist/hosts.js +155 -134
- package/dist/impedimento.js +108 -14
- package/dist/index.js +1421 -1019
- package/dist/indice-vetorial.js +14 -12
- package/dist/indice.js +7 -1
- package/dist/init.js +54 -49
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +213 -88
- package/dist/intelligence-graph-contexto.js +56 -17
- package/dist/intelligence-graph-contract.js +2 -1
- package/dist/intelligence-graph-extract-md.js +56 -4
- package/dist/intelligence-graph-extract-ts.js +71 -3
- package/dist/intelligence-graph-query.js +96 -34
- package/dist/leases.js +19 -18
- package/dist/ledger-stats.js +17 -16
- package/dist/ledger.js +46 -2
- package/dist/licoes.js +12 -11
- package/dist/liveness.js +6 -3
- package/dist/locale-accounts.js +220 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +833 -0
- 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 +290 -0
- package/dist/locale-gerados.js +165 -0
- package/dist/locale-grafo.js +129 -0
- package/dist/locale-master.js +182 -0
- package/dist/locale-network.js +524 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-operacao-restante.js +931 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-projetos.js +100 -0
- package/dist/locale-prompts.js +194 -0
- package/dist/locale-pulse.js +349 -0
- package/dist/locale-reservas.js +87 -0
- package/dist/locale-retry.js +524 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +597 -0
- package/dist/locale-thread.js +421 -0
- package/dist/locale-verify.js +201 -0
- package/dist/locale-worktree.js +246 -0
- package/dist/locale.js +1258 -0
- package/dist/maestro-runtime.js +22 -3
- package/dist/manifest.js +415 -13
- package/dist/maquina-ociosa.js +211 -0
- package/dist/maquina.js +31 -7
- package/dist/master-digest.js +6 -1
- package/dist/master-nota-local.js +200 -0
- package/dist/master-nota.js +14 -8
- package/dist/master.js +139 -65
- package/dist/mcp-artifacts.js +11 -2
- package/dist/mcp-conhecimento.js +52 -0
- package/dist/mcp-experiencia.js +26 -5
- package/dist/mcp-git.js +23 -6
- package/dist/mcp-grafo.js +7 -4
- package/dist/mcp-install.js +73 -8
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +90 -16
- package/dist/mcp-ship-transporte.js +977 -0
- package/dist/mcp-ship.js +71 -25
- package/dist/mcp-transportes.js +17 -0
- package/dist/mcp-verify.js +6 -1
- package/dist/memoria.js +63 -58
- package/dist/modos-migracao.js +8 -6
- package/dist/modos.js +20 -24
- package/dist/network-roadmap.js +90 -51
- package/dist/noctum-aceite.js +789 -0
- package/dist/noctum-arco.js +1418 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-changelog.js +399 -0
- package/dist/noctum-cli.js +482 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1169 -0
- package/dist/noctum-envelope.js +1046 -0
- package/dist/noctum-execucao.js +376 -0
- package/dist/noctum-fechamento.js +405 -0
- package/dist/noctum-fila.js +314 -0
- package/dist/noctum-guarda.js +256 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +383 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +362 -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 +591 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +827 -0
- package/dist/noctum-resposta.js +207 -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 +639 -0
- package/dist/ocupacao.js +32 -3
- package/dist/onboarding.js +56 -26
- package/dist/orkmind.js +48 -25
- package/dist/orquestracao.js +44 -47
- package/dist/parado-no-condutor.js +174 -127
- package/dist/phase.js +144 -63
- package/dist/policies.js +37 -4
- package/dist/portfolio.js +4 -2
- package/dist/postura-local.js +235 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +220 -0
- package/dist/projeto-alvo.js +186 -24
- package/dist/prompts.js +140 -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 +151 -24
- package/dist/pulse-resposta.js +368 -4
- package/dist/pulse.js +188 -22
- package/dist/ratelimit.js +16 -6
- package/dist/recall.js +14 -13
- package/dist/redacao-saida.js +63 -0
- package/dist/rede-adesao.js +13 -8
- package/dist/rede-forja.js +108 -24
- package/dist/rede-status.js +66 -47
- package/dist/rede.js +86 -46
- package/dist/retomada-checkpoint.js +101 -0
- package/dist/retry.js +451 -212
- package/dist/roadmap-reservas.js +45 -28
- package/dist/roadmap-status.js +129 -33
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +284 -32
- package/dist/runtime-escada.js +423 -0
- package/dist/runtime-profiles.js +103 -46
- package/dist/runtimes.js +2 -1
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +355 -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 +188 -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 +26 -5
- package/dist/session-watcher-claude.js +81 -20
- package/dist/session-watcher.js +340 -42
- package/dist/sessoes-contas.js +10 -1
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +59 -58
- package/dist/ship-publicar.js +971 -0
- package/dist/ship.js +243 -97
- package/dist/steal.js +77 -0
- package/dist/superficie.js +14 -11
- package/dist/thread-close.js +12 -11
- package/dist/thread.js +274 -100
- 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 +13 -3
- package/dist/varredura-acoes.js +507 -0
- package/dist/verify.js +608 -76
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +167 -0
- package/dist/worktree.js +99 -83
- package/dist/yaml.js +27 -8
- 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 +9 -4
- package/references/security-checklist.md +3 -3
- package/schemas/code-artifact-graph.v1.schema.json +2 -1
- 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,80 @@
|
|
|
1
|
+
// Contrato do Clima de Cota (RM-059, onda 1, F4): os tipos da serie e da previsao das janelas de limite
|
|
2
|
+
// da conta, e o estado do mod. O Clima nao acrescenta noun ao `$`: usa o `$.ork` da `ork-ponte`, que ele
|
|
3
|
+
// lista em `dependencies`. Sem import nem referencia, como o motor exige de um contrato.
|
|
4
|
+
|
|
5
|
+
/** Um ponto da serie: quando foi lido (ms desde a epoca, relogio do `$.clock`) e o percentual. */
|
|
6
|
+
export type ClimaPonto = {
|
|
7
|
+
em: number
|
|
8
|
+
pct: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** A serie de uma janela (`five_hour`, `seven_day` ou a de gasto de um gateway), desde que ela renovou. */
|
|
12
|
+
export type ClimaJanela = {
|
|
13
|
+
kind: string
|
|
14
|
+
/** Quando renova, em ms desde a epoca; `null` quando o motor nao disse. */
|
|
15
|
+
renovaEm: number | null
|
|
16
|
+
pontos: ClimaPonto[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** A serie `ork.clima-serie/v1` no `$.store` do mod, que dura entre sessoes. */
|
|
20
|
+
export type ClimaSerie = {
|
|
21
|
+
formato: 'ork.clima-serie/v1'
|
|
22
|
+
janelas: ClimaJanela[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `esgotada`: 100% ou mais. `acaba-antes`: no ritmo atual, acaba antes de renovar. `folga`: o ritmo nao
|
|
27
|
+
* esgota antes de renovar. `sem-ritmo`: ainda sem leituras para medir o ritmo, ou com uma serie nova demais
|
|
28
|
+
* para prever tao longe (D15).
|
|
29
|
+
*/
|
|
30
|
+
export type ClimaEstado = 'esgotada' | 'acaba-antes' | 'folga' | 'sem-ritmo'
|
|
31
|
+
|
|
32
|
+
/** A previsao de uma janela no ritmo atual. */
|
|
33
|
+
export type ClimaPrevisao = {
|
|
34
|
+
kind: string
|
|
35
|
+
/** `5 h`, `7 d`, `gasto` ou o proprio `kind`. */
|
|
36
|
+
rotulo: string
|
|
37
|
+
/** O percentual da ultima leitura. */
|
|
38
|
+
pct: number
|
|
39
|
+
/** Quando a ultima leitura chegou, em ms desde a epoca. */
|
|
40
|
+
lidaEm: number
|
|
41
|
+
renovaEm: number | null
|
|
42
|
+
/** Pontos percentuais por hora no intervalo recente; `null` sem leituras suficientes. */
|
|
43
|
+
ritmoPorHora: number | null
|
|
44
|
+
/** Quando acaba no ritmo atual, em ms desde a epoca; `null` sem ritmo que esgote. */
|
|
45
|
+
acabaEm: number | null
|
|
46
|
+
estado: ClimaEstado
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Uma retomada da fila que nao cabe, como a ultima leitura da fila deixou. */
|
|
50
|
+
export type ClimaNaoCabe = {
|
|
51
|
+
id: string
|
|
52
|
+
thread: string
|
|
53
|
+
/** O que vai ao registro do mostrado da ponte (D8). */
|
|
54
|
+
texto: string
|
|
55
|
+
/** Se o registro ja aceitou; a que falhou e tentada de novo na medicao seguinte (D15). */
|
|
56
|
+
registrada: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** O ultimo problema de uma medicao, que o `/clima` mostra (D15). */
|
|
60
|
+
export type ClimaProblema = {
|
|
61
|
+
/** O que aconteceu, numa frase que comeca minuscula. */
|
|
62
|
+
motivo: string
|
|
63
|
+
/** Quando, em ms desde a epoca; `null` quando nem o relogio respondeu. */
|
|
64
|
+
em: number | null
|
|
65
|
+
/** Se veio da leitura: so a proxima leitura boa o limpa. */
|
|
66
|
+
daLeitura: boolean
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
declare module 'claude-code' {
|
|
70
|
+
interface PluginState {
|
|
71
|
+
'ork-clima': {
|
|
72
|
+
/** A ultima linha que o Clima publicou na faixa da ponte; `null` depois de tira-la. */
|
|
73
|
+
faixa: string | null
|
|
74
|
+
/** As retomadas que nao cabiam na ultima leitura da fila, para as medicoes sem leitura nova (D13). */
|
|
75
|
+
naoCabem: ClimaNaoCabe[]
|
|
76
|
+
/** O ultimo problema de medicao, ate uma medicao boa limpa-lo (D15). */
|
|
77
|
+
problema: ClimaProblema | null
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ork-freio",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Freio de Lote do Orkastery no Claude Code: na sessão de fase, acha as claims que o lote de ferramentas mexeu, pede ao núcleo a conferência delas no sandbox do verify e devolve o que quebrou no lote seguinte.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Orkastery contributors",
|
|
7
|
+
"url": "https://github.com/orkastery"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://orkastery.com/",
|
|
10
|
+
"repository": "https://github.com/orkastery/orkastery",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"types": "./types/index.d.ts",
|
|
13
|
+
"dependencies": ["ork-ponte"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// A carga do Freio de Lote (RM-059, F2, T2.1): o que ele le do nucleo para saber quais claims vigiar.
|
|
2
|
+
// Modulo puro: interpreta o que as ferramentas de leitura do servidor `orkastery` devolvem e o retrato
|
|
3
|
+
// da ponte. As chamadas ao `$` ficam no register.ts; nada aqui le `.orkastery/` do disco (D2).
|
|
4
|
+
import type { FreioCarga, FreioClaim } from '../types'
|
|
5
|
+
|
|
6
|
+
export const SERVIDOR = 'orkastery'
|
|
7
|
+
/**
|
|
8
|
+
* A lista fechada de ferramentas MCP do Freio (D2): as duas de leitura. O `$.mcp.call` nao pede permissao
|
|
9
|
+
* ao dono, entao o teste do nucleo confere pela AST que o mod so chama estas.
|
|
10
|
+
*/
|
|
11
|
+
export const FERRAMENTA_DAS_CLAIMS = 'ork_claims_list'
|
|
12
|
+
export const FERRAMENTA_DO_PLANO = 'ork_artifact_read'
|
|
13
|
+
export const FERRAMENTAS_DO_FREIO: readonly string[] = [FERRAMENTA_DAS_CLAIMS, FERRAMENTA_DO_PLANO]
|
|
14
|
+
/** Claims com mais idade que isto sao relidas no lote que precisa delas. */
|
|
15
|
+
export const IDADE_DAS_CLAIMS_MS = 60000
|
|
16
|
+
/** O plano com mais idade que isto e relido no lote que precisa dele. */
|
|
17
|
+
export const IDADE_DO_PLANO_MS = 300000
|
|
18
|
+
|
|
19
|
+
const ID_DE_CLAIM = /^C\d+$/
|
|
20
|
+
const ID_DE_THREAD = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/
|
|
21
|
+
/** O rotulo de `touch_paths` de uma tarefa nos formatos em uso nos planos; o grupo 1 e o resto da linha. */
|
|
22
|
+
const ROTULO_DE_TOUCH_PATHS = /^\s*(?:[-*+]\s+)?(?:\*\*touch_paths:?\*\*\s*:?|`touch_paths`\s*:|touch_paths\s*:)\s*(.*)$/i
|
|
23
|
+
/** Linha que abre outro item de lista, cabecalho ou cerca de codigo (a mesma regra do verify da tarefa no nucleo). */
|
|
24
|
+
const ABRE_BLOCO = /^\s*(?:[-*+]\s|\d+[.)]\s|#{1,6}\s|```|~~~)/
|
|
25
|
+
const TRECHO = /`([^`]+)`/g
|
|
26
|
+
|
|
27
|
+
export class ErroDeCarga extends Error {}
|
|
28
|
+
|
|
29
|
+
/** Os argumentos de cada ferramenta da lista fechada para a thread do despacho. */
|
|
30
|
+
export function argsDaFerramenta(ferramenta: string, thread: string): Record<string, unknown> {
|
|
31
|
+
if (!ID_DE_THREAD.test(thread)) throw new ErroDeCarga('ork-freio: id de thread invalido')
|
|
32
|
+
if (ferramenta === FERRAMENTA_DAS_CLAIMS) return { threadId: thread }
|
|
33
|
+
if (ferramenta === FERRAMENTA_DO_PLANO) return { threadId: thread, tipo: 'plan' }
|
|
34
|
+
throw new ErroDeCarga(`ork-freio: ferramenta fora da lista fechada: ${ferramenta}`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** O JSON do primeiro bloco de texto de um resultado MCP; resultado com erro vira excecao. */
|
|
38
|
+
export function jsonDoMcp(r: unknown, ferramenta: string): unknown {
|
|
39
|
+
const resultado = r as { content?: ReadonlyArray<{ type?: string; text?: unknown }>; isError?: boolean } | null
|
|
40
|
+
const texto = (resultado?.content ?? []).find(c => c?.type === 'text' && typeof c.text === 'string')?.text as string | undefined
|
|
41
|
+
if (resultado?.isError) throw new ErroDeCarga(`ork-freio: ${ferramenta} respondeu com erro${texto ? `: ${texto.slice(0, 200)}` : ''}`)
|
|
42
|
+
if (texto === undefined) throw new ErroDeCarga(`ork-freio: ${ferramenta} nao devolveu texto`)
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(texto)
|
|
45
|
+
} catch {
|
|
46
|
+
throw new ErroDeCarga(`ork-freio: ${ferramenta} devolveu texto que nao e JSON`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Caminho relativo normalizado: barras para a frente, sem `./` na frente nem barra no fim. */
|
|
51
|
+
export function normalizar(caminho: string): string {
|
|
52
|
+
return caminho.trim().replace(/\\/g, '/').replace(/^(?:\.\/)+/, '').replace(/\/+$/, '')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* As claims nao retiradas, com o que o Freio precisa: id, arquivo e comandos. O `claims.jsonl` e append-only e
|
|
57
|
+
* o nucleo ja devolve a versao mais nova de cada claim; se vier repetida, a ultima vence do mesmo jeito.
|
|
58
|
+
*/
|
|
59
|
+
export function claimsDoNucleo(bruto: unknown): FreioClaim[] {
|
|
60
|
+
if (!Array.isArray(bruto)) throw new ErroDeCarga('ork-freio: a lista de claims nao e lista')
|
|
61
|
+
const porId = new Map<string, FreioClaim | null>()
|
|
62
|
+
for (const item of bruto) {
|
|
63
|
+
const c = item as { id?: unknown; arquivo?: unknown; verificar?: unknown; estado?: unknown } | null
|
|
64
|
+
if (!c || typeof c.id !== 'string' || !ID_DE_CLAIM.test(c.id)) continue
|
|
65
|
+
if (c.estado === 'retirada') { porId.set(c.id, null); continue }
|
|
66
|
+
const comandos = Array.isArray(c.verificar) ? c.verificar.filter((v): v is string => typeof v === 'string' && v.trim() !== '') : []
|
|
67
|
+
const arquivo = typeof c.arquivo === 'string' && c.arquivo.trim() !== '' ? normalizar(c.arquivo) : null
|
|
68
|
+
porId.set(c.id, { id: c.id, arquivo, comandos })
|
|
69
|
+
}
|
|
70
|
+
return [...porId.values()].filter((c): c is FreioClaim => c !== null)
|
|
71
|
+
.sort((a, b) => Number(a.id.slice(1)) - Number(b.id.slice(1)))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* O maior numero de claim que o nucleo ja deu na thread, retiradas incluidas: claim com numero acima dele foi
|
|
76
|
+
* cadastrada depois desta leitura, e a rodada nao a tira da fila por nao estar na lista.
|
|
77
|
+
*/
|
|
78
|
+
export function maiorNumeroDeClaim(bruto: unknown): number {
|
|
79
|
+
if (!Array.isArray(bruto)) return 0
|
|
80
|
+
let maior = 0
|
|
81
|
+
for (const item of bruto) {
|
|
82
|
+
const id = (item as { id?: unknown } | null)?.id
|
|
83
|
+
if (typeof id === 'string' && ID_DE_CLAIM.test(id)) maior = Math.max(maior, Number(id.slice(1)))
|
|
84
|
+
}
|
|
85
|
+
return maior
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** O texto do plano que o `ork_artifact_read` devolve, ou `null` quando a thread ainda nao tem plano. */
|
|
89
|
+
export function textoDoPlano(bruto: unknown): string | null {
|
|
90
|
+
const documento = bruto as { tipo?: unknown; conteudo?: unknown } | null
|
|
91
|
+
if (!documento || typeof documento !== 'object') throw new ErroDeCarga('ork-freio: o plano lido nao e objeto')
|
|
92
|
+
return typeof documento.conteudo === 'string' ? documento.conteudo : null
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function ehCaminho(texto: string): boolean {
|
|
96
|
+
return texto !== '' && !/\s/.test(texto) && !texto.startsWith('-') && !texto.split('/').includes('..')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* A uniao dos `touch_paths` de todas as tarefas do plano (D9): os trechos entre crases do item do rotulo inteiro,
|
|
101
|
+
* como o Markdown o junta e como o nucleo le o verify da tarefa: a linha do rotulo, as linhas mais recuadas que
|
|
102
|
+
* ela (sub-itens e continuacao quebrada) e a continuacao logo abaixo que nao abre outro bloco. `null` sem plano
|
|
103
|
+
* ou sem nenhum caminho.
|
|
104
|
+
*/
|
|
105
|
+
export function touchPathsDoPlano(conteudo: string | null): string[] | null {
|
|
106
|
+
if (typeof conteudo !== 'string') return null
|
|
107
|
+
const achados = new Set<string>()
|
|
108
|
+
const juntar = (texto: string) => {
|
|
109
|
+
for (const m of texto.matchAll(TRECHO)) {
|
|
110
|
+
const caminho = normalizar(m[1] as string)
|
|
111
|
+
if (ehCaminho(caminho)) achados.add(caminho)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
let recuoDoRotulo = -1
|
|
115
|
+
let depoisDeBranco = false
|
|
116
|
+
for (const linha of conteudo.replace(/\r\n/g, '\n').split('\n')) {
|
|
117
|
+
const recuo = linha.length - linha.trimStart().length
|
|
118
|
+
const rotulo = ROTULO_DE_TOUCH_PATHS.exec(linha)
|
|
119
|
+
if (rotulo) {
|
|
120
|
+
juntar(rotulo[1] as string)
|
|
121
|
+
recuoDoRotulo = recuo
|
|
122
|
+
depoisDeBranco = false
|
|
123
|
+
continue
|
|
124
|
+
}
|
|
125
|
+
if (recuoDoRotulo < 0) continue
|
|
126
|
+
if (linha.trim() === '') { depoisDeBranco = true; continue }
|
|
127
|
+
if (recuo <= recuoDoRotulo && (depoisDeBranco || ABRE_BLOCO.test(linha))) { recuoDoRotulo = -1; continue }
|
|
128
|
+
juntar(linha)
|
|
129
|
+
depoisDeBranco = false
|
|
130
|
+
}
|
|
131
|
+
return achados.size > 0 ? [...achados].sort() : null
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** O status da thread na secao `threads` do retrato `ork.maestro-snapshot/v1`, ou `null` quando ele nao diz. */
|
|
135
|
+
export function statusNoRetrato(retrato: unknown, thread: string): string | null {
|
|
136
|
+
const itens = (retrato as { sections?: { threads?: { items?: unknown } } } | null)?.sections?.threads?.items
|
|
137
|
+
if (!Array.isArray(itens)) return null
|
|
138
|
+
const item = itens.find(i => (i as { id?: unknown } | null)?.id === thread) as { status?: unknown } | undefined
|
|
139
|
+
return typeof item?.status === 'string' ? item.status : null
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** O Freio age na thread? So deixa de agir com a thread fechada no retrato (D10). */
|
|
143
|
+
export function threadAtiva(status: string | null): boolean {
|
|
144
|
+
return status !== 'fechada'
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** A carga de uma thread antes da primeira leitura. */
|
|
148
|
+
export function cargaVazia(thread: string): FreioCarga {
|
|
149
|
+
return { thread, statusDaThread: null, claims: null, claimsEm: 0, maiorClaim: 0, touchPaths: null, planoLido: false, planoEm: 0, erros: [] }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** As claims precisam ser relidas: nunca lidas, velhas, ou o lote mexeu nelas. */
|
|
153
|
+
export function claimsVelhas(carga: FreioCarga, agora: number, loteMexeuNasClaims: boolean): boolean {
|
|
154
|
+
return carga.claims === null || loteMexeuNasClaims || !(agora - carga.claimsEm >= 0 && agora - carga.claimsEm < IDADE_DAS_CLAIMS_MS)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** O plano precisa ser relido: nunca lido, velho, ou o lote o regravou. */
|
|
158
|
+
export function planoVelho(carga: FreioCarga, agora: number, loteMexeuNoPlano: boolean): boolean {
|
|
159
|
+
return !carga.planoLido || loteMexeuNoPlano || !(agora - carga.planoEm >= 0 && agora - carga.planoEm < IDADE_DO_PLANO_MS)
|
|
160
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// A conferencia pelo nucleo e a devolucao no lote seguinte (RM-059, F2, T2.3). Modulo puro: monta o argv do
|
|
2
|
+
// `ork claims conferir`, le o JSON `ork.claims-conferencia/v1`, cuida da rodada, apura o resultado e escreve o
|
|
3
|
+
// texto do lote e a linha de status. O Freio nunca roda o comando de uma claim: quem roda e o nucleo, no
|
|
4
|
+
// sandbox do verify (D12 do plano dos mods), e quem verifica de verdade continua sendo o `ork verify`.
|
|
5
|
+
import type { FreioEntrega, FreioFalha, FreioPedido, FreioRodada, FreioVigia } from '../types'
|
|
6
|
+
|
|
7
|
+
export const FORMATO_DA_CONFERENCIA = 'ork.claims-conferencia/v1'
|
|
8
|
+
/** O prazo total pedido ao nucleo, em segundos (o padrao do `ork claims conferir`, D6). */
|
|
9
|
+
export const PRAZO_DA_CONFERENCIA_S = 180
|
|
10
|
+
/** O vigia do mod: a conferencia que passar disto e encerrada e fica sem veredito (D6, D7). */
|
|
11
|
+
export const VIGIA_DA_CONFERENCIA_MS = 240000
|
|
12
|
+
/**
|
|
13
|
+
* Depois do vigia, quanto o laco espera o processo fechar; se ele seguir aberto, a conferencia fica indisponivel
|
|
14
|
+
* e nenhuma rodada nova abre enquanto ele nao fechar (duas conferencias nunca correm juntas).
|
|
15
|
+
*/
|
|
16
|
+
export const ESPERA_DO_FIM_MS = 30000
|
|
17
|
+
/** O motivo de indisponivel quando o processo da rodada anterior nao fechou. */
|
|
18
|
+
export const MOTIVO_PROCESSO_ABERTO = 'o processo anterior do ork claims conferir nao fechou depois do vigia'
|
|
19
|
+
/** Claims por rodada; so uma rodada roda por vez (D5). */
|
|
20
|
+
export const TETO_POR_RODADA = 6
|
|
21
|
+
/** A pausa depois de uma conferencia indisponivel (D7). */
|
|
22
|
+
export const PAUSA_SEM_CONFERENCIA_MS = 600000
|
|
23
|
+
/** A pausa curta quando outra conducao segura a thread (saida 3): a rodada volta para a fila. */
|
|
24
|
+
export const PAUSA_DE_CONDUCAO_MS = 60000
|
|
25
|
+
/** Tetos do texto ao modelo (D8). */
|
|
26
|
+
export const TETO_DE_CLAIMS_NO_TEXTO = 3
|
|
27
|
+
export const TETO_DE_LINHAS_DA_SAIDA = 12
|
|
28
|
+
export const TETO_DE_CARACTERES_DA_SAIDA = 1200
|
|
29
|
+
export const TETO_DO_TEXTO = 6000
|
|
30
|
+
/** O que o mod guarda da saida do processo: o JSON inteiro cabe com folga; do stderr, so o fim. */
|
|
31
|
+
export const TETO_DA_SAIDA_LIDA = 4194304
|
|
32
|
+
export const TETO_DO_ERRO_LIDO = 2000
|
|
33
|
+
|
|
34
|
+
const ID_DE_CLAIM = /^C\d+$/
|
|
35
|
+
const ID_DE_THREAD = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/
|
|
36
|
+
/** A recusa do nucleo por uma claim so (retirada ou que nao existe): as outras da rodada voltam para a fila. */
|
|
37
|
+
const RECUSA_POR_CLAIM = /^claims\.conferir\.(?:retirada|desconhecida): (C\d+)\b/
|
|
38
|
+
/** A saida do CLI quando outra conducao segura a thread. */
|
|
39
|
+
const SAIDA_DE_CONDUCAO = 3
|
|
40
|
+
|
|
41
|
+
/** Uma claim como a conferencia a devolveu, so com o que o Freio entrega. */
|
|
42
|
+
export type ItemConferido = {
|
|
43
|
+
id: string
|
|
44
|
+
alegacao: string
|
|
45
|
+
arquivo: string | null
|
|
46
|
+
verificado: boolean
|
|
47
|
+
motivo: string | null
|
|
48
|
+
comando: string
|
|
49
|
+
codigo: number | null
|
|
50
|
+
fim: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A leitura de uma rodada: o resultado do nucleo; a recusa de uma claim so (retirada ou desconhecida); a thread
|
|
55
|
+
* conduzida por outro (saida 3); a conferencia indisponivel; ou o vigia do mod vencido.
|
|
56
|
+
*/
|
|
57
|
+
export type Leitura =
|
|
58
|
+
| { tipo: 'resultado'; itens: ItemConferido[] }
|
|
59
|
+
| { tipo: 'recusada'; id: string; motivo: string }
|
|
60
|
+
| { tipo: 'ocupada'; motivo: string }
|
|
61
|
+
| { tipo: 'indisponivel'; motivo: string }
|
|
62
|
+
| { tipo: 'prazo' }
|
|
63
|
+
|
|
64
|
+
/** O argv do `ork claims conferir` de uma rodada; o comando das claims fica com o nucleo. */
|
|
65
|
+
export function argvDaConferencia(thread: string, ids: readonly string[]): string[] {
|
|
66
|
+
if (!ID_DE_THREAD.test(thread)) throw new Error('ork-freio: id de thread invalido')
|
|
67
|
+
if (ids.length === 0 || ids.some(id => !ID_DE_CLAIM.test(id))) throw new Error('ork-freio: ids de claim invalidos')
|
|
68
|
+
return ['ork', 'claims', 'conferir', thread, '--claims', ids.join(','), '--prazo', String(PRAZO_DA_CONFERENCIA_S), '--json']
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Junta um pedaco da saida, ate o teto; do stderr fica so o fim. */
|
|
72
|
+
export function acumular(atual: string, pedaco: string, doErro: boolean): string {
|
|
73
|
+
const junto = atual + pedaco
|
|
74
|
+
if (doErro) return junto.length > TETO_DO_ERRO_LIDO ? junto.slice(-TETO_DO_ERRO_LIDO) : junto
|
|
75
|
+
return junto.length > TETO_DA_SAIDA_LIDA ? junto.slice(0, TETO_DA_SAIDA_LIDA) : junto
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const ultimaLinha = (texto: string) => texto.trim().split('\n').filter(l => l.trim() !== '').slice(-1)[0]?.trim().slice(0, 300) ?? ''
|
|
79
|
+
|
|
80
|
+
function itemDoNucleo(bruto: unknown): ItemConferido | null {
|
|
81
|
+
const i = bruto as { id?: unknown; alegacao?: unknown; arquivo?: unknown; verificado?: unknown; motivo?: unknown; execucoes?: unknown } | null
|
|
82
|
+
if (!i || typeof i.id !== 'string' || !ID_DE_CLAIM.test(i.id)) return null
|
|
83
|
+
const execucoes = Array.isArray(i.execucoes) ? i.execucoes as Array<{ comando?: unknown; ok?: unknown; code?: unknown; fim?: unknown }> : []
|
|
84
|
+
const chave = execucoes.find(x => x && x.ok === false) ?? execucoes[0]
|
|
85
|
+
return {
|
|
86
|
+
id: i.id,
|
|
87
|
+
alegacao: typeof i.alegacao === 'string' ? i.alegacao : '',
|
|
88
|
+
arquivo: typeof i.arquivo === 'string' ? i.arquivo : null,
|
|
89
|
+
verificado: i.verificado === true,
|
|
90
|
+
motivo: typeof i.motivo === 'string' ? i.motivo : null,
|
|
91
|
+
comando: typeof chave?.comando === 'string' ? chave.comando : '',
|
|
92
|
+
codigo: typeof chave?.code === 'number' ? chave.code : null,
|
|
93
|
+
fim: typeof chave?.fim === 'string' ? chave.fim : '',
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* A saida do `ork claims conferir --json` (D6, D7): o resultado so com o formato certo, itens em lista e saida
|
|
99
|
+
* 0 ou 1; a recusa de uma claim so (saida 2 com `claims.conferir.retirada` ou `.desconhecida`) e por claim; a
|
|
100
|
+
* saida 3 e outra conducao segurando a thread; o resto (saida 2 com `erro`, um `ork` antigo) e indisponivel.
|
|
101
|
+
*/
|
|
102
|
+
export function lerConferencia(stdout: string, codigo: number | null, stderr: string): Leitura {
|
|
103
|
+
let j: { formato?: unknown; itens?: unknown; erro?: unknown } | null = null
|
|
104
|
+
try { j = JSON.parse(stdout) } catch { j = null }
|
|
105
|
+
if (j && j.formato === FORMATO_DA_CONFERENCIA && Array.isArray(j.itens) && (codigo === 0 || codigo === 1)) {
|
|
106
|
+
return { tipo: 'resultado', itens: j.itens.map(itemDoNucleo).filter((i): i is ItemConferido => i !== null) }
|
|
107
|
+
}
|
|
108
|
+
const erro = j && typeof j.erro === 'string' ? j.erro.trim().slice(0, 300) : ''
|
|
109
|
+
const recusa = RECUSA_POR_CLAIM.exec(erro)
|
|
110
|
+
if (recusa) return { tipo: 'recusada', id: recusa[1] as string, motivo: erro }
|
|
111
|
+
// JSON que nao serve nao vira motivo: o fim do stderr diz mais; texto solto (um `ork` antigo) entra pelo fim.
|
|
112
|
+
const motivo = erro || ultimaLinha(stderr) || (j === null ? ultimaLinha(stdout) : '') || `saiu com codigo ${codigo ?? 'desconhecido'}`
|
|
113
|
+
if (codigo === SAIDA_DE_CONDUCAO) return { tipo: 'ocupada', motivo }
|
|
114
|
+
if (erro) return { tipo: 'indisponivel', motivo: erro }
|
|
115
|
+
return { tipo: 'indisponivel', motivo: `ork claims conferir sem resultado: ${motivo}` }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function entregaVazia(): FreioEntrega {
|
|
119
|
+
return { falhas: [], semVeredito: [], recuperadas: [], indisponivel: null }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A vigia com os campos da conferencia preenchidos (a vigia gravada antes deles nasce sem eles). */
|
|
123
|
+
export function comConferencia(v: FreioVigia): Required<FreioVigia> {
|
|
124
|
+
return {
|
|
125
|
+
rodada: null, entrega: entregaVazia(), emRisco: [], pausaAte: 0, indisponivel: null, avisouIndisponivel: false, foraPendentes: [],
|
|
126
|
+
avisadas: [],
|
|
127
|
+
...v,
|
|
128
|
+
} as Required<FreioVigia>
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Ha trabalho para o laco de fundo: fila com claim ou rodada aberta (a de um laco que morreu com o worker, D10). */
|
|
132
|
+
export function precisaDeLaco(vigia: FreioVigia): boolean {
|
|
133
|
+
const v = comConferencia(vigia)
|
|
134
|
+
return v.fila.length > 0 || v.rodada !== null
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const numero = (id: string) => Number(id.slice(1)) || 0
|
|
138
|
+
|
|
139
|
+
/** A mesma ordem da fila do lote: a forca maior antes; na mesma forca, a claim mais nova antes. */
|
|
140
|
+
function ordenar(pedidos: FreioPedido[]): FreioPedido[] {
|
|
141
|
+
return pedidos.sort((a, b) => b.forca - a.forca || numero(b.id) - numero(a.id))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Devolve pedidos a fila sem repeticao, juntando os caminhos e ficando com a forca maior. */
|
|
145
|
+
function devolverAFila(fila: readonly FreioPedido[], pedidos: readonly FreioPedido[]): FreioPedido[] {
|
|
146
|
+
const porId = new Map(fila.map(p => [p.id, { ...p, caminhos: [...p.caminhos] }]))
|
|
147
|
+
for (const p of pedidos) {
|
|
148
|
+
const ja = porId.get(p.id)
|
|
149
|
+
if (!ja) { porId.set(p.id, { ...p, caminhos: [...p.caminhos] }); continue }
|
|
150
|
+
ja.forca = Math.max(ja.forca, p.forca)
|
|
151
|
+
for (const c of p.caminhos) if (!ja.caminhos.includes(c)) ja.caminhos.push(c)
|
|
152
|
+
}
|
|
153
|
+
return ordenar([...porId.values()])
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Os pedidos de uma rodada, para voltarem a fila. */
|
|
157
|
+
function pedidosDaRodada(rodada: FreioRodada, ids: readonly string[]): FreioPedido[] {
|
|
158
|
+
return ids.map(id => ({ id, forca: rodada.forcas?.[id] ?? 1, caminhos: [...(rodada.caminhos[id] ?? [])] }))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Abre a rodada: tira da fila ate o teto, se nao ha rodada aberta nem pausa; a rodada aberta segue como esta.
|
|
163
|
+
* Com a lista das claims ativas, a claim que saiu dela (retirada) sai da fila antes; a claim com numero acima do
|
|
164
|
+
* maior que a leitura viu (cadastrada depois dela) fica, e a recusa por claim do nucleo cobre o resto.
|
|
165
|
+
*/
|
|
166
|
+
export function iniciarRodada(vigia: FreioVigia, agora: number, teto = TETO_POR_RODADA,
|
|
167
|
+
ativas: { ids: readonly string[]; maior: number } | null = null): Required<FreioVigia> {
|
|
168
|
+
const v = comConferencia(vigia)
|
|
169
|
+
const fila = ativas ? v.fila.filter(p => ativas.ids.includes(p.id) || numero(p.id) > ativas.maior) : v.fila
|
|
170
|
+
if (v.rodada || fila.length === 0 || agora < v.pausaAte) return fila === v.fila ? v : { ...v, fila }
|
|
171
|
+
const escolhidos = fila.slice(0, teto)
|
|
172
|
+
const rodada: FreioRodada = {
|
|
173
|
+
ids: escolhidos.map(p => p.id),
|
|
174
|
+
caminhos: Object.fromEntries(escolhidos.map(p => [p.id, [...p.caminhos]])),
|
|
175
|
+
forcas: Object.fromEntries(escolhidos.map(p => [p.id, p.forca])),
|
|
176
|
+
inicio: v.seq,
|
|
177
|
+
}
|
|
178
|
+
return { ...v, fila: fila.slice(teto), rodada }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* O resultado da claim e velho (D6): a claim voltou para a fila durante a rodada (um lote tocou qualquer caminho
|
|
183
|
+
* que a afeta: o arquivo dela, um caminho do comando ou o nome-base) ou um caminho que a abriu foi tocado depois.
|
|
184
|
+
*/
|
|
185
|
+
function velha(v: Required<FreioVigia>, rodada: FreioRodada, id: string): boolean {
|
|
186
|
+
return v.fila.some(p => p.id === id) || (rodada.caminhos[id] ?? []).some(c => (v.toques[c] ?? 0) > rodada.inicio)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Fecha a rodada com a leitura: quebra, sem veredito, recuperada, recusa, conducao alheia e indisponivel (D6, D7). */
|
|
190
|
+
export function fecharRodada(vigia: FreioVigia, leitura: Leitura, agora: number): Required<FreioVigia> {
|
|
191
|
+
const v = comConferencia(vigia)
|
|
192
|
+
const rodada = v.rodada
|
|
193
|
+
if (!rodada) return v
|
|
194
|
+
if (leitura.tipo === 'indisponivel') {
|
|
195
|
+
return {
|
|
196
|
+
...v, rodada: null, fila: [], pausaAte: agora + PAUSA_SEM_CONFERENCIA_MS, indisponivel: leitura.motivo,
|
|
197
|
+
entrega: v.avisouIndisponivel ? v.entrega : { ...v.entrega, indisponivel: leitura.motivo }, avisouIndisponivel: true,
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (leitura.tipo === 'recusada') {
|
|
201
|
+
// So a claim recusada sai; as outras voltam para a fila e rodam na proxima rodada, sem pausa e sem aviso.
|
|
202
|
+
const fila = devolverAFila(v.fila.filter(p => p.id !== leitura.id), pedidosDaRodada(rodada, rodada.ids.filter(id => id !== leitura.id)))
|
|
203
|
+
return { ...v, rodada: null, fila, emRisco: v.emRisco.filter(id => id !== leitura.id) }
|
|
204
|
+
}
|
|
205
|
+
if (leitura.tipo === 'ocupada') {
|
|
206
|
+
return { ...v, rodada: null, fila: devolverAFila(v.fila, pedidosDaRodada(rodada, rodada.ids)), pausaAte: agora + PAUSA_DE_CONDUCAO_MS }
|
|
207
|
+
}
|
|
208
|
+
const avisadas = new Set(v.avisadas)
|
|
209
|
+
const falhas = new Map(v.entrega.falhas.map(f => [f.id, f]))
|
|
210
|
+
const semVeredito = new Map(v.entrega.semVeredito.map(s => [s.id, s]))
|
|
211
|
+
const recuperadas = new Set(v.entrega.recuperadas)
|
|
212
|
+
const emRisco = new Set(v.emRisco)
|
|
213
|
+
const semVez = (id: string, motivo: string) => { semVeredito.set(id, { id, motivo }); falhas.delete(id) }
|
|
214
|
+
if (leitura.tipo === 'prazo') {
|
|
215
|
+
for (const id of rodada.ids) if (!velha(v, rodada, id)) semVez(id, 'prazo do Freio')
|
|
216
|
+
} else {
|
|
217
|
+
for (const item of leitura.itens) {
|
|
218
|
+
if (!rodada.ids.includes(item.id) || velha(v, rodada, item.id)) continue
|
|
219
|
+
if (item.verificado) {
|
|
220
|
+
// So volta como recuperada a claim cuja falha o modelo ja recebeu; a que ele nunca viu sai sem barulho.
|
|
221
|
+
falhas.delete(item.id)
|
|
222
|
+
semVeredito.delete(item.id)
|
|
223
|
+
emRisco.delete(item.id)
|
|
224
|
+
if (avisadas.delete(item.id)) recuperadas.add(item.id)
|
|
225
|
+
} else if (item.motivo === 'claims.failed') {
|
|
226
|
+
const falha: FreioFalha = { id: item.id, alegacao: item.alegacao, arquivo: item.arquivo, comando: item.comando, codigo: item.codigo, fim: item.fim }
|
|
227
|
+
falhas.set(item.id, falha)
|
|
228
|
+
semVeredito.delete(item.id)
|
|
229
|
+
recuperadas.delete(item.id)
|
|
230
|
+
emRisco.add(item.id)
|
|
231
|
+
} else semVez(item.id, item.motivo ?? 'sem motivo')
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
...v, rodada: null, indisponivel: null, emRisco: [...emRisco], avisadas: [...avisadas],
|
|
236
|
+
entrega: { ...v.entrega, falhas: [...falhas.values()], semVeredito: [...semVeredito.values()], recuperadas: [...recuperadas] },
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* A conferencia fica indisponivel sem rodada aberta (o processo da rodada anterior nao fechou): o mesmo efeito da
|
|
242
|
+
* leitura indisponivel (D7), avisando o modelo so na primeira vez.
|
|
243
|
+
*/
|
|
244
|
+
export function indisponivelSemRodada(vigia: FreioVigia, motivo: string, agora: number): Required<FreioVigia> {
|
|
245
|
+
const v = comConferencia(vigia)
|
|
246
|
+
return {
|
|
247
|
+
...v, fila: [], pausaAte: agora + PAUSA_SEM_CONFERENCIA_MS, indisponivel: motivo,
|
|
248
|
+
entrega: v.avisouIndisponivel ? v.entrega : { ...v.entrega, indisponivel: motivo }, avisouIndisponivel: true,
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Tira a entrega da vigia para o lote devolver: a vigia fica com a entrega vazia e lembra as falhas avisadas. */
|
|
253
|
+
export function tomarEntrega(vigia: FreioVigia): { vigia: Required<FreioVigia>; entrega: FreioEntrega } {
|
|
254
|
+
const v = comConferencia(vigia)
|
|
255
|
+
const avisadas = [...new Set([...v.avisadas, ...v.entrega.falhas.map(f => f.id)])]
|
|
256
|
+
return { vigia: { ...v, entrega: entregaVazia(), avisadas }, entrega: v.entrega }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** O fim da saida de uma claim: as ultimas linhas e o ultimo trecho, dentro dos tetos (D8). */
|
|
260
|
+
export function fimDaSaida(fim: string): string[] {
|
|
261
|
+
let texto = fim.replace(/\s+$/, '')
|
|
262
|
+
if (texto.length > TETO_DE_CARACTERES_DA_SAIDA) texto = texto.slice(-TETO_DE_CARACTERES_DA_SAIDA)
|
|
263
|
+
return texto.split('\n').slice(-TETO_DE_LINHAS_DA_SAIDA)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** O texto inteiro de um lote dentro do teto (D8), com a marca de corte. */
|
|
267
|
+
export function limitarTexto(texto: string): string {
|
|
268
|
+
return texto.length > TETO_DO_TEXTO ? `${texto.slice(0, TETO_DO_TEXTO - 40)}\n(texto cortado pelo Freio de Lote)` : texto
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const lista = (ids: readonly string[]) => ids.join(', ')
|
|
272
|
+
|
|
273
|
+
/** O texto que o lote devolve ao modelo (D8); sem novidade, nenhum texto. */
|
|
274
|
+
export function textoDaEntrega(e: FreioEntrega): string {
|
|
275
|
+
const partes: string[] = []
|
|
276
|
+
const n = e.falhas.length
|
|
277
|
+
if (n > 0) {
|
|
278
|
+
partes.push(`Freio de Lote: a conferencia do nucleo reprovou ${n === 1 ? '1 claim ligada' : `${n} claims ligadas`} ao que voce mexeu (ork claims conferir, no sandbox do verify, sem recibo).`)
|
|
279
|
+
for (const f of e.falhas.slice(0, TETO_DE_CLAIMS_NO_TEXTO)) {
|
|
280
|
+
partes.push(`- ${f.id}${f.arquivo ? ` (${f.arquivo})` : ''}: ${f.alegacao}`)
|
|
281
|
+
partes.push(` comando: ${f.comando}`)
|
|
282
|
+
partes.push(` saiu com codigo ${f.codigo ?? 'desconhecido'}; fim da saida:`)
|
|
283
|
+
for (const linha of fimDaSaida(f.fim)) partes.push(` | ${linha}`)
|
|
284
|
+
}
|
|
285
|
+
if (n > TETO_DE_CLAIMS_NO_TEXTO) partes.push(`- e mais ${n - TETO_DE_CLAIMS_NO_TEXTO}: ${lista(e.falhas.slice(TETO_DE_CLAIMS_NO_TEXTO).map(f => f.id))}`)
|
|
286
|
+
partes.push('Rode o comando para confirmar: teste que cria processo pode reprovar no sandbox e passar no ork verify, que continua sendo quem verifica.')
|
|
287
|
+
}
|
|
288
|
+
if (e.recuperadas.length > 0) {
|
|
289
|
+
partes.push(`Freio de Lote: ${lista(e.recuperadas)} ${e.recuperadas.length === 1 ? 'voltou' : 'voltaram'} a passar na conferencia do nucleo.`)
|
|
290
|
+
}
|
|
291
|
+
if (e.semVeredito.length > 0) {
|
|
292
|
+
const motivos = [...new Set(e.semVeredito.map(s => s.motivo))]
|
|
293
|
+
partes.push(`Freio de Lote: a conferencia de ${lista(e.semVeredito.map(s => s.id))} terminou sem veredito (${motivos.join(', ')}); o ork verify decide.`)
|
|
294
|
+
}
|
|
295
|
+
if (e.indisponivel) {
|
|
296
|
+
partes.push(`Freio de Lote: a conferencia das claims esta indisponivel nesta sessao (${e.indisponivel}). O Freio segue sem conferir; o ork verify continua valendo.`)
|
|
297
|
+
}
|
|
298
|
+
return limitarTexto(partes.join('\n'))
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** A linha de status do Freio (D8); `undefined` limpa a linha. */
|
|
302
|
+
export function textoDoStatus(vigia: FreioVigia, agora: number): string | undefined {
|
|
303
|
+
const v = comConferencia(vigia)
|
|
304
|
+
if (v.indisponivel && agora < v.pausaAte) return 'freio: conferencia indisponivel'
|
|
305
|
+
if (v.rodada) return `freio: conferindo ${lista(v.rodada.ids)}`
|
|
306
|
+
const n = v.emRisco.length
|
|
307
|
+
if (n > 0) return `freio: ${n === 1 ? '1 claim' : `${n} claims`} em risco (${lista(v.emRisco.slice(0, 5))}${n > 5 ? ', ...' : ''})`
|
|
308
|
+
return undefined
|
|
309
|
+
}
|