/** * `src/services/observability/aggregation-types.ts` * * The result shapes of the read-side aggregations over observability events * (`aggregation.ts`), plus the data they are built from: the slice lifecycle * terminal states, the RD/QA repair-loop cap, and the zeroed fan-out row. * Extracted verbatim (wave 3, file-size cap campaign) so the aggregation * module stays under the 300 raw-line cap — no aggregation logic lives here. * `aggregation.ts` imports and re-exports every PUBLIC name below, so * importers keep resolving them from `aggregation.js` unchanged; the * module-private constants are imported for use and stay unexported there. */ import type { ObservabilitySubagentRole } from './observability-service.js'; export type StatusAggregate = { totalEvents: number; totalSlices: number; successCount: number; failCount: number; repairCyclePeak: number; fanoutCostTotal: number; }; export type SliceRollup = { sliceRid: string; transitions: number; firstTs: string | null; lastTs: string | null; durationMs: number | null; finalState: string | null; fanoutCount: number; repairCycleCount: number; success: boolean; }; export type FanoutBreakdown = { total: number; perRole: Record; }; /** * The v1 convention, kept alive under a name that says what it is. It counts * slice-transition events whose `detail.artifactRole === 'qa'` — QA's own * internal state transitions, doubled by the duplicate emission, and NOT a * repair-cycle count. It exists so the v1 and v2 numbers can be compared side * by side instead of being compared by accident. */ export type LegacyQaEventCount = { metric: 'qa-role-transition-event-count'; metricVersion: 1; note: string; total: number; peak: number; capHitCount: number; perSlice: Array<{ sliceRid: string; eventCount: number; }>; }; /** * QA phases, reported separately from repair cycles: `qa-handoff → * verdict-issued → qa-handoff` is a QA round, not an RD rework. */ export type QaRoundSummary = { metric: 'qa-rounds'; total: number; peak: number; perSlice: Array<{ sliceRid: string; roundCount: number; }>; }; export type RepairCycleReport = { metric: 'repair-cycles'; /** Which convention produced the numbers below. */ metricVersion: number; /** What the metric counts, in one sentence. */ definition: string; totalCycles: number; cap: number; capHit: boolean; /** Slices at or over the cap — computed from the v2 metric. */ capHitCount: number; perSlice: Array<{ sliceRid: string; cycleCount: number; }>; qaRounds: QaRoundSummary; legacyQaEventCount: LegacyQaEventCount; }; export declare const TERMINAL_HAPPY_STATES: ReadonlySet; export declare const TERMINAL_FAIL_STATES: ReadonlySet; /** RD/QA repair-loop cap (matches the peaks-code repair-loop contract). */ export declare const REPAIR_CYCLE_CAP = 3; export declare const ZERO_FANOUT: Record; export type Period = 'day' | 'week' | 'month'; /** * Cumulative 5-metric surface for the `peaks dashboard summary` CLI. * All values are derived from raw observability events (per-event * counting), not from state files — semantics differ from * `peaks dashboard long-run`, which derives indicators from * `.peaks/_runtime//24h-state.json`. */ export type DashboardMetrics = { readonly cycleCount: number; readonly tokenCount: number; readonly dispatchCount: number; readonly compactCount: number; readonly monotonicTriggerCount: number; };