@orkastery/cli 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/adapters/claude-code/agents/ork-master.md +2 -0
  2. package/adapters/claude-code/commands/master.md +8 -0
  3. package/adapters/claude-code/commands/ork.md +9 -0
  4. package/adapters/codex/skills/ork/SKILL.md +18 -3
  5. package/adapters/hermes/README.md +1 -0
  6. package/adapters/hermes/bin/ork-network-status.sh +10 -0
  7. package/adapters/hermes/hermes.plugin.json +1 -0
  8. package/adapters/hermes/hitl-ingress/__init__.py +2 -2
  9. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +6 -5
  10. package/adapters/openclaw/README.md +24 -4
  11. package/adapters/openclaw/dist/hitl-ingress.js +2 -2
  12. package/adapters/openclaw/dist/index.js +46 -11
  13. package/adapters/openclaw/openclaw.plugin.json +5 -1
  14. package/adapters/openclaw/package.json +2 -2
  15. package/adapters/openclaw/src/hitl-ingress.ts +2 -2
  16. package/adapters/openclaw/src/index.ts +49 -11
  17. package/assets/orkmind_bridge.py +117 -9
  18. package/dist/adapters/claude-bg.js +39 -5
  19. package/dist/adapters/codex.js +4 -3
  20. package/dist/agents-md.js +1 -0
  21. package/dist/auditrun.js +5 -1
  22. package/dist/board.js +16 -14
  23. package/dist/branch-de-estado.js +66 -10
  24. package/dist/busca-semantica.js +52 -12
  25. package/dist/canarios-rm057.js +149 -0
  26. package/dist/canarios.js +2 -0
  27. package/dist/ci.js +8 -1
  28. package/dist/claims.js +39 -1
  29. package/dist/company-brain-context.js +158 -22
  30. package/dist/docs.js +48 -9
  31. package/dist/doctor-pulse-cron.js +194 -0
  32. package/dist/doctor-rede.js +149 -0
  33. package/dist/doctor.js +89 -9
  34. package/dist/entrega-pr.js +20 -8
  35. package/dist/esgotamentos.js +181 -0
  36. package/dist/experiencia.js +12 -2
  37. package/dist/fabrica-estado.js +14 -6
  38. package/dist/fabrica-publicar.js +6 -0
  39. package/dist/fechamento.js +20 -66
  40. package/dist/forja.js +31 -7
  41. package/dist/gates.js +5 -1
  42. package/dist/hitl-contract.js +59 -4
  43. package/dist/hitl-curto.js +11 -6
  44. package/dist/hitl-gates.js +5 -0
  45. package/dist/hitl-lote.js +5 -2
  46. package/dist/hitl-resumo.js +9 -0
  47. package/dist/hitl-tempo-parado.js +201 -0
  48. package/dist/hitl-texto-livre.js +5 -5
  49. package/dist/horario.js +27 -0
  50. package/dist/hosts.js +52 -10
  51. package/dist/impedimento.js +205 -0
  52. package/dist/index.js +391 -74
  53. package/dist/indice-vetorial.js +87 -10
  54. package/dist/indice.js +3 -1
  55. package/dist/init.js +17 -0
  56. package/dist/integracoes-locais.js +2 -0
  57. package/dist/intelligence-graph-cli.js +91 -8
  58. package/dist/intelligence-graph-contexto.js +215 -0
  59. package/dist/intelligence-graph-parsers.js +6 -4
  60. package/dist/leases.js +664 -87
  61. package/dist/ledger-stats.js +15 -1
  62. package/dist/ledger.js +3 -0
  63. package/dist/licoes.js +1 -0
  64. package/dist/maestro-runtime.js +4 -1
  65. package/dist/manifest.js +20 -1
  66. package/dist/master-nota.js +14 -5
  67. package/dist/master.js +129 -12
  68. package/dist/mcp-artifacts.js +34 -3
  69. package/dist/mcp-git.js +20 -3
  70. package/dist/mcp-grafo-worker.js +5 -3
  71. package/dist/mcp-grafo.js +50 -4
  72. package/dist/mcp-server.js +14 -1
  73. package/dist/memoria.js +48 -6
  74. package/dist/network-roadmap.js +191 -16
  75. package/dist/ocupacao.js +11 -3
  76. package/dist/orkmind.js +90 -5
  77. package/dist/orquestracao.js +12 -10
  78. package/dist/parado-no-condutor.js +188 -32
  79. package/dist/phase.js +68 -15
  80. package/dist/policies.js +52 -1
  81. package/dist/portfolio.js +4 -1
  82. package/dist/projeto-alvo.js +5 -1
  83. package/dist/prompts.js +36 -1
  84. package/dist/prova-ativacao.js +75 -6
  85. package/dist/pulse-delivery.js +34 -2
  86. package/dist/pulse.js +49 -3
  87. package/dist/ratelimit.js +20 -4
  88. package/dist/recall.js +3 -1
  89. package/dist/rede-adesao.js +399 -0
  90. package/dist/rede-forja.js +289 -0
  91. package/dist/rede-projetos.js +239 -0
  92. package/dist/rede-status.js +336 -0
  93. package/dist/rede.js +980 -0
  94. package/dist/retry.js +69 -2
  95. package/dist/roadmap-status.js +23 -3
  96. package/dist/runtime-profiles.js +22 -1
  97. package/dist/saida-segura.js +58 -0
  98. package/dist/session-watcher-claude.js +113 -23
  99. package/dist/sessoes-contas.js +187 -0
  100. package/dist/sessoes-inventario.js +6 -18
  101. package/dist/sessoes.js +83 -2
  102. package/dist/ship.js +85 -19
  103. package/dist/thread.js +192 -13
  104. package/dist/worktree.js +5 -2
  105. package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
  106. package/package.json +7 -3
  107. package/references/definition-of-done.md +1 -1
  108. package/skills/README.md +1 -1
  109. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  110. package/skills/phases/master-metrics/SKILL.md +8 -3
