@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/policies.js
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* ela volta na lista de desconhecidas, para o `doctor` e o CLI dizerem que ela nao vale.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.POLICIES_CONHECIDAS = void 0;
|
|
14
|
+
exports.POLICIES_DE_PROVA_LOCAL = exports.POLICIES_CONHECIDAS = void 0;
|
|
15
15
|
exports.procurarSegredos = procurarSegredos;
|
|
16
|
+
exports.policyDeProvaLocal = policyDeProvaLocal;
|
|
16
17
|
exports.policiesDesconhecidas = policiesDesconhecidas;
|
|
17
18
|
exports.avaliarPolicies = avaliarPolicies;
|
|
18
19
|
exports.avisos = avisos;
|
|
@@ -95,7 +96,28 @@ exports.POLICIES_CONHECIDAS = {
|
|
|
95
96
|
quando: ['ship'],
|
|
96
97
|
descricao: 'avisa quando a branch da thread esta atras da base',
|
|
97
98
|
},
|
|
99
|
+
// RM-008 (B8): a licao `claims.failed` ("rode o comando da claim antes de registra-la"). Desligada por
|
|
100
|
+
// padrao; declarada, o `ork claims add` roda o comando uma vez no prazo do verify. So avisa, nunca para.
|
|
101
|
+
claim_sem_prova_local: {
|
|
102
|
+
quando: ['claims.add'],
|
|
103
|
+
descricao: 'avisa quando o comando da claim reprova (ou estoura o prazo do verify) no registro',
|
|
104
|
+
},
|
|
105
|
+
claims_failed: {
|
|
106
|
+
quando: ['claims.add'],
|
|
107
|
+
descricao: 'a mesma conferencia de claim_sem_prova_local, com o nome que o ork licoes propoe',
|
|
108
|
+
},
|
|
98
109
|
};
|
|
110
|
+
/** RM-008 (B8): as policies que conferem a claim no registro (um aviso so, como verify_regression e verify_failed). */
|
|
111
|
+
exports.POLICIES_DE_PROVA_LOCAL = ['claim_sem_prova_local', 'claims_failed'];
|
|
112
|
+
/** A primeira policy de prova local declarada fora de `off`, ou `null` (o `claims add` nao roda nada). */
|
|
113
|
+
function policyDeProvaLocal(manifesto) {
|
|
114
|
+
const declaradas = manifesto.policies ?? {};
|
|
115
|
+
for (const [nome, bruta] of Object.entries(declaradas)) {
|
|
116
|
+
if (exports.POLICIES_DE_PROVA_LOCAL.includes(nome) && severidade(bruta) !== 'off')
|
|
117
|
+
return nome;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
99
121
|
/**
|
|
100
122
|
* Ensaio da 0.5.0: a thread criada sem `--worktree auto` entrega a base para a base, e a correcao
|
|
101
123
|
* repetia o proprio `ork ship`. A thread que ainda nao passou do GO ganha a branch com
|
|
@@ -122,6 +144,8 @@ function avaliarPolicies(manifesto, ctx) {
|
|
|
122
144
|
const violacoes = [];
|
|
123
145
|
// verify_regression e verify_failed conferem a mesma coisa: um aviso so, com o nome da primeira declarada.
|
|
124
146
|
let baselineJaAvaliada = false;
|
|
147
|
+
// claim_sem_prova_local e claims_failed idem.
|
|
148
|
+
let provaLocalJaAvaliada = false;
|
|
125
149
|
for (const [nome, bruta] of Object.entries(declaradas)) {
|
|
126
150
|
const conhecida = exports.POLICIES_CONHECIDAS[nome];
|
|
127
151
|
if (!conhecida || !conhecida.quando.includes(ctx.gate))
|
|
@@ -224,6 +248,33 @@ function avaliarPolicies(manifesto, ctx) {
|
|
|
224
248
|
}
|
|
225
249
|
continue;
|
|
226
250
|
}
|
|
251
|
+
if (exports.POLICIES_DE_PROVA_LOCAL.includes(nome)) {
|
|
252
|
+
if (provaLocalJaAvaliada)
|
|
253
|
+
continue;
|
|
254
|
+
provaLocalJaAvaliada = true;
|
|
255
|
+
const r = ctx.provaLocalReprovada;
|
|
256
|
+
if (r) {
|
|
257
|
+
const id = ctx.threadId ?? '<thread>';
|
|
258
|
+
violacoes.push({
|
|
259
|
+
policy: nome,
|
|
260
|
+
// O registro de claim nunca para: `block` declarado avisa como `warn`.
|
|
261
|
+
severidade: 'warn',
|
|
262
|
+
motivo: r.estourou ? 'verify.timeout' : 'claims.failed',
|
|
263
|
+
detalhe: r.semDiretorio
|
|
264
|
+
? `a worktree da thread (${r.semDiretorio}) nao existe; o comando da claim ${r.claim} nao rodou e a claim entrou sem prova local`
|
|
265
|
+
: r.estourou
|
|
266
|
+
? `o comando da claim ${r.claim} estourou o prazo do verify (${Math.round(r.prazoMs / 1000)} s) no registro; a claim entrou sem prova local`
|
|
267
|
+
: `o comando da claim ${r.claim} saiu ${r.code} no registro; a claim entrou sem prova local e reprova no verify`,
|
|
268
|
+
correcao: r.semDiretorio
|
|
269
|
+
? `recrie a worktree da thread (ou feche a thread que perdeu a worktree); depois, ork verify ${id}`
|
|
270
|
+
: r.estourou
|
|
271
|
+
? `divida o comando ou suba verify.timeout_ms; depois, ork verify ${id}`
|
|
272
|
+
: `corrija o produto ou o comando e anexe o certo com ork claims verificar ${id} ${r.claim} --comando "<comando>"; ` +
|
|
273
|
+
`se a alegacao nao vale, ork claims retirar ${id} ${r.claim} --motivo "<motivo>"`,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
227
278
|
if (nome === 'tree_blocked') {
|
|
228
279
|
if (ctx.branchAtrasDaBase === true) {
|
|
229
280
|
violacoes.push({
|
package/dist/portfolio.js
CHANGED
|
@@ -44,6 +44,7 @@ exports.assertCycleScope = assertCycleScope;
|
|
|
44
44
|
/** Catálogo determinístico de produto -> projeto -> iniciativa. */
|
|
45
45
|
const fs = __importStar(require("node:fs"));
|
|
46
46
|
const project_state_1 = require("./project-state");
|
|
47
|
+
const estado_thread_1 = require("./estado-thread");
|
|
47
48
|
const company_brain_journal_1 = require("./company-brain-journal");
|
|
48
49
|
const util_1 = require("./util");
|
|
49
50
|
const creation_operation_store_1 = require("./creation-operation-store");
|
|
@@ -65,7 +66,9 @@ function readPortfolio(root) {
|
|
|
65
66
|
}
|
|
66
67
|
function persist(root, value) { value.updatedAt = (0, util_1.agora)(); (0, company_brain_journal_1.replaceWithJournal)(file(root), value); return value; }
|
|
67
68
|
function mutatePortfolio(root, run) {
|
|
68
|
-
|
|
69
|
+
// RM-036 (D5): o portfolio.json e canonico, e o lock de espera tambem: chamado da raiz ou de uma worktree,
|
|
70
|
+
// quem chega depois espera a vez, em vez de recusar com brain.journal.busy no lock interno.
|
|
71
|
+
return (0, creation_operation_store_1.withCreationLock)((0, estado_thread_1.raizDoEstado)(root), 'portfolio', () => (0, company_brain_journal_1.portfolioMutation)(file(root), run));
|
|
69
72
|
}
|
|
70
73
|
function validateBase(kind, input) {
|
|
71
74
|
if (!ID.test(input.id) || !input.id.startsWith(PREFIX[kind]))
|
package/dist/projeto-alvo.js
CHANGED
|
@@ -75,6 +75,7 @@ exports.linhasDaConsulta = linhasDaConsulta;
|
|
|
75
75
|
const fs = __importStar(require("node:fs"));
|
|
76
76
|
const os = __importStar(require("node:os"));
|
|
77
77
|
const path = __importStar(require("node:path"));
|
|
78
|
+
const branch_de_estado_1 = require("./branch-de-estado");
|
|
78
79
|
const estado_thread_1 = require("./estado-thread");
|
|
79
80
|
const manifest_1 = require("./manifest");
|
|
80
81
|
const maquina_1 = require("./maquina");
|
|
@@ -198,7 +199,10 @@ function remotoSemCredencial(url) {
|
|
|
198
199
|
}
|
|
199
200
|
/** URL do remoto, sem credencial. `null` quando o projeto nao tem aquele remoto. */
|
|
200
201
|
function remotoDoProjeto(raiz, remoto = 'origin') {
|
|
201
|
-
|
|
202
|
+
// RM-047: o nome vem do manifesto; fora do formato de remoto, nada vai ao git.
|
|
203
|
+
if (!(0, branch_de_estado_1.remotoValido)(remoto))
|
|
204
|
+
return null;
|
|
205
|
+
const r = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], raiz, 5000);
|
|
202
206
|
const url = r.ok ? r.stdout.trim() : '';
|
|
203
207
|
return url ? remotoSemCredencial(url) : null;
|
|
204
208
|
}
|
package/dist/prompts.js
CHANGED
|
@@ -49,11 +49,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
49
49
|
};
|
|
50
50
|
})();
|
|
51
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
-
exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
|
|
52
|
+
exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
|
|
53
|
+
exports.pedidoComDicaDoGrafo = pedidoComDicaDoGrafo;
|
|
53
54
|
exports.dirDeTemplates = dirDeTemplates;
|
|
54
55
|
exports.variaveisUsadas = variaveisUsadas;
|
|
55
56
|
exports.renderizar = renderizar;
|
|
56
57
|
exports.parseTemplate = parseTemplate;
|
|
58
|
+
exports.procurarHitlEmTextoLivre = procurarHitlEmTextoLivre;
|
|
57
59
|
exports.lintTemplate = lintTemplate;
|
|
58
60
|
exports.carregarTemplatesDe = carregarTemplatesDe;
|
|
59
61
|
exports.carregarTemplates = carregarTemplates;
|
|
@@ -69,6 +71,15 @@ const policies_1 = require("./policies");
|
|
|
69
71
|
const types_1 = require("./types");
|
|
70
72
|
/** Limite duro de um template, o mesmo do manifesto: prosa longa nao vira prompt. */
|
|
71
73
|
exports.LIMITE_TEMPLATE_BYTES = 16384;
|
|
74
|
+
/** KG5 fatia 2: dica opt-in no pedido; desligada preserva o texto byte a byte. */
|
|
75
|
+
function pedidoComDicaDoGrafo(pedido, thread, ligado) {
|
|
76
|
+
if (!ligado)
|
|
77
|
+
return pedido;
|
|
78
|
+
return pedido.trimEnd() + '\n\n## Contexto do grafo (opcional)\n'
|
|
79
|
+
+ `Consulte ork_grafo_contexto {threadId: "${thread}"} ou ork grafo contexto ${thread} --json para o pacote da thread com evidencias e teto em bytes.\n`
|
|
80
|
+
+ 'As tools ork_grafo_vizinhos, ork_grafo_chamadores, ork_grafo_importadores e ork_grafo_caminho permitem aprofundar. '
|
|
81
|
+
+ 'Sem indice do HEAD, rode ork grafo indexar. O grafo e parcial; com arvore modificada, descreve o HEAD.\n';
|
|
82
|
+
}
|
|
72
83
|
/** Onde um projeto guarda os templates que sobrescrevem os embutidos. */
|
|
73
84
|
function dirDeTemplates(raiz) {
|
|
74
85
|
return path.join(raiz, 'prompts');
|
|
@@ -170,6 +181,27 @@ exports.CONTRATO_DE_FASE = {
|
|
|
170
181
|
variavelObrigatoria: 'pedido',
|
|
171
182
|
validaFases: true,
|
|
172
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* RM-057: os jeitos de um template pedir ao dono texto livre ou texto colado. Lista fechada, como o
|
|
186
|
+
* vocabulario do pulse: acrescentar um padrao e decisao de contrato, com teste. Casa sobre a linha
|
|
187
|
+
* em minusculas e sem acento.
|
|
188
|
+
*/
|
|
189
|
+
exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = Object.freeze([
|
|
190
|
+
{ oQue: 'que o dono cole texto', padrao: /\b(cole|colar|colem)\b[^.\n]{0,60}\b(texto|aqui|mensagem|pedido|resposta|saida|conteudo)\b/ },
|
|
191
|
+
{ oQue: 'que o dono cole texto', padrao: /\bpaste\b/ },
|
|
192
|
+
{ oQue: 'confirmacao em texto livre', padrao: /\b(responda|digite|escreva|confirme|responder|digitar|escrever)\b[^.\n]{0,40}(\bconfirmo\b|texto livre|\bem texto\b)/ },
|
|
193
|
+
{ oQue: 'confirmacao em texto livre', padrao: /\b(peca|peco|pedir|solicite|solicitar)\b[^.\n]{0,30}\bconfirmacao\b[^.\n]{0,20}\b(por escrito|em texto|textual)\b/ },
|
|
194
|
+
]);
|
|
195
|
+
function procurarHitlEmTextoLivre(corpo) {
|
|
196
|
+
const achados = [];
|
|
197
|
+
corpo.split('\n').forEach((bruta, i) => {
|
|
198
|
+
const linha = bruta.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
|
|
199
|
+
const casou = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE.find(p => p.padrao.test(linha));
|
|
200
|
+
if (casou)
|
|
201
|
+
achados.push({ linha: i + 1, oQue: casou.oQue });
|
|
202
|
+
});
|
|
203
|
+
return achados;
|
|
204
|
+
}
|
|
173
205
|
/**
|
|
174
206
|
* Lint de um template. Devolve os problemas; lista vazia quer dizer aprovado.
|
|
175
207
|
*
|
|
@@ -231,6 +263,9 @@ function lintTemplate(t, contrato = exports.CONTRATO_DE_FASE) {
|
|
|
231
263
|
if (bytes > exports.LIMITE_TEMPLATE_BYTES) {
|
|
232
264
|
erro('tamanho', `${bytes} bytes acima do limite de ${exports.LIMITE_TEMPLATE_BYTES}`);
|
|
233
265
|
}
|
|
266
|
+
for (const achado of procurarHitlEmTextoLivre(t.corpo)) {
|
|
267
|
+
erro('hitl-texto-livre', `linha ${achado.linha} pede ${achado.oQue}; HITL de conducao e selecao de 3 a 5 alternativas com uma Recomendacao (RM-057)`);
|
|
268
|
+
}
|
|
234
269
|
if (t.bruto.includes('—')) {
|
|
235
270
|
aviso('idioma', 'o template usa travessao longo (U+2014); o padrao do projeto e hifen ou virgula');
|
|
236
271
|
}
|
package/dist/prova-ativacao.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.ENTRADAS = exports.HOSTS_DA_PROVA = void 0;
|
|
37
37
|
exports.transcriptDoClaude = transcriptDoClaude;
|
|
38
38
|
exports.transcriptDoOpenclaw = transcriptDoOpenclaw;
|
|
39
|
+
exports.transcriptDoCodex = transcriptDoCodex;
|
|
39
40
|
exports.extrairSnapshot = extrairSnapshot;
|
|
40
41
|
exports.conferirProva = conferirProva;
|
|
41
42
|
exports.redigir = redigir;
|
|
@@ -44,7 +45,7 @@ exports.redigirObjeto = redigirObjeto;
|
|
|
44
45
|
* RM-032: conferência da prova de ativação por host, sem host.
|
|
45
46
|
*
|
|
46
47
|
* O roteiro `core/scripts/prova-ativacao.cjs` abre uma sessão nova e não interativa no host
|
|
47
|
-
* (Claude Code ou
|
|
48
|
+
* (Claude Code, OpenClaw ou Codex), diz `orkastery maestro` e entrega aqui o transcript. Esta
|
|
48
49
|
* conferência olha só o que é determinístico: qual ferramenta o modelo chamou, o resultado que
|
|
49
50
|
* ela devolveu (contra o contrato da entrada) e o projeto lido. Da resposta final em texto
|
|
50
51
|
* livre, exige apenas que cite o projeto e não repita o incidente de 29/09 ("roadmap vazio").
|
|
@@ -52,20 +53,31 @@ exports.redigirObjeto = redigirObjeto;
|
|
|
52
53
|
const fs = __importStar(require("node:fs"));
|
|
53
54
|
const path = __importStar(require("node:path"));
|
|
54
55
|
const maestro_contract_1 = require("./maestro-contract");
|
|
55
|
-
exports.HOSTS_DA_PROVA = ['claude-code', 'openclaw'];
|
|
56
|
+
exports.HOSTS_DA_PROVA = ['claude-code', 'openclaw', 'codex'];
|
|
56
57
|
/**
|
|
57
58
|
* As entradas da frase em cada host. No Claude, a tool MCP do servidor `orkastery` fixado no
|
|
58
59
|
* projeto (MAESTRO_HOST_SURFACES em hosts.ts). No OpenClaw 0.5.0 (RM-054, fatia 2), a frase sem
|
|
59
60
|
* projeto vai a `ork_network_roadmap`, a única tool da extensão no perfil `coding`; com projeto
|
|
60
|
-
* nomeado, a `ork_maestro`.
|
|
61
|
-
*
|
|
61
|
+
* nomeado, a `ork_maestro`. No Codex (B11), a tool `ork_maestro` do servidor `orkastery` que o
|
|
62
|
+
* `ork mcp install --host codex` grava no projeto; o nome segue o padrão `mcp__<servidor>__<tool>`.
|
|
63
|
+
* `ork maestro` pelo shell do host é desvio: o CLI resolve o projeto pelo diretório atual, a classe
|
|
64
|
+
* de erro do incidente.
|
|
62
65
|
*/
|
|
63
66
|
exports.ENTRADAS = {
|
|
64
67
|
'claude-code': [{ ferramenta: 'mcp__orkastery__ork_maestro', contrato: 'maestro' }],
|
|
65
68
|
openclaw: [{ ferramenta: 'ork_network_roadmap', contrato: 'rede' }, { ferramenta: 'ork_maestro', contrato: 'maestro' }],
|
|
69
|
+
codex: [{ ferramenta: 'mcp__orkastery__ork_maestro', contrato: 'maestro' }],
|
|
66
70
|
};
|
|
67
|
-
const SHELL_DO_HOST = { 'claude-code': 'Bash', openclaw: 'exec' };
|
|
68
|
-
|
|
71
|
+
const SHELL_DO_HOST = { 'claude-code': 'Bash', openclaw: 'exec', codex: 'command_execution' };
|
|
72
|
+
// B11: o shell do Codex chega embrulhado (`bash -lc 'ork maestro'`), então aspas também abrem o comando.
|
|
73
|
+
// Suspeitas da revisão de 03/10: o mesmo CLI roda também pelo caminho do binário (`$(which ork)`), pelo
|
|
74
|
+
// node (`core/dist/index.js`), pelo npx (`@orkastery/cli`) e com o projeto entre aspas. É desvio a
|
|
75
|
+
// invocação do ork cujo subcomando, depois só de opções (com valor, até entre aspas), é `maestro`;
|
|
76
|
+
// `maestro` dentro do argumento de outro subcomando não é.
|
|
77
|
+
const INVOCACAO_DO_ORK = String.raw `(?:(?:^|[^\w.@-])ork|@orkastery\/cli(?:@[\w.-]+)?|\bdist\/index\.js)(?![\w.-])[)\x60]?`;
|
|
78
|
+
const VALOR = String.raw `(?:"[^"]*"|'[^']*'|[^\s"'-][^\s"']*)`;
|
|
79
|
+
const OPCOES = String.raw `(?:\s+-[\w-]*(?:=(?:"[^"]*"|'[^']*'|[^\s"']+))?(?:\s+${VALOR})?)*`;
|
|
80
|
+
const ORK_MAESTRO_NO_SHELL = new RegExp(String.raw `${INVOCACAO_DO_ORK}${OPCOES}\s+maestro(?![\w.-])`);
|
|
69
81
|
function linhasJson(texto) {
|
|
70
82
|
const eventos = [];
|
|
71
83
|
for (const linha of texto.split('\n')) {
|
|
@@ -172,6 +184,63 @@ function transcriptDoOpenclaw(eventsJsonl, agenteJson) {
|
|
|
172
184
|
const textos = (agente.payloads ?? []).map(p => p?.text).filter((t) => typeof t === 'string');
|
|
173
185
|
return { ferramentasExpostas, chamadas, respostaFinal: textos.length ? textos.join('\n') : null };
|
|
174
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Eventos do `codex exec --json` (B11): `item.started`/`item.completed` com `mcp_tool_call` (servidor,
|
|
189
|
+
* tool, argumentos, resultado, erro), `command_execution` (o shell do host) e `agent_message` (a
|
|
190
|
+
* resposta). O `codex exec` não lista as ferramentas expostas ao modelo: quem chama passa as do
|
|
191
|
+
* `tools/list` do mesmo servidor MCP que a sessão recebeu, já com o nome `mcp__<servidor>__<tool>`.
|
|
192
|
+
*/
|
|
193
|
+
function transcriptDoCodex(eventosJsonl, ferramentasExpostas) {
|
|
194
|
+
const porItem = new Map();
|
|
195
|
+
const chamadas = [];
|
|
196
|
+
const mensagens = [];
|
|
197
|
+
for (const e of linhasJson(eventosJsonl)) {
|
|
198
|
+
if (e.type !== 'item.started' && e.type !== 'item.completed')
|
|
199
|
+
continue;
|
|
200
|
+
const item = (e.item ?? {});
|
|
201
|
+
const id = typeof item.id === 'string' ? item.id : null;
|
|
202
|
+
if (item.type === 'agent_message') {
|
|
203
|
+
if (e.type === 'item.completed' && typeof item.text === 'string')
|
|
204
|
+
mensagens.push(item.text);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
let ferramenta, argumentos, resultado = null, erro = false;
|
|
208
|
+
if (item.type === 'mcp_tool_call' && typeof item.server === 'string' && typeof item.tool === 'string') {
|
|
209
|
+
ferramenta = `mcp__${item.server}__${item.tool}`;
|
|
210
|
+
argumentos = item.arguments ?? null;
|
|
211
|
+
const r = item.result;
|
|
212
|
+
resultado = typeof r === 'string' ? r : textoDoConteudo(r?.content);
|
|
213
|
+
const falha = item.error;
|
|
214
|
+
erro = !!falha || item.status === 'failed';
|
|
215
|
+
if (erro && resultado === null)
|
|
216
|
+
resultado = typeof falha === 'string' ? falha : typeof falha?.message === 'string' ? falha.message : 'falhou';
|
|
217
|
+
}
|
|
218
|
+
else if (item.type === 'command_execution' && typeof item.command === 'string') {
|
|
219
|
+
ferramenta = 'command_execution';
|
|
220
|
+
argumentos = { command: item.command };
|
|
221
|
+
resultado = typeof item.aggregated_output === 'string' ? item.aggregated_output : null;
|
|
222
|
+
erro = item.status === 'failed' || (typeof item.exit_code === 'number' && item.exit_code !== 0);
|
|
223
|
+
}
|
|
224
|
+
else
|
|
225
|
+
continue;
|
|
226
|
+
const tipo = classificar('codex', ferramenta, argumentos);
|
|
227
|
+
if (!tipo)
|
|
228
|
+
continue;
|
|
229
|
+
const anterior = id ? porItem.get(id) : undefined;
|
|
230
|
+
if (anterior) {
|
|
231
|
+
// `item.completed` do mesmo item fecha a chamada aberta no `item.started`.
|
|
232
|
+
if (e.type === 'item.completed')
|
|
233
|
+
Object.assign(anterior, { argumentos, resultado, erro });
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const chamada = { ferramenta, ...tipo, argumentos, resultado: e.type === 'item.completed' ? resultado : null,
|
|
237
|
+
erro: e.type === 'item.completed' ? erro : false };
|
|
238
|
+
if (id)
|
|
239
|
+
porItem.set(id, chamada);
|
|
240
|
+
chamadas.push(chamada);
|
|
241
|
+
}
|
|
242
|
+
return { ferramentasExpostas, chamadas, respostaFinal: mensagens.length ? mensagens.at(-1) : null };
|
|
243
|
+
}
|
|
175
244
|
/** O primeiro objeto `ork.maestro-snapshot/v1` do texto (o host pode juntar stderr ao stdout). */
|
|
176
245
|
function extrairSnapshot(texto) {
|
|
177
246
|
const inicio = texto.indexOf('{"schema":"ork.maestro-snapshot/v1"');
|
package/dist/pulse-delivery.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.assinaturaPulse = assinaturaPulse;
|
|
|
38
38
|
exports.assinaturaDoResumo = assinaturaDoResumo;
|
|
39
39
|
exports.mensagemPulse = mensagemPulse;
|
|
40
40
|
exports.varrerPulse = varrerPulse;
|
|
41
|
+
exports.varrerEDepoisPublicarNaRede = varrerEDepoisPublicarNaRede;
|
|
41
42
|
exports.enviarPayloadHost = enviarPayloadHost;
|
|
42
43
|
const manifest_1 = require("./manifest");
|
|
43
44
|
const write_activation_1 = require("./write-activation");
|
|
@@ -59,6 +60,8 @@ const hitl_contract_1 = require("./hitl-contract");
|
|
|
59
60
|
const monitor_lock_1 = require("./monitor-lock");
|
|
60
61
|
const fabrica_estado_1 = require("./fabrica-estado");
|
|
61
62
|
const maquina_1 = require("./maquina");
|
|
63
|
+
const rede_1 = require("./rede");
|
|
64
|
+
const rede_adesao_1 = require("./rede-adesao");
|
|
62
65
|
const pulse_cadencia_1 = require("./pulse-cadencia");
|
|
63
66
|
// O lock dos monitores mudou de modulo (I-41, GO-FIX 1); quem o importava daqui continua importando.
|
|
64
67
|
var monitor_lock_2 = require("./monitor-lock");
|
|
@@ -253,7 +256,9 @@ function varrerPulse(opcoes) {
|
|
|
253
256
|
const guardadas = anterior ? fila.candidatos.filter(c => anterior.candidatos.some(a => a.thread === c.thread)).length : 0;
|
|
254
257
|
const resumo = (0, hitl_resumo_1.resumirHitl)(itens, { quando, janelaMin, prontas: fila.candidatos.length, acumuladas: guardadas,
|
|
255
258
|
consertos: fila.consertos, atoDoItem: i => fila.atos.get(`${i.thread}|${i.fase}`),
|
|
256
|
-
decisoes: decisoesNovas, acimaDoLimiar: pulse.acimaDoLimiar ?? [], outrasMaquinas: outras, paradosNoCondutor: parados
|
|
259
|
+
decisoes: decisoesNovas, acimaDoLimiar: pulse.acimaDoLimiar ?? [], outrasMaquinas: outras, paradosNoCondutor: parados,
|
|
260
|
+
// RM-057 (fatia 3): a linha so acompanha o resumo que ja sai; nao e novidade nem fura a cadencia.
|
|
261
|
+
...(pulse.hitlDeConducao ? { hitlDeConducao: pulse.hitlDeConducao } : {}) });
|
|
257
262
|
// Pedir licenca para mandar zero perguntas era o defeito: sem pergunta, nao ha codigo.
|
|
258
263
|
// I-50: cadencia curta nao encurta o prazo do dono para responder ao resumo (minimo de 60 min).
|
|
259
264
|
const consentimento = fila.candidatos.length ? (0, monitor_lock_1.comLockDaConversa)(dir, () => (0, pulse_consentimento_1.abrirConsentimento)(raiz, { quando,
|
|
@@ -287,6 +292,22 @@ function varrerPulse(opcoes) {
|
|
|
287
292
|
trava.liberar();
|
|
288
293
|
}
|
|
289
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* RM-053: a entrega ao dono vem primeiro, e a rede depois, mesmo quando a varredura falha. M4 do
|
|
297
|
+
* CHECK 1: antes da entrega, uma forja lenta atrasava o HITL em minutos. S13 da revisao 2: sem o
|
|
298
|
+
* `finally`, uma excecao na varredura suprimia tambem a batida da rede.
|
|
299
|
+
*/
|
|
300
|
+
function varrerEDepoisPublicarNaRede(varrer, publicar) {
|
|
301
|
+
try {
|
|
302
|
+
return varrer();
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
try {
|
|
306
|
+
publicar();
|
|
307
|
+
}
|
|
308
|
+
catch { /* a rede registra a propria falha no rede.log */ }
|
|
309
|
+
}
|
|
310
|
+
}
|
|
290
311
|
if (require.main === module) {
|
|
291
312
|
try {
|
|
292
313
|
const raiz = process.argv[2] ?? process.cwd();
|
|
@@ -317,7 +338,18 @@ if (require.main === module) {
|
|
|
317
338
|
}
|
|
318
339
|
const outrasMaquinas = compartilhada
|
|
319
340
|
? () => (0, fabrica_estado_1.resumoDasOutrasMaquinas)((0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto, semRemoto: true }), (0, maquina_1.nomeDaMaquina)()) : undefined;
|
|
320
|
-
|
|
341
|
+
// RM-053 (D9): depois da entrega ao dono, a mesma batida publica o retrato desta maquina na rede da
|
|
342
|
+
// pessoa (so membro, uma tentativa a cada 14 min, retrato igual so de hora em hora).
|
|
343
|
+
const r = varrerEDepoisPublicarNaRede(() => varrerPulse({ raiz, escopo, comCadencia: true, outrasMaquinas }), () => {
|
|
344
|
+
try {
|
|
345
|
+
const rede = (0, rede_1.publicarRedeNaBatida)({ diretorio: carregado.raiz });
|
|
346
|
+
if (rede)
|
|
347
|
+
(0, rede_adesao_1.registrarNaRede)({ ...rede, origem: 'pulse' });
|
|
348
|
+
}
|
|
349
|
+
catch (e) {
|
|
350
|
+
(0, rede_adesao_1.registrarNaRede)({ acao: 'falhou', origem: 'pulse', erro: e.message });
|
|
351
|
+
}
|
|
352
|
+
});
|
|
321
353
|
console.log(JSON.stringify(r));
|
|
322
354
|
process.exitCode = r.code;
|
|
323
355
|
}
|
package/dist/pulse.js
CHANGED
|
@@ -13,6 +13,7 @@ const liveness_1 = require("./liveness");
|
|
|
13
13
|
const master_1 = require("./master");
|
|
14
14
|
const master_batch_1 = require("./master-batch");
|
|
15
15
|
const orquestracao_1 = require("./orquestracao");
|
|
16
|
+
const impedimento_1 = require("./impedimento");
|
|
16
17
|
const thread_1 = require("./thread");
|
|
17
18
|
const sessoes_adopt_1 = require("./sessoes-adopt");
|
|
18
19
|
const ledger_1 = require("./ledger");
|
|
@@ -27,6 +28,7 @@ const docs_1 = require("./docs");
|
|
|
27
28
|
const conducao_1 = require("./conducao");
|
|
28
29
|
const conducao_texto_1 = require("./conducao-texto");
|
|
29
30
|
const hitl_resumo_1 = require("./hitl-resumo");
|
|
31
|
+
const hitl_tempo_parado_1 = require("./hitl-tempo-parado");
|
|
30
32
|
const parado_no_condutor_1 = require("./parado-no-condutor");
|
|
31
33
|
exports.CONTRATO_PULSE = 'ork.pulse/v1';
|
|
32
34
|
/** Uma semana: o resumo cita a decisao uma vez, e ela continua lida ate sair da janela. */
|
|
@@ -169,6 +171,19 @@ function comporPulse(carregado, entrada) {
|
|
|
169
171
|
thread: l.thread, fase: p.fase, sessionId: null, desdeEm: p.desdeEm, paradaHaMin: p.paradaHaMin, impacto: impacto(p.fase),
|
|
170
172
|
pergunta: p.detalhe, opcoes: [], recomendacao: p.correcao, comandoResposta: p.correcao, evidencia: [p.evidencia],
|
|
171
173
|
fontes: ['monitor'], contextoLogs: [] };
|
|
174
|
+
// RM-055: o impedimento do despacho sai no contrato curto, com o comando exato e o re-despacho depois.
|
|
175
|
+
if (p.impedimento) {
|
|
176
|
+
try {
|
|
177
|
+
const curto = (0, impedimento_1.pedidoCurtoDoImpedimento)({ thread: l.thread, fase: p.fase, motivo: p.motivo, detalhe: p.detalhe,
|
|
178
|
+
desdeEm: p.desdeEm, impedimento: p.impedimento }, quando);
|
|
179
|
+
item.apresentacaoCurta = { telegram: (0, hitl_curto_1.textoDoPedidoCurto)(curto, 'telegram'), terminal: (0, hitl_curto_1.textoDoPedidoCurto)(curto, 'terminal') };
|
|
180
|
+
item.opcoes = curto.alternativas.map(a => `${a.chave}. ${a.texto}`);
|
|
181
|
+
item.comandoResposta = `ork retry run ${l.thread}`;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
item.evidencia.push('Pedido curto do impedimento indisponível; a correção acima vale.');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
172
187
|
// I-45: vaga parada e sinal do escalonador (`ork board reap` devolve a vaga), nao pergunta ao dono.
|
|
173
188
|
const esperaAutomatica = ['lease.busy', 'conducao.em-andamento', 'concurrency.limite', 'runtime.rate-limited', 'vaga.stale'].includes(p.motivo);
|
|
174
189
|
(esperaAutomatica ? automaticas : humanos).push(item);
|
|
@@ -276,11 +291,26 @@ function montarPulse(carregado, opcoes = {}) {
|
|
|
276
291
|
(0, parado_no_condutor_1.gravarRetratoDePrs)(carregado.raiz, leitura.retrato);
|
|
277
292
|
}
|
|
278
293
|
catch { /* o retrato e economia do status */ }
|
|
294
|
+
try {
|
|
295
|
+
(0, parado_no_condutor_1.esquecerForjaSemLeitura)(carregado.raiz);
|
|
296
|
+
}
|
|
297
|
+
catch { /* sem a marca, a proxima perda de leitura e dita de novo */ }
|
|
279
298
|
}
|
|
280
299
|
return leitura;
|
|
281
300
|
} });
|
|
282
|
-
|
|
283
|
-
|
|
301
|
+
const leitura = entregas.prs;
|
|
302
|
+
if (leitura && !leitura.ok && leitura.semLeitura) {
|
|
303
|
+
// RM-037 (fatia 5, A5): a forja sem leitura de PR e dita uma vez por remoto e host; as batidas seguintes nao repetem.
|
|
304
|
+
let novidade = true;
|
|
305
|
+
try {
|
|
306
|
+
novidade = (0, parado_no_condutor_1.avisarForjaSemLeitura)(carregado.raiz, leitura.semLeitura, leitura.erro, quando);
|
|
307
|
+
}
|
|
308
|
+
catch { /* sem marca, diz de novo */ }
|
|
309
|
+
if (novidade)
|
|
310
|
+
diagnosticos.push(`prs.sem-leitura: ${leitura.erro.slice(0, 160)}`);
|
|
311
|
+
}
|
|
312
|
+
else if (leitura && !leitura.ok)
|
|
313
|
+
diagnosticos.push(`prs.nao-lidos: ${leitura.erro.slice(0, 160)}`);
|
|
284
314
|
}
|
|
285
315
|
catch (e) {
|
|
286
316
|
diagnosticos.push(`entregas.indisponiveis: ${e.message.slice(0, 120)}`);
|
|
@@ -298,6 +328,15 @@ function montarPulse(carregado, opcoes = {}) {
|
|
|
298
328
|
catch (e) {
|
|
299
329
|
diagnosticos.push(`decisoes.indisponiveis: ${e.message.slice(0, 120)}`);
|
|
300
330
|
}
|
|
331
|
+
// RM-057 (fatia 3): leitura pura do ledger; falhar aqui nunca derruba a fila de atencao.
|
|
332
|
+
try {
|
|
333
|
+
const hitl = (0, hitl_tempo_parado_1.lerHitlDeConducaoAgora)(carregado.raiz, quando);
|
|
334
|
+
if (hitl.abertas.length || hitl.seteDias.pedidos || hitl.seteDias.respondidos)
|
|
335
|
+
pulse.hitlDeConducao = hitl;
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
diagnosticos.push(`hitl-conducao.indisponivel: ${e.message.slice(0, 120)}`);
|
|
339
|
+
}
|
|
301
340
|
if (diagnosticos.length)
|
|
302
341
|
pulse.runtime.detalhe = [pulse.runtime.detalhe, ...diagnosticos].filter(Boolean).join('; ');
|
|
303
342
|
return pulse;
|
|
@@ -307,7 +346,7 @@ function textoDoPulse(p) {
|
|
|
307
346
|
const local = (texto) => (0, horario_1.localizarTexto)(texto, { agora: p.consultadoEm });
|
|
308
347
|
const linhas = [`Pulse (${p.contrato}) ${(0, horario_1.formatarDataHoraRotulada)(p.consultadoEm, { agora: p.consultadoEm })}`, `Precisa de humano agora: ${p.resumo.humanos}`, `${p.resumo.scores} entrega(s) sem nota, aceitas por padrão com registro`];
|
|
309
348
|
// RM-037 (fatia 4): PR nao lido tambem e dito, para a falta de linha do condutor nao parecer "nada parado".
|
|
310
|
-
if (p.runtime.ok && ['liveness.snapshot.invalid', 'prs.nao-lidos', 'entregas.indisponiveis'].some(d => p.runtime.detalhe.includes(d))) {
|
|
349
|
+
if (p.runtime.ok && ['liveness.snapshot.invalid', 'prs.nao-lidos', 'prs.sem-leitura', 'entregas.indisponiveis'].some(d => p.runtime.detalhe.includes(d))) {
|
|
311
350
|
linhas.push(`[diagnostico] ${local(p.runtime.detalhe)}`);
|
|
312
351
|
}
|
|
313
352
|
if (!p.runtime.ok)
|
|
@@ -326,6 +365,13 @@ function textoDoPulse(p) {
|
|
|
326
365
|
for (const x of p.paradoNoCondutor)
|
|
327
366
|
linhas.push((0, hitl_resumo_1.linhaDoParadoNoCondutor)(x, { agora: p.consultadoEm }));
|
|
328
367
|
}
|
|
368
|
+
// RM-057 (fatia 3): quanto tempo cada pergunta de conducao aberta ja parou a thread, e a mediana da semana.
|
|
369
|
+
if (p.hitlDeConducao) {
|
|
370
|
+
const h = p.hitlDeConducao;
|
|
371
|
+
linhas.push('', `HITL de condução: ${h.abertas.length} aberta(s); ${(0, hitl_tempo_parado_1.textoDaMediana)(h)}`);
|
|
372
|
+
for (const a of h.abertas)
|
|
373
|
+
linhas.push((0, hitl_tempo_parado_1.linhaDaPerguntaParada)(a, { agora: p.consultadoEm }));
|
|
374
|
+
}
|
|
329
375
|
linhas.push('', `Ações automáticas pendentes: ${p.resumo.automaticas}`);
|
|
330
376
|
for (const i of p.acoesAutomaticas)
|
|
331
377
|
linhas.push(`${i.thread}: ${i.motivo}; ${i.comandoResposta}`);
|
package/dist/ratelimit.js
CHANGED
|
@@ -61,6 +61,7 @@ exports.lerFilaDeRetomada = lerFilaDeRetomada;
|
|
|
61
61
|
exports.janelaPadraoMs = janelaPadraoMs;
|
|
62
62
|
exports.enfileirar = enfileirar;
|
|
63
63
|
exports.prazoDaConta = prazoDaConta;
|
|
64
|
+
exports.prazoDaCotaVista = prazoDaCotaVista;
|
|
64
65
|
exports.marcarContaDaFalha = marcarContaDaFalha;
|
|
65
66
|
exports.gravarPedido = gravarPedido;
|
|
66
67
|
exports.exigirPedido = exigirPedido;
|
|
@@ -151,15 +152,30 @@ function prazoDaConta(manifesto, falha, agoraMs = Date.now()) {
|
|
|
151
152
|
return falha.resetEm;
|
|
152
153
|
return new Date(agoraMs + janelaPadraoMs(manifesto)).toISOString();
|
|
153
154
|
}
|
|
154
|
-
/**
|
|
155
|
-
|
|
155
|
+
/**
|
|
156
|
+
* RM-037 (fatia 5): ate quando a conta sai do rodizio pela cota que o observador viu na transcricao, com a
|
|
157
|
+
* sessao viva. Vale a hora dita (ja ancorada no instante da mensagem) ou a janela padrao contada da mensagem,
|
|
158
|
+
* nunca do relogio de quem leu. Prazo que ja venceu volta `null`: a conta ja voltou, e marcar agora tiraria do
|
|
159
|
+
* rodizio uma conta boa (a regra A10 do despacho recusado nao vale aqui, porque ninguem acabou de recusar nada).
|
|
160
|
+
*/
|
|
161
|
+
function prazoDaCotaVista(manifesto, falha, mensagemMs, agoraMs = Date.now()) {
|
|
162
|
+
if (falha.motivo !== 'runtime.quota-exhausted' || !Number.isFinite(mensagemMs))
|
|
163
|
+
return null;
|
|
164
|
+
const prazo = falha.resetEm ?? new Date(mensagemMs + janelaPadraoMs(manifesto)).toISOString();
|
|
165
|
+
return Date.parse(prazo) > agoraMs ? prazo : null;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Marca no store o perfil que falhou pela conta. Sem perfil (ambiente do processo), nada a marcar. `prazo`,
|
|
169
|
+
* quando vem, e o ja calculado por quem viu a falha (`prazoDaCotaVista`); sem ele, vale `prazoDaConta`.
|
|
170
|
+
*/
|
|
171
|
+
function marcarContaDaFalha(carregado, perfil, falha, agoraMs = Date.now(), prazo) {
|
|
156
172
|
// RM-037 (defeitosdeco D-6): modelo inacessivel nao e falha da conta inteira; o perfil fica no rodizio.
|
|
157
173
|
if (!perfil || falha.motivo === 'runtime.model-unavailable')
|
|
158
174
|
return null;
|
|
159
175
|
const esgotado = falha.motivo === 'runtime.quota-exhausted';
|
|
160
176
|
return (0, runtime_profiles_1.marcarFalhaDePerfil)(carregado.raiz, perfil.id, { estado: esgotado ? 'esgotado' : 'sem-auth',
|
|
161
|
-
esgotadoAte: prazoDaConta(carregado.manifesto, falha, agoraMs), motivo: falha.motivo,
|
|
162
|
-
em: new Date(agoraMs).toISOString() });
|
|
177
|
+
esgotadoAte: esgotado && prazo ? prazo : prazoDaConta(carregado.manifesto, falha, agoraMs), motivo: falha.motivo,
|
|
178
|
+
detalhe: falha.trecho, em: new Date(agoraMs).toISOString() });
|
|
163
179
|
}
|
|
164
180
|
/** Regrava um pedido (append-only: a versao nova vence, o historico fica). */
|
|
165
181
|
function gravarPedido(raiz, pedido) {
|
package/dist/recall.js
CHANGED
|
@@ -257,7 +257,9 @@ function recallDaThread(carregado, memoria, threadId, opcoes = {}) {
|
|
|
257
257
|
falhas.push({ id: 'memoria-busca', titulo: 'Descoberta de handoffs da fase', location: '',
|
|
258
258
|
orkmind: null, retrieve_when: fase, resolvido: false, motivo: 'orkmind-indisponivel', via: null,
|
|
259
259
|
conteudo: '', metodo: '', sha256: '', intervalo: null,
|
|
260
|
-
|
|
260
|
+
// RM-038: a janela cheia do export tem codigo proprio; o resto segue como falha de transporte.
|
|
261
|
+
detalhe: `${memoria.leituraRestrita ? falhaDeConsulta(erro) : erro instanceof Error && erro.message === 'memory.query.window-saturated'
|
|
262
|
+
? erro.message : 'memory.transport.export'}: busca semantica falhou; resultado nao comprova colecao vazia` });
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
if (opcoes.id !== undefined && resolvidos.length === 0 && falhas.length === 0 && adiados.length === 0) {
|