/**
 * Group-by dimensions + time-to-first-tool latency for the traces insight
 * engine (the console's Issue bar).
 *
 * Pure functions, no I/O. Classifiers are DATA-DRIVEN TABLES — a new task type
 * or timing bucket is a row, not a new if/else-by-name arm. The integrator
 * (`insights.ts` / `sync.ts`) tags each session; this file does not write the
 * shard.
 *
 * Input is the redacted `SessionDetail` from `agents traces sync` plus the
 * SyncRow fields the detail strips (prompt, gitBranch, files). Structural —
 * `SessionDetail` is a valid `SegmentSession`.
 */
export declare const TASK_TYPES: readonly ["bugfix", "feature", "refactor", "test", "chore", "other"];
export type TaskType = (typeof TASK_TYPES)[number];
export declare const FAILURE_TIMINGS: readonly ["early", "mid", "late"];
export type FailureTiming = (typeof FAILURE_TIMINGS)[number];
/** The #1 group-by axis: compare the pair, never the model alone. */
export interface SegmentAgent {
    model: string;
    harness: string;
}
export interface SegmentFile {
    path: string;
    /** Write/create vs Edit/patch. */
    action: 'new' | 'edit';
}
export interface SegmentStep {
    startMs: number;
    durationMs?: number;
    outcome?: 'ok' | 'error' | 'unknown' | string;
    tool?: string;
    kind?: 'tool' | 'thinking' | string;
    label?: string;
}
/**
 * Session shape the classifiers read. `SessionDetail` (sessions/<id>.json)
 * satisfies this; callers may also pass SyncRow fields (`prompt`, `gitBranch`,
 * `agent`, `model`, `files`) alongside steps.
 */
export interface SegmentSession {
    id?: string;
    prompt?: string | null;
    gitBranch?: string | null;
    topic?: string | null;
    label?: string | null;
    mode?: string | null;
    agent?: string | null;
    harness?: string | null;
    model?: string | null;
    spanMs?: number | null;
    files?: readonly SegmentFile[] | null;
    meta?: {
        agent?: string | null;
        model?: string | null;
        spanMs?: number | null;
        repo?: string | null;
        tools?: number | null;
    } | null;
    steps?: readonly SegmentStep[] | null;
    whereItWentWrong?: string | null;
}
export interface Percentiles {
    p50: number;
    p90: number;
    p99: number;
    max: number;
}
/** Time-to-first-tool latency — `steps[0].startMs` over tool-using sessions. */
export interface LatencyInsight {
    firstToolMs: Percentiles;
}
export interface SegmentDimensions {
    agent: SegmentAgent;
    taskType: TaskType;
    failureTiming: FailureTiming | null;
}
/**
 * Tool name → file action. Lowercased. Write-family is a new file; Edit-family
 * is a patch. Anything else is ignored for diff-shape.
 */
export declare const FILE_ACTION_TOOLS: ReadonlyArray<{
    action: SegmentFile['action'];
    tools: readonly string[];
}>;
type DiffShape = {
    files: readonly SegmentFile[];
    testOnly: boolean;
    newOnly: boolean;
    choreOnly: boolean;
};
/**
 * Task-type rules, first match wins. Prompt/branch keywords outrank diff shape
 * except where `shape` is set (test-only files, chore-only files, all-new files).
 *
 * Order is the product priority: test-only work is not a "feature"; a `fix/`
 * branch is a bugfix even if files are new; chore lockfile edits are not features.
 */
export declare const TASK_TYPE_RULES: ReadonlyArray<{
    type: Exclude<TaskType, 'other'>;
    patterns: readonly RegExp[];
    shape?: keyof Pick<DiffShape, 'testOnly' | 'newOnly' | 'choreOnly'>;
}>;
/**
 * Normalized position of the first failing step inside the session span.
 * Early failures cascade — highest-signal bucket. Exclusive upper bound.
 */
export declare const FAILURE_TIMING_BUCKETS: ReadonlyArray<{
    timing: FailureTiming;
    maxExclusive: number;
}>;
/** Model × harness unit — the #1 group-by axis. */
export declare function deriveAgent(session: SegmentSession): SegmentAgent;
/**
 * Classify the session's work from the opening prompt + diff shape (files
 * touched, new vs edit, test-only). First matching table row wins.
 */
export declare function classifyTaskType(session: SegmentSession): TaskType;
/**
 * Bucket the FIRST failing step by its normalized position in the session
 * span (`firstFailure.startMs / spanMs`). Sessions with no failing step
 * return null — they do not belong on the failure-timing axis.
 */
export declare function failureTiming(session: SegmentSession): FailureTiming | null;
/**
 * Time-to-first-tool latency from `steps[0].startMs` across sessions that
 * recorded at least one step. Nearest-rank percentiles (same formula as the
 * traces index stats) so p99 on `/tmp/traces-real` lands at ~128s.
 */
export declare function computeLatency(sessions: readonly SegmentSession[]): LatencyInsight;
/** All three group-by dimensions for one session. */
export declare function deriveDimensions(session: SegmentSession): SegmentDimensions;
export {};
