@orkastery/cli 0.5.1 → 0.5.3
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-master.md +2 -0
- package/adapters/claude-code/commands/master.md +8 -0
- package/adapters/claude-code/commands/ork.md +9 -0
- package/adapters/codex/skills/ork/SKILL.md +18 -3
- package/adapters/hermes/README.md +1 -0
- package/adapters/hermes/bin/ork-network-status.sh +10 -0
- package/adapters/hermes/hermes.plugin.json +1 -0
- package/adapters/hermes/hitl-ingress/__init__.py +2 -2
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +6 -5
- package/adapters/openclaw/README.md +24 -4
- package/adapters/openclaw/dist/hitl-ingress.js +2 -2
- package/adapters/openclaw/dist/index.js +46 -11
- package/adapters/openclaw/openclaw.plugin.json +5 -1
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +2 -2
- package/adapters/openclaw/src/index.ts +49 -11
- package/assets/orkmind_bridge.py +117 -9
- package/dist/adapters/claude-bg.js +39 -5
- package/dist/adapters/codex.js +4 -3
- package/dist/agents-md.js +1 -0
- package/dist/auditrun.js +5 -1
- package/dist/board.js +16 -14
- package/dist/branch-de-estado.js +66 -10
- package/dist/busca-semantica.js +52 -12
- package/dist/canarios-rm057.js +149 -0
- package/dist/canarios.js +2 -0
- package/dist/ci.js +8 -1
- package/dist/claims.js +39 -1
- package/dist/company-brain-context.js +158 -22
- package/dist/docs.js +48 -9
- package/dist/doctor-pulse-cron.js +194 -0
- package/dist/doctor-rede.js +149 -0
- package/dist/doctor.js +89 -9
- package/dist/entrega-pr.js +20 -8
- package/dist/esgotamentos.js +181 -0
- package/dist/experiencia.js +12 -2
- package/dist/fabrica-estado.js +14 -6
- package/dist/fabrica-publicar.js +6 -0
- package/dist/fechamento.js +20 -66
- package/dist/forja.js +31 -7
- package/dist/gates.js +5 -1
- package/dist/hitl-contract.js +59 -4
- package/dist/hitl-curto.js +11 -6
- package/dist/hitl-gates.js +5 -0
- package/dist/hitl-lote.js +5 -2
- package/dist/hitl-resumo.js +9 -0
- package/dist/hitl-tempo-parado.js +201 -0
- package/dist/hitl-texto-livre.js +5 -5
- package/dist/horario.js +27 -0
- package/dist/hosts.js +52 -10
- package/dist/impedimento.js +205 -0
- package/dist/index.js +391 -74
- package/dist/indice-vetorial.js +87 -10
- package/dist/indice.js +3 -1
- package/dist/init.js +17 -0
- package/dist/integracoes-locais.js +2 -0
- package/dist/intelligence-graph-cli.js +91 -8
- package/dist/intelligence-graph-contexto.js +215 -0
- package/dist/intelligence-graph-parsers.js +6 -4
- package/dist/leases.js +664 -87
- package/dist/ledger-stats.js +15 -1
- package/dist/ledger.js +3 -0
- package/dist/licoes.js +1 -0
- package/dist/maestro-runtime.js +4 -1
- package/dist/manifest.js +20 -1
- package/dist/master-nota.js +14 -5
- package/dist/master.js +129 -12
- package/dist/mcp-artifacts.js +34 -3
- package/dist/mcp-git.js +20 -3
- package/dist/mcp-grafo-worker.js +5 -3
- package/dist/mcp-grafo.js +50 -4
- package/dist/mcp-server.js +14 -1
- package/dist/memoria.js +48 -6
- package/dist/network-roadmap.js +191 -16
- package/dist/ocupacao.js +11 -3
- package/dist/orkmind.js +90 -5
- package/dist/orquestracao.js +12 -10
- package/dist/parado-no-condutor.js +188 -32
- package/dist/phase.js +68 -15
- package/dist/policies.js +52 -1
- package/dist/portfolio.js +4 -1
- package/dist/projeto-alvo.js +5 -1
- package/dist/prompts.js +36 -1
- package/dist/prova-ativacao.js +75 -6
- package/dist/pulse-delivery.js +34 -2
- package/dist/pulse.js +49 -3
- package/dist/ratelimit.js +20 -4
- package/dist/recall.js +3 -1
- package/dist/rede-adesao.js +399 -0
- package/dist/rede-forja.js +289 -0
- package/dist/rede-projetos.js +239 -0
- package/dist/rede-status.js +336 -0
- package/dist/rede.js +980 -0
- package/dist/retry.js +69 -2
- package/dist/roadmap-status.js +23 -3
- package/dist/runtime-profiles.js +22 -1
- package/dist/saida-segura.js +58 -0
- package/dist/session-watcher-claude.js +113 -23
- package/dist/sessoes-contas.js +187 -0
- package/dist/sessoes-inventario.js +6 -18
- package/dist/sessoes.js +83 -2
- package/dist/ship.js +85 -19
- package/dist/thread.js +192 -13
- package/dist/worktree.js +5 -2
- package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
- package/package.json +7 -3
- package/references/definition-of-done.md +1 -1
- package/skills/README.md +1 -1
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/master-metrics/SKILL.md +8 -3
package/dist/retry.js
CHANGED
|
@@ -97,6 +97,7 @@ const modos_1 = require("./modos");
|
|
|
97
97
|
const thread_1 = require("./thread");
|
|
98
98
|
const tokens_1 = require("./tokens");
|
|
99
99
|
const util_1 = require("./util");
|
|
100
|
+
const impedimento_1 = require("./impedimento");
|
|
100
101
|
const worktree_1 = require("./worktree");
|
|
101
102
|
const delegation_1 = require("./delegation");
|
|
102
103
|
const gates_2 = require("./gates");
|
|
@@ -163,6 +164,14 @@ exports.POLITICA_DE_RETRY = {
|
|
|
163
164
|
porque: 'repetir o despacho no MESMO runtime daria o mesmo resultado: o que falta nao e tentativa, e um validador que nao seja quem executou. Escolher o outro runtime e decisao de conducao, nao retry',
|
|
164
165
|
correcao: 'despache o CHECK em outro runtime (`ork phase run <thread> CHECK --runtime <outro>`), ou tire a exigencia de validacao cruzada da thread se ela nao se justifica',
|
|
165
166
|
},
|
|
167
|
+
// RM-056 (D1): o perfil pedido nao existe ou e de outro runtime. Quem corrige e quem pediu.
|
|
168
|
+
'runtime.profile-invalid': {
|
|
169
|
+
motivo: 'runtime.profile-invalid',
|
|
170
|
+
acao: 'escalar-humano',
|
|
171
|
+
automatica: false,
|
|
172
|
+
porque: 'o perfil foi pedido pelo dono (--perfil) e nao existe no store ou e de outro runtime: repetir o pedido daria a mesma recusa, e trocar de perfil sozinho desobedeceria o pedido',
|
|
173
|
+
correcao: 'ork accounts list mostra os perfis de cada runtime; repita o despacho com um perfil do runtime certo ou sem --perfil',
|
|
174
|
+
},
|
|
166
175
|
'cost.violation': {
|
|
167
176
|
motivo: 'cost.violation',
|
|
168
177
|
acao: 'sem-retry',
|
|
@@ -251,6 +260,22 @@ exports.POLITICA_DE_RETRY = {
|
|
|
251
260
|
porque: 'o modelo pedido nao existe ou a conta nao tem acesso a ele: o MESMO prompt, com o mesmo sha256, segue no proximo perfil do mesmo runtime com o mesmo modelo e depois no fallback do bloco, nunca de novo no par que ja recusou',
|
|
252
261
|
correcao: 'ork retry run <thread> troca o destino; sem destino, ork setup <modo> --bloco N --model <modelo acessivel> ou --fallback runtime:modelo',
|
|
253
262
|
},
|
|
263
|
+
// RM-055: so o dono destrava, no terminal. O retry nao repete o despacho as cegas: confere antes se o
|
|
264
|
+
// impedimento saiu (a confianca do diretorio tem prova local) e, sem prova, deixa o runtime decidir.
|
|
265
|
+
'runtime.workspace-untrusted': {
|
|
266
|
+
motivo: 'runtime.workspace-untrusted',
|
|
267
|
+
acao: 'reexecutar',
|
|
268
|
+
automatica: true,
|
|
269
|
+
porque: 'o runtime recusou o diretorio da worktree antes de rodar qualquer coisa: depois que o dono aceita a confianca no terminal, o MESMO prompt, com o mesmo sha256, volta a mesma fase; enquanto a confianca nao aparece no .claude.json da conta, nada e despachado',
|
|
270
|
+
correcao: 'o dono roda o comando da pausa (cd <worktree> && claude, aceita a confianca); ork retry run <thread> re-despacha o prompt ja gravado',
|
|
271
|
+
},
|
|
272
|
+
'runtime.consent-pending': {
|
|
273
|
+
motivo: 'runtime.consent-pending',
|
|
274
|
+
acao: 'reexecutar',
|
|
275
|
+
automatica: true,
|
|
276
|
+
porque: 'o runtime espera o dono aceitar termos novos antes de rodar qualquer coisa: depois do aceite, o MESMO prompt, com o mesmo sha256, volta a mesma fase; se o runtime recusar de novo, a mesma pausa do dono volta',
|
|
277
|
+
correcao: 'o dono abre o CLI do runtime e aceita os termos; ork retry run <thread> re-despacha o prompt ja gravado',
|
|
278
|
+
},
|
|
254
279
|
'tree.blocked': {
|
|
255
280
|
motivo: 'tree.blocked',
|
|
256
281
|
acao: 'sincronizar-worktree',
|
|
@@ -258,6 +283,13 @@ exports.POLITICA_DE_RETRY = {
|
|
|
258
283
|
porque: 'a arvore de destino andou por baixo da thread: rebasar a worktree contra a base e o passo que desbloqueia, e reexecutar antes disso so repete o conflito',
|
|
259
284
|
correcao: 'ork worktree sync <thread> e so entao repetir o passo',
|
|
260
285
|
},
|
|
286
|
+
'lease.resume-unavailable': {
|
|
287
|
+
motivo: 'lease.resume-unavailable',
|
|
288
|
+
acao: 'escalar-humano',
|
|
289
|
+
automatica: false,
|
|
290
|
+
porque: 'sem inode seguro, a remocao forcada exige avaliar a posse antes de retomar',
|
|
291
|
+
correcao: 'ork lease release <nome> --forcar; depois repita a aquisicao',
|
|
292
|
+
},
|
|
261
293
|
'lease.busy': {
|
|
262
294
|
motivo: 'lease.busy',
|
|
263
295
|
acao: 'reexecutar',
|
|
@@ -677,8 +709,19 @@ tomadaPrevia) {
|
|
|
677
709
|
if (!resultado.ok || !resultado.sessionId) {
|
|
678
710
|
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, thread.id), thread.id, 'phase_dispatch_failed', { fase, runtime, slug, cwd,
|
|
679
711
|
promptPath: absoluto, promptSha256: sha, controlador: resultado.controlador, model, effort,
|
|
680
|
-
erro: resultado.erro ?? 'runtime.unavailable: sem sessionId',
|
|
712
|
+
erro: resultado.erro ?? 'runtime.unavailable: sem sessionId', stderr: (resultado.stderr ?? '').slice(0, 500),
|
|
713
|
+
origem: 'retry', ...(perfil ? { perfil } : {}) });
|
|
681
714
|
const sinal = resultado.rateLimit ?? null;
|
|
715
|
+
// RM-055: o redespacho recusado pelo que so o dono resolve reabre a pausa dele, com o mesmo comando.
|
|
716
|
+
const impedimento = !resultado.falhaDeConta && !sinal
|
|
717
|
+
? (0, impedimento_1.registrarImpedimentoDoDono)((0, thread_1.dirThread)(raiz, thread.id), thread, { fase, slug, runtime, cwd, origem: 'retry',
|
|
718
|
+
promptPath: absoluto, promptSha256: sha, perfil, saida: `${resultado.stderr ?? ''}\n${resultado.erro ?? ''}` })
|
|
719
|
+
: null;
|
|
720
|
+
if (impedimento) {
|
|
721
|
+
return { ok: false, slug, sessionId: null, verificada: false, motivo: impedimento.motivo,
|
|
722
|
+
detalhe: `${impedimento.motivo}: ${impedimento.trecho}`, sinal: null, falhaDeConta: null, perfil: perfil ?? null,
|
|
723
|
+
comando: resultado.comando, controlador: resultado.controlador, dryRun: false };
|
|
724
|
+
}
|
|
682
725
|
// I-33 (D5): a conta recusou o redespacho; o perfil sai do rodizio aqui, onde a evidencia esta.
|
|
683
726
|
if (resultado.falhaDeConta) {
|
|
684
727
|
try {
|
|
@@ -1121,6 +1164,17 @@ function jaMarcado(raiz, perfil, falha, agoraMs = Date.now()) {
|
|
|
1121
1164
|
? atual.estado === 'esgotado' && atual.esgotadoAte !== null && Date.parse(atual.esgotadoAte) > agoraMs
|
|
1122
1165
|
: atual.estado === 'sem-auth';
|
|
1123
1166
|
}
|
|
1167
|
+
/**
|
|
1168
|
+
* RM-037 (fatia 5, aviso da rodada 1 do CHECK): a cota que o observador viu ao vivo (`runtime_quota_detected`, da mesma
|
|
1169
|
+
* sessao e do mesmo despacho, com o mesmo prazo dito) ja tirou o perfil do rodizio ate a hora da mensagem. Marcar de
|
|
1170
|
+
* novo aqui, depois dessa hora, pela janela padrao (A10), tiraria do rodizio uma conta que ja voltou.
|
|
1171
|
+
*/
|
|
1172
|
+
function cotaJaVistaAoVivo(eventos, gate, falha) {
|
|
1173
|
+
if (falha.motivo !== 'runtime.quota-exhausted' || typeof gate?.sessionId !== 'string')
|
|
1174
|
+
return false;
|
|
1175
|
+
return eventos.some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.cotaVistaNaTranscricao && e.sessionId === gate.sessionId &&
|
|
1176
|
+
e.despachoEm === gate.despachoEm && (e.resetEm ?? null) === falha.resetEm);
|
|
1177
|
+
}
|
|
1124
1178
|
function sinalDoGate(gate, motivo) {
|
|
1125
1179
|
const f = gate?.falhaDeConta;
|
|
1126
1180
|
return { motivo: motivo === 'runtime.auth-missing' ? 'runtime.auth-missing' : 'runtime.quota-exhausted',
|
|
@@ -1282,6 +1336,18 @@ function executarRetry(carregado, threadId, opcoes = {}) {
|
|
|
1282
1336
|
registrarTentativa(false, detalhe);
|
|
1283
1337
|
return { ...vazio, detalhe };
|
|
1284
1338
|
}
|
|
1339
|
+
// RM-055: o impedimento do dono com prova local (confianca do diretorio) so volta ao runtime depois de
|
|
1340
|
+
// resolvido. Sem a prova, nada e despachado e a tentativa nao conta: a pausa do dono continua aberta.
|
|
1341
|
+
if (plano.motivo && (0, impedimento_1.ehImpedimentoDoDono)(plano.motivo) && typeof falho.cwd === 'string') {
|
|
1342
|
+
const perfilFalho = perfilDoEvento(falho);
|
|
1343
|
+
const resolvido = (0, impedimento_1.impedimentoResolvido)(plano.motivo, { cwd: falho.cwd,
|
|
1344
|
+
runtime: typeof falho.runtime === 'string' ? falho.runtime : '', configDir: perfilFalho?.configDir ?? null });
|
|
1345
|
+
if (resolvido === false) {
|
|
1346
|
+
const detalhe = `${plano.motivo}: o runtime ainda nao confia em ${falho.cwd}; nada foi despachado. ` +
|
|
1347
|
+
`Rode \`cd ${falho.cwd} && claude\`, aceite a confianca e repita \`ork retry run ${threadId}\``;
|
|
1348
|
+
return { ...vazio, detalhe };
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1285
1351
|
const redespacho = redespachar(carregado, thread, plano.fase, falho.promptPath, falho.promptSha256, {
|
|
1286
1352
|
effort: plano.effort,
|
|
1287
1353
|
runtime: typeof falho.runtime === 'string' ? falho.runtime : null,
|
|
@@ -1349,7 +1415,8 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
|
|
|
1349
1415
|
const politica = (0, runtime_profiles_1.politicaDeRotacao)(manifesto);
|
|
1350
1416
|
const falha = sinalDoGate(gate, motivo);
|
|
1351
1417
|
// I-33 (D12): o observador ja marca o perfil no caminho terminal; remarcar empurraria o prazo a cada retry.
|
|
1352
|
-
|
|
1418
|
+
// RM-037 (fatia 5, aviso da rodada 1 do CHECK): a cota que ele viu ao vivo ja marcou ate a hora da mensagem.
|
|
1419
|
+
if (!opcoes.dryRun && perfil && !jaMarcado(raiz, perfil, falha) && !cotaJaVistaAoVivo(eventos, gate, falha)) {
|
|
1353
1420
|
try {
|
|
1354
1421
|
(0, ratelimit_1.marcarContaDaFalha)(carregado, perfil, falha);
|
|
1355
1422
|
}
|
package/dist/roadmap-status.js
CHANGED
|
@@ -37,6 +37,7 @@ const horario_1 = require("./horario");
|
|
|
37
37
|
const projeto_alvo_1 = require("./projeto-alvo");
|
|
38
38
|
const fabrica_estado_1 = require("./fabrica-estado");
|
|
39
39
|
const hitl_resumo_1 = require("./hitl-resumo");
|
|
40
|
+
const hitl_tempo_parado_1 = require("./hitl-tempo-parado");
|
|
40
41
|
const manifest_1 = require("./manifest");
|
|
41
42
|
const maquina_1 = require("./maquina");
|
|
42
43
|
const parado_no_condutor_1 = require("./parado-no-condutor");
|
|
@@ -129,8 +130,13 @@ function fatosLocais(raiz, quando, fuso) {
|
|
|
129
130
|
if (entregas !== undefined)
|
|
130
131
|
return entregas;
|
|
131
132
|
try {
|
|
132
|
-
const
|
|
133
|
-
|
|
133
|
+
const carregado = (0, manifest_1.exigirManifesto)(raiz);
|
|
134
|
+
// RM-037 (fatia 5, A5): a forja sem leitura que o pulse ja disse vale sobre o retrato, que e de antes dela (a
|
|
135
|
+
// leitura boa apaga a marca), e a linha nao diz "PR nao lido".
|
|
136
|
+
const aviso = (0, parado_no_condutor_1.forjaSemLeituraDoRemoto)(raiz, carregado.manifesto.fabrica.remoto);
|
|
137
|
+
const retrato = aviso ? null : (0, parado_no_condutor_1.lerRetratoDePrs)(raiz);
|
|
138
|
+
entregas = (0, parado_no_condutor_1.entregasDoProjeto)(carregado, { quando, lerPrs: () => (retrato ? { ok: true, retrato }
|
|
139
|
+
: aviso ? { ok: false, lidoEm: aviso.ditoEm, erro: aviso.motivo, semLeitura: { remoto: aviso.remoto, host: aviso.host } } : null) });
|
|
134
140
|
}
|
|
135
141
|
catch {
|
|
136
142
|
entregas = null;
|
|
@@ -221,8 +227,18 @@ function montarStatusDoRoadmap(raiz, opcoes = {}) {
|
|
|
221
227
|
catch {
|
|
222
228
|
fabrica = undefined;
|
|
223
229
|
}
|
|
230
|
+
// RM-057 (fatia 3): leitura pura do ledger; sem ela o relatorio sai como antes.
|
|
231
|
+
let hitlDeConducao;
|
|
232
|
+
try {
|
|
233
|
+
const h = (0, hitl_tempo_parado_1.lerHitlDeConducaoAgora)(raiz, quando);
|
|
234
|
+
if (h.abertas.length || h.seteDias.pedidos || h.seteDias.respondidos)
|
|
235
|
+
hitlDeConducao = h;
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
hitlDeConducao = undefined;
|
|
239
|
+
}
|
|
224
240
|
return montarStatusDeFatos((0, docs_1.carregarDocs)(raiz).docs, fatosLocais(raiz, quando), { quando, projeto: opcoes.projeto, consulta: opcoes.consulta,
|
|
225
|
-
...(fabrica ? { fabrica } : {}) });
|
|
241
|
+
...(fabrica ? { fabrica } : {}), ...(hitlDeConducao ? { hitlDeConducao } : {}) });
|
|
226
242
|
}
|
|
227
243
|
/** O relatorio a partir das paginas do roadmap e dos fatos das threads, de onde quer que venham. */
|
|
228
244
|
function montarStatusDeFatos(docs, fatos, opcoes) {
|
|
@@ -271,6 +287,7 @@ function montarStatusDeFatos(docs, fatos, opcoes) {
|
|
|
271
287
|
emSeguida: itens.filter(i => i.conduzindo && !i.hitl).map(i => ({ item: i.id, ...i.conduzindo })),
|
|
272
288
|
...(opcoes.consulta ? { consulta: opcoes.consulta } : {}),
|
|
273
289
|
...(opcoes.fabrica ? { fabrica: opcoes.fabrica } : {}),
|
|
290
|
+
...(opcoes.hitlDeConducao ? { hitlDeConducao: opcoes.hitlDeConducao } : {}),
|
|
274
291
|
};
|
|
275
292
|
}
|
|
276
293
|
/** "orkastery" vira "Orkastery": o titulo diz o nome do projeto como gente escreve. */
|
|
@@ -341,6 +358,9 @@ function textoDoStatusDoRoadmap(s, fuso, opcoes = {}) {
|
|
|
341
358
|
...(s.precisaDeVoce.length ? cortar(s.precisaDeVoce, x => `• ${x.item}${naMaquina(x.espera.maquina)}: ${x.espera.pergunta}` +
|
|
342
359
|
(x.espera.codigo ? ` Responda ${x.espera.codigo} ${x.espera.recomendada ?? 'a'} (ou outra letra).` : ' A pergunta chega no próximo resumo.'))
|
|
343
360
|
: ['• Nada agora.']),
|
|
361
|
+
// RM-057 (fatia 3): ha quanto tempo cada pergunta de conducao parou a thread, e a mediana da semana.
|
|
362
|
+
...(s.hitlDeConducao ? [`• HITL de condução: ${s.hitlDeConducao.abertas.length} aberta(s); ${(0, hitl_tempo_parado_1.textoDaMediana)(s.hitlDeConducao)}.`,
|
|
363
|
+
...cortar(s.hitlDeConducao.abertas, a => ` ${(0, hitl_tempo_parado_1.linhaDaPerguntaParada)(a, { agora: s.consultadoEm, fuso })}.`)] : []),
|
|
344
364
|
'', 'O que eu faço em seguida',
|
|
345
365
|
...(s.emSeguida.length ? cortar(s.emSeguida, x => linhaDoQueVem(x, s.consultadoEm, fuso))
|
|
346
366
|
: ['• Nada em andamento; sigo o que você priorizar.']),
|
package/dist/runtime-profiles.js
CHANGED
|
@@ -67,6 +67,7 @@ exports.perfisDoRuntime = perfisDoRuntime;
|
|
|
67
67
|
exports.perfilDisponivel = perfilDisponivel;
|
|
68
68
|
exports.politicaDeRotacao = politicaDeRotacao;
|
|
69
69
|
exports.proximoPerfilDisponivel = proximoPerfilDisponivel;
|
|
70
|
+
exports.proximoPerfilPorCarga = proximoPerfilPorCarga;
|
|
70
71
|
exports.prazoDoRuntime = prazoDoRuntime;
|
|
71
72
|
exports.prazoDaFila = prazoDaFila;
|
|
72
73
|
exports.menorEsgotadoAte = menorEsgotadoAte;
|
|
@@ -794,7 +795,8 @@ exports.POLITICA_PADRAO = { mesmoRuntimePorCota: true, mesmoRuntimePorAuth: true
|
|
|
794
795
|
function politicaDeRotacao(manifesto) {
|
|
795
796
|
const r = manifesto.runtime_profiles;
|
|
796
797
|
return { mesmoRuntimePorCota: r?.rotate_same_runtime_on_quota !== false,
|
|
797
|
-
mesmoRuntimePorAuth: r?.rotate_same_runtime_on_auth !== false
|
|
798
|
+
mesmoRuntimePorAuth: r?.rotate_same_runtime_on_auth !== false,
|
|
799
|
+
...(r?.distribuir === 'carga' ? { distribuir: 'carga' } : {}) };
|
|
798
800
|
}
|
|
799
801
|
/**
|
|
800
802
|
* D14: o perfil da vez do runtime, na ordem do store. `desativado` e `provider-pago` nunca foram
|
|
@@ -819,6 +821,25 @@ function proximoPerfilDisponivel(store, runtime, politica, opcoes = {}) {
|
|
|
819
821
|
}
|
|
820
822
|
return null;
|
|
821
823
|
}
|
|
824
|
+
/**
|
|
825
|
+
* RM-056 (D3): a escolha por carga. Respeita a politica da D14 (sem perfil da vez pela ordem, sem
|
|
826
|
+
* perfil nenhum: a mesma retencao do runtime), e entre os perfis disponiveis vence o de menor
|
|
827
|
+
* carga (sessoes vivas da conta nesta maquina); empate pelo `ultimoUso` mais antigo (nunca usado
|
|
828
|
+
* primeiro), depois a ordem do store. O `ultimoUso` e gravado no despacho, entao dois despachos
|
|
829
|
+
* seguidos com carga igual vao a perfis diferentes mesmo antes de o runtime listar a sessao.
|
|
830
|
+
*/
|
|
831
|
+
function proximoPerfilPorCarga(store, runtime, politica, carga, opcoes = {}) {
|
|
832
|
+
const daVez = proximoPerfilDisponivel(store, runtime, politica, opcoes);
|
|
833
|
+
if (!daVez)
|
|
834
|
+
return null;
|
|
835
|
+
const agoraMs = opcoes.agoraMs ?? Date.now();
|
|
836
|
+
const candidatos = perfisDoRuntime(store, runtime)
|
|
837
|
+
.map((p, i) => ({ p, i }))
|
|
838
|
+
.filter(({ p }) => !(opcoes.excluir ?? []).includes(p.id) && perfilDisponivel(p, agoraMs));
|
|
839
|
+
const uso = (p) => p.ultimoUso === null ? -Infinity : Date.parse(p.ultimoUso);
|
|
840
|
+
candidatos.sort((x, y) => (carga.get(x.p.id) ?? 0) - (carga.get(y.p.id) ?? 0) || uso(x.p) - uso(y.p) || x.i - y.i);
|
|
841
|
+
return candidatos[0]?.p ?? daVez;
|
|
842
|
+
}
|
|
822
843
|
/**
|
|
823
844
|
* D14: quando o runtime volta a ter perfil da vez, pela mesma regra da escolha. Com a troca por
|
|
824
845
|
* cota desligada, e o prazo do perfil que segura o runtime; ligada, o menor prazo entre os
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RM-053 (fatia 2): o saneador de saida comum ao nucleo.
|
|
4
|
+
*
|
|
5
|
+
* Texto que vem de fora (o retrato de outra maquina, a branch `ork/fabrica-estado` do remoto de um
|
|
6
|
+
* projeto, onde outras pessoas escrevem) chega a tela do dono. A rede ja limpava o que imprime desde
|
|
7
|
+
* a revisao 4; o `ork fabrica` imprimia o `por` e o `projeto` legados crus. Este modulo e a regra
|
|
8
|
+
* unica: quem imprime valor alheio passa por aqui.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.emUmaLinha = exports.INVISIVEL = exports.CF_VISIVEL = void 0;
|
|
12
|
+
exports.valoresEmUmaLinha = valoresEmUmaLinha;
|
|
13
|
+
exports.jsonSemInvisivel = jsonSemInvisivel;
|
|
14
|
+
/**
|
|
15
|
+
* Y4 do CHECK 7: as marcas de `Cf` que se veem, lista fechada (todo `Prepended_Concatenation_Mark=Yes`
|
|
16
|
+
* do Unicode 17: os sinais numericos arabes U+0600 a U+0605, o fim de aya U+06DD, a abreviacao siriaca
|
|
17
|
+
* U+070F, as marcas de libra e piastra U+0890 e U+0891, o sanah U+08E2 e as marcas de numero kaithi
|
|
18
|
+
* U+110BD e U+110CD). Elas tem glifo e nao movem o texto, ao contrario das bidi, de largura zero e das
|
|
19
|
+
* tags, que seguem invisiveis. O regex do JS nao aceita `\p{Prepended_Concatenation_Mark}`; por isso a
|
|
20
|
+
* lista literal, presa ao `INVISIVEL` e conferida ponto a ponto no teste.
|
|
21
|
+
*/
|
|
22
|
+
exports.CF_VISIVEL = Object.freeze([
|
|
23
|
+
0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x06dd, 0x070f, 0x0890, 0x0891, 0x08e2, 0x110bd, 0x110cd,
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* V2 da revisao 4, W11 da revisao 5 e X3 da revisao 6: caractere que o terminal executa ou que
|
|
27
|
+
* ninguem ve, pelas classes do Unicode: controles (`Cc`: ESC, BEL, CSI, quebra de linha), formato
|
|
28
|
+
* (`Cf`: bidi, largura zero, tags), separadores de linha e todo `Default_Ignorable_Code_Point`
|
|
29
|
+
* (preenchimentos Hangul, seletores de variacao, os de musica e de estenografia), mais o braile
|
|
30
|
+
* vazio. Ficam de fora o ZWJ (U+200D) e os seletores U+FE0E e U+FE0F: eles montam emoji comuns, e as
|
|
31
|
+
* marcas visiveis de `Cf` (`CF_VISIVEL`, Y4 do CHECK 7).
|
|
32
|
+
*/
|
|
33
|
+
exports.INVISIVEL = /(?![\u200d\ufe0e\ufe0f\u0600-\u0605\u06dd\u070f\u0890\u0891\u08e2\u{110bd}\u{110cd}])[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\p{Default_Ignorable_Code_Point}\u2800]/u;
|
|
34
|
+
const INVISIVEIS = new RegExp(exports.INVISIVEL.source, 'gu');
|
|
35
|
+
/**
|
|
36
|
+
* W4 da revisao 5: o valor numa linha so, sem nada invisivel. A quebra de linha (e a tabulacao) vira
|
|
37
|
+
* espaco: um valor que vem de fora nunca abre uma linha propria na saida, como se fosse do `ork`.
|
|
38
|
+
*/
|
|
39
|
+
const emUmaLinha = (texto) => texto.replace(INVISIVEIS, (c) => (/[\t\n\v\f\r\u0085\u2028\u2029]/.test(c) ? ' ' : ''));
|
|
40
|
+
exports.emUmaLinha = emUmaLinha;
|
|
41
|
+
/**
|
|
42
|
+
* Cada texto de uma estrutura (objeto, lista, aninhados) em uma linha, sem invisivel; numero,
|
|
43
|
+
* booleano e `null` ficam como estao (X5 da revisao 6: a ida e volta em JSON trocava `NaN` por `null`).
|
|
44
|
+
*/
|
|
45
|
+
function valoresEmUmaLinha(valor) {
|
|
46
|
+
const limpar = (v) => typeof v === 'string' ? (0, exports.emUmaLinha)(v)
|
|
47
|
+
: Array.isArray(v) ? v.map(limpar)
|
|
48
|
+
: v && typeof v === 'object' ? Object.fromEntries(Object.entries(v).map(([k, x]) => [k, limpar(x)])) : v;
|
|
49
|
+
return limpar(valor);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* O JSON para a tela: o mesmo valor, com os caracteres invisiveis escritos como `\uXXXX` (quem le o
|
|
53
|
+
* JSON recebe o mesmo texto; so o terminal deixa de executa-lo). A quebra de linha da indentacao fica.
|
|
54
|
+
*/
|
|
55
|
+
function jsonSemInvisivel(valor) {
|
|
56
|
+
return JSON.stringify(valor, null, 2).replace(INVISIVEIS, (c) => c === '\n' ? c
|
|
57
|
+
: Array.from({ length: c.length }, (_, i) => `\\u${c.charCodeAt(i).toString(16).padStart(4, '0')}`).join(''));
|
|
58
|
+
}
|
|
@@ -38,6 +38,7 @@ exports.normalizarNativo = normalizarNativo;
|
|
|
38
38
|
exports.stopCorrelacionado = stopCorrelacionado;
|
|
39
39
|
exports.bloqueioPendente = bloqueioPendente;
|
|
40
40
|
exports.classificarSessaoClaude = classificarSessaoClaude;
|
|
41
|
+
exports.ultimoErroDeApi = ultimoErroDeApi;
|
|
41
42
|
exports.falhaDeContaDaTranscricao = falhaDeContaDaTranscricao;
|
|
42
43
|
exports.comFalhaDeConta = comFalhaDeConta;
|
|
43
44
|
exports.processoNativo = processoNativo;
|
|
@@ -268,22 +269,27 @@ function textoDoErroDeApi(e) {
|
|
|
268
269
|
const codigo = typeof e.error === 'string' ? e.error : '';
|
|
269
270
|
return (0, hitl_1.redigirSegredos)([codigo, textos.filter(Boolean).join(' ')].filter(Boolean).join(': ')).slice(0, 4096);
|
|
270
271
|
}
|
|
272
|
+
const UUID = /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i;
|
|
273
|
+
/** A transcricao da sessao no diretorio do perfil (ou no implicito, sem perfil); `null` com sessao que nao e uuid. */
|
|
274
|
+
function arquivoDaTranscricao(perfil, cwd, sessionId) {
|
|
275
|
+
if (!UUID.test(sessionId))
|
|
276
|
+
return null;
|
|
277
|
+
return path.join((0, runtime_profiles_1.diretorioEfetivo)('claude-bg', perfil), 'projects', path.resolve(cwd).replace(/[^a-zA-Z0-9-]/g, '-'), `${sessionId}.jsonl`);
|
|
278
|
+
}
|
|
271
279
|
/**
|
|
272
|
-
* I-33 (D11b):
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* (N3), o que encerrou a sessao. O codigo `rate_limit`
|
|
277
|
-
* do Claude Code cobre tanto o limite do plano quanto o 429 transitorio ("Request rejected (429)",
|
|
278
|
-
* "not your usage limit"): quem separa e o criterio unico da D16 (`naturezaDoLimite`), pela frase.
|
|
280
|
+
* I-33 (D11b): o erro de API que o proprio Claude Code gravou na transcricao da sessao. So entram linhas marcadas
|
|
281
|
+
* como erro de API (`isApiErrorMessage` ou campo `error`): texto do agente nunca vira motivo. Leitura limitada da
|
|
282
|
+
* cauda, sem seguir link; ausencia de transcricao e ausencia de evidencia. Vale o ULTIMO erro de API (N3), o que
|
|
283
|
+
* encerrou a sessao. RM-037 (fatia 5): com ele vem o instante da linha, que e a ancora da hora dita.
|
|
279
284
|
*/
|
|
280
|
-
function
|
|
281
|
-
|
|
285
|
+
function ultimoErroDeApi(perfil, cwd, sessionId) {
|
|
286
|
+
const arquivo = arquivoDaTranscricao(perfil, cwd, sessionId);
|
|
287
|
+
if (!arquivo)
|
|
282
288
|
return null;
|
|
283
|
-
const arquivo = path.join((0, runtime_profiles_1.diretorioEfetivo)('claude-bg', perfil), 'projects', path.resolve(cwd).replace(/[^a-zA-Z0-9-]/g, '-'), `${sessionId}.jsonl`);
|
|
284
289
|
let fd;
|
|
290
|
+
// O_NONBLOCK: um FIFO no lugar da transcricao nao trava o observador no open (sugestao da rodada 1 do CHECK).
|
|
285
291
|
try {
|
|
286
|
-
fd = fs.openSync(arquivo, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
292
|
+
fd = fs.openSync(arquivo, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
287
293
|
}
|
|
288
294
|
catch {
|
|
289
295
|
return null;
|
|
@@ -300,7 +306,7 @@ function falhaDeContaDaTranscricao(perfil, cwd, sessionId, agoraMs = Date.now())
|
|
|
300
306
|
finally {
|
|
301
307
|
fs.closeSync(fd);
|
|
302
308
|
}
|
|
303
|
-
|
|
309
|
+
let ultimo = null;
|
|
304
310
|
for (const linha of cauda.split('\n')) {
|
|
305
311
|
let e;
|
|
306
312
|
try {
|
|
@@ -311,14 +317,82 @@ function falhaDeContaDaTranscricao(perfil, cwd, sessionId, agoraMs = Date.now())
|
|
|
311
317
|
}
|
|
312
318
|
if (!e || typeof e !== 'object' || (e.isApiErrorMessage !== true && e.error === undefined))
|
|
313
319
|
continue;
|
|
314
|
-
|
|
320
|
+
const ms = typeof e.timestamp === 'string' ? Date.parse(e.timestamp) : NaN;
|
|
321
|
+
ultimo = { texto: textoDoErroDeApi(e), em: Number.isFinite(ms) ? new Date(ms).toISOString() : null,
|
|
322
|
+
uuid: typeof e.uuid === 'string' && UUID.test(e.uuid) ? e.uuid.toLowerCase() : null };
|
|
315
323
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
324
|
+
return ultimo;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* I-33 (D11b): falha de conta registrada pelo Claude Code na transcricao da sessao. O codigo `rate_limit` do
|
|
328
|
+
* Claude Code cobre tanto o limite do plano quanto o 429 transitorio ("Request rejected (429)", "not your usage
|
|
329
|
+
* limit"): quem separa e o criterio unico da D16 (`naturezaDoLimite`), pela frase. I-33 (N3): o criterio roda
|
|
330
|
+
* sobre o erro que encerrou a sessao, nunca sobre os anteriores juntos. RM-037 (fatia 5): a hora dita e ancorada
|
|
331
|
+
* no instante da mensagem; sem instante na linha, no relogio de quem le, como antes.
|
|
332
|
+
*/
|
|
333
|
+
function falhaDeContaDaTranscricao(perfil, cwd, sessionId, agoraMs = Date.now()) {
|
|
334
|
+
return falhaDoErro(ultimoErroDeApi(perfil, cwd, sessionId), agoraMs);
|
|
335
|
+
}
|
|
336
|
+
function falhaDoErro(erro, agoraMs) {
|
|
337
|
+
return erro ? (0, claude_bg_1.parseFalhaDeConta)(erro.texto, erro.em ? Date.parse(erro.em) : agoraMs) : null;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* RM-037 (fatia 5): a cota vista com a sessao viva. Em 02/10/2026 as sessoes de uma conta pararam as 06:00Z no
|
|
341
|
+
* limite de gasto ("your session limit resets 4:40am (<fuso>)"), sem Stop e com o processo vivo por mais uma
|
|
342
|
+
* hora; o perfil so saiu do rodizio as 07:15Z, quando o processo morreu, e o redespacho das 06:14Z caiu na mesma
|
|
343
|
+
* conta. Aqui, a cada volta com a transcricao maior que na anterior, o ultimo erro de API depois do despacho passa
|
|
344
|
+
* pelo criterio unico da D16; esgotamento com prazo futuro marca o perfil ate a hora dita (ou a janela padrao
|
|
345
|
+
* contada da mensagem) e grava `runtime_quota_detected` uma vez por erro. A fase nao fecha e a conducao nao muda:
|
|
346
|
+
* a sessao continua viva, e o fecho segue o caminho de sempre, sem marcar de novo o mesmo erro.
|
|
347
|
+
*/
|
|
348
|
+
function cotaAoVivo(ctx, perfil, cwd, cursor, erroDaTranscricao, gravar) {
|
|
349
|
+
const { sessao, dir } = ctx;
|
|
350
|
+
const arquivo = arquivoDaTranscricao(perfil, cwd, sessao.sessionId);
|
|
351
|
+
let tamanho;
|
|
352
|
+
try {
|
|
353
|
+
const st = arquivo ? fs.lstatSync(arquivo) : null;
|
|
354
|
+
// Link, FIFO ou diretorio no lugar da transcricao nao e transcricao: nada a ler.
|
|
355
|
+
tamanho = st?.isFile() ? st.size : NaN;
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!Number.isFinite(tamanho) || cursor.transcricaoBytes === tamanho)
|
|
361
|
+
return;
|
|
362
|
+
cursor.transcricaoBytes = tamanho;
|
|
363
|
+
const erro = erroDaTranscricao();
|
|
364
|
+
const erroMs = erro?.em ? Date.parse(erro.em) : NaN;
|
|
365
|
+
// Linha sem instante, ou de antes deste despacho (sessao retomada), nao prova que a cota e deste turno.
|
|
366
|
+
if (!erro || !Number.isFinite(erroMs) || erroMs < Date.parse(sessao.despachadaEm))
|
|
367
|
+
return;
|
|
368
|
+
const falha = falhaDoErro(erro, ctx.agoraMs);
|
|
369
|
+
if (falha?.motivo !== 'runtime.quota-exhausted' || !ctx.carregado)
|
|
370
|
+
return;
|
|
371
|
+
const esgotadoAte = (0, ratelimit_1.prazoDaCotaVista)(ctx.carregado.manifesto, falha, erroMs, ctx.agoraMs);
|
|
372
|
+
if (!esgotadoAte)
|
|
373
|
+
return;
|
|
374
|
+
// A chave do erro: o uuid da linha ou, sem ele, o instante e o trecho (dado de maquina, nunca texto).
|
|
375
|
+
const sensorEventId = (0, node_crypto_1.createHash)('sha256')
|
|
376
|
+
.update(JSON.stringify([sessao.sessionId, sessao.despachadaEm, erro.uuid ?? [erro.em, falha.trecho]])).digest('hex');
|
|
377
|
+
(0, session_events_1.comLockDeSessao)(dir, () => {
|
|
378
|
+
if ((0, ledger_1.lerLedger)(dir).some(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.cotaVistaNaTranscricao && e.sensorEventId === sensorEventId))
|
|
379
|
+
return;
|
|
380
|
+
if (perfil) {
|
|
381
|
+
try {
|
|
382
|
+
(0, ratelimit_1.marcarContaDaFalha)(ctx.carregado, perfil, falha, ctx.agoraMs, esgotadoAte);
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// Store ocupado ou invalido: a proxima volta le a transcricao de novo e tenta outra vez.
|
|
386
|
+
delete cursor.transcricaoBytes;
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
gravar(ledger_1.TIPOS_DE_EVENTO.cotaVistaNaTranscricao, { fase: sessao.fase, sessionId: sessao.sessionId, despachoEm: sessao.despachadaEm,
|
|
391
|
+
runtime: 'claude-bg', sensorEventId, motivo: falha.motivo, erroEm: erro.em, resetEm: falha.resetEm, fonteDoPrazo: falha.fonte,
|
|
392
|
+
// O trecho ja vem redigido e numa linha; sem controle, como no store de perfis.
|
|
393
|
+
esgotadoAte, trecho: falha.trecho.replace(/\p{Cc}/gu, ' '), perfil: perfil ? { id: perfil.id, runtime: perfil.runtime } : null,
|
|
394
|
+
perfilMarcado: !!perfil, origem: 'sessions.watch' });
|
|
395
|
+
});
|
|
322
396
|
}
|
|
323
397
|
/**
|
|
324
398
|
* I-33 (D11): precedencia entre a prova da I-34 e a falha de conta. Com Stop correlacionado vale
|
|
@@ -360,8 +434,10 @@ function estadoDoArtefato(raiz, threadId, arquivo) {
|
|
|
360
434
|
const file = path.join((0, thread_1.dirThread)(raiz, threadId), arquivo);
|
|
361
435
|
const vazio = { sha256: null, mtimeMs: null, texto: null };
|
|
362
436
|
let fd;
|
|
437
|
+
// RM-037 (fatia 5, sugestao da rodada 2 do CHECK): O_NONBLOCK, como na transcricao, para um FIFO no lugar do
|
|
438
|
+
// artefato nao travar o observador no open; o `isFile` abaixo o recusa.
|
|
363
439
|
try {
|
|
364
|
-
fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
440
|
+
fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
365
441
|
}
|
|
366
442
|
catch (erro) {
|
|
367
443
|
return erro.code === 'ENOENT' ? vazio : { ...vazio, invalido: true };
|
|
@@ -600,9 +676,13 @@ function observarClaudeSobLock(ctx) {
|
|
|
600
676
|
const registro = consulta.ok ? consulta.registros.find(s => s.sessionId === sessao.sessionId && s.cwd === fonte.cwd) ?? null : null;
|
|
601
677
|
const artefato = saidaDoArtefato(raiz, thread.id, sessao, fonte, eventos);
|
|
602
678
|
let prova;
|
|
679
|
+
// RM-037 (fatia 5): o ultimo erro de API da transcricao, lido no maximo uma vez por volta, serve a cota ao vivo
|
|
680
|
+
// e ao fecho.
|
|
681
|
+
let erroLido;
|
|
682
|
+
const erroDaTranscricao = () => erroLido !== undefined ? erroLido : (erroLido = ultimoErroDeApi(perfil, fonte.cwd, sessao.sessionId));
|
|
603
683
|
const { c, falha } = comFalhaDeConta(classificarSessaoClaude({ sessao, eventos, consulta, registro, cursor, agoraMs: ctx.agoraMs,
|
|
604
684
|
limiteMs: ctx.limiteMs, pausaAoFim: (0, thread_1.pausaNaThread)(thread, sessao.fase),
|
|
605
|
-
prova: () => prova ??= provaDoOrk(raiz, thread.id, sessao, eventos, fonte), processo: processoNativo }), () =>
|
|
685
|
+
prova: () => prova ??= provaDoOrk(raiz, thread.id, sessao, eventos, fonte), processo: processoNativo }), () => falhaDoErro(erroDaTranscricao(), ctx.agoraMs));
|
|
606
686
|
(0, codex_runner_1.gravarAtomico)(arquivoCursor, cursor);
|
|
607
687
|
// GO-FIX 3 (achado 1): cursor gravado numa thread que sumiu durante a consulta é desfeito aqui;
|
|
608
688
|
// as pastas criadas pela observação, pelo `session-watcher`.
|
|
@@ -610,6 +690,12 @@ function observarClaudeSobLock(ctx) {
|
|
|
610
690
|
fs.rmSync(arquivoCursor, { force: true });
|
|
611
691
|
throw new Error(exports.THREAD_REMOVIDA);
|
|
612
692
|
}
|
|
693
|
+
if (!c.terminal) {
|
|
694
|
+
const lidos = cursor.transcricaoBytes;
|
|
695
|
+
cotaAoVivo(ctx, perfil, fonte.cwd, cursor, erroDaTranscricao, gravar);
|
|
696
|
+
if (cursor.transcricaoBytes !== lidos)
|
|
697
|
+
(0, codex_runner_1.gravarAtomico)(arquivoCursor, cursor);
|
|
698
|
+
}
|
|
613
699
|
if (!c.terminal && c.inconclusivo)
|
|
614
700
|
return (0, session_events_1.comLockDeSessao)(dir, () => {
|
|
615
701
|
const diagnosticoId = `${resultadoId}:inconclusivo`;
|
|
@@ -649,8 +735,12 @@ function observarClaudeSobLock(ctx) {
|
|
|
649
735
|
observadoEm, gate: 'phase.dispatch', origem: 'sessions.watch' };
|
|
650
736
|
if (!atuais.some(e => e.tipo === c.classificacao && e.sensorResultId === resultadoId))
|
|
651
737
|
gravar(c.classificacao, dados);
|
|
652
|
-
// I-33 (D12): o perfil sai do rodizio na primeira gravacao do resultado, onde a evidencia esta.
|
|
653
|
-
|
|
738
|
+
// I-33 (D12): o perfil sai do rodizio na primeira gravacao do resultado, onde a evidencia esta. RM-037 (fatia 5):
|
|
739
|
+
// o erro que a cota ao vivo ja marcou nao marca de novo; depois do prazo dito, marcar de novo tiraria do
|
|
740
|
+
// rodizio uma conta que ja voltou.
|
|
741
|
+
const jaVista = !!erroLido?.em && atuais.some(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.cotaVistaNaTranscricao &&
|
|
742
|
+
e.sessionId === sessao.sessionId && e.despachoEm === sessao.despachadaEm && e.erroEm === erroLido.em);
|
|
743
|
+
if (falha && perfil && ctx.carregado && !jaVista && !atuais.some(e => e.tipo === 'phase_result' && e.sensorResultId === resultadoId)) {
|
|
654
744
|
try {
|
|
655
745
|
(0, ratelimit_1.marcarContaDaFalha)(ctx.carregado, perfil, falha, ctx.agoraMs);
|
|
656
746
|
}
|