openplanr 1.21.2 → 1.22.0

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 (100) hide show
  1. package/dist/cli/commands/doctor.d.ts.map +1 -1
  2. package/dist/cli/commands/doctor.js +11 -1
  3. package/dist/cli/commands/doctor.js.map +1 -1
  4. package/dist/cli/commands/operate.d.ts.map +1 -1
  5. package/dist/cli/commands/operate.js +91 -2
  6. package/dist/cli/commands/operate.js.map +1 -1
  7. package/dist/services/operate/advisors.d.ts +63 -0
  8. package/dist/services/operate/advisors.d.ts.map +1 -1
  9. package/dist/services/operate/advisors.js +68 -4
  10. package/dist/services/operate/advisors.js.map +1 -1
  11. package/dist/services/operate/artifacts.d.ts +9 -3
  12. package/dist/services/operate/artifacts.d.ts.map +1 -1
  13. package/dist/services/operate/artifacts.js +126 -5
  14. package/dist/services/operate/artifacts.js.map +1 -1
  15. package/dist/services/operate/citation-resolution.d.ts +14 -0
  16. package/dist/services/operate/citation-resolution.d.ts.map +1 -1
  17. package/dist/services/operate/citation-resolution.js +9 -0
  18. package/dist/services/operate/citation-resolution.js.map +1 -1
  19. package/dist/services/operate/completion.d.ts +80 -0
  20. package/dist/services/operate/completion.d.ts.map +1 -0
  21. package/dist/services/operate/completion.js +279 -0
  22. package/dist/services/operate/completion.js.map +1 -0
  23. package/dist/services/operate/config.d.ts +7 -0
  24. package/dist/services/operate/config.d.ts.map +1 -1
  25. package/dist/services/operate/config.js +7 -0
  26. package/dist/services/operate/config.js.map +1 -1
  27. package/dist/services/operate/context-research.d.ts +43 -0
  28. package/dist/services/operate/context-research.d.ts.map +1 -1
  29. package/dist/services/operate/context-research.js +219 -1
  30. package/dist/services/operate/context-research.js.map +1 -1
  31. package/dist/services/operate/decision-brief.d.ts +90 -1
  32. package/dist/services/operate/decision-brief.d.ts.map +1 -1
  33. package/dist/services/operate/decision-brief.js +175 -1
  34. package/dist/services/operate/decision-brief.js.map +1 -1
  35. package/dist/services/operate/doctor.d.ts +58 -0
  36. package/dist/services/operate/doctor.d.ts.map +1 -1
  37. package/dist/services/operate/doctor.js +395 -21
  38. package/dist/services/operate/doctor.js.map +1 -1
  39. package/dist/services/operate/engine.d.ts +75 -2
  40. package/dist/services/operate/engine.d.ts.map +1 -1
  41. package/dist/services/operate/engine.js +504 -33
  42. package/dist/services/operate/engine.js.map +1 -1
  43. package/dist/services/operate/event-store.d.ts +22 -0
  44. package/dist/services/operate/event-store.d.ts.map +1 -1
  45. package/dist/services/operate/event-store.js +35 -0
  46. package/dist/services/operate/event-store.js.map +1 -1
  47. package/dist/services/operate/evidence-cache.d.ts.map +1 -1
  48. package/dist/services/operate/evidence-cache.js +41 -5
  49. package/dist/services/operate/evidence-cache.js.map +1 -1
  50. package/dist/services/operate/index.d.ts.map +1 -1
  51. package/dist/services/operate/index.js +98 -1
  52. package/dist/services/operate/index.js.map +1 -1
  53. package/dist/services/operate/interaction/question-engine.d.ts.map +1 -1
  54. package/dist/services/operate/interaction/question-engine.js +36 -8
  55. package/dist/services/operate/interaction/question-engine.js.map +1 -1
  56. package/dist/services/operate/interaction/question-registry.d.ts +8 -0
  57. package/dist/services/operate/interaction/question-registry.d.ts.map +1 -1
  58. package/dist/services/operate/interaction/question-registry.js +21 -2
  59. package/dist/services/operate/interaction/question-registry.js.map +1 -1
  60. package/dist/services/operate/lifecycle-driver.d.ts +309 -0
  61. package/dist/services/operate/lifecycle-driver.d.ts.map +1 -0
  62. package/dist/services/operate/lifecycle-driver.js +434 -0
  63. package/dist/services/operate/lifecycle-driver.js.map +1 -0
  64. package/dist/services/operate/maintenance.d.ts +65 -1
  65. package/dist/services/operate/maintenance.d.ts.map +1 -1
  66. package/dist/services/operate/maintenance.js +718 -24
  67. package/dist/services/operate/maintenance.js.map +1 -1
  68. package/dist/services/operate/mission-dispatch.d.ts +61 -1
  69. package/dist/services/operate/mission-dispatch.d.ts.map +1 -1
  70. package/dist/services/operate/mission-dispatch.js +78 -5
  71. package/dist/services/operate/mission-dispatch.js.map +1 -1
  72. package/dist/services/operate/profile-migration.d.ts +69 -0
  73. package/dist/services/operate/profile-migration.d.ts.map +1 -0
  74. package/dist/services/operate/profile-migration.js +462 -0
  75. package/dist/services/operate/profile-migration.js.map +1 -0
  76. package/dist/services/operate/projection-persistence.d.ts.map +1 -1
  77. package/dist/services/operate/projection-persistence.js +24 -5
  78. package/dist/services/operate/projection-persistence.js.map +1 -1
  79. package/dist/services/operate/projection.d.ts.map +1 -1
  80. package/dist/services/operate/projection.js +9 -0
  81. package/dist/services/operate/projection.js.map +1 -1
  82. package/dist/services/operate/protocol.d.ts +1 -0
  83. package/dist/services/operate/protocol.d.ts.map +1 -1
  84. package/dist/services/operate/protocol.js.map +1 -1
  85. package/dist/services/operate/scratch.d.ts +81 -0
  86. package/dist/services/operate/scratch.d.ts.map +1 -0
  87. package/dist/services/operate/scratch.js +190 -0
  88. package/dist/services/operate/scratch.js.map +1 -0
  89. package/dist/services/operate/types.d.ts +3 -2
  90. package/dist/services/operate/types.d.ts.map +1 -1
  91. package/dist/services/operate/types.js.map +1 -1
  92. package/dist/services/operate/workspace.d.ts +1 -0
  93. package/dist/services/operate/workspace.d.ts.map +1 -1
  94. package/dist/services/operate/workspace.js +2 -0
  95. package/dist/services/operate/workspace.js.map +1 -1
  96. package/dist/services/runtime-manager-service.d.ts +23 -0
  97. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  98. package/dist/services/runtime-manager-service.js +30 -0
  99. package/dist/services/runtime-manager-service.js.map +1 -1
  100. package/package.json +2 -2
