garak/payloads.py implements the payload/probe separation introduced at v0.10.0, where attack content (payloads) is decoupled from probe logic and managed by a Director that scans a payload directory.[1] Payload files are loaded from PAYLOAD_DIR, which resolves to garak/data/payloads/ (i.e., data_path / "payloads").[1] garak/resources/autodan/genetic.py unconditionally imports Garak's NLTK wrapper module to ensure NLTK's data cache is redirected to the Garak-managed location, regardless of which code path initialises the library first. Importing NLTK directly before Garak's NLTK wrapper is initialised causes data to be written to or read from the wrong cache directory, producing subtle inconsistencies in AutoDAN and other resource-dependent probes.
Payload JSON files must match PAYLOAD_SCHEMA in garak/payloads.py, which requires three fields — garak_payload_name (string), payload_types (array of strings), and payloads (array of strings) — with optional fields intent, detector_name, detector_config, and lang.[1]
PayloadGroup._load() raises garak.exception.PayloadFailure on file-not-found, JSON decode errors, and JSON schema validation failures, and does not silently swallow these errors.[1] PayloadGroup._load() also raises garak.exception.PayloadFailure if detector_config is present but cannot be coerced to a dict.[1] Director.load() raises garak.exception.PayloadFailure if the requested payload name is not found in the registered payload_list.[1] When a garak report file is open, PayloadGroup._load() writes a payload_init JSONL entry to the report file containing the payload name, path, entry count, file size, and modification time.[1]
garak/payloads.py exposes module-level search() and load() convenience functions that internally construct a Director instance, providing a simpler public API without requiring callers to manage the Director directly.[1]
Sources