@telora/daemon 0.22.181 → 0.22.189

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 (263) hide show
  1. package/build-info.json +9 -3
  2. package/dist/audit/audit-floor-policy.d.ts +188 -0
  3. package/dist/audit/audit-floor-policy.d.ts.map +1 -0
  4. package/dist/audit/audit-floor-policy.js +353 -0
  5. package/dist/audit/audit-floor-policy.js.map +1 -0
  6. package/dist/audit/audit-prompt.d.ts +4 -177
  7. package/dist/audit/audit-prompt.d.ts.map +1 -1
  8. package/dist/audit/audit-prompt.js +6 -329
  9. package/dist/audit/audit-prompt.js.map +1 -1
  10. package/dist/completion/escalations.d.ts.map +1 -1
  11. package/dist/completion/escalations.js +4 -1
  12. package/dist/completion/escalations.js.map +1 -1
  13. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  14. package/dist/completion/review-exit-phase.js +11 -4
  15. package/dist/completion/review-exit-phase.js.map +1 -1
  16. package/dist/completion/standing-approval-convergence.d.ts.map +1 -1
  17. package/dist/completion/standing-approval-convergence.js +2 -1
  18. package/dist/completion/standing-approval-convergence.js.map +1 -1
  19. package/dist/focus/focus-executor.d.ts.map +1 -1
  20. package/dist/focus/focus-executor.js +2 -0
  21. package/dist/focus/focus-executor.js.map +1 -1
  22. package/dist/focus/focus-loop-registry.js +2 -2
  23. package/dist/focus/focus-loop-registry.js.map +1 -1
  24. package/dist/focus/session-health.d.ts.map +1 -1
  25. package/dist/focus/session-health.js +2 -1
  26. package/dist/focus/session-health.js.map +1 -1
  27. package/dist/focus-stage-lifecycle/planning-release.d.ts +52 -17
  28. package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
  29. package/dist/focus-stage-lifecycle/planning-release.js +58 -70
  30. package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
  31. package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts +108 -0
  32. package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts.map +1 -0
  33. package/dist/focus-stage-lifecycle/ratify-bar-gate.js +174 -0
  34. package/dist/focus-stage-lifecycle/ratify-bar-gate.js.map +1 -0
  35. package/dist/git/merge-to-main.d.ts.map +1 -1
  36. package/dist/git/merge-to-main.js.map +1 -1
  37. package/dist/loops/llm-client.d.ts +1 -1
  38. package/dist/loops/llm-client.d.ts.map +1 -1
  39. package/dist/loops/llm-client.js +18 -105
  40. package/dist/loops/llm-client.js.map +1 -1
  41. package/dist/nexus/index.d.ts.map +1 -1
  42. package/dist/nexus/index.js +2 -1
  43. package/dist/nexus/index.js.map +1 -1
  44. package/dist/nexus/intake-prompt-sections.d.ts +70 -0
  45. package/dist/nexus/intake-prompt-sections.d.ts.map +1 -0
  46. package/dist/nexus/intake-prompt-sections.js +145 -0
  47. package/dist/nexus/intake-prompt-sections.js.map +1 -0
  48. package/dist/nexus/intake-spawn.d.ts +49 -13
  49. package/dist/nexus/intake-spawn.d.ts.map +1 -1
  50. package/dist/nexus/intake-spawn.js +45 -122
  51. package/dist/nexus/intake-spawn.js.map +1 -1
  52. package/dist/nexus/intake.d.ts +55 -0
  53. package/dist/nexus/intake.d.ts.map +1 -1
  54. package/dist/nexus/intake.js +62 -1
  55. package/dist/nexus/intake.js.map +1 -1
  56. package/dist/prd/arm-readiness.d.ts +93 -0
  57. package/dist/prd/arm-readiness.d.ts.map +1 -0
  58. package/dist/prd/arm-readiness.js +254 -0
  59. package/dist/prd/arm-readiness.js.map +1 -0
  60. package/dist/prd/arm-refusal.d.ts +149 -0
  61. package/dist/prd/arm-refusal.d.ts.map +1 -0
  62. package/dist/prd/arm-refusal.js +219 -0
  63. package/dist/prd/arm-refusal.js.map +1 -0
  64. package/dist/prd/controller-shared.d.ts +111 -0
  65. package/dist/prd/controller-shared.d.ts.map +1 -1
  66. package/dist/prd/controller-shared.js +3 -1
  67. package/dist/prd/controller-shared.js.map +1 -1
  68. package/dist/prd/controller.d.ts +16 -10
  69. package/dist/prd/controller.d.ts.map +1 -1
  70. package/dist/prd/controller.js +28 -35
  71. package/dist/prd/controller.js.map +1 -1
  72. package/dist/prd/frontier-arming.d.ts +151 -0
  73. package/dist/prd/frontier-arming.d.ts.map +1 -0
  74. package/dist/prd/frontier-arming.js +315 -0
  75. package/dist/prd/frontier-arming.js.map +1 -0
  76. package/dist/prd/index.d.ts +10 -1
  77. package/dist/prd/index.d.ts.map +1 -1
  78. package/dist/prd/index.js +9 -1
  79. package/dist/prd/index.js.map +1 -1
  80. package/dist/prd/scoping-prompt.d.ts +68 -0
  81. package/dist/prd/scoping-prompt.d.ts.map +1 -0
  82. package/dist/prd/scoping-prompt.js +86 -0
  83. package/dist/prd/scoping-prompt.js.map +1 -0
  84. package/dist/prompt/prompt-contradictions.d.ts +20 -1
  85. package/dist/prompt/prompt-contradictions.d.ts.map +1 -1
  86. package/dist/prompt/prompt-contradictions.js +35 -0
  87. package/dist/prompt/prompt-contradictions.js.map +1 -1
  88. package/dist/prompt/team-prompt-base.d.ts +18 -0
  89. package/dist/prompt/team-prompt-base.d.ts.map +1 -1
  90. package/dist/prompt/team-prompt-base.js +56 -11
  91. package/dist/prompt/team-prompt-base.js.map +1 -1
  92. package/dist/prompt-sections/persona-sections.d.ts +36 -13
  93. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  94. package/dist/prompt-sections/persona-sections.js +93 -16
  95. package/dist/prompt-sections/persona-sections.js.map +1 -1
  96. package/dist/prompt-sections/scoping-sections.d.ts +19 -5
  97. package/dist/prompt-sections/scoping-sections.d.ts.map +1 -1
  98. package/dist/prompt-sections/scoping-sections.js +45 -38
  99. package/dist/prompt-sections/scoping-sections.js.map +1 -1
  100. package/dist/prompt-sections/shared.d.ts +8 -0
  101. package/dist/prompt-sections/shared.d.ts.map +1 -1
  102. package/dist/prompt-sections/shared.js.map +1 -1
  103. package/dist/queries/agent-resolvable-promotion.d.ts +12 -0
  104. package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
  105. package/dist/queries/agent-resolvable-promotion.js +17 -6
  106. package/dist/queries/agent-resolvable-promotion.js.map +1 -1
  107. package/dist/queries/delivery-gate-state.d.ts +3 -0
  108. package/dist/queries/delivery-gate-state.d.ts.map +1 -1
  109. package/dist/queries/delivery-gate-state.js +1 -1
  110. package/dist/queries/delivery-gate-state.js.map +1 -1
  111. package/dist/queries/focus-criteria-standing.d.ts +170 -7
  112. package/dist/queries/focus-criteria-standing.d.ts.map +1 -1
  113. package/dist/queries/focus-criteria-standing.js +143 -8
  114. package/dist/queries/focus-criteria-standing.js.map +1 -1
  115. package/dist/queries/focus-ratify-release.d.ts +43 -0
  116. package/dist/queries/focus-ratify-release.d.ts.map +1 -0
  117. package/dist/queries/focus-ratify-release.js +45 -0
  118. package/dist/queries/focus-ratify-release.js.map +1 -0
  119. package/dist/queries/focuses.d.ts +0 -10
  120. package/dist/queries/focuses.d.ts.map +1 -1
  121. package/dist/queries/focuses.js +0 -14
  122. package/dist/queries/focuses.js.map +1 -1
  123. package/dist/queries/prd.d.ts +31 -0
  124. package/dist/queries/prd.d.ts.map +1 -1
  125. package/dist/queries/prd.js +26 -1
  126. package/dist/queries/prd.js.map +1 -1
  127. package/dist/queries/shared.js +1 -1
  128. package/dist/queries/verify-own-holds.d.ts +89 -0
  129. package/dist/queries/verify-own-holds.d.ts.map +1 -0
  130. package/dist/queries/verify-own-holds.js +93 -0
  131. package/dist/queries/verify-own-holds.js.map +1 -0
  132. package/dist/resolvers/focus-criteria-standing.d.ts.map +1 -1
  133. package/dist/resolvers/focus-criteria-standing.js +324 -25
  134. package/dist/resolvers/focus-criteria-standing.js.map +1 -1
  135. package/dist/security/security-auto-inject.d.ts +51 -0
  136. package/dist/security/security-auto-inject.d.ts.map +1 -1
  137. package/dist/security/security-auto-inject.js +101 -11
  138. package/dist/security/security-auto-inject.js.map +1 -1
  139. package/dist/security/security-scan-engine.d.ts +4 -4
  140. package/dist/security/security-scan-engine.d.ts.map +1 -1
  141. package/dist/security/security-scan-engine.js +6 -0
  142. package/dist/security/security-scan-engine.js.map +1 -1
  143. package/dist/session/session-lineage.d.ts.map +1 -1
  144. package/dist/session/session-lineage.js +2 -0
  145. package/dist/session/session-lineage.js.map +1 -1
  146. package/dist/shell/constants.d.ts +5 -0
  147. package/dist/shell/constants.d.ts.map +1 -1
  148. package/dist/shell/constants.js +5 -0
  149. package/dist/shell/constants.js.map +1 -1
  150. package/dist/shell/daemon-instance.d.ts +74 -64
  151. package/dist/shell/daemon-instance.d.ts.map +1 -1
  152. package/dist/shell/daemon-instance.js +16 -121
  153. package/dist/shell/daemon-instance.js.map +1 -1
  154. package/dist/shell/health-events.js +1 -1
  155. package/dist/shell/health-events.js.map +1 -1
  156. package/dist/shell/instance-liveness.d.ts +112 -0
  157. package/dist/shell/instance-liveness.d.ts.map +1 -0
  158. package/dist/shell/instance-liveness.js +205 -0
  159. package/dist/shell/instance-liveness.js.map +1 -0
  160. package/dist/shell/schema-version-gate.d.ts +22 -0
  161. package/dist/shell/schema-version-gate.d.ts.map +1 -1
  162. package/dist/shell/schema-version-gate.js +116 -6
  163. package/dist/shell/schema-version-gate.js.map +1 -1
  164. package/dist/shell/worker-pidfile.d.ts +21 -8
  165. package/dist/shell/worker-pidfile.d.ts.map +1 -1
  166. package/dist/shell/worker-pidfile.js +38 -9
  167. package/dist/shell/worker-pidfile.js.map +1 -1
  168. package/dist/spawn/lead-launch.d.ts.map +1 -1
  169. package/dist/spawn/lead-launch.js +2 -1
  170. package/dist/spawn/lead-launch.js.map +1 -1
  171. package/dist/spawn/one-shot-model.d.ts +145 -0
  172. package/dist/spawn/one-shot-model.d.ts.map +1 -0
  173. package/dist/spawn/one-shot-model.js +329 -0
  174. package/dist/spawn/one-shot-model.js.map +1 -0
  175. package/dist/spawn/one-shot-scoping-spawn.d.ts +51 -0
  176. package/dist/spawn/one-shot-scoping-spawn.d.ts.map +1 -0
  177. package/dist/spawn/one-shot-scoping-spawn.js +156 -0
  178. package/dist/spawn/one-shot-scoping-spawn.js.map +1 -0
  179. package/dist/spawn/process-spawn.d.ts +12 -0
  180. package/dist/spawn/process-spawn.d.ts.map +1 -1
  181. package/dist/spawn/process-spawn.js +1 -1
  182. package/dist/spawn/process-spawn.js.map +1 -1
  183. package/dist/spawn/prompt-assembly.d.ts +8 -0
  184. package/dist/spawn/prompt-assembly.d.ts.map +1 -1
  185. package/dist/spawn/prompt-assembly.js +15 -3
  186. package/dist/spawn/prompt-assembly.js.map +1 -1
  187. package/dist/spawn/review-hold-park.d.ts.map +1 -1
  188. package/dist/spawn/review-hold-park.js +7 -3
  189. package/dist/spawn/review-hold-park.js.map +1 -1
  190. package/dist/spawn/routing-decider-spawn.d.ts +30 -0
  191. package/dist/spawn/routing-decider-spawn.d.ts.map +1 -1
  192. package/dist/spawn/routing-decider-spawn.js +84 -2
  193. package/dist/spawn/routing-decider-spawn.js.map +1 -1
  194. package/dist/spawn/routing-decider.d.ts.map +1 -1
  195. package/dist/spawn/routing-decider.js +22 -0
  196. package/dist/spawn/routing-decider.js.map +1 -1
  197. package/dist/spawn/spawn-cooldown.d.ts +15 -1
  198. package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
  199. package/dist/spawn/spawn-cooldown.js +67 -19
  200. package/dist/spawn/spawn-cooldown.js.map +1 -1
  201. package/dist/spawn/worktree-session.d.ts +24 -6
  202. package/dist/spawn/worktree-session.d.ts.map +1 -1
  203. package/dist/spawn/worktree-session.js +37 -14
  204. package/dist/spawn/worktree-session.js.map +1 -1
  205. package/dist/testing/arm-coverage-model.d.ts +75 -0
  206. package/dist/testing/arm-coverage-model.d.ts.map +1 -0
  207. package/dist/testing/arm-coverage-model.js +114 -0
  208. package/dist/testing/arm-coverage-model.js.map +1 -0
  209. package/dist/testing/fixtures/index.js +1 -1
  210. package/dist/types/index.js +1 -1
  211. package/dist/verify/ai-inspection-runner.d.ts.map +1 -1
  212. package/dist/verify/ai-inspection-runner.js +26 -7
  213. package/dist/verify/ai-inspection-runner.js.map +1 -1
  214. package/dist/verify/de-restatement.d.ts +9 -2
  215. package/dist/verify/de-restatement.d.ts.map +1 -1
  216. package/dist/verify/de-restatement.js +14 -76
  217. package/dist/verify/de-restatement.js.map +1 -1
  218. package/dist/verify/default-on-guards.d.ts +5 -2
  219. package/dist/verify/default-on-guards.d.ts.map +1 -1
  220. package/dist/verify/default-on-guards.js +5 -3
  221. package/dist/verify/default-on-guards.js.map +1 -1
  222. package/dist/verify/verification-boundary-env.d.ts +7 -2
  223. package/dist/verify/verification-boundary-env.d.ts.map +1 -1
  224. package/dist/verify/verification-boundary-env.js +9 -4
  225. package/dist/verify/verification-boundary-env.js.map +1 -1
  226. package/dist/verify/verification-deps-default.d.ts.map +1 -1
  227. package/dist/verify/verification-deps-default.js +6 -0
  228. package/dist/verify/verification-deps-default.js.map +1 -1
  229. package/dist/verify/verification-deps.d.ts +10 -0
  230. package/dist/verify/verification-deps.d.ts.map +1 -1
  231. package/dist/verify/verification-deterministic.d.ts +7 -0
  232. package/dist/verify/verification-deterministic.d.ts.map +1 -1
  233. package/dist/verify/verification-deterministic.js.map +1 -1
  234. package/dist/verify/verification-engine.d.ts +1 -20
  235. package/dist/verify/verification-engine.d.ts.map +1 -1
  236. package/dist/verify/verification-engine.js +24 -55
  237. package/dist/verify/verification-engine.js.map +1 -1
  238. package/dist/verify/verification-evidence-unavailable-feedback.d.ts +3 -1
  239. package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -1
  240. package/dist/verify/verification-evidence-unavailable-feedback.js +3 -1
  241. package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -1
  242. package/dist/verify/verification-feedback.d.ts +4 -12
  243. package/dist/verify/verification-feedback.d.ts.map +1 -1
  244. package/dist/verify/verification-feedback.js +7 -12
  245. package/dist/verify/verification-feedback.js.map +1 -1
  246. package/dist/verify/verification-history-reset.d.ts.map +1 -1
  247. package/dist/verify/verification-history-reset.js +11 -3
  248. package/dist/verify/verification-history-reset.js.map +1 -1
  249. package/dist/verify/verification-model-unavailable-hold.d.ts +92 -0
  250. package/dist/verify/verification-model-unavailable-hold.d.ts.map +1 -0
  251. package/dist/verify/verification-model-unavailable-hold.js +207 -0
  252. package/dist/verify/verification-model-unavailable-hold.js.map +1 -0
  253. package/dist/verify/verification-strategies.d.ts +32 -0
  254. package/dist/verify/verification-strategies.d.ts.map +1 -0
  255. package/dist/verify/verification-strategies.js +47 -0
  256. package/dist/verify/verification-strategies.js.map +1 -0
  257. package/dist/verify/verify-reconciliation.d.ts.map +1 -1
  258. package/dist/verify/verify-reconciliation.js +2 -1
  259. package/dist/verify/verify-reconciliation.js.map +1 -1
  260. package/dist/verify/verify-restatement.d.ts.map +1 -1
  261. package/dist/verify/verify-restatement.js +21 -8
  262. package/dist/verify/verify-restatement.js.map +1 -1
  263. package/package.json +2 -2
