@orkastery/cli 0.5.1 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/agents/ork-master.md +2 -0
  3. package/adapters/claude-code/commands/master.md +8 -0
  4. package/adapters/claude-code/commands/ork.md +9 -0
  5. package/adapters/claude-code/mods/autoridade.json +56 -0
  6. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  8. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  9. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  10. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  11. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  12. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  13. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  16. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  17. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  18. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  19. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  20. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  21. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  25. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  27. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  28. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  29. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  30. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  33. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  34. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  35. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  36. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  37. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  38. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  44. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  45. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  46. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  47. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  48. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  49. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  52. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  53. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  54. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  55. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  56. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  57. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  59. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  60. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  61. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  62. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  63. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  64. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  67. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  68. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  69. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  70. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  71. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  72. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  77. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  78. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  79. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  80. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  81. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  82. package/adapters/codex/skills/ork/SKILL.md +18 -3
  83. package/adapters/hermes/README.md +1 -0
  84. package/adapters/hermes/bin/ork-network-status.sh +10 -0
  85. package/adapters/hermes/hermes.plugin.json +1 -0
  86. package/adapters/hermes/hitl-ingress/__init__.py +2 -2
  87. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +7 -6
  88. package/adapters/openclaw/README.md +26 -5
  89. package/adapters/openclaw/dist/hitl-ingress.js +2 -2
  90. package/adapters/openclaw/dist/index.js +46 -11
  91. package/adapters/openclaw/openclaw.plugin.json +5 -1
  92. package/adapters/openclaw/package.json +2 -2
  93. package/adapters/openclaw/src/hitl-ingress.ts +2 -2
  94. package/adapters/openclaw/src/index.ts +49 -11
  95. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  96. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  97. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  98. package/assets/docs-en/produto/README.md +14 -0
  99. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  100. package/assets/docs-en/roadmap/README.md +14 -0
  101. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  102. package/assets/orkmind_bridge.py +117 -9
  103. package/dist/adapters/claude-bg.js +116 -18
  104. package/dist/adapters/codex.js +14 -4
  105. package/dist/agents-md.js +24 -14
  106. package/dist/auditrun.js +22 -3
  107. package/dist/board.js +20 -17
  108. package/dist/branch-de-estado.js +88 -10
  109. package/dist/busca-semantica.js +52 -12
  110. package/dist/canarios-rm057.js +149 -0
  111. package/dist/canarios.js +2 -0
  112. package/dist/catalogo.js +33 -0
  113. package/dist/ci.js +21 -8
  114. package/dist/claims-conferir.js +342 -0
  115. package/dist/claims.js +41 -1
  116. package/dist/company-brain-client.js +36 -1
  117. package/dist/company-brain-context.js +158 -22
  118. package/dist/company-brain-journal.js +2 -1
  119. package/dist/company-brain-migration.js +36 -1
  120. package/dist/conducao-sentinela.js +388 -0
  121. package/dist/conducao-texto.js +12 -18
  122. package/dist/conducao.js +122 -30
  123. package/dist/conhecimento.js +490 -0
  124. package/dist/docs.js +70 -17
  125. package/dist/doctor-pulse-cron.js +349 -0
  126. package/dist/doctor-rede.js +150 -0
  127. package/dist/doctor.js +195 -111
  128. package/dist/entrega-pr.js +42 -29
  129. package/dist/escopo-escrita.js +10 -1
  130. package/dist/esgotamentos.js +181 -0
  131. package/dist/estado-thread.js +23 -1
  132. package/dist/experiencia-instalacao.js +45 -25
  133. package/dist/experiencia.js +12 -2
  134. package/dist/fabrica-batida.js +310 -0
  135. package/dist/fabrica-estado.js +52 -14
  136. package/dist/fabrica-publicar.js +9 -1
  137. package/dist/fechamento.js +20 -66
  138. package/dist/fila-pesada.js +444 -0
  139. package/dist/fix.js +3 -2
  140. package/dist/forja.js +31 -7
  141. package/dist/gates.js +3 -24
  142. package/dist/handoff.js +10 -6
  143. package/dist/hitl-contract.js +59 -4
  144. package/dist/hitl-curto.js +11 -6
  145. package/dist/hitl-gates.js +5 -0
  146. package/dist/hitl-local-receipt.js +2 -0
  147. package/dist/hitl-lote.js +5 -2
  148. package/dist/hitl-resumo.js +38 -3
  149. package/dist/hitl-tempo-parado.js +201 -0
  150. package/dist/hitl-texto-livre.js +5 -5
  151. package/dist/hitl.js +29 -33
  152. package/dist/horario.js +41 -7
  153. package/dist/hosts.js +104 -11
  154. package/dist/impedimento.js +299 -0
  155. package/dist/index.js +961 -542
  156. package/dist/indice-vetorial.js +87 -10
  157. package/dist/indice.js +9 -1
  158. package/dist/init.js +56 -43
  159. package/dist/instabilidade.js +144 -0
  160. package/dist/integracoes-locais.js +4 -0
  161. package/dist/intelligence-graph-cli.js +170 -16
  162. package/dist/intelligence-graph-contexto.js +254 -0
  163. package/dist/intelligence-graph-contract.js +2 -1
  164. package/dist/intelligence-graph-extract-md.js +56 -4
  165. package/dist/intelligence-graph-extract-ts.js +71 -3
  166. package/dist/intelligence-graph-parsers.js +6 -4
  167. package/dist/intelligence-graph-query.js +66 -19
  168. package/dist/leases.js +664 -87
  169. package/dist/ledger-stats.js +15 -1
  170. package/dist/ledger.js +18 -1
  171. package/dist/licoes.js +1 -0
  172. package/dist/liveness.js +6 -3
  173. package/dist/locale-ajuda.js +761 -0
  174. package/dist/locale-gerados.js +160 -0
  175. package/dist/locale-master.js +99 -0
  176. package/dist/locale-onboarding.js +92 -0
  177. package/dist/locale-phase.js +151 -0
  178. package/dist/locale-pulse.js +211 -0
  179. package/dist/locale-retry.js +385 -0
  180. package/dist/locale-roadmap.js +102 -0
  181. package/dist/locale-ship.js +494 -0
  182. package/dist/locale-thread.js +277 -0
  183. package/dist/locale-verify.js +125 -0
  184. package/dist/locale.js +714 -0
  185. package/dist/maestro-runtime.js +4 -1
  186. package/dist/manifest.js +149 -4
  187. package/dist/maquina.js +23 -4
  188. package/dist/master-digest.js +6 -1
  189. package/dist/master-nota.js +18 -11
  190. package/dist/master.js +145 -31
  191. package/dist/mcp-artifacts.js +43 -3
  192. package/dist/mcp-git.js +42 -8
  193. package/dist/mcp-grafo-worker.js +5 -3
  194. package/dist/mcp-grafo.js +55 -6
  195. package/dist/mcp-server.js +22 -3
  196. package/dist/mcp-ship.js +3 -1
  197. package/dist/mcp-verify.js +6 -1
  198. package/dist/memoria.js +48 -6
  199. package/dist/modos.js +3 -6
  200. package/dist/network-roadmap.js +196 -18
  201. package/dist/noctum-arco.js +911 -0
  202. package/dist/noctum-capacidade.js +141 -0
  203. package/dist/noctum-envelope.js +810 -0
  204. package/dist/noctum-execucao.js +304 -0
  205. package/dist/noctum-fila.js +280 -0
  206. package/dist/ocupacao.js +40 -5
  207. package/dist/onboarding.js +40 -21
  208. package/dist/orkmind.js +99 -7
  209. package/dist/orquestracao.js +24 -21
  210. package/dist/parado-no-condutor.js +219 -38
  211. package/dist/phase.js +160 -52
  212. package/dist/policies.js +56 -5
  213. package/dist/portfolio.js +8 -3
  214. package/dist/postura-local.js +234 -0
  215. package/dist/preflight.js +11 -10
  216. package/dist/procedencia.js +225 -0
  217. package/dist/projeto-alvo.js +132 -5
  218. package/dist/prompts.js +40 -1
  219. package/dist/prova-ativacao.js +75 -6
  220. package/dist/pulse-delivery.js +47 -4
  221. package/dist/pulse.js +98 -19
  222. package/dist/ratelimit.js +24 -6
  223. package/dist/recall.js +3 -1
  224. package/dist/redacao-saida.js +63 -0
  225. package/dist/rede-adesao.js +399 -0
  226. package/dist/rede-forja.js +289 -0
  227. package/dist/rede-projetos.js +239 -0
  228. package/dist/rede-status.js +337 -0
  229. package/dist/rede.js +980 -0
  230. package/dist/retry.js +291 -140
  231. package/dist/roadmap-reservas.js +20 -3
  232. package/dist/roadmap-status.js +150 -34
  233. package/dist/runtime-context.js +181 -3
  234. package/dist/runtime-profiles.js +22 -1
  235. package/dist/runtimes.js +2 -1
  236. package/dist/saida-segura.js +58 -0
  237. package/dist/session-events.js +7 -3
  238. package/dist/session-watcher-claude.js +120 -24
  239. package/dist/session-watcher.js +185 -33
  240. package/dist/sessoes-contas.js +187 -0
  241. package/dist/sessoes-inventario.js +6 -18
  242. package/dist/sessoes.js +83 -2
  243. package/dist/ship-publicar.js +800 -0
  244. package/dist/ship.js +157 -88
  245. package/dist/steal.js +77 -0
  246. package/dist/thread-close.js +3 -2
  247. package/dist/thread.js +299 -49
  248. package/dist/util.js +8 -1
  249. package/dist/verify.js +141 -52
  250. package/dist/vida-da-thread.js +254 -0
  251. package/dist/worktree-local.js +165 -0
  252. package/dist/worktree.js +25 -2
  253. package/dist/yaml.js +27 -8
  254. package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
  255. package/package.json +7 -3
  256. package/references/definition-of-done.md +1 -1
  257. package/schemas/code-artifact-graph.v1.schema.json +2 -1
  258. package/skills/README.md +1 -1
  259. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  260. package/skills/phases/master-metrics/SKILL.md +8 -3
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ exports.main = main;
42
42
  const company_brain_cli_1 = require("./company-brain-cli");
43
43
  const estado_thread_1 = require("./estado-thread");
44
44
  const intelligence_graph_cli_1 = require("./intelligence-graph-cli");
45
+ const mcp_grafo_1 = require("./mcp-grafo");
45
46
  const maestro_cli_1 = require("./maestro-cli");
46
47
  const hitl_public_receipt_1 = require("./hitl-public-receipt");
47
48
  const hitl_presentation_1 = require("./hitl-presentation");
@@ -92,6 +93,7 @@ const orquestracao_1 = require("./orquestracao");
92
93
  const divida_1 = require("./divida");
93
94
  const ciclos_1 = require("./ciclos");
94
95
  const claims_1 = require("./claims");
96
+ const claims_conferir_1 = require("./claims-conferir");
95
97
  const catalogo_1 = require("./catalogo");
96
98
  const doctor_1 = require("./doctor");
97
99
  const preflight_1 = require("./preflight");
@@ -106,6 +108,7 @@ const agents_md_1 = require("./agents-md");
106
108
  const leases_1 = require("./leases");
107
109
  const sessoes_inventario_1 = require("./sessoes-inventario");
108
110
  const ledger_stats_1 = require("./ledger-stats");
111
+ const esgotamentos_1 = require("./esgotamentos");
109
112
  const sessoes_adopt_1 = require("./sessoes-adopt");
110
113
  const sessoes_1 = require("./sessoes");
111
114
  const runtime_ambiente_1 = require("./runtime-ambiente");
@@ -116,7 +119,7 @@ const horario_1 = require("./horario");
116
119
  const onboarding_1 = require("./onboarding");
117
120
  const experiencia_1 = require("./experiencia");
118
121
  const hosts_2 = require("./hosts");
119
- const init_2 = require("./init");
122
+ const locale_1 = require("./locale");
120
123
  const memoria_1 = require("./memoria");
121
124
  const orkmind_1 = require("./orkmind");
122
125
  const indice_vetorial_1 = require("./indice-vetorial");
@@ -135,6 +138,7 @@ const runtime_profiles_1 = require("./runtime-profiles");
135
138
  const claude_bg_1 = require("./adapters/claude-bg");
136
139
  const codex_1 = require("./adapters/codex");
137
140
  const conducao_1 = require("./conducao");
141
+ const conducao_sentinela_1 = require("./conducao-sentinela");
138
142
  const phase_1 = require("./phase");
139
143
  const prompts_1 = require("./prompts");
140
144
  const sessoes_2 = require("./sessoes");
@@ -145,19 +149,30 @@ const thread_1 = require("./thread");
145
149
  const docs_1 = require("./docs");
146
150
  const roadmap_reservas_1 = require("./roadmap-reservas");
147
151
  const fabrica_estado_1 = require("./fabrica-estado");
152
+ const branch_de_estado_1 = require("./branch-de-estado");
148
153
  const network_roadmap_1 = require("./network-roadmap");
149
154
  const fabrica_publicar_1 = require("./fabrica-publicar");
155
+ const fabrica_batida_1 = require("./fabrica-batida");
150
156
  const maquina_1 = require("./maquina");
157
+ const rede_1 = require("./rede");
158
+ const rede_adesao_1 = require("./rede-adesao");
159
+ const saida_segura_1 = require("./saida-segura");
160
+ const rede_forja_1 = require("./rede-forja");
161
+ const rede_status_1 = require("./rede-status");
151
162
  const ledger_1 = require("./ledger");
152
163
  const tokens_1 = require("./tokens");
153
164
  const types_1 = require("./types");
154
165
  const verify_1 = require("./verify");
166
+ const fila_pesada_1 = require("./fila-pesada");
155
167
  const worktree_1 = require("./worktree");
156
168
  const claim_lint_1 = require("./claim-lint");
157
169
  const licoes_1 = require("./licoes");
158
170
  const demo_1 = require("./demo");
159
171
  const entrega_pr_1 = require("./entrega-pr");
172
+ const ship_publicar_1 = require("./ship-publicar");
160
173
  const projeto_alvo_1 = require("./projeto-alvo");
174
+ const worktree_local_1 = require("./worktree-local");
175
+ const postura_local_1 = require("./postura-local");
161
176
  /** A versao publicada em `@orkastery/cli`, lida do package.json (`versao.ts`). */
162
177
  // Antes de qualquer arquivo ou despacho: sem escrita de grupo nem de outros, que o sensor recusaria.
163
178
  (0, preflight_1.endurecerUmask)();
