@titan-design/session-analytics 0.4.0 → 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/README.md +133 -4
- package/dist/index.d.ts +1037 -7
- package/dist/index.js +1226 -48
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/prices.ts","../src/price-request.ts","../src/classify-session.ts","../src/bands.ts","../src/cost-report.ts","../src/cost-report-queries.ts","../src/episodes.ts","../src/initiative.ts","../src/roles.ts","../src/render-text.ts"],"sourcesContent":["/** USD per million tokens. Fitted against 392 `cost-state` rows in the 2026-09-20 audit. */\nexport interface PriceRow {\n /** Matched against the model string by longest prefix. */\n modelPrefix: string;\n /** ISO date. The latest row at or before a request's timestamp wins. */\n effectiveFrom: string;\n input: number;\n cacheRead: number;\n cacheWrite5m: number;\n cacheWrite1h: number;\n output: number;\n}\n\n/** Bump on any edit to PRICE_TABLE. The cost report prints it in its footer. */\nexport const PRICE_TABLE_VERSION = 1;\n\nconst OPUS = { input: 5.0, cacheRead: 0.5, cacheWrite5m: 6.25, cacheWrite1h: 10.0, output: 25.0 };\nconst SONNET = { input: 2.0, cacheRead: 0.2, cacheWrite5m: 2.5, cacheWrite1h: 4.0, output: 10.0 };\n// Fable's cache read is 0.025 of input, not the 0.1 every other model uses. Reading it as\n// 0.1 overstated the 2026-09-20 audit by about $1,700; `fable-cache-read.test` pins the ratio.\nconst FABLE = { input: 10.0, cacheRead: 0.25, cacheWrite5m: 12.5, cacheWrite1h: 20.0, output: 50.0 };\nconst HAIKU = { input: 1.0, cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 2.0, output: 5.0 };\nconst FREE = { input: 0, cacheRead: 0, cacheWrite5m: 0, cacheWrite1h: 0, output: 0 };\n\nconst GENESIS = \"2026-01-01\";\n\nexport const PRICE_TABLE: readonly PriceRow[] = [\n { modelPrefix: \"claude-opus-5\", effectiveFrom: GENESIS, ...OPUS },\n { modelPrefix: \"claude-opus-4-8\", effectiveFrom: GENESIS, ...OPUS },\n { modelPrefix: \"claude-sonnet-5\", effectiveFrom: GENESIS, ...SONNET },\n { modelPrefix: \"claude-fable-5-1\", effectiveFrom: GENESIS, ...FABLE },\n { modelPrefix: \"claude-fable-5\", effectiveFrom: GENESIS, ...FABLE },\n { modelPrefix: \"claude-haiku-4-5\", effectiveFrom: GENESIS, ...HAIKU },\n { modelPrefix: \"<synthetic>\", effectiveFrom: GENESIS, ...FREE },\n];\n\n/**\n * The longest prefix that matches the model, then the latest row effective at `ts`.\n * Returns null for a model no row covers: an unknown model is unpriced, never defaulted,\n * because a default silently prices a new model at an old model's rate.\n */\nexport function findPrice(model: string, ts: string, prices: readonly PriceRow[] = PRICE_TABLE): PriceRow | null {\n let best: PriceRow | null = null;\n for (const row of prices) {\n if (!model.startsWith(row.modelPrefix)) continue;\n if (row.effectiveFrom > ts) continue;\n if (best && !isBetterMatch(row, best)) continue;\n best = row;\n }\n return best;\n}\n\nfunction isBetterMatch(row: PriceRow, best: PriceRow): boolean {\n if (row.modelPrefix.length !== best.modelPrefix.length) return row.modelPrefix.length > best.modelPrefix.length;\n return row.effectiveFrom > best.effectiveFrom;\n}\n","import type { PriceRow } from \"./prices.js\";\nimport { PRICE_TABLE, findPrice } from \"./prices.js\";\n\n/** Raw token counts for one API request, as the transcript reports them. */\nexport interface RequestTokens {\n inputTokens?: number;\n cacheReadTokens?: number;\n /** Total cache creation. Used only when the 5m/1h split is absent. */\n cacheCreationTokens?: number;\n cacheCreation5mTokens?: number;\n cacheCreation1hTokens?: number;\n outputTokens?: number;\n}\n\nexport interface PricedRequest {\n inputUsd: number;\n cacheReadUsd: number;\n cacheWrite5mUsd: number;\n cacheWrite1hUsd: number;\n outputUsd: number;\n costUsd: number;\n /** False when no price row covers the model. Every component is then zero. */\n priced: boolean;\n}\n\nconst UNPRICED: PricedRequest = {\n inputUsd: 0,\n cacheReadUsd: 0,\n cacheWrite5mUsd: 0,\n cacheWrite1hUsd: 0,\n outputUsd: 0,\n costUsd: 0,\n priced: false,\n};\n\nexport function priceRequest(\n tokens: RequestTokens,\n model: string,\n ts: string,\n prices: readonly PriceRow[] = PRICE_TABLE,\n): PricedRequest {\n const row = findPrice(model, ts, prices);\n if (!row) return { ...UNPRICED };\n\n const { write5m, write1h } = splitCacheCreation(tokens);\n const inputUsd = perMTok(tokens.inputTokens, row.input);\n const cacheReadUsd = perMTok(tokens.cacheReadTokens, row.cacheRead);\n const cacheWrite5mUsd = perMTok(write5m, row.cacheWrite5m);\n const cacheWrite1hUsd = perMTok(write1h, row.cacheWrite1h);\n const outputUsd = perMTok(tokens.outputTokens, row.output);\n const costUsd = inputUsd + cacheReadUsd + cacheWrite5mUsd + cacheWrite1hUsd + outputUsd;\n return { inputUsd, cacheReadUsd, cacheWrite5mUsd, cacheWrite1hUsd, outputUsd, costUsd, priced: true };\n}\n\n/**\n * Older transcripts carry a cache_creation total with no ttl breakdown. Charging the\n * 5m rate there under-reads rather than over-reads, and 5m is the harness default.\n */\nfunction splitCacheCreation(tokens: RequestTokens): { write5m: number; write1h: number } {\n const write5m = tokens.cacheCreation5mTokens ?? 0;\n const write1h = tokens.cacheCreation1hTokens ?? 0;\n if (write5m > 0 || write1h > 0) return { write5m, write1h };\n return { write5m: tokens.cacheCreationTokens ?? 0, write1h: 0 };\n}\n\nfunction perMTok(tokens: number | undefined, ratePerMTok: number): number {\n return ((tokens ?? 0) * ratePerMTok) / 1_000_000;\n}\n","export type SessionClass = \"agent_spawned\" | \"human_interactive\" | \"headless_sdk\" | \"other_headless\";\n\n/** Human sessions only. A coordinator drives other agents; an adhoc session does not. */\nexport type HumanRole = \"coordinator\" | \"adhoc\";\n\n/** The agent-chat spawn record for a session, as the origin resolver returns it. */\nexport interface SessionOrigin {\n depth: number;\n parentName?: string | null;\n /** \"adopted\" and \"inherited\" mark a pane the human took over, not a spawned worker. */\n originKind?: string | null;\n profile?: string | null;\n}\n\nexport interface SessionFacts {\n /** The harness entrypoint. Agent-chat workers and `-p` miners both report \"sdk-cli\". */\n startType?: string | null;\n origin?: SessionOrigin | null;\n firstUserText?: string | null;\n humanTurnCount?: number;\n inboundKinds?: readonly string[];\n signalKinds?: readonly string[];\n}\n\nexport interface SessionClassification {\n sessionClass: SessionClass;\n reason: string;\n humanRole: HumanRole | null;\n}\n\nconst COORDINATOR_SIGNALS = new Set([\"agent_spawn\", \"chat_send\"]);\n\n/**\n * Rule order matters. The origin row wins over `startType` because agent-chat workers\n * run `claude -p` and so report \"sdk-cli\" exactly like a headless miner does.\n */\nexport function classifySession(facts: SessionFacts): SessionClassification {\n const [sessionClass, reason] = classOf(facts);\n const humanRole = sessionClass === \"human_interactive\" ? humanRoleOf(facts) : null;\n return { sessionClass, reason, humanRole };\n}\n\nfunction classOf(facts: SessionFacts): [SessionClass, string] {\n const origin = facts.origin;\n if (origin) {\n if (isAdoptedPane(origin)) return [\"human_interactive\", \"origin depth 0, human or adopted parent\"];\n return [\"agent_spawned\", \"origin depth >= 1\"];\n }\n if (facts.startType === \"sdk-cli\") return [\"headless_sdk\", \"start_type sdk-cli with no origin row\"];\n if (isProgrammaticPrompt(facts)) return [\"other_headless\", \"content-block prompt with <= 2 human turns\"];\n return [\"human_interactive\", \"no origin row, no headless marker\"];\n}\n\nfunction isAdoptedPane(origin: SessionOrigin): boolean {\n if (origin.depth !== 0) return false;\n if (origin.parentName === \"human\") return true;\n if (origin.originKind === \"adopted\" || origin.originKind === \"inherited\") return true;\n return !origin.profile;\n}\n\n/** Cron and RemoteTrigger daemons inject a structured content block, never typed prose. */\nfunction isProgrammaticPrompt(facts: SessionFacts): boolean {\n const text = (facts.firstUserText ?? \"\").trimStart();\n return text.startsWith(\"[{\") && (facts.humanTurnCount ?? 0) <= 2;\n}\n\nfunction humanRoleOf(facts: SessionFacts): HumanRole {\n if (facts.inboundKinds?.includes(\"channel_message\")) return \"coordinator\";\n if (facts.signalKinds?.some((kind) => COORDINATOR_SIGNALS.has(kind))) return \"coordinator\";\n return \"adhoc\";\n}\n","/** Half-open [lo, hi) in the band's own unit. */\nexport interface Band {\n lo: number;\n hi: number;\n name: string;\n}\n\n/** Context size in tokens. From `cf_analyze.py` BANDS. */\nexport const CONTEXT_BANDS: readonly Band[] = [\n { lo: 0, hi: 50_000, name: \"<50k\" },\n { lo: 50_000, hi: 100_000, name: \"50-100k\" },\n { lo: 100_000, hi: 200_000, name: \"100-200k\" },\n { lo: 200_000, hi: Number.POSITIVE_INFINITY, name: \"200k+\" },\n];\n\n/** Idle gap in milliseconds. From `cf_analyze.py` IDLE. */\nexport const GAP_BANDS: readonly Band[] = [\n { lo: 0, hi: 5 * 60_000, name: \"<5m\" },\n { lo: 5 * 60_000, hi: 60 * 60_000, name: \"5-60m\" },\n { lo: 60 * 60_000, hi: Number.POSITIVE_INFINITY, name: \">60m\" },\n];\n\n/** Null for a value no band covers, so a caller reports the gap instead of inventing one. */\nexport function bandOf(value: number, bands: readonly Band[]): string | null {\n for (const band of bands) {\n if (value >= band.lo && value < band.hi) return band.name;\n }\n return null;\n}\n\nexport function contextBand(tokens: number): string | null {\n return bandOf(tokens, CONTEXT_BANDS);\n}\n\nexport function gapBand(millis: number): string | null {\n return bandOf(millis, GAP_BANDS);\n}\n","import type { Db } from \"@titan-design/store-sqlite\";\nimport { z } from \"zod\";\nimport { classifySession, type SessionClass } from \"./classify-session.js\";\nimport {\n readCompactions,\n readCostRows,\n readCoverage,\n readPriceTableVersion,\n readSessionContexts,\n type CompactionRow,\n type CostRow,\n type ReportWindow,\n type SessionContext,\n} from \"./cost-report-queries.js\";\nimport { assignmentCount, heuristicFor } from \"./episodes.js\";\nimport { sessionInitiative } from \"./initiative.js\";\nimport { sessionRole } from \"./roles.js\";\n\nconst count = z.number().int().nonnegative();\nconst bucketSchema = z.object({ key: z.string(), requests: count, sessions: count, costUsd: z.number() });\nconst wakePartSchema = bucketSchema.extend({ midLoopRequests: count, midLoopCostUsd: z.number() });\nconst cellSchema = z.object({ wakeCause: z.string(), gapBand: z.string(), requests: count, costUsd: z.number() });\n\nexport const TOKEN_CLASSES = [\"input\", \"cache_read\", \"cache_write_5m\", \"cache_write_1h\", \"output\"] as const;\nexport type TokenClass = (typeof TOKEN_CLASSES)[number];\n\nexport const costReportSchema = z.object({\n window: z.object({ since: z.string().nullable(), until: z.string().nullable() }),\n priceTableVersion: z.number().int().nullable(),\n totals: z.object({ requests: count, sessions: count, costUsd: z.number(), unpricedRequests: count }),\n byTokenClass: z.array(z.object({ tokenClass: z.enum(TOKEN_CLASSES), tokens: count, costUsd: z.number() })),\n byAccount: z.array(bucketSchema),\n byModel: z.array(bucketSchema),\n byClass: z.array(bucketSchema),\n byRole: z.array(bucketSchema),\n /** Sessions by how many episodes their class's heuristic cut them into; `none` when not yet segmented. */\n byEpisodeCount: z.array(bucketSchema),\n byInitiative: z.array(bucketSchema),\n byContextBand: z.array(bucketSchema),\n byWakeCause: z.array(wakePartSchema.extend({ parts: z.array(wakePartSchema) })),\n wakeCauseByGapBand: z.array(cellSchema),\n coldRebuild: z.object({ requests: count, costUsd: z.number(), byGapBandAndCause: z.array(cellSchema) }),\n compactions: z.object({ total: count, manual: count, auto: count, midLoop: count, droppedTokens: count }),\n topSessions: z.array(\n z.object({\n sessionId: z.string(),\n sessionClass: z.string(),\n role: z.string(),\n initiative: z.string(),\n account: z.string(),\n requests: count,\n costUsd: z.number(),\n }),\n ),\n unpricedModels: z.array(z.object({ model: z.string(), requests: count, tokens: count })),\n coverage: z.object({ transcriptsIndexed: count, transcriptsDiscovered: count.nullable(), facetBacklog: count }),\n});\n\nexport type CostReport = z.infer<typeof costReportSchema>;\nexport type CostBucket = z.infer<typeof bucketSchema>;\nexport type WakeCauseBucket = CostReport[\"byWakeCause\"][number];\nexport type WakeGapCell = z.infer<typeof cellSchema>;\n\nexport interface CostReportOptions {\n /** ISO timestamp or date, inclusive. Overrides `days`. */\n since?: string;\n /** ISO timestamp or date, exclusive. */\n until?: string;\n /** Window length ending at `until`, or at `now` when `until` is absent. */\n days?: number;\n now?: Date;\n /** Sessions listed in `topSessions`. */\n top?: number;\n /** Transcripts the caller discovered on disk; the graph cannot know this. */\n transcriptsDiscovered?: number;\n /** The extraction version an audit facet must reach to count as current. */\n facetVersion?: number;\n}\n\n/** AskUserQuestion answers are the human answering, so they count under `human` (decisions Q4). */\nconst HUMAN_CAUSES: readonly string[] = [\"human_typed\", \"ask_user_answer\"];\nconst NONE = \"none\";\nconst DEFAULT_TOP = 10;\nconst EPISODE_COUNT_CAP = 5;\nconst DAY_MS = 86_400_000;\n\ninterface SessionTags {\n sessionClass: SessionClass;\n role: string;\n episodeCount: string;\n initiative: string;\n account: string;\n}\n\ntype TaggedRow = CostRow & SessionTags;\n\n/** Reads the graph and never writes it, so a read-only connection is enough. */\nexport function costReport(db: Db, options: CostReportOptions = {}): CostReport {\n const window = resolveWindow(options);\n const costRows = readCostRows(db, window);\n const sessionIds = [...new Set(costRows.map((row) => row.sessionId))];\n const tags = tagSessions(readSessionContexts(db, sessionIds));\n const rows = costRows.map((row) => ({ ...row, ...tags.get(row.sessionId)! }));\n return {\n window,\n priceTableVersion: readPriceTableVersion(db),\n totals: { ...sumOf(rows), sessions: sessionIds.length, unpricedRequests: rows.filter((row) => !row.priced).length },\n byTokenClass: tokenClasses(rows),\n ...dimensionBuckets(rows),\n byWakeCause: wakeCauses(rows),\n wakeCauseByGapBand: gapCells(rows),\n coldRebuild: coldRebuild(rows),\n compactions: compactionCounts(readCompactions(db, window)),\n topSessions: topSessions(rows, options.top ?? DEFAULT_TOP),\n unpricedModels: unpricedModels(rows),\n coverage: { ...readCoverage(db, options.facetVersion ?? null), transcriptsDiscovered: options.transcriptsDiscovered ?? null },\n };\n}\n\nexport function resolveWindow(options: CostReportOptions): ReportWindow {\n const until = options.until ?? null;\n if (options.since !== undefined) return { since: options.since, until };\n if (options.days === undefined) return { since: null, until };\n const end = until ? Date.parse(until) : (options.now ?? new Date()).getTime();\n return { since: new Date(end - options.days * DAY_MS).toISOString(), until };\n}\n\nfunction tagSessions(contexts: Map<string, SessionContext>): Map<string, SessionTags> {\n const tags = new Map<string, SessionTags>();\n for (const [sessionId, context] of contexts) {\n const classification = classifySession(context.facts);\n const episodes = context.episodes.filter((episode) => episode.heuristic === heuristicFor(classification.sessionClass));\n const worker = { profile: context.facts.origin?.profile, lifetimeMs: context.lifetimeMs, assignments: assignmentCount(episodes) };\n tags.set(sessionId, {\n sessionClass: classification.sessionClass,\n role: sessionRole(classification, worker),\n episodeCount: episodeCountKey(episodes.length),\n initiative: sessionInitiative(context.tasks, context.cwd),\n account: context.account ?? \"unknown\",\n });\n }\n return tags;\n}\n\n/** The worker report's assignment buckets: 1, 2, 3, 4, 5+. */\nfunction episodeCountKey(episodes: number): string {\n if (episodes === 0) return NONE;\n return episodes >= EPISODE_COUNT_CAP ? `${EPISODE_COUNT_CAP}+` : String(episodes);\n}\n\nfunction sumOf(rows: readonly CostRow[]): { requests: number; costUsd: number } {\n return { requests: rows.length, costUsd: rows.reduce((sum, row) => sum + row.costUsd, 0) };\n}\n\nfunction tokenClasses(rows: readonly CostRow[]): CostReport[\"byTokenClass\"] {\n const pick: Record<TokenClass, (row: CostRow) => [number, number]> = {\n input: (row) => [row.inputTokens, row.inputCostUsd],\n cache_read: (row) => [row.cacheReadTokens, row.cacheReadCostUsd],\n cache_write_5m: (row) => [row.cacheWrite5mTokens, row.cacheWrite5mCostUsd],\n cache_write_1h: (row) => [row.cacheWrite1hTokens, row.cacheWrite1hCostUsd],\n output: (row) => [row.outputTokens, row.outputCostUsd],\n };\n return TOKEN_CLASSES.map((tokenClass) => {\n const pairs = rows.map(pick[tokenClass]);\n return { tokenClass, tokens: pairs.reduce((sum, [tokens]) => sum + tokens, 0), costUsd: pairs.reduce((sum, [, cost]) => sum + cost, 0) };\n });\n}\n\nfunction dimensionBuckets(rows: readonly TaggedRow[]) {\n return {\n byAccount: bucketsBy(rows, (row) => row.account),\n byModel: bucketsBy(rows, (row) => row.model),\n byClass: bucketsBy(rows, (row) => row.sessionClass),\n byRole: bucketsBy(rows, (row) => row.role),\n byEpisodeCount: bucketsBy(rows, (row) => row.episodeCount),\n byInitiative: bucketsBy(rows, (row) => row.initiative),\n byContextBand: bucketsBy(rows, (row) => row.contextBand),\n };\n}\n\n/** Most expensive first; ties by key so the report is stable. */\nfunction bucketsBy<T extends CostRow>(rows: readonly T[], keyOf: (row: T) => string): CostBucket[] {\n const groups = groupRows(rows, keyOf);\n return [...groups]\n .map(([key, members]) => ({ key, ...sumOf(members), sessions: new Set(members.map((row) => row.sessionId)).size }))\n .sort(byCostThenKey);\n}\n\nfunction groupRows<T>(rows: readonly T[], keyOf: (row: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = keyOf(row);\n const members = groups.get(key);\n if (members) members.push(row);\n else groups.set(key, [row]);\n }\n return groups;\n}\n\nfunction byCostThenKey(a: { key: string; costUsd: number }, b: { key: string; costUsd: number }): number {\n return b.costUsd - a.costUsd || a.key.localeCompare(b.key);\n}\n\nfunction wakeCauses(rows: readonly CostRow[]): WakeCauseBucket[] {\n const causeOf = (row: CostRow) => row.wakeCause ?? NONE;\n const groupOf = (row: CostRow) => (HUMAN_CAUSES.includes(causeOf(row)) ? \"human\" : causeOf(row));\n return [...groupRows(rows, groupOf)]\n .map(([key, members]) => ({\n ...wakePart(key, members),\n parts: key === \"human\" ? [...groupRows(members, causeOf)].map(([cause, part]) => wakePart(cause, part)).sort(byCostThenKey) : [],\n }))\n .sort(byCostThenKey);\n}\n\nfunction wakePart(key: string, rows: readonly CostRow[]) {\n const midLoop = rows.filter((row) => row.wakeDelivery === \"mid_loop\");\n const sessions = new Set(rows.map((row) => row.sessionId)).size;\n return { key, ...sumOf(rows), sessions, midLoopRequests: midLoop.length, midLoopCostUsd: sumOf(midLoop).costUsd };\n}\n\nfunction gapCells(rows: readonly CostRow[]): WakeGapCell[] {\n const keyOf = (row: CostRow) => JSON.stringify([row.wakeCause ?? NONE, row.gapBand ?? NONE]);\n return [...groupRows(rows, keyOf)]\n .map(([key, members]) => {\n const [wakeCause, gapBand] = JSON.parse(key) as [string, string];\n return { wakeCause, gapBand, ...sumOf(members) };\n })\n .sort((a, b) => b.costUsd - a.costUsd || a.wakeCause.localeCompare(b.wakeCause) || a.gapBand.localeCompare(b.gapBand));\n}\n\nfunction coldRebuild(rows: readonly CostRow[]): CostReport[\"coldRebuild\"] {\n const cold = rows.filter((row) => row.isCold);\n return { ...sumOf(cold), byGapBandAndCause: gapCells(cold) };\n}\n\nfunction compactionCounts(rows: readonly CompactionRow[]): CostReport[\"compactions\"] {\n return {\n total: rows.length,\n manual: rows.filter((row) => row.trigger === \"manual\").length,\n auto: rows.filter((row) => row.trigger === \"auto\").length,\n midLoop: rows.filter((row) => row.midLoop).length,\n droppedTokens: rows.reduce((sum, row) => sum + (row.droppedTokens ?? 0), 0),\n };\n}\n\nfunction topSessions(rows: readonly TaggedRow[], top: number): CostReport[\"topSessions\"] {\n return [...groupRows(rows, (row) => row.sessionId)]\n .map(([sessionId, members]) => {\n const { sessionClass, role, initiative, account } = members[0]!;\n return { sessionId, sessionClass, role, initiative, account, ...sumOf(members) };\n })\n .sort((a, b) => b.costUsd - a.costUsd || a.sessionId.localeCompare(b.sessionId))\n .slice(0, top);\n}\n\nfunction unpricedModels(rows: readonly CostRow[]): CostReport[\"unpricedModels\"] {\n const unpriced = rows.filter((row) => !row.priced);\n return [...groupRows(unpriced, (row) => row.model)]\n .map(([model, members]) => ({ model, requests: members.length, tokens: members.reduce((sum, row) => sum + tokensOf(row), 0) }))\n .sort((a, b) => b.tokens - a.tokens || a.model.localeCompare(b.model));\n}\n\nfunction tokensOf(row: CostRow): number {\n return row.inputTokens + row.cacheReadTokens + row.cacheWrite5mTokens + row.cacheWrite1hTokens + row.outputTokens;\n}\n","import { AUDIT_FACET, EPISODE_TABLE, FACET_TABLE, KIT } from \"@titan-design/session-graph\";\nimport type { Db } from \"@titan-design/store-sqlite\";\nimport type { SessionFacts } from \"./classify-session.js\";\nimport type { TaskInitiative } from \"./initiative.js\";\n\n/** ISO bounds on request `ts`: `since` inclusive, `until` exclusive, null for open. */\nexport interface ReportWindow {\n since: string | null;\n until: string | null;\n}\n\n/** One deduplicated, priced request as the `request_cost` view returns it. */\nexport interface CostRow {\n sessionId: string;\n model: string;\n inputTokens: number;\n cacheReadTokens: number;\n cacheWrite5mTokens: number;\n cacheWrite1hTokens: number;\n outputTokens: number;\n inputCostUsd: number;\n cacheReadCostUsd: number;\n cacheWrite5mCostUsd: number;\n cacheWrite1hCostUsd: number;\n outputCostUsd: number;\n costUsd: number;\n priced: boolean;\n isCold: boolean;\n contextBand: string;\n gapBand: string | null;\n wakeCause: string | null;\n wakeDelivery: string | null;\n}\n\n/** What the report needs about one session beyond its requests. */\nexport interface SessionContext {\n facts: SessionFacts;\n cwd: string | null;\n account: string | null;\n tasks: TaskInitiative[];\n /** First to last main-thread request over the whole session, not just the window. */\n lifetimeMs: number;\n /** Stored episode rows of every heuristic, in episode order. */\n episodes: StoredEpisode[];\n}\n\nexport interface StoredEpisode {\n heuristic: string;\n openedBy: string;\n}\n\nexport interface CompactionRow {\n trigger: string | null;\n midLoop: boolean;\n droppedTokens: number | null;\n}\n\nconst IN_WINDOW = \"(@since IS NULL OR ts >= @since) AND (@until IS NULL OR ts < @until)\";\nconst IN_SESSIONS = \"session_id IN (SELECT value FROM json_each(@ids))\";\n\n// The 5m write column mirrors the view: a split-less write is billed at the 5m rate.\nconst COST_ROWS = `\n SELECT session_id AS sessionId, model,\n input_tokens AS inputTokens, cache_read_tokens AS cacheReadTokens,\n CASE WHEN cache_creation_5m + cache_creation_1h = 0 THEN cache_creation_tokens ELSE cache_creation_5m END AS cacheWrite5mTokens,\n cache_creation_1h AS cacheWrite1hTokens, output_tokens AS outputTokens,\n input_cost_usd AS inputCostUsd, cache_read_cost_usd AS cacheReadCostUsd,\n cache_write_5m_cost_usd AS cacheWrite5mCostUsd, cache_write_1h_cost_usd AS cacheWrite1hCostUsd,\n output_cost_usd AS outputCostUsd, cost_usd AS costUsd, priced, is_cold AS isCold,\n context_band AS contextBand, gap_band AS gapBand, wake_cause AS wakeCause, wake_delivery AS wakeDelivery\n FROM request_cost WHERE ${IN_WINDOW}\n`;\n\nexport function readCostRows(db: Db, window: ReportWindow): CostRow[] {\n const rows = db.prepare(COST_ROWS).all(window) as (Omit<CostRow, \"priced\" | \"isCold\"> & { priced: number; isCold: number })[];\n return rows.map((row) => ({ ...row, priced: row.priced === 1, isCold: row.isCold === 1 }));\n}\n\nexport function readCompactions(db: Db, window: ReportWindow): CompactionRow[] {\n const sql = `SELECT trigger, mid_loop AS midLoop, dropped_tokens AS droppedTokens FROM compaction WHERE ${IN_WINDOW}`;\n const rows = db.prepare(sql).all(window) as (Omit<CompactionRow, \"midLoop\"> & { midLoop: number | null })[];\n return rows.map((row) => ({ ...row, midLoop: row.midLoop === 1 }));\n}\n\n/** The graph's own price version, which is what `request_cost` priced with; null before any price row exists. */\nexport function readPriceTableVersion(db: Db): number | null {\n return (db.prepare(\"SELECT MAX(table_version) AS version FROM price\").get() as { version: number | null }).version;\n}\n\n/** Indexed transcripts, and those whose audit facet is missing or older than `facetVersion`. */\nexport function readCoverage(db: Db, facetVersion: number | null): { transcriptsIndexed: number; facetBacklog: number } {\n const indexed = db.prepare(`SELECT COUNT(*) AS n FROM \"${KIT.watermark}\"`).get() as { n: number };\n const backlog = db\n .prepare(\n `SELECT COUNT(*) AS n FROM \"${KIT.watermark}\" t LEFT JOIN \"${FACET_TABLE}\" f\n ON f.transcript_id = t.source_id AND f.facet = @facet AND (@version IS NULL OR f.version >= @version)\n WHERE f.transcript_id IS NULL`,\n )\n .get({ facet: AUDIT_FACET, version: facetVersion }) as { n: number };\n return { transcriptsIndexed: indexed.n, facetBacklog: backlog.n };\n}\n\nexport function readSessionContexts(db: Db, sessionIds: readonly string[]): Map<string, SessionContext> {\n const ids = JSON.stringify(sessionIds);\n const contexts = new Map<string, SessionContext>(sessionIds.map((id) => [id, emptyContext()]));\n addSessionRows(db, ids, contexts);\n addOrigins(db, ids, contexts);\n addInbounds(db, ids, contexts);\n addSignals(db, ids, contexts);\n addTaskInitiatives(db, ids, contexts);\n addLifetimes(db, ids, contexts);\n addEpisodes(db, ids, contexts);\n return contexts;\n}\n\nfunction emptyContext(): SessionContext {\n return { facts: { inboundKinds: [], signalKinds: [], humanTurnCount: 0 }, cwd: null, account: null, tasks: [], lifetimeMs: 0, episodes: [] };\n}\n\nfunction addSessionRows(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, start_type AS startType, cwd, seed_prompt AS seedPrompt, account FROM session WHERE ${IN_SESSIONS}`;\n type Row = { sessionId: string; startType: string | null; cwd: string | null; seedPrompt: string | null; account: string | null };\n for (const row of db.prepare(sql).all({ ids }) as Row[]) {\n const context = contexts.get(row.sessionId)!;\n context.cwd = row.cwd;\n context.account = row.account;\n context.facts.startType = row.startType;\n context.facts.firstUserText = row.seedPrompt;\n }\n}\n\nfunction addOrigins(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, depth, parent_name AS parentName, origin_kind AS originKind, profile FROM session_origin WHERE ${IN_SESSIONS}`;\n type Row = { sessionId: string; depth: number | null; parentName: string | null; originKind: string | null; profile: string | null };\n for (const { sessionId, depth, ...origin } of db.prepare(sql).all({ ids }) as Row[]) {\n contexts.get(sessionId)!.facts.origin = { ...origin, depth: depth ?? 0 };\n }\n}\n\nfunction addInbounds(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, cause, SUM(delivery = 'turn_start') AS turnStarts FROM inbound WHERE ${IN_SESSIONS} GROUP BY session_id, cause`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; cause: string; turnStarts: number }[]) {\n const facts = contexts.get(row.sessionId)!.facts;\n facts.inboundKinds = [...(facts.inboundKinds ?? []), row.cause];\n if (row.cause === \"human_typed\") facts.humanTurnCount = row.turnStarts;\n }\n}\n\nfunction addSignals(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT DISTINCT session_id AS sessionId, signal FROM session_signal WHERE ${IN_SESSIONS}`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; signal: string }[]) {\n const facts = contexts.get(row.sessionId)!.facts;\n facts.signalKinds = [...(facts.signalKinds ?? []), row.signal];\n }\n}\n\nfunction addTaskInitiatives(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `\n SELECT substr(e.source_ref, 9) AS sessionId, t.initiative, COUNT(*) AS edges\n FROM \"${KIT.edge}\" e JOIN task t ON t.task_ref = e.target_ref\n WHERE e.relation = 'ran' AND e.t_expired IS NULL AND t.initiative IS NOT NULL\n AND e.source_ref IN (SELECT 'session:' || value FROM json_each(@ids))\n GROUP BY e.source_ref, t.initiative`;\n for (const row of db.prepare(sql).all({ ids }) as ({ sessionId: string } & TaskInitiative)[]) {\n contexts.get(row.sessionId)!.tasks.push({ initiative: row.initiative, edges: row.edges });\n }\n}\n\nfunction addLifetimes(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, MIN(ts) AS first, MAX(ts) AS last FROM request_dedup WHERE ${IN_SESSIONS} AND is_sidechain = 0 GROUP BY session_id`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; first: string; last: string }[]) {\n contexts.get(row.sessionId)!.lifetimeMs = Date.parse(row.last) - Date.parse(row.first);\n }\n}\n\nfunction addEpisodes(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, heuristic, opened_by AS openedBy FROM \"${EPISODE_TABLE}\" WHERE ${IN_SESSIONS} ORDER BY session_id, heuristic, episode_index`;\n for (const { sessionId, ...episode } of db.prepare(sql).all({ ids }) as ({ sessionId: string } & StoredEpisode)[]) {\n contexts.get(sessionId)!.episodes.push(episode);\n }\n}\n","import { replaceEpisodes, type EpisodeRow, type SessionGraph } from \"@titan-design/session-graph\";\nimport type { Db } from \"@titan-design/store-sqlite\";\nimport { classifySession, type SessionClass } from \"./classify-session.js\";\nimport { readSessionContexts } from \"./cost-report-queries.js\";\n\n/** Two rule sets on purpose (design section 18): workers segment by assignment, coordinators by work phase. */\nexport type Heuristic = \"worker-v1\" | \"coordinator-v1\";\nexport const HEURISTIC_VERSIONS: Readonly<Record<Heuristic, number>> = { \"worker-v1\": 1, \"coordinator-v1\": 1 };\n\nexport interface EpisodeRequest {\n offset: number;\n ts: string;\n transcriptId: number;\n contextTokens: number;\n wakeCause: string | null;\n}\nexport interface EpisodeInbound {\n offset: number;\n ts: string;\n transcriptId: number;\n cause: string;\n}\nexport interface EpisodeSignal {\n offset: number;\n ts: string;\n transcriptId: number;\n signal: string;\n}\nexport interface EpisodeInput {\n requests: readonly EpisodeRequest[];\n inbounds: readonly EpisodeInbound[];\n signals: readonly EpisodeSignal[];\n /** An agent-chat spawn has a brief; anything else opens at `session_start`. */\n spawned: boolean;\n}\n\nconst MINUTE_MS = 60_000;\nexport const IDLE_GAP_MS = 30 * MINUTE_MS;\nexport const CHANNEL_CLUSTER_MS = 10 * MINUTE_MS;\nexport const COORDINATOR_MIN_EPISODE_REQUESTS = 8;\nexport const COORDINATOR_MERGE_DEDUPE_REQUESTS = 15;\nexport const COORDINATOR_WAVE_QUIET_REQUESTS = 15;\nexport const CONTEXT_RESET_TOKENS = 20_000;\nconst DELIVERABLE_SIGNALS = new Set([\"status_report\", \"pr_create\", \"commit\", \"doc_written\", \"task_wrap\"]);\nconst ASSIGNMENT_OPENERS = new Set([\"brief\", \"channel_followup\"]);\n\n/** Pure: the same rows always cut the same way. Rows come back in episode order. */\nexport function buildEpisodes(input: EpisodeInput, heuristic: Heuristic): EpisodeRow[] {\n return heuristic === \"worker-v1\" ? workerEpisodes(input) : coordinatorEpisodes(input);\n}\n\n/** Workers are segmented; human sessions get the coordinator rule; headless runs get none. */\nexport function heuristicFor(sessionClass: SessionClass): Heuristic | null {\n if (sessionClass === \"agent_spawned\") return \"worker-v1\";\n if (sessionClass === \"human_interactive\") return \"coordinator-v1\";\n return null;\n}\n\n/** The worker report's `n_assignments`: episodes an assignment opened, which is what the standing-peer overlay counts. */\nexport function assignmentCount(rows: readonly Pick<EpisodeRow, \"openedBy\">[]): number {\n return rows.filter((row) => ASSIGNMENT_OPENERS.has(row.openedBy)).length;\n}\n\n// ---------------------------------------------------------------- worker-v1\n\ntype Event =\n | { kind: \"request\"; offset: number; ts: string; ms: number; transcriptId: number }\n | { kind: \"inbound\"; offset: number; ts: string; ms: number; transcriptId: number; cause: string }\n | { kind: \"signal\"; offset: number; ts: string; ms: number; transcriptId: number; signal: string };\n\ninterface Draft {\n row: EpisodeRow;\n hasRequest: boolean;\n}\n\ninterface WorkerState {\n drafts: Draft[];\n lastRequestMs: number | null;\n lastChannelMs: number | null;\n}\n\n/** worker-forensics-report.md section 5 and wf_analyze.py:241-251, with the status-report trigger from design section 9. */\nfunction workerEpisodes(input: EpisodeInput): EpisodeRow[] {\n const state: WorkerState = { drafts: [], lastRequestMs: null, lastChannelMs: null };\n for (const event of timeline(input)) {\n const current = state.drafts.at(-1);\n const reason = current ? workerBoundary(event, current, state) : input.spawned ? \"brief\" : \"session_start\";\n if (reason && (!current || current.hasRequest)) state.drafts.push(openDraft(event, reason, state.drafts.length));\n absorb(state.drafts.at(-1)!, event);\n if (event.kind === \"request\") state.lastRequestMs = event.ms;\n if (isChannel(event)) state.lastChannelMs = event.ms;\n }\n return state.drafts.map((draft) => draft.row);\n}\n\nfunction workerBoundary(event: Event, current: Draft, state: WorkerState): string | null {\n if (event.kind === \"request\" && state.lastRequestMs !== null && event.ms - state.lastRequestMs >= IDLE_GAP_MS) return \"idle_gap\";\n if (!isChannel(event)) return null;\n const startsCluster = state.lastChannelMs === null || event.ms - state.lastChannelMs > CHANNEL_CLUSTER_MS;\n return startsCluster && current.row.firstStatusOffset != null ? \"channel_followup\" : null;\n}\n\nfunction isChannel(event: Event): boolean {\n return event.kind === \"inbound\" && event.cause === \"channel_message\";\n}\n\nfunction openDraft(event: Event, openedBy: string, episodeIndex: number): Draft {\n const assignment = ASSIGNMENT_OPENERS.has(openedBy) && event.kind === \"inbound\" ? event.offset : null;\n const row: EpisodeRow = {\n episodeIndex,\n heuristicVersion: HEURISTIC_VERSIONS[\"worker-v1\"],\n startedAt: event.ts,\n endedAt: event.ts,\n startOffset: event.offset,\n endOffset: event.offset,\n openedBy,\n startTranscriptId: event.transcriptId,\n endTranscriptId: event.transcriptId,\n assignmentOffset: assignment,\n firstDeliverableOffset: null,\n firstDeliverableSignal: null,\n firstStatusOffset: null,\n };\n return { row, hasRequest: false };\n}\n\n/** The first commit is recorded as a deliverable but not as a report: commit fires early for implementers (221 of 411). */\nfunction absorb(draft: Draft, event: Event): void {\n draft.row.endedAt = event.ts;\n draft.row.endOffset = event.offset;\n draft.row.endTranscriptId = event.transcriptId;\n if (event.kind === \"request\") draft.hasRequest = true;\n if (event.kind !== \"signal\") return;\n if (draft.row.firstDeliverableOffset == null && DELIVERABLE_SIGNALS.has(event.signal)) {\n draft.row.firstDeliverableOffset = event.offset;\n draft.row.firstDeliverableSignal = event.signal;\n }\n if (draft.row.firstStatusOffset == null && event.signal === \"status_report\") draft.row.firstStatusOffset = event.offset;\n}\n\n/**\n * Offsets only order events inside one transcript, so time orders first, then the transcript a\n * session resumed into, then the offset breaks ties within it.\n */\nfunction timeline(input: EpisodeInput): Event[] {\n const events: Event[] = [\n ...input.requests.map((r) => ({ kind: \"request\" as const, offset: r.offset, ts: r.ts, ms: Date.parse(r.ts), transcriptId: r.transcriptId })),\n ...input.inbounds.map((i) => ({ kind: \"inbound\" as const, offset: i.offset, ts: i.ts, ms: Date.parse(i.ts), transcriptId: i.transcriptId, cause: i.cause })),\n ...input.signals.map((s) => ({ kind: \"signal\" as const, offset: s.offset, ts: s.ts, ms: Date.parse(s.ts), transcriptId: s.transcriptId, signal: s.signal })),\n ];\n return events.sort((a, b) => a.ms - b.ms || a.transcriptId - b.transcriptId || a.offset - b.offset);\n}\n\n// ---------------------------------------------------------------- coordinator-v1\n\ninterface Turn {\n request: EpisodeRequest;\n ms: number;\n signals: Set<string>;\n}\n\ninterface Boundary {\n at: number;\n reason: string;\n}\n\n/** coordinator-forensics-report.md section 1, ported from co_analyze.py `segment` with `merge_lag` 0. */\nfunction coordinatorEpisodes(input: EpisodeInput): EpisodeRow[] {\n const turns = toTurns(input);\n if (turns.length === 0) return [];\n const opens = [{ at: 0, reason: \"session_start\" }, ...dropShort(coordinatorBoundaries(turns), turns.length)];\n return opens.map((open, index) => {\n const first = turns[open.at]!.request;\n const last = turns[(opens[index + 1]?.at ?? turns.length) - 1]!.request;\n return {\n episodeIndex: index,\n heuristicVersion: HEURISTIC_VERSIONS[\"coordinator-v1\"],\n startedAt: first.ts,\n endedAt: last.ts,\n startOffset: first.offset,\n endOffset: last.offset,\n startTranscriptId: first.transcriptId,\n endTranscriptId: last.transcriptId,\n openedBy: open.reason,\n };\n });\n}\n\nfunction coordinatorBoundaries(turns: readonly Turn[]): Boundary[] {\n const bounds: Boundary[] = [];\n let spawnedSince = false;\n let lastMerge = -Infinity;\n for (let i = 1; i < turns.length; i++) {\n const reason = coordinatorTrigger(turns, i, lastMerge) ?? (spawnedSince && waveComplete(turns, i) ? \"spawn_wave_complete\" : null);\n if (turns[i - 1]!.signals.has(\"pr_merge\")) lastMerge = i;\n if (reason) {\n bounds.push({ at: i, reason });\n spawnedSince = false;\n }\n if (turns[i]!.signals.has(\"agent_spawn\")) spawnedSince = true;\n }\n return bounds;\n}\n\n/** Checked in the source's order; the first that fires names the boundary. */\nfunction coordinatorTrigger(turns: readonly Turn[], i: number, lastMerge: number): string | null {\n const [a, b] = [turns[i - 1]!, turns[i]!];\n if (b.ms - a.ms >= IDLE_GAP_MS) return \"idle_gap\";\n if (a.signals.has(\"pr_merge\") && i - lastMerge > COORDINATOR_MERGE_DEDUPE_REQUESTS) return \"pr_merge\";\n if (a.signals.has(\"task_wrap\") || a.signals.has(\"task_done\")) return \"task_wrap\";\n const drop = a.request.contextTokens - b.request.contextTokens;\n if (a.request.contextTokens > 0 && drop > CONTEXT_RESET_TOKENS) return \"context_reset\";\n return null;\n}\n\n/** The last agent-chat traffic before a quiet run; the source also counted any agent-chat tool call, which only reaches the graph as `chat_send` or `agent_spawn`. */\nfunction waveComplete(turns: readonly Turn[], i: number): boolean {\n return hasChatTraffic(turns[i - 1]!) && !turns.slice(i, i + COORDINATOR_WAVE_QUIET_REQUESTS).some(hasChatTraffic);\n}\n\nfunction hasChatTraffic(turn: Turn): boolean {\n return turn.request.wakeCause === \"channel_message\" || turn.signals.has(\"chat_send\") || turn.signals.has(\"agent_spawn\");\n}\n\n/** No episode shorter than the minimum, at either end of the session. */\nfunction dropShort(bounds: readonly Boundary[], total: number): Boundary[] {\n const kept: Boundary[] = [];\n let last = 0;\n for (const bound of bounds) {\n if (bound.at - last < COORDINATOR_MIN_EPISODE_REQUESTS || total - bound.at < COORDINATOR_MIN_EPISODE_REQUESTS) continue;\n kept.push(bound);\n last = bound.at;\n }\n return kept;\n}\n\n/** A signal belongs to the latest request at or before it; one before any request goes to the first. */\nfunction toTurns(input: EpisodeInput): Turn[] {\n const turns = input.requests\n .map((request) => ({ request, ms: Date.parse(request.ts), signals: new Set<string>() }))\n .sort((a, b) => a.ms - b.ms || a.request.transcriptId - b.request.transcriptId || a.request.offset - b.request.offset);\n for (const signal of input.signals) ownerOf(turns, signal)?.signals.add(signal.signal);\n return turns;\n}\n\nfunction ownerOf(turns: readonly Turn[], signal: EpisodeSignal): Turn | undefined {\n const ms = Date.parse(signal.ts);\n for (let i = turns.length - 1; i >= 0; i--) {\n const turn = turns[i]!;\n if (turn.ms < ms || (turn.ms === ms && turn.request.offset <= signal.offset)) return turn;\n }\n return turns[0];\n}\n\n// ---------------------------------------------------------------- graph I/O\n\nconst IN_SESSION = \"session_id = ?\";\n\n/**\n * `request_dedup` for one session without ranking every request: SQLite cannot push the session filter\n * through the view's window. Copies of a request can sit in other sessions, so the rank still covers\n * every copy of each request id the session holds.\n */\nconst SESSION_REQUEST_DEDUP = `\n SELECT * FROM (\n SELECT r.*, ROW_NUMBER() OVER (PARTITION BY r.request_id ORDER BY r.ts, r.transcript_id) AS copy_rank\n FROM request r WHERE r.request_id IN (SELECT request_id FROM request WHERE session_id = @sessionId)\n ) WHERE copy_rank = 1 AND session_id = @sessionId`;\n\n/** Main-thread requests only: a sidechain's requests belong to its subagent, not to the session's episodes. */\nexport const EPISODE_REQUESTS_SQL = `\n SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, context_tokens AS contextTokens, wake_cause AS wakeCause\n FROM (${SESSION_REQUEST_DEDUP}) WHERE is_sidechain = 0`;\n\nexport function readEpisodeInput(db: Db, sessionId: string, spawned: boolean): EpisodeInput {\n const requests = db.prepare(EPISODE_REQUESTS_SQL).all({ sessionId }) as EpisodeRequest[];\n const inbounds = db\n .prepare(`SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, cause FROM inbound WHERE ${IN_SESSION}`)\n .all(sessionId) as EpisodeInbound[];\n const signals = db\n .prepare(`SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, signal FROM session_signal WHERE ${IN_SESSION}`)\n .all(sessionId) as EpisodeSignal[];\n return { requests, inbounds, signals, spawned };\n}\n\nexport interface WrittenEpisodes {\n sessionId: string;\n heuristic: Heuristic;\n episodes: number;\n}\n\n/** Segments each session with its class's heuristic and replaces that heuristic's rows. Headless sessions are skipped. */\nexport function writeEpisodes(graph: SessionGraph, sessionIds: readonly string[]): WrittenEpisodes[] {\n const written: WrittenEpisodes[] = [];\n for (const [sessionId, context] of readSessionContexts(graph.db, sessionIds)) {\n const { sessionClass } = classifySession(context.facts);\n const heuristic = heuristicFor(sessionClass);\n if (!heuristic) continue;\n const rows = buildEpisodes(readEpisodeInput(graph.db, sessionId, sessionClass === \"agent_spawned\"), heuristic);\n written.push({ sessionId, heuristic, episodes: replaceEpisodes(graph, sessionId, heuristic, rows) });\n }\n return written;\n}\n","/** Initiatives a session's task edges name, with how many edges name each. */\nexport interface TaskInitiative {\n initiative: string;\n edges: number;\n}\n\n/**\n * A task edge names the initiative outright, so it wins over the cwd guess. Among several,\n * the most-named initiative wins and a tie goes to the alphabetically first, for a stable report.\n */\nexport function sessionInitiative(tasks: readonly TaskInitiative[], cwd: string | null | undefined): string {\n const best = [...tasks].sort((a, b) => b.edges - a.edges || a.initiative.localeCompare(b.initiative))[0];\n return best ? best.initiative : initiativeFromCwd(cwd);\n}\n\n/** The cwd rule from `cf_analyze.py` `initiative()`. A worktree under a repo counts as that repo. */\nexport function initiativeFromCwd(cwd: string | null | undefined): string {\n if (!cwd) return \"unknown\";\n const repo = /\\/projects\\/([^/]+)/.exec(cwd);\n if (repo) return `repo:${repo[1]}`;\n const activeWork = /active-work\\/([^/]+)/.exec(cwd);\n if (activeWork) return `active-work:${activeWork[1]}`;\n if (/ac-fork-\\w+/.test(cwd)) return \"ac-fork(tmp)\";\n const trimmed = cwd.replace(/\\/+$/, \"\");\n return `other:${trimmed.slice(trimmed.lastIndexOf(\"/\") + 1)}`;\n}\n","import type { SessionClassification } from \"./classify-session.js\";\n\n/** worker-v1's role vocabulary, from worker-forensics-report.md section 2. */\nexport type WorkerRole = \"implementer\" | \"reviewer\" | \"researcher\" | \"planner\" | \"coordinator\" | \"standing_peer\" | \"unknown\";\n\n/** Spawn profile to role, as the worker report's table (wf_analyze.py:79-91) maps it. */\nexport const PROFILE_ROLES: Readonly<Record<string, WorkerRole>> = {\n implementer: \"implementer\",\n \"implementer-lite\": \"implementer\",\n \"relay-implementer\": \"implementer\",\n \"beat-builder\": \"implementer\",\n \"fable-optimizer\": \"implementer\",\n reviewer: \"reviewer\",\n \"relay-reviewer\": \"reviewer\",\n researcher: \"researcher\",\n explorer: \"researcher\",\n \"fable-architect\": \"planner\",\n planner: \"planner\",\n \"fable-coordinator\": \"coordinator\",\n peer: \"standing_peer\",\n};\n\nexport const STANDING_PEER_MIN_HOURS = 12;\nexport const STANDING_PEER_MIN_ASSIGNMENTS = 2;\nconst HOUR_MS = 3_600_000;\n\nexport interface WorkerFacts {\n profile?: string | null;\n /** First request to last request, over the whole session rather than a report window. */\n lifetimeMs: number;\n /** worker-v1 episodes opened by an assignment (the brief or a channel follow-up), not by an idle gap. */\n assignments: number;\n}\n\nexport function roleFromProfile(profile: string | null | undefined): WorkerRole {\n return PROFILE_ROLES[(profile ?? \"\").toLowerCase()] ?? \"unknown\";\n}\n\n/** A worker that outlives its first assignment is a standing peer whatever it was spawned as (wf_analyze.py:94-103). */\nexport function workerRole(facts: WorkerFacts): WorkerRole {\n const outlived = facts.lifetimeMs >= STANDING_PEER_MIN_HOURS * HOUR_MS && facts.assignments >= STANDING_PEER_MIN_ASSIGNMENTS;\n return outlived ? \"standing_peer\" : roleFromProfile(facts.profile);\n}\n\n/** The report's role key: `coordinator` or `adhoc` for humans, `worker:<role>` for spawned agents, else the class. */\nexport function sessionRole(classification: SessionClassification, worker: WorkerFacts): string {\n if (classification.humanRole) return classification.humanRole;\n if (classification.sessionClass === \"agent_spawned\") return `worker:${workerRole(worker)}`;\n return classification.sessionClass;\n}\n","import type { CostBucket, CostReport, WakeGapCell } from \"./cost-report.js\";\nimport { PRICE_TABLE_VERSION } from \"./prices.js\";\n\nexport const LIST_PRICE_CAVEAT =\n \"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.\";\n\ntype Cell = string | number;\n\n/** The same report as plain-text tables, one section per report field, caveat and footer last. */\nexport function renderCostReportText(report: CostReport): string {\n const sections = [\n header(report),\n table(\"By token class\", [\"class\", \"tokens\", \"cost\"], report.byTokenClass.map((row) => [row.tokenClass, row.tokens, usd(row.costUsd)])),\n bucketTable(\"By account\", report.byAccount, report.totals.costUsd),\n bucketTable(\"By model\", report.byModel, report.totals.costUsd),\n bucketTable(\"By class\", report.byClass, report.totals.costUsd),\n bucketTable(\"By role\", report.byRole, report.totals.costUsd),\n bucketTable(\"By episode count\", report.byEpisodeCount, report.totals.costUsd),\n bucketTable(\"By initiative\", report.byInitiative, report.totals.costUsd),\n bucketTable(\"By context band\", report.byContextBand, report.totals.costUsd),\n wakeCauseTable(report),\n cellTable(\"Wake cause by gap band\", report.wakeCauseByGapBand),\n cellTable(`Cold rebuilds: ${report.coldRebuild.requests} requests, ${usd(report.coldRebuild.costUsd)}`, report.coldRebuild.byGapBandAndCause),\n compactionTable(report.compactions),\n topSessionTable(report.topSessions),\n unpricedTable(report.unpricedModels),\n [LIST_PRICE_CAVEAT, footer(report)].join(\"\\n\"),\n ];\n return sections.join(\"\\n\\n\") + \"\\n\";\n}\n\nfunction header(report: CostReport): string {\n const { since, until } = report.window;\n const { requests, sessions, costUsd } = report.totals;\n return `Cost report, ${since ?? \"beginning\"} to ${until ?? \"now\"}\\nTotal ${usd(costUsd)} over ${requests} requests in ${sessions} sessions`;\n}\n\nfunction bucketTable(title: string, buckets: readonly CostBucket[], total: number): string {\n const rows = buckets.map((b) => [b.key, b.requests, b.sessions, usd(b.costUsd), share(b.costUsd, total)]);\n return table(title, [\"key\", \"requests\", \"sessions\", \"cost\", \"share\"], rows);\n}\n\n/** Q4: answers sit under `human`, with typed text and answers indented one level down. */\nfunction wakeCauseTable(report: CostReport): string {\n const rows = report.byWakeCause.flatMap((group) => [\n [group.key, group.requests, usd(group.costUsd), group.midLoopRequests, usd(group.midLoopCostUsd)],\n ...group.parts.map((part) => [` ${part.key}`, part.requests, usd(part.costUsd), part.midLoopRequests, usd(part.midLoopCostUsd)]),\n ]);\n return table(\"By wake cause\", [\"cause\", \"requests\", \"cost\", \"mid-loop\", \"mid-loop cost\"], rows);\n}\n\nfunction cellTable(title: string, cells: readonly WakeGapCell[]): string {\n return table(title, [\"cause\", \"gap\", \"requests\", \"cost\"], cells.map((c) => [c.wakeCause, c.gapBand, c.requests, usd(c.costUsd)]));\n}\n\nfunction compactionTable(c: CostReport[\"compactions\"]): string {\n return table(\"Compactions\", [\"total\", \"manual\", \"auto\", \"mid-loop\", \"dropped tokens\"], [[c.total, c.manual, c.auto, c.midLoop, c.droppedTokens]]);\n}\n\nfunction topSessionTable(sessions: CostReport[\"topSessions\"]): string {\n const rows = sessions.map((s) => [s.sessionId, s.sessionClass, s.role, s.initiative, s.requests, usd(s.costUsd)]);\n return table(\"Top sessions\", [\"session\", \"class\", \"role\", \"initiative\", \"requests\", \"cost\"], rows);\n}\n\nfunction unpricedTable(models: CostReport[\"unpricedModels\"]): string {\n if (models.length === 0) return \"Unpriced models: none\";\n return table(\"Unpriced models (counted at zero cost)\", [\"model\", \"requests\", \"tokens\"], models.map((m) => [m.model, m.requests, m.tokens]));\n}\n\nfunction footer(report: CostReport): string {\n const { transcriptsIndexed, transcriptsDiscovered, facetBacklog } = report.coverage;\n const discovered = transcriptsDiscovered === null ? \"\" : ` of ${transcriptsDiscovered} discovered`;\n const version = report.priceTableVersion === null ? \"none\" : `v${report.priceTableVersion}`;\n const stale = report.priceTableVersion !== null && report.priceTableVersion !== PRICE_TABLE_VERSION ? ` (package has v${PRICE_TABLE_VERSION})` : \"\";\n return `Price table ${version}${stale}. Coverage: ${transcriptsIndexed} transcripts indexed${discovered}, facet backlog ${facetBacklog}.`;\n}\n\nfunction table(title: string, head: readonly string[], rows: readonly (readonly Cell[])[]): string {\n if (rows.length === 0) return `${title}: none`;\n const text = [head, ...rows].map((row) => row.map(String));\n const widths = head.map((_, i) => Math.max(...text.map((row) => row[i]!.length)));\n const rightAligned = head.map((_, i) => rows.every((row) => isNumeric(row[i]!)));\n const pad = (cell: string, i: number) => (rightAligned[i] ? cell.padStart(widths[i]!) : cell.padEnd(widths[i]!));\n const lines = text.map((row) => row.map(pad).join(\" \").trimEnd());\n return [title, ...lines].join(\"\\n\");\n}\n\nfunction isNumeric(cell: Cell): boolean {\n return typeof cell === \"number\" || /^\\$|%$/.test(cell);\n}\n\nfunction usd(value: number): string {\n return `$${value.toFixed(2)}`;\n}\n\nfunction share(value: number, total: number): string {\n return total > 0 ? `${((value / total) * 100).toFixed(1)}%` : \"-\";\n}\n"],"mappings":"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","names":["gapBand"]}
|
|
1
|
+
{"version":3,"sources":["../src/prices.ts","../src/price-request.ts","../src/classify-session.ts","../src/bands.ts","../src/cost-report.ts","../src/cost-report-queries.ts","../src/episodes.ts","../src/handoff-threshold.ts","../src/initiative.ts","../src/request-owner.ts","../src/roles.ts","../src/scope.ts","../src/turn-action.ts","../src/wake-episodes.ts","../src/render-text.ts","../src/cache-ttl.ts","../src/blocked-flow-merge.ts","../src/blocked-flow-denials.ts","../src/blocked-flow-idle.ts","../src/blocked-flow.ts"],"sourcesContent":["/** USD per million tokens. Fitted against 392 `cost-state` rows in the 2026-09-20 audit. */\nexport interface PriceRow {\n /** Matched at a model-id boundary: the id itself, or followed by a -YYYYMMDD or [..] suffix. */\n modelPrefix: string;\n /** ISO date. The latest row at or before a request's timestamp wins. */\n effectiveFrom: string;\n input: number;\n cacheRead: number;\n cacheWrite5m: number;\n cacheWrite1h: number;\n output: number;\n}\n\n/** Bump on any edit to PRICE_TABLE. The cost report prints it in its footer. */\nexport const PRICE_TABLE_VERSION = 2;\n\nconst OPUS = { input: 5.0, cacheRead: 0.5, cacheWrite5m: 6.25, cacheWrite1h: 10.0, output: 25.0 };\nconst OPUS_5_5 = { input: 4.0, cacheRead: 0.2, cacheWrite5m: 5.0, cacheWrite1h: 8.0, output: 20.0 };\nconst SONNET = { input: 2.0, cacheRead: 0.2, cacheWrite5m: 2.5, cacheWrite1h: 4.0, output: 10.0 };\n// Fable's cache read is 0.025 of input, not the 0.1 every other model uses. Reading it as\n// 0.1 overstated the 2026-09-20 audit by about $1,700; `fable-cache-read.test` pins the ratio.\nconst FABLE = { input: 10.0, cacheRead: 0.25, cacheWrite5m: 12.5, cacheWrite1h: 20.0, output: 50.0 };\nconst SONNET_5_5 = { input: 2.0, cacheRead: 0.2, cacheWrite5m: 2.5, cacheWrite1h: 4.0, output: 10.0 };\nconst HAIKU = { input: 1.0, cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 2.0, output: 5.0 };\nconst FREE = { input: 0, cacheRead: 0, cacheWrite5m: 0, cacheWrite1h: 0, output: 0 };\n\nconst GENESIS = \"2026-01-01\";\n\nexport const PRICE_TABLE: readonly PriceRow[] = [\n // 5.5 rows: claude-api skill shared/models.md and prompt-caching.md, bundled copy cached 2026-09-25.\n { modelPrefix: \"claude-opus-5-5\", effectiveFrom: GENESIS, ...OPUS_5_5 },\n { modelPrefix: \"claude-opus-5\", effectiveFrom: GENESIS, ...OPUS },\n { modelPrefix: \"claude-opus-4-8\", effectiveFrom: GENESIS, ...OPUS },\n { modelPrefix: \"claude-sonnet-5-5\", effectiveFrom: GENESIS, ...SONNET_5_5 },\n { modelPrefix: \"claude-sonnet-5\", effectiveFrom: GENESIS, ...SONNET },\n { modelPrefix: \"claude-fable-5-1\", effectiveFrom: GENESIS, ...FABLE },\n { modelPrefix: \"claude-fable-5\", effectiveFrom: GENESIS, ...FABLE },\n { modelPrefix: \"claude-haiku-4-5\", effectiveFrom: GENESIS, ...HAIKU },\n { modelPrefix: \"<synthetic>\", effectiveFrom: GENESIS, ...FREE },\n];\n\n/**\n * The longest prefix that matches the model at an id boundary, then the latest row effective at `ts`.\n * Returns null for a model no row covers: an unknown model is unpriced, never defaulted,\n * because a default silently prices a new model at an old model's rate.\n */\nexport function findPrice(model: string, ts: string, prices: readonly PriceRow[] = PRICE_TABLE): PriceRow | null {\n let best: PriceRow | null = null;\n for (const row of prices) {\n if (!matchesAtBoundary(model, row.modelPrefix)) continue;\n if (row.effectiveFrom > ts) continue;\n if (best && !isBetterMatch(row, best)) continue;\n best = row;\n }\n return best;\n}\n\nfunction isBetterMatch(row: PriceRow, best: PriceRow): boolean {\n if (row.modelPrefix.length !== best.modelPrefix.length) return row.modelPrefix.length > best.modelPrefix.length;\n return row.effectiveFrom > best.effectiveFrom;\n}\n\n// A bare startsWith lets claude-opus-5 price claude-opus-5-5 at the older model's rates.\nfunction matchesAtBoundary(model: string, prefix: string): boolean {\n if (!model.startsWith(prefix)) return false;\n const rest = model.slice(prefix.length);\n return rest === \"\" || rest.startsWith(\"[\") || /^-\\d{8}(\\[.*\\])?$/.test(rest);\n}\n","import type { PriceRow } from \"./prices.js\";\nimport { PRICE_TABLE, findPrice } from \"./prices.js\";\n\n/** Raw token counts for one API request, as the transcript reports them. */\nexport interface RequestTokens {\n inputTokens?: number;\n cacheReadTokens?: number;\n /** Total cache creation. Used only when the 5m/1h split is absent. */\n cacheCreationTokens?: number;\n cacheCreation5mTokens?: number;\n cacheCreation1hTokens?: number;\n outputTokens?: number;\n}\n\nexport interface PricedRequest {\n inputUsd: number;\n cacheReadUsd: number;\n cacheWrite5mUsd: number;\n cacheWrite1hUsd: number;\n outputUsd: number;\n costUsd: number;\n /** False when no price row covers the model. Every component is then zero. */\n priced: boolean;\n}\n\nconst UNPRICED: PricedRequest = {\n inputUsd: 0,\n cacheReadUsd: 0,\n cacheWrite5mUsd: 0,\n cacheWrite1hUsd: 0,\n outputUsd: 0,\n costUsd: 0,\n priced: false,\n};\n\nexport function priceRequest(\n tokens: RequestTokens,\n model: string,\n ts: string,\n prices: readonly PriceRow[] = PRICE_TABLE,\n): PricedRequest {\n const row = findPrice(model, ts, prices);\n if (!row) return { ...UNPRICED };\n\n const { write5m, write1h } = splitCacheCreation(tokens);\n const inputUsd = perMTok(tokens.inputTokens, row.input);\n const cacheReadUsd = perMTok(tokens.cacheReadTokens, row.cacheRead);\n const cacheWrite5mUsd = perMTok(write5m, row.cacheWrite5m);\n const cacheWrite1hUsd = perMTok(write1h, row.cacheWrite1h);\n const outputUsd = perMTok(tokens.outputTokens, row.output);\n const costUsd = inputUsd + cacheReadUsd + cacheWrite5mUsd + cacheWrite1hUsd + outputUsd;\n return { inputUsd, cacheReadUsd, cacheWrite5mUsd, cacheWrite1hUsd, outputUsd, costUsd, priced: true };\n}\n\n/**\n * Older transcripts carry a cache_creation total with no ttl breakdown. Charging the\n * 5m rate there under-reads rather than over-reads, and 5m is the harness default.\n */\nfunction splitCacheCreation(tokens: RequestTokens): { write5m: number; write1h: number } {\n const write5m = tokens.cacheCreation5mTokens ?? 0;\n const write1h = tokens.cacheCreation1hTokens ?? 0;\n if (write5m > 0 || write1h > 0) return { write5m, write1h };\n return { write5m: tokens.cacheCreationTokens ?? 0, write1h: 0 };\n}\n\nfunction perMTok(tokens: number | undefined, ratePerMTok: number): number {\n return ((tokens ?? 0) * ratePerMTok) / 1_000_000;\n}\n","export type SessionClass = \"agent_spawned\" | \"human_interactive\" | \"headless_sdk\" | \"other_headless\";\n\n/** Human sessions only. A coordinator drives other agents; an adhoc session does not. */\nexport type HumanRole = \"coordinator\" | \"adhoc\";\n\n/** The agent-chat spawn record for a session, as the origin resolver returns it. */\nexport interface SessionOrigin {\n depth: number;\n parentName?: string | null;\n /** \"adopted\" and \"inherited\" mark a pane the human took over, not a spawned worker. */\n originKind?: string | null;\n profile?: string | null;\n}\n\nexport interface SessionFacts {\n /** The harness entrypoint. Agent-chat workers and `-p` miners both report \"sdk-cli\". */\n startType?: string | null;\n origin?: SessionOrigin | null;\n firstUserText?: string | null;\n humanTurnCount?: number;\n inboundKinds?: readonly string[];\n signalKinds?: readonly string[];\n}\n\nexport interface SessionClassification {\n sessionClass: SessionClass;\n reason: string;\n humanRole: HumanRole | null;\n}\n\nconst COORDINATOR_SIGNALS = new Set([\"agent_spawn\", \"chat_send\"]);\n\n/**\n * Rule order matters. The origin row wins over `startType` because agent-chat workers\n * run `claude -p` and so report \"sdk-cli\" exactly like a headless miner does.\n */\nexport function classifySession(facts: SessionFacts): SessionClassification {\n const [sessionClass, reason] = classOf(facts);\n const humanRole = sessionClass === \"human_interactive\" ? humanRoleOf(facts) : null;\n return { sessionClass, reason, humanRole };\n}\n\nfunction classOf(facts: SessionFacts): [SessionClass, string] {\n const origin = facts.origin;\n if (origin) {\n if (isAdoptedPane(origin)) return [\"human_interactive\", \"origin depth 0, human or adopted parent\"];\n return [\"agent_spawned\", \"origin depth >= 1\"];\n }\n if (facts.startType === \"sdk-cli\") return [\"headless_sdk\", \"start_type sdk-cli with no origin row\"];\n if (isProgrammaticPrompt(facts)) return [\"other_headless\", \"content-block prompt with <= 2 human turns\"];\n return [\"human_interactive\", \"no origin row, no headless marker\"];\n}\n\nfunction isAdoptedPane(origin: SessionOrigin): boolean {\n if (origin.depth !== 0) return false;\n if (origin.parentName === \"human\") return true;\n if (origin.originKind === \"adopted\" || origin.originKind === \"inherited\") return true;\n return !origin.profile;\n}\n\n/** Cron and RemoteTrigger daemons inject a structured content block, never typed prose. */\nfunction isProgrammaticPrompt(facts: SessionFacts): boolean {\n const text = (facts.firstUserText ?? \"\").trimStart();\n return text.startsWith(\"[{\") && (facts.humanTurnCount ?? 0) <= 2;\n}\n\nfunction humanRoleOf(facts: SessionFacts): HumanRole {\n if (facts.inboundKinds?.includes(\"channel_message\")) return \"coordinator\";\n if (facts.signalKinds?.some((kind) => COORDINATOR_SIGNALS.has(kind))) return \"coordinator\";\n return \"adhoc\";\n}\n","/** Half-open [lo, hi) in the band's own unit. */\nexport interface Band {\n lo: number;\n hi: number;\n name: string;\n}\n\n/** Context size in tokens. From `cf_analyze.py` BANDS. */\nexport const CONTEXT_BANDS: readonly Band[] = [\n { lo: 0, hi: 50_000, name: \"<50k\" },\n { lo: 50_000, hi: 100_000, name: \"50-100k\" },\n { lo: 100_000, hi: 200_000, name: \"100-200k\" },\n { lo: 200_000, hi: Number.POSITIVE_INFINITY, name: \"200k+\" },\n];\n\n/** Idle gap in milliseconds. From `cf_analyze.py` IDLE. */\nexport const GAP_BANDS: readonly Band[] = [\n { lo: 0, hi: 5 * 60_000, name: \"<5m\" },\n { lo: 5 * 60_000, hi: 60 * 60_000, name: \"5-60m\" },\n { lo: 60 * 60_000, hi: Number.POSITIVE_INFINITY, name: \">60m\" },\n];\n\n/** Null for a value no band covers, so a caller reports the gap instead of inventing one. */\nexport function bandOf(value: number, bands: readonly Band[]): string | null {\n for (const band of bands) {\n if (value >= band.lo && value < band.hi) return band.name;\n }\n return null;\n}\n\nexport function contextBand(tokens: number): string | null {\n return bandOf(tokens, CONTEXT_BANDS);\n}\n\nexport function gapBand(millis: number): string | null {\n return bandOf(millis, GAP_BANDS);\n}\n","import type { Db } from \"@titan-design/store-sqlite\";\nimport { z } from \"zod\";\nimport { classifySession, type SessionClass } from \"./classify-session.js\";\nimport {\n readAgentNames,\n readCompactions,\n readCostRows,\n readCoverage,\n readAgentSessions,\n readPriceTableVersion,\n readRequestEvents,\n readSessionContexts,\n readWakeEvents,\n type CompactionRow,\n type CostRow,\n type ReportWindow,\n type SessionContext,\n} from \"./cost-report-queries.js\";\nimport { assignmentCount, heuristicFor } from \"./episodes.js\";\nimport { handoffThreshold, handoffThresholdSchema, isBootAction, parseTeleportEvents, type HandoffOptions, type HandoffThreshold } from \"./handoff-threshold.js\";\nimport { sessionInitiative } from \"./initiative.js\";\nimport { readRequestToolCalls } from \"./request-owner.js\";\nimport { sessionRole } from \"./roles.js\";\nimport { scopeFilter, type ReportScope } from \"./scope.js\";\nimport {\n ACTION_CLASSES,\n DEFAULT_ACTION_RULES,\n DEFAULT_MECHANICAL_CLASSES,\n classifyRequest,\n type ActionClass,\n type ActionRule,\n} from \"./turn-action.js\";\nimport {\n DEFAULT_EPISODE_ROLES,\n DEFAULT_NO_ACTION_CLASSES,\n buildWakeEpisodes,\n episodeNames,\n summarizeWakeEpisodes,\n wakeEpisodesSchema,\n type WakeEpisodes,\n} from \"./wake-episodes.js\";\n\nconst count = z.number().int().nonnegative();\nconst bucketSchema = z.object({ key: z.string(), requests: count, sessions: count, costUsd: z.number() });\nconst wakePartSchema = bucketSchema.extend({ midLoopRequests: count, midLoopCostUsd: z.number() });\nconst cellSchema = z.object({ wakeCause: z.string(), gapBand: z.string(), requests: count, costUsd: z.number() });\nconst fraction = z.number().min(0).max(1);\nconst roleShareSchema = z.object({ role: z.string(), costUsd: z.number(), share: fraction });\n\nexport const TOKEN_CLASSES = [\"input\", \"cache_read\", \"cache_write_5m\", \"cache_write_1h\", \"output\"] as const;\nexport type TokenClass = (typeof TOKEN_CLASSES)[number];\n\nexport const costReportSchema = z.object({\n window: z.object({ since: z.string().nullable(), until: z.string().nullable() }),\n priceTableVersion: z.number().int().nullable(),\n totals: z.object({ requests: count, sessions: count, costUsd: z.number(), unpricedRequests: count }),\n byTokenClass: z.array(z.object({ tokenClass: z.enum(TOKEN_CLASSES), tokens: count, costUsd: z.number() })),\n byAccount: z.array(bucketSchema),\n byModel: z.array(bucketSchema),\n byClass: z.array(bucketSchema),\n byRole: z.array(bucketSchema),\n /** Per role, cost by the action class of each request, from the tool calls it issued. */\n byAction: z.array(z.object({ role: z.string(), buckets: z.array(bucketSchema) })),\n /** Cost of the mechanical action classes over the window total; each role's share is over that role's cost. */\n mechanicalShare: z.object({ classes: z.array(z.enum(ACTION_CLASSES)), costUsd: z.number(), share: fraction, byRole: z.array(roleShareSchema) }),\n /** Sessions by how many episodes their class's heuristic cut them into; `none` when not yet segmented. */\n byEpisodeCount: z.array(bucketSchema),\n byInitiative: z.array(bucketSchema),\n byContextBand: z.array(bucketSchema),\n byWakeCause: z.array(wakePartSchema.extend({ parts: z.array(wakePartSchema) })),\n /** Per wake episode of the episode roles: an arrival and the requests up to the next one, mid-loop deliveries included. */\n wakeEpisodes: wakeEpisodesSchema,\n /** Per role and model, the handoff threshold K that minimises boot plus cache-read cost per request. */\n handoffThreshold: handoffThresholdSchema,\n wakeCauseByGapBand: z.array(cellSchema),\n coldRebuild: z.object({ requests: count, costUsd: z.number(), byGapBandAndCause: z.array(cellSchema) }),\n compactions: z.object({ total: count, manual: count, auto: count, midLoop: count, droppedTokens: count }),\n topSessions: z.array(\n z.object({\n sessionId: z.string(),\n sessionClass: z.string(),\n role: z.string(),\n initiative: z.string(),\n account: z.string(),\n requests: count,\n costUsd: z.number(),\n }),\n ),\n unpricedModels: z.array(z.object({ model: z.string(), requests: count, tokens: count })),\n coverage: z.object({ transcriptsIndexed: count, transcriptsDiscovered: count.nullable(), facetBacklog: count }),\n});\n\nexport type CostReport = z.infer<typeof costReportSchema>;\nexport type CostBucket = z.infer<typeof bucketSchema>;\nexport type WakeCauseBucket = CostReport[\"byWakeCause\"][number];\nexport type WakeGapCell = z.infer<typeof cellSchema>;\nexport type RoleActions = CostReport[\"byAction\"][number];\nexport type MechanicalShare = CostReport[\"mechanicalShare\"];\n\nexport interface CostReportOptions {\n /** ISO timestamp or date, inclusive. Overrides `days`. */\n since?: string;\n /** ISO timestamp or date, exclusive. */\n until?: string;\n /** Window length ending at `until`, or at `now` when `until` is absent. */\n days?: number;\n now?: Date;\n /** Sessions listed in `topSessions`. */\n top?: number;\n /** Transcripts the caller discovered on disk; the graph cannot know this. */\n transcriptsDiscovered?: number;\n /** The extraction version an audit facet must reach to count as current. */\n facetVersion?: number;\n /** Action rules in precedence order; seat-specific rules belong in the caller's config. */\n actionRules?: readonly ActionRule[];\n /** Action classes counted as mechanical in `mechanicalShare`. */\n mechanicalClasses?: readonly ActionClass[];\n /** Report roles whose wakes `wakeEpisodes` cuts into episodes. */\n episodeRoles?: readonly string[];\n /** A wake is no-action when every one of its requests falls in these action classes. */\n noActionClasses?: readonly ActionClass[];\n /** The broker log's lines, read by the caller; its teleport starts give each handoff's exit fill. */\n brokerLogLines?: () => Iterable<string>;\n handoff?: HandoffOptions;\n /** Narrows every request-keyed field to some sessions; absent means all. */\n scope?: ReportScope;\n}\n\n/** AskUserQuestion answers are the human answering, so they count under `human` (decisions Q4). */\nconst HUMAN_CAUSES: readonly string[] = [\"human_typed\", \"ask_user_answer\"];\nconst NONE = \"none\";\nconst DEFAULT_TOP = 10;\nconst EPISODE_COUNT_CAP = 5;\nconst DAY_MS = 86_400_000;\n\ninterface SessionTags {\n sessionClass: SessionClass;\n role: string;\n episodeCount: string;\n initiative: string;\n account: string;\n}\n\ntype TaggedRow = CostRow & SessionTags & { action: ActionClass; bootAction: boolean };\n\n/** Reads the graph and never writes it, so a read-only connection is enough. */\nexport function costReport(db: Db, options: CostReportOptions = {}): CostReport {\n const window = resolveWindow(options);\n const rows = readTaggedRows(db, window, options.actionRules ?? DEFAULT_ACTION_RULES).filter(scopeFilter(db, options.scope));\n return {\n window,\n priceTableVersion: readPriceTableVersion(db),\n totals: { ...sumOf(rows), sessions: new Set(rows.map((row) => row.sessionId)).size, unpricedRequests: rows.filter((row) => !row.priced).length },\n byTokenClass: tokenClasses(rows),\n ...dimensionBuckets(rows),\n byAction: roleActions(rows),\n mechanicalShare: mechanicalShare(rows, options.mechanicalClasses ?? DEFAULT_MECHANICAL_CLASSES),\n byWakeCause: wakeCauses(rows),\n wakeEpisodes: wakeEpisodes(db, window, rows, options),\n handoffThreshold: handoff(db, window, rows, options),\n wakeCauseByGapBand: gapCells(rows),\n coldRebuild: coldRebuild(rows),\n compactions: compactionCounts(readCompactions(db, window)),\n topSessions: topSessions(rows, options.top ?? DEFAULT_TOP),\n unpricedModels: unpricedModels(rows),\n coverage: { ...readCoverage(db, options.facetVersion ?? null), transcriptsDiscovered: options.transcriptsDiscovered ?? null },\n };\n}\n\nfunction readTaggedRows(db: Db, window: ReportWindow, rules: readonly ActionRule[]): TaggedRow[] {\n const costRows = readCostRows(db, window);\n const tags = tagSessions(readSessionContexts(db, [...new Set(costRows.map((row) => row.sessionId))]));\n const calls = readRequestToolCalls(db, window);\n return costRows.map((row) => {\n const requestCalls = calls.get(row.requestId) ?? [];\n return { ...row, ...tags.get(row.sessionId)!, action: classifyRequest(requestCalls, rules), bootAction: isBootAction(requestCalls) };\n });\n}\n\nexport function resolveWindow(options: CostReportOptions): ReportWindow {\n const until = options.until ?? null;\n if (options.since !== undefined) return { since: options.since, until };\n if (options.days === undefined) return { since: null, until };\n const end = until ? Date.parse(until) : (options.now ?? new Date()).getTime();\n return { since: new Date(end - options.days * DAY_MS).toISOString(), until };\n}\n\nexport function tagSessions(contexts: Map<string, SessionContext>): Map<string, SessionTags> {\n const tags = new Map<string, SessionTags>();\n for (const [sessionId, context] of contexts) {\n const classification = classifySession(context.facts);\n const episodes = context.episodes.filter((episode) => episode.heuristic === heuristicFor(classification.sessionClass));\n const worker = { profile: context.facts.origin?.profile, lifetimeMs: context.lifetimeMs, assignments: assignmentCount(episodes) };\n tags.set(sessionId, {\n sessionClass: classification.sessionClass,\n role: sessionRole(classification, worker),\n episodeCount: episodeCountKey(episodes.length),\n initiative: sessionInitiative(context.tasks, context.cwd),\n account: context.account ?? \"unknown\",\n });\n }\n return tags;\n}\n\n/** The worker report's assignment buckets: 1, 2, 3, 4, 5+. */\nfunction episodeCountKey(episodes: number): string {\n if (episodes === 0) return NONE;\n return episodes >= EPISODE_COUNT_CAP ? `${EPISODE_COUNT_CAP}+` : String(episodes);\n}\n\nfunction sumOf(rows: readonly CostRow[]): { requests: number; costUsd: number } {\n return { requests: rows.length, costUsd: rows.reduce((sum, row) => sum + row.costUsd, 0) };\n}\n\nfunction tokenClasses(rows: readonly CostRow[]): CostReport[\"byTokenClass\"] {\n const pick: Record<TokenClass, (row: CostRow) => [number, number]> = {\n input: (row) => [row.inputTokens, row.inputCostUsd],\n cache_read: (row) => [row.cacheReadTokens, row.cacheReadCostUsd],\n cache_write_5m: (row) => [row.cacheWrite5mTokens, row.cacheWrite5mCostUsd],\n cache_write_1h: (row) => [row.cacheWrite1hTokens, row.cacheWrite1hCostUsd],\n output: (row) => [row.outputTokens, row.outputCostUsd],\n };\n return TOKEN_CLASSES.map((tokenClass) => {\n const pairs = rows.map(pick[tokenClass]);\n return { tokenClass, tokens: pairs.reduce((sum, [tokens]) => sum + tokens, 0), costUsd: pairs.reduce((sum, [, cost]) => sum + cost, 0) };\n });\n}\n\nfunction dimensionBuckets(rows: readonly TaggedRow[]) {\n return {\n byAccount: bucketsBy(rows, (row) => row.account),\n byModel: bucketsBy(rows, (row) => row.model),\n byClass: bucketsBy(rows, (row) => row.sessionClass),\n byRole: bucketsBy(rows, (row) => row.role),\n byEpisodeCount: bucketsBy(rows, (row) => row.episodeCount),\n byInitiative: bucketsBy(rows, (row) => row.initiative),\n byContextBand: bucketsBy(rows, (row) => row.contextBand),\n };\n}\n\n/** Roles most expensive first, the same order as `byRole`. */\nfunction roleActions(rows: readonly TaggedRow[]): RoleActions[] {\n return [...groupRows(rows, (row) => row.role)]\n .map(([role, members]) => ({ key: role, costUsd: sumOf(members).costUsd, buckets: bucketsBy(members, (row) => row.action) }))\n .sort(byCostThenKey)\n .map(({ key, buckets }) => ({ role: key, buckets }));\n}\n\nfunction mechanicalShare(rows: readonly TaggedRow[], classes: readonly ActionClass[]): MechanicalShare {\n const isMechanical = (row: TaggedRow) => classes.includes(row.action);\n const shareOf = (members: readonly TaggedRow[]) => {\n const costUsd = sumOf(members.filter(isMechanical)).costUsd;\n return { costUsd, share: ratio(costUsd, sumOf(members).costUsd) };\n };\n const byRole = [...groupRows(rows, (row) => row.role)]\n .map(([role, members]) => ({ role, ...shareOf(members) }))\n .sort((a, b) => b.costUsd - a.costUsd || a.role.localeCompare(b.role));\n return { classes: [...classes], ...shareOf(rows), byRole };\n}\n\nfunction ratio(part: number, whole: number): number {\n return whole > 0 ? Math.min(part / whole, 1) : 0;\n}\n\n/** Most expensive first; ties by key so the report is stable. */\nfunction bucketsBy<T extends CostRow>(rows: readonly T[], keyOf: (row: T) => string): CostBucket[] {\n const groups = groupRows(rows, keyOf);\n return [...groups]\n .map(([key, members]) => ({ key, ...sumOf(members), sessions: new Set(members.map((row) => row.sessionId)).size }))\n .sort(byCostThenKey);\n}\n\nfunction groupRows<T>(rows: readonly T[], keyOf: (row: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = keyOf(row);\n const members = groups.get(key);\n if (members) members.push(row);\n else groups.set(key, [row]);\n }\n return groups;\n}\n\nfunction byCostThenKey(a: { key: string; costUsd: number }, b: { key: string; costUsd: number }): number {\n return b.costUsd - a.costUsd || a.key.localeCompare(b.key);\n}\n\nfunction wakeCauses(rows: readonly CostRow[]): WakeCauseBucket[] {\n const causeOf = (row: CostRow) => row.wakeCause ?? NONE;\n const groupOf = (row: CostRow) => (HUMAN_CAUSES.includes(causeOf(row)) ? \"human\" : causeOf(row));\n return [...groupRows(rows, groupOf)]\n .map(([key, members]) => ({\n ...wakePart(key, members),\n parts: key === \"human\" ? [...groupRows(members, causeOf)].map(([cause, part]) => wakePart(cause, part)).sort(byCostThenKey) : [],\n }))\n .sort(byCostThenKey);\n}\n\nfunction wakeEpisodes(db: Db, window: ReportWindow, rows: readonly TaggedRow[], options: CostReportOptions): WakeEpisodes {\n const roles = options.episodeRoles ?? DEFAULT_EPISODE_ROLES;\n const noActionClasses = options.noActionClasses ?? DEFAULT_NO_ACTION_CLASSES;\n const members = rows.filter((row) => roles.includes(row.role));\n const sessionIds = [...new Set(members.map((row) => row.sessionId))];\n const eventOf = readRequestEvents(db, window, sessionIds);\n const requests = members.map((row) => ({ costUsd: row.costUsd, action: row.action, eventKey: eventOf.get(row.requestId) ?? null }));\n const episodes = buildWakeEpisodes(readWakeEvents(db, window, sessionIds), requests, episodeNames(readAgentNames(db)), noActionClasses);\n return summarizeWakeEpisodes(episodes, requests, roles, noActionClasses);\n}\n\nfunction handoff(db: Db, window: ReportWindow, rows: readonly TaggedRow[], options: CostReportOptions): HandoffThreshold {\n const inWindow = (ts: string) => (window.since === null || ts >= window.since) && (window.until === null || ts < window.until);\n const teleports = parseTeleportEvents(options.brokerLogLines?.() ?? []).filter((event) => inWindow(event.ts));\n const requests = rows\n .filter((row) => !row.isSidechain)\n .map((row) => ({\n sessionId: row.sessionId,\n role: row.role,\n model: row.model,\n ts: row.ts,\n fill: row.contextTokens,\n tokens: { inputTokens: row.inputTokens, cacheReadTokens: row.cacheReadTokens, cacheCreation5mTokens: row.cacheWrite5mTokens, cacheCreation1hTokens: row.cacheWrite1hTokens, outputTokens: row.outputTokens },\n bootAction: row.bootAction,\n }));\n return handoffThreshold(requests, teleports, readAgentSessions(db), options.handoff);\n}\n\nfunction wakePart(key: string, rows: readonly CostRow[]) {\n const midLoop = rows.filter((row) => row.wakeDelivery === \"mid_loop\");\n const sessions = new Set(rows.map((row) => row.sessionId)).size;\n return { key, ...sumOf(rows), sessions, midLoopRequests: midLoop.length, midLoopCostUsd: sumOf(midLoop).costUsd };\n}\n\nfunction gapCells(rows: readonly CostRow[]): WakeGapCell[] {\n const keyOf = (row: CostRow) => JSON.stringify([row.wakeCause ?? NONE, row.gapBand ?? NONE]);\n return [...groupRows(rows, keyOf)]\n .map(([key, members]) => {\n const [wakeCause, gapBand] = JSON.parse(key) as [string, string];\n return { wakeCause, gapBand, ...sumOf(members) };\n })\n .sort((a, b) => b.costUsd - a.costUsd || a.wakeCause.localeCompare(b.wakeCause) || a.gapBand.localeCompare(b.gapBand));\n}\n\nfunction coldRebuild(rows: readonly CostRow[]): CostReport[\"coldRebuild\"] {\n const cold = rows.filter((row) => row.isCold);\n return { ...sumOf(cold), byGapBandAndCause: gapCells(cold) };\n}\n\nfunction compactionCounts(rows: readonly CompactionRow[]): CostReport[\"compactions\"] {\n return {\n total: rows.length,\n manual: rows.filter((row) => row.trigger === \"manual\").length,\n auto: rows.filter((row) => row.trigger === \"auto\").length,\n midLoop: rows.filter((row) => row.midLoop).length,\n droppedTokens: rows.reduce((sum, row) => sum + (row.droppedTokens ?? 0), 0),\n };\n}\n\nfunction topSessions(rows: readonly TaggedRow[], top: number): CostReport[\"topSessions\"] {\n return [...groupRows(rows, (row) => row.sessionId)]\n .map(([sessionId, members]) => {\n const { sessionClass, role, initiative, account } = members[0]!;\n return { sessionId, sessionClass, role, initiative, account, ...sumOf(members) };\n })\n .sort((a, b) => b.costUsd - a.costUsd || a.sessionId.localeCompare(b.sessionId))\n .slice(0, top);\n}\n\nfunction unpricedModels(rows: readonly CostRow[]): CostReport[\"unpricedModels\"] {\n const unpriced = rows.filter((row) => !row.priced);\n return [...groupRows(unpriced, (row) => row.model)]\n .map(([model, members]) => ({ model, requests: members.length, tokens: members.reduce((sum, row) => sum + tokensOf(row), 0) }))\n .sort((a, b) => b.tokens - a.tokens || a.model.localeCompare(b.model));\n}\n\nfunction tokensOf(row: CostRow): number {\n return row.inputTokens + row.cacheReadTokens + row.cacheWrite5mTokens + row.cacheWrite1hTokens + row.outputTokens;\n}\n","import { AUDIT_FACET, EPISODE_TABLE, FACET_TABLE, KIT } from \"@titan-design/session-graph\";\nimport type { Db } from \"@titan-design/store-sqlite\";\nimport type { SessionFacts } from \"./classify-session.js\";\nimport type { TaskInitiative } from \"./initiative.js\";\n\n/** ISO bounds on request `ts`: `since` inclusive, `until` exclusive, null for open. */\nexport interface ReportWindow {\n since: string | null;\n until: string | null;\n}\n\n/** One deduplicated, priced request as the `request_cost` view returns it. */\nexport interface CostRow {\n sessionId: string;\n requestId: string;\n ts: string;\n model: string;\n /** Tokens in context at the request. */\n contextTokens: number;\n isSidechain: boolean;\n inputTokens: number;\n cacheReadTokens: number;\n cacheWrite5mTokens: number;\n cacheWrite1hTokens: number;\n outputTokens: number;\n inputCostUsd: number;\n cacheReadCostUsd: number;\n cacheWrite5mCostUsd: number;\n cacheWrite1hCostUsd: number;\n outputCostUsd: number;\n costUsd: number;\n priced: boolean;\n isCold: boolean;\n contextBand: string;\n gapBand: string | null;\n wakeCause: string | null;\n wakeDelivery: string | null;\n}\n\n/** What the report needs about one session beyond its requests. */\nexport interface SessionContext {\n facts: SessionFacts;\n cwd: string | null;\n account: string | null;\n tasks: TaskInitiative[];\n /** First to last main-thread request over the whole session, not just the window. */\n lifetimeMs: number;\n /** Stored episode rows of every heuristic, in episode order. */\n episodes: StoredEpisode[];\n}\n\nexport interface StoredEpisode {\n heuristic: string;\n openedBy: string;\n}\n\nexport interface CompactionRow {\n trigger: string | null;\n midLoop: boolean;\n droppedTokens: number | null;\n}\n\nconst IN_WINDOW = \"(@since IS NULL OR ts >= @since) AND (@until IS NULL OR ts < @until)\";\nconst IN_SESSIONS = \"session_id IN (SELECT value FROM json_each(@ids))\";\n\n// The 5m write column mirrors the view: a split-less write is billed at the 5m rate.\nconst COST_ROWS = `\n SELECT session_id AS sessionId, request_id AS requestId, ts, model, COALESCE(context_tokens, 0) AS contextTokens, is_sidechain AS isSidechain,\n input_tokens AS inputTokens, cache_read_tokens AS cacheReadTokens,\n CASE WHEN cache_creation_5m + cache_creation_1h = 0 THEN cache_creation_tokens ELSE cache_creation_5m END AS cacheWrite5mTokens,\n cache_creation_1h AS cacheWrite1hTokens, output_tokens AS outputTokens,\n input_cost_usd AS inputCostUsd, cache_read_cost_usd AS cacheReadCostUsd,\n cache_write_5m_cost_usd AS cacheWrite5mCostUsd, cache_write_1h_cost_usd AS cacheWrite1hCostUsd,\n output_cost_usd AS outputCostUsd, cost_usd AS costUsd, priced, is_cold AS isCold,\n context_band AS contextBand, gap_band AS gapBand, wake_cause AS wakeCause, wake_delivery AS wakeDelivery\n FROM request_cost WHERE ${IN_WINDOW}\n`;\n\nexport function readCostRows(db: Db, window: ReportWindow): CostRow[] {\n type Row = Omit<CostRow, \"priced\" | \"isCold\" | \"isSidechain\"> & { priced: number; isCold: number; isSidechain: number | null };\n const rows = db.prepare(COST_ROWS).all(window) as Row[];\n return rows.map((row) => ({ ...row, priced: row.priced === 1, isCold: row.isCold === 1, isSidechain: row.isSidechain === 1 }));\n}\n\nexport function readCompactions(db: Db, window: ReportWindow): CompactionRow[] {\n const sql = `SELECT trigger, mid_loop AS midLoop, dropped_tokens AS droppedTokens FROM compaction WHERE ${IN_WINDOW}`;\n const rows = db.prepare(sql).all(window) as (Omit<CompactionRow, \"midLoop\"> & { midLoop: number | null })[];\n return rows.map((row) => ({ ...row, midLoop: row.midLoop === 1 }));\n}\n\n/** The graph's own price version, which is what `request_cost` priced with; null before any price row exists. */\nexport function readPriceTableVersion(db: Db): number | null {\n return (db.prepare(\"SELECT MAX(table_version) AS version FROM price\").get() as { version: number | null }).version;\n}\n\n/** Indexed transcripts, and those whose audit facet is missing or older than `facetVersion`. */\nexport function readCoverage(db: Db, facetVersion: number | null): { transcriptsIndexed: number; facetBacklog: number } {\n const indexed = db.prepare(`SELECT COUNT(*) AS n FROM \"${KIT.watermark}\"`).get() as { n: number };\n const backlog = db\n .prepare(\n `SELECT COUNT(*) AS n FROM \"${KIT.watermark}\" t LEFT JOIN \"${FACET_TABLE}\" f\n ON f.transcript_id = t.source_id AND f.facet = @facet AND (@version IS NULL OR f.version >= @version)\n WHERE f.transcript_id IS NULL`,\n )\n .get({ facet: AUDIT_FACET, version: facetVersion }) as { n: number };\n return { transcriptsIndexed: indexed.n, facetBacklog: backlog.n };\n}\n\n/** An arrival that opens a wake episode: a turn-start record or a mid-loop `queued_command` delivery. */\nexport interface WakeEventRow {\n key: string;\n sessionId: string;\n cause: string;\n delivery: string;\n fromName: string | null;\n /** The same `msg_id` reached more than one session. */\n broadcast: boolean;\n}\n\n/** One agent-chat identity: the name a session carries and how it came to carry it. */\nexport interface AgentNameRow {\n sessionId: string;\n agentName: string;\n originKind: string | null;\n profile: string | null;\n}\n\nconst EPISODE_DELIVERIES = \"('turn_start', 'mid_loop')\";\n\n// A record with several blocks is one event; its last block decides, as the request rollup does.\nconst WAKE_EVENTS = `\n WITH event AS (\n SELECT transcript_id, byte_offset, MAX(block_index) AS block_index FROM inbound\n WHERE ${IN_SESSIONS} AND ${IN_WINDOW} AND delivery IN ${EPISODE_DELIVERIES}\n GROUP BY transcript_id, byte_offset\n ), fanout AS (\n SELECT msg_id, COUNT(DISTINCT session_id) AS receivers FROM inbound\n WHERE msg_id IN (SELECT i.msg_id FROM event JOIN inbound i USING (transcript_id, byte_offset, block_index))\n GROUP BY msg_id\n )\n SELECT i.transcript_id || ':' || i.byte_offset AS key, i.session_id AS sessionId, i.cause, i.delivery,\n i.from_name AS fromName, COALESCE(f.receivers, 1) > 1 AS broadcast\n FROM event JOIN inbound i USING (transcript_id, byte_offset, block_index)\n LEFT JOIN fanout f ON f.msg_id = i.msg_id\n ORDER BY i.transcript_id, i.byte_offset`;\n\nconst REQUEST_EVENTS = `\n SELECT d.request_id AS requestId, d.transcript_id || ':' || (\n SELECT MAX(i.byte_offset) FROM inbound i\n WHERE i.transcript_id = d.transcript_id AND i.session_id = d.session_id AND i.byte_offset < d.byte_offset\n AND i.delivery IN ${EPISODE_DELIVERIES}) AS eventKey\n FROM request_dedup d WHERE d.${IN_SESSIONS} AND (@since IS NULL OR d.ts >= @since) AND (@until IS NULL OR d.ts < @until)`;\n\nexport function readWakeEvents(db: Db, window: ReportWindow, sessionIds: readonly string[]): WakeEventRow[] {\n const rows = db.prepare(WAKE_EVENTS).all({ ...window, ids: JSON.stringify(sessionIds) }) as (Omit<WakeEventRow, \"broadcast\"> & { broadcast: number })[];\n return rows.map((row) => ({ ...row, broadcast: row.broadcast === 1 }));\n}\n\n/** The event each request in the window follows, keyed by `request_id`; null before a transcript's first event. */\nexport function readRequestEvents(db: Db, window: ReportWindow, sessionIds: readonly string[]): Map<string, string | null> {\n const rows = db.prepare(REQUEST_EVENTS).all({ ...window, ids: JSON.stringify(sessionIds) }) as { requestId: string; eventKey: string | null }[];\n return new Map(rows.map((row) => [row.requestId, row.eventKey]));\n}\n\nexport function readAgentNames(db: Db): AgentNameRow[] {\n const sql = `SELECT session_id AS sessionId, agent_name AS agentName, origin_kind AS originKind, profile FROM session_origin WHERE agent_name IS NOT NULL`;\n return db.prepare(sql).all() as AgentNameRow[];\n}\n\n/** Each agent-chat agent id to the sessions it ran as; the broker log names agents by id. */\nexport function readAgentSessions(db: Db): Map<string, string[]> {\n const sql = `SELECT agent_id AS agentId, session_id AS sessionId FROM session_origin WHERE agent_id IS NOT NULL`;\n const sessions = new Map<string, string[]>();\n for (const row of db.prepare(sql).all() as { agentId: string; sessionId: string }[]) sessions.set(row.agentId, [...(sessions.get(row.agentId) ?? []), row.sessionId]);\n return sessions;\n}\n\nexport function readSessionContexts(db: Db, sessionIds: readonly string[]): Map<string, SessionContext> {\n const ids = JSON.stringify(sessionIds);\n const contexts = new Map<string, SessionContext>(sessionIds.map((id) => [id, emptyContext()]));\n addSessionRows(db, ids, contexts);\n addOrigins(db, ids, contexts);\n addInbounds(db, ids, contexts);\n addSignals(db, ids, contexts);\n addTaskInitiatives(db, ids, contexts);\n addLifetimes(db, ids, contexts);\n addEpisodes(db, ids, contexts);\n return contexts;\n}\n\nfunction emptyContext(): SessionContext {\n return { facts: { inboundKinds: [], signalKinds: [], humanTurnCount: 0 }, cwd: null, account: null, tasks: [], lifetimeMs: 0, episodes: [] };\n}\n\nfunction addSessionRows(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, start_type AS startType, cwd, seed_prompt AS seedPrompt, account FROM session WHERE ${IN_SESSIONS}`;\n type Row = { sessionId: string; startType: string | null; cwd: string | null; seedPrompt: string | null; account: string | null };\n for (const row of db.prepare(sql).all({ ids }) as Row[]) {\n const context = contexts.get(row.sessionId)!;\n context.cwd = row.cwd;\n context.account = row.account;\n context.facts.startType = row.startType;\n context.facts.firstUserText = row.seedPrompt;\n }\n}\n\nfunction addOrigins(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, depth, parent_name AS parentName, origin_kind AS originKind, profile FROM session_origin WHERE ${IN_SESSIONS}`;\n type Row = { sessionId: string; depth: number | null; parentName: string | null; originKind: string | null; profile: string | null };\n for (const { sessionId, depth, ...origin } of db.prepare(sql).all({ ids }) as Row[]) {\n contexts.get(sessionId)!.facts.origin = { ...origin, depth: depth ?? 0 };\n }\n}\n\nfunction addInbounds(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, cause, SUM(delivery = 'turn_start') AS turnStarts FROM inbound WHERE ${IN_SESSIONS} GROUP BY session_id, cause`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; cause: string; turnStarts: number }[]) {\n const facts = contexts.get(row.sessionId)!.facts;\n facts.inboundKinds = [...(facts.inboundKinds ?? []), row.cause];\n if (row.cause === \"human_typed\") facts.humanTurnCount = row.turnStarts;\n }\n}\n\nfunction addSignals(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT DISTINCT session_id AS sessionId, signal FROM session_signal WHERE ${IN_SESSIONS}`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; signal: string }[]) {\n const facts = contexts.get(row.sessionId)!.facts;\n facts.signalKinds = [...(facts.signalKinds ?? []), row.signal];\n }\n}\n\nfunction addTaskInitiatives(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `\n SELECT substr(e.source_ref, 9) AS sessionId, t.initiative, COUNT(*) AS edges\n FROM \"${KIT.edge}\" e JOIN task t ON t.task_ref = e.target_ref\n WHERE e.relation = 'ran' AND e.t_expired IS NULL AND t.initiative IS NOT NULL\n AND e.source_ref IN (SELECT 'session:' || value FROM json_each(@ids))\n GROUP BY e.source_ref, t.initiative`;\n for (const row of db.prepare(sql).all({ ids }) as ({ sessionId: string } & TaskInitiative)[]) {\n contexts.get(row.sessionId)!.tasks.push({ initiative: row.initiative, edges: row.edges });\n }\n}\n\nfunction addLifetimes(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, MIN(ts) AS first, MAX(ts) AS last FROM request_dedup WHERE ${IN_SESSIONS} AND is_sidechain = 0 GROUP BY session_id`;\n for (const row of db.prepare(sql).all({ ids }) as { sessionId: string; first: string; last: string }[]) {\n contexts.get(row.sessionId)!.lifetimeMs = Date.parse(row.last) - Date.parse(row.first);\n }\n}\n\nfunction addEpisodes(db: Db, ids: string, contexts: Map<string, SessionContext>): void {\n const sql = `SELECT session_id AS sessionId, heuristic, opened_by AS openedBy FROM \"${EPISODE_TABLE}\" WHERE ${IN_SESSIONS} ORDER BY session_id, heuristic, episode_index`;\n for (const { sessionId, ...episode } of db.prepare(sql).all({ ids }) as ({ sessionId: string } & StoredEpisode)[]) {\n contexts.get(sessionId)!.episodes.push(episode);\n }\n}\n","import { replaceEpisodes, type EpisodeRow, type SessionGraph } from \"@titan-design/session-graph\";\nimport type { Db } from \"@titan-design/store-sqlite\";\nimport { classifySession, type SessionClass } from \"./classify-session.js\";\nimport { readSessionContexts } from \"./cost-report-queries.js\";\n\n/** Two rule sets on purpose (design section 18): workers segment by assignment, coordinators by work phase. */\nexport type Heuristic = \"worker-v1\" | \"coordinator-v1\";\nexport const HEURISTIC_VERSIONS: Readonly<Record<Heuristic, number>> = { \"worker-v1\": 1, \"coordinator-v1\": 1 };\n\nexport interface EpisodeRequest {\n offset: number;\n ts: string;\n transcriptId: number;\n contextTokens: number;\n wakeCause: string | null;\n}\nexport interface EpisodeInbound {\n offset: number;\n ts: string;\n transcriptId: number;\n cause: string;\n}\nexport interface EpisodeSignal {\n offset: number;\n ts: string;\n transcriptId: number;\n signal: string;\n}\nexport interface EpisodeInput {\n requests: readonly EpisodeRequest[];\n inbounds: readonly EpisodeInbound[];\n signals: readonly EpisodeSignal[];\n /** An agent-chat spawn has a brief; anything else opens at `session_start`. */\n spawned: boolean;\n}\n\nconst MINUTE_MS = 60_000;\nexport const IDLE_GAP_MS = 30 * MINUTE_MS;\nexport const CHANNEL_CLUSTER_MS = 10 * MINUTE_MS;\nexport const COORDINATOR_MIN_EPISODE_REQUESTS = 8;\nexport const COORDINATOR_MERGE_DEDUPE_REQUESTS = 15;\nexport const COORDINATOR_WAVE_QUIET_REQUESTS = 15;\nexport const CONTEXT_RESET_TOKENS = 20_000;\nconst DELIVERABLE_SIGNALS = new Set([\"status_report\", \"pr_create\", \"commit\", \"doc_written\", \"task_wrap\"]);\nconst ASSIGNMENT_OPENERS = new Set([\"brief\", \"channel_followup\"]);\n\n/** Pure: the same rows always cut the same way. Rows come back in episode order. */\nexport function buildEpisodes(input: EpisodeInput, heuristic: Heuristic): EpisodeRow[] {\n return heuristic === \"worker-v1\" ? workerEpisodes(input) : coordinatorEpisodes(input);\n}\n\n/** Workers are segmented; human sessions get the coordinator rule; headless runs get none. */\nexport function heuristicFor(sessionClass: SessionClass): Heuristic | null {\n if (sessionClass === \"agent_spawned\") return \"worker-v1\";\n if (sessionClass === \"human_interactive\") return \"coordinator-v1\";\n return null;\n}\n\n/** The worker report's `n_assignments`: episodes an assignment opened, which is what the standing-peer overlay counts. */\nexport function assignmentCount(rows: readonly Pick<EpisodeRow, \"openedBy\">[]): number {\n return rows.filter((row) => ASSIGNMENT_OPENERS.has(row.openedBy)).length;\n}\n\n// ---------------------------------------------------------------- worker-v1\n\ntype Event =\n | { kind: \"request\"; offset: number; ts: string; ms: number; transcriptId: number }\n | { kind: \"inbound\"; offset: number; ts: string; ms: number; transcriptId: number; cause: string }\n | { kind: \"signal\"; offset: number; ts: string; ms: number; transcriptId: number; signal: string };\n\ninterface Draft {\n row: EpisodeRow;\n hasRequest: boolean;\n}\n\ninterface WorkerState {\n drafts: Draft[];\n lastRequestMs: number | null;\n lastChannelMs: number | null;\n}\n\n/** worker-forensics-report.md section 5 and wf_analyze.py:241-251, with the status-report trigger from design section 9. */\nfunction workerEpisodes(input: EpisodeInput): EpisodeRow[] {\n const state: WorkerState = { drafts: [], lastRequestMs: null, lastChannelMs: null };\n for (const event of timeline(input)) {\n const current = state.drafts.at(-1);\n const reason = current ? workerBoundary(event, current, state) : input.spawned ? \"brief\" : \"session_start\";\n if (reason && (!current || current.hasRequest)) state.drafts.push(openDraft(event, reason, state.drafts.length));\n absorb(state.drafts.at(-1)!, event);\n if (event.kind === \"request\") state.lastRequestMs = event.ms;\n if (isChannel(event)) state.lastChannelMs = event.ms;\n }\n return state.drafts.map((draft) => draft.row);\n}\n\nfunction workerBoundary(event: Event, current: Draft, state: WorkerState): string | null {\n if (event.kind === \"request\" && state.lastRequestMs !== null && event.ms - state.lastRequestMs >= IDLE_GAP_MS) return \"idle_gap\";\n if (!isChannel(event)) return null;\n const startsCluster = state.lastChannelMs === null || event.ms - state.lastChannelMs > CHANNEL_CLUSTER_MS;\n return startsCluster && current.row.firstStatusOffset != null ? \"channel_followup\" : null;\n}\n\nfunction isChannel(event: Event): boolean {\n return event.kind === \"inbound\" && event.cause === \"channel_message\";\n}\n\nfunction openDraft(event: Event, openedBy: string, episodeIndex: number): Draft {\n const assignment = ASSIGNMENT_OPENERS.has(openedBy) && event.kind === \"inbound\" ? event.offset : null;\n const row: EpisodeRow = {\n episodeIndex,\n heuristicVersion: HEURISTIC_VERSIONS[\"worker-v1\"],\n startedAt: event.ts,\n endedAt: event.ts,\n startOffset: event.offset,\n endOffset: event.offset,\n openedBy,\n startTranscriptId: event.transcriptId,\n endTranscriptId: event.transcriptId,\n assignmentOffset: assignment,\n firstDeliverableOffset: null,\n firstDeliverableSignal: null,\n firstStatusOffset: null,\n };\n return { row, hasRequest: false };\n}\n\n/** The first commit is recorded as a deliverable but not as a report: commit fires early for implementers (221 of 411). */\nfunction absorb(draft: Draft, event: Event): void {\n draft.row.endedAt = event.ts;\n draft.row.endOffset = event.offset;\n draft.row.endTranscriptId = event.transcriptId;\n if (event.kind === \"request\") draft.hasRequest = true;\n if (event.kind !== \"signal\") return;\n if (draft.row.firstDeliverableOffset == null && DELIVERABLE_SIGNALS.has(event.signal)) {\n draft.row.firstDeliverableOffset = event.offset;\n draft.row.firstDeliverableSignal = event.signal;\n }\n if (draft.row.firstStatusOffset == null && event.signal === \"status_report\") draft.row.firstStatusOffset = event.offset;\n}\n\n/**\n * Offsets only order events inside one transcript, so time orders first, then the transcript a\n * session resumed into, then the offset breaks ties within it.\n */\nfunction timeline(input: EpisodeInput): Event[] {\n const events: Event[] = [\n ...input.requests.map((r) => ({ kind: \"request\" as const, offset: r.offset, ts: r.ts, ms: Date.parse(r.ts), transcriptId: r.transcriptId })),\n ...input.inbounds.map((i) => ({ kind: \"inbound\" as const, offset: i.offset, ts: i.ts, ms: Date.parse(i.ts), transcriptId: i.transcriptId, cause: i.cause })),\n ...input.signals.map((s) => ({ kind: \"signal\" as const, offset: s.offset, ts: s.ts, ms: Date.parse(s.ts), transcriptId: s.transcriptId, signal: s.signal })),\n ];\n return events.sort((a, b) => a.ms - b.ms || a.transcriptId - b.transcriptId || a.offset - b.offset);\n}\n\n// ---------------------------------------------------------------- coordinator-v1\n\ninterface Turn {\n request: EpisodeRequest;\n ms: number;\n signals: Set<string>;\n}\n\ninterface Boundary {\n at: number;\n reason: string;\n}\n\n/** coordinator-forensics-report.md section 1, ported from co_analyze.py `segment` with `merge_lag` 0. */\nfunction coordinatorEpisodes(input: EpisodeInput): EpisodeRow[] {\n const turns = toTurns(input);\n if (turns.length === 0) return [];\n const opens = [{ at: 0, reason: \"session_start\" }, ...dropShort(coordinatorBoundaries(turns), turns.length)];\n return opens.map((open, index) => {\n const first = turns[open.at]!.request;\n const last = turns[(opens[index + 1]?.at ?? turns.length) - 1]!.request;\n return {\n episodeIndex: index,\n heuristicVersion: HEURISTIC_VERSIONS[\"coordinator-v1\"],\n startedAt: first.ts,\n endedAt: last.ts,\n startOffset: first.offset,\n endOffset: last.offset,\n startTranscriptId: first.transcriptId,\n endTranscriptId: last.transcriptId,\n openedBy: open.reason,\n };\n });\n}\n\nfunction coordinatorBoundaries(turns: readonly Turn[]): Boundary[] {\n const bounds: Boundary[] = [];\n let spawnedSince = false;\n let lastMerge = -Infinity;\n for (let i = 1; i < turns.length; i++) {\n const reason = coordinatorTrigger(turns, i, lastMerge) ?? (spawnedSince && waveComplete(turns, i) ? \"spawn_wave_complete\" : null);\n if (turns[i - 1]!.signals.has(\"pr_merge\")) lastMerge = i;\n if (reason) {\n bounds.push({ at: i, reason });\n spawnedSince = false;\n }\n if (turns[i]!.signals.has(\"agent_spawn\")) spawnedSince = true;\n }\n return bounds;\n}\n\n/** Checked in the source's order; the first that fires names the boundary. */\nfunction coordinatorTrigger(turns: readonly Turn[], i: number, lastMerge: number): string | null {\n const [a, b] = [turns[i - 1]!, turns[i]!];\n if (b.ms - a.ms >= IDLE_GAP_MS) return \"idle_gap\";\n if (a.signals.has(\"pr_merge\") && i - lastMerge > COORDINATOR_MERGE_DEDUPE_REQUESTS) return \"pr_merge\";\n if (a.signals.has(\"task_wrap\") || a.signals.has(\"task_done\")) return \"task_wrap\";\n const drop = a.request.contextTokens - b.request.contextTokens;\n if (a.request.contextTokens > 0 && drop > CONTEXT_RESET_TOKENS) return \"context_reset\";\n return null;\n}\n\n/** The last agent-chat traffic before a quiet run; the source also counted any agent-chat tool call, which only reaches the graph as `chat_send` or `agent_spawn`. */\nfunction waveComplete(turns: readonly Turn[], i: number): boolean {\n return hasChatTraffic(turns[i - 1]!) && !turns.slice(i, i + COORDINATOR_WAVE_QUIET_REQUESTS).some(hasChatTraffic);\n}\n\nfunction hasChatTraffic(turn: Turn): boolean {\n return turn.request.wakeCause === \"channel_message\" || turn.signals.has(\"chat_send\") || turn.signals.has(\"agent_spawn\");\n}\n\n/** No episode shorter than the minimum, at either end of the session. */\nfunction dropShort(bounds: readonly Boundary[], total: number): Boundary[] {\n const kept: Boundary[] = [];\n let last = 0;\n for (const bound of bounds) {\n if (bound.at - last < COORDINATOR_MIN_EPISODE_REQUESTS || total - bound.at < COORDINATOR_MIN_EPISODE_REQUESTS) continue;\n kept.push(bound);\n last = bound.at;\n }\n return kept;\n}\n\n/** A signal belongs to the latest request at or before it; one before any request goes to the first. */\nfunction toTurns(input: EpisodeInput): Turn[] {\n const turns = input.requests\n .map((request) => ({ request, ms: Date.parse(request.ts), signals: new Set<string>() }))\n .sort((a, b) => a.ms - b.ms || a.request.transcriptId - b.request.transcriptId || a.request.offset - b.request.offset);\n for (const signal of input.signals) ownerOf(turns, signal)?.signals.add(signal.signal);\n return turns;\n}\n\nfunction ownerOf(turns: readonly Turn[], signal: EpisodeSignal): Turn | undefined {\n const ms = Date.parse(signal.ts);\n for (let i = turns.length - 1; i >= 0; i--) {\n const turn = turns[i]!;\n if (turn.ms < ms || (turn.ms === ms && turn.request.offset <= signal.offset)) return turn;\n }\n return turns[0];\n}\n\n// ---------------------------------------------------------------- graph I/O\n\nconst IN_SESSION = \"session_id = ?\";\n\n/**\n * `request_dedup` for one session without ranking every request: SQLite cannot push the session filter\n * through the view's window. Copies of a request can sit in other sessions, so the rank still covers\n * every copy of each request id the session holds.\n */\nconst SESSION_REQUEST_DEDUP = `\n SELECT * FROM (\n SELECT r.*, ROW_NUMBER() OVER (PARTITION BY r.request_id ORDER BY r.ts, r.transcript_id) AS copy_rank\n FROM request r WHERE r.request_id IN (SELECT request_id FROM request WHERE session_id = @sessionId)\n ) WHERE copy_rank = 1 AND session_id = @sessionId`;\n\n/** Main-thread requests only: a sidechain's requests belong to its subagent, not to the session's episodes. */\nexport const EPISODE_REQUESTS_SQL = `\n SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, context_tokens AS contextTokens, wake_cause AS wakeCause\n FROM (${SESSION_REQUEST_DEDUP}) WHERE is_sidechain = 0`;\n\nexport function readEpisodeInput(db: Db, sessionId: string, spawned: boolean): EpisodeInput {\n const requests = db.prepare(EPISODE_REQUESTS_SQL).all({ sessionId }) as EpisodeRequest[];\n const inbounds = db\n .prepare(`SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, cause FROM inbound WHERE ${IN_SESSION}`)\n .all(sessionId) as EpisodeInbound[];\n const signals = db\n .prepare(`SELECT byte_offset AS offset, ts, transcript_id AS transcriptId, signal FROM session_signal WHERE ${IN_SESSION}`)\n .all(sessionId) as EpisodeSignal[];\n return { requests, inbounds, signals, spawned };\n}\n\nexport interface WrittenEpisodes {\n sessionId: string;\n heuristic: Heuristic;\n episodes: number;\n}\n\n/** Segments each session with its class's heuristic and replaces that heuristic's rows. Headless sessions are skipped. */\nexport function writeEpisodes(graph: SessionGraph, sessionIds: readonly string[]): WrittenEpisodes[] {\n const written: WrittenEpisodes[] = [];\n for (const [sessionId, context] of readSessionContexts(graph.db, sessionIds)) {\n const { sessionClass } = classifySession(context.facts);\n const heuristic = heuristicFor(sessionClass);\n if (!heuristic) continue;\n const rows = buildEpisodes(readEpisodeInput(graph.db, sessionId, sessionClass === \"agent_spawned\"), heuristic);\n written.push({ sessionId, heuristic, episodes: replaceEpisodes(graph, sessionId, heuristic, rows) });\n }\n return written;\n}\n","import { z } from \"zod\";\nimport { priceRequest, type RequestTokens } from \"./price-request.js\";\nimport { PRICE_TABLE, findPrice, type PriceRow } from \"./prices.js\";\nimport type { ActionCall } from \"./turn-action.js\";\n\n/** A dispatch or a send; with any file write, the first such request ends a session's boot. */\nexport const BOOT_TOOL = /(agent_(spawn|resume)|chat_(send|broadcast))$/;\n\n/** The charter's `teleport_k` and `retire_k` at the time of the TP-499 plan; callers pass their own. */\nexport const DEFAULT_CONFIGURED_K: readonly number[] = [170_000, 250_000];\nexport const DEFAULT_K_SWEEP = { fromK: 20_000, toK: 1_000_000, stepK: 5_000 } as const;\nexport const DEFAULT_REVIEWER_ROLE = \"worker:reviewer\";\nexport const DEFAULT_STANDING_ROLE = \"worker:standing_peer\";\nexport const DEFAULT_REVIEWER_PRS = 10;\n/** The broker logs this when a seat starts handing over; `from` is the outgoing agent id. */\nexport const TELEPORT_EVENT = \"teleport_started\";\n\nconst MTOK = 1_000_000;\nconst count = z.number().int().nonnegative();\nconst kCostSchema = z.object({ k: count, costPerRequest: z.number().nullable(), deltaPerRequest: z.number().nullable() });\nconst sweepResultSchema = z.object({ bestK: count.nullable(), bestCostPerRequest: z.number().nullable(), atConfigured: z.array(kCostSchema) });\nconst paramsSchema = z.object({ bootCostUsd: z.number(), bootFill: z.number(), growthPerRequest: z.number(), readPricePerMTok: z.number() });\n\nconst sessionSchema = paramsSchema.extend({\n sessionId: z.string(),\n role: z.string(),\n model: z.string(),\n requests: count,\n bootRequests: count,\n exitFill: count,\n /** Timestamp of the session's last request; orders reviewer cohorts by recency. */\n lastTs: z.string(),\n bestK: count.nullable(),\n});\nconst cohortSchema = paramsSchema.extend({\n role: z.string(),\n model: z.string(),\n sessions: count,\n ...sweepResultSchema.shape,\n /** The same sweep when only half the boot is overhead the next session pays again. */\n halfBoot: sweepResultSchema,\n});\nconst teleportSchema = z.object({\n ts: z.string(),\n name: z.string().nullable(),\n sessionId: z.string(),\n role: z.string(),\n model: z.string(),\n exitFill: count,\n bestK: count.nullable(),\n /** Exit fill minus each configured K; positive means the seat left late. */\n overConfigured: z.array(z.object({ k: count, over: z.number() })),\n});\n/** `requestsFrom` when the report has no reviewer session at all, so requests per PR is 0. */\nexport const POOLED_REVIEWERS = \"pooled\";\nconst reviewerCostSchema = z.object({\n role: z.string(),\n model: z.string(),\n sessions: count,\n /** Mean requests after boot of a per-PR reviewer: the work each PR adds. */\n requestsPerPr: z.number(),\n /** The reviewer model whose sessions give `requestsPerPr`: the row's own, else the newest reviewer cohort; `pooled` with none. */\n requestsFrom: z.string(),\n costUsd: z.number(),\n});\nconst reviewerSchema = z.object({ prs: count, fresh: z.array(reviewerCostSchema), standing: z.array(reviewerCostSchema) });\n\nexport const handoffThresholdSchema = z.object({\n configuredK: z.array(count),\n sweep: z.object({ fromK: count, toK: count, stepK: count }),\n cohorts: z.array(cohortSchema),\n sessions: z.array(sessionSchema),\n /** Sessions with no dispatch, send or write, or none priced: they have no boot to measure. */\n unbootedSessions: count,\n teleports: z.array(teleportSchema),\n unmatchedTeleports: count,\n /** Boot and cache reads for `prs` reviews: a fresh reviewer per PR against one standing reviewer. */\n reviewers: reviewerSchema,\n});\n\nexport type HandoffThreshold = z.infer<typeof handoffThresholdSchema>;\nexport type HandoffCohort = z.infer<typeof cohortSchema>;\nexport type HandoffSession = z.infer<typeof sessionSchema>;\nexport type HandoffTeleport = z.infer<typeof teleportSchema>;\nexport type ReviewerComparison = z.infer<typeof reviewerSchema>;\nexport type CycleParams = z.infer<typeof paramsSchema>;\nexport type KSweep = HandoffThreshold[\"sweep\"];\n\n/** One main-thread request as the handoff model needs it. */\nexport interface HandoffRequestRow {\n sessionId: string;\n role: string;\n model: string;\n ts: string;\n /** Tokens in context: input, cache reads and cache writes. */\n fill: number;\n tokens: RequestTokens;\n bootAction: boolean;\n}\n\nexport interface TeleportEvent {\n ts: string;\n name: string | null;\n fromAgentId: string;\n}\n\nexport interface HandoffOptions {\n configuredK?: readonly number[];\n sweep?: KSweep;\n reviewerRole?: string;\n /** The role whose boot, fill and growth price a reviewer that stays up across PRs. */\n standingRole?: string;\n reviewerPrs?: number;\n /** Prices every request and the read rate; the package table, not the graph's stored one. */\n prices?: readonly PriceRow[];\n}\n\nexport function isBootAction(calls: readonly ActionCall[]): boolean {\n return calls.some((call) => BOOT_TOOL.test(call.tool) || (call.writePaths?.length ?? 0) > 0);\n}\n\n/** Broker log lines to teleport starts; any other line, or one that is not JSON, is skipped. */\nexport function parseTeleportEvents(lines: Iterable<string>): TeleportEvent[] {\n const events: TeleportEvent[] = [];\n for (const line of lines) {\n const entry = parseJson(line);\n if (entry?.event !== TELEPORT_EVENT || typeof entry.from !== \"string\" || typeof entry.ts !== \"string\") continue;\n events.push({ ts: entry.ts, name: typeof entry.name === \"string\" ? entry.name : null, fromAgentId: entry.from });\n }\n return events;\n}\n\nfunction parseJson(line: string): Record<string, unknown> | null {\n try {\n const value: unknown = JSON.parse(line);\n return typeof value === \"object\" && value !== null ? (value as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n}\n\n/** 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. */\nexport function costPerRequest(params: CycleParams, k: number): number | null {\n const requests = (k - params.bootFill) / params.growthPerRequest;\n if (!(params.growthPerRequest > 0) || requests < 1) return null;\n return params.bootCostUsd / requests + (params.readPricePerMTok / MTOK) * ((params.bootFill + k) / 2);\n}\n\n/** The cheapest K on the sweep grid, then each configured K against it. */\nexport function sweepK(params: CycleParams, sweep: KSweep, configuredK: readonly number[]): z.infer<typeof sweepResultSchema> {\n let best: { k: number; cost: number } | null = null;\n for (let k = sweep.fromK; k <= sweep.toK; k += sweep.stepK) {\n const cost = costPerRequest(params, k);\n if (cost !== null && (best === null || cost < best.cost)) best = { k, cost };\n }\n const atConfigured = configuredK.map((k) => {\n const cost = costPerRequest(params, k);\n return { k, costPerRequest: cost, deltaPerRequest: cost === null || best === null ? null : cost - best.cost };\n });\n return { bestK: best?.k ?? null, bestCostPerRequest: best?.cost ?? null, atConfigured };\n}\n\n/** Per role and model: boot cost and fill, fill growth and read price from the requests, then the K sweep. */\nexport function handoffThreshold(rows: readonly HandoffRequestRow[], teleports: readonly TeleportEvent[], agentSessions: ReadonlyMap<string, readonly string[]>, options: HandoffOptions = {}): HandoffThreshold {\n const configuredK = [...(options.configuredK ?? DEFAULT_CONFIGURED_K)];\n const sweep = { ...(options.sweep ?? DEFAULT_K_SWEEP) };\n const bySession = groupBy(rows, (row) => row.sessionId);\n const fits = [...bySession.values()].map((requests) => fitSession(requests, options.prices ?? PRICE_TABLE, sweep));\n const sessions = fits.filter((fit): fit is HandoffSession => fit !== null).sort((a, b) => a.sessionId.localeCompare(b.sessionId));\n const cohorts = cohortsOf(sessions, sweep, configuredK);\n const matched = teleports.map((event) => teleportExit(event, agentSessions, bySession, cohorts, configuredK)).filter((t): t is HandoffTeleport => t !== null);\n return {\n configuredK,\n sweep,\n cohorts,\n sessions,\n unbootedSessions: fits.length - sessions.length,\n teleports: matched.sort((a, b) => a.ts.localeCompare(b.ts)),\n unmatchedTeleports: teleports.length - matched.length,\n reviewers: reviewerComparison(sessions, options.reviewerRole ?? DEFAULT_REVIEWER_ROLE, options.standingRole ?? DEFAULT_STANDING_ROLE, options.reviewerPrs ?? DEFAULT_REVIEWER_PRS),\n };\n}\n\nfunction fitSession(unsorted: readonly HandoffRequestRow[], prices: readonly PriceRow[], sweep: KSweep): HandoffSession | null {\n const requests = [...unsorted].sort((a, b) => a.ts.localeCompare(b.ts));\n const first = requests[0]!;\n const bootIndex = requests.findIndex((row) => row.bootAction);\n const price = findPrice(first.model, first.ts, prices);\n if (bootIndex < 0 || price === null) return null;\n const params: CycleParams = {\n bootCostUsd: requests.slice(0, bootIndex + 1).reduce((sum, row) => sum + priceRequest(row.tokens, row.model, row.ts, prices).costUsd, 0),\n bootFill: requests[bootIndex]!.fill,\n growthPerRequest: meanGrowth(requests.slice(bootIndex).map((row) => row.fill)),\n readPricePerMTok: price.cacheRead,\n };\n const { sessionId, role, model } = first;\n const last = requests[requests.length - 1]!;\n return { sessionId, role, model, requests: requests.length, bootRequests: bootIndex + 1, exitFill: last.fill, lastTs: last.ts, ...params, bestK: sweepK(params, sweep, []).bestK };\n}\n\n/** Rises only, so a compaction's drop does not cancel the growth before it; zero with no request after boot. */\nfunction meanGrowth(fills: readonly number[]): number {\n if (fills.length < 2) return 0;\n let rise = 0;\n for (let i = 1; i < fills.length; i += 1) rise += Math.max(0, fills[i]! - fills[i - 1]!);\n return rise / (fills.length - 1);\n}\n\n/** Session means per role and model; a model's read price differs, so it splits the role. */\nfunction cohortsOf(sessions: readonly HandoffSession[], sweep: KSweep, configuredK: readonly number[]): HandoffCohort[] {\n return [...groupBy(sessions, (s) => JSON.stringify([s.role, s.model]))]\n .map(([, members]) => {\n const params = meanParams(members);\n return {\n role: members[0]!.role,\n model: members[0]!.model,\n sessions: members.length,\n ...params,\n ...sweepK(params, sweep, configuredK),\n halfBoot: sweepK({ ...params, bootCostUsd: params.bootCostUsd / 2 }, sweep, configuredK),\n };\n })\n .sort((a, b) => a.role.localeCompare(b.role) || a.model.localeCompare(b.model));\n}\n\nfunction meanParams(sessions: readonly HandoffSession[]): CycleParams {\n const mean = (pick: (s: HandoffSession) => number) => sessions.reduce((sum, s) => sum + pick(s), 0) / sessions.length;\n return {\n bootCostUsd: mean((s) => s.bootCostUsd),\n bootFill: mean((s) => s.bootFill),\n growthPerRequest: meanGrowthOf(sessions),\n readPricePerMTok: mean((s) => s.readPricePerMTok),\n };\n}\n\n/** Sessions with no request after boot have g = 0; counting them would dilute the growth of those that grew. */\nfunction meanGrowthOf(sessions: readonly HandoffSession[]): number {\n const grown = sessions.filter((s) => s.growthPerRequest > 0);\n return grown.length === 0 ? 0 : grown.reduce((sum, s) => sum + s.growthPerRequest, 0) / grown.length;\n}\n\n/** The fill of the outgoing session's last request at or before the teleport. */\nfunction teleportExit(\n event: TeleportEvent,\n agentSessions: ReadonlyMap<string, readonly string[]>,\n bySession: ReadonlyMap<string, readonly HandoffRequestRow[]>,\n cohorts: readonly HandoffCohort[],\n configuredK: readonly number[],\n): HandoffTeleport | null {\n const candidates = (agentSessions.get(event.fromAgentId) ?? []).flatMap((id) => bySession.get(id) ?? []);\n const exit = candidates.filter((row) => row.ts <= event.ts).sort((a, b) => b.ts.localeCompare(a.ts))[0];\n if (!exit) return null;\n const cohort = cohorts.find((c) => c.role === exit.role && c.model === exit.model);\n return {\n ts: event.ts,\n name: event.name,\n sessionId: exit.sessionId,\n role: exit.role,\n model: exit.model,\n exitFill: exit.fill,\n bestK: cohort?.bestK ?? null,\n overConfigured: configuredK.map((k) => ({ k, over: exit.fill - k })),\n };\n}\n\n/** Reads over m requests from f0 growing g each: m f0 + g m(m + 1) / 2 tokens at the read price. */\nfunction readCost(params: CycleParams, requests: number): number {\n return ((requests * params.bootFill + (params.growthPerRequest * requests * (requests + 1)) / 2) * params.readPricePerMTok) / MTOK;\n}\n\n/** Fresh: every PR pays a boot and its own reads. Standing: one boot, then every PR's requests read the context the earlier ones left. */\nfunction reviewerComparison(sessions: readonly HandoffSession[], reviewerRole: string, standingRole: string, prs: number): ReviewerComparison {\n const cohorts = (role: string) => [...groupBy(sessions.filter((s) => s.role === role), (s) => s.model)].sort(([a], [b]) => a.localeCompare(b));\n const reviewers = cohorts(reviewerRole);\n const perPr = new Map(reviewers.map(([model, members]) => [model, meanRequestsAfterBoot(members)]));\n const newest = newestCohort(reviewers);\n const priced = (role: string, costOf: (params: CycleParams, requests: number) => number) =>\n cohorts(role).map(([model, members]) => {\n const from = perPr.has(model) ? model : newest;\n const requestsPerPr = from === null ? 0 : perPr.get(from)!;\n return { role, model, sessions: members.length, requestsPerPr, requestsFrom: from ?? POOLED_REVIEWERS, costUsd: costOf(meanParams(members), requestsPerPr) };\n });\n return {\n prs,\n fresh: priced(reviewerRole, (params, requests) => prs * (params.bootCostUsd + readCost(params, requests))),\n standing: priced(standingRole, (params, requests) => params.bootCostUsd + readCost(params, prs * requests)),\n };\n}\n\n/** The reviewer model whose latest session is newest; a tie goes to the later model name. */\nfunction newestCohort(reviewers: readonly (readonly [string, readonly HandoffSession[]])[]): string | null {\n const latest = reviewers.map(([model, members]) => ({ model, ts: members.reduce((max, s) => (s.lastTs > max ? s.lastTs : max), \"\") }));\n latest.sort((a, b) => b.ts.localeCompare(a.ts) || b.model.localeCompare(a.model));\n return latest[0]?.model ?? null;\n}\n\nfunction meanRequestsAfterBoot(sessions: readonly HandoffSession[]): number {\n return sessions.length === 0 ? 0 : sessions.reduce((sum, s) => sum + s.requests - s.bootRequests, 0) / sessions.length;\n}\n\nfunction groupBy<T>(rows: readonly T[], keyOf: (row: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = keyOf(row);\n const members = groups.get(key);\n if (members) members.push(row);\n else groups.set(key, [row]);\n }\n return groups;\n}\n","/** Initiatives a session's task edges name, with how many edges name each. */\nexport interface TaskInitiative {\n initiative: string;\n edges: number;\n}\n\n/**\n * A task edge names the initiative outright, so it wins over the cwd guess. Among several,\n * the most-named initiative wins and a tie goes to the alphabetically first, for a stable report.\n */\nexport function sessionInitiative(tasks: readonly TaskInitiative[], cwd: string | null | undefined): string {\n const best = [...tasks].sort((a, b) => b.edges - a.edges || a.initiative.localeCompare(b.initiative))[0];\n return best ? best.initiative : initiativeFromCwd(cwd);\n}\n\n/** The cwd rule from `cf_analyze.py` `initiative()`. A worktree under a repo counts as that repo. */\nexport function initiativeFromCwd(cwd: string | null | undefined): string {\n if (!cwd) return \"unknown\";\n const repo = /\\/projects\\/([^/]+)/.exec(cwd);\n if (repo) return `repo:${repo[1]}`;\n const activeWork = /active-work\\/([^/]+)/.exec(cwd);\n if (activeWork) return `active-work:${activeWork[1]}`;\n if (/ac-fork-\\w+/.test(cwd)) return \"ac-fork(tmp)\";\n const trimmed = cwd.replace(/\\/+$/, \"\");\n return `other:${trimmed.slice(trimmed.lastIndexOf(\"/\") + 1)}`;\n}\n","import type { Db } from \"@titan-design/store-sqlite\";\nimport type { ReportWindow } from \"./cost-report-queries.js\";\nimport type { ActionCall } from \"./turn-action.js\";\n\n/** The signals session-read extracts per tool use that the action classifier reads. */\nconst CALL_SIGNALS = { command_heads: \"heads\", file_read: \"readPaths\", file_write: \"writePaths\" } as const;\ntype CallSignal = keyof typeof CALL_SIGNALS;\n\n/**\n * A tool_use line follows the first line of the request that issued it, so the owner is the latest\n * request at or before it; context_contribution maps the other way, to the request it feeds.\n * Joining owners to request_dedup drops every fan-out copy along with its tool calls.\n */\nconst OWNED_CALLS = `\n WITH scope AS (\n SELECT DISTINCT transcript_id FROM request_dedup\n WHERE (@since IS NULL OR ts >= @since) AND (@until IS NULL OR ts < @until)\n ), stream AS (\n SELECT transcript_id, byte_offset, -1 AS lane, 0 AS block_index, request_id, NULL AS tool_use_id, NULL AS name\n FROM request WHERE transcript_id IN (SELECT transcript_id FROM scope)\n UNION ALL\n SELECT transcript_id, byte_offset, 0, block_index, NULL, tool_use_id, name\n FROM tool_call WHERE transcript_id IN (SELECT transcript_id FROM scope)\n ), ordered AS (\n SELECT *, COUNT(request_id) OVER (PARTITION BY transcript_id ORDER BY byte_offset, lane, block_index ROWS UNBOUNDED PRECEDING) AS requests_seen\n FROM stream\n ), owned AS (\n SELECT c.transcript_id, c.byte_offset, c.block_index, c.tool_use_id, c.name, r.request_id\n FROM ordered c JOIN ordered r ON r.transcript_id = c.transcript_id AND r.lane = -1 AND r.requests_seen = c.requests_seen\n WHERE c.lane = 0\n )\n SELECT o.request_id AS requestId, o.transcript_id || ':' || o.byte_offset || ':' || o.block_index AS callKey, o.name AS tool, s.signal, s.detail\n FROM owned o\n JOIN request_dedup d ON d.transcript_id = o.transcript_id AND d.request_id = o.request_id\n LEFT JOIN session_signal s ON s.transcript_id = o.transcript_id AND s.tool_use_id = o.tool_use_id\n AND s.signal IN ('command_heads', 'file_read', 'file_write')\n WHERE (@since IS NULL OR d.ts >= @since) AND (@until IS NULL OR d.ts < @until)\n ORDER BY o.transcript_id, o.byte_offset, o.block_index\n`;\n\ninterface OwnedRow {\n requestId: string;\n callKey: string;\n tool: string;\n signal: CallSignal | null;\n detail: string | null;\n}\n\n/** The tool calls each request in the window issued, keyed by `request_id`; a request with none is absent. */\nexport function readRequestToolCalls(db: Db, window: ReportWindow): Map<string, ActionCall[]> {\n const byRequest = new Map<string, Map<string, ActionCall>>();\n for (const row of db.prepare(OWNED_CALLS).all(window) as OwnedRow[]) {\n const calls = byRequest.get(row.requestId) ?? new Map<string, ActionCall>();\n byRequest.set(row.requestId, calls);\n const call = calls.get(row.callKey) ?? { tool: row.tool };\n calls.set(row.callKey, row.signal ? withSignal(call, row.signal, row.detail ?? \"\") : call);\n }\n return new Map([...byRequest].map(([requestId, calls]) => [requestId, [...calls.values()]]));\n}\n\n/** `command_heads` is one `;`-joined string per Bash call; file signals carry one path each. */\nfunction withSignal(call: ActionCall, signal: CallSignal, detail: string): ActionCall {\n const field = CALL_SIGNALS[signal];\n const values = signal === \"command_heads\" ? detail.split(\";\").filter(Boolean) : [detail];\n return { ...call, [field]: [...(call[field] ?? []), ...values] };\n}\n","import type { SessionClassification } from \"./classify-session.js\";\n\n/** worker-v1's role vocabulary, from worker-forensics-report.md section 2. */\nexport type WorkerRole = \"implementer\" | \"reviewer\" | \"researcher\" | \"planner\" | \"coordinator\" | \"standing_peer\" | \"unknown\";\n\n/** Spawn profile to role, as the worker report's table (wf_analyze.py:79-91) maps it. */\nexport const PROFILE_ROLES: Readonly<Record<string, WorkerRole>> = {\n implementer: \"implementer\",\n \"implementer-lite\": \"implementer\",\n \"relay-implementer\": \"implementer\",\n \"beat-builder\": \"implementer\",\n \"fable-optimizer\": \"implementer\",\n \"bd-implementer\": \"implementer\",\n \"bd-implementer-lite\": \"implementer\",\n reviewer: \"reviewer\",\n \"relay-reviewer\": \"reviewer\",\n \"bd-reviewer\": \"reviewer\",\n researcher: \"researcher\",\n explorer: \"researcher\",\n \"fable-architect\": \"planner\",\n planner: \"planner\",\n \"bd-planner\": \"planner\",\n \"fable-coordinator\": \"coordinator\",\n \"opus-coordinator\": \"coordinator\",\n peer: \"standing_peer\",\n};\n\nexport const STANDING_PEER_MIN_HOURS = 12;\nexport const STANDING_PEER_MIN_ASSIGNMENTS = 2;\nconst HOUR_MS = 3_600_000;\n\nexport interface WorkerFacts {\n profile?: string | null;\n /** First request to last request, over the whole session rather than a report window. */\n lifetimeMs: number;\n /** worker-v1 episodes opened by an assignment (the brief or a channel follow-up), not by an idle gap. */\n assignments: number;\n}\n\nexport function roleFromProfile(profile: string | null | undefined): WorkerRole {\n return PROFILE_ROLES[(profile ?? \"\").toLowerCase()] ?? \"unknown\";\n}\n\n/** A worker that outlives its first assignment is a standing peer whatever it was spawned as (wf_analyze.py:94-103). */\nexport function workerRole(facts: WorkerFacts): WorkerRole {\n const outlived = facts.lifetimeMs >= STANDING_PEER_MIN_HOURS * HOUR_MS && facts.assignments >= STANDING_PEER_MIN_ASSIGNMENTS;\n return outlived ? \"standing_peer\" : roleFromProfile(facts.profile);\n}\n\n/** The report's role key: `coordinator` or `adhoc` for humans, `worker:<role>` for spawned agents, else the class. */\nexport function sessionRole(classification: SessionClassification, worker: WorkerFacts): string {\n if (classification.humanRole) return classification.humanRole;\n if (classification.sessionClass === \"agent_spawned\") return `worker:${workerRole(worker)}`;\n return classification.sessionClass;\n}\n","import type { Db } from \"@titan-design/store-sqlite\";\nimport { readAgentNames } from \"./cost-report-queries.js\";\n\n/**\n * Narrows a report to some sessions. Every field left out matches all, and fields combine with AND.\n * Compactions and coverage stay window-wide: the graph does not key them to a request.\n */\nexport interface ReportScope {\n sessionIds?: readonly string[];\n /** Keeps sessions whose agent-chat agent name starts with it. */\n agentPrefix?: string;\n /** Report roles, as `byRole` names them. */\n roles?: readonly string[];\n}\n\n/** A predicate over a request's session and role; with no scope every request passes. */\nexport function scopeFilter(db: Db, scope: ReportScope = {}): (row: { sessionId: string; role: string }) => boolean {\n const ids = scope.sessionIds ? new Set(scope.sessionIds) : null;\n const named = scope.agentPrefix === undefined ? null : agentSessions(db, scope.agentPrefix);\n const roles = scope.roles ? new Set(scope.roles) : null;\n return (row) => (!ids || ids.has(row.sessionId)) && (!named || named.has(row.sessionId)) && (!roles || roles.has(row.role));\n}\n\nfunction agentSessions(db: Db, prefix: string): Set<string> {\n return new Set(readAgentNames(db).filter((row) => row.agentName.startsWith(prefix)).map((row) => row.sessionId));\n}\n","export const ACTION_CLASSES = [\n \"journal-write\",\n \"pr-ci-check\",\n \"merge\",\n \"dispatch\",\n \"retire\",\n \"task-state\",\n \"budget-status\",\n \"scorer\",\n \"message\",\n \"read-investigate\",\n \"text-only\",\n \"other\",\n] as const;\n\nexport type ActionClass = (typeof ACTION_CLASSES)[number];\n\n/** One tool call of a request, with the signals session-read extracted for it. */\nexport interface ActionCall {\n tool: string;\n /** Command heads of a Bash call, such as `gh pr checks`. */\n heads?: readonly string[];\n readPaths?: readonly string[];\n writePaths?: readonly string[];\n}\n\n/** A rule matches a call when every field it sets matches; list order is the precedence. */\nexport interface ActionRule {\n cls: ActionClass;\n tool?: RegExp;\n head?: RegExp;\n readPath?: RegExp;\n writePath?: RegExp;\n}\n\n/** A basename naming a log, journal or event file, so `catalog.md`, `CHANGELOG.md` and `fixture.jsonl` stay out. */\nconst JOURNAL_BASENAME = String.raw`(?:(?:[^/]*[-_.])?(?:log|journal|events?)(?:[-_.][^/]*)?\\.(?:md|jsonl)|[^/]*journal[^/]*)$`;\nconst INTERPRETER = String.raw`(?:(?:python3?|node|tsx|bash|sh) )?`;\n\nexport const DEFAULT_ACTION_RULES: readonly ActionRule[] = [\n { cls: \"journal-write\", writePath: new RegExp(String.raw`(?:^|/)${JOURNAL_BASENAME}`, \"i\") },\n { cls: \"journal-write\", head: new RegExp(`^>(?:[^/]*/)?${JOURNAL_BASENAME}`, \"i\") },\n { cls: \"pr-ci-check\", head: /^gh pr (checks|view)\\b/ },\n { cls: \"pr-ci-check\", head: /^gh run\\b/ },\n { cls: \"pr-ci-check\", head: /^git merge-tree\\b/ },\n { cls: \"pr-ci-check\", head: /^gh api GET commits\\/check-runs$/ },\n { cls: \"pr-ci-check\", head: /^gh api GET commits\\/status$/ },\n { cls: \"merge\", head: /^gh pr merge\\b/ },\n { cls: \"merge\", head: /^gh api PUT pulls\\/merge$/ },\n { cls: \"dispatch\", tool: /agent_(spawn|resume)$/ },\n { cls: \"retire\", head: /^(agent-chat )?agent retire\\b/ },\n { cls: \"task-state\", head: /^active-work task\\b/ },\n { cls: \"budget-status\", tool: /(session_budget|chat_status)$/ },\n { cls: \"budget-status\", head: /^(agent-chat )?agent list\\b/ },\n { cls: \"budget-status\", head: /^(agent-chat )?agent (ls|budget|worktrees)\\b/ },\n { cls: \"budget-status\", head: /^git worktree list\\b/ },\n { cls: \"budget-status\", tool: /(agent_list|chat_list|ListAgents)$/ },\n { cls: \"scorer\", tool: /(^|__)scor/i },\n { cls: \"scorer\", head: new RegExp(`^${INTERPRETER}[\\\\w.-]*scor`, \"i\") },\n { cls: \"message\", tool: /chat_send$/ },\n { cls: \"message\", tool: /(chat_ask|chat_inbox|chat_claim|chat_release)$/ },\n { cls: \"read-investigate\", tool: /^(Read|Grep|Glob)$/ },\n { cls: \"read-investigate\", head: /^(cat|ls|grep|rg|head|tail|find|wc|git (log|diff|show|status))\\b/ },\n];\n\n/** Dispatch is judgment about what to hand out, so it stays out of the mechanical list. */\nexport const DEFAULT_MECHANICAL_CLASSES: readonly ActionClass[] = [\n \"journal-write\",\n \"pr-ci-check\",\n \"task-state\",\n \"budget-status\",\n \"retire\",\n \"merge\",\n \"scorer\",\n];\n\nfunction callMatches(call: ActionCall, rule: ActionRule): boolean {\n if (rule.tool && !rule.tool.test(call.tool)) return false;\n if (rule.head && !(call.heads ?? []).some((h) => rule.head?.test(h))) return false;\n if (rule.readPath && !(call.readPaths ?? []).some((p) => rule.readPath?.test(p))) return false;\n if (rule.writePath && !(call.writePaths ?? []).some((p) => rule.writePath?.test(p))) return false;\n return true;\n}\n\nexport function classifyRequest(\n calls: readonly ActionCall[],\n rules: readonly ActionRule[] = DEFAULT_ACTION_RULES,\n): ActionClass {\n if (calls.length === 0) return \"text-only\";\n const hit = rules.find((rule) => calls.some((call) => callMatches(call, rule)));\n return hit?.cls ?? \"other\";\n}\n","import { z } from \"zod\";\nimport type { AgentNameRow, WakeEventRow } from \"./cost-report-queries.js\";\nimport { roleFromProfile } from \"./roles.js\";\nimport { ACTION_CLASSES, type ActionClass } from \"./turn-action.js\";\n\nexport const WAKE_FROM_KINDS = [\"seat\", \"agent\", \"broadcast\", \"broker\", \"none\"] as const;\nexport type WakeFromKind = (typeof WAKE_FROM_KINDS)[number];\n\n/** Report roles whose wakes are cut into episodes: a human coordinator and a spawned coordinator seat. */\nexport const DEFAULT_EPISODE_ROLES: readonly string[] = [\"coordinator\", \"worker:coordinator\"];\n\n/** A wake whose requests only read, answer in text, or call tools no rule names changed nothing outside the session. */\nexport const DEFAULT_NO_ACTION_CLASSES: readonly ActionClass[] = [\"read-investigate\", \"text-only\", \"other\"];\n\n/** agent-chat's own name on the notices it writes, such as the agent lifecycle notice. */\nexport const BROKER_SENDER = \"agent-chat\";\nexport const AGENT_LIFECYCLE = \"agent_lifecycle\";\nconst UNNAMED = \"unnamed\";\n\nconst count = z.number().int().nonnegative();\nconst costFields = { episodes: count, requests: count, costUsd: z.number(), noActionEpisodes: count, noActionCostUsd: z.number() };\nconst fromSchema = z.object({ key: z.enum(WAKE_FROM_KINDS), ...costFields });\nconst causeSchema = z.object({\n key: z.string(),\n ...costFields,\n midLoopEpisodes: count,\n requestsPerEpisode: z.number(),\n costPerEpisode: z.number(),\n byFrom: z.array(fromSchema),\n});\nconst pairSchema = z.object({ from: z.string(), fromKind: z.enum(WAKE_FROM_KINDS), to: z.string(), ...costFields });\n\nexport const wakeEpisodesSchema = z.object({\n roles: z.array(z.string()),\n noActionClasses: z.array(z.enum(ACTION_CLASSES)),\n ...costFields,\n /** Requests in the window that follow no event in it: the work an earlier arrival started. */\n unattributed: z.object({ requests: count, costUsd: z.number() }),\n byCause: z.array(causeSchema),\n /** Sender by receiver; a seat is named, every other sender is its kind. */\n pairs: z.array(pairSchema),\n});\n\nexport type WakeEpisodes = z.infer<typeof wakeEpisodesSchema>;\nexport type WakeCauseEpisodes = z.infer<typeof causeSchema>;\nexport type WakePair = z.infer<typeof pairSchema>;\n\n/** One request as the episode view needs it. */\nexport interface EpisodeRequestRow {\n costUsd: number;\n action: ActionClass;\n eventKey: string | null;\n}\n\nexport interface WakeEpisode {\n key: string;\n cause: string;\n midLoop: boolean;\n fromKind: WakeFromKind;\n from: string;\n to: string;\n requests: number;\n costUsd: number;\n noAction: boolean;\n}\n\nexport interface EpisodeNames {\n seats: ReadonlySet<string>;\n /** Each receiving session's agent-chat name. */\n receivers: ReadonlyMap<string, string>;\n}\n\n/** A seat is a name some top-level session carries, or one a coordinator profile was spawned under. */\nexport function episodeNames(rows: readonly AgentNameRow[]): EpisodeNames {\n const isSeat = (row: AgentNameRow) => row.originKind !== \"spawned\" || roleFromProfile(row.profile) === \"coordinator\";\n return {\n seats: new Set(rows.filter(isSeat).map((row) => row.agentName)),\n receivers: new Map(rows.map((row) => [row.sessionId, row.agentName])),\n };\n}\n\n/** The lifecycle notice is session-read's `channel_system`; every other cause keeps its name. */\nexport function episodeCause(cause: string): string {\n return cause === \"channel_system\" ? AGENT_LIFECYCLE : cause;\n}\n\nexport function fromKindOf(event: WakeEventRow, seats: ReadonlySet<string>): WakeFromKind {\n if (!event.cause.startsWith(\"channel_\") || event.fromName === null) return \"none\";\n if (event.fromName === BROKER_SENDER) return \"broker\";\n if (event.broadcast) return \"broadcast\";\n return seats.has(event.fromName) ? \"seat\" : \"agent\";\n}\n\n/** Each event with the requests that followed it, flagged no-action when every request's class is listed. */\nexport function buildWakeEpisodes(\n events: readonly WakeEventRow[],\n requests: readonly EpisodeRequestRow[],\n names: EpisodeNames,\n noActionClasses: readonly ActionClass[],\n): WakeEpisode[] {\n const byEvent = groupBy(requests, (request) => request.eventKey ?? \"\");\n return events.map((event) => {\n const members = byEvent.get(event.key) ?? [];\n const fromKind = fromKindOf(event, names.seats);\n return {\n key: event.key,\n cause: episodeCause(event.cause),\n midLoop: event.delivery === \"mid_loop\",\n fromKind,\n from: pairSender(fromKind, event.fromName, names.seats),\n to: names.receivers.get(event.sessionId) ?? UNNAMED,\n requests: members.length,\n costUsd: members.reduce((sum, row) => sum + row.costUsd, 0),\n noAction: members.every((row) => noActionClasses.includes(row.action)),\n };\n });\n}\n\n/** Spawned agents have one-off names, so they collapse to `agent`; a seat broadcasting keeps its name. */\nfunction pairSender(kind: WakeFromKind, name: string | null, seats: ReadonlySet<string>): string {\n if (kind === \"seat\" || (kind === \"broadcast\" && name !== null && seats.has(name))) return name!;\n return kind === \"broadcast\" ? \"agent\" : kind;\n}\n\nexport function summarizeWakeEpisodes(\n episodes: readonly WakeEpisode[],\n requests: readonly EpisodeRequestRow[],\n roles: readonly string[],\n noActionClasses: readonly ActionClass[],\n): WakeEpisodes {\n const keys = new Set(episodes.map((episode) => episode.key));\n const unattributed = requests.filter((row) => row.eventKey === null || !keys.has(row.eventKey));\n return {\n roles: [...roles],\n noActionClasses: [...noActionClasses],\n ...costOf(episodes),\n unattributed: { requests: unattributed.length, costUsd: unattributed.reduce((sum, row) => sum + row.costUsd, 0) },\n byCause: causeBuckets(episodes),\n pairs: pairBuckets(episodes),\n };\n}\n\nfunction costOf(episodes: readonly WakeEpisode[]) {\n const noAction = episodes.filter((episode) => episode.noAction);\n const sum = (list: readonly WakeEpisode[], pick: (episode: WakeEpisode) => number) => list.reduce((total, episode) => total + pick(episode), 0);\n return {\n episodes: episodes.length,\n requests: sum(episodes, (episode) => episode.requests),\n costUsd: sum(episodes, (episode) => episode.costUsd),\n noActionEpisodes: noAction.length,\n noActionCostUsd: sum(noAction, (episode) => episode.costUsd),\n };\n}\n\n/** Most expensive first; ties by key so the report is stable. */\nfunction causeBuckets(episodes: readonly WakeEpisode[]): WakeCauseEpisodes[] {\n return [...groupBy(episodes, (episode) => episode.cause)]\n .map(([key, members]) => {\n const cost = costOf(members);\n return {\n key,\n ...cost,\n midLoopEpisodes: members.filter((episode) => episode.midLoop).length,\n requestsPerEpisode: cost.requests / cost.episodes,\n costPerEpisode: cost.costUsd / cost.episodes,\n byFrom: [...groupBy(members, (episode) => episode.fromKind)].map(([kind, part]) => ({ key: kind as WakeFromKind, ...costOf(part) })).sort(byCostThenKey),\n };\n })\n .sort(byCostThenKey);\n}\n\nfunction pairBuckets(episodes: readonly WakeEpisode[]): WakePair[] {\n const sent = episodes.filter((episode) => episode.fromKind !== \"none\");\n return [...groupBy(sent, (episode) => JSON.stringify([episode.from, episode.fromKind, episode.to]))]\n .map(([key, members]) => {\n const [from, fromKind, to] = JSON.parse(key) as [string, WakeFromKind, string];\n return { from, fromKind, to, ...costOf(members) };\n })\n .sort((a, b) => b.costUsd - a.costUsd || a.from.localeCompare(b.from) || a.to.localeCompare(b.to));\n}\n\nfunction groupBy<T>(rows: readonly T[], keyOf: (row: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = keyOf(row);\n const members = groups.get(key);\n if (members) members.push(row);\n else groups.set(key, [row]);\n }\n return groups;\n}\n\nfunction byCostThenKey(a: { key: string; costUsd: number }, b: { key: string; costUsd: number }): number {\n return b.costUsd - a.costUsd || a.key.localeCompare(b.key);\n}\n","import type { CostBucket, CostReport, MechanicalShare, RoleActions, WakeGapCell } from \"./cost-report.js\";\nimport type { HandoffThreshold } from \"./handoff-threshold.js\";\nimport { PRICE_TABLE_VERSION } from \"./prices.js\";\nimport type { WakeEpisodes } from \"./wake-episodes.js\";\n\nexport const LIST_PRICE_CAVEAT =\n \"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.\";\n\ntype Cell = string | number;\n\n/** Wake causes and sender pairs the text shows; the JSON carries all of them. */\nexport const TOP_WAKE_ROWS = 10;\n\n/** The same report as plain-text tables, one section per report field, caveat and footer last. */\nexport function renderCostReportText(report: CostReport): string {\n const sections = [\n header(report),\n table(\"By token class\", [\"class\", \"tokens\", \"cost\"], report.byTokenClass.map((row) => [row.tokenClass, row.tokens, usd(row.costUsd)])),\n bucketTable(\"By account\", report.byAccount, report.totals.costUsd),\n bucketTable(\"By model\", report.byModel, report.totals.costUsd),\n bucketTable(\"By class\", report.byClass, report.totals.costUsd),\n bucketTable(\"By role\", report.byRole, report.totals.costUsd),\n actionTable(report.byAction),\n mechanicalTable(report.mechanicalShare),\n bucketTable(\"By episode count\", report.byEpisodeCount, report.totals.costUsd),\n bucketTable(\"By initiative\", report.byInitiative, report.totals.costUsd),\n bucketTable(\"By context band\", report.byContextBand, report.totals.costUsd),\n wakeCauseTable(report),\n episodeTable(report.wakeEpisodes),\n pairTable(report.wakeEpisodes),\n handoffTable(report.handoffThreshold),\n teleportTable(report.handoffThreshold),\n reviewerTable(report.handoffThreshold),\n cellTable(\"Wake cause by gap band\", report.wakeCauseByGapBand),\n cellTable(`Cold rebuilds: ${report.coldRebuild.requests} requests, ${usd(report.coldRebuild.costUsd)}`, report.coldRebuild.byGapBandAndCause),\n compactionTable(report.compactions),\n topSessionTable(report.topSessions),\n unpricedTable(report.unpricedModels),\n [LIST_PRICE_CAVEAT, footer(report)].join(\"\\n\"),\n ];\n return sections.join(\"\\n\\n\") + \"\\n\";\n}\n\n/** The report's sections a caller may render alone, keyed by the field each one shows. */\nexport const COST_REPORT_SECTIONS = {\n byRole: (report: CostReport) => bucketTable(\"By role\", report.byRole, report.totals.costUsd),\n byAction: (report: CostReport) => actionTable(report.byAction),\n mechanicalShare: (report: CostReport) => mechanicalTable(report.mechanicalShare),\n byWakeCause: (report: CostReport) => wakeCauseTable(report),\n wakeEpisodes: (report: CostReport) => episodeTable(report.wakeEpisodes),\n wakePairs: (report: CostReport) => pairTable(report.wakeEpisodes),\n handoff: (report: CostReport) => handoffTable(report.handoffThreshold),\n teleports: (report: CostReport) => teleportTable(report.handoffThreshold),\n reviewers: (report: CostReport) => reviewerTable(report.handoffThreshold),\n} as const;\n\nexport type CostReportSection = keyof typeof COST_REPORT_SECTIONS;\n\n/** Some sections of the report under its header, with the caveat and footer last as in the full text. */\nexport function renderCostReportSections(report: CostReport, sections: readonly CostReportSection[]): string {\n const body = sections.map((section) => COST_REPORT_SECTIONS[section](report));\n return [header(report), ...body, [LIST_PRICE_CAVEAT, footer(report)].join(\"\\n\")].join(\"\\n\\n\") + \"\\n\";\n}\n\nfunction header(report: CostReport): string {\n const { since, until } = report.window;\n const { requests, sessions, costUsd } = report.totals;\n return `Cost report, ${since ?? \"beginning\"} to ${until ?? \"now\"}\\nTotal ${usd(costUsd)} over ${requests} requests in ${sessions} sessions`;\n}\n\nfunction bucketTable(title: string, buckets: readonly CostBucket[], total: number): string {\n const rows = buckets.map((b) => [b.key, b.requests, b.sessions, usd(b.costUsd), share(b.costUsd, total)]);\n return table(title, [\"key\", \"requests\", \"sessions\", \"cost\", \"share\"], rows);\n}\n\n/** Each role's row carries its total; its action classes sit indented beneath, sharing that total. */\nfunction actionTable(roles: readonly RoleActions[]): string {\n const rows = roles.flatMap(({ role, buckets }) => {\n const total = buckets.reduce((sum, b) => sum + b.costUsd, 0);\n const requests = buckets.reduce((sum, b) => sum + b.requests, 0);\n return [[role, requests, usd(total), share(total, total)], ...buckets.map((b) => [` ${b.key}`, b.requests, usd(b.costUsd), share(b.costUsd, total)])];\n });\n return table(\"By action per role\", [\"role / action\", \"requests\", \"cost\", \"share\"], rows);\n}\n\nfunction mechanicalTable(m: MechanicalShare): string {\n const title = `Mechanical share: ${percent(m.share)} (${usd(m.costUsd)}) of total; classes ${m.classes.join(\", \") || \"none\"}`;\n return table(title, [\"role\", \"mechanical cost\", \"share of role\"], m.byRole.map((r) => [r.role, usd(r.costUsd), percent(r.share)]));\n}\n\n/** Q4: answers sit under `human`, with typed text and answers indented one level down. */\nfunction wakeCauseTable(report: CostReport): string {\n const rows = report.byWakeCause.flatMap((group) => [\n [group.key, group.requests, usd(group.costUsd), group.midLoopRequests, usd(group.midLoopCostUsd)],\n ...group.parts.map((part) => [` ${part.key}`, part.requests, usd(part.costUsd), part.midLoopRequests, usd(part.midLoopCostUsd)]),\n ]);\n return table(\"By wake cause\", [\"cause\", \"requests\", \"cost\", \"mid-loop\", \"mid-loop cost\"], rows);\n}\n\n/** Q4: the costliest causes per episode first, each with its senders indented beneath. */\nfunction episodeTable(w: WakeEpisodes): string {\n const title = `Wake episodes of ${w.roles.join(\", \")}: ${w.episodes} episodes, ${w.requests} requests, ${usd(w.costUsd)}; no-action means only ${w.noActionClasses.join(\", \")}`;\n const causes = [...w.byCause].sort((a, b) => b.costPerEpisode - a.costPerEpisode || a.key.localeCompare(b.key)).slice(0, TOP_WAKE_ROWS);\n const rows = causes.flatMap((c) => [\n [c.key, c.episodes, c.midLoopEpisodes, c.requests, c.requestsPerEpisode.toFixed(1), usd(c.costUsd), usd(c.costPerEpisode), noActionCell(c)],\n ...c.byFrom.map((f) => [` from ${f.key}`, f.episodes, \"\", f.requests, (f.requests / f.episodes).toFixed(1), usd(f.costUsd), usd(f.costUsd / f.episodes), noActionCell(f)]),\n ]);\n return table(title, [\"cause\", \"episodes\", \"mid-loop\", \"requests\", \"req/ep\", \"cost\", \"cost/ep\", \"no-action\"], rows);\n}\n\nfunction noActionCell(bucket: { episodes: number; noActionEpisodes: number }): string {\n return `${bucket.noActionEpisodes} (${share(bucket.noActionEpisodes, bucket.episodes)})`;\n}\n\nfunction pairTable(w: WakeEpisodes): string {\n const rows = w.pairs.slice(0, TOP_WAKE_ROWS).map((p) => [p.from, p.fromKind, p.to, p.episodes, p.requests, usd(p.costUsd), noActionCell(p)]);\n return table(\"Wake senders by receiver\", [\"from\", \"kind\", \"to\", \"episodes\", \"requests\", \"cost\", \"no-action\"], rows);\n}\n\n/** Q2: per role and model, the fitted boot, fill and growth, the best K, and each configured K's extra cost per request. */\nfunction handoffTable(h: HandoffThreshold): string {\n const title = `Handoff threshold per role, priced at package table v${PRICE_TABLE_VERSION}: best K over ${kilo(h.sweep.fromK)}-${kilo(h.sweep.toK)}, half-boot K in brackets`;\n const head = [\"role\", \"model\", \"sessions\", \"boot\", \"boot fill\", \"growth/req\", \"read $/MTok\", \"best K\", \"$/req\", ...h.configuredK.map((k) => `+$/req @${kilo(k)}`)];\n const rows = h.cohorts.map((c) => [\n c.role,\n c.model,\n c.sessions,\n usd(c.bootCostUsd),\n kilo(c.bootFill),\n Math.round(c.growthPerRequest),\n c.readPricePerMTok.toFixed(3),\n `${kiloOrDash(c.bestK)} (${kiloOrDash(c.halfBoot.bestK)})`,\n c.bestCostPerRequest === null ? \"-\" : `$${c.bestCostPerRequest.toFixed(4)}`,\n ...c.atConfigured.map((at) => (at.deltaPerRequest === null ? \"-\" : `$${at.deltaPerRequest.toFixed(4)}`)),\n ]);\n return table(title, head, rows);\n}\n\nfunction teleportTable(h: HandoffThreshold): string {\n const title = `Teleport exit fill: ${h.teleports.length} matched, ${h.unmatchedTeleports} unmatched; the latest ${TOP_WAKE_ROWS}`;\n const head = [\"ts\", \"name\", \"role\", \"exit fill\", \"best K\", ...h.configuredK.map((k) => `over ${kilo(k)}`)];\n const rows = h.teleports.slice(-TOP_WAKE_ROWS).map((t) => [t.ts, t.name ?? \"-\", t.role, kilo(t.exitFill), kiloOrDash(t.bestK), ...t.overConfigured.map((o) => kilo(o.over))]);\n return table(title, head, rows);\n}\n\nfunction reviewerTable(h: HandoffThreshold): string {\n const row = (kind: string) => (c: HandoffThreshold[\"reviewers\"][\"fresh\"][number]) => [kind, c.role, c.model, c.sessions, c.requestsPerPr.toFixed(1), c.requestsFrom, usd(c.costUsd)];\n const rows = [...h.reviewers.fresh.map(row(\"fresh per PR\")), ...h.reviewers.standing.map(row(\"standing\"))];\n return table(`Reviewers over ${h.reviewers.prs} PRs, boot and reads: fresh per PR against one standing`, [\"reviewer\", \"role\", \"model\", \"sessions\", \"req/PR\", \"req/PR from\", \"cost\"], rows);\n}\n\nfunction kilo(tokens: number): string {\n return `${Math.round(tokens / 1_000)}k`;\n}\n\nfunction kiloOrDash(tokens: number | null): string {\n return tokens === null ? \"-\" : kilo(tokens);\n}\n\nfunction cellTable(title: string, cells: readonly WakeGapCell[]): string {\n return table(title, [\"cause\", \"gap\", \"requests\", \"cost\"], cells.map((c) => [c.wakeCause, c.gapBand, c.requests, usd(c.costUsd)]));\n}\n\nfunction compactionTable(c: CostReport[\"compactions\"]): string {\n return table(\"Compactions\", [\"total\", \"manual\", \"auto\", \"mid-loop\", \"dropped tokens\"], [[c.total, c.manual, c.auto, c.midLoop, c.droppedTokens]]);\n}\n\nfunction topSessionTable(sessions: CostReport[\"topSessions\"]): string {\n const rows = sessions.map((s) => [s.sessionId, s.sessionClass, s.role, s.initiative, s.requests, usd(s.costUsd)]);\n return table(\"Top sessions\", [\"session\", \"class\", \"role\", \"initiative\", \"requests\", \"cost\"], rows);\n}\n\nfunction unpricedTable(models: CostReport[\"unpricedModels\"]): string {\n if (models.length === 0) return \"Unpriced models: none\";\n return table(\"Unpriced models (counted at zero cost)\", [\"model\", \"requests\", \"tokens\"], models.map((m) => [m.model, m.requests, m.tokens]));\n}\n\nfunction footer(report: CostReport): string {\n const { transcriptsIndexed, transcriptsDiscovered, facetBacklog } = report.coverage;\n const discovered = transcriptsDiscovered === null ? \"\" : ` of ${transcriptsDiscovered} discovered`;\n const version = report.priceTableVersion === null ? \"none\" : `v${report.priceTableVersion}`;\n const stale = report.priceTableVersion !== null && report.priceTableVersion !== PRICE_TABLE_VERSION ? ` (package has v${PRICE_TABLE_VERSION})` : \"\";\n return `Price table ${version}${stale}. Coverage: ${transcriptsIndexed} transcripts indexed${discovered}, facet backlog ${facetBacklog}.`;\n}\n\nexport function table(title: string, head: readonly string[], rows: readonly (readonly Cell[])[]): string {\n if (rows.length === 0) return `${title}: none`;\n const text = [head, ...rows].map((row) => row.map(String));\n const widths = head.map((_, i) => Math.max(...text.map((row) => row[i]!.length)));\n const rightAligned = head.map((_, i) => rows.every((row) => isNumeric(row[i]!)));\n const pad = (cell: string, i: number) => (rightAligned[i] ? cell.padStart(widths[i]!) : cell.padEnd(widths[i]!));\n const lines = text.map((row) => row.map(pad).join(\" \").trimEnd());\n return [title, ...lines].join(\"\\n\");\n}\n\nfunction isNumeric(cell: Cell): boolean {\n return typeof cell === \"number\" || /^\\$|%$/.test(cell);\n}\n\nexport function usd(value: number): string {\n return `$${value.toFixed(2)}`;\n}\n\nfunction share(value: number, total: number): string {\n return total > 0 ? percent(value / total) : \"-\";\n}\n\nfunction percent(fraction: number): string {\n return `${(fraction * 100).toFixed(1)}%`;\n}\n","import type { Db } from \"@titan-design/store-sqlite\";\nimport { z } from \"zod\";\nimport { GAP_BANDS, gapBand } from \"./bands.js\";\nimport { readSessionContexts, type ReportWindow } from \"./cost-report-queries.js\";\nimport { resolveWindow, tagSessions, type CostReportOptions } from \"./cost-report.js\";\nimport { PRICE_TABLE, PRICE_TABLE_VERSION, findPrice, type PriceRow } from \"./prices.js\";\nimport { LIST_PRICE_CAVEAT, table, usd } from \"./render-text.js\";\nimport { scopeFilter } from \"./scope.js\";\n\nconst FIVE_MINUTES_MS = 5 * 60_000;\nconst MTOK = 1e6;\nconst NO_PROFILE = \"none\";\n\n/** Gap bands past a 5-minute TTL: the next request finds the cache gone. */\nexport const REBUILD_GAP_BANDS: readonly string[] = GAP_BANDS.filter((band) => band.lo >= FIVE_MINUTES_MS).map((band) => band.name);\n\n/** One request as the TTL what-if needs it. */\nexport interface TtlRequestRow {\n sessionId: string;\n role: string;\n profile: string;\n model: string;\n ts: string;\n cacheReadTokens: number;\n cacheWrite1hTokens: number;\n /** Milliseconds since the session's previous request; null for its first. */\n gapMs: number | null;\n}\n\nconst count = z.number().int().nonnegative();\nconst effectFields = {\n sessions: count,\n requests: count,\n write1hTokens: count,\n /** 1h writes repriced at the 5m write rate. */\n repriceSavingUsd: z.number(),\n rebuilds: count,\n rebuildTokens: count,\n /** Each rebuild writes at the 5m rate what the 1h cache still served as a read. */\n rebuildCostUsd: z.number(),\n netSavingUsd: z.number(),\n netPerSessionUsd: z.number(),\n};\nconst bucketSchema = z.object({ key: z.string(), ...effectFields, fiveMinuteLoses: z.boolean() });\n\nexport const cacheTtlWhatIfSchema = z.object({\n window: z.object({ since: z.string().nullable(), until: z.string().nullable() }).optional(),\n priceTableVersion: z.number().int(),\n rebuildGapBands: z.array(z.string()),\n totals: z.object(effectFields),\n unpricedRequests: count,\n byRole: z.array(bucketSchema),\n byProfile: z.array(bucketSchema),\n /** Roles whose rebuilds after long gaps outweigh the cheaper writes. */\n lossRoles: z.array(z.string()),\n});\n\nexport type CacheTtlWhatIf = z.infer<typeof cacheTtlWhatIfSchema>;\nexport type CacheTtlBucket = z.infer<typeof bucketSchema>;\n\ninterface RequestEffect {\n sessionId: string;\n write1hTokens: number;\n repriceSavingUsd: number;\n rebuildTokens: number;\n rebuildCostUsd: number;\n}\n\n/** Q3: what each role and profile would have paid with `CLAUDE_CODE_PROMPT_CACHE_TTL=5m` instead of 1h. */\nexport function cacheTtlWhatIf(rows: readonly TtlRequestRow[], prices: readonly PriceRow[] = PRICE_TABLE): CacheTtlWhatIf {\n const effects = new Map<TtlRequestRow, RequestEffect>();\n for (const row of rows) {\n const price = findPrice(row.model, row.ts, prices);\n if (price) effects.set(row, requestEffect(row, price));\n }\n const priced = [...effects.keys()];\n const byRole = buckets(priced, effects, (row) => row.role);\n return {\n priceTableVersion: PRICE_TABLE_VERSION,\n rebuildGapBands: [...REBUILD_GAP_BANDS],\n totals: sumEffects([...effects.values()]),\n unpricedRequests: rows.length - priced.length,\n byRole,\n byProfile: buckets(priced, effects, (row) => row.profile),\n lossRoles: byRole.filter((bucket) => bucket.fiveMinuteLoses).map((bucket) => bucket.key),\n };\n}\n\nfunction requestEffect(row: TtlRequestRow, price: PriceRow): RequestEffect {\n const band = row.gapMs === null ? null : gapBand(row.gapMs);\n const rebuildTokens = band !== null && REBUILD_GAP_BANDS.includes(band) ? row.cacheReadTokens : 0;\n return {\n sessionId: row.sessionId,\n write1hTokens: row.cacheWrite1hTokens,\n repriceSavingUsd: (row.cacheWrite1hTokens * (price.cacheWrite1h - price.cacheWrite5m)) / MTOK,\n rebuildTokens,\n rebuildCostUsd: (rebuildTokens * (price.cacheWrite5m - price.cacheRead)) / MTOK,\n };\n}\n\nfunction sumEffects(effects: readonly RequestEffect[]): CacheTtlWhatIf[\"totals\"] {\n const sum = (pick: (effect: RequestEffect) => number) => effects.reduce((total, effect) => total + pick(effect), 0);\n const sessions = new Set(effects.map((effect) => effect.sessionId)).size;\n const netSavingUsd = sum((effect) => effect.repriceSavingUsd - effect.rebuildCostUsd);\n return {\n sessions,\n requests: effects.length,\n write1hTokens: sum((effect) => effect.write1hTokens),\n repriceSavingUsd: sum((effect) => effect.repriceSavingUsd),\n rebuilds: effects.filter((effect) => effect.rebuildTokens > 0).length,\n rebuildTokens: sum((effect) => effect.rebuildTokens),\n rebuildCostUsd: sum((effect) => effect.rebuildCostUsd),\n netSavingUsd,\n netPerSessionUsd: sessions > 0 ? netSavingUsd / sessions : 0,\n };\n}\n\n/** Largest saving first, so the roles 5m would cost money sit at the bottom. */\nfunction buckets(rows: readonly TtlRequestRow[], effects: Map<TtlRequestRow, RequestEffect>, keyOf: (row: TtlRequestRow) => string): CacheTtlBucket[] {\n const groups = new Map<string, RequestEffect[]>();\n for (const row of rows) {\n const key = keyOf(row);\n const members = groups.get(key);\n if (members) members.push(effects.get(row)!);\n else groups.set(key, [effects.get(row)!]);\n }\n return [...groups]\n .map(([key, members]) => {\n const totals = sumEffects(members);\n return { key, ...totals, fiveMinuteLoses: totals.netSavingUsd < 0 };\n })\n .sort((a, b) => b.netSavingUsd - a.netSavingUsd || a.key.localeCompare(b.key));\n}\n\nconst IN_WINDOW = \"(@since IS NULL OR ts >= @since) AND (@until IS NULL OR ts < @until)\";\n\n// The miner leaves `gap_ms` null, so the gap falls back to the session's previous request, even one before the window.\nconst TTL_ROWS = `\n WITH member AS (SELECT DISTINCT session_id FROM request_dedup WHERE ${IN_WINDOW}),\n timed AS (\n SELECT session_id, model, ts, cache_read_tokens, cache_creation_1h, gap_ms,\n LAG(ts) OVER (PARTITION BY session_id, is_sidechain ORDER BY ts, request_id) AS previous_ts\n FROM request_dedup WHERE session_id IN member\n )\n SELECT session_id AS sessionId, model, ts, cache_read_tokens AS cacheReadTokens, cache_creation_1h AS cacheWrite1hTokens,\n COALESCE(gap_ms, CAST(ROUND((julianday(ts) - julianday(previous_ts)) * 86400000) AS INTEGER)) AS gapMs\n FROM timed WHERE ${IN_WINDOW}`;\n\n/** Reads the graph and never writes it; roles are the cost report's. */\nexport function cacheTtlReport(db: Db, options: CostReportOptions = {}, prices: readonly PriceRow[] = PRICE_TABLE): CacheTtlWhatIf {\n const window = resolveWindow(options);\n return { window, ...cacheTtlWhatIf(readTtlRows(db, window).filter(scopeFilter(db, options.scope)), prices) };\n}\n\nexport function readTtlRows(db: Db, window: ReportWindow): TtlRequestRow[] {\n const rows = db.prepare(TTL_ROWS).all(window) as Omit<TtlRequestRow, \"role\" | \"profile\">[];\n const contexts = readSessionContexts(db, [...new Set(rows.map((row) => row.sessionId))]);\n const tags = tagSessions(contexts);\n return rows.map((row) => ({\n ...row,\n role: tags.get(row.sessionId)!.role,\n profile: contexts.get(row.sessionId)!.facts.origin?.profile ?? NO_PROFILE,\n }));\n}\n\n/** One table per dimension; a role or profile 5m would cost money is marked `loss`. */\nexport function renderCacheTtlText(whatIf: CacheTtlWhatIf): string {\n const { totals, window } = whatIf;\n const span = window ? `, ${window.since ?? \"beginning\"} to ${window.until ?? \"now\"}` : \"\";\n const header = [\n `Cache TTL what-if, 5m against 1h${span}`,\n `Net ${usd(totals.netSavingUsd)} over ${totals.sessions} sessions: 1h writes repriced save ${usd(totals.repriceSavingUsd)}, ` +\n `${totals.rebuilds} rebuilds after gaps in ${whatIf.rebuildGapBands.join(\", \")} cost ${usd(totals.rebuildCostUsd)}`,\n `Roles where 5m loses: ${whatIf.lossRoles.join(\", \") || \"none\"}`,\n ].join(\"\\n\");\n const footer = `Price table v${whatIf.priceTableVersion}; ${whatIf.unpricedRequests} unpriced requests left out.`;\n return [header, ttlTable(\"By role\", whatIf.byRole), ttlTable(\"By profile\", whatIf.byProfile), [LIST_PRICE_CAVEAT, footer].join(\"\\n\")].join(\"\\n\\n\") + \"\\n\";\n}\n\nfunction ttlTable(title: string, rows: readonly CacheTtlBucket[]): string {\n const head = [\"key\", \"sessions\", \"requests\", \"reprice saving\", \"rebuilds\", \"rebuild cost\", \"net\", \"net per session\", \"5m\"];\n const cells = rows.map((b) => [b.key, b.sessions, b.requests, usd(b.repriceSavingUsd), b.rebuilds, usd(b.rebuildCostUsd), usd(b.netSavingUsd), usd(b.netPerSessionUsd), b.fiveMinuteLoses ? \"loss\" : \"saves\"]);\n return table(title, head, cells);\n}\n","import { z } from \"zod\";\n\n/** One reviewer verdict message, as agent-chat's events table records it. */\nexport interface VerdictRecord {\n eventId: number;\n at: string;\n /** The seat the verdict was sent to. */\n seat: string;\n reviewer: string;\n verdict: string;\n repo: string;\n pr: number;\n head: string;\n}\n\n/** A PR as GitHub REST reports it at the time of the run. */\nexport interface PullState {\n repo: string;\n pr: number;\n state: \"open\" | \"closed\";\n mergedAt: string | null;\n headSha: string;\n}\n\nexport type ParsedVerdict = Pick<VerdictRecord, \"verdict\" | \"repo\" | \"pr\" | \"head\">;\n\nconst VERDICT_LINE = /^Verdict:\\s*([A-Z_]+)/;\nconst PR_LINE = /^PR:\\s*(?:https:\\/\\/github\\.com\\/)?([\\w.-]+\\/[\\w.-]+)(?:#|\\/pull\\/)(\\d+)/m;\nconst HEAD_LINE = /^Head:\\s*`?([0-9a-f]{7,40})\\b/m;\n\n/** Reads a `Verdict:` message's first three lines; null when any of them is missing. */\nexport function parseVerdict(body: string): ParsedVerdict | null {\n const verdict = VERDICT_LINE.exec(body)?.[1];\n const pr = PR_LINE.exec(body);\n const head = HEAD_LINE.exec(body)?.[1];\n if (!verdict || !pr || !head) return null;\n return { verdict, repo: pr[1]!, pr: Number(pr[2]), head };\n}\n\nexport type MergeStatus = \"merged\" | \"open\" | \"stale-head\" | \"closed\" | \"unknown\";\n\n/** A PR holding at least one MERGE verdict, resolved against its GitHub state at `asOf`. */\nexport interface MergeOutcome {\n repo: string;\n pr: number;\n status: MergeStatus;\n /** The first MERGE verdict at the PR's final head; null when no verdict names that head. */\n verdict: VerdictRecord | null;\n /** Verdict to merge for merged PRs; verdict to `asOf` (a censored age) for open ones. */\n minutes: number | null;\n}\n\nconst MINUTE_MS = 60_000;\n\nexport function mergeOutcomes(verdicts: readonly VerdictRecord[], pulls: readonly PullState[], asOf: string): MergeOutcome[] {\n const byPr = new Map<string, VerdictRecord[]>();\n for (const v of verdicts) if (v.verdict === \"MERGE\") byPr.set(prKey(v), [...(byPr.get(prKey(v)) ?? []), v]);\n const pullByKey = new Map(pulls.map((p) => [prKey(p), p]));\n return [...byPr.values()].map((held) => outcome(held, pullByKey.get(prKey(held[0]!)), asOf));\n}\n\nexport function prKey(row: { repo: string; pr: number }): string {\n return `${row.repo}#${row.pr}`;\n}\n\nfunction outcome(held: VerdictRecord[], pull: PullState | undefined, asOf: string): MergeOutcome {\n const { repo, pr } = held[0]!;\n if (!pull) return { repo, pr, status: \"unknown\", verdict: null, minutes: null };\n const atHead = held.filter((v) => sameSha(v.head, pull.headSha)).sort((a, b) => a.at.localeCompare(b.at))[0];\n const mergedBy = pull.mergedAt !== null && pull.mergedAt <= asOf;\n if (!atHead) return { repo, pr, status: pull.mergedAt !== null || pull.state === \"open\" ? \"stale-head\" : \"closed\", verdict: null, minutes: null };\n if (mergedBy) return { repo, pr, status: \"merged\", verdict: atHead, minutes: Math.max(0, minutesBetween(atHead.at, pull.mergedAt!)) };\n if (pull.state === \"open\" || pull.mergedAt !== null) return { repo, pr, status: \"open\", verdict: atHead, minutes: minutesBetween(atHead.at, asOf) };\n return { repo, pr, status: \"closed\", verdict: atHead, minutes: null };\n}\n\nfunction sameSha(a: string, b: string): boolean {\n return a.startsWith(b) || b.startsWith(a);\n}\n\nfunction minutesBetween(from: string, to: string): number {\n return (Date.parse(to) - Date.parse(from)) / MINUTE_MS;\n}\n\nconst minutes = z.number().nullable();\n\nexport const latencyStatsSchema = z.object({\n merged: z.number().int().nonnegative(),\n medianMin: minutes,\n meanMin: minutes,\n p90Min: minutes,\n maxMin: minutes,\n /** Open PRs holding MERGE at their current head; their ages are lower bounds on the wait. */\n censored: z.number().int().nonnegative(),\n oldestCensoredMin: minutes,\n censoredPrMinutes: z.number().nonnegative(),\n /** Median over merged waits and censored ages together: a lower bound on the true median. */\n medianWithCensoredMin: minutes,\n});\n\nexport type LatencyStats = z.infer<typeof latencyStatsSchema>;\n\nexport function latencyStats(outcomes: readonly MergeOutcome[]): LatencyStats {\n const merged = sorted(outcomes.filter((o) => o.status === \"merged\").map((o) => o.minutes!));\n const censored = sorted(outcomes.filter((o) => o.status === \"open\").map((o) => o.minutes!));\n return {\n merged: merged.length,\n medianMin: median(merged),\n meanMin: merged.length === 0 ? null : round(merged.reduce((a, b) => a + b, 0) / merged.length),\n p90Min: nearestRank(merged, 0.9),\n maxMin: merged.at(-1) === undefined ? null : round(merged.at(-1)!),\n censored: censored.length,\n oldestCensoredMin: censored.at(-1) === undefined ? null : round(censored.at(-1)!),\n censoredPrMinutes: round(censored.reduce((a, b) => a + b, 0)),\n medianWithCensoredMin: median(sorted([...merged, ...censored])),\n };\n}\n\nfunction sorted(values: number[]): number[] {\n return values.sort((a, b) => a - b);\n}\n\nfunction median(values: readonly number[]): number | null {\n if (values.length === 0) return null;\n const mid = Math.floor(values.length / 2);\n return round(values.length % 2 === 1 ? values[mid]! : (values[mid - 1]! + values[mid]!) / 2);\n}\n\nfunction nearestRank(values: readonly number[], p: number): number | null {\n return values.length === 0 ? null : round(values[Math.ceil(p * values.length) - 1]!);\n}\n\nexport function round(value: number): number {\n return Math.round(value * 10) / 10;\n}\n","/** One action the auto-mode classifier refused, read from a seat's transcript. */\nexport interface DenialRecord {\n seat: string;\n at: string;\n /** The classifier's bracketed reason, such as \"Merge Without Review\". */\n reason: string;\n /** What the refused call was doing, from its tool input; the reason label alone is loose. */\n action: string;\n tool: string;\n}\n\nconst DENIAL = /^Permission for this action (?:was|has been) denied by the Claude Code auto mode classifier\\. Reason: \\[([^\\]]+)\\]/;\n\nconst BASH_ACTIONS: readonly (readonly [string, RegExp])[] = [\n [\"merge\", /\\bgh pr merge\\b|\\/pulls\\/\\d+\\/merge\\b/],\n [\"retire\", /\\bagent[ _-]retire\\b|\\bagent\\s+retire\\b/],\n [\"worktree-remove\", /\\bgit\\b.*\\bworktree (?:remove|prune)\\b/],\n [\"branch-delete\", /\\bgit branch -[dD]\\b|\\bpush\\b.*--delete\\b|\\/git\\/refs\\/heads\\/\\S*.*-X DELETE|-X DELETE\\b.*\\/git\\/refs\\//],\n [\"push\", /\\bgit\\b.*\\bpush\\b/],\n [\"github-write\", /\\bgh (?:pr|issue) (?:create|edit|comment|close)\\b|\\bgh api\\b.*(?:-X|--method)\\s*(?:POST|PATCH|PUT|DELETE)\\b/],\n [\"service-restart\", /\\bservice restart\\b|\\blaunchctl\\b/],\n [\"process-kill\", /\\b(?:pkill|kill)\\b/],\n [\"file-write\", /\\s>>?\\s*(?!\\/dev\\/null|&)\\S|\\bopen\\([^)]*[\"'][wa][\"']\\)|\\bsed -i\\b/],\n];\n\nconst FILE_TOOLS = new Set([\"Edit\", \"Write\", \"MultiEdit\", \"NotebookEdit\"]);\n\n/** Classifies a refused call by what it did; MCP tools keep their own short name. */\nexport function classifyDeniedAction(tool: string, input: unknown): string {\n if (tool === \"Bash\") return bashAction(String((input as { command?: unknown } | null)?.command ?? \"\"));\n if (FILE_TOOLS.has(tool)) return \"file-edit\";\n if (tool.startsWith(\"mcp__\")) return `mcp:${tool.split(\"__\").at(-1)}`;\n return `tool:${tool}`;\n}\n\nfunction bashAction(command: string): string {\n return BASH_ACTIONS.find(([, pattern]) => pattern.test(command))?.[0] ?? \"bash-other\";\n}\n\ninterface TranscriptEntry {\n timestamp?: string;\n message?: { content?: unknown };\n}\n\ninterface ContentBlock {\n type?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: unknown;\n}\n\n/** Scans transcript JSONL for classifier refusals and joins each to the tool call it refused. */\nexport function parseDenials(lines: Iterable<string>, seat: string): DenialRecord[] {\n const calls = new Map<string, { tool: string; input: unknown }>();\n const denials: DenialRecord[] = [];\n for (const line of lines) {\n if (!line.includes('\"tool_use\"') && !line.includes(\"auto mode classifier\")) continue;\n const entry = parseLine(line);\n for (const block of blocksOf(entry)) {\n if (block.type === \"tool_use\" && block.id) calls.set(block.id, { tool: block.name ?? \"unknown\", input: block.input });\n const reason = block.type === \"tool_result\" ? DENIAL.exec(resultText(block.content))?.[1] : undefined;\n if (reason === undefined) continue;\n const call = calls.get(block.tool_use_id ?? \"\") ?? { tool: \"unknown\", input: null };\n denials.push({ seat, at: entry?.timestamp ?? \"\", reason, action: classifyDeniedAction(call.tool, call.input), tool: call.tool });\n }\n }\n return denials;\n}\n\nfunction parseLine(line: string): TranscriptEntry | null {\n try {\n return JSON.parse(line) as TranscriptEntry;\n } catch {\n return null;\n }\n}\n\nfunction blocksOf(entry: TranscriptEntry | null): ContentBlock[] {\n const content = entry?.message?.content;\n return Array.isArray(content) ? (content as ContentBlock[]) : [];\n}\n\nfunction resultText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const first = (content as { type?: string; text?: string }[]).find((part) => part.type === \"text\");\n return first?.text ?? \"\";\n}\n","/** A seat journal line that states its implementer slot count, and why it did not fill a free slot. */\nexport interface SlotTick {\n seat: string;\n at: string;\n used: number;\n cap: number;\n reason: string;\n /** The journal line number, so a row can be checked against its source. */\n line: number;\n}\n\nexport interface SeatJournal {\n ticks: SlotTick[];\n /** The journal's last timestamped line; the final tick holds until then. */\n lastAt: string | null;\n}\n\nexport const UNSTATED_REASON = \"unstated\";\n\n/** A tick's count holds at most this long, so a dark seat is not read as an hour of idle slots. */\nexport const TICK_HOLD_MAX_MIN = 60;\n\nconst STAMP = /^(\\d{1,2}):(\\d{2})(?::(\\d{2}))?\\s/;\nconst IMPL = /\\bimpl(?:ementers?)?\\s+(\\d+)\\s*\\/\\s*(\\d+)/i;\nconst REASON = /\\b(?:no dispatch|dispatch 0)\\s*:\\s*([^.;(]+)/i;\n\n/**\n * Reads `HH:MM[:SS] ...` journal lines for the date the journal covers.\n * `utcOffsetMin` is the journal clock's offset east of UTC, such as -360 for UTC-6.\n */\nexport function parseSeatJournal(text: string, seat: string, date: string, utcOffsetMin: number): SeatJournal {\n const ticks: SlotTick[] = [];\n let lastAt: string | null = null;\n text.split(\"\\n\").forEach((raw, index) => {\n const stamp = STAMP.exec(raw);\n if (!stamp) return;\n const at = journalTime(date, stamp, utcOffsetMin);\n lastAt = at;\n const impl = IMPL.exec(raw);\n if (!impl) return;\n const used = Number(impl[1]);\n const cap = Number(impl[2]);\n const reason = used < cap ? (REASON.exec(raw)?.[1]?.trim().toLowerCase() ?? UNSTATED_REASON) : \"\";\n ticks.push({ seat, at, used, cap, reason, line: index + 1 });\n });\n return { ticks, lastAt };\n}\n\nfunction journalTime(date: string, stamp: RegExpExecArray, utcOffsetMin: number): string {\n const [year, month, day] = date.split(\"-\").map(Number);\n const local = Date.UTC(year!, month! - 1, day!, Number(stamp[1]), Number(stamp[2]), Number(stamp[3] ?? 0));\n return new Date(local - utcOffsetMin * 60_000).toISOString();\n}\n\nexport interface IdleSlotRow {\n seat: string;\n reason: string;\n slotMinutes: number;\n ticks: number;\n /** Journal line numbers of the ticks counted here. */\n lines: number[];\n}\n\n/** Free implementer slots times the minutes each tick's count held, clipped to the window. */\nexport function idleSlotMinutes(journals: readonly SeatJournal[], window: { since?: string; until?: string }): IdleSlotRow[] {\n const rows = new Map<string, IdleSlotRow>();\n for (const journal of journals) {\n journal.ticks.forEach((tick, i) => {\n const free = Math.max(0, tick.cap - tick.used);\n const held = heldMinutes(tick.at, journal.ticks[i + 1]?.at ?? journal.lastAt ?? tick.at, window);\n if (free === 0 || held <= 0) return;\n const key = `${tick.seat}\\u0000${tick.reason}`;\n const row = rows.get(key) ?? { seat: tick.seat, reason: tick.reason, slotMinutes: 0, ticks: 0, lines: [] };\n rows.set(key, { ...row, slotMinutes: row.slotMinutes + free * held, ticks: row.ticks + 1, lines: [...row.lines, tick.line] });\n });\n }\n return [...rows.values()].map((r) => ({ ...r, slotMinutes: Math.round(r.slotMinutes) })).sort((a, b) => b.slotMinutes - a.slotMinutes);\n}\n\nfunction heldMinutes(from: string, to: string, window: { since?: string; until?: string }): number {\n const start = Math.max(Date.parse(from), window.since ? Date.parse(window.since) : -Infinity);\n const capped = Math.min(Date.parse(to), Date.parse(from) + TICK_HOLD_MAX_MIN * 60_000);\n const end = Math.min(capped, window.until ? Date.parse(window.until) : Infinity);\n return Math.max(0, (end - start) / 60_000);\n}\n","import { z } from \"zod\";\nimport { latencyStats, latencyStatsSchema, mergeOutcomes, round, type LatencyStats, type MergeOutcome, type PullState, type VerdictRecord } from \"./blocked-flow-merge.js\";\nimport type { DenialRecord } from \"./blocked-flow-denials.js\";\nimport { TICK_HOLD_MAX_MIN, idleSlotMinutes, type SeatJournal } from \"./blocked-flow-idle.js\";\nimport { LIST_PRICE_CAVEAT, table } from \"./render-text.js\";\n\n/** Where each section's numbers come from: the command that re-reads them and the field it reads. */\nexport const BLOCKED_FLOW_SOURCES = {\n verdicts: {\n command: `sqlite3 -readonly <events.db> \"SELECT id, ts, target, body FROM events WHERE kind='message' AND body LIKE 'Verdict:%'\"`,\n field: \"events.ts, events.target, events.body lines Verdict:, PR:, Head:\",\n },\n pulls: { command: \"gh api repos/<owner>/<repo>/pulls/<n>\", field: \".state, .merged_at, .head.sha\" },\n denials: {\n command: \"grep 'auto mode classifier. Reason: \\\\[' <seat transcript>.jsonl\",\n field: \"tool_result.content Reason: [<class>], joined to tool_use.input by tool_use_id\",\n },\n journals: { command: \"grep -nE 'impl [0-9]+/[0-9]+' <seat journal>.md\", field: \"impl <used>/<cap>, No dispatch: <reason>\" },\n} as const;\n\nexport type BlockedFlowSource = keyof typeof BLOCKED_FLOW_SOURCES;\n\nexport interface BlockedFlowInput {\n verdicts: readonly VerdictRecord[];\n pulls: readonly PullState[];\n denials: readonly DenialRecord[];\n journals: readonly SeatJournal[];\n /** Waits are measured to here; a PR merged later counts as open. */\n asOf: string;\n window?: { since?: string; until?: string };\n /** Splits verdict-to-merge by verdict time, such as the moment a seat was granted merge authority. */\n splitAt?: string;\n /** Keeps only verdicts sent to, and denials and journals of, these seats. */\n seats?: readonly string[];\n}\n\nconst source = z.enum([\"verdicts\", \"pulls\", \"denials\", \"journals\"]);\nconst count = z.number().int().nonnegative();\n\nconst latencyRowSchema = z.object({\n repo: z.string(),\n prs: count,\n staleHead: count,\n closed: count,\n unknown: count,\n all: latencyStatsSchema,\n before: latencyStatsSchema.optional(),\n after: latencyStatsSchema.optional(),\n});\n\nconst openRowSchema = z.object({\n repo: z.string(),\n pr: count,\n head: z.string(),\n seat: z.string(),\n verdictAt: z.string(),\n ageMin: z.number(),\n eventId: count,\n});\n\nexport const blockedFlowSchema = z.object({\n asOf: z.string(),\n window: z.object({ since: z.string().optional(), until: z.string().optional() }),\n splitAt: z.string().optional(),\n sources: z.record(source, z.object({ command: z.string(), field: z.string() })),\n verdictToMerge: z.object({ cites: z.array(source), rows: z.array(latencyRowSchema) }),\n openHoldingMerge: z.object({ cites: z.array(source), prMinutes: z.number(), rows: z.array(openRowSchema) }),\n denials: z.object({\n cites: z.array(source),\n total: count,\n rows: z.array(z.object({ reason: z.string(), action: z.string(), seat: z.string(), count })),\n }),\n idleSlots: z.object({\n cites: z.array(source),\n holdMaxMin: z.number(),\n total: z.number(),\n rows: z.array(z.object({ seat: z.string(), reason: z.string(), slotMinutes: z.number(), ticks: count, lines: z.array(count) })),\n }),\n});\n\nexport type BlockedFlowReport = z.infer<typeof blockedFlowSchema>;\nexport type LatencyRow = z.infer<typeof latencyRowSchema>;\n\nexport const ALL_REPOS = \"all\";\n\n/** Per repo: verdict-to-merge waits, PRs still holding MERGE, classifier denials and idle implementer slots. */\nexport function blockedFlowReport(input: BlockedFlowInput): BlockedFlowReport {\n const window = input.window ?? {};\n const inScope = scopeTest(input.seats, window);\n const outcomes = mergeOutcomes(input.verdicts.filter((v) => inScope(v.seat, v.at)), input.pulls, input.asOf);\n const open = openRows(outcomes);\n const journals = input.journals.map((j) => ({ ...j, ticks: j.ticks.filter((t) => inScope(t.seat)) }));\n const idle = idleSlotMinutes(journals, window);\n return {\n asOf: input.asOf,\n window,\n ...(input.splitAt ? { splitAt: input.splitAt } : {}),\n sources: BLOCKED_FLOW_SOURCES,\n verdictToMerge: { cites: [\"verdicts\", \"pulls\"], rows: latencyRows(outcomes, input.splitAt) },\n openHoldingMerge: { cites: [\"verdicts\", \"pulls\"], prMinutes: round(open.reduce((sum, r) => sum + r.ageMin, 0)), rows: open },\n denials: denialSection(input.denials.filter((d) => inScope(d.seat, d.at))),\n idleSlots: { cites: [\"journals\"], holdMaxMin: TICK_HOLD_MAX_MIN, total: idle.reduce((sum, r) => sum + r.slotMinutes, 0), rows: idle },\n };\n}\n\nfunction scopeTest(seats: readonly string[] | undefined, window: { since?: string; until?: string }) {\n const named = seats ? new Set(seats) : null;\n return (seat: string, at?: string): boolean =>\n (!named || named.has(seat)) && (at === undefined || ((!window.since || at >= window.since) && (!window.until || at < window.until)));\n}\n\nfunction latencyRows(outcomes: readonly MergeOutcome[], splitAt: string | undefined): LatencyRow[] {\n const repos = [...new Set(outcomes.map((o) => o.repo))];\n const rows = repos.map((repo) => latencyRow(repo, outcomes.filter((o) => o.repo === repo), splitAt));\n return [...rows.sort((a, b) => b.prs - a.prs || a.repo.localeCompare(b.repo)), latencyRow(ALL_REPOS, outcomes, splitAt)];\n}\n\nfunction latencyRow(repo: string, outcomes: readonly MergeOutcome[], splitAt: string | undefined): LatencyRow {\n const status = (s: string) => outcomes.filter((o) => o.status === s).length;\n const row: LatencyRow = { repo, prs: outcomes.length, staleHead: status(\"stale-head\"), closed: status(\"closed\"), unknown: status(\"unknown\"), all: latencyStats(outcomes) };\n if (!splitAt) return row;\n const timed = outcomes.filter((o) => o.verdict !== null);\n return { ...row, before: latencyStats(timed.filter((o) => o.verdict!.at < splitAt)), after: latencyStats(timed.filter((o) => o.verdict!.at >= splitAt)) };\n}\n\nfunction openRows(outcomes: readonly MergeOutcome[]): BlockedFlowReport[\"openHoldingMerge\"][\"rows\"] {\n return outcomes\n .filter((o) => o.status === \"open\")\n .map((o) => ({ repo: o.repo, pr: o.pr, head: o.verdict!.head, seat: o.verdict!.seat, verdictAt: o.verdict!.at, ageMin: round(o.minutes!), eventId: o.verdict!.eventId }))\n .sort((a, b) => b.ageMin - a.ageMin);\n}\n\nfunction denialSection(denials: readonly DenialRecord[]): BlockedFlowReport[\"denials\"] {\n const counts = new Map<string, { reason: string; action: string; seat: string; count: number }>();\n for (const d of denials) {\n const key = [d.reason, d.action, d.seat].join(\"\\u0000\");\n const row = counts.get(key) ?? { reason: d.reason, action: d.action, seat: d.seat, count: 0 };\n counts.set(key, { ...row, count: row.count + 1 });\n }\n const rows = [...counts.values()].sort((a, b) => b.count - a.count || a.reason.localeCompare(b.reason) || a.action.localeCompare(b.action));\n return { cites: [\"denials\"], total: denials.length, rows };\n}\n\n/** Each table's title names the JSON field its numbers come from; the sources close the report. */\nexport function renderBlockedFlowText(report: BlockedFlowReport): string {\n const scope = `Blocked flow as of ${report.asOf}${report.window.since ? `, since ${report.window.since}` : \"\"}${report.window.until ? `, until ${report.window.until}` : \"\"}`;\n const latency = [latencyTable(\"Verdict to merge, minutes from the first MERGE at the final head [verdictToMerge.rows[].all]\", report.verdictToMerge.rows, \"all\")];\n if (report.splitAt) latency.push(...([\"before\", \"after\"] as const).map((part) => latencyTable(`Verdict to merge, verdicts ${part} ${report.splitAt} [verdictToMerge.rows[].${part}]`, report.verdictToMerge.rows, part)));\n return [scope, ...latency, openTable(report), denialTable(report), idleTable(report), sourceLines(report), LIST_PRICE_CAVEAT].join(\"\\n\\n\") + \"\\n\";\n}\n\nfunction latencyTable(title: string, rows: readonly LatencyRow[], part: \"all\" | \"before\" | \"after\"): string {\n const cells = rows.map((r) => [r.repo, r.prs, ...statCells(r[part]!), r.staleHead]);\n return table(title, [\"repo\", \"prs\", \"merged\", \"median\", \"mean\", \"p90\", \"max\", \"open\", \"oldest open\", \"median incl. open\", \"stale head\"], cells);\n}\n\nfunction statCells(s: LatencyStats): (string | number)[] {\n const n = (v: number | null) => (v === null ? \"-\" : v);\n return [s.merged, n(s.medianMin), n(s.meanMin), n(s.p90Min), n(s.maxMin), s.censored, n(s.oldestCensoredMin), n(s.medianWithCensoredMin)];\n}\n\nfunction openTable(report: BlockedFlowReport): string {\n const rows = report.openHoldingMerge.rows.map((r) => [r.repo, `#${r.pr}`, r.head.slice(0, 7), r.seat, r.verdictAt, r.ageMin, `events#${r.eventId}`]);\n const title = `Open PRs holding MERGE at their current head, ${report.openHoldingMerge.prMinutes} PR-minutes [openHoldingMerge.rows[].ageMin]`;\n return table(title, [\"repo\", \"pr\", \"head\", \"seat\", \"verdict at\", \"age min\", \"verdict\"], rows);\n}\n\nfunction denialTable(report: BlockedFlowReport): string {\n const rows = report.denials.rows.map((r) => [r.reason, r.action, r.seat, r.count]);\n return table(`Classifier denials, ${report.denials.total} in all [denials.rows[].count]`, [\"reason\", \"action\", \"seat\", \"count\"], rows);\n}\n\nfunction idleTable(report: BlockedFlowReport): string {\n const rows = report.idleSlots.rows.map((r) => [r.seat, r.reason, r.slotMinutes, r.ticks, r.lines.join(\",\")]);\n const title = `Idle implementer slot-minutes by stated reason, ${report.idleSlots.total} in all, each tick held at most ${report.idleSlots.holdMaxMin} min [idleSlots.rows[].slotMinutes]`;\n return table(title, [\"seat\", \"reason\", \"slot-min\", \"ticks\", \"journal lines\"], rows);\n}\n\nfunction sourceLines(report: BlockedFlowReport): string {\n return [\"Sources\", ...Object.entries(report.sources).map(([name, s]) => `${name}: ${s.command} (${s.field})`)].join(\"\\n\");\n}\n"],"mappings":"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","names":["z","agentSessions","costOf","z","count","z","groupBy","count","z","byCostThenKey","buckets","gapBand","buckets","fraction","z","MTOK","count","z","bucketSchema","IN_WINDOW","header","footer","z","MINUTE_MS","z","z","count"]}
|