Skip to content
🚧 Early alpha — building the foundation. See the roadmap →

URM ingestion readiness — the per-framework checklist

Created Updated

Per the 2026-06-02 decision: format decides ingestability, not framework. So the checklist sorts by distance from the floor, not by framework importance:

  1. ✅ Ingested — through the production render() already
  2. 🟢 Ready now — structured file held + reader exists; only a recipe is missing
  3. 🟡 Needs the JSON reader — structured file held; the planned iterator-path reader unblocks it
  4. 🟠 Needs a new adapter — structured (YAML / XML) but no reader branch exists
  5. 🔴 Below the floor — prose PDF/HTML; needs a bridge step or the STRM proxy

Reader capability today (what can parse what)

Section titled “Reader capability today (what can parse what)”
SurfaceFormatsNotes
Plugin wizard (Obsidian)CSV · XLSX · JSON✅ XLSX (sheet picker + header row) and JSON (iterator + row filter) wired 2026-06-12 — same logic as the harness readers
Plugin SSSOM importerSSSOM TSVdedicated modal + importSssom(); bundled fixtures one-click
Headless harness (tools/generate-fixtures.ts)CSV · XLSX--sheet / --header-row / header-key normalization; recipe-driven via real render()
OLIR crosswalk tool (tools/crosswalk-from-olir.ts)XLSX (OLIR layout)→ crosswalk-edge notes + SSSOM TSV artifact
Harness JSON readerJSON (nested)✅ built 2026-06-12 — --iterator '$.objects[*]' + --where 'type=attack-pattern,revoked!=true' (dev log §JSON reader); smoke-verified on ATT&CK STIX (697) + CPRT CSF (185)
YAML / XML reader—nothing; lower priority (YAML is a thin branch once the JSON iterator exists)

1 — ✅ Ingested (through the production engine)

