opencode-swarm 7.148.2 → 7.148.4

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 (64) hide show
  1. package/dist/background/delegation-health.d.ts +100 -0
  2. package/dist/background/pending-delegations.d.ts +97 -0
  3. package/dist/background/queue.d.ts +45 -7
  4. package/dist/background/worker.d.ts +24 -3
  5. package/dist/cli/{config-doctor-6danhdcy.js → config-doctor-ycf9ws4p.js} +2 -2
  6. package/dist/cli/{core-0ghwny8q.js → core-a1bhs3xa.js} +1 -1
  7. package/dist/cli/{curation-policy-hkdghd3a.js → curation-policy-fbvctttr.js} +5 -5
  8. package/dist/cli/{curator-wvm7qbkk.js → curator-8y57gq1g.js} +26 -26
  9. package/dist/cli/{curator-llm-factory-6n47j5qn.js → curator-llm-factory-rj4vw5fd.js} +26 -26
  10. package/dist/cli/{evidence-summary-service-0xwrkmf9.js → evidence-summary-service-wkp0gfpd.js} +10 -10
  11. package/dist/cli/{gate-evidence-6e5yhcy6.js → gate-evidence-qty15skw.js} +5 -5
  12. package/dist/cli/{guardrail-explain-tgv7rvap.js → guardrail-explain-2n3ahs0m.js} +27 -27
  13. package/dist/cli/{guardrail-log-k0zk6rbs.js → guardrail-log-bmxrb3r2.js} +3 -3
  14. package/dist/cli/{guardrail-reset-4fw16xmb.js → guardrail-reset-be3sx0am.js} +26 -26
  15. package/dist/cli/{hive-promoter-zemwxxw1.js → hive-promoter-te5d78yt.js} +26 -26
  16. package/dist/cli/{index-x9q0b3a8.js → index-0045n7qe.js} +2 -2
  17. package/dist/cli/{index-7jaq84cg.js → index-1vbmra32.js} +1 -1
  18. package/dist/cli/{index-q6kscnts.js → index-622phhp5.js} +3 -3
  19. package/dist/cli/{index-84ytts36.js → index-6kw1a3bk.js} +4 -4
  20. package/dist/cli/{index-nqwn8sf0.js → index-7rerkeg8.js} +1 -1
  21. package/dist/cli/{index-x4kgn37c.js → index-8djgxw2w.js} +2 -2
  22. package/dist/cli/{index-ndqhtgrc.js → index-8kzrgjt6.js} +1 -1
  23. package/dist/cli/{index-x9jppg8b.js → index-9m8jy3av.js} +2 -2
  24. package/dist/cli/{index-xn7h24x4.js → index-9qzkcmry.js} +3 -3
  25. package/dist/cli/{index-5vyej8pc.js → index-b1c83zf9.js} +5 -5
  26. package/dist/cli/{index-s0nss8c4.js → index-b94487xm.js} +1 -1
  27. package/dist/cli/{index-pzt7ed53.js → index-bccfz7br.js} +4 -4
  28. package/dist/cli/{index-mbcyz77e.js → index-gswx08pr.js} +4 -4
  29. package/dist/cli/{index-hsq8nyen.js → index-hj1xd3pg.js} +265 -83
  30. package/dist/cli/{index-ebt47fnp.js → index-j382eh60.js} +1 -1
  31. package/dist/cli/{index-m5z2fgs4.js → index-k1s8gxjh.js} +1 -1
  32. package/dist/cli/{index-zpn3wqvp.js → index-kg4knw6r.js} +2 -2
  33. package/dist/cli/{index-r9g7ymv2.js → index-nq4tkfpc.js} +1 -1
  34. package/dist/cli/{index-k2ad2vtb.js → index-qbvq3xt2.js} +1 -1
  35. package/dist/cli/{index-3pbvdde0.js → index-qpewzk0q.js} +2 -2
  36. package/dist/cli/{index-2n9rwvcc.js → index-qwmrt51t.js} +1 -1
  37. package/dist/cli/{index-03wz9h63.js → index-rzzwem6x.js} +28 -28
  38. package/dist/cli/{index-s0s1e5jp.js → index-skgeytf6.js} +6 -6
  39. package/dist/cli/{index-wgrvq2bc.js → index-sxtz2d26.js} +6 -6
  40. package/dist/cli/{index-092deqxs.js → index-t25evmna.js} +400 -12
  41. package/dist/cli/{index-2zz8b0rb.js → index-vhefvcta.js} +2 -2
  42. package/dist/cli/{index-rsn4jm90.js → index-vrp2zva8.js} +1 -1
  43. package/dist/cli/{index-nxydm56k.js → index-w00hn0dd.js} +2 -2
  44. package/dist/cli/{index-crpkb5x6.js → index-ye7kpzrk.js} +5 -5
  45. package/dist/cli/{index-mgcffsk0.js → index-yq89bgnz.js} +1 -1
  46. package/dist/cli/index.js +26 -26
  47. package/dist/cli/{knowledge-escalator-rfw35yt1.js → knowledge-escalator-9w53tx55.js} +10 -10
  48. package/dist/cli/{knowledge-events-wmjm5wn6.js → knowledge-events-my31zepa.js} +8 -8
  49. package/dist/cli/{knowledge-link-5dctq0ax.js → knowledge-link-spw879rs.js} +4 -4
  50. package/dist/cli/{knowledge-store-f2ev6s5p.js → knowledge-store-yf59mxp5.js} +5 -5
  51. package/dist/cli/{knowledge-validator-6cmwpx9e.js → knowledge-validator-8n569fp4.js} +7 -7
  52. package/dist/cli/{pending-delegations-h4gr264y.js → pending-delegations-f4wvyzbf.js} +10 -2
  53. package/dist/cli/{pr-subscriptions-9mg6mwc0.js → pr-subscriptions-f4xw1rxy.js} +2 -2
  54. package/dist/cli/{runner-9g2pcg10.js → runner-rk26nk58.js} +5 -5
  55. package/dist/cli/{scan-cursor-x1ma7edk.js → scan-cursor-www6dbn8.js} +6 -6
  56. package/dist/cli/{schema-g5ggmb47.js → schema-vyg0k7rh.js} +1 -1
  57. package/dist/cli/{scope-persistence-gt0zpp6a.js → scope-persistence-3qbr019s.js} +6 -6
  58. package/dist/cli/{skill-generator-q6m110d5.js → skill-generator-fh8emssb.js} +12 -12
  59. package/dist/cli/{worktree-collision-ownership-e0p490vw.js → worktree-collision-ownership-wqy7mgb3.js} +2 -2
  60. package/dist/cli/{worktree-isolation-akwwt8n5.js → worktree-isolation-sbsdx1yj.js} +26 -26
  61. package/dist/hooks/delegation-gate.d.ts +1 -0
  62. package/dist/index.js +16 -15
  63. package/dist/services/status-service.d.ts +55 -3
  64. package/package.json +1 -1