@@ -0,0 +1,434 @@
1
+ import { runMissionDispatchFanOut } from './mission-dispatch.js';
2
+ import { OperateError } from './types.js';
3
+ /** The four terminal states; a role in any of them never transitions again. */
4
+ export const ADVISOR_LIFECYCLE_TERMINAL_STATES = Object.freeze([
5
+ 'recorded',
6
+ 'not_evaluated',
7
+ 'failed',
8
+ 'cancelled',
9
+ ]);
10
+ export function isAdvisorLifecycleTerminal(state) {
11
+ return ADVISOR_LIFECYCLE_TERMINAL_STATES.includes(state);
12
+ }
13
+ /**
14
+ * The legal transition table. A `from` state maps to the events it accepts and
15
+ * the `to` state each yields. Any (state, event) pair absent from this table is
16
+ * an illegal transition and `advance` refuses it, which is what keeps the state
17
+ * space closed to exactly the eight declared states.
18
+ *
19
+ * `retry` re-opens a role from `running`/`returned`/`validating` back to
20
+ * `running`; the retry-budget accounting that decides WHETHER a retry is allowed
21
+ * lives in the driver (`stall`), not in the table.
22
+ */
23
+ const LIFECYCLE_TRANSITIONS = Object.freeze({
24
+ pending: {
25
+ dispatch: 'running',
26
+ cancel: 'cancelled',
27
+ fail: 'failed',
28
+ 'not-evaluated': 'not_evaluated',
29
+ },
30
+ running: {
31
+ return: 'returned',
32
+ retry: 'running',
33
+ fail: 'failed',
34
+ cancel: 'cancelled',
35
+ 'not-evaluated': 'not_evaluated',
36
+ },
37
+ returned: {
38
+ validate: 'validating',
39
+ retry: 'running',
40
+ fail: 'failed',
41
+ cancel: 'cancelled',
42
+ 'not-evaluated': 'not_evaluated',
43
+ },
44
+ validating: {
45
+ record: 'recorded',
46
+ retry: 'running',
47
+ fail: 'failed',
48
+ cancel: 'cancelled',
49
+ 'not-evaluated': 'not_evaluated',
50
+ },
51
+ // Terminal states accept no events.
52
+ recorded: {},
53
+ not_evaluated: {},
54
+ failed: {},
55
+ cancelled: {},
56
+ });
57
+ /**
58
+ * A stall/timeout signal raised inside the driver's own dispatch wrapper. It is
59
+ * caught by the retry loop and never escapes to a sibling — a stalled role's
60
+ * failure is always converted to a governed terminal, so it cannot reject the
61
+ * fan-out or cancel another lens.
62
+ */
63
+ export class AdvisorRoleStalledError extends Error {
64
+ constructor(message) {
65
+ super(message);
66
+ this.name = 'AdvisorRoleStalledError';
67
+ }
68
+ }
69
+ export class AdvisorLifecycleDriver {
70
+ roles = new Map();
71
+ order = [];
72
+ recordRole;
73
+ heartbeatFn;
74
+ now;
75
+ setTimer;
76
+ clearTimer;
77
+ heartbeatLeadMs;
78
+ concurrency;
79
+ roleTimeoutMs;
80
+ leaseExpiresAtMs;
81
+ heartbeatCount = 0;
82
+ timeline = [];
83
+ gaps = [];
84
+ constructor(options) {
85
+ this.recordRole = options.recordRole;
86
+ this.heartbeatFn = options.heartbeat;
87
+ this.now = options.now ?? Date.now;
88
+ this.setTimer =
89
+ options.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
90
+ this.clearTimer =
91
+ options.clearTimer ?? ((handle) => clearTimeout(handle));
92
+ this.heartbeatLeadMs = options.heartbeatLeadMs ?? 120_000;
93
+ this.concurrency = options.concurrency;
94
+ this.roleTimeoutMs = options.roleTimeoutMs;
95
+ this.leaseExpiresAtMs = options.leaseExpiresAtMs ?? Number.POSITIVE_INFINITY;
96
+ const defaultBudget = options.retryBudget ?? 1;
97
+ for (const plan of options.roles) {
98
+ if (this.roles.has(plan.roleId)) {
99
+ throw new OperateError('E_OPERATE_STATE_INVALID', `Advisor role ${plan.roleId} was prepared more than once.`);
100
+ }
101
+ const initial = plan.initialState ?? 'pending';
102
+ const record = {
103
+ plan: {
104
+ roleId: plan.roleId,
105
+ structurallyRequired: plan.structurallyRequired ?? false,
106
+ retryBudget: Math.max(0, plan.retryBudget ?? defaultBudget),
107
+ },
108
+ state: initial,
109
+ attempts: 0,
110
+ retriesUsed: 0,
111
+ statusReason: plan.initialReason,
112
+ };
113
+ // A resume-seeded terminal role (e.g. already `recorded`) surfaces its
114
+ // governed gap so the Chair still sees a resumed not_evaluated perspective.
115
+ if (isAdvisorLifecycleTerminal(initial) && initial !== 'recorded') {
116
+ this.gaps.push({
117
+ roleId: plan.roleId,
118
+ outcome: initial === 'failed' ? 'failed' : 'not_evaluated',
119
+ reason: plan.initialReason ?? `resumed as ${initial}`,
120
+ });
121
+ }
122
+ this.roles.set(plan.roleId, record);
123
+ this.order.push(plan.roleId);
124
+ }
125
+ }
126
+ /** The current state of a prepared role. */
127
+ state(roleId) {
128
+ return this.require(roleId).state;
129
+ }
130
+ /** The governed statusReason recorded on a terminal `not_evaluated`/`failed`, if any. */
131
+ statusReason(roleId) {
132
+ return this.require(roleId).statusReason;
133
+ }
134
+ /**
135
+ * Apply one validated lifecycle transition and return the new state. An illegal
136
+ * (state, event) pair — anything absent from `LIFECYCLE_TRANSITIONS` — is
137
+ * refused with `E_OPERATE_STATE_INVALID`, so a role can never reach a state
138
+ * outside the declared eight, and a terminal role can never be re-opened.
139
+ *
140
+ * `retry` additionally consults the role's retry budget; a retry beyond budget
141
+ * is refused here (the driver's `stall` decides retry-vs-terminate before ever
142
+ * calling this).
143
+ */
144
+ advance(roleId, event) {
145
+ const record = this.require(roleId);
146
+ const next = LIFECYCLE_TRANSITIONS[record.state][event.kind];
147
+ if (next === undefined) {
148
+ throw new OperateError('E_OPERATE_STATE_INVALID', `Advisor role ${roleId} cannot ${event.kind} from ${record.state}.`, { roleId, from: record.state, event: event.kind });
149
+ }
150
+ if (event.kind === 'retry') {
151
+ if (record.retriesUsed >= record.plan.retryBudget) {
152
+ throw new OperateError('E_OPERATE_STATE_INVALID', `Advisor role ${roleId} exhausted its retry budget of ${record.plan.retryBudget}.`, { roleId, retriesUsed: record.retriesUsed, retryBudget: record.plan.retryBudget });
153
+ }
154
+ record.retriesUsed += 1;
155
+ record.attempts += 1;
156
+ record.statusReason = event.reason;
157
+ }
158
+ if (event.kind === 'dispatch') {
159
+ record.attempts += 1;
160
+ }
161
+ if (event.kind === 'fail' || event.kind === 'cancel' || event.kind === 'not-evaluated') {
162
+ record.statusReason = event.reason;
163
+ }
164
+ record.state = next;
165
+ return next;
166
+ }
167
+ /** Whether the given role still has retry budget for another independent attempt. */
168
+ canRetry(roleId) {
169
+ const record = this.require(roleId);
170
+ return record.retriesUsed < record.plan.retryBudget;
171
+ }
172
+ /**
173
+ * Resolve a stalled/failed attempt: retry independently while budget remains,
174
+ * otherwise terminate. A structurally-required role terminates `failed`; an
175
+ * optional role terminates `not_evaluated` with a governed gap and the cycle
176
+ * continues. Returns the role's state after the decision (`running` on retry).
177
+ * Never throws for a legitimately dispatched role and never touches a sibling.
178
+ */
179
+ stall(roleId, reason) {
180
+ const record = this.require(roleId);
181
+ if (this.canRetry(roleId)) {
182
+ return this.advance(roleId, { kind: 'retry', reason });
183
+ }
184
+ if (record.plan.structurallyRequired) {
185
+ this.advance(roleId, { kind: 'fail', reason });
186
+ this.gaps.push({ roleId, outcome: 'failed', reason });
187
+ return 'failed';
188
+ }
189
+ this.advance(roleId, { kind: 'not-evaluated', reason });
190
+ this.gaps.push({ roleId, outcome: 'not_evaluated', reason });
191
+ return 'not_evaluated';
192
+ }
193
+ /**
194
+ * Drive ONE role's full lifecycle around a caller-supplied `dispatch` (the
195
+ * runtime's native-agent launch — the driver never dispatches itself). Owns the
196
+ * per-role retry loop, per-attempt timeout, immediate recording through T-002,
197
+ * and terminal classification. It resolves to the role's terminal state and
198
+ * NEVER rejects: a stall or hard failure becomes a governed terminal, so a
199
+ * sibling's fan-out slot is never rejected or cancelled by this role (FR3).
200
+ */
201
+ async executeRole(roleId, dispatch, signal) {
202
+ const record = this.require(roleId);
203
+ if (isAdvisorLifecycleTerminal(record.state)) {
204
+ // Resume: an already-terminal role (e.g. recorded in a prior session) is not
205
+ // re-dispatched — resume recovers recorded work without re-running it (FR2).
206
+ return record.state;
207
+ }
208
+ this.advance(roleId, { kind: 'dispatch' });
209
+ for (;;) {
210
+ try {
211
+ const output = await this.withTimeout(dispatch(signal), roleId);
212
+ this.advance(roleId, { kind: 'return' });
213
+ this.advance(roleId, { kind: 'validate' });
214
+ const outcome = await this.recordRole({ roleId, output });
215
+ this.updateLease(outcome.leaseExpiresAtMs);
216
+ if (outcome.recorded && !outcome.notEvaluated) {
217
+ this.advance(roleId, { kind: 'record' });
218
+ return 'recorded';
219
+ }
220
+ // T-002 durably committed a governed quiet/zero-grounding result. That is a
221
+ // TERMINAL not_evaluated outcome, not a stall — do not consume retry budget.
222
+ const reason = outcome.statusReason ?? 'recorded result grounded no resolvable evidence';
223
+ this.advance(roleId, { kind: 'not-evaluated', reason });
224
+ this.gaps.push({ roleId, outcome: 'not_evaluated', reason });
225
+ return 'not_evaluated';
226
+ }
227
+ catch (error) {
228
+ const reason = stallReason(error);
229
+ const state = this.stall(roleId, reason);
230
+ if (state === 'running')
231
+ continue; // retried independently on its own budget
232
+ return state; // terminal not_evaluated/failed — siblings are untouched
233
+ }
234
+ }
235
+ }
236
+ /**
237
+ * Fan the prepared, non-terminal roles out through the shared bounded-concurrency
238
+ * primitive, driving each through `executeRole`. Already-terminal (resumed) roles
239
+ * are skipped. The fan-out's new lifecycle reporter records an observability
240
+ * timeline through the driver without owning any state transition — `executeRole`
241
+ * remains the single source of truth for the state machine.
242
+ */
243
+ async run(input) {
244
+ const items = this.order.filter((roleId) => !isAdvisorLifecycleTerminal(this.state(roleId)));
245
+ await runMissionDispatchFanOut({
246
+ items,
247
+ parallel: input.parallel,
248
+ ...(this.concurrency !== undefined ? { concurrency: this.concurrency } : {}),
249
+ ...(input.perRoleBudgetMs !== undefined ? { perRoleBudgetMs: input.perRoleBudgetMs } : {}),
250
+ now: this.now,
251
+ lifecycle: {
252
+ onDispatch: (roleId) => this.recordTimeline(roleId, 'dispatch'),
253
+ onReturn: (roleId) => this.recordTimeline(roleId, 'return'),
254
+ onError: (roleId) => this.recordTimeline(roleId, 'error'),
255
+ },
256
+ run: (roleId, signal) => this.executeRole(roleId, (s) => input.dispatch(roleId, s), signal),
257
+ });
258
+ return this.summary();
259
+ }
260
+ /**
261
+ * True once every non-structurally-required role has reached a terminal state,
262
+ * without requiring a structurally-optional role to have RECORDED — a governed
263
+ * `not_evaluated` optional role satisfies readiness because the Chair surfaces
264
+ * it as a gap (FR13). Structurally-required roles must reach `recorded`
265
+ * specifically: their missing analysis is a hard gap the Chair cannot synthesize
266
+ * around, so a required role that is `failed`/`not_evaluated`/`cancelled` — or
267
+ * still in flight — holds Chair readiness closed. The `chair` role itself is
268
+ * dispatched separately and is excluded here.
269
+ */
270
+ chairReady() {
271
+ for (const roleId of this.order) {
272
+ if (roleId === 'chair')
273
+ continue;
274
+ const record = this.require(roleId);
275
+ if (record.plan.structurallyRequired) {
276
+ if (record.state !== 'recorded')
277
+ return false;
278
+ }
279
+ else if (!isAdvisorLifecycleTerminal(record.state)) {
280
+ return false;
281
+ }
282
+ }
283
+ return true;
284
+ }
285
+ /**
286
+ * Schedule automatic lease heartbeats independent of any role completing (FR2).
287
+ * Every `intervalMs` (injected timer) the scheduler checks the lease's remaining
288
+ * time against `heartbeatLeadMs`; when the window is approaching it renews
289
+ * through T-002's `heartbeat` action and carries the refreshed expiry forward.
290
+ * Returns a cancel function; the scheduler also stops on its own once every role
291
+ * is terminal (nothing left to keep alive). A slow lens can therefore hold the
292
+ * session open while siblings keep their recorded work, without raising the
293
+ * configured lease duration.
294
+ */
295
+ scheduleHeartbeat(intervalMs) {
296
+ if (!this.heartbeatFn) {
297
+ throw new OperateError('E_OPERATE_STATE_INVALID', 'Heartbeat scheduling requires a heartbeat action; none was injected.');
298
+ }
299
+ let cancelled = false;
300
+ let handle = null;
301
+ const stop = () => {
302
+ cancelled = true;
303
+ if (handle !== null)
304
+ this.clearTimer(handle);
305
+ };
306
+ const tick = async () => {
307
+ if (cancelled)
308
+ return;
309
+ if (this.allRolesTerminal()) {
310
+ stop();
311
+ return;
312
+ }
313
+ const remaining = this.leaseExpiresAtMs - this.now();
314
+ if (remaining <= this.heartbeatLeadMs) {
315
+ const snapshot = await this.heartbeatFn();
316
+ this.updateLease(snapshot.leaseExpiresAtMs);
317
+ this.heartbeatCount += 1;
318
+ }
319
+ if (!cancelled)
320
+ handle = this.setTimer(() => void tick(), intervalMs);
321
+ };
322
+ handle = this.setTimer(() => void tick(), intervalMs);
323
+ return stop;
324
+ }
325
+ /** How many heartbeats the scheduler has issued so far (observability/tests). */
326
+ heartbeatsIssued() {
327
+ return this.heartbeatCount;
328
+ }
329
+ /** The current lease expiry (ms epoch) the driver is tracking. */
330
+ leaseExpiry() {
331
+ return this.leaseExpiresAtMs;
332
+ }
333
+ /** Governed gaps for roles that terminated without a recorded analysis (FR13). */
334
+ governedGaps() {
335
+ return [...this.gaps];
336
+ }
337
+ /** The observability timeline recorded through the fan-out reporter. */
338
+ dispatchTimeline() {
339
+ return [...this.timeline];
340
+ }
341
+ /** A per-role snapshot in prepared order for `status`/`report` (FR5). */
342
+ snapshot() {
343
+ return this.order.map((roleId) => {
344
+ const record = this.require(roleId);
345
+ return {
346
+ roleId,
347
+ state: record.state,
348
+ attempts: record.attempts,
349
+ retriesUsed: record.retriesUsed,
350
+ retryBudget: record.plan.retryBudget,
351
+ structurallyRequired: record.plan.structurallyRequired,
352
+ ...(record.statusReason ? { statusReason: record.statusReason } : {}),
353
+ };
354
+ });
355
+ }
356
+ /**
357
+ * Cancel every still-in-flight role (bookkeeping only — the session cancel is
358
+ * the caller's concern). Already-terminal roles are left untouched, so a
359
+ * mid-cycle cancel preserves recorded work.
360
+ */
361
+ cancelInFlight(reason) {
362
+ for (const roleId of this.order) {
363
+ const record = this.require(roleId);
364
+ if (!isAdvisorLifecycleTerminal(record.state)) {
365
+ this.advance(roleId, { kind: 'cancel', reason });
366
+ }
367
+ }
368
+ }
369
+ summary() {
370
+ const collect = (state) => this.order.filter((roleId) => roleId !== 'chair' && this.state(roleId) === state);
371
+ return {
372
+ roles: this.snapshot(),
373
+ recorded: collect('recorded'),
374
+ notEvaluated: collect('not_evaluated'),
375
+ failed: collect('failed'),
376
+ cancelled: collect('cancelled'),
377
+ gaps: this.governedGaps(),
378
+ chairReady: this.chairReady(),
379
+ heartbeats: this.heartbeatCount,
380
+ };
381
+ }
382
+ allRolesTerminal() {
383
+ return this.order.every((roleId) => isAdvisorLifecycleTerminal(this.state(roleId)));
384
+ }
385
+ recordTimeline(roleId, event) {
386
+ this.timeline.push({ roleId, event, at: this.now() });
387
+ }
388
+ updateLease(expiresAtMs) {
389
+ if (expiresAtMs !== undefined && Number.isFinite(expiresAtMs)) {
390
+ this.leaseExpiresAtMs = expiresAtMs;
391
+ }
392
+ }
393
+ require(roleId) {
394
+ const record = this.roles.get(roleId);
395
+ if (!record) {
396
+ throw new OperateError('E_OPERATE_STATE_INVALID', `Advisor role ${roleId} was not prepared by this driver.`, { roleId });
397
+ }
398
+ return record;
399
+ }
400
+ /**
401
+ * Race a role's dispatch against its per-attempt timeout using the INJECTED
402
+ * timer, so timeout behaviour is deterministic under a test clock and never a
403
+ * wall-clock sleep. With no configured timeout the dispatch promise is returned
404
+ * as-is. A fired timeout rejects with `AdvisorRoleStalledError`, which the retry
405
+ * loop converts to a governed retry or terminal — it never escapes to a sibling.
406
+ */
407
+ withTimeout(promise, roleId) {
408
+ const timeoutMs = this.roleTimeoutMs;
409
+ if (!timeoutMs || timeoutMs <= 0)
410
+ return promise;
411
+ return new Promise((resolve, reject) => {
412
+ const handle = this.setTimer(() => {
413
+ reject(new AdvisorRoleStalledError(`Advisor role ${roleId} did not return within its ${timeoutMs}ms attempt budget.`));
414
+ }, timeoutMs);
415
+ promise.then((value) => {
416
+ this.clearTimer(handle);
417
+ resolve(value);
418
+ }, (error) => {
419
+ this.clearTimer(handle);
420
+ reject(error instanceof Error ? error : new Error(String(error)));
421
+ });
422
+ });
423
+ }
424
+ }
425
+ function stallReason(error) {
426
+ if (error instanceof AdvisorRoleStalledError)
427
+ return error.message;
428
+ if (error instanceof OperateError)
429
+ return `${error.code}: ${error.message}`;
430
+ if (error instanceof Error)
431
+ return error.message;
432
+ return String(error);
433
+ }
434
+ //# sourceMappingURL=lifecycle-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-driver.js","sourceRoot":"","sources":["../../../src/services/operate/lifecycle-driver.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,24 @@ export declare function purgeBoardMachineLocalCaches(input: {
17
17
  removedAdvisorSessions: number;
