Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions NTO/Academy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Academy

NTO for the Bardioc Academy: courses and their dependencies, learner enrollment and
progress, ratings, the catalogue and its tracks, and verifiable certificates. The
Bardioc graph is the source of truth; Area9 is the LMS.

## New entity (entities/)

- **Enrollment** -- reified learner<->course state: `enrollmentStatus`, `lastVerb`,
`registrationId`, `progress`, xAPI Result fields, `resumeLocation`, lifecycle
timestamps, per-course licence window. Reified because OGIT edges carry no attributes
(cf. `ogit:Rating`). Canonical learner edge: `ogit.Auth:Account -has-> Enrollment`.

## New verbs (verbs/)

`enrolledIn` (Enrollment->Course), `resultedIn` (Enrollment->Certificate), `certifies`
(Certificate->Course), `supersedes` (Course->Course, version/re-training). No Academy
edge uses the generic `ogit:relates`.

## New attributes (attributes/) -- 45, namespace `ogit.Academy`

- **Course:** achievementId, activityId, courseCode, criteria, criteriaId, courseMode,
passingScore, educationalLevel, timeRequired, moveOn, launchUrl, promoted,
prerequisiteSummary.
- **Certificate:** credentialId, credentialType, credentialContext, proofValue,
securingMechanism, proofCryptosuite, joseAlgorithm, proofVerificationMethod,
proofPurpose, proofCreatedAt, credentialStatus, verificationUrl.
- **Enrollment:** enrollmentStatus, lastVerb, registrationId, progress, completion,
success, scoreScaled/Raw/Min/Max, sessionDuration, resumeLocation, enrolledAt,
startedAt, completedAt, lastActivityAt, licenseIssuedAt, licenseExpiresAt.
- **Account:** lmsActivatedAt, lmsActiveUntil.

## Reused types / verbs

Types: `ogit:Course`, `ogit:Certificate`, `ogit:Catalog`, `ogit:Rating`,
`ogit:Attachment`, `ogit.Documents:Document`, `ogit:Person`, `ogit:Organization`,
`ogit.Auth:Account`, `ogit.ClassificationStandard:ClassificationStandardTreeBranch`
(tracks), `ogit.HR.Recruiting:Skill` (prior knowledge), `ogit.Forum:Award` (badges).
Verbs: `requires`, `precedes` (one direction; follows derived), `contains`, `rates`,
`provides`, `receives`, `creates`, `has`, `classifiedUnder`.

## Extensions to existing core types (additions only)

These types gain allowed-edge entries (and Course/Certificate/Account a few optional
attributes) to wire in the Academy types; see the diff for the exact lines:
`ogit:Course`, `ogit:Certificate`, `ogit:Person`, `ogit:Catalog`, `ogit:Organization`,
`ogit:Rating`, `ogit.Auth:Account`.

## Modelling notes

- **IRIs:** `ogit:id` is the internal node id (UUID). The standards' HTTP IRIs use
dedicated attributes: `achievementId` (OB Achievement.id), `credentialId`
(VC/OB credential id), `activityId` (xAPI Activity id / cmi5 grouping).
- **Account is the canonical learner anchor:** `has -> Enrollment` and `lmsActivatedAt`/
`lmsActiveUntil` are on the Account only; Person only `receives -> Certificate/Award`.
- **`promoted`** is a phase-1, course-global flag (per-catalogue promotion is phase-2).
- **"available"** is derived (no Enrollment / NotStarted), not an enum value.
- **Certificate signing:** the signed VC/JWS/PDF lives in an `Attachment`; the `proof*`
attributes are a queryable cache (embedded Data Integrity case) -- for enveloping
(JOSE/SD-JWT/COSE) only the Attachment is authoritative.

## Standards alignment

