- Add validated mitre_attack frontmatter to all 754 skills (286 distinct
techniques), verified against MITRE ATT&CK v19.1 via the official
mitreattack-python library: 0 revoked, deprecated, or invalid IDs
- Curate precise per-skill technique IDs for forensics, malware-analysis,
threat-intel, and red-team skills (e.g. DCSync -> T1003.006,
Kerberoasting -> T1558.003, Pass-the-Ticket -> T1550.003)
- Reconcile v19.1 tactic restructuring: Defense Evasion split into
Stealth (TA0005) and Defense Impairment (TA0112); revoked T1562.*
family and T1070.001/.002 remapped to active equivalents (T1685.*)
- Normalize word-split tags across 35 skills (remove filename-derived
stopword tags, add semantic cybersecurity tags)
- Add api-reference.md for 3 skills that were missing it
- Update README ATT&CK section with accurate v19.1 tactic distribution
Three SKILL.md files had tags that were simply words split from the
skill name (e.g., "analyzing", "block", "with", "logs") rather than
meaningful discovery keywords. Replace with domain-specific terms that
agents and search tools can actually use for routing.
- analyzing-powershell-script-block-logging: [powershell, script-block-logging, event-id-4104, obfuscation-detection, windows-forensics, endpoint-security]
- analyzing-azure-activity-logs-for-threats: [azure, cloud-security, azure-monitor, kql, threat-hunting, activity-logs]
- analyzing-memory-forensics-with-lime-and-volatility: [memory-forensics, linux-forensics, lime, volatility, incident-response, kernel-modules]
Co-Authored-By: Claude Code <noreply@anthropic.com>
Mapped every skill to NIST CSF 2.0 subcategory IDs (GV/ID/PR/DE/RS/RC functions)
based on subdomain and content analysis. Restores 11 skills corrupted during
prior rebase, re-enriching with ATLAS, D3FEND, NIST AI RMF, and CSF 2.0 fields.
All 754 skills now carry structured mappings for all 5 security frameworks:
- MITRE ATT&CK (in tags)
- MITRE ATLAS v5.5 (atlas_techniques)
- MITRE D3FEND v1.3 (d3fend_techniques)
- NIST AI RMF 1.0 (nist_ai_rmf)
- NIST CSF 2.0 (nist_csf)
Three issues fixed:
1. Description list check — added elif isinstance(desc, list) branch that
emits 'Description must be a string value, not a list'. Previously the
block was silently skipped when YAML returned a list, causing the skill
to pass without validating the description field.
2. tools/README.md synced — updated description constraint from '20-500
characters' to 'at least 50 characters (no upper limit)' to match the
current code (DESCRIPTION_MIN_CHARS=50, no max enforced).
3. --all with wrong CWD now exits 1 — if glob returns no skill dirs,
the script prints an error and exits with code 1 instead of reporting
'Total: 0 Passed: 0 Failed: 0' and exiting 0, which would cause CI to
silently pass while validating nothing.
All 754 skills continue to pass (0 regressions).
Required changes:
- Error handling: IOError and UnicodeDecodeError already wrapped in
try/except from previous commit — still present and correct.
- ALLOWED_SUBDOMAINS: synced with actual repo usage (audited all 754
skills). identity-access-management (34 skills) added; identity-security
was the placeholder in its place.
New in this commit:
1. Description minimum: raised from 20 → 50 chars to align with other
repo tooling as requested.
2. Folded scalar support: parse_frontmatter now handles YAML `>-` and `>`
folded scalars, preventing incorrect parse of multi-line descriptions.
Added a comment documenting the one remaining edge case (value-less key
followed by non-list content — treated as no-value, acceptable for
well-formed SKILL.md files).
3. Canonical subdomain warnings: alias subdomain values (e.g.
security-operations vs soc-operations) now print a WARN line pointing
to the canonical form, but are non-blocking. A _SUBDOMAIN_ALIASES dict
documents canonical/alias pairs explicitly.
4. Description upper limit: removed hard cap — folded scalars legitimately
produce long strings in existing skills.
5. PR description: removed false mention of type hints (there are none
in this file).
Validator now passes 754/754 skills in the repo with 0 errors.
- Wrap open() call in try/except for IOError and UnicodeDecodeError
to report clean errors instead of crashing on encoding issues
- Add all subdomains actually used by existing skills in the repo:
identity-access-management (33 skills), security-operations (28),
identity-and-access-management, zero-trust, ot-security, purple-team,
red-team, ai-security, social-engineering-defense, and others
- Remove identity-security as the canonical form is identity-access-management
- Fix FilterCriteria to use singular Severity/Status with Value objects
instead of invalid plural Severities/Statuses arrays (SKILL.md + process.py)
- Fix get_entity_history: rename to get_investigation_indicators, use
investigation_id instead of entity_arn for InvestigationId parameter
- Replace invalid inv-* placeholders with 21-digit numeric IDs
- Fix Expected Output to match real API response structure (no embedded
Indicators; document separate list-indicators call and indicator types)
- Fix CLI --filter-criteria example to use correct format
- Update process.py --severity to accept single value with validation
- Add --max-results validation (1-100 range)
- Add pagination via _collect_all_pages helper for all list API calls
- Reorder Response Actions checklist: evidence preservation before containment
- Reorder Phase 5 workflow: preserve evidence first when safe
The process.py script was empty (0 bytes). Added a functional
implementation that lists behavior graphs, retrieves investigations,
queries indicators, and exports results — matching the pattern of
other skills in the repository.