mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-28 20:29:40 +03:00
ci: add description-quality and collision gates
The description is the only signal an agent sees at discovery time, so overlapping descriptions cause misrouting. Nothing in CI checked for that. - tools/lint-descriptions.py enforces name==folder, description <=1024 chars, terminal punctuation (a truncation canary), a trigger clause, a negative trigger, and a 500-line body cap. Pre-existing failures are grandfathered in tools/lint-baseline.json so this blocks new debt only; the baseline may shrink and never grow. - tools/detect-collisions.py scores every description pair by TF-IDF cosine and ratchets the count of unreviewed near-duplicates. It strips negative-trigger clauses before vectorizing: those name the sibling skill on purpose, so scoring them would make correct disambiguation raise a pair's similarity. - wire both into validate-skills.yml, along with agentskills conformance, an index.json freshness check, and a guard that fails the build if a regex frontmatter parser is reintroduced. - broaden the path filters from tools/validate-skill.py to tools/**, as noted when #105 merged. All five gates verified to fail on deliberately broken input.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"_comment": [
|
||||
"Skill pairs that score as near-duplicates but are legitimately distinct.",
|
||||
"",
|
||||
"Add a pair here ONLY after reading both descriptions and confirming a real",
|
||||
"difference in scope, platform, or offense-vs-defense posture. The 'reason'",
|
||||
"is not bookkeeping: it is the wording each skill's negative trigger should",
|
||||
"use, e.g. reason 'Linux vs Windows' becomes 'Do not use for Windows hosts",
|
||||
"- use hardening-windows-endpoint-with-cis-benchmark.'",
|
||||
"",
|
||||
"A pair that is genuinely ambiguous does NOT belong here. Disambiguate the",
|
||||
"two descriptions instead.",
|
||||
"",
|
||||
"Regenerate the candidate list with: python tools/detect-collisions.py"
|
||||
],
|
||||
"reviewed_distinct": [
|
||||
{
|
||||
"pair": [
|
||||
"hardening-linux-endpoint-with-cis-benchmark",
|
||||
"hardening-windows-endpoint-with-cis-benchmark"
|
||||
],
|
||||
"reason": "Same CIS Benchmark methodology, different operating systems. The controls, tooling and audit commands do not overlap, so both must exist; each description must name the OS explicitly and point at the other."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Find skill pairs whose descriptions compete for the same user request.
|
||||
|
||||
An agent picks a skill from its description alone. When two descriptions are
|
||||
near-duplicates, the router cannot reliably choose between them and misroutes
|
||||
-- "skill collision". This scores every pair by TF-IDF cosine similarity over
|
||||
description + slug and reports the ones close enough to collide.
|
||||
|
||||
A high score is NOT automatically a defect. Some near-twins are legitimately
|
||||
distinct (Linux vs Windows CIS hardening; red-team DCSync vs blue-team DCSync
|
||||
detection). Those belong in tools/collision-allowlist.json with a reason, which
|
||||
is also a record of WHY they differ -- exactly the wording their negative
|
||||
triggers need.
|
||||
|
||||
Pure stdlib; no numpy/sklearn required.
|
||||
|
||||
Usage:
|
||||
python tools/detect-collisions.py
|
||||
python tools/detect-collisions.py --threshold 0.5
|
||||
python tools/detect-collisions.py --json
|
||||
python tools/detect-collisions.py --max-unreviewed 60 # CI gate
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import Counter
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from skill_frontmatter import description_of, iter_skill_dirs, load_frontmatter, FrontmatterError
|
||||
|
||||
ALLOWLIST_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"collision-allowlist.json")
|
||||
DEFAULT_THRESHOLD = 0.45
|
||||
|
||||
# Words too common in this corpus to carry signal.
|
||||
STOPWORDS = set("""
|
||||
the a an and or of to for in on with using use uses used when this that is are be by
|
||||
from as it its into via at not skill security detect detects detecting analyze analyzes
|
||||
analyzing perform performs performing implement implements implementing
|
||||
""".split())
|
||||
|
||||
# A term appearing in more than this many skills is treated as a domain-wide
|
||||
# background word and skipped when pairing (keeps the comparison O(usable pairs)).
|
||||
MAX_DOCS_PER_TERM = 60
|
||||
|
||||
|
||||
# A negative trigger names the sibling skill on purpose ("Do not use for X -
|
||||
# use other-skill."). Scoring that text would inject the sibling's own slug
|
||||
# tokens into this skill's vector, so correctly disambiguating a pair would
|
||||
# RAISE its similarity score -- the metric would punish the fix. Strip the
|
||||
# disambiguation scaffolding and score only the descriptive part.
|
||||
DISAMBIGUATION_RE = re.compile(r"\b(?:do\s+not\s+use|don'?t\s+use|avoid\s+(?:this\s+)?(?:skill\s+)?for)\b.*",
|
||||
re.IGNORECASE | re.DOTALL)
|
||||
KEYWORDS_LABEL_RE = re.compile(r"\bkeywords\s*:", re.IGNORECASE)
|
||||
|
||||
|
||||
def strip_disambiguation(text: str) -> str:
|
||||
"""Drop negative-trigger sentences and the literal 'Keywords:' label.
|
||||
|
||||
The keyword TERMS stay -- they are real content. Only the label is removed,
|
||||
since it would otherwise be a shared token across every fixed skill.
|
||||
"""
|
||||
text = DISAMBIGUATION_RE.sub("", text)
|
||||
return KEYWORDS_LABEL_RE.sub(" ", text)
|
||||
|
||||
|
||||
def tokenize(text: str) -> Counter:
|
||||
return Counter(w for w in re.findall(r"[a-z0-9]+", text.lower())
|
||||
if w not in STOPWORDS and len(w) > 2)
|
||||
|
||||
|
||||
def build_vectors(skills_dir: str) -> dict[str, dict[str, float]]:
|
||||
"""L2-normalized TF-IDF vectors keyed by slug."""
|
||||
docs: dict[str, Counter] = {}
|
||||
for slug, skill_dir in iter_skill_dirs(skills_dir):
|
||||
try:
|
||||
frontmatter = load_frontmatter(os.path.join(skill_dir, "SKILL.md"))
|
||||
except FrontmatterError:
|
||||
continue
|
||||
described = strip_disambiguation(description_of(frontmatter))
|
||||
docs[slug] = tokenize(f"{described} {slug.replace('-', ' ')}")
|
||||
|
||||
doc_freq: Counter = Counter()
|
||||
for counts in docs.values():
|
||||
doc_freq.update(counts.keys())
|
||||
|
||||
total = len(docs)
|
||||
vectors: dict[str, dict[str, float]] = {}
|
||||
for slug, counts in docs.items():
|
||||
weights = {term: (1 + math.log(freq)) * math.log(total / doc_freq[term])
|
||||
for term, freq in counts.items()}
|
||||
norm = math.sqrt(sum(w * w for w in weights.values())) or 1.0
|
||||
vectors[slug] = {term: w / norm for term, w in weights.items()}
|
||||
return vectors
|
||||
|
||||
|
||||
def score_pairs(vectors: dict[str, dict[str, float]], threshold: float):
|
||||
"""Cosine similarity for every pair sharing at least one discriminating term."""
|
||||
postings: dict[str, list[str]] = {}
|
||||
for slug, vector in vectors.items():
|
||||
for term in vector:
|
||||
postings.setdefault(term, []).append(slug)
|
||||
|
||||
sims: dict[tuple[str, str], float] = {}
|
||||
for term, slugs in postings.items():
|
||||
if len(slugs) > MAX_DOCS_PER_TERM:
|
||||
continue
|
||||
weight_by_slug = {s: vectors[s][term] for s in slugs}
|
||||
for a, b in itertools.combinations(sorted(slugs), 2):
|
||||
sims[(a, b)] = sims.get((a, b), 0.0) + weight_by_slug[a] * weight_by_slug[b]
|
||||
|
||||
return sorted(((s, p) for p, s in sims.items() if s >= threshold), reverse=True)
|
||||
|
||||
|
||||
def load_allowlist() -> dict[tuple[str, str], str]:
|
||||
if not os.path.isfile(ALLOWLIST_PATH):
|
||||
return {}
|
||||
with open(ALLOWLIST_PATH, encoding="utf-8") as handle:
|
||||
data = json.load(handle)
|
||||
out: dict[tuple[str, str], str] = {}
|
||||
for entry in data.get("reviewed_distinct", []):
|
||||
pair = tuple(sorted(entry["pair"]))
|
||||
out[pair] = entry.get("reason", "")
|
||||
return out
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--threshold", type=float, default=DEFAULT_THRESHOLD)
|
||||
parser.add_argument("--json", action="store_true", dest="as_json")
|
||||
parser.add_argument("--max-unreviewed", type=int, default=None,
|
||||
help="exit 1 if unreviewed colliding pairs exceed this")
|
||||
parser.add_argument("--skills-dir", default="skills")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isdir(args.skills_dir):
|
||||
print(f"ERROR: '{args.skills_dir}' not found. Run from the repository root.")
|
||||
return 1
|
||||
|
||||
vectors = build_vectors(args.skills_dir)
|
||||
pairs = score_pairs(vectors, args.threshold)
|
||||
allowlist = load_allowlist()
|
||||
|
||||
unreviewed = [(s, p) for s, p in pairs if p not in allowlist]
|
||||
reviewed = [(s, p) for s, p in pairs if p in allowlist]
|
||||
involved = {slug for _, pair in unreviewed for slug in pair}
|
||||
|
||||
if args.as_json:
|
||||
print(json.dumps({
|
||||
"threshold": args.threshold,
|
||||
"total_pairs": len(pairs),
|
||||
"unreviewed": [{"score": round(s, 3), "pair": list(p)} for s, p in unreviewed],
|
||||
"reviewed_distinct": [{"score": round(s, 3), "pair": list(p),
|
||||
"reason": allowlist[p]} for s, p in reviewed],
|
||||
"skills_involved": sorted(involved),
|
||||
}, indent=2))
|
||||
else:
|
||||
print(f"Colliding pairs at cosine >= {args.threshold}: {len(pairs)} "
|
||||
f"({len(reviewed)} reviewed-distinct, {len(unreviewed)} unreviewed)")
|
||||
print(f"Skills involved in an unreviewed collision: {len(involved)} "
|
||||
f"of {len(vectors)}\n")
|
||||
for score, (a, b) in unreviewed:
|
||||
print(f" {score:.2f} {a}\n {b}")
|
||||
if reviewed:
|
||||
print(f"\nReviewed as legitimately distinct ({len(reviewed)}):")
|
||||
for score, (a, b) in reviewed:
|
||||
print(f" {score:.2f} {a} || {b}\n reason: {allowlist[(a, b)]}")
|
||||
|
||||
if args.max_unreviewed is not None and len(unreviewed) > args.max_unreviewed:
|
||||
print(f"\nERROR: {len(unreviewed)} unreviewed colliding pairs "
|
||||
f"exceeds --max-unreviewed {args.max_unreviewed}.")
|
||||
print("Either disambiguate the descriptions or record the pair in "
|
||||
f"{os.path.relpath(ALLOWLIST_PATH)} with a reason.")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,992 @@
|
||||
{
|
||||
"_comment": "Pre-existing lint failures, grandfathered so CI can gate new work today. This file may only shrink. Never add a slug by hand -- fix the skill, then run: python tools/lint-descriptions.py --update-baseline",
|
||||
"_total_grandfathered": 980,
|
||||
"desc-ends-punctuation": [
|
||||
"analyzing-active-directory-acl-abuse",
|
||||
"analyzing-malicious-url-with-urlscan",
|
||||
"detecting-aws-iam-privilege-escalation",
|
||||
"exploiting-active-directory-with-bloodhound",
|
||||
"implementing-email-sandboxing-with-proofpoint",
|
||||
"implementing-patch-management-workflow",
|
||||
"implementing-secrets-scanning-in-ci-cd",
|
||||
"performing-cryptographic-audit-of-application",
|
||||
"performing-dark-web-monitoring-for-threats",
|
||||
"performing-malware-ioc-extraction",
|
||||
"performing-open-source-intelligence-gathering",
|
||||
"performing-service-account-audit",
|
||||
"prioritizing-vulnerabilities-with-cvss-scoring"
|
||||
],
|
||||
"desc-has-use-when": [
|
||||
"analyzing-active-directory-acl-abuse",
|
||||
"analyzing-android-malware-with-apktool",
|
||||
"analyzing-apt-group-with-mitre-navigator",
|
||||
"analyzing-certificate-transparency-for-phishing",
|
||||
"analyzing-cobalt-strike-beacon-configuration",
|
||||
"analyzing-docker-container-forensics",
|
||||
"analyzing-ethereum-smart-contract-vulnerabilities",
|
||||
"analyzing-heap-spray-exploitation",
|
||||
"analyzing-ios-app-security-with-objection",
|
||||
"analyzing-linux-audit-logs-for-intrusion",
|
||||
"analyzing-linux-kernel-rootkits",
|
||||
"analyzing-macro-malware-in-office-documents",
|
||||
"analyzing-malicious-url-with-urlscan",
|
||||
"analyzing-memory-dumps-with-volatility",
|
||||
"analyzing-network-flow-data-with-netflow",
|
||||
"analyzing-network-traffic-for-incidents",
|
||||
"analyzing-network-traffic-of-malware",
|
||||
"analyzing-network-traffic-with-wireshark",
|
||||
"analyzing-office365-audit-logs-for-compromise",
|
||||
"analyzing-pdf-malware-with-pdfid",
|
||||
"analyzing-powershell-script-block-logging",
|
||||
"analyzing-ransomware-encryption-mechanisms",
|
||||
"analyzing-sbom-for-supply-chain-vulnerabilities",
|
||||
"analyzing-security-logs-with-splunk",
|
||||
"analyzing-supply-chain-malware-artifacts",
|
||||
"analyzing-web-server-logs-for-intrusion",
|
||||
"auditing-aws-s3-bucket-permissions",
|
||||
"auditing-azure-active-directory-configuration",
|
||||
"auditing-gcp-iam-permissions",
|
||||
"auditing-kubernetes-cluster-rbac",
|
||||
"auditing-terraform-infrastructure-for-security",
|
||||
"auditing-tls-certificate-transparency-logs",
|
||||
"auditing-uefi-firmware-with-chipsec",
|
||||
"building-detection-rule-with-splunk-spl",
|
||||
"bypassing-authentication-with-forced-browsing",
|
||||
"coercing-authentication-with-coercer-petitpotam",
|
||||
"collecting-indicators-of-compromise",
|
||||
"conducting-api-security-testing",
|
||||
"conducting-cloud-penetration-testing",
|
||||
"conducting-domain-persistence-with-dcsync",
|
||||
"conducting-internal-network-penetration-test",
|
||||
"conducting-man-in-the-middle-attack-simulation",
|
||||
"conducting-memory-forensics-with-volatility",
|
||||
"conducting-mobile-app-penetration-test",
|
||||
"conducting-network-penetration-test",
|
||||
"conducting-post-incident-lessons-learned",
|
||||
"conducting-social-engineering-pretext-call",
|
||||
"conducting-spearphishing-simulation-campaign",
|
||||
"conducting-wireless-network-penetration-test",
|
||||
"containing-active-breach",
|
||||
"deploying-decoy-files-for-ransomware-detection",
|
||||
"detecting-anomalous-authentication-patterns",
|
||||
"detecting-attacks-on-scada-systems",
|
||||
"detecting-aws-cloudtrail-anomalies",
|
||||
"detecting-aws-iam-privilege-escalation",
|
||||
"detecting-azure-lateral-movement",
|
||||
"detecting-business-email-compromise-with-ai",
|
||||
"detecting-cryptomining-in-cloud",
|
||||
"detecting-lateral-movement-in-network",
|
||||
"detecting-lateral-movement-with-zeek",
|
||||
"detecting-living-off-the-land-attacks",
|
||||
"detecting-malicious-scheduled-tasks-with-sysmon",
|
||||
"detecting-network-scanning-with-ids-signatures",
|
||||
"detecting-port-scanning-with-fail2ban",
|
||||
"detecting-process-injection-techniques",
|
||||
"detecting-ransomware-precursors-in-network",
|
||||
"detecting-s3-data-exfiltration-attempts",
|
||||
"detecting-serverless-function-injection",
|
||||
"detecting-sql-injection-via-waf-logs",
|
||||
"detecting-suspicious-oauth-application-consent",
|
||||
"detecting-typosquatting-packages-in-npm-pypi",
|
||||
"emulating-cloud-attacks-with-stratus-red-team",
|
||||
"enumerating-cloud-with-cloudfox",
|
||||
"executing-active-directory-attack-simulation",
|
||||
"executing-phishing-simulation-campaign",
|
||||
"exploiting-active-directory-certificate-services-esc1",
|
||||
"exploiting-active-directory-with-bloodhound",
|
||||
"exploiting-bgp-hijacking-vulnerabilities",
|
||||
"exploiting-insecure-deserialization",
|
||||
"exploiting-ipv6-vulnerabilities",
|
||||
"exploiting-oauth-misconfiguration",
|
||||
"exploiting-server-side-request-forgery",
|
||||
"exploiting-smb-vulnerabilities-with-metasploit",
|
||||
"exploiting-sql-injection-vulnerabilities",
|
||||
"exploiting-sql-injection-with-sqlmap",
|
||||
"exploiting-websocket-vulnerabilities",
|
||||
"extracting-windows-event-logs-artifacts",
|
||||
"hunting-for-anomalous-powershell-execution",
|
||||
"hunting-for-beaconing-with-frequency-analysis",
|
||||
"hunting-for-command-and-control-beaconing",
|
||||
"hunting-for-defense-evasion-via-timestomping",
|
||||
"hunting-for-registry-run-key-persistence",
|
||||
"hunting-for-spearphishing-indicators",
|
||||
"implementing-aqua-security-for-container-scanning",
|
||||
"implementing-cloud-trail-log-analysis",
|
||||
"implementing-ddos-mitigation-with-cloudflare",
|
||||
"implementing-diamond-model-analysis",
|
||||
"implementing-email-sandboxing-with-proofpoint",
|
||||
"implementing-honeypot-for-ransomware-detection",
|
||||
"implementing-mitre-attack-coverage-mapping",
|
||||
"implementing-network-deception-with-honeypots",
|
||||
"implementing-patch-management-workflow",
|
||||
"implementing-proofpoint-email-security-gateway",
|
||||
"implementing-runtime-application-self-protection",
|
||||
"implementing-secret-scanning-with-gitleaks",
|
||||
"implementing-secrets-scanning-in-ci-cd",
|
||||
"implementing-security-monitoring-with-datadog",
|
||||
"implementing-semgrep-for-custom-sast-rules",
|
||||
"implementing-velociraptor-for-ir-collection",
|
||||
"investigating-ransomware-attack-artifacts",
|
||||
"monitoring-scada-modbus-traffic-anomalies",
|
||||
"performing-active-directory-compromise-investigation",
|
||||
"performing-active-directory-vulnerability-assessment",
|
||||
"performing-agentless-vulnerability-scanning",
|
||||
"performing-api-inventory-and-discovery",
|
||||
"performing-aws-privilege-escalation-assessment",
|
||||
"performing-brand-monitoring-for-impersonation",
|
||||
"performing-clickjacking-attack-test",
|
||||
"performing-credential-access-with-lazagne",
|
||||
"performing-cryptographic-audit-of-application",
|
||||
"performing-csrf-attack-simulation",
|
||||
"performing-dark-web-monitoring-for-threats",
|
||||
"performing-dns-enumeration-and-zone-transfer",
|
||||
"performing-external-network-penetration-test",
|
||||
"performing-firmware-extraction-with-binwalk",
|
||||
"performing-gcp-security-assessment-with-forseti",
|
||||
"performing-graphql-depth-limit-attack",
|
||||
"performing-graphql-security-assessment",
|
||||
"performing-initial-access-with-evilginx3",
|
||||
"performing-iot-security-assessment",
|
||||
"performing-ip-reputation-analysis-with-shodan",
|
||||
"performing-lateral-movement-with-wmiexec",
|
||||
"performing-log-analysis-for-forensic-investigation",
|
||||
"performing-malware-ioc-extraction",
|
||||
"performing-malware-persistence-investigation",
|
||||
"performing-memory-forensics-with-volatility3-plugins",
|
||||
"performing-mobile-app-certificate-pinning-bypass",
|
||||
"performing-oauth-scope-minimization-review",
|
||||
"performing-open-source-intelligence-gathering",
|
||||
"performing-ot-network-security-assessment",
|
||||
"performing-ot-vulnerability-scanning-safely",
|
||||
"performing-packet-injection-attack",
|
||||
"performing-paste-site-monitoring-for-credentials",
|
||||
"performing-physical-intrusion-assessment",
|
||||
"performing-plc-firmware-security-analysis",
|
||||
"performing-privilege-escalation-assessment",
|
||||
"performing-s7comm-protocol-security-analysis",
|
||||
"performing-sca-dependency-scanning-with-snyk",
|
||||
"performing-scada-hmi-security-assessment",
|
||||
"performing-second-order-sql-injection",
|
||||
"performing-security-headers-audit",
|
||||
"performing-serverless-function-security-review",
|
||||
"performing-service-account-audit",
|
||||
"performing-subdomain-enumeration-with-subfinder",
|
||||
"performing-thick-client-application-penetration-test",
|
||||
"performing-threat-hunting-with-yara-rules",
|
||||
"performing-vulnerability-scanning-with-nessus",
|
||||
"performing-web-application-penetration-test",
|
||||
"performing-web-cache-poisoning-attack",
|
||||
"performing-wifi-password-cracking-with-aircrack",
|
||||
"performing-wireless-network-penetration-test",
|
||||
"performing-wireless-security-assessment-with-kismet",
|
||||
"prioritizing-vulnerabilities-with-cvss-scoring",
|
||||
"reverse-engineering-ransomware-encryption-routine",
|
||||
"scanning-infrastructure-with-nessus",
|
||||
"testing-api-authentication-weaknesses",
|
||||
"testing-cors-misconfiguration",
|
||||
"testing-for-host-header-injection",
|
||||
"testing-for-sensitive-data-exposure",
|
||||
"testing-for-xml-injection-vulnerabilities",
|
||||
"testing-for-xss-vulnerabilities-with-burpsuite",
|
||||
"testing-for-xxe-injection-vulnerabilities",
|
||||
"testing-jwt-token-security",
|
||||
"validating-tpm-measured-boot-attestation",
|
||||
"verifying-build-provenance-with-slsa-sigstore"
|
||||
],
|
||||
"desc-has-negative-trigger": [
|
||||
"abusing-dpapi-for-credential-access",
|
||||
"abusing-shadow-credentials-for-privesc",
|
||||
"achieving-cmmc-level-2-compliance",
|
||||
"acquiring-disk-image-with-dd-and-dcfldd",
|
||||
"analyzing-active-directory-acl-abuse",
|
||||
"analyzing-android-malware-with-apktool",
|
||||
"analyzing-api-gateway-access-logs",
|
||||
"analyzing-apt-group-with-mitre-navigator",
|
||||
"analyzing-azure-activity-logs-for-threats",
|
||||
"analyzing-bootkit-and-rootkit-samples",
|
||||
"analyzing-browser-forensics-with-hindsight",
|
||||
"analyzing-campaign-attribution-evidence",
|
||||
"analyzing-certificate-transparency-for-phishing",
|
||||
"analyzing-cloud-storage-access-patterns",
|
||||
"analyzing-cobalt-strike-beacon-configuration",
|
||||
"analyzing-cobaltstrike-malleable-c2-profiles",
|
||||
"analyzing-command-and-control-communication",
|
||||
"analyzing-cyber-kill-chain",
|
||||
"analyzing-disk-image-with-autopsy",
|
||||
"analyzing-dns-logs-for-exfiltration",
|
||||
"analyzing-docker-container-forensics",
|
||||
"analyzing-email-headers-for-phishing-investigation",
|
||||
"analyzing-ethereum-smart-contract-vulnerabilities",
|
||||
"analyzing-golang-malware-with-ghidra",
|
||||
"analyzing-heap-spray-exploitation",
|
||||
"analyzing-indicators-of-compromise",
|
||||
"analyzing-ios-app-security-with-objection",
|
||||
"analyzing-linux-audit-logs-for-intrusion",
|
||||
"analyzing-linux-elf-malware",
|
||||
"analyzing-linux-kernel-rootkits",
|
||||
"analyzing-linux-system-artifacts",
|
||||
"analyzing-lnk-file-and-jump-list-artifacts",
|
||||
"analyzing-macro-malware-in-office-documents",
|
||||
"analyzing-malicious-pdf-with-peepdf",
|
||||
"analyzing-malicious-url-with-urlscan",
|
||||
"analyzing-malware-behavior-with-cuckoo-sandbox",
|
||||
"analyzing-malware-family-relationships-with-malpedia",
|
||||
"analyzing-malware-persistence-with-autoruns",
|
||||
"analyzing-malware-sandbox-evasion-techniques",
|
||||
"analyzing-memory-dumps-with-volatility",
|
||||
"analyzing-memory-forensics-with-lime-and-volatility",
|
||||
"analyzing-mft-for-deleted-file-recovery",
|
||||
"analyzing-network-covert-channels-in-malware",
|
||||
"analyzing-network-flow-data-with-netflow",
|
||||
"analyzing-network-packets-with-scapy",
|
||||
"analyzing-network-traffic-for-incidents",
|
||||
"analyzing-network-traffic-of-malware",
|
||||
"analyzing-network-traffic-with-wireshark",
|
||||
"analyzing-office365-audit-logs-for-compromise",
|
||||
"analyzing-outlook-pst-for-email-forensics",
|
||||
"analyzing-packed-malware-with-upx-unpacker",
|
||||
"analyzing-pdf-malware-with-pdfid",
|
||||
"analyzing-persistence-mechanisms-in-linux",
|
||||
"analyzing-powershell-empire-artifacts",
|
||||
"analyzing-powershell-script-block-logging",
|
||||
"analyzing-prefetch-files-for-execution-history",
|
||||
"analyzing-ransomware-encryption-mechanisms",
|
||||
"analyzing-ransomware-leak-site-intelligence",
|
||||
"analyzing-ransomware-network-indicators",
|
||||
"analyzing-ransomware-payment-wallets",
|
||||
"analyzing-sbom-for-supply-chain-vulnerabilities",
|
||||
"analyzing-security-logs-with-splunk",
|
||||
"analyzing-slack-space-and-file-system-artifacts",
|
||||
"analyzing-supply-chain-malware-artifacts",
|
||||
"analyzing-threat-actor-ttps-with-mitre-attack",
|
||||
"analyzing-threat-actor-ttps-with-mitre-navigator",
|
||||
"analyzing-threat-intelligence-feeds",
|
||||
"analyzing-threat-landscape-with-misp",
|
||||
"analyzing-tls-certificate-transparency-logs",
|
||||
"analyzing-typosquatting-domains-with-dnstwist",
|
||||
"analyzing-uefi-bootkit-persistence",
|
||||
"analyzing-usb-device-connection-history",
|
||||
"analyzing-web-server-logs-for-intrusion",
|
||||
"analyzing-windows-amcache-artifacts",
|
||||
"analyzing-windows-event-logs-in-splunk",
|
||||
"analyzing-windows-lnk-files-for-artifacts",
|
||||
"analyzing-windows-prefetch-with-python",
|
||||
"analyzing-windows-registry-for-artifacts",
|
||||
"analyzing-windows-shellbag-artifacts",
|
||||
"assessing-vector-and-embedding-weaknesses",
|
||||
"attacking-entra-id-with-roadtools",
|
||||
"attacking-oauth-with-device-code-phishing",
|
||||
"auditing-aws-s3-bucket-permissions",
|
||||
"auditing-azure-active-directory-configuration",
|
||||
"auditing-cloud-with-cis-benchmarks",
|
||||
"auditing-entra-id-with-aadinternals",
|
||||
"auditing-foundry-smart-contract-security",
|
||||
"auditing-gcp-iam-permissions",
|
||||
"auditing-kubernetes-cluster-rbac",
|
||||
"auditing-mcp-servers-for-tool-poisoning",
|
||||
"auditing-terraform-infrastructure-for-security",
|
||||
"auditing-tls-certificate-transparency-logs",
|
||||
"auditing-uefi-firmware-with-chipsec",
|
||||
"automating-ioc-enrichment",
|
||||
"building-adversary-infrastructure-tracking-system",
|
||||
"building-attack-pattern-library-from-cti-reports",
|
||||
"building-automated-malware-submission-pipeline",
|
||||
"building-c2-infrastructure-with-sliver-framework",
|
||||
"building-c2-redirector-infrastructure",
|
||||
"building-detection-rule-with-splunk-spl",
|
||||
"building-detection-rules-with-sigma",
|
||||
"building-devsecops-pipeline-with-gitlab-ci",
|
||||
"building-identity-federation-with-saml-azure-ad",
|
||||
"building-identity-governance-lifecycle-process",
|
||||
"building-incident-response-dashboard",
|
||||
"building-incident-response-playbook",
|
||||
"building-incident-timeline-with-timesketch",
|
||||
"building-ioc-defanging-and-sharing-pipeline",
|
||||
"building-ioc-enrichment-pipeline-with-opencti",
|
||||
"building-malware-incident-communication-template",
|
||||
"building-patch-tuesday-response-process",
|
||||
"building-phishing-reporting-button-workflow",
|
||||
"building-ransomware-playbook-with-cisa-framework",
|
||||
"building-red-team-c2-infrastructure-with-havoc",
|
||||
"building-role-mining-for-rbac-optimization",
|
||||
"building-soc-escalation-matrix",
|
||||
"building-soc-metrics-and-kpi-tracking",
|
||||
"building-soc-playbook-for-ransomware",
|
||||
"building-super-timelines-with-plaso",
|
||||
"building-threat-actor-profile-from-osint",
|
||||
"building-threat-feed-aggregation-with-misp",
|
||||
"building-threat-hunt-hypothesis-framework",
|
||||
"building-threat-intelligence-enrichment-in-splunk",
|
||||
"building-threat-intelligence-feed-integration",
|
||||
"building-threat-intelligence-platform",
|
||||
"building-vulnerability-aging-and-sla-tracking",
|
||||
"building-vulnerability-dashboard-with-defectdojo",
|
||||
"building-vulnerability-exception-tracking-system",
|
||||
"building-vulnerability-scanning-workflow",
|
||||
"bypassing-authentication-with-forced-browsing",
|
||||
"coercing-authentication-with-coercer-petitpotam",
|
||||
"collecting-indicators-of-compromise",
|
||||
"collecting-open-source-intelligence",
|
||||
"collecting-threat-intelligence-with-misp",
|
||||
"collecting-volatile-evidence-from-compromised-host",
|
||||
"conducting-api-security-testing",
|
||||
"conducting-cloud-incident-response",
|
||||
"conducting-cloud-penetration-testing",
|
||||
"conducting-cyber-risk-assessment-with-nist-800-30",
|
||||
"conducting-domain-persistence-with-dcsync",
|
||||
"conducting-external-reconnaissance-with-osint",
|
||||
"conducting-full-scope-red-team-engagement",
|
||||
"conducting-internal-network-penetration-test",
|
||||
"conducting-internal-reconnaissance-with-bloodhound-ce",
|
||||
"conducting-malware-incident-response",
|
||||
"conducting-man-in-the-middle-attack-simulation",
|
||||
"conducting-memory-forensics-with-volatility",
|
||||
"conducting-mobile-app-penetration-test",
|
||||
"conducting-network-penetration-test",
|
||||
"conducting-pass-the-ticket-attack",
|
||||
"conducting-phishing-incident-response",
|
||||
"conducting-post-incident-lessons-learned",
|
||||
"conducting-social-engineering-penetration-test",
|
||||
"conducting-social-engineering-pretext-call",
|
||||
"conducting-spearphishing-simulation-campaign",
|
||||
"conducting-wireless-network-penetration-test",
|
||||
"configuring-active-directory-tiered-model",
|
||||
"configuring-aws-verified-access-for-ztna",
|
||||
"configuring-certificate-authority-with-openssl",
|
||||
"configuring-host-based-intrusion-detection",
|
||||
"configuring-hsm-for-key-storage",
|
||||
"configuring-identity-aware-proxy-with-google-iap",
|
||||
"configuring-ldap-security-hardening",
|
||||
"configuring-microsegmentation-for-zero-trust",
|
||||
"configuring-multi-factor-authentication-with-duo",
|
||||
"configuring-network-segmentation-with-vlans",
|
||||
"configuring-oauth2-authorization-flow",
|
||||
"configuring-pfsense-firewall-rules",
|
||||
"configuring-snort-ids-for-intrusion-detection",
|
||||
"configuring-suricata-for-network-monitoring",
|
||||
"configuring-tls-1-3-for-secure-communications",
|
||||
"configuring-windows-defender-advanced-settings",
|
||||
"configuring-windows-event-logging-for-detection",
|
||||
"configuring-zscaler-private-access-for-ztna",
|
||||
"containing-active-breach",
|
||||
"continuous-llm-red-teaming-with-promptfoo",
|
||||
"correlating-security-events-in-qradar",
|
||||
"correlating-threat-campaigns",
|
||||
"defending-llms-with-guardrails",
|
||||
"deobfuscating-javascript-malware",
|
||||
"deobfuscating-powershell-obfuscated-malware",
|
||||
"deploying-active-directory-honeytokens",
|
||||
"deploying-cloud-deception-with-decoy-resources",
|
||||
"deploying-cloudflare-access-for-zero-trust",
|
||||
"deploying-decoy-files-for-ransomware-detection",
|
||||
"deploying-edr-agent-with-crowdstrike",
|
||||
"deploying-honeytokens-and-canarytokens",
|
||||
"deploying-osquery-for-endpoint-monitoring",
|
||||
"deploying-palo-alto-prisma-access-zero-trust",
|
||||
"deploying-ransomware-canary-files",
|
||||
"deploying-software-defined-perimeter",
|
||||
"deploying-tailscale-for-zero-trust-vpn",
|
||||
"designing-adversary-engagement-with-mitre-engage",
|
||||
"detecting-ai-model-prompt-injection-attacks",
|
||||
"detecting-anomalies-in-industrial-control-systems",
|
||||
"detecting-anomalous-authentication-patterns",
|
||||
"detecting-api-enumeration-attacks",
|
||||
"detecting-arp-poisoning-in-network-traffic",
|
||||
"detecting-attacks-on-historian-servers",
|
||||
"detecting-attacks-on-scada-systems",
|
||||
"detecting-aws-cloudtrail-anomalies",
|
||||
"detecting-aws-credential-exposure-with-trufflehog",
|
||||
"detecting-aws-guardduty-findings-automation",
|
||||
"detecting-aws-iam-privilege-escalation",
|
||||
"detecting-azure-lateral-movement",
|
||||
"detecting-azure-service-principal-abuse",
|
||||
"detecting-azure-storage-account-misconfigurations",
|
||||
"detecting-beaconing-patterns-with-zeek",
|
||||
"detecting-bluetooth-low-energy-attacks",
|
||||
"detecting-broken-object-property-level-authorization",
|
||||
"detecting-business-email-compromise",
|
||||
"detecting-business-email-compromise-with-ai",
|
||||
"detecting-cloud-threats-with-guardduty",
|
||||
"detecting-command-and-control-over-dns",
|
||||
"detecting-compromised-cloud-credentials",
|
||||
"detecting-credential-dumping-techniques",
|
||||
"detecting-cryptomining-in-cloud",
|
||||
"detecting-data-and-model-poisoning",
|
||||
"detecting-dcsync-attack-in-active-directory",
|
||||
"detecting-deepfake-audio-in-vishing-attacks",
|
||||
"detecting-dependency-confusion",
|
||||
"detecting-dll-sideloading-attacks",
|
||||
"detecting-dnp3-protocol-anomalies",
|
||||
"detecting-dns-exfiltration-with-dns-query-analysis",
|
||||
"detecting-email-account-compromise",
|
||||
"detecting-email-forwarding-rules-attack",
|
||||
"detecting-entra-offensive-tools-in-graph-logs",
|
||||
"detecting-evasion-techniques-in-endpoint-logs",
|
||||
"detecting-exfiltration-over-dns-with-zeek",
|
||||
"detecting-fileless-attacks-on-endpoints",
|
||||
"detecting-fileless-malware-techniques",
|
||||
"detecting-golden-ticket-attacks-in-kerberos-logs",
|
||||
"detecting-golden-ticket-forgery",
|
||||
"detecting-indirect-prompt-injection",
|
||||
"detecting-insider-data-exfiltration-via-dlp",
|
||||
"detecting-insider-threat-behaviors",
|
||||
"detecting-insider-threat-with-ueba",
|
||||
"detecting-kerberoasting-attacks",
|
||||
"detecting-lateral-movement-in-network",
|
||||
"detecting-lateral-movement-with-splunk",
|
||||
"detecting-lateral-movement-with-zeek",
|
||||
"detecting-living-off-the-land-attacks",
|
||||
"detecting-living-off-the-land-with-lolbas",
|
||||
"detecting-malicious-npm-packages",
|
||||
"detecting-malicious-scheduled-tasks-with-sysmon",
|
||||
"detecting-mimikatz-execution-patterns",
|
||||
"detecting-misconfigured-azure-storage",
|
||||
"detecting-mobile-malware-behavior",
|
||||
"detecting-modbus-command-injection-attacks",
|
||||
"detecting-modbus-protocol-anomalies",
|
||||
"detecting-model-extraction-attacks",
|
||||
"detecting-network-anomalies-with-zeek",
|
||||
"detecting-network-scanning-with-ids-signatures",
|
||||
"detecting-ntlm-relay-with-event-correlation",
|
||||
"detecting-oauth-token-theft",
|
||||
"detecting-pass-the-hash-attacks",
|
||||
"detecting-pass-the-ticket-attacks",
|
||||
"detecting-port-scanning-with-fail2ban",
|
||||
"detecting-privilege-escalation-attempts",
|
||||
"detecting-process-hollowing-technique",
|
||||
"detecting-process-injection-techniques",
|
||||
"detecting-qr-code-phishing-with-email-security",
|
||||
"detecting-ransomware-encryption-behavior",
|
||||
"detecting-ransomware-precursors-in-network",
|
||||
"detecting-rdp-brute-force-attacks",
|
||||
"detecting-rootkit-activity",
|
||||
"detecting-s3-data-exfiltration-attempts",
|
||||
"detecting-secure-boot-bypass",
|
||||
"detecting-serverless-function-injection",
|
||||
"detecting-service-account-abuse",
|
||||
"detecting-shadow-api-endpoints",
|
||||
"detecting-shadow-it-cloud-usage",
|
||||
"detecting-spearphishing-with-email-gateway",
|
||||
"detecting-sql-injection-via-waf-logs",
|
||||
"detecting-stuxnet-style-attacks",
|
||||
"detecting-supply-chain-attacks-in-ci-cd",
|
||||
"detecting-suspicious-oauth-application-consent",
|
||||
"detecting-suspicious-powershell-execution",
|
||||
"detecting-t1003-credential-dumping-with-edr",
|
||||
"detecting-t1055-process-injection-with-sysmon",
|
||||
"detecting-t1548-abuse-elevation-control-mechanism",
|
||||
"detecting-typosquatting-packages",
|
||||
"detecting-typosquatting-packages-in-npm-pypi",
|
||||
"detecting-wmi-persistence",
|
||||
"emulating-cloud-attacks-with-stratus-red-team",
|
||||
"enumerating-cloud-with-cloudfox",
|
||||
"eradicating-malware-from-infected-systems",
|
||||
"evaluating-threat-intelligence-platforms",
|
||||
"executing-active-directory-attack-simulation",
|
||||
"executing-nist-rmf-authorization-to-operate",
|
||||
"executing-phishing-simulation-campaign",
|
||||
"executing-red-team-engagement-planning",
|
||||
"executing-red-team-exercise",
|
||||
"exploiting-active-directory-certificate-services-esc1",
|
||||
"exploiting-active-directory-with-bloodhound",
|
||||
"exploiting-adcs-with-certipy",
|
||||
"exploiting-api-injection-vulnerabilities",
|
||||
"exploiting-aws-with-pacu",
|
||||
"exploiting-bgp-hijacking-vulnerabilities",
|
||||
"exploiting-broken-function-level-authorization",
|
||||
"exploiting-broken-link-hijacking",
|
||||
"exploiting-constrained-delegation-abuse",
|
||||
"exploiting-deeplink-vulnerabilities",
|
||||
"exploiting-excessive-data-exposure-in-api",
|
||||
"exploiting-http-request-smuggling",
|
||||
"exploiting-idor-vulnerabilities",
|
||||
"exploiting-insecure-data-storage-in-mobile",
|
||||
"exploiting-insecure-deserialization",
|
||||
"exploiting-ipv6-vulnerabilities",
|
||||
"exploiting-jwt-algorithm-confusion-attack",
|
||||
"exploiting-kerberoasting-with-impacket",
|
||||
"exploiting-mass-assignment-in-rest-apis",
|
||||
"exploiting-ms17-010-eternalblue-vulnerability",
|
||||
"exploiting-nopac-cve-2021-42278-42287",
|
||||
"exploiting-nosql-injection-vulnerabilities",
|
||||
"exploiting-oauth-misconfiguration",
|
||||
"exploiting-prototype-pollution-in-javascript",
|
||||
"exploiting-race-condition-vulnerabilities",
|
||||
"exploiting-server-side-request-forgery",
|
||||
"exploiting-smb-vulnerabilities-with-metasploit",
|
||||
"exploiting-sql-injection-vulnerabilities",
|
||||
"exploiting-sql-injection-with-sqlmap",
|
||||
"exploiting-template-injection-vulnerabilities",
|
||||
"exploiting-type-juggling-vulnerabilities",
|
||||
"exploiting-vulnerabilities-with-metasploit-framework",
|
||||
"exploiting-websocket-vulnerabilities",
|
||||
"exploiting-zerologon-vulnerability-cve-2020-1472",
|
||||
"extracting-browser-history-artifacts",
|
||||
"extracting-config-from-agent-tesla-rat",
|
||||
"extracting-credentials-from-memory-dump",
|
||||
"extracting-iocs-from-malware-samples",
|
||||
"extracting-memory-artifacts-with-rekall",
|
||||
"extracting-windows-event-logs-artifacts",
|
||||
"fleet-hunting-with-velociraptor",
|
||||
"generating-and-analyzing-sboms",
|
||||
"generating-forensic-timelines-with-hayabusa",
|
||||
"generating-threat-intelligence-reports",
|
||||
"hardening-linux-endpoint-with-cis-benchmark",
|
||||
"hardening-windows-endpoint-with-cis-benchmark",
|
||||
"hunting-advanced-persistent-threats",
|
||||
"hunting-bootkits-in-efi-system-partition",
|
||||
"hunting-credential-stuffing-attacks",
|
||||
"hunting-evtx-with-chainsaw",
|
||||
"hunting-for-anomalous-powershell-execution",
|
||||
"hunting-for-beaconing-with-frequency-analysis",
|
||||
"hunting-for-cobalt-strike-beacons",
|
||||
"hunting-for-command-and-control-beaconing",
|
||||
"hunting-for-data-exfiltration-indicators",
|
||||
"hunting-for-data-staging-before-exfiltration",
|
||||
"hunting-for-dcom-lateral-movement",
|
||||
"hunting-for-dcsync-attacks",
|
||||
"hunting-for-defense-evasion-via-timestomping",
|
||||
"hunting-for-dns-based-persistence",
|
||||
"hunting-for-dns-tunneling-with-zeek",
|
||||
"hunting-for-domain-fronting-c2-traffic",
|
||||
"hunting-for-lateral-movement-via-wmi",
|
||||
"hunting-for-living-off-the-cloud-techniques",
|
||||
"hunting-for-living-off-the-land-binaries",
|
||||
"hunting-for-lolbins-execution-in-endpoint-logs",
|
||||
"hunting-for-ntlm-relay-attacks",
|
||||
"hunting-for-persistence-mechanisms-in-windows",
|
||||
"hunting-for-persistence-via-wmi-subscriptions",
|
||||
"hunting-for-process-injection-techniques",
|
||||
"hunting-for-registry-persistence-mechanisms",
|
||||
"hunting-for-registry-run-key-persistence",
|
||||
"hunting-for-scheduled-task-persistence",
|
||||
"hunting-for-shadow-copy-deletion",
|
||||
"hunting-for-spearphishing-indicators",
|
||||
"hunting-for-startup-folder-persistence",
|
||||
"hunting-for-supply-chain-compromise",
|
||||
"hunting-for-suspicious-scheduled-tasks",
|
||||
"hunting-for-t1098-account-manipulation",
|
||||
"hunting-for-unusual-network-connections",
|
||||
"hunting-for-unusual-service-installations",
|
||||
"hunting-for-webshell-activity",
|
||||
"hunting-saas-sso-token-abuse",
|
||||
"implementing-aes-encryption-for-data-at-rest",
|
||||
"implementing-alert-fatigue-reduction",
|
||||
"implementing-anti-phishing-training-program",
|
||||
"implementing-anti-ransomware-group-policy",
|
||||
"implementing-api-abuse-detection-with-rate-limiting",
|
||||
"implementing-api-gateway-security-controls",
|
||||
"implementing-api-key-security-controls",
|
||||
"implementing-api-rate-limiting-and-throttling",
|
||||
"implementing-api-schema-validation-security",
|
||||
"implementing-api-security-posture-management",
|
||||
"implementing-api-security-testing-with-42crunch",
|
||||
"implementing-api-threat-protection-with-apigee",
|
||||
"implementing-application-whitelisting-with-applocker",
|
||||
"implementing-aqua-security-for-container-scanning",
|
||||
"implementing-attack-path-analysis-with-xm-cyber",
|
||||
"implementing-attack-surface-management",
|
||||
"implementing-aws-config-rules-for-compliance",
|
||||
"implementing-aws-iam-permission-boundaries",
|
||||
"implementing-aws-macie-for-data-classification",
|
||||
"implementing-aws-nitro-enclave-security",
|
||||
"implementing-azure-ad-privileged-identity-management",
|
||||
"implementing-bgp-security-with-rpki",
|
||||
"implementing-browser-isolation-for-zero-trust",
|
||||
"implementing-canary-tokens-for-network-intrusion",
|
||||
"implementing-cisa-zero-trust-maturity-model",
|
||||
"implementing-cloud-trail-log-analysis",
|
||||
"implementing-cloud-vulnerability-posture-management",
|
||||
"implementing-cloud-waf-rules",
|
||||
"implementing-cloud-workload-protection",
|
||||
"implementing-code-signing-for-artifacts",
|
||||
"implementing-conditional-access-policies-azure-ad",
|
||||
"implementing-conduit-security-for-ot-remote-access",
|
||||
"implementing-continuous-security-validation-with-bas",
|
||||
"implementing-data-loss-prevention-with-microsoft-purview",
|
||||
"implementing-ddos-mitigation-with-cloudflare",
|
||||
"implementing-deception-based-detection-with-canarytoken",
|
||||
"implementing-delinea-secret-server-for-pam",
|
||||
"implementing-device-posture-assessment-in-zero-trust",
|
||||
"implementing-devsecops-security-scanning",
|
||||
"implementing-diamond-model-analysis",
|
||||
"implementing-digital-signatures-with-ed25519",
|
||||
"implementing-disk-encryption-with-bitlocker",
|
||||
"implementing-dmarc-dkim-spf-email-security",
|
||||
"implementing-ebpf-security-monitoring",
|
||||
"implementing-email-sandboxing-with-proofpoint",
|
||||
"implementing-end-to-end-encryption-for-messaging",
|
||||
"implementing-endpoint-detection-with-wazuh",
|
||||
"implementing-endpoint-dlp-controls",
|
||||
"implementing-envelope-encryption-with-aws-kms",
|
||||
"implementing-epss-score-for-vulnerability-prioritization",
|
||||
"implementing-file-integrity-monitoring-with-aide",
|
||||
"implementing-fuzz-testing-in-cicd-with-aflplusplus",
|
||||
"implementing-gcp-binary-authorization",
|
||||
"implementing-gcp-organization-policy-constraints",
|
||||
"implementing-gdpr-data-protection-controls",
|
||||
"implementing-gdpr-data-subject-access-request",
|
||||
"implementing-github-advanced-security-for-code-scanning",
|
||||
"implementing-google-workspace-admin-security",
|
||||
"implementing-google-workspace-phishing-protection",
|
||||
"implementing-google-workspace-sso-configuration",
|
||||
"implementing-hardware-security-key-authentication",
|
||||
"implementing-hashicorp-vault-dynamic-secrets",
|
||||
"implementing-hipaa-security-rule-safeguards",
|
||||
"implementing-honeypot-for-ransomware-detection",
|
||||
"implementing-honeytokens-for-breach-detection",
|
||||
"implementing-ics-firewall-with-tofino",
|
||||
"implementing-identity-governance-with-sailpoint",
|
||||
"implementing-identity-verification-for-zero-trust",
|
||||
"implementing-iec-62443-security-zones",
|
||||
"implementing-immutable-backup-with-restic",
|
||||
"implementing-infrastructure-as-code-security-scanning",
|
||||
"implementing-iso-27001-information-security-management",
|
||||
"implementing-just-in-time-access-provisioning",
|
||||
"implementing-jwt-signing-and-verification",
|
||||
"implementing-llm-guardrails-for-security",
|
||||
"implementing-log-forwarding-with-fluentd",
|
||||
"implementing-log-integrity-with-blockchain",
|
||||
"implementing-memory-protection-with-dep-aslr",
|
||||
"implementing-microsegmentation-with-guardicore",
|
||||
"implementing-mimecast-targeted-attack-protection",
|
||||
"implementing-mitre-attack-coverage-mapping",
|
||||
"implementing-mobile-application-management",
|
||||
"implementing-mtls-for-zero-trust-services",
|
||||
"implementing-nerc-cip-compliance-controls",
|
||||
"implementing-network-access-control",
|
||||
"implementing-network-access-control-with-cisco-ise",
|
||||
"implementing-network-deception-with-honeypots",
|
||||
"implementing-network-intrusion-prevention-with-suricata",
|
||||
"implementing-network-segmentation-for-ot",
|
||||
"implementing-network-segmentation-with-firewall-zones",
|
||||
"implementing-network-traffic-analysis-with-arkime",
|
||||
"implementing-network-traffic-baselining",
|
||||
"implementing-next-generation-firewall-with-palo-alto",
|
||||
"implementing-ot-incident-response-playbook",
|
||||
"implementing-ot-network-traffic-analysis-with-nozomi",
|
||||
"implementing-pam-for-database-access",
|
||||
"implementing-passwordless-auth-with-microsoft-entra",
|
||||
"implementing-passwordless-authentication-with-fido2",
|
||||
"implementing-patch-management-for-ot-systems",
|
||||
"implementing-patch-management-workflow",
|
||||
"implementing-pci-dss-compliance-controls",
|
||||
"implementing-policy-as-code-with-open-policy-agent",
|
||||
"implementing-privileged-access-management-with-cyberark",
|
||||
"implementing-privileged-access-workstation",
|
||||
"implementing-privileged-session-monitoring",
|
||||
"implementing-proofpoint-email-security-gateway",
|
||||
"implementing-purdue-model-network-segmentation",
|
||||
"implementing-ransomware-backup-strategy",
|
||||
"implementing-ransomware-kill-switch-detection",
|
||||
"implementing-rapid7-insightvm-for-scanning",
|
||||
"implementing-rsa-key-pair-management",
|
||||
"implementing-runtime-application-self-protection",
|
||||
"implementing-saml-sso-with-okta",
|
||||
"implementing-scim-provisioning-with-okta",
|
||||
"implementing-secret-scanning-with-gitleaks",
|
||||
"implementing-secrets-management-with-vault",
|
||||
"implementing-secrets-scanning-in-ci-cd",
|
||||
"implementing-security-chaos-engineering",
|
||||
"implementing-security-information-sharing-with-stix2",
|
||||
"implementing-security-monitoring-with-datadog",
|
||||
"implementing-semgrep-for-custom-sast-rules",
|
||||
"implementing-siem-correlation-rules-for-apt",
|
||||
"implementing-siem-use-case-tuning",
|
||||
"implementing-siem-use-cases-for-detection",
|
||||
"implementing-sigstore-for-software-signing",
|
||||
"implementing-soar-automation-with-phantom",
|
||||
"implementing-soar-playbook-for-phishing",
|
||||
"implementing-soar-playbook-with-palo-alto-xsoar",
|
||||
"implementing-stix-taxii-feed-integration",
|
||||
"implementing-syslog-centralization-with-rsyslog",
|
||||
"implementing-taxii-server-with-opentaxii",
|
||||
"implementing-threat-intelligence-lifecycle-management",
|
||||
"implementing-threat-modeling-with-mitre-attack",
|
||||
"implementing-ticketing-system-for-incidents",
|
||||
"implementing-usb-device-control-policy",
|
||||
"implementing-velociraptor-for-ir-collection",
|
||||
"implementing-vulnerability-management-with-greenbone",
|
||||
"implementing-vulnerability-remediation-sla",
|
||||
"implementing-vulnerability-sla-breach-alerting",
|
||||
"implementing-web-application-logging-with-modsecurity",
|
||||
"implementing-zero-knowledge-proof-for-authentication",
|
||||
"implementing-zero-standing-privilege-with-cyberark",
|
||||
"implementing-zero-trust-dns-with-nextdns",
|
||||
"implementing-zero-trust-for-saas-applications",
|
||||
"implementing-zero-trust-in-cloud",
|
||||
"implementing-zero-trust-network-access",
|
||||
"implementing-zero-trust-network-access-with-zscaler",
|
||||
"implementing-zero-trust-with-beyondcorp",
|
||||
"implementing-zero-trust-with-hashicorp-boundary",
|
||||
"integrating-dast-with-owasp-zap-in-pipeline",
|
||||
"integrating-sast-into-github-actions-pipeline",
|
||||
"intercepting-mobile-traffic-with-burpsuite",
|
||||
"investigating-insider-threat-indicators",
|
||||
"investigating-phishing-email-incident",
|
||||
"investigating-ransomware-attack-artifacts",
|
||||
"managing-cloud-identity-with-okta",
|
||||
"managing-intelligence-lifecycle",
|
||||
"managing-third-party-vendor-risk",
|
||||
"mapping-attack-paths-with-bloodhound-ce",
|
||||
"mapping-mitre-attack-techniques",
|
||||
"migrating-to-post-quantum-cryptography",
|
||||
"modeling-threats-with-opencti",
|
||||
"monitoring-darkweb-sources",
|
||||
"monitoring-scada-modbus-traffic-anomalies",
|
||||
"moving-laterally-with-netexec",
|
||||
"operating-havoc-c2",
|
||||
"operating-sliver-c2",
|
||||
"operationalizing-misp-threat-feeds",
|
||||
"orchestrating-llm-attacks-with-pyrit",
|
||||
"parsing-artifacts-with-eric-zimmerman-tools",
|
||||
"performing-access-recertification-with-saviynt",
|
||||
"performing-access-review-and-certification",
|
||||
"performing-active-directory-bloodhound-analysis",
|
||||
"performing-active-directory-compromise-investigation",
|
||||
"performing-active-directory-forest-trust-attack",
|
||||
"performing-active-directory-penetration-test",
|
||||
"performing-active-directory-vulnerability-assessment",
|
||||
"performing-adversary-in-the-middle-phishing-detection",
|
||||
"performing-agentless-vulnerability-scanning",
|
||||
"performing-ai-driven-osint-correlation",
|
||||
"performing-alert-triage-with-elastic-siem",
|
||||
"performing-android-app-static-analysis-with-mobsf",
|
||||
"performing-api-fuzzing-with-restler",
|
||||
"performing-api-inventory-and-discovery",
|
||||
"performing-api-rate-limiting-bypass",
|
||||
"performing-api-security-testing-with-postman",
|
||||
"performing-asset-criticality-scoring-for-vulns",
|
||||
"performing-authenticated-scan-with-openvas",
|
||||
"performing-authenticated-vulnerability-scan",
|
||||
"performing-automated-malware-analysis-with-cape",
|
||||
"performing-aws-account-enumeration-with-scout-suite",
|
||||
"performing-aws-privilege-escalation-assessment",
|
||||
"performing-bandwidth-throttling-attack-simulation",
|
||||
"performing-binary-exploitation-analysis",
|
||||
"performing-blind-ssrf-exploitation",
|
||||
"performing-bluetooth-security-assessment",
|
||||
"performing-brand-monitoring-for-impersonation",
|
||||
"performing-clickjacking-attack-test",
|
||||
"performing-cloud-asset-inventory-with-cartography",
|
||||
"performing-cloud-forensics-investigation",
|
||||
"performing-cloud-forensics-with-aws-cloudtrail",
|
||||
"performing-cloud-incident-containment-procedures",
|
||||
"performing-cloud-log-forensics-with-athena",
|
||||
"performing-cloud-native-forensics-with-falco",
|
||||
"performing-cloud-native-threat-hunting-with-aws-detective",
|
||||
"performing-cloud-penetration-testing-with-pacu",
|
||||
"performing-cloud-storage-forensic-acquisition",
|
||||
"performing-container-image-hardening",
|
||||
"performing-content-security-policy-bypass",
|
||||
"performing-credential-access-with-lazagne",
|
||||
"performing-cryptographic-audit-of-application",
|
||||
"performing-csrf-attack-simulation",
|
||||
"performing-cve-prioritization-with-kev-catalog",
|
||||
"performing-dark-web-monitoring-for-threats",
|
||||
"performing-deception-technology-deployment",
|
||||
"performing-directory-traversal-testing",
|
||||
"performing-disk-forensics-investigation",
|
||||
"performing-dmarc-policy-enforcement-rollout",
|
||||
"performing-dns-enumeration-and-zone-transfer",
|
||||
"performing-dns-tunneling-detection",
|
||||
"performing-dynamic-analysis-of-android-app",
|
||||
"performing-dynamic-analysis-with-any-run",
|
||||
"performing-endpoint-forensics-investigation",
|
||||
"performing-endpoint-vulnerability-remediation",
|
||||
"performing-entitlement-review-with-sailpoint-iiq",
|
||||
"performing-external-network-penetration-test",
|
||||
"performing-false-positive-reduction-in-siem",
|
||||
"performing-file-carving-with-foremost",
|
||||
"performing-firmware-extraction-with-binwalk",
|
||||
"performing-firmware-malware-analysis",
|
||||
"performing-fuzzing-with-aflplusplus",
|
||||
"performing-gcp-penetration-testing-with-gcpbucketbrute",
|
||||
"performing-gcp-security-assessment-with-forseti",
|
||||
"performing-graphql-depth-limit-attack",
|
||||
"performing-graphql-introspection-attack",
|
||||
"performing-graphql-security-assessment",
|
||||
"performing-hardware-security-module-integration",
|
||||
"performing-hash-cracking-with-hashcat",
|
||||
"performing-http-parameter-pollution-attack",
|
||||
"performing-indicator-lifecycle-management",
|
||||
"performing-initial-access-with-evilginx3",
|
||||
"performing-insider-threat-investigation",
|
||||
"performing-ioc-enrichment-automation",
|
||||
"performing-ios-app-security-assessment",
|
||||
"performing-iot-security-assessment",
|
||||
"performing-ip-reputation-analysis-with-shodan",
|
||||
"performing-jwt-none-algorithm-attack",
|
||||
"performing-kerberoasting-attack",
|
||||
"performing-lateral-movement-with-wmiexec",
|
||||
"performing-linux-log-forensics-investigation",
|
||||
"performing-log-analysis-for-forensic-investigation",
|
||||
"performing-log-source-onboarding-in-siem",
|
||||
"performing-malware-hash-enrichment-with-virustotal",
|
||||
"performing-malware-ioc-extraction",
|
||||
"performing-malware-persistence-investigation",
|
||||
"performing-malware-triage-with-yara",
|
||||
"performing-memory-forensics-with-volatility3",
|
||||
"performing-memory-forensics-with-volatility3-plugins",
|
||||
"performing-mobile-app-certificate-pinning-bypass",
|
||||
"performing-mobile-device-forensics-with-cellebrite",
|
||||
"performing-network-forensics-with-wireshark",
|
||||
"performing-network-packet-capture-analysis",
|
||||
"performing-network-traffic-analysis-with-tshark",
|
||||
"performing-network-traffic-analysis-with-zeek",
|
||||
"performing-nist-csf-maturity-assessment",
|
||||
"performing-oauth-scope-minimization-review",
|
||||
"performing-open-source-intelligence-gathering",
|
||||
"performing-osint-with-spiderfoot",
|
||||
"performing-ot-network-security-assessment",
|
||||
"performing-ot-vulnerability-scanning-safely",
|
||||
"performing-packet-injection-attack",
|
||||
"performing-paste-site-monitoring-for-credentials",
|
||||
"performing-phishing-simulation-with-gophish",
|
||||
"performing-physical-intrusion-assessment",
|
||||
"performing-plc-firmware-security-analysis",
|
||||
"performing-post-quantum-cryptography-migration",
|
||||
"performing-privacy-impact-assessment",
|
||||
"performing-privilege-escalation-assessment",
|
||||
"performing-privilege-escalation-on-linux",
|
||||
"performing-privileged-account-access-review",
|
||||
"performing-privileged-account-discovery",
|
||||
"performing-purple-team-atomic-testing",
|
||||
"performing-purple-team-exercise",
|
||||
"performing-ransomware-response",
|
||||
"performing-ransomware-tabletop-exercise",
|
||||
"performing-red-team-phishing-with-gophish",
|
||||
"performing-red-team-with-covenant",
|
||||
"performing-s7comm-protocol-security-analysis",
|
||||
"performing-sca-dependency-scanning-with-snyk",
|
||||
"performing-scada-hmi-security-assessment",
|
||||
"performing-second-order-sql-injection",
|
||||
"performing-security-headers-audit",
|
||||
"performing-serverless-function-security-review",
|
||||
"performing-service-account-audit",
|
||||
"performing-service-account-credential-rotation",
|
||||
"performing-soap-web-service-security-testing",
|
||||
"performing-soc-tabletop-exercise",
|
||||
"performing-soc2-type2-audit-preparation",
|
||||
"performing-sqlite-database-forensics",
|
||||
"performing-ssl-certificate-lifecycle-management",
|
||||
"performing-ssl-stripping-attack",
|
||||
"performing-ssl-tls-inspection-configuration",
|
||||
"performing-ssl-tls-security-assessment",
|
||||
"performing-ssrf-vulnerability-exploitation",
|
||||
"performing-static-malware-analysis-with-pe-studio",
|
||||
"performing-steganography-detection",
|
||||
"performing-subdomain-enumeration-with-subfinder",
|
||||
"performing-supply-chain-attack-simulation",
|
||||
"performing-thick-client-application-penetration-test",
|
||||
"performing-threat-emulation-with-atomic-red-team",
|
||||
"performing-threat-hunting-with-elastic-siem",
|
||||
"performing-threat-hunting-with-yara-rules",
|
||||
"performing-threat-intelligence-sharing-with-misp",
|
||||
"performing-threat-landscape-assessment-for-sector",
|
||||
"performing-threat-modeling-with-owasp-threat-dragon",
|
||||
"performing-timeline-reconstruction-with-plaso",
|
||||
"performing-user-behavior-analytics",
|
||||
"performing-vlan-hopping-attack",
|
||||
"performing-vulnerability-scanning-with-nessus",
|
||||
"performing-web-application-firewall-bypass",
|
||||
"performing-web-application-penetration-test",
|
||||
"performing-web-application-scanning-with-nikto",
|
||||
"performing-web-application-vulnerability-triage",
|
||||
"performing-web-cache-deception-attack",
|
||||
"performing-web-cache-poisoning-attack",
|
||||
"performing-wifi-password-cracking-with-aircrack",
|
||||
"performing-windows-artifact-analysis-with-eric-zimmerman-tools",
|
||||
"performing-wireless-network-penetration-test",
|
||||
"performing-wireless-security-assessment-with-kismet",
|
||||
"performing-yara-rule-development-for-detection",
|
||||
"post-exploiting-microsoft-graph-with-graphrunner",
|
||||
"prioritizing-vulnerabilities-with-cvss-scoring",
|
||||
"processing-stix-taxii-feeds",
|
||||
"profiling-threat-actor-groups",
|
||||
"recovering-deleted-files-with-photorec",
|
||||
"recovering-from-ransomware-attack",
|
||||
"red-teaming-llms-with-garak",
|
||||
"relaying-ntlm-for-adcs-esc8",
|
||||
"remediating-s3-bucket-misconfiguration",
|
||||
"reverse-engineering-android-malware-with-jadx",
|
||||
"reverse-engineering-dotnet-malware-with-dnspy",
|
||||
"reverse-engineering-ios-app-with-frida",
|
||||
"reverse-engineering-malware-with-ghidra",
|
||||
"reverse-engineering-ransomware-encryption-routine",
|
||||
"reverse-engineering-rust-malware",
|
||||
"scanning-containers-with-trivy-in-cicd",
|
||||
"scanning-iac-and-images-with-trivy",
|
||||
"scanning-infrastructure-with-nessus",
|
||||
"scanning-network-with-nmap-advanced",
|
||||
"securing-agentic-ai-tool-invocation",
|
||||
"securing-api-gateway-with-aws-waf",
|
||||
"securing-aws-iam-permissions",
|
||||
"securing-aws-lambda-execution-roles",
|
||||
"securing-azure-with-microsoft-defender",
|
||||
"securing-container-registry-images",
|
||||
"securing-github-actions-workflows",
|
||||
"securing-historian-server-in-ot-environment",
|
||||
"securing-kubernetes-on-cloud",
|
||||
"securing-remote-access-to-ot-environment",
|
||||
"securing-serverless-functions",
|
||||
"testing-android-intents-for-vulnerabilities",
|
||||
"testing-api-authentication-weaknesses",
|
||||
"testing-api-for-broken-object-level-authorization",
|
||||
"testing-api-for-mass-assignment-vulnerability",
|
||||
"testing-api-security-with-owasp-top-10",
|
||||
"testing-cors-misconfiguration",
|
||||
"testing-for-broken-access-control",
|
||||
"testing-for-business-logic-vulnerabilities",
|
||||
"testing-for-email-header-injection",
|
||||
"testing-for-host-header-injection",
|
||||
"testing-for-json-web-token-vulnerabilities",
|
||||
"testing-for-open-redirect-vulnerabilities",
|
||||
"testing-for-sensitive-data-exposure",
|
||||
"testing-for-system-prompt-leakage",
|
||||
"testing-for-xml-injection-vulnerabilities",
|
||||
"testing-for-xss-vulnerabilities",
|
||||
"testing-for-xss-vulnerabilities-with-burpsuite",
|
||||
"testing-for-xxe-injection-vulnerabilities",
|
||||
"testing-jwt-token-security",
|
||||
"testing-mobile-api-authentication",
|
||||
"testing-oauth2-implementation-flaws",
|
||||
"testing-prompt-injection-in-rag-pipelines",
|
||||
"testing-ransomware-recovery-procedures",
|
||||
"testing-websocket-api-security",
|
||||
"tracking-threat-actor-infrastructure",
|
||||
"triaging-security-alerts-in-splunk",
|
||||
"triaging-security-incident",
|
||||
"triaging-security-incident-with-ir-playbook",
|
||||
"triaging-vulnerabilities-with-ssvc-framework",
|
||||
"triaging-windows-with-kape",
|
||||
"validating-backup-integrity-for-recovery",
|
||||
"validating-tpm-measured-boot-attestation",
|
||||
"verifying-build-provenance-with-slsa-sigstore"
|
||||
],
|
||||
"body-max-lines": [
|
||||
"building-automated-malware-submission-pipeline",
|
||||
"building-identity-governance-lifecycle-process",
|
||||
"detecting-anomalous-authentication-patterns",
|
||||
"detecting-attacks-on-scada-systems",
|
||||
"detecting-command-and-control-over-dns",
|
||||
"detecting-living-off-the-land-attacks",
|
||||
"detecting-modbus-command-injection-attacks",
|
||||
"detecting-ntlm-relay-with-event-correlation",
|
||||
"detecting-serverless-function-injection",
|
||||
"hunting-for-dcom-lateral-movement",
|
||||
"implementing-data-loss-prevention-with-microsoft-purview",
|
||||
"implementing-google-workspace-admin-security",
|
||||
"implementing-hashicorp-vault-dynamic-secrets",
|
||||
"implementing-iec-62443-security-zones",
|
||||
"implementing-passwordless-auth-with-microsoft-entra",
|
||||
"implementing-zero-trust-with-hashicorp-boundary",
|
||||
"performing-cloud-log-forensics-with-athena",
|
||||
"performing-graphql-introspection-attack",
|
||||
"performing-ics-asset-discovery-with-claroty",
|
||||
"performing-oauth-scope-minimization-review",
|
||||
"performing-ot-network-security-assessment",
|
||||
"performing-plc-firmware-security-analysis",
|
||||
"performing-purple-team-atomic-testing"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Lint SKILL.md descriptions for the qualities that drive agent routing.
|
||||
|
||||
The description is the ONLY signal an agent sees at discovery time, so it must
|
||||
say what the skill does, when to fire, and -- critically -- when NOT to fire.
|
||||
Skills whose descriptions overlap without a distinguishing negative trigger get
|
||||
misrouted ("skill collision").
|
||||
|
||||
Rules
|
||||
-----
|
||||
name-matches-folder frontmatter name == directory name
|
||||
desc-max-length description <= 1024 chars (agentskills.io limit)
|
||||
desc-ends-punctuation ends in . ! ? ) " ' -- a truncation canary
|
||||
desc-has-use-when carries an explicit trigger clause
|
||||
desc-has-negative-trigger says what it is NOT for
|
||||
body-max-lines SKILL.md <= 500 lines (Anthropic guidance)
|
||||
|
||||
Grandfathering
|
||||
--------------
|
||||
Known pre-existing failures live in tools/lint-baseline.json so CI can go green
|
||||
today while the debt is paid down. A baselined skill that starts passing is
|
||||
reported as a stale entry -- run --update-baseline to shrink the file. The
|
||||
baseline can only ever shrink in review, never silently grow: any NEW failure
|
||||
is a hard error.
|
||||
|
||||
Usage:
|
||||
python tools/lint-descriptions.py --all
|
||||
python tools/lint-descriptions.py --all --stats
|
||||
python tools/lint-descriptions.py --update-baseline
|
||||
python tools/lint-descriptions.py skills/<slug>
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from skill_frontmatter import description_of, iter_skill_dirs, load_frontmatter, FrontmatterError
|
||||
|
||||
BASELINE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lint-baseline.json")
|
||||
|
||||
DESCRIPTION_MAX_CHARS = 1024
|
||||
BODY_MAX_LINES = 500
|
||||
SENTENCE_ENDINGS = ".!?)\"'"
|
||||
|
||||
# "Use when ...", "Use this skill when ...", "Use for ...", "Use during ..."
|
||||
USE_WHEN_RE = re.compile(
|
||||
r"\buse\s+(?:this\s+)?(?:skill\s+)?(?:when|whenever|for|during|after|before)\b",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
# "Do not use for X", "Don't use when Y", "Not for Z"
|
||||
NEGATIVE_TRIGGER_RE = re.compile(
|
||||
r"\b(?:do\s+not\s+use|don'?t\s+use|not\s+for\b|avoid\s+(?:this\s+)?(?:skill\s+)?for)\b",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
RULES = (
|
||||
"name-matches-folder",
|
||||
"desc-max-length",
|
||||
"desc-ends-punctuation",
|
||||
"desc-has-use-when",
|
||||
"desc-has-negative-trigger",
|
||||
"body-max-lines",
|
||||
)
|
||||
|
||||
RED, GREEN, YELLOW, DIM, RESET = "\033[91m", "\033[92m", "\033[93m", "\033[2m", "\033[0m"
|
||||
|
||||
|
||||
def check_skill(slug: str, skill_dir: str) -> dict[str, str]:
|
||||
"""Return {rule_id: human message} for every rule this skill violates."""
|
||||
skill_md = os.path.join(skill_dir, "SKILL.md")
|
||||
violations: dict[str, str] = {}
|
||||
|
||||
try:
|
||||
frontmatter = load_frontmatter(skill_md)
|
||||
except FrontmatterError as exc:
|
||||
return {"name-matches-folder": f"unparseable frontmatter: {exc}"}
|
||||
|
||||
name = str(frontmatter.get("name", "") or "")
|
||||
if name != slug:
|
||||
violations["name-matches-folder"] = f"name {name!r} != folder {slug!r}"
|
||||
|
||||
description = description_of(frontmatter)
|
||||
|
||||
if len(description) > DESCRIPTION_MAX_CHARS:
|
||||
violations["desc-max-length"] = (
|
||||
f"{len(description)} chars, max {DESCRIPTION_MAX_CHARS}")
|
||||
|
||||
if description and description[-1] not in SENTENCE_ENDINGS:
|
||||
violations["desc-ends-punctuation"] = f"ends with {description[-40:]!r}"
|
||||
|
||||
if not USE_WHEN_RE.search(description):
|
||||
violations["desc-has-use-when"] = "no trigger clause (add 'Use when ...')"
|
||||
|
||||
if not NEGATIVE_TRIGGER_RE.search(description):
|
||||
violations["desc-has-negative-trigger"] = (
|
||||
"no negative trigger (add 'Do not use for X - use <other-skill>.')")
|
||||
|
||||
with open(skill_md, encoding="utf-8") as handle:
|
||||
line_count = sum(1 for _ in handle)
|
||||
if line_count > BODY_MAX_LINES:
|
||||
violations["body-max-lines"] = f"{line_count} lines, max {BODY_MAX_LINES}"
|
||||
|
||||
return violations
|
||||
|
||||
|
||||
def collect(skills_dir: str = "skills") -> dict[str, dict[str, str]]:
|
||||
return {slug: v for slug, d in iter_skill_dirs(skills_dir)
|
||||
if (v := check_skill(slug, d))}
|
||||
|
||||
|
||||
def load_baseline() -> dict[str, list[str]]:
|
||||
if not os.path.isfile(BASELINE_PATH):
|
||||
return {}
|
||||
with open(BASELINE_PATH, encoding="utf-8") as handle:
|
||||
return {k: v for k, v in json.load(handle).items() if not k.startswith("_")}
|
||||
|
||||
|
||||
def write_baseline(violations: dict[str, dict[str, str]]) -> dict[str, list[str]]:
|
||||
baseline = {rule: sorted(s for s, v in violations.items() if rule in v)
|
||||
for rule in RULES}
|
||||
baseline = {rule: slugs for rule, slugs in baseline.items() if slugs}
|
||||
payload = {
|
||||
"_comment": (
|
||||
"Pre-existing lint failures, grandfathered so CI can gate new work today. "
|
||||
"This file may only shrink. Never add a slug by hand -- fix the skill, then "
|
||||
"run: python tools/lint-descriptions.py --update-baseline"
|
||||
),
|
||||
"_total_grandfathered": sum(len(s) for s in baseline.values()),
|
||||
**baseline,
|
||||
}
|
||||
with open(BASELINE_PATH, "w", encoding="utf-8") as handle:
|
||||
json.dump(payload, handle, indent=2)
|
||||
handle.write("\n")
|
||||
return baseline
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("target", nargs="?", help="a single skills/<slug> directory")
|
||||
parser.add_argument("--all", action="store_true", help="lint every skill")
|
||||
parser.add_argument("--stats", action="store_true", help="show per-rule totals")
|
||||
parser.add_argument("--update-baseline", action="store_true",
|
||||
help="rewrite lint-baseline.json from current state")
|
||||
parser.add_argument("--skills-dir", default="skills")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isdir(args.skills_dir):
|
||||
print(f"ERROR: '{args.skills_dir}' not found. Run from the repository root.")
|
||||
return 1
|
||||
|
||||
single_skill = bool(args.target) and not (args.all or args.update_baseline)
|
||||
if single_skill:
|
||||
slug = os.path.basename(args.target.rstrip("/\\"))
|
||||
violations = {slug: v} if (v := check_skill(slug, args.target.rstrip("/\\"))) else {}
|
||||
else:
|
||||
violations = collect(args.skills_dir)
|
||||
|
||||
if args.update_baseline:
|
||||
baseline = write_baseline(violations)
|
||||
total = sum(len(s) for s in baseline.values())
|
||||
print(f"Baseline written: {total} grandfathered violation(s) across "
|
||||
f"{len(baseline)} rule(s) -> {os.path.relpath(BASELINE_PATH)}")
|
||||
for rule in RULES:
|
||||
if baseline.get(rule):
|
||||
print(f" {rule:26s} {len(baseline[rule])}")
|
||||
return 0
|
||||
|
||||
baseline = load_baseline()
|
||||
|
||||
new_failures: list[tuple[str, str, str]] = []
|
||||
grandfathered = 0
|
||||
for slug, rule_map in sorted(violations.items()):
|
||||
for rule, message in sorted(rule_map.items()):
|
||||
if slug in baseline.get(rule, []):
|
||||
grandfathered += 1
|
||||
else:
|
||||
new_failures.append((slug, rule, message))
|
||||
|
||||
# Only meaningful over the whole tree: linting one skill says nothing about
|
||||
# whether the other 816 baselined violations still stand.
|
||||
stale = [] if single_skill else [
|
||||
(rule, slug) for rule, slugs in baseline.items() for slug in slugs
|
||||
if rule not in violations.get(slug, {})
|
||||
]
|
||||
|
||||
if args.stats:
|
||||
print("Violations by rule (grandfathered + new):")
|
||||
for rule in RULES:
|
||||
count = sum(1 for v in violations.values() if rule in v)
|
||||
remaining = len(baseline.get(rule, []))
|
||||
print(f" {rule:26s} {count:4d} baselined {remaining:4d}")
|
||||
print()
|
||||
|
||||
for slug, rule, message in new_failures:
|
||||
print(f"{RED}FAIL{RESET} {slug}: {YELLOW}{rule}{RESET} - {message}")
|
||||
|
||||
if stale:
|
||||
print(f"\n{GREEN}{len(stale)} baselined violation(s) now pass.{RESET} "
|
||||
f"Shrink the baseline: python tools/lint-descriptions.py --update-baseline")
|
||||
for rule, slug in stale[:10]:
|
||||
print(f" {DIM}fixed{RESET} {slug}: {rule}")
|
||||
|
||||
print(f"\n{'=' * 60}")
|
||||
checked = 1 if single_skill else sum(1 for _ in iter_skill_dirs(args.skills_dir))
|
||||
print(f"Skills: {checked} "
|
||||
f"{RED}New failures: {len(new_failures)}{RESET} "
|
||||
f"{YELLOW}Grandfathered: {grandfathered}{RESET}")
|
||||
|
||||
return 1 if new_failures else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user