@orkastery/cli 0.2.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.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/adapters/README.md +22 -0
  4. package/adapters/claude-code/.claude-plugin/marketplace.json +15 -0
  5. package/adapters/claude-code/.claude-plugin/plugin.json +31 -0
  6. package/adapters/claude-code/README.md +102 -0
  7. package/adapters/claude-code/agents/ork-check.md +32 -0
  8. package/adapters/claude-code/agents/ork-go.md +32 -0
  9. package/adapters/claude-code/agents/ork-goal.md +33 -0
  10. package/adapters/claude-code/agents/ork-master.md +32 -0
  11. package/adapters/claude-code/agents/ork-plan.md +32 -0
  12. package/adapters/claude-code/agents/ork-ship.md +32 -0
  13. package/adapters/claude-code/commands/check.md +45 -0
  14. package/adapters/claude-code/commands/go.md +46 -0
  15. package/adapters/claude-code/commands/goal.md +54 -0
  16. package/adapters/claude-code/commands/master.md +42 -0
  17. package/adapters/claude-code/commands/ork.md +37 -0
  18. package/adapters/claude-code/commands/plan.md +47 -0
  19. package/adapters/claude-code/commands/ship.md +45 -0
  20. package/adapters/claude-code/hooks/hooks.json +17 -0
  21. package/adapters/claude-code/hooks/ork-guard.js +130 -0
  22. package/adapters/hermes/README.md +45 -0
  23. package/adapters/hermes/bin/ork-abrir-thread.sh +25 -0
  24. package/adapters/hermes/hermes.plugin.json +21 -0
  25. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +116 -0
  26. package/adapters/openclaw/README.md +63 -0
  27. package/adapters/openclaw/bin/ork-abrir-thread.sh +24 -0
  28. package/adapters/openclaw/openclaw.plugin.json +138 -0
  29. package/dist/adapters/claude-bg.js +308 -0
  30. package/dist/auditoria.js +848 -0
  31. package/dist/auditrun.js +976 -0
  32. package/dist/board.js +314 -0
  33. package/dist/canarios.js +271 -0
  34. package/dist/catalogo.js +124 -0
  35. package/dist/ciclos.js +156 -0
  36. package/dist/claims.js +226 -0
  37. package/dist/divida.js +374 -0
  38. package/dist/doctor.js +246 -0
  39. package/dist/evalrunner.js +458 -0
  40. package/dist/fix.js +450 -0
  41. package/dist/gates.js +92 -0
  42. package/dist/handoff.js +521 -0
  43. package/dist/hosts.js +331 -0
  44. package/dist/index.js +1910 -0
  45. package/dist/init.js +231 -0
  46. package/dist/leases.js +508 -0
  47. package/dist/ledger.js +138 -0
  48. package/dist/manifest.js +255 -0
  49. package/dist/master.js +453 -0
  50. package/dist/memoria.js +773 -0
  51. package/dist/modos.js +220 -0
  52. package/dist/orkmind.js +487 -0
  53. package/dist/orquestracao.js +559 -0
  54. package/dist/phase.js +572 -0
  55. package/dist/policies.js +176 -0
  56. package/dist/prompts.js +406 -0
  57. package/dist/ratelimit.js +179 -0
  58. package/dist/recall.js +252 -0
  59. package/dist/retry.js +917 -0
  60. package/dist/sandbox.js +94 -0
  61. package/dist/sessoes.js +104 -0
  62. package/dist/ship.js +551 -0
  63. package/dist/slug.js +100 -0
  64. package/dist/superficie.js +1347 -0
  65. package/dist/thread.js +333 -0
  66. package/dist/tokens.js +228 -0
  67. package/dist/types.js +20 -0
  68. package/dist/util.js +156 -0
  69. package/dist/verify.js +262 -0
  70. package/dist/worktree.js +576 -0
  71. package/dist/yaml.js +112 -0
  72. package/eval/README.md +85 -0
  73. package/eval/casos/check-quality.json +103 -0
  74. package/eval/casos/code-reviewer.json +102 -0
  75. package/eval/casos/decision-triage.json +103 -0
  76. package/eval/casos/go-implementation.json +103 -0
  77. package/eval/casos/goal-definition.json +103 -0
  78. package/eval/casos/master-metrics.json +103 -0
  79. package/eval/casos/narrative-guardian.json +163 -0
  80. package/eval/casos/orkastery-bootstrap.json +102 -0
  81. package/eval/casos/plan-specification.json +102 -0
  82. package/eval/casos/roadmap-keeper.json +103 -0
  83. package/eval/casos/scope-check-capability-map.json +83 -0
  84. package/eval/casos/security-auditor.json +102 -0
  85. package/eval/casos/ship-release.json +122 -0
  86. package/eval/casos/test-engineer.json +122 -0
  87. package/eval/casos/thread-state.json +82 -0
  88. package/eval/casos/thread-tracing.json +83 -0
  89. package/eval/casos/web-performance-auditor.json +102 -0
  90. package/eval/fixtures/b0-slug-e-modos/caso.json +56 -0
  91. package/eval/fixtures/b2-master-log/caso.json +91 -0
  92. package/eval/fixtures/fx-concurrency/caso.json +15 -0
  93. package/eval/fixtures/fx-hallucination/caso.json +12 -0
  94. package/eval/fixtures/fx-happy/caso.json +16 -0
  95. package/eval/fixtures/fx-schema-drift/caso.json +15 -0
  96. package/eval/fixtures/fx-stale-base/caso.json +12 -0
  97. package/eval/fixtures/fx-wiki-destroy/caso.json +16 -0
  98. package/eval/fixtures/superficie-de-rede/README.md +22 -0
  99. package/eval/fixtures/superficie-de-rede/api-express.js +30 -0
  100. package/eval/fixtures/superficie-de-rede/api_fastapi.py +17 -0
  101. package/eval/fixtures/superficie-de-rede/api_gin.go +18 -0
  102. package/package.json +56 -0
  103. package/references/README.md +25 -0
  104. package/references/code-review-axes.md +82 -0
  105. package/references/definition-of-done.md +74 -0
  106. package/references/performance-checklist.md +53 -0
  107. package/references/security-checklist.md +101 -0
  108. package/references/testing-patterns.md +51 -0
  109. package/skills/README.md +43 -0
  110. package/skills/core/orkastery-bootstrap/SKILL.md +89 -0
  111. package/skills/core/thread-state/SKILL.md +86 -0
  112. package/skills/governance/decision-triage/SKILL.md +65 -0
  113. package/skills/governance/narrative-guardian/SKILL.md +66 -0
  114. package/skills/governance/roadmap-keeper/SKILL.md +60 -0
  115. package/skills/governance/scope-check-capability-map/SKILL.md +61 -0
  116. package/skills/observability/thread-tracing/SKILL.md +63 -0
  117. package/skills/phases/check-quality/SKILL.md +87 -0
  118. package/skills/phases/go-implementation/SKILL.md +70 -0
  119. package/skills/phases/goal-definition/SKILL.md +69 -0
  120. package/skills/phases/master-metrics/SKILL.md +65 -0
  121. package/skills/phases/plan-specification/SKILL.md +67 -0
  122. package/skills/phases/ship-release/SKILL.md +68 -0
  123. package/skills/reviewers/code-reviewer/SKILL.md +61 -0
  124. package/skills/reviewers/security-auditor/SKILL.md +68 -0
  125. package/skills/reviewers/test-engineer/SKILL.md +66 -0
  126. package/skills/reviewers/web-performance-auditor/SKILL.md +63 -0
