@orkastery/cli 0.3.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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/adapters/claude-code/commands/check.md +4 -3
  3. package/adapters/claude-code/commands/goal.md +3 -2
  4. package/adapters/claude-code/commands/master.md +3 -2
  5. package/adapters/claude-code/commands/ork.md +1 -1
  6. package/adapters/claude-code/hooks/ork-guard.js +1 -1
  7. package/adapters/hermes/README.md +6 -8
  8. package/adapters/hermes/hermes.plugin.json +0 -2
  9. package/adapters/openclaw/README.md +3 -3
  10. package/adapters/openclaw/dist/index.js +4 -4
  11. package/adapters/openclaw/openclaw.plugin.json +1 -1
  12. package/adapters/openclaw/package.json +1 -1
  13. package/adapters/openclaw/src/index.ts +6 -4
  14. package/dist/auditoria.js +1 -1
  15. package/dist/board.js +1 -1
  16. package/dist/ci.js +8 -1
  17. package/dist/doctor.js +1 -1
  18. package/dist/fix.js +1 -1
  19. package/dist/gates.js +5 -3
  20. package/dist/index.js +5 -1
  21. package/dist/ledger.js +2 -0
  22. package/dist/licoes.js +10 -4
  23. package/dist/ocupacao.js +1 -1
  24. package/dist/phase.js +16 -1
  25. package/dist/policies.js +72 -0
  26. package/dist/retry.js +5 -5
  27. package/dist/session-watcher.js +22 -5
  28. package/dist/ship.js +18 -4
  29. package/dist/yaml.js +3 -1
  30. package/eval/casos/master-metrics.json +1 -1
  31. package/eval/casos/orkastery-bootstrap.json +2 -2
  32. package/eval/casos/ship-release.json +1 -1
  33. package/package.json +5 -5
  34. package/references/definition-of-done.md +2 -2
  35. package/skills/README.md +3 -3
  36. package/skills/core/orkastery-bootstrap/SKILL.md +1 -1
  37. package/skills/governance/decision-triage/SKILL.md +4 -4
  38. package/skills/governance/narrative-guardian/SKILL.md +1 -1
  39. package/skills/governance/roadmap-keeper/SKILL.md +1 -1
  40. package/skills/observability/thread-tracing/SKILL.md +1 -1
  41. package/skills/phases/check-quality/SKILL.md +2 -2
  42. package/skills/phases/goal-definition/SKILL.md +1 -1
  43. package/skills/phases/master-metrics/SKILL.md +9 -7
  44. package/skills/phases/plan-specification/SKILL.md +1 -1
  45. package/skills/phases/ship-release/SKILL.md +1 -1
  46. package/adapters/hermes/bin/ork-objective-message.sh +0 -17
  47. package/adapters/hermes/bin/ork-objective-status.sh +0 -12
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @orkastery/cli, the `ork` core
2
2
 
3
- **Your agents say "done". `ork` re-runs it.**
3
+ **A software factory of AI agents that proves its work: parallel threads, verified results, and short decisions only when they matter.**
4
4
 
5
5
  `ork` conducts coding agents (Claude Code, Codex) through six-phase threads, verifies every
6
6
  claim by re-running the command that proves it, and only delivers with the push proven on the
@@ -27,11 +27,12 @@ ork worktree audit <thread>
27
27
  ork phase list <thread>
28
28
  ```
29
29
 
30
- 4. Consolida UM veredito (PASSOU, PRECISA DE MUDANCA, BLOQUEADO) e, se o modo pausa, apresenta ao
31
- builder e espera:
30
+ 4. Consolida UM veredito (PASSOU, PRECISA DE MUDANCA, BLOQUEADO) e, se o modo pausa, abre o pedido
31
+ e espera. O builder responde pelo canal autenticado (dialogo nativo do host, ou
32
+ `/ork gate <thread> <pedido> <resposta>` no Telegram); o agente nunca responde por ele:
32
33
 
33
34
  ```bash
34
- ork gate approve <thread> evidencias --por "<quem>"
35
+ ork gate request <thread>
35
36
  ```
36
37
 
37
38
  ## Regras do adaptador
@@ -37,10 +37,11 @@ ork claims add <thread> <arquivo> --claim "<alegacao>" --verificar "<comando>" -
37
37
  ork verify <thread> --so-claims
38
38
  ```
39
39
 
40
- 5. Se o modo pausa neste bloco, apresenta a evidencia ao builder e para. A liberacao e registrada:
40
+ 5. Se o modo pausa neste bloco, apresenta a evidencia ao builder e para. O pedido sai do nucleo, e a
41
+ liberacao so e registrada quando o builder responde pelo canal autenticado:
41
42
 
42
43
  ```bash
43
- ork gate approve <thread> objetivo --por "<quem>"
44
+ ork gate request <thread>
44
45
  ```
45
46
 
46
47
  ## Regras do adaptador
@@ -25,10 +25,11 @@ ork master classes
25
25
  ork master <thread> --score <0-5> --justificativa "<texto>" --classe <classe> --por "<quem>"
26
26
  ```
27
27
 
28
- 4. Nos modos sem pausa de MASTER, mostra a fila que ainda espera humano:
28
+ 4. Nos modos sem pausa de MASTER, a entrega e aceita a menos que o builder diga o contrario. Mostra
29
+ as entregas com o indice derivado do ledger, inclusive as ja pontuadas:
29
30
 
30
31
  ```bash
31
- ork master --batch
32
+ ork master --todas
32
33
  ```
33
34
 
34
35
  ## Regras do adaptador
@@ -73,7 +73,7 @@ ork pulse --json
73
73
  ork board plan
74
74
  ork doctor
75
75
  ork modos
76
- ork master --batch
76
+ ork master
77
77
  ```
78
78
 
79
79
  Use apenas as consultas necessarias. Nao rode todas a cada mensagem. O preflight pertence ao
@@ -52,7 +52,7 @@ const BLOQUEIOS = [
52
52
  nome: 'reset-destrutivo',
53
53
  regex: /\bgit\s+(?:reset\s+--hard|clean\s+-[a-zA-Z]*[fd]|checkout\s+--\s+\.)/,
54
54
  motivo: 'descarte em massa apaga trabalho nao commitado sem deixar rastro',
55
- caminho: 'descarte por arquivo, ou registre a decisao antes: ork gate approve <thread> <sobre> --por <quem>',
55
+ caminho: 'descarte por arquivo; se o descarte amplo for mesmo necessario, peca a decisao ao dono: ork gate request <thread>',
56
56
  },
57
57
  {
58
58
  nome: 'remocao-recursiva-ampla',
@@ -44,16 +44,14 @@ ork adapter install hermes --dry-run # lista o que seria escrito
44
44
  | `hermes.plugin.json` | Declara a skill, o binario do `ork` e as tags de conducao |
45
45
  | `bin/ork-abrir-thread.sh` | Abre a thread com o modo lido do pedido, em um comando |
46
46
  | `bin/ork-brain.sh` | Consulta o Company Brain pelo contrato e identidade autenticada do OrkMind |
47
- | `bin/ork-objective-status.sh` | Lê o ticket canônico compartilhado com o Kanban |
48
- | `bin/ork-objective-message.sh` | Grava a mensagem do canal no histórico do ticket |
49
47
 
50
- ## Continuidade com o Kanban
48
+ ## Tickets `obj-*` aposentados
51
49
 
52
- Quando uma conversa mencionar um `obj-*`, use `ork_objective_status` para retomar o estado
53
- canônico e `ork_objective_message` para preservar a mensagem do Telegram. O Kanban relê o
54
- mesmo `messages.jsonl`, então o dono pode trocar de canal sem duplicar a demanda. O identificador
55
- do autor deve vir do gateway autenticado. Mensagens de conversa não aprovam gates: decisões
56
- continuam passando pelos comandos HITL correlacionados.
50
+ `ork_objective_status` e `ork_objective_message` sairam com o `ork objective` na I-43: o nucleo
51
+ recusa qualquer subcomando com `objective.aposentado` e saida != 0. O estado de uma entrega vem de
52
+ `ork thread status <thread>`; os ciclos ligados a um produto, projeto ou iniciativa, de
53
+ `ork portfolio inspect <id> --json`. Mensagem de conversa continua sem aprovar gate: a decisao do
54
+ dono passa pelo `/ork gate <thread> <pedido> <resposta>` correlacionado.
57
55
 
58
56
  ## O encolhimento, que e o ponto
59
57
 
@@ -12,8 +12,6 @@
12
12
  "ork_maestro": "./bin/ork-maestro.sh",
13
13
  "ork-abrir-thread": "./bin/ork-abrir-thread.sh",
14
14
  "ork_brain": "./bin/ork-brain.sh",
15
- "ork_objective_status": "./bin/ork-objective-status.sh",
16
- "ork_objective_message": "./bin/ork-objective-message.sh",
17
15
  "ork_gate_answer": "./bin/ork-hitl-answer.py",
18
16
  "ork_session_answer": "./bin/ork-hitl-answer.py"
19
17
  },
