@orkastery/cli 0.6.3 → 0.6.5
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/openclaw/openclaw.plugin.json +1 -1
- package/adapters/openclaw/package.json +1 -1
- package/dist/adapters/codex-controller-sensor.js +21 -2
- package/dist/adapters/codex-events.js +15 -6
- package/dist/adapters/grok-events.js +43 -2
- package/dist/adapters/grok.js +28 -5
- package/dist/agendador-cpu.js +120 -30
- package/dist/cenarios-sensores.js +5 -4
- package/dist/check-agil.js +87 -11
- package/dist/check-paralelo.js +385 -13
- package/dist/check-selecao.js +149 -0
- package/dist/codex-task-complete.js +95 -0
- package/dist/junit.js +546 -0
- package/dist/locale-verify.js +37 -0
- package/dist/manifest.js +237 -13
- package/dist/retry.js +35 -0
- package/dist/security-scan/agil.js +28 -12
- package/dist/security-scan/executor.js +1 -0
- package/dist/security-scan/incremental.js +289 -0
- package/dist/security-scan/trabalhador.js +53 -5
- package/dist/session-watcher-claude.js +38 -22
- package/dist/session-watcher-grok.js +10 -0
- package/dist/session-watcher.js +47 -18
- package/dist/ship.js +9 -3
- package/dist/verify.js +215 -41
- package/package.json +1 -1
package/dist/session-watcher.js
CHANGED
|
@@ -62,6 +62,7 @@ const session_watcher_grok_1 = require("./session-watcher-grok");
|
|
|
62
62
|
const conta_esgotada_1 = require("./conta-esgotada");
|
|
63
63
|
const trabalho_thread_1 = require("./trabalho-thread");
|
|
64
64
|
const pedido_conducao_1 = require("./pedido-conducao");
|
|
65
|
+
const codex_task_complete_1 = require("./codex-task-complete");
|
|
65
66
|
/** O gate estreito da própria sessão vence diagnósticos genéricos do watcher. */
|
|
66
67
|
function pedidoDaConducao(eventos, sessionId, despachoEm) {
|
|
67
68
|
const evento = eventos.filter(e => e.tipo === 'gate_blocked' && e.origem === 'mcp.request_conduction' &&
|
|
@@ -389,6 +390,16 @@ function observarSessao(carregado, sessionId, opcoes = {}) {
|
|
|
389
390
|
return observarSessaoResolvida(carregado, sessionId, resolvida, opcoes);
|
|
390
391
|
}
|
|
391
392
|
catch (e) {
|
|
393
|
+
if (e.code === 'SESSION_STATE_SPLIT' && threadId) {
|
|
394
|
+
const thread = (0, thread_1.lerThread)(carregado.raiz, threadId);
|
|
395
|
+
const registrada = thread.sessoes.find(s => s.sessionId === sessionId);
|
|
396
|
+
if (registrada) {
|
|
397
|
+
const sessao = (0, session_events_1.exigirSessaoDespachada)(registrada, sessionId);
|
|
398
|
+
const prova = (0, codex_task_complete_1.taskCompleteFixadoDaSessao)(carregado.raiz, thread, sessao, (0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, threadId)), opcoes.agoraMs ?? Date.now());
|
|
399
|
+
if (prova)
|
|
400
|
+
return observarSessaoResolvida(carregado, sessionId, { thread, sessao }, { ...opcoes, taskCompleteFixado: prova });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
392
403
|
if (threadId)
|
|
393
404
|
tentarRegistrarErroWatcher(carregado.raiz, threadId, sessionId, e);
|
|
394
405
|
throw e;
|
|
@@ -542,7 +553,8 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
542
553
|
return desfazer();
|
|
543
554
|
if (sessao.runtime === 'claude-bg') {
|
|
544
555
|
const r = comLockWatcher(pasta, () => (0, session_watcher_claude_1.observarClaudeSobLock)({ raiz: carregado.raiz,
|
|
545
|
-
thread, sessao, dir, pasta, chave, agoraMs: now, limiteMs: exports.LIMITE_MORTE_MS, consulta: opcoes.consultaClaude,
|
|
556
|
+
thread, sessao, dir, pasta, chave, agoraMs: now, limiteMs: exports.LIMITE_MORTE_MS, consulta: opcoes.consultaClaude,
|
|
557
|
+
tela: opcoes.telaClaude, carregado })) ?? { ...base, ocupado: true };
|
|
546
558
|
return (0, ledger_1.threadPresente)(dir) ? r : desfazer();
|
|
547
559
|
}
|
|
548
560
|
// RM-067 (F2): o grok tem observador próprio (stream, recibo do supervisor e pasta da sessão), no mesmo lock.
|
|
@@ -565,6 +577,7 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
565
577
|
const perfil = (0, runtime_profiles_1.perfilDoRegistro)(eventos, sessao);
|
|
566
578
|
// Fonte do controller validada ANTES de ler rollout ou escrever cursor.
|
|
567
579
|
let fonteControlador = null, snapshot = null;
|
|
580
|
+
let taskCompleteFixado = opcoes.taskCompleteFixado ?? null;
|
|
568
581
|
let cwdDespacho;
|
|
569
582
|
if (registro?.controlador) {
|
|
570
583
|
const despacho = eventos.filter(e => e.tipo === 'phase_dispatch' && e.sessionId === sessionId).at(-1);
|
|
@@ -580,7 +593,16 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
580
593
|
vinculo: { thread: thread.id, fase: sessao.fase, promptSha256: sessao.promptSha256 }
|
|
581
594
|
});
|
|
582
595
|
// Relógio injetado vale como está; o real é lido pelo sensor depois do state.json.
|
|
583
|
-
|
|
596
|
+
try {
|
|
597
|
+
snapshot = (0, codex_controller_sensor_1.lerSnapshotController)(fonteControlador, opcoes.agoraMs === undefined ? {} : { agoraMs: now });
|
|
598
|
+
}
|
|
599
|
+
catch (e) {
|
|
600
|
+
// A varredura integral e excepcional: no fluxo saudável o cursor incremental
|
|
601
|
+
// reconhece task_complete sem reler todo o rollout a cada polling.
|
|
602
|
+
taskCompleteFixado ??= (0, codex_task_complete_1.taskCompleteFixadoDaFonte)(fonteControlador, now);
|
|
603
|
+
if (!taskCompleteFixado)
|
|
604
|
+
throw e;
|
|
605
|
+
}
|
|
584
606
|
}
|
|
585
607
|
const file = path.join(pasta, 'cursor.json');
|
|
586
608
|
const cursor = lerJson(file) ?? { schema: 'ork.session-cursor/v1', sessionId,
|
|
@@ -590,7 +612,7 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
590
612
|
// Cursor anterior media bytes, nao progresso: migracao conservadora desde o despacho.
|
|
591
613
|
cursor.progressoEm ??= Date.parse(sessao.despachadaEm);
|
|
592
614
|
// Transporte do controller não admite descoberta nem override de rollout.
|
|
593
|
-
const fontes = { stream: registro?.logPath, rollout:
|
|
615
|
+
const fontes = { stream: registro?.logPath, rollout: fonteControlador ? fonteControlador.rollout
|
|
594
616
|
: opcoes.rollout === undefined ? (0, codex_1.acharRollout)(sessionId, 3, (0, codex_1.casaDoCodex)(perfil)) : opcoes.rollout };
|
|
595
617
|
let bytesLidos = 0, temMais = false, cresceu = false;
|
|
596
618
|
for (const [nome, fonte] of Object.entries(fontes)) {
|
|
@@ -673,7 +695,10 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
673
695
|
return tempo || (y.numeroTurno ?? 0) - (x.numeroTurno ?? 0) ||
|
|
674
696
|
ordem[x.classificacao] - ordem[y.classificacao] || a.nome.localeCompare(b.nome);
|
|
675
697
|
});
|
|
676
|
-
|
|
698
|
+
const taskCompleteDoCursor = fonteControlador ? terminais.find(({ nome, terminal: atual }) => nome === 'rollout' && atual.fonte === 'rollout.task_complete')?.terminal : undefined;
|
|
699
|
+
let terminal = taskCompleteFixado?.terminal ?? taskCompleteDoCursor ?? terminais[0]?.terminal;
|
|
700
|
+
const taskCompleteAutenticado = terminal !== undefined &&
|
|
701
|
+
(terminal === taskCompleteFixado?.terminal || terminal === taskCompleteDoCursor);
|
|
677
702
|
const fontesAtuais = Object.values(cursor.fontes);
|
|
678
703
|
const aberto = fontesAtuais.some(f => {
|
|
679
704
|
if (!f.parser.turnoAberto)
|
|
@@ -700,22 +725,23 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
700
725
|
const invalido = fontesAtuais.some(f => f.parser.invalido);
|
|
701
726
|
// Conclusão nativa é medida em todo terminal, independente da política de retry:
|
|
702
727
|
// bloqueio sem retry preserva o motivo, mas não prova que o turno do runtime terminou.
|
|
703
|
-
const provaNativa = snapshot && terminal
|
|
728
|
+
const provaNativa = taskCompleteAutenticado ? null : snapshot && terminal
|
|
704
729
|
? semProvaNativa(snapshot, terminal, terminais[0]?.nome, fechamento, sessionId, cwdDespacho)
|
|
705
730
|
: 'terminal nativo do controller ausente';
|
|
706
731
|
// Parecer negativo também exige conclusão nativa inteira: texto claims.failed de
|
|
707
732
|
// turno interrompido não pode virar rejeição autenticada de um objetivo.
|
|
708
|
-
const semProva = snapshot && terminal && terminal.classificacao !== 'human.pending' && !bloqueioPreservado(terminal)
|
|
733
|
+
const semProva = !taskCompleteAutenticado && snapshot && terminal && terminal.classificacao !== 'human.pending' && !bloqueioPreservado(terminal)
|
|
709
734
|
? provaNativa : null;
|
|
710
735
|
const descorrelacionado = !!semProva;
|
|
711
|
-
const
|
|
736
|
+
const observacaoInvalida = !taskCompleteAutenticado && (invalido || aberto || descorrelacionado);
|
|
737
|
+
const incompleto = !taskCompleteAutenticado && (semCloseNoLimite && (!!terminal || estado !== 'ausente' || aberto || parcial || invalido) || !backlog && (((parcial || aberto || invalido || descorrelacionado || !terminal) && !!fechamento) ||
|
|
712
738
|
(estavel && (parcial || (aberto && estado === 'ausente') ||
|
|
713
|
-
(supervisionado && estado === 'desconhecido'))));
|
|
739
|
+
(supervisionado && estado === 'desconhecido')))));
|
|
714
740
|
const morte = estado === 'ausente' && estavel && !temMais;
|
|
715
741
|
// Fechamento supervisionado precisa existir antes de associar o código de saída ao turno.
|
|
716
|
-
const podeTerminar = !esperaHumana && (incompleto || (!temMais && !aberto &&
|
|
742
|
+
const podeTerminar = taskCompleteAutenticado || !esperaHumana && (incompleto || (!temMais && !aberto &&
|
|
717
743
|
((terminal && (fechamento || !supervisionado)) || morte)));
|
|
718
|
-
const conta = falhaDeContaDoTerminal(terminal, !invalido && !aberto, snapshot, now);
|
|
744
|
+
const conta = falhaDeContaDoTerminal(terminal, taskCompleteAutenticado || !invalido && !aberto, snapshot, now);
|
|
719
745
|
(0, codex_runner_1.gravarAtomico)(file, cursor);
|
|
720
746
|
return (0, session_events_1.comLockDeSessao)(dir, () => {
|
|
721
747
|
const atuais = (0, ledger_1.lerLedger)(dir);
|
|
@@ -735,9 +761,9 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
735
761
|
const pedido = pedidoDaConducao(atuais, sessionId, sessao.despachadaEm);
|
|
736
762
|
const semTerminal = !terminal;
|
|
737
763
|
// Fato registrado para a autoridade de revisão: `null` só com terminal nativo correlacionado.
|
|
738
|
-
const conclusaoNativa = incompleto ||
|
|
764
|
+
const conclusaoNativa = incompleto || observacaoInvalida
|
|
739
765
|
? provaNativa ?? 'observação incompleta ou inválida' : provaNativa;
|
|
740
|
-
if (incompleto ||
|
|
766
|
+
if (incompleto || observacaoInvalida)
|
|
741
767
|
terminal = { classificacao: 'gate_blocked', motivo: 'runtime.unavailable',
|
|
742
768
|
timestamp: new Date(now).toISOString(), turnId: null, fonte: semProva ?? 'observação incompleta ou inválida',
|
|
743
769
|
tokens: new codex_events_1.ParserCodex().estado.tokens, duracaoMs: null };
|
|
@@ -745,12 +771,12 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
745
771
|
terminal = { classificacao: 'gate_blocked', motivo: 'runtime.silencio',
|
|
746
772
|
timestamp: new Date(now).toISOString(), turnId: null, fonte: 'processo ausente e arquivos estáveis',
|
|
747
773
|
tokens: new codex_events_1.ParserCodex().estado.tokens, duracaoMs: null };
|
|
748
|
-
if (pedido && (terminal.classificacao === 'fase_concluida' ||
|
|
774
|
+
if (pedido && (taskCompleteAutenticado || terminal.classificacao === 'fase_concluida' ||
|
|
749
775
|
terminal.classificacao === 'gate_blocked' && ['runtime.unavailable', 'runtime.silencio'].includes(terminal.motivo ?? ''))) {
|
|
750
776
|
terminal = { ...terminal, classificacao: 'gate_blocked', motivo: pedido.motivo,
|
|
751
777
|
fonte: `mcp.request_conduction: ${pedido.detalhe}` };
|
|
752
778
|
}
|
|
753
|
-
if (fechamento && (fechamento.exitCode !== 0 || fechamento.signal || fechamento.erro) &&
|
|
779
|
+
if (!taskCompleteAutenticado && fechamento && (fechamento.exitCode !== 0 || fechamento.signal || fechamento.erro) &&
|
|
754
780
|
terminal.classificacao !== 'human.pending' && !bloqueioPreservado(terminal)) {
|
|
755
781
|
terminal = { ...terminal, classificacao: 'gate_blocked', motivo: 'runtime.unavailable' };
|
|
756
782
|
}
|
|
@@ -761,16 +787,19 @@ function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registr
|
|
|
761
787
|
fonte: `${conta.fonte}: ${conta.falha.motivo} (${conta.falha.trecho})` };
|
|
762
788
|
const respostaFinal = terminal.respostaFinal
|
|
763
789
|
? (0, trabalho_thread_1.gravarRespostaFinalDaSessao)(carregado.raiz, thread.id, sessionId, terminal.respostaFinal) : null;
|
|
790
|
+
const taskCompleteBloqueado = taskCompleteAutenticado && terminal.classificacao !== 'fase_concluida';
|
|
764
791
|
const dados = { fase: sessao.fase, sessionId, despachoEm: sessao.despachadaEm, sensorResultId: resultadoId,
|
|
765
792
|
classificacao: terminal.classificacao, motivo: terminal.motivo, runtime: 'codex', fonte: terminal.fonte,
|
|
766
|
-
fonteVencedora: pedido
|
|
793
|
+
fonteVencedora: pedido ? null : taskCompleteAutenticado ? 'rollout'
|
|
794
|
+
: incompleto || invalido || aberto || descorrelacionado ? null : terminais[0]?.nome ?? null,
|
|
767
795
|
turnId: terminal.turnId, numeroTurno: terminal.numeroTurno ?? null,
|
|
768
796
|
tokens: terminal.tokens, exitCode: fechamento?.exitCode ?? null, exitCodeFonte: fechamento?.fonte ?? 'unavailable',
|
|
769
797
|
signal: fechamento?.signal ?? null, duracaoMs: fechamento?.duracaoMs ?? terminal.duracaoMs,
|
|
770
798
|
duracaoFonte: fechamento?.fonte ?? (terminal.duracaoMs === null ? 'unavailable' : terminal.fonte),
|
|
771
|
-
ok: terminal.classificacao === 'fase_concluida' && fechamento?.exitCode === 0,
|
|
772
|
-
conclusaoNativa: conclusaoNativa === null,
|
|
773
|
-
conclusaoNativaAusente:
|
|
799
|
+
ok: terminal.classificacao === 'fase_concluida' && (taskCompleteAutenticado || fechamento?.exitCode === 0),
|
|
800
|
+
conclusaoNativa: conclusaoNativa === null && !taskCompleteBloqueado,
|
|
801
|
+
conclusaoNativaAusente: taskCompleteBloqueado
|
|
802
|
+
? 'task_complete encerrou o turno com resultado bloqueado' : conclusaoNativa,
|
|
774
803
|
estado: terminal.classificacao === 'fase_concluida' ? 'concluida' : 'bloqueada',
|
|
775
804
|
observadoEm: terminal.timestamp, gate: 'phase.dispatch', origem: 'sessions.watch',
|
|
776
805
|
morteLatenciaMs: morte ? now - cursor.progressoEm : null, ...(perfil ? { perfil } : {}),
|
package/dist/ship.js
CHANGED
|
@@ -51,6 +51,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
51
51
|
})();
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
53
|
exports.MODOS_QUE_AUTORIZAM_PUSH = void 0;
|
|
54
|
+
exports.verificacaoCompletaParaShip = verificacaoCompletaParaShip;
|
|
54
55
|
exports.commitQueIncorporou = commitQueIncorporou;
|
|
55
56
|
exports.autorizacaoDePush = autorizacaoDePush;
|
|
56
57
|
exports.arvoreComBranch = arvoreComBranch;
|
|
@@ -88,6 +89,10 @@ const mcp_ship_transporte_1 = require("./mcp-ship-transporte");
|
|
|
88
89
|
const branch_de_estado_1 = require("./branch-de-estado");
|
|
89
90
|
const locale_1 = require("./locale");
|
|
90
91
|
const noctum_guarda_1 = require("./noctum-guarda");
|
|
92
|
+
/** RM-081 F3: `ok` nunca basta quando a rodada nao cobriu a suite inteira. */
|
|
93
|
+
function verificacaoCompletaParaShip(verificacao) {
|
|
94
|
+
return verificacao.ok && !verificacao.parcial;
|
|
95
|
+
}
|
|
91
96
|
/**
|
|
92
97
|
* RM-037 (fatia 5, A1): o commit de primeiro pai da base que incorporou o `shaDe`: o merge que trouxe a branch, ou
|
|
93
98
|
* o proprio `shaDe` quando a base avancou por fast-forward ate ele. Com a branch ja incorporada, a ponta da base e
|
|
@@ -556,9 +561,10 @@ function ship(carregado, threadId, opcoes) {
|
|
|
556
561
|
const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify,
|
|
557
562
|
conducao: { filaPesada: { ...opcoes.avisoDaFilaPesada, esperarMs: opcoes.esperarFilaPesadaMs } } });
|
|
558
563
|
r.verificacao = verificacao;
|
|
559
|
-
if (!verificacao
|
|
560
|
-
const motivo = verificacao.
|
|
561
|
-
|
|
564
|
+
if (!verificacaoCompletaParaShip(verificacao)) {
|
|
565
|
+
const motivo = (verificacao.parcial ? 'verify.failed'
|
|
566
|
+
: verificacao.motivos.find((m) => m !== 'claims.unverifiable'));
|
|
567
|
+
return bloquear(motivo, (0, locale_1.textoDoCatalogo)((m) => m.ship.verificacaoReprovou(verificacao.commit, verificacao.parcial ? 'verify.parcial' : verificacao.motivos.join(', '))), (0, locale_1.textoDoCatalogo)((m) => m.ship.rodeVerify(threadId)));
|
|
562
568
|
}
|
|
563
569
|
// Referencias locais, resolvidas antes de tomar o lease.
|
|
564
570
|
const shaDe = shaDaRef(raiz, `refs/heads/${de}`);
|