@orkastery/cli 0.4.2 → 0.5.0

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.
Files changed (128) hide show
  1. package/adapters/README.md +11 -0
  2. package/adapters/claude-code/.claude-plugin/plugin.json +3 -1
  3. package/adapters/claude-code/agents/ork-check.md +1 -1
  4. package/adapters/claude-code/agents/ork-go.md +2 -2
  5. package/adapters/claude-code/agents/ork-goal.md +1 -1
  6. package/adapters/claude-code/agents/ork-master.md +1 -1
  7. package/adapters/claude-code/agents/ork-plan.md +1 -1
  8. package/adapters/claude-code/agents/ork-ship.md +1 -1
  9. package/adapters/claude-code/commands/master.md +11 -8
  10. package/adapters/claude-code/commands/ork.md +8 -0
  11. package/adapters/claude-code/commands/ship.md +2 -2
  12. package/adapters/codex/skills/ork/SKILL.md +12 -1
  13. package/adapters/hermes/README.md +3 -0
  14. package/adapters/hermes/bin/ork-abrir-thread.sh +17 -2
  15. package/adapters/hermes/bin/ork-brain.sh +3 -0
  16. package/adapters/hermes/bin/ork-maestro.sh +4 -1
  17. package/adapters/hermes/bin/ork-network-roadmap.sh +11 -0
  18. package/adapters/hermes/bin/ork-roadmap-status.sh +9 -0
  19. package/adapters/hermes/hermes.plugin.json +2 -0
  20. package/adapters/hermes/hitl-ingress/__init__.py +36 -3
  21. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +19 -20
  22. package/adapters/openclaw/README.md +34 -3
  23. package/adapters/openclaw/dist/hitl-ingress.js +37 -3
  24. package/adapters/openclaw/dist/index.js +92 -39
  25. package/adapters/openclaw/openclaw.plugin.json +10 -3
  26. package/adapters/openclaw/package.json +2 -2
  27. package/adapters/openclaw/src/hitl-ingress.ts +32 -3
  28. package/adapters/openclaw/src/index.ts +108 -41
  29. package/assets/docs/padroes/documentacao-de-produto.md +2 -2
  30. package/assets/docs/padroes/roadmap-de-produto.md +1 -1
  31. package/assets/docs/produto/_modelo-feature.md +2 -0
  32. package/assets/orkmind_bridge.py +214 -1
  33. package/dist/adapters/claude-bg.js +88 -9
  34. package/dist/adapters/codex-events.js +3 -1
  35. package/dist/board.js +74 -0
  36. package/dist/branch-de-estado.js +5 -4
  37. package/dist/busca-semantica.js +161 -0
  38. package/dist/ci.js +141 -10
  39. package/dist/company-brain-cli.js +27 -2
  40. package/dist/company-brain-context.js +132 -0
  41. package/dist/company-brain-dossie.js +376 -0
  42. package/dist/company-brain-mcp.js +4 -1
  43. package/dist/conducao.js +117 -31
  44. package/dist/decisao-autonoma.js +42 -0
  45. package/dist/docs.js +64 -22
  46. package/dist/doctor.js +33 -0
  47. package/dist/entrega-pr.js +109 -5
  48. package/dist/experiencia-instalacao.js +256 -0
  49. package/dist/experiencia.js +72 -0
  50. package/dist/fabrica-estado.js +43 -10
  51. package/dist/fechamento.js +105 -0
  52. package/dist/fix.js +1 -1
  53. package/dist/forja.js +435 -0
  54. package/dist/gates.js +10 -1
  55. package/dist/hitl-classificacao.js +11 -1
  56. package/dist/hitl-contract.js +50 -7
  57. package/dist/hitl-curto.js +158 -0
  58. package/dist/hitl-gates.js +67 -1
  59. package/dist/hitl-lote.js +30 -15
  60. package/dist/hitl-presentation.js +10 -7
  61. package/dist/hitl-resumo.js +33 -12
  62. package/dist/hitl-texto-livre.js +150 -0
  63. package/dist/hosts.js +86 -1
  64. package/dist/index.js +605 -41
  65. package/dist/indice-vetorial.js +317 -0
  66. package/dist/init.js +13 -0
  67. package/dist/integracoes-locais.js +1 -1
  68. package/dist/intelligence-benchmark-contract.js +570 -0
  69. package/dist/intelligence-graph-cli.js +430 -0
  70. package/dist/intelligence-graph-contract.js +577 -0
  71. package/dist/intelligence-graph-extract-md.js +469 -0
  72. package/dist/intelligence-graph-extract-ts.js +810 -0
  73. package/dist/intelligence-graph-extract.js +369 -0
  74. package/dist/intelligence-graph-index.js +512 -0
  75. package/dist/intelligence-graph-parsers.js +327 -0
  76. package/dist/intelligence-graph-query.js +344 -0
  77. package/dist/intelligence-graph-repo.js +187 -0
  78. package/dist/leases.js +84 -0
  79. package/dist/ledger.js +14 -0
  80. package/dist/maestro-cli.js +10 -1
  81. package/dist/maestro-contract.js +5 -1
  82. package/dist/maestro-discovery.js +16 -2
  83. package/dist/maestro-snapshot.js +6 -2
  84. package/dist/manifest.js +142 -5
  85. package/dist/master-batch.js +3 -2
  86. package/dist/master-digest.js +2 -2
  87. package/dist/master-nota.js +203 -0
  88. package/dist/master.js +4 -0
  89. package/dist/mcp-experiencia.js +164 -0
  90. package/dist/mcp-git.js +36 -10
  91. package/dist/mcp-install.js +3 -1
  92. package/dist/mcp-maestro.js +3 -2
  93. package/dist/mcp-server.js +84 -5
  94. package/dist/memoria.js +147 -1
  95. package/dist/network-roadmap.js +907 -0
  96. package/dist/ocupacao.js +38 -2
  97. package/dist/onboarding.js +113 -7
  98. package/dist/orkmind.js +165 -9
  99. package/dist/phase.js +166 -13
  100. package/dist/policies.js +2 -0
  101. package/dist/projeto-alvo.js +551 -0
  102. package/dist/prompts.js +1 -1
  103. package/dist/pulse-consentimento.js +4 -2
  104. package/dist/pulse-delivery.js +5 -0
  105. package/dist/pulse-resposta.js +674 -49
  106. package/dist/pulse.js +21 -0
  107. package/dist/ratelimit.js +3 -2
  108. package/dist/retry.js +230 -9
  109. package/dist/roadmap-reservas.js +262 -20
  110. package/dist/roadmap-status.js +213 -0
  111. package/dist/runtime-ambiente.js +12 -1
  112. package/dist/session-watcher-claude.js +26 -0
  113. package/dist/sessoes.js +49 -15
  114. package/dist/thread-close.js +3 -0
  115. package/dist/verify.js +5 -4
  116. package/dist/worktree.js +77 -0
  117. package/eval/casos/orchestration-experience-pt-br.json +48 -0
  118. package/eval/casos/orchestration-experience.json +48 -0
  119. package/package.json +1 -1
  120. package/schemas/code-artifact-graph.v1.schema.json +581 -0
  121. package/schemas/graph-benchmark.v1.schema.json +2240 -0
  122. package/schemas/maestro-snapshot.schema.json +23 -0
  123. package/skills/README.md +7 -5
  124. package/skills/core/onboarding/SKILL.md +7 -0
  125. package/skills/core/orchestration-experience/SKILL.md +113 -0
  126. package/skills/core/orchestration-experience-pt-br/SKILL.md +112 -0
  127. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  128. package/skills/phases/go-implementation/SKILL.md +2 -0