package/dist/thread.js CHANGED
@@ -47,7 +47,16 @@ exports.lerThread = lerThread;
47
47
  exports.gravarThread = gravarThread;
48
48
  exports.avisoDeThreadSemBase = avisoDeThreadSemBase;
49
49
  exports.idDisponivel = idDisponivel;
50
+ exports.pastaDaWorktree = pastaDaWorktree;
51
+ exports.alvoDaWorktree = alvoDaWorktree;
52
+ exports.worktreePrevista = worktreePrevista;
50
53
  exports.criarWorktree = criarWorktree;
54
+ exports.pedidoDeWorktree = pedidoDeWorktree;
55
+ exports.linhaDaWorktree = linhaDaWorktree;
56
+ exports.avisoDeThreadSemWorktree = avisoDeThreadSemWorktree;
57
+ exports.avisoDeWorktreeQueFalharia = avisoDeWorktreeQueFalharia;
58
+ exports.avisoDeChaveSemCommit = avisoDeChaveSemCommit;
59
+ exports.avisoDaWorktree = avisoDaWorktree;
51
60
  exports.novaThread = novaThread;
52
61
  exports.exigirVarianteCompativel = exigirVarianteCompativel;
53
62
  exports.blocoDaThread = blocoDaThread;
@@ -141,6 +150,43 @@ function idDisponivel(raiz, abbrev, assunto) {
141
150
  }
142
151
  return { id: `${abbrev}-${candidato}`, assunto: candidato };
143
152
  }
153
+ /**
154
+ * Pasta da worktree de uma thread: `worktree.dir` resolvido na arvore principal, nunca na worktree de onde o comando
155
+ * roda. P4 do ensaio da 0.5.0 (CHECK): com a chave valendo, o `ork thread new` rodado de dentro da worktree de outra
156
+ * thread aninhava a nova na pasta da mae, e o release da mae levava a da filha junto.
157
+ */
158
+ function pastaDaWorktree(carregado, id) {
159
+ return path.resolve((0, estado_thread_1.raizDoEstado)(carregado.raiz), carregado.manifesto.worktree.dir, id);
160
+ }
161
+ /** Pasta e branch da worktree de uma thread: o que `criarWorktree` cria e o `--dry-run` preve. */
162
+ function alvoDaWorktree(carregado, id, slug, opcoes = {}) {
163
+ return { dir: pastaDaWorktree(carregado, id), branch: opcoes.branchExistente ?? `ork/${slug}` };
164
+ }
165
+ /**
166
+ * P4 do ensaio da 0.5.0: a worktree que `criarWorktree` criaria para este id, sem criar nada. Mesma pasta, mesma
167
+ * branch e o commit de onde ela partiria: a branch existente (ciclo `merge-branch`), senao a base do manifesto,
168
+ * senao o HEAD. Diz tambem o que faria a criacao recusar: a pasta que ja existe, o repositorio sem commit ou a
169
+ * branch nova que ja existe.
170
+ */
171
+ function worktreePrevista(carregado, id, slug, opcoes = {}) {
172
+ const alvo = alvoDaWorktree(carregado, id, slug, opcoes);
173
+ const refs = opcoes.branchExistente
174
+ ? [opcoes.branchExistente]
175
+ : [opcoes.base ?? carregado.manifesto.worktree.base_branch, 'HEAD'];
176
+ let commit = null;
177
+ for (const ref of refs) {
178
+ const r = (0, util_1.exec)('git', ['rev-parse', '--verify', ref], carregado.raiz);
179
+ if (r.ok) {
180
+ commit = r.stdout.trim();
181
+ break;
182
+ }
183
+ }
184
+ const branchJaExiste = !opcoes.branchExistente &&
185
+ (0, util_1.exec)('git', ['rev-parse', '--verify', '--quiet', `refs/heads/${alvo.branch}`], carregado.raiz).ok;
186
+ const falha = fs.existsSync(alvo.dir) ? 'pasta-existe'
187
+ : commit === null ? 'sem-commit' : branchJaExiste ? 'branch-existe' : null;
188
+ return { ...alvo, commit, falha };
189
+ }
144
190
  /**
145
191
  * Cria a worktree isolada da thread (paralelismo sem colisao entre threads).
146
192
  *
@@ -150,8 +196,7 @@ function idDisponivel(raiz, abbrev, assunto) {
150
196
  */
