@orkastery/cli 0.5.3 → 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 (212) hide show
  1. package/adapters/claude-code/README.md +158 -0
  2. package/adapters/claude-code/mods/autoridade.json +56 -0
  3. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  4. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  5. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  6. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  7. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  8. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  9. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  10. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  11. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  12. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  13. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  14. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  15. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  16. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  17. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  18. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  19. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  20. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  21. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  22. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  23. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  24. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  25. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  26. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  27. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  28. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  29. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
  30. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  31. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  32. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  33. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  34. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  35. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  36. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  37. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  38. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  39. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  40. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  41. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  42. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  43. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  44. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  45. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  46. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  47. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  48. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  49. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  50. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  51. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  52. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  53. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  54. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  55. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  56. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  57. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  58. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  59. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  60. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  61. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  62. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  63. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  64. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  65. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  66. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  67. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  68. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  69. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  70. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  71. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  72. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  73. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  74. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  75. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  76. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  77. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  78. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  79. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +1 -1
  80. package/adapters/openclaw/README.md +2 -1
  81. package/adapters/openclaw/openclaw.plugin.json +1 -1
  82. package/adapters/openclaw/package.json +1 -1
  83. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  84. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  85. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  86. package/assets/docs-en/produto/README.md +14 -0
  87. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  88. package/assets/docs-en/roadmap/README.md +14 -0
  89. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  90. package/dist/adapters/claude-bg.js +77 -13
  91. package/dist/adapters/codex.js +10 -1
  92. package/dist/agents-md.js +24 -15
  93. package/dist/auditrun.js +17 -2
  94. package/dist/board.js +4 -3
  95. package/dist/branch-de-estado.js +23 -1
  96. package/dist/catalogo.js +33 -0
  97. package/dist/ci.js +13 -7
  98. package/dist/claims-conferir.js +342 -0
  99. package/dist/claims.js +3 -1
  100. package/dist/company-brain-client.js +36 -1
  101. package/dist/company-brain-journal.js +2 -1
  102. package/dist/company-brain-migration.js +36 -1
  103. package/dist/conducao-sentinela.js +388 -0
  104. package/dist/conducao-texto.js +12 -18
  105. package/dist/conducao.js +122 -30
  106. package/dist/conhecimento.js +490 -0
  107. package/dist/docs.js +22 -8
  108. package/dist/doctor-pulse-cron.js +182 -27
  109. package/dist/doctor-rede.js +18 -17
  110. package/dist/doctor.js +115 -111
  111. package/dist/entrega-pr.js +22 -21
  112. package/dist/escopo-escrita.js +10 -1
  113. package/dist/estado-thread.js +23 -1
  114. package/dist/experiencia-instalacao.js +45 -25
  115. package/dist/fabrica-batida.js +310 -0
  116. package/dist/fabrica-estado.js +38 -8
  117. package/dist/fabrica-publicar.js +3 -1
  118. package/dist/fila-pesada.js +444 -0
  119. package/dist/fix.js +3 -2
  120. package/dist/forja.js +1 -1
  121. package/dist/gates.js +3 -28
  122. package/dist/handoff.js +10 -6
  123. package/dist/hitl-local-receipt.js +2 -0
  124. package/dist/hitl-resumo.js +29 -3
  125. package/dist/hitl-tempo-parado.js +4 -4
  126. package/dist/hitl.js +29 -33
  127. package/dist/horario.js +14 -7
  128. package/dist/hosts.js +52 -1
  129. package/dist/impedimento.js +108 -14
  130. package/dist/index.js +623 -521
  131. package/dist/indice.js +7 -1
  132. package/dist/init.js +43 -47
  133. package/dist/instabilidade.js +144 -0
  134. package/dist/integracoes-locais.js +2 -0
  135. package/dist/intelligence-graph-cli.js +92 -21
  136. package/dist/intelligence-graph-contexto.js +56 -17
  137. package/dist/intelligence-graph-contract.js +2 -1
  138. package/dist/intelligence-graph-extract-md.js +56 -4
  139. package/dist/intelligence-graph-extract-ts.js +71 -3
  140. package/dist/intelligence-graph-query.js +66 -19
  141. package/dist/ledger.js +15 -1
  142. package/dist/liveness.js +6 -3
  143. package/dist/locale-ajuda.js +761 -0
  144. package/dist/locale-gerados.js +160 -0
  145. package/dist/locale-master.js +99 -0
  146. package/dist/locale-onboarding.js +92 -0
  147. package/dist/locale-phase.js +151 -0
  148. package/dist/locale-pulse.js +211 -0
  149. package/dist/locale-retry.js +385 -0
  150. package/dist/locale-roadmap.js +102 -0
  151. package/dist/locale-ship.js +494 -0
  152. package/dist/locale-thread.js +277 -0
  153. package/dist/locale-verify.js +125 -0
  154. package/dist/locale.js +714 -0
  155. package/dist/manifest.js +129 -3
  156. package/dist/maquina.js +23 -4
  157. package/dist/master-digest.js +6 -1
  158. package/dist/master-nota.js +4 -6
  159. package/dist/master.js +21 -24
  160. package/dist/mcp-artifacts.js +11 -2
  161. package/dist/mcp-git.js +23 -6
  162. package/dist/mcp-grafo.js +7 -4
  163. package/dist/mcp-server.js +8 -2
  164. package/dist/mcp-ship.js +3 -1
  165. package/dist/mcp-verify.js +6 -1
  166. package/dist/modos.js +3 -6
  167. package/dist/network-roadmap.js +5 -2
  168. package/dist/noctum-arco.js +911 -0
  169. package/dist/noctum-capacidade.js +141 -0
  170. package/dist/noctum-envelope.js +810 -0
  171. package/dist/noctum-execucao.js +304 -0
  172. package/dist/noctum-fila.js +280 -0
  173. package/dist/ocupacao.js +29 -2
  174. package/dist/onboarding.js +40 -21
  175. package/dist/orkmind.js +9 -2
  176. package/dist/orquestracao.js +13 -12
  177. package/dist/parado-no-condutor.js +34 -9
  178. package/dist/phase.js +94 -39
  179. package/dist/policies.js +4 -4
  180. package/dist/portfolio.js +4 -2
  181. package/dist/postura-local.js +234 -0
  182. package/dist/preflight.js +11 -10
  183. package/dist/procedencia.js +225 -0
  184. package/dist/projeto-alvo.js +127 -4
  185. package/dist/prompts.js +6 -2
  186. package/dist/pulse-delivery.js +13 -2
  187. package/dist/pulse.js +52 -19
  188. package/dist/ratelimit.js +4 -2
  189. package/dist/redacao-saida.js +63 -0
  190. package/dist/rede-status.js +3 -2
  191. package/dist/retry.js +232 -148
  192. package/dist/roadmap-reservas.js +20 -3
  193. package/dist/roadmap-status.js +129 -33
  194. package/dist/runtime-context.js +181 -3
  195. package/dist/runtimes.js +2 -1
  196. package/dist/session-events.js +7 -3
  197. package/dist/session-watcher-claude.js +7 -1
  198. package/dist/session-watcher.js +185 -33
  199. package/dist/sessoes-contas.js +1 -1
  200. package/dist/ship-publicar.js +800 -0
  201. package/dist/ship.js +84 -81
  202. package/dist/steal.js +77 -0
  203. package/dist/thread-close.js +3 -2
  204. package/dist/thread.js +153 -82
  205. package/dist/util.js +8 -1
  206. package/dist/verify.js +141 -52
  207. package/dist/vida-da-thread.js +254 -0
  208. package/dist/worktree-local.js +165 -0
  209. package/dist/worktree.js +20 -0
  210. package/dist/yaml.js +27 -8
  211. package/package.json +1 -1
  212. package/schemas/code-artifact-graph.v1.schema.json +2 -1
