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.