@@ -64,6 +64,38 @@ export interface DelegationHealthUncertaintySection {
64
64
  source: string;
65
65
  repairHint?: string;
66
66
  }
67
+ /**
68
+ * One durable operator fact emitted by the shared background maintenance
69
+ * service (issue #2104): every release, retained ambiguity, lease renewal,
70
+ * contention, and maintenance failure is recorded here so operators can see
71
+ * why a coder reservation disappeared or stayed. Bounded ring (latest
72
+ * MAX_MAINTENANCE_FACTS); an observation copy, never ownership state.
73
+ */
74
+ export interface DelegationMaintenanceFact {
75
+ at: number;
76
+ kind: 'release' | 'retained-ambiguity' | 'retained-protected-legacy' | 'lease-renewed' | 'maintenance-failure' | 'lock-contention';
77
+ reservationId?: string;
78
+ correlationId?: string;
79
+ generation?: number;
80
+ reason: string;
81
+ }
82
+ export interface DelegationHealthMaintenanceSection {
83
+ lastRunAt: number;
84
+ lastOkAt: number | null;
85
+ lastFailure: {
86
+ reason: string;
87
+ at: number;
88
+ } | null;
89
+ lastContentionAt: number | null;
90
+ /** Summary counters of the last completed run (not cumulative). */
91
+ lastSummary: {
92
+ sweptStale: number;
93
+ released: number;
94
+ renewed: number;
95
+ retained: number;
96
+ };
97
+ facts: DelegationMaintenanceFact[];
98
+ }
67
99
  export interface DelegationLedgerHealth {
68
100
  schemaVersion: 1;
69
101
  updatedAt: number;
@@ -82,6 +114,7 @@ export interface DelegationLedgerHealth {
82
114
  lateTerminals: number;
83
115
  orphanWorktreeOwners: number;
84
116
  };
117
+ maintenance?: DelegationHealthMaintenanceSection | null;
85
118
  }