18
18
  removedIncrementalBaselines: number;
19
19
  }>;
20
+ /**
21
+ * FR7 (T-006): sibling machine-local cleanup for OpenPlanr-owned scratch left
22
+ * behind by a session that never finalized. Deliberately NOT folded into
23
+ * `purgeBoardMachineLocalCaches` — scratch has its own narrower per-cycle
24
+ * lifecycle. Removes ONLY scratch a valid `openplanr-operate-scratch` manifest
25
+ * confirms this project wrote and whose lease window has lapsed; it never touches
26
+ * an unowned file found under the scratch root, nor any other machine-local
27
+ * cache. This is the owned-only removal the doctor's abandoned-scratch diagnostic
28
+ * points at, and the sibling `operate cache purge` invokes.
29
+ */
30
+ export declare function purgeAbandonedOperatingScratch(input: {
31
+ projectRoot: string;
32
+ localRoot?: string;
33
+ now?: () => Date;
34
+ }): Promise<{
35
+ removed: number;
36
+ cycles: string[];
37
+ }>;
20
38
  export declare function operatingCacheAction(input: {
21
39
  projectRoot: string;
22
40
  action: 'status' | 'purge';
@@ -57,13 +75,18 @@ export declare function createOperatingAdapterStartHandoff(input: {
57
75
  }): Promise<OperatingAdapterHandoff>;
58
76
  export declare function operateAdapterLifecycle(input: {
59
77
  projectRoot: string;
60
- action: 'prepare' | 'record' | 'resume' | 'finalize' | 'cancel';
78
+ action: 'prepare' | 'record' | 'resume' | 'finalize' | 'cancel' | 'heartbeat' | 'abandon';
61
79
  cycleId?: string;
62
80
  evidenceDigest?: string;
63
81
  lease?: string;
64
82
  idempotencyKey?: string;
65
83
  role?: string;
66
84
  stdin?: string;
85
+ /**
86
+ * SPEC-005 T-020: the governed reason a lens is abandoned terminal
87
+ * `not_evaluated`. Required for `action: 'abandon'`; unused otherwise.
88
+ */
89
+ reason?: string;
67
90
  localRoot?: string;
68
91
  /**
69
92
  * Injectable clock (FR10 / T-008). Defaults to wall-clock. Tests supply a
@@ -72,4 +95,45 @@ export declare function operateAdapterLifecycle(input: {
72
95
  */
73
96
  now?: () => Date;
74
97
  }): Promise<unknown>;
98
+ /**
99
+ * SPEC-005 T-020 (FR13) — the OPERATOR escape, independent of a well-behaved
100
+ * runtime. When a runtime dispatched a lens and then reported nothing at all — it
101
+ * crashed, or does not implement `harness abandon` — the cycle is stranded at
102
+ * `phase: advisors` on every continuation: the stalled lens is never recorded, so
103
+ * it stays runnable-and-required and Chair is never assembled. The only prior
104
+ * recourse was `cycles cancel`, which discards the whole cycle including the
105
+ * siblings that DID record.
106
+ *
107
+ * This governed escape reaches a reviewable cycle without discarding it. It is
108
+ * gated on a LAPSED lease — the legitimate signal that no runtime is actively
109
+ * working the session — and an explicit operator confirmation. It never touches
110
+ * the runtime lifecycle (`harness abandon`/`record`/`finalize`), so it works when
111
+ * the runtime is gone. For each still-unrecorded advisor lens it commits the SAME
112
+ * governed terminal `not_evaluated` gap the runtime path commits
113
+ * (`governTerminalNotEvaluated`), so the next `run` continuation reconstructs the
114
+ * lens `not_evaluated` from committed state and consolidation proceeds. Recorded
115
+ * siblings are never read, re-dispatched, or altered. It fabricates nothing.
116
+ *
117
+ * It does not itself run consolidation — the operator reaches `reviewable` with a
118
+ * following `planr operate run` (offline when no runtime is available), so the
119
+ * choice of a real or offline Chair stays the operator's.
120
+ */
121
+ export declare function reapStalledOperatingRoles(input: {
122
+ projectRoot: string;
123
+ cycleId: string;
124
+ role?: string;
125
+ reason?: string;
126
+ confirmed?: boolean;
127
+ localRoot?: string;
128
+ now?: () => Date;
129
+ }): Promise<{
130
+ cycleId: string;
131
+ reaped: Array<{
132
+ roleId: string;
133
+ reason: string;
134
+ gapId: string;
135
+ }>;
136
+ alreadyRecorded: string[];
137
+ next: string[];
138
+ }>;
75
139
  //# sourceMappingURL=maintenance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../../src/services/operate/maintenance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../../src/services/operate/maintenance.ts"],"names":[],"mappings":"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"}