import type { HmacAuthority, OutcomeCategory, OutcomeEnvelope, OutcomeResult, OutcomeWorkflow } from '../evidence/types.js'; /** * The outcome authority used for cross-project mining must come from stable, * studio-managed secret storage. A process/session key would assign a project a * new pseudonym after every restart and could falsely satisfy the diversity gate. */ export interface StudioOutcomeAuthority extends HmacAuthority { readonly scope: 'studio'; readonly persistence: 'cross-session'; } export type ImprovementProposalState = 'inactive' | 'approved' | 'rejected' | 'superseded'; export interface ImprovementProvenance { readonly eventIds: readonly string[]; readonly envelopeHashes: readonly string[]; readonly projectPseudonyms: readonly string[]; } export interface ImprovementProposal { readonly proposalId: string; readonly state: ImprovementProposalState; readonly workflow: OutcomeWorkflow; readonly result: OutcomeResult; readonly category: OutcomeCategory; readonly support: number; readonly distinctProjects: number; readonly confidence: number; readonly createdAt: string; readonly provenance: ImprovementProvenance; readonly supersededBy?: string; readonly decision?: Readonly<{ kind: 'approve' | 'reject'; occurredAt: string; actorPseudonym: string; }>; } export type ImprovementEvent = Readonly<{ eventId: string; type: 'outcome.accepted'; envelope: OutcomeEnvelope; }> | Readonly<{ eventId: string; type: 'proposal.created'; proposal: Omit; }> | Readonly<{ eventId: string; type: 'proposal.superseded'; proposalId: string; supersededBy: string; }> | Readonly<{ eventId: string; type: 'proposal.decided'; proposalId: string; decision: 'approve' | 'reject'; occurredAt: string; actorPseudonym: string; }>; export interface ImprovementStore { append(event: ImprovementEvent): 'stored' | 'replay'; appendBatch(events: readonly ImprovementEvent[]): readonly ('stored' | 'replay')[]; events(): readonly ImprovementEvent[]; }