/** * [WHO]: Evolution artifact (with the optional `overrides` update instruction), prediction/attribution, stream-aware gate report, revision, current pointer, active fixture pointer, quarantine, and command result contracts * [FROM]: Depends only on local extension trust-boundary decisions * [TO]: Consumed by evolution-store, evolution-format, evolution-refiner, and extension entry * [HERE]: extensions/optional/evolution/evolution-types.ts - narrow optional evolution type surface */ import type { EvolutionBenchmarkPromotionReportV1 } from "./benchmark-types.js"; export type EvolutionScope = "session" | "workspace" | "global"; export type EvolutionArtifactKind = "prompt_note" | "memory" | "skill_manifest" | "subagent_spec" | "tool_spec" | "workflow_spec" | "executable_tool" | "eval_fixture"; export type EvolutionCandidateStatus = "proposed" | "rejected" | "promoted" | "quarantined"; export interface EvolutionArtifact { id: string; kind: EvolutionArtifactKind; title: string; content: string; applicability?: string; nonApplicability?: string; tokenBudget?: number; /** * Names the active artifact this one replaces. Absent means "add", which is what every * candidate written before this field existed means, so the store keeps behaving exactly as it * did. It is a proposal-time instruction, not stored state: the merged revision holds the * resolved artifact set with this field dropped. */ overrides?: { skillId: string; }; metadata?: Record; } export type EvolutionPredictionDirection = "increase" | "decrease" | "stay_at_or_above" | "stay_at_or_below" | "no_regression"; export interface EvolutionPrediction { id: string; metric: string; direction: EvolutionPredictionDirection; target: string; rationale: string; } export type EvolutionAttributionStatus = "kept" | "falsified" | "inconclusive"; export interface EvolutionPredictionAttribution { predictionId: string; metric: string; status: EvolutionAttributionStatus; observedValue?: number; target: string; reason: string; } export interface EvolutionStreamAttribution { streamId: string; mode: "isolated" | "sequential" | "interleaved"; passed: boolean; metrics: EvolutionGateReport["metrics"]; results: EvolutionPredictionAttribution[]; } export interface EvolutionAttribution { schemaVersion: 1; id: string; revisionId: string; gateReport: EvolutionGateReport; results: EvolutionPredictionAttribution[]; streamResults?: EvolutionStreamAttribution[]; attributedAt: string; attributedBy: string; } export interface EvolutionCandidateInput { scope: EvolutionScope; summary: string; rationale: string; expectedOutcome: string; artifacts: EvolutionArtifact[]; predictions?: EvolutionPrediction[]; evidence?: Record; } export interface EvolutionValidationReport { passed: boolean; errors: string[]; warnings: string[]; validatedAt: string; } export interface EvolutionGateReport { name: string; passed: boolean; checkedAt: string; metrics: { passRate: number; replayDivergences: number; policyViolations: number; unpairedToolCalls: number; }; streams?: { id: string; mode: "isolated" | "sequential" | "interleaved"; passed: boolean; metrics: EvolutionGateReport["metrics"]; }[]; benchmark?: EvolutionBenchmarkPromotionReportV1; failure?: string; } export interface EvolutionCandidate extends EvolutionCandidateInput { schemaVersion: 1; id: string; contentHash: string; status: EvolutionCandidateStatus; createdAt: string; updatedAt: string; validation: EvolutionValidationReport; /** * Revision that was active when this candidate was created, captured by * `createEvolutionCandidate` from store state. `null` means no revision was active, which is * a legitimate first-candidate state and is distinct from a record that predates this field. * * The store owns this value. It is deliberately not part of `EvolutionCandidateInput`, so a * model proposal, the refine tool, and a caller cannot supply or influence it. */ baselineRevisionId?: string | null; rejectedAt?: string; rejectedBy?: string; rejectionReason?: string; promotedRevisionId?: string; } export interface EvolutionRevision { schemaVersion: 1; id: string; candidateId: string; scope: EvolutionScope; summary: string; rationale: string; expectedOutcome: string; artifacts: EvolutionArtifact[]; predictions?: EvolutionPrediction[]; contentHash: string; gateReport?: EvolutionGateReport; createdAt: string; approvedBy: string; predecessorRevisionId?: string; attribution?: EvolutionAttribution; } export interface EvolutionCurrent { schemaVersion: 1; revisionId: string; activatedAt: string; activatedBy: string; rollbackOf?: string; } export interface EvolutionActiveFixtures { schemaVersion: 1; activeArtifactIds: string[]; archivedArtifactIds: string[]; updatedAt: string; updatedBy: string; } export interface EvolutionQuarantine { schemaVersion: 1; id: string; revisionId?: string; reason: string; quarantinedAt: string; source: "active_revision"; } export interface EvolutionUsageRecord { schemaVersion: 1; id: string; artifactId: string; artifactKind: EvolutionArtifactKind; revisionId?: string; scope: EvolutionScope; status: "success" | "error"; usedAt: string; usedBy: string; inputHash?: string; resultSummary?: string; error?: string; } export interface EvolutionFeedbackRecord { schemaVersion: 1; id: string; usageId: string; artifactId: string; revisionId?: string; scope: EvolutionScope; outcome: "useful" | "not_useful"; note?: string; recordedAt: string; recordedBy: string; } export interface EvolutionScopeSelector { scope: EvolutionScope; sessionId?: string; cwd?: string; } export interface EvolutionInspection { current?: EvolutionCurrent; activeFixtures?: EvolutionActiveFixtures; candidates: EvolutionCandidate[]; revisions: EvolutionRevision[]; attributions: EvolutionAttribution[]; quarantines: EvolutionQuarantine[]; usages: EvolutionUsageRecord[]; feedbacks: EvolutionFeedbackRecord[]; }