import { z } from 'zod';
/**
 * Local mirror of SseTransportEvent from './sse/common'. Re-defining the
 * three-field interface avoids a cross-file relative import inside this leaf
 * module: the daemon walks this file via the './critique' subpath export
 * under NodeNext (which requires explicit '.js' extensions), while the web
 * Turbopack build refuses to rewrite '.js' to '.ts' on the same source.
 * Keeping the type local makes the file self-contained for both consumers.
 */
interface SseTransportEvent<Name extends string, Payload> {
    id?: string;
    event: Name;
    data: Payload;
}
export declare const PANELIST_ROLES: readonly ["designer", "critic", "brand", "a11y", "copy"];
export type PanelistRole = typeof PANELIST_ROLES[number];
export declare const FALLBACK_POLICIES: readonly ["ship_best", "ship_last", "fail"];
export type FallbackPolicy = typeof FALLBACK_POLICIES[number];
export declare const CRITIQUE_PROTOCOL_VERSION = 1;
export declare const RoleWeights: z.ZodObject<{
    designer: z.ZodNumber;
    critic: z.ZodNumber;
    brand: z.ZodNumber;
    a11y: z.ZodNumber;
    copy: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    designer: number;
    critic: number;
    brand: number;
    a11y: number;
    copy: number;
}, {
    designer: number;
    critic: number;
    brand: number;
    a11y: number;
    copy: number;
}>;
export type RoleWeights = z.infer<typeof RoleWeights>;
export declare const CritiqueConfigSchema: z.ZodEffects<z.ZodObject<{
    enabled: z.ZodBoolean;
    cast: z.ZodArray<z.ZodEnum<["designer", "critic", "brand", "a11y", "copy"]>, "many">;
    maxRounds: z.ZodNumber;
    scoreScale: z.ZodNumber;
    scoreThreshold: z.ZodNumber;
    weights: z.ZodObject<{
        designer: z.ZodNumber;
        critic: z.ZodNumber;
        brand: z.ZodNumber;
        a11y: z.ZodNumber;
        copy: z.ZodNumber;
    }, "strip", z.ZodTypeAny, {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    }, {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    }>;
    perRoundTimeoutMs: z.ZodNumber;
    totalTimeoutMs: z.ZodNumber;
    parserMaxBlockBytes: z.ZodNumber;
    fallbackPolicy: z.ZodEnum<["ship_best", "ship_last", "fail"]>;
    protocolVersion: z.ZodNumber;
    maxConcurrentRuns: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    enabled: boolean;
    cast: ("designer" | "critic" | "brand" | "a11y" | "copy")[];
    maxRounds: number;
    scoreScale: number;
    scoreThreshold: number;
    weights: {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    };
    perRoundTimeoutMs: number;
    totalTimeoutMs: number;
    parserMaxBlockBytes: number;
    fallbackPolicy: "ship_best" | "ship_last" | "fail";
    protocolVersion: number;
    maxConcurrentRuns: number;
}, {
    enabled: boolean;
    cast: ("designer" | "critic" | "brand" | "a11y" | "copy")[];
    maxRounds: number;
    scoreScale: number;
    scoreThreshold: number;
    weights: {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    };
    perRoundTimeoutMs: number;
    totalTimeoutMs: number;
    parserMaxBlockBytes: number;
    fallbackPolicy: "ship_best" | "ship_last" | "fail";
    protocolVersion: number;
    maxConcurrentRuns: number;
}>, {
    enabled: boolean;
    cast: ("designer" | "critic" | "brand" | "a11y" | "copy")[];
    maxRounds: number;
    scoreScale: number;
    scoreThreshold: number;
    weights: {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    };
    perRoundTimeoutMs: number;
    totalTimeoutMs: number;
    parserMaxBlockBytes: number;
    fallbackPolicy: "ship_best" | "ship_last" | "fail";
    protocolVersion: number;
    maxConcurrentRuns: number;
}, {
    enabled: boolean;
    cast: ("designer" | "critic" | "brand" | "a11y" | "copy")[];
    maxRounds: number;
    scoreScale: number;
    scoreThreshold: number;
    weights: {
        designer: number;
        critic: number;
        brand: number;
        a11y: number;
        copy: number;
    };
    perRoundTimeoutMs: number;
    totalTimeoutMs: number;
    parserMaxBlockBytes: number;
    fallbackPolicy: "ship_best" | "ship_last" | "fail";
    protocolVersion: number;
    maxConcurrentRuns: number;
}>;
export type CritiqueConfig = z.infer<typeof CritiqueConfigSchema>;
export declare function defaultCritiqueConfig(): CritiqueConfig;
export declare const DEGRADED_REASONS: readonly ["malformed_block", "oversize_block", "adapter_unsupported", "protocol_version_mismatch", "missing_artifact"];
export type DegradedReason = typeof DEGRADED_REASONS[number];
export declare const FAILED_CAUSES: readonly ["cli_exit_nonzero", "per_round_timeout", "total_timeout", "orchestrator_internal"];
export type FailedCause = typeof FAILED_CAUSES[number];
export declare const PARSER_WARNING_KINDS: readonly ["weak_debate", "unknown_role", "score_clamped", "composite_mismatch", "duplicate_ship"];
export type ParserWarningKind = typeof PARSER_WARNING_KINDS[number];
export declare const ROUND_DECISIONS: readonly ["continue", "ship"];
export type RoundDecision = typeof ROUND_DECISIONS[number];
export declare const SHIP_STATUSES: readonly ["shipped", "below_threshold", "timed_out", "interrupted"];
export type ShipStatus = typeof SHIP_STATUSES[number];
export type PanelEvent = {
    type: 'run_started';
    runId: string;
    protocolVersion: number;
    cast: PanelistRole[];
    maxRounds: number;
    threshold: number;
    scale: number;
} | {
    type: 'panelist_open';
    runId: string;
    round: number;
    role: PanelistRole;
} | {
    type: 'panelist_dim';
    runId: string;
    round: number;
    role: PanelistRole;
    dimName: string;
    dimScore: number;
    dimNote: string;
} | {
    type: 'panelist_must_fix';
    runId: string;
    round: number;
    role: PanelistRole;
    text: string;
} | {
    type: 'panelist_close';
    runId: string;
    round: number;
    role: PanelistRole;
    score: number;
} | {
    type: 'round_end';
    runId: string;
    round: number;
    composite: number;
    mustFix: number;
    decision: RoundDecision;
    reason: string;
} | {
    type: 'ship';
    runId: string;
    round: number;
    composite: number;
    status: ShipStatus;
    artifactRef: {
        projectId: string;
        artifactId: string;
    };
    summary: string;
} | {
    type: 'degraded';
    runId: string;
    reason: DegradedReason;
    adapter: string;
} | {
    type: 'interrupted';
    runId: string;
    bestRound: number;
    composite: number;
} | {
    type: 'failed';
    runId: string;
    cause: FailedCause;
} | {
    type: 'parser_warning';
    runId: string;
    kind: ParserWarningKind;
    position: number;
};
/**
 * Strict runtime guard for the `PanelEvent` union. Validates the union tag
 * (`type`), the non-empty `runId` header, every variant-specific required
 * field, the membership of closed-enum fields (`role`, `status`, `reason`,
 * `cause`, `kind`, `decision`), and the numeric domain of every numeric
 * field (integer / positive / non-negative / range), not just finiteness.
 *
 * This is the single source of truth for wire-side validation. Both the web
 * SSE path (`sseToPanelEvent`) and the transcript replay parser go through
 * here, so a malformed frame (missing field, unknown enum value, NaN /
 * Infinity score, `scale: 0` causing downstream divide-by-zero, threshold
 * outside `[0, scale]`, fractional or negative round numbers) is rejected
 * before any reducer or component touches it.
 *
 * Numeric domains enforced (lefarcen P2 on PR #1314 round 4):
 *
 *   - `protocolVersion`, `maxRounds`, `scale`, `round`: positive integers.
 *     ScoreTicker divides by `scale` for inline CSS, so a `scale: 0` would
 *     produce Infinity and ship as broken style; rounds are 1-indexed.
 *   - `bestRound`, `mustFix`, `position`: non-negative integers. `bestRound:
 *     0` is the valid "interrupt before any round closed" sentinel.
 *   - `threshold`: non-negative finite; cross-checked `threshold <= scale`
 *     inside `run_started`. Threshold is allowed to be fractional (e.g.
 *     8.5 on a scale of 10).
 *   - `composite`, `score`, `dimScore`: non-negative finite. The
 *     `<= scale` bound is per-run state the guard does not see; downstream
 *     code clamps to scale on render, but a negative score is never valid.
 *
 * Earlier review history:
 *
 *   - Siri-Ray round-3 P1: the original guard checked `typeof === 'string'`
 *     for enum fields and accepted unknown values; now validated against
 *     the closed-set arrays.
 */
