@orkastery/cli 0.6.5 → 0.6.7
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/claude-code/agents/ork-check.md +4 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +1 -1
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +2 -1
- package/adapters/openclaw/openclaw.plugin.json +1 -1
- package/adapters/openclaw/package.json +1 -1
- package/assets/adapters-en/claude-code/agents/ork-check.md +4 -0
- package/assets/skills-en/phases/check-quality/SKILL.md +14 -0
- package/dist/adapters/claude-bg.js +1 -1
- package/dist/agendador-cpu.js +27 -4
- package/dist/ambiente-funcional.js +72 -0
- package/dist/cenarios-sensores.js +3 -7
- package/dist/check-agil.js +204 -60
- package/dist/check-paralelo.js +101 -36
- package/dist/claim-lint.js +19 -0
- package/dist/claims.js +77 -11
- package/dist/fila-pesada.js +8 -6
- package/dist/fix.js +152 -6
- package/dist/hitl-gates.js +1 -1
- package/dist/index.js +53 -4
- package/dist/locale-ajuda.js +10 -4
- package/dist/locale-claims.js +22 -6
- package/dist/locale-operacao-restante.js +12 -0
- package/dist/locale-prompts.js +4 -2
- package/dist/locale-pulse.js +2 -0
- package/dist/locale-retry.js +8 -0
- package/dist/locale-verify.js +8 -0
- package/dist/mcp-artifacts.js +24 -0
- package/dist/mcp-install.js +1 -1
- package/dist/mcp-server.js +11 -1
- package/dist/mcp-verify-async.js +2 -1
- package/dist/noctum-provas.js +56 -30
- package/dist/recibo-prova.js +87 -0
- package/dist/retry.js +6 -0
- package/dist/security-scan/executor.js +9 -3
- package/dist/security-scan/guard.js +5 -2
- package/dist/session-watcher.js +94 -23
- package/dist/ship.js +1 -1
- package/dist/temporario-das-lanes.js +94 -0
- package/dist/verify.js +662 -410
- package/eval/fixtures/fx-sensores-runtime/caso.json +1 -1
- package/package.json +1 -1
- package/skills/phases/check-quality/SKILL.md +14 -0
package/dist/locale-claims.js
CHANGED
|
@@ -36,7 +36,7 @@ const ESTADOS_EN = {
|
|
|
36
36
|
};
|
|
37
37
|
exports.CLAIMS_PT_BR = {
|
|
38
38
|
// ork claims add
|
|
39
|
-
usoAdd: 'uso: ork claims add <thread-id> <arquivo> --claim "<alegacao>" [--verificar "<comando>"]',
|
|
39
|
+
usoAdd: 'uso: ork claims add <thread-id> <arquivo> --claim "<alegacao>" [--verificar "<comando>"] [--dependencia-externa rede,relogio]',
|
|
40
40
|
registrada: (id, thread) => `Claim ${id} registrada na thread ${thread}.`,
|
|
41
41
|
campoArquivo: (arquivo) => ` arquivo ${arquivo}`,
|
|
42
42
|
campoAlegacao: (alegacao) => ` alegacao ${alegacao}`,
|
|
@@ -54,7 +54,9 @@ exports.CLAIMS_PT_BR = {
|
|
|
54
54
|
nomesDoLint: { 'suite-inteira': 'roda a suite inteira', 'sha-intermediario': 'fixa um SHA intermediario',
|
|
55
55
|
'contagem-de-commits': 'compara contagem de commits', 'binario-rg': 'usa o binario rg ausente no runner',
|
|
56
56
|
'ork-fora-do-path': 'chama ork fora do PATH do runner', 'estado-local': 'le estado local fora do checkout',
|
|
57
|
-
'aspas-escapadas': 'leva aspas escapadas literalmente'
|
|
57
|
+
'aspas-escapadas': 'leva aspas escapadas literalmente',
|
|
58
|
+
'contexto-artificial': 'executa contexto artificial isolado',
|
|
59
|
+
'artefato-de-fechamento': 'le artefato gerado pelo fechamento' },
|
|
58
60
|
correcoesDoLint: {
|
|
59
61
|
'suite-inteira': 'rode só o teste da claim (`node --test` no arquivo do teste, ou o comando do projeto que roda um arquivo) ' +
|
|
60
62
|
'ou um script hermético do projeto',
|
|
@@ -64,6 +66,8 @@ exports.CLAIMS_PT_BR = {
|
|
|
64
66
|
'ork-fora-do-path': 'use `node core/dist/index.js ...`; o runner nao instala `ork` no PATH',
|
|
65
67
|
'estado-local': 'prove somente arquivos versionados do checkout; `.orkastery/` e estado local e nao vai ao CI',
|
|
66
68
|
'aspas-escapadas': 'use aspas reais do shell; nao serialize `\\x22` ou `\\x27` dentro do comando',
|
|
69
|
+
'contexto-artificial': 'exercite a API publica ou um teste do produto no contexto real, sem reconstruir a funcao em `node -e`, `vm` ou `new Function`',
|
|
70
|
+
'artefato-de-fechamento': 'prove a fonte versionada que gera o artefato; o artefato que contem a claim nao pode provar a si proprio',
|
|
67
71
|
},
|
|
68
72
|
// ork claims conferir
|
|
69
73
|
usoConferir: 'uso: ork claims conferir <thread-id> --claims C1,C2 | --tarefa T1 [--prazo S] [--json]',
|
|
@@ -111,8 +115,12 @@ exports.CLAIMS_PT_BR = {
|
|
|
111
115
|
usoVerificar: 'uso: ork claims verificar <thread-id> <claim-id> --comando "<comando>"',
|
|
112
116
|
comandoAnexado: (id) => `Claim ${id} agora tem comando de verificacao.`,
|
|
113
117
|
proveAgora: (thread) => `Prove agora: ork verify ${thread}`,
|
|
114
|
-
usoRetirar: 'uso: ork claims retirar <thread-id> <claim-id> --motivo "<motivo>"',
|
|
118
|
+
usoRetirar: 'uso: ork claims retirar <thread-id> <claim-id> [--motivo-tipo substituicao|obsoleta|erro] [--substituida-por <claim-id>] --motivo "<motivo>"',
|
|
115
119
|
retirada: (id, thread) => `Claim ${id} retirada da thread ${thread}.`,
|
|
120
|
+
retiradaTipada: (tipada) => ` retirada ${tipada ? 'tipada' : 'nao tipada (compatibilidade)'}`,
|
|
121
|
+
autorDaRetirada: (tipo, id) => ` autor ${tipo}:${id}`,
|
|
122
|
+
retiradaPendente: (id) => `Claim ${id} continua ativa; retirada sem substituta enviada ao dono.`,
|
|
123
|
+
substitutaDaRetirada: (id) => ` substituta ${id}`,
|
|
116
124
|
historicoContinua: ' o historico da alegacao continua no claims.jsonl e no ledger.',
|
|
117
125
|
usoAusente: 'uso: ork claims ausente <thread-id> --paths A,B --motivo "<motivo>" [--commit SHA]',
|
|
118
126
|
ausenciaRegistrada: (thread, paths) => `Ausencia de prova registrada na thread ${thread}: ${paths}.`,
|
|
@@ -134,7 +142,7 @@ exports.CLAIMS_PT_BR = {
|
|
|
134
142
|
ausenteSemCaminhos: 'prova.ausente: informe os caminhos que ficaram sem prova',
|
|
135
143
|
};
|
|
136
144
|
exports.CLAIMS_EN = {
|
|
137
|
-
usoAdd: 'usage: ork claims add <thread-id> <file> --claim "<statement>" [--verificar "<command>"]',
|
|
145
|
+
usoAdd: 'usage: ork claims add <thread-id> <file> --claim "<statement>" [--verificar "<command>"] [--dependencia-externa rede,relogio]',
|
|
138
146
|
registrada: (id, thread) => `Claim ${id} recorded in thread ${thread}.`,
|
|
139
147
|
campoArquivo: (arquivo) => ` file ${arquivo}`,
|
|
140
148
|
campoAlegacao: (alegacao) => ` statement ${alegacao}`,
|
|
@@ -150,7 +158,9 @@ exports.CLAIMS_EN = {
|
|
|
150
158
|
nomesDoLint: { 'suite-inteira': 'runs the whole suite', 'sha-intermediario': 'pins an intermediate SHA',
|
|
151
159
|
'contagem-de-commits': 'compares a commit count', 'binario-rg': 'uses the rg binary missing from the runner',
|
|
152
160
|
'ork-fora-do-path': 'calls ork outside the runner PATH', 'estado-local': 'reads local state outside the checkout',
|
|
153
|
-
'aspas-escapadas': 'passes escaped quotes literally'
|
|
161
|
+
'aspas-escapadas': 'passes escaped quotes literally',
|
|
162
|
+
'contexto-artificial': 'runs an isolated artificial context',
|
|
163
|
+
'artefato-de-fechamento': 'reads an artifact generated by phase closing' },
|
|
154
164
|
correcoesDoLint: {
|
|
155
165
|
'suite-inteira': 'run only the claim test (`node --test` on the test file, or the project command that runs one file) ' +
|
|
156
166
|
'or a hermetic project script',
|
|
@@ -160,6 +170,8 @@ exports.CLAIMS_EN = {
|
|
|
160
170
|
'ork-fora-do-path': 'use `node core/dist/index.js ...`; the runner does not install `ork` in PATH',
|
|
161
171
|
'estado-local': 'prove only versioned checkout files; `.orkastery/` is local state and is not sent to CI',
|
|
162
172
|
'aspas-escapadas': 'use real shell quotes; do not serialize `\\x22` or `\\x27` inside the command',
|
|
173
|
+
'contexto-artificial': 'exercise the public API or a product test in its real context instead of rebuilding the function with `node -e`, `vm`, or `new Function`',
|
|
174
|
+
'artefato-de-fechamento': 'prove the versioned source that generates the artifact; an artifact containing the claim cannot prove itself',
|
|
163
175
|
},
|
|
164
176
|
usoConferir: 'usage: ork claims conferir <thread-id> --claims C1,C2 | --tarefa T1 [--prazo S] [--json]',
|
|
165
177
|
conferencia: (thread) => `Spot check of thread ${thread} (no receipt: \`ork verify\` is still what verifies)`,
|
|
@@ -205,8 +217,12 @@ exports.CLAIMS_EN = {
|
|
|
205
217
|
usoVerificar: 'usage: ork claims verificar <thread-id> <claim-id> --comando "<command>"',
|
|
206
218
|
comandoAnexado: (id) => `Claim ${id} now has a verification command.`,
|
|
207
219
|
proveAgora: (thread) => `Prove it now: \`ork verify ${thread}\``,
|
|
208
|
-
usoRetirar: 'usage: ork claims retirar <thread-id> <claim-id> --motivo "<reason>"',
|
|
220
|
+
usoRetirar: 'usage: ork claims retirar <thread-id> <claim-id> [--motivo-tipo substituicao|obsoleta|erro] [--substituida-por <claim-id>] --motivo "<reason>"',
|
|
209
221
|
retirada: (id, thread) => `Claim ${id} withdrawn from thread ${thread}.`,
|
|
222
|
+
retiradaTipada: (tipada) => ` withdrawal ${tipada ? 'typed' : 'untyped (compatibility)'}`,
|
|
223
|
+
autorDaRetirada: (tipo, id) => ` author ${tipo}:${id}`,
|
|
224
|
+
retiradaPendente: (id) => `Claim ${id} remains active; withdrawal without a replacement was sent to the owner.`,
|
|
225
|
+
substitutaDaRetirada: (id) => ` replacement ${id}`,
|
|
210
226
|
historicoContinua: ' the history of the statement stays in claims.jsonl and in the ledger.',
|
|
211
227
|
usoAusente: 'usage: ork claims ausente <thread-id> --paths A,B --motivo "<reason>" [--commit SHA]',
|
|
212
228
|
ausenciaRegistrada: (thread, paths) => `Missing proof recorded in thread ${thread}: ${paths}.`,
|
|
@@ -102,6 +102,12 @@ exports.OPERACAO_RESTANTE_PT_BR = {
|
|
|
102
102
|
fix: {
|
|
103
103
|
usoOpen: 'uso: ork fix open <thread-id> [--so-claims] [--reverify]',
|
|
104
104
|
usoList: 'uso: ork fix list <thread-id> [--rodada N]',
|
|
105
|
+
usoStatus: 'uso: ork fix status <thread-id> [--rodada N] [--json]',
|
|
106
|
+
status: (rodada, thread) => `Estado da rodada ${rodada} da thread ${thread}`,
|
|
107
|
+
estado: (estado) => ` estado ${estado}`,
|
|
108
|
+
faltam: (itens) => ` faltam ${itens}`,
|
|
109
|
+
semFaltas: '(nada)',
|
|
110
|
+
colunasStatus: ['CORRECAO', 'ACHADO', 'ORIGEM', 'LOCAL', 'ESTADO', 'COMMIT QUE FECHOU'],
|
|
105
111
|
semRodada: (thread) => `A thread ${thread} nao tem rodada de GO-FIX. Abra com: ork fix open ${thread}`,
|
|
106
112
|
lista: (rodada, thread) => `Correcoes da rodada ${rodada} da thread ${thread}`,
|
|
107
113
|
colunasLista: ['ID', 'TIPO', 'MOTIVO', 'ALVO', 'ESTADO', 'JULGADO POR'],
|
|
@@ -578,6 +584,12 @@ exports.OPERACAO_RESTANTE_EN = {
|
|
|
578
584
|
fix: {
|
|
579
585
|
usoOpen: 'usage: ork fix open <thread-id> [--so-claims] [--reverify]',
|
|
580
586
|
usoList: 'usage: ork fix list <thread-id> [--rodada N]',
|
|
587
|
+
usoStatus: 'usage: ork fix status <thread-id> [--rodada N] [--json]',
|
|
588
|
+
status: (round, thread) => `Status of round ${round} of thread ${thread}`,
|
|
589
|
+
estado: (state) => ` state ${state}`,
|
|
590
|
+
faltam: (items) => ` remaining ${items}`,
|
|
591
|
+
semFaltas: '(nothing)',
|
|
592
|
+
colunasStatus: ['FIX', 'FINDING', 'SOURCE', 'LOCATION', 'STATE', 'CLOSING COMMIT'],
|
|
581
593
|
semRodada: (thread) => `Thread ${thread} has no GO-FIX round. Open one with: ork fix open ${thread}`,
|
|
582
594
|
lista: (round, thread) => `Fixes from round ${round} of thread ${thread}`,
|
|
583
595
|
colunasLista: ['ID', 'TYPE', 'REASON', 'TARGET', 'STATE', 'JUDGED BY'],
|
package/dist/locale-prompts.js
CHANGED
|
@@ -9,7 +9,8 @@ exports.PROMPTS_PT_BR = {
|
|
|
9
9
|
PLAN: 'PLAN (F2): plano com tarefas, touch_paths, decisoes D1..Dn com domicilio unico e verify executavel por tarefa. Nao implementa.',
|
|
10
10
|
GO: 'GO (F3): implementacao slice por slice, um commit atomico por tarefa, dentro da worktree da thread.',
|
|
11
11
|
CHECK: 'CHECK (F4): verificacao contra a baseline (regressao versus divida pre-existente), review de codigo, testes, seguranca e performance; ' +
|
|
12
|
-
'o parecer diz o modo do CHECK da rodada (Agile Check ou Classic Check, da linha `check` do `ork verify`).'
|
|
12
|
+
'o parecer diz o modo do CHECK da rodada (Agile Check ou Classic Check, da linha `check` do `ork verify`). ' +
|
|
13
|
+
'Claim nova afirma o comportamento correto e passa com a correcao; a reproducao do defeito fica como comando no parecer e nunca vira claim.',
|
|
13
14
|
SHIP: 'SHIP (F5): merge serializado, push provado por comando, roadmap atualizado e plano de rollback.',
|
|
14
15
|
MASTER: 'MASTER (F6): MASTER log com postmortem tipado, licoes e o score humano de 0 a 5. Uma entrega sem MASTER log nao aconteceu.',
|
|
15
16
|
},
|
|
@@ -103,7 +104,8 @@ exports.PROMPTS_EN = {
|
|
|
103
104
|
PLAN: 'PLAN (F2): sliced tasks, queryable touch_paths, D1..Dn decisions with one home, and executable verify per task. Does not implement.',
|
|
104
105
|
GO: 'GO (F3): implement slice by slice, one atomic commit per task, inside the thread worktree.',
|
|
105
106
|
CHECK: 'CHECK (F4): verify against the baseline (regressions versus pre-existing debt), then review code, tests, security, and performance; ' +
|
|
106
|
-
'the verdict names the CHECK mode of the round (Agile Check or Classic Check, from the `check` line of `ork verify`).'
|
|
107
|
+
'the verdict names the CHECK mode of the round (Agile Check or Classic Check, from the `check` line of `ork verify`). ' +
|
|
108
|
+
'A new claim states the correct behavior and passes with the fix; defect reproduction stays as a command in the report and never becomes a claim.',
|
|
107
109
|
SHIP: 'SHIP (F5): serialized merge, command-proven push, updated roadmap, and rollback plan.',
|
|
108
110
|
MASTER: 'MASTER (F6): typed POSTMORTEM, MASTER log, lessons, and a human score from 0 to 5. A delivery without a MASTER log did not happen.',
|
|
109
111
|
},
|
package/dist/locale-pulse.js
CHANGED
|
@@ -172,6 +172,7 @@ exports.PULSE_PT_BR = {
|
|
|
172
172
|
'artifact.missing': 'artefato exigido pela fase nao existe no disco',
|
|
173
173
|
'claims.failed': 'alegacao verificavel reprovou na reexecucao no HEAD real',
|
|
174
174
|
'claims.unverifiable': 'alegacao sem comando de verificacao declarado',
|
|
175
|
+
'claims.retirada-sem-substituta': 'retirada tipada sem claim substituta verde espera decisao do dono',
|
|
175
176
|
'policy.violation': 'policy do manifesto com severidade block foi violada',
|
|
176
177
|
'runtime.autoconferencia': 'o CHECK foi despachado no mesmo runtime que fez o GO, e a thread exige validacao cruzada',
|
|
177
178
|
'verify.regression': 'comando que passava na baseline falha agora',
|
|
@@ -324,6 +325,7 @@ exports.PULSE_EN = {
|
|
|
324
325
|
'artifact.missing': 'an artifact the phase requires does not exist on disk',
|
|
325
326
|
'claims.failed': 'a verifiable claim failed when rerun on the real HEAD',
|
|
326
327
|
'claims.unverifiable': 'a claim with no verification command declared',
|
|
328
|
+
'claims.retirada-sem-substituta': 'typed withdrawal without a green replacement claim waits for the owner',
|
|
327
329
|
'policy.violation': 'a manifest policy with block severity was violated',
|
|
328
330
|
'runtime.autoconferencia': 'CHECK was dispatched on the same runtime that did GO, and the thread requires cross-validation',
|
|
329
331
|
'verify.regression': 'a command that passed in the baseline fails now',
|
package/dist/locale-retry.js
CHANGED
|
@@ -26,6 +26,10 @@ exports.RETRY_PT_BR = {
|
|
|
26
26
|
porque: 'alegacao sem comando de verificacao vira correcao tipo A: anexar o comando (ou retirar a alegacao com motivo) e uma linha, nao um GO inteiro',
|
|
27
27
|
correcao: 'ork claims verificar <thread> <claim> --comando "<comando>"',
|
|
28
28
|
},
|
|
29
|
+
'claims.retirada-sem-substituta': {
|
|
30
|
+
porque: 'retirar uma regra sem substituta verde apaga evidencia ativa: a maquina nao decide sozinha que a alegacao deixou de valer',
|
|
31
|
+
correcao: 'o dono decide pelo pedido tipado; ou registre e verifique uma claim substituta antes de repetir a retirada',
|
|
32
|
+
},
|
|
29
33
|
'policy.violation': {
|
|
30
34
|
porque: 'policy com severidade block reprova em qualquer modo: reexecutar sozinho seria a maquina revogando a policy do manifesto',
|
|
31
35
|
correcao: 'corrija a violacao no pedido/manifesto; policy block nao se resolve por repeticao',
|
|
@@ -312,6 +316,10 @@ exports.RETRY_EN = {
|
|
|
312
316
|
porque: 'a claim without a verification command becomes a type A fix: attaching the command (or withdrawing the claim with a reason) is one line, not a whole GO',
|
|
313
317
|
correcao: 'ork claims verificar <thread> <claim> --comando "<command>"',
|
|
314
318
|
},
|
|
319
|
+
'claims.retirada-sem-substituta': {
|
|
320
|
+
porque: 'withdrawing a rule without a green replacement removes active evidence: the machine cannot decide by itself that the claim no longer applies',
|
|
321
|
+
correcao: 'the owner decides through the typed request; or record and verify a replacement claim before retrying the withdrawal',
|
|
322
|
+
},
|
|
315
323
|
'policy.violation': {
|
|
316
324
|
porque: 'a policy with block severity fails in any mode: rerunning on its own would be the machine revoking the manifest policy',
|
|
317
325
|
correcao: 'fix the violation in the request or the manifest; a block policy is not solved by repetition',
|
package/dist/locale-verify.js
CHANGED
|
@@ -54,8 +54,12 @@ exports.VERIFY_PT_BR = {
|
|
|
54
54
|
agile: (reaproveitadas, inteiras, paralelo, lanes) => ` agile ${reaproveitadas} comando(s) de claim contra o produto do preparo, ${inteiras} inteiro(s); ` +
|
|
55
55
|
`${paralelo ? `grupo em paralelo${lanes.length ? ` com as lanes ${lanes.join(', ')}` : ''}` : 'comandos do manifesto em serie'}`,
|
|
56
56
|
agileFallback: (peca, motivo, fallback) => ` fallback ${peca}: ${motivo || 'sem motivo dito'}; rodou ${fallback || 'o equivalente do Classic'}`,
|
|
57
|
+
tmpdirDaRodada: 'TMPDIR compartilhado pela rodada',
|
|
58
|
+
discoComTmpdirDaRodada: 'disco com TMPDIR da rodada',
|
|
57
59
|
agileDegradado: (peca, motivo) => ` degradado ${peca}: ${motivo || 'sem motivo dito'}; preservou o plano paralelo`,
|
|
58
60
|
agilePeca: (peca, motivo) => ` agile ${peca}: ${motivo || 'sem motivo dito'}`,
|
|
61
|
+
claimLaneReaproveitada: (claim, evidencia) => ` claim-lane ${claim}: reaproveitada das lanes (${evidencia || 'evidencia nominal da rodada'})`,
|
|
62
|
+
claimLaneRecusada: (claim, motivo) => ` claim-lane ${claim}: recusada (${motivo}); rodou a claim inteira`,
|
|
59
63
|
reservaIntegracao: (cpus, fonte) => `reserva da integracao ${cpus} CPU(s), origem ${{ medida: 'medida', conservadora: 'conservadora', classic: 'Classic' }[fonte]}`,
|
|
60
64
|
preparo: (situacao, segundos, alterado) => ` preparo ${situacao} em ` +
|
|
61
65
|
`${segundos} s, uma vez para a rodada; produto ` +
|
|
@@ -173,8 +177,12 @@ exports.VERIFY_EN = {
|
|
|
173
177
|
agile: (reaproveitadas, inteiras, paralelo, lanes) => ` agile ${reaproveitadas} claim command(s) against the prepared product, ${inteiras} in full; ` +
|
|
174
178
|
`${paralelo ? `parallel group${lanes.length ? ` with lanes ${lanes.join(', ')}` : ''}` : 'manifest commands in series'}`,
|
|
175
179
|
agileFallback: (peca, motivo, fallback) => ` fallback ${peca}: ${motivo || 'no reason given'}; ran ${fallback || 'the Classic equivalent'}`,
|
|
180
|
+
tmpdirDaRodada: 'TMPDIR shared by the run',
|
|
181
|
+
discoComTmpdirDaRodada: 'disk with the run TMPDIR',
|
|
176
182
|
agileDegradado: (peca, motivo) => ` degraded ${peca}: ${motivo || 'no reason given'}; kept the parallel plan`,
|
|
177
183
|
agilePeca: (peca, motivo) => ` agile ${peca}: ${motivo || 'no reason given'}`,
|
|
184
|
+
claimLaneReaproveitada: (claim, evidencia) => ` claim-lane ${claim}: reused from lanes (${evidencia || 'nominal evidence from this run'})`,
|
|
185
|
+
claimLaneRecusada: (claim, motivo) => ` claim-lane ${claim}: refused (${motivo}); ran the full claim`,
|
|
178
186
|
reservaIntegracao: (cpus, fonte) => `integration reservation ${cpus} CPU(s), ` +
|
|
179
187
|
`source ${{ medida: 'measured', conservadora: 'conservative', classic: 'Classic' }[fonte]}`,
|
|
180
188
|
preparo: (situacao, segundos, alterado) => ` prepare ${situacao} in ${segundos} s, once for the run; product ` +
|
package/dist/mcp-artifacts.js
CHANGED
|
@@ -39,6 +39,7 @@ exports.lerArtefatoMcp = lerArtefatoMcp;
|
|
|
39
39
|
exports.escreverArtefatoMcp = escreverArtefatoMcp;
|
|
40
40
|
exports.listarClaimsMcp = listarClaimsMcp;
|
|
41
41
|
exports.adicionarClaimMcp = adicionarClaimMcp;
|
|
42
|
+
exports.retirarClaimMcp = retirarClaimMcp;
|
|
42
43
|
/** Documentos do agente, separados dos recibos oficiais do nucleo. Backend Linux como HITL. */
|
|
43
44
|
const fs = __importStar(require("node:fs"));
|
|
44
45
|
const path = __importStar(require("node:path"));
|
|
@@ -47,6 +48,7 @@ const thread_1 = require("./thread");
|
|
|
47
48
|
const hitl_gates_1 = require("./hitl-gates");
|
|
48
49
|
const leases_1 = require("./leases");
|
|
49
50
|
const claims_1 = require("./claims");
|
|
51
|
+
const verify_1 = require("./verify");
|
|
50
52
|
const fases = { goal: 'GOAL', plan: 'PLAN', check: 'CHECK' };
|
|
51
53
|
const limite = 128 * 1024;
|
|
52
54
|
const hash = (bytes) => (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
|
|
@@ -267,6 +269,8 @@ function adicionarClaimMcp(raiz, id, entrada) {
|
|
|
267
269
|
if (!entrada.alegacao.trim() || entrada.alegacao.length > 8192 || entrada.verificar.length > 20 ||
|
|
268
270
|
entrada.verificar.some(c => typeof c !== 'string' || !c.trim() || c.length > 8192))
|
|
269
271
|
throw Error('mcp.claim.invalid');
|
|
272
|
+
if (entrada.dependenciasExternas?.some(d => d !== 'rede' && d !== 'relogio'))
|
|
273
|
+
throw Error('mcp.claim.external-dependency.invalid');
|
|
270
274
|
return comDocs(raiz, id, () => comEscrita(raiz, id, () => {
|
|
271
275
|
if ((0, thread_1.lerThread)(raiz, id).status === 'fechada')
|
|
272
276
|
throw Error('mcp.claim.closed');
|
|
@@ -274,3 +278,23 @@ function adicionarClaimMcp(raiz, id, entrada) {
|
|
|
274
278
|
return (0, claims_1.adicionarClaim)(raiz, id, { ...entrada, semProvaLocal: true });
|
|
275
279
|
}));
|
|
276
280
|
}
|
|
281
|
+
function claimDaRetiradaMcp(claim) {
|
|
282
|
+
const { verificar, ...projecao } = claim;
|
|
283
|
+
return { ...projecao, verificarSha256: (0, verify_1.impressaoDosComandos)(verificar) };
|
|
284
|
+
}
|
|
285
|
+
function retirarClaimMcp(raiz, id, entrada) {
|
|
286
|
+
validarId(id);
|
|
287
|
+
if (!/^C\d+$/.test(entrada.claimId) || entrada.substituidaPor !== undefined && !/^C\d+$/.test(entrada.substituidaPor) ||
|
|
288
|
+
!entrada.motivo.trim() || entrada.motivo.length > 8192)
|
|
289
|
+
throw Error('mcp.claim.withdraw.invalid');
|
|
290
|
+
const resultado = comDocs(raiz, id, () => comEscrita(raiz, id, () => {
|
|
291
|
+
if ((0, thread_1.lerThread)(raiz, id).status === 'fechada')
|
|
292
|
+
throw Error('mcp.claim.closed');
|
|
293
|
+
return (0, claims_1.retirarClaimTipada)(raiz, id, entrada.claimId, entrada);
|
|
294
|
+
}));
|
|
295
|
+
const resposta = { ...resultado, claim: claimDaRetiradaMcp(resultado.claim) };
|
|
296
|
+
if (resultado.estado !== 'pendente-do-dono')
|
|
297
|
+
return resposta;
|
|
298
|
+
const pedido = (0, hitl_gates_1.abrirPedidoGate)(raiz, id, resultado.motivo);
|
|
299
|
+
return { ...resposta, pedidoId: pedido.id };
|
|
300
|
+
}
|
package/dist/mcp-install.js
CHANGED
|
@@ -55,7 +55,7 @@ const IMPRESSAO_SSH = /^SHA256:[A-Za-z0-9+/]{43}$/;
|
|
|
55
55
|
exports.TOOLS_DONO_CODEX = ['ork_thread_new', 'ork_phase_run', 'ork_request_decision'];
|
|
56
56
|
// RM-037 (rm037defeito, defeito 1): a decisao autonoma da sessao entra com as outras mutacoes do filho;
|
|
57
57
|
// sem o grant, o codex com approval_policy never recusaria a chamada.
|
|
58
|
-
exports.TOOLS_FILHO_CODEX = ['ork_artifact_write', 'ork_claim_add', 'ork_decision_record', 'ork_request_conduction',
|
|
58
|
+
exports.TOOLS_FILHO_CODEX = ['ork_artifact_write', 'ork_claim_add', 'ork_claim_withdraw', 'ork_decision_record', 'ork_request_conduction',
|
|
59
59
|
'ork_git_commit', 'ork_verify', 'ork_verify_status', 'ork_ship'];
|
|
60
60
|
// Brain mutation tools are deliberately excluded from the existing opt-in bundle.
|
|
61
61
|
// A native integration must request exact startup grants plus scoped activation.
|
package/dist/mcp-server.js
CHANGED
|
@@ -531,7 +531,17 @@ function criarServidorMcp(opcoes) {
|
|
|
531
531
|
});
|
|
532
532
|
registrarTool('ork_claim_add', { description: 'Registra alegacao prospectiva e comandos como dados. Nao executa comandos nem declara a alegacao verificada.',
|
|
533
533
|
inputSchema: daThread.extend({ arquivo: zod_1.z.string().min(1).max(500), alegacao: zod_1.z.string().min(1).max(8192),
|
|
534
|
-
verificar: zod_1.z.array(zod_1.z.string().min(1).max(8192)).max(20)
|
|
534
|
+
verificar: zod_1.z.array(zod_1.z.string().min(1).max(8192)).max(20),
|
|
535
|
+
dependenciasExternas: zod_1.z.array(zod_1.z.enum(['rede', 'relogio'])).max(2).optional() }).strict(), annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId, ...entrada }) => { thread(threadId); livre(threadId); return resposta((0, mcp_artifacts_1.adicionarClaimMcp)(raiz, threadId, entrada)); });
|
|
536
|
+
registrarTool('ork_claim_withdraw', { description: 'Retira claim com motivo tipado. Exige substituta ativa e verde no ultimo verify; sem substituta, preserva a claim e abre pedido ao dono.',
|
|
537
|
+
inputSchema: daThread.extend({ claimId: zod_1.z.string().regex(/^C\d+$/), motivoTipo: zod_1.z.enum(['substituicao', 'obsoleta', 'erro']),
|
|
538
|
+
substituidaPor: zod_1.z.string().regex(/^C\d+$/).optional(), motivo: zod_1.z.string().min(1).max(8192) }).strict(),
|
|
539
|
+
annotations: { readOnlyHint: false, destructiveHint: true } }, async ({ threadId, ...entrada }) => {
|
|
540
|
+
thread(threadId);
|
|
541
|
+
livre(threadId);
|
|
542
|
+
const autor = { tipo: 'sessao', id: opcoes.dispatchId ?? `mcp:${opcoes.host}` };
|
|
543
|
+
return resposta((0, mcp_artifacts_1.retirarClaimMcp)(raiz, threadId, { ...entrada, autor }));
|
|
544
|
+
});
|
|
535
545
|
registrarTool('ork_thread_status', { description: 'Estado canonico de uma thread deste projeto; pausas previstas nao sao pedidos abertos.',
|
|
536
546
|
inputSchema: daThread, annotations: { readOnlyHint: true } }, async ({ threadId }) => {
|
|
537
547
|
const t = thread(threadId);
|
package/dist/mcp-verify-async.js
CHANGED
|
@@ -326,7 +326,8 @@ function executarVerifyMcpWorker(raiz, threadId, rodadaId) {
|
|
|
326
326
|
}));
|
|
327
327
|
const locale = (0, locale_1.resolverLocale)(carregado.manifesto.owner?.language).locale;
|
|
328
328
|
const veredito = { ok: resultado.ok, commit: resultado.commit, motivos: resultado.motivos,
|
|
329
|
-
check: resultado.check, texto: (0, locale_1.comLocale)(locale, () => (0, verify_1.textoDoVerify)(resultado)),
|
|
329
|
+
check: resultado.check, texto: (0, locale_1.comLocale)(locale, () => (0, verify_1.textoDoVerify)(resultado)),
|
|
330
|
+
resultado: (0, verify_1.resultadoVerifyRedigido)(resultado) };
|
|
330
331
|
terminal = { estado: 'concluido', lane: null, veredito, falha: undefined, ocupantes: undefined };
|
|
331
332
|
}
|
|
332
333
|
catch (e) {
|
package/dist/noctum-provas.js
CHANGED
|
@@ -82,9 +82,9 @@ const policies_1 = require("./policies");
|
|
|
82
82
|
const session_watcher_claude_1 = require("./session-watcher-claude");
|
|
83
83
|
const ship_publicar_1 = require("./ship-publicar");
|
|
84
84
|
const thread_1 = require("./thread");
|
|
85
|
-
const types_1 = require("./types");
|
|
86
85
|
const verify_1 = require("./verify");
|
|
87
86
|
const worktree_1 = require("./worktree");
|
|
87
|
+
const recibo_prova_1 = require("./recibo-prova");
|
|
88
88
|
exports.CONTRATO_DAS_PROVAS = 'ork.noctum-provas/v1';
|
|
89
89
|
/** D2, D3, D4, D6 a D11: as recusas da entrega, num tipo fechado próprio (fora de `MotivoGate` e das recusas do envelope). */
|
|
90
90
|
exports.MOTIVOS_DA_ENTREGA = [
|
|
@@ -201,7 +201,12 @@ function lacunaDaCadeia(f) {
|
|
|
201
201
|
const c = f.cadeia.find(x => x.tipo === 'sem-leitura');
|
|
202
202
|
return c ? `o commit ${curto(c.sha)} da cadeia não se classificou: ${c.detalhe}` : null;
|
|
203
203
|
}
|
|
204
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Os `verify_run` do SHA da fonte, na ordem do ledger.
|
|
206
|
+
*
|
|
207
|
+
* A chave decide se um resultado verde ainda pode ser reaproveitado; ela nao tira uma
|
|
208
|
+
* rodada da historia. Assim, uma chave antiga nunca esconde reprovacao nem reduz o teto.
|
|
209
|
+
*/
|
|
205
210
|
function verifiesDaFonte(f) {
|
|
206
211
|
return f.verifies.filter(v => equivalente(f.cadeia, v.commit, NEUTROS_DO_VERIFY).ok);
|
|
207
212
|
}
|
|
@@ -234,6 +239,12 @@ function provaDoVerify(f) {
|
|
|
234
239
|
if (semExecucao.length) {
|
|
235
240
|
return repetir('noctum.entrega.verify-ausente', `claim(s) ativa(s) que o verify ${ultimo.eventId} não executou: ${semExecucao.slice(0, 10).join(', ')}`, { semExecucao });
|
|
236
241
|
}
|
|
242
|
+
if (!ultimo.chaveAtual || !(0, recibo_prova_1.mesmaChaveDoRecibo)(ultimo.recibo, ultimo.chaveAtual)) {
|
|
243
|
+
return repetir('noctum.entrega.verify-ausente', `a chave do recibo verde ${ultimo.eventId} não confere com HEAD, claims ativas e plano atuais`);
|
|
244
|
+
}
|
|
245
|
+
if (ultimo.reavaliadoSemMudanca && ultimo.chaveAtual.dependenciasExternas.length > 0) {
|
|
246
|
+
return repetir('noctum.entrega.verify-ausente', `o verify ${ultimo.eventId} tem dependência externa e precisa rodar depois da reavaliação sem mudança`);
|
|
247
|
+
}
|
|
237
248
|
return fim(prova('verify', null, `verify verde em ${curto(ultimo.commit)} (${ultimo.eventId})` +
|
|
238
249
|
(falhas.length ? `, com ${falhas.length} reprovação(ões) anterior(es) no mesmo SHA registrada(s)` : ''), evidencia));
|
|
239
250
|
}
|
|
@@ -281,9 +292,6 @@ function provaDaRevisao(f) {
|
|
|
281
292
|
if (f.autores.includes(r.sessionId)) {
|
|
282
293
|
return prova('revisao', 'noctum.entrega.revisor-autor', `a sessão ${r.sessionId.slice(0, 8)} também é autora do candidato: não é revisão independente`, ev);
|
|
283
294
|
}
|
|
284
|
-
if (f.ultimoDespachoDeAutor && !(Date.parse(r.despachadaEm) > Date.parse(f.ultimoDespachoDeAutor))) {
|
|
285
|
-
return prova('revisao', 'noctum.entrega.revisao-antiga', 'o CHECK foi despachado antes do último despacho de quem escreveu o candidato', ev);
|
|
286
|
-
}
|
|
287
295
|
if (r.resultado === 'em-curso')
|
|
288
296
|
return prova('revisao', 'noctum.entrega.revisao-em-curso', `a sessão de CHECK ${r.sessionId.slice(0, 8)} ainda não tem resultado`, ev);
|
|
289
297
|
if (r.prova.veredito && r.prova.veredito !== 'PASSOU') {
|
|
@@ -298,6 +306,9 @@ function provaDaRevisao(f) {
|
|
|
298
306
|
return prova('revisao', 'noctum.entrega.revisao-antiga', 'o parecer do CHECK mudou depois do resultado que o observador gravou', ev);
|
|
299
307
|
if (!r.revisado)
|
|
300
308
|
return prova('revisao', 'noctum.entrega.revisao-sem-sha', 'o CHECK não rodou verify no intervalo: o SHA revisado é desconhecido', ev);
|
|
309
|
+
if (!r.chaveAtual || !(0, recibo_prova_1.mesmaChaveDoRecibo)(r.recibo, r.chaveAtual)) {
|
|
310
|
+
return prova('revisao', 'noctum.entrega.revisao-antiga', 'a chave do recibo do CHECK não confere com HEAD, claims ativas e plano atuais', ev);
|
|
311
|
+
}
|
|
301
312
|
const lacuna = lacunaDaCadeia(f);
|
|
302
313
|
if (lacuna)
|
|
303
314
|
return prova('revisao', LACUNA, lacuna, ev);
|
|
@@ -650,28 +661,17 @@ function segredosDaHistoria(raiz, base, fonte) {
|
|
|
650
661
|
}
|
|
651
662
|
return { lido: true, commits: blocos.length, polvos, achados };
|
|
652
663
|
}
|
|
653
|
-
/**
|
|
654
|
-
function autoresDaThread(
|
|
664
|
+
/** RM-078: autores do candidato são somente sessões com commit confirmado na cadeia da fonte. */
|
|
665
|
+
function autoresDaThread(raiz, eventos, fonte) {
|
|
655
666
|
const autores = new Set();
|
|
656
|
-
let ultimo = null;
|
|
657
|
-
const marcar = (id, em) => {
|
|
658
|
-
autores.add(id);
|
|
659
|
-
if (em && (!ultimo || Date.parse(em) > Date.parse(ultimo)))
|
|
660
|
-
ultimo = em;
|
|
661
|
-
};
|
|
662
|
-
for (const s of t.sessoes ?? []) {
|
|
663
|
-
const fases = (s.bloco ?? '').split('-');
|
|
664
|
-
const antesDoGo = fases.includes('GO') && types_1.FASES.indexOf(s.fase) <= types_1.FASES.indexOf('GO');
|
|
665
|
-
if (s.fase === 'GO' || antesDoGo)
|
|
666
|
-
marcar(s.sessionId, s.despachadaEm);
|
|
667
|
-
}
|
|
668
667
|
for (const e of eventos) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
668
|
+
const commit = typeof e.commit === 'string' && SHA.test(e.commit) ? e.commit : null;
|
|
669
|
+
const naCadeia = !!commit && !!fonte && git(raiz, ['merge-base', '--is-ancestor', commit, fonte]).ok;
|
|
670
|
+
if ((e.tipo === 'mcp_git_committed' || e.tipo === 'commit') && naCadeia && typeof e.sessionId === 'string' && e.sessionId) {
|
|
671
|
+
autores.add(e.sessionId);
|
|
672
672
|
}
|
|
673
673
|
}
|
|
674
|
-
return
|
|
674
|
+
return [...autores];
|
|
675
675
|
}
|
|
676
676
|
/** O vínculo da sessão de CHECK provado pelo núcleo, como o Maestro confere (`maestro-authority.ts`), ou o que faltou. */
|
|
677
677
|
function vinculoDaSessao(raiz, t, s, eventos) {
|
|
@@ -719,16 +719,20 @@ function revisoesDaThread(raiz, t, eventos) {
|
|
|
719
719
|
const gravada = resultado?.provaOrk;
|
|
720
720
|
let prova;
|
|
721
721
|
let revisado;
|
|
722
|
+
let eventoDoVerify;
|
|
723
|
+
const ate = resultado ? posicao.get(resultado) ?? eventos.length : eventos.length;
|
|
722
724
|
if (gravada && typeof gravada.ok === 'boolean') {
|
|
723
725
|
prova = { ok: gravada.ok, fonte: texto(gravada.fonte) ?? 'a prova do núcleo gravada no resultado do CHECK', veredito: texto(gravada.veredito) };
|
|
724
726
|
revisado = texto(gravada.verify?.commit);
|
|
727
|
+
eventoDoVerify = [...intervalo].reverse().find(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.verificacao &&
|
|
728
|
+
(posicao.get(e) ?? eventos.length) < ate && e.commit === revisado);
|
|
725
729
|
}
|
|
726
730
|
else {
|
|
727
731
|
const p = (0, session_watcher_claude_1.provaDoOrk)(raiz, t.id, sessao, eventos, (0, session_watcher_claude_1.fonteRegistrada)(eventos, sessao));
|
|
728
732
|
prova = { ok: p.ok, fonte: p.fonte, veredito: p.veredito ?? null };
|
|
729
733
|
// Pela posição no ledger, e não pela hora: dois eventos no mesmo milissegundo não trocam de lado.
|
|
730
|
-
|
|
731
|
-
revisado = texto(
|
|
734
|
+
eventoDoVerify = intervalo.filter(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.verificacao && (posicao.get(e) ?? eventos.length) < ate).at(-1);
|
|
735
|
+
revisado = texto(eventoDoVerify?.commit);
|
|
732
736
|
}
|
|
733
737
|
// O parecer do resultado: o sha que o observador viu; sem ele (o observador do codex não grava), a data do arquivo, que
|
|
734
738
|
// não pode ser depois do resultado (A5 da rodada 1). O `ts` do ledger é de milissegundo; a data do arquivo, mais fina.
|
|
@@ -736,11 +740,30 @@ function revisoesDaThread(raiz, t, eventos) {
|
|
|
736
740
|
const parecer = (0, session_watcher_claude_1.estadoDoArtefato)(raiz, t.id, 'docs/check.md');
|
|
737
741
|
const parecerMudou = viu ? parecer.sha256 !== viu
|
|
738
742
|
: !!resultado && parecer.mtimeMs !== null && Math.floor(parecer.mtimeMs) > Date.parse(resultado.ts);
|
|
743
|
+
const shaRevisado = revisado && SHA.test(revisado) ? revisado : null;
|
|
739
744
|
return { sessionId: s.sessionId, runtime: s.runtime, despachadaEm: s.despachadaEm, semVinculo: vinculoDaSessao(raiz, t, s, eventos),
|
|
740
|
-
resultado: estado, prova, revisado:
|
|
745
|
+
resultado: estado, prova, revisado: shaRevisado, recibo: reciboDoEvento(eventoDoVerify?.recibo),
|
|
746
|
+
chaveAtual: shaRevisado ? chaveAtualSegura(raiz, t.id, shaRevisado) : null, parecerMudou };
|
|
741
747
|
});
|
|
742
748
|
}
|
|
743
|
-
function
|
|
749
|
+
function reciboDoEvento(valor) {
|
|
750
|
+
if (!valor || typeof valor !== 'object')
|
|
751
|
+
return null;
|
|
752
|
+
const r = valor;
|
|
753
|
+
return r.contrato === recibo_prova_1.CONTRATO_DO_RECIBO_DE_PROVA && typeof r.head === 'string' && typeof r.claimsSha256 === 'string' &&
|
|
754
|
+
(typeof r.planoSha256 === 'string' || r.planoSha256 === null) && Array.isArray(r.dependenciasExternas) && typeof r.sha256 === 'string'
|
|
755
|
+
? r : null;
|
|
756
|
+
}
|
|
757
|
+
function chaveAtualSegura(raiz, threadId, head) {
|
|
758
|
+
try {
|
|
759
|
+
return (0, recibo_prova_1.chaveDoReciboDeProva)(raiz, threadId, head);
|
|
760
|
+
}
|
|
761
|
+
catch {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function verifiesDoLedger(raiz, threadId, eventos) {
|
|
766
|
+
const posicao = new Map(eventos.map((e, i) => [e, i]));
|
|
744
767
|
return eventos.filter(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.verificacao && typeof e.commit === 'string' && SHA.test(e.commit)).map(e => ({
|
|
745
768
|
eventId: texto(e.eventId) ?? '-', ts: e.ts, commit: e.commit, ok: e.veredito === 'verdade sustentada',
|
|
746
769
|
motivos: Array.isArray(e.motivos) ? e.motivos.map(String) : [],
|
|
@@ -748,6 +771,9 @@ function verifiesDoLedger(eventos) {
|
|
|
748
771
|
comComandos: Array.isArray(e.comandos) && e.comandos.length > 0,
|
|
749
772
|
claims: Array.isArray(e.claims) ? e.claims.filter(c => typeof c?.id === 'string')
|
|
750
773
|
.map(c => ({ id: c.id, verificado: c.verificado === true, motivo: texto(c.motivo) })) : [],
|
|
774
|
+
recibo: reciboDoEvento(e.recibo), chaveAtual: chaveAtualSegura(raiz, threadId, e.commit),
|
|
775
|
+
reavaliadoSemMudanca: eventos.slice((posicao.get(e) ?? eventos.length) + 1)
|
|
776
|
+
.some(x => x.tipo === 'phase_result' && x.resultado === 'go.sem-mudanca'),
|
|
751
777
|
}));
|
|
752
778
|
}
|
|
753
779
|
/** Os fatos da entrega de uma thread, lidos agora do disco, do git e da forja. Não grava nada. */
|
|
@@ -766,7 +792,7 @@ function lerFatosDaEntrega(carregado, threadId, opcoes = {}) {
|
|
|
766
792
|
base.erro = `o commit ${curto(base.sha)} da base não chegou a esta cópia`;
|
|
767
793
|
base.sha = null;
|
|
768
794
|
}
|
|
769
|
-
const
|
|
795
|
+
const autores = autoresDaThread(raiz, eventos, fonte);
|
|
770
796
|
const claimsAtivas = (() => { try {
|
|
771
797
|
return (0, claims_1.lerClaims)(raiz, threadId).filter(c => c.estado !== 'retirada');
|
|
772
798
|
}
|
|
@@ -775,8 +801,8 @@ function lerFatosDaEntrega(carregado, threadId, opcoes = {}) {
|
|
|
775
801
|
} })();
|
|
776
802
|
const daBranch = (0, ship_publicar_1.manifestoDaBranch)(carregado, fonte);
|
|
777
803
|
const fatos = {
|
|
778
|
-
thread: t.id, branch, fonte, base, integrada: null, cadeia: [], cadeiaLida: false, autores,
|
|
779
|
-
revisoes: revisoesDaThread(raiz, t, eventos), verifies: verifiesDoLedger(eventos),
|
|
804
|
+
thread: t.id, branch, fonte, base, integrada: null, cadeia: [], cadeiaLida: false, autores,
|
|
805
|
+
revisoes: revisoesDaThread(raiz, t, eventos), verifies: verifiesDoLedger(raiz, t.id, eventos),
|
|
780
806
|
comandosEsperados: (0, verify_1.comandosDoManifesto)(daBranch.manifesto).length,
|
|
781
807
|
// A2 da rodada 1: a claim de mutante sem comando não executa nada e nunca prova a guarda; ela não conta como mutante.
|
|
782
808
|
claims: claimsAtivas.map(c => ({ id: c.id, mutante: exports.ALEGACAO_DE_MUTANTE.test(c.alegacao) && c.verificar.length > 0 })),
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CONTRATO_DO_RECIBO_DE_PROVA = void 0;
|
|
37
|
+
exports.materialDasClaims = materialDasClaims;
|
|
38
|
+
exports.chaveDoReciboDeProva = chaveDoReciboDeProva;
|
|
39
|
+
exports.mesmaChaveDoRecibo = mesmaChaveDoRecibo;
|
|
40
|
+
/**
|
|
41
|
+
* RM-078: identidade do que um verify e um CHECK provaram.
|
|
42
|
+
*
|
|
43
|
+
* O recibo nao depende do horario do despacho. Ele depende do HEAD exato da prova,
|
|
44
|
+
* dos ids e comandos das claims ativas e dos bytes do plano. A equivalencia entre
|
|
45
|
+
* esse HEAD e a fonte continua sendo responsabilidade da cadeia classificada em
|
|
46
|
+
* `noctum-provas.ts`; este modulo nunca chama commits de produto de equivalentes.
|
|
47
|
+
*/
|
|
48
|
+
const node_crypto_1 = require("node:crypto");
|
|
49
|
+
const fs = __importStar(require("node:fs"));
|
|
50
|
+
const path = __importStar(require("node:path"));
|
|
51
|
+
const thread_1 = require("./thread");
|
|
52
|
+
const util_1 = require("./util");
|
|
53
|
+
exports.CONTRATO_DO_RECIBO_DE_PROVA = 'ork.recibo-prova/v1';
|
|
54
|
+
const sha256 = (valor) => (0, node_crypto_1.createHash)('sha256').update(valor).digest('hex');
|
|
55
|
+
/** Forma canonica das claims: id ordenado e ordem declarada dos comandos preservada. */
|
|
56
|
+
function materialDasClaims(claims) {
|
|
57
|
+
const ativas = claims.filter((c) => c.estado !== 'retirada').sort((a, b) => a.id.localeCompare(b.id, 'en', { numeric: true }));
|
|
58
|
+
const dependenciasExternas = [...new Set(ativas.flatMap((c) => c.dependenciasExternas ?? []))].sort();
|
|
59
|
+
return {
|
|
60
|
+
claims: ativas.map((c) => ({ id: c.id, verificar: [...c.verificar] })),
|
|
61
|
+
dependenciasExternas,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** A chave atual. Plano ausente fica explicito e nunca compara como recibo valido. */
|
|
65
|
+
function chaveDoReciboDeProva(raiz, threadId, head) {
|
|
66
|
+
const dir = (0, thread_1.dirThread)(raiz, threadId);
|
|
67
|
+
const claims = (0, util_1.lerJsonl)(path.join(dir, 'claims.jsonl'));
|
|
68
|
+
const material = materialDasClaims(claims);
|
|
69
|
+
const plano = path.join(dir, 'docs', 'plan.md');
|
|
70
|
+
const planoSha256 = fs.existsSync(plano) ? sha256(fs.readFileSync(plano)) : null;
|
|
71
|
+
const base = {
|
|
72
|
+
contrato: exports.CONTRATO_DO_RECIBO_DE_PROVA,
|
|
73
|
+
head,
|
|
74
|
+
claimsSha256: sha256(JSON.stringify(material.claims)),
|
|
75
|
+
planoSha256,
|
|
76
|
+
dependenciasExternas: material.dependenciasExternas,
|
|
77
|
+
};
|
|
78
|
+
return { ...base, sha256: sha256(JSON.stringify(base)) };
|
|
79
|
+
}
|
|
80
|
+
/** Recibo completo e igual; forma legada, adulterada ou sem plano volta a executar. */
|
|
81
|
+
function mesmaChaveDoRecibo(recibo, atual) {
|
|
82
|
+
return recibo?.contrato === exports.CONTRATO_DO_RECIBO_DE_PROVA && recibo.planoSha256 !== null &&
|
|
83
|
+
recibo.head === atual.head && recibo.claimsSha256 === atual.claimsSha256 &&
|
|
84
|
+
recibo.planoSha256 === atual.planoSha256 &&
|
|
85
|
+
JSON.stringify(recibo.dependenciasExternas) === JSON.stringify(atual.dependenciasExternas) &&
|
|
86
|
+
recibo.sha256 === atual.sha256;
|
|
87
|
+
}
|
package/dist/retry.js
CHANGED
|
@@ -160,6 +160,12 @@ exports.POLITICA_DE_RETRY = {
|
|
|
160
160
|
automatica: true,
|
|
161
161
|
...TEXTOS_DA_POLITICA['claims.unverifiable'],
|
|
162
162
|
},
|
|
163
|
+
'claims.retirada-sem-substituta': {
|
|
164
|
+
motivo: 'claims.retirada-sem-substituta',
|
|
165
|
+
acao: 'escalar-humano',
|
|
166
|
+
automatica: false,
|
|
167
|
+
...TEXTOS_DA_POLITICA['claims.retirada-sem-substituta'],
|
|
168
|
+
},
|
|
163
169
|
'policy.violation': {
|
|
164
170
|
motivo: 'policy.violation',
|
|
165
171
|
acao: 'escalar-humano',
|
|
@@ -38,6 +38,7 @@ exports.defaultProbe = defaultProbe;
|
|
|
38
38
|
exports.chooseExecutor = chooseExecutor;
|
|
39
39
|
exports.nativeVersionOf = nativeVersionOf;
|
|
40
40
|
exports.defaultsDir = defaultsDir;
|
|
41
|
+
exports.opcoesDoPrazo = opcoesDoPrazo;
|
|
41
42
|
exports.argumentosDeCpuDoDocker = argumentosDeCpuDoDocker;
|
|
42
43
|
exports.expand = expand;
|
|
43
44
|
exports.ensureImage = ensureImage;
|
|
@@ -109,6 +110,10 @@ function defaultsDir() {
|
|
|
109
110
|
exports.CONFIG_FILES = { gitleaks: 'gitleaks.toml', eslint: 'eslint.config.mjs', ruff: 'ruff.toml', 'golangci-lint': '.golangci.yml' };
|
|
110
111
|
const CONTAINER = { src: '/src', out: '/out', config: '/config' };
|
|
111
112
|
const MAX_BUFFER = 512 * 1024 * 1024;
|
|
113
|
+
/** `spawnSync` rejects Infinity; an unbounded fixture omits the inner timeout and remains bounded by the outer round. */
|
|
114
|
+
function opcoesDoPrazo(timeoutMs) {
|
|
115
|
+
return Number.isFinite(timeoutMs) ? { timeout: timeoutMs } : {};
|
|
116
|
+
}
|
|
112
117
|
/** A cota so existe no grupo Agile; sem a variavel, o Classic continua com o argv de sempre. */
|
|
113
118
|
function argumentosDeCpuDoDocker(ambiente = process.env) {
|
|
114
119
|
const limite = Number(ambiente[agendador_cpu_1.ENV_CPUS_DOCKER]);
|
|
@@ -131,7 +136,7 @@ function ensureImage(image, timeoutMs) {
|
|
|
131
136
|
const present = (0, node_child_process_1.spawnSync)('docker', ['image', 'inspect', image], { stdio: 'ignore', timeout: Math.min(PROBE_TIMEOUT_MS, timeoutMs) });
|
|
132
137
|
if (!present.error && present.status === 0)
|
|
133
138
|
return true;
|
|
134
|
-
const pull = (0, node_child_process_1.spawnSync)('docker', ['pull', '--quiet', image], { stdio: 'ignore',
|
|
139
|
+
const pull = (0, node_child_process_1.spawnSync)('docker', ['pull', '--quiet', image], { stdio: 'ignore', ...opcoesDoPrazo(timeoutMs), killSignal: 'SIGKILL' });
|
|
135
140
|
return !pull.error && pull.status === 0;
|
|
136
141
|
}
|
|
137
142
|
/**
|
|
@@ -162,7 +167,7 @@ function runDocker(inv) {
|
|
|
162
167
|
...inv.argv.slice(1).map(a => expand(a, values))];
|
|
163
168
|
(0, agendador_cpu_1.registrarContainerDaLane)(name);
|
|
164
169
|
inv.guard?.add('containers', name);
|
|
165
|
-
const r = (0, node_child_process_1.spawnSync)('docker', args, { encoding: 'utf8',
|
|
170
|
+
const r = (0, node_child_process_1.spawnSync)('docker', args, { encoding: 'utf8', ...opcoesDoPrazo(inv.timeoutMs), killSignal: 'SIGKILL', maxBuffer: MAX_BUFFER, env: process.env });
|
|
166
171
|
const timedOut = r.error?.code === 'ETIMEDOUT';
|
|
167
172
|
if (timedOut || r.error)
|
|
168
173
|
(0, node_child_process_1.spawnSync)('docker', ['rm', '-f', name], { stdio: 'ignore', timeout: PROBE_TIMEOUT_MS });
|
|
@@ -186,7 +191,8 @@ function runNative(inv) {
|
|
|
186
191
|
const pgidFile = inv.guard?.pgidFile() ?? path.join(inv.outHost, '.native.pgid');
|
|
187
192
|
const marker = `${pgidFile}${guard_1.LAUNCH_TIMEOUT_SUFFIX}`;
|
|
188
193
|
try {
|
|
189
|
-
const
|
|
194
|
+
const prazoDoLauncher = Number.isFinite(inv.timeoutMs) ? inv.timeoutMs + 10000 : inv.timeoutMs;
|
|
195
|
+
const r = (0, node_child_process_1.spawnSync)(process.execPath, (0, guard_1.launcherArgs)(pgidFile, inv.timeoutMs, bin, rest), { cwd: inv.srcHost, encoding: 'utf8', ...opcoesDoPrazo(prazoDoLauncher), killSignal: 'SIGKILL', maxBuffer: MAX_BUFFER, env });
|
|
190
196
|
const timedOut = fs.existsSync(marker) || r.error?.code === 'ETIMEDOUT';
|
|
191
197
|
return { status: r.status, timedOut, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
|
|
192
198
|
}
|