From 03bf8253e7fe1e1133928b912ce9aa69b1bf2675 Mon Sep 17 00:00:00 2001 From: Hans-Christian Boos Date: Fri, 26 Jun 2026 10:03:12 +0200 Subject: [PATCH] Add Academy NTO for the Bardioc Academy New NTO/Academy modelling courses, learner enrollment and progress, verifiable certificates, the catalogue and tracks for the Bardioc Academy (Area9 LMS integration; the Bardioc graph is the source of truth). - 1 new entity: ogit.Academy:Enrollment -- a reified learner<->course state (cmi5 lifecycle, xAPI Result fields, licence window). Edges cannot carry attributes, so the relationship is reified (precedent: ogit:Rating). - 4 new verbs: enrolledIn, resultedIn, certifies, supersedes. - 45 new ogit.Academy attributes: course/catalogue metadata, certificate W3C VC 2.0 / Open Badges 3.0 fields, and enrollment/xAPI Result fields. - Existing SGO/NTO core types are extended via allowed-edge and optional-attribute additions only (no removals): ogit:Course, ogit:Certificate, ogit:Person, ogit:Catalog, ogit:Organization, ogit:Rating, ogit.Auth:Account. The model is designed as a lossless superset of the variable mandatory cores of Open Badges 3.0 / W3C Verifiable Credentials 2.0 (certificates), xAPI (IEEE 9274.1.1-2023) + cmi5 (learning records) and schema.org Course (catalogue). The export mapping and a conformance-deviation table (for the few standard-mandatory fields that cannot be enforced on the shared SGO core types and are enforced at the application layer instead) are in NTO/Academy/README.md. Validated locally with rdflib (syntax) and a cross-reference check (every referenced OGIT identifier is defined in the repository). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_018ehGgXoZabSmS3Hp5F4mGx --- NTO/Academy/README.md | 81 +++++++++++++++++++ NTO/Academy/attributes/achievementId.ttl | 14 ++++ NTO/Academy/attributes/activityId.ttl | 14 ++++ NTO/Academy/attributes/completedAt.ttl | 14 ++++ NTO/Academy/attributes/completion.ttl | 16 ++++ NTO/Academy/attributes/courseCode.ttl | 14 ++++ NTO/Academy/attributes/courseMode.ttl | 16 ++++ NTO/Academy/attributes/credentialContext.ttl | 14 ++++ NTO/Academy/attributes/credentialId.ttl | 14 ++++ NTO/Academy/attributes/credentialStatus.ttl | 16 ++++ NTO/Academy/attributes/credentialType.ttl | 14 ++++ NTO/Academy/attributes/criteria.ttl | 14 ++++ NTO/Academy/attributes/criteriaId.ttl | 14 ++++ NTO/Academy/attributes/educationalLevel.ttl | 16 ++++ NTO/Academy/attributes/enrolledAt.ttl | 14 ++++ NTO/Academy/attributes/enrollmentStatus.ttl | 16 ++++ NTO/Academy/attributes/joseAlgorithm.ttl | 14 ++++ NTO/Academy/attributes/lastActivityAt.ttl | 14 ++++ NTO/Academy/attributes/lastVerb.ttl | 14 ++++ NTO/Academy/attributes/launchUrl.ttl | 14 ++++ NTO/Academy/attributes/licenseExpiresAt.ttl | 14 ++++ NTO/Academy/attributes/licenseIssuedAt.ttl | 14 ++++ NTO/Academy/attributes/lmsActivatedAt.ttl | 14 ++++ NTO/Academy/attributes/lmsActiveUntil.ttl | 14 ++++ NTO/Academy/attributes/moveOn.ttl | 16 ++++ NTO/Academy/attributes/passingScore.ttl | 14 ++++ .../attributes/prerequisiteSummary.ttl | 14 ++++ NTO/Academy/attributes/progress.ttl | 14 ++++ NTO/Academy/attributes/promoted.ttl | 16 ++++ NTO/Academy/attributes/proofCreatedAt.ttl | 14 ++++ NTO/Academy/attributes/proofCryptosuite.ttl | 14 ++++ NTO/Academy/attributes/proofPurpose.ttl | 16 ++++ NTO/Academy/attributes/proofValue.ttl | 14 ++++ .../attributes/proofVerificationMethod.ttl | 14 ++++ NTO/Academy/attributes/registrationId.ttl | 14 ++++ NTO/Academy/attributes/resumeLocation.ttl | 14 ++++ NTO/Academy/attributes/scoreMax.ttl | 14 ++++ NTO/Academy/attributes/scoreMin.ttl | 14 ++++ NTO/Academy/attributes/scoreRaw.ttl | 14 ++++ NTO/Academy/attributes/scoreScaled.ttl | 14 ++++ NTO/Academy/attributes/securingMechanism.ttl | 16 ++++ NTO/Academy/attributes/sessionDuration.ttl | 14 ++++ NTO/Academy/attributes/startedAt.ttl | 14 ++++ NTO/Academy/attributes/success.ttl | 16 ++++ NTO/Academy/attributes/timeRequired.ttl | 14 ++++ NTO/Academy/attributes/verificationUrl.ttl | 14 ++++ NTO/Academy/entities/Enrollment.ttl | 48 +++++++++++ NTO/Academy/verbs/certifies.ttl | 17 ++++ NTO/Academy/verbs/enrolledIn.ttl | 17 ++++ NTO/Academy/verbs/resultedIn.ttl | 17 ++++ NTO/Academy/verbs/supersedes.ttl | 17 ++++ NTO/Auth/entities/Account.ttl | 6 ++ SGO/sgo/entities/Catalog.ttl | 1 + SGO/sgo/entities/Certificate.ttl | 18 +++++ SGO/sgo/entities/Course.ttl | 31 +++++++ SGO/sgo/entities/Organization.ttl | 1 + SGO/sgo/entities/Person.ttl | 6 ++ SGO/sgo/entities/Rating.ttl | 1 + 58 files changed, 911 insertions(+) create mode 100644 NTO/Academy/README.md create mode 100644 NTO/Academy/attributes/achievementId.ttl create mode 100644 NTO/Academy/attributes/activityId.ttl create mode 100644 NTO/Academy/attributes/completedAt.ttl create mode 100644 NTO/Academy/attributes/completion.ttl create mode 100644 NTO/Academy/attributes/courseCode.ttl create mode 100644 NTO/Academy/attributes/courseMode.ttl create mode 100644 NTO/Academy/attributes/credentialContext.ttl create mode 100644 NTO/Academy/attributes/credentialId.ttl create mode 100644 NTO/Academy/attributes/credentialStatus.ttl create mode 100644 NTO/Academy/attributes/credentialType.ttl create mode 100644 NTO/Academy/attributes/criteria.ttl create mode 100644 NTO/Academy/attributes/criteriaId.ttl create mode 100644 NTO/Academy/attributes/educationalLevel.ttl create mode 100644 NTO/Academy/attributes/enrolledAt.ttl create mode 100644 NTO/Academy/attributes/enrollmentStatus.ttl create mode 100644 NTO/Academy/attributes/joseAlgorithm.ttl create mode 100644 NTO/Academy/attributes/lastActivityAt.ttl create mode 100644 NTO/Academy/attributes/lastVerb.ttl create mode 100644 NTO/Academy/attributes/launchUrl.ttl create mode 100644 NTO/Academy/attributes/licenseExpiresAt.ttl create mode 100644 NTO/Academy/attributes/licenseIssuedAt.ttl create mode 100644 NTO/Academy/attributes/lmsActivatedAt.ttl create mode 100644 NTO/Academy/attributes/lmsActiveUntil.ttl create mode 100644 NTO/Academy/attributes/moveOn.ttl create mode 100644 NTO/Academy/attributes/passingScore.ttl create mode 100644 NTO/Academy/attributes/prerequisiteSummary.ttl create mode 100644 NTO/Academy/attributes/progress.ttl create mode 100644 NTO/Academy/attributes/promoted.ttl create mode 100644 NTO/Academy/attributes/proofCreatedAt.ttl create mode 100644 NTO/Academy/attributes/proofCryptosuite.ttl create mode 100644 NTO/Academy/attributes/proofPurpose.ttl create mode 100644 NTO/Academy/attributes/proofValue.ttl create mode 100644 NTO/Academy/attributes/proofVerificationMethod.ttl create mode 100644 NTO/Academy/attributes/registrationId.ttl create mode 100644 NTO/Academy/attributes/resumeLocation.ttl create mode 100644 NTO/Academy/attributes/scoreMax.ttl create mode 100644 NTO/Academy/attributes/scoreMin.ttl create mode 100644 NTO/Academy/attributes/scoreRaw.ttl create mode 100644 NTO/Academy/attributes/scoreScaled.ttl create mode 100644 NTO/Academy/attributes/securingMechanism.ttl create mode 100644 NTO/Academy/attributes/sessionDuration.ttl create mode 100644 NTO/Academy/attributes/startedAt.ttl create mode 100644 NTO/Academy/attributes/success.ttl create mode 100644 NTO/Academy/attributes/timeRequired.ttl create mode 100644 NTO/Academy/attributes/verificationUrl.ttl create mode 100644 NTO/Academy/entities/Enrollment.ttl create mode 100644 NTO/Academy/verbs/certifies.ttl create mode 100644 NTO/Academy/verbs/enrolledIn.ttl create mode 100644 NTO/Academy/verbs/resultedIn.ttl create mode 100644 NTO/Academy/verbs/supersedes.ttl diff --git a/NTO/Academy/README.md b/NTO/Academy/README.md new file mode 100644 index 0000000000..5bfed35573 --- /dev/null +++ b/NTO/Academy/README.md @@ -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) | diff --git a/NTO/Academy/attributes/achievementId.ttl b/NTO/Academy/attributes/achievementId.ttl new file mode 100644 index 0000000000..d5d8591b44 --- /dev/null +++ b/NTO/Academy/attributes/achievementId.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/activityId.ttl b/NTO/Academy/attributes/activityId.ttl new file mode 100644 index 0000000000..57046774b3 --- /dev/null +++ b/NTO/Academy/attributes/activityId.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/completedAt.ttl b/NTO/Academy/attributes/completedAt.ttl new file mode 100644 index 0000000000..79c5c139a3 --- /dev/null +++ b/NTO/Academy/attributes/completedAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/completion.ttl b/NTO/Academy/attributes/completion.ttl new file mode 100644 index 0000000000..ad6b4c4d8b --- /dev/null +++ b/NTO/Academy/attributes/completion.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/courseCode.ttl b/NTO/Academy/attributes/courseCode.ttl new file mode 100644 index 0000000000..ddcdac0148 --- /dev/null +++ b/NTO/Academy/attributes/courseCode.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/courseMode.ttl b/NTO/Academy/attributes/courseMode.ttl new file mode 100644 index 0000000000..2a8fba662b --- /dev/null +++ b/NTO/Academy/attributes/courseMode.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/credentialContext.ttl b/NTO/Academy/attributes/credentialContext.ttl new file mode 100644 index 0000000000..e7cd3b3a8c --- /dev/null +++ b/NTO/Academy/attributes/credentialContext.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/credentialId.ttl b/NTO/Academy/attributes/credentialId.ttl new file mode 100644 index 0000000000..5554f87e8b --- /dev/null +++ b/NTO/Academy/attributes/credentialId.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/credentialStatus.ttl b/NTO/Academy/attributes/credentialStatus.ttl new file mode 100644 index 0000000000..97ec97031d --- /dev/null +++ b/NTO/Academy/attributes/credentialStatus.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/credentialType.ttl b/NTO/Academy/attributes/credentialType.ttl new file mode 100644 index 0000000000..51418b2d2c --- /dev/null +++ b/NTO/Academy/attributes/credentialType.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/criteria.ttl b/NTO/Academy/attributes/criteria.ttl new file mode 100644 index 0000000000..e4e889ba8a --- /dev/null +++ b/NTO/Academy/attributes/criteria.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/criteriaId.ttl b/NTO/Academy/attributes/criteriaId.ttl new file mode 100644 index 0000000000..1bf96c6bed --- /dev/null +++ b/NTO/Academy/attributes/criteriaId.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/educationalLevel.ttl b/NTO/Academy/attributes/educationalLevel.ttl new file mode 100644 index 0000000000..ad10176843 --- /dev/null +++ b/NTO/Academy/attributes/educationalLevel.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/enrolledAt.ttl b/NTO/Academy/attributes/enrolledAt.ttl new file mode 100644 index 0000000000..4661e729a8 --- /dev/null +++ b/NTO/Academy/attributes/enrolledAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/enrollmentStatus.ttl b/NTO/Academy/attributes/enrollmentStatus.ttl new file mode 100644 index 0000000000..22ae1a62aa --- /dev/null +++ b/NTO/Academy/attributes/enrollmentStatus.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/joseAlgorithm.ttl b/NTO/Academy/attributes/joseAlgorithm.ttl new file mode 100644 index 0000000000..7d51ed8100 --- /dev/null +++ b/NTO/Academy/attributes/joseAlgorithm.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/lastActivityAt.ttl b/NTO/Academy/attributes/lastActivityAt.ttl new file mode 100644 index 0000000000..3e20ae3e24 --- /dev/null +++ b/NTO/Academy/attributes/lastActivityAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/lastVerb.ttl b/NTO/Academy/attributes/lastVerb.ttl new file mode 100644 index 0000000000..7f239da322 --- /dev/null +++ b/NTO/Academy/attributes/lastVerb.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/launchUrl.ttl b/NTO/Academy/attributes/launchUrl.ttl new file mode 100644 index 0000000000..d8738ef9a0 --- /dev/null +++ b/NTO/Academy/attributes/launchUrl.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix 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"; +. diff --git a/NTO/Academy/attributes/licenseExpiresAt.ttl b/NTO/Academy/attributes/licenseExpiresAt.ttl new file mode 100644 index 0000000000..e18ed5f452 --- /dev/null +++ b/NTO/Academy/attributes/licenseExpiresAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:licenseExpiresAt + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "licenseExpiresAt"; + dcterms:description "Timestamp when the LMS license/seat for this course expires. ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/licenseIssuedAt.ttl b/NTO/Academy/attributes/licenseIssuedAt.ttl new file mode 100644 index 0000000000..0c69dec078 --- /dev/null +++ b/NTO/Academy/attributes/licenseIssuedAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:licenseIssuedAt + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "licenseIssuedAt"; + dcterms:description "Timestamp when the LMS license/seat was issued for this course. ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/lmsActivatedAt.ttl b/NTO/Academy/attributes/lmsActivatedAt.ttl new file mode 100644 index 0000000000..76e89a9bbb --- /dev/null +++ b/NTO/Academy/attributes/lmsActivatedAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:lmsActivatedAt + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "lmsActivatedAt"; + dcterms:description "Timestamp when the learner was marked active on the LMS (first module access). Lives on ogit.Auth:Account ONLY (the canonical SSO identity). ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/lmsActiveUntil.ttl b/NTO/Academy/attributes/lmsActiveUntil.ttl new file mode 100644 index 0000000000..39709cf457 --- /dev/null +++ b/NTO/Academy/attributes/lmsActiveUntil.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:lmsActiveUntil + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "lmsActiveUntil"; + dcterms:description "Timestamp until which the learner counts as an active LMS seat; after this the learner is set inactive to stay within the license scope. Absent/past = inactive. On ogit.Auth:Account ONLY. ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/moveOn.ttl b/NTO/Academy/attributes/moveOn.ttl new file mode 100644 index 0000000000..578a4f71c5 --- /dev/null +++ b/NTO/Academy/attributes/moveOn.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:moveOn + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "moveOn"; + dcterms:description "cmi5 moveOn criterion defining when the learner has satisfied this course (assignable unit)."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + ogit:validation-type "fixed"; + ogit:validation-parameter "Passed,Completed,CompletedAndPassed,CompletedOrPassed,NotApplicable"; +. diff --git a/NTO/Academy/attributes/passingScore.ttl b/NTO/Academy/attributes/passingScore.ttl new file mode 100644 index 0000000000..91c71194e8 --- /dev/null +++ b/NTO/Academy/attributes/passingScore.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:passingScore + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "passingScore"; + dcterms:description "The mastery threshold a learner must reach to pass, as a scaled value between 0 and 1 (e.g. 0.8 = 80%). Maps to the cmi5 masteryScore (the cmi5 term); named passingScore here for readability. Range enforced at the application layer."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/prerequisiteSummary.ttl b/NTO/Academy/attributes/prerequisiteSummary.ttl new file mode 100644 index 0000000000..4d670e4e92 --- /dev/null +++ b/NTO/Academy/attributes/prerequisiteSummary.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:prerequisiteSummary + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "prerequisiteSummary"; + dcterms:description "Human-readable summary of recommended prior knowledge. Structured prerequisites are modelled as ogit:requires edges to other Courses or to ogit.HR.Recruiting:Skill."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/progress.ttl b/NTO/Academy/attributes/progress.ttl new file mode 100644 index 0000000000..e89108d90a --- /dev/null +++ b/NTO/Academy/attributes/progress.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:progress + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "progress"; + dcterms:description "Completion progress as a real number between 0 and 1 (range enforced at the application layer; OGIT has no native numeric range validator). Aligns with SCORM cmi.progress_measure."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/promoted.ttl b/NTO/Academy/attributes/promoted.ttl new file mode 100644 index 0000000000..f1982c4f65 --- /dev/null +++ b/NTO/Academy/attributes/promoted.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:promoted + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "promoted"; + dcterms:description "PHASE-1, COURSE-GLOBAL promotion flag (App-Store-style feature). NOTE: this is a single value across all catalogues; per-catalogue promotion is a phase-2 concern (planned via a CatalogItem intermediary). Documented as a known phase-1 limitation in the README."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + ogit:validation-type "fixed"; + ogit:validation-parameter "true,false"; +. diff --git a/NTO/Academy/attributes/proofCreatedAt.ttl b/NTO/Academy/attributes/proofCreatedAt.ttl new file mode 100644 index 0000000000..1d6d29efd3 --- /dev/null +++ b/NTO/Academy/attributes/proofCreatedAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:proofCreatedAt + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "proofCreatedAt"; + dcterms:description "EMBEDDED (DataIntegrityProof) credentials only: VC 2.0 proof.created (proof generation timestamp). ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/proofCryptosuite.ttl b/NTO/Academy/attributes/proofCryptosuite.ttl new file mode 100644 index 0000000000..5d600f8d18 --- /dev/null +++ b/NTO/Academy/attributes/proofCryptosuite.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:proofCryptosuite + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "proofCryptosuite"; + dcterms:description "EMBEDDED (DataIntegrityProof) credentials only: the VC 2.0 proof.cryptosuite (a W3C cryptosuite-registry identifier, e.g. eddsa-rdfc-2022)."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/proofPurpose.ttl b/NTO/Academy/attributes/proofPurpose.ttl new file mode 100644 index 0000000000..0690644e20 --- /dev/null +++ b/NTO/Academy/attributes/proofPurpose.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:proofPurpose + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "proofPurpose"; + dcterms:description "EMBEDDED (DataIntegrityProof) credentials only: VC 2.0 proof.proofPurpose."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + ogit:validation-type "fixed"; + ogit:validation-parameter "assertionMethod,authentication,keyAgreement,capabilityInvocation,capabilityDelegation"; +. diff --git a/NTO/Academy/attributes/proofValue.ttl b/NTO/Academy/attributes/proofValue.ttl new file mode 100644 index 0000000000..66c2191b0d --- /dev/null +++ b/NTO/Academy/attributes/proofValue.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:proofValue + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "proofValue"; + dcterms:description "EMBEDDED (DataIntegrityProof) credentials only: the VC 2.0 proof.proofValue (multibase-encoded signature). Not populated for enveloping mechanisms (JOSE/SD-JWT/COSE), whose signed token is the credential itself and lives only in the Certificate's Attachment."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/proofVerificationMethod.ttl b/NTO/Academy/attributes/proofVerificationMethod.ttl new file mode 100644 index 0000000000..216d08e10c --- /dev/null +++ b/NTO/Academy/attributes/proofVerificationMethod.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:proofVerificationMethod + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "proofVerificationMethod"; + dcterms:description "EMBEDDED (DataIntegrityProof) credentials only: VC 2.0 proof.verificationMethod (the URI of the public key / verification method)."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/registrationId.ttl b/NTO/Academy/attributes/registrationId.ttl new file mode 100644 index 0000000000..433bc7d569 --- /dev/null +++ b/NTO/Academy/attributes/registrationId.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:registrationId + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "registrationId"; + dcterms:description "The cmi5 context.registration UUID for the learner's registration on this course. Created by the LMS at launch; required for a cmi5-conformant statement export. Optional on the node (a NotStarted enrollment has no registration yet); presence required once the enrollment has been launched, enforced at the application layer (see README deviation table)."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/resumeLocation.ttl b/NTO/Academy/attributes/resumeLocation.ttl new file mode 100644 index 0000000000..208e30bf35 --- /dev/null +++ b/NTO/Academy/attributes/resumeLocation.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:resumeLocation + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "resumeLocation"; + dcterms:description "Per-learner resume position / bookmark within the course. Authoritative in-course session state is managed by the LMS; this is a cached resume pointer."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/scoreMax.ttl b/NTO/Academy/attributes/scoreMax.ttl new file mode 100644 index 0000000000..ba9d72af50 --- /dev/null +++ b/NTO/Academy/attributes/scoreMax.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:scoreMax + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "scoreMax"; + dcterms:description "Maximum possible score. Aligns with xAPI Result.score.max."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/scoreMin.ttl b/NTO/Academy/attributes/scoreMin.ttl new file mode 100644 index 0000000000..717ef7d26a --- /dev/null +++ b/NTO/Academy/attributes/scoreMin.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:scoreMin + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "scoreMin"; + dcterms:description "Minimum possible score. Aligns with xAPI Result.score.min."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/scoreRaw.ttl b/NTO/Academy/attributes/scoreRaw.ttl new file mode 100644 index 0000000000..a0bb48335f --- /dev/null +++ b/NTO/Academy/attributes/scoreRaw.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:scoreRaw + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "scoreRaw"; + dcterms:description "Raw score. Aligns with xAPI Result.score.raw."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/scoreScaled.ttl b/NTO/Academy/attributes/scoreScaled.ttl new file mode 100644 index 0000000000..bbba1b058c --- /dev/null +++ b/NTO/Academy/attributes/scoreScaled.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:scoreScaled + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "scoreScaled"; + dcterms:description "Normalised score between -1 and 1 (range enforced at the application layer). Aligns with xAPI Result.score.scaled."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/securingMechanism.ttl b/NTO/Academy/attributes/securingMechanism.ttl new file mode 100644 index 0000000000..bb6bee0c3b --- /dev/null +++ b/NTO/Academy/attributes/securingMechanism.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:securingMechanism + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "securingMechanism"; + dcterms:description "Local discriminator for how the credential is secured -- NOT a single VC field. For an embedded proof the value 'DataIntegrityProof' equals the VC 2.0 proof.type; for an enveloping proof (JOSE/SD-JWT/COSE) there is no proof object at all and the value names the envelope family (signed token in the Attachment). The other proof* / proofCryptosuite / joseAlgorithm attributes apply ONLY for the matching mechanism (see README)."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + ogit:validation-type "fixed"; + ogit:validation-parameter "DataIntegrityProof,JOSE,SD-JWT,COSE"; +. diff --git a/NTO/Academy/attributes/sessionDuration.ttl b/NTO/Academy/attributes/sessionDuration.ttl new file mode 100644 index 0000000000..99a50091f7 --- /dev/null +++ b/NTO/Academy/attributes/sessionDuration.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:sessionDuration + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "sessionDuration"; + dcterms:description "Cumulative time the learner has spent on the course across all attempts, as an ISO 8601 duration. In the phase-1 aggregate model this is a total; it equals xAPI Result.duration only for a single-session enrollment. Per-attempt durations are a phase-2 (per-statement) concern."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/startedAt.ttl b/NTO/Academy/attributes/startedAt.ttl new file mode 100644 index 0000000000..a49a1258af --- /dev/null +++ b/NTO/Academy/attributes/startedAt.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:startedAt + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "startedAt"; + dcterms:description "Timestamp when the learner first started the course (cmi5 Initialized). ISO 8601 date-time."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/success.ttl b/NTO/Academy/attributes/success.ttl new file mode 100644 index 0000000000..a4e63b8fdb --- /dev/null +++ b/NTO/Academy/attributes/success.ttl @@ -0,0 +1,16 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:success + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "success"; + dcterms:description "xAPI Result.success (whether the learner passed). Stored as the string literal 'true' or 'false' per the OGIT fixed-value convention (not a native boolean). Distinct from enrollmentStatus -- a mastery flag, not the lifecycle state."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + ogit:validation-type "fixed"; + ogit:validation-parameter "true,false"; +. diff --git a/NTO/Academy/attributes/timeRequired.ttl b/NTO/Academy/attributes/timeRequired.ttl new file mode 100644 index 0000000000..130fa928c1 --- /dev/null +++ b/NTO/Academy/attributes/timeRequired.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:timeRequired + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "timeRequired"; + dcterms:description "Estimated time required to complete the course, as an ISO 8601 duration (e.g. PT2H30M). Aligns with schema.org timeRequired."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/attributes/verificationUrl.ttl b/NTO/Academy/attributes/verificationUrl.ttl new file mode 100644 index 0000000000..e55301d96a --- /dev/null +++ b/NTO/Academy/attributes/verificationUrl.ttl @@ -0,0 +1,14 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:verificationUrl + a owl:DatatypeProperty; + rdfs:subPropertyOf ogit:Attribute; + rdfs:label "verificationUrl"; + dcterms:description "Public URL (QR-code target) where the credential can be independently verified."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; +. diff --git a/NTO/Academy/entities/Enrollment.ttl b/NTO/Academy/entities/Enrollment.ttl new file mode 100644 index 0000000000..9a6e6c76f0 --- /dev/null +++ b/NTO/Academy/entities/Enrollment.ttl @@ -0,0 +1,48 @@ +@prefix ogit: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:Enrollment + a rdfs:Class; + rdfs:subClassOf ogit:Entity; + rdfs:label "Enrollment"; + dcterms:description "A reified relationship between a learner and a course. CANONICAL learner edge: ogit.Auth:Account -has-> Enrollment (the SSO identity); reached from the Account via the incoming ogit:has edge (no outgoing Enrollment->learner edge). Carries xAPI Result and cmi5 lifecycle data plus the per-course LMS licence window. ogit:id listed conventionally."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + dcterms:created "2026-06-25"; + ogit:admin-contact "Almato AG"; + ogit:tech-contact "Almato AG"; + ogit:scope "NTO"; + ogit:parent ogit:Node; + ogit:mandatory-attributes ( + ogit.Academy:enrollmentStatus + ); + ogit:optional-attributes ( + ogit:id + ogit.Academy:lastVerb + ogit.Academy:registrationId + ogit.Academy:progress + ogit.Academy:completion + ogit.Academy:success + ogit.Academy:scoreScaled + ogit.Academy:scoreRaw + ogit.Academy:scoreMin + ogit.Academy:scoreMax + ogit.Academy:sessionDuration + ogit.Academy:resumeLocation + ogit.Academy:enrolledAt + ogit.Academy:startedAt + ogit.Academy:completedAt + ogit.Academy:lastActivityAt + ogit.Academy:licenseIssuedAt + ogit.Academy:licenseExpiresAt + ); + ogit:indexed-attributes ( + ogit.Academy:enrollmentStatus + ); + ogit:allowed ( + [ ogit.Academy:enrolledIn ogit:Course ] + [ ogit.Academy:resultedIn ogit:Certificate ] + ); +. diff --git a/NTO/Academy/verbs/certifies.ttl b/NTO/Academy/verbs/certifies.ttl new file mode 100644 index 0000000000..79ecc77bc5 --- /dev/null +++ b/NTO/Academy/verbs/certifies.ttl @@ -0,0 +1,17 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:certifies + a owl:ObjectProperty; + rdfs:subPropertyOf ogit:Verb; + rdfs:label "certifies"; + dcterms:description "Indicates that a certificate (credential) certifies the achievement defined by a course. Disambiguates the Certificate->Course link from the generic ogit:relates."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + dcterms:created "2026-06-25"; + ogit:admin-contact "Almato AG"; + ogit:tech-contact "Almato AG"; +. diff --git a/NTO/Academy/verbs/enrolledIn.ttl b/NTO/Academy/verbs/enrolledIn.ttl new file mode 100644 index 0000000000..c4f3823208 --- /dev/null +++ b/NTO/Academy/verbs/enrolledIn.ttl @@ -0,0 +1,17 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:enrolledIn + a owl:ObjectProperty; + rdfs:subPropertyOf ogit:Verb; + rdfs:label "enrolledIn"; + dcterms:description "Indicates the course an enrollment is for. Disambiguates the Enrollment->Course link from the generic ogit:relates."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + dcterms:created "2026-06-25"; + ogit:admin-contact "Almato AG"; + ogit:tech-contact "Almato AG"; +. diff --git a/NTO/Academy/verbs/resultedIn.ttl b/NTO/Academy/verbs/resultedIn.ttl new file mode 100644 index 0000000000..42be1909f3 --- /dev/null +++ b/NTO/Academy/verbs/resultedIn.ttl @@ -0,0 +1,17 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:resultedIn + a owl:ObjectProperty; + rdfs:subPropertyOf ogit:Verb; + rdfs:label "resultedIn"; + dcterms:description "Indicates the certificate that an enrollment's completion produced. The learner-side canonical edge remains ogit.Auth:Account -receives-> Certificate; the issuance service creates both edges atomically."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + dcterms:created "2026-06-25"; + ogit:admin-contact "Almato AG"; + ogit:tech-contact "Almato AG"; +. diff --git a/NTO/Academy/verbs/supersedes.ttl b/NTO/Academy/verbs/supersedes.ttl new file mode 100644 index 0000000000..6ab42a6ff4 --- /dev/null +++ b/NTO/Academy/verbs/supersedes.ttl @@ -0,0 +1,17 @@ +@prefix ogit: . +@prefix owl: . +@prefix rdfs: . +@prefix dcterms: . +@prefix ogit.Academy: . + +ogit.Academy:supersedes + a owl:ObjectProperty; + rdfs:subPropertyOf ogit:Verb; + rdfs:label "supersedes"; + dcterms:description "Indicates that a newer course version or re-training supersedes an earlier course version. Distinct from ogit:precedes (recommended order) and ogit:requires (prerequisite). No existing OGIT verb captures version succession."; + dcterms:valid "start=2026-06-25;"; + dcterms:creator "Almato AG"; + dcterms:created "2026-06-25"; + ogit:admin-contact "Almato AG"; + ogit:tech-contact "Almato AG"; +. diff --git a/NTO/Auth/entities/Account.ttl b/NTO/Auth/entities/Account.ttl index 1d244113cc..65152a9180 100644 --- a/NTO/Auth/entities/Account.ttl +++ b/NTO/Auth/entities/Account.ttl @@ -23,6 +23,7 @@ @prefix ogit: . @prefix rdfs: . @prefix dcterms: . +@prefix ogit.Academy: . ogit.Auth:Account a rdfs:Class; @@ -50,6 +51,8 @@ ogit.Auth:Account ogit.Auth.Account:acceptedProjectTerms ogit.Auth.Account:allowCookies ogit.Auth.Account:statusReason + ogit.Academy:lmsActivatedAt + ogit.Academy:lmsActiveUntil ); ogit:indexed-attributes ( @@ -79,5 +82,8 @@ ogit.Auth:Account [ ogit:supports ogit.Project:Project ] [ ogit:defines ogit.UserMeta:Filter ] [ ogit:repliedWith ogit.Survey:Reply ] + [ ogit:has ogit.Academy:Enrollment ] + [ ogit:receives ogit:Certificate ] + [ ogit:receives ogit.Forum:Award ] ); . diff --git a/SGO/sgo/entities/Catalog.ttl b/SGO/sgo/entities/Catalog.ttl index d0f5a7c6ee..be7f824da9 100644 --- a/SGO/sgo/entities/Catalog.ttl +++ b/SGO/sgo/entities/Catalog.ttl @@ -53,5 +53,6 @@ ogit:Catalog [ ogit:contains ogit.Factory:Plant ] [ ogit:contains ogit.ServiceManagement:Service ] [ ogit:belongs ogit:Category ] + [ ogit:contains ogit:Course ] ); . diff --git a/SGO/sgo/entities/Certificate.ttl b/SGO/sgo/entities/Certificate.ttl index 4659638e39..06c33acaae 100644 --- a/SGO/sgo/entities/Certificate.ttl +++ b/SGO/sgo/entities/Certificate.ttl @@ -16,6 +16,8 @@ @prefix ogit: . @prefix rdfs: . @prefix dcterms: . +@prefix ogit.Academy: . +@prefix ogit.Documents: . ogit:Certificate a rdfs:Class; @@ -34,6 +36,19 @@ ogit:Certificate ogit:subject ogit:validFrom ogit:validTo + ogit:name + ogit.Academy:credentialId + ogit.Academy:credentialType + ogit.Academy:credentialContext + ogit.Academy:proofValue + ogit.Academy:securingMechanism + ogit.Academy:proofCryptosuite + ogit.Academy:joseAlgorithm + ogit.Academy:proofVerificationMethod + ogit.Academy:proofPurpose + ogit.Academy:proofCreatedAt + ogit.Academy:credentialStatus + ogit.Academy:verificationUrl ); ogit:indexed-attributes ( @@ -41,5 +56,8 @@ ogit:Certificate ogit:allowed ( [ ogit:relates ogit:Installation ] [ ogit:belongs ogit:Organization ] + [ ogit.Academy:certifies ogit:Course ] + [ ogit:has ogit:Attachment ] + [ ogit:has ogit.Documents:Document ] ); . diff --git a/SGO/sgo/entities/Course.ttl b/SGO/sgo/entities/Course.ttl index f20668d8ac..308ed282c7 100644 --- a/SGO/sgo/entities/Course.ttl +++ b/SGO/sgo/entities/Course.ttl @@ -1,6 +1,10 @@ @prefix ogit: . @prefix rdfs: . @prefix dcterms: . +@prefix ogit.Academy: . +@prefix ogit.HR.Recruiting: . +@prefix ogit.ClassificationStandard: . +@prefix ogit.Documents: . ogit:Course a rdfs:Class; @@ -20,10 +24,37 @@ ogit:Course ogit:description ogit:status ogit:creator + ogit:version + ogit:tags + ogit:category + ogit:lastUpdatedAt + ogit:url + ogit:language + ogit.Academy:achievementId + ogit.Academy:activityId + ogit.Academy:criteria + ogit.Academy:criteriaId + ogit.Academy:courseMode + ogit.Academy:passingScore + ogit.Academy:educationalLevel + ogit.Academy:timeRequired + ogit.Academy:courseCode + ogit.Academy:moveOn + ogit.Academy:launchUrl + ogit.Academy:promoted + ogit.Academy:prerequisiteSummary ); ogit:indexed-attributes ( ); ogit:allowed ( + [ ogit:requires ogit:Course ] + [ ogit:precedes ogit:Course ] + [ ogit:contains ogit:Course ] + [ ogit.Academy:supersedes ogit:Course ] + [ ogit:requires ogit.HR.Recruiting:Skill ] + [ ogit:has ogit:Attachment ] + [ ogit:has ogit.Documents:Document ] + [ ogit.ClassificationStandard:classifiedUnder ogit.ClassificationStandard:ClassificationStandardTreeBranch ] ); . diff --git a/SGO/sgo/entities/Organization.ttl b/SGO/sgo/entities/Organization.ttl index 2d96395928..bf77c4add4 100644 --- a/SGO/sgo/entities/Organization.ttl +++ b/SGO/sgo/entities/Organization.ttl @@ -120,6 +120,7 @@ The ogit/function attribute should be used to tell what kind of grouping an enti [ ogit:provides ogit:ConfigurationItem ] [ ogit:provides ogit.Documents:Document ] [ ogit:provides ogit:Product ] + [ ogit:provides ogit:Course ] [ ogit:supervises ogit.ServiceManagement:SubTask ] [ ogit:supervises ogit.ServiceManagement:ChangeRequest ] [ ogit:supervises ogit.ServiceManagement:Order ] diff --git a/SGO/sgo/entities/Person.ttl b/SGO/sgo/entities/Person.ttl index 686621e7fe..fa48e11cda 100644 --- a/SGO/sgo/entities/Person.ttl +++ b/SGO/sgo/entities/Person.ttl @@ -30,6 +30,7 @@ @prefix ogit.Legal: . @prefix ogit.HR.Recruiting: . @prefix ogit.Auth: . +@prefix ogit.Forum: . ogit:Person a rdfs:Class; @@ -323,5 +324,10 @@ ogit:Person # Personal-Vault anchor (Bardioc GFS dependency, 2026-06-01 -- per Cy phone call: use ogit.Auth:owns rather than introducing hasVault) [ ogit.Auth:owns ogit.Auth:DataScope ] + + # --- Academy additions --- + [ ogit:receives ogit:Certificate ] + [ ogit:receives ogit.Forum:Award ] + [ ogit:provides ogit:Rating ] ); . diff --git a/SGO/sgo/entities/Rating.ttl b/SGO/sgo/entities/Rating.ttl index 85589f14eb..7ad94ae825 100644 --- a/SGO/sgo/entities/Rating.ttl +++ b/SGO/sgo/entities/Rating.ttl @@ -32,5 +32,6 @@ ogit:Rating [ ogit:rates ogit.Auth:Application ] [ ogit:rates ogit.ServiceManagement:Service ] [ ogit:rates ogit.Forms:Form] + [ ogit:rates ogit:Course ] ); .