/**
 * SqliteEncryptedStore — concrete SecretStore + SettingsStore on
 * better-sqlite3.
 *
 * Lives at /workspace/secrets.db on Railway, ~/.studiograph/secrets.db
 * locally. File mode 0600 enforced after open. The audit table lives in
 * the same DB so cross-table operations stay atomic.
 *
 * After the scope-collapse refactor, the schema has no `scope` /
 * `scope_id` columns — Studiograph is single-workspace-per-process, so
 * each key has at most one row. Existing populated databases (with the
 * old `(scope, scope_id, key)` shape) are migrated transparently on
 * first construction via `migrateScopeCollapse()`.
 *
 * AAD binding for encrypted rows keeps the four-tuple `AADInput` shape so
 * the shared encryption module continues to serve auth.db (which uses
 * different `scope: 'user'` AAD per user). Inside this store every row
 * binds AAD with the constant `scope: 'workspace'`, `scopeId: ''` —
 * cosmetic-only after the migration since each row is also uniquely
 * keyed by `(key)`.
 */
import type { ActorContext, SecretMetadata, SecretStore, SetSecretInput } from './SecretStore.js';
import type { SettingMetadata, SettingsStore, SetSettingInput } from './SettingsStore.js';
import { AuditLogger } from './audit.js';
export interface SqliteEncryptedStoreOptions {
    dbPath: string;
    masterKey: Uint8Array;
    /** Defaults to 'mk_v1'. Bumped by master-key rotation. */
    keyVersion?: string;
    /** Optional secondary key for transition reads after a rotation. */
    previousMasterKey?: Uint8Array;
    previousKeyVersion?: string;
}
export declare class SqliteEncryptedStore implements SecretStore, SettingsStore {
    private readonly db;
    private readonly masterKey;
    private readonly keyVersion;
    private readonly previousMasterKey?;
    private readonly previousKeyVersion?;
    readonly audit: AuditLogger;
    constructor(opts: SqliteEncryptedStoreOptions);
    private initSchema;
    /**
     * One-shot migration: collapse the legacy `(scope, scope_id, key)` tables
     * into the single-tier shape. Steps:
     *
     *   1. Detect legacy shape by querying `PRAGMA table_info` for the
     *      `scope` column on settings or secrets.
     *   2. Back up secrets.db → secrets.db.backup.<ts> with mode 0o600.
     *   3. For each legacy row in `secrets`, decrypt with its original AAD
     *      (4-tuple including the row's scope+scope_id), re-encrypt under
     *      the new constant AAD, INSERT into the new table. Drop the old.
     *   4. For `settings`, INSERT...SELECT keeping just `key`/`value_json`/
     *      timestamps. Duplicate keys across scopes would collide; assert
     *      none before commit.
     *   5. For `audit_log`, ALTER TABLE DROP COLUMN scope/scope_id. SQLite
     *      3.35+ supports this directly; PK is auto-increment so no rebuild.
     *   6. Mark `meta.scope_collapse_migrated_at`. Re-running is a no-op.
     *
     * Failure modes: per-row decrypt failures during step 3 are logged as
     * decrypt_fail audit rows and the row is skipped. The transaction
     * still commits — the alternative is refusing to start when one
     * historical row got out of sync, which is worse than dropping a key
     * that already couldn't decrypt.
     */
    private migrateScopeCollapse;
    private actorString;
    set(input: SetSettingInput | SetSecretInput, actor: ActorContext): Promise<any>;
    private setSetting;
    get<T = unknown>(key: string): T | undefined;
    list(): SettingMetadata[];
    delete(key: string, actor: ActorContext): Promise<boolean>;
    private setSecret;
    describe(key: string): SecretMetadata | undefined;
    listSecrets(actor?: ActorContext): SecretMetadata[];
    unsafeGetForResolver(key: string): string | undefined;
    /**
     * Read a value from the `meta` key/value table — used by one-shot
     * migrations to mark completion (e.g., scope-collapse, R2 structural
     * import). Returns undefined when the row is absent. Not audited:
     * meta rows are operational state, not configuration.
     */
    getMeta(key: string): string | undefined;
    /**
     * Write a value to the `meta` key/value table. Upserts. Paired with
     * `getMeta` for migration completion markers.
     */
    setMeta(key: string, value: string): void;
    close(): void;
}