@@ -193,13 +208,22 @@ function parseArgs(argv) {
193
208
  function texto(v) {
194
209
  return typeof v === 'string' ? v : undefined;
195
210
  }
211
+ /**
212
+ * RM-058 N2 (A1 da rodada 2 do CHECK): a fila de recursos pesados de um comando que verifica por dentro, pelo `--esperar`
213
+ * dele, com o aviso no stderr e o comando que a recusa sugere. Sem `--esperar`, vale o padrão curto do verify.
214
+ */
215
+ function filaPesadaDoCli(args, operacao, comandoDeEsperar) {
216
+ const m = (0, locale_1.msg)().verify;
217
+ return { esperarMs: conducaoDoCli(args).esperarMs, comandoDeEsperar,
218
+ aoEsperar: (ocupantes) => console.error(m.filaPesadaEsperando(operacao, ocupantes.map((o) => m.filaPesadaOcupante(o.operacao, o.thread, (0, horario_1.formatarDataHora)(o.desde))).join('; '))) };
219
+ }
196
220
  /**
197
221
  * I-36 (D2, D6): o que o CLI declara sobre a conducao. `--canal` (sem ele, o que a borda exporta),
198
222
  * `--correlacao` (conversa ou mensagem de origem) e `--esperar [minutos]` (sem valor, 30).
199
223
  */
200
224
  function conducaoDoCli(args) {
201
225
  if (args.opcoes.canal === true)
202
- throw new Error('uso: --canal <claude-code|hermes|openclaw|codex|mcp|cli>');
226
+ throw new Error((0, locale_1.msg)().phase.canalUso);
203
227
  const bruto = args.opcoes.esperar;
204
228
  let esperarMs;
205
229
  if (bruto === true)
@@ -207,343 +231,38 @@ function conducaoDoCli(args) {
207
231
  else if (typeof bruto === 'string') {
208
232
  const minutos = Number(bruto);
209
233
  if (!Number.isFinite(minutos) || minutos <= 0 || minutos > 24 * 60)
210
- throw new Error('uso: --esperar [minutos], de 1 a 1440 (sem valor, 30)');
234
+ throw new Error((0, locale_1.msg)().phase.esperarUso);
211
235
  esperarMs = Math.round(minutos * 60_000);
212
236
  }
213
237
  return { canal: (0, conducao_1.canalDoProcesso)(texto(args.opcoes.canal)), correlacao: texto(args.opcoes.correlacao) ?? null, esperarMs };
214
238
  }
215
- const AJUDA = `ork ${VERSAO}, nucleo de orquestracao do Orkastery
216
-
217
- Uso: ork [--projeto <nome|caminho>] <comando> [argumentos]
218
-
219
- --projeto <nome|caminho> Projeto-alvo de qualquer comando (RM-052): vence ORK_PROJETO, que vence o
220
- diretorio atual; nome ambiguo ou desconhecido recusa com os candidatos (saida 4)
221
- projetos [--json] Projetos conhecidos desta maquina (~/.orkastery/projetos.json)
222
- projetos registrar [caminho] Registra a copia (init, thread new e fabrica entrar ja registram)
223
- projetos esquecer <nome|caminho> Tira do registro a copia que sumiu ou sobrou (nada no disco e apagado)
224
-
225
- doctor O que vale nesta maquina agora (sai != 0 se bloqueado)
226
- init [--force] [--name N] [--abbrev A] Gera o orkastery.yaml do repositorio
227
- modos Tabela dos ${modos_1.ORDEM_DOS_MODOS.length} modos de conducao vivos por #TAG
228
-
229
- setup Pauta da entrevista #setup: runtime/modelo/esforco
230
- por bloco de cada modo (default claude-bg/opus/high; #Fast: sonnet)
231
- onboarding [show|set <etapa>|reset [etapa]] Pauta e respostas do projeto (9 etapas)
232
- [--conteudo JSON] [--por Q] [--json] Segredos ficam ${onboarding_1.ONDE_FICAM_OS_SEGREDOS}
233
- [--reset [etapa]] Reset seletivo ou total, idempotente
234
- onboarding sync [--json] Publicação opcional na memória, com degradação
235
- experiencia show [--json] Preferências efetivas; configure por onboarding set maestro --conteudo '{"owner":{"experience":true}}'
236
- experiencia uninstall <host> [--dry-run] [--json]
237
- Remove o bloco de Claude Code/Codex; sem --dry-run aplica a remoção
238
- setup <modo> Config atual de cada bloco do modo
239
- setup <modo> --bloco N [--runtime R] Edita o bloco (runtimes: claude-bg, codex);
240
- [--model M] [--effort E] [--por Q] evento setup_configured no ledger do projeto
241
- [--fallback R:M[:E],...] ordem de fallback de runtime do bloco (I-33)
242
- accounts list [--json] Perfis de conta por runtime, sem segredo (I-33)
243
- accounts add <id> --runtime R --dir D Cria o perfil e roda o login do proprio CLI com o env
244
- [--sem-login] do perfil (nunca copia credencial)
245
- accounts remove <id> Desativa o perfil (diretorio e login ficam onde estao)
246
- accounts check [<id>] Confere o login de cada perfil e marca o store
247
- setup [<modo>] --reset Volta o modo (ou tudo) ao default
248
- setup versionar Leva o setup que vale para orkastery.setup.json: por PR, vale em
249
- todas as maquinas e passa a ser o arquivo editado (I-52)
250
-
251
- thread new <nome> --modo <MODO> Cria a thread, o slug de 3 partes e o ledger
252
- [--exige-runtime-diferente] o CHECK precisa de runtime que o GO nao usou
253
- [--done "<criterio> :: <comando>"] criterio de pronto EXECUTAVEL (use ;; para varios)
254
- [--slug S] [--assunto A] [--worktree auto|DIR] [--dry-run]
255
- [--roadmap RM-NNN] reserva o item do roadmap antes de criar (I-47)
256
- thread list [--todas] [--json] Threads NAO fechadas do projeto (--todas inclui as fechadas)
257
- thread close <id> --motivo orfa|engano|superada --por Q --justificativa J
258
- thread entrega <id> --arquivo A --sha256 H --por Q
259
- thread status <thread-id> [--json] Estado da thread, cruzado com o runtime
260
-
261
- portfolio inspect <id> --json Entidade, origem e ciclos com lacunas explícitas
262
- creation start --input-file F --json Criação durável com identidade do processo local
263
- creation show|list|events [id] --json Consulta journal e recuperação
264
- creation resume|compensate <id> --expected-version N --json
265
- portfolio create <product|project|initiative> <id> --title T [--parent ID]
266
- portfolio list [product|project|initiative] [--parent ID] [--json]
267
- portfolio show <id> [--json] Catálogo prod -> proj -> init
268
- [--constraints A;B] [--outcomes A;B] [--threads N]
269
- [--execution-runtime R] [--validation-runtimes R1,R2]
270
- objective ... Aposentado na I-43: as duas vigas viraram
271
- --exige-runtime-diferente e --done de thread
272
-
273
- phase run <thread-id> <FASE> --prompt "<texto>"
274
- [--runtime R] [--model M] Despacha a fase como background agent
275
- [--effort E] [--dry-run] (runtime: CLI > setup do bloco > manifesto;
276
- so --model assume --effort high; o trio
277
- efetivo vai ao ledger como fato verificavel)
278
- [--canal C] [--correlacao ID] Canal de origem (sem ele, o que o host declara)
279
- [--esperar [min]] Com a thread ja conduzida, espera a vez (sem: recusa na hora)
280
- phase list <thread-id> Historico do ledger da thread
281
- (mostra o modelo/esforco reais de cada fase)
282
- ledger stats --desde 7d [--ate ISO] Telemetria economica do ledger (intervalo [desde,ate))
283
- [--thread T] [--modo M] [--runtime R] [--json]
284
- ledger estimate <thread-id> --sem-ia H --ia-sem-ork H --por Q --metodo M --premissas P
285
- [--incerteza I] Registra estimativas explicitas da fase PLAN
286
-
287
- sessions [--all] [--global] [--json] Inventário Claude e Codex da conta atual
288
- [--exigir-limpo] Sai != 0 com fonte inválida ou sessão sem thread
289
- sessions adopt <id> [--json] Adota identidade real sem executar prompt
290
- sessions event --tipo T --sessao ID Ingere JSON limitado no stdin; observa sem aprovar gates
291
- sessions watch --thread T [--sessao ID] Observa somente a sessão selecionada; --once faz uma varredura
292
- sessions logs <sessao> [--linhas N] Logs de uma sessao
293
- sessions supersede <thread> <UUID> --fase F --runtime R Confirma encerramento de sessão superada
294
- sessions request <thread> <UUID> --fase F --runtime R --pergunta P Abre pedido vinculado ao prompt nativo
295
- sessions answer <thread> <pedido> --stdin --origem telegram --canal C --por ID --mensagem REF [--conta ID] Confirma entrega autenticada
296
- sessions reconcile <thread> <pedido> Fecha envio pendente so com thread e pedido; consulta recibo, nunca reenvia
297
- sessions stop <sessao> Para uma sessao
298
- sessions attach <sessao> Imprime o comando de attach (precisa de TTY)
299
- pulse [--json] [--registrar] Fila unificada de atenção humana e retry de órfãs
300
- pulse responder --resposta-stdin --origem telegram --canal C --por ID --mensagem REF [--conta ID]
301
- Recebe o que o dono digitou no canal do resumo (P4EJ a, 1a 2c)
302
- pulse cadencia [<tag>] [--por P] [--json] Mostra ou troca a cadencia do resumo: OrkPulseOn, OrkPulseOn-15m,
303
- -30m, -60m ou OrkPulseOff; pergunta nova sai na hora (I-50)
304
- sessions hitl [--json] [--so-paradas] Radar de sessoes que exigem acao humana AGORA:
305
- [--atencao N] [--sem-logs] classifica o estado de cada sessao do runtime,
306
- [--so-da-raiz] [--exigir-limpo] le a pergunta que a sessao trava e diz o que
307
- destrava (pega HITL de sessao SEM thread)
308
-
309
- claims add <thread-id> <arquivo> --claim "<alegacao>" [--verificar "<comando>"] [--fase F]
310
- Registra alegacao verificavel da thread
311
- claims list <thread-id> Claims da thread e o estado de cada uma
312
- decisao registrar <thread-id> --decidido D --porque P --como-mudar C --custo-agora A --custo-depois B
313
- --criterio manifesto:CHAVE|ledger:REF|medicao:COMANDO --quem Q --evidencia E [--razao R] [--reverte ID]
314
- Decisao tomada sem perguntar: chega ao dono no resumo
315
- decisao placar <thread-id> [--json] Decididas contra perguntas por fase, reversoes e o limiar
316
- claims verificar <thread-id> <claim-id> --comando "<comando>"
317
- Anexa o comando que comprova uma claim ja feita
318
- claims retirar <thread-id> <claim-id> --motivo "<motivo>"
319
- Retira a alegacao (o historico fica no claims.jsonl)
320
- claims ausente <thread-id> --paths A,B --motivo "<motivo>" [--commit SHA]
321
- Ciclo sem CHECK: declara no ledger o que ficou sem prova
322
- verify <thread-id> [--baseline] Reexecuta claims e verify do manifesto no HEAD real
323
- [--so-claims] --baseline grava o estado do mundo antes do GO
324
- [--canal C] [--esperar [min]] So executa com a conducao da thread (sai 3 se outra conduz)
325
- ci prepare <thread-id> Exporta claims/comandos para a candidata (.ork-ci/<thread>.json)
326
- ci run [<thread-id>] [--bundle ARQ] Executa o CHECK no runner independente
327
- [--branch B] acha o bundle da thread pelo nome da branch (o CI usa)
328
- ci status [--sha SHA] [--remoto origin] Consulta o check exato publicado no GitHub
329
-
330
- gate next <thread-id> [--proximo FASE] Gate de tokens: mesma sessao ou nova sessao
331
- [--ocupacao 0..1] [--fonte F] [--transcript ARQ] [--janela N] [--refazer]
332
- gate request <thread-id> [--motivo M] Apresenta pedido HITL correlacionado à pausa
333
- [--formato telegram|terminal] no contrato curto, com o codigo estavel para responder
334
- gate answer <thread-id> <pedido> Recebe envelope do ingresso humano autenticado
335
- --resposta-stdin --por Q --mensagem ID --origem telegram [--canal hermes|openclaw]
336
- [--conta ID] conta homologada do canal; obrigatoria no canal openclaw
337
- gate approve Aposentado: aprovação sem pedido é recusada
338
-
339
- retry policy [--motivo M] [--json] Politica de retry por motivo tipado de gate
340
- retry plan <thread-id> [--motivo M] O que o ork faria pelo ultimo gate reprovado
341
- [--fase F] [--json] (calcula, nao executa, nao gasta tentativa)
342
- retry run <thread-id> [--reverify] Executa a acao tipada do ultimo gate reprovado
343
- [--por Q] [--dry-run] (--por autoriza quando o bloco do modo pausa)
344
- retry list [--json] Fila DURAVEL de rate limit do projeto
345
- retry resume [--id R1] [--agora ISO] Retoma a fase morta por rate limit na janela seguinte
346
- [--ocupacao 0..1] [--forcar] [--dry-run] (playbooks: mesma-sessao, nova-sessao, escalada)
347
- retry cancel <id> --motivo M Tira um pedido da fila, com motivo registrado
348
- retry parse --stderr "<texto>" Le o horario de reset do stderr do adapter
349
-
350
- fix open <thread-id> [--so-claims] GO-FIX: deriva a spec exata do CHECK reprovado
351
- [--reverify] [--json] (uma correcao por motivo tipado, tipo A ou B)
352
- fix list <thread-id> [--rodada N] Correcoes da rodada e o veredito de cada uma
353
- fix reverify <thread-id> [--rodada N] CHECK-REVERIFY com veredito POR correcao
354
- [--parcial] [--json] (--parcial e RECUSADO se houver tipo B)
355
-
356
- handoff export <thread-id> Handoff triado CRITICO/IMPORTANTE/RESUMIVEL
357
- [--proxima-fase FASE] [--slug S]
358
- handoff recall <thread-id> <ponteiro> Resolve um ponteiro path#ancora de volta ao conteudo
359
-
360
- recall <thread-id> --fase FASE Recuperacao TARDIA: resolve so os ponteiros do
361
- [--id ptr-N] [--todos] [--forcar] momento (retrieve_when), nunca a janela inteira
362
- [--sem-conteudo] [--json] (orkmind por tag, files por path#ancora)
363
-
364
- brain status|inventory|get|query|receipts|context|dossie|sync|reconcile|apply|rollback|bind
365
- brain dossie --thread T [--decisao ID] Dossie de decisao: vinculo, contexto citavel, alternativas,
366
- quem decidiu e evidencia, com os ids do Brain (so leitura)
367
- memory status [--json] [--sondar] Regime efetivo (files|orkmind), tenant, degradacao e embeddings
368
- (--sondar: uma chamada real de embedding, com a latencia)
369
- memory sync [<thread-id>] [--json] Publica decisoes, policies, handoff, licao e roadmap
370
- memory inventory --escopo <threads> [--json] Inventaria fontes canonicas e tenants excluidos, sem gravar
371
- memory migrate --operadora <thread> --escopo <threads> [--dry-run] [--json] Migra handoffs por G3, com pacote integral e readback
372
- memory search --tags '<json>' [--colecao C] Busca deterministica por tag (mandatory sempre volta)
373
- [--thread ID] [--restrito] [--janela N] [--limite N] [--json]
374
- memory search --texto "<frase>" Busca por significado (I-38): vetor + FTS por RRF no tenant,
375
- [--modo hibrido|vetor|fts] NAO deterministica; nao combina com --tags nem --thread
376
- [--colecao C] [--limite N] [--json]
377
- memory index [--modelo primario|fallback|todos] Indice vetorial local do tenant (I-38), idempotente,
378
- [--dry-run] [--json] com tokens e custo estimados; --dry-run nao chama o provider
379
-
380
- grafo indexar [--verificar] [--forcar] Indice do grafo de codigo do HEAD limpo (RM-031 KG3) no estado do projeto:
381
- [--json] pastas 0700, chave por revisao e extrator, idempotente; incremental (KG4)
382
- a partir do indice ancestral, ou completo com o motivo; --forcar extrai
383
- completo; --verificar confere contrato, bytes, determinismo e o incremental
384
- contra a completa; precisa de typescript e micromark
385
- grafo status [--json] Indices guardados, o do HEAD, os analisadores e o tamanho
386
- grafo vizinhos <no> [--profundidade N] Vizinhanca de arquivo ou simbolo, com extrator e evidencia de cada aresta
387
- [--sentido entrada|saida|ambos] [--tipo T,...] [--limite N] [--json]
388
- grafo chamadores <simbolo> Quem chama (arestas calls que chegam) [--profundidade N] [--limite N] [--json]
389
- grafo importadores <arquivo|simbolo> Quem importa (arestas imports que chegam) [--profundidade N] [--limite N] [--json]
390
- grafo caminho <de> <para> Menor caminho pelas arestas [--sentido saida|entrada|ambos] [--tipo T,...] [--json]
391
- [--json --teto-bytes N] Nas quatro consultas (KG5): JSON compacto de no maximo N bytes; as arestas mais
392
- longe do alvo saem ate caber, e o caminho que nao cabe recusa
393
- grafo amostra [--por-estrato N] Amostra de arestas para auditoria manual; --conferir ARQ confere a auditada
394
- grafo limpar [--tudo] [--json] Apaga os indices que nao sao do HEAD e as sobras com mais de uma hora
395
-
396
- ship <thread-id> --para <branch> Merge --no-ff serializado por lease e push PROVADO
397
- ship registrar-pr <thread-id>|--todas A entrega feita por PR vira ship_done: merge ship(<thread>) na base
398
- [--remoto R] [--json] remota e CI verde no head do PR; depois, ork master --aceitar-omissao
399
- [--repo <dono/nome> --pr <n>] PR mesclado em repositorio externo de ci.external_repositories
400
- [--dry-run] Ensaio: as mesmas conferencias, sem gravar ship_done, fase nem fabrica
401
- [--de <branch>] [--remoto origin] [--autorizar-push <quem>] [--sem-push] [--dry-run]
402
-
403
- board [--all] [--sem-remoto] Visao unica das threads (todos os perfis com --all); com a
404
- fabrica compartilhada, tambem as outras maquinas (I-51)
405
- board plan Escalonador: quem avanca agora, quem espera e por que
406
-
407
- orquestracao status [--all] [--json] Monitor PROATIVO de pausas e impedimentos: quem esta
408
- [--atencao N] [--so-paradas] parado, esperando o que, ha quanto tempo e o que
409
- [--sem-runtime] [--exigir-limpo] destrava (alias curto: ork monitor)
410
-
411
- worktree ensure <thread-id> Garante a worktree da thread (base resolvida pelo ork)
412
- worktree sync <thread-id> [--dry-run] Rebasa a branch da thread quando a base avancou
413
- worktree audit <thread-id> Confere a worktree no proprio git (sai != 0 se divergir)
414
- worktree release <thread-id> [--forcar] Remove a worktree e limpa o registro
415
-
416
- activation plan|status|enable|disable Escrita escopada com aceite, hash, leases e recibo
417
- lease list Leases, familias e as filas (merge e colisao de regiao)
418
- lease acquire <nome> --thread T --motivo M Toma um lease tipado (entra na fila se colidir)
419
- lease release <nome> [--thread T] [--forcar]
420
- conducao status <thread-id> [--json] Quem conduz a thread agora (canal, sessao, fase, desde)
421
- conducao assumir <thread-id> --por Q --motivo M
422
- Handoff: encerra a conducao atual pelo runtime e registra quem assumiu
423
-
424
- master propor <id> --score N --justificativa J --por <agente>
425
- master batch --aceitar <thread:assinatura,...> --por <humano>
426
- master migrar --dry-run --por Q Inspeciona correções sem alterar originais
427
- master digest <enviar|preview|responder> Digest semanal com recibos do host
428
- master <thread-id> --score 0-5 --justificativa "<texto>"
429
- [--classe C[,C]] [--resumo R] [--por Q] [--refazer]
430
- Fecha a thread: POSTMORTEM + MASTER log + score (so do terminal;
431
- de processo de host e recusado com master.prova-de-canal)
432
- master pedir <thread-id> [--formato telegram|terminal|json]
433
- Pede a nota ao dono com codigo curto; ele responde pelo Telegram
434
- (<codigo> <0 a 5> <porque>) e a nota vai ao ledger com o recibo (RM-048)
435
- master [--todas] [--json] As entregas, com o indice derivado do ledger
436
- master --aceitar-omissao [--json] Aceita as entregues por omissao, com registro
437
- master classes As classes de falha fixas do POSTMORTEM
438
- licoes [--json] O que volta no GOAL e no PLAN da proxima thread (POSTMORTEM e
439
- MASTER) e as propostas de policy por recorrencia (I-55)
440
-
441
- demo [--manter] [--dir D] A promessa em 30 s: uma afirmacao falsa reprovada e a corrigida aceita,
442
- offline, num repositorio temporario (I-56)
443
- ciclos Variantes de ciclo de "ork thread new --ciclo"
444
- modos --do-pedido "<texto>" [--json] Le a #TAG do pedido do builder (usado pelos adaptadores)
445
- modos migrar [--dry-run] [--por Q] Tira modo aposentado do orkastery.yaml e do setup.json
446
- [--json] (idempotente, com backup; nao toca em historico)
447
-
448
- prompt list Templates de prompt (embutidos e os do projeto)
449
- prompt lint [--template ID] Reprova template quebrado antes de ele virar despacho
450
- prompt render <thread-id> --fase F Mostra o prompt exato, com o sha256 que vai ao ledger
451
- [--pedido "<texto>"] [--template ID]
452
- prompt render --exemplo --fase F --modo M Renderiza sem thread nenhuma, para revisar o texto
453
-
454
- roadmap status [--json] Status report unico do roadmap: grupos com icones, #HITL no que espera
455
- voce e o fecho com o que precisa de voce e o que vem a seguir (RM-048)
456
- roadmap reservas [--json] [--remoto R] Quem esta com cada item do roadmap, lido da branch ork/roadmap-reservas
457
- [--soltar-orfas] marca a reserva de thread ja fechada (orfa) e, com a opcao, solta
458
- ou passa para outra thread aberta do mesmo item, com registro
459
- roadmap pegar <RM-NNN> [--thread T] Reserva o item para esta maquina (push atomico: o primeiro vence)
460
- [--nota N] [--por Q] [--maquina M] maquina = --maquina, ORK_MAQUINA ou o hostname
461
- [--forcar --motivo M] tomar a reserva de outra maquina fica registrado
462
- roadmap soltar <RM-NNN> [--forcar --motivo M] Devolve o item
463
- roadmap feat [--thread T] [--nota N] Reserva o proximo numero de FEAT na mesma branch (push atomico: duas
464
- maquinas nunca levam o mesmo numero; numero reservado nao volta)
465
- fabrica [--json] [--sem-remoto] O que cada maquina conduz, lido da branch ork/fabrica-estado (I-51)
466
- fabrica entrar [--maquina NOME] Esta maquina entra na fabrica compartilhada deste usuario, com
467
- este nome (~/.orkastery/maquina.json), e publica o primeiro retrato
468
- fabrica publicar [--forcar] [--json] Grava o retrato desta maquina na branch (push atomico, sem forca);
469
- depois de entrar, sai sozinho ao criar thread, despachar fase,
470
- entregar e fechar, e a cada batida do pulse
471
- fabrica sair Para de publicar daqui e tira o retrato desta maquina da branch
472
- network roadmap [--projeto P] [--json] Roadmap, reservas e threads de cada maquina de cada projeto, de qualquer diretorio:
473
- [--sem-remoto] fonte e hora de cada parte, lacuna tipada no que nao leu. P = caminho do clone,
474
- github:dono/repo, gitlab:grupo/repo ou nome conhecido; sem clone, le a forja (RM-054)
475
- docs verificar [--json] [--pr] Documentacao de produto e roadmap contra o codigo e o git; no PR (--pr),
476
- o merge de outra thread e o indice que divergem da main so avisam
477
- (padrao do dono: frontmatter, leitura, paridade; sai != 0 com erro)
478
- docs sincronizar [--escrever] Fatos do ledger e do git para o roadmap (merge, fase) e indices;
479
- sem --escrever so mostra; nunca muda status por passagem de tempo
480
- [--so RM-NNN[,RM-MMM]] [--todos] so esses itens (e os indices); na worktree de uma thread com item,
481
- o padrao e o item dela; --todos volta a todo item (RM-037)
482
- docs init Cria padroes, modelos, indices e o lint de Markdown no projeto
483
-
484
- mcp serve --project RAIZ --host HOST Servidor MCP stdio deste projeto (codex|claude-code)
485
- mcp install --project RAIZ --host HOST Prepara MCP; aceita --dry-run, --ship-transport, --child-permissions e --owner-permissions (Codex)
486
-
487
- adapter list Adaptadores de host (Camada 1) e o destino de cada um
488
- adapter show <host> Os 3 pitfalls de instalacao do host
489
- adapter install <host> [--dir D] Instala o adaptador (claude-code|codex|hermes|openclaw)
490
- [--dry-run] [--force] divergencia segura resolve sozinha; o resto pergunta
491
- [--aceitar-catalogo <arquivo>] sobrescreve a copia com o catalogo, arquivo a arquivo
492
- [--manter-copia <arquivo>] deixa a copia como esta, arquivo a arquivo
493
-
494
- eval [--skill S] [--canario C] Canarios de comportamento + corpus das skills finas
495
- [--so-canarios] [--so-skills] [--json] (sai != 0 em qualquer falha)
496
-
497
- audit packs [--estagio E] [--pack P] Os 7 packs, o estagio que os ativa e a postura
498
- audit run <pack> [--profile P] Monta o prompt do pack e despacha pelo runtime adapter
499
- [--since Nd] [--tudo] [--effort E] [--model M] [--agora "<quem>"] [--forcar] [--dry-run]
500
- audit list Rodadas de auditoria do projeto
501
- audit show <rodada> [--ledger] Contexto, achados e propostas de uma rodada
502
- audit prompt <pack> [--since Nd] O prompt exato do pack, com o sha256 que vai ao ledger
503
- audit lint Reprova template de auditoria quebrado (auditors/)
504
- audit ingest <rodada> --arquivo J Registra em lote os achados que o auditor escreveu
505
- audit finding add <rodada> --regra R Registra um achado com evidencia, claim e proposta
506
- --titulo T --arquivo caminho:linha --impacto I --fix F --estimativa E
507
- [--severidade critico|maior|menor] [--irreversivel "<passo>"] [--verificar "<comando>"]
508
- audit verify <rodada> Reexecuta as claims dos achados (auditor sem self-report)
509
- audit report <rodada> [--publicar] Relatorio com o bloco OBRIGATORIO de propostas
510
- audit divida [--pack P] [--todos] Board de divida: propostas abertas e recorrencia
511
- audit surface [<dir>] [--regra SPn] Varredura DETERMINISTICA da superficie de ataque de rede
512
- [--limite N] [--json] (SP8..SP12; sai != 0 quando ha achado)
513
- audit surface --registrar <rodada> Grava os achados da varredura no board da rodada
514
- audit finding estado <id> <estado> Carimba o achado (aberto|adiado|resolvido|descartado)
515
-
516
- thread new <nome> --from-finding <ID> Abre a thread a partir de um achado de auditoria
517
- [--modo M] [--worktree auto] [--dry-run] (evidencia, claim e proposta viajam junto)
518
-
519
- Regimes de memoria: files (fallback honesto) e orkmind (bloco B6, base propria por tenant
520
- declarada em memory.database_url_env pelo NOME da variavel de ambiente, sem fallback).
521
- Colecoes gravadas no OrkMind: decision, handoff, rule, learning, roadmap (source=agent,
522
- nunca mandatory: regra critica so nasce de humano autenticado).
523
-
524
- Retry tipado (bloco B3): reexecutar, corrigir-dirigido, sincronizar-worktree,
525
- escalar-esforco, esperar-janela, escalar-humano, sem-retry. Violacao de custo
526
- (cost.violation) NUNCA recebe retry automatico. O limite de escalacao do manifesto
527
- (retry.max_tentativas) pausa QUALQUER modo, inclusive #Auto.
528
-
529
- Monitor de orquestracao (ork orquestracao status / ork monitor): duas naturezas de parada.
530
- pausa-humana e a parada PREVISTA pelo modo (o bloco fechou e espera veredito, com o
531
- pausaSobre do bloco dizendo o que o humano decide); impedimento e a nao prevista
532
- (lease.busy, runtime.rate-limited, concurrency.limite e os demais gates tipados). Tudo e
533
- DERIVADO de thread.json, ledger.jsonl e das filas em disco: o monitor le, nunca grava.
534
- --exigir-limpo sai != 0 enquanto houver thread parada, para virar watchdog do orquestrador.
535
-
536
- Fases: GOAL PLAN GO CHECK SHIP MASTER. Modos: ${modos_1.ORDEM_DOS_MODOS.map((m) => modos_1.MODOS[m].tag).join(' ')}.
537
- Familias de lease: main-tree, worktree-write:<thread>, path:<glob>, board:<card>, service:<porta>.
538
- Ciclos: greenfield, merge-branch, goal-plan, gap, feature-xl-faseada.
539
- Fontes de medida do gate de tokens: runtime_reported, estimated, informada, unavailable.
540
- Hosts de Camada 1: claude-code, codex, hermes, openclaw. Canarios: fx-happy, fx-hallucination,
541
- fx-stale-base, fx-wiki-destroy, fx-schema-drift, fx-concurrency.
542
- Packs de auditoria: clean-code, reuse, architecture, data-model, ux, security-privacy, process.
543
- Superficie de ataque de rede (SP8..SP12, varredura deterministica): rota sem auth, endpoint de
544
- administracao exposto, rota sem rate limit, CORS permissivo, rota sem esquema de payload.
545
- Estagios do produto: nascente, crescendo, maduro (hardening gradual, visao secao 5.2).
546
- `;
239
+ /** RM-061 (F2a): o que a ajuda interpola; a redacao mora no catalogo (`msg().ajuda`, D10). */
240
+ function dadosDaAjuda(locale = (0, locale_1.localeAtivo)()) {
241
+ return { versao: VERSAO, modos: modos_1.ORDEM_DOS_MODOS.length, segredos: (0, locale_1.msg)(locale).onboarding.segredos,
242
+ tags: modos_1.ORDEM_DOS_MODOS.map((m) => modos_1.MODOS[m].tag).join(' ') };
243
+ }
244
+ /** A ajuda em pt-BR, o texto de sempre: o `docs verificar` a compara com a referencia do CLI. */
245
+ const AJUDA = (0, locale_1.msg)('pt-BR').ajuda.texto(dadosDaAjuda('pt-BR'));
246
+ /**
247
+ * RM-061 (F2a): a ajuda segue o locale como os comandos cobertos: `owner.language` do projeto de
248
+ * `--projeto` ou do diretorio, senao `LC_ALL`, `LC_MESSAGES` e `LANG`. Manifesto ilegivel nao derruba a ajuda.
249
+ */
250
+ function localeDaAjuda(projeto) {
251
+ // A ajuda sai antes de o projeto-alvo ser fixado: com `--projeto`, vale o manifesto dele (D14).
252
+ let raiz;
253
+ if (projeto !== undefined) {
254
+ try {
255
+ raiz = (0, projeto_alvo_1.resolverProjetoAlvo)({ opcao: projeto })?.raiz;
256
+ }
257
+ catch { /* nome ambiguo ou desconhecido: o cwd */ }
258
+ }
259
+ let ownerLanguage;
260
+ try {
261
+ ownerLanguage = (0, manifest_1.carregarManifesto)(raiz)?.manifesto.owner?.language;
262
+ }
263
+ catch { /* vale o ambiente */ }
264
+ return (0, locale_1.resolverLocale)(ownerLanguage).locale;
265
+ }
547
266
  function comandoThread(args) {
548
267
  if (args.posicionais[1] === 'close' || args.posicionais[1] === 'entrega') {
549
268
  const raiz = (0, manifest_1.exigirManifesto)().raiz, id = args.posicionais[2];
@@ -574,15 +293,23 @@ function comandoThread(args) {
574
293
  return 2;
575
294
  }
576
295
  }
577
- const brutoWorktreeAchado = args.opcoes.worktree;
578
- const criarWorktreeAchado = brutoWorktreeAchado === true || brutoWorktreeAchado === 'auto';
296
+ // P4 do ensaio da 0.5.0 (D2): a thread do achado segue a mesma regra de worktree do `thread new`.
297
+ let pedidoAchado;
298
+ try {
299
+ pedidoAchado = (0, thread_1.pedidoDeWorktree)({ worktree: args.opcoes.worktree, semWorktree: args.opcoes['sem-worktree'] }, carregado.manifesto.worktree.por_thread);
300
+ }
301
+ catch (e) {
302
+ console.error(e.message);
303
+ return 2;
304
+ }
579
305
  const r = (0, auditrun_1.abrirThreadDoAchado)(carregado, doAchado, {
580
306
  nome: args.posicionais[2],
581
307
  modo: modoAchado ?? undefined,
582
308
  slug: texto(args.opcoes.slug),
583
309
  assunto: texto(args.opcoes.assunto),
584
- criarWorktree: criarWorktreeAchado,
585
- worktree: criarWorktreeAchado ? null : (texto(brutoWorktreeAchado) ?? null),
310
+ criarWorktree: pedidoAchado.criar,
311
+ worktree: pedidoAchado.dir,
312
+ origemDaWorktree: pedidoAchado.origem,
586
313
  dryRun: args.opcoes['dry-run'] === true,
587
314
  });
588
315
  if (!r.ok) {
@@ -607,6 +334,13 @@ function comandoThread(args) {
607
334
  console.log((0, thread_1.resumoDaThread)(r.thread));
608
335
  console.log('');
609
336
  console.log(` slug em 3 partes: ${(0, phase_1.descreverSlug)(r.thread.slug)}`);
337
+ const linhaDaWorktreeDoAchado = (0, thread_1.linhaDaWorktree)(r.worktreePor, gravadaDoAchado);
338
+ if (linhaDaWorktreeDoAchado)
339
+ console.log(linhaDaWorktreeDoAchado);
340
+ const avisoDaWorktreeDoAchado = r.worktreeFalharia ? (0, thread_1.avisoDeWorktreeQueFalharia)(r.worktreeFalharia)
341
+ : (0, thread_1.avisoDaWorktree)(pedidoAchado.origem, { thread: r.thread, gravada: gravadaDoAchado, worktreePor: r.worktreePor }, carregado.manifesto);
342
+ if (avisoDaWorktreeDoAchado)
343
+ console.error(avisoDaWorktreeDoAchado);
610
344
  }
611
345
  if (r.motivo === 'claims.unverifiable') {
612
346
  console.log('');
@@ -635,8 +369,9 @@ function comandoThread(args) {
635
369
  return 0;
636
370
  }
637
371
  const nome = args.posicionais[2];
372
+ const mt = (0, locale_1.msg)().thread;
638
373
  if (!nome) {
639
- console.error('uso: ork thread new <nome> --modo <MODO>');
374
+ console.error(mt.usoNew);
640
375
  return 2;
641
376
  }
642
377
  const avisoRoadmap = avisoRoadmapSemAssociacao(nome, texto(args.opcoes.roadmap));
@@ -662,25 +397,52 @@ function comandoThread(args) {
662
397
  const doneWhen = (texto(args.opcoes.done) ?? '').split(';;').map((p) => p.trim()).filter(Boolean)
663
398
  .map((entrada) => {
664
399
  const corte = entrada.indexOf('::');
665
- if (corte < 0) {
666
- throw new Error(`done.sem-comando: "${entrada}" nao traz comando. `
667
- + 'Use --done "<criterio> :: <comando que o prova>"; criterio sem comando e prosa, nao criterio de pronto.');
668
- }
400
+ if (corte < 0)
401
+ throw new Error(mt.doneSemComando(entrada));
669
402
  const criterio = entrada.slice(0, corte).trim();
670
403
  const comando = entrada.slice(corte + 2).trim();
671
404
  if (!criterio || !comando)
672
- throw new Error(`done.incompleto: "${entrada}" precisa de criterio E comando`);
405
+ throw new Error(mt.doneIncompleto(entrada));
673
406
  return { criterio, comando };
674
407
  });
675
408
  const dryRun = args.opcoes['dry-run'] === true;
676
- const brutoWorktree = args.opcoes.worktree;
677
- // `--worktree auto` (ou `--worktree` sozinho) cria a worktree isolada da thread;
678
- // um caminho reusa um diretorio que ja existe.
679
- const criarWorktree = brutoWorktree === true || brutoWorktree === 'auto';
409
+ // RM-059 (T6.0): o pedido do builder, guardado para o render da fase quando falta `--pedido`.
410
+ if (args.opcoes.pedido === true) {
411
+ console.error(mt.usoPedido);
412
+ return 2;
413
+ }
414
+ const pedidoDoBuilder = texto(args.opcoes.pedido);
415
+ // A4 do CHECK: pedido invalido e erro de uso, e sai antes da reserva do roadmap, que vai ao remoto.
416
+ if (pedidoDoBuilder !== undefined) {
417
+ try {
418
+ (0, thread_1.prepararPedido)(pedidoDoBuilder);
419
+ }
420
+ catch (e) {
421
+ console.error(mt.usoComMotivo((0, locale_1.mensagemDoErro)(e)));
422
+ return 2;
423
+ }
424
+ }
425
+ // `--worktree auto` (ou `--worktree` sozinho) cria a worktree isolada da thread; um caminho reusa um
426
+ // diretorio que ja existe. P4 do ensaio da 0.5.0: sem flag, `worktree.por_thread: true` cria como o
427
+ // `--worktree auto`, e `--sem-worktree` cria sem ela. Uso invalido sai antes da reserva do roadmap.
428
+ let pedido;
429
+ try {
430
+ pedido = (0, thread_1.pedidoDeWorktree)({ worktree: args.opcoes.worktree, semWorktree: args.opcoes['sem-worktree'] }, carregado.manifesto.worktree.por_thread);
431
+ }
432
+ catch (e) {
433
+ console.error(e.message);
434
+ return 2;
435
+ }
680
436
  const brutoCiclo = texto(args.opcoes.ciclo) ?? texto(args.opcoes.variante);
681
437
  const variante = brutoCiclo ? (0, ciclos_1.parseVariante)(brutoCiclo) : null;
682
438
  if (brutoCiclo && !variante) {
683
- console.error(`variante de ciclo invalida: "${brutoCiclo}". Use uma de: ${Object.keys(ciclos_1.VARIANTES).join(', ')}`);
439
+ console.error(mt.varianteInvalida(brutoCiclo, Object.keys(ciclos_1.VARIANTES).join(', ')));
440
+ return 2;
441
+ }
442
+ // P4 do ensaio da 0.5.0 (D4, CHECK): a recusa do ciclo sai antes da reserva do roadmap, como os outros erros de
443
+ // uso; a do `novaThread` fica como defesa de quem o chama direto.
444
+ if (variante && (0, ciclos_1.definicaoDaVariante)(variante).exigeWorktree && pedido.origem === 'sem-worktree') {
445
+ console.error(mt.cicloExigeWorktree(variante));
684
446
  return 2;
685
447
  }
686
448
  const brutoFatias = texto(args.opcoes.fatias);
@@ -688,16 +450,18 @@ function comandoThread(args) {
688
450
  // atomico entre maquinas (o primeiro push vence); a thread e local. Se a criacao falhar,
689
451
  // a reserva e devolvida; se der certo, ela passa a apontar para a thread.
690
452
  const itemDoRoadmap = dryRun ? undefined : texto(args.opcoes.roadmap);
691
- const itemReservado = itemDoRoadmap ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap).item : undefined;
453
+ // RM-061 (F2a, D6): o que grava estado (reserva, thread, ledger, worktree, registro, publicacoes) roda em pt-BR.
454
+ const itemReservado = itemDoRoadmap ? (0, locale_1.comLocale)('pt-BR', () => (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap).item) : undefined;
692
455
  let criada;
693
456
  try {
694
- criada = (0, thread_1.novaThread)(carregado, {
457
+ criada = (0, locale_1.comLocale)('pt-BR', () => (0, thread_1.novaThread)(carregado, {
695
458
  nome,
696
459
  modo,
697
460
  slug: texto(args.opcoes.slug),
698
461
  assunto: texto(args.opcoes.assunto),
699
- worktree: criarWorktree ? null : (texto(brutoWorktree) ?? null),
700
- criarWorktree,
462
+ worktree: pedido.dir,
463
+ criarWorktree: pedido.criar,
464
+ origemDaWorktree: pedido.origem,
701
465
  dryRun,
702
466
  variante,
703
467
  branch: texto(args.opcoes.branch),
@@ -705,44 +469,56 @@ function comandoThread(args) {
705
469
  exigeRuntimeDiferente,
706
470
  doneWhen,
707
471
  roadmap: itemReservado,
708
- });
472
+ ...(pedidoDoBuilder !== undefined ? { pedido: pedidoDoBuilder } : {}),
473
+ }));
709
474
  }
710
475
  catch (e) {
711
476
  if (itemDoRoadmap) {
712
477
  try {
713
- (0, roadmap_reservas_1.soltarItem)(carregado.raiz, itemDoRoadmap);
478
+ (0, locale_1.comLocale)('pt-BR', () => (0, roadmap_reservas_1.soltarItem)(carregado.raiz, itemDoRoadmap));
714
479
  }
715
480
  catch { /* fica reservado; `ork roadmap soltar` resolve */ }
716
481
  }
717
482
  throw e;
718
483
  }
719
484
  const { thread, gravada } = criada;
720
- const reservaDoItem = itemDoRoadmap && gravada ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap, { thread: thread.id }) : null;
485
+ const reservaDoItem = itemDoRoadmap && gravada
486
+ ? (0, locale_1.comLocale)('pt-BR', () => (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap, { thread: thread.id })) : null;
721
487
  // I-51 (RM-047): com a fabrica compartilhada, as outras maquinas veem a thread nova.
722
488
  if (gravada)
723
- (0, fabrica_publicar_1.publicarEmSegundoPlano)(carregado.raiz);
489
+ (0, locale_1.comLocale)('pt-BR', () => (0, fabrica_publicar_1.publicarEmSegundoPlano)(carregado.raiz));
724
490
  // RM-052 (D7): quem abre thread aqui conhece este projeto; o aviso nunca derruba a criacao.
725
- const avisoDoRegistro = gravada ? (0, projeto_alvo_1.registrarProjetoEmSilencio)(carregado.raiz, 'thread new') : null;
491
+ const avisoDoRegistro = gravada ? (0, locale_1.comLocale)('pt-BR', () => (0, projeto_alvo_1.registrarProjetoEmSilencio)(carregado.raiz, 'thread new')) : null;
726
492
  if (avisoDoRegistro)
727
493
  console.error(avisoDoRegistro);
728
- console.log(gravada ? 'Thread criada.' : 'Simulacao (--dry-run), nada foi gravado.');
494
+ console.log(gravada ? mt.criada : mt.simulacao);
729
495
  if (reservaDoItem)
730
- console.log(` roadmap: ${reservaDoItem.item} reservado para esta maquina (${reservaDoItem.reserva?.maquina})`);
496
+ console.log(mt.roadmapReservado(reservaDoItem.item, reservaDoItem.reserva?.maquina));
731
497
  console.log((0, thread_1.resumoDaThread)(thread));
732
498
  console.log('');
733
- console.log(` slug em 3 partes: ${(0, phase_1.descreverSlug)(thread.slug)}`);
499
+ console.log(mt.slugEm3Partes((0, phase_1.descreverSlug)(thread.slug)));
500
+ const linhaDaWorktreeNova = (0, thread_1.linhaDaWorktree)(criada.worktreePor, gravada, variante);
501
+ if (linhaDaWorktreeNova)
502
+ console.log(linhaDaWorktreeNova);
503
+ const avisoDaWorktreeNova = criada.worktreeFalharia ? (0, thread_1.avisoDeWorktreeQueFalharia)(criada.worktreeFalharia)
504
+ : (0, thread_1.avisoDaWorktree)(pedido.origem, criada, carregado.manifesto);
734
505
  const avisoSemBase = (0, thread_1.avisoDeThreadSemBase)(thread, gravada);
506
+ if (thread.pedido) {
507
+ console.log(mt.pedidoGuardado(gravada, `.orkastery/threads/${thread.id}/${thread.pedido.arquivo}`, (0, util_1.shaCurto)(thread.pedido.sha256), thread.pedido.bytes));
508
+ }
735
509
  if (gravada) {
736
- console.log(` estado: .orkastery/threads/${thread.id}/thread.json`);
510
+ console.log(mt.estado(thread.id));
737
511
  // Bloco B6: a origem da thread e as policies do projeto vao para a memoria
738
512
  // semantica quando ela esta ligada. Em regime files nada muda nesta saida.
739
- relatarPublicacao((0, memoria_1.publicar)(carregado, thread.id));
513
+ relatarPublicacao((0, locale_1.comLocale)('pt-BR', () => (0, memoria_1.publicar)(carregado, thread.id)));
740
514
  // Thread sem base nao tem fase para rodar: o proximo passo e o do aviso.
741
515
  if (!avisoSemBase) {
742
516
  console.log('');
743
- console.log(`Proximo passo: ork phase run ${thread.id} ${thread.faseAtual} --prompt "<pedido>"`);
517
+ console.log(mt.proximoPasso(thread.id, thread.faseAtual));
744
518
  }
745
519
  }
520
+ if (avisoDaWorktreeNova)
521
+ console.error(avisoDaWorktreeNova);
746
522
  if (avisoSemBase)
747
523
  console.error(avisoSemBase);
748
524
  return 0;
@@ -764,8 +540,9 @@ function comandoThread(args) {
764
540
  if (sub === 'status') {
765
541
  const carregado = (0, manifest_1.exigirManifesto)();
766
542
  const id = args.posicionais[2];
543
+ const mt = (0, locale_1.msg)().thread;
767
544
  if (!id) {
768
- console.error('uso: ork thread status <thread-id>');
545
+ console.error(mt.usoStatus);
769
546
  return 2;
770
547
  }
771
548
  const thread = (0, thread_1.lerThread)(carregado.raiz, id);
@@ -779,20 +556,19 @@ function comandoThread(args) {
779
556
  console.log((0, thread_1.resumoDaThread)(thread, (0, conducao_1.conducaoDaThread)(carregado.raiz, thread.id)));
780
557
  console.log('');
781
558
  if (thread.sessoes.length === 0) {
782
- console.log(' nenhuma sessao despachada ainda');
559
+ console.log(mt.nenhumaSessao);
783
560
  }
784
561
  else {
785
- console.log(' sessoes despachadas (estado real conferido em `ork sessions`)');
562
+ console.log(mt.sessoesDespachadas);
786
563
  for (const s of thread.sessoes) {
787
- console.log(` ${s.slug.padEnd(24)} ${s.fase.padEnd(6)} ${s.sessionId.slice(0, 8)} ` +
788
- `verificada no runtime: ${s.verificada ? 'sim' : 'nao'} canal: ${(0, thread_1.canalDaSessao)(s)}`);
564
+ console.log(` ${s.slug.padEnd(24)} ${s.fase.padEnd(6)} ${s.sessionId.slice(0, 8)} ` + mt.sessao(s.verificada, (0, thread_1.canalDaSessao)(s)));
789
565
  }
790
566
  }
791
567
  console.log('');
792
- console.log(` pausas humanas do modo: ${(0, modos_1.pausasDoModo)(thread.modo)}`);
568
+ console.log(mt.pausasDoModo((0, modos_1.pausasDoModo)(thread.modo)));
793
569
  return 0;
794
570
  }
795
- console.error(`subcomando desconhecido: thread ${sub}`);
571
+ console.error((0, locale_1.msg)().cli.subcomandoDesconhecido('thread', sub));
796
572
  return 2;
797
573
  }
798
574
  /**
@@ -804,7 +580,7 @@ function comandoThread(args) {
804
580
  * Toda edicao vira evento `setup_configured` no ledger do projeto.
805
581
  */
806
582
  function comandoOnboarding(args) {
807
- const invalido = () => { throw new Error('onboarding.input.invalid: use ork onboarding [show|set <etapa>|reset [etapa]] --conteudo <JSON> [--por Q] [--json]'); };
583
+ const invalido = () => { throw new Error((0, locale_1.msg)().onboarding.usoInvalido); };
808
584
  if (Object.keys(args.opcoes).some(k => !['conteudo', 'por', 'json', 'reset'].includes(k)))
809
585
  invalido();
810
586
  if ('json' in args.opcoes && args.opcoes.json !== true)
@@ -833,6 +609,7 @@ function comandoOnboarding(args) {
833
609
  return 0;
834
610
  }
835
611
  let estado;
612
+ // RM-061 (F2a, D6): a recusa de uso sai no locale do comando; a gravacao roda em pt-BR (o dado nao muda).
836
613
  if (sub === 'set') {
837
614
  let conteudo;
838
615
  try {
@@ -841,10 +618,13 @@ function comandoOnboarding(args) {
841
618
  catch {
842
619
  return invalido();
843
620
  }
844
- estado = (0, onboarding_1.gravarEtapa)(raiz, etapa, conteudo, por);
621
+ (0, onboarding_1.validarPedidoDeEtapa)(etapa, conteudo, por);
622
+ estado = (0, locale_1.comLocale)('pt-BR', () => (0, onboarding_1.gravarEtapa)(raiz, etapa, conteudo, por));
623
+ }
624
+ else if (sub === 'reset') {
625
+ (0, onboarding_1.validarPedidoDeEtapa)(etapa, undefined, por);
626
+ estado = (0, locale_1.comLocale)('pt-BR', () => (0, onboarding_1.resetarOnboarding)(raiz, etapa, por));
845
627
  }
846
- else if (sub === 'reset')
847
- estado = (0, onboarding_1.resetarOnboarding)(raiz, etapa, por);
848
628
  else
849
629
  estado = (0, onboarding_1.lerOnboarding)(raiz);
850
630
  console.log(args.opcoes.json === true ? JSON.stringify(estado, null, 2) : (0, onboarding_1.textoDaPauta)(estado, (0, manifest_1.exigirManifesto)(raiz).manifesto.owner));
@@ -866,7 +646,7 @@ function aspasDeShell(valor) {
866
646
  function avisarChavesDePerfis(carregado) {
867
647
  for (const a of carregado.avisos)
868
648
  if (a.startsWith('runtime_profiles.'))
869
- console.error(`aviso: ${a}`);
649
+ console.error((0, locale_1.msg)().phase.aviso(a));
870
650
  }
871
651
  function comandoAccounts(args) {
872
652
  const carregado = (0, manifest_1.exigirManifesto)();
@@ -980,7 +760,20 @@ function comandoAccounts(args) {
980
760
  imprimir();
981
761
  return falhas > 0 ? 1 : 0;
982
762
  }
983
- console.error(`subcomando desconhecido: accounts ${sub} (use list, add, remove ou check)`);
763
+ if (sub === 'esgotamentos') {
764
+ // RM-040 (B7): so leitura do registro de contas e dos ledgers dos projetos registrados.
765
+ let relatorio;
766
+ try {
767
+ relatorio = (0, esgotamentos_1.relatorioDeEsgotamentos)({ desde: texto(args.opcoes.desde) ?? '7d' });
768
+ }
769
+ catch (e) {
770
+ console.error(`${e.message} (use --desde 7d, 24h, 30m ou uma data ISO)`);
771
+ return 2;
772
+ }
773
+ console.log(args.opcoes.json === true ? JSON.stringify(relatorio, null, 2) : (0, esgotamentos_1.textoDosEsgotamentos)(relatorio));
774
+ return 0;
775
+ }
776
+ console.error(`subcomando desconhecido: accounts ${sub} (use list, add, remove, check ou esgotamentos)`);
984
777
  return 2;
985
778
  }
986
779
  function comandoSetup(args) {
@@ -999,6 +792,91 @@ function comandoSetup(args) {
999
792
  console.log(' Leve para o repositorio por PR: dali em diante ele vale em todas as maquinas, e ork setup <modo> --bloco N passa a editar este arquivo.');
1000
793
  return 0;
1001
794
  }
795
+ if (modoBruto === 'worktree') {
796
+ // RM-047 (P3): worktree.dir fora da raiz so cria checkout com a confirmacao desta maquina, fora do git.
797
+ const acao = args.posicionais[2];
798
+ const json = args.opcoes.json === true;
799
+ if (acao === 'confirmar') {
800
+ const local = (0, worktree_local_1.confirmarWorktreeLocal)(raiz, carregado.manifesto, por, args.posicionais[3]);
801
+ if (json) {
802
+ console.log(JSON.stringify(local, null, 2));
803
+ return 0;
804
+ }
805
+ console.log(`Pasta das worktrees "${local.dir}" confirmada nesta maquina para ${local.raiz}.`);
806
+ console.log(` Gravada em .orkastery/private/${worktree_local_1.ARQUIVO_WORKTREE_LOCAL} (local, fora do git). Para desfazer: ork setup worktree revogar.`);
807
+ return 0;
808
+ }
809
+ if (acao === 'revogar') {
810
+ const havia = (0, worktree_local_1.revogarWorktreeLocal)(raiz);
811
+ if (json) {
812
+ console.log(JSON.stringify({ revogada: havia }, null, 2));
813
+ return 0;
814
+ }
815
+ console.log(havia ? 'Confirmacao local da pasta das worktrees revogada.' : 'Nao havia confirmacao local da pasta das worktrees.');
816
+ return 0;
817
+ }
818
+ if (acao !== undefined) {
819
+ console.error(`subcomando desconhecido: setup worktree ${acao} (use confirmar [<dir>] ou revogar)`);
820
+ return 2;
821
+ }
822
+ const pedida = (0, worktree_local_1.pastaDasWorktreesPedida)(raiz, carregado.manifesto);
823
+ const local = (0, worktree_local_1.lerWorktreeLocal)(raiz);
824
+ const recusa = (0, worktree_local_1.recusaDePastaDasWorktrees)(raiz, carregado.manifesto);
825
+ if (json) {
826
+ console.log(JSON.stringify({ manifesto: carregado.manifesto.worktree.dir, dir: pedida.dir, dentroDaRaiz: pedida.dentro,
827
+ confirmadaNestaMaquina: local.local?.dir ?? null, criacao: recusa === null ? 'permitida' : 'recusada' }, null, 2));
828
+ return 0;
829
+ }
830
+ console.log(`worktree.dir no orkastery.yaml: ${carregado.manifesto.worktree.dir} (${pedida.dir}, ${pedida.dentro ? 'dentro' : 'fora'} da raiz)`);
831
+ console.log(`confirmacao local desta maquina: ${local.local ? local.local.dir : `nenhuma (${local.motivo})`}`);
832
+ console.log(recusa === null ? 'criacao de worktree: permitida' : `criacao de worktree: recusada. ${worktree_local_1.COMANDO_CONFIRMAR_WORKTREE}`);
833
+ return 0;
834
+ }
835
+ if (modoBruto === 'sandbox') {
836
+ // RM-047 (P1): a postura de sandbox que afrouxa so vale com a confirmacao desta maquina, fora do git.
837
+ const acao = args.posicionais[2];
838
+ const json = args.opcoes.json === true;
839
+ if (acao === 'confirmar') {
840
+ const postura = args.posicionais[3];
841
+ if (!postura) {
842
+ console.error('uso: ork setup sandbox confirmar <read-only|workspace-write|danger-full-access> [--por Q]');
843
+ return 2;
844
+ }
845
+ const p = (0, postura_local_1.confirmarPosturaLocal)(raiz, postura, por);
846
+ if (json) {
847
+ console.log(JSON.stringify(p, null, 2));
848
+ return 0;
849
+ }
850
+ console.log(`Postura de sandbox "${p.sandbox}" confirmada nesta maquina para ${p.raiz}.`);
851
+ console.log(` Gravada em ${(0, postura_local_1.caminhoDaPosturaLocal)(raiz)} (local, fora do git). Para desfazer: ork setup sandbox revogar.`);
852
+ return 0;
853
+ }
854
+ if (acao === 'revogar') {
855
+ const havia = (0, postura_local_1.revogarPosturaLocal)(raiz);
856
+ if (json) {
857
+ console.log(JSON.stringify({ revogada: havia }, null, 2));
858
+ return 0;
859
+ }
860
+ console.log(havia ? 'Confirmacao local da postura de sandbox revogada.' : 'Nao havia confirmacao local de postura de sandbox.');
861
+ return 0;
862
+ }
863
+ if (acao !== undefined) {
864
+ console.error(`subcomando desconhecido: setup sandbox ${acao} (use confirmar <postura> ou revogar)`);
865
+ return 2;
866
+ }
867
+ const pedida = carregado.manifesto.runtime.sandbox;
868
+ const local = (0, postura_local_1.lerPosturaLocal)(raiz);
869
+ const recusa = (0, postura_local_1.recusaDePostura)(raiz, carregado.manifesto, 'codex');
870
+ if (json) {
871
+ console.log(JSON.stringify({ manifesto: pedida, afrouxa: (0, postura_local_1.posturaAfrouxada)(carregado.manifesto) !== null,
872
+ confirmadaNestaMaquina: local.postura?.sandbox ?? null, despachoCodex: recusa === null ? 'permitido' : 'recusado' }, null, 2));
873
+ return 0;
874
+ }
875
+ console.log(`runtime.sandbox no orkastery.yaml: ${pedida}`);
876
+ console.log(`confirmacao local desta maquina: ${local.postura ? local.postura.sandbox : `nenhuma (${local.motivo})`}`);
877
+ console.log(recusa === null ? 'despacho pelo codex: permitido' : `despacho pelo codex: recusado. ${(0, postura_local_1.comandoDeConfirmacao)(pedida)}`);
878
+ return 0;
879
+ }
1002
880
  if (!modoBruto) {
1003
881
  if (args.opcoes.reset === true) {
1004
882
  (0, setup_1.resetarSetup)(raiz, undefined, por);
@@ -1067,29 +945,34 @@ function comandoSetup(args) {
1067
945
  function comandoPhase(args) {
1068
946
  const sub = args.posicionais[1];
1069
947
  const carregado = (0, manifest_1.exigirManifesto)();
948
+ const m = (0, locale_1.msg)().phase;
1070
949
  if (sub === 'run') {
1071
950
  avisarChavesDePerfis(carregado);
1072
951
  const id = args.posicionais[2];
1073
952
  const faseBruta = args.posicionais[3];
1074
953
  const prompt = texto(args.opcoes.prompt);
1075
954
  if (!id || !faseBruta || !prompt) {
1076
- console.error('uso: ork phase run <thread-id> <FASE> --prompt "<texto>"');
955
+ console.error(m.usoRun);
1077
956
  return 2;
1078
957
  }
1079
958
  const thread = (0, thread_1.lerThread)(carregado.raiz, id);
1080
959
  const fase = (0, thread_1.exigirFase)(thread, faseBruta);
1081
960
  const conducao = conducaoDoCli(args);
1082
- const r = (0, phase_1.rodarFase)(carregado, id, {
961
+ // RM-061 (F2a, D6): o despacho grava prompt, ledger, lease e pedidos em pt-BR; so a impressao segue o locale.
962
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, phase_1.rodarFase)(carregado, id, {
1083
963
  fase,
1084
964
  prompt,
1085
965
  runtime: texto(args.opcoes.runtime),
1086
966
  model: texto(args.opcoes.model),
1087
967
  effort: texto(args.opcoes.effort),
968
+ perfil: texto(args.opcoes.perfil),
1088
969
  dryRun: args.opcoes['dry-run'] === true,
1089
970
  canal: conducao.canal,
1090
971
  ...(conducao.correlacao ? { correlacao: conducao.correlacao } : {}),
1091
972
  ...(conducao.esperarMs ? { esperarMs: conducao.esperarMs } : {}),
1092
- });
973
+ // A baseline que o despacho grava espera a fila pesada com aviso; a recusa sugere gravá-la antes, com mais espera.
974
+ filaPesada: filaPesadaDoCli(args, 'baseline', `ork verify ${id} --baseline --esperar 120`),
975
+ }));
1093
976
  // I-36 (T12, T14): pedido repetido e segundo pedido tem resposta propria, antes dos outros gates.
1094
977
  if (r.idempotente && r.conducao) {
1095
978
  console.log((0, conducao_1.textoDoPedidoRepetido)(id, r.conducao));
@@ -1105,14 +988,13 @@ function comandoPhase(args) {
1105
988
  console.log(JSON.stringify({ motivo: r.motivo, ...r.vaga }, null, 2));
1106
989
  return 3;
1107
990
  }
1108
- console.log(`Despacho recusado: concurrency.limite. O projeto ja tem ${r.vaga.ocupam.length} sessao(oes) viva(s) ` +
1109
- `em outras threads e o limite e ${r.vaga.limite} (concurrency.max_parallel_threads).`);
991
+ console.log(m.vagaRecusada(r.vaga.ocupam.length, r.vaga.limite));
1110
992
  for (const o of r.vaga.ocupam) {
1111
993
  console.log(` ${o.thread.padEnd(20)} ${(o.fase ?? '-').padEnd(6)} ` +
1112
- `${o.sessao ? `${o.runtime} ${o.sessao.slice(0, 8)}` : 'despacho em curso'}, desde ${(0, horario_1.localizarTextoRotulado)(o.desde)}`);
994
+ `${o.sessao ? `${o.runtime} ${o.sessao.slice(0, 8)}` : m.despachoEmCurso}, ${m.desde((0, horario_1.localizarTextoRotulado)(o.desde))}`);
1113
995
  }
1114
- console.log(` correcao: ${r.vaga.correcao}`);
1115
- console.log(r.dryRun ? ' ensaio (--dry-run): nada foi gravado.' : ` evento slot_refused no ledger de ${id}; nenhuma sessao aberta.`);
996
+ console.log(m.correcao(r.vaga.correcao));
997
+ console.log(r.dryRun ? m.vagaEnsaio : m.vagaLedger(id));
1116
998
  return 3;
1117
999
  }
1118
1000
  // RM-037 (S-4 do CHECK 3): a baseline que o despacho nao conseguiu gravar nao e gate reprovado.
@@ -1121,69 +1003,71 @@ function comandoPhase(args) {
1121
1003
  console.log(JSON.stringify({ motivo: r.motivo, detalhe: r.erro }, null, 2));
1122
1004
  return 1;
1123
1005
  }
1124
- console.error(`Despacho recusado: ${r.erro}`);
1125
- console.error(' nenhuma sessao aberta; o ledger nao ganhou gate_blocked');
1006
+ console.error(m.recusado(`${r.erro}`));
1007
+ console.error(m.baselinePendente);
1126
1008
  return 1;
1127
1009
  }
1010
+ // RM-061 (F2a): o resumo do despacho sai pelo catalogo; o rotulo tem largura 14, como antes.
1011
+ const campo = (rotulo, valor) => ` ${rotulo.padEnd(14)} : ${valor}`, rt = m.rotulos;
1128
1012
  if (r.dryRun && !r.bloqueado) {
1129
- console.log('Simulacao (--dry-run), nada foi despachado.');
1130
- console.log(` slug da sessao : ${r.slug}`);
1131
- console.log(` prompt : ${r.promptPath}`);
1132
- console.log(` sha256 : ${r.promptSha256}`);
1133
- console.log(` pausa ao fim : ${r.pausaAoFim ? 'sim' : 'nao'}`);
1134
- console.log(` runtime : ${r.runtime}`);
1135
- console.log(` modelo/esforco : ${r.model}/${r.effort}`);
1013
+ console.log(m.simulacao);
1014
+ console.log(campo(rt.slug, r.slug));
1015
+ console.log(campo(rt.prompt, `${r.promptPath}`));
1016
+ console.log(campo(rt.sha256, `${r.promptSha256}`));
1017
+ console.log(campo(rt.pausaAoFim, m.simNao(!!r.pausaAoFim)));
1018
+ console.log(campo(rt.runtime, `${r.runtime}`));
1019
+ console.log(campo(rt.modelo, `${r.model}/${r.effort}`));
1136
1020
  // O prompt inteiro nao cabe na tela: o argumento longo aparece mascarado.
1137
- console.log(` comando : ${r.comando.map((c) => (c.length > 80 ? '"<prompt>"' : c)).join(' ')}`);
1021
+ console.log(campo(rt.comando, r.comando.map((c) => (c.length > 80 ? '"<prompt>"' : c)).join(' ')));
1138
1022
  for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
1139
1023
  console.log(l);
1140
1024
  return 0;
1141
1025
  }
1142
1026
  if (r.bloqueado) {
1143
- console.error(`Despacho BLOQUEADO pelo gate tipado: ${r.motivo}`);
1027
+ console.error(m.bloqueado(`${r.motivo}`));
1144
1028
  for (const v of r.violacoes) {
1145
1029
  console.error(` [${v.severidade}] policy ${v.policy}: ${v.detalhe}`);
1146
- console.error(` correcao: ${v.correcao}`);
1030
+ console.error(m.violacaoCorrecao(v.correcao));
1147
1031
  }
1148
- console.error(` o prompt nao foi gravado em disco; evento gate_blocked no ledger de ${id}`);
1032
+ console.error(m.promptNaoGravado(id));
1149
1033
  return 1;
1150
1034
  }
1151
1035
  if (!r.sessionId) {
1152
1036
  // I-35: o erro vai ao ledger com o ISO; o dono le no fuso dele, com o fuso dito uma vez.
1153
- console.error(`Despacho falhou: ${r.erro ? (0, horario_1.localizarTextoRotulado)(r.erro) : r.erro}`);
1154
- console.error(` evento registrado no ledger de ${id}`);
1037
+ console.error(m.falhou(`${r.erro ? (0, horario_1.localizarTextoRotulado)(r.erro) : r.erro}`));
1038
+ console.error(m.falhouLedger(id));
1155
1039
  return 1;
1156
1040
  }
1157
- console.log(`Fase ${fase} despachada como background agent.`);
1041
+ console.log(m.despachada(fase));
1158
1042
  for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
1159
1043
  console.log(l);
1160
- console.log(` sessionId : ${r.sessionId}`);
1161
- console.log(` slug da sessao : ${r.slug} (${(0, phase_1.descreverSlug)(r.slug)})`);
1162
- console.log(` prompt : ${r.promptPath}`);
1163
- console.log(` sha256 : ${r.promptSha256}`);
1164
- console.log(` runtime : ${r.runtime}`);
1165
- console.log(` modelo/esforco : ${r.model}/${r.effort} (gravado no ledger, veja \`ork phase list\`)`);
1166
- console.log(` verificada no runtime: ${r.verificada ? 'sim' : 'NAO (confira `ork sessions`)'}`);
1167
- console.log(` pausa ao fim do bloco: ${r.pausaAoFim ? 'sim' : 'nao (decisao autonoma no ledger)'}`);
1044
+ console.log(campo(rt.sessionId, r.sessionId));
1045
+ console.log(campo(rt.slug, `${r.slug} (${(0, phase_1.descreverSlug)(r.slug)})`));
1046
+ console.log(campo(rt.prompt, `${r.promptPath}`));
1047
+ console.log(campo(rt.sha256, `${r.promptSha256}`));
1048
+ console.log(campo(rt.runtime, `${r.runtime}`));
1049
+ console.log(campo(rt.modelo, m.modeloGravado(`${r.model}`, `${r.effort}`)));
1050
+ console.log(m.verificada(!!r.verificada));
1051
+ console.log(m.pausaNoFim(!!r.pausaAoFim));
1168
1052
  console.log('');
1169
1053
  if (r.runtime === 'claude-bg') {
1170
- console.log(`Acompanhe: claude attach ${r.sessionId} | ork phase list ${id}`);
1054
+ console.log(m.acompanheClaude(r.sessionId, id));
1171
1055
  }
1172
1056
  else {
1173
- console.log(`Acompanhe: ork phase list ${id} (eventos do despacho no log da thread)`);
1057
+ console.log(m.acompanhe(id));
1174
1058
  }
1175
1059
  return r.verificada ? 0 : 1;
1176
1060
  }
1177
1061
  if (sub === 'list') {
1178
1062
  const id = args.posicionais[2];
1179
1063
  if (!id) {
1180
- console.error('uso: ork phase list <thread-id>');
1064
+ console.error(m.usoList);
1181
1065
  return 2;
1182
1066
  }
1183
1067
  console.log((0, phase_1.tabelaDoLedger)(carregado.raiz, id));
1184
1068
  return 0;
1185
1069
  }
1186
- console.error(`subcomando desconhecido: phase ${sub}`);
1070
+ console.error((0, locale_1.msg)().cli.subcomandoDesconhecido('phase', sub));
1187
1071
  return 2;
1188
1072
  }
1189
1073
  function comandoLedger(args) {
@@ -1281,6 +1165,15 @@ function comandoSessions(args) {
1281
1165
  console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, sessoes_1.textoDoInventario)(r));
1282
1166
  return !r.ok || (args.opcoes['exigir-limpo'] === true && r.semThread > 0) ? 1 : 0;
1283
1167
  }
1168
+ if (sub === 'limpar-fantasmas') {
1169
+ if (!carregado) {
1170
+ console.error('ork sessions limpar-fantasmas precisa de um projeto (orkastery.yaml)');
1171
+ return 2;
1172
+ }
1173
+ const r = (0, sessoes_2.limparFantasmas)(raiz, { dryRun: args.opcoes['dry-run'] === true });
1174
+ console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, sessoes_2.textoDaLimpeza)(r));
1175
+ return r.ok ? 0 : 1;
1176
+ }
1284
1177
  if (sub === 'hitl') {
1285
1178
  return comandoSessionsHitl(args, carregado ? raiz : '');
1286
1179
  }
@@ -1467,6 +1360,13 @@ function comandoClaims(args) {
1467
1360
  console.log('');
1468
1361
  console.log('AVISO: alegacao negativa sem comando de verificacao reprova em `ork verify`.');
1469
1362
  }
1363
+ // RM-008 (B8): a conferencia local da policy claim_sem_prova_local avisa e segue.
1364
+ const linhasDePolicy = (0, policies_1.linhasDeAviso)(claim.avisosDePolicy ?? []);
1365
+ if (linhasDePolicy.length) {
1366
+ console.log('');
1367
+ for (const l of linhasDePolicy)
1368
+ console.log(l);
1369
+ }
1470
1370
  // I-53 (RM-037, P6): o lint avisa aqui; a suite inteira e recusada no `ci prepare`.
1471
1371
  for (const a of claim.lint ?? []) {
1472
1372
  console.log('');
@@ -1474,6 +1374,40 @@ function comandoClaims(args) {
1474
1374
  }
1475
1375
  return 0;
1476
1376
  }
1377
+ if (sub === 'conferir') {
1378
+ // RM-059 (T0.10): so o que foi pedido, no sandbox do verify, sob a conducao da thread, sem recibo.
1379
+ const id = args.posicionais[2];
1380
+ const json = args.opcoes.json === true;
1381
+ const claims = texto(args.opcoes.claims);
1382
+ const tarefa = texto(args.opcoes.tarefa);
1383
+ const prazo = texto(args.opcoes.prazo);
1384
+ const semValor = ['claims', 'tarefa', 'prazo'].some((o) => args.opcoes[o] === true);
1385
+ if (!id || semValor || (claims === undefined) === (tarefa === undefined)) {
1386
+ console.error('uso: ork claims conferir <thread-id> --claims C1,C2 | --tarefa T1 [--prazo S] [--json]');
1387
+ return 2;
1388
+ }
1389
+ const conducao = conducaoDoCli(args);
1390
+ try {
1391
+ const r = (0, claims_conferir_1.conferirClaims)(carregado, id, {
1392
+ claims: claims !== undefined ? (0, claims_conferir_1.idsDeClaims)(claims) : undefined,
1393
+ tarefa,
1394
+ prazoMs: prazo !== undefined ? Number(prazo) * 1000 : undefined,
1395
+ canal: conducao.canal,
1396
+ correlacao: conducao.correlacao,
1397
+ });
1398
+ console.log(json ? JSON.stringify(r, null, 2) : (0, claims_conferir_1.textoDaConferencia)(r));
1399
+ return r.ok ? 0 : 1;
1400
+ }
1401
+ catch (e) {
1402
+ if (!(e instanceof claims_conferir_1.ErroDeConferencia))
1403
+ throw e;
1404
+ if (json)
1405
+ console.log(JSON.stringify({ formato: claims_conferir_1.FORMATO_DA_CONFERENCIA, thread: id, ok: false, erro: e.message }, null, 2));
1406
+ else
1407
+ console.error(e.message);
1408
+ return 2;
1409
+ }
1410
+ }
1477
1411
  if (sub === 'verificar') {
1478
1412
  const id = args.posicionais[2];
1479
1413
  const claimId = args.posicionais[3];
@@ -1533,25 +1467,36 @@ function comandoClaims(args) {
1533
1467
  function comandoVerify(args) {
1534
1468
  const carregado = (0, manifest_1.exigirManifesto)();
1535
1469
  const id = args.posicionais[1];
1470
+ const m = (0, locale_1.msg)().verify;
1536
1471
  if (!id) {
1537
- console.error('uso: ork verify <thread-id> [--baseline] [--so-claims] [--canal C] [--esperar [min]]');
1472
+ console.error(m.uso);
1538
1473
  return 2;
1539
1474
  }
1540
- const conducao = conducaoDoCli(args);
1475
+ // RM-058 N2 (D10): enquanto a fila de recursos pesados nao da a vez, o CLI diz uma vez por quem espera.
1476
+ const aoEsperar = (ocupantes) => console.error(m.filaPesadaEsperando(args.opcoes.baseline === true ? 'baseline' : 'verify', ocupantes.map((o) => m.filaPesadaOcupante(o.operacao, o.thread, (0, horario_1.formatarDataHora)(o.desde))).join('; ')));
1477
+ const doCli = conducaoDoCli(args);
1478
+ // O `ork verify` do CLI espera a fila em primeiro plano ate `--esperar` ou 60 min; a recusa sugere o dobro.
1479
+ const conducao = { ...doCli, filaPesada: { aoEsperar, esperarMs: doCli.esperarMs ?? verify_1.ESPERA_DA_FILA_PESADA_MS,
1480
+ comandoDeEsperar: `ork verify ${id}${args.opcoes.baseline === true ? ' --baseline' : ''} --esperar 120` } };
1541
1481
  if (args.opcoes.baseline === true) {
1542
- const b = (0, verify_1.gravarBaseline)(carregado, id, undefined, conducao);
1543
- console.log(`Baseline gravada para a thread ${id}.`);
1544
- console.log(` commit ${b.commit}`);
1482
+ // RM-061 (F2b, G2): a baseline e o ledger sao gravados em pt-BR; so a impressao segue o locale.
1483
+ const b = (0, locale_1.comLocale)('pt-BR', () => (0, verify_1.gravarBaseline)(carregado, id, undefined, conducao));
1484
+ console.log(m.baselineGravada(id));
1485
+ console.log(m.baselineCommit(b.commit));
1545
1486
  for (const c of b.comandos) {
1546
- console.log(` ${c.nome.padEnd(10)} ${c.ok ? 'passava' : `ja falhava (codigo ${c.code})`} ${c.comando}`);
1487
+ console.log(m.baselineComando(c.nome, c.ok, c.code, c.comando));
1488
+ }
1489
+ if (b.comandos.some((c) => !c.ok)) {
1490
+ // Ensaio de 03/10 (R7): "ja falhava" sem dizer onde ver a saida do comando.
1491
+ console.log(m.baselineSaida((0, thread_1.caminhoThread)(carregado.raiz, id), id));
1547
1492
  }
1548
1493
  if (b.comandos.length === 0) {
1549
1494
  // Fatia 2 do ensaio da 0.5.0 (R5): a baseline foi gravada; o que falta e comando, nao baseline.
1550
- console.log(' (nenhum comando em verify: no manifesto: a baseline guarda so o commit, e o verify nao tem como separar regressao de divida)');
1495
+ console.log(m.baselineSemComandos);
1551
1496
  }
1552
1497
  return 0;
1553
1498
  }
1554
- const r = (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
1499
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao }));
1555
1500
  console.log((0, verify_1.textoDoVerify)(r));
1556
1501
  return r.ok ? 0 : 1;
1557
1502
  }
@@ -1559,10 +1504,45 @@ function comandoVerify(args) {
1559
1504
  * `ork conducao status|assumir` (I-36, T15): quem conduz a thread agora, e o handoff explicito. O
1560
1505
  * status tambem libera, com prova no ledger, a conducao que ficou sem dono (T16).
1561
1506
  */
1507
+ /**
1508
+ * RM-059 (F6, T6.4; DD5 do plano dos mods): `ork conducao sentinela status|bater|desligar`. A presenca da
1509
+ * Sentinela do Condutor nesta maquina e o passo do condutor em cada thread aberta; o condutor externo le o
1510
+ * `status --json` para ceder o despacho enquanto a presenca vale. Nada aqui despacha.
1511
+ */
1512
+ function comandoSentinela(carregado, args) {
1513
+ const acao = args.posicionais[2] ?? 'status';
1514
+ const json = args.opcoes.json === true;
1515
+ if (acao === 'status') {
1516
+ const s = (0, conducao_sentinela_1.statusDaSentinela)(carregado);
1517
+ console.log(json ? JSON.stringify(s, null, 2) : (0, conducao_sentinela_1.textoDoStatusDaSentinela)(s));
1518
+ return 0;
1519
+ }
1520
+ if (acao !== 'bater' && acao !== 'desligar')
1521
+ throw new Error('uso: ork conducao sentinela status|bater|desligar [--sessao <id>] [--json]');
1522
+ const sessao = texto(args.opcoes.sessao);
1523
+ if (!sessao)
1524
+ throw new Error(`uso: ork conducao sentinela ${acao} --sessao <id> [--json]`);
1525
+ if (acao === 'bater') {
1526
+ const r = (0, conducao_sentinela_1.baterSentinela)(carregado.raiz, { sessao });
1527
+ const curta = r.presenca.sessao.slice(0, 8);
1528
+ console.log(json ? JSON.stringify(r, null, 2) : r.ok
1529
+ ? `Sentinela ${r.ligou ? 'ligada' : 'renovada'} na maquina ${r.presenca.maquina} pela sessao ${curta}; vale 3 min sem batida.`
1530
+ : `Outra sessao (${curta}) conduz pela Sentinela na maquina ${r.presenca.maquina}; esta fica so olhando.`);
1531
+ return r.ok ? 0 : 3;
1532
+ }
1533
+ const motivo = texto(args.opcoes.motivo);
1534
+ const r = (0, conducao_sentinela_1.desligarSentinela)(carregado.raiz, { sessao, ...(motivo ? { motivo } : {}) });
1535
+ console.log(json ? JSON.stringify(r, null, 2) : r.desligada
1536
+ ? 'Sentinela desligada nesta maquina; o condutor externo volta a conduzir.'
1537
+ : 'Nada a desligar: a presenca nesta maquina nao e desta sessao.');
1538
+ return 0;
1539
+ }
1562
1540
  function comandoConducao(args) {
1563
1541
  const carregado = (0, manifest_1.exigirManifesto)();
1564
1542
  const sub = args.posicionais[1];
1565
1543
  const id = args.posicionais[2];
1544
+ if (sub === 'sentinela')
1545
+ return comandoSentinela(carregado, args);
1566
1546
  if (sub === 'status') {
1567
1547
  if (!id)
1568
1548
  throw new Error('uso: ork conducao status <thread-id> [--json]');
@@ -1580,7 +1560,7 @@ function comandoConducao(args) {
1580
1560
  console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : `${r.ok ? 'Conducao assumida.' : 'Handoff recusado.'} ${r.detalhe}`);
1581
1561
  return r.ok ? 0 : 3;
1582
1562
  }
1583
- throw new Error('uso: ork conducao status|assumir <thread-id>');
1563
+ throw new Error('uso: ork conducao status|assumir <thread-id> | ork conducao sentinela status|bater|desligar');
1584
1564
  }
1585
1565
  /** RM-048 (D1): o gate aberto no contrato curto, com o codigo estavel e o "desde" do ledger. */
1586
1566
  function textoDoGateCurto(raiz, pedido, canal) {
@@ -1741,7 +1721,7 @@ function comandoRetry(args) {
1741
1721
  if (sub === 'plan' || sub === 'run') {
1742
1722
  const id = args.posicionais[2];
1743
1723
  if (!id) {
1744
- console.error(`uso: ork retry ${sub} <thread-id> [--motivo M] [--fase F]`);
1724
+ console.error((0, locale_1.msg)().retry.usoPlanRun(sub));
1745
1725
  return 2;
1746
1726
  }
1747
1727
  const thread = (0, thread_1.lerThread)(carregado.raiz, id);
@@ -1752,7 +1732,8 @@ function comandoRetry(args) {
1752
1732
  autorizadoPor: texto(args.opcoes.por) ?? texto(args.opcoes.quem),
1753
1733
  };
1754
1734
  if (sub === 'plan') {
1755
- const plano = (0, retry_1.planejarRetry)(carregado, id, opcoes);
1735
+ // RM-061 (F2b, G2): a razao nasce em pt-BR, como o --json e o ledger a guardam; so a impressao segue o locale.
1736
+ const plano = (0, locale_1.comLocale)('pt-BR', () => (0, retry_1.planejarRetry)(carregado, id, opcoes));
1756
1737
  if (args.opcoes.json === true) {
1757
1738
  console.log(JSON.stringify(plano, null, 2));
1758
1739
  return 0;
@@ -1764,11 +1745,11 @@ function comandoRetry(args) {
1764
1745
  const conducao = conducaoDoCli(args);
1765
1746
  if (conducao.esperarMs && args.opcoes['dry-run'] !== true)
1766
1747
  (0, conducao_1.esperarConducaoLivre)(carregado.raiz, id, conducao.esperarMs);
1767
- const r = (0, retry_1.executarRetry)(carregado, id, {
1748
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, retry_1.executarRetry)(carregado, id, {
1768
1749
  ...opcoes,
1769
1750
  dryRun: args.opcoes['dry-run'] === true,
1770
1751
  reverify: args.opcoes.reverify === true,
1771
- });
1752
+ }));
1772
1753
  if (args.opcoes.json === true) {
1773
1754
  console.log(JSON.stringify(r, null, 2));
1774
1755
  }
@@ -1848,7 +1829,7 @@ function comandoFix(args) {
1848
1829
  console.error('uso: ork fix open <thread-id> [--so-claims] [--reverify]');
1849
1830
  return 2;
1850
1831
  }
1851
- const conducao = conducaoDoCli(args);
1832
+ const conducao = { ...conducaoDoCli(args), filaPesada: filaPesadaDoCli(args, 'verify', `ork fix open ${id} --esperar 30`) };
1852
1833
  const rodada = (0, fix_1.abrirRodada)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
1853
1834
  const reverify = args.opcoes.reverify === true && rodada.correcoes.length > 0
1854
1835
  ? (0, fix_1.reverificar)(carregado, id, { rodada: rodada.rodada, conducao })
@@ -1903,7 +1884,7 @@ function comandoFix(args) {
1903
1884
  }
1904
1885
  const rodadaBruta = texto(args.opcoes.rodada);
1905
1886
  const r = (0, fix_1.reverificar)(carregado, id, {
1906
- conducao: conducaoDoCli(args),
1887
+ conducao: { ...conducaoDoCli(args), filaPesada: filaPesadaDoCli(args, 'verify', `ork fix reverify ${id} --esperar 30`) },
1907
1888
  rodada: rodadaBruta ? Number(rodadaBruta) : undefined,
1908
1889
  parcial: args.opcoes.parcial === true,
1909
1890
  });
@@ -1956,8 +1937,76 @@ function comandoHandoff(args) {
1956
1937
  console.error(`subcomando desconhecido: handoff ${sub}`);
1957
1938
  return 2;
1958
1939
  }
1940
+ /**
1941
+ * RM-059 (F7, T7.1; DD4 do plano dos mods): `ork ship publicar <thread>`. So publica no modo que ja autoriza push
1942
+ * (#Auto e #Maestro); a autorizacao humana na linha nao vale aqui (D1 da ork-rm059pista), e o push do modo que pausa
1943
+ * e do dono, no terminal dele.
1944
+ */
1945
+ function comandoShipPublicar(carregado, args) {
1946
+ const m = (0, locale_1.msg)().ship;
1947
+ const p = m.publicar;
1948
+ if (args.opcoes['autorizar-push'] !== undefined) {
1949
+ console.error(p.semAutorizarPush);
1950
+ return 2;
1951
+ }
1952
+ const alvo = args.posicionais[2];
1953
+ if (!alvo || args.posicionais.length > 3) {
1954
+ console.error(p.uso);
1955
+ return 2;
1956
+ }
1957
+ if (args.opcoes.remoto !== undefined)
1958
+ (0, branch_de_estado_1.exigirRemoto)(args.opcoes.remoto, 'ship');
1959
+ // Como o ship: o que o publicar grava (ledger, detalhe e correcao do --json) nasce em pt-BR.
1960
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, ship_publicar_1.publicarEntrega)(carregado, alvo, {
1961
+ remoto: texto(args.opcoes.remoto), dryRun: args.opcoes['dry-run'] === true,
1962
+ }));
1963
+ if (args.opcoes.json === true) {
1964
+ console.log(JSON.stringify(r, null, 2));
1965
+ return r.acao === 'recusada' ? 1 : 0;
1966
+ }
1967
+ for (const linha of (0, ship_publicar_1.linhasDaPublicacao)(r))
1968
+ console.log(linha);
1969
+ return r.acao === 'recusada' ? 1 : 0;
1970
+ }
1971
+ /** RM-059 (F7, T7.1): `ork ship pista [<thread>]`, as etapas da entrega e o proximo passo que o nucleo declara. */
1972
+ function comandoShipPista(carregado, args) {
1973
+ const p = (0, locale_1.msg)().ship.publicar;
1974
+ if (args.posicionais.length > 3) {
1975
+ console.error(p.usoPista);
1976
+ return 2;
1977
+ }
1978
+ if (args.opcoes.remoto !== undefined)
1979
+ (0, branch_de_estado_1.exigirRemoto)(args.opcoes.remoto, 'ship');
1980
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, ship_publicar_1.pistaDeEntrega)(carregado, { remoto: texto(args.opcoes.remoto), thread: args.posicionais[2] }));
1981
+ if (args.opcoes.json === true) {
1982
+ console.log(JSON.stringify(r, null, 2));
1983
+ return 0;
1984
+ }
1985
+ console.log(p.cabecalhoPista((0, horario_1.formatarDataHora)(r.lidoEm), r.remoto, r.base));
1986
+ if (!r.remotoLido)
1987
+ console.log(p.remotoNaoRespondeu(r.remoto));
1988
+ if (!r.prsLidos)
1989
+ console.log(p.prsNaoResponderam((0, locale_1.remontar)(r.prsNaoLidos ?? '-')));
1990
+ if (!r.pistas.length)
1991
+ console.log(p.semPistas);
1992
+ for (const pista of r.pistas) {
1993
+ console.log('');
1994
+ console.log(p.linhaDaThread(pista.thread, pista.tag, pista.branch));
1995
+ console.log(` ${pista.etapas.map((e) => `${p.nomeDaEtapa(e.id)} ${p.marcaDaEtapa(e.estado)}`).join(' | ')}`);
1996
+ for (const e of pista.etapas.filter((x) => x.estado !== 'feita' && x.estado !== 'nao-se-aplica')) {
1997
+ console.log(` ${p.nomeDaEtapa(e.id)}: ${(0, locale_1.remontar)(e.texto)}`);
1998
+ }
1999
+ console.log(p.linhaDoProximo((0, locale_1.remontar)(pista.proximo.texto), pista.proximo.comando));
2000
+ }
2001
+ return 0;
2002
+ }
1959
2003
  function comandoShip(args) {
1960
2004
  const carregado = (0, manifest_1.exigirManifesto)();
2005
+ const m = (0, locale_1.msg)().ship;
2006
+ if (args.posicionais[1] === 'publicar')
2007
+ return comandoShipPublicar(carregado, args);
2008
+ if (args.posicionais[1] === 'pista')
2009
+ return comandoShipPista(carregado, args);
1961
2010
  if (args.posicionais[1] === 'registrar-pr') {
1962
2011
  // I-57 (RM-008): a entrega feita por PR vira ship_done, provada no remoto e no CI.
1963
2012
  const alvo = args.posicionais[2];
@@ -1965,43 +2014,68 @@ function comandoShip(args) {
1965
2014
  // RM-037 (defeito 5): PR mesclado em repositorio externo declarado em ci.external_repositories.
1966
2015
  const repo = texto(args.opcoes.repo), numeroDoPr = texto(args.opcoes.pr);
1967
2016
  if ((!alvo && args.opcoes.todas !== true) || (!!repo !== !!numeroDoPr) || (repo && !alvo)) {
1968
- console.error('uso: ork ship registrar-pr <thread-id> [--repo <dono/nome> --pr <n>] | --todas [--remoto R] [--json] [--dry-run]');
2017
+ console.error(m.usoRegistrarPr);
1969
2018
  return 2;
1970
2019
  }
2020
+ // RM-047: o `--remoto` da linha de comando so chega ao git como nome de remoto (ship.remoto-invalido).
2021
+ if (args.opcoes.remoto !== undefined)
2022
+ (0, branch_de_estado_1.exigirRemoto)(args.opcoes.remoto, 'ship');
1971
2023
  // RM-037 (fatia 3, defeito 6): o `--dry-run` era ignorado, e o ensaio gravava o ship_done de verdade.
1972
2024
  const dryRun = args.opcoes['dry-run'] === true;
1973
- const r = alvo && repo ? [(0, entrega_pr_1.registrarEntregaExternaPorPr)(carregado, alvo, { repositorio: repo, pr: Number(numeroDoPr), dryRun })]
1974
- : alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto, dryRun })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto, dryRun });
2025
+ // RM-061 (F2b, G2): o ship_done e o motivo nascem em pt-BR; so a impressao segue o locale.
2026
+ const r = (0, locale_1.comLocale)('pt-BR', () => alvo && repo
2027
+ ? [(0, entrega_pr_1.registrarEntregaExternaPorPr)(carregado, alvo, { repositorio: repo, pr: Number(numeroDoPr), dryRun })]
2028
+ : alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto, dryRun })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto, dryRun }));
1975
2029
  if (args.opcoes.json === true) {
1976
2030
  console.log(JSON.stringify(r, null, 2));
1977
2031
  return r.some((x) => x.acao === 'recusada') ? 1 : 0;
1978
2032
  }
1979
2033
  if (dryRun)
1980
- console.log('Ensaio (--dry-run): nada foi gravado.');
2034
+ console.log(m.ensaio);
1981
2035
  if (r.length === 0)
1982
- console.log('Nenhuma thread aberta com merge ship(<thread>) na base.');
2036
+ console.log(m.nenhumaComMerge);
1983
2037
  for (const x of r)
1984
- console.log(` ${x.thread.padEnd(20)} ${x.acao.padEnd(13)} ${x.motivo}`);
2038
+ console.log(m.linhaDoRegistro(x.thread, m.acoes[x.acao] ?? x.acao, (0, locale_1.remontar)(x.motivo)));
2039
+ // RM-044 (A3): a pagina que o push da base vai reprovar em docs.paridade.merge, com o comando que corrige.
2040
+ // So aviso: nada e gravado e o codigo de saida nao muda.
2041
+ const pendentes = r.flatMap((x) => x.docsPendentes.map((d) => ({ thread: x.thread, ...d })));
2042
+ if (pendentes.length) {
2043
+ console.log('');
2044
+ console.log(m.avisoDeDocs(pendentes.length));
2045
+ for (const d of pendentes) {
2046
+ console.log(m.docPendente(d.id, d.arquivo, d.merge.slice(0, 7), d.thread, d.codigo));
2047
+ console.log(m.docPendenteComando(d.comando));
2048
+ }
2049
+ }
1985
2050
  const registradas = r.filter((x) => x.acao === 'registrou').length;
1986
2051
  const registrariam = r.filter((x) => x.acao === 'registraria').length;
1987
2052
  if (registradas) {
1988
2053
  console.log('');
1989
- console.log(`${registradas} entrega(s) registrada(s). Fechar pelo MASTER: ork master --aceitar-omissao (a nota humana sobrescreve).`);
2054
+ // RM-008 (03/10): o texto ensina a forma COM a thread. A forma sem thread fechava tambem as
2055
+ // entregues de outras frentes paralelas, e era ela que os condutores copiavam daqui.
2056
+ console.log(m.registradas(registradas));
2057
+ for (const x of r.filter((y) => y.acao === 'registrou'))
2058
+ console.log(` ork master ${x.thread} --aceitar-omissao`);
1990
2059
  }
1991
2060
  if (registrariam) {
1992
2061
  console.log('');
1993
- console.log(`${registrariam} entrega(s) seria(m) registrada(s). Para gravar, rode o mesmo comando sem --dry-run.`);
2062
+ console.log(m.registrariam(registrariam));
1994
2063
  }
1995
2064
  return r.some((x) => x.acao === 'recusada') ? 1 : 0;
1996
2065
  }
1997
2066
  const id = args.posicionais[1];
1998
2067
  const para = texto(args.opcoes.para) ?? texto(args.opcoes.to);
1999
2068
  if (!id || !para) {
2000
- console.error('uso: ork ship <thread-id> --para <branch> [--de <branch>] [--dry-run]');
2069
+ console.error(m.uso);
2001
2070
  return 2;
2002
2071
  }
2072
+ // RM-047: como no registrar-pr, o `--remoto` so chega ao git como nome de remoto (ship.remoto-invalido),
2073
+ // e `--remoto` sem valor nao vira `origin` em silencio.
2074
+ if (args.opcoes.remoto !== undefined)
2075
+ (0, branch_de_estado_1.exigirRemoto)(args.opcoes.remoto, 'ship');
2003
2076
  const autorizar = args.opcoes['autorizar-push'];
2004
- const r = (0, ship_1.ship)(carregado, id, {
2077
+ // RM-061 (F2b, G2): o que o ship grava (ledger, verificacao, mensagem do merge) nasce em pt-BR.
2078
+ const r = (0, locale_1.comLocale)('pt-BR', () => (0, ship_1.ship)(carregado, id, {
2005
2079
  para,
2006
2080
  de: texto(args.opcoes.de),
2007
2081
  remoto: texto(args.opcoes.remoto),
@@ -2009,10 +2083,28 @@ function comandoShip(args) {
2009
2083
  dryRun: args.opcoes['dry-run'] === true,
2010
2084
  autorizarPush: typeof autorizar === 'string' ? autorizar : undefined,
2011
2085
  semPush: args.opcoes['sem-push'] === true,
2012
- });
2086
+ // RM-058 N2 (A1 da rodada 2 do CHECK): o `--esperar` chega à fila pesada da verificação do ship, com aviso.
2087
+ ...((f) => ({ esperarFilaPesadaMs: f.esperarMs, avisoDaFilaPesada: { aoEsperar: f.aoEsperar, comandoDeEsperar: f.comandoDeEsperar } }))(filaPesadaDoCli(args, 'verify', `ork ship ${id} --para ${para} --esperar 30`)),
2088
+ }));
2013
2089
  console.log((0, ship_1.textoDoShip)(r));
2014
2090
  return r.ok ? 0 : 1;
2015
2091
  }
2092
+ /**
2093
+ * RM-043 (sobra achada na RM-044): opcoes que o `portfolio show` herdou do `objective`,
2094
+ * aposentado na I-43. A ajuda as listava e o `parseArgs` as aceitava, mas o `show` nunca as
2095
+ * leu: eram ignoradas em silencio. A recusa e tipada e diz para onde ir, como a do
2096
+ * `objective.aposentado`.
2097
+ */
2098
+ const SOBRAS_DO_OBJECTIVE = ['constraints', 'outcomes', 'threads', 'execution-runtime', 'validation-runtimes'];
2099
+ function recusarSobraDoObjective(opcao) {
2100
+ console.error(`portfolio.opcao-aposentada: --${opcao} era do Objective Envelope, aposentado na I-43, e o\n` +
2101
+ ' portfolio show nunca a leu. As duas vigas do envelope viraram propriedade de thread comum:\n' +
2102
+ ' ork thread new "<nome>" --modo <MODO> --exige-runtime-diferente\n' +
2103
+ ' o CHECK precisa de runtime que o GO nao usou\n' +
2104
+ ' ork thread new "<nome>" --modo <MODO> --done "<criterio> :: <comando>"\n' +
2105
+ ' criterio de pronto EXECUTAVEL, que vira claim e roda no ork verify');
2106
+ return 2;
2107
+ }
2016
2108
  function comandoPortfolio(args) {
2017
2109
  const root = (0, manifest_1.exigirManifesto)().raiz;
2018
2110
  const sub = args.posicionais[1] ?? 'list';
@@ -2040,6 +2132,9 @@ function comandoPortfolio(args) {
2040
2132
  return 0;
2041
2133
  }
2042
2134
  if (sub === 'show') {
2135
+ const sobra = SOBRAS_DO_OBJECTIVE.find((opcao) => args.opcoes[opcao] !== undefined);
2136
+ if (sobra)
2137
+ return recusarSobraDoObjective(sobra);
2043
2138
  const id = args.posicionais[2];
2044
2139
  if (!id) {
2045
2140
  console.error('uso: ork portfolio show <id>');
@@ -2194,10 +2289,15 @@ function comandoCi(args) {
2194
2289
  if (sub === 'status') {
2195
2290
  const sha = texto(args.opcoes.sha) ?? args.posicionais[2] ?? (0, util_1.exec)('git', ['rev-parse', 'HEAD'], carregado.raiz).stdout.trim();
2196
2291
  if (!/^[0-9a-f]{40}$/.test(sha)) {
2197
- console.error('uso: ork ci status --sha <commit> [--remoto origin]');
2292
+ // Ensaio de 03/10 (R4): `--sha HEAD` ou um sha curto respondiam so a linha de uso, sem dizer por que.
2293
+ console.error('erro: ci status: --sha exige o sha completo, de 40 caracteres hexadecimais minusculos ' +
2294
+ '(git rev-parse HEAD); o check e consultado no commit exato, nunca por ref nem prefixo');
2295
+ console.error('uso: ork ci status --sha <sha de 40 caracteres> [--remoto origin]');
2198
2296
  return 2;
2199
2297
  }
2200
- const result = (0, ci_1.consultarCi)(carregado, sha, texto(args.opcoes.remoto) ?? 'origin');
2298
+ // RM-047: recusa o `--remoto` que nao e nome de remoto mesmo com o gate de CI desligado.
2299
+ const remoto = (0, branch_de_estado_1.exigirRemoto)(args.opcoes.remoto === undefined ? 'origin' : args.opcoes.remoto, 'ci');
2300
+ const result = (0, ci_1.consultarCi)(carregado, sha, remoto);
2201
2301
  console.log(args.opcoes.json === true ? JSON.stringify(result, null, 2) : `${result.ok ? 'CI VERDE' : 'CI NÃO LIBEROU'}: ${result.detail}`);
2202
2302
  return result.ok ? 0 : 1;
2203
2303
  }
@@ -2324,7 +2424,14 @@ const CONTRATO_DO_BOARD = 'ork.board/v1';
2324
2424
  function comandoFabrica(args) {
2325
2425
  const carregado = (0, manifest_1.exigirManifesto)();
2326
2426
  const sub = args.posicionais[1];
2427
+ // RM-063 (F1): a batida e do crontab desta maquina; nao le nem escreve o remoto.
2428
+ if (sub === 'batida')
2429
+ return comandoDaBatida(carregado, args);
2430
+ // RM-047: o remoto vem do manifesto de quem fez o repositorio; fora do formato, recusa antes do git.
2431
+ // O `publicar` recusa dentro do try (publicarMaquina), para o silencioso deixar a recusa no log.
2327
2432
  const remoto = texto(args.opcoes.remoto) ?? carregado.manifesto.fabrica.remoto;
2433
+ if (sub !== 'publicar')
2434
+ (0, branch_de_estado_1.exigirRemoto)(remoto, 'fabrica');
2328
2435
  if (sub === 'publicar') {
2329
2436
  const silencioso = args.opcoes.silencioso === true;
2330
2437
  try {
@@ -2343,6 +2450,9 @@ function comandoFabrica(args) {
2343
2450
  : `Fabrica: retrato de ${r.maquina} igual ao ultimo publicado; nada a enviar (use --forcar para publicar mesmo assim).`);
2344
2451
  if (!(0, maquina_1.fabricaCompartilhada)(carregado.manifesto) && !silencioso) {
2345
2452
  console.log(' esta maquina nao entrou na fabrica compartilhada: so publica quando voce pede (ork fabrica entrar liga).');
2453
+ // RM-047 (P5): o manifesto que pede a fabrica nao liga a publicacao desta maquina.
2454
+ if (carregado.manifesto.fabrica.compartilhada)
2455
+ console.log(' o orkastery.yaml pede a fabrica compartilhada; quem liga e a maquina, com ork fabrica entrar.');
2346
2456
  }
2347
2457
  return 0;
2348
2458
  }
@@ -2376,13 +2486,14 @@ function comandoFabrica(args) {
2376
2486
  console.log(`Fabrica: ${(0, maquina_1.nomeDaMaquina)()} saiu; nada mais e publicado daqui.` +
2377
2487
  (r ? ` Retrato removido de ork/fabrica-estado (${r.slice(0, 7)}).` : ' Nao havia retrato desta maquina na branch.'));
2378
2488
  if ((0, maquina_1.fabricaCompartilhada)(carregado.manifesto))
2379
- console.log(' AVISO: o manifesto do projeto (ou ORK_FABRICA_COMPARTILHADA) ainda liga a fabrica aqui.');
2489
+ console.log(' AVISO: ORK_FABRICA_COMPARTILHADA=1 neste shell ainda liga a fabrica aqui.');
2380
2490
  void config;
2381
2491
  return 0;
2382
2492
  }
2383
2493
  if (sub !== undefined && sub !== 'list') {
2384
2494
  console.error(`subcomando desconhecido: fabrica ${sub}`);
2385
- console.error('uso: ork fabrica [--json] [--sem-remoto] | fabrica publicar [--forcar] [--json] | fabrica entrar [--maquina NOME] | fabrica sair');
2495
+ console.error('uso: ork fabrica [--json] [--sem-remoto] | fabrica publicar [--forcar] [--json] | fabrica entrar [--maquina NOME] | fabrica sair' +
2496
+ ' | fabrica batida [status|instalar|remover] [--por Q] [--json]');
2386
2497
  return 2;
2387
2498
  }
2388
2499
  // RM-052: a fabrica le a branch de UM projeto, no remoto dele; o cabecalho diz qual e o que ficou de fora.
@@ -2395,13 +2506,128 @@ function comandoFabrica(args) {
2395
2506
  naoLido: [projeto_alvo_1.FORA_DA_CONSULTA.roadmap, projeto_alvo_1.FORA_DA_CONSULTA.reservas, ...(url === null ? [(0, projeto_alvo_1.semRemoto)(remoto)] : [])],
2396
2507
  });
2397
2508
  if (args.opcoes.json === true) {
2398
- console.log(JSON.stringify({ ...painel, consulta }, null, 2));
2509
+ // RM-053 (fatia 2): o mesmo JSON, com o invisivel do remoto escrito como \uXXXX.
2510
+ console.log((0, saida_segura_1.jsonSemInvisivel)({ ...painel, consulta }));
2399
2511
  return 0;
2400
2512
  }
2401
2513
  console.log([...(0, projeto_alvo_1.linhasDaConsulta)(consulta), ''].join('\n'));
2402
2514
  console.log(url === null
2403
2515
  ? `Fabrica: o projeto ${carregado.manifesto.project.name} nao tem o remoto ${remoto}; nada foi lido de ork/fabrica-estado.`
2404
2516
  : (0, fabrica_estado_1.textoDaFabrica)(painel, (0, maquina_1.nomeDaMaquina)()));
2517
+ // RM-047 (P5): o manifesto pede a fabrica, mas quem liga a publicacao e a maquina.
2518
+ const pedida = (0, maquina_1.avisoDaFabricaPedida)(carregado.manifesto);
2519
+ if (pedida)
2520
+ console.log(`\n${pedida}`);
2521
+ return 0;
2522
+ }
2523
+ /**
2524
+ * RM-063 (F1): `ork fabrica batida` instala, mostra e remove a batida da varredura do pulse no crontab desta
2525
+ * maquina. `status` sai 0 com a batida instalada e 1 sem ela (ou sem crontab legivel); `instalar` e
2526
+ * `remover` gravam o evento no ledger da maquina quando o crontab muda.
2527
+ */
2528
+ function comandoDaBatida(carregado, args) {
2529
+ const acao = args.posicionais[2] ?? 'status';
2530
+ const json = args.opcoes.json === true;
2531
+ if (acao === 'status') {
2532
+ const estado = (0, fabrica_batida_1.estadoDaBatida)(carregado.raiz);
2533
+ console.log(json ? JSON.stringify(estado, null, 2) : (0, fabrica_batida_1.textoDoEstadoDaBatida)(estado));
2534
+ return estado.leitura.ok && estado.instalada ? 0 : 1;
2535
+ }
2536
+ if ((acao === 'instalar' || acao === 'remover') && args.posicionais.length === 3) {
2537
+ const por = texto(args.opcoes.por);
2538
+ const r = acao === 'instalar' ? (0, fabrica_batida_1.instalarBatida)(carregado.raiz, { por }) : (0, fabrica_batida_1.removerBatida)(carregado.raiz, { por });
2539
+ console.log(json ? JSON.stringify(r, null, 2) : (0, fabrica_batida_1.textoDoResultadoDaBatida)(r));
2540
+ return 0;
2541
+ }
2542
+ console.error('uso: ork fabrica batida [status|instalar|remover] [--por Q] [--json]');
2543
+ return 2;
2544
+ }
2545
+ /**
2546
+ * RM-053: `ork network` e a Orkastery Network, as maquinas de uma pessoa em rede. Roda de qualquer
2547
+ * diretorio, com ou sem projeto: a rede e da pessoa, nao de um repositorio. O projeto do diretorio
2548
+ * atual, quando ha, so entra no retrato e na leitura da fabrica legada.
2549
+ */
2550
+ function comandoNetwork(args) {
2551
+ const sub = args.posicionais[1];
2552
+ // RM-054: `network roadmap` tem o proprio --projeto e o proprio uso.
2553
+ if (sub === 'roadmap')
2554
+ return comandoNetworkRoadmap(args);
2555
+ const diretorio = process.cwd();
2556
+ const uso = 'uso: ork network [status] [--json] [--sem-remoto] | network entrar [--maquina NOME] [--forja github|gitlab] ' +
2557
+ '[--repositorio [DONO/]NOME] [--forcar] | network publicar [--forcar] [--json] | network sair | ' +
2558
+ 'network roadmap [--projeto P] [--json] [--sem-remoto]';
2559
+ const forja = texto(args.opcoes.forja), repositorio = texto(args.opcoes.repositorio);
2560
+ if ((args.opcoes.forja !== undefined && !(0, rede_forja_1.ehNomeDeForja)(forja)) || args.opcoes.repositorio === true ||
2561
+ (repositorio !== undefined && !/^(?:[A-Za-z0-9][A-Za-z0-9._-]{0,99}\/)?[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(repositorio))) {
2562
+ console.error(uso);
2563
+ return 2;
2564
+ }
2565
+ if (sub === 'entrar') {
2566
+ const r = (0, rede_1.entrarNaRede)({ maquina: texto(args.opcoes.maquina), forja: (0, rede_forja_1.ehNomeDeForja)(forja) ? forja : undefined, repositorio, diretorio,
2567
+ tomarNome: args.opcoes.forcar === true });
2568
+ console.log(`Rede: ${r.publicacao.maquina} entrou na Orkastery Network de ${r.casa.dono} (${r.casa.forja}: ${(0, rede_1.refDaCasa)(r.casa)}, ` +
2569
+ `privado${r.criado ? ', criado agora' : ''}).`);
2570
+ console.log(` Primeiro retrato publicado (${r.publicacao.commit?.slice(0, 7)}). Depois, esta maquina publica sozinha na batida do pulse`);
2571
+ if (r.publicacao.tomouNome)
2572
+ console.log(` Tomou o nome "${r.publicacao.maquina}" de outra instalacao; o commit registra.`);
2573
+ console.log(' e ao criar thread, despachar fase, entregar e fechar. De qualquer maquina desta pessoa: ork network status');
2574
+ for (const d of r.publicacao.descartados) {
2575
+ console.log(` AVISO: um projeto ficou fora do retrato: padrao "${d.padrao}" em ${d.campo} (valor omitido de proposito).`);
2576
+ }
2577
+ if (process.env.ORK_MAQUINA && process.env.ORK_MAQUINA.trim() !== r.publicacao.maquina) {
2578
+ console.log(` AVISO: ORK_MAQUINA=${process.env.ORK_MAQUINA} neste shell vence o nome gravado; alinhe os dois.`);
2579
+ }
2580
+ return 0;
2581
+ }
2582
+ if (sub === 'sair') {
2583
+ const r = (0, rede_1.sairDaRede)({ forja: (0, rede_forja_1.ehNomeDeForja)(forja) ? forja : undefined, repositorio });
2584
+ console.log(`Rede: ${r.maquina} saiu; nada mais e publicado daqui.` + (r.commit
2585
+ ? ` Retrato removido de ${r.casa} (${r.commit.slice(0, 7)}).`
2586
+ : r.alheio
2587
+ ? ` O retrato "${r.maquina}" em ${r.casa} e de outra instalacao com o mesmo nome; nada foi removido.` +
2588
+ (r.mesmoHostname ? ' Ele tem o hostname desta maquina: se ~/.orkastery foi apagada, retome o nome com ork network entrar --forcar.' : '')
2589
+ : ` Nao havia retrato desta maquina${r.casa ? ` em ${r.casa}` : ' numa casa alcancavel'}.`));
2590
+ if ((0, maquina_1.lerConfigDaMaquina)()?.fabricaCompartilhada) {
2591
+ console.log(' A fabrica compartilhada dos projetos continua publicando daqui (ork/fabrica-estado); ork fabrica sair em cada um para parar.');
2592
+ }
2593
+ return 0;
2594
+ }
2595
+ if (sub === 'publicar') {
2596
+ if (args.opcoes.silencioso === true) {
2597
+ // O filho do evento de thread: quem disparou ja tomou a vez (teto de 14 min) e nao espera.
2598
+ try {
2599
+ (0, rede_adesao_1.registrarNaRede)({ ...(0, rede_1.publicarRede)({ diretorio }), origem: 'evento' });
2600
+ return 0;
2601
+ }
2602
+ catch (e) {
2603
+ (0, rede_adesao_1.registrarNaRede)({ acao: 'falhou', origem: 'evento', erro: e.message });
2604
+ return 1;
2605
+ }
2606
+ }
2607
+ const r = (0, rede_1.publicarRede)({ diretorio, forcar: args.opcoes.forcar === true, forja: (0, rede_forja_1.ehNomeDeForja)(forja) ? forja : undefined, repositorio });
2608
+ if (args.opcoes.json === true)
2609
+ console.log(JSON.stringify(r, null, 2));
2610
+ else
2611
+ console.log(r.acao === 'publicou'
2612
+ ? `Rede: ${r.maquina} publicou o retrato em ${r.casa} (${r.commit?.slice(0, 7)}, ${r.tentativas} tentativa(s)).`
2613
+ : r.acao === 'ocupado'
2614
+ ? 'Rede: outra publicacao desta maquina esta em andamento; tente de novo em instantes.'
2615
+ : `Rede: retrato de ${r.maquina} igual ao ultimo publicado em ${r.casa}; nada a enviar (use --forcar para publicar mesmo assim).`);
2616
+ if (args.opcoes.json !== true) {
2617
+ for (const d of r.descartados)
2618
+ console.log(` AVISO: um projeto ficou fora do retrato: padrao "${d.padrao}" em ${d.campo} (valor omitido de proposito).`);
2619
+ }
2620
+ return 0;
2621
+ }
2622
+ if (sub !== undefined && sub !== 'status') {
2623
+ console.error(`subcomando desconhecido: network ${sub}`);
2624
+ console.error(uso);
2625
+ return 2;
2626
+ }
2627
+ // RM-054 (fatia 3): o host sem cwd de projeto (RM-052, D3) nao faz do diretorio do gateway um projeto lido.
2628
+ const doHost = (process.env[projeto_alvo_1.ENV_PROJETO_EXPLICITO] ?? '').trim() === '1';
2629
+ const status = (0, rede_status_1.lerRede)({ semRemoto: args.opcoes['sem-remoto'] === true, diretorio: doHost ? null : diretorio });
2630
+ console.log(args.opcoes.json === true ? (0, rede_status_1.jsonDaRede)(status) : (0, rede_status_1.textoDaRede)(status));
2405
2631
  return 0;
2406
2632
  }
2407
2633
  /**
@@ -2581,8 +2807,9 @@ function comandoMaster(args) {
2581
2807
  const id = args.posicionais[2];
2582
2808
  const formato = texto(args.opcoes.formato) ?? 'telegram';
2583
2809
  if (!id || !['telegram', 'terminal', 'json'].includes(formato))
2584
- throw new Error('uso: ork master pedir <thread> [--formato telegram|terminal|json]');
2585
- const pedido = (0, master_nota_1.pedirNota)(carregado.raiz, id, { codigosEmUso: (0, pulse_resposta_1.codigosEmUso)(carregado.raiz) });
2810
+ throw new Error((0, locale_1.msg)().master.usoPedir);
2811
+ // RM-061 (F2b, G2): o pedido de nota e gravado no escopo pt-BR; o erro da entrega volta no locale do comando.
2812
+ const pedido = (0, locale_1.comLocale)('pt-BR', () => (0, master_nota_1.pedirNota)(carregado.raiz, id, { codigosEmUso: (0, pulse_resposta_1.codigosEmUso)(carregado.raiz) }));
2586
2813
  console.log(formato === 'json' ? JSON.stringify(pedido, null, 2) : (0, master_nota_1.textoDoPedidoDeNota)(carregado.raiz, pedido, formato));
2587
2814
  return 0;
2588
2815
  }
@@ -2640,26 +2867,13 @@ function comandoMaster(args) {
2640
2867
  console.error('master.fila-aposentada: a fila de ratificacao de score saiu na I-43. ' +
2641
2868
  'Entregue e aceito, a menos que voce diga o contrario.\n' +
2642
2869
  ' ork master as entregas, com o indice ja derivado do ledger\n' +
2643
- ' ork master --aceitar-omissao aceita as entregues, com indice e insumos no ledger\n' +
2870
+ ' ork master <id> --aceitar-omissao aceita so esta entrega, com indice e insumos no ledger\n' +
2871
+ ' ork master --aceitar-omissao aceita todas as entregues (--dry-run mostra quais)\n' +
2644
2872
  ' ork master <id> --score <0-5> --justificativa "<por que>" --por <humano> para reclamar');
2645
2873
  return 2;
2646
2874
  }
2647
- if (args.opcoes['aceitar-omissao'] === true) {
2648
- const aceitos = (0, master_2.aceitarPendentesPorOmissao)(carregado.raiz);
2649
- if (args.opcoes.json === true) {
2650
- console.log(JSON.stringify(aceitos, null, 2));
2651
- return 0;
2652
- }
2653
- if (aceitos.length === 0) {
2654
- console.log('Nenhuma entrega esperando decisao.');
2655
- return 0;
2656
- }
2657
- console.log(`Aceitas por omissao: ${aceitos.length}. O indice e os insumos foram ao ledger.`);
2658
- for (const a of aceitos)
2659
- console.log(` ${a.thread.padEnd(20)} indice ${a.indice.valor}/${a.indice.base}`);
2660
- console.log('');
2661
- console.log('Discordou? A nota humana sobrescreve, e o registro da omissao permanece.');
2662
- return 0;
2875
+ if (args.opcoes['aceitar-omissao'] !== undefined) {
2876
+ return comandoAceitarOmissao(args, carregado.raiz, primeiro);
2663
2877
  }
2664
2878
  if (primeiro === undefined) {
2665
2879
  console.log(args.opcoes.json
@@ -2675,7 +2889,7 @@ function comandoMaster(args) {
2675
2889
  const brutoScore = texto(args.opcoes.score);
2676
2890
  const justificativa = texto(args.opcoes.justificativa) ?? texto(args.opcoes.porque);
2677
2891
  if (brutoScore === undefined) {
2678
- console.error('uso: ork master <thread-id> --score 0-5 --justificativa "<texto>"');
2892
+ console.error('uso: ork master <thread-id> --score 0-5 --justificativa "<texto>" --por <seu-nome>');
2679
2893
  console.error(' o score do MASTER e humano, de 0 a 5, e a justificativa e obrigatoria.');
2680
2894
  return 2;
2681
2895
  }
@@ -2727,6 +2941,89 @@ function comandoMaster(args) {
2727
2941
  console.log(`Proximo passo: ork board --all | entregas e indice: ork master`);
2728
2942
  return 0;
2729
2943
  }
2944
+ /**
2945
+ * RM-008 (03/10/2026): `ork master [<thread>] --aceitar-omissao [--thread T] [--dry-run] [--json]`.
2946
+ *
2947
+ * Tres vezes na madrugada de 03/10, um condutor rodou `ork master --aceitar-omissao` para fechar a
2948
+ * propria thread, e o comando fechou tambem as entregues de outras frentes (ork-rm057fatia3t,
2949
+ * ork-rm025modocon). A thread indicada (posicional, `--thread T` ou `--aceitar-omissao=T`) limita o
2950
+ * aceite a ela. Sem thread, o padrao continua o mesmo, por decisao registrada: drenar todas, agora
2951
+ * listando cada uma e avisando em stderr quando quem roda e processo de agente.
2952
+ */
2953
+ function comandoAceitarOmissao(args, raiz, posicional) {
2954
+ const bruto = args.opcoes['aceitar-omissao'];
2955
+ const candidatos = [posicional, texto(args.opcoes.thread), typeof bruto === 'string' ? bruto : undefined]
2956
+ .filter((v) => typeof v === 'string' && v.trim() !== '').map((v) => v.trim());
2957
+ if (args.opcoes.thread === true || new Set(candidatos).size > 1) {
2958
+ console.error((0, locale_1.msg)().master.usoOmissao);
2959
+ return 2;
2960
+ }
2961
+ const alvo = candidatos[0];
2962
+ const dryRun = args.opcoes['dry-run'] === true;
2963
+ const json = args.opcoes.json === true;
2964
+ if (alvo) {
2965
+ const fora = (0, master_2.motivoForaDaOmissao)(raiz, alvo);
2966
+ if (fora) {
2967
+ if (json)
2968
+ console.log(JSON.stringify(dryRun ? { dryRun: true, fecharia: [], motivo: fora.motivo } : [], null, 2));
2969
+ else
2970
+ (fora.motivo === 'ja-fechada' ? console.log : console.error)(fora.texto);
2971
+ return fora.motivo === 'ja-fechada' ? 0 : 1;
2972
+ }
2973
+ }
2974
+ if (dryRun) {
2975
+ const fecharia = (0, master_2.entregasParaOmissao)(raiz, alvo).map((p) => ({ thread: p.thread.id, indice: (0, master_2.indiceDaThread)(raiz, p.thread.id) }));
2976
+ if (json) {
2977
+ console.log(JSON.stringify({ dryRun: true, fecharia }, null, 2));
2978
+ return 0;
2979
+ }
2980
+ const m = (0, locale_1.msg)().master;
2981
+ console.log(m.ensaio);
2982
+ if (fecharia.length === 0) {
2983
+ console.log(m.nadaEsperando);
2984
+ return 0;
2985
+ }
2986
+ console.log(m.fecharia(fecharia.length));
2987
+ for (const f of fecharia)
2988
+ console.log(m.linhaDoIndice(f.thread, f.indice.valor, f.indice.base));
2989
+ avisoDeOmissaoSemAlvo(alvo, fecharia.length, true);
2990
+ return 0;
2991
+ }
2992
+ // RM-061 (F2b, G2): o MASTER log, o POSTMORTEM e o registro da omissao nascem em pt-BR.
2993
+ const aceitos = (0, locale_1.comLocale)('pt-BR', () => (0, master_2.aceitarPendentesPorOmissao)(raiz, { thread: alvo }));
2994
+ avisoDeOmissaoSemAlvo(alvo, aceitos.length, false);
2995
+ if (json) {
2996
+ console.log(JSON.stringify(aceitos, null, 2));
2997
+ return 0;
2998
+ }
2999
+ const m = (0, locale_1.msg)().master;
3000
+ if (aceitos.length === 0) {
3001
+ console.log(m.nadaEsperando);
3002
+ return 0;
3003
+ }
3004
+ console.log(m.aceitas(aceitos.length));
3005
+ for (const a of aceitos)
3006
+ console.log(m.linhaDoIndice(a.thread, a.indice.valor, a.indice.base));
3007
+ console.log('');
3008
+ console.log(m.discordou);
3009
+ return 0;
3010
+ }
3011
+ /**
3012
+ * O aviso do aceite SEM thread vindo de processo de agente que alcanca mais de uma entrega. A marca
3013
+ * e a mesma do `master.prova-de-canal` (ambiente do host ou do despacho). Vai para stderr: o stdout,
3014
+ * inclusive o `--json`, fica como era.
3015
+ */
3016
+ function avisoDeOmissaoSemAlvo(alvo, quantas, ensaio) {
3017
+ if (alvo || quantas <= 1)
3018
+ return;
3019
+ const marca = (0, master_nota_1.marcaDeHost)(process.env);
3020
+ if (!marca)
3021
+ return;
3022
+ const propria = (process.env[runtime_ambiente_1.ENV_THREAD_DO_DESPACHO] ?? '').trim();
3023
+ console.error('');
3024
+ console.error((0, locale_1.msg)().master.avisoSemThread(marca, ensaio, quantas));
3025
+ console.error((0, locale_1.msg)().master.avisoSoASua(propria || '<thread-id>', ensaio));
3026
+ }
2730
3027
  /** I-55 (RM-008): `ork licoes` mostra o que volta no proximo GOAL e PLAN, e as propostas de policy. */
2731
3028
  function comandoLicoes(args) {
2732
3029
  const carregado = (0, manifest_1.exigirManifesto)();
@@ -2764,9 +3061,26 @@ function comandoRoadmap(args) {
2764
3061
  : soltas.map((s) => `${s.item}: ${s.detalhe} (thread fechada ${s.thread})`).join('\n'));
2765
3062
  return 0;
2766
3063
  }
2767
- const painel = (0, roadmap_reservas_1.listarReservas)(carregado.raiz, { remoto });
3064
+ // RM-052 (fatia 2, D4): as reservas moram no remoto do projeto. Sem ele, nada e lido; com ele mudo e
3065
+ // sem copia, tambem nao. A resposta diz qual projeto leu e o que ficou de fora, nunca "nenhum item".
3066
+ // RM-047: nome fora do formato de remoto recusa antes do git, como sempre.
3067
+ const nomeDoRemoto = (0, branch_de_estado_1.exigirRemoto)(remoto ?? roadmap_reservas_1.REMOTO_PADRAO, 'roadmap');
3068
+ const url = (0, projeto_alvo_1.remotoDoProjeto)(carregado.raiz, nomeDoRemoto);
3069
+ const painel = url === null ? { reservas: [], feats: [], atualizado: false, ponta: null }
3070
+ : (0, roadmap_reservas_1.listarReservas)(carregado.raiz, { remoto });
3071
+ const leitura = (0, roadmap_reservas_1.leituraDasReservas)(painel, url !== null);
2768
3072
  const orfas = (0, roadmap_reservas_1.reservasOrfas)(carregado.raiz, painel.reservas);
2769
- console.log(args.opcoes.json === true ? JSON.stringify({ ...painel, orfas }, null, 2) : (0, roadmap_reservas_1.textoDasReservas)(painel, orfas));
3073
+ const lido = leitura === 'lido-agora' || leitura === 'copia-local';
3074
+ const consulta = (0, projeto_alvo_1.consultaDoProjeto)(carregado, {
3075
+ remoto: url,
3076
+ lido: lido ? [`reservas do roadmap (${roadmap_reservas_1.BRANCH_DE_RESERVAS} em ${nomeDoRemoto}, ${leitura === 'lido-agora' ? 'lido agora' : 'última cópia local'})`] : [],
3077
+ naoLido: [projeto_alvo_1.FORA_DA_CONSULTA.roadmap,
3078
+ ...(leitura === 'sem-remoto' ? [`reservas do roadmap: o projeto não tem o remoto ${nomeDoRemoto}, nada foi lido de ${roadmap_reservas_1.BRANCH_DE_RESERVAS}`]
3079
+ : leitura === 'sem-copia' ? [`reservas do roadmap: o remoto ${nomeDoRemoto} não respondeu e não há cópia local de ${roadmap_reservas_1.BRANCH_DE_RESERVAS}`]
3080
+ : [])],
3081
+ });
3082
+ console.log(args.opcoes.json === true ? JSON.stringify({ ...painel, orfas, leitura, consulta }, null, 2)
3083
+ : [...(0, projeto_alvo_1.linhasDaConsulta)(consulta), '', (0, roadmap_reservas_1.textoDasReservas)(painel, orfas, { remoto: nomeDoRemoto, projeto: carregado.manifesto.project.name, temRemoto: url !== null })].join('\n'));
2770
3084
  return 0;
2771
3085
  }
2772
3086
  if (sub === 'status') {
@@ -2774,7 +3088,11 @@ function comandoRoadmap(args) {
2774
3088
  // RM-052: com o projeto consultado e o que ficou de fora (as outras maquinas nao sao lidas aqui).
2775
3089
  const consulta = (0, projeto_alvo_1.consultaDoProjeto)(carregado, { lido: ['roadmap (docs/roadmap)', projeto_alvo_1.FORA_DA_CONSULTA.threadsDaMaquina],
2776
3090
  naoLido: [projeto_alvo_1.FORA_DA_CONSULTA.reservas, 'threads de outras máquinas (ork network roadmap)'] });
2777
- const status = (0, roadmap_status_1.montarStatusDoRoadmap)(carregado.raiz, { projeto: carregado.manifesto.project.name, consulta });
3091
+ // RM-061 (F2b, G2): o status e montado em pt-BR, como o --json; so o texto segue o locale. Os canais (Hermes,
3092
+ // OpenClaw) transportam o texto: com owner.language ou LANG en no host, o dono o recebe em ingles.
3093
+ // RM-063 (F2): o fecho le a mesma fila do `ork pulse`, sem forja e sem registrar.
3094
+ const status = (0, locale_1.comLocale)('pt-BR', () => (0, roadmap_status_1.montarStatusDoRoadmap)(carregado.raiz, { projeto: carregado.manifesto.project.name, consulta,
3095
+ fila: (quando) => (0, pulse_1.filaDoDono)(carregado, { quando }) }));
2778
3096
  console.log(args.opcoes.json === true ? JSON.stringify(status, null, 2) : (0, roadmap_status_1.textoDoStatusDoRoadmap)(status));
2779
3097
  return 0;
2780
3098
  }
@@ -2824,7 +3142,7 @@ function comandoRoadmap(args) {
2824
3142
  * RM-054 (fatia 1): `ork network roadmap`, o roadmap da rede de qualquer diretorio. Pedido de projeto
2825
3143
  * ambiguo ou desconhecido e resposta, nao erro: a recusa com os candidatos, e o codigo da RM-052.
2826
3144
  */
2827
- function comandoNetwork(args) {
3145
+ function comandoNetworkRoadmap(args) {
2828
3146
  const pedido = texto(args.opcoes.projeto);
2829
3147
  if (args.posicionais[1] !== 'roadmap' || args.posicionais.length > 2 || (args.opcoes.projeto !== undefined && !pedido)) {
2830
3148
  console.error('uso: ork network roadmap [--projeto <caminho|github:dono/repo|gitlab:grupo/repo|nome>] [--json] [--sem-remoto]');
@@ -2897,11 +3215,13 @@ function comandoDocs(args) {
2897
3215
  return 0;
2898
3216
  }
2899
3217
  if (sub === 'init') {
2900
- const criados = (0, docs_1.iniciarDocs)(raiz);
3218
+ // RM-061 (F3a, D1 e D5): os sete arquivos nascem na lingua do dono, resolvida pelo manifesto (tambem com `--json`,
3219
+ // que tira so o texto impresso do locale); o texto segue o locale do comando coberto.
3220
+ const criados = (0, docs_1.iniciarDocs)(raiz, (0, locale_1.resolverLocale)(carregado?.manifesto.owner?.language).locale);
3221
+ const m = (0, locale_1.msg)().gerados.docsInit;
2901
3222
  console.log(criados.length === 0
2902
- ? 'Documentacao como codigo ja estava no projeto: nada criado.'
2903
- : ['Criado:', ...criados.map((c) => ` ${c}`), '',
2904
- 'Proximo passo: copie docs/produto/_modelo-feature.md e docs/roadmap/_modelo-item.md, e rode ork docs verificar'].join('\n'));
3223
+ ? m.jaEstava
3224
+ : [m.criado, ...criados.map((c) => ` ${c}`), '', m.proximoPasso].join('\n'));
2905
3225
  return 0;
2906
3226
  }
2907
3227
  console.error(`uso: ork docs verificar [--json] [--pr] | sincronizar [--escrever] [--so RM-NNN] [--todos] | init`);
@@ -2957,12 +3277,18 @@ function comandoPrompt(args) {
2957
3277
  return 2;
2958
3278
  }
2959
3279
  const thread = (0, thread_1.lerThread)(obrigatorio.raiz, threadId);
3280
+ // RM-059 (T6.0): sem --pedido, o pedido guardado na criacao, conferido pelo sha256; thread sem pedido
3281
+ // guardado segue com o texto de exemplo, como antes.
3282
+ const guardado = texto(args.opcoes.pedido) === undefined ? (0, thread_1.pedidoDaThread)(obrigatorio.raiz, thread) : null;
3283
+ const pedidoDaFase = guardado?.texto ?? pedido;
2960
3284
  const template = idTemplate ? (0, prompts_1.exigirTemplate)(idTemplate, obrigatorio.raiz) : (0, prompts_1.templateDaFase)(fase, obrigatorio.raiz);
2961
3285
  const prompt = idTemplate
2962
- ? (0, prompts_1.renderizar)(template, (0, phase_1.valoresDoPrompt)(thread, fase, pedido))
2963
- : (0, phase_1.montarPrompt)(thread, fase, pedido, obrigatorio.raiz);
3286
+ ? (0, prompts_1.renderizar)(template, (0, phase_1.valoresDoPrompt)(thread, fase, pedidoDaFase))
3287
+ : (0, phase_1.montarPrompt)(thread, fase, pedidoDaFase, obrigatorio.raiz);
2964
3288
  console.log(`# template ${template.id} v${template.versao} (origem: ${template.origem})`);
2965
3289
  console.log(`# thread ${thread.id}, fase ${fase}, sha256 ${(0, phase_1.hashDoPrompt)(prompt)}`);
3290
+ if (guardado)
3291
+ console.log(`# pedido guardado na criacao da thread (sha256 ${(0, util_1.shaCurto)(guardado.sha256)})`);
2966
3292
  console.log('');
2967
3293
  console.log(prompt);
2968
3294
  return 0;
@@ -2981,6 +3307,19 @@ function exigirFaseCanonica(bruto) {
2981
3307
  /**
2982
3308
  * `ork adapter list|show|install <host>`: instalacao dos adaptadores de Camada 1 (bloco B4).
2983
3309
  */
3310
+ /**
3311
+ * O caminho real do `ork` em execução, quando o processo é este CLI (argv[1] resolve para este arquivo).
3312
+ * Importado por outro script, devolve undefined e o install volta à ordem antiga (PATH, catálogo).
3313
+ */
3314
+ function orkEmExecucao() {
3315
+ try {
3316
+ const proprio = fs.realpathSync(__filename);
3317
+ return process.argv[1] && fs.realpathSync(process.argv[1]) === proprio ? proprio : undefined;
3318
+ }
3319
+ catch {
3320
+ return undefined;
3321
+ }
3322
+ }
2984
3323
  function comandoAdapter(args) {
2985
3324
  const sub = args.posicionais[1] ?? 'list';
2986
3325
  if (sub === 'list') {
@@ -3014,11 +3353,15 @@ function comandoAdapter(args) {
3014
3353
  dryRun: args.opcoes['dry-run'] === true,
3015
3354
  force: args.opcoes.force === true || args.opcoes.forcar === true,
3016
3355
  orkBin: texto(args.opcoes.ork),
3356
+ // Ensaio de 03/10: a extensão chama o ork que a instalou, não o primeiro do PATH.
3357
+ orkEmExecucao: orkEmExecucao(),
3017
3358
  versao: VERSAO,
3018
3359
  // I-43 (D5): a decisao por ARQUIVO, que e o que faz `--force` deixar de ser o
3019
3360
  // unico caminho de saida. `;` separa varios, como o resto do CLI ja faz.
3020
3361
  aceitarCatalogo: (texto(args.opcoes['aceitar-catalogo']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
3021
3362
  manterCopia: (texto(args.opcoes['manter-copia']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
3363
+ // RM-061 (F3a, D1 e D9): o bloco da experiência nasce na língua do dono; o texto impresso segue em pt-BR (F3b).
3364
+ locale: (0, locale_1.resolverLocale)(carregado?.manifesto.owner?.language).locale,
3022
3365
  });
3023
3366
  console.log((0, hosts_1.textoDaInstalacao)(r));
3024
3367
  return r.ok ? 0 : 2;
@@ -3033,7 +3376,8 @@ function comandoAdapter(args) {
3033
3376
  * de zero em qualquer falha, para o CI do kit poder barrar merge sem eval.
3034
3377
  */
3035
3378
  function comandoEval(args) {
3036
- const catalogo = (0, catalogo_1.exigirCatalogo)((0, manifest_1.carregarManifesto)()?.raiz ?? (0, manifest_1.diretorioDoProjeto)());
3379
+ // RM-047 (P4): o eval so executa o catalogo do proprio pacote, nunca o achado a partir do cwd.
3380
+ const catalogo = (0, catalogo_1.exigirCatalogoDoPacote)((0, manifest_1.carregarManifesto)()?.raiz ?? (0, manifest_1.diretorioDoProjeto)());
3037
3381
  const lista = (v) => {
3038
3382
  const t = texto(v);
3039
3383
  return t ? t.split(',').map((x) => x.trim()).filter(Boolean) : undefined;
@@ -3184,6 +3528,9 @@ function comandoAudit(args) {
3184
3528
  return 0;
3185
3529
  }
3186
3530
  if (sub === 'show') {
3531
+ const sobra = SOBRAS_DO_OBJECTIVE.find((opcao) => args.opcoes[opcao] !== undefined);
3532
+ if (sobra)
3533
+ return recusarSobraDoObjective(sobra);
3187
3534
  const id = args.posicionais[2];
3188
3535
  if (!id) {
3189
3536
  console.error('uso: ork audit show <rodada> [--ledger]');
@@ -3432,8 +3779,9 @@ function comandoAudit(args) {
3432
3779
  * que sempre teve. E o que garante que ligar o B6 nao muda o que o builder ja conhece.
3433
3780
  */
3434
3781
  function relatarPublicacao(r) {
3782
+ const m = (0, locale_1.msg)().thread;
3435
3783
  if (r.publicacao?.estado === 'pendente') {
3436
- console.log(`Memoria: publicacao pendente (${r.publicacao.motivo}); ativacao explicita necessaria.`);
3784
+ console.log(m.publicacaoPendente(`${r.publicacao.motivo}`));
3437
3785
  return;
3438
3786
  }
3439
3787
  if (r.regime !== 'orkmind')
@@ -3446,9 +3794,9 @@ function relatarPublicacao(r) {
3446
3794
  r.roadmap?.ok ? '1 roadmap' : '',
3447
3795
  ].filter((t) => t !== '');
3448
3796
  console.log('');
3449
- console.log(`Memoria (orkmind, tenant ${r.estado.tenant}): ${gravados.join(', ') || 'nada a gravar'}.`);
3797
+ console.log(m.memoriaGravada(`${r.estado.tenant}`, gravados.join(', ') || m.nadaAGravar));
3450
3798
  if (r.falhas > 0)
3451
- console.log(` ${r.falhas} gravacao(oes) nao concluida(s); veja ork memory status.`);
3799
+ console.log(m.gravacoesFalhas(r.falhas));
3452
3800
  }
3453
3801
  /** Janela de origem e corte de apresentação são inteiros positivos explícitos. */
3454
3802
  function limiteDeLeitura(valor) {
@@ -3650,7 +3998,20 @@ function comandoMemory(args) {
3650
3998
  const config = (0, manifest_1.configDeEmbedding)(carregado.manifesto);
3651
3999
  const driver = (0, orkmind_1.configDoManifesto)(carregado.manifesto);
3652
4000
  const embedder = new orkmind_1.DriverCliOrkMind(driver);
3653
- const universo = (0, indice_vetorial_1.universoDoTenant)(memoria, memoria.estado.tenant);
4001
+ // RM-038: o universo da busca inteiro, numa leitura; sem ele, nada e embedado (nunca um pedaco).
4002
+ let universo;
4003
+ try {
4004
+ universo = (0, indice_vetorial_1.universoDaBusca)(memoria, memoria.estado.tenant);
4005
+ }
4006
+ catch (erro) {
4007
+ const motivo = (0, indice_vetorial_1.codigoDaFalha)(erro);
4008
+ const detalhe = 'o universo da busca nao foi lido inteiro; nada foi embedado';
4009
+ if (args.opcoes.json === true)
4010
+ console.log(JSON.stringify({ motivo, detalhe }, null, 2));
4011
+ else
4012
+ console.error(`memory.index: ${motivo}; ${detalhe}`);
4013
+ return 1;
4014
+ }
3654
4015
  const alvos = modelo === 'todos' ? ['primario', 'fallback'] : [modelo];
3655
4016
  const resultados = alvos.map(alvo => (0, indice_vetorial_1.indexar)({ raiz: carregado.raiz, tenant: memoria.estado.tenant,
3656
4017
  dsn: driver.dsn, config, alvo, universo, dryRun: args.opcoes['dry-run'] === true,
@@ -3663,7 +4024,7 @@ function comandoMemory(args) {
3663
4024
  }
3664
4025
  else {
3665
4026
  for (const r of resultados)
3666
- console.log(textoDoIndice(r));
4027
+ console.log((0, indice_vetorial_1.textoDoIndice)(r));
3667
4028
  }
3668
4029
  return resultados.some(r => !r.dryRun && r.motivo) ? 1 : 0;
3669
4030
  }
@@ -3675,7 +4036,7 @@ function avisoRoadmapSemAssociacao(nome, roadmap) {
3675
4036
  const item = /\bRM-\d{3}\b/i.exec(nome)?.[0].toUpperCase();
3676
4037
  if (!item || roadmap)
3677
4038
  return null;
3678
- return `Aviso: ${item} no nome não associa a thread ao roadmap. No terminal, consulte ork roadmap reservas e ork fabrica; para associar e reservar, use --roadmap ${item} em ork thread new. Nenhuma reserva foi criada por este aviso.`;
4039
+ return (0, locale_1.msg)().thread.roadmapNoNome(item);
3679
4040
  }
3680
4041
  /**
3681
4042
  * `ork memory search --texto` (I-38 D7): busca por significado, separada da busca por tag.
@@ -3701,51 +4062,43 @@ function buscaPorTexto(args, carregado) {
3701
4062
  const memoria = (0, memoria_1.abrirMemoria)(carregado);
3702
4063
  const config = (0, manifest_1.configDeEmbedding)(carregado.manifesto);
3703
4064
  let r;
4065
+ const vazio = { texto: frase, modo, origem: 'nenhum', modeloUsado: null, deterministico: false,
4066
+ resultados: [], listas: { vetor: [], fts: [] }, ftsForaDoUniverso: 0, coberturaDoIndice: null };
4067
+ let universo = null;
4068
+ let falhaDoUniverso = '';
4069
+ if (memoria.ativo) {
4070
+ try {
4071
+ universo = (0, indice_vetorial_1.universoDaBusca)(memoria, memoria.estado.tenant);
4072
+ }
4073
+ catch (erro) {
4074
+ falhaDoUniverso = (0, indice_vetorial_1.codigoDaFalha)(erro);
4075
+ }
4076
+ }
3704
4077
  if (!memoria.ativo) {
3705
- r = { texto: frase, modo, origem: 'nenhum', modeloUsado: null, deterministico: false, motivo: memoria.estado.motivo,
3706
- detalhe: `${memoria.estado.detalhe}; correcao: ${memoria.estado.correcao}`, resultados: [], listas: { vetor: [], fts: [] } };
4078
+ r = { ...vazio, motivo: memoria.estado.motivo, detalhe: `${memoria.estado.detalhe}; correcao: ${memoria.estado.correcao}` };
4079
+ }
4080
+ else if (!universo) {
4081
+ // RM-038: sem o universo inteiro nao ha busca; o motivo tipado sai, nunca um resultado parcial.
4082
+ r = { ...vazio, motivo: falhaDoUniverso, detalhe: 'o universo da busca nao foi lido inteiro; nada foi buscado' };
3707
4083
  }
3708
4084
  else {
3709
4085
  const driver = (0, orkmind_1.configDoManifesto)(carregado.manifesto);
3710
4086
  const transporte = new orkmind_1.DriverCliOrkMind(driver);
3711
4087
  const fallback = memoria.estado.embeddings?.fallback;
3712
4088
  r = (0, busca_semantica_1.buscarPorSignificado)({ raiz: carregado.raiz, tenant: memoria.estado.tenant, dsn: driver.dsn, config,
3713
- universo: (0, indice_vetorial_1.universoDoTenant)(memoria, memoria.estado.tenant, colecao ? [colecao] : orkmind_1.COLECOES_DO_ORK),
4089
+ universo, colecao: colecao,
3714
4090
  texto: frase, modo, limite, timeoutMs: driver.timeoutMs,
3715
4091
  chavePresente: memoria.estado.embeddings?.chavePresente === true,
3716
4092
  fallbackUsavel: memoria.estado.embeddings?.sondado === true && fallback?.dependencias === true,
3717
4093
  embeddar: (p, o) => transporte.embeddar(p, o), buscarTexto: (t, q) => transporte.buscarTexto(t, q) });
3718
4094
  }
4095
+ const codigo = universo ? 0 : 1;
3719
4096
  if (args.opcoes.json === true) {
3720
4097
  console.log(JSON.stringify(r, null, 2));
3721
- return 0;
4098
+ return codigo;
3722
4099
  }
3723
- console.log(`Busca por significado (NAO deterministica; modo ${r.modo}, origem ${r.origem}${r.modeloUsado ? ` ${r.modeloUsado}` : ''})`);
3724
- if (r.motivo)
3725
- console.log(` motivo: ${r.motivo}${r.detalhe ? `; ${r.detalhe}` : ''}`);
3726
- console.log('');
3727
- r.resultados.forEach((e, i) => {
3728
- const sim = e.similaridade === null ? '' : ` similaridade ${e.similaridade}`;
3729
- console.log(` ${i + 1}. [${e.collection}] ${e.id} score ${e.score} ${e.fontes.join('+')}${sim}`);
3730
- console.log(` ${e.resumo}`);
3731
- });
3732
- console.log('');
3733
- console.log(` ${r.resultados.length} resultado(s); busca por tag continua em ork memory search --tags`);
3734
- return 0;
3735
- }
3736
- /** Texto de `ork memory index`: o que foi (ou seria) embedado e quanto custa estimado. */
3737
- function textoDoIndice(r) {
3738
- const custo = r.custoEstimadoUsd === null ? 'nao estimado' : `US$ ${r.custoEstimadoUsd.toFixed(8)}`;
3739
- return [
3740
- `Indice vetorial (${r.alvo}${r.dryRun ? ', --dry-run' : ''}): ${r.modelo ?? '(sem modelo)'}${r.dim ? ` / ${r.dim} dim` : ''}`,
3741
- ` universo do tenant ${r.universo} entrada(s); coerentes ${r.coerentes}`,
3742
- ` embedados ${r.embedados} (reescritos ${r.reescritos}); removidos ${r.removidos}`,
3743
- ` fora do indice ${r.recusados} recusada(s) por padrao de segredo, ${r.foraDoLimite} acima do limite`,
3744
- ...(r.truncados ? [` truncados ${r.truncados} acima do contexto do modelo local, embedados pelo comeco`] : []),
3745
- ` estimativa ${r.tokensEstimados} token(s), ${custo}; chamadas ao provider ${r.chamadasAoProvider}`,
3746
- ...(r.arquivo ? [` arquivo ${r.arquivo}`] : []),
3747
- ...(r.motivo ? [` motivo ${r.motivo}: ${r.detalhe}`] : r.detalhe ? [` ${r.detalhe}`] : []),
3748
- ].join('\n');
4100
+ console.log((0, busca_semantica_1.textoDaBuscaPorSignificado)(r));
4101
+ return codigo;
3749
4102
  }
3750
4103
  /**
3751
4104
  * RM-052: `--projeto <nome|caminho>` e opcao GLOBAL. Sai do argv em qualquer posicao, antes de
@@ -3775,24 +4128,58 @@ function extrairOpcaoDeProjeto(argv) {
3775
4128
  }
3776
4129
  /** Comandos que nao leem projeto: o alvo nao e resolvido (nem recusado) para eles. */
3777
4130
  const COMANDOS_SEM_PROJETO = new Set(['demo', 'ciclos', 'mcp', 'init', 'projetos']);
4131
+ /**
4132
+ * Fatia 2 (D3): os comandos que leem projeto e nao terminam com a linha `Projeto consultado`. Hoje so
4133
+ * o `sessions event`, o sensor dos hooks do Claude Code: maquina falando com maquina, e o sensor compara
4134
+ * o stderr da recusa. O `maestro` declara no snapshot e nao passa por aqui.
4135
+ */
4136
+ const SEM_DECLARACAO_DO_PROJETO = new Set(['sessions event']);
3778
4137
  /**
3779
4138
  * Comandos cujo `--projeto` e DELES (RM-054: `ork network roadmap --projeto github:dono/repo`, que
3780
4139
  * le varios projetos). A opcao volta intacta ao argv do subcomando e o alvo global nao e resolvido:
3781
4140
  * nem `--projeto`, nem `ORK_PROJETO`, nem o modo host escolhem um projeto por eles.
3782
4141
  */
3783
4142
  exports.COMANDOS_COM_PROJETO_PROPRIO = new Set(['network']);
3784
- /** Resolve e fixa o projeto-alvo do processo (D2, D3). `null`: vale o cwd de sempre. */
3785
- function fixarAlvoDoProcesso(projeto) {
4143
+ /**
4144
+ * Resolve e fixa o projeto-alvo do processo (D2, D3). `null`: vale o cwd de sempre. Fatia 2 (D3): com
4145
+ * `declarar`, o comando termina dizendo qual projeto leu, quando o leitor nao tem como saber.
4146
+ */
4147
+ function fixarAlvoDoProcesso(projeto, declarar = true) {
3786
4148
  const alvo = (0, projeto_alvo_1.resolverProjetoAlvo)({ opcao: projeto ?? null });
3787
4149
  (0, projeto_alvo_1.fixarProjetoAlvo)(alvo);
4150
+ if (declarar)
4151
+ (0, projeto_alvo_1.pedirDeclaracaoDoProjeto)(alvo);
3788
4152
  return alvo;
3789
4153
  }
4154
+ /**
4155
+ * RM-052 (fatia 2, D3): o comando que leu um projeto que o leitor nao tem como adivinhar (no host, ou
4156
+ * fora do diretorio dele) escreve no fim a linha `Projeto consultado: ...` no stderr, salvo se ja montou
4157
+ * o proprio cabecalho. Quando ele falha, a linha sai antes da mensagem de erro, que a entrada imprime.
4158
+ */
3790
4159
  function main(argvBruto) {
3791
4160
  // I-35: todo horário para pessoa sai no fuso do dono deste projeto (lido só se for preciso, e já
3792
4161
  // depois de o projeto-alvo abaixo estar fixado: a fonte é preguiçosa).
3793
4162
  (0, horario_1.registrarFonteDoFuso)(() => (0, horario_1.fusoDoManifesto)((0, manifest_1.carregarManifesto)()));
3794
4163
  // RM-052: sem alvo herdado de uma chamada anterior no mesmo processo (os testes chamam `main` em serie).
3795
4164
  (0, projeto_alvo_1.fixarProjetoAlvo)(null);
4165
+ // Prova de conceito do CLI por locale: cada chamada comeca em pt-BR; so os comandos cobertos trocam.
4166
+ (0, locale_1.ativarLocale)(undefined);
4167
+ // RM-061 (F2b, D1): e sem o registro dos textos remontaveis, que so os comandos cobertos ligam.
4168
+ (0, locale_1.ligarRemontagem)(false);
4169
+ (0, projeto_alvo_1.iniciarDeclaracaoDoProjeto)();
4170
+ try {
4171
+ return executarComando(argvBruto);
4172
+ }
4173
+ finally {
4174
+ // RM-061 (F2b): o registro dos textos remontaveis nao sobrevive a chamada (o locale sim: a entrada do CLI
4175
+ // ainda imprime o erro no locale do comando).
4176
+ (0, locale_1.ligarRemontagem)(false);
4177
+ const linha = (0, projeto_alvo_1.declaracaoQueFaltou)();
4178
+ if (linha)
4179
+ console.error(linha);
4180
+ }
4181
+ }
4182
+ function executarComando(argvBruto) {
3796
4183
  const extraida = extrairOpcaoDeProjeto(argvBruto);
3797
4184
  const proprio = exports.COMANDOS_COM_PROJETO_PROPRIO.has(parseArgs(extraida.argv).posicionais[0] ?? '');
3798
4185
  const argv = proprio && extraida.projeto !== undefined
@@ -3819,8 +4206,9 @@ function main(argvBruto) {
3819
4206
  if (argv[0] === 'maestro') {
3820
4207
  if (argv.length === 2 && argv[1] === '--help')
3821
4208
  return (0, maestro_cli_1.runMaestroCli)(argv.slice(1));
3822
- // RM-052: o alvo explicito vira SELECAO entre as raizes permitidas; sem ele, o cwd de sempre.
3823
- const alvo = fixarAlvoDoProcesso(projeto);
4209
+ // RM-052: o alvo explicito vira SELECAO entre as raizes permitidas; sem ele, o cwd de sempre. O
4210
+ // snapshot ja declara o projeto consultado (project.root, notConsulted): sem a linha da fatia 2.
4211
+ const alvo = fixarAlvoDoProcesso(projeto, false);
3824
4212
  return alvo ? (0, maestro_cli_1.runMaestroCli)(argv.slice(1), alvo.raiz, { allowedRoots: [alvo.raiz], selected: alvo.raiz })
3825
4213
  : (0, maestro_cli_1.runMaestroCli)(argv.slice(1));
3826
4214
  }
@@ -3832,11 +4220,13 @@ function main(argvBruto) {
3832
4220
  return 0;
3833
4221
  }
3834
4222
  if (!comando || args.opcoes.help === true || comando === 'help') {
3835
- console.log(AJUDA);
4223
+ (0, locale_1.ativarLocale)(localeDaAjuda(projeto));
4224
+ console.log((0, locale_1.msg)().ajuda.texto(dadosDaAjuda()));
3836
4225
  return 0;
3837
4226
  }
3838
- if (!COMANDOS_SEM_PROJETO.has(comando) && !proprio)
3839
- fixarAlvoDoProcesso(projeto);
4227
+ if (!COMANDOS_SEM_PROJETO.has(comando) && !proprio) {
4228
+ fixarAlvoDoProcesso(projeto, !SEM_DECLARACAO_DO_PROJETO.has(`${comando} ${args.posicionais[1] ?? ''}`.trim()));
4229
+ }
3840
4230
  else if (projeto !== undefined && comando !== 'projetos') {
3841
4231
  throw new Error(comando === 'init'
3842
4232
  ? 'uso: ork init cria o projeto no diretório atual; entre nele e rode ork init, sem --projeto'
@@ -3854,6 +4244,13 @@ function main(argvBruto) {
3854
4244
  for (const nome of runtime_ambiente_1.ENVS_DE_PROVIDER_PAGO)
3855
4245
  delete process.env[nome];
3856
4246
  }
4247
+ // CLI por locale (RM-061, EN1 e EN7): a escolha do onboarding (owner.language) ou o LC_ALL/LC_MESSAGES/LANG
4248
+ // decidem a lingua do TEXTO dos comandos cobertos (`cobreLocale`); `--json` e contrato, e os recortes da D2
4249
+ // da F2a (`doctor --modo`, `thread new --from-finding` e os subcomandos fora da lista) ficam em pt-BR.
4250
+ if ((0, locale_1.cobreLocale)(args.posicionais, args.opcoes)) {
4251
+ (0, locale_1.ativarLocale)((0, locale_1.resolverLocale)(ambienteManifesto?.manifesto.owner?.language).locale);
4252
+ (0, locale_1.ligarRemontagem)(true);
4253
+ }
3857
4254
  switch (comando) {
3858
4255
  case 'mcp': {
3859
4256
  const projeto = texto(args.opcoes.project), host = texto(args.opcoes.host), threadId = texto(args.opcoes.thread);
@@ -3896,39 +4293,48 @@ function main(argvBruto) {
3896
4293
  console.log((0, preflight_1.textoPreflight)(r));
3897
4294
  return r.prontoPrimeiroBloco ? 0 : 1;
3898
4295
  }
3899
- const r = (0, doctor_1.doctor)((0, manifest_1.diretorioDoProjeto)(), nomesHerdados);
4296
+ // RM-031: o check dos analisadores do grafo entra por aqui, a porta da familia do grafo (fronteira do KG1).
4297
+ // RM-061 (F2a): a redacao do check vem do catalogo, no locale do comando (a familia do grafo nao o importa).
4298
+ const r = (0, doctor_1.doctor)((0, manifest_1.diretorioDoProjeto)(), nomesHerdados, () => (0, intelligence_graph_cli_1.checarAnalisadoresDoGrafo)(versao_1.VERSAO_DO_ORK, undefined, undefined, (0, locale_1.msg)().doctor.grafo));
3900
4299
  console.log(r.texto);
3901
4300
  return r.codigo;
3902
4301
  }
3903
4302
  case 'init': {
4303
+ (0, init_1.exigirRepositorioParaInit)(process.cwd());
4304
+ // RM-061 (F3a, D1 e D2): os arquivos nascem na lingua do dono no momento da geracao, resolvida pelo manifesto lido
4305
+ // antes do `--force` regrava-lo (o YAML e o AGENTS.md saem na mesma lingua) e independente do texto impresso, que
4306
+ // nao segue o locale com `--json` (GO-FIX do CHECK, W3).
4307
+ const localeDosArquivos = (0, locale_1.resolverLocale)(ambienteManifesto?.manifesto.owner?.language).locale;
3904
4308
  const r = (0, init_1.init)(process.cwd(), {
3905
4309
  force: args.opcoes.force === true,
3906
4310
  nome: texto(args.opcoes.name) ?? texto(args.opcoes.nome),
3907
4311
  abbrev: texto(args.opcoes.abbrev),
4312
+ locale: localeDosArquivos,
3908
4313
  });
3909
4314
  const carregado = (0, manifest_1.exigirManifesto)(r.deteccao.raiz);
3910
- const agents = (0, agents_md_1.atualizarAgentsMd)(r.deteccao.raiz, carregado.manifesto);
4315
+ const agents = (0, agents_md_1.atualizarAgentsMd)(r.deteccao.raiz, carregado.manifesto, localeDosArquivos);
3911
4316
  // RM-052 (D7): o projeto entra no registro desta maquina; falha vira aviso, nunca derruba o init.
3912
4317
  const avisoDoRegistro = (0, projeto_alvo_1.registrarProjetoEmSilencio)(r.deteccao.raiz, 'init');
3913
4318
  if (avisoDoRegistro)
3914
4319
  console.error(avisoDoRegistro);
4320
+ const m = (0, locale_1.msg)().init, estadoAgents = m.estadosAgents[agents.estado] ?? agents.estado;
3915
4321
  if (!r.criado) {
3916
- console.log(`Manifesto ja existe: ${r.caminho}`);
3917
- console.log('Nada foi sobrescrito. Use --force para regerar.');
3918
- console.log(`AGENTS.md ${agents.estado}: ${agents.caminho}`);
4322
+ console.log(m.jaExiste(r.caminho));
4323
+ console.log(m.nadaSobrescrito);
4324
+ console.log(m.agentsMd(estadoAgents, agents.caminho));
3919
4325
  return 0;
3920
4326
  }
3921
- console.log(`Manifesto criado: ${r.caminho}`);
3922
- console.log(` projeto ${r.deteccao.nome} (abbrev "${r.deteccao.abbrev}")`);
3923
- console.log(` branch base ${r.deteccao.baseBranch}`);
3924
- console.log(` gerenciador ${r.deteccao.gerenciador}`);
3925
- console.log(` verify ${Object.entries(r.deteccao.verify).map(([k, v]) => `${k}="${v}"`).join(', ') || '(nenhum script detectado)'}`);
3926
- console.log(` AGENTS.md ${agents.estado}: ${agents.caminho}`);
4327
+ console.log(m.criado(r.caminho));
4328
+ console.log(m.projeto(r.deteccao.nome, r.deteccao.abbrev));
4329
+ console.log(m.branchBase(r.deteccao.baseBranch));
4330
+ console.log(m.gerenciador(r.deteccao.gerenciador));
4331
+ console.log(m.verify(Object.entries(r.deteccao.verify).map(([k, v]) => `${k}="${v}"`).join(', ') || m.semScript));
4332
+ console.log(m.agentsMdLinha(estadoAgents, agents.caminho));
3927
4333
  // Fatia 2 do ensaio da 0.5.0 (P3): o estado fica fora do git por um `.gitignore` proprio.
3928
4334
  if (r.estadoIgnorado)
3929
- console.log(` estado ${manifest_1.DIR_ESTADO}/ fora do git (${manifest_1.DIR_ESTADO}/.gitignore com *; o seu .gitignore fica como está)`);
4335
+ console.log(m.estado(manifest_1.DIR_ESTADO));
3930
4336
  console.log('');
3931
- console.log(init_2.PROXIMO_PASSO_INIT);
4337
+ console.log(m.proximoPasso);
3932
4338
  return 0;
3933
4339
  }
3934
4340
  case 'modos': {
@@ -3996,16 +4402,17 @@ function main(argvBruto) {
3996
4402
  }
3997
4403
  if ((args.posicionais[1] ?? 'show') !== 'show' || args.posicionais.length > 2 ||
3998
4404
  Object.keys(args.opcoes).some(k => k !== 'json') || ('json' in args.opcoes && args.opcoes.json !== true)) {
3999
- throw Error('uso: ork experiencia show [--json]');
4405
+ throw Error((0, locale_1.msg)().onboarding.experienciaUso);
4000
4406
  }
4001
4407
  const manifesto = (0, manifest_1.exigirManifesto)(), p = (0, experiencia_1.resolverExperiencia)(manifesto.manifesto.owner);
4002
4408
  // Preferência inválida vale o padrão e faz o adapter install pular o pacote: a consulta avisa.
4003
4409
  const avisos = manifesto.avisos.filter(a => a.startsWith('experiencia.config.invalid'));
4410
+ const m = (0, locale_1.msg)().onboarding;
4004
4411
  console.log(args.opcoes.json ? JSON.stringify({ ...p, avisos }, null, 2) :
4005
- `Experiência ${p.experience ? 'ativa' : 'desativada'}: ${p.language}, ${p.timezone}, profundidade ${p.depth}.\nSkill: ${p.skill}\n` +
4412
+ `${m.experiencia(p.experience, p.language, p.timezone, p.depth)}\nSkill: ${p.skill}\n` +
4006
4413
  // Fatia 2 do ensaio da 0.5.0 (R2): as origens em texto, e nao o JSON cru.
4007
- `Origens: ${Object.entries(p.origem).map(([chave, origem]) => `${chave} ${origem}`).join(', ')}` +
4008
- avisos.map(a => `\nAviso: ${a}; o adapter install pula o pacote até ork onboarding set maestro corrigir.`).join(''));
4414
+ m.experienciaOrigens(Object.entries(p.origem).map(([chave, origem]) => `${chave} ${m.origemDaPreferencia(origem)}`).join(', ')) +
4415
+ avisos.map(a => `\n${m.experienciaAviso(m.avisoDaPreferencia(a))}`).join(''));
4009
4416
  return 0;
4010
4417
  }
4011
4418
  case 'thread':
@@ -4040,10 +4447,12 @@ function main(argvBruto) {
4040
4447
  }
4041
4448
  if (args.posicionais[1] === 'cadencia')
4042
4449
  return comandoCadenciaDoPulse(args);
4043
- const p = (0, pulse_1.montarPulse)((0, manifest_1.exigirManifesto)(), { registrar: args.opcoes.registrar === true,
4450
+ // RM-061 (F2b, G2): o pulse grava (sensores, condução) e monta o --json em pt-BR; so o texto segue o locale.
4451
+ const carregadoDoPulse = (0, manifest_1.exigirManifesto)();
4452
+ const p = (0, locale_1.comLocale)('pt-BR', () => (0, pulse_1.montarPulse)(carregadoDoPulse, { registrar: args.opcoes.registrar === true,
4044
4453
  escopo: texto(args.opcoes.escopo)?.split(',').map(s => s.trim()),
4045
4454
  semRuntime: args.opcoes['sem-runtime'] === true,
4046
- linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)) });
4455
+ linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)) }));
4047
4456
  console.log(args.opcoes.json === true ? JSON.stringify(p, null, 2) : (0, pulse_1.textoDoPulse)(p));
4048
4457
  return p.runtime.ok || args.opcoes['sem-runtime'] === true ? 0 : 1;
4049
4458
  }
@@ -4075,7 +4484,9 @@ function main(argvBruto) {
4075
4484
  case 'grafo': {
4076
4485
  // RM-031 KG3 (D7): o argv cru depois do comando; o parser do grafo e estrito.
4077
4486
  const carregado = (0, manifest_1.exigirManifesto)();
4078
- return (0, intelligence_graph_cli_1.executarGrafo)(argv.slice(argv.indexOf('grafo') + 1), { raiz: carregado.raiz, estado: (0, estado_thread_1.raizDoEstado)(carregado.raiz), repositorio: carregado.manifesto.project.name, escrever: (texto) => console.log(texto) });
4487
+ return (0, intelligence_graph_cli_1.executarGrafo)(argv.slice(argv.indexOf('grafo') + 1), { raiz: carregado.raiz, estado: (0, estado_thread_1.raizDoEstado)(carregado.raiz), repositorio: carregado.manifesto.project.name, versao: versao_1.VERSAO_DO_ORK,
4488
+ contextoDaThread: (id) => (0, mcp_grafo_1.lerEntradaDaThread)(carregado.raiz, id),
4489
+ escrever: (texto) => console.log(texto) });
4079
4490
  }
4080
4491
  case 'ship':
4081
4492
  return comandoShip(args);
@@ -4123,8 +4534,9 @@ function main(argvBruto) {
4123
4534
  console.log((0, ciclos_1.tabelaDeVariantes)());
4124
4535
  return 0;
4125
4536
  default:
4126
- console.error(`comando desconhecido: ${comando}`);
4127
- console.log(AJUDA);
4537
+ (0, locale_1.ativarLocale)(localeDaAjuda());
4538
+ console.error((0, locale_1.msg)().ajuda.comandoDesconhecido(comando));
4539
+ console.log((0, locale_1.msg)().ajuda.texto(dadosDaAjuda()));
4128
4540
  return 2;
4129
4541
  }
4130
4542
  }
@@ -4138,13 +4550,20 @@ if (require.main === module) {
4138
4550
  console.log(process.argv.includes('--json') ? JSON.stringify(e.recusa, null, 2) : e.recusa.texto);
4139
4551
  process.exitCode = 3;
4140
4552
  }
4553
+ else if (e instanceof fila_pesada_1.ErroDaFilaPesada) {
4554
+ // RM-058 N2 (D10): a fila pesada que nao deu a vez no prazo responde como a conducao: o texto ou o JSON, e 3.
4555
+ console.log(process.argv.includes('--json') ? JSON.stringify(e.recusa, null, 2) : e.recusa.texto);
4556
+ process.exitCode = 3;
4557
+ }
4141
4558
  else if (e instanceof projeto_alvo_1.ErroDeProjeto) {
4142
4559
  // RM-052 (D3): a recusa de projeto-alvo e a resposta (a escolha, os candidatos), nao um stack trace.
4143
4560
  console.log(process.argv.includes('--json') ? JSON.stringify(e.recusa, null, 2) : e.texto);
4144
4561
  process.exitCode = projeto_alvo_1.SAIDA_DE_PROJETO;
4145
4562
  }
4146
4563
  else {
4147
- console.error(`erro: ${e.message}`);
4564
+ // RM-061 (F2a, D11): o prefixo segue o locale do comando coberto; a mensagem sai como veio, salvo o
4565
+ // erro do catalogo, remontado no locale do comando (D14).
4566
+ console.error((0, locale_1.msg)().cli.erro((0, locale_1.mensagemDoErro)(e)));
4148
4567
  process.exitCode = 1;
4149
4568
  }
4150
4569
  }