package/dist/conducao.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ErroDeConducao = exports.ESPERA_PADRAO_MS = exports.PRAZO_DA_RESERVA_MS = exports.PRAZO_DE_SESSAO_PADRAO_MS = exports.MARGEM_DO_PRAZO_MS = exports.ENV_SESSAO_CLAUDE = exports.ENV_THREAD_DO_DESPACHO = exports.ENV_IDENTIDADE_DE_DESPACHO = exports.ENV_CANAL = exports.ERRO_CANAL_DESCONHECIDO = exports.CANAIS_DE_CONDUCAO = exports.conducaoDoLease = void 0;
36
+ exports.ErroDeConducao = exports.ESPERA_PADRAO_MS = exports.PRAZO_DA_RESERVA_MS = exports.PRAZO_DE_SESSAO_PADRAO_MS = exports.MARGEM_DO_PRAZO_MS = exports.ENV_SESSAO_CLAUDE = exports.ENV_THREAD_DO_DESPACHO = exports.ENV_IDENTIDADE_DE_DESPACHO = exports.ENV_CANAL = exports.BATIDA_DA_SENTINELA_MS = exports.PRAZO_DA_PRESENCA_MS = exports.CANAL_DA_SENTINELA = exports.CONTRATO_DA_SENTINELA = exports.ERRO_CANAL_DESCONHECIDO = exports.CANAIS_DE_CONDUCAO = exports.conducaoDoLease = void 0;
37
37
  exports.validarCanal = validarCanal;