@@ -57,14 +57,14 @@ fallback: usa `ORK_BIN` do ambiente ou o `ork` do PATH.
57
57
  | `ork_claims_add` | Registra alegacao verificavel com o comando que a comprova |
58
58
  | `ork_verify` / `ork_verify_baseline` | Reexecuta no HEAD real; grava a baseline antes do GO |
59
59
  | `ork_worktree_ensure` / `ork_worktree_audit` | Worktree isolada, conferida no proprio git |
60
- | `ork_objective_status` | Retoma o ticket canônico compartilhado com o Kanban |
61
- | `ork_objective_message` | Preserva no ticket uma mensagem do canal autenticado |
60
+ | `ork_objective_status` / `ork_objective_message` | Aposentadas com o `ork objective` na I-43: devolvem a recusa tipada `objective.aposentado` |
62
61
  | `ork_portfolio_list` | Lista produtos, projetos e iniciativas canônicos |
63
62
  | `ork_gate_answer` | Resposta humana correlacionada a um gate |
64
63
  | `ork_session_answer` | Resposta humana correlacionada a uma sessão |
65
64
  | `ork_ship` | Merge serializado por lease e push provado contra o remoto |
66
65
  | `ork_master` | POSTMORTEM tipado e o score HUMANO de 0 a 5 |
67
- | `ork_board` / `ork_master_batch` | Escalonador e fila de score |
66
+ | `ork_board` | Escalonador: quem avanca agora e quem espera |
67
+ | `ork_master_batch` | Todas as entregas, com o indice do ledger (`ork master --todas`; a fila de score saiu na I-43) |
68
68
 
69
69
  ## A #TAG de conducao
70
70
 
@@ -256,13 +256,13 @@ const FERRAMENTAS = [
256
256
  },
257
257
  {
258
258
  name: 'ork_objective_status',
259
- description: 'Retoma no canal o mesmo ticket canônico e histórico vistos no Kanban.',
259
+ description: 'Aposentado na I-43 junto com ork objective: devolve a recusa tipada objective.aposentado, com saida != 0. Estado de uma entrega: ork_thread_status. Ciclos ligados a um produto, projeto ou iniciativa: ork portfolio inspect <id> --json.',
260
260
  parameters: schema({ objective: { type: 'string', description: 'ID obj-* do ticket' } }),
261
261
  argv: (p) => ['objective', 'status', texto(p, 'objective'), '--json'],
262
262
  },
