export interface ConsentRecord { accepted: boolean; attempt: 1 | 2; decided_at: string; version: "1.0.0"; } /** * Optional dependencies for consent I/O. * * Production callers pass nothing — `homeDir` defaults to `os.homedir()`. * Tests pass `{ homeDir: () => tmpHome }` to redirect file I/O into a * per-test tmpdir without mutating `process.env.HOME` (which races across * concurrent vitest workers — see issue #134). */ export interface ConsentDeps { homeDir?: () => string; } export declare function consentFilePath(deps?: ConsentDeps): string; export declare function readConsent(deps?: ConsentDeps): ConsentRecord | null; export declare function writeConsent(record: ConsentRecord, deps?: ConsentDeps): void; export type PromptOutcome = "yes" | "no" | "skip"; export declare function promptForConsent(): Promise; export interface ConsentDecision { accepted: boolean; justAsked: boolean; } export declare function resetConsentCache(): void; /** * Test-only: seed the per-process consent cache directly, bypassing disk * I/O. Used by consumer-side tests (ndjson-store, sender, local-log) that * need to assert behavior under "consent accepted" or "consent declined" * without writing a consent.json to disk. * * CONCURRENCY: writes module-level mutable state. Safe under vitest's * default per-file isolation, but UNSAFE inside `describe.concurrent` / * `test.concurrent` (multiple tests in the same worker would race on the * cache). For new tests that need concurrent execution, use the * `{ homeDir: () => tmpHome }` deps-injection path instead. * * PRODUCTION GUARD: throws if called outside a test runner — privacy- * sensitive code must never bypass disk-resident consent silently. */ export declare function __setCacheForTest(state: { accepted: boolean; initialised: boolean; }): void; export declare function getCachedConsent(deps?: ConsentDeps): boolean; /** * Resolve the consent decision WITHOUT ever prompting: env override and * persisted record only. The audit path calls this before running so the * first score renders prompt-free; the interactive prompt (if still * undecided) runs at the end of the run via {@link ensureConsentDecision}. */ export declare function resolveConsentNonInteractive(deps?: ConsentDeps): ConsentDecision; export declare function ensureConsentDecision(deps?: ConsentDeps): Promise;