38
38
  exports.canalDoProcesso = canalDoProcesso;
39
39
  exports.ambienteDaConducao = ambienteDaConducao;
@@ -85,10 +85,13 @@ const ledger_1 = require("./ledger");
85
85
  const maquina_1 = require("./maquina");
86
86
  const thread_1 = require("./thread");
87
87
  const horario_1 = require("./horario");
88
+ const locale_1 = require("./locale");
88
89
  const util_1 = require("./util");
90
+ const procedencia_1 = require("./procedencia");
89
91
  const runtime_ambiente_1 = require("./runtime-ambiente");
90
92
  Object.defineProperty(exports, "ENV_IDENTIDADE_DE_DESPACHO", { enumerable: true, get: function () { return runtime_ambiente_1.ENV_IDENTIDADE_DE_DESPACHO; } });
91
93
  Object.defineProperty(exports, "ENV_THREAD_DO_DESPACHO", { enumerable: true, get: function () { return runtime_ambiente_1.ENV_THREAD_DO_DESPACHO; } });
94
+ const projeto_alvo_1 = require("./projeto-alvo");
92
95
  // ---------------------------------------------------------------------------
93
96
  // Canais (D5, D6): registro fechado, declarado pela borda.
94
97
  // ---------------------------------------------------------------------------
@@ -121,6 +124,18 @@ exports.CANAIS_DE_CONDUCAO = {
121
124
  };
122
125
  /** Codigo tipado da recusa de canal fora do registro. */
123
126
  exports.ERRO_CANAL_DESCONHECIDO = 'conducao.canal-desconhecido';
127
+ // ---------------------------------------------------------------------------
128
+ // RM-059 (F6, T6.4; DD5 do plano dos mods): a conducao pela Sentinela do Condutor. A presenca e o passo
129
+ // do condutor moram em `conducao-sentinela.ts`; as constantes ficam aqui, para quem so conhece a conducao.
130
+ // ---------------------------------------------------------------------------
131
+ /** O contrato do `ork conducao sentinela status --json`. */
132
+ exports.CONTRATO_DA_SENTINELA = 'ork.conducao-sentinela/v1';
133
+ /** A Sentinela roda na sessao do dono no Claude Code: e o canal dela, sempre. */
134
+ exports.CANAL_DA_SENTINELA = 'claude-code';
135
+ /** A presenca vale ate 3 min depois da ultima batida; vencida, o condutor externo volta a conduzir. */
136
+ exports.PRAZO_DA_PRESENCA_MS = 3 * 60 * 1000;
137
+ /** A Sentinela bate a cada 60 s: tres batidas perdidas e a presenca vence. */
138
+ exports.BATIDA_DA_SENTINELA_MS = 60 * 1000;
124
139
  /** Canal fora do registro e recusado com motivo tipado, nunca adivinhado (T9). */
