/**
 * SecretStore — write-only-from-the-outside contract for secret-classified
 * keys. The value never round-trips out via `describe()`; only metadata is
 * exposed to the UI/API. Internal callers (resolver, encryption migration)
 * read raw values via `unsafeGetForResolver()`.
 *
 * After the scope-collapse refactor, the store is single-tier: Studiograph
 * is single-workspace-per-process, so secrets.db has no `scope` / `scope_id`
 * dimension. The `Classification` registry tag (workspace-secret /
 * workspace-setting) is the only categorization that matters.
 */
import type { Classification } from './registry.js';
export interface ActorContext {
    type: 'user' | 'system';
    /** Set when type === 'user'. */
    userId?: string;
    /** Set when type === 'system'. e.g. 'importer', 'boot-migration', 'cli-rotate-master'. */
    systemId?: string;
    /** Optional, for HTTP-originated calls. */
    ip?: string;
    userAgent?: string;
}
export interface SecretMetadata {
    key: string;
    classification: Classification;
    /** Human label set when written, e.g. "Production Anthropic". */
    label?: string;
    /** Provider hint for UI presentation. */
    provider?: string;
    /** Last successful test_connection timestamp (ms epoch). */
    lastTestedAt?: number;
    /** 'ok' | 'fail' | undefined when never tested. */
    lastTestResult?: 'ok' | 'fail';
    updatedAt: number;
    updatedBy: string;
    /** Master-key version used to encrypt the row. */
    keyVersion: string;
}
export interface SetSecretInput {
    key: string;
    value: string;
    label?: string;
    provider?: string;
}
export interface SecretStore {
    /**
     * Write or overwrite a secret. Audit-logged. Validates that `key` is in
     * the registry with a *-secret classification (workspace-secret) —
     * bootstrap and user-secret keys reject.
     */
    set(input: SetSecretInput, actor: ActorContext): Promise<SecretMetadata>;
    /**
     * Return metadata for a given key. The actual ciphertext
     * is NEVER returned through this method. Use `unsafeGetForResolver()` for
     * resolver / migration paths.
     */
    describe(key: string): SecretMetadata | undefined;
    /**
     * Enumerate secret metadata. Audit-logged when actor is provided
     * (UI/API metadata reads). Named `listSecrets` to avoid ambiguity with
     * `SettingsStore.list()` when one class implements both interfaces.
     */
    listSecrets(actor?: ActorContext): SecretMetadata[];
    /**
     * Delete a secret. Audit-logged.
     */
    delete(key: string, actor: ActorContext): Promise<boolean>;
    /**
     * Resolver-only path: return the decrypted plaintext or undefined. NOT
     * audit-logged (hot path). Throws on AEAD failure (caller should audit
     * the failure as `decrypt_fail`).
     *
     * Named `unsafe*` because every UI/API caller MUST go through `describe()`
     * instead — the value should not leave the resolver.
     */
    unsafeGetForResolver(key: string): string | undefined;
}
