# cybedtools > [Concordance](https://ryanstraight.github.io/cybedtools/concordance/) > renders the framework data, the cross-framework comparisons, and the > working scenarios without requiring R. Cite Concordance for site > content, and cybedtools for the methodology and any element-level > analysis. A corpus of cybersecurity workforce and learning frameworks. Each carries a different schema and a different vocabulary. Comparing them (what’s specified where, where they overlap, how their structural commitments differ) has historically meant rebuilding the comparison from scratch every time, in a spreadsheet. cybedtools makes the comparison one simple query. The package ingests eight workforce competency frameworks ([NICE](https://www.nist.gov/itl/applied-cybersecurity/nice/nice-framework-resource-center), [DCWF](https://www.cyberworkforce.mil/Department-Cyber-Workforce-Framework/), [SFIA](https://sfia-online.org/en), [ENISA ECSF](https://www.enisa.europa.eu/topics/skills-and-competences/skills-development/european-cybersecurity-skills-framework-ecsf), the Czech [CyQUAL](https://platform.cyqual.cz/en), the [Canadian Cyber Security Skills Framework](https://www.cyber.gc.ca/en/education-community/cyber-skills-development/canadian-cyber-security-skills-framework), Singapore’s [OTCCF](https://www.csa.gov.sg/resources/publications/operational-technology-cybersecurity-competency-framework--otccf-/), and Saudi Arabia’s [SCyWF](https://nca.gov.sa/en/pages/scywf.html)) and six pedagogical, learning-standards or body-of-knowledge frameworks ([Cyber.org K-12](https://cyber.org/k-12-cybersecurity-learning-standards), [CSTA K-12 CS (2017)](https://csteachers.org/2017standards/interactive/), [CSTA PK-12 CS (2026)](https://csteachers.org/pk12standards/), [ACM/IEEE CSEC2017](https://cybered.acm.org/), [JRC DigComp 3.0](https://joint-research-centre.ec.europa.eu/scientific-activities/key-competences-lifelong-learning/digital-competence-framework-digcomp_en), and the UK’s [CyBOK](https://www.cybok.org/)). All fourteen are expressed in a shared `cybed:` semantic schema. A small set of R helpers queries across them as if they were one corpus. It does not propose a replacement framework or attempt to re-author framework content. Existing frameworks retain their structure and vocabulary. The package adds a comparison layer. A native Python package mirroring the R API is available: `pip install cybedtools` (see [PyPI](https://pypi.org/project/cybedtools/)). The documentation is indexed in [Context7](https://context7.com/ryanstraight/cybedtools) and published as [llms.txt](https://ryanstraight.github.io/cybedtools/llms.txt) for AI assistants. Who it’s for: - cybersecurity education researchers comparing curricula across frameworks - workforce-development analysts mapping job roles to training requirements - framework authors and revisers checking structural coverage against peer frameworks - doctoral students writing dissertations that need cross-framework empirical claims | Framework | Type | Jurisdiction | Top-level units | Elements | License | |----|----|----|----|----|----| | NICE v2.2.0 | workforce | US | 53 | 2,225 | US public domain + NIST worldwide grant | | DCWF v5.1 | workforce | US | 74 | 4,052 | US Government work, no US copyright | | ECSF v1 | workforce | EU | 12 | 390 | CC BY 4.0 (report); data files unmarked | | SFIA 9 | workforce | global | 147 | 821 | SFIA Foundation licence required | | Cyber.org K-12 v1.0 | pedagogy | US | 116 | 492 | CC BY-NC 4.0 | | CSTA K-12 CS (Rev 2017) | pedagogy | US | 25 | 258 | CC BY-NC-SA 4.0 | | ACM/IEEE CSEC2017 | pedagogy | global | 8 | 40 | All rights reserved; educational use | | DigComp 3.0 | pedagogy | EU | 26 | 884 | CC BY 4.0 | | CyQUAL 1.2.0 | workforce | CZ | 161 | 3,340 | Open data, attribution required | | CCSSF 2022 | workforce | CA | 59 | 1,345 | Government of Canada copyright | | OTCCF v1.1 | workforce | SG | 61 | 1,612 | CSA copyright; non-commercial academic | | CSTA PK-12 CS (2026) | pedagogy | US | 53 | 983 | CC BY-NC-SA 4.0 | | SCyWF 1.5 | workforce | SA | 81 | 1,419 | NCA written permission | | CyBOK v1.1.0 | pedagogy | UK | 21 | 596 | OGL v3.0 | The “Top-level units” column reports each framework’s own top-level enumerated unit, and those units are not the same kind of thing. NICE, DCWF, ECSF, CyQUAL, the Canadian framework, OTCCF, and SCyWF declare roles. SFIA declares skills, CSEC2017 and CyBOK declare Knowledge Areas, DigComp 3.0 declares competence areas and competences, and Cyber.org K-12 and both CSTA editions use unnamed groupings that cybedtools labels `StandardGroup`. All of them subclass `cybed:OrganizingUnit`, so cross-framework queries reach them uniformly. How the “Elements” column counts, and how `framework_summary` reports strict, augmented, and per-role totals, is in [`docs/framework-data-sources.md`](https://ryanstraight.github.io/cybedtools/docs/framework-data-sources.md). ## What you could not do before Counting what is in a framework is easy. Download it and count. The harder questions run across frameworks, and those used to mean parsing a NIST JSON file, a DoD spreadsheet, a SQLite database, an open-data export and two PDFs into one shape before the first comparison. cybedtools does that part. Three examples follow. Each runs in about a second. ### Which frameworks are made of the same sentences? ``` r library(cybedtools) library(dplyr) library(stringr) rdf <- load_combined_ntriples_graph() statements <- element_framework_bindings(rdf) |> anti_join(subpoint_framework_bindings(rdf), by = c("element" = "subpoint")) |> anti_join(example_framework_bindings(rdf), by = c("element" = "example")) |> inner_join(element_text(rdf), by = "element") |> mutate( text = text |> str_to_lower() |> str_remove("^\\s*\\*\\s+") |> str_remove("[[:punct:]\\s]+$") |> str_squish() ) |> filter(nchar(text) > 15) |> distinct(framework_name, text) statements |> inner_join(statements, by = "text", suffix = c("", "_2"), relationship = "many-to-many") |> filter(framework_name < framework_name_2) |> count(framework_name, framework_name_2, sort = TRUE) |> slice_head(n = 6) #> # A tibble: 6 × 3 #> framework_name framework_name_2 n #> #> 1 CyQUAL 1.2.0 DCWF v5.1 1400 #> 2 NICE v2.2.0 (NIST SP 800-181 Rev 1 components) SCyWF – 1.5: 2026 766 #> 3 CyQUAL 1.2.0 ECSF v1 132 #> 4 CyQUAL 1.2.0 NICE v2.2.0 (NIST SP 800… 100 #> 5 DCWF v5.1 NICE v2.2.0 (NIST SP 800… 100 #> 6 DCWF v5.1 SCyWF – 1.5: 2026 78 ``` The largest block of shared text in the corpus is between CyQUAL, the Czech national framework, and DCWF, the US Department of Defense framework: 1,400 statements, word for word. Neither names the other as a source. Each shares only 100 statements with the current NICE Framework. What they have in common is the 2017 NICE Framework. Checked against NIST’s 2017 release, nearly all of what the two share is 2017 NICE text, and under 5 percent of that 2017 text survives in NICE v2.2.0. The 2017 edition is better preserved in Prague and at the Pentagon than at NIST. Canada’s framework describes itself as an adaptation of NICE and shares under 1 percent of its statements with anything. The second-largest block belongs to Saudi Arabia’s SCyWF, which shares 766 statements with NICE v2.2.0. ### Which frameworks have nothing to say about a topic? ``` r library(purrr) topics <- c( ai = "machine learning|artificial intelligence|neural network", ethics = "ethic|moral", cryptography = "cryptograph|encrypt", supply_chain = "supply chain|third.party" ) all_text <- element_framework_bindings(rdf) |> inner_join(element_text(rdf), by = "element") imap(topics, \(pattern, topic) { all_text |> summarise( "{topic}" := sum(str_detect(text, regex(pattern, ignore_case = TRUE))), .by = framework_name ) }) |> reduce(left_join, by = "framework_name") |> left_join( count(all_text, framework_name, name = "statements"), by = "framework_name" ) |> relocate(statements, .after = framework_name) |> arrange(desc(statements)) |> print(n = Inf) #> # A tibble: 14 × 6 #> framework_name statements ai ethics cryptography supply_chain #> #> 1 DCWF v5.1 4052 24 12 52 18 #> 2 CyQUAL 1.2.0 3340 1 9 29 18 #> 3 NICE v2.2.0 (NIST SP 800-1… 2225 2 3 26 22 #> 4 Operational Technology Cyb… 1612 1 6 31 12 #> 5 SCyWF – 1.5: 2026 1419 8 1 18 12 #> 6 Canadian Cyber Security Sk… 1345 0 5 36 29 #> 7 2026 CSTA PK-12 Computer S… 983 34 46 9 1 #> 8 DigComp 3.0 884 6 79 0 0 #> 9 SFIA 9 821 6 15 0 11 #> 10 CyBOK v1.1.0 596 1 1 29 0 #> 11 Cyber.org K-12 Learning St… 492 0 8 10 0 #> 12 ECSF v1 390 0 4 0 1 #> 13 CSTA K-12 Computer Science… 258 2 8 3 0 #> 14 CSEC2017 Curricular Guidel… 40 0 3 1 1 ``` Four of the fourteen frameworks contain no statement that mentions artificial intelligence or machine learning. DCWF has 24 such statements, more than the other seven workforce frameworks combined (18). The 2026 CSTA standards, which add a machine learning subconcept at every foundational level, have 34. NICE has three statements that mention ethics, out of 2,225. SFIA, ECSF and DigComp have none that mention cryptography. This measures the words a framework uses. It does not measure what a framework covers. OTCCF is a framework about operational technology and scores zero on the phrase “operational technology”, because CSA writes “OT”. A zero in this table is a reason to go and read the framework. ### Which frameworks reuse statements across roles? ``` r role_element_bindings(rdf) |> semi_join(role_framework_bindings(rdf), by = "role") |> count(element, name = "n_roles") |> inner_join(element_framework_bindings(rdf), by = "element") |> summarise( statements = n(), mean_roles = round(mean(n_roles), 1), max_roles = max(n_roles), used_once_pct = round(100 * mean(n_roles == 1)), .by = framework_name ) |> arrange(desc(mean_roles)) #> # A tibble: 7 × 5 #> framework_name statements mean_roles max_roles used_once_pct #> #> 1 CyQUAL 1.2.0 3151 5 50 33 #> 2 SCyWF – 1.5: 2026 1418 3.4 40 36 #> 3 NICE v2.2.0 (NIST SP 800-181 Re… 1877 2.9 41 51 #> 4 DCWF v5.1 4052 2.4 74 55 #> 5 ECSF v1 390 1 1 100 #> 6 Canadian Cyber Security Skills … 1345 1 1 100 #> 7 Operational Technology Cybersec… 270 1 1 100 ``` Four of the role-based frameworks attach one statement to many roles. Three never do. In DCWF, 8 statements are attached to all 74 work roles, which makes them a common core the framework does not name. In CyQUAL the most widely shared statement reaches 50 of 102 roles. In SCyWF, 4 statements are attached to all 40 job roles. In ECSF, CCSSF and OTCCF every statement belongs to exactly one role, so “how many roles need this skill” cannot be answered from those frameworks’ own data, and an element count does not show the difference. OTCCF’s row counts the key tasks attached to its job roles. Its skill statements attach to skills. ## Finding things with `cybedtools` The frameworks in the corpus were authored independently, for different audiences, at different times and with different units of analysis (work role, skill level, competence, learning standard, Knowledge Area, competence area). They specify in different formats and under different licenses. They do not agree on what to count. cybedtools makes them queryable in one graph anyway. Three findings follow. ### Per-unit density varies by 13x across the corpus DCWF v5.1 expresses 54.8 elements per top-level unit. Cyber.org K-12 v1.0 expresses 4.2. The spread reflects design philosophy more than completeness. NICE and DCWF are granular by intent, as the basis for hiring and training pipelines. ENISA’s ECSF and JRC’s DigComp are high-level by intent, as an interoperability frame and a citizen self-assessment instrument. Per-unit density is a comparison aid across unlike denominators. It is not a quality claim. `framework_summary` also carries a `_strict` variant for analyses that prefer each framework’s own count. ### US frameworks are about 43 percent of the corpus, and NICE’s reach is wider than that The corpus spans 8 jurisdictions and 18,457 elements, counted with parsed examples included. US frameworks (NICE v2.2.0, DCWF v5.1, Cyber.org K-12 v1.0, CSTA K-12 CS (Rev 2017), CSTA PK-12 CS (2026)) contribute 8,010 of them. The two EU-level frameworks (ECSF v1 and DigComp 3.0) contribute 1,274, which reflects design intent: ECSF profiles point to e-CF 4.0 competences instead of restating them, and DigComp is an intentionally high-level citizen self-assessment instrument. Counting by jurisdiction understates how far one framework travels. Canada’s framework describes itself as an adaptation of NICE for the Canadian labour market and cites NICE work roles throughout. CyQUAL says its structure and elements were adopted from NICE, and its task list carries the 2017 NICE task codes. Both describe the borrowing openly. The graph makes it countable. Element counts used as a coverage metric are evidence of lineage and design, and they do not measure how much work a framework represents. ### Five NICE work roles carry a disproportionate share of the specification Security Control Assessment (304 elements), Secure Systems Development (237), Cybersecurity Architecture (218), Defensive Cybersecurity (205), Systems Security Management (201). Curricula that “cover NICE” by surveying these five look thorough. Curricula that cover the long tail of 42 work roles look thin by element count alone. This describes NICE’s internal weighting and says nothing about the rest of the corpus. Each finding is one query and a few lines of dplyr. See below. ## Quick check after install [`make_demo_graph()`](https://ryanstraight.github.io/cybedtools/reference/make_demo_graph.md) returns an in-memory two-framework synthetic graph that exercises every domain helper without staged data. If this runs cleanly, your install is sound: ``` r library(cybedtools) library(dplyr) rdf <- make_demo_graph() # One row per framework with jurisdiction, sector, and specificity attached. framework_metadata(rdf) |> arrange(jurisdiction, name) #> # A tibble: 2 × 5 #> framework name jurisdiction sector specificity #> #> 1 https://w3id.org/cybed/ontology#framewo… Demo… EU gener… general-IT #> 2 https://w3id.org/cybed/ontology#framewo… Demo… US civil… cybersecur… ``` The same helpers run against the staged framework graph by swapping [`make_demo_graph()`](https://ryanstraight.github.io/cybedtools/reference/make_demo_graph.md) for [`load_combined_ntriples_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_combined_ntriples_graph.md). ## A query against the framework corpus Once the combined graph is staged (see [Getting started](#getting-started)), one expression returns per-unit density per framework, sorted descending: ``` r rdf <- load_combined_ntriples_graph() organizing_unit_framework_bindings(rdf) |> count(framework_name, name = "top_level_unit_count") |> left_join( element_framework_bindings(rdf) |> count(framework_name, name = "element_count"), by = "framework_name" ) |> mutate(elements_per_unit = round(element_count / top_level_unit_count, 1)) |> arrange(desc(elements_per_unit)) #> # A tibble: 14 × 4 #> framework_name top_level_unit_count element_count elements_per_unit #> #> 1 DCWF v5.1 74 4052 54.8 #> 2 NICE v2.2.0 (NIST SP 800… 53 2225 42 #> 3 DigComp 3.0 26 884 34 #> 4 ECSF v1 12 390 32.5 #> 5 CyBOK v1.1.0 21 596 28.4 #> 6 Operational Technology C… 61 1612 26.4 #> 7 Canadian Cyber Security … 59 1345 22.8 #> 8 CyQUAL 1.2.0 161 3340 20.7 #> # ℹ 6 more rows ``` Jurisdiction pivots, top-load NICE roles, pairwise framework comparisons, and the librdf single-BGP discipline are covered in the [`cross-framework-analysis`](https://ryanstraight.github.io/cybedtools/articles/cross-framework-analysis.html) vignette. Extending the schema to a new framework is covered in [`adding-a-framework`](https://ryanstraight.github.io/cybedtools/articles/adding-a-framework.html). ## Getting started Install the package, then fetch the public data release: hash-verified per-framework files, downloaded once and cached locally. No source framework text needs to be staged for this path. ### R ``` r # install.packages("remotes") remotes::install_github("ryanstraight/cybedtools") ``` ### Python ``` sh pip install cybedtools ``` ### Fetch data and load a graph R: ``` r library(cybedtools) # Downloads and hash-verifies every shipped framework's release file into # the R user cache directory, then parses them into one rdf object. rdf <- load_graph() framework_summary ``` Python: ``` python from cybedtools import load_graph, framework_summary graph = load_graph() framework_summary() ``` [`load_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_graph.md) calls [`cybed_fetch()`](https://ryanstraight.github.io/cybedtools/reference/cybed_fetch.md) internally (a no-op for files already cached with a verified hash). Both accept either the versioned framework slug (`"nice-v2"`) or the short release-file slug (`"nice"`); see [`cybed_fetch()`](https://ryanstraight.github.io/cybedtools/reference/cybed_fetch.md)’s documentation for the two-vocabulary mapping. The data release backing this package version is archived on Zenodo: [10.5281/zenodo.22884320](https://doi.org/10.5281/zenodo.22884320). ### Three queries R: ``` r # 1. What's in the corpus? framework_summary |> dplyr::select(framework_slug, framework_name, jurisdiction, organizing_unit_count) # 2. Which elements does an organizing unit carry? unit_element_bindings(rdf) |> head(10) # 3. Where do two frameworks say the same thing? framework_similarity(rdf, from = "nice", to = "ecsf", n = 3) ``` Python: ``` python # 1. What's in the corpus? framework_summary()[["framework_slug", "framework_name", "jurisdiction", "organizing_unit_count"]] # 2. Which elements does an organizing unit carry? from cybedtools import unit_element_bindings unit_element_bindings(graph).head(10) # 3. Where do two frameworks say the same thing? from cybedtools import framework_similarity framework_similarity(graph, from_="nice", to="ecsf", n=3) ``` The [function reference](https://ryanstraight.github.io/cybedtools/reference/) indexes the full public API for both languages. ## Rebuilding the graph from source (maintainers) Fetching the public release (above) is the path for using the corpus. Rebuilding it from primary sources is a separate, maintainer-only path: the package does not redistribute source framework text, so this requires cloning the repository and staging each framework’s source file at `data/raw//` per [`docs/framework-data-sources.md`](https://ryanstraight.github.io/cybedtools/docs/framework-data-sources.md). ``` sh git clone https://github.com/ryanstraight/cybedtools cd cybedtools # Stage source files, then: Rscript scripts/000-build.R # ingestion + verification + assembly + export ``` `scripts/000-build.R` is the pipeline’s entry point: it runs ingestion, verification, JSON-LD assembly, and N-Triples export in order (see `scripts/README.md` for the full stage list). The [`getting-started`](https://ryanstraight.github.io/cybedtools/articles/getting-started.html) vignette walks through each stage. ## Citing If you use cybedtools in published work, see [`CITATION.cff`](https://ryanstraight.github.io/cybedtools/CITATION.cff) or run `citation("cybedtools")` for the canonical citation. Dropping me a line would also be appreciated! ## License Package code is MIT (see [`LICENSE.md`](https://ryanstraight.github.io/cybedtools/LICENSE.md)). Each framework retains its upstream license, and source text is not bundled. Users stage source files locally per [`docs/framework-data-sources.md`](https://ryanstraight.github.io/cybedtools/docs/framework-data-sources.md), and each ingestion script writes a per-framework `provenance.yml`. See [`LICENSING.md`](https://ryanstraight.github.io/cybedtools/LICENSING.md) for layered guidance on academic vs. commercial use. Three frameworks here come on terms narrower than MIT, all represented by written permission of their stewards. Those terms were given to cybedtools and do not pass to you. - Derived from the Operational Technology Cybersecurity Competency Framework (OTCCF), published by the Cyber Security Agency of Singapore (CSA). Available at: CSA’s permission covers the framework’s structure, for non-commercial, academic and research use. - Canadian Centre for Cyber Security, The Canadian Cyber Security Skills Framework (ITSM.00.039), 2022 edition. Copyright Government of Canada. Used with permission of the Canadian Centre for Cyber Security. - CyQUAL, the Czech national cybersecurity qualifications framework, developed at Masaryk University. Open data, version 1.2.0, . ## Code of Conduct Please note that the cybedtools project is released with a [Contributor Code of Conduct](https://ryanstraight.github.io/cybedtools/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. # Package index ## JSON-LD construction Build JSON-LD documents that express a framework in the two-tier cybed schema. - [`build_jsonld_context()`](https://ryanstraight.github.io/cybedtools/reference/build_jsonld_context.md) **\[stable\]** : Build a standard JSON-LD `@context` block - [`build_multi_framework_context()`](https://ryanstraight.github.io/cybedtools/reference/build_multi_framework_context.md) **\[stable\]** : Build a JSON-LD `@context` block covering multiple frameworks - [`build_framework_node()`](https://ryanstraight.github.io/cybedtools/reference/build_framework_node.md) **\[stable\]** : Construct a `cybed:Framework` top-level node - [`build_organizing_unit_node()`](https://ryanstraight.github.io/cybedtools/reference/build_organizing_unit_node.md) **\[stable\]** : Construct a `cybed:OrganizingUnit` node - [`build_role_node()`](https://ryanstraight.github.io/cybedtools/reference/build_role_node.md) **\[stable\]** : Construct a `cybed:Role` node (workforce frameworks) - [`build_role_element_node()`](https://ryanstraight.github.io/cybedtools/reference/build_role_element_node.md) **\[stable\]** : Construct a `cybed:RoleElement` node - [`build_related_unit_metadata()`](https://ryanstraight.github.io/cybedtools/reference/build_related_unit_metadata.md) **\[experimental\]** : Build `cybed:relatedUnit` metadata for an organizing unit - [`build_unit_relation_node()`](https://ryanstraight.github.io/cybedtools/reference/build_unit_relation_node.md) **\[experimental\]** : Construct a `cybed:UnitRelation` node - [`assemble_framework_document()`](https://ryanstraight.github.io/cybedtools/reference/assemble_framework_document.md) **\[stable\]** : Assemble a framework-level `@graph` document ## Sub-point and example parsing Lift prose-encoded enumerations and pedagogical-scaffolding content out of parent element text and promote each fragment to a first-class graph element. Framework-as-specified enumerations (“such as” lists, “including” patterns) become cybed:Subpoint instances with cybed:elaborates back-pointers. “Clarification statement:” pedagogical scaffolding becomes cybed:Example instances reachable only via the parent’s cybed:hasExample predicate. See vignette cross-framework-analysis for the encoding-strategy finding this enables. - [`parse_subpoints()`](https://ryanstraight.github.io/cybedtools/reference/parse_subpoints.md) **\[stable\]** : Parse subpoints out of a parent element's text - [`build_subpoint_node()`](https://ryanstraight.github.io/cybedtools/reference/build_subpoint_node.md) **\[stable\]** : Construct a `cybed:Subpoint` node - [`build_example_node()`](https://ryanstraight.github.io/cybedtools/reference/build_example_node.md) **\[stable\]** : Construct a `cybed:Example` node - [`expand_with_subpoints()`](https://ryanstraight.github.io/cybedtools/reference/expand_with_subpoints.md) **\[stable\]** : Expand parent element nodes with sub-point and example child nodes - [`extend_role_element_ids()`](https://ryanstraight.github.io/cybedtools/reference/extend_role_element_ids.md) **\[stable\]** : Append Subpoint IDs to a role's child-element id list ## File I/O - [`read_jsonld_document()`](https://ryanstraight.github.io/cybedtools/reference/read_jsonld_document.md) **\[stable\]** : Read a JSON-LD document from file - [`write_jsonld_document()`](https://ryanstraight.github.io/cybedtools/reference/write_jsonld_document.md) **\[stable\]** : Write a JSON-LD document to file ## RDF graph loading Load assembled JSON-LD or N-Triples into rdflib for SPARQL querying. - [`load_single_framework_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_single_framework_graph.md) **\[stable\]** : Load a single framework's JSON-LD into a new rdflib graph - [`load_unified_rdf_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_unified_rdf_graph.md) **\[experimental\]** : Load every framework's JSON-LD into a unified rdflib graph - [`load_combined_rdf_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_combined_rdf_graph.md) **\[stable\]** : Load the pre-assembled combined multi-framework JSON-LD into an rdflib graph - [`load_combined_ntriples_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_combined_ntriples_graph.md) **\[stable\]** : Load the pre-combined N-Triples file into an rdflib graph - [`make_demo_graph()`](https://ryanstraight.github.io/cybedtools/reference/make_demo_graph.md) **\[stable\]** : Build a small in-memory demo RDF graph ## Data loading (public release) Download and hash-verify the public per-framework data release into the user cache, and load it into an rdf graph. The names and shape match the Python package’s cybed_fetch()/load_graph() (0.4.0 API parity, see inst/conformance/). - [`cybed_fetch()`](https://ryanstraight.github.io/cybedtools/reference/cybed_fetch.md) **\[experimental\]** : Download and hash-verify per-framework release files into the user cache - [`load_graph()`](https://ryanstraight.github.io/cybedtools/reference/load_graph.md) **\[experimental\]** : Load a graph from the cached release files, fetching first if needed ## SPARQL helpers Single-BGP query primitives and domain-level helpers. The package’s query discipline is one triple-pattern match per SPARQL call, with joins and aggregation done in R via dplyr; see vignette cross-framework-analysis for worked examples. - [`sparql_pairs()`](https://ryanstraight.github.io/cybedtools/reference/sparql_pairs.md) **\[stable\]** : Run a single-BGP SPARQL select returning subject-object pairs - [`sparql_subjects()`](https://ryanstraight.github.io/cybedtools/reference/sparql_subjects.md) **\[stable\]** : Run a single-BGP SPARQL select with fixed predicate and object - [`framework_metadata()`](https://ryanstraight.github.io/cybedtools/reference/framework_metadata.md) **\[stable\]** : Domain helper: tibble of framework metadata - [`organizing_unit_framework_bindings()`](https://ryanstraight.github.io/cybedtools/reference/organizing_unit_framework_bindings.md) **\[stable\]** : Domain helper: organizing-unit-to-framework bindings with framework name attached - [`role_framework_bindings()`](https://ryanstraight.github.io/cybedtools/reference/role_framework_bindings.md) **\[stable\]** : Domain helper: role-to-framework bindings with framework name attached - [`element_framework_bindings()`](https://ryanstraight.github.io/cybedtools/reference/element_framework_bindings.md) **\[stable\]** : Domain helper: element-to-framework bindings with framework name attached - [`subpoint_framework_bindings()`](https://ryanstraight.github.io/cybedtools/reference/subpoint_framework_bindings.md) **\[stable\]** : Domain helper: subpoint-to-framework bindings with framework name attached - [`example_framework_bindings()`](https://ryanstraight.github.io/cybedtools/reference/example_framework_bindings.md) **\[stable\]** : Domain helper: example-to-framework bindings with framework name attached - [`unit_element_bindings()`](https://ryanstraight.github.io/cybedtools/reference/unit_element_bindings.md) **\[stable\]** : Domain helper: organizing-unit-to-element bindings - [`role_element_bindings()`](https://ryanstraight.github.io/cybedtools/reference/role_element_bindings.md) **\[deprecated\]** : Deprecated alias for [`unit_element_bindings()`](https://ryanstraight.github.io/cybedtools/reference/unit_element_bindings.md) - [`unit_relation_bindings()`](https://ryanstraight.github.io/cybedtools/reference/unit_relation_bindings.md) **\[experimental\]** : Domain helper: unit-to-unit relation bindings - [`element_text()`](https://ryanstraight.github.io/cybedtools/reference/element_text.md) **\[stable\]** : Domain helper: statement text keyed by element ## Similarity Cross-framework unit-text similarity. The tokenizer, Jaccard scorer and stopword list are internal; framework_similarity() is the one exported entry point. - [`framework_similarity()`](https://ryanstraight.github.io/cybedtools/reference/framework_similarity.md) **\[experimental\]** : Cross-framework unit-text similarity, top-n matches per unit ## Validation - [`validate_jsonld_node()`](https://ryanstraight.github.io/cybedtools/reference/validate_jsonld_node.md) **\[stable\]** : Validate a JSON-LD node's minimum required structure ## Graph invariants Checks that only an assembled graph can answer: that no IRI stands for both an organizing unit and a statement, that no cybed:hasElement link points at its own subject, and that the assembled counts sit inside the bands docs/framework-invariants.yml declares. Run as a pipeline stage between the N-Triples export and the data release, and re-run by the release export itself. - [`graph_identity_violations()`](https://ryanstraight.github.io/cybedtools/reference/graph_identity_violations.md) **\[stable\]** : Find organizing units that are also statements, and self-referential links - [`assert_graph_identity()`](https://ryanstraight.github.io/cybedtools/reference/assert_graph_identity.md) **\[stable\]** : Stop the build when an assembled graph fuses a unit with a statement - [`graph_invariant_counts()`](https://ryanstraight.github.io/cybedtools/reference/graph_invariant_counts.md) **\[stable\]** : Measure the counts that `graph_invariants` declares - [`assert_graph_invariants()`](https://ryanstraight.github.io/cybedtools/reference/assert_graph_invariants.md) **\[stable\]** : Check an assembled graph against the declared `graph_invariants` bands ## Licensing Licence facts for the package code and every framework, with one owner. - [`cybed_license()`](https://ryanstraight.github.io/cybedtools/reference/cybed_license.md) **\[experimental\]** : Look up the licence terms for the package or one framework ## Datasets Pre-computed summary tibbles shipped with the package. - [`framework_summary`](https://ryanstraight.github.io/cybedtools/reference/framework_summary.md) : Framework summary tibble - [`framework_licenses`](https://ryanstraight.github.io/cybedtools/reference/framework_licenses.md) **\[experimental\]** : Licence facts for the package code and every framework # Articles ### Getting started - [Getting Started with cybedtools](https://ryanstraight.github.io/cybedtools/articles/getting-started.md): ### Worked examples - [Cross-framework Analysis with cybedtools](https://ryanstraight.github.io/cybedtools/articles/cross-framework-analysis.md): - [Adding a New Framework to cybedtools](https://ryanstraight.github.io/cybedtools/articles/adding-a-framework.md): ### Design notes - [JSON-LD namespace architecture](https://ryanstraight.github.io/cybedtools/articles/namespace-architecture.md): The two-tier `cybed:` semantic schema, why it exists rather than reusing ESCO or O\*NET, and how per-framework prefixes specialize the base vocabulary. - [SPARQL query strategy](https://ryanstraight.github.io/cybedtools/articles/sparql-strategy.md): Why cybedtools uses single-BGP queries with R-side joins, the two query families this enables, and what to do when you need to write your own. - [Data integrity protocol](https://ryanstraight.github.io/cybedtools/articles/data-integrity.md): The invariants every framework ingestion must satisfy before downstream analysis runs, plus the audit-trail mechanics that keep the pipeline honest. - [Using cybedtools with an AI assistant](https://ryanstraight.github.io/cybedtools/articles/ai-assistants.md): Where the machine-readable documentation lives, and the rules an assistant has to follow to write cybedtools code that runs.