86
119
  export declare const DelegationCheckpointAuditSchema: z.ZodObject<{
87
120
  dispatchCount: z.ZodNumber;
@@ -100,6 +133,23 @@ export declare const DelegationCheckpointAuditSchema: z.ZodObject<{
100
133
  lastTerminalAt: z.ZodNullable<z.ZodNumber>;
101
134
  lastCompactionAt: z.ZodNumber;
102
135
  }, z.core.$strict>;
136
+ /** Bound for the maintenance facts ring (latest facts kept). */
137
+ export declare const MAX_MAINTENANCE_FACTS = 20;
138
+ export declare const DelegationMaintenanceFactSchema: z.ZodObject<{
139
+ at: z.ZodNumber;
140
+ kind: z.ZodEnum<{
141
+ release: "release";
142
+ "retained-ambiguity": "retained-ambiguity";
143
+ "retained-protected-legacy": "retained-protected-legacy";
144
+ "lease-renewed": "lease-renewed";
145
+ "maintenance-failure": "maintenance-failure";
146
+ "lock-contention": "lock-contention";
147
+ }>;
148
+ reservationId: z.ZodOptional<z.ZodString>;
149
+ correlationId: z.ZodOptional<z.ZodString>;
150
+ generation: z.ZodOptional<z.ZodNumber>;
151
+ reason: z.ZodString;
152
+ }, z.core.$strict>;
103
153
  export declare const DelegationLedgerHealthSchema: z.ZodObject<{
104
154
  schemaVersion: z.ZodLiteral<1>;
105
155
  updatedAt: z.ZodNumber;
@@ -162,6 +212,36 @@ export declare const DelegationLedgerHealthSchema: z.ZodObject<{
162
212
  lateTerminals: z.ZodNumber;
163
213
  orphanWorktreeOwners: z.ZodNumber;
164
214
  }, z.core.$strict>;
215
+ maintenance: z.ZodOptional<z.ZodNullable<z.ZodObject<{
216
+ lastRunAt: z.ZodNumber;
217
+ lastOkAt: z.ZodNullable<z.ZodNumber>;
218
+ lastFailure: z.ZodNullable<z.ZodObject<{
219
+ reason: z.ZodString;
220
+ at: z.ZodNumber;
221
+ }, z.core.$strict>>;
222
+ lastContentionAt: z.ZodNullable<z.ZodNumber>;
223
+ lastSummary: z.ZodObject<{
224
+ sweptStale: z.ZodNumber;
225
+ released: z.ZodNumber;
226
+ renewed: z.ZodNumber;
227
+ retained: z.ZodNumber;
228
+ }, z.core.$strict>;
229
+ facts: z.ZodArray<z.ZodObject<{
230
+ at: z.ZodNumber;
231
+ kind: z.ZodEnum<{
232
+ release: "release";
233
+ "retained-ambiguity": "retained-ambiguity";
234
+ "retained-protected-legacy": "retained-protected-legacy";
235
+ "lease-renewed": "lease-renewed";
236
+ "maintenance-failure": "maintenance-failure";
237
+ "lock-contention": "lock-contention";
238
+ }>;
239
+ reservationId: z.ZodOptional<z.ZodString>;
240
+ correlationId: z.ZodOptional<z.ZodString>;
241
+ generation: z.ZodOptional<z.ZodNumber>;
242
+ reason: z.ZodString;
243
+ }, z.core.$strict>>;
244
+ }, z.core.$strict>>>;
165
245
  }, z.core.$strict>;
166
246
  /**
167
247
  * Test seam for the atomic-rename retry (issue #2034): tests inject a
@@ -186,6 +266,7 @@ export declare function writeDelegationHealthArtifact(directory: string, update:
186
266
  lastUncertainty?: DelegationLedgerHealth['lastUncertainty'] | null;
187
267
  counts?: DelegationLedgerHealth['counts'];
188
268
  uncertainty?: DelegationHealthUncertaintySection;
269
+ maintenance?: DelegationLedgerHealth['maintenance'];
189
270
  }): DelegationLedgerHealth | null;
190
271
  /**
191
272
  * Record a startup-recovery observation (called by init-orphan-recovery after
@@ -200,6 +281,25 @@ export declare function recordDelegationRecoveryObservation(directory: string, o
200
281
  reason?: string;
201
282
  repairHint?: string;
202
283
  }): void;
284
+ /**
285
+ * Append a background-maintenance observation (issue #2104): updates the
286
+ * run/failure/contention stamps and merges the run's operator facts into the
287
+ * bounded ring. Called by the shared maintenance service after it has
288
+ * released its locks — the artifact write itself is lock-free and atomic
289
+ * (observation copy). Best-effort: never throws.
290
+ */
291
+ export declare function appendDelegationMaintenanceObservation(directory: string, observation: {
292
+ at: number;
293
+ status: 'ok' | 'contention' | 'failure';
294
+ reason?: string;
295
+ summary?: {
296
+ sweptStale: number;
297
+ released: number;
298
+ renewed: number;
299
+ retained: number;
300
+ };
301
+ facts: DelegationMaintenanceFact[];
302
+ }): void;
203
303
  /**
204
304
  * Fold-free health collection for `/swarm status`: statSync of the ledger and
205
305
  * checkpoint, a display-tolerant manifest peek (sequence/tailRolled only), and
@@ -84,6 +84,15 @@ export type RecoveryOwnershipScanResult<T> = {
84
84
  };
85
85
  /** An abandoned ingestion lease may be reclaimed after this bounded interval. */
86
86
  export declare const BACKGROUND_INGESTION_LEASE_MS = 30000;
87
+ /**
88
+ * Coder-reservation lease bounds (issue #2104). The lease is a liveness hint,
89
+ * never release authority: expiry only triggers corroborated reconciliation.
90
+ * `leaseMs` inputs are clamped into [MIN, MAX]. Documented default 15 min,
91
+ * hard maximum 60 min, floor 60 s.
92
+ */
93
+ export declare const BACKGROUND_CODER_RESERVATION_LEASE_MS: number;
94
+ export declare const BACKGROUND_CODER_RESERVATION_LEASE_MAX_MS: number;
95
+ export declare const BACKGROUND_CODER_RESERVATION_LEASE_MIN_MS = 60000;
87
96
  /**
88
97
  * Canonical default staleness horizon for a tracked background delegation: a
89
98
  * record whose `updatedAt` has not advanced in this long is treated as
@@ -314,6 +323,24 @@ export interface BackgroundCoderReservation {
314
323
  callID: string;
315
324
  state: 'reserved' | 'bound';
316
325
  correlationId: string | null;
326
+ /**
327
+ * Launch generation this reservation currently owns (issue #2104). New in
328
+ * this schema revision: absent on legacy records and read as 1. Bind
329
+ * couples the reservation to the delegation record's launch generation and
330
+ * may only move it forward. No current dispatch path advances a record
331
+ * past generation 1 (PR #2091 hydrates replays at the stored generation),
332
+ * so the generation fences in bind/release/maintenance are currently
333
+ * forward-looking defense-in-depth: they exist so a future
334
+ * generation-advancing relaunch caller cannot have its reservation
335
+ * released or rebound by an older attempt's terminal.
336
+ */
337
+ generation?: number;
338
+ /**
339
+ * Lease expiry (issue #2104): a liveness hint for maintenance, never
340
+ * release authority by itself. Absent on legacy records, which stay
341
+ * protected (only proven-terminal reconciliation may release them).
342
+ */
343
+ leaseExpiresAt?: number;
317
344
  createdAt: number;
318
345
  updatedAt: number;
319
346
  }
