{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.philterd.ai/schemas/redaction-policy/1.0.0/schema.json",
  "version": "1.0.0",
  "title": "Phileas Redaction Policy",
  "description": "Schema for a Phileas redaction policy JSON file. A policy defines which types of sensitive information to detect and how to redact or transform each type.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "config": {
      "description": "Global configuration settings for the policy.",
      "$ref": "#/$defs/config"
    },
    "crypto": {
      "description": "AES encryption settings used by the CRYPTO_REPLACE strategy.",
      "$ref": "#/$defs/crypto"
    },
    "fpe": {
      "description": "Format-preserving encryption settings used by the FPE_ENCRYPT_REPLACE strategy.",
      "$ref": "#/$defs/fpe"
    },
    "identifiers": {
      "description": "Defines which types of sensitive information to detect and how to handle each type.",
      "$ref": "#/$defs/identifiers"
    },
    "ignored": {
      "description": "Lists of terms to ignore globally during filtering.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/ignored"
      }
    },
    "ignoredPatterns": {
      "description": "Regex patterns to ignore globally during filtering.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/ignoredPattern"
      }
    },
    "graphical": {
      "description": "Graphical redaction settings for image and PDF redaction.",
      "$ref": "#/$defs/graphical"
    }
  },
  "$defs": {
    "config": {
      "description": "Global configuration settings for the policy.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "splitting": {
          "description": "Controls whether and how input text is split into smaller chunks before filtering.",
          "$ref": "#/$defs/splitting"
        },
        "pdf": {
          "description": "Settings for PDF redaction rendering.",
          "$ref": "#/$defs/pdf"
        },
        "postFilters": {
          "description": "Post-processing filters applied after redaction.",
          "$ref": "#/$defs/postFilters"
        },
        "analysis": {
          "description": "Settings for analysis features.",
          "$ref": "#/$defs/analysis"
        }
      }
    },
    "splitting": {
      "description": "Controls whether and how input text is split into smaller chunks before filtering.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "description": "Enable text splitting.",
          "type": "boolean",
          "default": false
        },
        "threshold": {
          "description": "Character count threshold above which text is split.",
          "type": "integer",
          "default": 10000
        },
        "method": {
          "description": "Method used to split text.",
          "type": "string",
          "default": "newline"
        }
      }
    },
    "pdf": {
      "description": "Settings for PDF redaction rendering.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "redactionColor": {
          "description": "Color of the redaction box drawn over redacted text in PDFs.",
          "type": "string",
          "default": "black"
        },
        "showReplacement": {
          "description": "Whether to render replacement text inside the redaction box.",
          "type": "boolean",
          "default": false
        },
        "replacementFont": {
          "description": "Font used for replacement text in PDFs.",
          "type": "string",
          "default": "helvetica"
        },
        "replacementMaxFontSize": {
          "description": "Maximum font size for replacement text in PDFs.",
          "type": "number",
          "default": 12
        },
        "replacementFontColor": {
          "description": "Color of the replacement text in PDFs.",
          "type": "string"
        },
        "scale": {
          "description": "Scale factor for PDF rendering.",
          "type": "number",
          "default": 0.25
        },
        "dpi": {
          "description": "DPI for PDF rendering.",
          "type": "integer",
          "default": 150
        },
        "compressionQuality": {
          "description": "JPEG compression quality for PDF output (0.0 to 1.0).",
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "default": 1.0
        },
        "preserveUnredactedPages": {
          "description": "Whether to preserve pages that contain no redactions in their original form.",
          "type": "boolean",
          "default": false
        }
      }
    },
    "postFilters": {
      "description": "Post-processing filters applied after redaction.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "removeTrailingPeriods": {
          "description": "Remove trailing periods from redacted output.",
          "type": "boolean",
          "default": true
        },
        "removeTrailingSpaces": {
          "description": "Remove trailing spaces from redacted output.",
          "type": "boolean",
          "default": true
        },
        "removeTrailingNewLines": {
          "description": "Remove trailing newlines from redacted output.",
          "type": "boolean",
          "default": true
        }
      }
    },
    "analysis": {
      "description": "Settings for analysis features.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "identification": {
          "description": "Enable identification analysis.",
          "type": "boolean",
          "default": true
        }
      }
    },
    "crypto": {
      "description": "AES-GCM encryption settings used by the CRYPTO_REPLACE strategy. A fresh random nonce is generated per value, so no initialization vector is configured. Values may be prefixed with 'env:' to read from environment variables.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "key": {
          "description": "AES encryption key. Prefix with 'env:' to read from an environment variable (e.g. 'env:CRYPTO_KEY').",
          "type": "string"
        }
      },
      "required": ["key"]
    },
    "fpe": {
      "description": "Format-preserving encryption settings used by the FPE_ENCRYPT_REPLACE strategy. Values may be prefixed with 'env:' to read from environment variables.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "key": {
          "description": "FPE encryption key. Prefix with 'env:' to read from an environment variable.",
          "type": "string"
        },
        "tweak": {
          "description": "FPE tweak value. Prefix with 'env:' to read from an environment variable.",
          "type": "string"
        }
      },
      "required": ["key", "tweak"]
    },
    "ignored": {
      "description": "A named list of terms to ignore during filtering.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "Name of this ignore list.",
          "type": "string"
        },
        "terms": {
          "description": "Terms to ignore.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "files": {
          "description": "Paths to files containing terms to ignore (one term per line).",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "caseSensitive": {
          "description": "Whether term matching is case-sensitive.",
          "type": "boolean",
          "default": false
        }
      }
    },
    "ignoredPattern": {
      "description": "A named regex pattern whose matches are ignored during filtering.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "Name of this ignored pattern.",
          "type": "string"
        },
        "pattern": {
          "description": "Java-compatible regular expression. Matches are excluded from filtering.",
          "type": "string"
        }
      }
    },
    "graphical": {
      "description": "Graphical redaction settings for image and PDF redaction.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "boundingBoxes": {
          "description": "Fixed bounding boxes to redact in images or PDFs.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/boundingBox"
          }
        }
      }
    },
    "boundingBox": {
      "description": "A rectangular region to redact in an image or PDF page.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "color": {
          "description": "Fill color for the redaction box.",
          "type": "string"
        },
        "x": {
          "description": "X coordinate of the top-left corner.",
          "type": "number"
        },
        "y": {
          "description": "Y coordinate of the top-left corner.",
          "type": "number"
        },
        "w": {
          "description": "Width of the bounding box.",
          "type": "number"
        },
        "h": {
          "description": "Height of the bounding box.",
          "type": "number"
        },
        "page": {
          "description": "Page number (1-based) for PDF redaction.",
          "type": "integer",
          "default": 1,
          "minimum": 1
        },
        "enabled": {
          "description": "Whether this bounding box is active.",
          "type": "boolean",
          "default": true
        },
        "ignored": {
          "description": "Specific values to ignore.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "ignoredFiles": {
          "description": "Paths to files containing values to ignore.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "ignoredPatterns": {
          "description": "Regex patterns whose matches are ignored.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ignoredPattern"
          }
        },
        "windowSize": {
          "description": "Context window size (number of surrounding tokens to consider).",
          "type": "integer"
        },
        "priority": {
          "description": "Priority of this filter relative to others. Higher values take precedence.",
          "type": "integer"
        }
      }
    },
    "identifiers": {
      "description": "Defines which types of sensitive information to detect and how to handle each type.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "age": {
          "description": "Detects age values (e.g. '35 years old', 'age 42').",
          "$ref": "#/$defs/filterAge"
        },
        "bankRoutingNumber": {
          "description": "Detects bank routing numbers.",
          "$ref": "#/$defs/filterBankRoutingNumber"
        },
        "bitcoinAddress": {
          "description": "Detects Bitcoin wallet addresses.",
          "$ref": "#/$defs/filterBitcoinAddress"
        },
        "city": {
          "description": "Detects city names using dictionary matching.",
          "$ref": "#/$defs/filterCity"
        },
        "county": {
          "description": "Detects county names using dictionary matching.",
          "$ref": "#/$defs/filterCounty"
        },
        "creditCard": {
          "description": "Detects credit card numbers.",
          "$ref": "#/$defs/filterCreditCard"
        },
        "currency": {
          "description": "Detects currency values (e.g. '$100.00', '50 EUR').",
          "$ref": "#/$defs/filterCurrency"
        },
        "date": {
          "description": "Detects date values in various formats.",
          "$ref": "#/$defs/filterDate"
        },
        "dictionaries": {
          "description": "Custom dictionary filters. Each entry defines a set of terms to detect.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/filterCustomDictionary"
          }
        },
        "driversLicense": {
          "description": "Detects driver's license numbers.",
          "$ref": "#/$defs/filterDriversLicense"
        },
        "emailAddress": {
          "description": "Detects email addresses.",
          "$ref": "#/$defs/filterEmailAddress"
        },
        "firstName": {
          "description": "Detects first names using dictionary matching.",
          "$ref": "#/$defs/filterFirstName"
        },
        "hospital": {
          "description": "Detects hospital names using dictionary matching.",
          "$ref": "#/$defs/filterHospital"
        },
        "ibanCode": {
          "description": "Detects International Bank Account Numbers (IBAN).",
          "$ref": "#/$defs/filterIbanCode"
        },
        "identifiers": {
          "description": "Custom regex-based identifier filters. Each entry defines a pattern to detect.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/filterIdentifier"
          }
        },
        "ipAddress": {
          "description": "Detects IPv4 and IPv6 addresses.",
          "$ref": "#/$defs/filterIpAddress"
        },
        "macAddress": {
          "description": "Detects MAC addresses.",
          "$ref": "#/$defs/filterMacAddress"
        },
        "medicalCondition": {
          "description": "Detects medical conditions using PhEye AI-based detection.",
          "$ref": "#/$defs/filterMedicalCondition"
        },
        "passportNumber": {
          "description": "Detects passport numbers.",
          "$ref": "#/$defs/filterPassportNumber"
        },
        "person": {
          "description": "Deprecated. Use 'pheyes' instead.",
          "deprecated": true,
          "$ref": "#/$defs/filterPhEye"
        },
        "pheyes": {
          "description": "PhEye AI-based entity detection filters.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/filterPhEye"
          }
        },
        "phoneNumber": {
          "description": "Detects phone numbers.",
          "$ref": "#/$defs/filterPhoneNumber"
        },
        "phoneNumberExtension": {
          "description": "Detects phone number extensions (e.g. 'ext. 1234').",
          "$ref": "#/$defs/filterPhoneNumberExtension"
        },
        "physicianName": {
          "description": "Detects physician names.",
          "$ref": "#/$defs/filterPhysicianName"
        },
        "sections": {
          "description": "Section-based filters. Each entry defines a start/end pattern pair to redact.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/filterSection"
          }
        },
        "ssn": {
          "description": "Detects U.S. Social Security Numbers.",
          "$ref": "#/$defs/filterSsn"
        },
        "state": {
          "description": "Detects U.S. state names using dictionary matching.",
          "$ref": "#/$defs/filterState"
        },
        "stateAbbreviation": {
          "description": "Detects U.S. state abbreviations (e.g. 'CA', 'NY').",
          "$ref": "#/$defs/filterStateAbbreviation"
        },
        "streetAddress": {
          "description": "Detects street addresses.",
          "$ref": "#/$defs/filterStreetAddress"
        },
        "surname": {
          "description": "Detects surnames/last names using dictionary matching.",
          "$ref": "#/$defs/filterSurname"
        },
        "trackingNumber": {
          "description": "Detects shipping tracking numbers (UPS, FedEx, USPS).",
          "$ref": "#/$defs/filterTrackingNumber"
        },
        "url": {
          "description": "Detects URLs.",
          "$ref": "#/$defs/filterUrl"
        },
        "vin": {
          "description": "Detects Vehicle Identification Numbers (VINs).",
          "$ref": "#/$defs/filterVin"
        },
        "zipCode": {
          "description": "Detects U.S. ZIP codes (5-digit and ZIP+4 formats).",
          "$ref": "#/$defs/filterZipCode"
        }
      }
    },
    "abstractFilterProperties": {
      "description": "Common properties inherited by all filters.",
      "type": "object",
      "properties": {
        "enabled": {
          "description": "Whether this filter is active.",
          "type": "boolean",
          "default": true
        },
        "ignored": {
          "description": "Specific values to ignore for this filter.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "ignoredFiles": {
          "description": "Paths to files containing values to ignore for this filter.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "ignoredPatterns": {
          "description": "Regex patterns whose matches are ignored by this filter.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ignoredPattern"
          }
        },
        "windowSize": {
          "description": "Context window size (number of surrounding tokens to consider).",
          "type": "integer"
        },
        "priority": {
          "description": "Priority of this filter relative to others. Higher values take precedence.",
          "type": "integer"
        }
      }
    },
    "baseFilterStrategy": {
      "description": "Common properties for all filter strategies.",
      "type": "object",
      "properties": {
        "id": {
          "description": "Unique identifier for this strategy instance. Auto-generated if not provided.",
          "type": "string",
          "format": "uuid"
        },
        "strategy": {
          "description": "The redaction/replacement strategy to apply.",
          "type": "string",
          "enum": [
            "REDACT",
            "RANDOM_REPLACE",
            "STATIC_REPLACE",
            "CRYPTO_REPLACE",
            "FPE_ENCRYPT_REPLACE",
            "HASH_SHA256_REPLACE",
            "LAST_4",
            "MASK",
            "TRUNCATE",
            "ABBREVIATE"
          ],
          "default": "REDACT"
        },
        "redactionFormat": {
          "description": "Format string for REDACT strategy. Supports placeholders: %t (filter type), %v (original value), %l (label).",
          "type": "string",
          "default": "{{{REDACTED-%t}}}"
        },
        "replacementScope": {
          "description": "Scope for consistent replacements. DOCUMENT: same token always gets same replacement within a document. CONTEXT: same token gets same replacement within a context.",
          "type": "string",
          "enum": ["DOCUMENT", "CONTEXT"],
          "default": "DOCUMENT"
        },
        "staticReplacement": {
          "description": "Replacement text for STATIC_REPLACE strategy.",
          "type": "string"
        },
        "maskCharacter": {
          "description": "Character used for MASK strategy.",
          "type": "string",
          "default": "*",
          "maxLength": 1
        },
        "maskLength": {
          "description": "Length of the mask. SAME preserves the original length. Can also be a number for fixed-length masking.",
          "type": "string",
          "default": "SAME"
        },
        "truncateLeaveCharacters": {
          "description": "Number of characters to leave visible when using TRUNCATE strategy.",
          "type": "integer",
          "minimum": 1
        },
        "truncateCharacter": {
          "description": "Character used to replace truncated portions.",
          "type": "string",
          "default": "*",
          "maxLength": 1
        },
        "truncateDirection": {
          "description": "Which end of the value to truncate.",
          "type": "string",
          "enum": ["LEADING", "TRAILING"],
          "default": "LEADING"
        },
        "condition": {
          "description": "Conditional expression that must be satisfied for this strategy to apply. Supports fields: token, context, confidence, population. Operators: startswith, ==, !=, >, <, >=, <=, is, is not. Multiple conditions joined with &&. Example: 'confidence > 0.9', 'token startswith \"5\"', 'population < 4500', 'token is birthdate'.",
          "type": "string"
        },
        "salt": {
          "description": "Whether to add a random salt to hashed values (HASH_SHA256_REPLACE).",
          "type": "boolean",
          "default": false
        },
        "anonymizationMethod": {
          "description": "Method used for RANDOM_REPLACE anonymization.",
          "type": "string",
          "enum": ["REALISTIC", "FROM_LIST", "UUID"],
          "default": "REALISTIC"
        },
        "anonymizationCandidates": {
          "description": "Custom candidate values for FROM_LIST anonymization method.",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "dateFilterStrategy": {
      "description": "A filter strategy for date values. Supports all base strategies plus date-specific strategies: TRUNCATE_TO_YEAR, SHIFT, and RELATIVE.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "description": "Unique identifier for this strategy instance. Auto-generated if not provided.",
          "type": "string",
          "format": "uuid"
        },
        "strategy": {
          "description": "The redaction/replacement strategy to apply. Date filters support additional strategies: TRUNCATE_TO_YEAR, SHIFT, and RELATIVE.",
          "type": "string",
          "enum": [
            "REDACT",
            "RANDOM_REPLACE",
            "STATIC_REPLACE",
            "CRYPTO_REPLACE",
            "FPE_ENCRYPT_REPLACE",
            "HASH_SHA256_REPLACE",
            "LAST_4",
            "MASK",
            "TRUNCATE",
            "TRUNCATE_TO_YEAR",
            "SHIFT",
            "RELATIVE"
          ],
          "default": "REDACT"
        },
        "redactionFormat": {
          "description": "Format string for REDACT strategy. Supports placeholders: %t (filter type), %v (original value), %l (label).",
          "type": "string",
          "default": "{{{REDACTED-%t}}}"
        },
        "replacementScope": {
          "description": "Scope for consistent replacements.",
          "type": "string",
          "enum": ["DOCUMENT", "CONTEXT"],
          "default": "DOCUMENT"
        },
        "staticReplacement": {
          "description": "Replacement text for STATIC_REPLACE strategy.",
          "type": "string"
        },
        "maskCharacter": {
          "description": "Character used for MASK strategy.",
          "type": "string",
          "default": "*",
          "maxLength": 1
        },
        "maskLength": {
          "description": "Length of the mask. SAME preserves the original length.",
          "type": "string",
          "default": "SAME"
        },
        "truncateLeaveCharacters": {
          "description": "Number of characters to leave visible when using TRUNCATE strategy.",
          "type": "integer",
          "minimum": 1
        },
        "truncateCharacter": {
          "description": "Character used to replace truncated portions.",
          "type": "string",
          "default": "*",
          "maxLength": 1
        },
        "truncateDirection": {
          "description": "Which end of the value to truncate.",
          "type": "string",
          "enum": ["LEADING", "TRAILING"],
          "default": "LEADING"
        },
        "condition": {
          "description": "Conditional expression that must be satisfied for this strategy to apply. Date filters support: 'token is birthdate', 'token is deathdate', 'token is birthdate or deathdate'.",
          "type": "string"
        },
        "salt": {
          "description": "Whether to add a random salt to hashed values.",
          "type": "boolean",
          "default": false
        },
        "anonymizationMethod": {
          "description": "Method used for RANDOM_REPLACE anonymization.",
          "type": "string",
          "enum": ["REALISTIC", "FROM_LIST", "UUID"],
          "default": "REALISTIC"
        },
        "anonymizationCandidates": {
          "description": "Custom candidate values for FROM_LIST anonymization method.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "shiftRandom": {
          "description": "Whether to shift dates by a random amount (SHIFT strategy).",
          "type": "boolean",
          "default": false
        },
        "shiftDays": {
          "description": "Number of days to shift dates (SHIFT strategy).",
          "type": "integer",
          "default": 0
        },
        "shiftMonths": {
          "description": "Number of months to shift dates (SHIFT strategy).",
          "type": "integer",
          "default": 0
        },
        "shiftYears": {
          "description": "Number of years to shift dates (SHIFT strategy).",
          "type": "integer",
          "default": 0
        },
        "futureDates": {
          "description": "Whether shifted dates may land in the future (SHIFT strategy).",
          "type": "boolean",
          "default": false
        }
      }
    },
    "filterAge": {
      "description": "Detects age values (e.g. '35 years old', 'age 42').",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "ageFilterStrategies": {
          "description": "Strategies for handling detected age values.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterBankRoutingNumber": {
      "description": "Detects bank routing numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "bankRoutingNumberFilterStrategies": {
          "description": "Strategies for handling detected bank routing numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterBitcoinAddress": {
      "description": "Detects Bitcoin wallet addresses.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "bitcoinFilterStrategies": {
          "description": "Strategies for handling detected Bitcoin addresses.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterCity": {
      "description": "Detects city names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "cityFilterStrategies": {
          "description": "Strategies for handling detected city names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of city names.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterCounty": {
      "description": "Detects county names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "countyFilterStrategies": {
          "description": "Strategies for handling detected county names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of county names.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterCreditCard": {
      "description": "Detects credit card numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "creditCardFilterStrategies": {
          "description": "Strategies for handling detected credit card numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "onlyValidCreditCardNumbers": {
          "description": "Only detect numbers that pass Luhn checksum validation.",
          "type": "boolean",
          "default": true
        },
        "ignoreWhenInUnixTimestamp": {
          "description": "Ignore sequences that appear to be Unix timestamps.",
          "type": "boolean",
          "default": false
        },
        "onlyWordBoundaries": {
          "description": "Only detect numbers at word boundaries.",
          "type": "boolean",
          "default": true
        }
      },
      "additionalProperties": false
    },
    "filterCurrency": {
      "description": "Detects currency values (e.g. '$100.00', '50 EUR').",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "currencyFilterStrategies": {
          "description": "Strategies for handling detected currency values.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterCustomDictionary": {
      "description": "Detects terms from a user-defined dictionary.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "customFilterStrategies": {
          "description": "Strategies for handling detected custom dictionary terms.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "classification": {
          "description": "Classification label assigned to matches from this dictionary.",
          "type": "string"
        },
        "terms": {
          "description": "Terms to detect.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "files": {
          "description": "Paths to files containing terms to detect (one term per line).",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "off"
        },
        "capitalized": {
          "description": "Only match capitalized variants of terms.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterDate": {
      "description": "Detects date values in various formats.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "dateFilterStrategies": {
          "description": "Strategies for handling detected dates. Supports date-specific strategies: TRUNCATE_TO_YEAR, SHIFT, RELATIVE.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/dateFilterStrategy"
          }
        },
        "onlyValidDates": {
          "description": "Only detect strings that parse as valid calendar dates.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterDriversLicense": {
      "description": "Detects driver's license numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "driversLicenseFilterStrategies": {
          "description": "Strategies for handling detected driver's license numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterEmailAddress": {
      "description": "Detects email addresses.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "emailAddressFilterStrategies": {
          "description": "Strategies for handling detected email addresses.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "onlyStrictMatches": {
          "description": "Use strict email validation rules.",
          "type": "boolean",
          "default": true
        },
        "onlyValidTLDs": {
          "description": "Only detect emails with recognized top-level domains.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterFirstName": {
      "description": "Detects first names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "firstNameFilterStrategies": {
          "description": "Strategies for handling detected first names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of first names.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterHospital": {
      "description": "Detects hospital names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "hospitalFilterStrategies": {
          "description": "Strategies for handling detected hospital names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of hospital names.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterIbanCode": {
      "description": "Detects International Bank Account Numbers (IBAN).",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "ibanCodeFilterStrategies": {
          "description": "Strategies for handling detected IBAN codes.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "onlyValidIBANCodes": {
          "description": "Only detect codes that pass IBAN checksum validation.",
          "type": "boolean",
          "default": true
        },
        "allowSpaces": {
          "description": "Allow spaces within IBAN codes.",
          "type": "boolean",
          "default": true
        }
      },
      "additionalProperties": false
    },
    "filterIdentifier": {
      "description": "Detects custom identifiers using a user-defined regex pattern.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "identifierFilterStrategies": {
          "description": "Strategies for handling detected custom identifiers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "pattern": {
          "description": "Java-compatible regular expression to match identifiers.",
          "type": "string",
          "default": "\\b[A-Z0-9_-]{6,}\\b"
        },
        "groupNumber": {
          "description": "Regex capture group number to extract as the identifier (0 = entire match).",
          "type": "integer",
          "default": 0,
          "minimum": 0
        },
        "caseSensitive": {
          "description": "Whether regex matching is case-sensitive.",
          "type": "boolean",
          "default": true
        },
        "classification": {
          "description": "Classification label assigned to matches from this identifier.",
          "type": "string",
          "default": "custom-identifier"
        }
      },
      "additionalProperties": false
    },
    "filterIpAddress": {
      "description": "Detects IPv4 and IPv6 addresses.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "ipAddressFilterStrategies": {
          "description": "Strategies for handling detected IP addresses.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterMacAddress": {
      "description": "Detects MAC addresses.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "macAddressFilterStrategies": {
          "description": "Strategies for handling detected MAC addresses.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterMedicalCondition": {
      "description": "Detects medical conditions using PhEye AI-based detection.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "medicalConditionFilterStrategies": {
          "description": "Strategies for handling detected medical conditions.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "phEyeConfiguration": {
          "description": "Configuration for connecting to a PhEye AI service.",
          "$ref": "#/$defs/phEyeConfiguration"
        },
        "removePunctuation": {
          "description": "Remove punctuation from text before sending to the AI model.",
          "type": "boolean",
          "default": false
        },
        "thresholds": {
          "description": "Confidence thresholds per label. Detections below the threshold are discarded.",
          "type": "object",
          "additionalProperties": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "additionalProperties": false
    },
    "filterPassportNumber": {
      "description": "Detects passport numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "passportNumberFilterStrategies": {
          "description": "Strategies for handling detected passport numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterPhEye": {
      "description": "PhEye AI-based entity detection filter. Uses a remote AI model to detect entities.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "phEyeFilterStrategies": {
          "description": "Strategies for handling entities detected by PhEye.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "phEyeConfiguration": {
          "description": "Configuration for connecting to a PhEye AI service.",
          "$ref": "#/$defs/phEyeConfiguration"
        },
        "removePunctuation": {
          "description": "Remove punctuation from text before sending to the AI model.",
          "type": "boolean",
          "default": false
        },
        "thresholds": {
          "description": "Confidence thresholds per label. Detections below the threshold are discarded.",
          "type": "object",
          "additionalProperties": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        }
      },
      "additionalProperties": false
    },
    "phEyeConfiguration": {
      "description": "Configuration for connecting to a PhEye AI service.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "endpoint": {
          "description": "URL of the PhEye service endpoint.",
          "type": "string",
          "format": "uri"
        },
        "bearerToken": {
          "description": "Bearer token for authenticating with the PhEye service.",
          "type": "string"
        },
        "timeout": {
          "description": "Request timeout in seconds.",
          "type": "integer",
          "default": 600
        },
        "maxIdleConnections": {
          "description": "Maximum number of idle HTTP connections to maintain.",
          "type": "integer",
          "default": 30
        },
        "labels": {
          "description": "Entity labels to detect (e.g. 'PER', 'LOC', 'ORG').",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "filterPhoneNumber": {
      "description": "Detects phone numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "phoneNumberFilterStrategies": {
          "description": "Strategies for handling detected phone numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterPhoneNumberExtension": {
      "description": "Detects phone number extensions (e.g. 'ext. 1234').",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "phoneNumberExtensionFilterStrategies": {
          "description": "Strategies for handling detected phone number extensions.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterPhysicianName": {
      "description": "Detects physician names.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "physicianNameFilterStrategies": {
          "description": "Strategies for handling detected physician names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterSection": {
      "description": "Detects and redacts sections of text bounded by start and end regex patterns.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "sectionFilterStrategies": {
          "description": "Strategies for handling detected sections.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "startPattern": {
          "description": "Java-compatible regex that marks the beginning of a section to redact.",
          "type": "string"
        },
        "endPattern": {
          "description": "Java-compatible regex that marks the end of a section to redact.",
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "filterSsn": {
      "description": "Detects U.S. Social Security Numbers.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "ssnFilterStrategies": {
          "description": "Strategies for handling detected SSNs.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterState": {
      "description": "Detects U.S. state names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "stateFilterStrategies": {
          "description": "Strategies for handling detected state names.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of state names.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterStateAbbreviation": {
      "description": "Detects U.S. state abbreviations (e.g. 'CA', 'NY').",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "stateAbbreviationFilterStrategies": {
          "description": "Strategies for handling detected state abbreviations.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterStreetAddress": {
      "description": "Detects street addresses.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "streetAddressFilterStrategies": {
          "description": "Strategies for handling detected street addresses.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterSurname": {
      "description": "Detects surnames/last names using dictionary matching.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "surnameFilterStrategies": {
          "description": "Strategies for handling detected surnames.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "fuzzy": {
          "description": "Enable fuzzy matching for approximate matches.",
          "type": "boolean",
          "default": false
        },
        "sensitivity": {
          "description": "Sensitivity level controlling match strictness when fuzzy matching is enabled.",
          "$ref": "#/$defs/sensitivityLevel",
          "default": "medium"
        },
        "capitalized": {
          "description": "Only match capitalized variants of surnames.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterTrackingNumber": {
      "description": "Detects shipping tracking numbers (UPS, FedEx, USPS).",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "trackingNumberFilterStrategies": {
          "description": "Strategies for handling detected tracking numbers.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "ups": {
          "description": "Detect UPS tracking numbers.",
          "type": "boolean",
          "default": true
        },
        "fedex": {
          "description": "Detect FedEx tracking numbers.",
          "type": "boolean",
          "default": true
        },
        "usps": {
          "description": "Detect USPS tracking numbers.",
          "type": "boolean",
          "default": true
        },
        "allowSpaces": {
          "description": "Allow spaces within tracking numbers.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "filterUrl": {
      "description": "Detects URLs.",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "urlFilterStrategies": {
          "description": "Strategies for handling detected URLs.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "requireHttpWwwPrefix": {
          "description": "Only detect URLs that start with http://, https://, or www.",
          "type": "boolean",
          "default": true
        }
      },
      "additionalProperties": false
    },
    "filterVin": {
      "description": "Detects Vehicle Identification Numbers (VINs).",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "vinFilterStrategies": {
          "description": "Strategies for handling detected VINs.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        }
      },
      "additionalProperties": false
    },
    "filterZipCode": {
      "description": "Detects U.S. ZIP codes (5-digit and ZIP+4 formats).",
      "type": "object",
      "allOf": [
        { "$ref": "#/$defs/abstractFilterProperties" }
      ],
      "properties": {
        "enabled": true,
        "ignored": true,
        "ignoredFiles": true,
        "ignoredPatterns": true,
        "windowSize": true,
        "priority": true,
        "zipCodeFilterStrategy": {
          "description": "Strategies for handling detected ZIP codes. Note: this property name is singular for backwards compatibility but accepts an array.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/baseFilterStrategy"
          }
        },
        "requireDelimiter": {
          "description": "Require a delimiter (hyphen) between the 5-digit and 4-digit parts of ZIP+4 codes.",
          "type": "boolean",
          "default": false
        },
        "validate": {
          "description": "Validate that detected ZIP codes are real U.S. ZIP codes.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false
    },
    "sensitivityLevel": {
      "description": "Controls how strictly fuzzy matching is applied. Higher sensitivity means more matches.",
      "type": "string",
      "enum": ["auto", "off", "low", "medium", "high"]
    }
  }
}
