The two-tier vocabulary
How cybedtools represents heterogeneous frameworks in a single graph
The design problem
Eight frameworks. Each one was authored against a different theory of what counts as a structural element. NICE has work roles, tasks, knowledge statements, and skill statements. DigComp has competence areas and proficiency levels. SFIA has skills and seven levels of responsibility. Cyber.org K-12 has grade-band-by-sub-concept cells plus prose clarification statements. CSTA has level-by-concept cells plus practices. CSEC2017 has eight knowledge areas. ECSF has twelve profiles. DCWF aligns to NICE work roles with overlap.
A single shared vocabulary that flattens these into one type hierarchy would erase the differences each framework was designed to express. A pure per-framework vocabulary with no shared terms would make cross-framework queries impossible. The schema has to preserve native vocabulary and enable shared queries at the same time.
The two-tier solution
A graph in 30 seconds. A graph is nodes connected by labeled edges. A query asks “find every node where these edges hold.” That is enough to read the diagram below. The technical names beneath each box show what the same graph looks like as RDF, but you do not need to know RDF or SPARQL to follow the structure.
cybedtools uses a two-tier RDF vocabulary.
Tier 1: cybed: cross-framework abstract terms
Every framework asserts these. They define the joinable surface for cross-framework queries.
Tier 2: per-framework subtypes
Each framework defines its own vocabulary that subclasses the cybed: abstracts. These preserve the framework’s native terminology.
The two-tier shape lets a researcher write one SPARQL query that runs across the entire corpus at the Tier 1 surface, without losing the ability to ask framework-specific questions through Tier 2 subtypes.
Tier 1 vocabulary
| Term | Type | Description |
|---|---|---|
cybed:Framework |
Class | The framework as a whole |
cybed:OrganizingUnit |
Class (subClassOf skos:Concept) |
Any top-level enumerated unit. All frameworks in the corpus assert this on their parents. |
cybed:Role |
Class (subClassOf cybed:OrganizingUnit) |
Workforce-restricted. NICE work roles, DCWF work roles, ECSF profiles only. |
cybed:RoleElement |
Class | Anything attached to an organizing unit via cybed:hasElement |
cybed:Subpoint |
Class (subClassOf cybed:RoleElement) |
Bullet points and enumerations embedded inside an element’s text |
cybed:Example |
Class (subClassOf cybed:RoleElement) |
Pedagogical scaffolding (such as clarification statements). Reachable only via cybed:hasExample |
cybed:hasOrganizingUnit |
Property | Framework → organizing unit |
cybed:hasRole |
Property | Framework → role (workforce subset) |
cybed:hasElement |
Property | Organizing unit → RoleElement (excluding Examples by default) |
cybed:hasExample |
Property | Organizing unit → Example (separate predicate) |
cybed:elaborates |
Property | Subpoint → parent (back-edge) |
Tier 2 vocabulary (per-framework subtypes)
Each framework declares its own per-framework namespace and subclasses the Tier 1 abstracts:
| Framework | Namespace | Per-framework subtypes |
|---|---|---|
| NICE | nice: |
nice:Framework, nice:WorkRole, nice:Task, nice:KnowledgeStatement, nice:SkillStatement |
| DCWF | dcwf: |
dcwf:Framework, dcwf:WorkRole, dcwf:Task, dcwf:KSA |
| ECSF | ecsf: |
ecsf:Framework, ecsf:Profile, ecsf:KSA |
| SFIA | sfia: |
sfia:Framework, sfia:Skill, sfia:LevelDescriptor |
| Cyber.org K-12 | cyberorg: |
cyberorg:Framework, cyberorg:StandardGroup, cyberorg:Standard |
| CSTA | csta: |
csta:Framework, csta:StandardGroup, csta:Standard |
| CSEC2017 | csec: |
csec:Framework, csec:KnowledgeArea, csec:Topic |
| DigComp | digcomp: |
digcomp:Framework, digcomp:CompetenceArea, digcomp:Competence, digcomp:ProficiencyDescriptor |
A nice:WorkRole is also a cybed:Role, which is also a cybed:OrganizingUnit, which is also a skos:Concept. The chain runs all the way up the abstraction hierarchy. A query at any tier returns results from every framework that asserts the relevant Tier 1 type.
Why a custom URI
The package uses https://w3id.org/cybed/ontology# as the namespace for cybed: terms. The W3ID redirect resolves to the schema documentation hosted with the package. That gives the vocabulary a stable, persistent URI that does not depend on any one repository’s URL.
What’s reachable from where
A cybed:hasElement traversal on any organizing unit returns cybed:Subpoint nodes, because they subclass cybed:RoleElement. It does not return cybed:Example nodes, because the Example predicate is separate. This is intentional. Examples are pedagogical scaffolding. Including them in default element traversals would double-count the same conceptual content under two different shapes.
A query that wants Examples explicitly uses cybed:hasExample instead. The package’s example_framework_bindings() helper does exactly this.
What this enables
The cybed:OrganizingUnit abstraction lets a single SPARQL query return organizing units across the entire corpus. The cybed:Role abstraction restricts that query to the three workforce frameworks (NICE, DCWF, ECSF). The cybed:hasElement predicate returns the strict numbered-element traversal across every framework that uses it. The cybed:hasExample predicate exposes the pedagogical scaffolding layer separately, where it exists at all (currently Cyber.org K-12 and CSTA only).
The two-tier shape is what makes the density spread query work across every framework with a single expression rather than reapplying per framework.