@@ -0,0 +1,329 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/spawn/one-shot-model.test.ts,
3
+ // packages/daemon/src/verify/verification-engine.test.ts,
4
+ // packages/daemon/src/verify/verification-model-unavailable-hold.test.ts,
5
+ // packages/daemon/src/verify/verify-restatement.test.ts
6
+ // PINNED-BY-END
7
+ /**
8
+ * One-shot model invocation: the single `claude --print` spawner every
9
+ * non-team model call in the daemon goes through.
10
+ *
11
+ * Before this module each caller (verify/de-restatement.ts, loops/llm-client.ts)
12
+ * spawned its own `claude --print`, discarded stdout on a non-zero exit and
13
+ * rejected with a bare Error carrying only stderr -- which the CLI leaves EMPTY
14
+ * on a rate limit. On 2026-09-23 (mars) the account was rate limited for ten
15
+ * hours; every one-shot exited 1 with the reason invisible, and every caller
16
+ * consumed that exit as a result: verify wrote it into the shortfall slot and
17
+ * parked four deliveries, the routing decider stamped it as a decision attempt.
18
+ * Meanwhile spawn-cooldown.ts knew the window and held only team spawns.
19
+ *
20
+ * What this module changes, at the source:
21
+ * - ONE argv and ONE result shape. Output is stream-json, so the CLI's own
22
+ * `rate_limit_event` (the typed reset instant the team path already reads
23
+ * via spawn/rate-limit.ts) and the `result` event (is_error, api_error_status,
24
+ * usage, cost) are parsed rather than guessed from prose.
25
+ * - A failure is a TYPED outcome. ModelUnavailable names its kind (rate_limit,
26
+ * auth, timeout, spawn, unknown), the exit code, the reset instant when the
27
+ * provider gave one, and the tail of BOTH streams. A caller that must tell
28
+ * "the model could not run" from "the model judged" reads `kind`; a caller
29
+ * that only catches keeps working (it is still an Error).
30
+ * - The provider-wide window is READ before spawning and WRITTEN on a
31
+ * rate-limit rejection (spawn-cooldown.ts providerRateLimitHoldUntilMs /
32
+ * recordProviderRateLimit). During an open window no subprocess is spawned:
33
+ * the call rejects at once with kind rate_limit and the reset instant.
34
+ *
35
+ * @module spawn/one-shot-model
36
+ */
37
+ import { spawn } from 'node:child_process';
38
+ import { createLogger } from '../shell/log.js';
39
+ import { trackChildProcess } from './worker-registry.js';
40
+ import { parseRateLimitInfo } from './rate-limit.js';
41
+ import { providerRateLimitHoldUntilMs, recordProviderRateLimit } from './spawn-cooldown.js';
42
+ const log = createLogger({ module: 'one-shot-model' });
43
+ const DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
44
+ /** How much of each stream a failure carries (enough to read the reason, never the whole transcript). */
45
+ const STREAM_TAIL_CHARS = 2000;
46
+ /**
47
+ * A model invocation that could not COMPLETE. Never a judgment: the model was
48
+ * not reached, was refused, or did not answer in time. Callers hold or retry on
49
+ * it; none of them may record it as a verdict, a shortfall or an attempt.
50
+ */
51
+ export class ModelUnavailable extends Error {
52
+ kind;
53
+ label;
54
+ exitCode;
55
+ /** Epoch ms when the provider says capacity returns (rate_limit only, when it said). */
56
+ resetAtMs;
57
+ stdoutTail;
58
+ stderrTail;
59
+ constructor(args) {
60
+ super(formatModelUnavailable(args));
61
+ this.name = 'ModelUnavailable';
62
+ this.kind = args.kind;
63
+ this.label = args.label;
64
+ this.exitCode = args.exitCode ?? null;
65
+ this.resetAtMs = args.resetAtMs ?? null;
66
+ this.stdoutTail = args.stdoutTail ?? '';
67
+ this.stderrTail = args.stderrTail ?? '';
68
+ }
69
+ }
70
+ function formatModelUnavailable(args) {
71
+ const parts = [`${args.label}: model unavailable (${args.kind}`];
72
+ if (args.exitCode !== undefined && args.exitCode !== null)
73
+ parts.push(`, exit ${args.exitCode}`);
74
+ if (args.resetAtMs !== undefined && args.resetAtMs !== null) {
75
+ parts.push(`, resets ${new Date(args.resetAtMs).toISOString()}`);
76
+ }
77
+ parts.push(')');
78
+ const reason = args.detail
79
+ ?? lastLine(args.stderrTail ?? '')
80
+ ?? lastLine(args.stdoutTail ?? '');
81
+ if (reason)
82
+ parts.push(`: ${reason}`);
83
+ return parts.join('');
84
+ }
85
+ function lastLine(text) {
86
+ const lines = text.split('\n').map((l) => l.trim()).filter((l) => l !== '');
87
+ return lines.length > 0 ? lines[lines.length - 1] : null;
88
+ }
89
+ /** Type guard: the thrown value is a typed unavailability, not a model judgment. */
90
+ export function isModelUnavailable(err) {
91
+ return err instanceof ModelUnavailable;
92
+ }
93
+ function isRecord(value) {
94
+ return typeof value === 'object' && value !== null;
95
+ }
96
+ /**
97
+ * Parse a `--output-format stream-json` transcript. One JSON object per line;
98
+ * lines that are not JSON (or not events we read) are skipped, so a partial
99
+ * transcript from a killed child still yields what it had. Pure.
100
+ */
101
+ export function parseOneShotStream(stdout) {
102
+ const summary = {};
103
+ for (const line of stdout.split('\n')) {
104
+ const trimmed = line.trim();
105
+ if (trimmed === '' || !trimmed.startsWith('{'))
106
+ continue;
107
+ let event;
108
+ try {
109
+ event = JSON.parse(trimmed);
110
+ }
111
+ catch {
112
+ continue;
113
+ }
114
+ if (!isRecord(event))
115
+ continue;
116
+ const type = event['type'];
117
+ if (type === 'system' && event['subtype'] === 'init' && typeof event['model'] === 'string') {
118
+ summary.initModel = event['model'];
119
+ continue;
120
+ }
121
+ if (type === 'rate_limit_event') {
122
+ const info = parseRateLimitInfo(event);
123
+ if (info && info.status === 'rejected') {
124
+ summary.rateLimitRejected = { resetAtMs: info.resetsAtMs, rateLimitType: info.rateLimitType };
125
+ }
126
+ continue;
127
+ }
128
+ if (type === 'result') {
129
+ const usage = isRecord(event['usage']) ? event['usage'] : undefined;
130
+ const modelUsage = event['modelUsage'];
131
+ const modelUsageKey = isRecord(modelUsage) ? Object.keys(modelUsage)[0] : undefined;
132
+ const status = event['api_error_status'];
133
+ summary.result = {
134
+ isError: event['is_error'] === true,
135
+ text: typeof event['result'] === 'string' ? event['result'] : null,
136
+ apiErrorStatus: typeof status === 'number' ? status : null,
137
+ ...(usage ? { usage } : {}),
138
+ ...(modelUsageKey ? { modelUsageKey } : {}),
139
+ costUsd: typeof event['total_cost_usd'] === 'number' ? event['total_cost_usd'] : null,
140
+ };
141
+ }
142
+ }
143
+ return summary;
144
+ }
145
+ /** The CLI's prose for a limit, when the typed event was not in the transcript (text mode, older CLI). */
146
+ const RATE_LIMIT_PROSE = /hit your (session|usage|weekly) limit|rate limit(ed)? (reached|exceeded)|usage limit|too many requests/i;
147
+ /** The CLI's prose for a refused credential. */
148
+ const AUTH_PROSE = /not logged in|unauthori[sz]ed|invalid api key|authentication (failed|required)/i;
149
+ /**
150
+ * The provider refusal the CLI's PROSE names, or null. One classifier for every
151
+ * spawner (the routing decider reads its result text through this too), so a CLI
152
+ * build whose rejection carries words but no status is read the same way
153
+ * everywhere. Callers pass prose only -- never a stream-json event line. Pure.
154
+ */
155
+ export function providerRefusalInProse(prose) {
156
+ if (RATE_LIMIT_PROSE.test(prose))
157
+ return 'rate_limit';
158
+ if (AUTH_PROSE.test(prose))
159
+ return 'auth';
160
+ return null;
161
+ }
162
+ /**
163
+ * The human-readable part of what the child wrote: the result text, stderr, and
164
+ * any stdout line that is NOT a stream-json event. The event lines are never
165
+ * scanned -- every healthy transcript carries the literal `rate_limit_event`
166
+ * (status allowed), and an assistant text block about "authentication" is the
167
+ * model's answer, not the provider's refusal. Pure.
168
+ */
169
+ function proseOf(summary, stdout, stderr) {
170
+ const plain = stdout.split('\n').filter((line) => !line.trim().startsWith('{'));
171
+ return [summary.result?.text ?? '', ...plain, stderr].join('\n');
172
+ }
173
+ /**
174
+ * Classify a finished child that did NOT complete an answer. Pure: takes what
175
+ * was observed, names the kind. Order matters: a typed rate-limit event beats
176
+ * every other signal, a status beats prose, and a timeout with no provider
177
+ * signal is a timeout (the prose is only consulted when nothing typed explains
178
+ * the exit).
179
+ */
180
+ export function classifyOneShotFailure(args) {
181
+ if (args.summary.rateLimitRejected) {
182
+ return { kind: 'rate_limit', resetAtMs: args.summary.rateLimitRejected.resetAtMs };
183
+ }
184
+ const status = args.summary.result?.apiErrorStatus ?? null;
185
+ if (status === 429)
186
+ return { kind: 'rate_limit', resetAtMs: null };
187
+ if (status === 401 || status === 403)
188
+ return { kind: 'auth', resetAtMs: null };
189
+ if (args.timedOut)
190
+ return { kind: 'timeout', resetAtMs: null };
191
+ const refusal = providerRefusalInProse(proseOf(args.summary, args.stdout, args.stderr));
192
+ return { kind: refusal ?? 'unknown', resetAtMs: null };
193
+ }
194
+ // ---------------------------------------------------------------------------
195
+ // Invocation
196
+ // ---------------------------------------------------------------------------
197
+ /** The argv every one-shot uses. Exported so a test can pin it without spawning. */
198
+ export function buildOneShotArgs(systemPrompt) {
199
+ return [
200
+ '--print',
201
+ '--output-format', 'stream-json',
202
+ '--verbose',
203
+ '--no-session-persistence',
204
+ '--system-prompt', systemPrompt,
205
+ ];
206
+ }
207
+ /** One log line per open window, not one per held call (verify ticks every ~90s per delivery). */
208
+ let lastLoggedHoldUntilMs = null;
209
+ /** The typed refusal for a call made inside an open provider window, or null when no window is open. */
210
+ function heldByProviderWindow(label, nowMs) {
211
+ const holdUntil = providerRateLimitHoldUntilMs(nowMs);
212
+ if (holdUntil === null)
213
+ return null;
214
+ if (lastLoggedHoldUntilMs !== holdUntil) {
215
+ lastLoggedHoldUntilMs = holdUntil;
216
+ log.info(`[one-shot] ${label}: not spawning -- provider rate limit holds every call until ` +
217
+ `${new Date(holdUntil).toISOString()}`);
218
+ }
219
+ return new ModelUnavailable({
220
+ kind: 'rate_limit',
221
+ label,
222
+ resetAtMs: holdUntil,
223
+ detail: 'provider rate-limit window open; no subprocess spawned',
224
+ });
225
+ }
226
+ /** The completed answer a parsed transcript amounts to. Pure. */
227
+ function completedResult(summary) {
228
+ const result = summary.result;
229
+ const model = summary.initModel ?? result.modelUsageKey;
230
+ return {
231
+ text: result.text ?? '',
232
+ ...(result.usage ? { usage: result.usage } : {}),
233
+ ...(model ? { model } : {}),
234
+ costUsd: result.costUsd,
235
+ };
236
+ }
237
+ /**
238
+ * Invoke the model once. The user message goes on stdin; the system prompt on
239
+ * argv. Resolves with the completed answer; rejects with ModelUnavailable when
240
+ * the model could not be reached, was refused or did not answer in time. Any
241
+ * other rejection is a programming error in this wrapper, not a model outcome.
242
+ */
243
+ export function invokeOneShotModel(systemPrompt, userMessage, opts) {
244
+ const label = opts.label;
245
+ const nowMs = opts.nowMs ?? (() => Date.now());
246
+ const claudeBin = opts.claudeBin ?? 'claude';
247
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
248
+ const spawnFn = opts.spawnFn ?? ((cmd, args, sopts) => spawn(cmd, args, sopts));
249
+ const held = heldByProviderWindow(label, nowMs());
250
+ if (held)
251
+ return Promise.reject(held);
252
+ return new Promise((resolve, reject) => {
253
+ let child;
254
+ try {
255
+ child = spawnFn(claudeBin, buildOneShotArgs(systemPrompt), { stdio: ['pipe', 'pipe', 'pipe'] });
256
+ }
257
+ catch (err) {
258
+ reject(new ModelUnavailable({ kind: 'spawn', label, detail: `spawn failed: ${err.message}` }));
259
+ return;
260
+ }
261
+ // Register so a graceful stop reaps this one-shot if it is still running.
262
+ trackChildProcess(child, label);
263
+ let stdout = '';
264
+ let stderr = '';
265
+ let timedOut = false;
266
+ let settled = false;
267
+ child.stdout?.on('data', (chunk) => { stdout += chunk.toString('utf8'); });
268
+ child.stderr?.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
269
+ // A child that exits before draining stdin emits EPIPE on the stdin socket
270
+ // asynchronously; unhandled, that would crash the daemon. The close handler
271
+ // classifies the exit; the write error itself carries nothing more.
272
+ child.stdin?.on?.('error', () => { });
273
+ // The timeout SETTLES the call: 'close' waits for every stdio pipe, and a
274
+ // grandchild (an MCP server the CLI started) that inherited stdout can hold
275
+ // it open after the CLI is dead. The child stays in the worker registry for
276
+ // the teardown reap; a late 'close' is ignored (settled).
277
+ const timer = setTimeout(() => {
278
+ timedOut = true;
279
+ try {
280
+ child.kill('SIGKILL');
281
+ }
282
+ catch { /* ignore */ }
283
+ const { kind, resetAtMs } = classifyOneShotFailure({ exitCode: null, timedOut, summary: parseOneShotStream(stdout), stdout, stderr });
284
+ fail(kind, null, resetAtMs, `no answer within ${Math.round(timeoutMs / 1000)}s; killed`);
285
+ }, timeoutMs);
286
+ const fail = (kind, exitCode, resetAtMs, detail) => {
287
+ if (settled)
288
+ return;
289
+ settled = true;
290
+ clearTimeout(timer);
291
+ if (kind === 'rate_limit' && resetAtMs !== null)
292
+ recordProviderRateLimit(resetAtMs, nowMs());
293
+ reject(new ModelUnavailable({
294
+ kind,
295
+ label,
296
+ exitCode,
297
+ resetAtMs,
298
+ stdoutTail: stdout.slice(-STREAM_TAIL_CHARS),
299
+ stderrTail: stderr.slice(-STREAM_TAIL_CHARS),
300
+ ...(detail ? { detail } : {}),
301
+ }));
302
+ };
303
+ child.on('error', (err) => {
304
+ fail('spawn', null, null, `spawn error: ${err.message}`);
305
+ });
306
+ child.on('close', (code) => {
307
+ if (settled)
308
+ return;
309
+ const summary = parseOneShotStream(stdout);
310
+ const completed = code === 0 && summary.result !== undefined && !summary.result.isError;
311
+ if (!completed) {
312
+ const { kind, resetAtMs } = classifyOneShotFailure({ exitCode: code, timedOut, summary, stdout, stderr });
313
+ fail(kind, code, resetAtMs, summary.result?.text ?? undefined);
314
+ return;
315
+ }
316
+ settled = true;
317
+ clearTimeout(timer);
318
+ resolve(completedResult(summary));
319
+ });
320
+ try {
321
+ child.stdin?.write(userMessage);
322
+ child.stdin?.end();
323
+ }
324
+ catch (err) {
325
+ fail('spawn', null, null, `stdin write failed: ${err.message}`);
326
+ }
327
+ });
328
+ }
329
+ //# sourceMappingURL=one-shot-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"one-shot-model.js","sourceRoot":"","sources":["../../src/spawn/one-shot-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { DaemonConfig } from '../types/index.js';
2
+ /**
3
+ * Kill a scoping agent that has not exited within this window (15 minutes).
4
+ *
5
+ * A caller's staleness window (the interval after which it will spawn a
6
+ * REPLACEMENT) must be strictly greater than this plus the SIGKILL grace, or a
7
+ * healthy long-running agent is double-spawned right as it finishes.
8
+ */
9
+ export declare const SCOPING_AGENT_TIMEOUT_MS: number;
10
+ /** Grace between SIGTERM and SIGKILL when the kill timeout fires. */
11
+ export declare const SCOPING_AGENT_SIGKILL_GRACE_MS = 10000;
12
+ /** Injectable process spawn seam (overridable in tests). */
13
+ export interface ScopingSpawnSeam {
14
+ spawnProcess: (command: string, args: string[], cwd: string, env: NodeJS.ProcessEnv) => {
15
+ pid?: number;
16
+ on: (event: string, cb: (arg?: unknown) => void) => void;
17
+ stdin?: {
18
+ end: () => void;
19
+ } | null;
20
+ };
21
+ }
22
+ /** One scoping agent to spawn: what to say to it, and who is asking. */
23
+ export interface OneShotScopingSpawn {
24
+ /**
25
+ * What this run is scoping, for the log line -- e.g. `request <uuid>` or
26
+ * `PRD overcome <uuid> (focus <uuid>)`. Never a UUID on its own: a log line
27
+ * that names only an id cannot be read without a second query.
28
+ */
29
+ label: string;
30
+ /** The fully-built prompt (a PURE builder's output), passed as a CLI arg. */
31
+ prompt: string;
32
+ /** Logger module name, so each caller's lines stay greppable under its own tag. */
33
+ logModule: string;
34
+ /** Kill timeout override (defaults to SCOPING_AGENT_TIMEOUT_MS). */
35
+ timeoutMs?: number;
36
+ /**
37
+ * Called once the process CLOSES, with its exit code (null when the code is
38
+ * unknown -- a signal kill, or a close event carrying no code). This is how a
39
+ * caller learns the run ended; the returned promise deliberately does not
40
+ * carry it, because it resolves minutes earlier.
41
+ */
42
+ onExit?: (code: number | null) => void;
43
+ }
44
+ /**
45
+ * Spawn a one-shot scoping agent. Resolves once the process has SPAWNED
46
+ * (fire-and-forget); rejects only if the process fails to spawn. The
47
+ * close/error handlers log the outcome and invoke `onExit`; the kill timeout
48
+ * bounds a hung agent.
49
+ */
50
+ export declare function spawnOneShotScopingAgent(config: DaemonConfig, request: OneShotScopingSpawn, seam?: ScopingSpawnSeam): Promise<void>;
51
+ //# sourceMappingURL=one-shot-scoping-spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"one-shot-scoping-spawn.d.ts","sourceRoot":"","sources":["../../src/spawn/one-shot-scoping-spawn.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAiB,CAAC;AAEvD,qEAAqE;AACrE,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAErD,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK;QACtF,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;QACzD,KAAK,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,IAAI,CAAA;SAAE,GAAG,IAAI,CAAC;KACpC,CAAC;CACH;AAOD,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACxC;AAOD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,mBAAmB,EAC5B,IAAI,GAAE,gBAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAgFf"}
@@ -0,0 +1,156 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/prd/prd-frontier-arming.test.ts,
3
+ // packages/daemon/src/spawn/one-shot-scoping-spawn.test.ts
4
+ // PINNED-BY-END
5
+ /**
6
+ * The ONE-SHOT SCOPING AGENT spawn seam.
7
+ *
8
+ * A scoping agent is a short-lived `claude --print` process whose whole job is
9
+ * to AUTHOR intent through the telora_* MCP tools and exit -- it writes no
10
+ * application code, makes no git changes, and runs in the product repo (where
11
+ * the per-product .mcp.json + CLAUDE.md live) rather than an isolated worktree.
12
+ *
13
+ * WHY THIS MODULE EXISTS (the choice a reviewer should check). The machinery
14
+ * was written for nexus intake (`nexus/intake-spawn.ts`). The PRD frontier
15
+ * needs the SAME process shape -- same kill timeout, same fire-and-forget
16
+ * settle, same cleaned env, same close/error logging -- for a different prompt.
17
+ * The delivery offered two shapes: extract the machinery so both callers share
18
+ * it, or add a thin helper and let each caller keep its own copy of the
19
+ * timeout/settle/log logic. EXTRACTION was taken: the copy is precisely where
20
+ * two spawners drift (one grows an unref'd timer, one does not; one resolves on
21
+ * 'spawn', one on 'close'), and the drift is invisible until a hung agent holds
22
+ * the daemon's event loop. What each caller keeps is its own PURE prompt
23
+ * builder -- the part that genuinely differs and is worth unit-testing on its
24
+ * own (`nexus/intake-spawn.ts` `buildIntakeScopingPrompt`,
25
+ * `prd/scoping-prompt.ts` `buildPrdScopingPrompt`).
26
+ *
27
+ * The extraction is behaviour-preserving for intake: the timeout, the SIGKILL
28
+ * grace, the resolve-on-'spawn' contract and every log line moved here
29
+ * verbatim, and intake re-exports the seam type + timeout constant under their
30
+ * original names so nothing downstream had to change.
31
+ *
32
+ * FIRE-AND-FORGET: a scoping agent runs for minutes. `spawnOneShotScopingAgent`
33
+ * resolves the moment the process is up (the 'spawn' event), NOT on close, so a
34
+ * daemon poll loop is never blocked. The caller's own in-flight guard (intake's
35
+ * `intake_scoping_started_at` stamp; the PRD controller's scoping-run ledger)
36
+ * is what prevents a re-spawn -- never this promise.
37
+ */
38
+ import { spawn } from 'node:child_process';
39
+ import { stripClaudeCodeEnvVars } from '@telora/daemon-core';
40
+ import { createLogger } from '../shell/log.js';
41
+ /**
42
+ * Kill a scoping agent that has not exited within this window (15 minutes).
43
+ *
44
+ * A caller's staleness window (the interval after which it will spawn a
45
+ * REPLACEMENT) must be strictly greater than this plus the SIGKILL grace, or a
46
+ * healthy long-running agent is double-spawned right as it finishes.
47
+ */
48
+ export const SCOPING_AGENT_TIMEOUT_MS = 15 * 60 * 1000;
49
+ /** Grace between SIGTERM and SIGKILL when the kill timeout fires. */
50
+ export const SCOPING_AGENT_SIGKILL_GRACE_MS = 10_000;
51
+ const defaultSeam = {
52
+ spawnProcess: (command, args, cwd, env) => spawn(command, args, { cwd, env, stdio: ['pipe', 'pipe', 'pipe'] }),
53
+ };
54
+ /** Normalize a close event's argument to an exit code or null. */
55
+ function toExitCode(code) {
56
+ return typeof code === 'number' ? code : null;
57
+ }
58
+ /**
59
+ * Spawn a one-shot scoping agent. Resolves once the process has SPAWNED
60
+ * (fire-and-forget); rejects only if the process fails to spawn. The
61
+ * close/error handlers log the outcome and invoke `onExit`; the kill timeout
62
+ * bounds a hung agent.
63
+ */
64
+ export function spawnOneShotScopingAgent(config, request, seam = defaultSeam) {
65
+ const log = createLogger({ module: request.logModule });
66
+ const timeoutMs = request.timeoutMs ?? SCOPING_AGENT_TIMEOUT_MS;
67
+ const args = [
68
+ '--print',
69
+ '--dangerously-skip-permissions',
70
+ '--setting-sources', 'project,local',
71
+ request.prompt,
72
+ ];
73
+ const env = stripClaudeCodeEnvVars(process.env);
74
+ const cwd = config.repoPath ?? process.cwd();
75
+ return new Promise((resolve, reject) => {
76
+ let settled = false;
77
+ let exitReported = false;
78
+ let proc;
79
+ try {
80
+ proc = seam.spawnProcess(config.claudeCodePath, args, cwd, env);
81
+ }
82
+ catch (err) {
83
+ reject(err instanceof Error ? err : new Error(String(err)));
84
+ return;
85
+ }
86
+ // Prompt is a CLI arg; close stdin immediately.
87
+ proc.stdin?.end?.();
88
+ const timeout = setTimeout(() => {
89
+ log.warn(`scoping agent for ${request.label} timed out after ${timeoutMs / 1000}s, killing`);
90
+ if (proc.pid) {
91
+ try {
92
+ process.kill(proc.pid, 'SIGTERM');
93
+ }
94
+ catch { /* ignore */ }
95
+ setTimeout(() => {
96
+ if (proc.pid) {
97
+ try {
98
+ process.kill(proc.pid, 'SIGKILL');
99
+ }
100
+ catch { /* ignore */ }
101
+ }
102
+ }, SCOPING_AGENT_SIGKILL_GRACE_MS);
103
+ }
104
+ }, timeoutMs);
105
+ // Do not let the kill timer keep the daemon event loop alive.
106
+ timeout.unref?.();
107
+ // The exit is reported at most ONCE, on whichever of close/error fires
108
+ // first: a caller's ledger moves the run out of 'in flight' on this
109
+ // callback, and a second report would clear a ledger entry a LATER spawn
110
+ // had already replaced.
111
+ const reportExit = (code) => {
112
+ if (exitReported)
113
+ return;
114
+ exitReported = true;
115
+ try {
116
+ request.onExit?.(code);
117
+ }
118
+ catch (err) {
119
+ // A caller's bookkeeping must never take down the daemon from a
120
+ // child-process event handler.
121
+ log.warn(`scoping agent exit handler for ${request.label} threw: ${err.message}`);
122
+ }
123
+ };
124
+ proc.on('spawn', () => {
125
+ // Process is up -- the daemon poll continues; the agent runs to completion
126
+ // in the background.
127
+ log.info(`scoping agent spawned for ${request.label} (PID: ${proc.pid ?? '?'})`);
128
+ if (!settled) {
129
+ settled = true;
130
+ resolve();
131
+ }
132
+ });
133
+ proc.on('close', (code) => {
134
+ clearTimeout(timeout);
135
+ log.info(`scoping agent for ${request.label} exited (code: ${code ?? '?'})`);
136
+ reportExit(toExitCode(code));
137
+ // If 'spawn' never fired (very early exit), still resolve -- the caller's
138
+ // in-flight guard already prevents an immediate re-spawn.
139
+ if (!settled) {
140
+ settled = true;
141
+ resolve();
142
+ }
143
+ });
144
+ proc.on('error', (err) => {
145
+ clearTimeout(timeout);
146
+ const message = err instanceof Error ? err.message : String(err);
147
+ log.error(`scoping agent spawn error for ${request.label}: ${message}`);
148
+ reportExit(null);
149
+ if (!settled) {
150
+ settled = true;
151
+ reject(new Error(message));
152
+ }
153
+ });
154
+ });
155
+ }
156
+ //# sourceMappingURL=one-shot-scoping-spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"one-shot-scoping-spawn.js","sourceRoot":"","sources":["../../src/spawn/one-shot-scoping-spawn.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ import type { SessionCloseUpdate } from '../queries/sessions.js';
22
22
  import type { ExitCategory } from '../types/index.js';