@@ -158,6 +158,20 @@ function classificarSessaoClaude(e) {
158
158
  : { terminal: true, classificacao: 'fase_concluida', motivo: null, fonte: `${sinal}; ${prova.fonte}`, conclusaoNativa, stop };
159
159
  return { ...c, dependeDoStop: true };
160
160
  };
161
+ // RM-037 (defeitosdeco D-1): turno encerrado pelo Stop e sessão viva em `blocked` é o Claude Code
162
+ // dizendo que o texto final pediu resposta. Nunca conclui direto, e a pausa humana abre sempre
163
+ // (`human.pending`): GO-FIX (R6 do CHECK), sem a prova o motivo também é o humano, porque um
164
+ // `artifact.missing` automático abriria correção sobre uma sessão viva que espera resposta.
165
+ const esperaHumana = () => {
166
+ const sinal = 'Stop correlacionado e sessão viva à espera humana (blocked)';
167
+ const prova = e.prova();
168
+ const c = !prova.ok
169
+ ? { ...bloqueio(`${sinal}; sem prova do ork: ${prova.fonte}; o humano decide`, 'human.pending'),
170
+ diagnostico: `a sessão espera resposta humana (blocked) e a fase ainda não tem a prova do ork: ${prova.fonte}` }
171
+ : { ...bloqueio(`${sinal}; ${prova.fonte}; o humano decide`, 'human.pending'),
172
+ diagnostico: 'a fase tem a prova do ork e a sessão espera resposta humana (blocked): o humano decide' };
173
+ return { ...c, dependeDoStop: true };
174
+ };
161
175
  const venceu = (desde) => agora - desde >= e.limiteMs;