export declare function isPanelEvent(value: unknown): value is PanelEvent;
type PayloadOf<T extends PanelEvent['type']> = Omit<Extract<PanelEvent, {
    type: T;
}>, 'type'>;
export type CritiqueSseEvent = SseTransportEvent<'critique.run_started', PayloadOf<'run_started'>> | SseTransportEvent<'critique.panelist_open', PayloadOf<'panelist_open'>> | SseTransportEvent<'critique.panelist_dim', PayloadOf<'panelist_dim'>> | SseTransportEvent<'critique.panelist_must_fix', PayloadOf<'panelist_must_fix'>> | SseTransportEvent<'critique.panelist_close', PayloadOf<'panelist_close'>> | SseTransportEvent<'critique.round_end', PayloadOf<'round_end'>> | SseTransportEvent<'critique.ship', PayloadOf<'ship'>> | SseTransportEvent<'critique.degraded', PayloadOf<'degraded'>> | SseTransportEvent<'critique.interrupted', PayloadOf<'interrupted'>> | SseTransportEvent<'critique.failed', PayloadOf<'failed'>> | SseTransportEvent<'critique.parser_warning', PayloadOf<'parser_warning'>>;
export declare const CRITIQUE_SSE_EVENT_NAMES: readonly ["critique.run_started", "critique.panelist_open", "critique.panelist_dim", "critique.panelist_must_fix", "critique.panelist_close", "critique.round_end", "critique.ship", "critique.degraded", "critique.interrupted", "critique.failed", "critique.parser_warning"];
export type CritiqueSseEventName = typeof CRITIQUE_SSE_EVENT_NAMES[number];
export declare function panelEventToSse(e: PanelEvent): CritiqueSseEvent;
/**
 * Per-round summary persisted with each critique run. Mirrors the shape the
 * orchestrator writes via decideRound; web clients consume it through the
 * rerun and history endpoints, so it lives in the shared contract layer.
 */