@@ -653,6 +680,10 @@ export interface ReserveBackgroundCoderSlotInput {
653
680
  callID: string;
654
681
  maxConcurrent: number;
655
682
  occupiedTaskIds?: readonly string[];
683
+ /** Launch generation to seed the reservation with (default 1, issue #2104). */
684
+ generation?: number;
685
+ /** Lease duration; clamped to the documented min/max bounds. */
686
+ leaseMs?: number;
656
687
  now?: number;
657
688
  }
658
689
  export type ReserveBackgroundCoderSlotResult = {
@@ -677,6 +708,15 @@ export interface BindBackgroundCoderReservationInput {
677
708
  planTaskId: string | null;
678
709
  callID: string;
679
710
  correlationId: string;
711
+ /**
712
+ * Launch generation of the dispatch being bound (issue #2104). May move
713
+ * the reservation's generation FORWARD only (a session.create retry after
714
+ * PR #2091 relaunches under a newer generation); an older generation can
715
+ * never rebind. Absent keeps the current generation.
716
+ */
717
+ generation?: number;
718
+ /** Lease duration for the renewal implied by this verified launch; clamped. */
719
+ leaseMs?: number;
680
720
  now?: number;
681
721
  }
682
722
  /** Bind the pre-launch owner to the exact trusted completion correlation. */
@@ -687,6 +727,13 @@ export interface ReleaseBackgroundCoderReservationInput {
687
727
  planTaskId: string | null;
688
728
  callID: string;
689
729
  correlationId: string | null;
730
+ /**
731
+ * Generation of the terminal claiming this release (issue #2104). When
732
+ * both this and the stored generation are present and differ, the release
733
+ * is refused: a terminal for generation N must never release the
734
+ * generation N+1 reservation.
735
+ */
736
+ generation?: number;
690
737
  reason: 'consumed' | 'recovered';
691
738
  }
692
739
  /**
@@ -694,3 +741,53 @@ export interface ReleaseBackgroundCoderReservationInput {
694
741
  * primary ledger; `recovered` is reserved for a caller that completed recovery.
695
742
  */
696
743
  export declare function releaseBackgroundCoderReservation(directory: string, input: ReleaseBackgroundCoderReservationInput): Promise<boolean>;
744
+ export interface MaintainBackgroundDelegationsOptions {
745
+ /** Stale-delegation corroboration timeout (default 30 min). */
746
+ staleTimeoutMs?: number;
747
+ /** Per-invocation bound on swept records and reconciled reservations. */
748
+ maxRecords?: number;
749
+ /** Lock wait bound. Short values let callers (status, admission) proceed. */
750
+ lockTimeoutMs?: number;
751
+ /** Typed label of the maintenance point invoking this run. */
752
+ reason?: string;
753
+ now?: number;
754
+ }
755
+ export interface MaintainBackgroundDelegationsResult {
756
+ status: 'ok' | 'contention' | 'failure';
757
+ reason?: string;
758
+ sweptStale: number;
759
+ released: Array<{
760
+ reservationId: string;
761
+ generation: number;
762
+ reason: string;
763
+ }>;
764
+ renewed: Array<{
765
+ reservationId: string;
766
+ generation: number;
767
+ }>;
768
+ retained: Array<{
769
+ reservationId: string;
770
+ reason: string;
771
+ }>;
772
+ examinedReservations: number;
773
+ }
774
+ /**
775
+ * Shared background maintenance service (issue #2104): one bounded,
776
+ * event-driven pass that sweeps stale delegation records and reconciles
777
+ * expired coder-reservation leases with corroborated owner evidence.
778
+ *
779
+ * Lock-ordering invariant: this is the ONLY site that touches both store
780
+ * locks, and it takes them SEQUENTIALLY — the delegations STORE lock first,
781
+ * fully released, then the RESERVATION lock. Never nested. No code path may
782
+ * acquire the RESERVATION lock and then the STORE lock.
783
+ *
784
+ * Per invocation the work is bounded (maxRecords sweeps / reconciliations;
785
+ * the underlying reads are already bounded by the checkpoint machinery and
786
+ * the 4 MiB recovery window). Every release, retained ambiguity, renewal,
787
+ * contention, and failure emits a durable operator fact into the health
788
+ * artifact's bounded maintenance ring. Expiry alone never releases: reclaim
789
+ * requires corroborated owner absence (stale exact owner record, or no owner
790
+ * record at all beyond the stale timeout), and any uncertainty retains the
791
+ * reservation fail-closed.
792
+ */
793
+ export declare function maintainBackgroundDelegations(directory: string, options?: MaintainBackgroundDelegationsOptions): Promise<MaintainBackgroundDelegationsResult>;
@@ -44,10 +44,23 @@ export interface QueueConfig {
44
44
  overflowStrategy?: OverflowStrategy;
45
45
  }
46
46
  /**
47
- * In-process queue with priority support and retry metadata
47
+ * In-process queue with priority support and retry metadata.
48
+ *
49
+ * Ownership model (issue #2104): an item exists in exactly one of three
50
+ * states — `queued` (in `items`), `in-flight` (in `inflight`, handed to a
51
+ * worker by `dequeue`), or `terminal` (recorded in `terminalIds` after
52
+ * `complete` or retry exhaustion). `dequeue` moves queued→in-flight, a
53
+ * scheduled `retry` moves in-flight→queued (honouring `nextAttemptAt`), and
54
+ * `complete`/retry-exhaustion moves either→terminal exactly once. A terminal
55
+ * ID can never be completed, retried, or removed again, so a recycled ID
56
+ * cannot act on a newer item.
48
57
  */
49
58
  export declare class AutomationQueue<T = unknown> {
50
59
  private items;
60
+ /** Dequeued items awaiting complete/retry; bounded by maxSize. */
61
+ private inflight;
62
+ /** Terminal IDs (completed or exhausted); FIFO-evicted at the cap. */
63
+ private terminalIds;
51
64
  private readonly maxSize;
52
65
  private readonly defaultMaxRetries;
53
66
  private readonly defaultBackoffMs;
@@ -65,7 +78,14 @@ export declare class AutomationQueue<T = unknown> {
65
78
  */
66
79
  enqueue(payload: T, priority?: QueuePriority, metadata?: Record<string, unknown>): string;
67
80
  /**
68
- * Dequeue the highest priority item
81
+ * Dequeue the highest priority item whose retry backoff has elapsed.
82
+ *
83
+ * `items` stays sorted by (priority, createdAt); a not-yet-due item is
84
+ * skipped without reordering, so a due lower-priority item can be handed
85
+ * out ahead of a not-due higher-priority one. The dequeued item moves to
86
+ * the in-flight map and remains addressable by ID for `complete`/`retry`
87
+ * until it settles (issue #2104: previously `shift()` removed it and every
88
+ * later `retry(id)` silently returned false).
69
89
  */
70
90
  dequeue(): QueueItem<T> | undefined;
71
91
  /**
@@ -73,19 +93,30 @@ export declare class AutomationQueue<T = unknown> {
73
93
  */
74
94
  peek(): QueueItem<T> | undefined;
75
95
  /**
76
- * Get item by ID
96
+ * Get item by ID (searches queued and in-flight items)
77
97
  */
78
98
  get(id: string): QueueItem<T> | undefined;
99
+ /** Number of items currently in flight (dequeued, not yet settled). */
100
+ inflightSize(): number;
101
+ private removeQueuedOrInflight;
102
+ private markTerminal;
79
103
  /**
80
- * Remove specific item by ID
104
+ * Remove specific item by ID (queued or in-flight)
81
105
  */
82
106
  remove(id: string): boolean;
83
107
  /**
84
- * Mark item as completed and remove from queue
108
+ * Mark item as completed and remove from queue. Exactly once: a second
109
+ * call for the same ID (or one for a recycled ID) returns false.
85
110
  */
86
111
  complete(id: string): boolean;
87
112
  /**
88
- * Mark item as failed and schedule retry if possible
113
+ * Mark item as failed and schedule retry if possible.
114
+ *
115
+ * Increments attempts exactly once per failed execution. On exhaustion the
116
+ * item becomes terminal: exactly one `queue.item.failed` event is emitted
117
+ * and the ID can never reappear. Otherwise the item returns to the queued
118
+ * set with `nextAttemptAt` honoured by `dequeue` before it can be handed
119
+ * out again (works for in-flight and still-queued items alike).
89
120
  */
90
121
  retry(id: string, _error?: unknown): boolean;
91
122
  /**
@@ -105,7 +136,13 @@ export declare class AutomationQueue<T = unknown> {
105
136
  */
106
137
  isFull(): boolean;
107
138
  /**
108
- * Clear all items from queue
139
+ * Clear all items from queue.
140
+ *
141
+ * Reset policy (issue #2104): both the queued set AND the in-flight set
142
+ * are dropped — an in-flight item whose handler is still running will find
143
+ * its later `complete`/`retry` returning false (the ID is no longer known;
144
+ * it is NOT marked terminal). The bounded terminal-ID registry is kept so
145
+ * recycling cannot resurrect a settled ID.
109
146
  */
110
147
  clear(): void;
111
148
  /**
@@ -124,5 +161,6 @@ export declare class AutomationQueue<T = unknown> {
124
161
  maxSize: number;
125
162
  byPriority: Record<QueuePriority, number>;
126
163
  retryable: number;
164
+ inflight: number;
127
165
  };
128
166
  }
@@ -43,15 +43,35 @@ export declare class WorkerManager {
43
43
  */
44
44
  start(name: string): boolean;
45
45
  /**
46
- * Start processing loop for a worker
46
+ * Start processing loop for a worker.
47
+ *
48
+ * The loop polls (bounded sleeps: 50 ms at the concurrency cap, 100 ms
49
+ * when idle or when every queued item is still inside its retry backoff —
50
+ * `dequeue` returns undefined for not-yet-due items, so there is no busy
51
+ * loop and no retry can run before `nextAttemptAt`).
47
52
  */
48
53
  private startProcessingLoop;
49
54
  /**
50
- * Handle a single queue item
55
+ * Handle a single queue item.
56
+ *
57
+ * The item is in the queue's in-flight set for the whole handler run
58
+ * (issue #2104), so both `complete` and `retry` address it reliably even
59
+ * though `dequeue` already removed it from the queued array.
51
60
  */
52
61
  private handleItem;
53
62
  /**
54
- * Stop a worker
63
+ * Stop a worker.
64
+ *
65
+ * In-flight policy (issue #2104): stopping flips the status to `stopped`
66
+ * synchronously — note the intermediate `stopping` value is written but
67
+ * never observable, since nothing awaits between the two assignments —
68
+ * and the processing loop exits when it reads the new status at its next
69
+ * bounded check (≤100 ms later). Already-running handlers are NOT
70
+ * cancelled: they run to completion and settle their item through the
71
+ * queue's in-flight `complete`/`retry`. Queued items stay queued for a
72
+ * future `start`. The method stays synchronous, so it does not wait for
73
+ * those handlers; use the queue's `inflightSize()` (exposed via
74
+ * `getStats().queueInflight`) to observe drain progress.
55
75
  */
56
76
  stop(name: string): boolean;
57
77
  /**
@@ -76,6 +96,7 @@ export declare class WorkerManager {
76
96
  errorCount: number;
77
97
  lastError?: unknown;
78
98
  queueSize: number;
99
+ queueInflight: number;
79
100
  } | undefined;
80
101
  /**
81
102
  * Get all worker names
@@ -12,8 +12,8 @@ import {
12
12
  shouldRunOnStartup,
13
13
  writeBackupArtifact,
14
14
  writeDoctorArtifact
15
- } from "./index-7jaq84cg.js";
16
- import"./index-mgcffsk0.js";
15
+ } from "./index-1vbmra32.js";
16
+ import"./index-yq89bgnz.js";
17
17
  import"./index-cpg98bh1.js";
18
18
  import"./index-z6xqpmqg.js";
19
19
  import"./index-zjygnfay.js";
@@ -14,7 +14,7 @@ import {
14
14
  resolveWorktreeBaseDir,
15
15
  shortenWorktreePath,
16
16
  writeLaneProfileToDiskReal
17
- } from "./index-ndqhtgrc.js";
17
+ } from "./index-8kzrgjt6.js";
18
18
  import"./index-cpg98bh1.js";
19
19
  import"./index-9e6fdz2h.js";
20
20
  import"./index-4rhhvd1a.js";
@@ -4,12 +4,12 @@ import {
4
4
  authorizeCuration,
5
5
  buildConfigFingerprintInput,
6
6
  readCohortConfigFingerprint
7
- } from "./index-r9g7ymv2.js";
7
+ } from "./index-nq4tkfpc.js";
8
8
  import"./index-rtry5xyf.js";
9
- import"./index-m5z2fgs4.js";
10
- import"./index-2zz8b0rb.js";
11
- import"./index-zpn3wqvp.js";
12
- import"./index-rsn4jm90.js";
9
+ import"./index-k1s8gxjh.js";
10
+ import"./index-vhefvcta.js";
11
+ import"./index-kg4knw6r.js";
12
+ import"./index-vrp2zva8.js";
13
13
  import"./index-ghbkknjz.js";
14
14
  import"./index-7g4c7s5r.js";
15
15
  import"./index-bpmtbmy9.js";
@@ -14,45 +14,45 @@ import {
14
14
  runCuratorInit,
15
15
  runCuratorPhase,
16
16
  writeCuratorSummary
17
- } from "./index-hsq8nyen.js";
18
- import"./index-ebt47fnp.js";
19
- import"./index-s0nss8c4.js";
20
- import"./index-7jaq84cg.js";
21
- import"./index-5vyej8pc.js";
22
- import"./index-x4kgn37c.js";
17
+ } from "./index-hj1xd3pg.js";
18
+ import"./index-j382eh60.js";
19
+ import"./index-b94487xm.js";
20
+ import"./index-1vbmra32.js";
21
+ import"./index-b1c83zf9.js";
22
+ import"./index-8djgxw2w.js";
23
23
  import"./index-134d35c1.js";
24
24
  import"./index-nj6rmyeh.js";
25
25
  import"./index-y8552snf.js";
26
- import"./index-crpkb5x6.js";
27
- import"./index-nxydm56k.js";
26
+ import"./index-ye7kpzrk.js";
27
+ import"./index-w00hn0dd.js";
28
28
  import"./index-70ha9e09.js";
29
29
  import"./index-c8s9a3zh.js";
30
30
  import"./index-9ss2m4rs.js";
31
31
  import"./index-g8wwj0sz.js";
32
- import"./index-2n9rwvcc.js";
33
- import"./index-pzt7ed53.js";
34
- import"./index-mbcyz77e.js";
35
- import"./index-r9g7ymv2.js";
32
+ import"./index-qwmrt51t.js";
33
+ import"./index-bccfz7br.js";
34
+ import"./index-gswx08pr.js";
35
+ import"./index-nq4tkfpc.js";
36
36
  import"./index-rtry5xyf.js";
37
37
  import"./index-zsrtt42s.js";
38
- import"./index-092deqxs.js";
38
+ import"./index-t25evmna.js";
39
39
  import"./index-fxvgaeq4.js";
40
- import"./index-q6kscnts.js";
41
- import"./index-ndqhtgrc.js";
42
- import"./index-84ytts36.js";
43
- import"./index-x9jppg8b.js";
40
+ import"./index-622phhp5.js";
41
+ import"./index-8kzrgjt6.js";
42
+ import"./index-6kw1a3bk.js";
43
+ import"./index-9m8jy3av.js";
44
44
  import"./index-556ja8an.js";
45
45
  import"./index-b43rt5ph.js";
46
46
  import"./index-q7sjgr1y.js";
47
47
  import"./index-3g0xk6tk.js";
48
48
  import"./index-85gkedsf.js";
49
- import"./index-wgrvq2bc.js";
50
- import"./index-s0s1e5jp.js";
51
- import"./index-x9q0b3a8.js";
49
+ import"./index-sxtz2d26.js";
50
+ import"./index-skgeytf6.js";
51
+ import"./index-0045n7qe.js";
52
52
  import"./index-gprxjmm7.js";
53
53
  import"./index-n832052r.js";
54
- import"./index-nqwn8sf0.js";
55
- import"./index-mgcffsk0.js";
54
+ import"./index-7rerkeg8.js";
55
+ import"./index-yq89bgnz.js";
56
56
  import"./index-cpg98bh1.js";
57
57
  import"./index-9e6fdz2h.js";
58
58
  import"./index-4rhhvd1a.js";
@@ -61,11 +61,11 @@ import"./index-z6xqpmqg.js";
61
61
  import"./index-r3mvsbtq.js";
62
62
  import"./index-zjygnfay.js";
63
63
  import"./index-ae75rja9.js";
64
- import"./index-m5z2fgs4.js";
65
- import"./index-2zz8b0rb.js";
64
+ import"./index-k1s8gxjh.js";
65
+ import"./index-vhefvcta.js";
66
66
  import"./index-bk5tah7q.js";
67
- import"./index-zpn3wqvp.js";
68
- import"./index-rsn4jm90.js";
67
+ import"./index-kg4knw6r.js";
68
+ import"./index-vrp2zva8.js";
69
69
  import"./index-ghbkknjz.js";
70
70
  import"./index-7g4c7s5r.js";
71
71
  import"./index-bpmtbmy9.js";
@@ -1,45 +1,45 @@
1
1
  // @bun
2
2
  import {
3
3
  createCuratorLLMDelegate
4
- } from "./index-hsq8nyen.js";
5
- import"./index-ebt47fnp.js";
6
- import"./index-s0nss8c4.js";
7
- import"./index-7jaq84cg.js";
8
- import"./index-5vyej8pc.js";
9
- import"./index-x4kgn37c.js";
4
+ } from "./index-hj1xd3pg.js";
5
+ import"./index-j382eh60.js";
6
+ import"./index-b94487xm.js";
7
+ import"./index-1vbmra32.js";
8
+ import"./index-b1c83zf9.js";
9
+ import"./index-8djgxw2w.js";
10
10
  import"./index-134d35c1.js";
11
11
  import"./index-nj6rmyeh.js";
12
12
  import"./index-y8552snf.js";
13
- import"./index-crpkb5x6.js";
14
- import"./index-nxydm56k.js";
13
+ import"./index-ye7kpzrk.js";
14
+ import"./index-w00hn0dd.js";
15
15
  import"./index-70ha9e09.js";
16
16
  import"./index-c8s9a3zh.js";
17
17
  import"./index-9ss2m4rs.js";
18
18
  import"./index-g8wwj0sz.js";
19
- import"./index-2n9rwvcc.js";
20
- import"./index-pzt7ed53.js";
21
- import"./index-mbcyz77e.js";
22
- import"./index-r9g7ymv2.js";
19
+ import"./index-qwmrt51t.js";
20
+ import"./index-bccfz7br.js";
21
+ import"./index-gswx08pr.js";
22
+ import"./index-nq4tkfpc.js";
23
23
  import"./index-rtry5xyf.js";
24
24
  import"./index-zsrtt42s.js";
25
- import"./index-092deqxs.js";
25
+ import"./index-t25evmna.js";
26
26
  import"./index-fxvgaeq4.js";
27
- import"./index-q6kscnts.js";
28
- import"./index-ndqhtgrc.js";
29
- import"./index-84ytts36.js";
30
- import"./index-x9jppg8b.js";
27
+ import"./index-622phhp5.js";
28
+ import"./index-8kzrgjt6.js";
29
+ import"./index-6kw1a3bk.js";
30
+ import"./index-9m8jy3av.js";
31
31
  import"./index-556ja8an.js";
32
32
  import"./index-b43rt5ph.js";
33
33
  import"./index-q7sjgr1y.js";
34
34
  import"./index-3g0xk6tk.js";
35
35
  import"./index-85gkedsf.js";
36
- import"./index-wgrvq2bc.js";
37
- import"./index-s0s1e5jp.js";
38
- import"./index-x9q0b3a8.js";
36
+ import"./index-sxtz2d26.js";
37
+ import"./index-skgeytf6.js";
38
+ import"./index-0045n7qe.js";
39
39
  import"./index-gprxjmm7.js";
40
40
  import"./index-n832052r.js";
41
- import"./index-nqwn8sf0.js";
42
- import"./index-mgcffsk0.js";
41
+ import"./index-7rerkeg8.js";
42
+ import"./index-yq89bgnz.js";
43
43
  import"./index-cpg98bh1.js";
44
44
  import"./index-9e6fdz2h.js";
45
45
  import"./index-4rhhvd1a.js";
@@ -48,11 +48,11 @@ import"./index-z6xqpmqg.js";
48
48
  import"./index-r3mvsbtq.js";
49
49
  import"./index-zjygnfay.js";
50
50
  import"./index-ae75rja9.js";
51
- import"./index-m5z2fgs4.js";
52
- import"./index-2zz8b0rb.js";
51
+ import"./index-k1s8gxjh.js";
52
+ import"./index-vhefvcta.js";
53
53
  import"./index-bk5tah7q.js";
54
- import"./index-zpn3wqvp.js";
55
- import"./index-rsn4jm90.js";
54
+ import"./index-kg4knw6r.js";
55
+ import"./index-vrp2zva8.js";
56
56
  import"./index-ghbkknjz.js";
57
57
  import"./index-7g4c7s5r.js";
58
58
  import"./index-bpmtbmy9.js";
@@ -6,21 +6,21 @@ import {
6
6
  loadPlanJsonOnly,
7
7
  mergeDurableGateEntriesFromEvidence,
8
8
  readDurableGateEvidence
9
- } from "./index-5vyej8pc.js";
10
- import"./index-x4kgn37c.js";
9
+ } from "./index-b1c83zf9.js";
10
+ import"./index-8djgxw2w.js";
11
11
  import"./index-134d35c1.js";
12
12
  import"./index-y8552snf.js";
13
13
  import"./index-9ss2m4rs.js";
14
14
  import"./index-zsrtt42s.js";
15
- import"./index-q6kscnts.js";
16
- import"./index-ndqhtgrc.js";
17
- import"./index-x9jppg8b.js";
15
+ import"./index-622phhp5.js";
16
+ import"./index-8kzrgjt6.js";
17
+ import"./index-9m8jy3av.js";
18
18
  import"./index-556ja8an.js";
19
19
  import"./index-85gkedsf.js";
20
20
  import"./index-gprxjmm7.js";
21
21
  import"./index-n832052r.js";
22
- import"./index-nqwn8sf0.js";
23
- import"./index-mgcffsk0.js";
22
+ import"./index-7rerkeg8.js";
23
+ import"./index-yq89bgnz.js";
24
24
  import"./index-cpg98bh1.js";
25
25
  import"./index-9e6fdz2h.js";
26
26
  import"./index-4rhhvd1a.js";
@@ -28,10 +28,10 @@ import"./index-4cgee5vh.js";
28
28
  import"./index-z6xqpmqg.js";
29
29
  import"./index-r3mvsbtq.js";
30
30
  import"./index-zjygnfay.js";
31
- import"./index-2zz8b0rb.js";
31
+ import"./index-vhefvcta.js";
32
32
  import"./index-bk5tah7q.js";
33
- import"./index-zpn3wqvp.js";
34
- import"./index-rsn4jm90.js";
33
+ import"./index-kg4knw6r.js";
34
+ import"./index-vrp2zva8.js";
35
35
  import"./index-ghbkknjz.js";
36
36
  import"./index-7g4c7s5r.js";
37
37
  import"./index-bpmtbmy9.js";