23
23
  import { fetchBackendEnvExtras } from './spawn-environment.js';
24
24
  import type { LeadOwnershipDeps } from './lead-process-ownership.js';
25
+ import type { LeadRecordDeps } from './lead-launch.js';
25
26
  import { getPendingSpawnDirective } from '../directive/directive-executor.js';
26
27
  import { type AssemblyManifestEntry } from '../resolvers/assembly-engine.js';
27
28
  import { insertAssemblyManifest } from '../queries/context-assembly.js';
@@ -102,6 +103,17 @@ export interface SpawnTeamProcessDeps {
102
103
  markDirectedAnswersConsumed?: typeof markDirectedAnswersConsumed;
103
104
  /** The lead's process-ownership record and kill path (spawn/lead-launch.ts). */
104
105
  ownership?: LeadOwnershipDeps;
106
+ /**
107
+ * The PRE-SPAWN reservation seam, which launchLeadProcess takes in a bag
108
+ * SEPARATE from `ownership`. It has to be threaded here too: a test that
109
+ * injects only `ownership` leaves `records.reserve` defaulting to
110
+ * `reserveLeadRecord(r)` with no path, which writes
111
+ * `$TELORA_STATE_DIR || ~/.telora` + `/daemon.workers.json` -- the LIVE fleet
112
+ * record of whatever host the suite runs on. That is the seam that put a
113
+ * `{"label":"Owned focus","focusId":"focus-own"}` reservation into the running
114
+ * daemon's record on mars.
115
+ */
116
+ records?: LeadRecordDeps;
105
117
  /** The child_process spawn the lead is launched with. */
106
118
  spawn?: typeof spawn;
107
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"process-spawn.d.ts","sourceRoot":"","sources":["../../src/spawn/process-spawn.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process-spawn.d.ts","sourceRoot":"","sources":["../../src/spawn/process-spawn.ts"],"names":[],"mappings":"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"}
@@ -441,7 +441,7 @@ export async function spawnTeamProcess(spec) {
441
441
  const proc = await launchLeadProcess({
442
442
  focusId, focusName, teamState, sessionId: session.id,
443
443
  spawn: () => spawnCrashIsolated(spawnCommand, spawnArgs, { cwd: worktreePath, env: spawnEnv }, handleProcessError, spec.deps?.spawn),
444
- }, spec.deps?.ownership);
444
+ }, spec.deps?.ownership, spec.deps?.records);
445
445
  if (!proc)
446
446
  return refuseSpawnOverUnendedLead({ update: updateSession, sessionId: session.id, focusId, teamState, logs, governor });
447
447
  // Attach stream parser, completion detector, activity tracker, event handlers