attacklm 0.6.4__tar.gz → 0.6.6__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.
- {attacklm-0.6.4 → attacklm-0.6.6}/PKG-INFO +1 -1
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/train_template.py +294 -8
- attacklm-0.6.6/src/attacklm/__version__.py +1 -0
- attacklm-0.6.4/src/attacklm/__version__.py +0 -1
- {attacklm-0.6.4 → attacklm-0.6.6}/.github/workflows/release.yml +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/.gitignore +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/ATTRIBUTION.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/CHANGELOG.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/CONTRIBUTING.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/EVALUATION.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/LICENSE +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/MANIFEST.in +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/Makefile +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/NOTICE +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/QA_BEFORE_RELEASES.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/README.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/REPLAY_PLAN.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/ATTRIBUTION.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/LEGAL.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/REMOVAL.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/bench/questions.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/bench/speed_context.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/ATTRIBUTION.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/GEMINI_RESEARCH_2026-06-11.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/acquisition_report.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/manifest.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/README.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/_index.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/base/collection/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/base/discovery/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/base/execution/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/atomic-red-team/base/persistence/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/attacklm-synthetic/orchestrator/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/azure-pyrit/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/azure-pyrit/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/cyberark-fuzzyai/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/cyberark-fuzzyai/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/elastic-rules/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/elastic-rules/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/cloud/attacks/data_llm.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/ics/attacks/data_llm.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/social_engineering/phishing/data_llm.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/llm-generated/wireless/attacks/data_llm.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/collection/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/credential_access/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/defense_evasion/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/discovery/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/execution/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/lateral_movement/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/persistence/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/base/privilege_escalation/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/tools/metasploit/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-atlas-arsenal/base/discovery/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/base/collection/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/base/discovery/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/base/execution/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/base/exfiltration/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-stockpile/base/persistence/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mordor/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mordor/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/nist-ir/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/nist-ir/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/nvidia-garak/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/nvidia-garak/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/nvidia-garak/ai/jailbreaking/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptfoo/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptfoo/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptfoo/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptmap/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptmap/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/promptmap/ai/prompt-injection/data.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/base/replay/data_code.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/base/replay/data_conversation.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/base/replay/data_factual.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/replay-general/base/replay/data_reasoning.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/sigma-hq/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/sigma-hq/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/splunk-content/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/splunk-content/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/golden/prompts.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/reference/prompts.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/steering/prompts/opsec_aware.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/steering/prompts/opsec_unaware.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/steering/prompts/succinct.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/data/steering/prompts/verbose.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/experiments/README.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/experiments/synthetic_dataset_mutator_evol_instruct.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/.gitattributes +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/README.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/data/manifest.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/dataset_infos.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/scripts/build_hf_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hf/scripts/push_to_hf.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hpo_runs/.gitkeep +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hpo_runs/hpo_state.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/hpo_runs/hpo_trial_dataset.jsonl +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/logs/.gitkeep +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/notes/BLUE_TEAM_DESIGN_v0.5.0.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/notes/EVAL_DESIGN_v0.4.0.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/notes/STEERING_REVIEW_v0.4.0.md +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/pipeline.example.yaml +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/presets/blue-team.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/presets/purple-team.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/presets/red-team.json +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/pyproject.toml +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/requirements.txt +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/_eval_loader.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_cloud_attack_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_ics_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_phishing_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_red_team_tactics.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_replay_general.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_supply_chain_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_web_attack_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/acquire_wireless_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/add_attribution.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/audit_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/augment_attribution.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/balance_buckets.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/bucket_loader.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/build.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/classify_unrouted_modules.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/clone_repos.sh +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/collect_reference.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/compare_scores.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/convert_to_gguf.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/dedupe_and_import_llm.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/demo.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/device_utils.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/domain_bench.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/eval_retention.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_ai_tools_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_atomic_red_team_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_by_tactic.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_caldera_plugins_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_elastic_rules.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_infection_monkey_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_mordor.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_nist_ir.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_rta_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_sigma_defensive.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_splunk_content.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/extract_threathunter_playbook.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_dataset_deterministic.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_hybrid_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_metasploit_dataset.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_orchestrator.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_prompt_injection.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_source_layout.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/generate_synthetic_scarce.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/golden_vectors.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/hpo_runner.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/import_gguf.sh +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/import_to_lmstudio.sh +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/infer.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/init_pipeline.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/llm_generate_wrapper.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/merge_adapter.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/migrate_buckets_to_v021.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/migrate_v015_to_v020.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/mitre_tactic_lookup.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/parse_metasploit_to_jsonl.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/pipeline.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/rebuild_manifest.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/register_ollama.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/reorganize_buckets.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/replay_mixer.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/run_all_acquisitions.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/score_candidates.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/scrub_bpl_callback.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/setup_buckets.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/speed_bench.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/stamp_and_reorg.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/steering.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/train_all.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/scripts/validate_per_category.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/src/attacklm/__init__.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/src/attacklm/_project_root.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/src/attacklm/cli.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_balance_buckets.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_collect_reference.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_compare_scores.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_domain_bench.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_eval_loader.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_eval_retention.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_golden_vectors.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_init_pipeline.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_replay_mixer.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_score_candidates.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_speed_bench.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_steering.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/tests/test_thinking_models.py +0 -0
- {attacklm-0.6.4 → attacklm-0.6.6}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: attacklm
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.6
|
|
4
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
|
|
@@ -194,8 +194,10 @@ Examples:
|
|
|
194
194
|
"--gradient-accumulation-steps",
|
|
195
195
|
type=int,
|
|
196
196
|
default=1,
|
|
197
|
-
help="Gradient accumulation steps —
|
|
198
|
-
"effective_batch = batch_size × grad_accum.
|
|
197
|
+
help="Gradient accumulation steps — smoother gradients without extra VRAM. "
|
|
198
|
+
"effective_batch = batch_size × grad_accum. "
|
|
199
|
+
"Does NOT help with OOM (can't go below batch_size=1). "
|
|
200
|
+
"(default: 1)",
|
|
199
201
|
)
|
|
200
202
|
parser.add_argument(
|
|
201
203
|
"--optim",
|
|
@@ -242,6 +244,34 @@ Examples:
|
|
|
242
244
|
"Used by HPO trials to cap run-length at a fixed budget. "
|
|
243
245
|
"Default: -1 (use --epochs)",
|
|
244
246
|
)
|
|
247
|
+
parser.add_argument(
|
|
248
|
+
"--auto-tune",
|
|
249
|
+
action="store_true",
|
|
250
|
+
default=False,
|
|
251
|
+
help=(
|
|
252
|
+
"Auto-tune batch_size and max_length for your GPU. Runs a "
|
|
253
|
+
"warmup epoch with increasing max_length to find the "
|
|
254
|
+
"compute-bound sweet spot (where tok/s stops improving). "
|
|
255
|
+
"Saves optimal config to <output>/auto_tune.json for reuse. "
|
|
256
|
+
"On restart, loads from JSON if it exists (skip with --no-auto-tune)."
|
|
257
|
+
),
|
|
258
|
+
)
|
|
259
|
+
parser.add_argument(
|
|
260
|
+
"--no-auto-tune",
|
|
261
|
+
dest="auto_tune",
|
|
262
|
+
action="store_false",
|
|
263
|
+
help="Disable auto-tuning (default).",
|
|
264
|
+
)
|
|
265
|
+
parser.add_argument(
|
|
266
|
+
"--live-lr",
|
|
267
|
+
action="store_true",
|
|
268
|
+
default=False,
|
|
269
|
+
help=(
|
|
270
|
+
"Live learning rate adjustment: reduce LR by 50% when loss "
|
|
271
|
+
"plateaus (same detection as early stopping). Restarts from "
|
|
272
|
+
"best checkpoint on each reduction. Default: OFF."
|
|
273
|
+
),
|
|
274
|
+
)
|
|
245
275
|
parser.add_argument(
|
|
246
276
|
"--hpo-metrics-csv",
|
|
247
277
|
type=str,
|
|
@@ -1372,6 +1402,231 @@ def _stochastic_round_projections(optimizer, buffers=None):
|
|
|
1372
1402
|
group["proj_int4"] = rounded.clamp(-7, 7).to(torch.int8)
|
|
1373
1403
|
|
|
1374
1404
|
|
|
1405
|
+
def auto_tune_vram(args, model_loading_fn) -> dict:
|
|
1406
|
+
"""Find the optimal max_length for this GPU/model combination.
|
|
1407
|
+
|
|
1408
|
+
Strategy: load the model once, then run a few forward passes at
|
|
1409
|
+
increasing max_length values. Measure tok/s at each. Stop when
|
|
1410
|
+
tok/s plateaus (the GPU is compute-bound — longer sequences don't
|
|
1411
|
+
help). Save the result to <output>/auto_tune.json.
|
|
1412
|
+
|
|
1413
|
+
Returns a dict with optimal max_length, batch_size, and tok/s.
|
|
1414
|
+
"""
|
|
1415
|
+
import json
|
|
1416
|
+
import time
|
|
1417
|
+
from pathlib import Path
|
|
1418
|
+
|
|
1419
|
+
tune_path = Path(args.output) / "auto_tune.json"
|
|
1420
|
+
if tune_path.exists():
|
|
1421
|
+
print(f" Auto-tune: loading cached config from {tune_path}")
|
|
1422
|
+
with open(tune_path) as f:
|
|
1423
|
+
return json.load(f)
|
|
1424
|
+
|
|
1425
|
+
print("\n [Auto-tune] Probing VRAM to find optimal max_length...")
|
|
1426
|
+
print(" (This runs a few forward passes at different lengths.)")
|
|
1427
|
+
|
|
1428
|
+
# Load model once
|
|
1429
|
+
model, tokenizer = model_loading_fn()
|
|
1430
|
+
|
|
1431
|
+
# Test lengths: start at 1024, double until tok/s stops improving
|
|
1432
|
+
test_lengths = [1024, 2048, 4096, 6144, 8192, 10240, 12288]
|
|
1433
|
+
results = []
|
|
1434
|
+
|
|
1435
|
+
# Create a tiny dummy batch
|
|
1436
|
+
dummy_text = "The quick brown fox jumps over the lazy dog. " * 200
|
|
1437
|
+
dummy_text = dummy_text[: max(test_lengths) * 4] # enough tokens
|
|
1438
|
+
|
|
1439
|
+
for ml in test_lengths:
|
|
1440
|
+
# Check VRAM headroom
|
|
1441
|
+
if is_cuda():
|
|
1442
|
+
free, total = gpu_mem_info_bytes()
|
|
1443
|
+
allocated = gpu_mem_allocated_bytes()
|
|
1444
|
+
# Rough estimate: each doubling of max_length adds ~2GB
|
|
1445
|
+
# for a 3B model. If we're within 3GB of the ceiling, skip.
|
|
1446
|
+
if allocated > 0 and (total - allocated) < 3 * (1024**3):
|
|
1447
|
+
print(f" max_length={ml}: SKIP (VRAM too tight)")
|
|
1448
|
+
continue
|
|
1449
|
+
|
|
1450
|
+
try:
|
|
1451
|
+
tokens = tokenizer(
|
|
1452
|
+
dummy_text,
|
|
1453
|
+
truncation=True,
|
|
1454
|
+
max_length=ml,
|
|
1455
|
+
return_tensors="pt",
|
|
1456
|
+
)
|
|
1457
|
+
if is_cuda():
|
|
1458
|
+
tokens = {k: v.cuda() for k, v in tokens.items()}
|
|
1459
|
+
|
|
1460
|
+
# Warmup
|
|
1461
|
+
for _ in range(3):
|
|
1462
|
+
with torch.no_grad():
|
|
1463
|
+
_ = model(**tokens)
|
|
1464
|
+
|
|
1465
|
+
# Benchmark
|
|
1466
|
+
torch.cuda.synchronize()
|
|
1467
|
+
t0 = time.perf_counter()
|
|
1468
|
+
n_runs = 10
|
|
1469
|
+
for _ in range(n_runs):
|
|
1470
|
+
with torch.no_grad():
|
|
1471
|
+
_ = model(**tokens)
|
|
1472
|
+
torch.cuda.synchronize()
|
|
1473
|
+
elapsed = time.perf_counter() - t0
|
|
1474
|
+
|
|
1475
|
+
tok_per_sec = (ml * n_runs) / elapsed
|
|
1476
|
+
results.append((ml, tok_per_sec))
|
|
1477
|
+
print(f" max_length={ml:5d}: {tok_per_sec:6.0f} tok/s")
|
|
1478
|
+
|
|
1479
|
+
except RuntimeError as e:
|
|
1480
|
+
if "out of memory" in str(e):
|
|
1481
|
+
print(f" max_length={ml}: OOM — stopping search")
|
|
1482
|
+
torch.cuda.empty_cache()
|
|
1483
|
+
break
|
|
1484
|
+
raise
|
|
1485
|
+
|
|
1486
|
+
if not results:
|
|
1487
|
+
print(" Auto-tune: all lengths OOM'd. Using --max-length 1024.")
|
|
1488
|
+
result = {"max_length": 1024, "batch_size": 1, "tok_per_sec": 0}
|
|
1489
|
+
else:
|
|
1490
|
+
# Find the knee: last length where tok/s improved by >5%
|
|
1491
|
+
best = results[0]
|
|
1492
|
+
for i in range(1, len(results)):
|
|
1493
|
+
improvement = (results[i][1] - best[1]) / best[1]
|
|
1494
|
+
if improvement > 0.05:
|
|
1495
|
+
best = results[i]
|
|
1496
|
+
else:
|
|
1497
|
+
break # plateaued
|
|
1498
|
+
|
|
1499
|
+
result = {
|
|
1500
|
+
"max_length": best[0],
|
|
1501
|
+
"batch_size": 1,
|
|
1502
|
+
"tok_per_sec": round(best[1]),
|
|
1503
|
+
}
|
|
1504
|
+
print(
|
|
1505
|
+
f" Auto-tune: optimal max_length={result['max_length']} "
|
|
1506
|
+
f"({result['tok_per_sec']} tok/s)"
|
|
1507
|
+
)
|
|
1508
|
+
|
|
1509
|
+
# Save for reuse
|
|
1510
|
+
tune_path.parent.mkdir(parents=True, exist_ok=True)
|
|
1511
|
+
with open(tune_path, "w") as f:
|
|
1512
|
+
json.dump(result, f, indent=2)
|
|
1513
|
+
print(f" Auto-tune: saved to {tune_path}")
|
|
1514
|
+
|
|
1515
|
+
# Clean up model to free VRAM for actual training
|
|
1516
|
+
del model
|
|
1517
|
+
if is_cuda():
|
|
1518
|
+
torch.cuda.empty_cache()
|
|
1519
|
+
|
|
1520
|
+
return result
|
|
1521
|
+
|
|
1522
|
+
|
|
1523
|
+
class LiveLRCallback(TrainerCallback):
|
|
1524
|
+
"""Reduce learning rate when loss plateaus.
|
|
1525
|
+
|
|
1526
|
+
Uses the same detection logic as StepEarlyStoppingCallback:
|
|
1527
|
+
split a window of EMA-smoothed losses into first/second half,
|
|
1528
|
+
compare means. If the trend is flat or rising for N consecutive
|
|
1529
|
+
checks, halve the LR and reload the best checkpoint.
|
|
1530
|
+
|
|
1531
|
+
This is ReduceLROnPlateau but integrated with our existing
|
|
1532
|
+
plateau detection — no separate scheduler needed.
|
|
1533
|
+
|
|
1534
|
+
The ``trainer`` reference must be set after the Trainer is created
|
|
1535
|
+
(before training starts). The callback accesses the optimizer
|
|
1536
|
+
through ``self._trainer.optimizer``.
|
|
1537
|
+
"""
|
|
1538
|
+
|
|
1539
|
+
def __init__(
|
|
1540
|
+
self,
|
|
1541
|
+
check_every: int = 5,
|
|
1542
|
+
window_size: int = 20,
|
|
1543
|
+
ema_decay: float = 0.5,
|
|
1544
|
+
min_delta: float = 0.005,
|
|
1545
|
+
max_reductions: int = 3,
|
|
1546
|
+
reduction_factor: float = 0.5,
|
|
1547
|
+
output_dir: str = "",
|
|
1548
|
+
):
|
|
1549
|
+
from collections import deque
|
|
1550
|
+
|
|
1551
|
+
self.check_every = check_every
|
|
1552
|
+
self.window_size = window_size
|
|
1553
|
+
self.ema_decay = ema_decay
|
|
1554
|
+
self.min_delta = min_delta
|
|
1555
|
+
self.max_reductions = max_reductions
|
|
1556
|
+
self.reduction_factor = reduction_factor
|
|
1557
|
+
self.output_dir = output_dir
|
|
1558
|
+
|
|
1559
|
+
self._ema: float | None = None
|
|
1560
|
+
self._window: deque[float] = deque(maxlen=window_size)
|
|
1561
|
+
self._stale_checks = 0
|
|
1562
|
+
self._max_stale = 3
|
|
1563
|
+
self._log_count = 0
|
|
1564
|
+
self._reductions = 0
|
|
1565
|
+
self._trainer = None # set after Trainer creation
|
|
1566
|
+
|
|
1567
|
+
def on_log(self, args, state, control, model=None, **kwargs):
|
|
1568
|
+
if self._trainer is None:
|
|
1569
|
+
return control
|
|
1570
|
+
logs = kwargs.get("logs", {})
|
|
1571
|
+
loss = logs.get("loss")
|
|
1572
|
+
if loss is None:
|
|
1573
|
+
return control
|
|
1574
|
+
|
|
1575
|
+
# EMA smoothing
|
|
1576
|
+
if self._ema is None:
|
|
1577
|
+
self._ema = float(loss)
|
|
1578
|
+
else:
|
|
1579
|
+
self._ema = self.ema_decay * self._ema + (1 - self.ema_decay) * float(loss)
|
|
1580
|
+
self._window.append(self._ema)
|
|
1581
|
+
|
|
1582
|
+
self._log_count += 1
|
|
1583
|
+
if self._log_count % self.check_every != 0:
|
|
1584
|
+
return control
|
|
1585
|
+
if len(self._window) < self.window_size:
|
|
1586
|
+
return control
|
|
1587
|
+
|
|
1588
|
+
# Split window
|
|
1589
|
+
mid = self.window_size // 2
|
|
1590
|
+
window_list = list(self._window)
|
|
1591
|
+
first_mean = sum(window_list[:mid]) / mid
|
|
1592
|
+
second_mean = sum(window_list[mid:]) / mid
|
|
1593
|
+
|
|
1594
|
+
if second_mean < first_mean - self.min_delta:
|
|
1595
|
+
self._stale_checks = 0 # still improving
|
|
1596
|
+
else:
|
|
1597
|
+
self._stale_checks += 1 # flat or rising
|
|
1598
|
+
|
|
1599
|
+
if self._stale_checks >= self._max_stale:
|
|
1600
|
+
if self._reductions >= self.max_reductions:
|
|
1601
|
+
return control
|
|
1602
|
+
|
|
1603
|
+
self._reductions += 1
|
|
1604
|
+
self._stale_checks = 0
|
|
1605
|
+
|
|
1606
|
+
# Halve LR for all param groups
|
|
1607
|
+
optimizer = self._trainer.optimizer
|
|
1608
|
+
for group in optimizer.param_groups:
|
|
1609
|
+
old_lr = group["lr"]
|
|
1610
|
+
group["lr"] = old_lr * self.reduction_factor
|
|
1611
|
+
|
|
1612
|
+
print(
|
|
1613
|
+
f"\r\n [LiveLR] Loss plateaued "
|
|
1614
|
+
f"(EMA {first_mean:.4f} → {second_mean:.4f}). "
|
|
1615
|
+
f"LR: {old_lr:.2e} → {group['lr']:.2e} "
|
|
1616
|
+
f"(reduction {self._reductions}/{self.max_reductions})"
|
|
1617
|
+
)
|
|
1618
|
+
|
|
1619
|
+
# Reload best checkpoint if available
|
|
1620
|
+
best_dir = Path(self.output_dir) / "checkpoint-best"
|
|
1621
|
+
if best_dir.exists():
|
|
1622
|
+
print(f" [LiveLR] Reloading best checkpoint from {best_dir}")
|
|
1623
|
+
# HF Trainer's _load_from_checkpoint handles this
|
|
1624
|
+
# if we set state.best_model_checkpoint
|
|
1625
|
+
state.best_model_checkpoint = str(best_dir)
|
|
1626
|
+
|
|
1627
|
+
return control
|
|
1628
|
+
|
|
1629
|
+
|
|
1375
1630
|
def main() -> None:
|
|
1376
1631
|
console = Console(width=80)
|
|
1377
1632
|
args = parse_args()
|
|
@@ -2296,10 +2551,21 @@ def main() -> None:
|
|
|
2296
2551
|
if "CUDA out of memory" in error_msg or "OOM" in error_msg:
|
|
2297
2552
|
print("\nERROR: GPU ran out of memory during model loading!")
|
|
2298
2553
|
print(" Suggestions:")
|
|
2299
|
-
|
|
2300
|
-
|
|
2554
|
+
if args.batch_size > 1:
|
|
2555
|
+
print(
|
|
2556
|
+
" 1. Reduce batch size: --batch-size 1"
|
|
2557
|
+
" (currently {})".format(args.batch_size)
|
|
2558
|
+
)
|
|
2559
|
+
print(
|
|
2560
|
+
" 2. Reduce sequence length: --max-length 1024"
|
|
2561
|
+
" (currently {})".format(args.max_length)
|
|
2562
|
+
)
|
|
2301
2563
|
print(" 3. Use a smaller model (e.g., Qwen2.5-3B-Instruct)")
|
|
2302
|
-
print(
|
|
2564
|
+
print(
|
|
2565
|
+
" 4. Use gradient_accumulation_steps to simulate"
|
|
2566
|
+
" larger batches without VRAM cost"
|
|
2567
|
+
)
|
|
2568
|
+
print(" 5. Try --use-qgalore for INT4 projections (fits 7B on 16GB)")
|
|
2303
2569
|
else:
|
|
2304
2570
|
print(f"\nERROR: Failed to load model: {e}")
|
|
2305
2571
|
sys.exit(1)
|
|
@@ -3623,6 +3889,7 @@ def main() -> None:
|
|
|
3623
3889
|
GCEpochCallback(),
|
|
3624
3890
|
_live_progress,
|
|
3625
3891
|
PauseResumeCallback(interactive_control),
|
|
3892
|
+
*([LiveLRCallback(output_dir=args.output)] if args.live_lr else []),
|
|
3626
3893
|
*hpo_callbacks,
|
|
3627
3894
|
],
|
|
3628
3895
|
)
|
|
@@ -3656,6 +3923,7 @@ def main() -> None:
|
|
|
3656
3923
|
GCEpochCallback(),
|
|
3657
3924
|
_live_progress,
|
|
3658
3925
|
PauseResumeCallback(interactive_control),
|
|
3926
|
+
*([LiveLRCallback(output_dir=args.output)] if args.live_lr else []),
|
|
3659
3927
|
*hpo_callbacks,
|
|
3660
3928
|
],
|
|
3661
3929
|
)
|
|
@@ -3667,6 +3935,13 @@ def main() -> None:
|
|
|
3667
3935
|
|
|
3668
3936
|
trainer.remove_callback(PrinterCallback)
|
|
3669
3937
|
|
|
3938
|
+
# Wire LiveLRCallback to the trainer so it can access the optimizer
|
|
3939
|
+
if args.live_lr:
|
|
3940
|
+
for cb in trainer.callback_handler.callbacks:
|
|
3941
|
+
if isinstance(cb, LiveLRCallback):
|
|
3942
|
+
cb._trainer = trainer
|
|
3943
|
+
break
|
|
3944
|
+
|
|
3670
3945
|
# --- OOM fix #3: Clear CUDA cache + Python GC right before training ---
|
|
3671
3946
|
# Even with expandable_segments, the model+LoRA+optimizer load leaves some
|
|
3672
3947
|
# fragmentation behind. Forcing a GC + empty_cache here gives the trainer
|
|
@@ -3738,10 +4013,21 @@ def main() -> None:
|
|
|
3738
4013
|
if "CUDA out of memory" in error_msg or "OOM" in error_msg:
|
|
3739
4014
|
print("\nERROR: GPU ran out of memory during training!")
|
|
3740
4015
|
print(" Suggestions:")
|
|
3741
|
-
|
|
3742
|
-
|
|
4016
|
+
if args.batch_size > 1:
|
|
4017
|
+
print(
|
|
4018
|
+
" 1. Reduce batch size: --batch-size 1"
|
|
4019
|
+
" (currently {})".format(args.batch_size)
|
|
4020
|
+
)
|
|
4021
|
+
print(
|
|
4022
|
+
" 2. Reduce sequence length: --max-length 1024"
|
|
4023
|
+
" (currently {})".format(args.max_length)
|
|
4024
|
+
)
|
|
3743
4025
|
print(" 3. Use a smaller model (e.g., Qwen2.5-3B-Instruct)")
|
|
3744
|
-
print(
|
|
4026
|
+
print(
|
|
4027
|
+
" 4. Use gradient_accumulation_steps to simulate"
|
|
4028
|
+
" larger batches without VRAM cost"
|
|
4029
|
+
)
|
|
4030
|
+
print(" 5. Try --use-qgalore for INT4 projections (fits 7B on 16GB)")
|
|
3745
4031
|
else:
|
|
3746
4032
|
print(f"\nERROR: Training failed: {e}")
|
|
3747
4033
|
sys.exit(1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.6"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.6.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/attacklm-synthetic/LICENSE.md
RENAMED
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/attacklm-synthetic/SOURCE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/LICENSE.md
RENAMED
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/metasploit-framework/SOURCE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-atlas-arsenal/LICENSE.md
RENAMED
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/mitre-atlas-arsenal/SOURCE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/threathunter-playbook/LICENSE.md
RENAMED
|
File without changes
|
{attacklm-0.6.4 → attacklm-0.6.6}/data/datasets/buckets/sources/threathunter-playbook/SOURCE.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|