export interface CritiqueRoundSummary {
    n: number;
    composite: number;
    mustFix: number;
    decision: RoundDecision;
}
/**
 * Terminal critique status persisted with each run. Superset of ShipStatus
 * that also covers degraded / failed / legacy outcomes. The daemon's CHECK
 * constraint also accepts the in-flight 'running' value, but that is handled
 * inline by daemon-side code; the public contract surface is terminal-only
 * because every consumer of this type works against finished runs.
 */
export type CritiqueRunStatus = ShipStatus | 'degraded' | 'failed' | 'legacy';
/**
 * Enumeration of every terminal CritiqueRunStatus value, in the order the
 * UI / docs / status filters typically display them: SHIP outcomes first
 * (shipped → below_threshold → timed_out → interrupted), then quality /
 * lifecycle exits (degraded → failed), then the historical 'legacy' tag
 * for runs created before the feature shipped. Web consumers (status
 * filters, analytics dashboards) iterate this constant directly so the
 * daemon stays the single source of truth on the order.
 */
export declare const CRITIQUE_RUN_STATUSES: readonly ["shipped", "below_threshold", "timed_out", "interrupted", "degraded", "failed", "legacy"];
/**
 * Compile-time guarantee that every `CritiqueRunStatus` variant appears in
 * `CRITIQUE_RUN_STATUSES`. `satisfies` only proves each listed value is
 * valid; this assertion proves the list is exhaustive, so adding a new
 * variant to `CritiqueRunStatus` (or `ShipStatus`) without updating the
 * array fails the build with a tuple naming the missing variants. Picked
 * up from lefarcen P3 on PR #1016. The exported helper type is reusable
 * by other shared enums (e.g. `PANELIST_ROLES`) once they need the same
 * guard.
 */
export type AssertExhaustiveValues<T extends string, U extends readonly T[]> = Exclude<T, U[number]> extends never ? true : ['Missing variants in array:', Exclude<T, U[number]>];
/**
 * Internal-to-the-daemon row status. Adds the in-flight `'running'` value
 * the DB CHECK constraint accepts to the public `CritiqueRunStatus` union
 * so DB-row types can be precisely typed without inline `as X | 'running'`
 * widens at every call site. Every public DTO continues to use the
 * terminal-only `CritiqueRunStatus` so a future endpoint cannot leak a
 * 'running' row through the wire. Picked up from lefarcen P2 on PR #1016.
 */
export type CritiquePersistedStatus = CritiqueRunStatus | 'running';
/**
 * Logical handle the daemon hands to the web layer for a critique run's
 * shipped artifact. Web clients never see daemon filesystem paths; they
 * fetch the artifact bytes via the `url` field, which the daemon serves
 * with the right `Content-Type` header derived from `mime`. Returned by
 * the rerun endpoint and the `GET /api/projects/:projectId/critique/:runId/artifact`
 * route that streams the bytes.
 */
export interface CritiqueArtifactRef {
    /** The owning project; matches the URL segment. */
    projectId: string;
    /** The owning critique run; matches the URL segment. */
    runId: string;
    /** Content-Type announced by the agent in `<ARTIFACT mime="…">`. */
    mime: string;
    /** Size of the artifact body in bytes, as written to disk. */
    sizeBytes: number;
    /** Daemon-relative HTTP path the web layer fetches to stream the bytes. */
    url: string;
}
export {};
//# sourceMappingURL=critique.d.ts.map