@orkastery/cli 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +118 -4
- 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/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 +16 -8
- 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 +500 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +183 -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 +84 -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 +81 -74
- package/dist/doctor-forja.js +345 -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 +143 -43
- 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 +13 -10
- 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 +16 -0
- package/dist/hosts.js +104 -134
- package/dist/index.js +848 -548
- package/dist/indice-vetorial.js +14 -12
- package/dist/init.js +11 -2
- package/dist/integracoes-locais.js +2 -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 +220 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +76 -4
- 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 +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 +145 -6
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +169 -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 +287 -11
- 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 +73 -8
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +82 -14
- 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/modos-migracao.js +8 -6
- package/dist/modos.js +17 -18
- package/dist/network-roadmap.js +85 -49
- package/dist/noctum-aceite.js +789 -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 +482 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1169 -0
- package/dist/noctum-envelope.js +252 -16
- package/dist/noctum-execucao.js +95 -23
- package/dist/noctum-fechamento.js +405 -0
- package/dist/noctum-fila.js +43 -9
- 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 +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 +146 -124
- package/dist/phase.js +53 -27
- package/dist/policies.js +33 -0
- package/dist/postura-local.js +4 -3
- 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 +12 -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 +228 -73
- package/dist/roadmap-reservas.js +32 -32
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +117 -43
- package/dist/runtime-escada.js +423 -0
- package/dist/runtime-profiles.js +103 -46
- 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 +19 -2
- package/dist/session-watcher-claude.js +74 -19
- package/dist/session-watcher.js +156 -10
- package/dist/sessoes-contas.js +9 -0
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +59 -58
- 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 +507 -0
- package/dist/verify.js +472 -29
- 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 +9 -4
- 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,500 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PECA_SEM_RELATORIO = exports.RelatorioDoCheck = exports.TETO_DO_RELATORIO_BYTES = exports.MAXIMO_DE_PREPAROS_REFEITOS = exports.GuardaDoProduto = void 0;
|
|
37
|
+
exports.paralelismoDaVarreduraNoGrupo = paralelismoDaVarreduraNoGrupo;
|
|
38
|
+
exports.passosDoComando = passosDoComando;
|
|
39
|
+
exports.elosDoComando = elosDoComando;
|
|
40
|
+
exports.tirarPassosDoPreparo = tirarPassosDoPreparo;
|
|
41
|
+
exports.hashDoProduto = hashDoProduto;
|
|
42
|
+
exports.prepararNoAgile = prepararNoAgile;
|
|
43
|
+
exports.executorDaClaimNoAgile = executorDaClaimNoAgile;
|
|
44
|
+
exports.refazerPreparo = refazerPreparo;
|
|
45
|
+
exports.testDasLanes = testDasLanes;
|
|
46
|
+
exports.comandosNoAgile = comandosNoAgile;
|
|
47
|
+
exports.pecasDoRelatorio = pecasDoRelatorio;
|
|
48
|
+
exports.listasDasLanes = listasDasLanes;
|
|
49
|
+
/**
|
|
50
|
+
* RM-072 (D3 a D8 da ork-check5x): o motor do Agile Check no verify.
|
|
51
|
+
*
|
|
52
|
+
* O Agile roda a mesma cobertura do Classic com menos repeticao e menos serie:
|
|
53
|
+
*
|
|
54
|
+
* - o preparo do Agile (`check.agile.preparo`, como o `tsgo` deste projeto) e, se ele falhar ou nao existir, o
|
|
55
|
+
* `verify.preparo`, com a peca `preparo` em fallback;
|
|
56
|
+
* - as claims, uma por vez, contra o produto do preparo: a claim que comeca pelos passos do `verify.preparo` roda sem
|
|
57
|
+
* eles quando a guarda vale (o preparo passou, a arvore e a mesma do fim do preparo e o hash dos caminhos de
|
|
58
|
+
* `check.agile.produto` tambem); qualquer divergencia roda o comando inteiro, e o motivo vai ao ledger. Passo no meio
|
|
59
|
+
* da cadeia fica: o que vem antes dele pode mudar a entrada do build (o mutante que edita o fonte e compila). Quando
|
|
60
|
+
* so o produto mudou (a claim anterior compilou de novo no meio da cadeia), o preparo roda de novo antes da proxima
|
|
61
|
+
* claim que o reaproveitaria, ate `MAXIMO_DE_PREPAROS_REFEITOS` vezes, e uma vez antes do grupo, com a peca
|
|
62
|
+
* `preparo-refeito`;
|
|
63
|
+
* - o `build` que e so passos do preparo, com a guarda valendo, sai do preparo desta rodada sem rodar de novo;
|
|
64
|
+
* - `typecheck`, as lanes de `test` (`check.agile.test`, ou o `verify.test`) e o `security_scan` num grupo paralelo, so
|
|
65
|
+
* com a guarda valendo; sem ela, em serie, como o Classic, com a peca `grupo` em fallback. O grupo nao passa da CPU
|
|
66
|
+
* da maquina: a lane de `check.agile.apos_a_varredura` so comeca quando o `security_scan` termina (as duas sobem
|
|
67
|
+
* containers), e a varredura roda ate `paralelismoDaVarreduraNoGrupo()` ferramentas ao mesmo tempo.
|
|
68
|
+
*
|
|
69
|
+
* O resultado volta na ordem canonica dos comandos do manifesto, com as lanes dentro do `test` (que fica ok so com todas
|
|
70
|
+
* ok e e o nome que a baseline compara). Nada aqui decide veredito: a classificacao e a do verify.
|
|
71
|
+
*/
|
|
72
|
+
const node_crypto_1 = require("node:crypto");
|
|
73
|
+
const fs = __importStar(require("node:fs"));
|
|
74
|
+
const os = __importStar(require("node:os"));
|
|
75
|
+
const path = __importStar(require("node:path"));
|
|
76
|
+
const check_modo_1 = require("./check-modo");
|
|
77
|
+
const redacao_url_1 = require("./redacao-url");
|
|
78
|
+
/**
|
|
79
|
+
* Quantas ferramentas a varredura roda ao mesmo tempo dentro do grupo, ao lado das lanes: um terco das CPUs que sobram
|
|
80
|
+
* de uma, e no minimo duas. Numa maquina de 7 CPUs, duas.
|
|
81
|
+
*/
|
|
82
|
+
function paralelismoDaVarreduraNoGrupo(cpus = os.availableParallelism()) {
|
|
83
|
+
return Math.max(2, Math.floor((cpus - 1) / 3));
|
|
84
|
+
}
|
|
85
|
+
const SEPARADOR = ' && ';
|
|
86
|
+
/** Os passos de um comando encadeado por `&&` no nivel do texto (o preparo e escrito assim no manifesto). */
|
|
87
|
+
function passosDoComando(comando) {
|
|
88
|
+
// O leitor de aspas quando ele le o comando (`&&` dentro de aspas nao separa); senao, o texto cru.
|
|
89
|
+
return (elosDoComando(comando) ?? comando.split(SEPARADOR)).map((p) => p.trim()).filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Os elos de nivel de topo de um comando encadeado por `&&`, ou `null` quando o comando tem o que este leitor nao acompanha
|
|
93
|
+
* com seguranca: subshell, chave, crase, substituicao, heredoc, comentario, quebra de linha, `$'...'` ou aspas abertas.
|
|
94
|
+
* Aspas simples, aspas duplas e a barra invertida sao respeitadas: `&&` dentro delas nao separa.
|
|
95
|
+
*/
|
|
96
|
+
function elosDoComando(comando) {
|
|
97
|
+
const elos = [];
|
|
98
|
+
let atual = '';
|
|
99
|
+
let aspas = null;
|
|
100
|
+
for (let i = 0; i < comando.length; i++) {
|
|
101
|
+
const c = comando[i];
|
|
102
|
+
const proximo = comando[i + 1] ?? '';
|
|
103
|
+
if (aspas === "'") {
|
|
104
|
+
atual += c;
|
|
105
|
+
if (c === "'")
|
|
106
|
+
aspas = null;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (c === '\\') {
|
|
110
|
+
atual += c + proximo;
|
|
111
|
+
i++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (aspas === '"') {
|
|
115
|
+
if (c === '`' || (c === '$' && (proximo === '(' || proximo === '{')))
|
|
116
|
+
return null;
|
|
117
|
+
atual += c;
|
|
118
|
+
if (c === '"')
|
|
119
|
+
aspas = null;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (c === "'" || c === '"') {
|
|
123
|
+
aspas = c;
|
|
124
|
+
atual += c;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if ('(){}`\n\r'.includes(c) || (c === '<' && proximo === '<') || (c === '$' && proximo === "'"))
|
|
128
|
+
return null;
|
|
129
|
+
if (c === '#' && (atual === '' || /\s$/.test(atual)))
|
|
130
|
+
return null;
|
|
131
|
+
if (c === '&' && proximo === '&') {
|
|
132
|
+
elos.push(atual.trim());
|
|
133
|
+
atual = '';
|
|
134
|
+
i++;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
atual += c;
|
|
138
|
+
}
|
|
139
|
+
if (aspas)
|
|
140
|
+
return null;
|
|
141
|
+
elos.push(atual.trim());
|
|
142
|
+
return elos;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Tira da frente do comando os passos que sao passos do preparo, na forma `passo && resto`. So o texto exato conta: um
|
|
146
|
+
* passo escrito de outro jeito (outra opcao, outro espaco) fica, e o comando roda inteiro. So a frente: no meio da cadeia
|
|
147
|
+
* (`antes && passo && depois`), o `antes` pode mudar a entrada do build, e a guarda so confere a arvore antes do comando.
|
|
148
|
+
*/
|
|
149
|
+
function tirarPassosDoPreparo(comando, passosDoPreparo) {
|
|
150
|
+
let resto = comando.trim();
|
|
151
|
+
const passos = [];
|
|
152
|
+
for (;;) {
|
|
153
|
+
const passo = passosDoPreparo.find((p) => resto === p || resto.startsWith(p + SEPARADOR));
|
|
154
|
+
if (!passo)
|
|
155
|
+
break;
|
|
156
|
+
passos.push(passo);
|
|
157
|
+
resto = resto === passo ? '' : resto.slice(passo.length + SEPARADOR.length).trim();
|
|
158
|
+
}
|
|
159
|
+
return { passos, resto };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* O sha256 do conteudo dos caminhos do produto (arquivos em ordem, com o caminho relativo). Caminho ausente entra como
|
|
163
|
+
* ausente, para o produto que some nao passar por igual; link simbolico entra pelo destino que ele aponta, sem segui-lo.
|
|
164
|
+
*/
|
|
165
|
+
function hashDoProduto(cwd, caminhos) {
|
|
166
|
+
const h = (0, node_crypto_1.createHash)('sha256');
|
|
167
|
+
const visitar = (relativo) => {
|
|
168
|
+
const absoluto = path.join(cwd, relativo);
|
|
169
|
+
const st = fs.lstatSync(absoluto, { throwIfNoEntry: false });
|
|
170
|
+
if (!st) {
|
|
171
|
+
h.update(`<ausente>${relativo}\0`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (st.isSymbolicLink()) {
|
|
175
|
+
h.update(`<link>${relativo}\0${fs.readlinkSync(absoluto)}\0`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (st.isDirectory()) {
|
|
179
|
+
for (const nome of fs.readdirSync(absoluto).sort())
|
|
180
|
+
visitar(path.join(relativo, nome));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (!st.isFile())
|
|
184
|
+
return;
|
|
185
|
+
h.update(`${relativo}\0${st.mode & 0o111 ? 'x' : '-'}\0`);
|
|
186
|
+
h.update(fs.readFileSync(absoluto));
|
|
187
|
+
};
|
|
188
|
+
for (const c of [...caminhos].sort())
|
|
189
|
+
visitar(c);
|
|
190
|
+
return h.digest('hex');
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* A guarda do produto (D5): o que o fim do preparo deixou, e a conferencia antes de cada uso. `identidade` e a da arvore
|
|
194
|
+
* (a de sempre do verify); `produto` e o hash dos caminhos declarados.
|
|
195
|
+
*/
|
|
196
|
+
class GuardaDoProduto {
|
|
197
|
+
cwd;
|
|
198
|
+
caminhos;
|
|
199
|
+
identidadeAgora;
|
|
200
|
+
motivoBase;
|
|
201
|
+
identidade;
|
|
202
|
+
produto;
|
|
203
|
+
constructor(cwd, caminhos, identidadeAgora, motivoBase) {
|
|
204
|
+
this.cwd = cwd;
|
|
205
|
+
this.caminhos = caminhos;
|
|
206
|
+
this.identidadeAgora = identidadeAgora;
|
|
207
|
+
this.motivoBase = motivoBase;
|
|
208
|
+
this.identidade = motivoBase ? null : identidadeAgora(cwd);
|
|
209
|
+
this.produto = motivoBase || !caminhos?.length ? null : hashDoProduto(cwd, caminhos);
|
|
210
|
+
}
|
|
211
|
+
/** `null` quando a guarda vale; senao, o motivo. */
|
|
212
|
+
conferir() {
|
|
213
|
+
if (this.motivoBase)
|
|
214
|
+
return this.motivoBase;
|
|
215
|
+
if (!this.caminhos?.length)
|
|
216
|
+
return 'produto-nao-declarado';
|
|
217
|
+
if (this.identidadeAgora(this.cwd) !== this.identidade)
|
|
218
|
+
return 'arvore-mudou';
|
|
219
|
+
if (hashDoProduto(this.cwd, this.caminhos) !== this.produto)
|
|
220
|
+
return 'produto-mudou';
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
/** O hash do produto no fim do preparo, curto, para o ledger. */
|
|
224
|
+
hashCurto() {
|
|
225
|
+
return this.produto ? this.produto.slice(0, 16) : null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.GuardaDoProduto = GuardaDoProduto;
|
|
229
|
+
/** O preparo do Agile, com o fallback para o `verify.preparo` (D4). */
|
|
230
|
+
function prepararNoAgile(manifesto, cwd, executor) {
|
|
231
|
+
const doAgile = manifesto.check?.agile?.preparo;
|
|
232
|
+
const doVerify = manifesto.verify.preparo;
|
|
233
|
+
if (!doAgile)
|
|
234
|
+
return { resultado: doVerify ? executor('preparo', doVerify, cwd) : null, pecas: [] };
|
|
235
|
+
const r = executor('preparo', doAgile, cwd);
|
|
236
|
+
if (r.ok)
|
|
237
|
+
return { resultado: r, pecas: [{ peca: 'preparo', estado: 'agile' }] };
|
|
238
|
+
const motivo = `${r.causa === 'timeout' ? 'estourou o prazo' : `saiu com codigo ${r.code}`}: ${(0, redacao_url_1.redigirCredenciaisUrl)(r.comando)}`;
|
|
239
|
+
if (!doVerify)
|
|
240
|
+
return { resultado: r, pecas: [{ peca: 'preparo', estado: 'fallback', motivo, fallback: 'nenhum (sem verify.preparo)' }] };
|
|
241
|
+
return { resultado: executor('preparo', doVerify, cwd), pecas: [{ peca: 'preparo', estado: 'fallback', motivo, fallback: 'verify.preparo' }] };
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* O resultado de um comando que e so passos do preparo desta rodada (D4, D5): o veredito e o do preparo. O resumo diz o
|
|
245
|
+
* preparo que rodou de fato (o do Agile, como o `tsgo`, ou o `verify.preparo` do fallback), nao so os passos tirados.
|
|
246
|
+
*/
|
|
247
|
+
function doPreparo(nome, comando, preparo, passos) {
|
|
248
|
+
return { nome, comando, ok: preparo.ok, code: preparo.code, resumo: `reaproveitado do preparo desta rodada (${(0, redacao_url_1.redigirCredenciaisUrl)(preparo.comando)})`,
|
|
249
|
+
causa: preparo.causa, prazoMs: preparo.prazoMs, duracaoMs: 0, executado: true, preparo: { reaproveitado: true, passos } };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* O executor das claims no Agile (D5): tira os passos do `verify.preparo` da frente do comando quando a guarda vale. O
|
|
253
|
+
* comando gravado continua o inteiro, e o que rodou de fato fica em `comandoExecutado`. S-d do CHECK: quando so o
|
|
254
|
+
* produto mudou (a claim anterior compilou de novo no meio da cadeia), o preparo roda de novo antes desta claim e a guarda
|
|
255
|
+
* nova decide; sem isso, toda claim seguinte rodaria inteira.
|
|
256
|
+
*/
|
|
257
|
+
function executorDaClaimNoAgile(manifesto, executor, vigente, refazer) {
|
|
258
|
+
const passosDoPreparo = manifesto.verify.preparo ? passosDoComando(manifesto.verify.preparo) : [];
|
|
259
|
+
return (nome, comando, cwd) => {
|
|
260
|
+
const { passos, resto } = tirarPassosDoPreparo(comando, passosDoPreparo);
|
|
261
|
+
if (passos.length === 0)
|
|
262
|
+
return executor(nome, comando, cwd);
|
|
263
|
+
let motivo = vigente.guarda.conferir();
|
|
264
|
+
if (motivo === 'produto-mudou' && refazer?.(nome))
|
|
265
|
+
motivo = vigente.guarda.conferir();
|
|
266
|
+
if (motivo)
|
|
267
|
+
return { ...executor(nome, comando, cwd), preparo: { reaproveitado: false, motivo } };
|
|
268
|
+
if (resto === '')
|
|
269
|
+
return doPreparo(nome, comando, vigente.preparo, passos);
|
|
270
|
+
return { ...executor(nome, resto, cwd), comando, comandoExecutado: resto, preparo: { reaproveitado: true, passos } };
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Quantas vezes as claims de uma rodada refazem o preparo; depois disso, a claim roda inteira, como sem a guarda. O grupo
|
|
275
|
+
* tem uma vaga a mais, so dele (S-h do CHECK 3).
|
|
276
|
+
*/
|
|
277
|
+
exports.MAXIMO_DE_PREPAROS_REFEITOS = 3;
|
|
278
|
+
/**
|
|
279
|
+
* O preparo refeito (A1, S-a e S-d do CHECK): roda o preparo do Agile de novo, toma a guarda nova e devolve a peca com o
|
|
280
|
+
* estado real. Falhou, a guarda nova nasce `preparo-falhou` e o resto da rodada roda inteiro, em serie.
|
|
281
|
+
*/
|
|
282
|
+
function refazerPreparo(manifesto, cwd, executor, vigente, novaGuarda, quando) {
|
|
283
|
+
const deNovo = prepararNoAgile(manifesto, cwd, executor);
|
|
284
|
+
vigente.preparo = deNovo.resultado;
|
|
285
|
+
vigente.guarda = novaGuarda(deNovo.resultado);
|
|
286
|
+
const r = deNovo.resultado;
|
|
287
|
+
const oQue = `o produto mudou sem mudar a arvore; o preparo rodou de novo ${quando}`;
|
|
288
|
+
const peca = r?.ok
|
|
289
|
+
? { peca: 'preparo-refeito', estado: 'agile', motivo: `${oQue} (${Math.round((r.duracaoMs ?? 0) / 1000)} s)` }
|
|
290
|
+
: { peca: 'preparo-refeito', estado: 'fallback',
|
|
291
|
+
motivo: `${oQue} e ${!r ? 'nao havia preparo' : r.causa === 'timeout' ? 'estourou o prazo' : `saiu com codigo ${r.code}`}`
|
|
292
|
+
+ (r ? `: ${(0, redacao_url_1.redigirCredenciaisUrl)(r.comando)}` : ''),
|
|
293
|
+
fallback: 'os comandos inteiros, em serie' };
|
|
294
|
+
return [peca, ...deNovo.pecas.filter((x) => x.estado === 'fallback')];
|
|
295
|
+
}
|
|
296
|
+
const PIOR_CAUSA = ['timeout', 'sinal', 'nao-encontrado', 'exit'];
|
|
297
|
+
/**
|
|
298
|
+
* O maior codigo de saida que e da propria lane: o mesmo `MAIOR_CODIGO_DO_COMANDO` da baseline (verify.ts). De 124 em
|
|
299
|
+
* diante fala quem nao a deixou terminar (o `timeout` de dentro, o shell, o comando que nao existe, o sinal).
|
|
300
|
+
*/
|
|
301
|
+
const MAIOR_CODIGO_DA_LANE = 123;
|
|
302
|
+
/**
|
|
303
|
+
* A lane caiu de verdade: terminou sozinha com o codigo dela (de 1 a 123, com causa `exit` ou nenhuma), rodou e nao caiu
|
|
304
|
+
* so em teste de relogio sob steal. N4 do CHECK 3: e o mesmo criterio do "ja falhava" da baseline, para a juncao nao
|
|
305
|
+
* depender da ordem das lanes.
|
|
306
|
+
*/
|
|
307
|
+
function caiuDeVerdade(r) {
|
|
308
|
+
return !r.ok && r.executado !== false && (r.causa === undefined || r.causa === 'exit') && Number.isInteger(r.code)
|
|
309
|
+
&& r.code >= 1 && r.code <= MAIOR_CODIGO_DA_LANE && !(r.relogioSobSteal?.length);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* O `test` das lanes (D4): ok so com todas ok; a evidencia de quem caiu; a parede e a da lane mais longa. A falha de
|
|
313
|
+
* verdade de uma lane manda, como num comando so do Classic: o estouro ou o relogio sob steal de outra lane nao a esconde.
|
|
314
|
+
* O relogio sob steal so vale quando toda lane que caiu caiu so nele, e a pior causa so vale sem falha de verdade. N1 do
|
|
315
|
+
* CHECK 2 e N6 do CHECK 4: com uma lane caida sem veredito (fora o caso em que todas as caidas estouraram ou cairam so
|
|
316
|
+
* no relogio, que o agregado ja diz por tempo), o `test` nao tem veredito inteiro (`executado` falso): no verify ele
|
|
317
|
+
* bloqueia como sem veredito, mesmo com a baseline `ja-falhava`, e na baseline ele e `sem-veredito`, em qualquer ordem das
|
|
318
|
+
* lanes; com falha de verdade junto, a causa, os testes e o trecho continuam os dela. A lane sozinha que sai com 124 antes
|
|
319
|
+
* do prazo de fora fica sem veredito, mais estrita que o comando unico do Classic, que a compara com a baseline.
|
|
320
|
+
*/
|
|
321
|
+
function testDasLanes(lanes) {
|
|
322
|
+
const caidas = lanes.filter((l) => !l.resultado.ok);
|
|
323
|
+
const deVerdade = caidas.filter((l) => caiuDeVerdade(l.resultado));
|
|
324
|
+
const semVeredito = caidas.filter((l) => !caiuDeVerdade(l.resultado));
|
|
325
|
+
// N6 do CHECK 4: so o estouro e o relogio sob steal ja dizem "sem veredito" pelo agregado (a causa ou o relogio dele);
|
|
326
|
+
// qualquer outra lane sem veredito deixa o `test` sem veredito inteiro, em qualquer ordem das lanes.
|
|
327
|
+
const soPorTempo = deVerdade.length === 0 && semVeredito.length > 0
|
|
328
|
+
&& semVeredito.every((l) => l.resultado.causa === 'timeout' || (l.resultado.relogioSobSteal?.length ?? 0) > 0);
|
|
329
|
+
const juntar = (f) => lanes.flatMap((l) => f(l.resultado) ?? []);
|
|
330
|
+
const causas = lanes.map((l) => l.resultado.causa).filter((c) => !!c);
|
|
331
|
+
const causa = deVerdade.length ? deVerdade[0].resultado.causa ?? 'exit' : PIOR_CAUSA.find((c) => causas.includes(c));
|
|
332
|
+
const soRelogio = caidas.length > 0 && caidas.every((l) => (l.resultado.relogioSobSteal?.length ?? 0) > 0);
|
|
333
|
+
const testes = juntar((r) => r.testeQueCaiu).slice(0, 10);
|
|
334
|
+
const falhas = juntar((r) => r.falhasDeTeste);
|
|
335
|
+
const relogio = soRelogio ? juntar((r) => r.relogioSobSteal) : [];
|
|
336
|
+
const trechos = caidas.map((l) => l.resultado.trecho).filter((t) => !!t);
|
|
337
|
+
return {
|
|
338
|
+
nome: 'test',
|
|
339
|
+
comando: lanes.map((l) => `${l.lane}: ${l.resultado.comando}`).join('; '),
|
|
340
|
+
ok: caidas.length === 0,
|
|
341
|
+
code: (deVerdade[0] ?? caidas[0])?.resultado.code ?? 0,
|
|
342
|
+
resumo: (caidas.length ? caidas : lanes).map((l) => `[${l.lane}] ${l.resultado.resumo}`).join('\n').slice(-800),
|
|
343
|
+
...(causa ? { causa } : {}),
|
|
344
|
+
prazoMs: Math.max(...lanes.map((l) => l.resultado.prazoMs ?? 0)),
|
|
345
|
+
duracaoMs: Math.max(...lanes.map((l) => l.resultado.duracaoMs ?? 0)),
|
|
346
|
+
executado: semVeredito.length === 0 || soPorTempo ? lanes.every((l) => l.resultado.executado !== false) : false,
|
|
347
|
+
...(testes.length ? { testeQueCaiu: testes } : {}),
|
|
348
|
+
...(falhas.length ? { falhasDeTeste: falhas } : {}),
|
|
349
|
+
...(trechos.length ? { trecho: trechos.join('\n').slice(0, 1024) } : {}),
|
|
350
|
+
...(lanes.some((l) => l.resultado.stealPct !== undefined) ? { stealPct: lanes.find((l) => l.resultado.stealPct !== undefined).resultado.stealPct } : {}),
|
|
351
|
+
...(relogio.length ? { relogioSobSteal: relogio } : {}),
|
|
352
|
+
lanes: lanes.map((l) => ({ lane: l.lane, comando: l.resultado.comando, ok: l.resultado.ok, code: l.resultado.code,
|
|
353
|
+
...(l.resultado.causa ? { causa: l.resultado.causa } : {}), duracaoMs: l.resultado.duracaoMs ?? 0 })),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Os comandos do manifesto no Agile (D4): `build` reaproveitado do preparo com a guarda valendo; o resto num grupo
|
|
358
|
+
* paralelo, com as lanes no lugar do `verify.test`, so com a guarda valendo; sem ela, tudo em serie (o Classic).
|
|
359
|
+
*/
|
|
360
|
+
function comandosNoAgile(manifesto, cwd, lista, executor, grupo, guarda, preparo) {
|
|
361
|
+
const pecas = [];
|
|
362
|
+
const passosDoPreparo = manifesto.verify.preparo ? passosDoComando(manifesto.verify.preparo) : [];
|
|
363
|
+
const lanesDeclaradas = Object.entries(manifesto.check?.agile?.test ?? {});
|
|
364
|
+
const motivo = guarda.conferir();
|
|
365
|
+
const porNome = new Map();
|
|
366
|
+
if (motivo) {
|
|
367
|
+
// Sem a guarda, o Agile nao arrisca: tudo roda em serie, na ordem e com os comandos do Classic, e o motivo vai ao
|
|
368
|
+
// ledger quando havia o que paralelizar.
|
|
369
|
+
const resto = lista.filter((c) => c.nome !== 'build');
|
|
370
|
+
if (resto.length > 1 || lanesDeclaradas.length > 0)
|
|
371
|
+
pecas.push({ peca: 'grupo', estado: 'fallback', motivo, fallback: 'comandos em serie' });
|
|
372
|
+
if (lanesDeclaradas.length > 0)
|
|
373
|
+
pecas.push({ peca: 'lanes', estado: 'fallback', motivo, fallback: 'verify.test' });
|
|
374
|
+
return { comandos: lista.map((c) => executor(c.nome, c.comando, cwd)), pecas, paralelo: false, lanes: [] };
|
|
375
|
+
}
|
|
376
|
+
// Com a guarda: o build primeiro (do preparo, quando e so passos dele), e o resto junto.
|
|
377
|
+
const build = lista.find((c) => c.nome === 'build');
|
|
378
|
+
if (build) {
|
|
379
|
+
const { passos, resto } = tirarPassosDoPreparo(build.comando, passosDoPreparo);
|
|
380
|
+
if (passos.length > 0 && resto === '')
|
|
381
|
+
porNome.set('build', doPreparo('build', build.comando, preparo, passos));
|
|
382
|
+
else
|
|
383
|
+
porNome.set('build', executor('build', build.comando, cwd));
|
|
384
|
+
}
|
|
385
|
+
const resto = lista.filter((c) => c.nome !== 'build');
|
|
386
|
+
const itens = [];
|
|
387
|
+
// A lane que sobe containers espera a varredura, que tambem sobe: o grupo nao junta as duas cargas.
|
|
388
|
+
const depoisDaVarredura = new Set(resto.some((c) => c.nome === 'security_scan') ? manifesto.check?.agile?.apos_a_varredura ?? [] : []);
|
|
389
|
+
const encadeados = [];
|
|
390
|
+
for (const c of resto) {
|
|
391
|
+
if (c.nome === 'test' && lanesDeclaradas.length > 0) {
|
|
392
|
+
for (const [lane, comando] of lanesDeclaradas) {
|
|
393
|
+
if (depoisDaVarredura.has(lane))
|
|
394
|
+
encadeados.push({ nome: `test:${lane}`, comando, apos: ['security_scan'] });
|
|
395
|
+
else
|
|
396
|
+
itens.push({ nome: `test:${lane}`, comando });
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else
|
|
400
|
+
itens.push({ nome: c.nome, comando: c.comando });
|
|
401
|
+
}
|
|
402
|
+
itens.push(...encadeados);
|
|
403
|
+
const resultados = itens.length > 1 ? grupo(itens, cwd) : itens.map((i) => executor(i.nome, i.comando, cwd));
|
|
404
|
+
const lanes = [];
|
|
405
|
+
itens.forEach((item, i) => {
|
|
406
|
+
if (item.nome.startsWith('test:'))
|
|
407
|
+
lanes.push({ lane: item.nome.slice('test:'.length), resultado: resultados[i] });
|
|
408
|
+
else
|
|
409
|
+
porNome.set(item.nome, resultados[i]);
|
|
410
|
+
});
|
|
411
|
+
// As lanes voltam na ordem do manifesto, mesmo com a encadeada no fim do grupo.
|
|
412
|
+
const ordem = (lane) => lanesDeclaradas.findIndex(([nome]) => nome === lane);
|
|
413
|
+
lanes.sort((a, b) => ordem(a.lane) - ordem(b.lane));
|
|
414
|
+
if (lanes.length > 0) {
|
|
415
|
+
porNome.set('test', testDasLanes(lanes));
|
|
416
|
+
pecas.push({ peca: 'lanes', estado: 'agile' });
|
|
417
|
+
}
|
|
418
|
+
if (itens.length > 1)
|
|
419
|
+
pecas.push({ peca: 'grupo', estado: 'agile' });
|
|
420
|
+
return { comandos: lista.map((c) => porNome.get(c.nome)), pecas, paralelo: itens.length > 1, lanes: lanes.map((l) => l.lane) };
|
|
421
|
+
}
|
|
422
|
+
/** O teto da leitura do relatorio da rodada. */
|
|
423
|
+
exports.TETO_DO_RELATORIO_BYTES = 4 * 1024 * 1024;
|
|
424
|
+
/** O arquivo do relatorio das pecas de uma rodada (D8), e a leitura dele no fim. */
|
|
425
|
+
class RelatorioDoCheck {
|
|
426
|
+
arquivo;
|
|
427
|
+
dir;
|
|
428
|
+
constructor() {
|
|
429
|
+
this.dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ork-check-relatorio-'));
|
|
430
|
+
this.arquivo = path.join(this.dir, 'pecas.jsonl');
|
|
431
|
+
fs.writeFileSync(this.arquivo, '', { mode: 0o600 });
|
|
432
|
+
}
|
|
433
|
+
ambiente() {
|
|
434
|
+
return { [check_modo_1.ENV_RELATORIO_DO_CHECK]: this.arquivo };
|
|
435
|
+
}
|
|
436
|
+
/** As linhas que as pecas escreveram; linha que nao abre fica de fora (o relatorio e evidencia, nao veredito). */
|
|
437
|
+
ler() {
|
|
438
|
+
// Teto de tamanho: qualquer comando da rodada pode escrever no arquivo; a linha cortada no teto nao abre e fica de fora.
|
|
439
|
+
let bruto = '';
|
|
440
|
+
let tamanho = 0;
|
|
441
|
+
try {
|
|
442
|
+
const fd = fs.openSync(this.arquivo, 'r');
|
|
443
|
+
try {
|
|
444
|
+
tamanho = fs.fstatSync(fd).size;
|
|
445
|
+
const buf = Buffer.alloc(Math.min(tamanho, exports.TETO_DO_RELATORIO_BYTES));
|
|
446
|
+
fs.readSync(fd, buf, 0, buf.length, 0);
|
|
447
|
+
bruto = buf.toString('utf8');
|
|
448
|
+
}
|
|
449
|
+
finally {
|
|
450
|
+
fs.closeSync(fd);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
return [];
|
|
455
|
+
}
|
|
456
|
+
const linhas = bruto.split('\n').filter(Boolean).flatMap((l) => {
|
|
457
|
+
try {
|
|
458
|
+
const v = JSON.parse(l);
|
|
459
|
+
return v && typeof v === 'object' && !Array.isArray(v) ? [v] : [];
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
// S-g do CHECK 2: o corte no teto vai ao ledger, nao some calado.
|
|
466
|
+
if (tamanho > exports.TETO_DO_RELATORIO_BYTES) {
|
|
467
|
+
linhas.push({ tipo: 'peca', peca: 'relatorio', estado: 'fallback',
|
|
468
|
+
motivo: `o relatorio da rodada passou do teto de ${exports.TETO_DO_RELATORIO_BYTES} bytes (${tamanho} bytes)`, fallback: 'so as linhas ate o teto' });
|
|
469
|
+
}
|
|
470
|
+
return linhas;
|
|
471
|
+
}
|
|
472
|
+
fechar() {
|
|
473
|
+
fs.rmSync(this.dir, { recursive: true, force: true });
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
exports.RelatorioDoCheck = RelatorioDoCheck;
|
|
477
|
+
/**
|
|
478
|
+
* As pecas que os comandos da rodada contaram no relatorio (D8), cada uma uma vez (dois processos que relatam o mesmo).
|
|
479
|
+
* Linha que nao e peca, ou peca com estado desconhecido, fica de fora: o relatorio e evidencia, nao veredito.
|
|
480
|
+
*/
|
|
481
|
+
function pecasDoRelatorio(linhas) {
|
|
482
|
+
const vistas = new Set();
|
|
483
|
+
return linhas.filter((l) => l.tipo === 'peca' && typeof l.peca === 'string' && (l.estado === 'agile' || l.estado === 'fallback'))
|
|
484
|
+
.map((l) => ({ peca: l.peca, estado: l.estado,
|
|
485
|
+
...(typeof l.motivo === 'string' ? { motivo: l.motivo } : {}), ...(typeof l.fallback === 'string' ? { fallback: l.fallback } : {}) }))
|
|
486
|
+
.filter((p) => { const chave = JSON.stringify(p); if (vistas.has(chave))
|
|
487
|
+
return false; vistas.add(chave); return true; });
|
|
488
|
+
}
|
|
489
|
+
/** A peca de quem roda com executor injetado (MCP, testes): o ambiente da rodada nao chega aos comandos (A6 do CHECK). */
|
|
490
|
+
exports.PECA_SEM_RELATORIO = { peca: 'relatorio', estado: 'fallback',
|
|
491
|
+
motivo: 'executor injetado (MCP ou teste): o ambiente da rodada nao chega aos comandos',
|
|
492
|
+
fallback: 'sem as pecas do preparo e da varredura e sem as listas das lanes no ledger' };
|
|
493
|
+
/** A lista de arquivos de cada lane, como o relatorio contou (D8): contagem e sha256 da lista ordenada. */
|
|
494
|
+
function listasDasLanes(linhas) {
|
|
495
|
+
return linhas.filter((l) => l.tipo === 'lista' && typeof l.lane === 'string' && Array.isArray(l.arquivos))
|
|
496
|
+
.map((l) => {
|
|
497
|
+
const arquivos = l.arquivos.filter((a) => typeof a === 'string').sort();
|
|
498
|
+
return { lane: l.lane, arquivos, sha256: (0, node_crypto_1.createHash)('sha256').update(arquivos.join('\n')).digest('hex') };
|
|
499
|
+
});
|
|
500
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RM-072 (D2 do dono, 24/10/2026): os dois modos do CHECK.
|
|
4
|
+
*
|
|
5
|
+
* O Classic Check e o CHECK de sempre: os mesmos comandos, na mesma ordem, com as mesmas ferramentas. O Agile Check
|
|
6
|
+
* roda a mesma cobertura com as pecas da RM-072 (lanes em paralelo, claims contra o produto do preparo, varredura em
|
|
7
|
+
* paralelo com cache) e e o padrao quando o projeto nao declara o modo. O modo da rodada vem da opcao do `ork verify`
|
|
8
|
+
* (`--check`), depois do manifesto (`check.mode`), depois do padrao; o `verify_run` grava o modo e de onde ele veio, e
|
|
9
|
+
* os comandos da rodada recebem o modo no ambiente (`ORK_CHECK_MODO`), para o `ork security-scan` filho rodar o mesmo.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ENV_VARREDURA_PARALELA_DO_CHECK = exports.ENV_RELATORIO_DO_CHECK = exports.ENV_MODO_DO_CHECK = exports.NOME_DO_MODO = exports.MODO_PADRAO = exports.MODOS_DO_CHECK = void 0;
|
|
13
|
+
exports.lerModo = lerModo;
|
|
14
|
+
exports.resolverModo = resolverModo;
|
|
15
|
+
exports.MODOS_DO_CHECK = ['agile', 'classic'];
|
|
16
|
+
/** O padrao desde a versao que levar a RM-072 a producao. */
|
|
17
|
+
exports.MODO_PADRAO = 'agile';
|
|
18
|
+
/** Os nomes de produto, iguais nas duas linguas. */
|
|
19
|
+
exports.NOME_DO_MODO = { agile: 'Agile Check', classic: 'Classic Check' };
|
|
20
|
+
/** O modo da rodada no ambiente dos comandos dela. */
|
|
21
|
+
exports.ENV_MODO_DO_CHECK = 'ORK_CHECK_MODO';
|
|
22
|
+
/** O arquivo onde as pecas do Agile (varredura, lanes) contam o que rodaram, em linhas JSON. */
|
|
23
|
+
exports.ENV_RELATORIO_DO_CHECK = 'ORK_CHECK_RELATORIO';
|
|
24
|
+
/**
|
|
25
|
+
* RM-072: quantas ferramentas a varredura do Agile roda ao mesmo tempo quando corre no grupo do verify, ao lado das
|
|
26
|
+
* lanes de teste (sozinha, ela roda todas juntas).
|
|
27
|
+
*/
|
|
28
|
+
exports.ENV_VARREDURA_PARALELA_DO_CHECK = 'ORK_CHECK_VARREDURA_PARALELA';
|
|
29
|
+
/** O modo escrito (manifesto, opcao, ambiente), sem diferenca de caixa nem espaco; `null` quando nao e um dos dois. */
|
|
30
|
+
function lerModo(valor) {
|
|
31
|
+
if (typeof valor !== 'string')
|
|
32
|
+
return null;
|
|
33
|
+
const t = valor.trim().toLowerCase();
|
|
34
|
+
return exports.MODOS_DO_CHECK.includes(t) ? t : null;
|
|
35
|
+
}
|
|
36
|
+
/** A opcao vence o manifesto, e o manifesto vence o padrao. */
|
|
37
|
+
function resolverModo(doManifesto, daOpcao) {
|
|
38
|
+
const [modo, origem] = daOpcao ? [daOpcao, 'opcao']
|
|
39
|
+
: doManifesto ? [doManifesto, 'manifesto'] : [exports.MODO_PADRAO, 'padrao'];
|
|
40
|
+
return { modo, origem, nome: exports.NOME_DO_MODO[modo] };
|
|
41
|
+
}
|