162
176
  // Sem prova para concluir nem para bloquear: `runtime.unavailable` reexecutaria o mesmo prompt
163
177
  // sobre uma fase que pode ter terminado. O observador encerra sem gate e o radar de liveness
@@ -183,6 +197,8 @@ function classificarSessaoClaude(e) {
183
197
  delete cursor.doneDesde;
184
198
  if (estado !== 'working' && estado !== 'blocked')
185
199
  delete cursor.mortoDesde;
200
+ if (estado !== 'blocked')
201
+ delete cursor.bloqueadoDesde;
186
202
  if (['done', 'failed', 'stopped', 'working', 'blocked'].includes(estado ?? ''))
187
203
  delete cursor.desconhecidoDesde;
188
204
  switch (estado) {
@@ -220,6 +236,16 @@ function classificarSessaoClaude(e) {
220
236
  return bloqueio(`processo da sessão morreu sem terminal nativo nem Stop correlacionado (estado ${estado})`);
221
237
  }
222
238
  delete cursor.mortoDesde;
239
+ // D-1: a segunda leitura, com pelo menos um intervalo do observador, separa o `blocked` estável
240
+ // de um instante de transição logo depois do Stop. `status` ocupado ainda é trabalho.
241
+ const ocupado = ['busy', 'running', 'working'].includes(r.status ?? '');
242
+ if (estado === 'blocked' && stop && !bloqueioPendente(e.eventos, e.sessao) && !ocupado) {
243
+ cursor.bloqueadoDesde ??= agora;
244
+ if (agora - cursor.bloqueadoDesde < exports.INTERVALO_WATCH_CLAUDE_MS)
245
+ return espera('turno encerrado pelo Stop com a sessão à espera humana (blocked); aguardando a segunda observação');
246
+ return esperaHumana();
247
+ }
248
+ delete cursor.bloqueadoDesde;
223
249
  return espera(estado === 'blocked' ? 'sessão bloqueada à espera humana' : 'sessão trabalhando');
224
250
  }
225
251
  default:
package/dist/sessoes.js CHANGED
@@ -46,6 +46,7 @@ exports.pararSessao = pararSessao;
46
46
  exports.comandoDeAttach = comandoDeAttach;
47
47
  const adapter = __importStar(require("./adapters/claude-bg"));
48
48
  const sessoes_inventario_1 = require("./sessoes-inventario");
49
+ const runtime_profiles_1 = require("./runtime-profiles");
49
50
  const util_1 = require("./util");
50
51
  function textoDoInventario(r) {
51
52
  const linhas = [
@@ -63,23 +64,56 @@ function textoDoInventario(r) {
63
64
  function tabelaDeSessoes(raiz, todas = false) {
64
65
  return textoDoInventario((0, sessoes_inventario_1.inventariarSessoes)(raiz, { todas }));
65
66
  }
66
- /** Logs de uma sessao pelo id curto, id completo ou nome. */
67
- function logsDaSessao(chave, linhas) {
68
- const r = adapter.logs(chave, linhas);
67
+ /**
68
+ * RM-037 (defeitosdeco D-2): a sessao pelo id curto, id completo ou nome, procurada no ambiente do
69
+ * processo e em cada perfil claude-bg do projeto (inclusive desativado, que ainda pode ter sessao
70
+ * viva). So uma conta pode responder; duas viram recusa, nenhuma mantem a mensagem de antes.
71
+ */
72
+ function localizarSessao(chave, raiz) {
73
+ let perfis = [];
74
+ const falhas = [];
75
+ if (raiz) {
76
+ try {
77
+ perfis = (0, runtime_profiles_1.lerPerfis)(raiz).perfis.filter(p => p.runtime === 'claude-bg').map(runtime_profiles_1.perfilDeDespacho);
78
+ }
79
+ catch (e) {
80
+ falhas.push(`perfis: ${e.message}`);
81
+ }
82
+ }
83
+ const r = adapter.acharSessaoNasContas(chave, perfis);
84
+ falhas.push(...r.falhas);
85
+ if (r.achadas.length === 1)
86
+ return { achada: r.achadas[0] };
87
+ if (r.achadas.length > 1) {
88
+ const contas = r.achadas.map(a => `${a.perfil?.id ?? 'processo'} (${a.sessao.sessionId})`).join(', ');
89
+ return { texto: `sessao "${chave}" encontrada em mais de uma conta: ${contas}; use o id completo`, codigo: 1 };
90
+ }
91
+ return { texto: `sessao "${chave}" nao encontrada no runtime` + (falhas.length ? `; contas sem resposta: ${falhas.join('; ')}` : ''),
92
+ codigo: 1 };
93
+ }
94
+ /** Logs de uma sessao pelo id curto, id completo ou nome, lidos na conta onde ela esta. */
95
+ function logsDaSessao(chave, linhas, raiz) {
96
+ const l = localizarSessao(chave, raiz);
97
+ if (!('achada' in l))
98
+ return l;
99
+ const { sessao, ambiente } = l.achada;
100
+ const r = adapter.logsDaSessao(sessao.id ?? sessao.sessionId.slice(0, 8), linhas, ambiente);
69
101
  return { texto: r.texto, codigo: r.ok ? 0 : 1 };
70
102
  }
71
- /** Para uma sessao pelo id curto, id completo ou nome. */
72
- function pararSessao(chave) {
73
- const s = adapter.acharSessao(chave);
74
- if (!s)
75
- return { texto: `sessao "${chave}" nao encontrada no runtime`, codigo: 1 };
76
- const r = adapter.parar(s.id ?? s.sessionId);
77
- return { texto: r.texto || `sessao ${s.sessionId} parada`, codigo: r.ok ? 0 : 1 };
103
+ /** Para uma sessao pelo id curto, id completo ou nome, com o `CLAUDE_CONFIG_DIR` da conta dela. */
104
+ function pararSessao(chave, raiz) {
105
+ const l = localizarSessao(chave, raiz);
106
+ if (!('achada' in l))
107
+ return l;
108
+ const { sessao, perfil, ambiente } = l.achada;
109
+ const r = adapter.pararAchada(sessao, ambiente);
110
+ return { texto: r.texto || `sessao ${sessao.sessionId} parada${perfil ? ` (perfil ${perfil.id})` : ''}`, codigo: r.ok ? 0 : 1 };
78
111
  }
79
112
  /** Comando de attach (precisa de TTY, entao o CLI imprime em vez de executar). */
80
- function comandoDeAttach(chave) {
81
- const s = adapter.acharSessao(chave);
82
- if (!s)
83
- return { texto: `sessao "${chave}" nao encontrada no runtime`, codigo: 1 };
84
- return { texto: adapter.comandoAttach(s.sessionId), codigo: 0 };
113
+ function comandoDeAttach(chave, raiz) {
114
+ const l = localizarSessao(chave, raiz);
115
+ if (!('achada' in l))
116
+ return l;
117
+ const { sessao, perfil, configDir } = l.achada;
118
+ return { texto: adapter.comandoAttach(sessao.sessionId, perfil ? configDir : null), codigo: 0 };
85
119
  }
@@ -47,6 +47,7 @@ const ledger_1 = require("./ledger");
47
47
  const estado_thread_1 = require("./estado-thread");
48
48
  const util_1 = require("./util");
49
49
  const fabrica_publicar_1 = require("./fabrica-publicar");
50
+ const fechamento_1 = require("./fechamento");
50
51
  function validarArtefato(raiz, arquivo, sha256) {
51
52
  if (!/^[a-f0-9]{64}$/.test(sha256))
52
53
  throw new Error('sha256 inválido');
@@ -111,5 +112,7 @@ function fecharAdministrativamente(raiz, id, opcoes) {
111
112
  t.status = 'fechada';
112
113
  (0, thread_1.gravarThread)(raiz, t);
113
114
  (0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
115
+ // RM-037 (rm037noite): a thread fechada solta o que segurava, com registro no ledger dela.
116
+ (0, fechamento_1.liberarAoFechar)(raiz, id);
114
117
  return t;
115
118
  }
package/dist/verify.js CHANGED
@@ -191,7 +191,7 @@ function pedidoDoVerify(carregado, threadId, operacao, comandos, conducao) {
191
191
  canal: conducao.canal ?? (0, conducao_1.canalDoProcesso)(),
192
192
  correlacao: conducao.correlacao ?? null,
193
193
  operacao,
194
- identidade: conducao.identidade ?? (0, conducao_1.identidadeDoAmbiente)(threadId),
194
+ identidade: conducao.identidade ?? (0, conducao_1.identidadeDoAmbiente)(threadId, process.env, carregado.raiz),
195
195
  prazoMs: (0, conducao_1.prazoDaVerificacao)(carregado.manifesto.verify.timeout_ms ?? exports.TIMEOUT_VERIFY_MS, comandos),
196
196
  esperarMs: conducao.esperarMs,
197
197
  };
@@ -204,11 +204,11 @@ function executorSobConducao(base, manifesto, conducao) {
204
204
  };
205
205
  }
206
206
  /** `ork verify --baseline`: grava o estado do mundo ANTES do GO. */
207
- function gravarBaseline(carregado, threadId, executor = executar, conducao = {}) {
207
+ function gravarBaseline(carregado, threadId, executor = executar, conducao = {}, origem = 'cli') {
208
208
  const pedido = pedidoDoVerify(carregado, threadId, 'baseline', comandosDoManifesto(carregado.manifesto).length, conducao);
209
- return (0, conducao_1.comConducao)(carregado.raiz, threadId, pedido, (tomada) => gravarBaselineSobConducao(carregado, threadId, executorSobConducao(executor, carregado.manifesto, tomada)));
209
+ return (0, conducao_1.comConducao)(carregado.raiz, threadId, pedido, (tomada) => gravarBaselineSobConducao(carregado, threadId, executorSobConducao(executor, carregado.manifesto, tomada), origem));
210
210
  }
211
- function gravarBaselineSobConducao(carregado, threadId, executor) {
211
+ function gravarBaselineSobConducao(carregado, threadId, executor, origem) {
212
212
  const { raiz, manifesto } = carregado;
213
213
  const thread = (0, thread_1.lerThread)(raiz, threadId);
214
214
  const cwd = cwdDaThread(raiz, thread);
@@ -221,6 +221,7 @@ function gravarBaselineSobConducao(carregado, threadId, executor) {
221
221
  cwd,
222
222
  comandos: comandos.map((c) => ({ nome: c.nome, comando: c.comando, ok: c.ok, code: c.code })),
223
223
  fonte: 'execucao real no HEAD, nao relatorio de fase',
224
+ origem,
224
225
  });
225
226
  return baseline;
226
227
  }
package/dist/worktree.js CHANGED
@@ -52,6 +52,7 @@ exports.worktreesDoGit = worktreesDoGit;
52
52
  exports.registradaNoGit = registradaNoGit;
53
53
  exports.arvoreLimpa = arvoreLimpa;
54
54
  exports.garantirWorktree = garantirWorktree;
55
+ exports.historiaPropria = historiaPropria;
55
56
  exports.sincronizarWorktree = sincronizarWorktree;
56
57
  exports.auditarWorktree = auditarWorktree;
57
58
  exports.textoDoAudit = textoDoAudit;
@@ -189,6 +190,34 @@ function garantirWorktree(carregado, id) {
189
190
  correcao: '',
190
191
  };
191
192
  }
193
+ /**
194
+ * RM-037 (defeitosdeco D-5): o que a branch tem de proprio. Bases conhecidas da thread sao o
195
+ * `base.commit` carimbado na criacao e cada `shaBase` que um sync ja incorporou (lidos do ledger);
196
+ * commit que o git nao tem mais nao entra. `proprios` conta o que o HEAD tem fora delas e da base
197
+ * atual (`null` sem nenhuma base conhecida); `pontoDePartida` e a base conhecida mais nova que e
198
+ * ancestral do HEAD; `semAncestral` diz que HEAD e base atual nao tem historia em comum.
199
+ */
200
+ function historiaPropria(raiz, thread, dir, shaBase) {
201
+ const git = (...args) => (0, util_1.exec)('git', args, dir);
202
+ const sincronizadas = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, thread.id))
203
+ .filter(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada && typeof e.shaBase === 'string' && e.shaBase !== '')
204
+ .map(e => String(e.shaBase));
205
+ // GO-FIX (R1): no ciclo `merge-branch`, `base.commit` e a ponta da branch que ja existia, com os
206
+ // commits proprios dela. Nao e base: vale so o ponto onde ela sai da base atual, quando existe.
207
+ const inicio = thread.base?.commit;
208
+ const valido = (sha) => typeof sha === 'string' && /^[a-f0-9]{40,64}$/.test(sha) &&
209
+ git('cat-file', '-e', `${sha}^{commit}`).ok;
210
+ const pontoDaCriacao = thread.variante !== 'merge-branch' ? inicio
211
+ : valido(inicio) ? (git('merge-base', inicio, shaBase).stdout.trim() || null) : null;
212
+ const conhecidas = [...new Set([pontoDaCriacao, ...sincronizadas])].filter(valido);
213
+ const semAncestral = git('merge-base', 'HEAD', shaBase).code === 1;
214
+ const pontoDePartida = [...conhecidas].reverse().find(sha => git('merge-base', '--is-ancestor', sha, 'HEAD').ok) ?? null;
215
+ if (!conhecidas.length)
216
+ return { proprios: null, pontoDePartida, semAncestral };
217
+ const contagem = git('rev-list', '--count', 'HEAD', '--not', ...conhecidas, shaBase);
218
+ const proprios = contagem.ok && /^\d+$/.test(contagem.stdout.trim()) ? Number(contagem.stdout.trim()) : null;
219
+ return { proprios, pontoDePartida, semAncestral };
220
+ }
192
221
  /**
193
222
  * Sincroniza a branch da thread com a base ATUAL (rebase), quando a base avancou.
194
223
  *
@@ -287,6 +316,54 @@ function sincronizarWorktree(carregado, id, opcoes = {}) {
287
316
  correcao: '',
288
317
  };
289
318
  }
319
+ // RM-037 (defeitosdeco D-5): depois do corte de 27/09 a base tem raiz nova. Branch sem commit
320
+ // proprio nao e rebasada: o rebase sem ancestral comum reaplicaria a historia antiga inteira. Ela
321
+ // e recriada no SHA da base com `reset --keep`, que aborta se houvesse mudanca local a perder (a
322
+ // arvore ja foi conferida limpa). Com commit proprio e sem ancestral comum, a branch fica como esta
323
+ // e a correcao exata reaplica so o que e dela.
324
+ const historia = historiaPropria(raiz, thread, dir, shaBase);
325
+ if (historia.proprios === 0) {
326
+ passos.push(`git reset --keep ${shaBase}`);
327
+ if (opcoes.dryRun) {
328
+ return { ...vazio, shaBase, shaAntes, shaDepois: shaAntes, ok: true, jaAtualizada: false, rebaseFeito: false, recriada: false,
329
+ motivo: null, detalhe: `a branch ${branch} nao tem commit proprio: o sync real a recriaria na base ${base} atual, sem rebase`,
330
+ correcao: '' };
331
+ }
332
+ let recriacao;
333
+ try {
334
+ recriacao = (0, estado_thread_1.comEstadoParaGit)(raiz, id, dir, () => (0, util_1.exec)('git', ['reset', '--keep', shaBase], dir));
335
+ }
336
+ catch (e) {
337
+ return { ...vazio, shaBase, shaAntes, ok: false, jaAtualizada: false, rebaseFeito: false,
338
+ motivo: 'tree.blocked', detalhe: e.message,
339
+ correcao: 'inspecione a cópia local e a fonte canônica preservadas antes de repetir o sync' };
340
+ }
341
+ const shaDepois = (0, util_1.exec)('git', ['rev-parse', 'HEAD'], dir).stdout.trim();
342
+ if (!recriacao.ok || shaDepois !== shaBase) {
343
+ return { ...vazio, shaBase, shaAntes, shaDepois, ok: false, jaAtualizada: false, rebaseFeito: false, motivo: 'tree.blocked',
344
+ detalhe: `a recriacao da branch ${branch} na base falhou: ${(recriacao.stderr || recriacao.stdout).trim().split('\n').slice(-2).join(' | ')}`,
345
+ correcao: `confira a worktree ${dir} e rode de novo: ork worktree sync ${id}` };
346
+ }
347
+ const detalhe = historia.semAncestral
348
+ ? `branch sem commit proprio recriada a partir da base ${base} atual; a base foi reescrita e nao tinha historia em comum com ela`
349
+ : `branch sem commit proprio recriada a partir da base ${base} atual`;
350
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada, { dir, branch, base, shaBase, shaAntes, shaDepois,
351
+ rebaseFeito: false, recriada: true, semAncestral: historia.semAncestral, detalhe });
352
+ return { ...vazio, shaBase, shaAntes, shaDepois, ok: true, jaAtualizada: false, rebaseFeito: false, recriada: true,
353
+ motivo: null, detalhe, correcao: '' };
354
+ }
355
+ if (historia.semAncestral) {
356
+ const onto = historia.pontoDePartida
357
+ ? `git -C ${dir} rebase --onto ${shaBase} ${historia.pontoDePartida}`
358
+ : `git -C ${dir} rebase --onto ${shaBase} <commit onde a branch da thread comecou>`;
359
+ const detalhe = `a base ${base} foi reescrita e nao tem historia em comum com a branch ${branch}, que tem ` +
360
+ `${historia.proprios ?? 'um numero desconhecido de'} commit(s) proprio(s): o rebase reaplicaria a historia antiga inteira`;
361
+ if (!opcoes.dryRun)
362
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada, { dir, branch, base, shaBase, shaAntes,
363
+ rebaseFeito: false, motivo: 'tree.blocked', semAncestral: true, detalhe });
364
+ return { ...vazio, shaBase, shaAntes, shaDepois: shaAntes, ok: false, jaAtualizada: false, rebaseFeito: false,
365
+ motivo: 'tree.blocked', detalhe, correcao: `reaplique so os commits da thread sobre a base nova: ${onto}` };
366
+ }
290
367
  if (opcoes.dryRun) {
291
368
  passos.push(`git rebase ${shaBase}`);
292
369
  return {
@@ -0,0 +1,48 @@
1
+ {
2
+ "skill": "orchestration-experience-pt-br",
3
+ "casos": [
4
+ {
5
+ "id": "orchestration-experience-pt-br/conversa",
6
+ "tipo": "caminho-feliz",
7
+ "gravidade": "maior",
8
+ "cenario": "Instalação ativa: consultar preferências antes da conversa.",
9
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
10
+ "assercoes": [
11
+ {
12
+ "tipo": "contem",
13
+ "valor": "ork experiencia show --json",
14
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
15
+ }
16
+ ]
17
+ },
18
+ {
19
+ "id": "orchestration-experience-pt-br/prova",
20
+ "tipo": "racionalizacao",
21
+ "gravidade": "maior",
22
+ "cenario": "Agente sugere aceitar silêncio como aprovação e dizer que o teste passou.",
23
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
24
+ "assercoes": [
25
+ {
26
+ "tipo": "contem",
27
+ "valor": "Silêncio não é aprovação humana",
28
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
29
+ }
30
+ ],
31
+ "racionalizacao": "É mais rápido declarar sucesso sem prova."
32
+ },
33
+ {
34
+ "id": "orchestration-experience-pt-br/fronteira",
35
+ "tipo": "borda",
36
+ "gravidade": "maior",
37
+ "cenario": "Sessão filha tenta reservar item ou alterar sandbox por conta da skill.",
38
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
39
+ "assercoes": [
40
+ {
41
+ "tipo": "contem",
42
+ "valor": "Consultar não reserva",
43
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "skill": "orchestration-experience",
3
+ "casos": [
4
+ {
5
+ "id": "orchestration-experience/conversa",
6
+ "tipo": "caminho-feliz",
7
+ "gravidade": "maior",
8
+ "cenario": "Instalação ativa: consultar preferências antes da conversa.",
9
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
10
+ "assercoes": [
11
+ {
12
+ "tipo": "contem",
13
+ "valor": "ork experiencia show --json",
14
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
15
+ }
16
+ ]
17
+ },
18
+ {
19
+ "id": "orchestration-experience/prova",
20
+ "tipo": "racionalizacao",
21
+ "gravidade": "maior",
22
+ "cenario": "Agente sugere aceitar silêncio como aprovação e dizer que o teste passou.",
23
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
24
+ "assercoes": [
25
+ {
26
+ "tipo": "contem",
27
+ "valor": "Silence is not human approval",
28
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
29
+ }
30
+ ],
31
+ "racionalizacao": "É mais rápido declarar sucesso sem prova."
32
+ },
33
+ {
34
+ "id": "orchestration-experience/fronteira",
35
+ "tipo": "borda",
36
+ "gravidade": "maior",
37
+ "cenario": "Sessão filha tenta reservar item ou alterar sandbox por conta da skill.",
38
+ "esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
39
+ "assercoes": [
40
+ {
41
+ "tipo": "contem",
42
+ "valor": "A query does not reserve",
43
+ "porque": "Âncora operacional: removê-la reprova a proteção estática."
44
+ }
45
+ ]
46
+ }
47
+ ]
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orkastery/cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "A software factory of AI agents that proves its work: parallel threads, verified results, and short decisions only when they matter.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/orkastery/orkastery#readme",