125
140
  function validarCanal(bruto) {
126
141
  const canal = bruto.trim();
@@ -149,9 +164,14 @@ function canalDoProcesso(explicito, ambiente = process.env) {
149
164
  return 'hermes';
150
165
  return 'cli';
151
166
  }
152
- /** O que o despacho poe no ambiente da sessao filha: identidade, thread e canal de origem. */
167
+ /**
168
+ * O que o despacho poe no ambiente da sessao filha: identidade, thread e canal de origem. RM-052
169
+ * (fatia 2, D2): tambem neutraliza o projeto-alvo de quem despachou, porque a sessao roda dentro do
170
+ * projeto (a worktree da thread) e le o projeto pelo proprio cwd; o modo host do gateway nao a segue.
171
+ */
153
172
  function ambienteDaConducao(identidade, threadId, canal) {
154
- return { [runtime_ambiente_1.ENV_IDENTIDADE_DE_DESPACHO]: identidade, [runtime_ambiente_1.ENV_THREAD_DO_DESPACHO]: threadId, [exports.ENV_CANAL]: canal };
173
+ return { [runtime_ambiente_1.ENV_IDENTIDADE_DE_DESPACHO]: identidade, [runtime_ambiente_1.ENV_THREAD_DO_DESPACHO]: threadId, [exports.ENV_CANAL]: canal,
174
+ ...projeto_alvo_1.AMBIENTE_SEM_PROJETO_HERDADO };
155
175
  }
156
176
  /** Variavel que o Claude Code poe em cada sessao, com o UUID dela; nao vem do daemon. */
157
177
  exports.ENV_SESSAO_CLAUDE = 'CLAUDE_CODE_SESSION_ID';
@@ -752,12 +772,12 @@ function recusaDeConducao(threadId, atual, pedido, opcoes = {}) {
752
772
  * e o texto diz onde acompanhar a sessao que ja atende o pedido.
753
773
  */
754
774
  function textoDoPedidoRepetido(threadId, atual, opcoes = {}) {
775
+ // RM-061 (F2a): texto de impressao (o despacho nao o grava), no locale do comando.
776
+ const m = (0, locale_1.msg)().phase;
755
777
  return [
756
- `Pedido ja em andamento: a fase ${atual.fase ?? '-'} da thread ${threadId} roda com este mesmo prompt ` +
757
- `(sha256 ${(atual.promptSha256 ?? '').slice(0, 12)}) desde ${(0, horario_1.formatarDataHoraRotulada)(atual.desde, opcoes)}. ` +
758
- 'Nenhuma sessao nova foi aberta e nenhuma cota foi gasta.',
778
+ m.repetido(atual.fase ?? '-', threadId, (atual.promptSha256 ?? '').slice(0, 12), (0, horario_1.formatarDataHoraRotulada)(atual.desde, opcoes)),
759
779
  ` ${(0, conducao_texto_1.linhaDeConducao)(atual, opcoes)}`,
760
- ` acompanhar: ${comandoDeAcompanhar(threadId, atual)}`,
780
+ m.acompanhar(comandoDeAcompanhar(threadId, atual)),
761
781
  ].join('\n');
762
782
  }
763
783
  /** A recusa tipada como erro, para quem nao tem um resultado estruturado onde devolve-la. */
@@ -843,7 +863,8 @@ function liberarSeOrfa(raiz, threadId, opcoes = {}) {
843
863
  function estadoDaWorktree(raiz, threadId) {
844
864
  try {
845
865
  const t = (0, thread_1.lerThread)(raiz, threadId);
846
- const dir = t.worktree ?? raiz;
866
+ // RM-047 (P2): o git do handoff so roda na worktree registrada.
867
+ const dir = (0, procedencia_1.diretorioDaThread)(raiz, t);
847
868
  const head = (0, util_1.exec)('git', ['rev-parse', 'HEAD'], dir);
848
869
  const st = (0, util_1.exec)('git', ['status', '--porcelain'], dir);
849
870
  return { head: head.ok ? head.stdout.trim() : null, alterados: st.ok ? st.stdout.split('\n').filter(Boolean).slice(0, 40) : [] };
@@ -860,6 +881,68 @@ const controleNativoDoHandoff = (runtime, raiz, threadId, sessionId) => {
860
881
  parar: (s) => ctl.parar(s),
861
882
  };
862
883
  };
884
+ /**
885
+ * A fonte fixada pelo sensor contém a identidade capturada no spawn, não um PID descoberto.
886
+ * Todos os watchers, o controller e o runtime precisam estar ausentes por identidade.
887
+ * Quem chama segura a trava da condução; nenhum prazo ou heartbeat autoriza esta soltura.
888
+ */
889
+ function morteLocalDoCodex(raiz, threadId, lease) {
890
+ const dono = lease.conducao?.dono;
891
+ if (dono?.tipo !== 'sessao' || dono.runtime !== 'codex' || dono.maquina !== (0, maquina_1.nomeDaMaquina)())
892
+ return null;
893
+ try {
894
+ const t = (0, thread_1.lerThread)(raiz, threadId), sessao = t.sessoes.at(-1);
895
+ if (!sessao || sessao.sessionId !== dono.sessionId || sessao.runtime !== 'codex' || !sessao.despachadaEm ||
896
+ sessao.fase !== lease.conducao?.fase || sessao.promptSha256 !== lease.conducao?.promptSha256)
897
+ return null;
898
+ const dir = (0, thread_1.dirThread)(raiz, threadId), eventos = (0, ledger_1.lerLedger)(dir);
899
+ if (fimDaSessao(eventos, lease))
900
+ return null;
901
+ const mesmo = (e) => e.sessionId === dono.sessionId && e.despachoEm === sessao.despachadaEm;
902
+ const watchers = eventos.filter(e => e.tipo === 'session_watcher_started' && mesmo(e));
903
+ if (!watchers.length || watchers.some(watcher => {
904
+ const identidade = watcher.identidade;
905
+ return !identidade || watcher.pid !== identidade.pid || (0, codex_runner_1.estadoProcesso)(identidade) !== 'ausente';
906
+ }))
907
+ return null;
908
+ const registro = eventos.filter(e => e.tipo === 'session_sensor_registered' && mesmo(e)).at(-1);
909
+ const despacho = eventos.filter(e => e.tipo === 'phase_dispatch' && e.sessionId === dono.sessionId).at(-1);
910
+ if (!registro || typeof registro.controlador !== 'string' || typeof registro.cwd !== 'string' ||
911
+ registro.logPath || registro.processoPath || registro.reciboPath || registro.nativo ||
912
+ despacho?.controlador !== registro.controlador || despacho.cwd !== registro.cwd ||
913
+ (sessao.controlador && sessao.controlador !== registro.controlador))
914
+ return null;
915
+ const chave = (0, node_crypto_1.createHash)('sha256').update(dono.sessionId + '|' + sessao.despachadaEm).digest('hex');
916
+ const fixacao = path.join(dir, 'sessoes', `watcher-source-${chave}.json`);
917
+ // Recuperação não cria uma fonte nova nem depende do state.json mutável de um controller morto.
918
+ if (!fs.existsSync(fixacao))
919
+ return null;
920
+ const { registrarFonteController } = require('./adapters/codex-controller-sensor');
921
+ const fonte = registrarFonteController(registro.controlador, { dirSessoes: path.join(dir, 'sessoes'), fixacao,
922
+ sessionId: dono.sessionId, cwd: registro.cwd, despachoEm: sessao.despachadaEm,
923
+ vinculo: { thread: threadId, fase: sessao.fase, promptSha256: sessao.promptSha256 } });
924
+ const controller = fonte.processoController;
925
+ if (!controller || (0, codex_runner_1.estadoProcesso)({ pid: controller.pid, inicio: controller.inicio, boot: controller.bootId }) !== 'ausente')
926
+ return null;
927
+ const runtime = fonte.processoRuntime;
928
+ if (!runtime || (0, codex_runner_1.estadoProcesso)({ pid: runtime.pid, inicio: runtime.inicio, boot: runtime.bootId }) !== 'ausente')
929
+ return null;
930
+ // O watcher pode ter gravado o terminal e saído durante a prova dos processos.
931
+ if (fimDaSessao((0, ledger_1.lerLedger)(dir), lease))
932
+ return null;
933
+ return { sessionId: dono.sessionId, despachoEm: sessao.despachadaEm, fase: sessao.fase, runtime: 'codex',
934
+ origem: 'conducao.assumir', motivo: 'watchers-controlador-e-runtime-ausentes',
935
+ prova: { fonte: 'session_sensor_registered+controller-source-pin+/proc',
936
+ registroEventId: registro.eventId,
937
+ watchers: watchers.map(w => ({ eventId: w.eventId, identidade: w.identidade, estado: 'ausente' })),
938
+ controlador: { pid: controller.pid, inicio: controller.inicio, boot: controller.bootId, uid: controller.uid },
939
+ runtime: { pid: runtime.pid, inicio: runtime.inicio, boot: runtime.bootId, uid: runtime.uid },
940
+ estadoControlador: 'ausente', estadoRuntime: 'ausente' } };
941
+ }
942
+ catch {
943
+ return null;
944
+ } // Fonte ilegível, divergente ou identidade desconhecida nunca prova morte.
945
+ }
863
946
  /**
864
947
  * `ork conducao assumir` (T15): encerra a conducao atual pelo mecanismo suportado do runtime, toma
865
948
  * uma reserva curta para o canal de quem assumiu e registra quem, de qual canal e por que. Processo
@@ -873,7 +956,8 @@ function assumirConducao(raiz, threadId, opcoes) {
873
956
  throw new Error('conducao.assumir: informe --motivo; handoff sem razao registrada e o mesmo kill de antes, com outro nome');
874
957
  const dir = (0, thread_1.dirThread)(raiz, threadId);
875
958
  (0, thread_1.lerThread)(raiz, threadId);
876
- liberarSeOrfa(raiz, threadId, { consultarSessao: opcoes.consultarSessao });
959
+ // A prova local vem antes de qualquer consulta ao runtime; ledger ainda libera sessões terminadas.
960
+ liberarSeOrfa(raiz, threadId, { consultarRuntime: false });
877
961
  const fd = tentarTrava(raiz, threadId);
878
962
  if (fd === null) {
879
963
  const atual = conducaoDaThread(raiz, threadId);
@@ -889,30 +973,38 @@ function assumirConducao(raiz, threadId, opcoes) {
889
973
  let prova = 'lease exec ausente';
890
974
  if (lease && anterior?.dono.tipo === 'sessao') {
891
975
  const dono = anterior.dono;
892
- const ctl = (opcoes.controle ?? controleNativoDoHandoff)(dono.runtime, raiz, threadId, dono.sessionId);
893
- const antes = ctl.consultar();
894
- if (!antes.ok) {
895
- return { ok: false, thread: threadId, anterior, mecanismo: 'nenhum',
896
- detalhe: 'runtime.unavailable: nao consegui consultar a sessao no runtime; nada foi encerrado e a conducao segue com ela' };
976
+ const morte = morteLocalDoCodex(raiz, threadId, lease);
977
+ if (morte) {
978
+ (0, ledger_1.registrar)(dir, threadId, 'sessao_morta', morte);
979
+ mecanismo = 'recuperação local: watchers, controlador e runtime ausentes por identidade';
980
+ prova = 'ledger: sessao_morta com identidades capturadas e ausência conferida no kernel';
897
981
  }
898
- const s = antes.sessoes.find((x) => x.sessionId === dono.sessionId);
899
- if (s && !TERMINAIS.includes(s.estado)) {
900
- if (!ctl.parar(s)) {
901
- return { ok: false, thread: threadId, anterior, mecanismo: `parar ${dono.runtime}`,
902
- detalhe: `runtime.unavailable: o runtime ${dono.runtime} nao confirmou o encerramento; a conducao segue com a sessao ${dono.sessionId.slice(0, 8)}` };
982
+ else {
983
+ const ctl = (opcoes.controle ?? controleNativoDoHandoff)(dono.runtime, raiz, threadId, dono.sessionId);
984
+ const antes = ctl.consultar();
985
+ if (!antes.ok) {
986
+ return { ok: false, thread: threadId, anterior, mecanismo: 'nenhum',
987
+ detalhe: 'runtime.unavailable: nao consegui consultar a sessao no runtime; nada foi encerrado e a conducao segue com ela' };
903
988
  }
904
- const depois = ctl.consultar();
905
- const ainda = depois.ok ? depois.sessoes.find((x) => x.sessionId === dono.sessionId) : s;
906
- if (!depois.ok || (ainda && !TERMINAIS.includes(ainda.estado))) {
907
- return { ok: false, thread: threadId, anterior, mecanismo: `parar ${dono.runtime}`,
908
- detalhe: 'runtime.unavailable: a consulta depois do encerramento nao confirma a sessao parada; o lease foi mantido' };
989
+ const s = antes.sessoes.find((x) => x.sessionId === dono.sessionId);
990
+ if (s && !TERMINAIS.includes(s.estado)) {
991
+ if (!ctl.parar(s)) {
992
+ return { ok: false, thread: threadId, anterior, mecanismo: `parar ${dono.runtime}`,
993
+ detalhe: `runtime.unavailable: o runtime ${dono.runtime} nao confirmou o encerramento; a conducao segue com a sessao ${dono.sessionId.slice(0, 8)}` };
994
+ }
995
+ const depois = ctl.consultar();
996
+ const ainda = depois.ok ? depois.sessoes.find((x) => x.sessionId === dono.sessionId) : s;
997
+ if (!depois.ok || (ainda && !TERMINAIS.includes(ainda.estado))) {
998
+ return { ok: false, thread: threadId, anterior, mecanismo: `parar ${dono.runtime}`,
999
+ detalhe: 'runtime.unavailable: a consulta depois do encerramento nao confirma a sessao parada; o lease foi mantido' };
1000
+ }
1001
+ mecanismo = `parar pelo runtime ${dono.runtime} (controle homologado)`;
1002
+ prova = `runtime: ${s.estado} -> ${ainda?.estado ?? 'ausente'}`;
1003
+ }
1004
+ else {
1005
+ mecanismo = 'nenhum: a sessao ja tinha terminado';
1006
+ prova = `runtime: ${s?.estado ?? 'sessao ausente'}`;
909
1007
  }
910
- mecanismo = `parar pelo runtime ${dono.runtime} (controle homologado)`;
911
- prova = `runtime: ${s.estado} -> ${ainda?.estado ?? 'ausente'}`;
912
- }
913
- else {
914
- mecanismo = 'nenhum: a sessao ja tinha terminado';
915
- prova = `runtime: ${s?.estado ?? 'sessao ausente'}`;
916
1008
  }
917
1009
  }
918
1010
  else if (lease && anterior?.dono.tipo === 'reserva') {