@orkastery/cli 0.2.0 → 0.4.1
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/LICENSE +1 -1
- package/README.md +86 -65
- package/adapters/README.md +30 -15
- package/adapters/claude-code/.claude-plugin/plugin.json +11 -5
- package/adapters/claude-code/README.md +110 -8
- package/adapters/claude-code/commands/check.md +4 -3
- package/adapters/claude-code/commands/goal.md +3 -2
- package/adapters/claude-code/commands/master.md +3 -2
- package/adapters/claude-code/commands/onboarding.md +21 -0
- package/adapters/claude-code/commands/ork.md +99 -27
- package/adapters/claude-code/hooks/hooks.json +6 -1
- package/adapters/claude-code/hooks/ork-guard.js +1 -1
- package/adapters/claude-code/hooks/ork-sensor.js +66 -0
- package/adapters/codex/skills/ork/SKILL.md +57 -0
- package/adapters/hermes/README.md +161 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +2 -0
- package/adapters/hermes/bin/ork-brain.sh +4 -0
- package/adapters/hermes/bin/ork-hitl-answer.py +82 -0
- package/adapters/hermes/bin/ork-maestro.sh +6 -0
- package/adapters/hermes/bin/ork-master-enviar.py +84 -0
- package/adapters/hermes/bin/ork-pulse-enviar.py +47 -0
- package/adapters/hermes/hermes.plugin.json +24 -4
- package/adapters/hermes/hitl-ingress/__init__.py +356 -0
- package/adapters/hermes/hitl-ingress/plugin.yaml +4 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +75 -22
- package/adapters/openclaw/README.md +136 -27
- package/adapters/openclaw/bin/ork-brain.sh +4 -0
- package/adapters/openclaw/construir.sh +19 -0
- package/adapters/openclaw/dist/hitl-ingress.js +199 -0
- package/adapters/openclaw/dist/index.js +437 -0
- package/adapters/openclaw/openclaw.plugin.json +39 -134
- package/adapters/openclaw/package.json +26 -0
- package/adapters/openclaw/src/hitl-ingress.ts +180 -0
- package/adapters/openclaw/src/index.ts +460 -0
- package/adapters/openclaw/src/tipos-openclaw.d.ts +58 -0
- package/adapters/openclaw/tsconfig.json +15 -0
- package/assets/docs/markdownlint-cli2.jsonc +22 -0
- package/assets/docs/padroes/documentacao-de-produto.md +133 -0
- package/assets/docs/padroes/roadmap-de-produto.md +98 -0
- package/assets/docs/produto/README.md +14 -0
- package/assets/docs/produto/_modelo-feature.md +59 -0
- package/assets/docs/roadmap/README.md +14 -0
- package/assets/docs/roadmap/_modelo-item.md +73 -0
- package/assets/orkmind-native-schema.json +32 -0
- package/assets/orkmind_bridge.py +357 -0
- package/assets/orkmind_fixture.py +67 -0
- package/assets/orkmind_prospective.py +138 -0
- package/assets/reference-tariffs-i07.json +23 -0
- package/dist/adapters/claude-bg.js +488 -39
- package/dist/adapters/codex-controller-sensor.js +449 -0
- package/dist/adapters/codex-controller-worker.js +361 -0
- package/dist/adapters/codex-controller.js +252 -0
- package/dist/adapters/codex-events.js +205 -0
- package/dist/adapters/codex-question.js +26 -0
- package/dist/adapters/codex-runner.js +133 -0
- package/dist/adapters/codex.js +394 -0
- package/dist/agents-md.js +84 -0
- package/dist/auditoria.js +12 -9
- package/dist/auditrun.js +5 -4
- package/dist/board.js +174 -23
- package/dist/branch-de-estado.js +136 -0
- package/dist/canarios-hitl.js +177 -0
- package/dist/canarios-i43.js +543 -0
- package/dist/canarios-pulse.js +147 -0
- package/dist/canarios-sensores.js +129 -0
- package/dist/canarios.js +111 -2
- package/dist/catalogo.js +9 -0
- package/dist/ci.js +223 -0
- package/dist/ciclos.js +2 -1
- package/dist/claim-lint.js +64 -0
- package/dist/claims.js +60 -0
- package/dist/company-brain-capture.js +195 -0
- package/dist/company-brain-cli.js +123 -0
- package/dist/company-brain-client.js +61 -0
- package/dist/company-brain-contract.js +166 -0
- package/dist/company-brain-journal.js +192 -0
- package/dist/company-brain-mcp.js +33 -0
- package/dist/company-brain-migration.js +60 -0
- package/dist/company-brain-source.js +177 -0
- package/dist/company-brain-worker.js +18 -0
- package/dist/conducao-texto.js +61 -0
- package/dist/conducao.js +876 -0
- package/dist/contrato-publico.js +39 -0
- package/dist/creation-operation-store.js +251 -0
- package/dist/creation-operation.js +148 -0
- package/dist/decisao-autonoma.js +183 -0
- package/dist/delegation.js +79 -0
- package/dist/demo.js +120 -0
- package/dist/docs.js +828 -0
- package/dist/doctor.js +184 -25
- package/dist/entrega-pr.js +117 -0
- package/dist/escopo-escrita.js +71 -0
- package/dist/estado-thread.js +222 -0
- package/dist/evalrunner.js +12 -0
- package/dist/fabrica-estado.js +329 -0
- package/dist/fabrica-publicar.js +76 -0
- package/dist/fix.js +22 -1
- package/dist/gates.js +59 -11
- package/dist/handoff.js +39 -23
- package/dist/hitl-canais.js +333 -0
- package/dist/hitl-classificacao.js +131 -0
- package/dist/hitl-contract.js +465 -0
- package/dist/hitl-estado.js +136 -0
- package/dist/hitl-gates.js +554 -0
- package/dist/hitl-ingress-receipt.js +382 -0
- package/dist/hitl-local-atestado.js +57 -0
- package/dist/hitl-local-receipt.js +328 -0
- package/dist/hitl-local.js +143 -0
- package/dist/hitl-lock.js +139 -0
- package/dist/hitl-lote.js +223 -0
- package/dist/hitl-native-offer.js +97 -0
- package/dist/hitl-native.js +65 -0
- package/dist/hitl-presentation.js +209 -0
- package/dist/hitl-public-receipt.js +176 -0
- package/dist/hitl-resumo.js +209 -0
- package/dist/hitl-sessions.js +475 -0
- package/dist/hitl.js +711 -0
- package/dist/horario.js +269 -0
- package/dist/hosts.js +198 -22
- package/dist/index.js +1741 -94
- package/dist/indice.js +99 -0
- package/dist/init.js +28 -3
- package/dist/integracoes-locais.js +17 -0
- package/dist/leases.js +65 -21
- package/dist/ledger-stats.js +272 -0
- package/dist/ledger.js +109 -2
- package/dist/licoes.js +221 -0
- package/dist/liveness.js +218 -0
- package/dist/maestro-actions.js +51 -0
- package/dist/maestro-authority.js +152 -0
- package/dist/maestro-cli.js +97 -0
- package/dist/maestro-contract.js +55 -0
- package/dist/maestro-discovery.js +132 -0
- package/dist/maestro-runtime.js +268 -0
- package/dist/maestro-snapshot.js +86 -0
- package/dist/maestro-sources.js +224 -0
- package/dist/manifest.js +165 -6
- package/dist/maquina.js +102 -0
- package/dist/master-audit.js +101 -0
- package/dist/master-batch.js +43 -0
- package/dist/master-digest.js +149 -0
- package/dist/master-migracao.js +155 -0
- package/dist/master.js +361 -77
- package/dist/mcp-artifacts.js +234 -0
- package/dist/mcp-git.js +433 -0
- package/dist/mcp-install.js +310 -0
- package/dist/mcp-maestro.js +25 -0
- package/dist/mcp-server.js +469 -0
- package/dist/mcp-ship.js +436 -0
- package/dist/mcp-verify.js +173 -0
- package/dist/memoria-humana.js +207 -0
- package/dist/memoria.js +314 -78
- package/dist/memory-migration.js +279 -0
- package/dist/memory-prospective.js +148 -0
- package/dist/modos-migracao.js +191 -0
- package/dist/modos.js +151 -15
- package/dist/monitor-lock.js +110 -0
- package/dist/objective.js +449 -0
- package/dist/ocupacao.js +267 -0
- package/dist/onboarding.js +303 -0
- package/dist/orkmind.js +389 -90
- package/dist/orquestracao.js +96 -69
- package/dist/phase.js +612 -151
- package/dist/playbook-capabilities.js +150 -0
- package/dist/playbook-contracts.js +188 -0
- package/dist/policies.js +72 -0
- package/dist/portfolio-context.js +61 -0
- package/dist/portfolio.js +180 -0
- package/dist/preflight.js +207 -0
- package/dist/process-audit.js +112 -0
- package/dist/project-state.js +93 -0
- package/dist/prompts.js +25 -5
- package/dist/prova-minima.js +112 -0
- package/dist/pulse-cadencia.js +163 -0
- package/dist/pulse-consentimento.js +260 -0
- package/dist/pulse-delivery.js +323 -0
- package/dist/pulse-resposta.js +542 -0
- package/dist/pulse.js +262 -0
- package/dist/ratelimit.js +35 -2
- package/dist/recall.js +80 -3
- package/dist/redacao-saida.js +45 -0
- package/dist/redacao-url.js +66 -0
- package/dist/retry.js +640 -118
- package/dist/roadmap-reservas.js +243 -0
- package/dist/runtime-ambiente.js +38 -0
- package/dist/runtime-context.js +215 -0
- package/dist/runtime-profiles.js +869 -0
- package/dist/runtimes.js +103 -0
- package/dist/sandbox.js +9 -0
- package/dist/session-events.js +203 -0
- package/dist/session-watcher-claude.js +637 -0
- package/dist/session-watcher.js +700 -0
- package/dist/sessoes-adopt.js +154 -0
- package/dist/sessoes-inventario.js +159 -0
- package/dist/sessoes.js +16 -35
- package/dist/setup.js +691 -0
- package/dist/ship.js +168 -19
- package/dist/slug.js +1 -1
- package/dist/thread-close.js +115 -0
- package/dist/thread.js +142 -28
- package/dist/tokens.js +1 -1
- package/dist/util.js +4 -2
- package/dist/verify-sandbox.js +265 -0
- package/dist/verify.js +270 -25
- package/dist/versao.js +60 -0
- package/dist/worktree.js +31 -2
- package/dist/write-activation.js +291 -0
- package/dist/yaml.js +5 -1
- package/eval/casos/master-metrics.json +1 -1
- package/eval/casos/onboarding.json +102 -0
- package/eval/casos/orkastery-bootstrap.json +37 -3
- package/eval/casos/scope-check-capability-map.json +45 -7
- package/eval/casos/ship-release.json +3 -3
- package/eval/fixtures/b0-slug-e-modos/caso.json +35 -22
- package/eval/fixtures/b2-master-log/caso.json +1 -1
- package/eval/fixtures/fx-adapter-editado-detectado/caso.json +19 -0
- package/eval/fixtures/fx-auto-quiet/caso.json +11 -0
- package/eval/fixtures/fx-blanket-approve/caso.json +10 -0
- package/eval/fixtures/fx-check-runtime-cruzado/caso.json +20 -0
- package/eval/fixtures/fx-codex-dry/caso.json +18 -0
- package/eval/fixtures/fx-donewhen-executavel/caso.json +15 -0
- package/eval/fixtures/fx-estado-dividido/caso.json +15 -0
- package/eval/fixtures/fx-fase-orfa/caso.json +116 -0
- package/eval/fixtures/fx-happy/caso.json +6 -4
- package/eval/fixtures/fx-hitl-latency/caso.json +20 -0
- package/eval/fixtures/fx-indice-reversao/caso.json +25 -0
- package/eval/fixtures/fx-listagem-abertas/caso.json +16 -0
- package/eval/fixtures/fx-maestro-bootstrap/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-escritor/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-leitor/caso.json +16 -0
- package/eval/fixtures/fx-objective-oscillation/caso.json +14 -0
- package/eval/fixtures/fx-omnicanal/caso.json +17 -0
- package/eval/fixtures/fx-sensores-runtime/caso.json +17 -0
- package/monitor/company-brain.cjs +17 -0
- package/monitor/pulse-scope.cjs +45 -0
- package/monitor/pulse.cron +18 -0
- package/monitor/varredura-pulse.sh +27 -0
- package/package.json +28 -7
- package/references/definition-of-done.md +2 -2
- package/schemas/claims.schema.json +25 -0
- package/schemas/company-brain.schema.json +1158 -0
- package/schemas/creation-operation.schema.json +365 -0
- package/schemas/maestro-snapshot.schema.json +2716 -0
- package/skills/README.md +3 -3
- package/skills/core/onboarding/SKILL.md +50 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +95 -65
- package/skills/core/thread-state/SKILL.md +3 -1
- package/skills/governance/decision-triage/SKILL.md +4 -4
- package/skills/governance/narrative-guardian/SKILL.md +1 -1
- package/skills/governance/roadmap-keeper/SKILL.md +1 -1
- package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
- package/skills/observability/thread-tracing/SKILL.md +1 -1
- package/skills/phases/check-quality/SKILL.md +2 -2
- package/skills/phases/goal-definition/SKILL.md +1 -1
- package/skills/phases/master-metrics/SKILL.md +9 -7
- package/skills/phases/plan-specification/SKILL.md +1 -1
- package/skills/phases/ship-release/SKILL.md +1 -1
package/dist/ship.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* A ordem dos passos e o contrato, e ela nao muda por modo de conducao:
|
|
6
6
|
*
|
|
7
|
-
* 1. autorizacao de push, pelo gate do modo (#
|
|
7
|
+
* 1. autorizacao de push, pelo gate do modo (#Classic usa a
|
|
8
8
|
* autorizacao antecipada registrada no ledger; #Maestro/#Auto usam a propria #TAG);
|
|
9
9
|
* 2. policies do manifesto no gate `ship` (push_direto_na_base e provider);
|
|
10
10
|
* 3. verificacao independente: `ork verify` reexecuta claims e comandos no HEAD real;
|
|
@@ -56,6 +56,8 @@ exports.prepararArvore = prepararArvore;
|
|
|
56
56
|
exports.shaDaRef = shaDaRef;
|
|
57
57
|
exports.shaNoRemoto = shaNoRemoto;
|
|
58
58
|
exports.remotoConfigurado = remotoConfigurado;
|
|
59
|
+
exports.detectarReversaoDaEntrega = detectarReversaoDaEntrega;
|
|
60
|
+
exports.registrarReversaoDaEntrega = registrarReversaoDaEntrega;
|
|
59
61
|
exports.ship = ship;
|
|
60
62
|
exports.textoDoShip = textoDoShip;
|
|
61
63
|
const fs = __importStar(require("node:fs"));
|
|
@@ -69,14 +71,31 @@ const policies_1 = require("./policies");
|
|
|
69
71
|
const thread_1 = require("./thread");
|
|
70
72
|
const util_1 = require("./util");
|
|
71
73
|
const verify_1 = require("./verify");
|
|
74
|
+
const ci_1 = require("./ci");
|
|
75
|
+
const contrato_publico_1 = require("./contrato-publico");
|
|
76
|
+
const prova_minima_1 = require("./prova-minima");
|
|
77
|
+
const horario_1 = require("./horario");
|
|
78
|
+
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
79
|
+
/** Os caminhos de contrato publico que a entrega traz sobre a base (diff desde o merge-base). */
|
|
80
|
+
function contratosDaEntrega(raiz, shaPara, shaDe) {
|
|
81
|
+
const base = (0, util_1.exec)('git', ['merge-base', shaPara, shaDe], raiz);
|
|
82
|
+
if (!base.ok)
|
|
83
|
+
return [];
|
|
84
|
+
const diff = (0, util_1.exec)('git', ['diff', '--name-only', '--no-renames', base.stdout.trim(), shaDe], raiz);
|
|
85
|
+
return diff.ok ? (0, contrato_publico_1.contratosTocados)(diff.stdout.split('\n').map((l) => l.trim()).filter(Boolean)) : [];
|
|
86
|
+
}
|
|
72
87
|
/** Modos em que a propria #TAG do pedido autoriza o push antecipadamente. */
|
|
73
88
|
const MODOS_QUE_AUTORIZAM_PUSH = ['maestro', 'auto'];
|
|
74
89
|
/**
|
|
75
90
|
* Quem autoriza o push desta thread.
|
|
76
91
|
*
|
|
77
|
-
* `#
|
|
78
|
-
*
|
|
79
|
-
*
|
|
92
|
+
* `#Classic` pausa no gate de evidencias, com autorizacao ANTECIPADA de push: aqui isso
|
|
93
|
+
* e conferido no ledger, nao presumido. `#Maestro` e `#Auto` seguem pela #TAG, que fica
|
|
94
|
+
* registrada.
|
|
95
|
+
*
|
|
96
|
+
* I-43: thread LEGADA em `#Look` ou `#Ork` pausava no proprio SHIP. Ela continua caindo
|
|
97
|
+
* neste mesmo caminho (nao esta em `MODOS_QUE_AUTORIZAM_PUSH`, entao exige autorizacao
|
|
98
|
+
* registrada), e por isso a regra nao precisou de um ramo so para ela.
|
|
80
99
|
*/
|
|
81
100
|
function autorizacaoDePush(raiz, thread, opcoes) {
|
|
82
101
|
const tag = (0, modos_1.tagDoModo)(thread.modo);
|
|
@@ -112,8 +131,7 @@ function autorizacaoDePush(raiz, thread, opcoes) {
|
|
|
112
131
|
tipo: 'pendente',
|
|
113
132
|
por: '',
|
|
114
133
|
razao: `o modo ${tag} pausa no push e ainda nao ha autorizacao humana registrada. ` +
|
|
115
|
-
`Autorize
|
|
116
|
-
`ou rode: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
|
|
134
|
+
`Autorize na entrega: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
|
|
117
135
|
};
|
|
118
136
|
}
|
|
119
137
|
/** Diretorio temporario onde a arvore de merge e montada quando preciso. */
|
|
@@ -225,6 +243,7 @@ function baseDoResultado(thread, de, opcoes) {
|
|
|
225
243
|
pushVerificado: false,
|
|
226
244
|
autorizacao: { autorizado: false, tipo: 'pendente', por: '', razao: '' },
|
|
227
245
|
verificacao: null,
|
|
246
|
+
ci: null,
|
|
228
247
|
violacoes: [],
|
|
229
248
|
lease: null,
|
|
230
249
|
leaseOcupadoPor: null,
|
|
@@ -232,7 +251,78 @@ function baseDoResultado(thread, de, opcoes) {
|
|
|
232
251
|
dryRun: opcoes.dryRun === true,
|
|
233
252
|
};
|
|
234
253
|
}
|
|
235
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* A entrega ja feita por esta thread foi REVERTIDA na base? (I-43, D3, T7)
|
|
256
|
+
*
|
|
257
|
+
* Este era o buraco que tornava o indice de qualidade um numero que nunca muda:
|
|
258
|
+
* `rollback_done` existia na allowlist do ciclo e NAO era escrito por ninguem, e ele
|
|
259
|
+
* e o insumo de maior peso. Sem escritor, 23 das 29 threads entregues ficariam
|
|
260
|
+
* coladas no teto para sempre.
|
|
261
|
+
*
|
|
262
|
+
* A deteccao ancora no marcador que o PROPRIO git escreve. `git revert -m 1 <sha>`
|
|
263
|
+
* poe "This reverts commit <sha>" no corpo do commit, e e isso que se procura no
|
|
264
|
+
* historico da base DEPOIS do merge. Nao se infere reversao por diff de arvore: um
|
|
265
|
+
* arquivo que voltou ao estado anterior pode ser trabalho de outra thread, e chamar
|
|
266
|
+
* isso de reversao seria rebaixar entrega alheia por coincidencia.
|
|
267
|
+
*
|
|
268
|
+
* `para` e OPCIONAL, e isso e o que permite perguntar fora do ship (GO-FIX 1, A1):
|
|
269
|
+
* sem ele, o destino sai do proprio `ship_done`, que ja grava para onde entregou. Quem
|
|
270
|
+
* calcula o indice depois do MASTER nao tem branch de destino na mao, e inventar uma
|
|
271
|
+
* seria pior que nao perguntar.
|
|
272
|
+
*
|
|
273
|
+
* So le git; nao escreve nada. Quem grava o evento e `registrarReversaoDaEntrega`.
|
|
274
|
+
*/
|
|
275
|
+
function detectarReversaoDaEntrega(raiz, thread, para) {
|
|
276
|
+
const dir = (0, thread_1.dirThread)(raiz, thread.id);
|
|
277
|
+
const entregas = (0, ledger_1.lerLedger)(dir)
|
|
278
|
+
.filter((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && typeof e.mergeSha === 'string')
|
|
279
|
+
.map((e) => ({ mergeSha: String(e.mergeSha), para: para ?? String(e.para ?? '') }))
|
|
280
|
+
.filter((e) => e.para.length > 0);
|
|
281
|
+
if (entregas.length === 0)
|
|
282
|
+
return null;
|
|
283
|
+
const perguntados = new Set();
|
|
284
|
+
for (const entrega of [...entregas].reverse()) {
|
|
285
|
+
const intervalo = `${entrega.mergeSha}..${entrega.para}`;
|
|
286
|
+
if (perguntados.has(intervalo))
|
|
287
|
+
continue;
|
|
288
|
+
perguntados.add(intervalo);
|
|
289
|
+
// 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);
|
|
291
|
+
if (!log.ok)
|
|
292
|
+
continue;
|
|
293
|
+
for (const bruto of log.stdout.split('\x1e')) {
|
|
294
|
+
const [sha, corpo] = bruto.split('\x1f');
|
|
295
|
+
if (!sha || !corpo)
|
|
296
|
+
continue;
|
|
297
|
+
if (corpo.includes(`This reverts commit ${entrega.mergeSha}`)) {
|
|
298
|
+
return { mergeSha: entrega.mergeSha, revertSha: sha.trim(), para: entrega.para };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Grava `rollback_done` quando a reversao e nova, e devolve o que encontrou.
|
|
306
|
+
*
|
|
307
|
+
* IDEMPOTENTE por `revertSha`: o ledger e append-only e o mesmo revert nao pode
|
|
308
|
+
* rebaixar a thread duas vezes so porque alguem rodou o comando de novo.
|
|
309
|
+
*/
|
|
310
|
+
function registrarReversaoDaEntrega(raiz, thread, para) {
|
|
311
|
+
const achada = detectarReversaoDaEntrega(raiz, thread, para);
|
|
312
|
+
if (!achada)
|
|
313
|
+
return null;
|
|
314
|
+
const dir = (0, thread_1.dirThread)(raiz, thread.id);
|
|
315
|
+
const jaRegistrada = (0, ledger_1.lerLedger)(dir).some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.rollbackConcluido && e.revertSha === achada.revertSha);
|
|
316
|
+
if (jaRegistrada)
|
|
317
|
+
return achada;
|
|
318
|
+
(0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.rollbackConcluido, {
|
|
319
|
+
fase: 'SHIP',
|
|
320
|
+
...achada,
|
|
321
|
+
prova: `git log ${achada.mergeSha.slice(0, 8)}..${achada.para} traz "This reverts commit ${achada.mergeSha}" em ${achada.revertSha.slice(0, 8)}`,
|
|
322
|
+
razao: 'I-43: a entrega foi desfeita na base; e o insumo de maior peso do indice de qualidade',
|
|
323
|
+
});
|
|
324
|
+
return achada;
|
|
325
|
+
}
|
|
236
326
|
function ship(carregado, threadId, opcoes) {
|
|
237
327
|
const { raiz, manifesto } = carregado;
|
|
238
328
|
const thread = (0, thread_1.lerThread)(raiz, threadId);
|
|
@@ -241,6 +331,14 @@ function ship(carregado, threadId, opcoes) {
|
|
|
241
331
|
const para = opcoes.para;
|
|
242
332
|
const remoto = opcoes.remoto ?? 'origin';
|
|
243
333
|
const r = baseDoResultado(thread, de, opcoes);
|
|
334
|
+
// I-43 (T7): antes de qualquer coisa, se a entrega ANTERIOR desta thread foi
|
|
335
|
+
// revertida na base, isso vira `rollback_done`. E o insumo de maior peso do indice
|
|
336
|
+
// de qualidade, e o unico fato que diz sem interpretacao que a entrega nao servia.
|
|
337
|
+
// Idempotente: o mesmo revert nao rebaixa a thread duas vezes.
|
|
338
|
+
try {
|
|
339
|
+
registrarReversaoDaEntrega(raiz, thread, para);
|
|
340
|
+
}
|
|
341
|
+
catch { /* git indisponivel nao barra o ship */ }
|
|
244
342
|
const bloquear = (motivo, detalhe, correcao) => {
|
|
245
343
|
(0, gates_1.registrarGateBloqueado)(dir, threadId, {
|
|
246
344
|
gate: 'ship',
|
|
@@ -266,22 +364,36 @@ function ship(carregado, threadId, opcoes) {
|
|
|
266
364
|
const autorizacao = autorizacaoDePush(raiz, thread, opcoes);
|
|
267
365
|
r.autorizacao = autorizacao;
|
|
268
366
|
if (!autorizacao.autorizado) {
|
|
269
|
-
return bloquear('human.pending', autorizacao.razao, `ork
|
|
367
|
+
return bloquear('human.pending', autorizacao.razao, `ork ship ${threadId} --para <branch> --autorizar-push <quem>`);
|
|
270
368
|
}
|
|
271
|
-
// 2. Policies do manifesto que valem no gate `ship`.
|
|
369
|
+
// 2. Policies do manifesto que valem no gate `ship`. RM-008 (fatia 3): a branch da thread
|
|
370
|
+
// atras da base e fato do git, calculado aqui (a ponta da base nao esta contida na branch).
|
|
371
|
+
const pontaDe = shaDaRef(raiz, `refs/heads/${de}`);
|
|
372
|
+
const pontaPara = shaDaRef(raiz, `refs/heads/${para}`);
|
|
373
|
+
const branchAtrasDaBase = pontaDe && pontaPara && de !== para
|
|
374
|
+
? !(0, util_1.exec)('git', ['merge-base', '--is-ancestor', pontaPara, pontaDe], raiz).ok
|
|
375
|
+
: undefined;
|
|
272
376
|
const violacoes = (0, policies_1.avaliarPolicies)(manifesto, {
|
|
273
377
|
gate: 'ship',
|
|
274
378
|
de,
|
|
275
379
|
para,
|
|
276
380
|
baseBranch: manifesto.worktree.base_branch,
|
|
381
|
+
threadId,
|
|
382
|
+
branchAtrasDaBase,
|
|
277
383
|
});
|
|
278
384
|
r.violacoes = violacoes;
|
|
385
|
+
if (!r.dryRun) {
|
|
386
|
+
for (const v of (0, policies_1.avisos)(violacoes)) {
|
|
387
|
+
(0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.politicaAviso, { gate: 'ship', de, para,
|
|
388
|
+
policy: v.policy, detalhe: v.detalhe, correcao: v.correcao, modo: thread.modo });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
279
391
|
const bloqueiam = (0, policies_1.bloqueantes)(violacoes);
|
|
280
392
|
if (bloqueiam.length > 0) {
|
|
281
393
|
return bloquear('policy.violation', bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; '), bloqueiam.map((v) => v.correcao).join('; '));
|
|
282
394
|
}
|
|
283
395
|
// 3. Verificacao independente: reexecuta claims e comandos no HEAD real da thread.
|
|
284
|
-
const verificacao = (0, verify_1.verificar)(carregado, threadId);
|
|
396
|
+
const verificacao = (0, verify_1.verificar)(carregado, threadId, { executor: opcoes.executorVerify });
|
|
285
397
|
r.verificacao = verificacao;
|
|
286
398
|
if (!verificacao.ok) {
|
|
287
399
|
const motivo = verificacao.motivos.find((m) => m !== 'claims.unverifiable');
|
|
@@ -298,6 +410,19 @@ function ship(carregado, threadId, opcoes) {
|
|
|
298
410
|
}
|
|
299
411
|
r.shaDe = shaDe;
|
|
300
412
|
r.shaParaAntes = shaPara;
|
|
413
|
+
// I-42 (D7): a fronteira do commit MCP vale tambem na entrega, onde aparece o commit feito
|
|
414
|
+
// por git direto. Ciclo sem PLAN nem CHECK nao entrega contrato publico.
|
|
415
|
+
const tocados = (0, prova_minima_1.cicloSemCheck)(thread) ? contratosDaEntrega(raiz, shaPara, shaDe) : [];
|
|
416
|
+
if (tocados.length > 0) {
|
|
417
|
+
return bloquear('policy.violation', `contrato publico em ciclo sem PLAN nem CHECK: ${tocados.join(', ')}`, 'refaca a mudanca numa thread #Classic, #Maestro ou #Auto');
|
|
418
|
+
}
|
|
419
|
+
// O recibo vem do provedor e pertence ao SHA exato da candidata. Teste local
|
|
420
|
+
// verde ou status de outro commit não libera a entrega.
|
|
421
|
+
const ci = (0, ci_1.consultarCi)(carregado, shaDe, remoto, opcoes.executorCi);
|
|
422
|
+
r.ci = ci;
|
|
423
|
+
if (!ci.ok) {
|
|
424
|
+
return bloquear('ci.failed', `${ci.detail} (commit ${shaDe}, contexto ${ci.context})`, `publique a branch, aguarde o check ${ci.context} verde no GitHub e repita o SHIP`);
|
|
425
|
+
}
|
|
301
426
|
// 4. Lease `main-tree`: so uma thread mergeia por vez.
|
|
302
427
|
if (r.dryRun) {
|
|
303
428
|
const ocupado = (0, leases_1.lerLease)(raiz, leases_1.LEASE_MAIN_TREE);
|
|
@@ -334,6 +459,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
334
459
|
thread: threadId,
|
|
335
460
|
motivo: `ship de ${de} para ${para}`,
|
|
336
461
|
ttlMs: opcoes.ttlLeaseMs,
|
|
462
|
+
retomarVencido: opcoes.retomarLeaseVencido,
|
|
337
463
|
});
|
|
338
464
|
if (!aquisicao.ok) {
|
|
339
465
|
r.leaseOcupadoPor = aquisicao.ocupadoPor;
|
|
@@ -369,6 +495,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
369
495
|
let arvore = null;
|
|
370
496
|
try {
|
|
371
497
|
try {
|
|
498
|
+
opcoes.revalidarGit?.('preparar');
|
|
372
499
|
arvore = prepararArvore(raiz, para);
|
|
373
500
|
}
|
|
374
501
|
catch (e) {
|
|
@@ -376,6 +503,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
376
503
|
return bloquear('tree.blocked', e.message, 'deixe a arvore da branch de destino limpa (ou libere a branch) e rode o ship de novo');
|
|
377
504
|
}
|
|
378
505
|
const passos = [];
|
|
506
|
+
opcoes.revalidarGit?.('merge', arvore.dir);
|
|
379
507
|
// 5. Merge --no-ff, conferido no proprio git.
|
|
380
508
|
const jaIncorporado = (0, util_1.exec)('git', ['merge-base', '--is-ancestor', shaDe, shaPara], raiz).ok;
|
|
381
509
|
r.jaIncorporado = jaIncorporado;
|
|
@@ -410,6 +538,7 @@ function ship(carregado, threadId, opcoes) {
|
|
|
410
538
|
passos.push(`(nada a mergear: ${de} ja e ancestral de ${para})`);
|
|
411
539
|
}
|
|
412
540
|
r.mergeSha = mergeSha;
|
|
541
|
+
opcoes.revalidarGit?.('push', arvore.dir);
|
|
413
542
|
// 6. Push PROVADO por ls-remote.
|
|
414
543
|
const temRemoto = remotoConfigurado(arvore.dir, remoto);
|
|
415
544
|
r.remoto = temRemoto ? remoto : null;
|
|
@@ -468,12 +597,18 @@ function ship(carregado, threadId, opcoes) {
|
|
|
468
597
|
evidencia: {
|
|
469
598
|
verificadoNoCommit: verificacao.commit,
|
|
470
599
|
claimsVerificadas: verificacao.claims.filter((c) => c.verificado).map((c) => c.claim.id),
|
|
471
|
-
|
|
600
|
+
// I-37 (T9): a mesma evidencia do `verify_run`, com causa, prazo e o teste que caiu.
|
|
601
|
+
comandos: verificacao.comandos.map(verify_1.comandoNoLedger),
|
|
602
|
+
ci,
|
|
472
603
|
passos,
|
|
473
604
|
},
|
|
474
605
|
});
|
|
606
|
+
(0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
|
|
475
607
|
const atualizada = (0, thread_1.lerThread)(raiz, threadId);
|
|
476
|
-
|
|
608
|
+
// I-42: ciclo sem SHIP (o `#Fast`) entrega sem trocar de fase; `faseAtual` fica sempre
|
|
609
|
+
// dentro do ciclo, porque board, pulse e prompt resolvem o bloco a partir dela.
|
|
610
|
+
if (!atualizada.fases?.length || atualizada.fases.includes('SHIP'))
|
|
611
|
+
atualizada.faseAtual = 'SHIP';
|
|
477
612
|
atualizada.leases = [
|
|
478
613
|
...(atualizada.leases ?? []),
|
|
479
614
|
{ nome: leases_1.LEASE_MAIN_TREE, adquiridoEm: aquisicao.lease?.adquiridoEm ?? (0, util_1.agora)(), liberadoEm: (0, util_1.agora)() },
|
|
@@ -495,20 +630,34 @@ function ship(carregado, threadId, opcoes) {
|
|
|
495
630
|
/** Texto de `ork ship` para o CLI. */
|
|
496
631
|
function textoDoShip(r) {
|
|
497
632
|
const linhas = [];
|
|
633
|
+
// I-35: horários no fuso do dono, sem rótulo por linha; o fuso é dito uma vez, no fim.
|
|
634
|
+
let comHorario = false;
|
|
635
|
+
const local = (texto) => {
|
|
636
|
+
const localizado = (0, horario_1.localizarTexto)(texto);
|
|
637
|
+
if (localizado !== texto)
|
|
638
|
+
comHorario = true;
|
|
639
|
+
return localizado;
|
|
640
|
+
};
|
|
641
|
+
const fechar = () => (comHorario ? [...linhas, (0, horario_1.legendaDoFuso)()] : linhas).join('\n');
|
|
498
642
|
const cabecalho = r.dryRun ? 'ork ship (--dry-run, nada foi executado)' : 'ork ship';
|
|
499
643
|
linhas.push(`${cabecalho}: thread ${r.thread}`);
|
|
500
644
|
linhas.push(` de ${r.de}${r.shaDe ? ` @ ${r.shaDe.slice(0, 8)}` : ''}`);
|
|
501
645
|
linhas.push(` para ${r.para}${r.shaParaAntes ? ` @ ${r.shaParaAntes.slice(0, 8)}` : ''}`);
|
|
502
646
|
linhas.push(` autorizacao ${r.autorizacao.autorizado ? `AUTORIZADO por ${r.autorizacao.por} (${r.autorizacao.tipo})` : 'AGUARDANDO AUTORIZACAO HUMANA'}`);
|
|
503
|
-
linhas.push(` ${r.autorizacao.razao}`);
|
|
647
|
+
linhas.push(` ${local(r.autorizacao.razao)}`);
|
|
504
648
|
if (r.verificacao) {
|
|
505
649
|
const v = r.verificacao;
|
|
506
650
|
linhas.push(` verificacao ${v.ok ? 'passou' : 'REPROVOU'} no HEAD ${v.commit.slice(0, 8)} ` +
|
|
507
651
|
`(${v.claims.filter((c) => c.verificado).length}/${v.claims.length} claims, ` +
|
|
508
652
|
`${v.comandos.filter((c) => c.ok).length}/${v.comandos.length} comandos)`);
|
|
509
653
|
}
|
|
654
|
+
if (r.ci) {
|
|
655
|
+
linhas.push(` ci ${r.ci.required ? `${r.ci.state.toUpperCase()} ${r.ci.context} em ${r.ci.sha.slice(0, 8)}` : 'não exigido'}`);
|
|
656
|
+
}
|
|
657
|
+
linhas.push(...(0, policies_1.linhasDeAviso)(r.violacoes ?? []));
|
|
510
658
|
if (r.leaseOcupadoPor) {
|
|
511
|
-
|
|
659
|
+
comHorario = true;
|
|
660
|
+
linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} OCUPADO pela thread ${r.leaseOcupadoPor.thread} (desde ${(0, horario_1.formatarDataHora)(r.leaseOcupadoPor.adquiridoEm)})`);
|
|
512
661
|
}
|
|
513
662
|
else if (r.lease) {
|
|
514
663
|
linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} tomado por ${r.thread} e liberado ao fim`);
|
|
@@ -519,16 +668,16 @@ function textoDoShip(r) {
|
|
|
519
668
|
if (r.bloqueado) {
|
|
520
669
|
linhas.push('');
|
|
521
670
|
linhas.push(`BLOQUEADO. motivo tipado: ${r.motivo}`);
|
|
522
|
-
linhas.push(` detalhe ${r.detalhe}`);
|
|
671
|
+
linhas.push(` detalhe ${local(r.detalhe)}`);
|
|
523
672
|
linhas.push(` correcao ${r.correcao}`);
|
|
524
|
-
return
|
|
673
|
+
return fechar();
|
|
525
674
|
}
|
|
526
675
|
if (r.dryRun) {
|
|
527
676
|
linhas.push('');
|
|
528
677
|
linhas.push('Passos que o ship real executaria, nesta ordem:');
|
|
529
678
|
for (const p of r.passos)
|
|
530
679
|
linhas.push(` ${p}`);
|
|
531
|
-
return
|
|
680
|
+
return fechar();
|
|
532
681
|
}
|
|
533
682
|
linhas.push('');
|
|
534
683
|
linhas.push(r.jaIncorporado
|
|
@@ -539,7 +688,7 @@ function textoDoShip(r) {
|
|
|
539
688
|
linhas.push(` e o destino local esta no mesmo sha: ${r.mergeSha}`);
|
|
540
689
|
}
|
|
541
690
|
else {
|
|
542
|
-
linhas.push(`Push nao provado: ${r.detalhe || 'sem remoto configurado'}`);
|
|
691
|
+
linhas.push(`Push nao provado: ${local(r.detalhe) || 'sem remoto configurado'}`);
|
|
543
692
|
}
|
|
544
693
|
linhas.push('');
|
|
545
694
|
linhas.push('Evidencia (comandos executados):');
|
|
@@ -547,5 +696,5 @@ function textoDoShip(r) {
|
|
|
547
696
|
linhas.push(` ${p}`);
|
|
548
697
|
linhas.push('');
|
|
549
698
|
linhas.push(`Ledger: ork phase list ${r.thread} (evento ship_done)`);
|
|
550
|
-
return
|
|
699
|
+
return fechar();
|
|
551
700
|
}
|
package/dist/slug.js
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.validarArtefato = validarArtefato;
|
|
37
|
+
exports.provaDeEntrega = provaDeEntrega;
|
|
38
|
+
exports.exigirEntrega = exigirEntrega;
|
|
39
|
+
exports.registrarArtefato = registrarArtefato;
|
|
40
|
+
exports.fecharAdministrativamente = fecharAdministrativamente;
|
|
41
|
+
/** Encerramento administrativo não representa uma entrega nem um score humano. */
|
|
42
|
+
const fs = __importStar(require("node:fs"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const node_crypto_1 = require("node:crypto");
|
|
45
|
+
const thread_1 = require("./thread");
|
|
46
|
+
const ledger_1 = require("./ledger");
|
|
47
|
+
const estado_thread_1 = require("./estado-thread");
|
|
48
|
+
const util_1 = require("./util");
|
|
49
|
+
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
50
|
+
function validarArtefato(raiz, arquivo, sha256) {
|
|
51
|
+
if (!/^[a-f0-9]{64}$/.test(sha256))
|
|
52
|
+
throw new Error('sha256 inválido');
|
|
53
|
+
const root = fs.realpathSync((0, estado_thread_1.raizDoEstado)(raiz));
|
|
54
|
+
const destino = fs.realpathSync(path.resolve(root, arquivo));
|
|
55
|
+
const relativo = path.relative(root, destino);
|
|
56
|
+
if (!relativo || relativo === '..' || relativo.startsWith(`..${path.sep}`) || path.isAbsolute(relativo)) {
|
|
57
|
+
throw new Error('artefato deve estar dentro do projeto');
|
|
58
|
+
}
|
|
59
|
+
if (!fs.statSync(destino).isFile())
|
|
60
|
+
throw new Error('artefato deve ser arquivo regular');
|
|
61
|
+
if ((0, node_crypto_1.createHash)('sha256').update(fs.readFileSync(destino)).digest('hex') !== sha256) {
|
|
62
|
+
throw new Error('hash do artefato diverge');
|
|
63
|
+
}
|
|
64
|
+
return { tipo: 'artefato', arquivo: relativo, sha256 };
|
|
65
|
+
}
|
|
66
|
+
function provaDeEntrega(raiz, id) {
|
|
67
|
+
const eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, id));
|
|
68
|
+
const ship = [...eventos].reverse().find(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido);
|
|
69
|
+
if (ship)
|
|
70
|
+
return { tipo: 'ship', ts: ship.ts, mergeSha: String(ship.mergeSha ?? '') };
|
|
71
|
+
for (const e of eventos.filter(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.artefatoEntregue).reverse()) {
|
|
72
|
+
try {
|
|
73
|
+
return validarArtefato(raiz, String(e.arquivo), String(e.sha256));
|
|
74
|
+
}
|
|
75
|
+
catch { /* prova precisa continuar válida */ }
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function exigirEntrega(raiz, id) {
|
|
80
|
+
const t = (0, thread_1.lerThread)(raiz, id);
|
|
81
|
+
if (t.fechamentoAdmin)
|
|
82
|
+
throw new Error('thread encerrada administrativamente não pode receber MASTER');
|
|
83
|
+
const prova = provaDeEntrega(raiz, id);
|
|
84
|
+
if (!prova)
|
|
85
|
+
throw new Error('MASTER exige entrega: ship_done ou artefato existente com hash verificado');
|
|
86
|
+
return prova;
|
|
87
|
+
}
|
|
88
|
+
function registrarArtefato(raiz, id, arquivo, sha256, por) {
|
|
89
|
+
const t = (0, thread_1.lerThread)(raiz, id);
|
|
90
|
+
if (t.status === 'fechada' || !por.trim())
|
|
91
|
+
throw new Error('artefato exige thread aberta e autoria explícita');
|
|
92
|
+
const prova = validarArtefato(raiz, arquivo, sha256);
|
|
93
|
+
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.artefatoEntregue, { arquivo, sha256, fase: 'SHIP', por: por.trim() });
|
|
94
|
+
return prova;
|
|
95
|
+
}
|
|
96
|
+
function fecharAdministrativamente(raiz, id, opcoes) {
|
|
97
|
+
if (!['orfa', 'engano', 'superada'].includes(opcoes.motivo))
|
|
98
|
+
throw new Error('motivo deve ser orfa, engano ou superada');
|
|
99
|
+
if (!opcoes.por.trim() || opcoes.justificativa.trim().length < 3)
|
|
100
|
+
throw new Error('fechamento exige autoria e justificativa');
|
|
101
|
+
const t = (0, thread_1.lerThread)(raiz, id);
|
|
102
|
+
if (t.fechamentoAdmin) {
|
|
103
|
+
if (t.fechamentoAdmin.motivo !== opcoes.motivo)
|
|
104
|
+
throw new Error('thread já encerrada por outro motivo');
|
|
105
|
+
return t;
|
|
106
|
+
}
|
|
107
|
+
if (provaDeEntrega(raiz, id) || t.score)
|
|
108
|
+
throw new Error('thread entregue ou pontuada exige MASTER, não fechamento administrativo');
|
|
109
|
+
t.fechamentoAdmin = { motivo: opcoes.motivo, por: opcoes.por.trim(), justificativa: opcoes.justificativa.trim(), fechadoEm: (0, util_1.agora)() };
|
|
110
|
+
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.threadFechadaAdmin, t.fechamentoAdmin);
|
|
111
|
+
t.status = 'fechada';
|
|
112
|
+
(0, thread_1.gravarThread)(raiz, t);
|
|
113
|
+
(0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
|
|
114
|
+
return t;
|
|
115
|
+
}
|