The two-tier vocabulary

How cybedtools represents heterogeneous frameworks in a single graph

The design problem

14 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, plus competency areas as a second grouping axis. DigComp has competence areas and proficiency levels. SFIA has skills and 7 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 8 knowledge areas. ECSF has 12 profiles. DCWF aligns to NICE work roles with overlap. CyQUAL has qualification units and proficiency levels. CCSSF has work roles and skills. OTCCF has job roles, skills, and role-to-role relations.

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 two-tier vocabulary architecture A nested-rectangle diagram showing how a Framework relates to its top-level Organizing units (which contain Roles as a subclass for workforce frameworks), and how Organizing units relate to Elements (containing Sub-elements as a subclass) and Examples (a separate predicate).Frameworkcybed:FrameworkOrganizing unitcybed:OrganizingUnitevery framework's top-level units assert thisevery framework asserts this on its top-level unitsRolecybed:Rolea kind of organizing unit · workforce frameworks onlysubClassOf · workforce frameworks only(NICE, DCWF, ECSF, CyQUAL, CCSSF, OTCCF)(NICE, DCWF, ECSF, CyQUAL, CCSSF, OTCCF)Elementcybed:RoleElementstructural pieces attached to an organizing unitattached via cybed:hasElementSub-elementcybed:Subpointa kind of element · points back to its parentsubClassOf · cybed:elaborates parentExamplecybed:Examplepedagogical scaffoldingpedagogical scaffoldingreached through its own connection,separate predicate · excluded fromnot the default element listdefault cybed:hasElement traversalscontainscybed:hasOrganizingUnithas elementcybed:hasElementhas examplecybed:hasExample
The two-tier shape. Outer rectangles are cross-framework abstracts. Nested rectangles are subclasses. The dashed border on the example box marks it as reachable through a separate connection, not the default element list. Click any box or edge label to flip between plain English and the technical schema name.

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, DCWF, CyQUAL, and CCSSF work roles, ECSF profiles, and OTCCF job roles.
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)
cybed:relatedUnit Property Organizing unit → cybed:UnitRelation, the reified edge between two units
cybed:UnitRelation Class A reified relation between two organizing units, so the edge can carry its own label and level
cybed:fromUnit Property Unit relation → the source organizing unit
cybed:toUnit Property Unit relation → the target organizing unit
cybed:relationLabel Property The steward’s own wording for what the relation means
cybed:proficiencyLevel Property The level as the steward printed it, always a literal string
cybed:niceCrossReference Property A framework’s own declared pointer at a NICE identifier
schema:creditText Property The attribution wording a steward asked to be reproduced
schema:inLanguage Property The BCP 47 language tag of an element’s statement text. Supported by the ingestion helpers, not asserted by any framework in the current corpus.

Proficiency levels are stored as printed and are never coerced to numbers. A CyQUAL level and an SFIA level are both called a level and are not the same scale, so arithmetic across them would invent a comparison the stewards never made.

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
CyQUAL cyqual: cyqual:Framework, cyqual:WorkRole, cyqual:Competency, cyqual:Requirement, cyqual:Task
CCSSF ccssf: ccssf:Framework, ccssf:WorkRole, ccssf:Competency, ccssf:Task, ccssf:ToolOrTechnology, ccssf:AdjacentRole
OTCCF otccf: otccf:Framework, otccf:JobRole, otccf:KeyTask, otccf:TechnicalSkillCompetency, otccf:CriticalCoreSkill, otccf:Knowledge, otccf:Ability

The first eight prefixes resolve under a steward’s own domain. The last three do not. CyQUAL, CCSSF, and OTCCF are minted by the package under https://w3id.org/cybed/framework/<slug>#, because those stewards publish no term namespace of their own. Putting a package-coined type under the package’s namespace is the point: a reader who resolves the URI lands on cybedtools documentation and can see that cybedtools coined the type, so a package-coined type is never mistaken for an identifier the steward issued.

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 6 workforce frameworks whose top-level unit is genuinely a role (NICE, DCWF, ECSF, CyQUAL, CCSSF, OTCCF). 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).

That split is worth stating as an argument, because the count behind it has moved. cybed:Role now covers 6 of the 14 frameworks, so it is the majority type, not a minority carve-out. The reason to keep it separate is unchanged and now easier to see. A NICE work role and a DigComp competence area are both organizing units and only one of them is a job. Collapsing the two would make every role-scoped query silently include competence areas, grade-band cells, and knowledge areas. cybed:OrganizingUnit is what makes the 8 non-role frameworks reachable in the same query as the rest. cybed:Role is what keeps them out when the question is about jobs.

The two-tier shape is what makes the density spread query work across every framework with a single expression rather than reapplying per framework.

Back to top