@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
@@ -33,9 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.refRemota = void 0;
36
+ exports.refRemota = exports.shaValido = exports.remotoValido = exports.REMOTO_DO_GIT = void 0;
37
37
  exports.git = git;
38
38
  exports.exigirGit = exigirGit;
39
+ exports.remotoRedigido = remotoRedigido;
40
+ exports.exigirRemoto = exigirRemoto;
41
+ exports.branchValida = branchValida;
39
42
  exports.pontaLocal = pontaLocal;
40
43
  exports.buscarBranch = buscarBranch;
41
44
  exports.jsonsDaPonta = jsonsDaPonta;
@@ -57,6 +60,7 @@ const node_child_process_1 = require("node:child_process");
57
60
  const fs = __importStar(require("node:fs"));
58
61
  const os = __importStar(require("node:os"));
59
62
  const path = __importStar(require("node:path"));
63
+ const redacao_url_1 = require("./redacao-url");
60
64
  function git(raiz, args, extra = {}) {
61
65
  const r = (0, node_child_process_1.spawnSync)('git', args, { cwd: raiz, encoding: 'utf8', input: extra.input, timeout: extra.timeoutMs ?? 60000,
62
66
  env: { ...process.env, ...extra.env } });
@@ -68,6 +72,63 @@ function exigirGit(raiz, args, prefixo, extra = {}) {
68
72
  throw new Error(`${prefixo}.git: git ${args[0]} falhou: ${r.stderr.trim().split('\n').pop() ?? ''}`);
69
73
  return r.stdout;
70
74
  }
75
+ /**
76
+ * Nome de remoto do git, como `origin`, `upstream` ou `meu-remoto.2`. O valor vem do manifesto
77
+ * versionado (`fabrica.remoto`) ou da linha de comando (`--remoto`): quem clona um repositorio roda
78
+ * o `orkastery.yaml` de outra pessoa. Um valor que comece com `-` viraria opcao do git, e uma URL
79
+ * escolheria o transporte (`ext::` roda comando): so este formato chega ao git (RM-047).
80
+ */
81
+ exports.REMOTO_DO_GIT = /^[A-Za-z0-9][A-Za-z0-9._-]*(?:\/[A-Za-z0-9][A-Za-z0-9._-]*)*$/;
82
+ /**
83
+ * `true` quando o valor e nome de remoto que pode ir ao git como argumento. Suspeitas da revisao de
84
+ * 03/10: o git aceita `/` no nome (`time/origem`), e a 0.5.2 tambem; cada parte comeca por letra ou
85
+ * digito, entao a barra nao abre caminho absoluto, `.`/`..`, opcao nem transporte.
86
+ */
87
+ const remotoValido = (remoto) => typeof remoto === 'string' && remoto.length <= 64 && exports.REMOTO_DO_GIT.test(remoto) && !remoto.includes('..') && !remoto.endsWith('.');
88
+ exports.remotoValido = remotoValido;
89
+ /**
90
+ * O valor recusado, para a mensagem: sem credencial de URL, sem caractere de controle e curto.
91
+ * A mensagem vai ao terminal, ao log da publicacao em segundo plano e ao ledger.
92
+ */
93
+ function remotoRedigido(remoto) {
94
+ if (typeof remoto !== 'string')
95
+ return `(${remoto === null ? 'null' : typeof remoto})`;
96
+ const semCredencial = (0, redacao_url_1.redigirCredenciaisUrl)(remoto);
97
+ const curto = semCredencial.length > 40 ? `${semCredencial.slice(0, 40)}...` : semCredencial;
98
+ return JSON.stringify(curto);
99
+ }
100
+ /**
101
+ * Recusa tipada (`<prefixo>.remoto-invalido`) antes de qualquer chamada ao git com o remoto.
102
+ * `prefixo` e o de quem usa: `fabrica` na fabrica, `roadmap` nas reservas.
103
+ */
104
+ function exigirRemoto(remoto, prefixo) {
105
+ if ((0, exports.remotoValido)(remoto))
106
+ return remoto;
107
+ throw new Error(`${prefixo}.remoto-invalido: o remoto ${remotoRedigido(remoto)} não é nome de remoto do git ` +
108
+ '(letras, dígitos, ".", "_", "-" e "/" entre partes, cada parte começando por letra ou dígito, sem URL); nada foi passado ao git. ' +
109
+ 'Corrija fabrica.remoto no orkastery.yaml ou --remoto (padrão: origin).');
110
+ }
111
+ /**
112
+ * RM-047 (fronteira de confiança): nome de branch que pode ir ao git como argumento. O valor vem do
113
+ * `worktree.base_branch` do manifesto, do campo `para` do ledger ou do frontmatter, e todos podem ser
114
+ * do clone: um nome que começa com `-` viraria opção do git (`--output=<arquivo>` grava arquivo).
115
+ * A regra é a do `git check-ref-format --branch`, então nenhum nome que o git aceite é recusado.
116
+ */
117
+ function branchValida(branch) {
118
+ if (typeof branch !== 'string' || branch.length === 0 || branch.length > 255)
119
+ return false;
120
+ if (branch.startsWith('-') || branch === '@' || branch.includes('..') || branch.includes('@{'))
121
+ return false;
122
+ // eslint-disable-next-line no-control-regex
123
+ if (/[\x00-\x20\x7f~^:?*[\\]/.test(branch))
124
+ return false;
125
+ if (branch.startsWith('/') || branch.endsWith('/') || branch.includes('//') || branch.endsWith('.'))
126
+ return false;
127
+ return branch.split('/').every((parte) => !parte.startsWith('.') && !parte.endsWith('.lock'));
128
+ }
129
+ /** Sha hexadecimal (abreviado ou inteiro, SHA-1 ou SHA-256): o único formato de commit lido do ledger que vai ao git. */
130
+ const shaValido = (sha) => typeof sha === 'string' && /^[0-9a-f]{7,64}$/i.test(sha);
131
+ exports.shaValido = shaValido;
71
132
  const refRemota = (remoto, branch) => `refs/remotes/${remoto}/${branch}`;
72
133
  exports.refRemota = refRemota;
73
134
  /** A ultima copia lida da branch nesta maquina, sem rede. `null` quando nunca foi lida. */
@@ -80,16 +141,32 @@ function pontaLocal(raiz, remoto, branch) {
80
141
  * copia local com `atualizado: false`.
81
142
  */
82
143
  function buscarBranch(raiz, remoto, branch, prefixo, timeoutMs, env) {
83
- const r = git(raiz, ['fetch', '--quiet', '--no-tags', remoto, `+refs/heads/${branch}:${(0, exports.refRemota)(remoto, branch)}`], { timeoutMs, env });
84
- if (r.ok)
85
- return { ponta: exigirGit(raiz, ['rev-parse', '--verify', (0, exports.refRemota)(remoto, branch)], prefixo).trim(), atualizado: true };
86
- if (/couldn't find remote ref|could not find remote ref/i.test(r.stderr)) {
87
- // A branch ainda nao nasceu: a primeira gravacao a cria. Copia local antiga nao vale mais.
88
- git(raiz, ['update-ref', '-d', (0, exports.refRemota)(remoto, branch)]);
89
- return { ponta: null, atualizado: true };
144
+ exigirRemoto(remoto, prefixo);
145
+ for (let tentativa = 1;; tentativa++) {
146
+ // `--`: daqui para a frente, so repositorio e refspec, nunca opcao (RM-047).
147
+ const r = git(raiz, ['fetch', '--quiet', '--no-tags', '--', remoto, `+refs/heads/${branch}:${(0, exports.refRemota)(remoto, branch)}`], { timeoutMs, env });
148
+ if (r.ok)
149
+ return { ponta: exigirGit(raiz, ['rev-parse', '--verify', (0, exports.refRemota)(remoto, branch)], prefixo).trim(), atualizado: true };
150
+ if (/couldn't find remote ref|could not find remote ref/i.test(r.stderr)) {
151
+ // A branch ainda nao nasceu: a primeira gravacao a cria. Copia local antiga nao vale mais.
152
+ git(raiz, ['update-ref', '-d', (0, exports.refRemota)(remoto, branch)]);
153
+ return { ponta: null, atualizado: true };
154
+ }
155
+ if (tentativa < TENTATIVAS_NA_DISPUTA_DE_REF && DISPUTA_DE_REF.test(r.stderr)) {
156
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50 * tentativa);
157
+ continue;
158
+ }
159
+ return { ponta: pontaLocal(raiz, remoto, branch), atualizado: false };
90
160
  }
91
- return { ponta: pontaLocal(raiz, remoto, branch), atualizado: false };
92
161
  }
162
+ /**
163
+ * Suspeitas da revisao de 03/10: dois `fetch` simultaneos na mesma copia (o `ork network status` e a
164
+ * publicacao no cache da casa, a leitura e a gravacao da fabrica no clone) disputam o lock da ref
165
+ * remota, e o perdedor sai com "incorrect old value provided" (ou "cannot lock ref") sem que a rede
166
+ * tenha falhado. A ref ja foi atualizada pelo vencedor: buscar de novo da certo.
167
+ */
168
+ const DISPUTA_DE_REF = /incorrect old value provided|cannot lock ref|unable to create '[^']*\.lock'|is at [0-9a-f]+ but expected/i;
169
+ const TENTATIVAS_NA_DISPUTA_DE_REF = 5;
93
170
  /** Os `.json` de um diretorio da ponta, ja lidos. Filtro por caminho: diretorio vazio some da arvore. */
94
171
  function jsonsDaPonta(raiz, ponta, dir, prefixo) {
95
172
  if (!ponta)
@@ -103,6 +180,7 @@ function jsonsDaPonta(raiz, ponta, dir, prefixo) {
103
180
  * indice temporario, blobs, `write-tree` e `commit-tree`. Push sem forca; recusa volta `false`.
104
181
  */
105
182
  function gravarNaBranch(raiz, remoto, branch, ponta, mudancas, mensagem, prefixo, rede = {}) {
183
+ exigirRemoto(remoto, prefixo);
106
184
  const indice = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'ork-branch-estado-')), 'index');
107
185
  const env = { GIT_INDEX_FILE: indice };
108
186
  try {
@@ -122,7 +200,7 @@ function gravarNaBranch(raiz, remoto, branch, ponta, mudancas, mensagem, prefixo
122
200
  const arvore = exigirGit(raiz, ['write-tree'], prefixo, { env }).trim();
123
201
  const commit = exigirGit(raiz, ['commit-tree', arvore, ...(ponta ? ['-p', ponta] : []), '-m', mensagem], prefixo).trim();
124
202
  // `rede`: prazo e ambiente so do que vai a rede (RM-037, achado A3: o fechamento nao espera 60 s).
125
- const push = git(raiz, ['push', '--quiet', remoto, `${commit}:refs/heads/${branch}`], rede);
203
+ const push = git(raiz, ['push', '--quiet', '--', remoto, `${commit}:refs/heads/${branch}`], rede);
126
204
  if (push.ok) {
127
205
  git(raiz, ['update-ref', (0, exports.refRemota)(remoto, branch), commit]);
128
206
  return commit;
@@ -6,10 +6,12 @@
6
6
  * deterministicos. Esta busca e superficie separada e todo resultado sai com
7
7
  * `deterministico: false`.
8
8
  *
9
- * O universo e o export governado do tenant (filtro de injecao e visibilidade da biblioteca):
9
+ * O universo e o universo da busca do tenant (RM-038: `universoDaBusca`, o mesmo do indice e do
10
+ * status, com a governanca da biblioteca aplicada na ponte):
10
11
  * - vetor: cosseno da consulta contra o indice local do MESMO modelo e dimensao, so para
11
12
  * entradas com sha256 coerente; nunca compara vetores de espacos diferentes;
12
- * - FTS: `search_by_text` da biblioteca, filtrado por tenant na ponte e intersectado aqui;
13
+ * - FTS: `search_by_text` da biblioteca, restrito ao universo na ponte e intersectado aqui (id
14
+ * fora do universo e descartado e declarado, nunca em silencio);
13
15
  * - fusao: RRF com k = 60.
14
16
  * A cadeia do vetor e primario, fallback local, nenhum; sem vetor, cai para FTS com motivo tipado.
15
17
  */
@@ -18,6 +20,7 @@ exports.CANDIDATOS_DO_VETOR = exports.LIMITE_MAXIMO_DA_BUSCA = exports.LIMITE_PA
18
20
  exports.cosseno = cosseno;
19
21
  exports.fundirRrf = fundirRrf;
20
22
  exports.buscarPorSignificado = buscarPorSignificado;
23
+ exports.textoDaBuscaPorSignificado = textoDaBuscaPorSignificado;
21
24
  const indice_vetorial_1 = require("./indice-vetorial");
22
25
  exports.MODOS_DE_BUSCA = ['hibrido', 'vetor', 'fts'];
23
26
  /** D9: constante da fusao RRF. */
@@ -44,7 +47,7 @@ function fundirRrf(listas, k = exports.RRF_K) {
44
47
  }
45
48
  const resumo = (conteudo) => conteudo.split('\n')[0].slice(0, 100);
46
49
  /** Lado vetorial: o primeiro caminho da cadeia que tem indice, responde e fala o mesmo espaco. */
47
- function ladoVetorial(o) {
50
+ function ladoVetorial(o, entradas) {
48
51
  const detalhes = [];
49
52
  let motivo = null;
50
53
  const falhar = (alvo, m, d) => {
@@ -103,7 +106,7 @@ function ladoVetorial(o) {
103
106
  }
104
107
  if (resposta.truncados?.length)
105
108
  detalhes.push(`${alvo}: consulta acima do contexto do modelo, embedada pelo comeco`);
106
- const ranking = [...(0, indice_vetorial_1.vetoresCoerentes)(lido.indice, o.universo)]
109
+ const ranking = [...(0, indice_vetorial_1.vetoresCoerentes)(lido.indice, entradas)]
107
110
  .map(([id, v]) => ({ id, sim: cosseno(vetor, v) }))
108
111
  .sort((a, b) => b.sim - a.sim || a.id.localeCompare(b.id));
109
112
  return { alvo, modelo: espaco.modelo, ranking, motivo, detalhes };
@@ -112,14 +115,21 @@ function ladoVetorial(o) {
112
115
  }
113
116
  /** `ork memory search --texto`: ranking hibrido, nunca deterministico, sempre dentro do tenant. */
114
117
  function buscarPorSignificado(o) {
115
- const universo = o.universo.filter(e => (e.tags.project ?? []).includes(o.tenant));
116
- const porId = new Map(universo.map(e => [e.id, e]));
118
+ // RM-038 (D6): entrada alheia no universo e violacao antes de embedar a consulta, nunca descarte.
119
+ if (o.universo.tenant !== o.tenant)
120
+ throw new Error('memory.query.scope-violation');
121
+ (0, indice_vetorial_1.conferirUniverso)(o.universo.entradas, o.tenant, o.universo.lidoEm);
122
+ const doUniverso = new Set(o.universo.entradas.map(e => e.id));
123
+ // As entradas buscadas: o universo inteiro, ou so a colecao pedida.
124
+ const buscadas = o.colecao ? o.universo.entradas.filter(e => e.collection === o.colecao) : o.universo.entradas;
125
+ const porId = new Map(buscadas.map(e => [e.id, e]));
117
126
  const saida = { texto: o.texto, modo: o.modo, origem: 'nenhum', modeloUsado: null,
118
- deterministico: false, motivo: null, detalhe: '', resultados: [], listas: { vetor: [], fts: [] } };
127
+ deterministico: false, motivo: null, detalhe: '', resultados: [], listas: { vetor: [], fts: [] },
128
+ ftsForaDoUniverso: 0, coberturaDoIndice: null };
119
129
  const detalhes = [];
120
130
  let similaridade = new Map();
121
131
  if (o.modo !== 'fts') {
122
- const v = ladoVetorial({ ...o, universo });
132
+ const v = ladoVetorial(o, buscadas);
123
133
  detalhes.push(...v.detalhes);
124
134
  saida.motivo = v.motivo;
125
135
  if (v.alvo) {
@@ -128,22 +138,33 @@ function buscarPorSignificado(o) {
128
138
  const candidatos = v.ranking.slice(0, exports.CANDIDATOS_DO_VETOR);
129
139
  saida.listas.vetor = candidatos.map(c => c.id);
130
140
  similaridade = new Map(candidatos.map(c => [c.id, c.sim]));
141
+ // RM-038 (D7): o vetor so ranqueia o que o indice cobre; menos que o universo e dito aqui.
142
+ saida.coberturaDoIndice = { coerentes: v.ranking.length, universo: buscadas.length };
143
+ const aviso = (0, indice_vetorial_1.avisoDeCobertura)(v.ranking.length, buscadas, v.alvo, o.colecao ? ` na colecao ${o.colecao}` : '');
144
+ if (aviso)
145
+ detalhes.push(`vetor: ${aviso}`);
131
146
  }
132
147
  }
133
148
  if (o.modo !== 'vetor') {
149
+ let ftsFalhou = false;
134
150
  try {
135
151
  if (!o.buscarTexto)
136
152
  throw new Error('memory.transport.fts');
137
- // A ponte ja filtra o tenant; a intersecao com o universo governado vale de novo aqui.
138
- saida.listas.fts = [...new Set(o.buscarTexto(o.tenant, o.texto))].filter(id => porId.has(id));
153
+ // A ponte ja restringe ao universo; a intersecao vale de novo aqui e a quantidade que sobra e declarada (D5).
154
+ const ids = [...new Set(o.buscarTexto(o.tenant, o.texto))];
155
+ saida.ftsForaDoUniverso = ids.filter(id => !doUniverso.has(id)).length;
156
+ if (saida.ftsForaDoUniverso)
157
+ detalhes.push(`fts: ${saida.ftsForaDoUniverso} id(s) fora do universo da busca descartado(s)`);
158
+ saida.listas.fts = ids.filter(id => porId.has(id));
139
159
  }
140
160
  catch (erro) {
141
- const codigo = /^[a-z]+(?:\.[a-z-]+)+/.exec(erro instanceof Error ? erro.message : '')?.[0] ?? 'memory.transport.fts';
161
+ ftsFalhou = true;
162
+ const codigo = (0, indice_vetorial_1.codigoDaFalha)(erro, 'memory.transport.fts');
142
163
  detalhes.push(`fts: ${codigo}`);
143
164
  if (o.modo === 'fts' || saida.origem === 'nenhum')
144
165
  saida.motivo = saida.motivo ?? codigo;
145
166
  }
146
- if (saida.origem === 'nenhum' && !detalhes.some(d => d.startsWith('fts:')))
167
+ if (saida.origem === 'nenhum' && !ftsFalhou)
147
168
  saida.origem = 'fts';
148
169
  }
149
170
  const scores = fundirRrf([saida.listas.vetor, saida.listas.fts]);
@@ -159,3 +180,22 @@ function buscarPorSignificado(o) {
159
180
  saida.detalhe = detalhes.join('; ');
160
181
  return saida;
161
182
  }
183
+ /**
184
+ * Texto de `ork memory search --texto`. Revisao de 03/10 (RM-038): o detalhe sai tambem sem motivo; o
185
+ * id do FTS fora do universo e o aviso de cobertura vivem nele, e o texto os perdia na busca que deu certo.
186
+ */
187
+ function textoDaBuscaPorSignificado(r) {
188
+ const linhas = [`Busca por significado (NAO deterministica; modo ${r.modo}, origem ${r.origem}${r.modeloUsado ? ` ${r.modeloUsado}` : ''})`];
189
+ if (r.motivo)
190
+ linhas.push(` motivo: ${r.motivo}${r.detalhe ? `; ${r.detalhe}` : ''}`);
191
+ else if (r.detalhe)
192
+ linhas.push(` detalhe: ${r.detalhe}`);
193
+ linhas.push('');
194
+ r.resultados.forEach((e, i) => {
195
+ const sim = e.similaridade === null ? '' : ` similaridade ${e.similaridade}`;
196
+ linhas.push(` ${i + 1}. [${e.collection}] ${e.id} score ${e.score} ${e.fontes.join('+')}${sim}`);
197
+ linhas.push(` ${e.resumo}`);
198
+ });
199
+ linhas.push('', ` ${r.resultados.length} resultado(s); busca por tag continua em ork memory search --tags`);
200
+ return linhas.join('\n');
201
+ }
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.fxPedidoColado = exports.PROMPTS_DE_CONDUCAO = exports.FRASE_DO_PEDIDO_COLADO = exports.PEDIDO_COLADO_DO_INCIDENTE = void 0;
37
+ /**
38
+ * RM-057 (fatia 2): o canario do incidente de 01/10/2026.
39
+ *
40
+ * Na noite de 01 para 02/10 o condutor recebeu, colado, o pedido do dono com push e merge
41
+ * autorizados ate um horario, parou para pedir um "confirmo" em texto livre e a fabrica ficou mais
42
+ * de 10 h sem produzir. O canario refaz a conducao inteira em sandbox SIMULADO e exige que o mesmo
43
+ * pedido colado siga sem parar:
44
+ *
45
+ * 1. o modo sai da #TAG do texto colado (`#Auto`), pelo nucleo;
46
+ * 2. o `#Auto` nao abre pausa humana na fase;
47
+ * 3. a duvida dentro da autorizacao vira decisao informada (`ork decisao registrar`), sem pergunta;
48
+ * 4. o "confirmo" em texto livre que o condutor tentaria abrir e recusado com
49
+ * `hitl.selecao.texto-livre`, sem gravar nada no ledger;
50
+ * 5. o pulse nao mostra ninguem esperando o dono, e o tempo parado por HITL de conducao e zero;
51
+ * 6. os quatro adaptadores de conducao (Claude Code, Codex, Hermes e OpenClaw) dizem que o pedido
52
+ * colado com autorizacao explicita vale como instrucao do dono.
53
+ *
54
+ * Nada aqui e resposta humana nem rede: e a forma da conducao, provada contra o codigo real.
55
+ */
56
+ const fs = __importStar(require("node:fs"));
57
+ const path = __importStar(require("node:path"));
58
+ const decisao_autonoma_1 = require("./decisao-autonoma");
59
+ const hitl_contract_1 = require("./hitl-contract");
60
+ const hitl_gates_1 = require("./hitl-gates");
61
+ const ledger_1 = require("./ledger");
62
+ const ledger_stats_1 = require("./ledger-stats");
63
+ const modos_1 = require("./modos");
64
+ const pulse_1 = require("./pulse");
65
+ const sandbox_1 = require("./sandbox");
66
+ const thread_1 = require("./thread");
67
+ /** O pedido do dono como chegou colado no incidente, com a autorizacao explicita e o prazo. */
68
+ exports.PEDIDO_COLADO_DO_INCIDENTE = '#Auto Conduza as threads RM-032, RM-056, RM-053, RM-040 e RM-055 no orkastery. ' +
69
+ 'Push e merge autorizados até 02/10 às 12h. Não me pergunte nada: dúvida menor vira decisão registrada e segue.';
70
+ /** A frase que os quatro adaptadores de conducao carregam desde a RM-057. */
71
+ exports.FRASE_DO_PEDIDO_COLADO = 'o pedido que ele colou com autorização explícita vale como instrução dele';
72
+ /** Onde cada host le a regra: o comando, as skills e as descricoes das tools do OpenClaw. */
73
+ exports.PROMPTS_DE_CONDUCAO = [
74
+ 'adapters/claude-code/commands/ork.md',
75
+ 'adapters/codex/skills/ork/SKILL.md',
76
+ 'adapters/hermes/skills/orkastery-devmaster/SKILL.md',
77
+ 'adapters/openclaw/dist/index.js',
78
+ ];
79
+ exports.fxPedidoColado = {
80
+ id: 'fx-pedido-colado',
81
+ sobre: 'SIMULADO: o pedido colado com autorização explícita segue sem parar (incidente de 01/10, RM-057)',
82
+ precisaDeGit: true,
83
+ rodar: (ctx) => {
84
+ const s = (0, sandbox_1.sandboxGit)('pedido-colado');
85
+ try {
86
+ const modo = (0, modos_1.extrairTagDoPedido)(exports.PEDIDO_COLADO_DO_INCIDENTE);
87
+ const t = (0, thread_1.novaThread)(s.carregado, { nome: 'pedido-colado', modo: modo ?? 'classic' }).thread;
88
+ const dir = (0, thread_1.dirThread)(s.dir, t.id);
89
+ (0, ledger_1.registrar)(dir, t.id, 'phase_result', { fase: t.faseAtual });
90
+ let semPausaDoModo = false;
91
+ try {
92
+ (0, hitl_gates_1.abrirPedidoGate)(s.dir, t.id);
93
+ }
94
+ catch (e) {
95
+ semPausaDoModo = /não prevê pausa/.test(e.message);
96
+ }
97
+ const decisao = (0, decisao_autonoma_1.registrarDecisao)(s.dir, t.id, {
98
+ decidido: 'Seguir com push e merge dentro da autorização colada', porque: 'o dono autorizou até 02/10 às 12h',
99
+ comoMudar: 'reverter o merge', custoDeReverter: { agora: 'um revert', depois: 'um revert' },
100
+ criterio: { tipo: 'ledger', referencia: `${t.id}#evento:1` }, quemDecidiu: 'canario-SIMULADO', evidencia: 'pedido colado',
101
+ });
102
+ const confirmo = {
103
+ contrato: hitl_contract_1.CONTRATO_HITL_V2, id: 'confirmo-SIMULADO', thread: t.id, fase: t.faseAtual, modo: t.modo,
104
+ criadoEm: new Date().toISOString(), profundidade: 'resumo', classe: 'pergunta',
105
+ alvo: { tipo: 'gate', sobre: 'premissas' }, motivo: 'human.pending', pergunta: 'Posso seguir com o push e o merge?',
106
+ alternativas: [
107
+ { letra: 'a', texto: 'Seguir', acao: 'aprovar', consequencia: 'segue', recomendada: true, porque: 'autorizado no pedido' },
108
+ { letra: 'b', texto: 'Parar', acao: 'recusar', consequencia: 'para' },
109
+ { letra: 'c', texto: 'Esperar', acao: 'esperar', consequencia: 'fica' },
110
+ ],
111
+ corpo: ['Responda confirmo para eu continuar'], tipoDeResposta: 'aberta', irreversivel: false, codigo: 'K3F9',
112
+ prazo: new Date(Date.now() + 3_600_000).toISOString(), acaoPadraoAoExpirar: 'esperar',
113
+ respostaAceita: { tipo: 'texto', maxCaracteres: 200 },
114
+ };
115
+ const antes = (0, ledger_1.lerLedger)(dir).length;
116
+ let confirmoRecusado = 'aceito';
117
+ try {
118
+ (0, hitl_gates_1.registrarPedidoHitl)(s.dir, confirmo);
119
+ }
120
+ catch (e) {
121
+ confirmoRecusado = e instanceof hitl_contract_1.SelecaoRecusada ? e.motivo : `outro: ${e.message}`;
122
+ }
123
+ const nadaGravadoNaRecusa = (0, ledger_1.lerLedger)(dir).length === antes;
124
+ const pulse = (0, pulse_1.montarPulse)(s.carregado, { consulta: { ok: true, sessoes: [], detalhe: 'runtime SIMULADO' } });
125
+ const parado = (0, ledger_stats_1.coletarEstatisticas)(s.dir, { desde: '1h', thread: t.id }).hitlDeConducao;
126
+ // No dist do OpenClaw a frase e uma concatenacao de literais: as emendas `' + '` saem antes da busca.
127
+ const umaLinha = (x) => x.replace(/'\s*\+\s*'/g, '').replace(/\s+/g, ' ');
128
+ const adaptadoresComARegra = exports.PROMPTS_DE_CONDUCAO.filter((rel) => {
129
+ const arquivo = path.join(ctx.catalogo, rel);
130
+ return fs.existsSync(arquivo) && umaLinha(fs.readFileSync(arquivo, 'utf8')).includes(exports.FRASE_DO_PEDIDO_COLADO);
131
+ }).length;
132
+ return {
133
+ simulado: true,
134
+ modoDoPedido: modo,
135
+ semPausaDoModo,
136
+ decisaoInformada: decisao.pedido.classe === 'decidido',
137
+ confirmoRecusado,
138
+ nadaGravadoNaRecusa,
139
+ humanosNoPulse: pulse.resumo.humanos,
140
+ perguntasDeConducao: parado.pedidos,
141
+ tempoParadoMs: parado.paradoMs,
142
+ adaptadoresComARegra,
143
+ };
144
+ }
145
+ finally {
146
+ s.limpar();
147
+ }
148
+ },
149
+ };
package/dist/canarios.js CHANGED
@@ -71,6 +71,7 @@ const canarios_pulse_1 = require("./canarios-pulse");
71
71
  const canarios_sensores_1 = require("./canarios-sensores");
72
72
  const canarios_hitl_1 = require("./canarios-hitl");
73
73
  const canarios_i43_1 = require("./canarios-i43");
74
+ const canarios_rm057_1 = require("./canarios-rm057");
74
75
  const objective_1 = require("./objective");
75
76
  const maestro_discovery_1 = require("./maestro-discovery");
76
77
  const maestro_cli_1 = require("./maestro-cli");
@@ -373,6 +374,7 @@ exports.CANARIOS = [
373
374
  canarios_sensores_1.CANARIO_SENSORES,
374
375
  ...canarios_hitl_1.CANARIOS_HITL,
375
376
  ...canarios_i43_1.CANARIOS_I43,
377
+ canarios_rm057_1.fxPedidoColado,
376
378
  ];
377
379
  /** Um canario por id, ou null quando a fixture aponta para um canario que nao existe. */
378
380
  function canarioPorId(id) {
package/dist/catalogo.js CHANGED
@@ -45,6 +45,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.BUCKETS = void 0;
46
46
  exports.raizDoCatalogo = raizDoCatalogo;
47
47
  exports.exigirCatalogo = exigirCatalogo;
48
+ exports.catalogoDoPacote = catalogoDoPacote;
49
+ exports.exigirCatalogoDoPacote = exigirCatalogoDoPacote;
48
50
  exports.cliDoCatalogo = cliDoCatalogo;
49
51
  exports.skillsDoCatalogo = skillsDoCatalogo;
50
52
  exports.referenciasDoCatalogo = referenciasDoCatalogo;
@@ -83,6 +85,37 @@ function exigirCatalogo(inicial) {
83
85
  }
84
86
  return raiz;
85
87
  }
88
+ /** A raiz do catálogo do pacote que está rodando: subindo a partir do próprio código, nunca do cwd. */
89
+ function catalogoDoPacote() {
90
+ return subirProcurando(__dirname);
91
+ }
92
+ function real(p) {
93
+ try {
94
+ return fs.realpathSync(p);
95
+ }
96
+ catch {
97
+ return path.resolve(p);
98
+ }
99
+ }
100
+ /**
101
+ * RM-047 (P4): o catálogo que o `ork eval` executa. O eval roda os canários, os hooks e o `core/dist`
102
+ * do catálogo, então ele só vale o do pacote que está rodando. Um diretório com `skills/`,
103
+ * `references/` e `eval/` achado a partir do cwd (um clone qualquer) que não seja o próprio pacote é
104
+ * recusado com `eval.catalogo-alheio`, com o comando que roda o eval daquele checkout de propósito.
105
+ */
106
+ function exigirCatalogoDoPacote(inicial) {
107
+ const pacote = catalogoDoPacote();
108
+ if (!pacote) {
109
+ throw new Error('catalogo do Orkastery nao encontrado (esperado um diretorio com skills/, references/ e eval/)');
110
+ }
111
+ const doCwd = subirProcurando(inicial);
112
+ if (doCwd && real(doCwd) !== real(pacote)) {
113
+ throw new Error(`eval.catalogo-alheio: ${doCwd} tem skills/, references/ e eval/, mas nao e o pacote deste ork ` +
114
+ `(${pacote}). O eval executa os canarios, os hooks e o core/dist do catalogo, e so roda o do proprio pacote. ` +
115
+ `Para avaliar aquele checkout de proposito, rode o ork dele: node ${path.join(doCwd, 'core', 'dist', 'index.js')} eval`);
116
+ }
117
+ return pacote;
118
+ }
86
119
  /** Os buckets do catalogo, na ordem em que o README os apresenta. */
87
120
  exports.BUCKETS = [
88
121
  'core',
package/dist/ci.js CHANGED
@@ -40,14 +40,18 @@ exports.consultarCi = consultarCi;
40
40
  exports.consultarCiDoRepositorio = consultarCiDoRepositorio;
41
41
  exports.executarCi = executarCi;
42
42
  exports.arquivoDoBundle = arquivoDoBundle;
43
+ exports.comandosDoBundle = comandosDoBundle;
43
44
  exports.lintDoBundle = lintDoBundle;
44
45
  exports.destinoDoBundle = destinoDoBundle;
45
46
  exports.prepararBundleCi = prepararBundleCi;
46
47
  exports.bundleDaBranch = bundleDaBranch;
47
48
  exports.executarCiDaBranch = executarCiDaBranch;
48
49
  exports.executarBundleCi = executarBundleCi;
50
+ /** GitHub CI como CHECK independente (I-12). */
51
+ const branch_de_estado_1 = require("./branch-de-estado");
49
52
  const util_1 = require("./util");
50
53
  const worktree_1 = require("./worktree");
54
+ const procedencia_1 = require("./procedencia");
51
55
  const verify_1 = require("./verify");
52
56
  const verify_2 = require("./verify");
53
57
  const claims_1 = require("./claims");
@@ -57,6 +61,7 @@ const claim_lint_1 = require("./claim-lint");
57
61
  const integracoes_locais_1 = require("./integracoes-locais");
58
62
  const ledger_1 = require("./ledger");
59
63
  const thread_1 = require("./thread");
64
+ const locale_1 = require("./locale");
60
65
  const MARCADORES_DE_HOST = [
61
66
  /(^|[\s;&|])\/home\//,
62
67
  /(^|[\s;&|])localhost(?=[:/\s;&|]|$)/,
@@ -73,9 +78,13 @@ const CASOS_DE_VERIFICADOR_COM_INTEGRACAO_LOCAL = [
73
78
  /verify-check-c2-b3\.cjs\s+channel-offer(?:\s|$)/,
74
79
  // I-38: a prova da busca por significado le a memoria do tenant pela DSN do manifesto.
75
80
  /prova-busca-semantica\.sh(?:\s|$)/,
81
+ // RM-038: a prova do universo da busca tambem le a memoria do tenant pela DSN do manifesto.
82
+ /prova-universo-da-busca\.cjs(?:\s|$)/,
76
83
  // RM-051: o ensaio instala o tarball com npm --offline e resolve as dependencias pelo cache do npm
77
84
  // da estacao; o runner hospedado so tem os tarballs do npm ci, sem os metadados do registro.
78
85
  /testar-experiencia-e2e\.cjs(?:\s|$)/,
86
+ // RM-037: a suite local inteira, com as integracoes locais; o runner hospedado roda o test:ci.
87
+ /suite-local\.cjs(?:\s|$)/,
79
88
  ];
80
89
  /**
81
90
  * I-38: o runner hospedado nao oferece OrkMind nem a base do tenant. Claim que chama a memoria
@@ -132,11 +141,12 @@ function consultarCi(carregado, sha, remoto = 'origin', executor = executorPadra
132
141
  const { ci } = carregado.manifesto;
133
142
  const context = ci.context || 'ork-verify';
134
143
  if (!ci.required_for_ship)
135
- return { schema: 'ork.ci-status/v1', required: false, ok: true, provider: 'github', repository: null, sha, context, state: 'disabled', url: null, detail: 'gate de CI não exigido pelo manifesto' };
136
- const remote = (0, util_1.exec)('git', ['remote', 'get-url', remoto], carregado.raiz);
144
+ return { schema: 'ork.ci-status/v1', required: false, ok: true, provider: 'github', repository: null, sha, context, state: 'disabled', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciNaoExigidoDetalhe) };
145
+ // RM-047: o `--remoto` do `ork ci status` vem da linha de comando; so nome de remoto chega ao git.
146
+ const remote = (0, util_1.exec)('git', ['remote', 'get-url', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ci')], carregado.raiz);
137
147
  const repository = remote.ok ? repositorioGitHub(remote.stdout) : null;
138
148
  if (!repository)
139
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository: null, sha, context, state: 'unavailable', url: null, detail: `remoto ${remoto} não é um repositório GitHub reconhecível` };
149
+ return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository: null, sha, context, state: 'unavailable', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRemotoNaoGithub(remoto)) };
140
150
  return consultarCiDoRepositorio(repository, sha, context, executor);
141
151
  }
142
152
  /**
@@ -146,23 +156,23 @@ function consultarCi(carregado, sha, remoto = 'origin', executor = executorPadra
146
156
  function consultarCiDoRepositorio(repository, sha, context, executor = executorPadrao) {
147
157
  const result = executor({ repository, sha, context });
148
158
  if (!result.ok)
149
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: (result.stderr || result.stdout || 'consulta ao GitHub falhou').trim().slice(0, 400) };
159
+ return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: (result.stderr || result.stdout || (0, locale_1.textoDoCatalogo)((m) => m.ship.ciConsultaFalhou)).trim().slice(0, 400) };
150
160
  let payload;
151
161
  try {
152
162
  payload = JSON.parse(result.stdout);
153
163
  }
154
164
  catch {
155
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: 'GitHub devolveu uma resposta de checks inválida' };
165
+ return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRespostaInvalida) };
156
166
  }
157
167
  const checks = (payload.check_runs ?? []).filter((check) => check.name === context);
158
168
  if (!checks.length)
159
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'missing', url: null, detail: `check ${context} não encontrado no commit` };
169
+ return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'missing', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciSemCheck(context)) };
160
170
  const check = checks.at(-1);
161
171
  const status = check.status ?? 'unknown';
162
172
  const conclusion = check.conclusion ?? '';
163
173
  const url = check.html_url ?? '';
164
174
  const state = status !== 'completed' ? 'pending' : conclusion === 'success' ? 'success' : 'failure';
165
- return { schema: 'ork.ci-status/v1', required: true, ok: state === 'success', provider: 'github', repository, sha, context, state, url: url || null, detail: state === 'success' ? 'CHECK independente verde no GitHub' : `check ${context}: ${status}/${conclusion || 'sem conclusão'}` };
175
+ return { schema: 'ork.ci-status/v1', required: true, ok: state === 'success', provider: 'github', repository, sha, context, state, url: url || null, detail: (0, locale_1.textoDoCatalogo)((m) => state === 'success' ? m.ship.ciVerde : m.ship.ciEstado(context, String(status), conclusion)) };
166
176
  }
167
177
  function executarCi(carregado, threadId) {
168
178
  const verify = (0, verify_1.verificar)(carregado, threadId);
@@ -195,6 +205,7 @@ function arquivoDoBundle(threadId) {
195
205
  throw new Error(`ci.bundle: "${threadId}" nao e id de thread`);
196
206
  return `${threadId}.json`;
197
207
  }
208
+ /** Os comandos que o bundle leva ao runner; o `ork ship publicar` confere os do bundle no HEAD contra estes. */
198
209
  function comandosDoBundle(carregado) {
199
210
  return carregado.manifesto.ci.command
200
211
  ? [{ name: 'ci', command: carregado.manifesto.ci.command }]
@@ -226,7 +237,9 @@ function lintDoBundle(claims) {
226
237
  */
227
238
  function destinoDoBundle(carregado, threadId) {
228
239
  const worktree = (0, thread_1.lerThread)(carregado.raiz, threadId).worktree;
229
- return worktree && fs.existsSync(worktree) ? worktree : carregado.raiz;
240
+ // RM-047 (P2): o bundle so e gravado na worktree registrada; outro diretorio do thread.json cai na raiz.
241
+ return worktree && fs.existsSync(worktree) && (0, procedencia_1.cwdLocalOuNulo)(carregado.raiz, threadId, worktree, 'thread') !== null
242
+ ? worktree : carregado.raiz;
230
243
  }
231
244
  function prepararBundleCi(carregado, threadId, opcoes = {}) {
232
245
  const commands = comandosDoBundle(carregado);