Section titled “1 — ✅ Ingested (through the production engine)”
Framework / edgeSource heldRecipeResultCaveats
NIST 800-53 r5CSV (NIST_SP-800-53_rev5_catalog_load.csv)recipes/import/nist-800-53-flat.json1,189 notes 🟢 commit-safeID padding resolved 2026-06-12 — --depad canonicalizes edge-side ids; wikilinks live
NIST CSF 2.0XLSX (csf2.xlsx, sheet “CSF 2.0”, header row 1)recipes/import/nist-csf-2.json (split filters)185 subcategories 🟢hierarchy columns need forward-fill; one [Withdrawn title parse artifact (DE.AE-01)
CRI Profile v2.2XLSX (structure sheet, header row 2)recipes/import/cri-profile-v2-2.json472 notes (F·C·S·DS) 🔴 FI-only, localsector: financial-services stamped; never treat as general-purpose
CSF 2.0 → 800-53 edgesXLSX (NIST OLIR crosswalk)crosswalk-edge.json via OLIR tool740 edges 🟢 + SSSOM TSVall intersects_with (source has no rel-type)
CRI → 800-53 edgesXLSX (OLIR ×20 family sheets)same1,039 edges 🔴 local803/1,842 rows skipped (per-sheet banner rows — still open); direction snag resolved 2026-06-12
CSF 2.0 → CRI edges (2026-06-12)CRI workbook’s “NIST CSF v2 Mapping” sheet — OLIR-shaped, --header-row 3 + column aliasessame154 edges, 0 skipped 🔴 local — completes the proving-ground triangle49 exact · 92 narrower (CSF ⊂ CRI) · 13 related; directions corrected 2026-06-12

2 — 🟢 Ready now (file + reader exist; write the recipe)

Section titled “2 — 🟢 Ready now (file + reader exist; write the recipe)”
FrameworkFile heldReaderWhat’s neededLicense
CIS Controls v8.1.2CIS_Controls_Version_8.1.2___March_2025.xlsxharness XLSX✅ ingested 2026-06-12 — recipes/import/cis-controls-v8.json → 153 safeguards (official count; IG1-3 in frontmatter; the “4.10-stored-as-4.1” Excel trap cured via formatted-text reads)🟡 CC BY-NC-SA — local
SCF 2026.1.1Secure.Controls.Framework.SCF.-.2026.1.1.xlsx (+ scf-extracted/)harness XLSX✅ nodes + hub edges 2026-06-12 — scf-2026-flat.json → 1,468 controls, and tools/crosswalk-from-melt.ts melted 7 mapping columns → 5,675 edges (the STRM proxy hub for §5 is LIVE)🟡 CC BY-ND — local
MITRE ATT&CK (techniques)enterprise-attack-v16.1.xlsx (also v15.1)harness XLSXsuperseded — STIX JSON path smoke-verified instead (§3)🟢 attribute
FedRAMP baselinesFedRAMP_Security_Controls_Baseline.xlsxharness XLSXrecipe🟢 public
PCI DSS v4.0.1 (requirements)Prioritized-Approach-Tool-For-PCI-DSS-v4_0_1.xlsx — a structured door despite PDF-first publishingharness XLSXrecipe🔴 PCI SSC — local
SOC 2 / TSC (criteria list)2017-tsc-mapping-to-gdpr.xlsx — partial structured door (criteria IDs + text)harness XLSXrecipe; verify coverage vs the PDF🔴 AICPA — local
CRI → CSF edges”NIST CSF v2 Mapping” sheet in the CRI workbookOLIR tool + --header-row 3 + column aliases✅ extracted 2026-06-12 — turned out OLIR-shaped, no new extractor needed → 154 edges (§1)🔴 FI, local
CTID / D3FEND mapping packs (edges)cri_profile-v2.1_attack-16.1-enterprise.csv · csa_ccm-4.1_attack-17.1-enterprise.csv · nist_800_53-rev5_attack-14.1-enterprise.xlsx · NISTCSF_MITRE.csv · d3fend*.csv · att&ck_to_d3fend.csv · Att&ckToCveMappings.csvharness CSV/XLSXper-pack crosswalk adapters — every mapping pack has its own column layout (known: “crosswalk files vary wildly”)🟢 mostly attribute

3 — 🟡 JSON sources (reader ✅ built 2026-06-12 — recipes remain)

Section titled “3 — 🟡 JSON sources (reader ✅ built 2026-06-12 — recipes remain)”

The logical-source + iterator reader landed (--iterator + --where, dev log) — these ~39 JSON files now only need recipes, same as §2:

SourceFile heldIteratorStatus
MITRE ATT&CK STIXenterprise-attack.json + *_stix.json packs$.objects[*] + --where type=attack-pattern,revoked!=true,x_mitre_deprecated!=true✅ smoke-verified — 697 techniques via recipes/import/mitre-attack-technique.json
NIST CPRT CSF 2.0 exportcprt_CSF_2_0_0_06-01-2026.json$.response.elements.elements[*] + --where element_type=subcategory✅ smoke-verified — 185 subcategories; cleaner than csf2.xlsx (pre-split id/text; no [Withdrawn artifact) — candidate to replace the XLSX CSF path
OSCAL catalogs (800-53; 800-171 on get-list)OSCAL-derived XLSX held; raw OSCAL JSON via usnistgov/oscal-content$.catalog.groups[*].controls[*]recipe needed
ATT&CK Navigator layers*_navigator_layer.json (azure, gcp, cri, csa…)$.techniques[*]recipe needed (edge-shaped)
D3FEND JSONd3fend.json, d3fend-full-mappings.jsontbd — inspectrecipe needed

4 — 🟠 Needs a new adapter (YAML / XML)

Section titled “4 — 🟠 Needs a new adapter (YAML / XML)”
SourceFile heldAdapter needed
MITRE ATLASATLAS-2026.05.yamlYAML branch in readSource() (trivial once JSON reader exists — same iterator idea)
CTID YAML packs*_attack-*.yamlsame
DORA (EU 2022/2554)cellar_*.xml (EUR-Lex Formex)XML adapter or one-off Formex → JSON pre-convert
SEC cyber disclosure ruleSEC-cyber-disclosure-*.xmlsame as DORA

5 — 🔴 Below the floor (prose; bridge or proxy)

Section titled “5 — 🔴 Below the floor (prose; bridge or proxy)”

These have no record structure — per the input floor, they need a bridge step or the STRM proxy (SCF’s published mappings reach into copyrighted frameworks without their text):

FrameworkWhat we holdDecided / likely path
ISO/IEC 27001:2022PDF only✅ STRM proxy live 2026-06-12 — scf-to-iso-27001 (316 edges) + scf-to-iso-27002 (506); ISO ids only, zero ISO prose
SOC 2 / TSC (full text)PDF✅ STRM proxy live 2026-06-12 — scf-to-aicpa-tsc (1,478 edges, incl. points-of-focus); never commit AICPA text
HIPAA Security RuleHTML/PDF (law)LLM extraction of the rule structure (§164.xxx) — public domain, commit-safe
NYDFS 500HTML/PDF (law)same — section-structured law text extracts well
FFIEC booklets / CATPDF/HTMLextraction; CAT legacy has tabular appendices worth checking first
CMMCPDFcheck for assessment-guide XLSX before building extraction
~102 corpus PDFs (general)PDFtriage rule from 06-02 stands: has a structured door elsewhere → use it; prose-only → defer

Cross-cutting correctness snags (gate trust, not ingestion)

Section titled “Cross-cutting correctness snags (gate trust, not ingestion)”
SnagAffectsStatus
SKOS→STRM direction inversion (broadMatch → is_broader_than)all directional CRI edges⚠️ open — resolve before trusting direction; counts unaffected
803 skipped CRI→800-53 rows (per-sheet banner headers)CRI edge completenessopen — per-sheet header detection in the OLIR tool
ID padding (AC-2 vs AC-02) + duplicate fixture notescrosswalk-edge → concept wikilinks (dead scheme: links in Bases)open — known ETL normalization step
Merged-cell forward-fillCSF/CRI hierarchy columns blank on child rowsopen — the named forward-fill primitive
[Withdrawn title artifact (DE.AE-01)CSF note qualitynew — withdrawn-row handling in the CSF recipe
  1. ✅ JSON reader — done 2026-06-12 (--iterator + --where; ATT&CK + CPRT smoke-verified)
  2. ✅ CIS v8.1.2 + SCF recipes — done 2026-06-12 (153 safeguards + 1,468 SCF controls into _licensed/; the melt extractor landed same-day — see item 5)
  3. ✅ CRI → CSF extractor — done 2026-06-12 (the mapping sheet was OLIR-shaped; 154 edges via --header-row + column aliases; triangle complete)
  4. ✅ Direction snag + padding fix — done 2026-06-12. (a) SKOS→STRM map was inverted (a real bug, not a convention) — flipped in src/import/sssom-importer.ts + the tool mirror, pinned by a unit test, all 3 edge sets regenerated; committed SSSOM TSVs unaffected (SKOS is the wire format). (b) --depad canonicalizes OLIR’s AC-01 → AC-1; --subject-note-folder/--object-note-folder emit folder-qualified subject_note/object_note wikilinks → 7,732 links, 99.5% resolve. CSF function/category notes back-filled from CPRT (nist-csf-2-cprt.json) to catch hierarchy-level mappings. Residual 16 unresolved ids are genuinely-absent concepts: 3 family-level 800-53 refs, IA-13 (r5.1.1, newer than our source), and ~11 CRI v2.2 extension ids masquerading as CSF ids (EX, GV.AU-*, GV.RM-08/09, PR.PS-07) — do not stub these as CSF notes
  5. CTID mapping-pack adapters (threat→control edges; feeds the Control lens)
  6. ✅ SCF mapping-column melt — done 2026-06-12: tools/crosswalk-from-melt.ts → 5,675 edges / 7 frameworks in one pass; ISO + SOC 2 + PCI now reachable as STRM-proxy edges (§5 mostly retired). PCI also got proxy edges (1,218), supplementing the §2 structured door
  7. ✅ Wizard XLSX + JSON wiring — done 2026-06-12 (UI parity audit gap #1): sheet picker + header-row offset (XLSX), iterator + row-filter inputs (JSON); shared JSON core moved into src/, harness imports it
  8. §4 YAML/XML, then remaining §5 extractions (HIPAA/GDPR/COBIT columns are one more --melt arg each), as demand pulls