@titan-design/session-analytics 0.4.1 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -110,8 +110,291 @@ interface ReportWindow {
110
110
  since: string | null;
111
111
  until: string | null;
112
112
  }
113
+ /** An arrival that opens a wake episode: a turn-start record or a mid-loop `queued_command` delivery. */
114
+ interface WakeEventRow {
115
+ key: string;
116
+ sessionId: string;
117
+ cause: string;
118
+ delivery: string;
119
+ fromName: string | null;
120
+ /** The same `msg_id` reached more than one session. */
121
+ broadcast: boolean;
122
+ }
123
+ /** One agent-chat identity: the name a session carries and how it came to carry it. */
124
+ interface AgentNameRow {
125
+ sessionId: string;
126
+ agentName: string;
127
+ originKind: string | null;
128
+ profile: string | null;
129
+ }
113
130
 
114
- declare const bucketSchema: z.ZodObject<{
131
+ declare const ACTION_CLASSES: readonly ["journal-write", "pr-ci-check", "merge", "dispatch", "retire", "task-state", "budget-status", "scorer", "message", "read-investigate", "text-only", "other"];
132
+ type ActionClass = (typeof ACTION_CLASSES)[number];
133
+ /** One tool call of a request, with the signals session-read extracted for it. */
134
+ interface ActionCall {
135
+ tool: string;
136
+ /** Command heads of a Bash call, such as `gh pr checks`. */
137
+ heads?: readonly string[];
138
+ readPaths?: readonly string[];
139
+ writePaths?: readonly string[];
140
+ }
141
+ /** A rule matches a call when every field it sets matches; list order is the precedence. */
142
+ interface ActionRule {
143
+ cls: ActionClass;
144
+ tool?: RegExp;
145
+ head?: RegExp;
146
+ readPath?: RegExp;
147
+ writePath?: RegExp;
148
+ }
149
+ declare const DEFAULT_ACTION_RULES: readonly ActionRule[];
150
+ /** Dispatch is judgment about what to hand out, so it stays out of the mechanical list. */
151
+ declare const DEFAULT_MECHANICAL_CLASSES: readonly ActionClass[];
152
+ declare function classifyRequest(calls: readonly ActionCall[], rules?: readonly ActionRule[]): ActionClass;
153
+
154
+ /** A dispatch or a send; with any file write, the first such request ends a session's boot. */
155
+ declare const BOOT_TOOL: RegExp;
156
+ /** The charter's `teleport_k` and `retire_k` at the time of the TP-499 plan; callers pass their own. */
157
+ declare const DEFAULT_CONFIGURED_K: readonly number[];
158
+ declare const DEFAULT_K_SWEEP: {
159
+ readonly fromK: 20000;
160
+ readonly toK: 1000000;
161
+ readonly stepK: 5000;
162
+ };
163
+ declare const DEFAULT_REVIEWER_ROLE = "worker:reviewer";
164
+ declare const DEFAULT_STANDING_ROLE = "worker:standing_peer";
165
+ declare const DEFAULT_REVIEWER_PRS = 10;
166
+ /** The broker logs this when a seat starts handing over; `from` is the outgoing agent id. */
167
+ declare const TELEPORT_EVENT = "teleport_started";
168
+ declare const sweepResultSchema: z.ZodObject<{
169
+ bestK: z.ZodNullable<z.ZodNumber>;
170
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
171
+ atConfigured: z.ZodArray<z.ZodObject<{
172
+ k: z.ZodNumber;
173
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
174
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
175
+ }, z.core.$strip>>;
176
+ }, z.core.$strip>;
177
+ declare const paramsSchema: z.ZodObject<{
178
+ bootCostUsd: z.ZodNumber;
179
+ bootFill: z.ZodNumber;
180
+ growthPerRequest: z.ZodNumber;
181
+ readPricePerMTok: z.ZodNumber;
182
+ }, z.core.$strip>;
183
+ declare const sessionSchema: z.ZodObject<{
184
+ bootCostUsd: z.ZodNumber;
185
+ bootFill: z.ZodNumber;
186
+ growthPerRequest: z.ZodNumber;
187
+ readPricePerMTok: z.ZodNumber;
188
+ sessionId: z.ZodString;
189
+ role: z.ZodString;
190
+ model: z.ZodString;
191
+ requests: z.ZodNumber;
192
+ bootRequests: z.ZodNumber;
193
+ exitFill: z.ZodNumber;
194
+ lastTs: z.ZodString;
195
+ bestK: z.ZodNullable<z.ZodNumber>;
196
+ }, z.core.$strip>;
197
+ declare const cohortSchema: z.ZodObject<{
198
+ bootCostUsd: z.ZodNumber;
199
+ bootFill: z.ZodNumber;
200
+ growthPerRequest: z.ZodNumber;
201
+ readPricePerMTok: z.ZodNumber;
202
+ halfBoot: z.ZodObject<{
203
+ bestK: z.ZodNullable<z.ZodNumber>;
204
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
205
+ atConfigured: z.ZodArray<z.ZodObject<{
206
+ k: z.ZodNumber;
207
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
208
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
209
+ }, z.core.$strip>>;
210
+ }, z.core.$strip>;
211
+ bestK: z.ZodNullable<z.ZodNumber>;
212
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
213
+ atConfigured: z.ZodArray<z.ZodObject<{
214
+ k: z.ZodNumber;
215
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
216
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
217
+ }, z.core.$strip>>;
218
+ role: z.ZodString;
219
+ model: z.ZodString;
220
+ sessions: z.ZodNumber;
221
+ }, z.core.$strip>;
222
+ declare const teleportSchema: z.ZodObject<{
223
+ ts: z.ZodString;
224
+ name: z.ZodNullable<z.ZodString>;
225
+ sessionId: z.ZodString;
226
+ role: z.ZodString;
227
+ model: z.ZodString;
228
+ exitFill: z.ZodNumber;
229
+ bestK: z.ZodNullable<z.ZodNumber>;
230
+ overConfigured: z.ZodArray<z.ZodObject<{
231
+ k: z.ZodNumber;
232
+ over: z.ZodNumber;
233
+ }, z.core.$strip>>;
234
+ }, z.core.$strip>;
235
+ /** `requestsFrom` when the report has no reviewer session at all, so requests per PR is 0. */
236
+ declare const POOLED_REVIEWERS = "pooled";
237
+ declare const reviewerSchema: z.ZodObject<{
238
+ prs: z.ZodNumber;
239
+ fresh: z.ZodArray<z.ZodObject<{
240
+ role: z.ZodString;
241
+ model: z.ZodString;
242
+ sessions: z.ZodNumber;
243
+ requestsPerPr: z.ZodNumber;
244
+ requestsFrom: z.ZodString;
245
+ costUsd: z.ZodNumber;
246
+ }, z.core.$strip>>;
247
+ standing: z.ZodArray<z.ZodObject<{
248
+ role: z.ZodString;
249
+ model: z.ZodString;
250
+ sessions: z.ZodNumber;
251
+ requestsPerPr: z.ZodNumber;
252
+ requestsFrom: z.ZodString;
253
+ costUsd: z.ZodNumber;
254
+ }, z.core.$strip>>;
255
+ }, z.core.$strip>;
256
+ declare const handoffThresholdSchema: z.ZodObject<{
257
+ configuredK: z.ZodArray<z.ZodNumber>;
258
+ sweep: z.ZodObject<{
259
+ fromK: z.ZodNumber;
260
+ toK: z.ZodNumber;
261
+ stepK: z.ZodNumber;
262
+ }, z.core.$strip>;
263
+ cohorts: z.ZodArray<z.ZodObject<{
264
+ bootCostUsd: z.ZodNumber;
265
+ bootFill: z.ZodNumber;
266
+ growthPerRequest: z.ZodNumber;
267
+ readPricePerMTok: z.ZodNumber;
268
+ halfBoot: z.ZodObject<{
269
+ bestK: z.ZodNullable<z.ZodNumber>;
270
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
271
+ atConfigured: z.ZodArray<z.ZodObject<{
272
+ k: z.ZodNumber;
273
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
274
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
275
+ }, z.core.$strip>>;
276
+ }, z.core.$strip>;
277
+ bestK: z.ZodNullable<z.ZodNumber>;
278
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
279
+ atConfigured: z.ZodArray<z.ZodObject<{
280
+ k: z.ZodNumber;
281
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
282
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
283
+ }, z.core.$strip>>;
284
+ role: z.ZodString;
285
+ model: z.ZodString;
286
+ sessions: z.ZodNumber;
287
+ }, z.core.$strip>>;
288
+ sessions: z.ZodArray<z.ZodObject<{
289
+ bootCostUsd: z.ZodNumber;
290
+ bootFill: z.ZodNumber;
291
+ growthPerRequest: z.ZodNumber;
292
+ readPricePerMTok: z.ZodNumber;
293
+ sessionId: z.ZodString;
294
+ role: z.ZodString;
295
+ model: z.ZodString;
296
+ requests: z.ZodNumber;
297
+ bootRequests: z.ZodNumber;
298
+ exitFill: z.ZodNumber;
299
+ lastTs: z.ZodString;
300
+ bestK: z.ZodNullable<z.ZodNumber>;
301
+ }, z.core.$strip>>;
302
+ unbootedSessions: z.ZodNumber;
303
+ teleports: z.ZodArray<z.ZodObject<{
304
+ ts: z.ZodString;
305
+ name: z.ZodNullable<z.ZodString>;
306
+ sessionId: z.ZodString;
307
+ role: z.ZodString;
308
+ model: z.ZodString;
309
+ exitFill: z.ZodNumber;
310
+ bestK: z.ZodNullable<z.ZodNumber>;
311
+ overConfigured: z.ZodArray<z.ZodObject<{
312
+ k: z.ZodNumber;
313
+ over: z.ZodNumber;
314
+ }, z.core.$strip>>;
315
+ }, z.core.$strip>>;
316
+ unmatchedTeleports: z.ZodNumber;
317
+ reviewers: z.ZodObject<{
318
+ prs: z.ZodNumber;
319
+ fresh: z.ZodArray<z.ZodObject<{
320
+ role: z.ZodString;
321
+ model: z.ZodString;
322
+ sessions: z.ZodNumber;
323
+ requestsPerPr: z.ZodNumber;
324
+ requestsFrom: z.ZodString;
325
+ costUsd: z.ZodNumber;
326
+ }, z.core.$strip>>;
327
+ standing: z.ZodArray<z.ZodObject<{
328
+ role: z.ZodString;
329
+ model: z.ZodString;
330
+ sessions: z.ZodNumber;
331
+ requestsPerPr: z.ZodNumber;
332
+ requestsFrom: z.ZodString;
333
+ costUsd: z.ZodNumber;
334
+ }, z.core.$strip>>;
335
+ }, z.core.$strip>;
336
+ }, z.core.$strip>;
337
+ type HandoffThreshold = z.infer<typeof handoffThresholdSchema>;
338
+ type HandoffCohort = z.infer<typeof cohortSchema>;
339
+ type HandoffSession = z.infer<typeof sessionSchema>;
340
+ type HandoffTeleport = z.infer<typeof teleportSchema>;
341
+ type ReviewerComparison = z.infer<typeof reviewerSchema>;
342
+ type CycleParams = z.infer<typeof paramsSchema>;
343
+ type KSweep = HandoffThreshold["sweep"];
344
+ /** One main-thread request as the handoff model needs it. */
345
+ interface HandoffRequestRow {
346
+ sessionId: string;
347
+ role: string;
348
+ model: string;
349
+ ts: string;
350
+ /** Tokens in context: input, cache reads and cache writes. */
351
+ fill: number;
352
+ tokens: RequestTokens;
353
+ bootAction: boolean;
354
+ }
355
+ interface TeleportEvent {
356
+ ts: string;
357
+ name: string | null;
358
+ fromAgentId: string;
359
+ }
360
+ interface HandoffOptions {
361
+ configuredK?: readonly number[];
362
+ sweep?: KSweep;
363
+ reviewerRole?: string;
364
+ /** The role whose boot, fill and growth price a reviewer that stays up across PRs. */
365
+ standingRole?: string;
366
+ reviewerPrs?: number;
367
+ /** Prices every request and the read rate; the package table, not the graph's stored one. */
368
+ prices?: readonly PriceRow[];
369
+ }
370
+ declare function isBootAction(calls: readonly ActionCall[]): boolean;
371
+ /** Broker log lines to teleport starts; any other line, or one that is not JSON, is skipped. */
372
+ declare function parseTeleportEvents(lines: Iterable<string>): TeleportEvent[];
373
+ /** One cycle boots to f0 and grows g per request up to K: boot/n + read price x mean fill, with n = (K - f0) / g. */
374
+ declare function costPerRequest(params: CycleParams, k: number): number | null;
375
+ /** The cheapest K on the sweep grid, then each configured K against it. */
376
+ declare function sweepK(params: CycleParams, sweep: KSweep, configuredK: readonly number[]): z.infer<typeof sweepResultSchema>;
377
+ /** Per role and model: boot cost and fill, fill growth and read price from the requests, then the K sweep. */
378
+ declare function handoffThreshold(rows: readonly HandoffRequestRow[], teleports: readonly TeleportEvent[], agentSessions: ReadonlyMap<string, readonly string[]>, options?: HandoffOptions): HandoffThreshold;
379
+
380
+ /**
381
+ * Narrows a report to some sessions. Every field left out matches all, and fields combine with AND.
382
+ * Compactions and coverage stay window-wide: the graph does not key them to a request.
383
+ */
384
+ interface ReportScope {
385
+ sessionIds?: readonly string[];
386
+ /** Keeps sessions whose agent-chat agent name starts with it. */
387
+ agentPrefix?: string;
388
+ /** Report roles, as `byRole` names them. */
389
+ roles?: readonly string[];
390
+ }
391
+ /** A predicate over a request's session and role; with no scope every request passes. */
392
+ declare function scopeFilter(db: Db, scope?: ReportScope): (row: {
393
+ sessionId: string;
394
+ role: string;
395
+ }) => boolean;
396
+
397
+ declare const bucketSchema$1: z.ZodObject<{
115
398
  key: z.ZodString;
116
399
  requests: z.ZodNumber;
117
400
  sessions: z.ZodNumber;
@@ -139,11 +422,11 @@ declare const costReportSchema: z.ZodObject<{
139
422
  }, z.core.$strip>;
140
423
  byTokenClass: z.ZodArray<z.ZodObject<{
141
424
  tokenClass: z.ZodEnum<{
425
+ output: "output";
142
426
  input: "input";
143
427
  cache_read: "cache_read";
144
428
  cache_write_5m: "cache_write_5m";
145
429
  cache_write_1h: "cache_write_1h";
146
- output: "output";
147
430
  }>;
148
431
  tokens: z.ZodNumber;
149
432
  costUsd: z.ZodNumber;
@@ -172,6 +455,38 @@ declare const costReportSchema: z.ZodObject<{
172
455
  sessions: z.ZodNumber;
173
456
  costUsd: z.ZodNumber;
174
457
  }, z.core.$strip>>;
458
+ byAction: z.ZodArray<z.ZodObject<{
459
+ role: z.ZodString;
460
+ buckets: z.ZodArray<z.ZodObject<{
461
+ key: z.ZodString;
462
+ requests: z.ZodNumber;
463
+ sessions: z.ZodNumber;
464
+ costUsd: z.ZodNumber;
465
+ }, z.core.$strip>>;
466
+ }, z.core.$strip>>;
467
+ mechanicalShare: z.ZodObject<{
468
+ classes: z.ZodArray<z.ZodEnum<{
469
+ "journal-write": "journal-write";
470
+ "pr-ci-check": "pr-ci-check";
471
+ merge: "merge";
472
+ dispatch: "dispatch";
473
+ retire: "retire";
474
+ "task-state": "task-state";
475
+ "budget-status": "budget-status";
476
+ scorer: "scorer";
477
+ message: "message";
478
+ "read-investigate": "read-investigate";
479
+ "text-only": "text-only";
480
+ other: "other";
481
+ }>>;
482
+ costUsd: z.ZodNumber;
483
+ share: z.ZodNumber;
484
+ byRole: z.ZodArray<z.ZodObject<{
485
+ role: z.ZodString;
486
+ costUsd: z.ZodNumber;
487
+ share: z.ZodNumber;
488
+ }, z.core.$strip>>;
489
+ }, z.core.$strip>;
175
490
  byEpisodeCount: z.ZodArray<z.ZodObject<{
176
491
  key: z.ZodString;
177
492
  requests: z.ZodNumber;
@@ -206,6 +521,154 @@ declare const costReportSchema: z.ZodObject<{
206
521
  midLoopCostUsd: z.ZodNumber;
207
522
  }, z.core.$strip>>;
208
523
  }, z.core.$strip>>;
524
+ wakeEpisodes: z.ZodObject<{
525
+ unattributed: z.ZodObject<{
526
+ requests: z.ZodNumber;
527
+ costUsd: z.ZodNumber;
528
+ }, z.core.$strip>;
529
+ byCause: z.ZodArray<z.ZodObject<{
530
+ midLoopEpisodes: z.ZodNumber;
531
+ requestsPerEpisode: z.ZodNumber;
532
+ costPerEpisode: z.ZodNumber;
533
+ byFrom: z.ZodArray<z.ZodObject<{
534
+ episodes: z.ZodNumber;
535
+ requests: z.ZodNumber;
536
+ costUsd: z.ZodNumber;
537
+ noActionEpisodes: z.ZodNumber;
538
+ noActionCostUsd: z.ZodNumber;
539
+ key: z.ZodEnum<{
540
+ broadcast: "broadcast";
541
+ seat: "seat";
542
+ agent: "agent";
543
+ broker: "broker";
544
+ none: "none";
545
+ }>;
546
+ }, z.core.$strip>>;
547
+ episodes: z.ZodNumber;
548
+ requests: z.ZodNumber;
549
+ costUsd: z.ZodNumber;
550
+ noActionEpisodes: z.ZodNumber;
551
+ noActionCostUsd: z.ZodNumber;
552
+ key: z.ZodString;
553
+ }, z.core.$strip>>;
554
+ pairs: z.ZodArray<z.ZodObject<{
555
+ episodes: z.ZodNumber;
556
+ requests: z.ZodNumber;
557
+ costUsd: z.ZodNumber;
558
+ noActionEpisodes: z.ZodNumber;
559
+ noActionCostUsd: z.ZodNumber;
560
+ from: z.ZodString;
561
+ fromKind: z.ZodEnum<{
562
+ broadcast: "broadcast";
563
+ seat: "seat";
564
+ agent: "agent";
565
+ broker: "broker";
566
+ none: "none";
567
+ }>;
568
+ to: z.ZodString;
569
+ }, z.core.$strip>>;
570
+ episodes: z.ZodNumber;
571
+ requests: z.ZodNumber;
572
+ costUsd: z.ZodNumber;
573
+ noActionEpisodes: z.ZodNumber;
574
+ noActionCostUsd: z.ZodNumber;
575
+ roles: z.ZodArray<z.ZodString>;
576
+ noActionClasses: z.ZodArray<z.ZodEnum<{
577
+ "journal-write": "journal-write";
578
+ "pr-ci-check": "pr-ci-check";
579
+ merge: "merge";
580
+ dispatch: "dispatch";
581
+ retire: "retire";
582
+ "task-state": "task-state";
583
+ "budget-status": "budget-status";
584
+ scorer: "scorer";
585
+ message: "message";
586
+ "read-investigate": "read-investigate";
587
+ "text-only": "text-only";
588
+ other: "other";
589
+ }>>;
590
+ }, z.core.$strip>;
591
+ handoffThreshold: z.ZodObject<{
592
+ configuredK: z.ZodArray<z.ZodNumber>;
593
+ sweep: z.ZodObject<{
594
+ fromK: z.ZodNumber;
595
+ toK: z.ZodNumber;
596
+ stepK: z.ZodNumber;
597
+ }, z.core.$strip>;
598
+ cohorts: z.ZodArray<z.ZodObject<{
599
+ bootCostUsd: z.ZodNumber;
600
+ bootFill: z.ZodNumber;
601
+ growthPerRequest: z.ZodNumber;
602
+ readPricePerMTok: z.ZodNumber;
603
+ halfBoot: z.ZodObject<{
604
+ bestK: z.ZodNullable<z.ZodNumber>;
605
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
606
+ atConfigured: z.ZodArray<z.ZodObject<{
607
+ k: z.ZodNumber;
608
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
609
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
610
+ }, z.core.$strip>>;
611
+ }, z.core.$strip>;
612
+ bestK: z.ZodNullable<z.ZodNumber>;
613
+ bestCostPerRequest: z.ZodNullable<z.ZodNumber>;
614
+ atConfigured: z.ZodArray<z.ZodObject<{
615
+ k: z.ZodNumber;
616
+ costPerRequest: z.ZodNullable<z.ZodNumber>;
617
+ deltaPerRequest: z.ZodNullable<z.ZodNumber>;
618
+ }, z.core.$strip>>;
619
+ role: z.ZodString;
620
+ model: z.ZodString;
621
+ sessions: z.ZodNumber;
622
+ }, z.core.$strip>>;
623
+ sessions: z.ZodArray<z.ZodObject<{
624
+ bootCostUsd: z.ZodNumber;
625
+ bootFill: z.ZodNumber;
626
+ growthPerRequest: z.ZodNumber;
627
+ readPricePerMTok: z.ZodNumber;
628
+ sessionId: z.ZodString;
629
+ role: z.ZodString;
630
+ model: z.ZodString;
631
+ requests: z.ZodNumber;
632
+ bootRequests: z.ZodNumber;
633
+ exitFill: z.ZodNumber;
634
+ lastTs: z.ZodString;
635
+ bestK: z.ZodNullable<z.ZodNumber>;
636
+ }, z.core.$strip>>;
637
+ unbootedSessions: z.ZodNumber;
638
+ teleports: z.ZodArray<z.ZodObject<{
639
+ ts: z.ZodString;
640
+ name: z.ZodNullable<z.ZodString>;
641
+ sessionId: z.ZodString;
642
+ role: z.ZodString;
643
+ model: z.ZodString;
644
+ exitFill: z.ZodNumber;
645
+ bestK: z.ZodNullable<z.ZodNumber>;
646
+ overConfigured: z.ZodArray<z.ZodObject<{
647
+ k: z.ZodNumber;
648
+ over: z.ZodNumber;
649
+ }, z.core.$strip>>;
650
+ }, z.core.$strip>>;
651
+ unmatchedTeleports: z.ZodNumber;
652
+ reviewers: z.ZodObject<{
653
+ prs: z.ZodNumber;
654
+ fresh: z.ZodArray<z.ZodObject<{
655
+ role: z.ZodString;
656
+ model: z.ZodString;
657
+ sessions: z.ZodNumber;
658
+ requestsPerPr: z.ZodNumber;
659
+ requestsFrom: z.ZodString;
660
+ costUsd: z.ZodNumber;
661
+ }, z.core.$strip>>;
662
+ standing: z.ZodArray<z.ZodObject<{
663
+ role: z.ZodString;
664
+ model: z.ZodString;
665
+ sessions: z.ZodNumber;
666
+ requestsPerPr: z.ZodNumber;
667
+ requestsFrom: z.ZodString;
668
+ costUsd: z.ZodNumber;
669
+ }, z.core.$strip>>;
670
+ }, z.core.$strip>;
671
+ }, z.core.$strip>;
209
672
  wakeCauseByGapBand: z.ZodArray<z.ZodObject<{
210
673
  wakeCause: z.ZodString;
211
674
  gapBand: z.ZodString;
@@ -250,9 +713,11 @@ declare const costReportSchema: z.ZodObject<{
250
713
  }, z.core.$strip>;
251
714
  }, z.core.$strip>;
252
715
  type CostReport = z.infer<typeof costReportSchema>;
253
- type CostBucket = z.infer<typeof bucketSchema>;
716
+ type CostBucket = z.infer<typeof bucketSchema$1>;
254
717
  type WakeCauseBucket = CostReport["byWakeCause"][number];
255
718
  type WakeGapCell = z.infer<typeof cellSchema>;
719
+ type RoleActions = CostReport["byAction"][number];
720
+ type MechanicalShare = CostReport["mechanicalShare"];
256
721
  interface CostReportOptions {
257
722
  /** ISO timestamp or date, inclusive. Overrides `days`. */
258
723
  since?: string;
@@ -267,10 +732,172 @@ interface CostReportOptions {
267
732
  transcriptsDiscovered?: number;
268
733
  /** The extraction version an audit facet must reach to count as current. */
269
734
  facetVersion?: number;
735
+ /** Action rules in precedence order; seat-specific rules belong in the caller's config. */
736
+ actionRules?: readonly ActionRule[];
737
+ /** Action classes counted as mechanical in `mechanicalShare`. */
738
+ mechanicalClasses?: readonly ActionClass[];
739
+ /** Report roles whose wakes `wakeEpisodes` cuts into episodes. */
740
+ episodeRoles?: readonly string[];
741
+ /** A wake is no-action when every one of its requests falls in these action classes. */
742
+ noActionClasses?: readonly ActionClass[];
743
+ /** The broker log's lines, read by the caller; its teleport starts give each handoff's exit fill. */
744
+ brokerLogLines?: () => Iterable<string>;
745
+ handoff?: HandoffOptions;
746
+ /** Narrows every request-keyed field to some sessions; absent means all. */
747
+ scope?: ReportScope;
270
748
  }
271
749
  /** Reads the graph and never writes it, so a read-only connection is enough. */
272
750
  declare function costReport(db: Db, options?: CostReportOptions): CostReport;
273
751
 
752
+ /** The tool calls each request in the window issued, keyed by `request_id`; a request with none is absent. */
753
+ declare function readRequestToolCalls(db: Db, window: ReportWindow): Map<string, ActionCall[]>;
754
+
755
+ declare const WAKE_FROM_KINDS: readonly ["seat", "agent", "broadcast", "broker", "none"];
756
+ type WakeFromKind = (typeof WAKE_FROM_KINDS)[number];
757
+ /** Report roles whose wakes are cut into episodes: a human coordinator and a spawned coordinator seat. */
758
+ declare const DEFAULT_EPISODE_ROLES: readonly string[];
759
+ /** A wake whose requests only read, answer in text, or call tools no rule names changed nothing outside the session. */
760
+ declare const DEFAULT_NO_ACTION_CLASSES: readonly ActionClass[];
761
+ declare const AGENT_LIFECYCLE = "agent_lifecycle";
762
+ declare const causeSchema: z.ZodObject<{
763
+ midLoopEpisodes: z.ZodNumber;
764
+ requestsPerEpisode: z.ZodNumber;
765
+ costPerEpisode: z.ZodNumber;
766
+ byFrom: z.ZodArray<z.ZodObject<{
767
+ episodes: z.ZodNumber;
768
+ requests: z.ZodNumber;
769
+ costUsd: z.ZodNumber;
770
+ noActionEpisodes: z.ZodNumber;
771
+ noActionCostUsd: z.ZodNumber;
772
+ key: z.ZodEnum<{
773
+ broadcast: "broadcast";
774
+ seat: "seat";
775
+ agent: "agent";
776
+ broker: "broker";
777
+ none: "none";
778
+ }>;
779
+ }, z.core.$strip>>;
780
+ episodes: z.ZodNumber;
781
+ requests: z.ZodNumber;
782
+ costUsd: z.ZodNumber;
783
+ noActionEpisodes: z.ZodNumber;
784
+ noActionCostUsd: z.ZodNumber;
785
+ key: z.ZodString;
786
+ }, z.core.$strip>;
787
+ declare const pairSchema: z.ZodObject<{
788
+ episodes: z.ZodNumber;
789
+ requests: z.ZodNumber;
790
+ costUsd: z.ZodNumber;
791
+ noActionEpisodes: z.ZodNumber;
792
+ noActionCostUsd: z.ZodNumber;
793
+ from: z.ZodString;
794
+ fromKind: z.ZodEnum<{
795
+ broadcast: "broadcast";
796
+ seat: "seat";
797
+ agent: "agent";
798
+ broker: "broker";
799
+ none: "none";
800
+ }>;
801
+ to: z.ZodString;
802
+ }, z.core.$strip>;
803
+ declare const wakeEpisodesSchema: z.ZodObject<{
804
+ unattributed: z.ZodObject<{
805
+ requests: z.ZodNumber;
806
+ costUsd: z.ZodNumber;
807
+ }, z.core.$strip>;
808
+ byCause: z.ZodArray<z.ZodObject<{
809
+ midLoopEpisodes: z.ZodNumber;
810
+ requestsPerEpisode: z.ZodNumber;
811
+ costPerEpisode: z.ZodNumber;
812
+ byFrom: z.ZodArray<z.ZodObject<{
813
+ episodes: z.ZodNumber;
814
+ requests: z.ZodNumber;
815
+ costUsd: z.ZodNumber;
816
+ noActionEpisodes: z.ZodNumber;
817
+ noActionCostUsd: z.ZodNumber;
818
+ key: z.ZodEnum<{
819
+ broadcast: "broadcast";
820
+ seat: "seat";
821
+ agent: "agent";
822
+ broker: "broker";
823
+ none: "none";
824
+ }>;
825
+ }, z.core.$strip>>;
826
+ episodes: z.ZodNumber;
827
+ requests: z.ZodNumber;
828
+ costUsd: z.ZodNumber;
829
+ noActionEpisodes: z.ZodNumber;
830
+ noActionCostUsd: z.ZodNumber;
831
+ key: z.ZodString;
832
+ }, z.core.$strip>>;
833
+ pairs: z.ZodArray<z.ZodObject<{
834
+ episodes: z.ZodNumber;
835
+ requests: z.ZodNumber;
836
+ costUsd: z.ZodNumber;
837
+ noActionEpisodes: z.ZodNumber;
838
+ noActionCostUsd: z.ZodNumber;
839
+ from: z.ZodString;
840
+ fromKind: z.ZodEnum<{
841
+ broadcast: "broadcast";
842
+ seat: "seat";
843
+ agent: "agent";
844
+ broker: "broker";
845
+ none: "none";
846
+ }>;
847
+ to: z.ZodString;
848
+ }, z.core.$strip>>;
849
+ episodes: z.ZodNumber;
850
+ requests: z.ZodNumber;
851
+ costUsd: z.ZodNumber;
852
+ noActionEpisodes: z.ZodNumber;
853
+ noActionCostUsd: z.ZodNumber;
854
+ roles: z.ZodArray<z.ZodString>;
855
+ noActionClasses: z.ZodArray<z.ZodEnum<{
856
+ "journal-write": "journal-write";
857
+ "pr-ci-check": "pr-ci-check";
858
+ merge: "merge";
859
+ dispatch: "dispatch";
860
+ retire: "retire";
861
+ "task-state": "task-state";
862
+ "budget-status": "budget-status";
863
+ scorer: "scorer";
864
+ message: "message";
865
+ "read-investigate": "read-investigate";
866
+ "text-only": "text-only";
867
+ other: "other";
868
+ }>>;
869
+ }, z.core.$strip>;
870
+ type WakeEpisodes = z.infer<typeof wakeEpisodesSchema>;
871
+ type WakeCauseEpisodes = z.infer<typeof causeSchema>;
872
+ type WakePair = z.infer<typeof pairSchema>;
873
+ /** One request as the episode view needs it. */
874
+ interface EpisodeRequestRow {
875
+ costUsd: number;
876
+ action: ActionClass;
877
+ eventKey: string | null;
878
+ }
879
+ interface WakeEpisode {
880
+ key: string;
881
+ cause: string;
882
+ midLoop: boolean;
883
+ fromKind: WakeFromKind;
884
+ from: string;
885
+ to: string;
886
+ requests: number;
887
+ costUsd: number;
888
+ noAction: boolean;
889
+ }
890
+ interface EpisodeNames {
891
+ seats: ReadonlySet<string>;
892
+ /** Each receiving session's agent-chat name. */
893
+ receivers: ReadonlyMap<string, string>;
894
+ }
895
+ /** A seat is a name some top-level session carries, or one a coordinator profile was spawned under. */
896
+ declare function episodeNames(rows: readonly AgentNameRow[]): EpisodeNames;
897
+ /** Each event with the requests that followed it, flagged no-action when every request's class is listed. */
898
+ declare function buildWakeEpisodes(events: readonly WakeEventRow[], requests: readonly EpisodeRequestRow[], names: EpisodeNames, noActionClasses: readonly ActionClass[]): WakeEpisode[];
899
+ declare function summarizeWakeEpisodes(episodes: readonly WakeEpisode[], requests: readonly EpisodeRequestRow[], roles: readonly string[], noActionClasses: readonly ActionClass[]): WakeEpisodes;
900
+
274
901
  /** Two rule sets on purpose (design section 18): workers segment by assignment, coordinators by work phase. */
275
902
  type Heuristic = "worker-v1" | "coordinator-v1";
276
903
  declare const HEURISTIC_VERSIONS: Readonly<Record<Heuristic, number>>;
@@ -343,5 +970,408 @@ declare function sessionRole(classification: SessionClassification, worker: Work
343
970
  declare const LIST_PRICE_CAVEAT = "List prices, not a bill: the accounts behind these sessions may run on subscription plans. Rankings hold; the absolute figure is not what you paid.";
344
971
  /** The same report as plain-text tables, one section per report field, caveat and footer last. */
345
972
  declare function renderCostReportText(report: CostReport): string;
973
+ /** The report's sections a caller may render alone, keyed by the field each one shows. */
974
+ declare const COST_REPORT_SECTIONS: {
975
+ readonly byRole: (report: CostReport) => string;
976
+ readonly byAction: (report: CostReport) => string;
977
+ readonly mechanicalShare: (report: CostReport) => string;
978
+ readonly byWakeCause: (report: CostReport) => string;
979
+ readonly wakeEpisodes: (report: CostReport) => string;
980
+ readonly wakePairs: (report: CostReport) => string;
981
+ readonly handoff: (report: CostReport) => string;
982
+ readonly teleports: (report: CostReport) => string;
983
+ readonly reviewers: (report: CostReport) => string;
984
+ };
985
+ type CostReportSection = keyof typeof COST_REPORT_SECTIONS;
986
+ /** Some sections of the report under its header, with the caveat and footer last as in the full text. */
987
+ declare function renderCostReportSections(report: CostReport, sections: readonly CostReportSection[]): string;
988
+
989
+ /** Gap bands past a 5-minute TTL: the next request finds the cache gone. */
990
+ declare const REBUILD_GAP_BANDS: readonly string[];
991
+ /** One request as the TTL what-if needs it. */
992
+ interface TtlRequestRow {
993
+ sessionId: string;
994
+ role: string;
995
+ profile: string;
996
+ model: string;
997
+ ts: string;
998
+ cacheReadTokens: number;
999
+ cacheWrite1hTokens: number;
1000
+ /** Milliseconds since the session's previous request; null for its first. */
1001
+ gapMs: number | null;
1002
+ }
1003
+ declare const bucketSchema: z.ZodObject<{
1004
+ fiveMinuteLoses: z.ZodBoolean;
1005
+ sessions: z.ZodNumber;
1006
+ requests: z.ZodNumber;
1007
+ write1hTokens: z.ZodNumber;
1008
+ repriceSavingUsd: z.ZodNumber;
1009
+ rebuilds: z.ZodNumber;
1010
+ rebuildTokens: z.ZodNumber;
1011
+ rebuildCostUsd: z.ZodNumber;
1012
+ netSavingUsd: z.ZodNumber;
1013
+ netPerSessionUsd: z.ZodNumber;
1014
+ key: z.ZodString;
1015
+ }, z.core.$strip>;
1016
+ declare const cacheTtlWhatIfSchema: z.ZodObject<{
1017
+ window: z.ZodOptional<z.ZodObject<{
1018
+ since: z.ZodNullable<z.ZodString>;
1019
+ until: z.ZodNullable<z.ZodString>;
1020
+ }, z.core.$strip>>;
1021
+ priceTableVersion: z.ZodNumber;
1022
+ rebuildGapBands: z.ZodArray<z.ZodString>;
1023
+ totals: z.ZodObject<{
1024
+ sessions: z.ZodNumber;
1025
+ requests: z.ZodNumber;
1026
+ write1hTokens: z.ZodNumber;
1027
+ repriceSavingUsd: z.ZodNumber;
1028
+ rebuilds: z.ZodNumber;
1029
+ rebuildTokens: z.ZodNumber;
1030
+ rebuildCostUsd: z.ZodNumber;
1031
+ netSavingUsd: z.ZodNumber;
1032
+ netPerSessionUsd: z.ZodNumber;
1033
+ }, z.core.$strip>;
1034
+ unpricedRequests: z.ZodNumber;
1035
+ byRole: z.ZodArray<z.ZodObject<{
1036
+ fiveMinuteLoses: z.ZodBoolean;
1037
+ sessions: z.ZodNumber;
1038
+ requests: z.ZodNumber;
1039
+ write1hTokens: z.ZodNumber;
1040
+ repriceSavingUsd: z.ZodNumber;
1041
+ rebuilds: z.ZodNumber;
1042
+ rebuildTokens: z.ZodNumber;
1043
+ rebuildCostUsd: z.ZodNumber;
1044
+ netSavingUsd: z.ZodNumber;
1045
+ netPerSessionUsd: z.ZodNumber;
1046
+ key: z.ZodString;
1047
+ }, z.core.$strip>>;
1048
+ byProfile: z.ZodArray<z.ZodObject<{
1049
+ fiveMinuteLoses: z.ZodBoolean;
1050
+ sessions: z.ZodNumber;
1051
+ requests: z.ZodNumber;
1052
+ write1hTokens: z.ZodNumber;
1053
+ repriceSavingUsd: z.ZodNumber;
1054
+ rebuilds: z.ZodNumber;
1055
+ rebuildTokens: z.ZodNumber;
1056
+ rebuildCostUsd: z.ZodNumber;
1057
+ netSavingUsd: z.ZodNumber;
1058
+ netPerSessionUsd: z.ZodNumber;
1059
+ key: z.ZodString;
1060
+ }, z.core.$strip>>;
1061
+ lossRoles: z.ZodArray<z.ZodString>;
1062
+ }, z.core.$strip>;
1063
+ type CacheTtlWhatIf = z.infer<typeof cacheTtlWhatIfSchema>;
1064
+ type CacheTtlBucket = z.infer<typeof bucketSchema>;
1065
+ /** Q3: what each role and profile would have paid with `CLAUDE_CODE_PROMPT_CACHE_TTL=5m` instead of 1h. */
1066
+ declare function cacheTtlWhatIf(rows: readonly TtlRequestRow[], prices?: readonly PriceRow[]): CacheTtlWhatIf;
1067
+ /** Reads the graph and never writes it; roles are the cost report's. */
1068
+ declare function cacheTtlReport(db: Db, options?: CostReportOptions, prices?: readonly PriceRow[]): CacheTtlWhatIf;
1069
+ declare function readTtlRows(db: Db, window: ReportWindow): TtlRequestRow[];
1070
+ /** One table per dimension; a role or profile 5m would cost money is marked `loss`. */
1071
+ declare function renderCacheTtlText(whatIf: CacheTtlWhatIf): string;
1072
+
1073
+ /** One reviewer verdict message, as agent-chat's events table records it. */
1074
+ interface VerdictRecord {
1075
+ eventId: number;
1076
+ at: string;
1077
+ /** The seat the verdict was sent to. */
1078
+ seat: string;
1079
+ reviewer: string;
1080
+ verdict: string;
1081
+ repo: string;
1082
+ pr: number;
1083
+ head: string;
1084
+ }
1085
+ /** A PR as GitHub REST reports it at the time of the run. */
1086
+ interface PullState {
1087
+ repo: string;
1088
+ pr: number;
1089
+ state: "open" | "closed";
1090
+ mergedAt: string | null;
1091
+ headSha: string;
1092
+ }
1093
+ type ParsedVerdict = Pick<VerdictRecord, "verdict" | "repo" | "pr" | "head">;
1094
+ /** Reads a `Verdict:` message's first three lines; null when any of them is missing. */
1095
+ declare function parseVerdict(body: string): ParsedVerdict | null;
1096
+ type MergeStatus = "merged" | "open" | "stale-head" | "closed" | "unknown";
1097
+ /** A PR holding at least one MERGE verdict, resolved against its GitHub state at `asOf`. */
1098
+ interface MergeOutcome {
1099
+ repo: string;
1100
+ pr: number;
1101
+ status: MergeStatus;
1102
+ /** The first MERGE verdict at the PR's final head; null when no verdict names that head. */
1103
+ verdict: VerdictRecord | null;
1104
+ /** Verdict to merge for merged PRs; verdict to `asOf` (a censored age) for open ones. */
1105
+ minutes: number | null;
1106
+ }
1107
+ declare function mergeOutcomes(verdicts: readonly VerdictRecord[], pulls: readonly PullState[], asOf: string): MergeOutcome[];
1108
+ declare function prKey(row: {
1109
+ repo: string;
1110
+ pr: number;
1111
+ }): string;
1112
+ declare const latencyStatsSchema: z.ZodObject<{
1113
+ merged: z.ZodNumber;
1114
+ medianMin: z.ZodNullable<z.ZodNumber>;
1115
+ meanMin: z.ZodNullable<z.ZodNumber>;
1116
+ p90Min: z.ZodNullable<z.ZodNumber>;
1117
+ maxMin: z.ZodNullable<z.ZodNumber>;
1118
+ censored: z.ZodNumber;
1119
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1120
+ censoredPrMinutes: z.ZodNumber;
1121
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1122
+ }, z.core.$strip>;
1123
+ type LatencyStats = z.infer<typeof latencyStatsSchema>;
1124
+ declare function latencyStats(outcomes: readonly MergeOutcome[]): LatencyStats;
1125
+
1126
+ /** One action the auto-mode classifier refused, read from a seat's transcript. */
1127
+ interface DenialRecord {
1128
+ seat: string;
1129
+ at: string;
1130
+ /** The classifier's bracketed reason, such as "Merge Without Review". */
1131
+ reason: string;
1132
+ /** What the refused call was doing, from its tool input; the reason label alone is loose. */
1133
+ action: string;
1134
+ tool: string;
1135
+ }
1136
+ /** Classifies a refused call by what it did; MCP tools keep their own short name. */
1137
+ declare function classifyDeniedAction(tool: string, input: unknown): string;
1138
+ /** Scans transcript JSONL for classifier refusals and joins each to the tool call it refused. */
1139
+ declare function parseDenials(lines: Iterable<string>, seat: string): DenialRecord[];
1140
+
1141
+ /** A seat journal line that states its implementer slot count, and why it did not fill a free slot. */
1142
+ interface SlotTick {
1143
+ seat: string;
1144
+ at: string;
1145
+ used: number;
1146
+ cap: number;
1147
+ reason: string;
1148
+ /** The journal line number, so a row can be checked against its source. */
1149
+ line: number;
1150
+ }
1151
+ interface SeatJournal {
1152
+ ticks: SlotTick[];
1153
+ /** The journal's last timestamped line; the final tick holds until then. */
1154
+ lastAt: string | null;
1155
+ }
1156
+ declare const UNSTATED_REASON = "unstated";
1157
+ /** A tick's count holds at most this long, so a dark seat is not read as an hour of idle slots. */
1158
+ declare const TICK_HOLD_MAX_MIN = 60;
1159
+ /**
1160
+ * Reads `HH:MM[:SS] ...` journal lines for the date the journal covers.
1161
+ * `utcOffsetMin` is the journal clock's offset east of UTC, such as -360 for UTC-6.
1162
+ */
1163
+ declare function parseSeatJournal(text: string, seat: string, date: string, utcOffsetMin: number): SeatJournal;
1164
+ interface IdleSlotRow {
1165
+ seat: string;
1166
+ reason: string;
1167
+ slotMinutes: number;
1168
+ ticks: number;
1169
+ /** Journal line numbers of the ticks counted here. */
1170
+ lines: number[];
1171
+ }
1172
+ /** Free implementer slots times the minutes each tick's count held, clipped to the window. */
1173
+ declare function idleSlotMinutes(journals: readonly SeatJournal[], window: {
1174
+ since?: string;
1175
+ until?: string;
1176
+ }): IdleSlotRow[];
1177
+
1178
+ /** Where each section's numbers come from: the command that re-reads them and the field it reads. */
1179
+ declare const BLOCKED_FLOW_SOURCES: {
1180
+ readonly verdicts: {
1181
+ readonly command: "sqlite3 -readonly <events.db> \"SELECT id, ts, target, body FROM events WHERE kind='message' AND body LIKE 'Verdict:%'\"";
1182
+ readonly field: "events.ts, events.target, events.body lines Verdict:, PR:, Head:";
1183
+ };
1184
+ readonly pulls: {
1185
+ readonly command: "gh api repos/<owner>/<repo>/pulls/<n>";
1186
+ readonly field: ".state, .merged_at, .head.sha";
1187
+ };
1188
+ readonly denials: {
1189
+ readonly command: "grep 'auto mode classifier. Reason: \\[' <seat transcript>.jsonl";
1190
+ readonly field: "tool_result.content Reason: [<class>], joined to tool_use.input by tool_use_id";
1191
+ };
1192
+ readonly journals: {
1193
+ readonly command: "grep -nE 'impl [0-9]+/[0-9]+' <seat journal>.md";
1194
+ readonly field: "impl <used>/<cap>, No dispatch: <reason>";
1195
+ };
1196
+ };
1197
+ type BlockedFlowSource = keyof typeof BLOCKED_FLOW_SOURCES;
1198
+ interface BlockedFlowInput {
1199
+ verdicts: readonly VerdictRecord[];
1200
+ pulls: readonly PullState[];
1201
+ denials: readonly DenialRecord[];
1202
+ journals: readonly SeatJournal[];
1203
+ /** Waits are measured to here; a PR merged later counts as open. */
1204
+ asOf: string;
1205
+ window?: {
1206
+ since?: string;
1207
+ until?: string;
1208
+ };
1209
+ /** Splits verdict-to-merge by verdict time, such as the moment a seat was granted merge authority. */
1210
+ splitAt?: string;
1211
+ /** Keeps only verdicts sent to, and denials and journals of, these seats. */
1212
+ seats?: readonly string[];
1213
+ }
1214
+ declare const latencyRowSchema: z.ZodObject<{
1215
+ repo: z.ZodString;
1216
+ prs: z.ZodNumber;
1217
+ staleHead: z.ZodNumber;
1218
+ closed: z.ZodNumber;
1219
+ unknown: z.ZodNumber;
1220
+ all: z.ZodObject<{
1221
+ merged: z.ZodNumber;
1222
+ medianMin: z.ZodNullable<z.ZodNumber>;
1223
+ meanMin: z.ZodNullable<z.ZodNumber>;
1224
+ p90Min: z.ZodNullable<z.ZodNumber>;
1225
+ maxMin: z.ZodNullable<z.ZodNumber>;
1226
+ censored: z.ZodNumber;
1227
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1228
+ censoredPrMinutes: z.ZodNumber;
1229
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1230
+ }, z.core.$strip>;
1231
+ before: z.ZodOptional<z.ZodObject<{
1232
+ merged: z.ZodNumber;
1233
+ medianMin: z.ZodNullable<z.ZodNumber>;
1234
+ meanMin: z.ZodNullable<z.ZodNumber>;
1235
+ p90Min: z.ZodNullable<z.ZodNumber>;
1236
+ maxMin: z.ZodNullable<z.ZodNumber>;
1237
+ censored: z.ZodNumber;
1238
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1239
+ censoredPrMinutes: z.ZodNumber;
1240
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1241
+ }, z.core.$strip>>;
1242
+ after: z.ZodOptional<z.ZodObject<{
1243
+ merged: z.ZodNumber;
1244
+ medianMin: z.ZodNullable<z.ZodNumber>;
1245
+ meanMin: z.ZodNullable<z.ZodNumber>;
1246
+ p90Min: z.ZodNullable<z.ZodNumber>;
1247
+ maxMin: z.ZodNullable<z.ZodNumber>;
1248
+ censored: z.ZodNumber;
1249
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1250
+ censoredPrMinutes: z.ZodNumber;
1251
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1252
+ }, z.core.$strip>>;
1253
+ }, z.core.$strip>;
1254
+ declare const blockedFlowSchema: z.ZodObject<{
1255
+ asOf: z.ZodString;
1256
+ window: z.ZodObject<{
1257
+ since: z.ZodOptional<z.ZodString>;
1258
+ until: z.ZodOptional<z.ZodString>;
1259
+ }, z.core.$strip>;
1260
+ splitAt: z.ZodOptional<z.ZodString>;
1261
+ sources: z.ZodRecord<z.ZodEnum<{
1262
+ verdicts: "verdicts";
1263
+ pulls: "pulls";
1264
+ denials: "denials";
1265
+ journals: "journals";
1266
+ }>, z.ZodObject<{
1267
+ command: z.ZodString;
1268
+ field: z.ZodString;
1269
+ }, z.core.$strip>>;
1270
+ verdictToMerge: z.ZodObject<{
1271
+ cites: z.ZodArray<z.ZodEnum<{
1272
+ verdicts: "verdicts";
1273
+ pulls: "pulls";
1274
+ denials: "denials";
1275
+ journals: "journals";
1276
+ }>>;
1277
+ rows: z.ZodArray<z.ZodObject<{
1278
+ repo: z.ZodString;
1279
+ prs: z.ZodNumber;
1280
+ staleHead: z.ZodNumber;
1281
+ closed: z.ZodNumber;
1282
+ unknown: z.ZodNumber;
1283
+ all: z.ZodObject<{
1284
+ merged: z.ZodNumber;
1285
+ medianMin: z.ZodNullable<z.ZodNumber>;
1286
+ meanMin: z.ZodNullable<z.ZodNumber>;
1287
+ p90Min: z.ZodNullable<z.ZodNumber>;
1288
+ maxMin: z.ZodNullable<z.ZodNumber>;
1289
+ censored: z.ZodNumber;
1290
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1291
+ censoredPrMinutes: z.ZodNumber;
1292
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1293
+ }, z.core.$strip>;
1294
+ before: z.ZodOptional<z.ZodObject<{
1295
+ merged: z.ZodNumber;
1296
+ medianMin: z.ZodNullable<z.ZodNumber>;
1297
+ meanMin: z.ZodNullable<z.ZodNumber>;
1298
+ p90Min: z.ZodNullable<z.ZodNumber>;
1299
+ maxMin: z.ZodNullable<z.ZodNumber>;
1300
+ censored: z.ZodNumber;
1301
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1302
+ censoredPrMinutes: z.ZodNumber;
1303
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1304
+ }, z.core.$strip>>;
1305
+ after: z.ZodOptional<z.ZodObject<{
1306
+ merged: z.ZodNumber;
1307
+ medianMin: z.ZodNullable<z.ZodNumber>;
1308
+ meanMin: z.ZodNullable<z.ZodNumber>;
1309
+ p90Min: z.ZodNullable<z.ZodNumber>;
1310
+ maxMin: z.ZodNullable<z.ZodNumber>;
1311
+ censored: z.ZodNumber;
1312
+ oldestCensoredMin: z.ZodNullable<z.ZodNumber>;
1313
+ censoredPrMinutes: z.ZodNumber;
1314
+ medianWithCensoredMin: z.ZodNullable<z.ZodNumber>;
1315
+ }, z.core.$strip>>;
1316
+ }, z.core.$strip>>;
1317
+ }, z.core.$strip>;
1318
+ openHoldingMerge: z.ZodObject<{
1319
+ cites: z.ZodArray<z.ZodEnum<{
1320
+ verdicts: "verdicts";
1321
+ pulls: "pulls";
1322
+ denials: "denials";
1323
+ journals: "journals";
1324
+ }>>;
1325
+ prMinutes: z.ZodNumber;
1326
+ rows: z.ZodArray<z.ZodObject<{
1327
+ repo: z.ZodString;
1328
+ pr: z.ZodNumber;
1329
+ head: z.ZodString;
1330
+ seat: z.ZodString;
1331
+ verdictAt: z.ZodString;
1332
+ ageMin: z.ZodNumber;
1333
+ eventId: z.ZodNumber;
1334
+ }, z.core.$strip>>;
1335
+ }, z.core.$strip>;
1336
+ denials: z.ZodObject<{
1337
+ cites: z.ZodArray<z.ZodEnum<{
1338
+ verdicts: "verdicts";
1339
+ pulls: "pulls";
1340
+ denials: "denials";
1341
+ journals: "journals";
1342
+ }>>;
1343
+ total: z.ZodNumber;
1344
+ rows: z.ZodArray<z.ZodObject<{
1345
+ reason: z.ZodString;
1346
+ action: z.ZodString;
1347
+ seat: z.ZodString;
1348
+ count: z.ZodNumber;
1349
+ }, z.core.$strip>>;
1350
+ }, z.core.$strip>;
1351
+ idleSlots: z.ZodObject<{
1352
+ cites: z.ZodArray<z.ZodEnum<{
1353
+ verdicts: "verdicts";
1354
+ pulls: "pulls";
1355
+ denials: "denials";
1356
+ journals: "journals";
1357
+ }>>;
1358
+ holdMaxMin: z.ZodNumber;
1359
+ total: z.ZodNumber;
1360
+ rows: z.ZodArray<z.ZodObject<{
1361
+ seat: z.ZodString;
1362
+ reason: z.ZodString;
1363
+ slotMinutes: z.ZodNumber;
1364
+ ticks: z.ZodNumber;
1365
+ lines: z.ZodArray<z.ZodNumber>;
1366
+ }, z.core.$strip>>;
1367
+ }, z.core.$strip>;
1368
+ }, z.core.$strip>;
1369
+ type BlockedFlowReport = z.infer<typeof blockedFlowSchema>;
1370
+ type LatencyRow = z.infer<typeof latencyRowSchema>;
1371
+ declare const ALL_REPOS = "all";
1372
+ /** Per repo: verdict-to-merge waits, PRs still holding MERGE, classifier denials and idle implementer slots. */
1373
+ declare function blockedFlowReport(input: BlockedFlowInput): BlockedFlowReport;
1374
+ /** Each table's title names the JSON field its numbers come from; the sources close the report. */
1375
+ declare function renderBlockedFlowText(report: BlockedFlowReport): string;
346
1376
 
347
- export { type Band, CHANNEL_CLUSTER_MS, CONTEXT_BANDS, CONTEXT_RESET_TOKENS, COORDINATOR_MERGE_DEDUPE_REQUESTS, COORDINATOR_MIN_EPISODE_REQUESTS, COORDINATOR_WAVE_QUIET_REQUESTS, type CostBucket, type CostReport, type CostReportOptions, type EpisodeInbound, type EpisodeInput, type EpisodeRequest, type EpisodeSignal, GAP_BANDS, HEURISTIC_VERSIONS, type Heuristic, type HumanRole, IDLE_GAP_MS, LIST_PRICE_CAVEAT, PRICE_TABLE, PRICE_TABLE_VERSION, PROFILE_ROLES, type PriceRow, type PricedRequest, type ReportWindow, type RequestTokens, STANDING_PEER_MIN_ASSIGNMENTS, STANDING_PEER_MIN_HOURS, type SessionClass, type SessionClassification, type SessionFacts, type SessionOrigin, TOKEN_CLASSES, type TaskInitiative, type TokenClass, type WakeCauseBucket, type WakeGapCell, type WorkerFacts, type WorkerRole, type WrittenEpisodes, assignmentCount, bandOf, buildEpisodes, classifySession, contextBand, costReport, costReportSchema, findPrice, gapBand, heuristicFor, initiativeFromCwd, priceRequest, readEpisodeInput, renderCostReportText, roleFromProfile, sessionInitiative, sessionRole, workerRole, writeEpisodes };
1377
+ export { ACTION_CLASSES, AGENT_LIFECYCLE, ALL_REPOS, type ActionCall, type ActionClass, type ActionRule, type AgentNameRow, BLOCKED_FLOW_SOURCES, BOOT_TOOL, type Band, type BlockedFlowInput, type BlockedFlowReport, type BlockedFlowSource, CHANNEL_CLUSTER_MS, CONTEXT_BANDS, CONTEXT_RESET_TOKENS, COORDINATOR_MERGE_DEDUPE_REQUESTS, COORDINATOR_MIN_EPISODE_REQUESTS, COORDINATOR_WAVE_QUIET_REQUESTS, COST_REPORT_SECTIONS, type CacheTtlBucket, type CacheTtlWhatIf, type CostBucket, type CostReport, type CostReportOptions, type CostReportSection, type CycleParams, DEFAULT_ACTION_RULES, DEFAULT_CONFIGURED_K, DEFAULT_EPISODE_ROLES, DEFAULT_K_SWEEP, DEFAULT_MECHANICAL_CLASSES, DEFAULT_NO_ACTION_CLASSES, DEFAULT_REVIEWER_PRS, DEFAULT_REVIEWER_ROLE, DEFAULT_STANDING_ROLE, type DenialRecord, type EpisodeInbound, type EpisodeInput, type EpisodeNames, type EpisodeRequest, type EpisodeRequestRow, type EpisodeSignal, GAP_BANDS, HEURISTIC_VERSIONS, type HandoffCohort, type HandoffOptions, type HandoffRequestRow, type HandoffSession, type HandoffTeleport, type HandoffThreshold, type Heuristic, type HumanRole, IDLE_GAP_MS, type IdleSlotRow, type KSweep, LIST_PRICE_CAVEAT, type LatencyRow, type LatencyStats, type MechanicalShare, type MergeOutcome, type MergeStatus, POOLED_REVIEWERS, PRICE_TABLE, PRICE_TABLE_VERSION, PROFILE_ROLES, type ParsedVerdict, type PriceRow, type PricedRequest, type PullState, REBUILD_GAP_BANDS, type ReportScope, type ReportWindow, type RequestTokens, type ReviewerComparison, type RoleActions, STANDING_PEER_MIN_ASSIGNMENTS, STANDING_PEER_MIN_HOURS, type SeatJournal, type SessionClass, type SessionClassification, type SessionFacts, type SessionOrigin, type SlotTick, TELEPORT_EVENT, TICK_HOLD_MAX_MIN, TOKEN_CLASSES, type TaskInitiative, type TeleportEvent, type TokenClass, type TtlRequestRow, UNSTATED_REASON, type VerdictRecord, WAKE_FROM_KINDS, type WakeCauseBucket, type WakeCauseEpisodes, type WakeEpisode, type WakeEpisodes, type WakeEventRow, type WakeFromKind, type WakeGapCell, type WakePair, type WorkerFacts, type WorkerRole, type WrittenEpisodes, assignmentCount, bandOf, blockedFlowReport, blockedFlowSchema, buildEpisodes, buildWakeEpisodes, cacheTtlReport, cacheTtlWhatIf, cacheTtlWhatIfSchema, classifyDeniedAction, classifyRequest, classifySession, contextBand, costPerRequest, costReport, costReportSchema, episodeNames, findPrice, gapBand, handoffThreshold, handoffThresholdSchema, heuristicFor, idleSlotMinutes, initiativeFromCwd, isBootAction, latencyStats, latencyStatsSchema, mergeOutcomes, parseDenials, parseSeatJournal, parseTeleportEvents, parseVerdict, prKey, priceRequest, readEpisodeInput, readRequestToolCalls, readTtlRows, renderBlockedFlowText, renderCacheTtlText, renderCostReportSections, renderCostReportText, roleFromProfile, scopeFilter, sessionInitiative, sessionRole, summarizeWakeEpisodes, sweepK, wakeEpisodesSchema, workerRole, writeEpisodes };