import type { Signal, ToolShortId } from '@opensip-tools/core'; /** * Run-level verdict header. `passed` ⇔ "no `critical`/`high` signals"; * `score` is the canonical {@link passRate} over `summary`. */ export interface RunVerdict { readonly score: number; readonly passed: boolean; readonly summary: { readonly total: number; readonly passed: number; readonly failed: number; readonly errors: number; readonly warnings: number; }; } /** * Per-unit fact sidecar. A "unit" is the neutral umbrella over a fit check, a * graph rule, and a sim scenario (ADR-0011). Carries ONLY what a flat * `Signal[]` cannot express: that a unit ran, whether it errored, and timing. * `passed` ⇔ "that unit emitted no `critical`/`high` signals". */ export interface UnitResult { readonly slug: string; readonly passed: boolean; readonly violationCount?: number; readonly durationMs: number; readonly error?: string; /** * Files the unit validated/scanned this run (fitness's "Validated" column). * A per-unit fact a flat `Signal[]` cannot express — a check that scanned * 450 files and emitted 0 signals still has `filesValidated: 450`. Optional: * graph rules / sim scenarios do not scan files and omit it (the terminal * table renders the column blank for those tools). `itemType` names the * scanned noun (`files` / `packages` / …) for the column label. */ readonly filesValidated?: number; readonly itemType?: string; /** * Findings suppressed by an inline `@fitness-ignore` directive this run * (fitness's "Ignores" column). Like {@link filesValidated}, a per-unit fact * not recoverable from the (post-suppression) signal list; optional and * omitted by tools without a suppression mechanism. */ readonly ignoredCount?: number; } /** The one tool-run output envelope. The `CommandResult` payload every tool returns. */ export interface SignalEnvelope { readonly schemaVersion: 2; readonly tool: ToolShortId; readonly recipe?: string; readonly runId: string; readonly createdAt: string; readonly verdict: RunVerdict; readonly units: readonly UnitResult[]; readonly signals: readonly Signal[]; /** Graph-only edge-fidelity marker, carried over from CliOutput.resolutionMode. */ readonly resolutionMode?: 'exact' | 'fast'; } /** * Input to {@link buildSignalEnvelope}. `signals` are already the wire * currency; `units` carry the per-unit ran/errored/timing facts. `runId` and * `createdAt` are supplied by the caller (formatter-purity contract: no * `Date.now()`/`randomUUID` in this layer, so tests stay deterministic). */ export interface BuildEnvelopeInput { readonly tool: ToolShortId; readonly recipe?: string; readonly runId: string; readonly createdAt: string; readonly units: readonly UnitResult[]; readonly signals: readonly Signal[]; readonly resolutionMode?: 'exact' | 'fast'; } /** * Assemble a {@link SignalEnvelope} from a run's units + signals. * * Centralises the verdict/summary computation so all three tools agree on * "`passed` ⇔ no critical/high" and the score definition. Pure: no IO, no * clock, no id generation — `runId`/`createdAt` arrive on the input. * * - `summary.total/passed/failed` come from `units` (units are what "ran"). * - `summary.errors/warnings` come from `signals` (critical|high → error, * else warning). * - `score = passRate(summary)`; `passed = errors === 0`. */ export declare function buildSignalEnvelope(input: BuildEnvelopeInput): SignalEnvelope; //# sourceMappingURL=signal-envelope.d.ts.map