/** * Personalization profile -> SOPS-encrypted /profile.yaml (Sprint 5). * Encryption is behind an injectable cipher seam; tests inject a reversible fake. * When the cipher is unavailable BOTH paths refuse and write NO plaintext PHI. * Hand-rolled flat YAML emit/parse (string[] arrays) — NEVER import src/vault. */ import { z } from "zod"; export declare const ProfileSchema: z.ZodObject<{ age: z.ZodNumber; sex: z.ZodEnum<["male", "female", "other"]>; conditions: z.ZodDefault>; medications: z.ZodDefault>; supplements: z.ZodDefault>; allergies: z.ZodDefault>; goals: z.ZodDefault>; }, "strip", z.ZodTypeAny, { age: number; sex: "male" | "female" | "other"; conditions: string[]; medications: string[]; supplements: string[]; allergies: string[]; goals: string[]; }, { age: number; sex: "male" | "female" | "other"; conditions?: string[] | undefined; medications?: string[] | undefined; supplements?: string[] | undefined; allergies?: string[] | undefined; goals?: string[] | undefined; }>; export type Profile = z.infer; /** * Encryption seam for profile.yaml (SOPS age key by default). * Tests inject a reversible fake; production uses the sops-via-execa default. * available() MUST be synchronous — the caller gates IO on its return value. */ export interface ProfileCipher { /** Returns true synchronously when the underlying binary is available. */ available(): boolean; /** Encrypt plaintext to ciphertext (may return a Promise). */ encrypt(plaintext: string): string | Promise; /** Decrypt ciphertext to plaintext (may return a Promise). */ decrypt(ciphertext: string): string | Promise; } /** * Emit a Profile as a minimal YAML string. * Scalars (age, sex) first; array fields follow. * Empty arrays are emitted as `key: []`; non-empty as `key:\n - item\n`. */ export declare function emitProfileYaml(p: Profile): string; /** * Parse a minimal profile YAML string into a plain object (for ProfileSchema.parse). * Handles flat scalars (age: 42, sex: male) and string arrays (key:\n - item). * Returns unknown — callers must validate through ProfileSchema.parse. */ export declare function parseProfileYaml(raw: string): unknown; /** Injectable dependencies for writeProfile / readProfile — production callers omit. */ export interface ProfileDeps { /** Override the encryption cipher (e.g. reversible fake in tests). */ cipher?: ProfileCipher; } /** * Validate, serialize, encrypt and write the profile to /profile.yaml. * * SAFETY: throws with a clear message (and writes NOTHING to disk) when * cipher.available() returns false. The only bytes written to disk are ciphertext. */ export declare function writeProfile(vaultDir: string, profile: Profile, deps?: ProfileDeps): Promise; /** * Read, decrypt, parse and validate the profile from /profile.yaml. * * SAFETY: throws with a clear message when cipher.available() returns false * (no disk reads are attempted). */ export declare function readProfile(vaultDir: string, deps?: ProfileDeps): Promise; /** * Core logic for `bober medical profile show`. * Reads and prints the profile to stdout. * Errors are caught, written to stderr, process.exitCode set to 1 — never throws. */ export declare function runProfileShow(projectRoot: string, opts: { vault?: string; }, deps?: ProfileDeps): Promise; /** * Core logic for `bober medical profile set `. * Reads the existing profile (or starts from a safe default on ENOENT), * updates one field, re-validates via ProfileSchema, and writes back. * For array keys, value is parsed as a comma-separated list. * Errors are caught, written to stderr, process.exitCode set to 1 — never throws. */ export declare function runProfileSet(projectRoot: string, key: string, value: string, opts: { vault?: string; }, deps?: ProfileDeps): Promise; //# sourceMappingURL=profile.d.ts.map