import type { PersistencePage, SessionEntry, SessionEntryQuery } from "../contracts.js"; /** Current shared persistence schema version for production database adapters. */ export declare const PERSISTENCE_SCHEMA_VERSION = 9; export type PersistenceTableName = "prism_tenants" | "prism_accounts" | "prism_users" | "prism_agent_definitions" | "prism_sessions" | "prism_branches" | "prism_session_entries" | "prism_session_append_idempotency" | "prism_runs" | "prism_agent_events" | "prism_agent_event_streams" | "prism_tool_calls" | "prism_usage" | "prism_run_feedback" | "prism_retention_policies" | "prism_legal_holds" | "prism_tenant_quotas" | "prism_migrations"; export type PersistenceColumnType = "text" | "integer" | "number" | "boolean" | "json" | "timestamp"; export interface PersistenceColumnDefinition { readonly name: string; readonly type: PersistenceColumnType; readonly nullable?: boolean; /** Portable SQL default literal, if the schema requires one. */ readonly defaultValue?: string; /** Column participates in tenant isolation boundaries when true. */ readonly tenantScoped?: boolean; } export interface PersistenceForeignKeyDefinition { readonly columns: readonly string[]; readonly referencesTable: PersistenceTableName; readonly referencesColumns: readonly string[]; /** When true, tenant_id must participate in the FK boundary for scoped tables. */ readonly tenantBound?: boolean; } export interface PersistenceTableDefinition { readonly name: PersistenceTableName; readonly columns: readonly PersistenceColumnDefinition[]; readonly primaryKey: readonly string[]; readonly uniqueKeys?: readonly (readonly string[])[]; readonly foreignKeys?: readonly PersistenceForeignKeyDefinition[]; } export interface PersistenceIndexDefinition { readonly name: string; readonly table: PersistenceTableName; readonly columns: readonly string[]; readonly unique?: boolean; /** Human-readable query-plan purpose for adapter authors and tests. */ readonly purpose: string; } /** Dialect-neutral schema model shared by SQLite and PostgreSQL adapters. */ export interface PersistenceSchemaModel { readonly version: number; readonly tables: readonly PersistenceTableDefinition[]; readonly indexes: readonly PersistenceIndexDefinition[]; } export interface PersistenceMigrationStep { readonly version: number; readonly name: string; readonly description?: string; /** SHA-256 of the canonical checked-in migration schema content. */ readonly checksum: string; } /** Versioned migration expectations shared by production database adapters. */ export interface PersistenceMigrationContract { readonly targetSchemaVersion: number; readonly appliedMigrationsTable: PersistenceTableName; readonly steps: readonly PersistenceMigrationStep[]; /** Advisory-lock or equivalent guidance for concurrent migration setup. */ readonly lockGuidance: string; /** Least-privilege role guidance for migration vs runtime credentials. */ readonly leastPrivilegeGuidance: string; } /** Cursor key shapes adapters must index so pagination avoids full scans. */ export interface PersistencePaginationCursor { readonly table: PersistenceTableName; readonly columns: readonly string[]; readonly supportsOrder: readonly ("asc" | "desc")[]; readonly purpose: string; } /** Guidance adapters must follow: values are bound parameters, never interpolated. */ export declare const PARAMETERIZED_QUERY_GUIDANCE = "Bind every user-supplied value (session ids, idempotency keys, tenant ids, timestamps, JSON payloads) as a query parameter. Quote/validate schema and table identifiers only; never interpolate untrusted strings into SQL text."; /** Canonical shared schema model for Tasks 2–3 adapter packages. */ export declare function createPersistenceSchemaModel(): PersistenceSchemaModel; /** Canonical migration contract for production adapters. */ export declare function createPersistenceMigrationContract(): PersistenceMigrationContract; /** Indexed cursor columns adapters must support for paginated reads. */ export declare function getPersistencePaginationCursors(): readonly PersistencePaginationCursor[]; /** Build a tenant-scoped unique key column list for adapter DDL. */ export declare function tenantScopedUniqueKey(baseColumns: readonly string[], tenantColumn?: "tenant_id" | "account_id" | "user_id"): readonly string[]; /** Assert a schema model includes required tables, tenant boundaries, and indexes. */ export declare function assertPersistenceSchemaModel(model: PersistenceSchemaModel): void; /** Assert migration steps are strictly increasing and end at the target schema version. */ export declare function assertPersistenceMigrationContract(contract: PersistenceMigrationContract): void; export type PersistenceSchemaDialect = "sqlite" | "postgres"; export interface PersistenceSchemaShapeColumn { readonly name: string; readonly type: string; readonly nullable: boolean; readonly defaultValue?: string; } export interface PersistenceSchemaShapeForeignKey { readonly columns: readonly string[]; readonly referencesTable: string; readonly referencesColumns: readonly string[]; } export interface PersistenceSchemaShapeTable { readonly name: string; readonly columns: readonly PersistenceSchemaShapeColumn[]; readonly primaryKey: readonly string[]; readonly uniqueKeys: readonly (readonly string[])[]; readonly foreignKeys: readonly PersistenceSchemaShapeForeignKey[]; } export interface PersistenceSchemaShapeIndex { readonly name: string; readonly table: string; readonly columns: readonly string[]; readonly unique: boolean; } export interface PersistenceSchemaShape { readonly tables: readonly PersistenceSchemaShapeTable[]; readonly indexes: readonly PersistenceSchemaShapeIndex[]; } /** Compare bounded dialect catalog output against every required schema-v3 detail. */ export declare function assertPersistenceSchemaShape(shape: PersistenceSchemaShape, dialect: PersistenceSchemaDialect, model?: PersistenceSchemaModel): void; export interface AppliedPersistenceMigration { readonly name: string; readonly version: string; readonly checksum: string | null; } /** Reject altered migration history before any new DDL or runtime write. */ export declare function assertAppliedPersistenceMigrations(contract: PersistenceMigrationContract, applied: readonly AppliedPersistenceMigration[]): { readonly legacyChecksums: boolean; }; /** * Assert a dialect-local adapter exposes the canonical table and index names. * Adapters pass the table/index names their migration runner created. */ export declare function assertAdapterSchemaMatchesModel(adapterTables: readonly string[], adapterIndexes: readonly string[], model?: PersistenceSchemaModel): void; /** Guard adapter SQL tests: reject obvious value interpolation into statement text. */ export declare function assertParameterizedQuery(sql: string, boundValues: readonly unknown[]): void; /** Simulate migration up + reopen: applied steps must match the contract in order. */ export declare function assertMigrationUpAndReopen(contract: PersistenceMigrationContract, appliedAfterUp: readonly AppliedPersistenceMigration[], appliedAfterReopen: readonly AppliedPersistenceMigration[]): void; export interface PersistenceQueryConformanceFixture { readonly seedEntries: (entries: readonly SessionEntry[]) => Promise | void; readonly queryEntries: (query: SessionEntryQuery) => Promise>; } /** Assert cursor pagination returns stable pages without repeating rows. */ export declare function assertPersistenceQueryPaginationConforms(fixture: PersistenceQueryConformanceFixture, sessionId?: string): Promise; /** Assert tenant-filtered queries do not return rows from another tenant. */ export declare function assertTenantScopedQueryIsolation(queryByTenant: (tenantId: string) => Promise): Promise;