Modelled to align with **Open Badges 3.0 / W3C Verifiable Credentials 2.0** (certificates),
**xAPI (IEEE 9274.1.1-2023) + cmi5** (learning records, aggregate state in phase 1) and
**schema.org Course** (catalogue). The VC `credentialSubject` and `issuer` and the
JSON-LD type strings are reconstructed at export from the graph, not stored verbatim.

## Application-layer enforcement

A few standard-mandatory fields cannot be enforced on the shared SGO core types
(`ogit:Course`, `ogit:Certificate`), so the Academy service enforces them on write:

| Field | OGIT slot | Rule |
| --- | --- | --- |
| Achievement.criteria, .description, .id | criteria / `ogit:description` / achievementId | reject Academy course without them |
| xAPI Activity id | activityId | reject Academy course without it |
| Credential id, validFrom | credentialId / `ogit:validFrom` | set/require at issuance |
| issuer id | Organization `ogit:webPage` | require a resolvable IRI at issuance |
| cmi5 registration | registrationId | require once the enrollment is past NotStarted |
| score / progress ranges | -- | range-check (no native validator) |
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/achievementId.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:achievementId
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "achievementId";
dcterms:description "The Open Badges 3.0 Achievement.id as an HTTP IRI: the canonical, globally-unique URI of the achievement this course certifies. Distinct from the internal graph node id ogit:id (a platform UUID). Presence enforced at the application layer (see README deviation table).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/activityId.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:activityId
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "activityId";
dcterms:description "The stable xAPI/cmi5 Activity IRI for the course (the object.id of an xAPI statement; also the cmi5 context.contextActivities.grouping IRI). A persistent HTTP IRI, distinct from launchUrl (dynamic) and courseCode. Presence enforced at the application layer (see README deviation table).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/completedAt.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:completedAt
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "completedAt";
dcterms:description "Timestamp when the learner completed the course. ISO 8601 date-time.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
16 changes: 16 additions & 0 deletions NTO/Academy/attributes/completion.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:completion
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "completion";
dcterms:description "xAPI Result.completion (whether the course content was completed). Stored as the string literal 'true' or 'false' per the OGIT fixed-value convention (not a native boolean). Distinct from enrollmentStatus -- a content-completion flag, not the lifecycle state.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
ogit:validation-type "fixed";
ogit:validation-parameter "true,false";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/courseCode.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:courseCode
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "courseCode";
dcterms:description "The external course code / identifier; carries the Area9 (LMS) course identifier. Aligns with schema.org courseCode. The stable xAPI Activity IRI is ogit.Academy:activityId, not this field.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
16 changes: 16 additions & 0 deletions NTO/Academy/attributes/courseMode.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:courseMode
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "courseMode";
dcterms:description "The mode of course delivery. Aligns with schema.org courseMode (lowercase to match the schema.org / Google structured-data examples; an intentional fixed subset of the schema.org free-text field).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
ogit:validation-type "fixed";
ogit:validation-parameter "online,blended,onsite";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/credentialContext.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:credentialContext
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "credentialContext";
dcterms:description "The JSON-LD @context of the credential, stored as a serialized JSON array string preserving order and permitting inline context objects.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/credentialId.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:credentialId
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "credentialId";
dcterms:description "The W3C VC 2.0 / Open Badges 3.0 credential id (AchievementCredential.id) as an HTTP IRI. Distinct from the internal graph node id ogit:id. Presence enforced at the application layer (see README deviation table).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
16 changes: 16 additions & 0 deletions NTO/Academy/attributes/credentialStatus.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:credentialStatus
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "credentialStatus";
dcterms:description "Cached evaluated revocation/suspension state for fast queries. NOT the VC 2.0 credentialStatus object (a status-list descriptor with id/type/statusListCredential/statusListIndex); that descriptor lives in the signed credential blob (Attachment).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
ogit:validation-type "fixed";
ogit:validation-parameter "active,revoked,suspended";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/credentialType.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:credentialType
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "credentialType";
dcterms:description "The Verifiable Credential 'type' value, stored as a serialized JSON array string preserving order (e.g. '[\"VerifiableCredential\",\"OpenBadgeCredential\"]').";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/criteria.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:criteria
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "criteria";
dcterms:description "The Open Badges 3.0 Achievement.criteria.narrative: a human-readable statement of what the learner must do to earn the achievement. The optional Criteria.id IRI is stored separately in ogit.Academy:criteriaId, so the OB 3.0 Criteria object {id, narrative} round-trips losslessly. OB 3.0 requires a Criteria; because ogit:Course is a shared SGO type the slot is optional and enforced at the application layer (see README deviation table).";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/criteriaId.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:criteriaId
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "criteriaId";
dcterms:description "The Open Badges 3.0 Achievement.criteria.id (an IRI), when the Criteria object carries one. Stored separately from the narrative (ogit.Academy:criteria) so the Criteria object round-trips losslessly.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
16 changes: 16 additions & 0 deletions NTO/Academy/attributes/educationalLevel.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:educationalLevel
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "educationalLevel";
dcterms:description "The difficulty / educational level of the course. Aligns with schema.org educationalLevel.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
ogit:validation-type "fixed";
ogit:validation-parameter "Beginner,Intermediate,Advanced,Expert";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/enrolledAt.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:enrolledAt
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "enrolledAt";
dcterms:description "Timestamp when the enrollment record was created. Distinct from startedAt and licenseIssuedAt. ISO 8601 date-time.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
16 changes: 16 additions & 0 deletions NTO/Academy/attributes/enrollmentStatus.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:enrollmentStatus
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "enrollmentStatus";
dcterms:description "Lifecycle/outcome status of the learner's engagement with the course. NotStarted and InProgress are OGIT aggregations; Completed/Passed/Failed/Abandoned/Waived/Satisfied are cmi5 outcome verbs. The transient/session-level cmi5 verbs Launched, Initialized and Terminated are intentionally NOT lifecycle states (Terminated marks an AU session end, not a course outcome); when they occur they are captured in lastVerb only.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
ogit:validation-type "fixed";
ogit:validation-parameter "NotStarted,InProgress,Completed,Passed,Failed,Abandoned,Waived,Satisfied";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/joseAlgorithm.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:joseAlgorithm
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "joseAlgorithm";
dcterms:description "ENVELOPING (JOSE/COSE) credentials only: the IANA JOSE/COSE algorithm identifier (the JWS/COSE 'alg' header, e.g. ES256, EdDSA). Distinct value namespace from proofCryptosuite.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/lastActivityAt.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:lastActivityAt
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "lastActivityAt";
dcterms:description "Timestamp of the learner's most recent activity in the course. ISO 8601 date-time.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/lastVerb.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:lastVerb
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "lastVerb";
dcterms:description "The xAPI/cmi5 verb IRI describing the most recent state transition (e.g. https://w3id.org/xapi/adl/verbs/completed, or the cmi5 Launched/Initialized IRIs). Stored so a conformant xAPI statement can be reconstructed; preserves verbs Area9 may emit outside the enrollmentStatus enum.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
14 changes: 14 additions & 0 deletions NTO/Academy/attributes/launchUrl.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@prefix ogit: <http://www.purl.org/ogit/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix ogit.Academy: <http://www.purl.org/ogit/Academy/> .

ogit.Academy:launchUrl
a owl:DatatypeProperty;
rdfs:subPropertyOf ogit:Attribute;
rdfs:label "launchUrl";
dcterms:description "The stable course-level launch base URL / deep-link template on the LMS. The LMS appends session-specific parameters at launch time; this stored value is itself stable (it is NOT the per-session URL, and is distinct from the stable identifier ogit.Academy:activityId). Per-learner in-course resume position is Enrollment.resumeLocation.";
dcterms:valid "start=2026-06-25;";
dcterms:creator "Almato AG";
.
Loading
Loading