attacklm 0.5.0__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. {attacklm-0.5.0 → attacklm-0.5.2}/ATTRIBUTION.md +25 -26
  2. {attacklm-0.5.0 → attacklm-0.5.2}/CHANGELOG.md +69 -0
  3. {attacklm-0.5.0 → attacklm-0.5.2}/PKG-INFO +126 -88
  4. {attacklm-0.5.0 → attacklm-0.5.2}/QA_BEFORE_RELEASES.md +1 -1
  5. {attacklm-0.5.0 → attacklm-0.5.2}/README.md +124 -86
  6. {attacklm-0.5.0 → attacklm-0.5.2}/hf/README.md +56 -56
  7. {attacklm-0.5.0 → attacklm-0.5.2}/hf/dataset_infos.json +1 -1
  8. {attacklm-0.5.0 → attacklm-0.5.2}/pyproject.toml +1 -1
  9. attacklm-0.5.2/src/attacklm/__version__.py +1 -0
  10. attacklm-0.5.0/src/attacklm/__version__.py +0 -1
  11. {attacklm-0.5.0 → attacklm-0.5.2}/.github/workflows/release.yml +0 -0
  12. {attacklm-0.5.0 → attacklm-0.5.2}/.gitignore +0 -0
  13. {attacklm-0.5.0 → attacklm-0.5.2}/CONTRIBUTING.md +0 -0
  14. {attacklm-0.5.0 → attacklm-0.5.2}/EVALUATION.md +0 -0
  15. {attacklm-0.5.0 → attacklm-0.5.2}/LICENSE +0 -0
  16. {attacklm-0.5.0 → attacklm-0.5.2}/MANIFEST.in +0 -0
  17. {attacklm-0.5.0 → attacklm-0.5.2}/Makefile +0 -0
  18. {attacklm-0.5.0 → attacklm-0.5.2}/NOTICE +0 -0
  19. {attacklm-0.5.0 → attacklm-0.5.2}/REPLAY_PLAN.md +0 -0
  20. {attacklm-0.5.0 → attacklm-0.5.2}/data/ATTRIBUTION.md +0 -0
  21. {attacklm-0.5.0 → attacklm-0.5.2}/data/LEGAL.md +0 -0
  22. {attacklm-0.5.0 → attacklm-0.5.2}/data/REMOVAL.md +0 -0
  23. {attacklm-0.5.0 → attacklm-0.5.2}/data/bench/questions.jsonl +0 -0
  24. {attacklm-0.5.0 → attacklm-0.5.2}/data/bench/speed_context.txt +0 -0
  25. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/ATTRIBUTION.md +0 -0
  26. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/GEMINI_RESEARCH_2026-06-11.md +0 -0
  27. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/acquisition_report.json +0 -0
  28. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/manifest.json +0 -0
  29. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/README.md +0 -0
  30. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/_index.json +0 -0
  31. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/LICENSE.md +0 -0
  32. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/SOURCE.md +0 -0
  33. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/collection/data.jsonl +0 -0
  34. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/discovery/data.jsonl +0 -0
  35. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/execution/data.jsonl +0 -0
  36. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/exfiltration/data.jsonl +0 -0
  37. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/atomic-red-team/base/persistence/data.jsonl +0 -0
  38. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md +0 -0
  39. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md +0 -0
  40. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/attacklm-synthetic/orchestrator/data.jsonl +0 -0
  41. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/azure-pyrit/LICENSE.md +0 -0
  42. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/azure-pyrit/SOURCE.md +0 -0
  43. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/cyberark-fuzzyai/LICENSE.md +0 -0
  44. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/cyberark-fuzzyai/SOURCE.md +0 -0
  45. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/elastic-rules/LICENSE.md +0 -0
  46. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/elastic-rules/SOURCE.md +0 -0
  47. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/LICENSE.md +0 -0
  48. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/SOURCE.md +0 -0
  49. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/cloud/attacks/data_llm.jsonl +0 -0
  50. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/ics/attacks/data_llm.jsonl +0 -0
  51. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/social_engineering/phishing/data_llm.jsonl +0 -0
  52. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/llm-generated/wireless/attacks/data_llm.jsonl +0 -0
  53. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md +0 -0
  54. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md +0 -0
  55. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/collection/data.jsonl +0 -0
  56. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/credential_access/data.jsonl +0 -0
  57. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/defense_evasion/data.jsonl +0 -0
  58. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/discovery/data.jsonl +0 -0
  59. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/execution/data.jsonl +0 -0
  60. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/lateral_movement/data.jsonl +0 -0
  61. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/persistence/data.jsonl +0 -0
  62. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/base/privilege_escalation/data.jsonl +0 -0
  63. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/metasploit-framework/tools/metasploit/data.jsonl +0 -0
  64. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md +0 -0
  65. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md +0 -0
  66. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-atlas-arsenal/base/discovery/data.jsonl +0 -0
  67. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/LICENSE.md +0 -0
  68. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/SOURCE.md +0 -0
  69. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/collection/data.jsonl +0 -0
  70. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/discovery/data.jsonl +0 -0
  71. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/execution/data.jsonl +0 -0
  72. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/exfiltration/data.jsonl +0 -0
  73. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mitre-stockpile/base/persistence/data.jsonl +0 -0
  74. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mordor/LICENSE.md +0 -0
  75. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/mordor/SOURCE.md +0 -0
  76. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nist-ir/LICENSE.md +0 -0
  77. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nist-ir/SOURCE.md +0 -0
  78. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/LICENSE.md +0 -0
  79. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/SOURCE.md +0 -0
  80. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/nvidia-garak/ai/jailbreaking/data.jsonl +0 -0
  81. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/LICENSE.md +0 -0
  82. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/SOURCE.md +0 -0
  83. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptfoo/ai/prompt-injection/data.jsonl +0 -0
  84. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/LICENSE.md +0 -0
  85. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/SOURCE.md +0 -0
  86. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/promptmap/ai/prompt-injection/data.jsonl +0 -0
  87. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/LICENSE.md +0 -0
  88. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/SOURCE.md +0 -0
  89. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_code.jsonl +0 -0
  90. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_conversation.jsonl +0 -0
  91. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_factual.jsonl +0 -0
  92. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/replay-general/base/replay/data_reasoning.jsonl +0 -0
  93. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/sigma-hq/LICENSE.md +0 -0
  94. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/sigma-hq/SOURCE.md +0 -0
  95. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/splunk-content/LICENSE.md +0 -0
  96. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/splunk-content/SOURCE.md +0 -0
  97. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md +0 -0
  98. {attacklm-0.5.0 → attacklm-0.5.2}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md +0 -0
  99. {attacklm-0.5.0 → attacklm-0.5.2}/data/golden/prompts.jsonl +0 -0
  100. {attacklm-0.5.0 → attacklm-0.5.2}/data/reference/prompts.jsonl +0 -0
  101. {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/opsec_aware.txt +0 -0
  102. {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/opsec_unaware.txt +0 -0
  103. {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/succinct.txt +0 -0
  104. {attacklm-0.5.0 → attacklm-0.5.2}/data/steering/prompts/verbose.txt +0 -0
  105. {attacklm-0.5.0 → attacklm-0.5.2}/experiments/README.md +0 -0
  106. {attacklm-0.5.0 → attacklm-0.5.2}/experiments/synthetic_dataset_mutator_evol_instruct.py +0 -0
  107. {attacklm-0.5.0 → attacklm-0.5.2}/hf/.gitattributes +0 -0
  108. {attacklm-0.5.0 → attacklm-0.5.2}/hf/data/manifest.json +0 -0
  109. {attacklm-0.5.0 → attacklm-0.5.2}/hf/scripts/build_hf_dataset.py +0 -0
  110. {attacklm-0.5.0 → attacklm-0.5.2}/hf/scripts/push_to_hf.py +0 -0
  111. {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/.gitkeep +0 -0
  112. {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/hpo_state.json +0 -0
  113. {attacklm-0.5.0 → attacklm-0.5.2}/hpo_runs/hpo_trial_dataset.jsonl +0 -0
  114. {attacklm-0.5.0 → attacklm-0.5.2}/logs/.gitkeep +0 -0
  115. {attacklm-0.5.0 → attacklm-0.5.2}/notes/BLUE_TEAM_DESIGN_v0.5.0.md +0 -0
  116. {attacklm-0.5.0 → attacklm-0.5.2}/notes/EVAL_DESIGN_v0.4.0.md +0 -0
  117. {attacklm-0.5.0 → attacklm-0.5.2}/notes/STEERING_REVIEW_v0.4.0.md +0 -0
  118. {attacklm-0.5.0 → attacklm-0.5.2}/presets/blue-team.json +0 -0
  119. {attacklm-0.5.0 → attacklm-0.5.2}/presets/purple-team.json +0 -0
  120. {attacklm-0.5.0 → attacklm-0.5.2}/presets/red-team.json +0 -0
  121. {attacklm-0.5.0 → attacklm-0.5.2}/requirements.txt +0 -0
  122. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/_eval_loader.py +0 -0
  123. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_cloud_attack_dataset.py +0 -0
  124. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_ics_dataset.py +0 -0
  125. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_phishing_dataset.py +0 -0
  126. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_red_team_tactics.py +0 -0
  127. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_replay_general.py +0 -0
  128. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_supply_chain_dataset.py +0 -0
  129. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_web_attack_dataset.py +0 -0
  130. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/acquire_wireless_dataset.py +0 -0
  131. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/add_attribution.py +0 -0
  132. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/audit_dataset.py +0 -0
  133. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/augment_attribution.py +0 -0
  134. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/balance_buckets.py +0 -0
  135. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/bucket_loader.py +0 -0
  136. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/build.py +0 -0
  137. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/classify_unrouted_modules.py +0 -0
  138. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/clone_repos.sh +0 -0
  139. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/collect_reference.py +0 -0
  140. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/compare_scores.py +0 -0
  141. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/convert_to_gguf.py +0 -0
  142. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/dedupe_and_import_llm.py +0 -0
  143. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/demo.py +0 -0
  144. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/device_utils.py +0 -0
  145. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/domain_bench.py +0 -0
  146. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/eval_retention.py +0 -0
  147. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_ai_tools_to_jsonl.py +0 -0
  148. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_atomic_red_team_to_jsonl.py +0 -0
  149. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_by_tactic.py +0 -0
  150. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_caldera_plugins_to_jsonl.py +0 -0
  151. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_elastic_rules.py +0 -0
  152. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_infection_monkey_to_jsonl.py +0 -0
  153. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_mordor.py +0 -0
  154. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_nist_ir.py +0 -0
  155. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_rta_to_jsonl.py +0 -0
  156. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_sigma_defensive.py +0 -0
  157. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_splunk_content.py +0 -0
  158. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/extract_threathunter_playbook.py +0 -0
  159. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_dataset.py +0 -0
  160. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_dataset_deterministic.py +0 -0
  161. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_hybrid_dataset.py +0 -0
  162. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_metasploit_dataset.py +0 -0
  163. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_orchestrator.py +0 -0
  164. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_prompt_injection.py +0 -0
  165. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_source_layout.py +0 -0
  166. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/generate_synthetic_scarce.py +0 -0
  167. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/golden_vectors.py +0 -0
  168. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/hpo_runner.py +0 -0
  169. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/import_gguf.sh +0 -0
  170. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/import_to_lmstudio.sh +0 -0
  171. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/infer.py +0 -0
  172. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/init_pipeline.py +0 -0
  173. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/llm_generate_wrapper.py +0 -0
  174. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/merge_adapter.py +0 -0
  175. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/migrate_buckets_to_v021.py +0 -0
  176. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/migrate_v015_to_v020.py +0 -0
  177. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/mitre_tactic_lookup.py +0 -0
  178. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/parse_metasploit_to_jsonl.py +0 -0
  179. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/rebuild_manifest.py +0 -0
  180. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/register_ollama.py +0 -0
  181. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/reorganize_buckets.py +0 -0
  182. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/replay_mixer.py +0 -0
  183. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/run_all_acquisitions.py +0 -0
  184. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/score_candidates.py +0 -0
  185. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/scrub_bpl_callback.py +0 -0
  186. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/setup_buckets.py +0 -0
  187. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/speed_bench.py +0 -0
  188. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/stamp_and_reorg.py +0 -0
  189. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/steering.py +0 -0
  190. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/train_all.py +0 -0
  191. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/train_template.py +0 -0
  192. {attacklm-0.5.0 → attacklm-0.5.2}/scripts/validate_per_category.py +0 -0
  193. {attacklm-0.5.0 → attacklm-0.5.2}/src/attacklm/__init__.py +0 -0
  194. {attacklm-0.5.0 → attacklm-0.5.2}/src/attacklm/cli.py +0 -0
  195. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_balance_buckets.py +0 -0
  196. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_collect_reference.py +0 -0
  197. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_compare_scores.py +0 -0
  198. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_domain_bench.py +0 -0
  199. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_eval_loader.py +0 -0
  200. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_eval_retention.py +0 -0
  201. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_golden_vectors.py +0 -0
  202. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_init_pipeline.py +0 -0
  203. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_replay_mixer.py +0 -0
  204. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_score_candidates.py +0 -0
  205. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_speed_bench.py +0 -0
  206. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_steering.py +0 -0
  207. {attacklm-0.5.0 → attacklm-0.5.2}/tests/test_thinking_models.py +0 -0
  208. {attacklm-0.5.0 → attacklm-0.5.2}/uv.lock +0 -0
@@ -16,11 +16,12 @@ artifact* learned from these sources; they are not a verbatim copy.
16
16
  attribution in this file** per each source's license.
17
17
  - If you modify the training data, **document what you changed**.
18
18
  - If you re-distribute the trained model commercially, **review the
19
- AGPLv3 RTA note below** — it has network-distribution implications.
19
+ DRL-1.1 and BSD-3-Clause requirements below** — they have attribution
20
+ obligations.
20
21
 
21
22
  ---
22
23
 
23
- ## Training Data Sources (16,982 pairs across 16 buckets)
24
+ ## Training Data Sources (21,865 pairs across 23 buckets)
24
25
 
25
26
  ### 1. Atomic Red Team (redcanaryco)
26
27
 
@@ -239,26 +240,27 @@ AGPLv3 terms.
239
240
 
240
241
  The full per-bucket manifest is at `data/datasets/buckets/manifest.json`.
241
242
  It records which pairs come from which upstream source (via the
242
- `source_file` field). Total: **16,982 pairs across 16 buckets**.
243
+ `source_file` field). Total: **21,865 pairs across 23 buckets**.
243
244
 
244
245
  | Bucket | Pairs | Upstream sources |
245
- |---|---:|---|
246
- | collection | 634 | atomic, caldera, metasploit |
247
- | command_and_control | 105 | atomic, caldera, metasploit |
248
- | credential_access | 589 | atomic, caldera, infection_monkey, metasploit |
249
- | defense_evasion | 1,375 | atomic, caldera, metasploit, RTA |
250
- | discovery | 1,846 | atomic, caldera, infection_monkey, metasploit, RTA |
251
- | execution | 767 | atomic, caldera, infection_monkey, metasploit, RTA |
252
- | exfiltration | 173 | atomic, caldera, metasploit |
253
- | lateral_movement | 252 | atomic, caldera, infection_monkey, metasploit |
254
- | persistence | 1,120 | atomic, caldera, infection_monkey, metasploit, RTA |
255
- | privilege_escalation | 537 | atomic, caldera, metasploit |
246
+ |---|---|---:|
247
+ | collection | 634 | atomic, metasploit, stockpile |
248
+ | command_and_control | 105 | atomic, metasploit, stockpile |
249
+ | credential_access | 589 | metasploit |
250
+ | defense_evasion | 1,375 | metasploit |
251
+ | discovery | 1,846 | atomic, metasploit, stockpile, atlas-arsenal |
252
+ | execution | 767 | atomic, metasploit, stockpile |
253
+ | exfiltration | 53 | atomic, stockpile |
254
+ | lateral_movement | 252 | metasploit |
255
+ | persistence | 1,120 | atomic, metasploit, stockpile |
256
+ | privilege_escalation | 537 | metasploit |
256
257
  | orchestrator | 380 | synthetic |
257
- | ai/jailbreaking | 56 | garak, PyRIT, FuzzyAI, TheBigPromptLibrary |
258
+ | ai/jailbreaking | 50 | garak |
258
259
  | ai/prompt-injection | 687 | promptfoo, promptmap, synthetic |
259
- | tools/infection_monkey | 36 | guardicore/monkey |
260
260
  | tools/metasploit | 8,349 | rapid7/metasploit-framework |
261
- | tools/rta | 76 | endgameinc/RTA (AGPLv3) |
261
+ | defensive/detection_engineering | 5,000 | sigma-hq, elastic-rules, splunk-content |
262
+ | defensive/threat_hunting | 650 | mordor, threathunter-playbook |
263
+ | defensive/incident_response | 200 | nist-ir |
262
264
 
263
265
  ---
264
266
 
@@ -268,16 +270,13 @@ If you fork AttackLM and re-distribute:
268
270
 
269
271
  1. **Keep this `ATTRIBUTION.md` file intact** in any derivative repo.
270
272
  2. **Keep all upstream LICENSE files** in `data/<source>/LICENSE*`.
271
- 3. **Do not remove any source's attribution** when removing its data
272
- if you remove the RTA bucket, also remove the RTA entry above.
273
- 4. **For Apache 2.0 sources (Caldera, MITRE ATT&CK, garak, FuzzyAI):**
273
+ 3. **Do not remove any source's attribution** when removing its data.
274
+ 4. **For Apache 2.0 sources (Caldera, garak, Mordor, ThreatHunter-Playbook, Splunk):**
274
275
  include a `NOTICE` file in your distribution (template below).
275
- 5. **For AGPLv3 (RTA):** if you host a model trained on RTA data over
276
- a network, provide access to the corresponding source — this
277
- public GitHub repo satisfies that requirement.
278
- 6. **For GPLv3 (Infection Monkey):** the dataset is a transformation
279
- of upstream code; the GPL may apply to the JSONL files but not
280
- to model weights learned from them.
276
+ 5. **For BSD-3-Clause (Metasploit):** preserve the copyright notice and
277
+ license text in derivative works per BSD §1.
278
+ 6. **For DRL-1.1 (Sigma):** preserve attribution to Sigma rule authors
279
+ per the Detection Rule License.
281
280
 
282
281
  ### NOTICE template (required by Apache 2.0)
283
282
 
@@ -4,6 +4,75 @@ All notable changes to AttackLM are documented in this file. Versions follow [Se
4
4
 
5
5
  ---
6
6
 
7
+ ## [0.5.0] — 2026-06-24 — Blue-team data sources, team presets, defensive extractors
8
+
9
+ ### Added
10
+
11
+ - **6 new blue-team/defensive data sources** (~5,850 pairs):
12
+ - SigmaHQ/sigma: 3,000 detection rules (DRL-1.1)
13
+ - Elastic/detection-rules: 1,200 EQL/KQL rules (Elastic-2.0)
14
+ - Splunk/security_content: 800 SPL detections (Apache-2.0)
15
+ - OTRF/Security-Datasets (Mordor): 500 event log scenarios (Apache-2.0)
16
+ - OTRF/ThreatHunter-Playbook: 150 hunting playbooks (Apache-2.0)
17
+ - NIST SP 800-61r3: 200 IR procedure pairs (Public Domain, template-based)
18
+ - **6 new extractor scripts**: `extract_sigma_defensive.py`, `extract_elastic_rules.py`,
19
+ `extract_splunk_content.py`, `extract_mordor.py`, `extract_threathunter_playbook.py`,
20
+ `extract_nist_ir.py`
21
+ - **3 team presets** (`presets/red-team.json`, `purple-team.json`, `blue-team.json`)
22
+ with pre-configured bucket weights for offensive/defensive mix control
23
+ - **`--preset` and `--system-prompt` flags** on `attacklm-balance`
24
+ - **3 new defensive buckets**: `defensive/detection_engineering` (5,000),
25
+ `defensive/threat_hunting` (650), `defensive/incident_response` (200)
26
+ - **12 attribution files** (SOURCE.md + LICENSE.md per new source)
27
+ - **`notes/BLUE_TEAM_DESIGN_v0.5.0.md`** — full architectural plan (792 lines)
28
+
29
+ ### Changed
30
+
31
+ - `scripts/init_pipeline.py` — 5 new local probes, 5 new remote repos, 6 new extractors
32
+ - `src/attacklm/cli.py` — 6 new extractors in extraction sequence
33
+ - `data/datasets/buckets/manifest.json` — 21,865 total pairs, 23 buckets, 17 sources
34
+ - `scripts/balance_buckets.py` — preset loading, weight resolution, `--preset` flag
35
+ - `src/attacklm/__version__.py` — bumped to `0.5.0`
36
+
37
+ ### Fixed
38
+
39
+ - `balance_buckets.py` `BASE_DIR` undefined in preset helpers
40
+ - `_caps_for_target_total` fallback for buckets not in any category share
41
+ - Manifest `total_pairs` math consistency (source_totals sum = tier_totals sum = total_pairs)
42
+
43
+ ---
44
+
45
+ ## [0.4.1] — 2026-06-22 — Evaluation framework, steering vectors, dataset cleanup
46
+
47
+ ### Added
48
+
49
+ - **7-pattern ds4 evaluation framework** (Patterns 1-7):
50
+ - Pattern 1: Reference-continuation NLL scoring (`collect_reference.py`, `score_candidates.py`, `compare_scores.py`)
51
+ - Pattern 2: Golden-vector regression gates (`golden_vectors.py`, 558 lines)
52
+ - Pattern 3: 100-question domain benchmark (`domain_bench.py`, 563 lines)
53
+ - Pattern 4: Speed profiling / context-frontier (`speed_bench.py`, 463 lines)
54
+ - Pattern 5: QA checklist (documentation)
55
+ - Pattern 6: Steering vectors (`steering.py`, 1,120 lines) — extract, apply, sweep, diagnose
56
+ - Pattern 7: Narrow-bet philosophy doc
57
+ - **Shared model loader** `_eval_loader.py` (149 lines) — extracted from `eval_retention.py`
58
+ - **4 new CLI entry points**: `attacklm-collect-ref`, `attacklm-score`, `attacklm-compare`, `attacklm-golden`
59
+ - **198 hermetic pytest tests** across 8 test files (all pass, 0.62s)
60
+ - **`notes/EVAL_DESIGN_v0.4.0.md`** (1,098 lines), **`notes/STEERING_REVIEW_v0.4.0.md`** (793 lines)
61
+ - **`EVALUATION.md`**, **`QA_BEFORE_RELEASES.md`** documentation
62
+
63
+ ### Changed
64
+
65
+ - `scripts/eval_retention.py` refactored to import from `_eval_loader.py`
66
+ - `scripts/domain_bench.py` — integrated steering vector flags
67
+ - `pyproject.toml` — 4 new eval entry points, `eval` optional-dependency group
68
+
69
+ ### Removed
70
+
71
+ - **8,649 template-generated synthetic records** deleted — dataset reduced from 25,601 → 16,015 pairs
72
+ (only 380 orchestrator records kept from synthetic sources)
73
+
74
+ ---
75
+
7
76
  ## [0.4.0] — 2026-06-22 — MoE-safe training, retention eval, and experience replay
8
77
 
9
78
  ### Added
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attacklm
3
- Version: 0.5.0
4
- Summary: QLoRA-fine-tuned Qwen2.5-Coder for offensive security and AI red-teaming
3
+ Version: 0.5.2
4
+ Summary: QLoRA-fine-tuned Qwen2.5-Coder for offensive/defensive security and AI red-teaming
5
5
  Project-URL: Homepage, https://github.com/Veedubin/AttackLM
6
6
  Project-URL: Repository, https://github.com/Veedubin/AttackLM
7
7
  Project-URL: Issues, https://github.com/Veedubin/AttackLM/issues
@@ -207,10 +207,11 @@ Description-Content-Type: text/markdown
207
207
 
208
208
  # AttackLM
209
209
 
210
- > A QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded red-team AI assistant.
211
- > 16,982 training pairs · 3B–70B Qwen base · 16GB–128GB VRAM.
210
+ > A QLoRA fine-tuning pipeline for a MITRE ATT&CK-grounded red/blue-team AI assistant.
211
+ > 21,865 training pairs · 3B–70B Qwen base · 16GB–128GB VRAM.
212
212
 
213
213
  [![License: MIT](https://img.shields.io/badge/code-MIT-blue.svg)](LICENSE)
214
+ [![PyPI version](https://img.shields.io/pypi/v/attacklm.svg)](https://pypi.org/project/attacklm/)
214
215
  [![Training data: mixed](https://img.shields.io/badge/data-mixed%20%28see%20ATTRIBUTION%29-orange.svg)](ATTRIBUTION.md)
215
216
  [![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](requirements.txt)
216
217
  [![Model: 3B-7B Qwen2.5](https://img.shields.io/badge/base%20model-Qwen2.5--Coder--3B--Instruct-green.svg)](https://huggingface.co/unsloth/Qwen2.5-Coder-3B-Instruct-bnb-4bit)
@@ -220,14 +221,17 @@ Description-Content-Type: text/markdown
220
221
  ## What is this?
221
222
 
222
223
  AttackLM is a complete pipeline for fine-tuning a small language model to be
223
- a competent red-team / AI-security assistant. The training data is grounded in
224
- **MITRE ATT&CK** techniques, sourced from openly licensed open-source projects
225
- (Atomic Red Team, MITRE Caldera, Metasploit, Sigma, Infection Monkey, RTA,
226
- plus prompt-injection and jailbreak corpora for AI-security coverage).
227
-
228
- The pipeline ingests 10 MITRE tactic buckets plus 6 specialized buckets
229
- (orchestrator routing, AI-model attacks, security tooling) and produces a
230
- QLoRA LoRA adapter you can drop on top of `Qwen2.5-Coder-3B-Instruct`.
224
+ a competent red-team / blue-team / AI-security assistant. The training data is
225
+ grounded in **MITRE ATT&CK** techniques, sourced from openly licensed
226
+ open-source projects (Atomic Red Team, MITRE Caldera, Metasploit, Sigma,
227
+ Elastic, Splunk, Mordor, ThreatHunter-Playbook, NIST IR, plus prompt-injection
228
+ and jailbreak corpora for AI-security coverage).
229
+
230
+ The pipeline ingests 10 MITRE tactic buckets, 3 defensive buckets, 3 tool
231
+ buckets, 2 AI-security buckets, 1 orchestrator bucket, and 4 extended-category
232
+ buckets (23 total) and produces a QLoRA LoRA adapter you can drop on top of
233
+ `Qwen2.5-Coder-3B-Instruct`. Team presets (red/purple/blue) let you control
234
+ the offensive/defensive mix.
231
235
 
232
236
  What makes it different:
233
237
  - **No LLM in the data pipeline.** Every training pair is deterministically
@@ -251,73 +255,68 @@ its contribution to AttackLM's training mix is documented in
251
255
  The full per-source map:
252
256
 
253
257
  | Source | Pairs | License | Repository |
254
- |---|---:|---|---|
255
- | Atomic Red Team | 2,506 | MIT | [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) |
256
- | MITRE Caldera / Stockpile | 608 | Apache-2.0 | [mitre/stockpile](https://github.com/mitre/stockpile) |
257
- | Caldera plugins (arsenal/manx/access) | 56 | Apache-2.0 | [mitre/caldera](https://github.com/mitre/caldera) |
258
- | Metasploit Framework | 8,349 | BSD-3-Clause | [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) |
259
- | Infection Monkey | 36 | GPL-3.0 | [guardicore/monkey](https://github.com/guardicore/monkey) |
260
- | RTA Red Team Automation | 76 | **AGPL-3.0** ⚠️ | [endgameinc/RTA](https://github.com/endgameinc/RTA) |
261
- | Sigma rules | (labels) | DRL-1.1 | [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) |
262
- | AI-security tools (promptfoo, garak, promptmap, PyRIT, FuzzyAI, TheBigPromptLibrary) | 743+ | mixed MIT/Apache-2.0 | various (see [ATTRIBUTION.md](ATTRIBUTION.md)) |
263
- | Synthetic orchestrator / prompt-injection | 1,067 | MIT | this repo |
264
- | **Total** | **16,982** | | |
265
-
266
- ⚠️ **AGPLv3 note:** RTA is the only AGPL-licensed source. The AGPL has
267
- network-distribution implications for derivative works. The public
268
- repository satisfies the source-availability requirement. If you need an
269
- AGPL-clean deployment, retrain after removing the `tools/rta` bucket.
270
- See [ATTRIBUTION.md §8](ATTRIBUTION.md) for the full analysis.
258
+ |---|---|---|---|
259
+ | Metasploit Framework | 13,997 | BSD-3-Clause | [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) |
260
+ | Sigma rules | 3,000 | DRL-1.1 | [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) |
261
+ | Elastic detection rules | 1,200 | Elastic-2.0 | [elastic/detection-rules](https://github.com/elastic/detection-rules) |
262
+ | Splunk security content | 800 | Apache-2.0 | [splunk/security_content](https://github.com/splunk/security_content) |
263
+ | Mordor (OTRF) | 500 | Apache-2.0 | [OTRF/Security-Datasets](https://github.com/OTRF/Security-Datasets) |
264
+ | Atomic Red Team | 1,115 | MIT | [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) |
265
+ | MITRE Caldera / Stockpile | 390 | Apache-2.0 | [mitre/stockpile](https://github.com/mitre/stockpile) |
266
+ | ThreatHunter-Playbook | 150 | Apache-2.0 | [OTRF/ThreatHunter-Playbook](https://github.com/OTRF/ThreatHunter-Playbook) |
267
+ | NIST SP 800-61r3 | 200 | Public Domain | NIST (template-based extractor) |
268
+ | AI-security tools (garak, promptfoo, promptmap) | 113 | mixed MIT/Apache-2.0 | various (see [ATTRIBUTION.md](ATTRIBUTION.md)) |
269
+ | Synthetic (orchestrator + extended categories) | 380 | MIT | this repo |
270
+ | **Total** | **21,865** | | |
271
271
 
272
272
  ---
273
273
 
274
- ## Quickstart (5 min)
274
+ ## Quickstart
275
+
276
+ ### Option A: Install from PyPI (fastest — 30 seconds)
275
277
 
276
278
  ```bash
277
279
  # 1. Install uv (Python package manager, ~10MB)
278
280
  curl -LsSf https://astral.sh/uv/install.sh | sh
279
281
 
280
- # 2. Clone this repo
282
+ # 2. Install AttackLM from PyPI with the full CUDA training stack
283
+ uv pip install "attacklm[all]"
284
+
285
+ # 3. Clone the repo for the training data (the PyPI package is code-only)
281
286
  git clone https://github.com/Veedubin/AttackLM.git
282
287
  cd AttackLM
283
288
 
284
- # 3a. Install as a Python package (gets you 11 `attacklm-*` commands)
285
- # — use `[all]` to get every optional dependency
286
- uv pip install -e ".[all]"
289
+ # 4. Initialize the dataset (probes local `data/` first; falls back to git clone)
290
+ attacklm-init --yes
287
291
 
288
- # Or, if you just want the bare CLI dispatchers (no ML stack):
289
- # uv pip install -e .
292
+ # 5. Train
293
+ attacklm-train-all --single-model \
294
+ --dataset base/ \
295
+ --base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
296
+ --epochs 5 --max-length 2048
297
+ ```
290
298
 
291
- # 3b. Alternative: classic uv-managed venv with all deps in pyproject.toml
292
- # uv sync
299
+ ### Option B: Install from source (if you want to modify the code)
293
300
 
294
- # 4. Initialize the dataset (probes local `data/` first; falls back to git clone)
301
+ ```bash
302
+ # 1. Install uv
303
+ curl -LsSf https://astral.sh/uv/install.sh | sh
304
+
305
+ # 2. Clone this repo
306
+ git clone https://github.com/Veedubin/AttackLM.git
307
+ cd AttackLM
308
+
309
+ # 3. Install as an editable Python package (gets you all `attacklm-*` commands)
310
+ uv pip install -e ".[all]"
311
+
312
+ # 4. Initialize the dataset
295
313
  attacklm-init --yes
296
314
 
297
- # The single command above replaces steps 4–7 below. If you'd rather
298
- # run each step individually, the four commands are still available:
299
- #
300
- # 4. Clone upstream data sources (~1.5GB total, optional — data is in the repo)
301
- # attacklm-clone
302
- #
303
- # 5. Extract training data from each source
304
- # attacklm-extract
305
- #
306
- # 6. Augment each JSONL with per-pair source/license attribution
307
- # attacklm-attribute
308
- #
309
- # 7. Organize into 16 MITRE/AI/tools buckets
310
- # attacklm-buckets
311
-
312
- # 8. Pick a base model — use an uncensored/abliterated one (see "Pick a base model" below)
313
- # Example: Qwen2.5-Coder-3B-Instruct with refusal direction removed
314
- # v0.2.0+ uses --dataset (multi-positional) instead of --include-tools etc.
315
+ # 5. Train
315
316
  attacklm-train-all --single-model \
316
317
  --dataset base/ \
317
318
  --base-model huihui-ai/Qwen2.5-Coder-3B-Instruct-abliterated \
318
319
  --epochs 5 --max-length 2048
319
-
320
- # Optional: add --hpo for automatic lora_r / lora_dropout sweep
321
320
  ```
322
321
 
323
322
  The trained LoRA adapter lands in `models/attacklm-single_<TIMESTAMP>/`
@@ -338,6 +337,17 @@ The project ships as a **proper Python package** (`pyproject.toml`,
338
337
  `src/attacklm/` layout, hatchling build backend) so users don't have to
339
338
  build anything by hand.
340
339
 
340
+ **Install from PyPI (recommended):**
341
+ ```bash
342
+ uv pip install "attacklm[all]" # CUDA training stack
343
+ uv pip install "attacklm[all-rocm]" # ROCm training stack
344
+ uv pip install "attacklm[infer]" # CPU / Apple Silicon (inference only)
345
+ ```
346
+
347
+ Then clone the repo for the training data: `git clone https://github.com/Veedubin/AttackLM.git`
348
+
349
+ **Install from source** (editable, for development):
350
+
341
351
  There are **two GPU stacks** — pick the one for your hardware.
342
352
 
343
353
  ---
@@ -437,7 +447,7 @@ prompts. Pick `[all-cuda]` or `[all-rocm]` for actual training.
437
447
 
438
448
  ---
439
449
 
440
- ### 11 console-script entry points
450
+ ### 21 console-script entry points
441
451
 
442
452
  All install paths give you these:
443
453
 
@@ -452,11 +462,18 @@ All install paths give you these:
452
462
  | `attacklm-build` | `scripts/build.py` | merge → GGUF → install (one shot) |
453
463
  | `attacklm-demo` | `scripts/demo.py` | Multi-agent orchestrator demo |
454
464
  | `attacklm-extract` | all 6 extractors | Extract data from cloned repos |
455
- | `attacklm-buckets` | `setup_buckets.py` + `reorganize_buckets.py` | Organize data into 16 buckets |
465
+ | `attacklm-buckets` | `setup_buckets.py` + `reorganize_buckets.py` | Organize data into 23 buckets |
456
466
  | `attacklm-attribute` | `scripts/augment_attribution.py` | Add source/license to each JSONL row |
457
467
  | `attacklm-clone` | `scripts/clone_repos.sh` | Clone upstream data repos |
458
468
  | `attacklm-init` | `scripts/init_pipeline.py` | **One-shot init: clone→extract→attribute→buckets** (probes local first) |
459
469
  | `attacklm-balance` | `scripts/balance_buckets.py` | Build a balanced subset of the buckets |
470
+ | `attacklm-build` | `scripts/build.py` | merge → GGUF → install (one shot) |
471
+ | `attacklm-train-lora` | `scripts/train_template.py` | Direct LoRA training (single dataset) |
472
+ | `attacklm-eval` | `scripts/eval_retention.py` | Retention evaluation suite |
473
+ | `attacklm-collect-ref` | `scripts/collect_reference.py` | Collect reference model outputs |
474
+ | `attacklm-score` | `scripts/score_candidates.py` | Score candidate models vs reference |
475
+ | `attacklm-compare` | `scripts/compare_scores.py` | Compare multiple candidate models |
476
+ | `attacklm-golden` | `scripts/golden_vectors.py` | Golden vector regression gates |
460
477
 
461
478
  The CLI dispatchers are thin wrappers — they use `runpy.run_path()` to
462
479
  invoke the canonical script in `scripts/`. So `scripts/` stays the
@@ -499,7 +516,7 @@ thin dispatcher layer.
499
516
 
500
517
  ## Architecture
501
518
 
502
- The training data is organized into **16 buckets**:
519
+ The training data is organized into **23 buckets**:
503
520
 
504
521
  - **10 MITRE tactic buckets** — under `base/`: `base/collection`,
505
522
  `base/command_and_control`, `base/credential_access`, `base/defense_evasion`,
@@ -510,9 +527,13 @@ The training data is organized into **16 buckets**:
510
527
  - **1 orchestrator bucket** — routing decisions across 6 sub-agents
511
528
  - **2 AI-model attack buckets** — under `ai/`: `ai/prompt-injection` and
512
529
  `ai/jailbreaking` (TA0040 — Adversarial ML)
513
- - **3 security-tool buckets** — under `tools/`: `tools/infection_monkey`,
514
- `tools/metasploit`, `tools/rta` (consolidated tool-specific data, re-routed
515
- to MITRE tactics where applicable)
530
+ - **3 security-tool buckets** — under `tools/`: `tools/metasploit`
531
+ - **3 defensive buckets** — under `defensive/`: `defensive/detection_engineering`
532
+ (Sigma, Elastic, Splunk 5,000 pairs), `defensive/threat_hunting`
533
+ (Mordor, ThreatHunter-Playbook — 650 pairs), `defensive/incident_response`
534
+ (NIST SP 800-61r3 — 200 pairs)
535
+ - **4 extended-category buckets** — `attack_tactics/`, `web_app/`, `cloud/`,
536
+ `ics/`, `wireless/`, `supply_chain/`, `social_engineering/`
516
537
 
517
538
  > **v0.2.1 layout change:** the 10 tactic buckets moved from top-level
518
539
  > into a new `base/` parent directory, and `ai-models/` was renamed to
@@ -666,13 +687,15 @@ The new dataset spec is dir-shaped and hierarchical:
666
687
  | Spec | Resolves to | Pair count |
667
688
  |-------------------------------|------------------------------------------------------|-----------:|
668
689
  | `base/` | All 10 MITRE tactic buckets | 7,398 |
669
- | `tools/` | All 3 tool buckets (metasploit, infection_monkey, rta) | 8,461 |
670
- | `tools/metasploit/` | Just metasploit | 8,349 |
671
- | `tools/infection_monkey/` | Just infection_monkey | 36 |
672
- | `tools/rta/` | Just RTA | 76 |
690
+ | `tools/` | All tool buckets (metasploit) | 13,997 |
691
+ | `tools/metasploit/` | Just metasploit | 13,997 |
673
692
  | `ai/` | Both AI buckets (jailbreaking, prompt-injection) | 743 |
693
+ | `defensive/` | All 3 defensive buckets | 5,850 |
694
+ | `defensive/detection_engineering/` | Sigma + Elastic + Splunk | 5,000 |
695
+ | `defensive/threat_hunting/` | Mordor + ThreatHunter-Playbook | 650 |
696
+ | `defensive/incident_response/` | NIST SP 800-61r3 | 200 |
674
697
  | `orchestrator` | The orchestrator bucket | 380 |
675
- | `all` | Everything (alias for `base + tools + ai + orchestrator`) | 16,982 |
698
+ | `all` | Everything (alias for `base + tools + ai + defensive + orchestrator`) | 21,865 |
676
699
  | `tactics` | Alias for `base/` | 7,398 |
677
700
 
678
701
  Multiple specs combine: `--dataset base/ tools/metasploit/` = 10 tactics + just metasploit = 15,747 pairs.
@@ -682,15 +705,17 @@ and translate internally to `--dataset` specs. The new flag wins if both are pas
682
705
 
683
706
  ### Balanced sampling (`attacklm-balance`)
684
707
 
685
- The 16 buckets are heavily skewed: `tools/metasploit` alone has 8,349
686
- pairs (49% of the 16,982 total). Training on raw `--dataset all`
708
+ The 23 buckets are heavily skewed: `tools/metasploit` alone has 13,997
709
+ pairs (64% of the 21,865 total). Training on raw `--dataset all`
687
710
  makes the model see ~2 Metasploit examples for every 1 non-Metasploit
688
711
  example, which overfits it to msfconsole syntax at the expense of
689
712
  broader tactical coverage.
690
713
 
691
714
  `attacklm-balance` builds a balanced subset of the buckets. It applies
692
715
  a per-bucket cap (one cap applied uniformly to all buckets) and
693
- selects examples from each bucket with a chosen strategy:
716
+ selects examples from each bucket with a chosen strategy. Team presets
717
+ (`--preset red-team|purple-team|blue-team`) control the offensive/defensive
718
+ mix with pre-configured bucket weights.
694
719
 
695
720
  ```bash
696
721
  # Dry-run: see the per-bucket caps + total without writing
@@ -715,7 +740,7 @@ attacklm-train --dataset data/datasets/balanced/balanced_7b-128gb.jsonl \
715
740
  | `7b-128gb` | 1,500 | ~9,800 | 7B QLoRA on 128 GB rig |
716
741
  | `14b-128gb`| 1,500 | ~9,800 | 14B QLoRA on 128 GB rig |
717
742
  | `31b-128gb`| 2,000 | ~10,600 | 31B QLoRA on 128 GB rig |
718
- | `full` | unlimited | 16,982 | All data, no cap |
743
+ | `full` | unlimited | 21,865 | All data, no cap |
719
744
  | `custom` | (you set)| (you set)| `--per-bucket-cap` or `--target-total` |
720
745
 
721
746
  **Strategies** (within a bucket, after the cap is applied):
@@ -860,20 +885,21 @@ print(tokenizer.decode(outputs[0], skip_special_tokens=True))
860
885
  ## Data Sources (upstream)
861
886
 
862
887
  | Project | License | Use |
863
- |---|---|---|
864
- | [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) | MIT | 2,506 atomic test triples |
865
- | [mitre/stockpile](https://github.com/mitre/stockpile) | Apache-2.0 | 608 adversary-emulation abilities |
866
- | [mitre/caldera](https://github.com/mitre/caldera) | Apache-2.0 | 56 plugin descriptors |
867
- | [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) | BSD-3-Clause | 8,349 module description triples |
868
- | [guardicore/monkey](https://github.com/guardicore/monkey) | GPL-3.0 | 36 plugin manifest triples |
869
- | [endgameinc/RTA](https://github.com/endgameinc/RTA) | **AGPL-3.0** ⚠️ | 76 Python TTP triples |
870
- | [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) | DRL-1.1 | Auxiliary context for triple structure |
888
+ |---|---|---|---|
889
+ | [rapid7/metasploit-framework](https://github.com/rapid7/metasploit-framework) | BSD-3-Clause | 13,997 module description triples |
890
+ | [SigmaHQ/sigma](https://github.com/SigmaHQ/sigma) | DRL-1.1 | 3,000 detection rules |
891
+ | [elastic/detection-rules](https://github.com/elastic/detection-rules) | Elastic-2.0 | 1,200 EQL/KQL detection rules |
892
+ | [splunk/security_content](https://github.com/splunk/security_content) | Apache-2.0 | 800 SPL detections |
893
+ | [redcanaryco/atomic-red-team](https://github.com/redcanaryco/atomic-red-team) | MIT | 1,115 atomic test triples |
894
+ | [OTRF/Security-Datasets](https://github.com/OTRF/Security-Datasets) | Apache-2.0 | 500 Mordor event log scenarios |
895
+ | [mitre/stockpile](https://github.com/mitre/stockpile) | Apache-2.0 | 390 adversary-emulation abilities |
896
+ | [OTRF/ThreatHunter-Playbook](https://github.com/OTRF/ThreatHunter-Playbook) | Apache-2.0 | 150 hunting playbooks |
897
+ | NIST SP 800-61r3 | Public Domain | 200 IR procedure pairs (template-based) |
871
898
  | [promptfoo/promptfoo](https://github.com/promptfoo/promptfoo) | MIT | Prompt injection probes |
872
899
  | [NVIDIA/garak](https://github.com/NVIDIA/garak) | Apache-2.0 | DAN/probe resources |
873
900
  | [utkusen/promptmap](https://github.com/utkusen/promptmap) | MIT | Prompt injection rules |
874
- | [Azure/PyRIT](https://github.com/Azure/PyRIT) | MIT | Jailbreak templates |
875
- | [cyberark/FuzzyAI](https://github.com/cyberark/FuzzyAI) | Apache-2.0 | Adversarial prompt resources |
876
- | [Resident-Falker/TheBigPromptLibrary](https://github.com/Resident-Falker/TheBigPromptLibrary) | mixed MIT/MPL | Jailbreak + system prompt library |
901
+ | [Azure/PyRIT](https://github.com/Azure/PyRIT) | MIT | Jailbreak templates (reserved) |
902
+ | [cyberark/FuzzyAI](https://github.com/cyberark/FuzzyAI) | Apache-2.0 | Adversarial prompt resources (reserved) |
877
903
 
878
904
  Full attribution, per-pair source mapping, and re-distribution guidance in
879
905
  [**`/ATTRIBUTION.md`**](ATTRIBUTION.md).
@@ -883,8 +909,10 @@ Full attribution, per-pair source mapping, and re-distribution guidance in
883
909
  ## License
884
910
 
885
911
  - **Code in this repository** — [MIT License](LICENSE)
886
- - **Training data** — inherits the most restrictive license of its components
887
- (currently AGPL-3.0 from RTA see [ATTRIBUTION.md §8](ATTRIBUTION.md))
912
+ - **Training data** — mixed licenses per source. The most restrictive
913
+ licenses in the dataset are DRL-1.1 (Sigma rules) and BSD-3-Clause
914
+ (Metasploit Framework). See [ATTRIBUTION.md](ATTRIBUTION.md) for the
915
+ full per-source license table.
888
916
  - **Trained model weights** — MIT License as a new statistical artifact
889
917
  learned from openly licensed material. Whether model weights are a
890
918
  "derivative work" in the copyright sense is an unsettled question; no
@@ -908,6 +936,16 @@ submitting PRs, and extending the bucket/extractor system.
908
936
  See [CHANGELOG.md](CHANGELOG.md) for the full version history. Notable
909
937
  recent releases:
910
938
 
939
+ - **v0.5.0** (2026-06-24) — Blue-team data sources (6 new extractors,
940
+ 5,850 pairs), team presets (red/purple/blue), 3 defensive buckets,
941
+ 21,865 total pairs, 23 buckets.
942
+ - **v0.4.1** (2026-06-22) — 7-pattern ds4 evaluation framework,
943
+ steering vectors, 198 hermetic tests, dataset cleanup (8,649
944
+ synthetic records removed).
945
+ - **v0.4.0** (2026-06-22) — MoE-safe training, retention eval,
946
+ experience replay, DoRA/LoftQ support.
947
+ - **v0.3.0** (2026-06-11) — Dataset license audit, per-source layout,
948
+ RTA/Infection Monkey/BPL removed, 100% per-record attribution.
911
949
  - **v0.2.2** (2026-06-10) — `attacklm-balance` (balanced bucket sampler),
912
950
  `attacklm-build` (one-shot merge+GGUF+install), auto-timestamped
913
951
  run dirs in `attacklm-train`, accurate epoch counter, GGUF
@@ -927,6 +965,6 @@ recent releases:
927
965
  ## Acknowledgments
928
966
 
929
967
  Thanks to the open-source security community — Red Canary, MITRE, Rapid7,
930
- Guardicore, Endgame/Elastic, the SigmaHQ maintainers, the promptfoo,
968
+ Elastic, Splunk, OTRF, NIST, the SigmaHQ maintainers, the promptfoo,
931
969
  garak, PyRIT, and FuzzyAI teams, and everyone who contributes to the
932
970
  projects we depend on. AttackLM stands on their shoulders.
@@ -12,7 +12,7 @@
12
12
  **Threshold**: 0 errors, 0 warnings
13
13
 
14
14
  **Checks**:
15
- - All 25,601 records present across 20 buckets
15
+ - All 21,865 records present across 23 buckets
16
16
  - No duplicate records
17
17
  - All required fields present (messages, source, license, attribution)
18
18
  - License attribution complete for all records