151
197
  function criarWorktree(carregado, id, slug, opcoes = {}) {
152
198
  const { raiz, manifesto } = carregado;
153
- const dir = path.resolve(raiz, manifesto.worktree.dir, id);
154
- const branch = opcoes.branchExistente ?? `ork/${slug}`;
199
+ const { dir, branch } = alvoDaWorktree(carregado, id, slug, opcoes);
155
200
  if (fs.existsSync(dir)) {
156
201
  throw new Error(`worktree ja existe em ${dir}`);
157
202
  }
@@ -170,7 +215,7 @@ function criarWorktree(carregado, id, slug, opcoes = {}) {
170
215
  throw new Error(`git worktree add falhou: ${(r.stderr || r.stdout).trim()}`);
171
216
  }
172
217
  if (pastaNova)
173
- (0, util_1.ignorarPastaNoGit)(pastaDasWorktrees, raiz);
218
+ (0, util_1.ignorarPastaNoGit)(pastaDasWorktrees, (0, estado_thread_1.raizDoEstado)(raiz));
174
219
  const lista = (0, util_1.exec)('git', ['worktree', 'list', '--porcelain'], raiz);
175
220
  const criada = lista.ok && lista.stdout.split('\n').some((l) => l.trim() === `worktree ${dir}`);
176
221
  if (!criada) {
@@ -179,6 +224,105 @@ function criarWorktree(carregado, id, slug, opcoes = {}) {
179
224
  (0, estado_thread_1.vincularEstado)(raiz, id, dir);
180
225
  return { dir, branch };
181
226
  }
227
+ /**
228
+ * Resolve `--worktree`, `--sem-worktree` e `worktree.por_thread`. As flags vencem a chave; as duas juntas, ou
229
+ * `--sem-worktree` com valor (o parser leva o argumento seguinte), sao erro de uso. `--worktree` sozinho ou `auto`
230
+ * cria a worktree; outro texto e um diretorio que ja existe, como antes.
231
+ */
232
+ function pedidoDeWorktree(flags, porThread) {
233
+ const worktree = flags.worktree === false ? undefined : flags.worktree;
234
+ if (typeof worktree === 'string' && !worktree.trim())
235
+ throw new Error('uso: --worktree pede auto ou um diretório que já existe');
236
+ if (typeof flags.semWorktree === 'string') {
237
+ throw new Error(`uso: --sem-worktree não leva valor (recebeu "${flags.semWorktree}")`);
238
+ }
239
+ const semWorktree = flags.semWorktree === true;
240
+ if (semWorktree && worktree !== undefined)
241
+ throw new Error('uso: --worktree e --sem-worktree se excluem; use um dos dois');
242
+ if (semWorktree)
243
+ return { criar: false, dir: null, origem: 'sem-worktree' };
244
+ if (worktree === true || worktree === 'auto')
245
+ return { criar: true, dir: null, origem: 'flag' };
246
+ if (typeof worktree === 'string')
247
+ return { criar: false, dir: worktree, origem: 'diretorio' };
248
+ return porThread ? { criar: true, dir: null, origem: 'chave' } : { criar: false, dir: null, origem: 'nenhuma' };
249
+ }
250
+ /**
251
+ * P4 do ensaio da 0.5.0: a linha que diz de onde veio a worktree da thread nova. Na criacao, so quando ela veio da
252
+ * chave (quem passou `--worktree auto` sabe de onde ela veio); no `--dry-run`, para qualquer origem.
253
+ */
254
+ function linhaDaWorktree(por, gravada, variante) {
255
+ if (!por || (gravada && por !== 'chave'))
256
+ return null;
257
+ const verbo = gravada ? 'criada' : 'seria criada';
258
+ if (por === 'chave') {
259
+ return ` worktree: ${verbo} pela chave worktree.por_thread do orkastery.yaml; para criar sem ela, use --sem-worktree`;
260
+ }
261
+ if (por === 'flag')
262
+ return ` worktree: ${verbo} pelo --worktree auto`;
263
+ return ` worktree: ${verbo} pelo ciclo ${variante ?? 'da thread'}, que exige worktree isolada`;
264
+ }
265
+ /**
266
+ * P4 do ensaio da 0.5.0: o que acontece no SHIP com a thread criada por `--sem-worktree`. O `ork ship` entrega a
267
+ * branch em que a raiz estava na criacao (`thread.base.branch`), e a policy `push_direto_na_base` do manifesto barra
268
+ * (`block`), avisa (outro valor) ou deixa passar (sem ela, ou `off`) a entrega de uma branch para ela mesma ou da
269
+ * base. Raiz fora de branch (HEAD destacado ou repositorio sem commit) nao tem branch de origem.
270
+ */
271
+ function avisoDeThreadSemWorktree(thread, manifesto, gravada = true) {
272
+ const base = manifesto.worktree.base_branch;
273
+ const branch = thread.base.branch;
274
+ const inicio = gravada
275
+ ? `Aviso: thread ${thread.id} sem worktree (--sem-worktree): ela trabalha na raiz do projeto`
276
+ : `Aviso: sem worktree (--sem-worktree), a thread ${thread.id} trabalharia na raiz do projeto`;
277
+ const ensure = `Antes do GO, ork worktree ensure ${thread.id} cria a worktree e a branch da thread`;
278
+ if (thread.base.commit === util_1.COMMIT_DESCONHECIDO) {
279
+ // Sem commit, nem o `ork worktree ensure` tem de onde partir: o caminho e o do aviso de thread sem base.
280
+ return `${inicio}, num repositório ainda sem commit, fora de qualquer branch, e o ork ship não tem branch de origem ` +
281
+ 'para entregar. Faça o primeiro commit e siga o aviso de thread sem base.';
282
+ }
283
+ if (branch === 'HEAD') {
284
+ return `${inicio}, com o HEAD destacado, fora de qualquer branch, e o ork ship não tem branch de origem para entregar. ${ensure}.`;
285
+ }
286
+ if (branch !== base) {
287
+ return `${inicio}, na branch ${branch}, e o ork ship entrega essa branch como estiver, com o que mais entrar nela; ` +
288
+ `com --para ${branch}, a entrega vira push direto, que a policy push_direto_na_base confere. ${ensure}.`;
289
+ }
290
+ const policy = manifesto.policies?.push_direto_na_base;
291
+ const efeito = policy === 'block'
292
+ ? 'o ork ship barra a entrega por push_direto_na_base (block): não há branch de thread para mergear'
293
+ : policy === undefined || policy === 'off'
294
+ ? 'o ork ship empurra a base direto, sem branch de thread (push_direto_na_base desligada)'
295
+ : `o ork ship avisa push_direto_na_base (${policy}) e empurra a base direto, sem branch de thread`;
296
+ return `${inicio}, na branch base ${base}, e ${efeito}. ${ensure}; depois do GO, os commits já estão na base e o ship não os separa.`;
297
+ }
298
+ /**
299
+ * P4 do ensaio da 0.5.0 (CHECK): no `--dry-run`, por que a criacao de verdade recusaria a worktree, em vez de preve-la.
300
+ * O ciclo que exige worktree nao aceita `--sem-worktree`, entao a saida so e sugerida para a chave e a flag.
301
+ */
302
+ function avisoDeWorktreeQueFalharia(f) {
303
+ const semWorktree = f.por === 'ciclo' ? '' : ' ou crie com --sem-worktree';
304
+ if (f.motivo === 'pasta-existe') {
305
+ return `Aviso: a pasta ${f.dir} já existe, e a criação de verdade recusaria a worktree da thread: tire a pasta${semWorktree}.`;
306
+ }
307
+ if (f.motivo === 'branch-existe') {
308
+ return `Aviso: a branch ${f.branch} já existe, e a criação de verdade recusaria a worktree da thread: tire a branch${semWorktree}.`;
309
+ }
310
+ return 'Aviso: o repositório ainda não tem commit, e a criação de verdade recusaria a worktree da thread no git worktree add: ' +
311
+ 'faça o primeiro commit antes.';
312
+ }
313
+ /** P4 do ensaio da 0.5.0: a worktree que a chave pede nao tem de onde partir num repositorio sem commit. */
314
+ function avisoDeChaveSemCommit(gravada) {
315
+ return 'Aviso: worktree.por_thread pede a worktree da thread, mas o repositório ainda não tem commit: ' +
316
+ `a thread ${gravada ? 'nasceu' : 'nasceria'} na raiz do projeto, sem worktree.`;
317
+ }
318
+ /** P4: o aviso de worktree do `ork thread new`, para o stderr, ou `null` quando nao ha o que avisar. */
319
+ function avisoDaWorktree(origem, resultado, manifesto) {
320
+ if (origem === 'sem-worktree')
321
+ return avisoDeThreadSemWorktree(resultado.thread, manifesto, resultado.gravada);
322
+ if (origem === 'chave' && !resultado.worktreePor)
323
+ return avisoDeChaveSemCommit(resultado.gravada);
324
+ return null;
325
+ }
182
326
  /** Cria a thread: valida modo contra o manifesto, gera o slug e carimba a base. */
183
327
  function novaThread(carregado, opcoes) {
184
328
  if (opcoes.dryRun)
@@ -236,6 +380,13 @@ function criarThreadSerializada(carregado, opcoes) {
236
380
  else if (opcoes.branch) {
237
381
  throw new Error('--branch so vale com --ciclo merge-branch');
238
382
  }
383
+ // `greenfield`, `merge-branch` e `feature-xl-faseada` exigem worktree isolada: sao os
384
+ // ciclos que escrevem codigo em paralelo com outras threads.
385
+ const exigeWorktree = variante ? (0, ciclos_1.definicaoDaVariante)(variante).exigeWorktree : false;
386
+ // P4 do ensaio da 0.5.0 (D4): o ciclo que exige worktree nao nasce sem ela, e a recusa sai antes de gravar.
387
+ if (exigeWorktree && opcoes.origemDaWorktree === 'sem-worktree') {
388
+ throw new Error(`o ciclo ${variante} exige worktree isolada: crie a thread sem --sem-worktree ou escolha outro ciclo`);
389
+ }
239
390
  const reservation = opcoes.reservation;
240
391
  const operation = reservation ? (0, creation_operation_store_1.readCreationOperation)(raiz, reservation.operationId, reservation.principal) : null;
241
392
  if (operation && (!operation.reserved.threadIds.includes(reservation.threadId)
@@ -260,11 +411,11 @@ function criarThreadSerializada(carregado, opcoes) {
260
411
  && fs.readdirSync(dirThread(raiz, reservation.threadId)).some((name) => !/^\.thread\.json\..+\.tmp$/.test(name))) {
261
412
  throw new Error('creation.conflict: diretório reservado sem origem confirmada');
262
413
  }
414
+ // P4 do ensaio da 0.5.0 (CHECK): o ensaio usa o mesmo id livre da criacao (o `idDisponivel` so le o disco), para a
415
+ // worktree que ele mostra ser a que a criacao usaria.
263
416
  const { id, assunto } = reservation
264
417
  ? { id: reservation.threadId, assunto: reservation.threadId.slice(abbrev.length + 1) }
265
- : opcoes.dryRun
266
- ? { id: `${abbrev}-${assuntoBruto}`, assunto: assuntoBruto }
267
- : idDisponivel(raiz, abbrev, assuntoBruto);
418
+ : idDisponivel(raiz, abbrev, assuntoBruto);
268
419
  const slug = opcoes.slug ?? (0, slug_1.montarSlug)(abbrev, assunto, blocos[0].slugFases);
269
420
  // O override `--slug` do builder tambem passa pela regex canonica.
270
421
  if (!(0, slug_1.slugValido)(slug)) {
@@ -300,13 +451,38 @@ function criarThreadSerializada(carregado, opcoes) {
300
451
  };
301
452
  if (variante === 'feature-xl-faseada')
302
453
  thread.fatias = opcoes.fatias ?? 3;
303
- if (opcoes.dryRun)
304
- return { thread, gravada: false };
454
+ // P4 do ensaio da 0.5.0: por que a thread ganha a worktree. O ensaio e a chave preveem a worktree antes; a pedida
455
+ // por flag ou por ciclo segue direto ao git, como era. A pedida so pela chave espera o primeiro commit (D3): sem
456
+ // commit, a thread fica na raiz, como antes. O ciclo que exige worktree vence a chave e a flag na origem: a worktree
457
+ // e dele, e o `--sem-worktree` que a linha da chave sugeriria ele recusa (CHECK, rodada 2).
458
+ const pedeWorktree = opcoes.criarWorktree === true || exigeWorktree;
459
+ const pelaChave = opcoes.criarWorktree === true && opcoes.origemDaWorktree === 'chave';
460
+ const prevista = pedeWorktree && (opcoes.dryRun || pelaChave)
461
+ ? worktreePrevista(carregado, id, slug, { branchExistente: opcoes.branch }) : null;
462
+ const worktreePor = !pedeWorktree || (pelaChave && !exigeWorktree && prevista?.falha === 'sem-commit') ? null
463
+ : exigeWorktree ? 'ciclo' : pelaChave ? 'chave' : 'flag';
464
+ if (opcoes.dryRun) {
465
+ // P4 (D8): o ensaio mostra a worktree que a criacao usaria; quando ela recusaria, diz por que, em vez de preve-la.
466
+ if (worktreePor && prevista?.falha) {
467
+ return { thread, gravada: false, worktreePor: null,
468
+ worktreeFalharia: { motivo: prevista.falha, dir: prevista.dir, branch: prevista.branch, por: worktreePor } };
469
+ }
470
+ if (worktreePor && prevista?.commit) {
471
+ thread.worktree = prevista.dir;
472
+ thread.base = { branch: prevista.branch, commit: prevista.commit };
473
+ }
474
+ return { thread, gravada: false, worktreePor };
475
+ }
476
+ // P4 (CHECK): a worktree pedida so pela chave, com a pasta ou a branch ja ocupadas, recusa dizendo de onde veio o
477
+ // pedido e qual e a saida.
478
+ const ocupadaPelaChave = pelaChave && !exigeWorktree && prevista &&
479
+ (prevista.falha === 'pasta-existe' || prevista.falha === 'branch-existe') ? prevista : null;
480
+ if (ocupadaPelaChave) {
481
+ const qual = ocupadaPelaChave.falha === 'pasta-existe' ? `a pasta ${ocupadaPelaChave.dir}` : `a branch ${ocupadaPelaChave.branch}`;
482
+ throw new Error(`${qual} já existe, e a chave worktree.por_thread pede a worktree da thread: tire-a ou crie com --sem-worktree`);
483
+ }
305
484
  let worktreeCriada = null;
306
- // `greenfield`, `merge-branch` e `feature-xl-faseada` exigem worktree isolada: sao os
307
- // ciclos que escrevem codigo em paralelo com outras threads.
308
- const exigeWorktree = variante ? (0, ciclos_1.definicaoDaVariante)(variante).exigeWorktree : false;
309
- if (opcoes.criarWorktree || exigeWorktree) {
485
+ if (worktreePor) {
310
486
  worktreeCriada = criarWorktree(carregado, id, slug, {
311
487
  branchExistente: opcoes.branch,
312
488
  });
@@ -328,6 +504,8 @@ function criarThreadSerializada(carregado, opcoes) {
328
504
  base: thread.base,
329
505
  projeto: manifesto.project.name,
330
506
  worktree: thread.worktree,
507
+ // P4 do ensaio da 0.5.0 (D9): quem abriu a thread sem worktree de proposito fica no rastro.
508
+ ...(opcoes.origemDaWorktree === 'sem-worktree' ? { semWorktree: true } : {}),
331
509
  variante,
332
510
  branchDeOrigem: opcoes.branch ?? null,
333
511
  maquina: thread.maquina,
@@ -338,10 +516,11 @@ function criarThreadSerializada(carregado, opcoes) {
338
516
  dir: worktreeCriada.dir,
339
517
  branch: worktreeCriada.branch,
340
518
  base: manifesto.worktree.base_branch,
519
+ origem: worktreePor,
341
520
  fonte: 'git worktree list --porcelain',
342
521
  });
343
522
  }
344
- return { thread, gravada: true };
523
+ return { thread, gravada: true, worktreePor };
345
524
  }
346
525
  /**
347
526
  * O bloco de loop que conduz a fase DESTA thread.
package/dist/worktree.js CHANGED
@@ -64,9 +64,12 @@ const leases_1 = require("./leases");
64
64
  const thread_1 = require("./thread");
65
65
  const util_1 = require("./util");
66
66
  const estado_thread_1 = require("./estado-thread");
67
- /** Diretorio canonico da worktree de uma thread, resolvido pelo `ork`. */
67
+ /**
68
+ * Diretorio canonico da worktree de uma thread, resolvido pelo `ork` na arvore principal: o mesmo que a criacao usa,
69
+ * tambem quando o comando roda de dentro de outra worktree (P4 do ensaio da 0.5.0).
70
+ */
68
71
  function dirDaWorktree(carregado, id) {
69
- return path.resolve(carregado.raiz, carregado.manifesto.worktree.dir, id);
72
+ return (0, thread_1.pastaDaWorktree)(carregado, id);
70
73
  }
71
74
  /** Branch canonica da worktree de uma thread. */
72
75
  function branchDaWorktree(thread) {
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "fx-pedido-colado",
3
+ "sobre": "Incidente de 01/10/2026 (RM-057): o pedido colado com autorização explícita segue sem parar",
4
+ "precisa": [
5
+ "git"
6
+ ],
7
+ "esperado": {
8
+ "simulado": true,
9
+ "modoDoPedido": "auto",
10
+ "semPausaDoModo": true,
11
+ "decisaoInformada": true,
12
+ "confirmoRecusado": "hitl.selecao.texto-livre",
13
+ "nadaGravadoNaRecusa": true,
14
+ "humanosNoPulse": 0,
15
+ "perguntasDeConducao": 0,
16
+ "tempoParadoMs": 0,
17
+ "adaptadoresComARegra": 4
18
+ },
19
+ "porque": "Na noite de 01 para 02/10 o condutor parou mais de 10 h pedindo um confirmo em texto livre a um pedido colado que já trazia a autorização. O canário prova, contra o código real, que o #Auto não pausa, a dúvida vira decisão informada, o confirmo em texto é recusado sem gravar nada, ninguém aparece esperando no pulse, o tempo parado é zero e os quatro adaptadores dizem a regra."
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orkastery/cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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",
@@ -65,12 +65,16 @@
65
65
  },
66
66
  "devDependencies": {
67
67
  "@types/node": "^22.10.2",
68
- "markdownlint-cli2": "^0.23.3",
69
- "typescript": "^5.9.2"
68
+ "markdownlint-cli2": "^0.22.1"
70
69
  },
71
70
  "dependencies": {
72
71
  "@modelcontextprotocol/sdk": "1.29.0",
72
+ "decode-named-character-reference": "1.3.0",
73
+ "micromark": "4.0.2",
74
+ "micromark-extension-gfm-table": "2.1.1",
75
+ "micromark-util-decode-numeric-character-reference": "2.0.2",
73
76
  "smol-toml": "1.8.0",
77
+ "typescript": "5.9.3",
74
78
  "zod": "3.25.76",
75
79
  "zod-to-json-schema": "3.25.2"
76
80
  }
@@ -54,7 +54,7 @@ flowchart LR
54
54
 
55
55
  | # | Verificacao | Como se comprova |
56
56
  |---|---|---|
57
- | 16 | Existe MASTER log valido contra o contrato congelado `ork.master-log/v1`, com POSTMORTEM tipado, classes de falha do catalogo fixo, score inteiro de 0 a 5 e justificativa nao vazia. Uma entrega sem MASTER log nao aconteceu. | `ork master <thread> --score N --justificativa "<texto>"`. O comando recusa score fora da escala, score sem justificativa e classe fora do catalogo, e nao grava nada quando recusa. |
57
+ | 16 | Existe MASTER log valido contra o contrato congelado `ork.master-log/v1`, com POSTMORTEM tipado, classes de falha do catalogo fixo, score inteiro de 0 a 5 e justificativa nao vazia. Uma entrega sem MASTER log nao aconteceu. | `ork master <thread> --score N --justificativa "<texto>" --por <quem>`. O comando recusa score fora da escala, score sem justificativa, score sem autoria humana em `--por` e classe fora do catalogo, e nao grava nada quando recusa. |
58
58
 
59
59
  ## Toda thread, no seu inicio
60
60
 
package/skills/README.md CHANGED
@@ -18,7 +18,7 @@ faz, o nucleo vence, e a divergencia e defeito da skill.
18
18
  | phases | [go-implementation](phases/go-implementation/SKILL.md) | `ork worktree ensure`, `ork verify --baseline` |
19
19
  | phases | [check-quality](phases/check-quality/SKILL.md) | `ork verify`, `ork gate request` |
20
20
  | phases | [ship-release](phases/ship-release/SKILL.md) | `ork ship` |
21
- | phases | [master-metrics](phases/master-metrics/SKILL.md) | `ork master`, `ork master --aceitar-omissao` |
21
+ | phases | [master-metrics](phases/master-metrics/SKILL.md) | `ork master`, `ork master <thread> --aceitar-omissao` |
22
22
  | reviewers | [code-reviewer](reviewers/code-reviewer/SKILL.md) | `references/code-review-axes.md` |
23
23
  | reviewers | [security-auditor](reviewers/security-auditor/SKILL.md) | `references/security-checklist.md` |
24
24
  | reviewers | [test-engineer](reviewers/test-engineer/SKILL.md) | `references/testing-patterns.md` |
@@ -56,6 +56,7 @@ Prefira MCP no projeto fixado pelo servidor, sem outro root/cwd. No Claude com s
56
56
  | Demanda nova | `ork_thread_new(nome, modo)` | `ork thread new "<nome>" --mode <modo> --worktree auto` |
57
57
  | Despacho | `ork_phase_run(threadId, fase, prompt, runtime?, model?, effort?, dryRun?)` | `ork phase run <thread> GOAL --prompt "<pedido>"` |
58
58
  | Progresso nativo | `ork_observe(threadId)` | `ork thread status <thread>` |
59
+ | Contexto do grafo (somente com `grafo.mcp: true`) | `ork_grafo_contexto(threadId, tetoBytes?)`; aprofundar com `ork_grafo_vizinhos`, `ork_grafo_chamadores`, `ork_grafo_importadores`, `ork_grafo_caminho` | `ork grafo contexto <thread> --json` |
59
60
  | Pendencia/decisao | `ork_hitl_pending`, `ork_request_decision(threadId, pedidoId)` | Consulte o ingresso suportado; nao fabrique resposta. |
60
61
 
61
62
  Prefira `ork_git_commit` (HEAD atual, paths com claims), `ork_verify` e `ork_ship` (HEADs fonte/destino reais) para registrar, verificar e entregar. Autoria/commit nao e SHIP; retorno incomplete exige reconciliacao antes de repetir. Para demandas novas, use `ork modos --do-pedido "<pedido do dono>"` e `ork_preflight({modo})` (CLI: `ork doctor --modo <modo>`). A sonda por bloco não comprova autenticação, gates ou entrega.
@@ -71,8 +72,7 @@ Dry-run nao inicia modelo, mas pode gravar prompt/eventos. Confira o trio efetiv
71
72
 
72
73
  ## Conducao durante o trabalho
73
74
 
74
- O modo afrouxa a pausa, NUNCA a verificacao. Claims, verify, policies e gates tipados
75
- rodam identicos em `#Classic` e em `#Auto`; o modo decide se o veredito espera o humano.
75
+ O modo afrouxa a pausa, NUNCA a verificacao. Claims, verify, policies e gates tipados rodam identicos em `#Classic` e em `#Auto`; o modo decide se o veredito espera o humano.
76
76
 
77
77
  Depois de uma acao, use o resultado do nucleo para executar o proximo passo autorizado.
78
78
  Em #Auto/#Maestro, nao termine um bloco apenas oferecendo continuar quando ainda ha trabalho
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: master-metrics
3
- description: "Fase MASTER (F6): POSTMORTEM tipado, MASTER log no contrato congelado ork.master-log/v1 e o score humano de 0 a 5 com justificativa. Roteia para ork master e ork master --aceitar-omissao."
3
+ description: "Fase MASTER (F6): POSTMORTEM tipado, MASTER log no contrato congelado ork.master-log/v1 e o score humano de 0 a 5 com justificativa. Roteia para ork master e ork master <thread> --aceitar-omissao."
4
4
  bucket: phases
5
- roteia: "ork master <thread> --score N --justificativa \"...\" | ork master --aceitar-omissao"
5
+ roteia: "ork master <thread> --score N --justificativa \"...\" | ork master <thread> --aceitar-omissao"
6
6
  license: MIT
7
7
  ---
8
8
 
@@ -21,9 +21,14 @@ ork master classes # as classes de falha do catalogo
21
21
  ork master <thread> --score 4 --justificativa "<texto>" --classe base-avancou --por <quem>
22
22
  ork master # as entregas, com o indice derivado do ledger
23
23
  ork master --todas # inclusive as ja pontuadas
24
- ork master --aceitar-omissao # aceita as entregues, com indice e insumos no ledger
24
+ ork master <thread> --aceitar-omissao # aceita so a entrega desta thread, com indice e insumos no ledger
25
+ ork master --aceitar-omissao --dry-run # lista o que a forma sem thread fecharia, sem gravar
25
26
  ```
26
27
 
28
+ Agente fecha so a propria thread: `ork master <thread> --aceitar-omissao`. Sem a thread, o comando
29
+ aceita TODAS as entregues do projeto, inclusive as de outras frentes paralelas (o que aconteceu tres
30
+ vezes em 03/10/2026); de processo de agente com mais de uma, o `ork` avisa em stderr.
31
+
27
32
  ## O que o MASTER entrega
28
33
 
29
34
  1. **POSTMORTEM tipado**, com as fases percorridas, o que falhou e a classe de falha vinda de um