package/dist/util.js ADDED
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ /** Utilitarios compartilhados: execucao de processo, arquivos e formatacao do CLI. */
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.exec = exec;
38
+ exports.noPath = noPath;
39
+ exports.subirAte = subirAte;
40
+ exports.gravar = gravar;
41
+ exports.lerJson = lerJson;
42
+ exports.gravarJson = gravarJson;
43
+ exports.lerJsonl = lerJsonl;
44
+ exports.anexarJsonl = anexarJsonl;
45
+ exports.proximoIdSequencial = proximoIdSequencial;
46
+ exports.agora = agora;
47
+ exports.simbolo = simbolo;
48
+ exports.tabela = tabela;
49
+ const node_child_process_1 = require("node:child_process");
50
+ const fs = __importStar(require("node:fs"));
51
+ const path = __importStar(require("node:path"));
52
+ /** Executa um comando capturando saida, sem shell (argumentos vao como array). */
53
+ function exec(cmd, args, cwd, timeoutMs = 120000) {
54
+ const r = (0, node_child_process_1.spawnSync)(cmd, args, {
55
+ cwd,
56
+ encoding: 'utf8',
57
+ timeout: timeoutMs,
58
+ env: process.env,
59
+ });
60
+ return {
61
+ ok: r.status === 0,
62
+ code: r.status ?? -1,
63
+ stdout: (r.stdout ?? '').toString(),
64
+ stderr: (r.stderr ?? '').toString(),
65
+ };
66
+ }
67
+ /** O binario esta no PATH? */
68
+ function noPath(bin) {
69
+ const r = exec('which', [bin]);
70
+ return r.ok ? r.stdout.trim() : null;
71
+ }
72
+ /** Sobe a arvore de diretorios procurando um arquivo. Retorna o diretorio que o contem. */
73
+ function subirAte(dirInicial, arquivo) {
74
+ let dir = path.resolve(dirInicial);
75
+ for (;;) {
76
+ if (fs.existsSync(path.join(dir, arquivo)))
77
+ return dir;
78
+ const pai = path.dirname(dir);
79
+ if (pai === dir)
80
+ return null;
81
+ dir = pai;
82
+ }
83
+ }
84
+ /** Grava um arquivo criando os diretorios que faltarem. */
85
+ function gravar(destino, conteudo) {
86
+ fs.mkdirSync(path.dirname(destino), { recursive: true });
87
+ fs.writeFileSync(destino, conteudo, 'utf8');
88
+ }
89
+ /** Le JSON tipado, com erro claro quando o arquivo esta corrompido. */
90
+ function lerJson(caminho) {
91
+ const bruto = fs.readFileSync(caminho, 'utf8');
92
+ try {
93
+ return JSON.parse(bruto);
94
+ }
95
+ catch (e) {
96
+ throw new Error(`JSON invalido em ${caminho}: ${e.message}`);
97
+ }
98
+ }
99
+ /** Grava JSON identado e com quebra de linha final. */
100
+ function gravarJson(caminho, valor) {
101
+ gravar(caminho, JSON.stringify(valor, null, 2) + '\n');
102
+ }
103
+ /**
104
+ * Le um armazem JSONL append-only em que a ULTIMA gravacao de um id vence.
105
+ *
106
+ * E o formato de `claims.jsonl` (bloco B1) e do board de divida (bloco B5): a correcao nao
107
+ * apaga a linha errada, ela grava a versao nova por cima. Linha corrompida e ignorada sem
108
+ * invalidar as demais, porque um caractere quebrado no meio do arquivo nao pode apagar o
109
+ * historico inteiro. A ordenacao e numerica por id (`C2` antes de `C10`).
110
+ */
111
+ function lerJsonl(caminho) {
112
+ if (!fs.existsSync(caminho))
113
+ return [];
114
+ const porId = new Map();
115
+ for (const linha of fs.readFileSync(caminho, 'utf8').split('\n')) {
116
+ if (linha.trim() === '')
117
+ continue;
118
+ try {
119
+ const item = JSON.parse(linha);
120
+ porId.set(item.id, item);
121
+ }
122
+ catch {
123
+ /* linha corrompida nao invalida as demais */
124
+ }
125
+ }
126
+ return [...porId.values()].sort((a, b) => a.id.localeCompare(b.id, 'en', { numeric: true }));
127
+ }
128
+ /** Anexa um registro ao armazem JSONL, criando o diretorio que faltar. */
129
+ function anexarJsonl(caminho, valor) {
130
+ fs.mkdirSync(path.dirname(caminho), { recursive: true });
131
+ fs.appendFileSync(caminho, JSON.stringify(valor) + '\n', 'utf8');
132
+ }
133
+ /** Proximo id sequencial de um armazem (`C1`, `C2`, ... / `F1`, `F2`, ...). */
134
+ function proximoIdSequencial(ids, prefixo) {
135
+ const regex = new RegExp(`^${prefixo}(\\d+)$`);
136
+ const maior = ids.reduce((max, id) => Math.max(max, Number((id.match(regex) ?? [])[1] ?? 0)), 0);
137
+ return `${prefixo}${maior + 1}`;
138
+ }
139
+ /** Carimbo de tempo ISO usado em todo o estado em disco. */
140
+ function agora() {
141
+ return new Date().toISOString();
142
+ }
143
+ const SIMBOLOS = { ok: '[ok] ', warn: '[warn]', fail: '[FAIL]' };
144
+ /** Prefixo de nivel usado por `ork doctor` e demais saidas. */
145
+ function simbolo(nivel) {
146
+ return SIMBOLOS[nivel];
147
+ }
148
+ /** Monta uma tabela de largura fixa a partir de cabecalho e linhas. */
149
+ function tabela(cabecalho, linhas) {
150
+ const larguras = cabecalho.map((c, i) => Math.max(c.length, ...linhas.map((l) => (l[i] ?? '').length)));
151
+ const formatar = (cols) => ' ' + cols.map((c, i) => (c ?? '').padEnd(larguras[i])).join(' ').trimEnd();
152
+ const saida = [formatar(cabecalho), ' ' + larguras.map((w) => '-'.repeat(w)).join(' ')];
153
+ for (const l of linhas)
154
+ saida.push(formatar(l));
155
+ return saida.join('\n');
156
+ }
package/dist/verify.js ADDED
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ /**
3
+ * `ork verify` e `ork verify --baseline` (bloco B1).
4
+ *
5
+ * Duas verdades diferentes, ambas reexecutadas no HEAD REAL, nunca lidas de relatorio:
6
+ *
7
+ * 1. CLAIMS: cada alegacao registrada tem o seu comando reexecutado agora. Passou =
8
+ * `verificado: sim`. Falhou = `claims.failed`. Alegacao negativa sem comando
9
+ * tambem reprova: e o caso EvoJ6, em que a frase absoluta falsa passou batido.
10
+ * 2. BASELINE: os comandos de `verify:` do manifesto rodam antes do GO e ficam
11
+ * gravados. No CHECK eles rodam de novo, e a diferenca separa REGRESSAO (passava e
12
+ * agora falha) de DIVIDA PRE-EXISTENTE (ja falhava). Sem baseline, a falha e
13
+ * declarada como `verify.failed`, e nao como regressao que nao da para provar.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.TIMEOUT_VERIFY_MS = void 0;
17
+ exports.executar = executar;
18
+ exports.comandosDoManifesto = comandosDoManifesto;
19
+ exports.cwdDaThread = cwdDaThread;
20
+ exports.commitReal = commitReal;
21
+ exports.gravarBaseline = gravarBaseline;
22
+ exports.verificarClaim = verificarClaim;
23
+ exports.verificar = verificar;
24
+ exports.textoDoVerify = textoDoVerify;
25
+ const claims_1 = require("./claims");
26
+ const gates_1 = require("./gates");
27
+ const ledger_1 = require("./ledger");
28
+ const thread_1 = require("./thread");
29
+ const util_1 = require("./util");
30
+ /** Teto de tempo de um comando de verificacao (build e suite completa cabem). */
31
+ exports.TIMEOUT_VERIFY_MS = 10 * 60 * 1000;
32
+ /** Ultimas linhas da saida real, o suficiente para servir de evidencia no ledger. */
33
+ function resumirSaida(stdout, stderr) {
34
+ const bruto = (stdout + (stderr ? '\n' + stderr : '')).trim();
35
+ const linhas = bruto.split('\n').filter((l) => l.trim() !== '');
36
+ return linhas.slice(-10).join('\n').slice(-800);
37
+ }
38
+ /** Executa um comando de verificacao pelo shell, no diretorio de trabalho da thread. */
39
+ function executar(nome, comando, cwd) {
40
+ const r = (0, util_1.exec)('bash', ['-c', comando], cwd, exports.TIMEOUT_VERIFY_MS);
41
+ return {
42
+ nome,
43
+ comando,
44
+ ok: r.ok,
45
+ code: r.code,
46
+ resumo: resumirSaida(r.stdout, r.stderr),
47
+ };
48
+ }
49
+ /** Comandos declarados em `verify:` no manifesto, na ordem canonica. */
50
+ function comandosDoManifesto(manifesto) {
51
+ const lista = [];
52
+ for (const nome of ['typecheck', 'build', 'test']) {
53
+ const comando = manifesto.verify[nome];
54
+ if (comando && comando.trim() !== '')
55
+ lista.push({ nome, comando });
56
+ }
57
+ return lista;
58
+ }
59
+ /** Diretorio onde a verificacao roda: a worktree da thread, ou a raiz do projeto. */
60
+ function cwdDaThread(raiz, thread) {
61
+ return thread.worktree ?? raiz;
62
+ }
63
+ /** HEAD real do diretorio de trabalho, carimbado em toda verificacao. */
64
+ function commitReal(cwd) {
65
+ const r = (0, util_1.exec)('git', ['rev-parse', 'HEAD'], cwd);
66
+ return r.ok ? r.stdout.trim() : 'desconhecido';
67
+ }
68
+ /** `ork verify --baseline`: grava o estado do mundo ANTES do GO. */
69
+ function gravarBaseline(carregado, threadId) {
70
+ const { raiz, manifesto } = carregado;
71
+ const thread = (0, thread_1.lerThread)(raiz, threadId);
72
+ const cwd = cwdDaThread(raiz, thread);
73
+ const comandos = comandosDoManifesto(manifesto).map((c) => executar(c.nome, c.comando, cwd));
74
+ const baseline = { commit: commitReal(cwd), gravadaEm: (0, util_1.agora)(), comandos };
75
+ thread.baseline = baseline;
76
+ (0, thread_1.gravarThread)(raiz, thread);
77
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.baselineGravada, {
78
+ commit: baseline.commit,
79
+ cwd,
80
+ comandos: comandos.map((c) => ({ nome: c.nome, comando: c.comando, ok: c.ok, code: c.code })),
81
+ fonte: 'execucao real no HEAD, nao relatorio de fase',
82
+ });
83
+ return baseline;
84
+ }
85
+ /**
86
+ * Reexecuta a claim no HEAD real e devolve o veredito com o motivo tipado.
87
+ *
88
+ * Exportada para o bloco B5: as claims dos ACHADOS de auditoria passam por este mesmo
89
+ * julgamento, sem uma segunda regra paralela que pudesse ser mais frouxa.
90
+ */
91
+ function verificarClaim(claim, cwd) {
92
+ if (claim.verificar.length === 0) {
93
+ const negativa = claim.negativa;
94
+ return {
95
+ claim,
96
+ verificado: false,
97
+ // Alegacao negativa sem comando e reprovacao (caso EvoJ6); positiva e aviso.
98
+ motivo: negativa ? 'claims.failed' : 'claims.unverifiable',
99
+ detalhe: negativa
100
+ ? 'alegacao negativa/absoluta sem comando de verificacao: nao ha como comprova-la'
101
+ : 'sem comando de verificacao declarado',
102
+ execucoes: [],
103
+ };
104
+ }
105
+ const execucoes = claim.verificar.map((c, i) => executar(`${claim.id}.${i + 1}`, c, cwd));
106
+ const falhou = execucoes.find((e) => !e.ok);
107
+ return {
108
+ claim,
109
+ verificado: !falhou,
110
+ motivo: falhou ? 'claims.failed' : null,
111
+ detalhe: falhou
112
+ ? `comando "${falhou.comando}" saiu com codigo ${falhou.code}`
113
+ : `${execucoes.length} comando(s) reexecutado(s) com sucesso`,
114
+ execucoes,
115
+ };
116
+ }
117
+ /**
118
+ * `ork verify`: reexecuta claims e comandos do manifesto e classifica cada falha.
119
+ * Nao decide pausa, decide VERDADE: quem pausa e o gate do modo de conducao.
120
+ */
121
+ function verificar(carregado, threadId, opcoes = {}) {
122
+ const { raiz, manifesto } = carregado;
123
+ const thread = (0, thread_1.lerThread)(raiz, threadId);
124
+ const cwd = cwdDaThread(raiz, thread);
125
+ const commit = commitReal(cwd);
126
+ const dir = (0, thread_1.dirThread)(raiz, threadId);
127
+ // Claim retirada sai do gate: o historico guarda a alegacao e o motivo da retirada.
128
+ const claims = (0, claims_1.lerClaims)(raiz, threadId)
129
+ .filter((c) => c.estado !== 'retirada')
130
+ .map((c) => verificarClaim(c, cwd));
131
+ for (const r of claims) {
132
+ const estado = r.verificado
133
+ ? 'verificado'
134
+ : r.motivo === 'claims.unverifiable'
135
+ ? 'nao-verificavel'
136
+ : 'reprovado';
137
+ if (r.claim.estado !== estado)
138
+ (0, claims_1.carimbarEstado)(raiz, r.claim, estado);
139
+ }
140
+ const comandos = opcoes.soClaims
141
+ ? []
142
+ : comandosDoManifesto(manifesto).map((c) => executar(c.nome, c.comando, cwd));
143
+ const baseline = thread.baseline ?? null;
144
+ const regressoes = [];
145
+ const preExistentes = [];
146
+ const falhasSemBaseline = [];
147
+ for (const atual of comandos) {
148
+ if (atual.ok)
149
+ continue;
150
+ const antes = baseline?.comandos.find((c) => c.nome === atual.nome);
151
+ if (!antes)
152
+ falhasSemBaseline.push(atual);
153
+ else if (antes.ok)
154
+ regressoes.push(atual);
155
+ else
156
+ preExistentes.push(atual);
157
+ }
158
+ const motivos = [];
159
+ if (claims.some((c) => c.motivo === 'claims.failed'))
160
+ motivos.push('claims.failed');
161
+ if (claims.some((c) => c.motivo === 'claims.unverifiable'))
162
+ motivos.push('claims.unverifiable');
163
+ if (regressoes.length > 0)
164
+ motivos.push('verify.regression');
165
+ if (falhasSemBaseline.length > 0)
166
+ motivos.push('verify.failed');
167
+ const bloqueantes = motivos.filter((m) => m !== 'claims.unverifiable');
168
+ const ok = bloqueantes.length === 0;
169
+ (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.verificacao, {
170
+ commit,
171
+ cwd,
172
+ claims: claims.map((c) => ({
173
+ id: c.claim.id,
174
+ verificado: c.verificado,
175
+ motivo: c.motivo,
176
+ detalhe: c.detalhe,
177
+ })),
178
+ comandos: comandos.map((c) => ({ nome: c.nome, ok: c.ok, code: c.code })),
179
+ baseline: baseline ? { commit: baseline.commit, gravadaEm: baseline.gravadaEm } : null,
180
+ regressoes: regressoes.map((r) => r.nome),
181
+ preExistentes: preExistentes.map((r) => r.nome),
182
+ falhasSemBaseline: falhasSemBaseline.map((r) => r.nome),
183
+ motivos,
184
+ veredito: ok ? 'verdade sustentada' : 'reprovado',
185
+ });
186
+ for (const motivo of bloqueantes) {
187
+ (0, gates_1.registrarGateBloqueado)(dir, threadId, {
188
+ gate: 'verify',
189
+ motivo,
190
+ modo: thread.modo,
191
+ detalhe: motivo === 'claims.failed'
192
+ ? claims
193
+ .filter((c) => c.motivo === 'claims.failed')
194
+ .map((c) => `${c.claim.id}: ${c.detalhe}`)
195
+ .join('; ')
196
+ : motivo === 'verify.regression'
197
+ ? `regressao em: ${regressoes.map((r) => r.nome).join(', ')}`
198
+ : `falha sem baseline em: ${falhasSemBaseline.map((r) => r.nome).join(', ')}`,
199
+ evidencia: `reexecucao no HEAD ${commit} em ${cwd}`,
200
+ correcao: motivo === 'claims.failed'
201
+ ? 'corrija o artefato ou a alegacao e rode `ork verify` de novo'
202
+ : 'corrija a regressao, ou grave a baseline antes do GO com `ork verify <thread> --baseline`',
203
+ });
204
+ }
205
+ return {
206
+ thread: threadId,
207
+ commit,
208
+ cwd,
209
+ claims,
210
+ comandos,
211
+ baseline,
212
+ regressoes,
213
+ preExistentes,
214
+ falhasSemBaseline,
215
+ motivos,
216
+ ok,
217
+ };
218
+ }
219
+ /** Texto de `ork verify`. */
220
+ function textoDoVerify(r) {
221
+ const linhas = [];
222
+ linhas.push(`ork verify da thread ${r.thread}`);
223
+ linhas.push(` HEAD real ${r.commit}`);
224
+ linhas.push(` diretorio ${r.cwd}`);
225
+ linhas.push(` baseline ${r.baseline ? `${r.baseline.commit.slice(0, 8)} de ${r.baseline.gravadaEm}` : '(nao gravada: falha nao pode ser chamada de regressao)'}`);
226
+ linhas.push('');
227
+ linhas.push('Claims reexecutadas no HEAD real:');
228
+ if (r.claims.length === 0) {
229
+ linhas.push(' (nenhuma claim registrada nesta thread)');
230
+ }
231
+ for (const c of r.claims) {
232
+ linhas.push(` ${c.claim.id} verificado: ${c.verificado ? 'sim' : 'NAO'} ${c.claim.alegacao}`);
233
+ linhas.push(` arquivo: ${c.claim.arquivo}`);
234
+ linhas.push(` ${c.claim.verificar.length > 0 ? `comando(s): ${c.claim.verificar.join(' && ')}` : 'sem comando de verificacao'}`);
235
+ if (!c.verificado)
236
+ linhas.push(` motivo tipado: ${c.motivo} (${c.detalhe})`);
237
+ }
238
+ if (r.comandos.length > 0) {
239
+ linhas.push('');
240
+ linhas.push('Comandos de verify do manifesto:');
241
+ for (const c of r.comandos) {
242
+ linhas.push(` ${c.nome.padEnd(10)} ${c.ok ? 'ok' : `FALHOU (codigo ${c.code})`} ${c.comando}`);
243
+ }
244
+ }
245
+ if (r.regressoes.length > 0 || r.preExistentes.length > 0 || r.falhasSemBaseline.length > 0) {
246
+ linhas.push('');
247
+ linhas.push(`Classificacao: ${r.regressoes.length} regressao(oes), ` +
248
+ `${r.preExistentes.length} pre-existente(s), ` +
249
+ `${r.falhasSemBaseline.length} falha(s) sem baseline`);
250
+ for (const c of r.regressoes)
251
+ linhas.push(` regressao ${c.nome}: ${c.comando}`);
252
+ for (const c of r.preExistentes)
253
+ linhas.push(` pre-existente ${c.nome}: ${c.comando}`);
254
+ for (const c of r.falhasSemBaseline)
255
+ linhas.push(` sem baseline ${c.nome}: ${c.comando}`);
256
+ }
257
+ linhas.push('');
258
+ linhas.push(r.ok
259
+ ? 'Veredito: VERDADE SUSTENTADA (nenhum motivo bloqueante).'
260
+ : `Veredito: REPROVADO. Motivos tipados: ${r.motivos.join(', ')}`);
261
+ return linhas.join('\n');
262
+ }