@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
|
@@ -19,6 +19,10 @@ ork phase list <thread> # o que ja aconteceu, com evidencia
|
|
|
19
19
|
## Regras desta fase
|
|
20
20
|
|
|
21
21
|
- **CHECK nao corrige.** Achado vira tarefa de GO, com commit proprio.
|
|
22
|
+
- Claim nova afirma o comportamento correto e passa depois da correcao; a reproducao do defeito
|
|
23
|
+
fica como comando no parecer e nunca vira claim.
|
|
24
|
+
- Achado sem claim usa `- A<n> [blocker|warning|suggestion] path:line - description`; a linha
|
|
25
|
+
seguinte pode usar `reproduce: \`command\``. Os tokens do formato sao estaveis nas duas linguas.
|
|
22
26
|
- Eixo sem achado sai com "nenhum" explicito.
|
|
23
27
|
- Zero bloqueadores de seguranca e condicao dura, em qualquer modo.
|
|
24
28
|
- Correcao tipo B devolve ao GO e o CHECK seguinte e reexecucao completa.
|
|
@@ -126,7 +126,7 @@ export function soLeitura(chamadas: readonly Chamada[]): boolean {
|
|
|
126
126
|
|
|
127
127
|
/** O lote registrou, retirou ou mudou claim: a lista do nucleo precisa ser relida. */
|
|
128
128
|
export function mexeuNasClaims(chamadas: readonly Chamada[]): boolean {
|
|
129
|
-
return chamadas.some(c => nomeDa(c)
|
|
129
|
+
return chamadas.some(c => ['mcp__orkastery__ork_claim_add', 'mcp__orkastery__ork_claim_withdraw'].includes(nomeDa(c))
|
|
130
130
|
|| (nomeDa(c) === 'Bash' && CLI_DE_CLAIMS.test(String((c.tool_input as { command?: unknown } | null)?.command ?? ''))))
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -7,6 +7,7 @@ export const FRASE_DO_MOTIVO: Readonly<Record<string, string>> = {
|
|
|
7
7
|
'artifact.missing': 'falta um artefato que a fase exige',
|
|
8
8
|
'claims.failed': 'uma claim reprovou no HEAD',
|
|
9
9
|
'claims.unverifiable': 'há claim sem comando de verificação',
|
|
10
|
+
'claims.retirada-sem-substituta': 'uma retirada sem substituta espera sua decisão',
|
|
10
11
|
'concurrency.lease-indeterminado': 'não foi possível provar se a vaga está livre',
|
|
11
12
|
'conducao.acao-necessaria': 'a condução precisa executar uma ação',
|
|
12
13
|
'policy.violation': 'uma policy de bloqueio foi violada',
|
|
@@ -36,7 +37,7 @@ export const FRASE_DO_MOTIVO: Readonly<Record<string, string>> = {
|
|
|
36
37
|
|
|
37
38
|
/** Os motivos que so o dono resolve (D6): a linha fica em "espera voce", nao em "parada". */
|
|
38
39
|
export const MOTIVOS_DO_DONO: readonly string[] = ['human.pending', 'runtime.workspace-untrusted', 'runtime.consent-pending',
|
|
39
|
-
'runtime.auth-missing']
|
|
40
|
+
'runtime.auth-missing', 'claims.retirada-sem-substituta']
|
|
40
41
|
|
|
41
42
|
/** A frase do motivo; motivo que a tabela nao conhece aparece cru, nunca some. */
|
|
42
43
|
export function fraseDoMotivo(motivo: string): string {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "orkastery",
|
|
3
3
|
"name": "Orkastery",
|
|
4
4
|
"description": "Conducao de looping threads em 6 fases pelo nucleo `ork`, exposta ao OpenClaw como tools `ork_*`. Zero regra de negocio no host: cada tool e uma chamada de CLI. Toda tool de projeto aceita projeto (nome do projeto pedido); o cwd do gateway nunca escolhe o projeto. O status do roadmap vem de ork_network_roadmap; as maquinas da pessoa, de ork_network_status (sem projeto).",
|
|
5
|
-
"version": "0.6.
|
|
5
|
+
"version": "0.6.7",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkastery/openclaw-plugin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "Plugin Orkastery para OpenClaw: 32 tools ork_* que traduzem intencao em chamada de CLI do nucleo `ork`. Zero regra de negocio no host.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": true,
|
|
@@ -19,6 +19,10 @@ ork phase list <thread> # o que ja aconteceu, com evidencia
|
|
|
19
19
|
## Rules for this phase
|
|
20
20
|
|
|
21
21
|
- **CHECK does not fix.** A finding becomes a GO task, with its own commit.
|
|
22
|
+
- A new claim states the correct behavior and passes after the fix; defect reproduction stays as
|
|
23
|
+
a command in the report and never becomes a claim.
|
|
24
|
+
- A finding without a claim uses `- A<n> [blocker|warning|suggestion] path:line - description`;
|
|
25
|
+
the following line may use `reproduce: \`command\``.
|
|
22
26
|
- An axis without findings comes out with an explicit "none".
|
|
23
27
|
- Zero security blockers is a hard condition, in any mode.
|
|
24
28
|
- A type B fix goes back to GO, and the next CHECK is a full re-run.
|
|
@@ -42,6 +42,20 @@ verdict up to a human in any mode, including `#Auto`.
|
|
|
42
42
|
The catalog's four reviewers come in here: `code-reviewer`, `security-auditor`, `test-engineer`
|
|
43
43
|
and `web-performance-auditor`. Each one runs in its own scope and returns categorized findings.
|
|
44
44
|
|
|
45
|
+
## Claims and defect reproductions
|
|
46
|
+
|
|
47
|
+
- A claim created during CHECK states the expected correct behavior and must pass after the fix.
|
|
48
|
+
It never states that the defect still occurs.
|
|
49
|
+
- The command that reproduces the defect stays only in the report (`docs/check.md`) as finding
|
|
50
|
+
evidence; that command never becomes a claim.
|
|
51
|
+
- A finding without a claim uses a machine-readable line for the correction cycle; the format
|
|
52
|
+
tokens stay the same in both languages:
|
|
53
|
+
|
|
54
|
+
`- A<n> [blocker|warning|suggestion] path:line - description`
|
|
55
|
+
|
|
56
|
+
The following line may record `reproduce: \`command\``. The command remains report evidence,
|
|
57
|
+
not claim verification.
|
|
58
|
+
|
|
45
59
|
## What CHECK delivers
|
|
46
60
|
|
|
47
61
|
1. **Comparison against the baseline**, separating regression from pre-existing debt. Without that
|
|
@@ -115,7 +115,7 @@ exports.CONSULTAS_MCP = [
|
|
|
115
115
|
];
|
|
116
116
|
// RM-037 (defeito 1): a decisao autonoma pelo MCP tem o mesmo grant nos dois runtimes.
|
|
117
117
|
exports.MUTACOES_WORKTREE = [
|
|
118
|
-
'mcp__orkastery__ork_artifact_write', 'mcp__orkastery__ork_claim_add', 'mcp__orkastery__ork_decision_record',
|
|
118
|
+
'mcp__orkastery__ork_artifact_write', 'mcp__orkastery__ork_claim_add', 'mcp__orkastery__ork_claim_withdraw', 'mcp__orkastery__ork_decision_record',
|
|
119
119
|
'mcp__orkastery__ork_request_conduction', 'mcp__orkastery__ork_git_commit', 'mcp__orkastery__ork_verify',
|
|
120
120
|
'mcp__orkastery__ork_ship',
|
|
121
121
|
];
|
package/dist/agendador-cpu.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AMOSTRAS_DA_SONDA = exports.JANELA_DA_SONDA_MS = exports.LIMIAR_STEAL_DO_AGENDADOR_PCT = exports.MINIMO_ESTRUTURAL_DO_GRUPO = exports.RESERVA_DO_GRUPO = exports.ENV_CONTAINERS_DA_LANE = exports.ENV_CPUS_DOCKER = exports.ENV_SINAL_DA_RESERVA = exports.ENV_CPUS_DA_LANE_APOS_RESERVA = exports.ENV_CPUS_DA_LANE_APOS_VARREDURA = exports.ENV_WORKERS = exports.ENV_CPUS_DA_LANE = void 0;
|
|
4
|
+
exports.registrarCotaDockerDaLane = registrarCotaDockerDaLane;
|
|
4
5
|
exports.registrarContainerDaLane = registrarContainerDaLane;
|
|
5
6
|
exports.workersDaReserva = workersDaReserva;
|
|
6
7
|
exports.cargaDoProcLoadavg = cargaDoProcLoadavg;
|
|
@@ -36,6 +37,16 @@ exports.MINIMO_ESTRUTURAL_DO_GRUPO = exports.RESERVA_DO_GRUPO + 1;
|
|
|
36
37
|
exports.LIMIAR_STEAL_DO_AGENDADOR_PCT = 10;
|
|
37
38
|
exports.JANELA_DA_SONDA_MS = 250;
|
|
38
39
|
exports.AMOSTRAS_DA_SONDA = 5;
|
|
40
|
+
/** O adaptador registra a decisão real do runtime no mesmo canal privado usado pela sonda dos contêineres. */
|
|
41
|
+
function registrarCotaDockerDaLane(evidencia, ambiente = process.env) {
|
|
42
|
+
const arquivo = ambiente[exports.ENV_CONTAINERS_DA_LANE];
|
|
43
|
+
if (!arquivo)
|
|
44
|
+
return;
|
|
45
|
+
try {
|
|
46
|
+
(0, node_fs_1.appendFileSync)(arquivo, JSON.stringify({ tipo: 'cota-docker', ...evidencia, em: new Date().toISOString() }) + '\n', { mode: 0o600 });
|
|
47
|
+
}
|
|
48
|
+
catch { /* a falta da evidência impede afirmar aplicação, mas não derruba a fixture */ }
|
|
49
|
+
}
|
|
39
50
|
/** Registra o container antes do `docker run`; falha de evidencia nunca impede a ferramenta de rodar. */
|
|
40
51
|
function registrarContainerDaLane(nome, ambiente = process.env) {
|
|
41
52
|
const arquivo = ambiente[exports.ENV_CONTAINERS_DA_LANE];
|
|
@@ -103,7 +114,7 @@ async function medirCpuDoGrupo(janelaMs = exports.JANELA_DA_SONDA_MS) {
|
|
|
103
114
|
return resumirMedicaoCpuDoGrupo(cargas, steals);
|
|
104
115
|
}
|
|
105
116
|
/** O plano unico que alimenta concorrencia das lanes, varredura e `docker run --cpus`. */
|
|
106
|
-
function planejarCpuDoGrupo(cpusInformadas, medicao) {
|
|
117
|
+
function planejarCpuDoGrupo(cpusInformadas, medicao, carga = {}) {
|
|
107
118
|
const cpus = cpusValidas(cpusInformadas);
|
|
108
119
|
const steal = Math.min(100, Math.max(0, medicao.stealPct ?? 0));
|
|
109
120
|
// So o steal desconta capacidade. A carga de um minuto do /proc/loadavg inclui o build do proprio verify e a rodada
|
|
@@ -130,6 +141,13 @@ function planejarCpuDoGrupo(cpusInformadas, medicao) {
|
|
|
130
141
|
? Math.max(1, Math.min(capacidadeEfetiva - 1, Math.ceil(medida)))
|
|
131
142
|
: ferramentas;
|
|
132
143
|
const integracaoEmParalelo = !saturado && medidaCompativel && capacidadeEfetiva - fatia - cpusIntegracao >= 1;
|
|
144
|
+
const cpusIntegracaoEmUso = integracaoEmParalelo ? cpusIntegracao : fatia;
|
|
145
|
+
const cadeiasDeClaims = Math.max(0, Math.floor(carga.cadeiasDeClaims ?? 0));
|
|
146
|
+
const hermeticaSemClaims = saturado ? classic
|
|
147
|
+
: Math.max(1, capacidadeEfetiva - fatia - (integracaoEmParalelo ? cpusIntegracao : 0));
|
|
148
|
+
// Cada cadeia recebe uma vaga, mas a lane critica conserva ao menos a mesma parcela. Sem duas vagas livres, a claim
|
|
149
|
+
// continua depois das lanes. A conta e proporcional a capacidade efetiva, nunca a uma maquina especifica.
|
|
150
|
+
const cpusClaims = saturado ? 0 : Math.min(cadeiasDeClaims, Math.floor(hermeticaSemClaims / 2));
|
|
133
151
|
const amostras = (xs, resumo) => `[${(xs?.length ? xs : resumo === null ? [] : [resumo]).join(', ')}]`;
|
|
134
152
|
const evidencia = `carga em /proc/loadavg: amostras ${amostras(medicao.amostrasCarga1, medicao.carga1)}, mediana ` +
|
|
135
153
|
`${medicao.carga1 ?? 'indisponivel'}; steal em /proc/stat: amostras ${amostras(medicao.amostrasStealPct, medicao.stealPct)}, ` +
|
|
@@ -138,7 +156,9 @@ function planejarCpuDoGrupo(cpusInformadas, medicao) {
|
|
|
138
156
|
? `${motivos.join('; ')}; ${evidencia}`
|
|
139
157
|
: `capacidade ${capacidadeEfetiva}/${cpus} CPU(s)${estado === 'degradado' ? ' depois do desconto do steal' : ' inteira'}; ${evidencia}; ` +
|
|
140
158
|
`${fatia} CPU(s) reservadas a varredura; ` +
|
|
141
|
-
(integracaoEmParalelo ? `integracao medida cabe em paralelo com ${cpusIntegracao} CPU(s)`
|
|
159
|
+
(integracaoEmParalelo ? `integracao medida cabe em paralelo com ${cpusIntegracao} CPU(s)`
|
|
160
|
+
: `integracao encadeada inicia depois da varredura com ${cpusIntegracaoEmUso} CPU(s)`) +
|
|
161
|
+
(cadeiasDeClaims ? `; claims com ${cpusClaims} vaga(s) para ${cadeiasDeClaims} cadeia(s)` : '');
|
|
142
162
|
return {
|
|
143
163
|
cpus,
|
|
144
164
|
ordem: saturado ? 'classic' : 'paralela',
|
|
@@ -146,13 +166,16 @@ function planejarCpuDoGrupo(cpusInformadas, medicao) {
|
|
|
146
166
|
capacidadeEfetiva,
|
|
147
167
|
saturado,
|
|
148
168
|
motivo,
|
|
149
|
-
cpusHermetica:
|
|
150
|
-
cpusHermeticaAposVarredura: saturado ? classic : Math.max(1, capacidadeEfetiva -
|
|
169
|
+
cpusHermetica: Math.max(1, hermeticaSemClaims - cpusClaims),
|
|
170
|
+
cpusHermeticaAposVarredura: saturado ? classic : Math.max(1, capacidadeEfetiva - cpusIntegracaoEmUso),
|
|
151
171
|
cpusHermeticaAposReserva: saturado ? classic : capacidadeEfetiva,
|
|
152
172
|
cpusIntegracao,
|
|
173
|
+
cpusClaims,
|
|
174
|
+
cadeiasDeClaims,
|
|
153
175
|
fonteCpusIntegracao: saturado ? 'classic' : medidaCompativel
|
|
154
176
|
? 'medida' : 'conservadora',
|
|
155
177
|
integracaoEmParalelo,
|
|
178
|
+
cpusIntegracaoEmUso,
|
|
156
179
|
cpusDaFatia: fatia,
|
|
157
180
|
ferramentasDaVarredura: ferramentas,
|
|
158
181
|
cpusPorContainer: Math.max(0.01, Math.floor((fatia / ferramentas) * 100) / 100),
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ambiente funcional observado pelos testes das lanes e pelas claims que podem reaproveita-las.
|
|
4
|
+
*
|
|
5
|
+
* A lane atravessa `bash` e `npm` antes de chegar ao `test-lanes.cjs`; a claim candidata parte
|
|
6
|
+
* direto do verify. Esta e a unica regra que retira transporte dessas duas rotas, aplica os
|
|
7
|
+
* acrescimos funcionais da rodada e produz a assinatura comparada pelo reaproveitamento.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ENV_PATH_FUNCIONAL_DA_RODADA = void 0;
|
|
11
|
+
exports.ambienteFuncionalDosTestes = ambienteFuncionalDosTestes;
|
|
12
|
+
exports.transporteDoAmbienteFuncional = transporteDoAmbienteFuncional;
|
|
13
|
+
exports.assinaturaDoAmbiente = assinaturaDoAmbiente;
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
/** O PATH anterior a shell/npm, transportado ate o controlador da lane. */
|
|
16
|
+
exports.ENV_PATH_FUNCIONAL_DA_RODADA = 'ORK_CHECK_PATH_FUNCIONAL_DA_RODADA';
|
|
17
|
+
/**
|
|
18
|
+
* Controles consumidos pela orquestracao, nunca pelos testes. PATH e ORK_CHECK_MODO nao sao
|
|
19
|
+
* ignorados: o primeiro e restaurado e o segundo e removido dos dois ambientes efetivos.
|
|
20
|
+
*/
|
|
21
|
+
const VARIAVEIS_REMOVIDAS = new Set([
|
|
22
|
+
'ORK_CHECK_MODO',
|
|
23
|
+
'ORK_CHECK_RELATORIO',
|
|
24
|
+
'ORK_CHECK_CPUS_DA_LANE',
|
|
25
|
+
'ORK_CHECK_CPUS_DA_LANE_APOS_VARREDURA',
|
|
26
|
+
'ORK_CHECK_CPUS_DA_LANE_APOS_RESERVA',
|
|
27
|
+
'ORK_CHECK_RESERVA_DEVOLVIDA',
|
|
28
|
+
'ORK_CHECK_CONTAINERS_DA_LANE',
|
|
29
|
+
'ORK_CHECK_CPUS_DOCKER',
|
|
30
|
+
'ORK_CHECK_TMPDIR_DA_RODADA',
|
|
31
|
+
'ORK_WORKERS',
|
|
32
|
+
exports.ENV_PATH_FUNCIONAL_DA_RODADA,
|
|
33
|
+
'NODE_TEST_CONTEXT',
|
|
34
|
+
// Shell nao interativo pode executar estes arquivos antes do comando. O verify e a lane nao
|
|
35
|
+
// dependem de inicializacao pessoal do chamador.
|
|
36
|
+
'BASH_ENV',
|
|
37
|
+
'ENV',
|
|
38
|
+
]);
|
|
39
|
+
/** Transporte do npm, do shell e do runner que nao entra no contrato funcional. */
|
|
40
|
+
function variavelIgnorada(nome) {
|
|
41
|
+
return nome.startsWith('npm_') || nome.startsWith('NPM_')
|
|
42
|
+
|| ['COLOR', 'NODE', 'EDITOR', 'NODE_COMPILE_CACHE', 'PWD', 'OLDPWD', 'SHLVL', '_', 'INIT_CWD'].includes(nome);
|
|
43
|
+
}
|
|
44
|
+
/** Monta o ambiente real dos testes, com as mesmas remocoes e acrescimos nas duas rotas. */
|
|
45
|
+
function ambienteFuncionalDosTestes(base, acrescimos = {}) {
|
|
46
|
+
const pathDaRodada = base[exports.ENV_PATH_FUNCIONAL_DA_RODADA];
|
|
47
|
+
const ambiente = Object.fromEntries(Object.entries(base).filter(([nome, valor]) => valor !== undefined && !VARIAVEIS_REMOVIDAS.has(nome) && !variavelIgnorada(nome)));
|
|
48
|
+
if (pathDaRodada !== undefined)
|
|
49
|
+
ambiente.PATH = pathDaRodada;
|
|
50
|
+
for (const [nome, valor] of Object.entries(acrescimos)) {
|
|
51
|
+
if (valor !== undefined)
|
|
52
|
+
ambiente[nome] = valor;
|
|
53
|
+
}
|
|
54
|
+
return ambiente;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Dados que deixam a lane recuperar o ambiente anterior ao shell/npm. BASH_ENV e ENV vazios
|
|
58
|
+
* impedem inicializacao pessoal antes de o script aplicar a regra unica.
|
|
59
|
+
*/
|
|
60
|
+
function transporteDoAmbienteFuncional(base) {
|
|
61
|
+
const pathDaRodada = ambienteFuncionalDosTestes(base).PATH;
|
|
62
|
+
return {
|
|
63
|
+
...(pathDaRodada === undefined ? {} : { [exports.ENV_PATH_FUNCIONAL_DA_RODADA]: pathDaRodada }),
|
|
64
|
+
BASH_ENV: '',
|
|
65
|
+
ENV: '',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Assina exatamente o ambiente funcional montado pela regra unica, inclusive seus acrescimos. */
|
|
69
|
+
function assinaturaDoAmbiente(base, acrescimos = {}) {
|
|
70
|
+
const pares = Object.entries(ambienteFuncionalDosTestes(base, acrescimos)).sort(([a], [b]) => a.localeCompare(b));
|
|
71
|
+
return (0, node_crypto_1.createHash)('sha256').update(JSON.stringify(pares)).digest('hex');
|
|
72
|
+
}
|
|
@@ -47,10 +47,7 @@ const estado_thread_1 = require("./estado-thread");
|
|
|
47
47
|
const catalogo_1 = require("./catalogo");
|
|
48
48
|
const linha = (e) => JSON.stringify(e) + '\n';
|
|
49
49
|
function esperar(teste) {
|
|
50
|
-
const limite = Date.now() + 15000;
|
|
51
50
|
while (!teste()) {
|
|
52
|
-
if (Date.now() >= limite)
|
|
53
|
-
throw new Error('subprocesso do cenário não terminou no prazo de transporte');
|
|
54
51
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
|
|
55
52
|
}
|
|
56
53
|
}
|
|
@@ -71,8 +68,7 @@ exports.CENARIO_SENSORES = {
|
|
|
71
68
|
const hook = path.join(catalogo, 'adapters/claude-code/hooks/ork-sensor.js');
|
|
72
69
|
const cli = (0, catalogo_1.cliDoCatalogo)(catalogo);
|
|
73
70
|
const start = Date.now();
|
|
74
|
-
|
|
75
|
-
const h = (0, node_child_process_1.spawnSync)(process.execPath, [hook], { cwd: wt, encoding: 'utf8', timeout: 15000,
|
|
71
|
+
const h = (0, node_child_process_1.spawnSync)(process.execPath, [hook], { cwd: wt, encoding: 'utf8',
|
|
76
72
|
input: JSON.stringify({ cwd: wt, session_id: 'fixture-claude', hook_event_name: 'PermissionRequest', tool_use_id: 'fixture-tool' }),
|
|
77
73
|
env: { ...process.env, ORK_SENSOR_CLI: cli } });
|
|
78
74
|
if (h.status !== 0 || h.stderr || h.stdout)
|
|
@@ -99,7 +95,7 @@ exports.CENARIO_SENSORES = {
|
|
|
99
95
|
}
|
|
100
96
|
// A identidade vem de um processo realmente executado e encerrado, sem recibo.
|
|
101
97
|
const runner = require.resolve('./adapters/codex-runner');
|
|
102
|
-
const morto = (0, node_child_process_1.spawnSync)(process.execPath, ['-e', `console.log(JSON.stringify(require(process.argv[1]).identidadeProcesso(process.pid)))`, runner], { cwd: wt, encoding: 'utf8'
|
|
98
|
+
const morto = (0, node_child_process_1.spawnSync)(process.execPath, ['-e', `console.log(JSON.stringify(require(process.argv[1]).identidadeProcesso(process.pid)))`, runner], { cwd: wt, encoding: 'utf8' });
|
|
103
99
|
if (morto.status !== 0)
|
|
104
100
|
throw new Error('processo de morte do cenário indisponível');
|
|
105
101
|
const filho = JSON.parse(morto.stdout);
|
|
@@ -117,7 +113,7 @@ exports.CENARIO_SENSORES = {
|
|
|
117
113
|
(0, session_watcher_1.observarSessao)(s.carregado, sid, { rollout: null, agoraMs: inicio + session_watcher_1.LIMITE_MORTE_MS });
|
|
118
114
|
const mortes = (0, ledger_1.lerLedger)(dir).filter(e => e.tipo === 'sessao_morta' && e.sessionId === sid);
|
|
119
115
|
return { tipoProva: 'harness isolado; protocolo Codex sintético', classificacoes, subprocessosComRecibo,
|
|
120
|
-
hookLatenciaMs, carimboLatenciaMs,
|
|
116
|
+
hookLatenciaMs, carimboLatenciaMs, hookRegistrado: !!bloqueio,
|
|
121
117
|
morteAntesDoLimite: antes.concluido, morteLatenciaMs: mortes[0]?.morteLatenciaMs ?? null,
|
|
122
118
|
mortosSemEvento: mortes.length === 1 ? 0 : 1, duplicatas,
|
|
123
119
|
estadoUnico: (0, estado_thread_1.auditarEstado)(s.dir, t.id, wt).nivel === 'ok' &&
|