263
263
  {
264
264
  name: 'ork_objective_message',
265
- description: 'Preserva no ticket uma mensagem recebida pelo canal autenticado. Não aprova gates.',
265
+ description: 'Aposentado na I-43 junto com ork objective: devolve a recusa tipada objective.aposentado, com saida != 0, e nao grava nada. Resposta do dono a uma pausa vai por ork_gate_answer ou ork_session_answer.',
266
266
  parameters: schema({
267
267
  objective: { type: 'string', description: 'ID obj-* do ticket' },
268
268
  author: { type: 'string', description: 'Identidade fornecida pelo gateway autenticado' },
@@ -403,9 +403,9 @@ const FERRAMENTAS = [
403
403
  },
404
404
  {
405
405
  name: 'ork_master_batch',
406
- description: 'A fila de score dos modos sem pausa de MASTER. Fila que ninguem passa e score que nao existe.',
406
+ description: 'Todas as entregas em JSON, com o indice derivado do ledger, as ja pontuadas e as aceitas por omissao. Roda ork master --todas; o nome e da antiga fila de score (ork master --batch), aposentada na I-43.',
407
407
  parameters: schema({}),
408
- argv: () => ['master', '--batch'],
408
+ argv: () => ['master', '--todas', '--json'],
409
409
  },
410
410
  ];
411
411
  const plugin = defineToolPlugin({
@@ -2,7 +2,7 @@
2
2
  "id": "orkastery",
3
3
  "name": "Orkastery",
4
4
  "description": "Conducao de looping threads em 6 fases pelo nucleo `ork`, exposta ao OpenClaw como tools `ork_*`. Zero regra de negocio no host: cada tool e uma chamada de CLI.",
5
- "version": "0.3.0",
5
+ "version": "0.4.1",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "properties": {},
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orkastery/openclaw-plugin",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Plugin Orkastery para OpenClaw: 25 tools ork_* que traduzem intencao em chamada de CLI do nucleo `ork`. Zero regra de negocio no host.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -267,13 +267,15 @@ const FERRAMENTAS: FerramentaOrk[] = [
267
267
  },
268
268
  {
269
269
  name: 'ork_objective_status',
270
- description: 'Retoma no canal o mesmo ticket canônico e histórico vistos no Kanban.',
270
+ description:
271
+ 'Aposentado na I-43 junto com ork objective: devolve a recusa tipada objective.aposentado, com saida != 0. Estado de uma entrega: ork_thread_status. Ciclos ligados a um produto, projeto ou iniciativa: ork portfolio inspect <id> --json.',
271
272
  parameters: schema({ objective: { type: 'string', description: 'ID obj-* do ticket' } }),
272
273
  argv: (p) => ['objective', 'status', texto(p, 'objective'), '--json'],
273
274
  },
274
275
  {
275
276
  name: 'ork_objective_message',
276
- description: 'Preserva no ticket uma mensagem recebida pelo canal autenticado. Não aprova gates.',
277
+ description:
278
+ 'Aposentado na I-43 junto com ork objective: devolve a recusa tipada objective.aposentado, com saida != 0, e nao grava nada. Resposta do dono a uma pausa vai por ork_gate_answer ou ork_session_answer.',
277
279
  parameters: schema({
278
280
  objective: { type: 'string', description: 'ID obj-* do ticket' },
279
281
  author: { type: 'string', description: 'Identidade fornecida pelo gateway autenticado' },
@@ -422,9 +424,9 @@ const FERRAMENTAS: FerramentaOrk[] = [
422
424
  {
423
425
  name: 'ork_master_batch',
424
426
  description:
425
- 'A fila de score dos modos sem pausa de MASTER. Fila que ninguem passa e score que nao existe.',
427
+ 'Todas as entregas em JSON, com o indice derivado do ledger, as ja pontuadas e as aceitas por omissao. Roda ork master --todas; o nome e da antiga fila de score (ork master --batch), aposentada na I-43.',
426
428
  parameters: schema({}),
427
- argv: () => ['master', '--batch'],
429
+ argv: () => ['master', '--todas', '--json'],
428
430
  },
429
431
  ];
430
432
 
package/dist/auditoria.js CHANGED
@@ -425,7 +425,7 @@ exports.PACKS = {
425
425
  },
426
426
  {
427
427
  id: 'PR2',
428
- regra: 'Thread entregue sem score humano registrado, parada na fila de batch.',
428
+ regra: 'Thread entregue sem score humano registrado.',
429
429
  evidencia: 'thread entregue sem master_done.por humano correspondente ao score',
430
430
  },
431
431
  {
package/dist/board.js CHANGED
@@ -212,7 +212,7 @@ function planejar(carregado, opcoes = {}) {
212
212
  situacao: 'pausada',
213
213
  motivo: 'human.pending',
214
214
  detalhe: oc.detalhe,
215
- correcao: `ork gate approve ${t.id} <sobre> --por <quem>`,
215
+ correcao: `ork gate request ${t.id}`,
216
216
  leases: meus,
217
217
  });
218
218
  continue;
package/dist/ci.js CHANGED
@@ -209,8 +209,15 @@ function executarBundleCi(carregado, file = '.ork-ci/bundle.json') {
209
209
  const bundle = JSON.parse(fs.readFileSync(absolute, 'utf8'));
210
210
  if (bundle.schema !== 'ork.ci-bundle/v1' || !/^ork-[a-z0-9-]+$/.test(bundle.thread) || !Array.isArray(bundle.claims) || !Array.isArray(bundle.commands))
211
211
  throw new Error('bundle de CI inválido');
212
+ // O CI roda o mesmo preparo do `ork verify` local (I-54), uma vez e antes das claims: a claim
213
+ // que passa na maquina de quem entrega passa aqui pelo mesmo caminho. Como no verify, o
214
+ // preparo nao e condicao de claim; ele so deixa a compilacao pronta e sai no resultado.
215
+ const comandoDoPreparo = carregado.manifesto.verify.preparo;
216
+ const preparo = comandoDoPreparo
217
+ ? (0, verify_2.executar)('preparo', comandoDoPreparo, carregado.raiz, (0, verify_2.prazoDoComando)(carregado.manifesto, 'preparo'))
218
+ : null;
212
219
  const claims = bundle.claims.map((claim) => (0, verify_2.verificarClaim)(claim, carregado.raiz));
213
220
  const commands = bundle.commands.map((item) => (0, verify_2.executar)(item.name, item.command, carregado.raiz));
214
221
  const ok = claims.every((item) => item.verificado || item.motivo === 'claims.unverifiable') && commands.every((item) => item.ok);
215
- return { schema: 'ork.ci-run/v1', ok, thread: bundle.thread, commit: (0, verify_2.commitReal)(carregado.raiz), claims, commands };
222
+ return { schema: 'ork.ci-run/v1', ok, thread: bundle.thread, commit: (0, verify_2.commitReal)(carregado.raiz), preparo, claims, commands };
216
223
  }
package/dist/doctor.js CHANGED
@@ -329,7 +329,7 @@ function checar(dirInicial = process.cwd(), nomesHerdados = (0, runtime_ambiente
329
329
  : `${esperando.length} aguardando janela, ${escalados.length} escalado(s) para humano` +
330
330
  (esperando.length > 0 ? `; proxima janela em ${(0, horario_1.formatarDataHoraRotulada)(esperando[0].liberaEm)}` : ''),
331
331
  correcao: escalados.length > 0
332
- ? `pedido escalado alem do limite de retry.max_tentativas: ork retry list e ork gate approve`
332
+ ? `pedido escalado alem do limite de retry.max_tentativas: ork retry list e ork gate request <thread>`
333
333
  : esperando.length > 0
334
334
  ? 'ork retry resume retoma o que ja liberou'
335
335
  : undefined,
package/dist/fix.js CHANGED
@@ -381,7 +381,7 @@ function reverificarSobConducao(carregado, threadId, opcoes) {
381
381
  modo: thread.modo,
382
382
  detalhe: razao,
383
383
  evidencia: `rodada ${rodada} de GO-FIX/CHECK-REVERIFY na thread ${threadId}`,
384
- correcao: `ork gate approve ${threadId} evidencias --por <quem>`,
384
+ correcao: `ork gate request ${threadId}`,
385
385
  rodada,
386
386
  limite,
387
387
  pausaQualquerModo: true,
package/dist/gates.js CHANGED
@@ -86,10 +86,12 @@ function descreverMotivo(motivo, detalhe) {
86
86
  return `motivo tipado: ${motivo} (${exports.DESCRICAO_DO_MOTIVO[motivo]})\n detalhe: ${detalhe}`;
87
87
  }
88
88
  /**
89
- * `ork gate approve`: o humano autoriza uma pausa do modo pela linha de comando.
89
+ * `ork gate approve`, APOSENTADO: aprovacao sem pedido e recusada. A pausa se libera pela
90
+ * resposta ao `ork gate request`, que chega pelo ingresso humano autenticado.
90
91
  *
91
- * E o que torna a "autorizacao antecipada de push" do `#Classic` verificavel: ela vira um
92
- * evento no ledger com quem autorizou e quando, em vez de memoria de conversa.
92
+ * Antes da aposentadoria, era o que tornava verificavel a "autorizacao antecipada de push"
93
+ * do `#Classic`: ela virava um evento no ledger com quem autorizou e quando, em vez de
94
+ * memoria de conversa.
93
95
  */
94
96
  function aprovarGateHumano(_raiz, _threadId, _sobre, _por, _observacao) {
95
97
  throw new Error('aprovação cega aposentada: use ork gate request e responda ao pedido pelo ingresso humano autenticado');
package/dist/index.js CHANGED
@@ -1022,6 +1022,8 @@ function comandoPhase(args) {
1022
1022
  console.log(` modelo/esforco : ${r.model}/${r.effort}`);
1023
1023
  // O prompt inteiro nao cabe na tela: o argumento longo aparece mascarado.
1024
1024
  console.log(` comando : ${r.comando.map((c) => (c.length > 80 ? '"<prompt>"' : c)).join(' ')}`);
1025
+ for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
1026
+ console.log(l);
1025
1027
  return 0;
1026
1028
  }
1027
1029
  if (r.bloqueado) {
@@ -1040,6 +1042,8 @@ function comandoPhase(args) {
1040
1042
  return 1;
1041
1043
  }
1042
1044
  console.log(`Fase ${fase} despachada como background agent.`);
1045
+ for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
1046
+ console.log(l);
1043
1047
  console.log(` sessionId : ${r.sessionId}`);
1044
1048
  console.log(` slug da sessao : ${r.slug} (${(0, phase_1.descreverSlug)(r.slug)})`);
1045
1049
  console.log(` prompt : ${r.promptPath}`);
@@ -1512,7 +1516,7 @@ function comandoGate(args) {
1512
1516
  const sobre = args.posicionais[3];
1513
1517
  const por = texto(args.opcoes.por) ?? texto(args.opcoes.quem);
1514
1518
  if (!id || !sobre || !por) {
1515
- console.error('uso: ork gate approve <thread-id> <sobre> --por <quem>');
1519
+ console.error('gate approve aposentado: aprovação sem pedido é recusada. Use ork gate request <thread-id> e responda pelo ingresso humano autenticado.');
1516
1520
  return 2;
1517
1521
  }
1518
1522
  (0, thread_1.lerThread)(carregado.raiz, id);
package/dist/ledger.js CHANGED
@@ -147,6 +147,8 @@ exports.TIPOS_DE_EVENTO = {
147
147
  lintDeClaim: 'claim_lint',
148
148
  // I-55 (RM-008): a mesma falha em 3+ threads fechadas virou proposta de policy (so proposta).
149
149
  politicaProposta: 'policy_proposta',
150
+ // RM-008 (fatia 3): policy em warn que disparou num gate. Registra e segue; nunca bloqueia.
151
+ politicaAviso: 'policy_warn',
150
152
  // I-36 (RM-036): conducao multicanal. O segundo pedido recusado, o despacho repetido que nao abriu
151
153
  // sessao nova, a liberacao com prova (fim da sessao ou dono morto), o handoff e a renovacao do prazo.
152
154
  conducaoRecusada: 'conducao_recusada',
package/dist/licoes.js CHANGED
@@ -57,6 +57,7 @@ const fs = __importStar(require("node:fs"));
57
57
  const path = __importStar(require("node:path"));
58
58
  const estado_thread_1 = require("./estado-thread");
59
59
  const ledger_1 = require("./ledger");
60
+ const policies_1 = require("./policies");
60
61
  /** O que evita cada bloqueio, na forma de comando. Sem dica, a licao so conta a recorrencia. */
61
62
  const DICA_DO_MOTIVO = {
62
63
  'claims.failed': 'rode o comando da claim antes de registra-la; claim sem prova local volta como GO-FIX',
@@ -175,10 +176,15 @@ function propostasDePolicy(raiz, agoraIso = new Date().toISOString()) {
175
176
  const limite = Date.parse(agoraIso) - exports.JANELA_DA_PROPOSTA_DIAS * 86_400_000;
176
177
  const recentes = lerLicoes(raiz).filter((l) => Date.parse(l.fechadaEm) >= limite);
177
178
  const { motivos, classes } = recorrencias(recentes);
178
- return [...motivos, ...classes].filter((r) => r.threads.length >= exports.PISO_DA_PROPOSTA).map((r) => ({
179
- chave: r.chave, tipo: r.tipo, nome: r.nome, threads: [...r.threads], janelaDias: exports.JANELA_DA_PROPOSTA_DIAS,
180
- sugestao: `policy \`${r.nome.replace(/[^a-z0-9]+/gi, '_')}\` em warn: ` + (r.dica ?? 'revisar a causa comum antes da proxima thread'),
181
- }));
179
+ return [...motivos, ...classes].filter((r) => r.threads.length >= exports.PISO_DA_PROPOSTA).map((r) => {
180
+ const policy = r.nome.replace(/[^a-z0-9]+/gi, '_');
181
+ const dica = r.dica ?? 'revisar a causa comum antes da proxima thread';
182
+ // RM-008 (fatia 3): com avaliador no nucleo, a proposta ja diz como vira policy de verdade.
183
+ const sugestao = policy in policies_1.POLICIES_CONHECIDAS
184
+ ? `policy \`${policy}\` executavel: declare \`${policy}: warn\` em policies: do orkastery.yaml; o que evita: ${dica}`
185
+ : `policy \`${policy}\` em warn: ${dica}`;
186
+ return { chave: r.chave, tipo: r.tipo, nome: r.nome, threads: [...r.threads], janelaDias: exports.JANELA_DA_PROPOSTA_DIAS, sugestao };
187
+ });
182
188
  }
183
189
  /**
184
190
  * Grava no ledger do projeto a proposta que ainda nao foi registrada nesta janela. Idempotente:
package/dist/ocupacao.js CHANGED
@@ -45,7 +45,7 @@ exports.EVENTOS_QUE_DESTRAVAM = [
45
45
  ledger_1.TIPOS_DE_EVENTO.shipConcluido,
46
46
  ledger_1.TIPOS_DE_EVENTO.masterConcluido,
47
47
  ];
48
- /** O evento e uma autorizacao humana ja registrada (`ork gate approve`)? */
48
+ /** O evento e uma autorizacao humana ja registrada (resposta ao `ork gate request`)? */
49
49
  function ehAprovacaoHumana(e) {
50
50
  return e.tipo === ledger_1.TIPOS_DE_EVENTO.pausaHumana && e.estado === 'aprovado';
51
51
  }
package/dist/phase.js CHANGED
@@ -560,8 +560,23 @@ function rodarFaseSobLock(carregado, threadId, opcoes) {
560
560
  // Gate tipado do bloco B1: as policies do manifesto valem ANTES do despacho, em
561
561
  // qualquer modo. Prompt reprovado nem chega a ser gravado em disco: gravar um prompt
562
562
  // com credencial e criar um segundo vazamento no proprio repositorio.
563
- const violacoes = (0, policies_1.avaliarPolicies)(manifesto, { gate: 'phase.dispatch', prompt });
563
+ // RM-008 (fatia 3): as licoes que viraram policy recebem os fatos da thread, calculados aqui.
564
+ const blocoDespachado = (0, thread_1.blocoDaThread)(thread, fase);
565
+ const violacoes = (0, policies_1.avaliarPolicies)(manifesto, {
566
+ gate: 'phase.dispatch', prompt, threadId: thread.id, modo: thread.modo, fase,
567
+ bloco: thread.blocos.indexOf(blocoDespachado) + 1,
568
+ blocoComGo: blocoDespachado.fases.includes('GO'),
569
+ temBaseline: (0, ledger_1.lerLedger)(dir).some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.baselineGravada),
570
+ fallbackDoBloco: (0, setup_1.fallbackDoBloco)(setup, thread.modo, fase),
571
+ });
564
572
  const bloqueiam = (0, policies_1.bloqueantes)(violacoes);
573
+ // Warn registra e segue: o aviso vai ao ledger (fora do ensaio) e o despacho continua.
574
+ if (!opcoes.dryRun) {
575
+ for (const v of (0, policies_1.avisos)(violacoes)) {
576
+ (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.politicaAviso, { gate: 'phase.dispatch', fase, slug,
577
+ policy: v.policy, detalhe: v.detalhe, correcao: v.correcao, modo: thread.modo });
578
+ }
579
+ }
565
580
  if (bloqueiam.length > 0) {
566
581
  const detalhe = bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; ');
567
582
  // Bloco B3: violacao de CUSTO sai tipada como tal. E o que permite a politica de
package/dist/policies.js CHANGED
@@ -15,8 +15,10 @@ exports.POLICIES_CONHECIDAS = void 0;
15
15
  exports.procurarSegredos = procurarSegredos;
16
16
  exports.policiesDesconhecidas = policiesDesconhecidas;
17
17
  exports.avaliarPolicies = avaliarPolicies;
18
+ exports.avisos = avisos;
18
19
  exports.bloqueantes = bloqueantes;
19
20
  exports.motivoDominante = motivoDominante;
21
+ exports.linhasDeAviso = linhasDeAviso;
20
22
  exports.textoDeViolacoes = textoDeViolacoes;
21
23
  /**
22
24
  * Variaveis que REDIRECIONAM o despacho do `claude` para um provider pago.
@@ -73,6 +75,24 @@ exports.POLICIES_CONHECIDAS = {
73
75
  quando: ['ship'],
74
76
  descricao: 'proibe entregar sem branch de thread (push direto na base)',
75
77
  },
78
+ // RM-008 (fatia 3): licoes do loop de aprendizado que o `ork` sabe conferir sem ambiguidade.
79
+ // O nome e o mesmo que o `ork licoes` propoe, para a proposta ser declarada como veio.
80
+ verify_regression: {
81
+ quando: ['phase.dispatch'],
82
+ descricao: 'avisa quando o bloco que contem GO sai sem baseline gravada',
83
+ },
84
+ verify_failed: {
85
+ quando: ['phase.dispatch'],
86
+ descricao: 'avisa quando o bloco que contem GO sai sem baseline gravada (mesma conferencia de verify_regression)',
87
+ },
88
+ runtime_unavailable: {
89
+ quando: ['phase.dispatch'],
90
+ descricao: 'avisa quando o bloco despachado nao declara runtime de fallback',
91
+ },
92
+ tree_blocked: {
93
+ quando: ['ship'],
94
+ descricao: 'avisa quando a branch da thread esta atras da base',
95
+ },
76
96
  };
77
97
  function severidade(bruta) {
78
98
  if (bruta === 'block' || bruta === 'warn' || bruta === 'off')
@@ -87,6 +107,8 @@ function policiesDesconhecidas(manifesto) {
87
107
  function avaliarPolicies(manifesto, ctx) {
88
108
  const declaradas = manifesto.policies ?? {};
89
109
  const violacoes = [];
110
+ // verify_regression e verify_failed conferem a mesma coisa: um aviso so, com o nome da primeira declarada.
111
+ let baselineJaAvaliada = false;
90
112
  for (const [nome, bruta] of Object.entries(declaradas)) {
91
113
  const conhecida = exports.POLICIES_CONHECIDAS[nome];
92
114
  if (!conhecida || !conhecida.quando.includes(ctx.gate))
@@ -148,9 +170,52 @@ function avaliarPolicies(manifesto, ctx) {
148
170
  }
149
171
  continue;
150
172
  }
173
+ if (nome === 'verify_regression' || nome === 'verify_failed') {
174
+ if (baselineJaAvaliada)
175
+ continue;
176
+ baselineJaAvaliada = true;
177
+ if (ctx.blocoComGo === true && ctx.temBaseline === false) {
178
+ violacoes.push({
179
+ policy: nome,
180
+ severidade: sev,
181
+ motivo: 'policy.violation',
182
+ detalhe: 'o bloco que contem GO vai sair sem baseline: uma falha que ja existia passaria por regressao desta thread',
183
+ correcao: `ork verify ${ctx.threadId ?? '<thread>'} --baseline`,
184
+ });
185
+ }
186
+ continue;
187
+ }
188
+ if (nome === 'runtime_unavailable') {
189
+ if (Array.isArray(ctx.fallbackDoBloco) && ctx.fallbackDoBloco.length === 0) {
190
+ violacoes.push({
191
+ policy: nome,
192
+ severidade: sev,
193
+ motivo: 'policy.violation',
194
+ detalhe: 'o bloco nao declara runtime de fallback: se o runtime cair, a fase para ate alguem trocar a mao',
195
+ correcao: `ork setup ${ctx.modo ?? '<modo>'} --bloco ${ctx.bloco ?? 'N'} --fallback <runtime:modelo>`,
196
+ });
197
+ }
198
+ continue;
199
+ }
200
+ if (nome === 'tree_blocked') {
201
+ if (ctx.branchAtrasDaBase === true) {
202
+ violacoes.push({
203
+ policy: nome,
204
+ severidade: sev,
205
+ motivo: 'policy.violation',
206
+ detalhe: `a branch "${ctx.de ?? 'da thread'}" esta atras de "${ctx.para ?? ctx.baseBranch ?? 'base'}": a entrega mistura a mudanca com o que a base ja andou`,
207
+ correcao: `ork worktree sync ${ctx.threadId ?? '<thread>'}`,
208
+ });
209
+ }
210
+ continue;
211
+ }
151
212
  }
152
213
  return violacoes;
153
214
  }
215
+ /** So as violacoes com severidade `warn` (as que registram e seguem). */
216
+ function avisos(violacoes) {
217
+ return violacoes.filter((v) => v.severidade === 'warn');
218
+ }
154
219
  /** So as violacoes com severidade `block` (as que reprovam em qualquer modo). */
155
220
  function bloqueantes(violacoes) {
156
221
  return violacoes.filter((v) => v.severidade === 'block');
@@ -168,6 +233,13 @@ function motivoDominante(violacoes) {
168
233
  ? 'cost.violation'
169
234
  : 'policy.violation';
170
235
  }
236
+ /** RM-008 (fatia 3): as linhas de aviso (policies em warn) para a saida do CLI. Nada quando nao ha aviso. */
237
+ function linhasDeAviso(violacoes, recuo = ' ') {
238
+ return avisos(violacoes).flatMap((v) => [
239
+ `${recuo}aviso da policy ${v.policy}: ${v.detalhe}`,
240
+ `${recuo} correcao: ${v.correcao}`,
241
+ ]);
242
+ }
171
243
  /** Texto das violacoes para a saida do CLI. */
172
244
  function textoDeViolacoes(violacoes) {
173
245
  return violacoes
package/dist/retry.js CHANGED
@@ -73,7 +73,7 @@ const claude_bg_1 = require("./adapters/claude-bg");
73
73
  * violacao de custo e gastar de novo, e a politica `subscription-only` esta no manifesto.
74
74
  * 2. **O modo afrouxa a PAUSA, nunca a VERIFICACAO.** A politica e identica em
75
75
  * `#Classic` e em `#Auto`. O que muda e a AUTORIZACAO: num bloco de loop que pausa,
76
- * a acao espera `ork gate approve`; num bloco sem pausa (`#Maestro`, `#Auto`) o
76
+ * a acao espera a resposta humana ao `ork gate request`; num bloco sem pausa (`#Maestro`, `#Auto`) o
77
77
  * `ork` executa sozinho e grava a decisao autonoma no ledger.
78
78
  * 3. **O limite de escalacao pausa QUALQUER modo.** Estouradas as tentativas do
79
79
  * manifesto pelo MESMO motivo na MESMA fase, a acao vira `escalar-humano`,
@@ -278,7 +278,7 @@ exports.POLITICA_DE_RETRY = {
278
278
  acao: 'escalar-humano',
279
279
  automatica: false,
280
280
  porque: 'nao e reprovacao de verdade, e espera de autorizacao: automatizar a espera seria a maquina se autorizando',
281
- correcao: 'ork gate approve <thread> <sobre> --por <quem>',
281
+ correcao: 'ork gate request <thread>',
282
282
  },
283
283
  };
284
284
  /** A politica de um motivo tipado. */
@@ -756,7 +756,7 @@ function retomarPedido(carregado, pedidoOriginal, opcoes = {}) {
756
756
  motivo: 'human.pending',
757
757
  modo: thread.modo,
758
758
  detalhe: escolha.razao,
759
- correcao: `ork gate approve ${thread.id} retomada --por <quem>`,
759
+ correcao: `ork gate request ${thread.id}`,
760
760
  fase: pedido.fase,
761
761
  slug: pedido.slug,
762
762
  pedido: pedido.id,
@@ -1137,7 +1137,7 @@ function executarRetry(carregado, threadId, opcoes = {}) {
1137
1137
  motivo: plano.acao === 'sem-retry' ? plano.motivo : 'human.pending',
1138
1138
  modo: thread.modo,
1139
1139
  detalhe: plano.razao,
1140
- correcao: plano.politica?.correcao ?? `ork gate approve ${threadId} retry --por <quem>`,
1140
+ correcao: plano.politica?.correcao ?? `ork gate request ${threadId}`,
1141
1141
  fase: plano.fase,
1142
1142
  origem: 'retry.run',
1143
1143
  pausaQualquerModo: true,
@@ -1259,7 +1259,7 @@ function rotacionarConta(carregado, thread, plano, opcoes, vazio, registrarTenta
1259
1259
  const escalar = (razao, diagnostico) => {
1260
1260
  if (!opcoes.dryRun) {
1261
1261
  (0, gates_1.registrarGateBloqueado)(dir, thread.id, { gate: 'phase.dispatch', motivo: 'human.pending', modo: thread.modo, detalhe: diagnostico,
1262
- diagnostico, correcao: `ork gate approve ${thread.id} retomada --por <quem>`, fase, origem: 'retry.rotacao', pausaQualquerModo: true });
1262
+ diagnostico, correcao: `ork gate request ${thread.id}`, fase, origem: 'retry.rotacao', pausaQualquerModo: true });
1263
1263
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.retryEscalado, { fase, motivo, origem: 'retry.rotacao', acao: plano.acao,
1264
1264
  tentativas: plano.tentativas, limite: plano.limite, modo: thread.modo, razao });
1265
1265
  }
@@ -118,6 +118,27 @@ function lerJson(file) {
118
118
  throw new Error('metadado de sensor excessivo');
119
119
  return JSON.parse(fs.readFileSync(file, 'utf8'));
120
120
  }
121
+ /**
122
+ * Sob o mutex de recovery: `true` quando o lock ficou livre (dono morto, lock sem dono vencido, ou
123
+ * dono vivo que soltou o lock no meio da leitura) e `false` quando o dono segue vivo.
124
+ */
125
+ function lockLiberado(lock, owner) {
126
+ try {
127
+ const atual = lerJson(owner);
128
+ if (atual ? (0, codex_runner_1.estadoProcesso)(atual.identidade) !== 'ausente' : Date.now() - fs.statSync(lock).mtimeMs < 60000)
129
+ return false;
130
+ if (atual)
131
+ fs.unlinkSync(owner);
132
+ fs.rmdirSync(lock);
133
+ return true;
134
+ }
135
+ catch (e) {
136
+ // O dono vivo pode soltar o lock entre o EEXIST e esta leitura: sumir aqui quer dizer lock livre, não falha.
137
+ if (e.code === 'ENOENT')
138
+ return true;
139
+ throw e;
140
+ }
141
+ }
121
142
  /** Recovery serializado: quem perde o mutex não remove lock recém-adquirido. */
122
143
  function comLockWatcher(dir, action) {
123
144
  const lock = path.join(dir, 'watch.lock'), recover = path.join(dir, 'recover.lock');
@@ -137,12 +158,8 @@ function comLockWatcher(dir, action) {
137
158
  return null;
138
159
  }
139
160
  try {
140
- const atual = lerJson(owner);
141
- if (atual ? (0, codex_runner_1.estadoProcesso)(atual.identidade) !== 'ausente' : Date.now() - fs.statSync(lock).mtimeMs < 60000)
161
+ if (!lockLiberado(lock, owner))
142
162
  return null;
143
- if (atual)
144
- fs.unlinkSync(owner);
145
- fs.rmdirSync(lock);
146
163
  try {
147
164
  criar();
148
165
  }
package/dist/ship.js CHANGED
@@ -131,8 +131,7 @@ function autorizacaoDePush(raiz, thread, opcoes) {
131
131
  tipo: 'pendente',
132
132
  por: '',
133
133
  razao: `o modo ${tag} pausa no push e ainda nao ha autorizacao humana registrada. ` +
134
- `Autorize com: ork gate approve ${thread.id} push --por <quem> ` +
135
- `ou rode: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
134
+ `Autorize na entrega: ork ship ${thread.id} --para <branch> --autorizar-push <quem>`,
136
135
  };
137
136
  }
138
137
  /** Diretorio temporario onde a arvore de merge e montada quando preciso. */
@@ -365,16 +364,30 @@ function ship(carregado, threadId, opcoes) {
365
364
  const autorizacao = autorizacaoDePush(raiz, thread, opcoes);
366
365
  r.autorizacao = autorizacao;
367
366
  if (!autorizacao.autorizado) {
368
- return bloquear('human.pending', autorizacao.razao, `ork gate approve ${threadId} push --por <quem>`);
367
+ return bloquear('human.pending', autorizacao.razao, `ork ship ${threadId} --para <branch> --autorizar-push <quem>`);
369
368
  }
370
- // 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;
371
376
  const violacoes = (0, policies_1.avaliarPolicies)(manifesto, {
372
377
  gate: 'ship',
373
378
  de,
374
379
  para,
375
380
  baseBranch: manifesto.worktree.base_branch,
381
+ threadId,
382
+ branchAtrasDaBase,
376
383
  });
377
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
+ }
378
391
  const bloqueiam = (0, policies_1.bloqueantes)(violacoes);
379
392
  if (bloqueiam.length > 0) {
380
393
  return bloquear('policy.violation', bloqueiam.map((v) => `${v.policy}: ${v.detalhe}`).join('; '), bloqueiam.map((v) => v.correcao).join('; '));
@@ -641,6 +654,7 @@ function textoDoShip(r) {
641
654
  if (r.ci) {
642
655
  linhas.push(` ci ${r.ci.required ? `${r.ci.state.toUpperCase()} ${r.ci.context} em ${r.ci.sha.slice(0, 8)}` : 'não exigido'}`);
643
656
  }
657
+ linhas.push(...(0, policies_1.linhasDeAviso)(r.violacoes ?? []));
644
658
  if (r.leaseOcupadoPor) {
645
659
  comHorario = true;
646
660
  linhas.push(` lease ${leases_1.LEASE_MAIN_TREE} OCUPADO pela thread ${r.leaseOcupadoPor.thread} (desde ${(0, horario_1.formatarDataHora)(r.leaseOcupadoPor.adquiridoEm)})`);
package/dist/yaml.js CHANGED
@@ -38,7 +38,9 @@ function escalar(bruto) {
38
38
  return true;
39
39
  if (t === 'false' || t === 'no')
40
40
  return false;
41
- if (/^-?\d+$/.test(t))
41
+ // Inteiro so vira numero quando volta igual ao texto. Zero a esquerda (um SHA curto como
42
+ // `0123456`) e digitos alem da precisao segura ficam texto, porque o numero perderia informacao.
43
+ if (/^-?(0|[1-9]\d*)$/.test(t) && Number.isSafeInteger(Number(t)))
42
44
  return Number(t);
43
45
  if (/^-?\d*\.\d+$/.test(t))
44
46
  return Number(t);
@@ -94,7 +94,7 @@
94
94
  },
95
95
  {
96
96
  "tipo": "contem",
97
- "valor": "fila de batch",
97
+ "valor": "a nota humana, quando vier, sobrescreve",
98
98
  "porque": "o caminho que preserva o humano nos modos sem pausa"
99
99
  }
100
100
  ]
@@ -45,7 +45,7 @@
45
45
  "tipo": "racionalizacao",
46
46
  "gravidade": "maior",
47
47
  "cenario": "Uma thread foi entregue sem score e o builder quer abrir a proxima antes de avaliar.",
48
- "esperado": "Recusado: entrega sem MASTER log nao aconteceu; nos modos sem pausa o score vai para a fila de batch, que continua humana.",
48
+ "esperado": "Recusado: entrega sem MASTER log nao aconteceu; nos modos sem pausa a entrega e aceita por omissao com o indice do ledger, e a nota humana sobrescreve.",
49
49
  "racionalizacao": "Depois eu dou o score da thread anterior.",
50
50
  "assercoes": [
51
51
  {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "tipo": "contem",
58
- "valor": "fila de batch",
58
+ "valor": "aceita por omissao com o indice do ledger",
59
59
  "porque": "o caminho que substitui a pausa nos modos autonomos, sem tirar o humano"
60
60
  }
61
61
  ]
@@ -94,7 +94,7 @@
94
94
  },
95
95
  {
96
96
  "tipo": "contem",
97
- "valor": "ork gate approve",
97
+ "valor": "--autorizar-push <quem>",
98
98
  "porque": "o comando exato que grava a autorizacao"
99
99
  }
100
100
  ]
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@orkastery/cli",
3
- "version": "0.3.0",
4
- "description": "Conduz agentes de código (Claude Code, Codex) em threads verificáveis: seis fases, quatro modos por #TAG, claims reexecutadas e entrega com push provado. Sem LLM embutido.",
3
+ "version": "0.4.1",
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
- "homepage": "https://github.com/Orkastery/orkastery#readme",
6
+ "homepage": "https://github.com/orkastery/orkastery#readme",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/Orkastery/orkastery.git",
9
+ "url": "git+https://github.com/orkastery/orkastery.git",
10
10
  "directory": "core"
11
11
  },
12
12
  "bugs": {
13
- "url": "https://github.com/Orkastery/orkastery/issues"
13
+ "url": "https://github.com/orkastery/orkastery/issues"
14
14
  },
15
15
  "keywords": [
16
16
  "orkastery",
@@ -39,7 +39,7 @@ flowchart LR
39
39
  | 8 | Os cinco eixos de review (correcao, seguranca, performance, manutenibilidade, estilo) trazem achados ou um "nenhum" explicito, cada um categorizado bloqueador, aviso ou sugestao. | A tabela dos cinco eixos do relatorio de CHECK, conforme [code-review-axes.md](code-review-axes.md). |
40
40
  | 9 | A auditoria de seguranca reporta zero bloqueadores, e a auditoria de performance web ou rodou ou declara por que o alvo nao tem superficie web. | As secoes de auditoria do relatorio, conforme [security-checklist.md](security-checklist.md) e [performance-checklist.md](performance-checklist.md). |
41
41
  | 10 | Correcoes classificadas com honestidade: tipo A e uma linha ou equivalente, registrada, com as verificacoes afetadas reexecutadas; tipo B devolveu a tarefa ao GO, e esta rodada de CHECK e a reexecucao completa. | `ork fix open <thread>` deriva uma correcao por motivo tipado, com a spec exata e o comando que a julga; `ork fix reverify <thread>` da o veredito POR correcao e RECUSA reexecucao parcial quando ha tipo B. Os eventos `go_fix_opened` e `check_reverify` do ledger contra as contagens do relatorio. Estas contagens medem a qualidade do PLAN e do GO, nao a do reviewer. |
42
- | 11 | O relatorio esta no diretorio da thread com exatamente um veredito (PASSOU, PRECISA DE MUDANCA, BLOQUEADO), todo aviso aceito tem seu registro, e o gate foi resolvido pelo caminho certo. | `ork gate approve <thread> evidencias --por <quem>` para decisao humana, ou o evento de decisao autonoma do modo, que so um veredito PASSOU pode tomar. Falha de verify, falha anti-alucinacao, qualquer CHECK com correcao tipo B, desvio de envelope, veredito diferente de PASSOU e emergencia sobem sempre para o humano, em qualquer modo. |
42
+ | 11 | O relatorio esta no diretorio da thread com exatamente um veredito (PASSOU, PRECISA DE MUDANCA, BLOQUEADO), todo aviso aceito tem seu registro, e o gate foi resolvido pelo caminho certo. | A resposta humana ao `ork gate request <thread>`, pelo canal autenticado, para decisao humana, ou o evento de decisao autonoma do modo, que so um veredito PASSOU pode tomar. Falha de verify, falha anti-alucinacao, qualquer CHECK com correcao tipo B, desvio de envelope, veredito diferente de PASSOU e emergencia sobem sempre para o humano, em qualquer modo. |
43
43
 
44
44
  ## Todo merge, antes de o SHIP fechar
45
45
 
@@ -48,7 +48,7 @@ flowchart LR
48
48
  | 12 | Guarda de contrato: nada no diff final muda contrato publico versionado (schema de telemetria, contrato de interface, layout de estado, tipos de evento) sem decisao de classe 2 ratificada. | `git diff <base>...HEAD` sobre esses arquivos e o id do gate que ratificou, no ledger. Sem ratificacao nao ha merge. |
49
49
  | 13 | O merge passou pela fila serializada, atualizado contra a base mais recente, revalidado por inteiro sempre que a atualizacao trouxe mudanca, com a guarda de `DoD 12` reexecutada contra o diff final. | `ork ship <thread> --para <base>` toma o lease `main-tree`; a atualizacao pode trazer mudanca que toca contrato, entao um veredito calculado antes dela descreve um diff que nao existe mais. |
50
50
  | 14 | O push foi provado por comando, nao relatado. | O `ork ship` compara o sha local com `git ls-remote` no remoto e grava `pushVerificado` no ledger. Push relatado sem sha do remoto conta como push nao acontecido. |
51
- | 15 | Passo irreversivel so acontece com autorizacao do modo: push, merge e delecao exigem a pausa que a #TAG previu ou uma autorizacao antecipada registrada. | `ork gate approve <thread> push --por <quem>`, visivel em `ork phase list <thread>`. |
51
+ | 15 | Passo irreversivel so acontece com autorizacao do modo: push, merge e delecao exigem a pausa que a #TAG previu ou uma autorizacao antecipada registrada. | `ork ship <thread> --para <base> --autorizar-push <quem>`, ou a resposta humana a pausa do modo, visivel em `ork phase list <thread>`. |
52
52
 
53
53
  ## Todo fechamento, antes de a thread morrer
54
54
 
package/skills/README.md CHANGED
@@ -15,14 +15,14 @@ faz, o nucleo vence, e a divergencia e defeito da skill.
15
15
  | phases | [goal-definition](phases/goal-definition/SKILL.md) | `ork phase run <t> GOAL`, `ork claims add` |
16
16
  | phases | [plan-specification](phases/plan-specification/SKILL.md) | `ork phase run <t> PLAN`, `ork lease acquire` |
17
17
  | phases | [go-implementation](phases/go-implementation/SKILL.md) | `ork worktree ensure`, `ork verify --baseline` |
18
- | phases | [check-quality](phases/check-quality/SKILL.md) | `ork verify`, `ork gate approve` |
18
+ | phases | [check-quality](phases/check-quality/SKILL.md) | `ork verify`, `ork gate request` |
19
19
  | phases | [ship-release](phases/ship-release/SKILL.md) | `ork ship` |
20
- | phases | [master-metrics](phases/master-metrics/SKILL.md) | `ork master`, `ork master --batch` |
20
+ | phases | [master-metrics](phases/master-metrics/SKILL.md) | `ork master`, `ork master --aceitar-omissao` |
21
21
  | reviewers | [code-reviewer](reviewers/code-reviewer/SKILL.md) | `references/code-review-axes.md` |
22
22
  | reviewers | [security-auditor](reviewers/security-auditor/SKILL.md) | `references/security-checklist.md` |
23
23
  | reviewers | [test-engineer](reviewers/test-engineer/SKILL.md) | `references/testing-patterns.md` |
24
24
  | reviewers | [web-performance-auditor](reviewers/web-performance-auditor/SKILL.md) | `references/performance-checklist.md` |
25
- | governance | [decision-triage](governance/decision-triage/SKILL.md) | `ork gate approve` |
25
+ | governance | [decision-triage](governance/decision-triage/SKILL.md) | `ork gate request` |
26
26
  | governance | [narrative-guardian](governance/narrative-guardian/SKILL.md) | `ork verify`, `ork phase list` |
27
27
  | governance | [roadmap-keeper](governance/roadmap-keeper/SKILL.md) | `ork board`, `ork thread new` |
28
28
  | governance | [scope-check-capability-map](governance/scope-check-capability-map/SKILL.md) | `ork doctor`, `ork board plan` |
@@ -110,7 +110,7 @@ No pedido de despacho, descreva o objetivo e o escopo de todas as fases do bloco
110
110
 
111
111
  Quando `ork_observe` mostrar `turno.estado=encerrado`, reconcilie o ultimo resultado oficial e os artefatos do bloco. Isso indica um turno encerrado, nao `phase_result`, fase concluida ou entrega. Os campos nativos `state` e `status` podem divergir; preserve a divergencia em vez de interpretar `working` isoladamente. Atividade posterior invalida a evidencia de turno encerrado. Sem resultado suficiente, registre o ponto pendente e use somente a continuacao suportada pelo nucleo, sem duplicar despacho nem fabricar conclusao. Nao use sleeps longos ou polling repetido para transformar silencio em prova de vida, morte ou progresso.
112
112
 
113
- Despacho nao e conclusao. Testes, CHECK, SHIP e MASTER sao provas diferentes. Entregue mudancas, validacao, publicacao efetiva e pendencias, com links uteis ao dono. SHIP usa `ork ship`; score humano pendente continua na fila de batch `ork master --batch`. Entrega sem MASTER log nao aconteceu; publicacao e ratificacao continuam distintas.
113
+ Despacho nao e conclusao. Testes, CHECK, SHIP e MASTER sao provas diferentes. Entregue mudancas, validacao, publicacao efetiva e pendencias, com links uteis ao dono. SHIP usa `ork ship`; entrega sem nota humana e aceita por omissao com o indice do ledger (`ork master`), e a nota humana sobrescreve. Entrega sem MASTER log nao aconteceu; publicacao e ratificacao continuam distintas.
114
114
  ## Racionalizacoes comuns
115
115
  Despacho, silêncio ou modo Auto nunca substituem resultado, `verify` e recibos.
116
116
  ## Bandeiras vermelhas
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: decision-triage
3
- description: "A disciplina de delegacao: classifica cada decisao em classe 1 (humano decide), 2 (contrato publico, exige ratificacao) ou 3 (delegada, registrada), e sobe tradeoff real com opcoes e uma recomendacao. Roteia para ork gate approve."
3
+ description: "A disciplina de delegacao: classifica cada decisao em classe 1 (humano decide), 2 (contrato publico, exige ratificacao) ou 3 (delegada, registrada), e sobe tradeoff real com opcoes e uma recomendacao. Roteia para ork gate request."
4
4
  bucket: governance
5
- roteia: "ork gate approve <thread> <sobre> --por <quem>"
5
+ roteia: "ork gate request <thread>"
6
6
  license: MIT
7
7
  ---
8
8
 
@@ -25,8 +25,8 @@ atras de "detalhe tecnico": ela classifica, registra o que e delegado e sobe o q
25
25
  ## Como rotear
26
26
 
27
27
  ```bash
28
- ork gate approve <thread> <sobre> --por <quem> # decisao humana registrada
29
- ork phase list <thread> # a auditoria de delegacao le daqui
28
+ ork gate request <thread> # abre o pedido; o humano responde pelo canal autenticado
29
+ ork phase list <thread> # a auditoria de delegacao le daqui
30
30
  ```
31
31
 
32
32
  ## Conduta
@@ -25,7 +25,7 @@ nao existe nao vira promessa em README.
25
25
  ```bash
26
26
  ork verify <thread> # o que a maquina realmente prova hoje
27
27
  ork phase list <thread> # a origem de cada evidencia citada
28
- ork master --batch # o que ja foi fechado e pode ser citado como entregue
28
+ ork master --todas # o que ja foi fechado e pode ser citado como entregue
29
29
  ```
30
30
 
31
31
  ## As regras do canon
@@ -20,7 +20,7 @@ silencio. **Demanda que vira thread sem estar registrada e trabalho sem dono e s
20
20
  ork board # o estado de todas as threads
21
21
  ork board plan # quem avanca agora, quem espera e por que
22
22
  ork thread new "<nome>" --mode <modo>
23
- ork master --batch # o que fechou e ainda espera score
23
+ ork master # as entregas, com o indice derivado do ledger
24
24
  ```
25
25
 
26
26
  ## Conduta
@@ -22,7 +22,7 @@ ork thread status <thread> # o estado gravado cruzado com o runtime real
22
22
  ork sessions --all # as sessoes vivas do runtime
23
23
  ork claims list <thread> # as alegacoes e o estado de cada uma
24
24
  ork board # todas as threads, uma visao
25
- ork master --batch # o que fechou e ainda espera score
25
+ ork master # as entregas, com o indice derivado do ledger
26
26
  ```
27
27
 
28
28
  ## O que o rastro precisa responder
@@ -2,7 +2,7 @@
2
2
  name: check-quality
3
3
  description: "Fase CHECK (F4): verificacao contra a baseline, os cinco eixos de review, auditoria de seguranca e de performance, auditoria de delegacao e um veredito unico. Roteia para ork verify e para as quatro skills de reviewer."
4
4
  bucket: phases
5
- roteia: "ork verify <thread> | ork gate approve <thread> evidencias"
5
+ roteia: "ork verify <thread> | ork gate request <thread>"
6
6
  license: MIT
7
7
  ---
8
8
 
@@ -20,7 +20,7 @@ corrige o que encontra: correcao e trabalho de GO.
20
20
  ork verify <thread> # reexecuta claims e verify contra a baseline
21
21
  ork phase list <thread> # o ledger, para a auditoria de delegacao
22
22
  ork worktree audit <thread> # a worktree confere no proprio git
23
- ork gate approve <thread> evidencias --por <quem>
23
+ ork gate request <thread> # o pedido da pausa; o humano responde pelo canal autenticado
24
24
  ```
25
25
 
26
26
  Quando o veredito e PRECISA DE MUDANCA, o sub-loop GO-FIX / CHECK-REVERIFY do bloco B3 e
@@ -21,7 +21,7 @@ ork thread new "<nome>" --mode <modo>
21
21
  ork phase run <thread> GOAL --prompt "<pedido do builder>"
22
22
  ork claims add <thread> <arquivo> --claim "<alegacao>" --verificar "<comando>" --fase GOAL
23
23
  ork verify <thread> --so-claims
24
- ork gate approve <thread> objetivo --por <quem>
24
+ ork gate request <thread>
25
25
  ```
26
26
 
27
27
  ## O que o GOAL entrega
@@ -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 --batch."
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."
4
4
  bucket: phases
5
- roteia: "ork master <thread> --score N --justificativa \"...\" | ork master --batch"
5
+ roteia: "ork master <thread> --score N --justificativa \"...\" | ork master --aceitar-omissao"
6
6
  license: MIT
7
7
  ---
8
8
 
@@ -19,8 +19,9 @@ cumpre. **Uma entrega sem MASTER log nao aconteceu.**
19
19
  ```bash
20
20
  ork master classes # as classes de falha do catalogo fixo
21
21
  ork master <thread> --score 4 --justificativa "<texto>" --classe base-avancou --por <quem>
22
- ork master --batch # a fila de score dos modos sem pausa de MASTER
23
- ork master --batch --todas
22
+ ork master # as entregas, com o indice derivado do ledger
23
+ ork master --todas # inclusive as ja pontuadas
24
+ ork master --aceitar-omissao # aceita as entregues, com indice e insumos no ledger
24
25
  ```
25
26
 
26
27
  ## O que o MASTER entrega
@@ -31,7 +32,8 @@ ork master --batch --todas
31
32
  2. **MASTER log no contrato `ork.master-log/v1`**, congelado: mudar o contrato sem mudar a versao
32
33
  e reprovado, porque contrato de telemetria e contrato publico.
33
34
  3. **Score humano inteiro de 0 a 5, com justificativa nao vazia.** O score e do humano, sempre. Nos
34
- modos sem pausa de MASTER ele vai para a fila de batch, e a fila continua sendo humana.
35
+ modos sem pausa de MASTER a entrega e aceita por omissao, com o indice derivado do ledger, que
36
+ nenhum agente digita; a nota humana, quando vier, sobrescreve.
35
37
  4. **Evidencia apontando o ledger e o POSTMORTEM**, com contagem de eventos, sessoes e claims. Log
36
38
  sem evidencia e recusado.
37
39
 
@@ -50,14 +52,14 @@ grava metade e pior que recusa inteira.
50
52
  | "Dou 4,5, ficou entre os dois" | O score e inteiro de 0 a 5. Escala com meio ponto vira negociacao, e o que se mede aqui e conducao, nao simpatia. |
51
53
  | "A classe de falha dessa foi 'quase deu certo'" | O catalogo e fixo. Classe inventada e recusada, porque classe livre destroi a comparabilidade entre threads. |
52
54
  | "Preencho o MASTER log depois, a entrega ja foi" | Uma entrega sem MASTER log nao aconteceu. Fase de aprendizado adiada e fase de aprendizado que nao existe. |
53
- | "O modo e `#Auto`, entao o score pode ser automatico" | O score e humano em todos os modos. `#Auto` muda quando ele e dado, para a fila de batch, nunca quem da. |
55
+ | "O modo e `#Auto`, entao o score pode ser automatico" | O score e humano em todos os modos. `#Auto` muda quando ele e dado (a entrega e aceita por omissao e a nota humana sobrescreve), nunca quem da. |
54
56
 
55
57
  ## Bandeiras vermelhas
56
58
 
57
59
  - Thread entregue sem `master-log.json`.
58
60
  - Score gravado sem nome de quem avaliou.
59
61
  - Classe de falha fora do catalogo fixo, ou nenhuma classe numa thread que teve retrabalho.
60
- - Fila de batch crescendo sem ninguem passar nela.
62
+ - Nota de score digitada por agente em nome do humano.
61
63
 
62
64
  ## Verificacao antes de sair da fase
63
65
 
@@ -19,7 +19,7 @@ tradeoff do humano: ela despacha a fase pelo `ork` e transforma o plano em taref
19
19
  ```bash
20
20
  ork phase run <thread> PLAN --prompt "<pedido do builder>"
21
21
  ork lease acquire "path:<glob>" --thread <thread> --motivo "PLAN reservou a regiao"
22
- ork gate approve <thread> premissas --por <quem>
22
+ ork gate request <thread>
23
23
  ork handoff export <thread> --proxima-fase GO
24
24
  ```
25
25
 
@@ -18,8 +18,8 @@ o push comparando o sha local com o que o remoto reporta**.
18
18
 
19
19
  ```bash
20
20
  ork worktree sync <thread> # rebasa quando a base avancou
21
- ork gate approve <thread> push --por <quem> # autorizacao humana registrada
22
21
  ork ship <thread> --para main --dry-run # ensaio: mostra tudo, nao toca em nada
22
+ # autorizacao humana registrada: vai no proprio ship, com o nome de quem autorizou
23
23
  ork ship <thread> --para main --autorizar-push <quem>
24
24
  ork phase list <thread> # a prova: mergeSha, shaRemoto, pushVerificado
25
25
  ```
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env sh
2
- # Acrescenta uma mensagem do canal ao mesmo histórico durável visto no Kanban.
3
- set -eu
4
- # I-36 (D6): o adaptador declara o canal de conducao do Hermes; descreve a porta, nao da autoridade.
5
- export ORK_CANAL="${ORK_CANAL:-hermes}"
6
-
7
- if [ "$#" -lt 3 ]; then
8
- echo "uso: ork-objective-message.sh <objective-id> <autor-do-canal> <texto>" >&2
9
- exit 2
10
- fi
11
-
12
- OBJECTIVE="$1"
13
- AUTHOR="$2"
14
- shift 2
15
-
16
- exec "${ORK_BIN:-ork}" objective message "$OBJECTIVE" \
17
- --text "$*" --por "$AUTHOR" --role human
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env sh
2
- # Lê o ticket canônico para que o Hermes continue a conversa iniciada no Kanban.
3
- set -eu
4
- # I-36 (D6): o adaptador declara o canal de conducao do Hermes; descreve a porta, nao da autoridade.
5
- export ORK_CANAL="${ORK_CANAL:-hermes}"
6
-
7
- if [ "$#" -ne 1 ]; then
8
- echo "uso: ork-objective-status.sh <objective-id>" >&2
9
- exit 2
10
- fi
11
-
12
- exec "${ORK_BIN:-ork}" objective status "$1" --json