{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.netify.ai/developer/agent/v5/schemas/netify-config-proc-dev-discovery.json",
  "title": "Netify Device Discovery Processor Configuration",
  "description": "JSON Schema for the Netify Device Discovery Processor plugin configuration.",
  "type": "object",
  "properties": {
    "format": {
      "$ref": "#/$defs/formatType",
      "description": "The default serialization format for the data payload."
    },
    "compressor": {
      "$ref": "#/$defs/compressorType",
      "description": "The default compression algorithm applied to the payload."
    },
    "confidence_policy": {
      "type": "object",
      "description": "Confidence threshold policy object.",
      "properties": {
        "max": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "default": 80,
          "description": "Confidence threshold (0-100) required before discovery stops for a device."
        },
        "update_ttl": {
          "type": "integer",
          "minimum": 0,
          "default": 0,
          "description": "Seconds an entry is re-analyzed even if above confidence level. 0 to never re-analyze."
        }
      }
    },
    "macs_policy": {
      "type": "integer",
      "default": 0,
      "description": "Maximum number of MAC addresses to track in memory. 0 for unlimited."
    },
    "mac_age_policy": {
      "type": "integer",
      "default": 172800,
      "description": "Maximum idle time (seconds) before a MAC address entry is purged from memory."
    },
    "http": {
      "type": "object",
      "description": "HTTP collection policy object.",
      "properties": {
        "user_agents_policy": {
          "$ref": "#/$defs/limitType",
          "description": "Policy for managing HTTP user agent strings on any given MAC address."
        }
      }
    },
    "mdns": {
      "type": "object",
      "description": "mDNS collection policy object.",
      "properties": {
        "answers_policy": {
          "$ref": "#/$defs/limitType",
          "description": "Policy for managing mDNS answer (PTR service instance name) strings on any given MAC address."
        }
      }
    },
    "ssdp": {
      "type": "object",
      "description": "SSDP collection policy object.",
      "properties": {
        "user_agents_policy": {
          "$ref": "#/$defs/limitType",
          "description": "Policy for managing SSDP user agent strings on any given MAC address."
        }
      }
    },
    "client_ja4_policy": {
      "$ref": "#/$defs/limitType",
      "description": "Policy for managing JA4 client hashes on any given MAC address."
    },
    "path_device_cache": {
      "type": "string",
      "description": "Filesystem path for persistent device cache."
    },
    "process_all_macs": {
      "type": "boolean",
      "default": false,
      "description": "If true, also creates a minimal device entry (MAC and one IP address only, no fingerprint data) for the counterparty MAC on each flow, not just the fully profiled origin MAC."
    },
    "device_mac_ignore": {
      "type": "array",
      "description": "List of MAC addresses to exclude from discovery.",
      "items": {
        "type": "string",
        "pattern": "^([0-9a-f]{2}:){5}[0-9a-f]{2}$"
      }
    },
    "device_mac_ignore_group": {
      "type": "string",
      "description": "Filesystem path to a group file containing MAC addresses to exclude from discovery."
    },
    "netify_api": {
      "type": "object",
      "description": "Netify API object definition.",
      "properties": {
        "enable": {
          "type": "boolean",
          "default": false,
          "description": "Enables or disables this Netify Cloud discovery engine."
        }
      }
    },
    "sinks": {
      "type": "object",
      "description": "Sink configuration.",
      "additionalProperties": {
        "type": "object",
        "description": "The specific output target (e.g., 'sink-mqtt', 'sink-http').",
        "additionalProperties": {
          "type": "object",
          "description": "The specific channel or topic for the target (e.g., 'aggregate').",
          "properties": {
            "enable": {
              "type": "boolean",
              "default": true,
              "description": "Enables or disables this specific sink channel."
            },
            "type": {
              "type": "string",
              "enum": ["mac_attributes", "device_discovery"],
              "description": "The telemetry type this channel receives. Defaults to the channel's own key name if omitted, so it only needs to be set explicitly when the channel key isn't itself \"mac_attributes\" or \"device_discovery\"."
            },
            "format": {
              "$ref": "#/$defs/formatType"
            },
            "compressor": {
              "$ref": "#/$defs/compressorType"
            },
            "flush": {
              "type": "boolean",
              "default": false,
              "description": "The flush policy."
            }
          }
        }
      }
    }
  },
  "$defs": {
    "formatType": {
      "type": "string",
      "enum": ["json", "msgpack"],
      "description": "The serialization format for the data payload."
    },
    "compressorType": {
      "type": "string",
      "enum": ["none", "gz"],
      "description": "The compression algorithm applied to the payload."
    },
    "limitType": {
      "type": "object",
      "description": "A tunable collection limit.",
      "properties": {
        "max": {
          "type": "integer",
          "minimum": 0,
          "description": "Maximum number of entries to retain.",
          "default": 10
        },
        "update_min": {
          "type": "integer",
          "minimum": 0,
          "default": 0,
          "description": "Minimum seconds between updates to an existing entry."
        },
        "update_ttl": {
          "type": "integer",
          "minimum": 0,
          "default": 0,
          "description": "Seconds an entry is retained since its last update before expiring."
        }
      },
      "additionalProperties": false
    }
  },
  "examples": [
    {
      "compressor": "gz",
      "format": "json",
      "confidence_policy": {
        "max": 80,
        "update_ttl": 86400
      },
      "macs_policy": 1500,
      "mac_age_policy": 4147200,
      "path_device_cache": "${path_state_persistent}/device-discovery-cache.json",
      "device_mac_ignore": [
        "00:00:00:00:00:00",
        "ff:ff:ff:ff:ff:ff"
      ],
      "http": {
        "user_agents_policy": {
          "max": 10
        }
      },
      "mdns": {
        "answers_policy": {
          "max": 10
        }
      },
      "ssdp": {
        "user_agents_policy": {
          "max": 10
        }
      },
      "client_ja4_policy": {
        "max": 10,
        "update_min": 1,
        "update_ttl": 3600
      },
      "netify_api": {
        "enable": true
      },
      "sinks": {
        "sink-log": {
          "mac_attributes": {
            "type": "mac_attributes",
            "enable": true,
            "flush": true,
            "format": "json",
            "compressor": "none"
          },
          "device_discovery": {
            "type": "device_discovery",
            "enable": true,
            "flush": true,
            "format": "json",
            "compressor": "none"
          }
        }
      }
    }
  ]
}
