map-parse-framework
Skill0 starsChanged 18 days agoApache-2.0View on GitHub
Parse a customer-provided control framework file (xlsx/json/md) into normalized framework_objectives[]. Produces map-framework-parsed.json consumed by map-assemble. Supports CCMv4, NIST 800-53, CIS Benchmarks, ISO 27001.
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 6 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
All frameworks use normal Intake and the mandatory published threat-model gate.
- Very specific: line 39
If --framework-file is not provided, scan the input folder for framework files:
- Very specific: line 47
If multiple framework files found, ask the user which to use.
- Very specific: line 48
If no framework file found and --framework is set, use built-in domain reference.
- Very specific: line 52
If inputs.framework_specification is present in 00-intake/intake-manifest.json, read it before parsing.
- Very specific: line 58
Use it to interpret non-obvious conventions in the framework file (e.g.
- Distinctive: line 131
If framework is CCMv4 but no xlsx is parseable, use this built-in domain reference:
- Distinctive: line 155
When using built-in fallback, each objective gets:
- Distinctive: line 185
Rule: If the customer provides a file with a recognizable framework name in its content (headers, sheet names, or first-row data), prefer …
- Very specific: line 190
Rule: If the file cannot be classified into any known framework, set framework.name = "Custom Framework".
- Very specific: line 219
Every objective MUST have: id, domain, title, specification, keywords
- Distinctive: line 233
Run this only when the active framework is NOT CCMv4 (the script no-ops for CCMv4 and skips cleanly if the parsed file is absent):
- Distinctive: line 251
Use borrowed guidance only when its meaning and scope fit the original objective.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Service Approval — Map: Parse Framework
Parse a customer-provided control framework file into a normalized array of framework objectives. This is the smallest, most deterministic sub-skill in the map pipeline.
An explicit customer framework file takes precedence over the default framework. All frameworks use normal Intake and the mandatory published threat-model gate. Custom frameworks are evaluated directly against source-backed controls. The optional CCM guidance lookup below does not determine mapping status.
Input: Framework file (xlsx/json/md) or built-in CCMv4 reference
Output: .service-approval/<slug>/04-map/map-framework-parsed.json
This is one of 4 focused map sub-skills. Each writes to a separate intermediate state file.
Prerequisites
mkdir -p .service-approval/<slug>/04-mapInputs
Parse arguments:
--framework=<type>— framework identifier (default: auto-detect from file)--framework-file=<path>— explicit path to framework file (overrides auto-detection)
Auto-detect framework file
If --framework-file is not provided, scan the input folder for framework files:
.xlsxfiles containing "CCMv4", "ccmv4", "CSA", "cloud controls matrix" in filename -> CCMv4.xlsxfiles containing "NIST", "800-53" in filename -> NIST 800-53.xlsxfiles containing "CIS" in filename -> CIS Benchmarks.xlsxfiles containing "ISO", "27001" in filename -> ISO 27001.jsonfiles with top-levelframeworkorcontrolskey -> parse and detect.mdfiles with framework headers -> parse and detect
If multiple framework files found, ask the user which to use.
If no framework file found and --framework is set, use built-in domain reference.
Customer framework specification (optional)
If inputs.framework_specification is present in 00-intake/intake-manifest.json,
read it before parsing. It is free-text guidance from the customer (supplied inline
via --framework-specification or at the intake prompt) about how their controls are
structured — for example how control IDs and sub-control IDs are formatted, which
column holds the control text, or how requirements are grouped.
Use it to interpret non-obvious conventions in the framework file (e.g. to
recognize a sub-control column, or to split a combined ID like AIS-01.2 into a
parent control and a sub-control). It is advisory only: never let it override
what the file actually contains, and never fail if it is absent or null.
Step 1: Parse Framework File
For .xlsx files (e.g., CCMv4-sample.xlsx):
python3 -c "
import openpyxl, json, sys
wb = openpyxl.load_workbook(sys.argv[1], read_only=True, data_only=True)
for sheet in wb.sheetnames:
ws = wb[sheet]
rows = list(ws.iter_rows(values_only=True))
if rows:
headers = [str(h).strip() if h else '' for h in rows[0]]
print(f'Sheet: {sheet}, Columns: {headers}')
for row in rows[1:6]:
print([str(c)[:80] if c else '' for c in row])
" "<framework-file>"Adapt column mapping based on detected framework:
- CCMv4: Control ID, Control Domain, Control Title, Control Specification
- NIST 800-53: Control Identifier, Control Family, Control Name, Control Description
- CIS: Recommendation #, Section, Title, Description, Level
- ISO 27001: Clause, Control, Objective, Implementation Guidance
For .json files:
import json
data = json.load(open("<framework-file>"))
# Detect structure and extract objectivesFor .md files:
Parse markdown headers and tables to extract framework objectives.
Step 2: Build Normalized framework_objectives[]
Regardless of source format, produce a normalized array where every objective has:
{
"id": "IAM-01",
"domain": "Identity & Access Management",
"title": "Identity and Access Management Policy and Procedures",
"specification": "Establish, document, approve, communicate, apply, evaluate...",
"keywords": ["access", "identity", "authentication", "policy"]
}Keyword extraction rules
Extract keywords from the specification text to aid downstream matching:
- Domain-specific terms (access, encryption, network, logging, etc.)
- Action verbs (restrict, monitor, audit, enforce, validate, protect)
- AWS-relevant terms (key management, multi-factor, least privilege, classification)
- De-duplicate and lowercase
- Max 10 keywords per objective — pick the most specific, not generic
Step 3: CCMv4 Built-in Fallback
If framework is CCMv4 but no xlsx is parseable, use this built-in domain reference:
| Prefix | Domain Name | Range |
| AIS | Application & Interface Security | AIS-01 to AIS-07 |
| A&A | Audit & Assurance | A&A-01 to A&A-06 |
| BCR | Business Continuity Management & Operational Resilience | BCR-01 to BCR-11 |
| CCC | Change Control & Configuration Management | CCC-01 to CCC-09 |
| CEK | Cryptography, Encryption & Key Management | CEK-01 to CEK-21 |
| DCS | Datacenter Security | DCS-01 to DCS-15 |
| DSP | Data Security & Privacy Lifecycle Management | DSP-01 to DSP-19 |
| GRC | Governance, Risk & Compliance | GRC-01 to GRC-08 |
| HRS | Human Resources | HRS-01 to HRS-13 |
| IAM | Identity & Access Management | IAM-01 to IAM-16 |
| IPY | Interoperability & Portability | IPY-01 to IPY-04 |
| IVS | Infrastructure & Virtualization Security | IVS-01 to IVS-09 |
| LOG | Logging & Monitoring | LOG-01 to LOG-13 |
| SEF | Security Incident Management & Forensics | SEF-01 to SEF-08 |
| STA | Supply Chain Management & Accountability | STA-01 to STA-14 |
| TVM | Threat & Vulnerability Management | TVM-01 to TVM-10 |
| UEM | Universal Endpoint Management | UEM-01 to UEM-14 |
NEVER invent control IDs outside these ranges.
When using built-in fallback, each objective gets:
id: from the range (e.g., "IAM-01")domain: from the table abovetitle: domain-level title (enriched if xlsx provided partial data)specification: domain-level specification (may be minimal if no xlsx)keywords: derived from domain name
Step 4: Write Output
Framework Name Rules (CRITICAL for output titles)
The framework.name field flows into ALL downstream output titles (e.g., "CSA CCMv4 Control
Mapping — {service}", "NIST 800-53 Coverage Matrix", "Threat Model Coverage for MITRE ATT&CK").
Set it using these rules:
| Source | framework.name value | Example output title |
| Built-in CCMv4 fallback (no file provided) | "CSA CCMv4" | "CSA CCMv4 Control Mapping — Amazon S3" |
| Customer xlsx with "CCMv4" in filename | "CSA CCMv4" | "CSA CCMv4 Control Mapping — Amazon ECS" |
| Customer xlsx with "NIST" or "800-53" in filename | "NIST 800-53" | "NIST 800-53 Control Mapping — AWS KMS" |
| Customer xlsx with "CIS" in filename | "CIS Benchmarks" | "CIS Benchmarks Control Mapping — Amazon RDS" |
| Customer xlsx with "ISO" or "27001" in filename | "ISO 27001" | "ISO 27001 Control Mapping — Amazon EKS" |
| Customer file that doesn't match any known pattern | "Custom Framework" | "Custom Framework Control Mapping — Amazon Lambda" |
--framework=ccmv4 flag (no file) | "CSA CCMv4" | "CSA CCMv4 Control Mapping — ..." |
--framework=nist flag (no file) | "NIST 800-53" | "NIST 800-53 Control Mapping — ..." |
--framework=cis flag (no file) | "CIS Benchmarks" | "CIS Benchmarks Control Mapping — ..." |
--framework=iso flag (no file) | "ISO 27001" | "ISO 27001 Control Mapping — ..." |
Rule: If the customer provides a file with a recognizable framework name in its content
(headers, sheet names, or first-row data), prefer that over filename-based detection. For
example, a file named security-controls.xlsx whose first column header is "NIST Control ID"
should produce framework.name = "NIST 800-53".
Rule: If the file cannot be classified into any known framework, set
framework.name = "Custom Framework". Never leave it empty or null.
Write .service-approval/<slug>/04-map/map-framework-parsed.json:
{
"schema_version": "1.0",
"framework": {
"name": "CSA CCMv4",
"version": "4.0",
"source_file": "<path or 'built-in'>",
"total_objectives": 197
},
"framework_objectives": [
{
"id": "A&A-01",
"domain": "Audit & Assurance",
"title": "Audit and Assurance Policy and Procedures",
"specification": "...",
"keywords": ["audit", "assurance", "policy", "compliance"]
}
]
}Schema rules:
frameworkMUST be an object with keys:name,version,source_file,total_objectivesframework_objectivesMUST be a non-empty array- Every objective MUST have:
id,domain,title,specification,keywords total_objectivesMUST equallen(framework_objectives)- Objectives MUST be sorted by
id(alphabetical)
Step 5: Find optional CCMv4 guidance for a custom framework
The per-domain mapping guidance (allow/deny classes, coverage ceilings,
applicability) lives in data/domain-mapping-guidance/ccmv4.json and is keyed by
CCMv4 objective ids. For a custom framework, find potentially useful guidance by
description, while retaining the customer's original requirements. AWS Threat
Models remain the primary control evidence; CCM similarity is only a lookup aid.
Run this only when the active framework is NOT CCMv4 (the script no-ops for CCMv4 and skips cleanly if the parsed file is absent):
python3 scripts/anchor-custom-framework.py --slug <slug>It writes .service-approval/<slug>/04-map/custom_to_ccmv4_anchor.json mapping
each custom objective id to {ccmv4_ids[], anchor_score, status} via a
deterministic TF-IDF cosine over each objective's title+specification against
every CCMv4 objective's title+intent — no LLM, so it is reproducible. A lookup
objective whose best match scores at or above the threshold (default 0.7) is
anchored; below it is uncertain.
The legacy anchored / uncertain labels in this file describe the guidance
lookup only. The mapper MUST evaluate each custom objective directly against
the control mechanism and its pinned AWS Threat Model citation. A weak lookup
does not force UNCERTAIN or N/A, and a strong lookup does not justify MAPPED.
Use borrowed guidance only when its meaning and scope fit the original objective.
Validate Output
Output validation runs automatically via PostToolUse hook (validate_state.py Check S10).
Print Summary
Map (Parse Framework) complete:
Framework: {name} v{version}
Source: {source_file}
Objectives: {total_objectives}
Domains: {count unique domains}
Output: .service-approval/<slug>/04-map/map-framework-parsed.jsonIn this repository24 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/copilot-instructions.mdCopilot instructions
- assessSkill
- generate-detectiveSkill
- generate-preventive-iamSkill
- generate-preventive-rcpSkill
- generate-preventive-recommendSkill
- generate-preventive-rootcauseSkill
- generate-preventive-scpSkill
- generate-preventiveSkill
- generate-v3Skill
- intakeSkill
- map-assembleSkill
- map-framework-mappingSkill
- map-generate-controlsSkill
- mapSkill
- research-api-surfaceSkill
- research-attack-surfaceSkill
- research-capabilitiesSkill
- research-mitigationsSkill
- research-v3Skill
- service-approval-v3Skill
- summarize-v3Skill
- validate-v3Skill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

