@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
package/dist/maestro-runtime.js
CHANGED
|
@@ -51,6 +51,7 @@ const ledger_1 = require("./ledger");
|
|
|
51
51
|
const horario_1 = require("./horario");
|
|
52
52
|
const conducao_1 = require("./conducao");
|
|
53
53
|
const conducao_texto_1 = require("./conducao-texto");
|
|
54
|
+
const indice_1 = require("./indice");
|
|
54
55
|
/** Valida todos os campos consumidos antes de deduplicar, filtrar ou publicar a fila. */
|
|
55
56
|
const retryView = zod_1.z.object({
|
|
56
57
|
id: zod_1.z.string().max(160).regex(/^R[1-9]\d*$/),
|
|
@@ -163,16 +164,34 @@ function operationalSources(reader, threads, native = [], now = new Date().toISO
|
|
|
163
164
|
sections.ship.items.push((0, maestro_sources_1.item)(`ship:${t.id}`, 'Entrega', proven ? 'delivered' : 'incomplete', refs, { pushVerified: proven, mergeSha: done?.mergeSha ?? null, receiptAt: ship.data.ts, receiptAtLocal: local(ship.data.ts) }));
|
|
164
165
|
}
|
|
165
166
|
}
|
|
167
|
+
// RM-059 (T8.2a, D2 da thread ork-rm059ritual): o que o Ritual do MASTER le para saber quais entregas esperam a nota
|
|
168
|
+
// do dono e mostrar a prova: o regime e as classes do MASTER log, o indice derivado dos eventos ja lidos (sem git),
|
|
169
|
+
// as reprovacoes tipadas e a entrega. Os eventos de ensaio ja ficaram de fora acima; recibo de ship invalido (GO-FIX7)
|
|
170
|
+
// tambem nao entra, nem na entrega nem no indice.
|
|
171
|
+
const validos = events.filter(e => !['ship_done', 'ship_started', 'ship_blocked'].includes(e.tipo) || shipView.safeParse(e).success);
|
|
172
|
+
const entrega = validos.filter(e => e.tipo === 'ship_done').at(-1);
|
|
173
|
+
// A entrega por artefato (`artifact_delivered`, a thread so de planejamento) tambem espera a nota: sem `ship_done`,
|
|
174
|
+
// vale o ultimo artefato, sem merge. O retrato nao confere o arquivo; o nucleo confere ao gravar a nota.
|
|
175
|
+
const artefato = entrega ? undefined : events.filter(e => e.tipo === 'artifact_delivered' && typeof e.arquivo === 'string').at(-1);
|
|
176
|
+
const quando = (entrega ?? artefato)?.ts;
|
|
177
|
+
const deliveredAt = typeof quando === 'string' && Number.isFinite(Date.parse(quando)) ? quando : null;
|
|
178
|
+
const indice = (0, indice_1.calcularIndice)(validos);
|
|
179
|
+
const daEntrega = { index: indice.valor, indexDetail: (0, maestro_sources_1.safeText)(indice.parcelas.map(x => `${x.evento} x${x.ocorrencias}`).join(', ')),
|
|
180
|
+
reprovals: events.filter(e => e.tipo === 'gate_blocked').length, deliveredAt, deliveredAtLocal: deliveredAt ? local(deliveredAt) : null,
|
|
181
|
+
deliveredSha: typeof entrega?.mergeSha === 'string' && /^[a-f0-9]{40}$/.test(entrega.mergeSha) ? entrega.mergeSha : null,
|
|
182
|
+
...(artefato ? { deliveredArtifact: (0, maestro_sources_1.safeText)(String(artefato.arquivo)) } : {}) };
|
|
166
183
|
try {
|
|
167
184
|
const receipt = reader.json(`.orkastery/threads/${t.id}/master-log.json`);
|
|
168
185
|
if (receipt) {
|
|
169
186
|
const pending = receipt.contrato === master_1.CONTRATO_MASTER_PENDENTE;
|
|
170
187
|
if ((pending ? (0, master_1.validarMasterPendente)(receipt) : (0, master_1.validarMasterLog)(receipt)).length || receipt.thread !== t.id)
|
|
171
188
|
throw Error('invalid');
|
|
172
|
-
|
|
189
|
+
const classes = Array.isArray(receipt.classesDeFalha) ? (0, maestro_sources_1.safeText)(receipt.classesDeFalha.filter(c => typeof c === 'string').join(', ')) : null;
|
|
190
|
+
sections.master.items.push((0, maestro_sources_1.item)(`master:${t.id}`, pending ? 'Ratificação humana pendente' : 'MASTER', pending ? 'ratificacao-pendente' : 'recorded', refs, { score: pending ? null : typeof receipt.score === 'number' ? receipt.score : null,
|
|
191
|
+
regime: !pending && typeof receipt.regime === 'string' ? (0, maestro_sources_1.safeText)(receipt.regime) : null, classes, ...daEntrega }));
|
|
173
192
|
}
|
|
174
|
-
else if (lastShip || t.faseAtual === 'MASTER')
|
|
175
|
-
sections.master.items.push((0, maestro_sources_1.item)(`master:${t.id}`, 'Score humano pendente', 'pending', refs, { score: null }));
|
|
193
|
+
else if (lastShip || artefato || t.faseAtual === 'MASTER')
|
|
194
|
+
sections.master.items.push((0, maestro_sources_1.item)(`master:${t.id}`, 'Score humano pendente', 'pending', refs, { score: null, regime: null, classes: null, ...daEntrega }));
|
|
176
195
|
}
|
|
177
196
|
catch {
|
|
178
197
|
sections.master.gaps.push(`master.invalid:${t.id}`);
|
package/dist/manifest.js
CHANGED
|
@@ -61,8 +61,11 @@ const horario_1 = require("./horario");
|
|
|
61
61
|
const experiencia_1 = require("./experiencia");
|
|
62
62
|
const runtime_ambiente_1 = require("./runtime-ambiente");
|
|
63
63
|
const orkmind_1 = require("./orkmind");
|
|
64
|
+
const dsn_da_memoria_1 = require("./dsn-da-memoria");
|
|
64
65
|
const locale_1 = require("./locale");
|
|
66
|
+
const contrato_1 = require("./forja/contrato");
|
|
65
67
|
const branch_de_estado_1 = require("./branch-de-estado");
|
|
68
|
+
const check_modo_1 = require("./check-modo");
|
|
66
69
|
exports.NOME_MANIFESTO = 'orkastery.yaml';
|
|
67
70
|
exports.NOME_MANIFESTO_LEGADO = 'devmaster.yaml';
|
|
68
71
|
exports.DIR_ESTADO = '.orkastery';
|
|
@@ -98,7 +101,7 @@ function dirEstado(raiz) {
|
|
|
98
101
|
// RM-047 (fronteira de confiança): `.orkastery` versionado como link levaria o estado para fora da raiz.
|
|
99
102
|
const dir = path.join(raiz, exports.DIR_ESTADO);
|
|
100
103
|
if (fs.lstatSync(dir, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
101
|
-
throw new
|
|
104
|
+
throw new locale_1.ErroDoCatalogo((m) => m.estado.dirEstadoLink(exports.DIR_ESTADO));
|
|
102
105
|
}
|
|
103
106
|
return dir;
|
|
104
107
|
}
|
|
@@ -140,8 +143,8 @@ function prazosDoVerify(verify, erros) {
|
|
|
140
143
|
const brutos = mapa(verify.timeout_ms_por_comando);
|
|
141
144
|
const porComando = {};
|
|
142
145
|
for (const nome of Object.keys(brutos)) {
|
|
143
|
-
if (!['build', 'test', 'typecheck'].includes(nome)) {
|
|
144
|
-
erros.push(`verify.timeout_ms_por_comando.${nome}: so build, test e
|
|
146
|
+
if (!['build', 'test', 'typecheck', 'security_scan'].includes(nome)) {
|
|
147
|
+
erros.push(`verify.timeout_ms_por_comando.${nome}: so build, test, typecheck e security_scan tem prazo proprio`);
|
|
145
148
|
continue;
|
|
146
149
|
}
|
|
147
150
|
const n = prazo(`verify.timeout_ms_por_comando.${nome}`, brutos[nome]);
|
|
@@ -153,8 +156,26 @@ function prazosDoVerify(verify, erros) {
|
|
|
153
156
|
return saida;
|
|
154
157
|
}
|
|
155
158
|
/**
|
|
156
|
-
* RM-037 (
|
|
157
|
-
*
|
|
159
|
+
* RM-037 (defeitos de 19 e 20/10/2026, defeito 2): `worktree.dependencias`, o comando que o `ork` roda dentro de toda
|
|
160
|
+
* worktree nova da thread. So vale texto: outro tipo e erro do manifesto, porque um preparo mal escrito que sumisse em
|
|
161
|
+
* silencio deixaria a worktree nova sem as dependencias, como antes. Texto vazio e o mesmo que nenhum.
|
|
162
|
+
*/
|
|
163
|
+
function dependenciasDaWorktree(v, erros) {
|
|
164
|
+
if (v === undefined || v === null)
|
|
165
|
+
return {};
|
|
166
|
+
if (typeof v !== 'string') {
|
|
167
|
+
erros.push(`worktree.dependencias precisa ser o comando, em texto (recebido ${exibir(v)})`);
|
|
168
|
+
return {};
|
|
169
|
+
}
|
|
170
|
+
const comando = v.trim();
|
|
171
|
+
return comando ? { dependencias: comando } : {};
|
|
172
|
+
}
|
|
173
|
+
/** O caminho de um projeto: dois segmentos ou mais (os subgrupos do GitLab). */
|
|
174
|
+
const CAMINHO_DE_PROJETO = /^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)+$/;
|
|
175
|
+
/**
|
|
176
|
+
* RM-037 (rm037defeito, defeito 5): `ci.external_repositories`, mapa do caminho do projeto (`dono/nome` no GitHub,
|
|
177
|
+
* `grupo/sub/projeto` no GitLab) para o check exigido no head do PR (texto vazio ou nulo: repositorio sem CI). Forma
|
|
178
|
+
* invalida e erro do manifesto, nunca adivinhada.
|
|
158
179
|
*/
|
|
159
180
|
function repositoriosExternos(v, erros) {
|
|
160
181
|
if (v === undefined || v === null)
|
|
@@ -165,8 +186,8 @@ function repositoriosExternos(v, erros) {
|
|
|
165
186
|
}
|
|
166
187
|
const r = {};
|
|
167
188
|
for (const [repo, check] of Object.entries(v)) {
|
|
168
|
-
if (
|
|
169
|
-
erros.push(`ci.external_repositories: "${repo}" nao e dono/nome do GitHub`);
|
|
189
|
+
if (!CAMINHO_DE_PROJETO.test(repo) || repo.split('/').some((p) => p === '.' || p === '..')) {
|
|
190
|
+
erros.push(`ci.external_repositories: "${repo}" nao e dono/nome do GitHub nem grupo/subgrupo/projeto do GitLab`);
|
|
170
191
|
continue;
|
|
171
192
|
}
|
|
172
193
|
if (check !== null && typeof check !== 'string') {
|
|
@@ -205,6 +226,116 @@ function lerGrafo(v, avisos) {
|
|
|
205
226
|
avisos.push(`grafo.mcp deve ser true ou false; vale false (${mostrar(mcp)} nao reconhecido)`);
|
|
206
227
|
return { mcp: false };
|
|
207
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* RM-072 (D1 da ork-check5x): o bloco `check`. `mode` aceita `agile` e `classic` (sem diferenca de caixa); outro valor e
|
|
231
|
+
* erro do manifesto com os dois valores aceitos, porque um modo mal escrito que caisse no padrao em silencio mudaria o
|
|
232
|
+
* CHECK sem ninguem saber. Ausente, `mode` vale o padrao na hora da rodada. Chave desconhecida so avisa.
|
|
233
|
+
*/
|
|
234
|
+
function lerCheck(v, erros, avisos) {
|
|
235
|
+
if (v === undefined || v === null)
|
|
236
|
+
return undefined;
|
|
237
|
+
if (typeof v !== 'object' || Array.isArray(v)) {
|
|
238
|
+
erros.push(`check precisa ser um mapa com mode: ${check_modo_1.MODOS_DO_CHECK.join(' ou ')} (recebido ${exibir(v)})`);
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
for (const chave of Object.keys(v)) {
|
|
242
|
+
if (!['mode', 'agile'].includes(chave))
|
|
243
|
+
avisos.push(`check.${chave} desconhecida; o bloco check tem mode e agile`);
|
|
244
|
+
}
|
|
245
|
+
const check = {};
|
|
246
|
+
if (v.mode !== undefined && v.mode !== null) {
|
|
247
|
+
const modo = (0, check_modo_1.lerModo)(v.mode);
|
|
248
|
+
if (modo)
|
|
249
|
+
check.mode = modo;
|
|
250
|
+
else
|
|
251
|
+
erros.push(`check.mode invalido: ${exibir(v.mode)} (aceitos: ${check_modo_1.MODOS_DO_CHECK.join(', ')})`);
|
|
252
|
+
}
|
|
253
|
+
const agile = lerAgile(v.agile, erros, avisos);
|
|
254
|
+
if (agile)
|
|
255
|
+
check.agile = agile;
|
|
256
|
+
return check;
|
|
257
|
+
}
|
|
258
|
+
/** Nome de lane: o que vira `test:<lane>` no ledger. */
|
|
259
|
+
const NOME_DE_LANE = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
260
|
+
/**
|
|
261
|
+
* RM-072 (D3): o bloco `check.agile`. Cada chave liga uma peca do Agile; tipo errado e erro do manifesto, porque uma
|
|
262
|
+
* peca mal escrita que sumisse em silencio mudaria o que o CHECK roda. `produto` so aceita caminho relativo dentro da
|
|
263
|
+
* raiz, fora do estado do `ork` e do `.git` (o hash da guarda le esses arquivos).
|
|
264
|
+
*/
|
|
265
|
+
function lerAgile(v, erros, avisos) {
|
|
266
|
+
if (v === undefined || v === null)
|
|
267
|
+
return undefined;
|
|
268
|
+
if (typeof v !== 'object' || Array.isArray(v)) {
|
|
269
|
+
erros.push(`check.agile precisa ser um mapa (recebido ${exibir(v)})`);
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
const conhecidas = ['produto', 'preparo', 'test', 'apos_a_varredura', 'osv_scanner', 'oxlint'];
|
|
273
|
+
for (const chave of Object.keys(v)) {
|
|
274
|
+
if (!conhecidas.includes(chave))
|
|
275
|
+
avisos.push(`check.agile.${chave} desconhecida; o bloco check.agile tem ${conhecidas.join(', ')}`);
|
|
276
|
+
}
|
|
277
|
+
const agile = {};
|
|
278
|
+
if (v.produto !== undefined && v.produto !== null) {
|
|
279
|
+
const lista = Array.isArray(v.produto) ? v.produto : [v.produto];
|
|
280
|
+
const validos = [];
|
|
281
|
+
for (const item of lista) {
|
|
282
|
+
const caminho = typeof item === 'string' ? item.trim().replace(/\/+$/, '') : '';
|
|
283
|
+
const normal = caminho ? path.posix.normalize(caminho) : '';
|
|
284
|
+
if (!caminho || path.isAbsolute(caminho) || normal.startsWith('..') || /^(\.orkastery|\.git)(\/|$)/.test(normal)) {
|
|
285
|
+
erros.push(`check.agile.produto: ${exibir(item)} precisa ser um caminho relativo dentro da raiz, fora de .orkastery e .git`);
|
|
286
|
+
}
|
|
287
|
+
else
|
|
288
|
+
validos.push(normal);
|
|
289
|
+
}
|
|
290
|
+
if (validos.length)
|
|
291
|
+
agile.produto = validos;
|
|
292
|
+
}
|
|
293
|
+
if (v.preparo !== undefined && v.preparo !== null) {
|
|
294
|
+
if (typeof v.preparo === 'string' && v.preparo.trim())
|
|
295
|
+
agile.preparo = v.preparo.trim();
|
|
296
|
+
else
|
|
297
|
+
erros.push(`check.agile.preparo precisa ser o comando, em texto (recebido ${exibir(v.preparo)})`);
|
|
298
|
+
}
|
|
299
|
+
if (v.test !== undefined && v.test !== null) {
|
|
300
|
+
if (typeof v.test !== 'object' || Array.isArray(v.test)) {
|
|
301
|
+
erros.push(`check.agile.test precisa ser um mapa de lane para comando (recebido ${exibir(v.test)})`);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const lanes = {};
|
|
305
|
+
for (const [lane, comando] of Object.entries(v.test)) {
|
|
306
|
+
if (!NOME_DE_LANE.test(lane))
|
|
307
|
+
erros.push(`check.agile.test.${lane}: nome de lane aceita [a-z0-9-], ate 32 caracteres`);
|
|
308
|
+
else if (typeof comando !== 'string' || !comando.trim())
|
|
309
|
+
erros.push(`check.agile.test.${lane} precisa ser o comando, em texto`);
|
|
310
|
+
else
|
|
311
|
+
lanes[lane] = comando.trim();
|
|
312
|
+
}
|
|
313
|
+
if (Object.keys(lanes).length)
|
|
314
|
+
agile.test = lanes;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (v.apos_a_varredura !== undefined && v.apos_a_varredura !== null) {
|
|
318
|
+
const validas = [];
|
|
319
|
+
for (const item of Array.isArray(v.apos_a_varredura) ? v.apos_a_varredura : [v.apos_a_varredura]) {
|
|
320
|
+
if (typeof item === 'string' && agile.test && Object.hasOwn(agile.test, item))
|
|
321
|
+
validas.push(item);
|
|
322
|
+
else
|
|
323
|
+
erros.push(`check.agile.apos_a_varredura: ${exibir(item)} precisa ser uma lane de check.agile.test`);
|
|
324
|
+
}
|
|
325
|
+
if (validas.length)
|
|
326
|
+
agile.apos_a_varredura = validas;
|
|
327
|
+
}
|
|
328
|
+
for (const chave of ['osv_scanner', 'oxlint']) {
|
|
329
|
+
const valor = v[chave];
|
|
330
|
+
if (valor === undefined || valor === null)
|
|
331
|
+
continue;
|
|
332
|
+
if (typeof valor === 'boolean')
|
|
333
|
+
agile[chave] = valor;
|
|
334
|
+
else
|
|
335
|
+
erros.push(`check.agile.${chave} precisa ser true ou false (recebido ${exibir(valor)})`);
|
|
336
|
+
}
|
|
337
|
+
return agile;
|
|
338
|
+
}
|
|
208
339
|
/** RM-059 (T10.4): os limites dos tetos de agent teams, os mesmos que o Portao de Tarefas aceita do ambiente. */
|
|
209
340
|
exports.TETO_MAXIMO_DE_TEAMMATES = 8;
|
|
210
341
|
exports.TETO_MAXIMO_DE_CUSTO_USD = 500;
|
|
@@ -264,6 +395,123 @@ function lerBlocoConhecimento(v, avisos) {
|
|
|
264
395
|
avisos.push('conhecimento.dir deve ser uma pasta dentro da raiz, como docs/conhecimento; o leitor recusa ate corrigir');
|
|
265
396
|
return { dir };
|
|
266
397
|
}
|
|
398
|
+
/** Nome de host sem esquema, porta, caminho ou credencial; um rotulo so vale (`localhost`). */
|
|
399
|
+
const HOST_DA_FORJA = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/;
|
|
400
|
+
const CHAVES_DA_FORJA = ['tipo', 'host', 'porta', 'caminho_base', 'ssh_host', 'ssh_porta', 'ca'];
|
|
401
|
+
/**
|
|
402
|
+
* O bloco opcional `forja:`. Ausente, nada muda: tudo vem do remoto e da sondagem. Valor fora da forma e erro do
|
|
403
|
+
* manifesto, nunca adivinhado: um host ou uma porta errados mandariam a consulta, e o login da CLI, a outro servidor.
|
|
404
|
+
* Chave desconhecida so avisa. `caminho_base` `/` e o mesmo que nenhum subcaminho.
|
|
405
|
+
*/
|
|
406
|
+
function lerBlocoForja(v, erros, avisos) {
|
|
407
|
+
if (v === undefined || v === null)
|
|
408
|
+
return undefined;
|
|
409
|
+
if (typeof v !== 'object' || Array.isArray(v)) {
|
|
410
|
+
erros.push(`forja deve ser um mapa com ${CHAVES_DA_FORJA.join(', ')} (recebido ${exibir(v)})`);
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
for (const chave of Object.keys(v)) {
|
|
414
|
+
if (!CHAVES_DA_FORJA.includes(chave))
|
|
415
|
+
avisos.push(`forja.${chave} desconhecida; o bloco forja tem ${CHAVES_DA_FORJA.join(', ')}`);
|
|
416
|
+
}
|
|
417
|
+
const forja = {};
|
|
418
|
+
if (v.tipo !== undefined && v.tipo !== null) {
|
|
419
|
+
if (typeof v.tipo === 'string' && contrato_1.TIPOS_DE_FORJA.includes(v.tipo))
|
|
420
|
+
forja.tipo = v.tipo;
|
|
421
|
+
else
|
|
422
|
+
erros.push(`forja.tipo aceita ${contrato_1.TIPOS_DE_FORJA.join(' ou ')} (recebido ${exibir(v.tipo)})`);
|
|
423
|
+
}
|
|
424
|
+
for (const chave of ['host', 'ssh_host']) {
|
|
425
|
+
const x = v[chave];
|
|
426
|
+
if (x === undefined || x === null)
|
|
427
|
+
continue;
|
|
428
|
+
const t = typeof x === 'string' ? x.trim().toLowerCase() : '';
|
|
429
|
+
if (HOST_DA_FORJA.test(t))
|
|
430
|
+
forja[chave] = t;
|
|
431
|
+
else
|
|
432
|
+
erros.push(`forja.${chave} deve ser um nome de host sem esquema, porta ou caminho (recebido ${exibir(x)})`);
|
|
433
|
+
}
|
|
434
|
+
for (const chave of ['porta', 'ssh_porta']) {
|
|
435
|
+
const x = v[chave];
|
|
436
|
+
if (x === undefined || x === null)
|
|
437
|
+
continue;
|
|
438
|
+
if (typeof x === 'number' && Number.isInteger(x) && x >= 1 && x <= 65535)
|
|
439
|
+
forja[chave] = x;
|
|
440
|
+
else
|
|
441
|
+
erros.push(`forja.${chave} deve ser um inteiro de 1 a 65535 (recebido ${exibir(x)})`);
|
|
442
|
+
}
|
|
443
|
+
if (v.caminho_base !== undefined && v.caminho_base !== null) {
|
|
444
|
+
const t = typeof v.caminho_base === 'string' ? v.caminho_base.trim().replace(/\/+$/, '') : null;
|
|
445
|
+
const valido = t !== null && (t === '' || (/^(?:\/[A-Za-z0-9._~-]+)+$/.test(t) && !t.split('/').some((p) => p === '.' || p === '..')));
|
|
446
|
+
if (!valido)
|
|
447
|
+
erros.push(`forja.caminho_base deve ser um caminho absoluto como /gitlab, sem .. (recebido ${exibir(v.caminho_base)})`);
|
|
448
|
+
else if (t)
|
|
449
|
+
forja.caminho_base = t;
|
|
450
|
+
}
|
|
451
|
+
if (forja.caminho_base && forja.tipo === 'github') {
|
|
452
|
+
erros.push('forja.caminho_base só vale para forja servida em subcaminho (gitlab); o GitHub não tem');
|
|
453
|
+
}
|
|
454
|
+
if (v.ca !== undefined && v.ca !== null) {
|
|
455
|
+
if (typeof v.ca === 'string' && path.isAbsolute(v.ca) && path.normalize(v.ca) === v.ca)
|
|
456
|
+
forja.ca = v.ca;
|
|
457
|
+
else
|
|
458
|
+
erros.push(`forja.ca deve ser o caminho absoluto de um arquivo PEM (recebido ${exibir(v.ca)})`);
|
|
459
|
+
}
|
|
460
|
+
return forja;
|
|
461
|
+
}
|
|
462
|
+
/** Um produtor: o slug de um app ou de um job, ou `status:<login>`. */
|
|
463
|
+
const PRODUTOR = /^(?:status:)?[A-Za-z0-9][A-Za-z0-9_.-]{0,99}$/;
|
|
464
|
+
/**
|
|
465
|
+
* `ci.produtor`: quem pode publicar o check exigido. Ausente: o padrao da forja. Lista vazia e erro (o gate nunca
|
|
466
|
+
* ficaria verde), e entrada que nao e produtor tambem: nunca se adivinha quem aprova.
|
|
467
|
+
*/
|
|
468
|
+
function lerProdutores(v, erros) {
|
|
469
|
+
if (v === undefined || v === null)
|
|
470
|
+
return undefined;
|
|
471
|
+
const lista = typeof v === 'string' ? [v] : Array.isArray(v) ? v : null;
|
|
472
|
+
if (!lista || lista.length === 0 || lista.length > 20) {
|
|
473
|
+
erros.push('ci.produtor deve ser uma lista de 1 a 20 produtores (app, job ou status:<login>), como [github-actions]');
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
const saida = [];
|
|
477
|
+
for (const x of lista) {
|
|
478
|
+
const t = typeof x === 'string' ? x.trim() : '';
|
|
479
|
+
if (!PRODUTOR.test(t)) {
|
|
480
|
+
erros.push(`ci.produtor: ${exibir(x)} não é um produtor (app, job ou status:<login>)`);
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (!saida.includes(t))
|
|
484
|
+
saida.push(t);
|
|
485
|
+
}
|
|
486
|
+
return saida.length ? saida : undefined;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* RM-058, integração (T6, D10 da ork-rm058integra): `ci.contexts`, os checks que a proteção da base exige, um por nome, na
|
|
490
|
+
* ordem. Lista vazia, item que não é texto de uma linha e nome repetido são erro do manifesto: a prova do CI nunca fica
|
|
491
|
+
* verde por um contexto que ninguém publica, e nunca se adivinha qual faltou.
|
|
492
|
+
*/
|
|
493
|
+
function lerContextos(v, erros) {
|
|
494
|
+
if (v === undefined || v === null)
|
|
495
|
+
return undefined;
|
|
496
|
+
if (!Array.isArray(v) || v.length === 0 || v.length > 20) {
|
|
497
|
+
erros.push('ci.contexts deve ser uma lista de 1 a 20 contextos de CI (os checks que a proteção da base exige), como ["ork-verify"]');
|
|
498
|
+
return undefined;
|
|
499
|
+
}
|
|
500
|
+
const saida = [];
|
|
501
|
+
for (const x of v) {
|
|
502
|
+
const t = typeof x === 'string' ? x.trim() : '';
|
|
503
|
+
if (!t || t.length > 200 || /[\r\n]/.test(t)) {
|
|
504
|
+
erros.push(`ci.contexts: ${exibir(x)} não é o nome de um contexto de CI (texto de uma linha)`);
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
if (saida.includes(t)) {
|
|
508
|
+
erros.push(`ci.contexts: "${t}" aparece duas vezes`);
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
saida.push(t);
|
|
512
|
+
}
|
|
513
|
+
return saida.length === v.length ? saida : undefined;
|
|
514
|
+
}
|
|
267
515
|
/** Mesmo contrato na leitura do YAML e nos consumidores de manifesto em memoria. */
|
|
268
516
|
function validarOptInPlaybook(valor) {
|
|
269
517
|
if (valor === undefined)
|
|
@@ -465,6 +713,9 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
465
713
|
catch (e) {
|
|
466
714
|
erros.push(e.message);
|
|
467
715
|
}
|
|
716
|
+
const forja = lerBlocoForja(dados.forja, erros, avisos);
|
|
717
|
+
const produtores = lerProdutores(ci.produtor, erros);
|
|
718
|
+
const contextos = lerContextos(ci.contexts, erros);
|
|
468
719
|
const abbrev = texto(project.abbrev, '');
|
|
469
720
|
const checkAbbrev = (0, slug_1.validarAbbrev)(abbrev);
|
|
470
721
|
if (!checkAbbrev.ok)
|
|
@@ -544,7 +795,22 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
544
795
|
'string de conexao (base propria por tenant, sem fallback para base alheia)');
|
|
545
796
|
}
|
|
546
797
|
else if (variavelDaDsn !== '' && !/^[A-Z][A-Z0-9_]*$/.test(variavelDaDsn)) {
|
|
547
|
-
|
|
798
|
+
// RM-069 (D3): o valor nao entra no erro; uma DSN `chave=valor` colada aqui sairia inteira.
|
|
799
|
+
erros.push('memory.database_url_env invalido (valor omitido): esperado nome de variavel de ambiente, [A-Z][A-Z0-9_]*');
|
|
800
|
+
}
|
|
801
|
+
// RM-069 (G2, G3): a fonte de arquivo so nomeia arquivo da pasta de segredos do `ork`, e nunca junto da variavel.
|
|
802
|
+
const arquivoDaDsn = texto(memory.database_url_file, '').trim();
|
|
803
|
+
if (arquivoDaDsn.includes('://')) {
|
|
804
|
+
erros.push(`memory.database_url_file recebe o CAMINHO do arquivo com a DSN (${dsn_da_memoria_1.PREFIXO_DO_ARQUIVO_DA_DSN}<nome>), ` +
|
|
805
|
+
'nunca a string de conexao');
|
|
806
|
+
}
|
|
807
|
+
else if (arquivoDaDsn !== '' && !(0, dsn_da_memoria_1.arquivoDaDsnValido)(arquivoDaDsn)) {
|
|
808
|
+
erros.push(`memory.database_url_file invalido (valor omitido): esperado ${dsn_da_memoria_1.PREFIXO_DO_ARQUIVO_DA_DSN}<nome>, arquivo 0600 do ` +
|
|
809
|
+
'dono na pasta de segredos do ork (o manifesto nao escolhe outro caminho)');
|
|
810
|
+
}
|
|
811
|
+
if (variavelDaDsn !== '' && arquivoDaDsn !== '') {
|
|
812
|
+
erros.push('memory.database_url_env e memory.database_url_file sao exclusivos: declare uma fonte so ' +
|
|
813
|
+
'(o ork nunca cai de uma para a outra)');
|
|
548
814
|
}
|
|
549
815
|
// RM-047 (fronteira de confiança): `memory.cli` escolhe o executável que o `ork doctor`, a memória e o
|
|
550
816
|
// `ork brain` rodam. Caminho relativo apontaria para um arquivo do próprio clone; só nome procurado no
|
|
@@ -554,8 +820,8 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
554
820
|
erros.push(`memory.cli invalido: ${JSON.stringify(cliDaMemoria).slice(0, 60)} ` +
|
|
555
821
|
'(esperado nome de executável no PATH, como orkmind, ou caminho absoluto; caminho relativo não é aceito)');
|
|
556
822
|
}
|
|
557
|
-
if (modoDeMemoria === 'orkmind' && variavelDaDsn === '') {
|
|
558
|
-
avisos.push('memory.mode: orkmind sem memory.database_url_env: o regime efetivo cai para files ' +
|
|
823
|
+
if (modoDeMemoria === 'orkmind' && variavelDaDsn === '' && arquivoDaDsn === '') {
|
|
824
|
+
avisos.push('memory.mode: orkmind sem memory.database_url_file nem memory.database_url_env: o regime efetivo cai para files ' +
|
|
559
825
|
'(o `ork` nao adivinha DSN, e base alheia e pior do que base nenhuma)');
|
|
560
826
|
}
|
|
561
827
|
const embedding = lerEmbedding(memory.embedding, variavelDaDsn, erros);
|
|
@@ -572,6 +838,7 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
572
838
|
avisos.push(`lendo ${exports.NOME_MANIFESTO_LEGADO} como fallback; migre para ${exports.NOME_MANIFESTO}`);
|
|
573
839
|
}
|
|
574
840
|
const conhecimento = lerBlocoConhecimento(dados.conhecimento, avisos);
|
|
841
|
+
const check = lerCheck(dados.check, erros, avisos);
|
|
575
842
|
const manifesto = {
|
|
576
843
|
project: {
|
|
577
844
|
name: nomeProjeto,
|
|
@@ -604,6 +871,7 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
604
871
|
// P4 do ensaio da 0.5.0: o `ork thread new` cria a worktree sem flag quando a chave diz true. Ausente le
|
|
605
872
|
// false, para o projeto que nunca a declarou seguir como era.
|
|
606
873
|
por_thread: booleano(worktree.por_thread, false),
|
|
874
|
+
...dependenciasDaWorktree(worktree.dependencias, erros),
|
|
607
875
|
},
|
|
608
876
|
verify: {
|
|
609
877
|
build: verify.build === null || verify.build === undefined ? undefined : texto(verify.build, ''),
|
|
@@ -612,14 +880,20 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
612
880
|
typecheck: verify.typecheck === null || verify.typecheck === undefined
|
|
613
881
|
? undefined
|
|
614
882
|
: texto(verify.typecheck, ''),
|
|
883
|
+
security_scan: verify.security_scan === null || verify.security_scan === undefined
|
|
884
|
+
? undefined
|
|
885
|
+
: texto(verify.security_scan, ''),
|
|
615
886
|
// I-54 (RM-037, D10): o preparo unico da rodada de verify, quando declarado.
|
|
616
887
|
...(typeof verify.preparo === 'string' && verify.preparo.trim() ? { preparo: verify.preparo.trim() } : {}),
|
|
617
888
|
},
|
|
889
|
+
...(check ? { check } : {}),
|
|
618
890
|
ci: {
|
|
619
891
|
required_for_ship: booleano(ci.required_for_ship, false),
|
|
620
892
|
context: texto(ci.context, 'ork-verify'),
|
|
893
|
+
...(contextos ? { contexts: contextos } : {}),
|
|
621
894
|
command: ci.command === null || ci.command === undefined ? undefined : texto(ci.command, ''),
|
|
622
895
|
external_repositories: repositoriosExternos(ci.external_repositories, erros),
|
|
896
|
+
...(produtores ? { produtor: produtores } : {}),
|
|
623
897
|
},
|
|
624
898
|
concurrency: {
|
|
625
899
|
max_parallel_threads: numero(concurrency.max_parallel_threads, 3),
|
|
@@ -652,6 +926,7 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
652
926
|
memory: {
|
|
653
927
|
mode: modoDeMemoria,
|
|
654
928
|
database_url_env: variavelDaDsn,
|
|
929
|
+
...(arquivoDaDsn ? { database_url_file: arquivoDaDsn } : {}),
|
|
655
930
|
cli: texto(memory.cli, 'orkmind'),
|
|
656
931
|
tenant: texto(memory.tenant, '') || nomeProjeto,
|
|
657
932
|
timeout_ms: numero(memory.timeout_ms, 15000),
|
|
@@ -675,6 +950,7 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
|
|
|
675
950
|
// RM-031 KG5 (D2): expor as tools do grafo no MCP e opt-in do dono.
|
|
676
951
|
grafo: lerGrafo(dados.grafo, avisos),
|
|
677
952
|
...(conhecimento ? { conhecimento } : {}),
|
|
953
|
+
...(forja ? { forja } : {}),
|
|
678
954
|
policies: Object.fromEntries(Object.entries(mapa(dados.policies)).map(([k, v]) => [k, texto(v, '')])),
|
|
679
955
|
};
|
|
680
956
|
return { caminho: achado.caminho, raiz, legado: achado.legado, bytes, manifesto, erros, avisos };
|
|
@@ -705,7 +981,7 @@ function comandosDoTextoDoManifesto(bruto) {
|
|
|
705
981
|
}
|
|
706
982
|
const verify = mapa(dados.verify), ci = mapa(dados.ci);
|
|
707
983
|
const opcional = (v) => (v === null || v === undefined ? undefined : texto(v, ''));
|
|
708
|
-
return { typecheck: opcional(verify.typecheck), build: opcional(verify.build), test: opcional(verify.test), ciCommand: opcional(ci.command) };
|
|
984
|
+
return { typecheck: opcional(verify.typecheck), build: opcional(verify.build), test: opcional(verify.test), securityScan: opcional(verify.security_scan), ciCommand: opcional(ci.command) };
|
|
709
985
|
}
|
|
710
986
|
/** Carrega o manifesto ou encerra com mensagem acionavel (uso nos subcomandos). */
|
|
711
987
|
function exigirManifesto(dirInicial = diretorioDoProjeto()) {
|