@orkastery/cli 0.5.1 → 0.5.6
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/README.md +158 -0
- 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/claude-code/mods/autoridade.json +56 -0
- package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
- package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
- package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
- package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
- package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
- package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
- package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
- package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
- package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
- package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
- package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
- package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
- package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
- package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
- package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
- package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
- package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
- package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
- package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
- package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
- package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
- package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
- package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
- package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
- package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
- package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
- package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
- package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
- package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
- package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
- package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
- package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
- package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -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 +7 -6
- package/adapters/openclaw/README.md +26 -5
- 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/docs-en/markdownlint-cli2.jsonc +22 -0
- package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
- package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
- package/assets/docs-en/produto/README.md +14 -0
- package/assets/docs-en/produto/_modelo-feature.md +62 -0
- package/assets/docs-en/roadmap/README.md +14 -0
- package/assets/docs-en/roadmap/_modelo-item.md +75 -0
- package/assets/orkmind_bridge.py +117 -9
- package/dist/adapters/claude-bg.js +116 -18
- package/dist/adapters/codex.js +14 -4
- package/dist/agents-md.js +24 -14
- package/dist/auditrun.js +22 -3
- package/dist/board.js +20 -17
- package/dist/branch-de-estado.js +88 -10
- package/dist/busca-semantica.js +52 -12
- package/dist/canarios-rm057.js +149 -0
- package/dist/canarios.js +2 -0
- package/dist/catalogo.js +33 -0
- package/dist/ci.js +21 -8
- package/dist/claims-conferir.js +342 -0
- package/dist/claims.js +41 -1
- package/dist/company-brain-client.js +36 -1
- package/dist/company-brain-context.js +158 -22
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +36 -1
- package/dist/conducao-sentinela.js +388 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +122 -30
- package/dist/conhecimento.js +490 -0
- package/dist/docs.js +70 -17
- package/dist/doctor-pulse-cron.js +349 -0
- package/dist/doctor-rede.js +150 -0
- package/dist/doctor.js +195 -111
- package/dist/entrega-pr.js +42 -29
- package/dist/escopo-escrita.js +10 -1
- package/dist/esgotamentos.js +181 -0
- package/dist/estado-thread.js +23 -1
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/experiencia.js +12 -2
- package/dist/fabrica-batida.js +310 -0
- package/dist/fabrica-estado.js +52 -14
- package/dist/fabrica-publicar.js +9 -1
- package/dist/fechamento.js +20 -66
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +3 -2
- package/dist/forja.js +31 -7
- package/dist/gates.js +3 -24
- package/dist/handoff.js +10 -6
- package/dist/hitl-contract.js +59 -4
- package/dist/hitl-curto.js +11 -6
- package/dist/hitl-gates.js +5 -0
- package/dist/hitl-local-receipt.js +2 -0
- package/dist/hitl-lote.js +5 -2
- package/dist/hitl-resumo.js +38 -3
- package/dist/hitl-tempo-parado.js +201 -0
- package/dist/hitl-texto-livre.js +5 -5
- package/dist/hitl.js +29 -33
- package/dist/horario.js +41 -7
- package/dist/hosts.js +104 -11
- package/dist/impedimento.js +299 -0
- package/dist/index.js +961 -542
- package/dist/indice-vetorial.js +87 -10
- package/dist/indice.js +9 -1
- package/dist/init.js +56 -43
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +170 -16
- package/dist/intelligence-graph-contexto.js +254 -0
- package/dist/intelligence-graph-contract.js +2 -1
- package/dist/intelligence-graph-extract-md.js +56 -4
- package/dist/intelligence-graph-extract-ts.js +71 -3
- package/dist/intelligence-graph-parsers.js +6 -4
- package/dist/intelligence-graph-query.js +66 -19
- package/dist/leases.js +664 -87
- package/dist/ledger-stats.js +15 -1
- package/dist/ledger.js +18 -1
- package/dist/licoes.js +1 -0
- package/dist/liveness.js +6 -3
- package/dist/locale-ajuda.js +761 -0
- package/dist/locale-gerados.js +160 -0
- package/dist/locale-master.js +99 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-pulse.js +211 -0
- package/dist/locale-retry.js +385 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-ship.js +494 -0
- package/dist/locale-thread.js +277 -0
- package/dist/locale-verify.js +125 -0
- package/dist/locale.js +714 -0
- package/dist/maestro-runtime.js +4 -1
- package/dist/manifest.js +149 -4
- package/dist/maquina.js +23 -4
- package/dist/master-digest.js +6 -1
- package/dist/master-nota.js +18 -11
- package/dist/master.js +145 -31
- package/dist/mcp-artifacts.js +43 -3
- package/dist/mcp-git.js +42 -8
- package/dist/mcp-grafo-worker.js +5 -3
- package/dist/mcp-grafo.js +55 -6
- package/dist/mcp-server.js +22 -3
- package/dist/mcp-ship.js +3 -1
- package/dist/mcp-verify.js +6 -1
- package/dist/memoria.js +48 -6
- package/dist/modos.js +3 -6
- package/dist/network-roadmap.js +196 -18
- package/dist/noctum-arco.js +911 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-envelope.js +810 -0
- package/dist/noctum-execucao.js +304 -0
- package/dist/noctum-fila.js +280 -0
- package/dist/ocupacao.js +40 -5
- package/dist/onboarding.js +40 -21
- package/dist/orkmind.js +99 -7
- package/dist/orquestracao.js +24 -21
- package/dist/parado-no-condutor.js +219 -38
- package/dist/phase.js +160 -52
- package/dist/policies.js +56 -5
- package/dist/portfolio.js +8 -3
- package/dist/postura-local.js +234 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +225 -0
- package/dist/projeto-alvo.js +132 -5
- package/dist/prompts.js +40 -1
- package/dist/prova-ativacao.js +75 -6
- package/dist/pulse-delivery.js +47 -4
- package/dist/pulse.js +98 -19
- package/dist/ratelimit.js +24 -6
- package/dist/recall.js +3 -1
- package/dist/redacao-saida.js +63 -0
- 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 +337 -0
- package/dist/rede.js +980 -0
- package/dist/retry.js +291 -140
- package/dist/roadmap-reservas.js +20 -3
- package/dist/roadmap-status.js +150 -34
- package/dist/runtime-context.js +181 -3
- package/dist/runtime-profiles.js +22 -1
- package/dist/runtimes.js +2 -1
- package/dist/saida-segura.js +58 -0
- package/dist/session-events.js +7 -3
- package/dist/session-watcher-claude.js +120 -24
- package/dist/session-watcher.js +185 -33
- package/dist/sessoes-contas.js +187 -0
- package/dist/sessoes-inventario.js +6 -18
- package/dist/sessoes.js +83 -2
- package/dist/ship-publicar.js +800 -0
- package/dist/ship.js +157 -88
- package/dist/steal.js +77 -0
- package/dist/thread-close.js +3 -2
- package/dist/thread.js +299 -49
- package/dist/util.js +8 -1
- package/dist/verify.js +141 -52
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +165 -0
- package/dist/worktree.js +25 -2
- package/dist/yaml.js +27 -8
- package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
- package/package.json +7 -3
- package/references/definition-of-done.md +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +2 -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/ship.js
CHANGED
|
@@ -50,6 +50,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
50
50
|
};
|
|
51
51
|
})();
|
|
52
52
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.MODOS_QUE_AUTORIZAM_PUSH = void 0;
|
|
54
|
+
exports.commitQueIncorporou = commitQueIncorporou;
|
|
53
55
|
exports.autorizacaoDePush = autorizacaoDePush;
|
|
54
56
|
exports.arvoreComBranch = arvoreComBranch;
|
|
55
57
|
exports.prepararArvore = prepararArvore;
|
|
@@ -62,6 +64,7 @@ exports.ship = ship;
|
|
|
62
64
|
exports.textoDoShip = textoDoShip;
|
|
63
65
|
const fs = __importStar(require("node:fs"));
|
|
64
66
|
const path = __importStar(require("node:path"));
|
|
67
|
+
const node_child_process_1 = require("node:child_process");
|
|
65
68
|
const gates_1 = require("./gates");
|
|
66
69
|
const leases_1 = require("./leases");
|
|
67
70
|
const ledger_1 = require("./ledger");
|
|
@@ -76,6 +79,46 @@ const contrato_publico_1 = require("./contrato-publico");
|
|
|
76
79
|
const prova_minima_1 = require("./prova-minima");
|
|
77
80
|
const horario_1 = require("./horario");
|
|
78
81
|
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
82
|
+
const branch_de_estado_1 = require("./branch-de-estado");
|
|
83
|
+
const locale_1 = require("./locale");
|
|
84
|
+
/**
|
|
85
|
+
* RM-037 (fatia 5, A1): o commit de primeiro pai da base que incorporou o `shaDe`: o merge que trouxe a branch, ou
|
|
86
|
+
* o proprio `shaDe` quando a base avancou por fast-forward ate ele. Com a branch ja incorporada, a ponta da base e
|
|
87
|
+
* outra coisa: no `ship_done` da ork-docsusuarios (27/09/2026), o unico do `ork ship` com `jaIncorporado` nos ledgers
|
|
88
|
+
* deste projeto, ela era o merge de outra thread. O que trouxe a branch e o commit mais velho do primeiro pai da base
|
|
89
|
+
* que descende do `shaDe`. GO-FIX (rodada 1 do CHECK): `--first-parent` junto com `--ancestry-path` so propaga a
|
|
90
|
+
* descendencia pelos commits de primeiro pai, e o merge do PR que recebeu "Update branch" no GitHub (o pai dele e um
|
|
91
|
+
* merge que descende do `shaDe`, nao o `shaDe`) sumia da lista; agora sao duas listas e a intersecao. `null` quando o
|
|
92
|
+
* git nao responde.
|
|
93
|
+
*/
|
|
94
|
+
function commitQueIncorporou(raiz, shaDe, ponta, passos = []) {
|
|
95
|
+
if (shaDe === ponta)
|
|
96
|
+
return shaDe;
|
|
97
|
+
// `passos` recebe os comandos que de fato rodaram, na ordem: e a evidencia do ship (sugestao da conferencia da rodada 2).
|
|
98
|
+
const curto = (sha) => sha.slice(0, 8);
|
|
99
|
+
// As listas crescem com o historico entre a branch e a ponta: o buffer vai alem do 1 MiB padrao do spawnSync.
|
|
100
|
+
const listar = (args) => {
|
|
101
|
+
passos.push(`git ${args.map((a) => a.replace(/^([0-9a-f]{40,64})\.\.([0-9a-f]{40,64})$/, (_, x, y) => `${curto(x)}..${curto(y)}`)).join(' ')}`);
|
|
102
|
+
const r = (0, node_child_process_1.spawnSync)('git', args, { cwd: raiz, encoding: 'utf8', timeout: 120000, maxBuffer: 256 * 1024 * 1024 });
|
|
103
|
+
return r.status === 0 && !r.error ? r.stdout.split('\n').filter((l) => /^[0-9a-f]{40,64}$/.test(l)) : null;
|
|
104
|
+
};
|
|
105
|
+
const primeiroPai = listar(['rev-list', '--first-parent', `${shaDe}..${ponta}`]);
|
|
106
|
+
const descendentes = listar(['rev-list', '--ancestry-path', `${shaDe}..${ponta}`]);
|
|
107
|
+
if (!primeiroPai || !descendentes)
|
|
108
|
+
return null;
|
|
109
|
+
const doShaDe = new Set(descendentes);
|
|
110
|
+
// Do mais velho para o mais novo: o primeiro de primeiro pai que descende do `shaDe`.
|
|
111
|
+
const maisVelho = [...primeiroPai].reverse().find((c) => doShaDe.has(c));
|
|
112
|
+
if (!maisVelho)
|
|
113
|
+
return null;
|
|
114
|
+
// O primeiro pai dele e o proprio `shaDe`: a branch ja estava no primeiro pai da base (fast-forward). Sem a resposta
|
|
115
|
+
// do git, nada e gravado: devolver o mais velho poria no `mergeSha` o filho do `shaDe` (sugestao da rodada 2).
|
|
116
|
+
passos.push(`git rev-parse ${curto(maisVelho)}^1`);
|
|
117
|
+
const pai = (0, util_1.exec)('git', ['rev-parse', `${maisVelho}^1`], raiz);
|
|
118
|
+
if (!pai.ok)
|
|
119
|
+
return null;
|
|
120
|
+
return pai.stdout.trim() === shaDe ? shaDe : maisVelho;
|
|
121
|
+
}
|
|
79
122
|
/** Os caminhos de contrato publico que a entrega traz sobre a base (diff desde o merge-base). */
|
|
80
123
|
function contratosDaEntrega(raiz, shaPara, shaDe) {
|
|
81
124
|
const base = (0, util_1.exec)('git', ['merge-base', shaPara, shaDe], raiz);
|
|
@@ -84,8 +127,8 @@ function contratosDaEntrega(raiz, shaPara, shaDe) {
|
|
|
84
127
|
const diff = (0, util_1.exec)('git', ['diff', '--name-only', '--no-renames', base.stdout.trim(), shaDe], raiz);
|
|
85
128
|
return diff.ok ? (0, contrato_publico_1.contratosTocados)(diff.stdout.split('\n').map((l) => l.trim()).filter(Boolean)) : [];
|
|
86
129
|
}
|
|
87
|
-
/** Modos em que a propria #TAG do pedido autoriza o push antecipadamente. */
|
|
88
|
-
|
|
130
|
+
/** Modos em que a propria #TAG do pedido autoriza o push antecipadamente (o `ork ship publicar` usa a mesma lista). */
|
|
131
|
+
exports.MODOS_QUE_AUTORIZAM_PUSH = ['maestro', 'auto'];
|
|
89
132
|
/**
|
|
90
133
|
* Quem autoriza o push desta thread.
|
|
91
134
|
*
|
|
@@ -104,15 +147,15 @@ function autorizacaoDePush(raiz, thread, opcoes) {
|
|
|
104
147
|
autorizado: true,
|
|
105
148
|
tipo: 'humano-no-cli',
|
|
106
149
|
por: opcoes.autorizarPush.trim(),
|
|
107
|
-
razao:
|
|
150
|
+
razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoNaLinha(tag)),
|
|
108
151
|
};
|
|
109
152
|
}
|
|
110
|
-
if (MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
|
|
153
|
+
if (exports.MODOS_QUE_AUTORIZAM_PUSH.includes(thread.modo)) {
|
|
111
154
|
return {
|
|
112
155
|
autorizado: true,
|
|
113
156
|
tipo: 'modo',
|
|
114
|
-
por:
|
|
115
|
-
razao:
|
|
157
|
+
por: (0, locale_1.textoDoCatalogo)((m) => m.ship.porTag(tag)),
|
|
158
|
+
razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoPeloModo(tag)),
|
|
116
159
|
};
|
|
117
160
|
}
|
|
118
161
|
if (thread.modo === 'classic') {
|
|
@@ -121,8 +164,9 @@ function autorizacaoDePush(raiz, thread, opcoes) {
|
|
|
121
164
|
return {
|
|
122
165
|
autorizado: true,
|
|
123
166
|
tipo: 'humano-antecipado',
|
|
124
|
-
por: String(antecipada.autorizadoPor
|
|
125
|
-
|
|
167
|
+
por: antecipada.autorizadoPor !== undefined && antecipada.autorizadoPor !== null ? String(antecipada.autorizadoPor)
|
|
168
|
+
: (0, locale_1.textoDoCatalogo)((m) => m.ship.humano),
|
|
169
|
+
razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizadoAntes(String(antecipada.ts))),
|
|
126
170
|
};
|
|
127
171
|
}
|
|
128
172
|
}
|
|
@@ -130,8 +174,7 @@ function autorizacaoDePush(raiz, thread, opcoes) {
|
|
|
130
174
|
autorizado: false,
|
|
131
175
|
tipo: 'pendente',
|
|
132
176
|
por: '',
|
|
133
|
-
razao:
|
|
134
|
-
`Autorize na entrega: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
|
|
177
|
+
razao: (0, locale_1.textoDoCatalogo)((m) => m.ship.semAutorizacao(tag, thread.id)),
|
|
135
178
|
};
|
|
136
179
|
}
|
|
137
180
|
/** Diretorio temporario onde a arvore de merge e montada quando preciso. */
|
|
@@ -178,16 +221,16 @@ function prepararArvore(raiz, para) {
|
|
|
178
221
|
const dona = arvoreComBranch(raiz, para);
|
|
179
222
|
if (dona) {
|
|
180
223
|
if (temAlteracaoNaoCommitada(dona)) {
|
|
181
|
-
throw new
|
|
182
|
-
'commite ou reverta la antes do ship');
|
|
224
|
+
throw new locale_1.ErroDoCatalogo((m) => m.ship.arvoreSuja(para, dona));
|
|
183
225
|
}
|
|
184
226
|
return { dir: dona, temporaria: false };
|
|
185
227
|
}
|
|
186
228
|
const dir = dirTemporarioDeShip(raiz, para);
|
|
187
229
|
fs.mkdirSync(path.dirname(dir), { recursive: true });
|
|
188
|
-
const r = (0, util_1.exec)('git', ['worktree', 'add', dir, para], raiz);
|
|
230
|
+
const r = (0, util_1.exec)('git', ['worktree', 'add', '--', dir, para], raiz);
|
|
189
231
|
if (!r.ok) {
|
|
190
|
-
|
|
232
|
+
const erro = (r.stderr || r.stdout).trim();
|
|
233
|
+
throw new locale_1.ErroDoCatalogo((m) => m.ship.arvoreNaoMontada(para, erro));
|
|
191
234
|
}
|
|
192
235
|
return { dir, temporaria: true };
|
|
193
236
|
}
|
|
@@ -211,18 +254,18 @@ function shaDaRef(dir, ref) {
|
|
|
211
254
|
* codigo de saida do `git push` nao prova que o remoto ficou com o commit certo.
|
|
212
255
|
*/
|
|
213
256
|
function shaNoRemoto(dir, remoto, branch) {
|
|
214
|
-
|
|
257
|
+
// RM-047: so nome de remoto chega ao git, e depois do `--` (nunca vira opcao nem transporte).
|
|
258
|
+
const r = (0, util_1.exec)('git', ['ls-remote', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship'), `refs/heads/${branch}`], dir, 120000);
|
|
215
259
|
if (!r.ok)
|
|
216
260
|
return null;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const sha = linha.split(/\s+/)[0];
|
|
261
|
+
// RM-059 (S1 da revisao da ork-rm059pista): o padrao do ls-remote casa por sufixo; vale so a linha da ref exata.
|
|
262
|
+
const linha = r.stdout.split('\n').map((l) => l.trim().split(/\s+/)).find((partes) => partes[1] === `refs/heads/${branch}`);
|
|
263
|
+
const sha = linha?.[0] ?? '';
|
|
221
264
|
return /^[0-9a-f]{40}$/.test(sha) ? sha : null;
|
|
222
265
|
}
|
|
223
266
|
/** O remoto esta configurado neste repositorio? */
|
|
224
267
|
function remotoConfigurado(dir, remoto) {
|
|
225
|
-
return (0, util_1.exec)('git', ['remote', 'get-url', remoto], dir).ok;
|
|
268
|
+
return (0, util_1.exec)('git', ['remote', 'get-url', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship')], dir).ok;
|
|
226
269
|
}
|
|
227
270
|
function baseDoResultado(thread, de, opcoes) {
|
|
228
271
|
return {
|
|
@@ -237,6 +280,7 @@ function baseDoResultado(thread, de, opcoes) {
|
|
|
237
280
|
shaDe: '',
|
|
238
281
|
shaParaAntes: '',
|
|
239
282
|
mergeSha: null,
|
|
283
|
+
pontaDaBase: null,
|
|
240
284
|
jaIncorporado: false,
|
|
241
285
|
remoto: opcoes.remoto ?? 'origin',
|
|
242
286
|
shaRemoto: null,
|
|
@@ -277,7 +321,9 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
|
|
|
277
321
|
const entregas = (0, ledger_1.lerLedger)(dir)
|
|
278
322
|
.filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && typeof e.mergeSha === 'string')
|
|
279
323
|
.map((e) => ({ mergeSha: String(e.mergeSha), para: para ?? String(e.para ?? '') }))
|
|
280
|
-
|
|
324
|
+
// RM-047 (fronteira de confiança): o ledger pode vir do clone. Só sha hexadecimal e nome de branch
|
|
325
|
+
// chegam ao `git log`; qualquer outro valor viraria opção dele e é ignorado.
|
|
326
|
+
.filter((e) => e.para.length > 0 && (0, branch_de_estado_1.shaValido)(e.mergeSha) && (0, branch_de_estado_1.branchValida)(e.para));
|
|
281
327
|
if (entregas.length === 0)
|
|
282
328
|
return null;
|
|
283
329
|
const perguntados = new Set();
|
|
@@ -287,7 +333,7 @@ function detectarReversaoDaEntrega(raiz, thread, para) {
|
|
|
287
333
|
continue;
|
|
288
334
|
perguntados.add(intervalo);
|
|
289
335
|
// O historico e append-only: o merge continua la, e o revert vem DEPOIS dele.
|
|
290
|
-
const log = (0, util_1.exec)('git', ['log', '--format=%H%x1f%B%x1e', intervalo], raiz, 60000);
|
|
336
|
+
const log = (0, util_1.exec)('git', ['log', '--format=%H%x1f%B%x1e', '--end-of-options', intervalo], raiz, 60000);
|
|
291
337
|
if (!log.ok)
|
|
292
338
|
continue;
|
|
293
339
|
for (const bruto of log.stdout.split('\x1e')) {
|
|
@@ -329,7 +375,10 @@ function ship(carregado, threadId, opcoes) {
|
|
|
329
375
|
const dir = (0, thread_1.dirThread)(raiz, threadId);
|
|
330
376
|
const de = opcoes.de ?? thread.base.branch;
|
|
331
377
|
const para = opcoes.para;
|
|
332
|
-
|
|
378
|
+
// RM-047: o `--remoto` vem da linha de comando. Antes de qualquer git (inclusive a leitura da reversao),
|
|
379
|
+
// so nome de remoto passa; o resto recusa com `ship.remoto-invalido`, e o ship nao entrega sem push provado
|
|
380
|
+
// por um remoto que nunca existiu.
|
|
381
|
+
const remoto = (0, branch_de_estado_1.exigirRemoto)(opcoes.remoto ?? 'origin', 'ship');
|
|
333
382
|
const r = baseDoResultado(thread, de, opcoes);
|
|
334
383
|
// I-43 (T7): antes de qualquer coisa, se a entrega ANTERIOR desta thread foi
|
|
335
384
|
// revertida na base, isso vira `rollback_done`. E o insumo de maior peso do indice
|
|
@@ -366,7 +415,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
366
415
|
const autorizacao = autorizacaoDePush(raiz, thread, opcoes);
|
|
367
416
|
r.autorizacao = autorizacao;
|
|
368
417
|
if (!autorizacao.autorizado) {
|
|
369
|
-
return bloquear('human.pending', autorizacao.razao,
|
|
418
|
+
return bloquear('human.pending', autorizacao.razao, (0, locale_1.textoDoCatalogo)((m) => m.ship.autorizeNaEntrega(threadId)));
|
|
370
419
|
}
|
|
371
420
|
// 2. Policies do manifesto que valem no gate `ship`. RM-008 (fatia 3): a branch da thread
|
|
372
421
|
// atras da base e fato do git, calculado aqui (a ponta da base nao esta contida na branch).
|
|
@@ -417,20 +466,21 @@ function ship(carregado, threadId, opcoes) {
|
|
|
417
466
|
return bloquear('policy.violation', bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; '), bloqueiam.map((v) => v.correcao).join('; '));
|
|
418
467
|
}
|
|
419
468
|
// 3. Verificacao independente: reexecuta claims e comandos no HEAD real da thread.
|
|
420
|
-
const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify
|
|
469
|
+
const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify,
|
|
470
|
+
conducao: { filaPesada: { ...opcoes.avisoDaFilaPesada, esperarMs: opcoes.esperarFilaPesadaMs } } });
|
|
421
471
|
r.verificacao = verificacao;
|
|
422
472
|
if (!verificacao.ok) {
|
|
423
473
|
const motivo = verificacao.motivos.find((m) => m !== 'claims.unverifiable');
|
|
424
|
-
return bloquear(motivo,
|
|
474
|
+
return bloquear(motivo, (0, locale_1.textoDoCatalogo)((m) => m.ship.verificacaoReprovou(verificacao.commit, verificacao.motivos.join(', '))), (0, locale_1.textoDoCatalogo)((m) => m.ship.rodeVerify(threadId)));
|
|
425
475
|
}
|
|
426
476
|
// Referencias locais, resolvidas antes de tomar o lease.
|
|
427
477
|
const shaDe = shaDaRef(raiz, `refs/heads/${de}`);
|
|
428
478
|
const shaPara = shaDaRef(raiz, `refs/heads/${para}`);
|
|
429
479
|
if (!shaDe) {
|
|
430
|
-
return bloquear('artifact.missing',
|
|
480
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.origemAusente(de)), (0, locale_1.textoDoCatalogo)((m) => m.ship.origemAusenteCorrecao));
|
|
431
481
|
}
|
|
432
482
|
if (!shaPara) {
|
|
433
|
-
return bloquear('artifact.missing',
|
|
483
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.destinoAusente(para)), (0, locale_1.textoDoCatalogo)((m) => m.ship.destinoAusenteCorrecao));
|
|
434
484
|
}
|
|
435
485
|
r.shaDe = shaDe;
|
|
436
486
|
r.shaParaAntes = shaPara;
|
|
@@ -438,31 +488,37 @@ function ship(carregado, threadId, opcoes) {
|
|
|
438
488
|
// por git direto. Ciclo sem PLAN nem CHECK nao entrega contrato publico.
|
|
439
489
|
const tocados = (0, prova_minima_1.cicloSemCheck)(thread) ? contratosDaEntrega(raiz, shaPara, shaDe) : [];
|
|
440
490
|
if (tocados.length > 0) {
|
|
441
|
-
return bloquear('policy.violation',
|
|
491
|
+
return bloquear('policy.violation', (0, locale_1.textoDoCatalogo)((m) => m.ship.contratoPublico(tocados.join(', '))), (0, locale_1.textoDoCatalogo)((m) => m.ship.contratoPublicoCorrecao));
|
|
442
492
|
}
|
|
443
493
|
// O recibo vem do provedor e pertence ao SHA exato da candidata. Teste local
|
|
444
494
|
// verde ou status de outro commit não libera a entrega.
|
|
445
495
|
const ci = (0, ci_1.consultarCi)(carregado, shaDe, remoto, opcoes.executorCi);
|
|
446
496
|
r.ci = ci;
|
|
447
497
|
if (!ci.ok) {
|
|
448
|
-
return bloquear('ci.failed',
|
|
498
|
+
return bloquear('ci.failed', (0, locale_1.textoDoCatalogo)((m) => m.ship.ciReprovou((0, locale_1.remontar)(ci.detail), shaDe, ci.context)), (0, locale_1.textoDoCatalogo)((m) => m.ship.ciReprovouCorrecao(ci.context)));
|
|
449
499
|
}
|
|
450
500
|
// 4. Lease `main-tree`: so uma thread mergeia por vez.
|
|
451
501
|
if (r.dryRun) {
|
|
452
|
-
const ocupado = (0, leases_1.
|
|
502
|
+
const ocupado = (0, leases_1.leasesColidentes)(raiz, leases_1.LEASE_MAIN_TREE)[0] ?? null;
|
|
453
503
|
r.leaseOcupadoPor = ocupado;
|
|
454
504
|
// O ensaio tambem responde ONDE o merge aconteceria e se aquela arvore esta limpa:
|
|
455
505
|
// descobrir isso so na hora do merge real seria descobrir tarde demais.
|
|
456
506
|
const dona = arvoreComBranch(raiz, para);
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
r.detalhe =
|
|
507
|
+
const suja = dona ? temAlteracaoNaoCommitada(dona) : false;
|
|
508
|
+
const temporaria = path.join((0, manifest_1.dirEstado)(raiz), 'tmp');
|
|
509
|
+
const arvoreDoMerge = (m) => dona ? m.ship.arvoreDona(dona, para, suja) : m.ship.arvoreTemporaria(temporaria, para);
|
|
510
|
+
r.detalhe = (0, locale_1.textoDoCatalogo)((m) => m.ship.arvoreDeMerge(arvoreDoMerge(m)));
|
|
511
|
+
// Ensaio de 03/10 (R5): sem remoto (ou com --sem-push), o ensaio diz o mesmo que o ship real, e nao
|
|
512
|
+
// promete um push e uma prova que nao vao acontecer.
|
|
513
|
+
const semPushNoReal = opcoes.semPush || !remotoConfigurado(raiz, remoto)
|
|
514
|
+
? (m) => opcoes.semPush ? m.ship.semPushPorFlag : m.ship.semRemoto(remoto) : null;
|
|
461
515
|
r.passos = [
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
516
|
+
r.detalhe,
|
|
517
|
+
(0, locale_1.textoDoCatalogo)((m) => m.ship.passoMerge(de)),
|
|
518
|
+
...(semPushNoReal ? [(0, locale_1.textoDoCatalogo)((m) => m.ship.passoSemPush(semPushNoReal(m)))] : [
|
|
519
|
+
`git push ${remoto} ${para}`,
|
|
520
|
+
(0, locale_1.textoDoCatalogo)((m) => m.ship.passoProvaDoPush(remoto, para)),
|
|
521
|
+
]),
|
|
466
522
|
];
|
|
467
523
|
(0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipIniciado, {
|
|
468
524
|
de,
|
|
@@ -493,11 +549,9 @@ function ship(carregado, threadId, opcoes) {
|
|
|
493
549
|
posicao: aquisicao.posicaoNaFila,
|
|
494
550
|
naFrente: (0, leases_1.esperandoPor)(raiz, leases_1.LEASE_MAIN_TREE).length,
|
|
495
551
|
bloqueadaPor: dono?.thread ?? '(desconhecida)',
|
|
496
|
-
motivo: 'lease.busy',
|
|
552
|
+
motivo: aquisicao.motivo ?? 'lease.busy',
|
|
497
553
|
});
|
|
498
|
-
return bloquear('lease.busy',
|
|
499
|
-
`desde ${dono?.adquiridoEm ?? '?'} (${dono?.motivo ?? 'sem motivo'}); ` +
|
|
500
|
-
`esta thread entrou na merge queue na posicao ${aquisicao.posicaoNaFila}`, `espere a vez na fila (ork lease list), ou libere com: ork lease release ${leases_1.LEASE_MAIN_TREE} --forcar`);
|
|
554
|
+
return bloquear(aquisicao.motivo ?? 'lease.busy', aquisicao.falhaRetomada ? aquisicao.detalhe : (0, locale_1.textoDoCatalogo)((m) => m.ship.leaseComOutra(leases_1.LEASE_MAIN_TREE, dono?.thread ?? m.ship.desconhecida, dono?.adquiridoEm ?? '?', dono?.motivo ?? m.ship.semMotivo, aquisicao.posicaoNaFila)), aquisicao.correcao);
|
|
501
555
|
}
|
|
502
556
|
r.lease = aquisicao.lease;
|
|
503
557
|
(0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.leaseAdquirido, {
|
|
@@ -524,7 +578,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
524
578
|
}
|
|
525
579
|
catch (e) {
|
|
526
580
|
// Arvore de destino indisponivel e reprovacao tipada, nao excecao vazando pelo CLI.
|
|
527
|
-
return bloquear('tree.blocked', e
|
|
581
|
+
return bloquear('tree.blocked', e instanceof locale_1.ErroDoCatalogo ? (0, locale_1.textoDoCatalogo)(e.montar) : e.message, (0, locale_1.textoDoCatalogo)((m) => m.ship.arvoreCorrecao));
|
|
528
582
|
}
|
|
529
583
|
const passos = [];
|
|
530
584
|
opcoes.revalidarGit?.('merge', arvore.dir);
|
|
@@ -532,6 +586,9 @@ function ship(carregado, threadId, opcoes) {
|
|
|
532
586
|
const jaIncorporado = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, shaPara], raiz).ok;
|
|
533
587
|
r.jaIncorporado = jaIncorporado;
|
|
534
588
|
let mergeSha = shaPara;
|
|
589
|
+
// RM-037 (fatia 5, A1): a ponta que o push prova. Com o merge feito aqui, e ele; com a branch ja incorporada, a
|
|
590
|
+
// ponta de antes, que pode trazer outros merges depois do que entregou esta thread.
|
|
591
|
+
let pontaDaBase = shaPara;
|
|
535
592
|
if (!jaIncorporado) {
|
|
536
593
|
const mensagem = opcoes.mensagem ??
|
|
537
594
|
`ship(${threadId}): merge de ${de} em ${para}\n\n` +
|
|
@@ -539,59 +596,68 @@ function ship(carregado, threadId, opcoes) {
|
|
|
539
596
|
`modo: ${(0, modos_1.tagDoModo)(thread.modo)}\n` +
|
|
540
597
|
`autorizado por: ${autorizacao.por} (${autorizacao.tipo})\n` +
|
|
541
598
|
`verificado em: HEAD ${verificacao.commit}\n`;
|
|
542
|
-
|
|
599
|
+
// RM-047: o merge e do sha verificado, e nao do nome que veio de `--de` (nome nunca vira opcao do git).
|
|
600
|
+
const merge = (0, util_1.exec)('git', ['merge', '--no-ff', '-m', mensagem, shaDe], arvore.dir, 300000);
|
|
543
601
|
passos.push(`git merge --no-ff ${de}`);
|
|
544
602
|
if (!merge.ok) {
|
|
545
603
|
(0, util_1.exec)('git', ['merge', '--abort'], arvore.dir);
|
|
546
604
|
r.passos = [...passos, 'git merge --abort'];
|
|
547
|
-
|
|
605
|
+
const erro = (merge.stderr || merge.stdout).trim().slice(0, 400);
|
|
606
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.mergeFalhou(de, para, erro)), (0, locale_1.textoDoCatalogo)((m) => m.ship.mergeFalhouCorrecao));
|
|
548
607
|
}
|
|
549
608
|
const novo = shaDaRef(arvore.dir, 'HEAD');
|
|
550
609
|
if (!novo) {
|
|
551
|
-
return bloquear('artifact.missing',
|
|
610
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.headIlegivel), (0, locale_1.textoDoCatalogo)((m) => m.ship.confiraRepositorio));
|
|
552
611
|
}
|
|
553
612
|
mergeSha = novo;
|
|
613
|
+
pontaDaBase = novo;
|
|
554
614
|
// Verificacao independente do merge: a origem precisa ser ancestral do resultado.
|
|
555
615
|
const incorporou = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, mergeSha], arvore.dir).ok;
|
|
556
616
|
passos.push(`git merge-base --is-ancestor ${shaDe.slice(0, 8)} ${mergeSha.slice(0, 8)}`);
|
|
557
617
|
if (!incorporou) {
|
|
558
|
-
return bloquear('artifact.missing',
|
|
618
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.naoAncestral(de, mergeSha)), (0, locale_1.textoDoCatalogo)((m) => m.ship.naoEmpurre));
|
|
559
619
|
}
|
|
560
620
|
}
|
|
561
621
|
else {
|
|
562
|
-
|
|
622
|
+
// RM-037 (fatia 5, A1): o merge que trouxe a branch, e nao a ponta da base.
|
|
623
|
+
const incorporadoEm = commitQueIncorporou(raiz, shaDe, shaPara, passos);
|
|
624
|
+
if (!incorporadoEm) {
|
|
625
|
+
return bloquear('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPai(de, para)), (0, locale_1.textoDoCatalogo)((m) => m.ship.semPrimeiroPaiCorrecao));
|
|
626
|
+
}
|
|
627
|
+
mergeSha = incorporadoEm;
|
|
628
|
+
const incorporado = mergeSha.slice(0, 8);
|
|
629
|
+
passos.push((0, locale_1.textoDoCatalogo)((m) => m.ship.passoJaIncorporado(de, para, incorporado)));
|
|
563
630
|
}
|
|
564
631
|
r.mergeSha = mergeSha;
|
|
632
|
+
r.pontaDaBase = pontaDaBase;
|
|
565
633
|
opcoes.revalidarGit?.('push', arvore.dir);
|
|
566
634
|
// 6. Push PROVADO por ls-remote.
|
|
567
635
|
const temRemoto = remotoConfigurado(arvore.dir, remoto);
|
|
568
636
|
r.remoto = temRemoto ? remoto : null;
|
|
569
637
|
if (opcoes.semPush || !temRemoto) {
|
|
570
638
|
r.pushVerificado = false;
|
|
571
|
-
r.detalhe = opcoes.semPush
|
|
572
|
-
? 'push nao executado por --sem-push (merge local concluido)'
|
|
573
|
-
: `remoto "${remoto}" nao configurado: merge local concluido, sem push a provar`;
|
|
639
|
+
r.detalhe = (0, locale_1.textoDoCatalogo)((m) => opcoes.semPush ? m.ship.semPushPorFlag : m.ship.semRemoto(remoto));
|
|
574
640
|
}
|
|
575
641
|
else {
|
|
576
642
|
const existeNoRemoto = shaNoRemoto(arvore.dir, remoto, para) !== null;
|
|
577
643
|
const argsPush = existeNoRemoto
|
|
578
|
-
? ['push', remoto,
|
|
579
|
-
: ['push', '-u', remoto,
|
|
644
|
+
? ['push', '--', remoto, `refs/heads/${para}:refs/heads/${para}`]
|
|
645
|
+
: ['push', '-u', '--', remoto, `refs/heads/${para}:refs/heads/${para}`];
|
|
580
646
|
const push = (0, util_1.exec)('git', argsPush, arvore.dir, 300000);
|
|
581
647
|
passos.push(`git ${argsPush.join(' ')}`);
|
|
582
648
|
if (!push.ok) {
|
|
583
649
|
r.passos = passos;
|
|
584
|
-
|
|
650
|
+
const erro = (push.stderr || push.stdout).trim().slice(0, 400);
|
|
651
|
+
return bloquear('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => m.ship.pushFalhou(remoto, para, erro)), (0, locale_1.textoDoCatalogo)((m) => m.ship.pushFalhouCorrecao));
|
|
585
652
|
}
|
|
586
653
|
// A prova: o sha que o REMOTO devolve tem que ser o mesmo do destino local.
|
|
587
654
|
const shaRemoto = shaNoRemoto(arvore.dir, remoto, para);
|
|
588
655
|
passos.push(`git ls-remote ${remoto} refs/heads/${para}`);
|
|
589
656
|
r.shaRemoto = shaRemoto;
|
|
590
|
-
r.pushVerificado = shaRemoto !== null && shaRemoto ===
|
|
657
|
+
r.pushVerificado = shaRemoto !== null && shaRemoto === pontaDaBase;
|
|
591
658
|
if (!r.pushVerificado) {
|
|
592
659
|
r.passos = passos;
|
|
593
|
-
return bloquear('runtime.unavailable',
|
|
594
|
-
'o push nao ficou provado', 'rode o ship de novo e confira o remoto');
|
|
660
|
+
return bloquear('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => m.ship.pushSemProva(shaRemoto, pontaDaBase)), (0, locale_1.textoDoCatalogo)((m) => m.ship.pushSemProvaCorrecao));
|
|
595
661
|
}
|
|
596
662
|
}
|
|
597
663
|
r.passos = passos;
|
|
@@ -609,6 +675,8 @@ function ship(carregado, threadId, opcoes) {
|
|
|
609
675
|
shaDe,
|
|
610
676
|
shaParaAntes: shaPara,
|
|
611
677
|
mergeSha,
|
|
678
|
+
// RM-037 (fatia 5, A1): a ponta da base vai em campo proprio; o `mergeSha` e o merge que entregou a thread.
|
|
679
|
+
pontaDaBase,
|
|
612
680
|
jaIncorporado,
|
|
613
681
|
remoto: r.remoto,
|
|
614
682
|
shaRemoto: r.shaRemoto,
|
|
@@ -651,74 +719,75 @@ function ship(carregado, threadId, opcoes) {
|
|
|
651
719
|
});
|
|
652
720
|
}
|
|
653
721
|
}
|
|
654
|
-
/**
|
|
722
|
+
/**
|
|
723
|
+
* Texto de `ork ship` para o CLI. A razao, o detalhe, a correcao e os passos que o ship montou pelo catalogo
|
|
724
|
+
* vieram em pt-BR (como o ledger os guarda) e saem remontados no locale ativo (G2 da F2b).
|
|
725
|
+
*/
|
|
655
726
|
function textoDoShip(r) {
|
|
727
|
+
const m = (0, locale_1.msg)().ship;
|
|
656
728
|
const linhas = [];
|
|
657
729
|
// I-35: horários no fuso do dono, sem rótulo por linha; o fuso é dito uma vez, no fim.
|
|
658
730
|
let comHorario = false;
|
|
659
731
|
const local = (texto) => {
|
|
660
|
-
const
|
|
661
|
-
|
|
732
|
+
const remontado = (0, locale_1.remontar)(texto);
|
|
733
|
+
const localizado = (0, horario_1.localizarTexto)(remontado);
|
|
734
|
+
if (localizado !== remontado)
|
|
662
735
|
comHorario = true;
|
|
663
736
|
return localizado;
|
|
664
737
|
};
|
|
665
738
|
const fechar = () => (comHorario ? [...linhas, (0, horario_1.legendaDoFuso)()] : linhas).join('\n');
|
|
666
|
-
|
|
667
|
-
linhas.push(
|
|
668
|
-
linhas.push(
|
|
669
|
-
linhas.push(
|
|
670
|
-
|
|
671
|
-
linhas.push(
|
|
739
|
+
linhas.push(m.cabecalho(r.dryRun, r.thread));
|
|
740
|
+
linhas.push(m.de(r.de, r.shaDe ? r.shaDe.slice(0, 8) : ''));
|
|
741
|
+
linhas.push(m.para(r.para, r.shaParaAntes ? r.shaParaAntes.slice(0, 8) : ''));
|
|
742
|
+
linhas.push(r.autorizacao.autorizado
|
|
743
|
+
? m.autorizado((0, locale_1.remontar)(r.autorizacao.por), m.tiposDeAutorizacao[r.autorizacao.tipo] ?? r.autorizacao.tipo) : m.aguardandoAutorizacao);
|
|
744
|
+
linhas.push(m.razao(local(r.autorizacao.razao)));
|
|
672
745
|
if (r.verificacao) {
|
|
673
746
|
const v = r.verificacao;
|
|
674
|
-
linhas.push(
|
|
675
|
-
`(${v.claims.filter((c) => c.verificado).length}/${v.claims.length} claims, ` +
|
|
676
|
-
`${v.comandos.filter((c) => c.ok).length}/${v.comandos.length} comandos)`);
|
|
747
|
+
linhas.push(m.verificacao(v.ok, (0, util_1.shaCurto)(v.commit), v.claims.filter((c) => c.verificado).length, v.claims.length, v.comandos.filter((c) => c.ok).length, v.comandos.length));
|
|
677
748
|
}
|
|
678
749
|
if (r.ci) {
|
|
679
|
-
linhas.push(
|
|
750
|
+
linhas.push(r.ci.required ? m.ciExigido(r.ci.state.toUpperCase(), r.ci.context, r.ci.sha.slice(0, 8)) : m.ciNaoExigido);
|
|
680
751
|
}
|
|
681
752
|
linhas.push(...(0, policies_1.linhasDeAviso)(r.violacoes ?? []));
|
|
682
753
|
if (r.leaseOcupadoPor) {
|
|
683
754
|
comHorario = true;
|
|
684
|
-
linhas.push(
|
|
755
|
+
linhas.push(m.leaseOcupado(leases_1.LEASE_MAIN_TREE, r.leaseOcupadoPor.thread, (0, horario_1.formatarDataHora)(r.leaseOcupadoPor.adquiridoEm)));
|
|
685
756
|
}
|
|
686
757
|
else if (r.lease) {
|
|
687
|
-
linhas.push(
|
|
758
|
+
linhas.push(m.leaseTomado(leases_1.LEASE_MAIN_TREE, r.thread));
|
|
688
759
|
}
|
|
689
760
|
else if (r.dryRun) {
|
|
690
|
-
linhas.push(
|
|
761
|
+
linhas.push(m.leaseLivre(leases_1.LEASE_MAIN_TREE));
|
|
691
762
|
}
|
|
692
763
|
if (r.bloqueado) {
|
|
693
764
|
linhas.push('');
|
|
694
|
-
linhas.push(
|
|
695
|
-
linhas.push(
|
|
696
|
-
linhas.push(
|
|
765
|
+
linhas.push(m.bloqueado(String(r.motivo)));
|
|
766
|
+
linhas.push(m.detalhe(local(r.detalhe)));
|
|
767
|
+
linhas.push(m.correcao((0, locale_1.remontar)(r.correcao)));
|
|
697
768
|
return fechar();
|
|
698
769
|
}
|
|
699
770
|
if (r.dryRun) {
|
|
700
771
|
linhas.push('');
|
|
701
|
-
linhas.push(
|
|
772
|
+
linhas.push(m.passosDoEnsaio);
|
|
702
773
|
for (const p of r.passos)
|
|
703
|
-
linhas.push(` ${p}`);
|
|
774
|
+
linhas.push(` ${(0, locale_1.remontar)(p)}`);
|
|
704
775
|
return fechar();
|
|
705
776
|
}
|
|
706
777
|
linhas.push('');
|
|
707
|
-
linhas.push(r.jaIncorporado
|
|
708
|
-
? `Nada a mergear: ${r.de} ja estava em ${r.para}.`
|
|
709
|
-
: `Merge --no-ff concluido: ${r.mergeSha}`);
|
|
778
|
+
linhas.push(r.jaIncorporado ? m.nadaAMergear(r.de, r.para, String(r.mergeSha)) : m.mergeConcluido(String(r.mergeSha)));
|
|
710
779
|
if (r.pushVerificado) {
|
|
711
|
-
linhas.push(
|
|
712
|
-
linhas.push(
|
|
780
|
+
linhas.push(m.pushProvado(String(r.remoto), r.para, String(r.shaRemoto)));
|
|
781
|
+
linhas.push(m.mesmoSha(r.pontaDaBase ?? String(r.mergeSha)));
|
|
713
782
|
}
|
|
714
783
|
else {
|
|
715
|
-
linhas.push(
|
|
784
|
+
linhas.push(m.pushNaoProvado(local(r.detalhe) || m.semRemotoConfigurado));
|
|
716
785
|
}
|
|
717
786
|
linhas.push('');
|
|
718
|
-
linhas.push(
|
|
787
|
+
linhas.push(m.evidencia);
|
|
719
788
|
for (const p of r.passos)
|
|
720
|
-
linhas.push(` ${p}`);
|
|
789
|
+
linhas.push(` ${(0, locale_1.remontar)(p)}`);
|
|
721
790
|
linhas.push('');
|
|
722
|
-
linhas.push(
|
|
791
|
+
linhas.push(m.ledger(r.thread));
|
|
723
792
|
return fechar();
|
|
724
793
|
}
|
package/dist/steal.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RM-037 (fatia 6): o steal da CPU durante o `ork verify`, medido em `/proc/stat`.
|
|
4
|
+
*
|
|
5
|
+
* Em 23 e 24/09/2026 a VPS perdeu de 67% a 92% da CPU para o hipervisor (sar), e a mesma suite que
|
|
6
|
+
* leva 3,4 min com CPU livre levou de 24 a 30 min. Teste que mede relogio reprova nessa hora sem que
|
|
7
|
+
* o codigo tenha mudado. O verify passa a medir o steal na janela de cada comando e da rodada e a
|
|
8
|
+
* gravar a medida no `verify_run`; a reprovacao de teste com relogio sob steal acima de 40% vira
|
|
9
|
+
* `verify.timeout` (o retry reexecuta), nunca regressao.
|
|
10
|
+
*
|
|
11
|
+
* A linha agregada `cpu` do `/proc/stat` traz, em jiffies desde o boot: user, nice, system, idle,
|
|
12
|
+
* iowait, irq, softirq, steal, guest e guest_nice. guest e guest_nice ja estao contados em user e
|
|
13
|
+
* nice, entao o total da janela soma so os oito primeiros.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.lerProcStat = exports.FONTE_STEAL = exports.LIMIAR_STEAL_PCT = void 0;
|
|
17
|
+
exports.amostraDoProcStat = amostraDoProcStat;
|
|
18
|
+
exports.stealDaJanela = stealDaJanela;
|
|
19
|
+
exports.abrirJanela = abrirJanela;
|
|
20
|
+
exports.reprovacaoSoDeRelogio = reprovacaoSoDeRelogio;
|
|
21
|
+
exports.stealAlto = stealAlto;
|
|
22
|
+
const node_fs_1 = require("node:fs");
|
|
23
|
+
/** Limiar da recomendada da RM-037: acima dele, o relogio do teste nao julga o codigo. */
|
|
24
|
+
exports.LIMIAR_STEAL_PCT = 40;
|
|
25
|
+
exports.FONTE_STEAL = '/proc/stat';
|
|
26
|
+
const lerProcStat = () => {
|
|
27
|
+
try {
|
|
28
|
+
return (0, node_fs_1.readFileSync)(exports.FONTE_STEAL, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
exports.lerProcStat = lerProcStat;
|
|
35
|
+
/** A linha `cpu ` (agregada) do `/proc/stat`. Kernel antigo, sem a coluna de steal, nao tem medida. */
|
|
36
|
+
function amostraDoProcStat(conteudo) {
|
|
37
|
+
if (!conteudo)
|
|
38
|
+
return null;
|
|
39
|
+
const linha = conteudo.split('\n').find((l) => /^cpu\s/.test(l));
|
|
40
|
+
if (!linha)
|
|
41
|
+
return null;
|
|
42
|
+
const campos = linha.trim().split(/\s+/).slice(1).map(Number);
|
|
43
|
+
if (campos.length < 8 || campos.slice(0, 8).some((n) => !Number.isFinite(n) || n < 0))
|
|
44
|
+
return null;
|
|
45
|
+
const total = campos.slice(0, 8).reduce((s, n) => s + n, 0);
|
|
46
|
+
return { steal: campos[7], total };
|
|
47
|
+
}
|
|
48
|
+
/** Steal da janela entre duas amostras, em porcentagem com uma casa. Janela vazia nao tem medida. */
|
|
49
|
+
function stealDaJanela(inicio, fim) {
|
|
50
|
+
if (!inicio || !fim)
|
|
51
|
+
return null;
|
|
52
|
+
const total = fim.total - inicio.total;
|
|
53
|
+
const steal = fim.steal - inicio.steal;
|
|
54
|
+
if (total <= 0 || steal < 0)
|
|
55
|
+
return null;
|
|
56
|
+
return Math.round((steal / total) * 1000) / 10;
|
|
57
|
+
}
|
|
58
|
+
/** Abre a janela agora; `fechar()` devolve o steal dela (ou `null` sem medida). */
|
|
59
|
+
function abrirJanela(leitor = exports.lerProcStat) {
|
|
60
|
+
const inicio = amostraDoProcStat(leitor());
|
|
61
|
+
return { fechar: () => stealDaJanela(inicio, amostraDoProcStat(leitor())) };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A reprovacao do comando e so de teste com relogio? Todo teste que caiu precisa ser de relogio:
|
|
65
|
+
* pela assinatura de prazo do runner (estouro do teste ou cancelado pelo pai que estourou) ou pelo
|
|
66
|
+
* registro de instabilidade. Comando sem teste nomeado (build, tsc, script) nunca entra.
|
|
67
|
+
*/
|
|
68
|
+
function reprovacaoSoDeRelogio(falhas, registro = new Set()) {
|
|
69
|
+
if (!falhas || falhas.length === 0)
|
|
70
|
+
return null;
|
|
71
|
+
const todas = falhas.every((f) => f.relogio || registro.has(f.nome));
|
|
72
|
+
return todas ? falhas.map((f) => f.nome) : null;
|
|
73
|
+
}
|
|
74
|
+
/** Steal acima do limiar? A medida ausente nunca atenua nada. */
|
|
75
|
+
function stealAlto(pct) {
|
|
76
|
+
return typeof pct === 'number' && pct > exports.LIMIAR_STEAL_PCT;
|
|
77
|
+
}
|
package/dist/thread-close.js
CHANGED
|
@@ -48,6 +48,7 @@ const estado_thread_1 = require("./estado-thread");
|
|
|
48
48
|
const util_1 = require("./util");
|
|
49
49
|
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
50
50
|
const fechamento_1 = require("./fechamento");
|
|
51
|
+
const locale_1 = require("./locale");
|
|
51
52
|
function validarArtefato(raiz, arquivo, sha256) {
|
|
52
53
|
if (!/^[a-f0-9]{64}$/.test(sha256))
|
|
53
54
|
throw new Error('sha256 inválido');
|
|
@@ -80,10 +81,10 @@ function provaDeEntrega(raiz, id) {
|
|
|
80
81
|
function exigirEntrega(raiz, id) {
|
|
81
82
|
const t = (0, thread_1.lerThread)(raiz, id);
|
|
82
83
|
if (t.fechamentoAdmin)
|
|
83
|
-
throw new
|
|
84
|
+
throw new locale_1.ErroDoCatalogo((m) => m.master.encerradaAdmin);
|
|
84
85
|
const prova = provaDeEntrega(raiz, id);
|
|
85
86
|
if (!prova)
|
|
86
|
-
throw new
|
|
87
|
+
throw new locale_1.ErroDoCatalogo((m) => m.master.exigeEntrega);
|
|
87
88
|
return prova;
|
|
88
89
|
}
|
|
89
90
|
function registrarArtefato(raiz, id, arquivo, sha256, por) {
|