@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.
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/adapters/README.md +22 -0
- package/adapters/claude-code/.claude-plugin/marketplace.json +15 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +31 -0
- package/adapters/claude-code/README.md +102 -0
- package/adapters/claude-code/agents/ork-check.md +32 -0
- package/adapters/claude-code/agents/ork-go.md +32 -0
- package/adapters/claude-code/agents/ork-goal.md +33 -0
- package/adapters/claude-code/agents/ork-master.md +32 -0
- package/adapters/claude-code/agents/ork-plan.md +32 -0
- package/adapters/claude-code/agents/ork-ship.md +32 -0
- package/adapters/claude-code/commands/check.md +45 -0
- package/adapters/claude-code/commands/go.md +46 -0
- package/adapters/claude-code/commands/goal.md +54 -0
- package/adapters/claude-code/commands/master.md +42 -0
- package/adapters/claude-code/commands/ork.md +37 -0
- package/adapters/claude-code/commands/plan.md +47 -0
- package/adapters/claude-code/commands/ship.md +45 -0
- package/adapters/claude-code/hooks/hooks.json +17 -0
- package/adapters/claude-code/hooks/ork-guard.js +130 -0
- package/adapters/hermes/README.md +45 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +25 -0
- package/adapters/hermes/hermes.plugin.json +21 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +116 -0
- package/adapters/openclaw/README.md +63 -0
- package/adapters/openclaw/bin/ork-abrir-thread.sh +24 -0
- package/adapters/openclaw/openclaw.plugin.json +138 -0
- package/dist/adapters/claude-bg.js +308 -0
- package/dist/auditoria.js +848 -0
- package/dist/auditrun.js +976 -0
- package/dist/board.js +314 -0
- package/dist/canarios.js +271 -0
- package/dist/catalogo.js +124 -0
- package/dist/ciclos.js +156 -0
- package/dist/claims.js +226 -0
- package/dist/divida.js +374 -0
- package/dist/doctor.js +246 -0
- package/dist/evalrunner.js +458 -0
- package/dist/fix.js +450 -0
- package/dist/gates.js +92 -0
- package/dist/handoff.js +521 -0
- package/dist/hosts.js +331 -0
- package/dist/index.js +1910 -0
- package/dist/init.js +231 -0
- package/dist/leases.js +508 -0
- package/dist/ledger.js +138 -0
- package/dist/manifest.js +255 -0
- package/dist/master.js +453 -0
- package/dist/memoria.js +773 -0
- package/dist/modos.js +220 -0
- package/dist/orkmind.js +487 -0
- package/dist/orquestracao.js +559 -0
- package/dist/phase.js +572 -0
- package/dist/policies.js +176 -0
- package/dist/prompts.js +406 -0
- package/dist/ratelimit.js +179 -0
- package/dist/recall.js +252 -0
- package/dist/retry.js +917 -0
- package/dist/sandbox.js +94 -0
- package/dist/sessoes.js +104 -0
- package/dist/ship.js +551 -0
- package/dist/slug.js +100 -0
- package/dist/superficie.js +1347 -0
- package/dist/thread.js +333 -0
- package/dist/tokens.js +228 -0
- package/dist/types.js +20 -0
- package/dist/util.js +156 -0
- package/dist/verify.js +262 -0
- package/dist/worktree.js +576 -0
- package/dist/yaml.js +112 -0
- package/eval/README.md +85 -0
- package/eval/casos/check-quality.json +103 -0
- package/eval/casos/code-reviewer.json +102 -0
- package/eval/casos/decision-triage.json +103 -0
- package/eval/casos/go-implementation.json +103 -0
- package/eval/casos/goal-definition.json +103 -0
- package/eval/casos/master-metrics.json +103 -0
- package/eval/casos/narrative-guardian.json +163 -0
- package/eval/casos/orkastery-bootstrap.json +102 -0
- package/eval/casos/plan-specification.json +102 -0
- package/eval/casos/roadmap-keeper.json +103 -0
- package/eval/casos/scope-check-capability-map.json +83 -0
- package/eval/casos/security-auditor.json +102 -0
- package/eval/casos/ship-release.json +122 -0
- package/eval/casos/test-engineer.json +122 -0
- package/eval/casos/thread-state.json +82 -0
- package/eval/casos/thread-tracing.json +83 -0
- package/eval/casos/web-performance-auditor.json +102 -0
- package/eval/fixtures/b0-slug-e-modos/caso.json +56 -0
- package/eval/fixtures/b2-master-log/caso.json +91 -0
- package/eval/fixtures/fx-concurrency/caso.json +15 -0
- package/eval/fixtures/fx-hallucination/caso.json +12 -0
- package/eval/fixtures/fx-happy/caso.json +16 -0
- package/eval/fixtures/fx-schema-drift/caso.json +15 -0
- package/eval/fixtures/fx-stale-base/caso.json +12 -0
- package/eval/fixtures/fx-wiki-destroy/caso.json +16 -0
- package/eval/fixtures/superficie-de-rede/README.md +22 -0
- package/eval/fixtures/superficie-de-rede/api-express.js +30 -0
- package/eval/fixtures/superficie-de-rede/api_fastapi.py +17 -0
- package/eval/fixtures/superficie-de-rede/api_gin.go +18 -0
- package/package.json +56 -0
- package/references/README.md +25 -0
- package/references/code-review-axes.md +82 -0
- package/references/definition-of-done.md +74 -0
- package/references/performance-checklist.md +53 -0
- package/references/security-checklist.md +101 -0
- package/references/testing-patterns.md +51 -0
- package/skills/README.md +43 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +89 -0
- package/skills/core/thread-state/SKILL.md +86 -0
- package/skills/governance/decision-triage/SKILL.md +65 -0
- package/skills/governance/narrative-guardian/SKILL.md +66 -0
- package/skills/governance/roadmap-keeper/SKILL.md +60 -0
- package/skills/governance/scope-check-capability-map/SKILL.md +61 -0
- package/skills/observability/thread-tracing/SKILL.md +63 -0
- package/skills/phases/check-quality/SKILL.md +87 -0
- package/skills/phases/go-implementation/SKILL.md +70 -0
- package/skills/phases/goal-definition/SKILL.md +69 -0
- package/skills/phases/master-metrics/SKILL.md +65 -0
- package/skills/phases/plan-specification/SKILL.md +67 -0
- package/skills/phases/ship-release/SKILL.md +68 -0
- package/skills/reviewers/code-reviewer/SKILL.md +61 -0
- package/skills/reviewers/security-auditor/SKILL.md +68 -0
- package/skills/reviewers/test-engineer/SKILL.md +66 -0
- package/skills/reviewers/web-performance-auditor/SKILL.md +63 -0
package/dist/fix.js
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GO-FIX e CHECK-REVERIFY automatizados (bloco B3).
|
|
4
|
+
*
|
|
5
|
+
* O melhor sub-loop do metodo era, ate aqui, manual: o CHECK reprovava, um humano lia o
|
|
6
|
+
* relatorio, escrevia a spec da correcao, mandava de volta ao GO e depois lembrava de
|
|
7
|
+
* reexecutar o CHECK inteiro. O B3 transforma esse ciclo em codigo, sem afrouxar nada:
|
|
8
|
+
*
|
|
9
|
+
* - A spec do GO-FIX nasce do resultado REAL do `ork verify`, nao de prosa. Cada
|
|
10
|
+
* correcao carrega o motivo tipado que a originou, o alvo exato (claim, comando ou
|
|
11
|
+
* artefato), o comando que a julga e a saida real que provou a reprovacao.
|
|
12
|
+
* - A classificacao A/B segue a regra do metodo (DoD 10, skill `check-quality`):
|
|
13
|
+
* tipo A e uma linha ou equivalente e reexecuta so o que foi afetado; tipo B devolve
|
|
14
|
+
* a tarefa ao GO, e o CHECK seguinte e reexecucao COMPLETA. Rodada com um unico tipo
|
|
15
|
+
* B RECUSA reverify parcial, porque "parcial depois de tipo B nao e CHECK".
|
|
16
|
+
* - O veredito e POR CORRECAO, alem do veredito final da rodada.
|
|
17
|
+
*
|
|
18
|
+
* Onde o humano continua entrando: no LIMITE DE ESCALACAO. Estouradas as tentativas do
|
|
19
|
+
* manifesto, a rodada sai `BLOQUEADO` e sobe para o humano, pausando QUALQUER modo,
|
|
20
|
+
* inclusive `#Auto`. Ate esse limite, `#Maestro` e `#Auto` atravessam sozinhos.
|
|
21
|
+
*
|
|
22
|
+
* Este modulo nao reimplementa verificacao: quem diz a verdade continua sendo o
|
|
23
|
+
* `ork verify` do B1, reexecutado no HEAD real.
|
|
24
|
+
*/
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.caminhoDosFixes = caminhoDosFixes;
|
|
60
|
+
exports.lerCorrecoes = lerCorrecoes;
|
|
61
|
+
exports.correcoesDaRodada = correcoesDaRodada;
|
|
62
|
+
exports.ultimaRodada = ultimaRodada;
|
|
63
|
+
exports.tipoDoMotivo = tipoDoMotivo;
|
|
64
|
+
exports.derivarCorrecoes = derivarCorrecoes;
|
|
65
|
+
exports.specDoGoFix = specDoGoFix;
|
|
66
|
+
exports.abrirRodada = abrirRodada;
|
|
67
|
+
exports.reverificar = reverificar;
|
|
68
|
+
exports.rodadasGastas = rodadasGastas;
|
|
69
|
+
exports.textoDaRodada = textoDaRodada;
|
|
70
|
+
exports.textoDoReverify = textoDoReverify;
|
|
71
|
+
const path = __importStar(require("node:path"));
|
|
72
|
+
const gates_1 = require("./gates");
|
|
73
|
+
const ledger_1 = require("./ledger");
|
|
74
|
+
const thread_1 = require("./thread");
|
|
75
|
+
const util_1 = require("./util");
|
|
76
|
+
const verify_1 = require("./verify");
|
|
77
|
+
/** Armazem append-only das correcoes da thread. */
|
|
78
|
+
function caminhoDosFixes(raiz, threadId) {
|
|
79
|
+
return path.join((0, thread_1.dirThread)(raiz, threadId), 'fixes.jsonl');
|
|
80
|
+
}
|
|
81
|
+
/** Todas as correcoes ja registradas na thread (a ultima gravacao de um id vence). */
|
|
82
|
+
function lerCorrecoes(raiz, threadId) {
|
|
83
|
+
return (0, util_1.lerJsonl)(caminhoDosFixes(raiz, threadId));
|
|
84
|
+
}
|
|
85
|
+
/** Correcoes de uma rodada especifica. */
|
|
86
|
+
function correcoesDaRodada(raiz, threadId, rodada) {
|
|
87
|
+
return lerCorrecoes(raiz, threadId).filter((c) => c.rodada === rodada);
|
|
88
|
+
}
|
|
89
|
+
/** Numero da ultima rodada de GO-FIX aberta na thread (0 quando nao houve nenhuma). */
|
|
90
|
+
function ultimaRodada(raiz, threadId) {
|
|
91
|
+
return lerCorrecoes(raiz, threadId).reduce((max, c) => Math.max(max, c.rodada), 0);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A classificacao A/B derivada do MOTIVO TIPADO, nao de julgamento de tamanho.
|
|
95
|
+
*
|
|
96
|
+
* O nucleo nao sabe medir "uma linha ou equivalente", entao ele nao finge saber: o
|
|
97
|
+
* padrao e o CONSERVADOR (tipo B, devolve ao GO e exige reexecucao completa). O unico
|
|
98
|
+
* caso que nasce tipo A e a alegacao sem comando de verificacao, em que a correcao E
|
|
99
|
+
* literalmente anexar o comando (`ork claims verificar`), sem tocar em codigo.
|
|
100
|
+
*/
|
|
101
|
+
function tipoDoMotivo(motivo) {
|
|
102
|
+
return motivo === 'claims.unverifiable' ? 'A' : 'B';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Deriva as correcoes dirigidas do resultado REAL do `ork verify`.
|
|
106
|
+
*
|
|
107
|
+
* Uma correcao por item reprovado, nunca uma correcao guarda-chuva: "o CHECK reprovou"
|
|
108
|
+
* nao e spec, e o GO-FIX precisa saber exatamente o que consertar e o que sera
|
|
109
|
+
* reexecutado para julga-lo.
|
|
110
|
+
*/
|
|
111
|
+
function derivarCorrecoes(thread, rodada, resultado, idsUsados) {
|
|
112
|
+
const correcoes = [];
|
|
113
|
+
const ids = [...idsUsados];
|
|
114
|
+
const proximo = () => {
|
|
115
|
+
const id = (0, util_1.proximoIdSequencial)(ids, 'FX');
|
|
116
|
+
ids.push(id);
|
|
117
|
+
return id;
|
|
118
|
+
};
|
|
119
|
+
const nascer = (origem, alvo, spec, verificar, evidencia) => {
|
|
120
|
+
correcoes.push({
|
|
121
|
+
id: proximo(),
|
|
122
|
+
thread: thread.id,
|
|
123
|
+
rodada,
|
|
124
|
+
tipo: tipoDoMotivo(origem),
|
|
125
|
+
origem,
|
|
126
|
+
alvo,
|
|
127
|
+
spec,
|
|
128
|
+
verificar,
|
|
129
|
+
evidencia,
|
|
130
|
+
estado: 'aberta',
|
|
131
|
+
vereditoEm: null,
|
|
132
|
+
detalheDoVeredito: '',
|
|
133
|
+
criadaEm: (0, util_1.agora)(),
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
for (const c of resultado.claims) {
|
|
137
|
+
if (c.verificado || c.motivo === null)
|
|
138
|
+
continue;
|
|
139
|
+
const falhou = c.execucoes.find((e) => !e.ok);
|
|
140
|
+
if (c.motivo === 'claims.unverifiable') {
|
|
141
|
+
nascer(c.motivo, `claim ${c.claim.id}`, `A alegacao ${c.claim.id} sobre ${c.claim.arquivo} ("${c.claim.alegacao}") nao tem comando ` +
|
|
142
|
+
'de verificacao. Anexe o comando que a comprova no HEAD real, ou retire a alegacao com ' +
|
|
143
|
+
`motivo: ork claims verificar ${thread.id} ${c.claim.id} --comando "<comando>"`, [], c.detalhe);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
nascer(c.motivo, `claim ${c.claim.id}`, `A alegacao ${c.claim.id} sobre ${c.claim.arquivo} ("${c.claim.alegacao}") REPROVOU na ` +
|
|
147
|
+
`reexecucao no HEAD real. ${c.detalhe}. Corrija o artefato ate o comando passar, ou ` +
|
|
148
|
+
'retire a alegacao com motivo. Nao edite o comando para faze-lo passar.', c.claim.verificar, falhou ? `${falhou.comando} saiu com codigo ${falhou.code}:\n${falhou.resumo}` : c.detalhe);
|
|
149
|
+
}
|
|
150
|
+
for (const cmd of resultado.regressoes) {
|
|
151
|
+
nascer('verify.regression', `comando ${cmd.nome}`, `REGRESSAO: "${cmd.comando}" passava na baseline gravada antes do GO (commit ` +
|
|
152
|
+
`${resultado.baseline?.commit.slice(0, 8) ?? 'desconhecido'}) e falha agora. Este defeito ` +
|
|
153
|
+
'e desta thread, nao divida pre-existente. Corrija ate o comando voltar a passar.', [cmd.comando], `codigo ${cmd.code}:\n${cmd.resumo}`);
|
|
154
|
+
}
|
|
155
|
+
for (const cmd of resultado.falhasSemBaseline) {
|
|
156
|
+
nascer('verify.failed', `comando ${cmd.nome}`, `"${cmd.comando}" falha e NAO ha baseline para separar regressao de divida pre-existente. ` +
|
|
157
|
+
'Corrija a falha, ou grave a baseline antes do GO com `ork verify <thread> --baseline` ' +
|
|
158
|
+
'para que a proxima rodada saiba de quem e a culpa.', [cmd.comando], `codigo ${cmd.code}:\n${cmd.resumo}`);
|
|
159
|
+
}
|
|
160
|
+
return correcoes;
|
|
161
|
+
}
|
|
162
|
+
/** A spec EXATA que vai no prompt do GO-FIX. Sai dos dados, nunca de prosa livre. */
|
|
163
|
+
function specDoGoFix(thread, rodada, correcoes) {
|
|
164
|
+
const temTipoB = correcoes.some((c) => c.tipo === 'B');
|
|
165
|
+
const linhas = [];
|
|
166
|
+
linhas.push(`GO-FIX da thread ${thread.id}, rodada ${rodada}.`);
|
|
167
|
+
linhas.push('');
|
|
168
|
+
linhas.push('O CHECK reprovou. Abaixo esta a spec EXATA de cada correcao, derivada do resultado real ' +
|
|
169
|
+
'de `ork verify` no HEAD, com o comando que vai julgar cada uma no CHECK-REVERIFY.');
|
|
170
|
+
linhas.push('');
|
|
171
|
+
for (const c of correcoes) {
|
|
172
|
+
linhas.push(`${c.id} (tipo ${c.tipo}, motivo tipado ${c.origem}) alvo: ${c.alvo}`);
|
|
173
|
+
linhas.push(` o que fazer: ${c.spec}`);
|
|
174
|
+
linhas.push(` como sera julgado: ${c.verificar.length > 0 ? c.verificar.join(' && ') : '(sem comando proprio: o verify completo julga)'}`);
|
|
175
|
+
linhas.push(' evidencia da reprovacao:');
|
|
176
|
+
for (const l of c.evidencia.split('\n').slice(-6))
|
|
177
|
+
linhas.push(` | ${l}`);
|
|
178
|
+
linhas.push('');
|
|
179
|
+
}
|
|
180
|
+
linhas.push('Regras desta rodada:');
|
|
181
|
+
linhas.push('- Corrija o ARTEFATO. Editar o comando de verificacao para faze-lo passar e fraude de gate.');
|
|
182
|
+
linhas.push('- Um commit atomico por correcao, citando o id da correcao na mensagem.');
|
|
183
|
+
linhas.push(temTipoB
|
|
184
|
+
? '- Ha correcao tipo B nesta rodada: o CHECK seguinte e reexecucao COMPLETA, nunca parcial.'
|
|
185
|
+
: '- Rodada so de tipo A: o CHECK seguinte reexecuta as verificacoes afetadas.');
|
|
186
|
+
linhas.push('- Nao ha pausa humana dentro deste sub-loop; o veredito final e que sobe.');
|
|
187
|
+
return linhas.join('\n');
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Abre a rodada de GO-FIX a partir de um CHECK reprovado.
|
|
191
|
+
*
|
|
192
|
+
* A verdade vem do `ork verify` reexecutado agora: a rodada nao acredita em relatorio de
|
|
193
|
+
* CHECK nenhum, nem no do proprio agente que acabou de rodar.
|
|
194
|
+
*/
|
|
195
|
+
function abrirRodada(carregado, threadId, opcoes = {}) {
|
|
196
|
+
const { raiz } = carregado;
|
|
197
|
+
const thread = (0, thread_1.lerThread)(raiz, threadId);
|
|
198
|
+
const resultado = (0, verify_1.verificar)(carregado, threadId, { soClaims: opcoes.soClaims });
|
|
199
|
+
const rodada = ultimaRodada(raiz, threadId) + 1;
|
|
200
|
+
if (resultado.ok && resultado.motivos.length === 0) {
|
|
201
|
+
return {
|
|
202
|
+
thread: threadId,
|
|
203
|
+
rodada: rodada - 1,
|
|
204
|
+
veredito: 'PASSOU',
|
|
205
|
+
correcoes: [],
|
|
206
|
+
temTipoB: false,
|
|
207
|
+
spec: '',
|
|
208
|
+
motivos: [],
|
|
209
|
+
abertaEm: (0, util_1.agora)(),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const idsUsados = lerCorrecoes(raiz, threadId).map((c) => c.id);
|
|
213
|
+
const correcoes = derivarCorrecoes(thread, rodada, resultado, idsUsados);
|
|
214
|
+
for (const c of correcoes)
|
|
215
|
+
(0, util_1.anexarJsonl)(caminhoDosFixes(raiz, threadId), c);
|
|
216
|
+
const temTipoB = correcoes.some((c) => c.tipo === 'B');
|
|
217
|
+
const spec = specDoGoFix(thread, rodada, correcoes);
|
|
218
|
+
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.fixAberto, {
|
|
219
|
+
fase: 'CHECK',
|
|
220
|
+
rodada,
|
|
221
|
+
veredito: 'PRECISA DE MUDANCA',
|
|
222
|
+
correcoes: correcoes.map((c) => ({ id: c.id, tipo: c.tipo, origem: c.origem, alvo: c.alvo })),
|
|
223
|
+
temTipoB,
|
|
224
|
+
motivos: resultado.motivos,
|
|
225
|
+
commit: resultado.commit,
|
|
226
|
+
evidencia: `ork verify reexecutado no HEAD ${resultado.commit} em ${resultado.cwd}`,
|
|
227
|
+
reexecucaoCompletaObrigatoria: temTipoB,
|
|
228
|
+
});
|
|
229
|
+
return {
|
|
230
|
+
thread: threadId,
|
|
231
|
+
rodada,
|
|
232
|
+
veredito: 'PRECISA DE MUDANCA',
|
|
233
|
+
correcoes,
|
|
234
|
+
temTipoB,
|
|
235
|
+
spec,
|
|
236
|
+
motivos: resultado.motivos,
|
|
237
|
+
abertaEm: (0, util_1.agora)(),
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/** Regrava uma correcao com o veredito do reverify. */
|
|
241
|
+
function carimbar(raiz, correcao, aprovada, detalhe) {
|
|
242
|
+
const atualizada = {
|
|
243
|
+
...correcao,
|
|
244
|
+
estado: aprovada ? 'aprovada' : 'reprovada',
|
|
245
|
+
vereditoEm: (0, util_1.agora)(),
|
|
246
|
+
detalheDoVeredito: detalhe,
|
|
247
|
+
};
|
|
248
|
+
(0, util_1.anexarJsonl)(caminhoDosFixes(raiz, correcao.thread), atualizada);
|
|
249
|
+
return atualizada;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* CHECK-REVERIFY: veredito POR CORRECAO mais o veredito final da rodada.
|
|
253
|
+
*
|
|
254
|
+
* A cobertura nao e escolha de gosto. Rodada com tipo B e sempre `completa`; pedir
|
|
255
|
+
* `--parcial` nela LANCA, em vez de degradar em silencio para uma verificacao mais
|
|
256
|
+
* frouxa do que o metodo manda.
|
|
257
|
+
*/
|
|
258
|
+
function reverificar(carregado, threadId, opcoes = {}) {
|
|
259
|
+
const { raiz, manifesto } = carregado;
|
|
260
|
+
const thread = (0, thread_1.lerThread)(raiz, threadId);
|
|
261
|
+
const rodada = opcoes.rodada ?? ultimaRodada(raiz, threadId);
|
|
262
|
+
if (rodada === 0) {
|
|
263
|
+
throw new Error(`a thread ${threadId} nao tem rodada de GO-FIX aberta (abra com: ork fix open ${threadId})`);
|
|
264
|
+
}
|
|
265
|
+
const correcoes = correcoesDaRodada(raiz, threadId, rodada);
|
|
266
|
+
if (correcoes.length === 0) {
|
|
267
|
+
throw new Error(`rodada ${rodada} nao existe na thread ${threadId}`);
|
|
268
|
+
}
|
|
269
|
+
const temTipoB = correcoes.some((c) => c.tipo === 'B');
|
|
270
|
+
if (opcoes.parcial && temTipoB) {
|
|
271
|
+
throw new Error(`a rodada ${rodada} tem correcao tipo B (${correcoes
|
|
272
|
+
.filter((c) => c.tipo === 'B')
|
|
273
|
+
.map((c) => c.id)
|
|
274
|
+
.join(', ')}): o CHECK seguinte e reexecucao COMPLETA. ` +
|
|
275
|
+
'Parcial depois de tipo B nao e CHECK (DoD 10).');
|
|
276
|
+
}
|
|
277
|
+
const cobertura = opcoes.parcial && !temTipoB ? 'parcial' : 'completa';
|
|
278
|
+
const cwd = (0, verify_1.cwdDaThread)(raiz, thread);
|
|
279
|
+
const vereditos = correcoes.map((c) => {
|
|
280
|
+
if (c.verificar.length === 0) {
|
|
281
|
+
// Sem comando proprio a correcao nao se julga sozinha: quem decide e o verify
|
|
282
|
+
// completo. Chamar isso de "aprovada" seria self-report com outro nome.
|
|
283
|
+
return {
|
|
284
|
+
correcao: c,
|
|
285
|
+
aprovada: false,
|
|
286
|
+
execucoes: [],
|
|
287
|
+
detalhe: 'sem comando proprio de verificacao: o veredito depende do verify completo',
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
const execucoes = c.verificar.map((cmd, i) => (0, verify_1.executar)(`${c.id}.${i + 1}`, cmd, cwd));
|
|
291
|
+
const falhou = execucoes.find((e) => !e.ok);
|
|
292
|
+
return {
|
|
293
|
+
correcao: c,
|
|
294
|
+
aprovada: !falhou,
|
|
295
|
+
execucoes,
|
|
296
|
+
detalhe: falhou
|
|
297
|
+
? `"${falhou.comando}" ainda sai com codigo ${falhou.code}`
|
|
298
|
+
: `${execucoes.length} comando(s) reexecutado(s) com sucesso no HEAD real`,
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
const verify = cobertura === 'completa' ? (0, verify_1.verificar)(carregado, threadId) : null;
|
|
302
|
+
for (const v of vereditos) {
|
|
303
|
+
// Correcao sem comando proprio herda o veredito do verify completo, e so quando ele
|
|
304
|
+
// roda: sem ele, ela continua aberta em vez de virar aprovada por conveniencia.
|
|
305
|
+
const aprovada = v.correcao.verificar.length === 0 ? (verify?.ok ?? false) : v.aprovada;
|
|
306
|
+
v.aprovada = aprovada;
|
|
307
|
+
carimbar(raiz, v.correcao, aprovada, v.detalhe);
|
|
308
|
+
}
|
|
309
|
+
const rodadas = rodada;
|
|
310
|
+
const limite = manifesto.retry.max_tentativas;
|
|
311
|
+
const todasAprovadas = vereditos.every((v) => v.aprovada);
|
|
312
|
+
const verifyOk = verify === null ? true : verify.ok;
|
|
313
|
+
const motivos = verify ? verify.motivos : [];
|
|
314
|
+
let veredito;
|
|
315
|
+
let escalado = false;
|
|
316
|
+
let razao;
|
|
317
|
+
if (todasAprovadas && verifyOk) {
|
|
318
|
+
veredito = 'PASSOU';
|
|
319
|
+
razao =
|
|
320
|
+
`${vereditos.length} correcao(oes) aprovada(s) por comando reexecutado no HEAD real` +
|
|
321
|
+
(verify ? `, com o verify completo verde no commit ${verify.commit.slice(0, 8)}` : '');
|
|
322
|
+
}
|
|
323
|
+
else if (rodadas >= limite) {
|
|
324
|
+
veredito = 'BLOQUEADO';
|
|
325
|
+
escalado = true;
|
|
326
|
+
razao =
|
|
327
|
+
`limite de escalacao atingido: ${rodadas} rodada(s) de GO-FIX para o limite de ${limite} ` +
|
|
328
|
+
'do manifesto. Escalacao tipada pausa QUALQUER modo, inclusive #Auto.';
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
veredito = 'PRECISA DE MUDANCA';
|
|
332
|
+
razao =
|
|
333
|
+
`${vereditos.filter((v) => !v.aprovada).length} correcao(oes) ainda reprovada(s); ` +
|
|
334
|
+
`rodada ${rodadas} de ${limite} antes da escalacao.`;
|
|
335
|
+
}
|
|
336
|
+
const dir = (0, thread_1.dirThread)(raiz, threadId);
|
|
337
|
+
(0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.reverifyConcluido, {
|
|
338
|
+
fase: 'CHECK',
|
|
339
|
+
rodada,
|
|
340
|
+
cobertura,
|
|
341
|
+
veredito,
|
|
342
|
+
modo: thread.modo,
|
|
343
|
+
bloco: (0, thread_1.blocoDaThread)(thread, 'CHECK').fases.join('-'),
|
|
344
|
+
vereditos: vereditos.map((v) => ({
|
|
345
|
+
correcao: v.correcao.id,
|
|
346
|
+
tipo: v.correcao.tipo,
|
|
347
|
+
origem: v.correcao.origem,
|
|
348
|
+
aprovada: v.aprovada,
|
|
349
|
+
detalhe: v.detalhe,
|
|
350
|
+
})),
|
|
351
|
+
verify: verify ? { commit: verify.commit, ok: verify.ok, motivos: verify.motivos } : null,
|
|
352
|
+
escalado,
|
|
353
|
+
razao,
|
|
354
|
+
evidencia: 'comandos reexecutados no HEAD real, um veredito por correcao',
|
|
355
|
+
});
|
|
356
|
+
if (escalado) {
|
|
357
|
+
(0, gates_1.registrarGateBloqueado)(dir, threadId, {
|
|
358
|
+
gate: 'verify',
|
|
359
|
+
motivo: 'human.pending',
|
|
360
|
+
modo: thread.modo,
|
|
361
|
+
detalhe: razao,
|
|
362
|
+
evidencia: `rodada ${rodada} de GO-FIX/CHECK-REVERIFY na thread ${threadId}`,
|
|
363
|
+
correcao: `ork gate approve ${threadId} evidencias --por <quem>`,
|
|
364
|
+
rodada,
|
|
365
|
+
limite,
|
|
366
|
+
pausaQualquerModo: true,
|
|
367
|
+
});
|
|
368
|
+
(0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.retryEscalado, {
|
|
369
|
+
fase: 'CHECK',
|
|
370
|
+
motivo: 'human.pending',
|
|
371
|
+
origem: 'check.reverify',
|
|
372
|
+
rodada,
|
|
373
|
+
limite,
|
|
374
|
+
modo: thread.modo,
|
|
375
|
+
razao,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
thread: threadId,
|
|
380
|
+
rodada,
|
|
381
|
+
cobertura,
|
|
382
|
+
vereditos,
|
|
383
|
+
verify,
|
|
384
|
+
veredito,
|
|
385
|
+
rodadas,
|
|
386
|
+
limite,
|
|
387
|
+
escalado,
|
|
388
|
+
motivos,
|
|
389
|
+
razao,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
/** Quantas rodadas de GO-FIX a thread ja gastou (para o limite de escalacao). */
|
|
393
|
+
function rodadasGastas(raiz, threadId) {
|
|
394
|
+
return (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)).filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.fixAberto)
|
|
395
|
+
.length;
|
|
396
|
+
}
|
|
397
|
+
/** Texto de `ork fix open`. */
|
|
398
|
+
function textoDaRodada(r) {
|
|
399
|
+
if (r.correcoes.length === 0) {
|
|
400
|
+
return (`Thread ${r.thread}: o CHECK PASSOU no HEAD real, nao ha correcao a abrir.\n` +
|
|
401
|
+
' (nenhum motivo tipado bloqueante em `ork verify`)');
|
|
402
|
+
}
|
|
403
|
+
const linhas = [];
|
|
404
|
+
linhas.push(`GO-FIX aberto na thread ${r.thread} (rodada ${r.rodada})`);
|
|
405
|
+
linhas.push(` veredito do CHECK ${r.veredito}`);
|
|
406
|
+
linhas.push(` motivos tipados ${r.motivos.join(', ')}`);
|
|
407
|
+
linhas.push(` reexecucao ${r.temTipoB ? 'COMPLETA obrigatoria (ha correcao tipo B)' : 'parcial permitida (rodada so de tipo A)'}`);
|
|
408
|
+
linhas.push('');
|
|
409
|
+
linhas.push((0, util_1.tabela)(['ID', 'TIPO', 'MOTIVO', 'ALVO', 'JULGADO POR'], r.correcoes.map((c) => [
|
|
410
|
+
c.id,
|
|
411
|
+
c.tipo,
|
|
412
|
+
c.origem,
|
|
413
|
+
c.alvo,
|
|
414
|
+
c.verificar.join(' && ') || '(verify completo)',
|
|
415
|
+
])));
|
|
416
|
+
linhas.push('');
|
|
417
|
+
linhas.push('Spec exata despachada ao GO-FIX:');
|
|
418
|
+
linhas.push('');
|
|
419
|
+
for (const l of r.spec.split('\n'))
|
|
420
|
+
linhas.push(` ${l}`);
|
|
421
|
+
return linhas.join('\n');
|
|
422
|
+
}
|
|
423
|
+
/** Texto de `ork fix reverify`. */
|
|
424
|
+
function textoDoReverify(r) {
|
|
425
|
+
const linhas = [];
|
|
426
|
+
linhas.push(`CHECK-REVERIFY da thread ${r.thread} (rodada ${r.rodada})`);
|
|
427
|
+
linhas.push(` cobertura ${r.cobertura}`);
|
|
428
|
+
linhas.push(` rodadas ${r.rodadas} de ${r.limite} antes da escalacao`);
|
|
429
|
+
linhas.push('');
|
|
430
|
+
linhas.push('Veredito por correcao:');
|
|
431
|
+
for (const v of r.vereditos) {
|
|
432
|
+
linhas.push(` ${v.correcao.id} tipo ${v.correcao.tipo} ${v.aprovada ? 'APROVADA' : 'REPROVADA'} ${v.correcao.alvo}`);
|
|
433
|
+
linhas.push(` motivo de origem: ${v.correcao.origem}`);
|
|
434
|
+
linhas.push(` ${v.detalhe}`);
|
|
435
|
+
for (const e of v.execucoes) {
|
|
436
|
+
linhas.push(` ${e.ok ? 'ok ' : 'FALHOU'} ${e.comando}`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (r.verify) {
|
|
440
|
+
linhas.push('');
|
|
441
|
+
linhas.push(`Verify completo no HEAD ${r.verify.commit.slice(0, 8)}: ${r.verify.ok ? 'verde' : `reprovado (${r.verify.motivos.join(', ')})`}`);
|
|
442
|
+
}
|
|
443
|
+
linhas.push('');
|
|
444
|
+
linhas.push(`Veredito final: ${r.veredito}`);
|
|
445
|
+
linhas.push(` ${r.razao}`);
|
|
446
|
+
if (r.escalado) {
|
|
447
|
+
linhas.push(' ESCALADO PARA HUMANO: esta pausa vale em qualquer modo, inclusive #Auto.');
|
|
448
|
+
}
|
|
449
|
+
return linhas.join('\n');
|
|
450
|
+
}
|
package/dist/gates.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gates tipados (bloco B1).
|
|
4
|
+
*
|
|
5
|
+
* O gate do B0 era por FASE e por MODO: decidia se o bloco pausa para o humano.
|
|
6
|
+
* O gate do B1 acrescenta o MOTIVO TIPADO da reprovacao: `claims.failed`,
|
|
7
|
+
* `policy.violation`, `verify.regression` e companhia, sempre do catalogo,
|
|
8
|
+
* nunca por contagem de bytes ou grep no artefato.
|
|
9
|
+
*
|
|
10
|
+
* Regra central que atravessa o espectro de modos: o modo afrouxa a PAUSA, nunca a
|
|
11
|
+
* VERIFICACAO. Por isso todo motivo tipado deste catalogo reprova em qualquer modo,
|
|
12
|
+
* inclusive `#Auto`; o que o modo decide e apenas se a AUTORIZACAO espera o humano.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DESCRICAO_DO_MOTIVO = void 0;
|
|
16
|
+
exports.reprovaEmTodoModo = reprovaEmTodoModo;
|
|
17
|
+
exports.bloqueia = bloqueia;
|
|
18
|
+
exports.registrarGateBloqueado = registrarGateBloqueado;
|
|
19
|
+
exports.registrarGateLiberado = registrarGateLiberado;
|
|
20
|
+
exports.descreverMotivo = descreverMotivo;
|
|
21
|
+
exports.aprovarGateHumano = aprovarGateHumano;
|
|
22
|
+
exports.aprovacoesHumanas = aprovacoesHumanas;
|
|
23
|
+
const ledger_1 = require("./ledger");
|
|
24
|
+
const modos_1 = require("./modos");
|
|
25
|
+
const thread_1 = require("./thread");
|
|
26
|
+
/** O que cada motivo tipado significa, em uma linha, para a saida do CLI. */
|
|
27
|
+
exports.DESCRICAO_DO_MOTIVO = {
|
|
28
|
+
'artifact.missing': 'artefato exigido pela fase nao existe no disco',
|
|
29
|
+
'claims.failed': 'alegacao verificavel reprovou na reexecucao no HEAD real',
|
|
30
|
+
'claims.unverifiable': 'alegacao sem comando de verificacao declarado',
|
|
31
|
+
'policy.violation': 'policy do manifesto com severidade block foi violada',
|
|
32
|
+
'verify.regression': 'comando que passava na baseline falha agora',
|
|
33
|
+
'verify.failed': 'comando de verificacao falhou (sem baseline para separar divida pre-existente)',
|
|
34
|
+
'runtime.unavailable': 'runtime adapter indisponivel para o despacho',
|
|
35
|
+
'runtime.rate-limited': 'o runtime bateu o limite de uso da assinatura e a fase morreu antes de terminar (bloco B3: entra na fila duravel e e retomada na janela seguinte)',
|
|
36
|
+
'cost.violation': 'o despacho seria redirecionado para provider pago (violacao de custo: e o unico motivo que NUNCA recebe retry automatico)',
|
|
37
|
+
'tree.blocked': 'a arvore de destino nao esta disponivel para o merge (branch em check-out com alteracao nao commitada, ou worktree que nao pode ser montada)',
|
|
38
|
+
'lease.busy': 'lease ocupado por outra thread',
|
|
39
|
+
'human.pending': 'gate humano do modo de conducao ainda nao autorizou',
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Motivos que reprovam em QUALQUER modo, inclusive `#Auto`.
|
|
43
|
+
*
|
|
44
|
+
* Sao todos os motivos de verificacao e de policy: o modo nunca afrouxa verificacao.
|
|
45
|
+
* `human.pending` e a excecao de natureza: nao e reprovacao de verdade, e espera de
|
|
46
|
+
* autorizacao, e por isso existe so nos modos que pausam.
|
|
47
|
+
*/
|
|
48
|
+
function reprovaEmTodoModo(motivo) {
|
|
49
|
+
return motivo !== 'human.pending';
|
|
50
|
+
}
|
|
51
|
+
/** Motivos que bloqueiam a entrega. `claims.unverifiable` avisa, mas nao bloqueia. */
|
|
52
|
+
function bloqueia(motivo) {
|
|
53
|
+
return motivo !== 'claims.unverifiable';
|
|
54
|
+
}
|
|
55
|
+
/** Registra a reprovacao tipada no ledger da thread. */
|
|
56
|
+
function registrarGateBloqueado(dirDaThread, threadId, dados) {
|
|
57
|
+
return (0, ledger_1.registrar)(dirDaThread, threadId, ledger_1.TIPOS_DE_EVENTO.gateBloqueado, {
|
|
58
|
+
...dados,
|
|
59
|
+
tag: modos_1.MODOS[dados.modo].tag,
|
|
60
|
+
significado: exports.DESCRICAO_DO_MOTIVO[dados.motivo],
|
|
61
|
+
reprovaEmTodoModo: reprovaEmTodoModo(dados.motivo),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Registra a liberacao do gate, com quem autorizou e com que evidencia. */
|
|
65
|
+
function registrarGateLiberado(dirDaThread, threadId, dados) {
|
|
66
|
+
return (0, ledger_1.registrar)(dirDaThread, threadId, ledger_1.TIPOS_DE_EVENTO.gateLiberado, {
|
|
67
|
+
...dados,
|
|
68
|
+
tag: modos_1.MODOS[dados.modo].tag,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** Linha de saida do CLI para um motivo tipado. */
|
|
72
|
+
function descreverMotivo(motivo, detalhe) {
|
|
73
|
+
return `motivo tipado: ${motivo} (${exports.DESCRICAO_DO_MOTIVO[motivo]})\n detalhe: ${detalhe}`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `ork gate approve`: o humano autoriza uma pausa do modo pela linha de comando.
|
|
77
|
+
*
|
|
78
|
+
* E o que torna a "autorizacao antecipada de push" do `#Ork` verificavel: ela vira um
|
|
79
|
+
* evento no ledger com quem autorizou e quando, em vez de memoria de conversa.
|
|
80
|
+
*/
|
|
81
|
+
function aprovarGateHumano(raiz, threadId, sobre, por, observacao) {
|
|
82
|
+
return (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.pausaHumana, {
|
|
83
|
+
estado: 'aprovado',
|
|
84
|
+
sobre,
|
|
85
|
+
autorizadoPor: por,
|
|
86
|
+
observacao: observacao ?? '',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Aprovacoes humanas ja registradas no ledger da thread, para os gates consultarem. */
|
|
90
|
+
function aprovacoesHumanas(raiz, threadId) {
|
|
91
|
+
return (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, threadId)).filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.pausaHumana && e.estado === 'aprovado');
|
|
92
|
+
}
|