import type { DependencyGraph } from "../../graph/build.ts"; import { type MaskSelection, type MaskStrategy } from "./types.ts"; /** * A user-supplied masking instruction for one field. Either a bare field name * (masked with strategy "auto" — `pickStrategy` chooses the preset) or an * explicit strategy. `"copy"` opts a field OUT — it removes the field from the * selection, which is how a user un-masks something the detector flagged by * default. * * Field NAMES only, never values — so this stays inside the AI boundary. */ export type MaskFieldSpec = string | { field: string; strategy: MaskStrategy | "copy"; }; /** object API name → list of field instructions. */ export type UserMaskFields = Record; /** * Build the masking selection (object → field → strategy) for a run. * * SIMPLE v1 (phases/masking-spec.md T8): the default selection is exactly the * fields the detector already flagged on each node (`sensitiveFields`), each * with strategy `"auto"`. The user then layers explicit instructions on top — * add a field, pin its strategy, or `"copy"` to opt out. * * Deliberately NOT in v1 (the "complex later"): augmenting the default with * type-based detection (`type ∈ email|phone`) or a broader name pattern. The * G1 recall analysis (masking-spec.md §4.4) showed the detector under-flags — * it misses names, `MailingStreet`, demographics, and whole custom objects — * but the mandatory dry-run review surfaces the selection so the user adds * those explicitly. Auto-expansion can land later without changing this * signature. */ export declare function resolveMaskSelection(graph: DependencyGraph, userMaskFields?: UserMaskFields, scopeObjects?: Iterable): MaskSelection; /** * Flatten a selection to per-object field NAMES (sorted). For the dry-run * report and response — names only, never values. Empty objects are omitted. */ export declare function maskedFieldNames(selection: MaskSelection): Record;