diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..c502d68 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,180 @@ +name: Learning Contracts Quality + +on: + pull_request: {} + push: + branches: [develop, main] + +permissions: + contents: read + +concurrency: + group: learning-contracts-quality-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + validate: + # Live exact-head evidence showed ubuntu-latest remaining unassigned with no + # executed steps. The explicit Ubuntu 24.04 image is already proven usable + # by the sibling Learning Content Studio quality lane. + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - name: Checkout exact revision + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + - name: Install pinned schema validator + run: python3 -m pip install --disable-pip-version-check --no-input 'jsonschema==4.26.0' 'rfc3339-validator==0.1.4' + - name: Validate documentation and schemas + shell: python3 {0} + run: | + import json + import re + from datetime import datetime + from pathlib import Path + + from jsonschema import Draft202012Validator, FormatChecker + from jsonschema.exceptions import SchemaError + + schema_path = Path("schemas/v1/learning-event.schema.json") + required = [ + Path("README.md"), + Path("AGENTS.md"), + Path("CLAUDE.md"), + Path("CHANGELOG.md"), + Path("docs/PRD.md"), + Path("docs/TRD.md"), + Path("docs/ARCHITECTURE.md"), + Path("docs/adr/0001-contract-authority-boundary.md"), + Path("docs/doctoring/STANDARD_TRACEABILITY.md"), + Path("docs/product-technical-gap-baseline.md"), + schema_path, + ] + missing = [str(path) for path in required if not path.is_file()] + if missing: + raise SystemExit(f"missing required bootstrap files: {missing}") + + schemas = {} + for path in Path("schemas").rglob("*.json"): + with path.open(encoding="utf-8") as handle: + value = json.load(handle) + try: + Draft202012Validator.check_schema(value) + except SchemaError as exc: + raise SystemExit(f"invalid Draft 2020-12 schema in {path}: {exc.message}") from exc + schemas[path] = value + + # Prove the validator is checking schema semantics rather than JSON syntax alone. + try: + Draft202012Validator.check_schema({"$schema": "https://json-schema.org/draft/2020-12/schema", "type": 7}) + except SchemaError: + pass + else: + raise SystemExit("schema validator accepted an invalid type keyword value") + + schema = schemas[schema_path] + if schema.get("$schema") != "https://json-schema.org/draft/2020-12/schema": + raise SystemExit("learning event schema must use JSON Schema Draft 2020-12") + + version = schema.get("x-cwl-schema-version", "") + version_match = re.fullmatch(r"(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)", version) + if not version_match: + raise SystemExit("learning event schema must declare a canonical semantic version") + path_major = schema_path.parent.name + if path_major != f"v{version_match.group(1)}": + raise SystemExit( + f"schema major version {version_match.group(1)} must match path segment {path_major!r}" + ) + + # `$id` is a canonical logical identifier, not a mutable branch URL or a + # claim that an unreleased schema has already been published. Its semantic + # version therefore determines an immutable identity before the first release. + expected_id = ( + "urn:contextualwisdomlab:learning-interoperability-contracts:" + f"learning-event:{version}" + ) + if schema.get("$id") != expected_id: + raise SystemExit("learning event schema $id must match the immutable version-derived identity") + + def parse_contract_timestamp(candidate: str) -> datetime: + normalized = candidate + if len(normalized) > 10 and normalized[10] == "t": + normalized = normalized[:10] + "T" + normalized[11:] + if normalized.endswith(("Z", "z")): + normalized = normalized[:-1] + "+00:00" + return datetime.fromisoformat(normalized) + + valid_timestamps = ( + "2026-08-19T14:00:00Z", + "2026-08-19t14:00:00z", + "2024-02-29T23:59:59+14:00", + "2026-01-01T00:00:00-05:30", + "2026-01-01T00:00:00.123456Z", + ) + invalid_timestamps = ( + "2026-08-19", + "not-a-date", + "2026-08-19T14:00:00", + "2026-02-29T14:00:00Z", + "2026-13-01T14:00:00Z", + "2026-04-31T14:00:00Z", + "2026-01-01T24:00:00Z", + "2026-01-01T14:60:00Z", + "2026-01-01T14:00:60Z", + "2026-01-01T14:00:00+24:00", + "2026-01-01T14:00:00+14:60", + ) + invalid_calendar_timestamps = ( + "2026-02-29T14:00:00Z", + "2026-04-31T14:00:00Z", + ) + + format_checker = FormatChecker() + if format_checker.conforms("2026-02-29T14:00:00Z", "date-time"): + raise SystemExit("date-time format checker is inactive or accepts an impossible calendar date") + + for field_name in ("occurred_at", "recorded_at"): + field = schema["properties"][field_name] + if field.get("format") != "date-time" or not field.get("pattern"): + raise SystemExit(f"{field_name} must require date-time format and a syntax pattern") + + # Draft 2020-12's default metaschema treats format as annotation. The + # contract gate therefore opts into executable format checking and + # combines it with the committed lexical pattern. + field_validator = Draft202012Validator(field, format_checker=format_checker) + + for candidate in valid_timestamps: + errors = list(field_validator.iter_errors(candidate)) + if errors: + raise SystemExit( + f"{field_name} schema rejects valid contract timestamp {candidate}: " + + "; ".join(error.message for error in errors) + ) + try: + parse_contract_timestamp(candidate) + except ValueError as exc: + raise SystemExit(f"{field_name} parser rejects valid timestamp: {candidate}") from exc + + for candidate in invalid_timestamps: + errors = list(field_validator.iter_errors(candidate)) + if not errors: + raise SystemExit(f"{field_name} schema accepts invalid timestamp: {candidate}") + + for candidate in invalid_calendar_timestamps: + try: + parse_contract_timestamp(candidate) + except ValueError: + pass + else: + raise SystemExit(f"{field_name} parser accepts impossible calendar date: {candidate}") + + forbidden = ("TODO: replace", "TBD: replace", "PLACEHOLDER_REPLACE") + for path in required: + text = path.read_text(encoding="utf-8") + for marker in forbidden: + if marker in text: + raise SystemExit(f"unresolved bootstrap marker {marker!r} in {path}") + + print("learning interoperability bootstrap contract validation passed") diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..05bf19e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,10 @@ +# Agent development rules + +- Preserve repository responsibility: contracts only, no application state or product-specific database ownership. +- Pin every standards adoption decision to a precise revision and authoritative source. Adoption is a product decision, not conformance evidence. +- Pin every implementation/conformance claim to the precise normative requirement, implementation location, executable fixture/test path, and exact-head CI evidence. Record absent evidence explicitly rather than inferring conformance from adoption or documentation. +- Maintain backward-compatible contracts where declared; incompatible changes require a new version. +- Do not silently translate historical learning records between xAPI versions. +- Generated SDKs must be reproducible from committed schemas. +- Production code introduced here requires 100% statement and branch coverage plus complete public API documentation. +- Database object naming rules are not applicable because this repository must not own a runtime database. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..04ffd3f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +## Unreleased + +### Added + +- Initial learning interoperability authority boundaries. +- Standards traceability baseline for xAPI, cmi5, LTI, QTI, CASE, Open Badges, CLR, and accessibility. +- Versioned learning-domain event envelope schema with an immutable semantic-version-derived logical URN. +- Repository agent development rules. +- Product requirements defining customer/integrator jobs, contract support gates, non-goals and release outcomes. +- Technical requirements defining the artifact-only bounded context, invariants, validation, release, security and consumer ACL requirements. + +### Changed + +- Pinned the adopted cmi5 Quartz normative source to the official immutable Quartz release commit instead of the mutable development branch. +- Reconciled the commercialization baseline so the immutable schema identity is distinguished from the still-missing protected release artifact, and portable timestamp conformance remains explicitly blocked until consumer format-assertion fixtures are executable across supported runtimes. +- Pinned the repository quality job to `ubuntu-24.04` after the live exact-head `ubuntu-latest` job remained unassigned with no executed steps; no validation, security, review, or release gate was weakened. +- Broadened repository Quality from only `develop`/`main` pull-request bases to every pull request so stacked feature PRs receive the same repository-local exact-head validation rather than silently skipping it. +- Repository Quality now requires PRD and TRD presence so foundational product/technical contracts cannot regress silently. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a793056 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +# Development context + +Follow `AGENTS.md` and the organization-level engineering policy. This repository defines shared learning interoperability contracts only. Keep runtime application state and product-specific persistence in the owning repositories. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 8f86331..e1d179e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,95 @@ # Learning Interoperability Contracts -Bootstrap anchor for the repository. Product development is proposed through `develop`. +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ContextualWisdomLab/learning-interoperability-contracts) + +**Versioned, provider-neutral contracts that let ContextualWisdomLab learning products exchange evidence without sharing implementation ownership.** + +Learning Interoperability Contracts is the shared contract authority for schemas, profiles, mappings, conformance fixtures, and generated-client contracts across the CWL Learning Platform. It defines what crosses product boundaries; it does not become the source of truth for learner state, authored content, learning records, psychometric computation, billing, or product databases. + +> **Status:** pre-release bootstrap. An open branch or schema path is not an immutable published contract release. + +## What this repository is for + +Use this repository when two learning products need a stable, reviewable interoperability boundary that must survive independent implementation and release cycles. + +The current portfolio tracks: + +- xAPI 2.0 as the canonical learning-record adoption target; +- cmi5 Quartz as an explicit xAPI 1.0.3 compatibility profile rather than a silent translation into xAPI 2.0; +- LTI 1.3; +- QTI 3; +- CASE 1.1; +- Open Badges 3.0; +- CLR 2.0; and +- accessibility-related contract metadata. + +A standards name in this list records adoption intent or contract scope. It is **not** by itself implementation, conformance, certification, endorsement, or production evidence. + +## Current bootstrap contract + +The foundation includes a versioned learning-domain event envelope at: + +`schemas/v1/learning-event.schema.json` + +Its logical identity is version-derived rather than branch-derived, and repository quality checks validate JSON Schema Draft 2020-12 semantics plus an executable RFC 3339/date-time boundary. The contract and its maturity remain source evidence until protected integration and an immutable release establish a distributable consumer authority. + +## How products should consume contracts + +Production consumers should depend on an **immutable released contract artifact/revision with verifiable provenance**, not a mutable branch, open pull request, sibling checkout, or copied source fragment. + +Consumer applications own their own Anti-Corruption Layer and runtime state. This repository owns the shared wire/profile contract only. In particular: + +- Learning Management Platform owns learner/enrollment/completion application state; +- Learning Content Studio owns authored content and publication authority; +- Learning Record Store owns canonical learning-record evidence; +- Psychometrics Commons owns assessment-session/response/result evidence; +- numerical psychometric estimation remains outside this contract repository; and +- no consumer may treat this repository as a shared application database. + +Until the first protected immutable release exists, current branch files are suitable for review and development only, not as a claim of released ecosystem compatibility. + +## Contributor quick start + +Repository quality is intentionally lightweight and contract-focused. The canonical validation workflow is [`.github/workflows/quality.yml`](.github/workflows/quality.yml); it uses Python 3 with pinned `jsonschema==4.26.0` and `rfc3339-validator==0.1.4` to validate required documentation, every committed schema, immutable schema identity, semantic-version/path alignment, and timestamp behavior. + +Before changing or adding a contract: + +1. read the [architecture boundary](docs/ARCHITECTURE.md); +2. check [standards traceability](docs/doctoring/STANDARD_TRACEABILITY.md) for the normative source and current adoption status; +3. preserve versioned schema/profile identity and backward-compatibility rules; +4. add or update executable fixtures/conformance evidence with the contract; and +5. run the repository quality contract and require fresh exact-head CI before integration. + +Do not copy official standards text, assessment content, descriptors, logos, or other rights-controlled material into a contract merely because the repository references that standard. + +## Architecture and evidence boundary + +This repository is a Shared Kernel for **interoperability contracts**, not for foreign product implementation. Contracts must be provider-neutral, versioned, provenance-aware, and narrow enough that consumers can validate them without importing another product's private runtime model. + +Key evidence rules: + +- `Adopted` does not mean `Implemented`. +- `Implemented` does not mean `Conformant`. +- local or repository conformance evidence does not mean third-party `Certified`. +- an open PR is not an immutable release. +- mutable branch URLs and sibling source trees are not production dependency authority. +- a future `Implemented` or `Conformant` claim must identify the normative requirement, implementation location, executable fixture/test, and exact-head evidence that supports it. + +## Documentation + +- [Architecture](docs/ARCHITECTURE.md) — contract ownership and integration boundaries. +- [Standards traceability](docs/doctoring/STANDARD_TRACEABILITY.md) — normative-source and adoption evidence. +- [Product and technical gap baseline](docs/product-technical-gap-baseline.md) — current maturity and commercialization gaps. +- [Public documentation landing](docs/index.md) — concise repository navigation and publication boundary. +- [CHANGELOG](CHANGELOG.md) — integrated source-history notes, not release evidence by itself. +- [GitHub Releases](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/releases) — immutable published releases when available. + +## Branch and release authority + +Product work targets `develop`. Promotion to `main` occurs only through the repository's protected process after exact-head validation and applicable review/security gates. A source commit on either branch is not automatically a published consumer release; release/version/artifact provenance must agree on the exact protected source. + +## License + +ContextualWisdomLab-authored source and documentation in this repository are licensed under the [Apache License 2.0](LICENSE). + +That repository grant does not relicense standards, schemas or assets copied from external authorities, generated material with separate terms, future package dependencies, certification marks, or external services. Every imported or derived component remains subject to independent provenance and commercial-license review. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..3a6d1b3 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,13 @@ +# Architecture + +This repository owns versioned learning interoperability contracts and no application runtime state. + +Primary families: xAPI 2.0, cmi5 Quartz compatibility, LTI 1.3, QTI 3, CASE 1.1, Open Badges 3.0, and CLR 2.0. + +Authority boundaries: +- Learning Management Platform: offerings, enrollment, progression, completion policy. +- Learning Content Studio: authoring state and immutable releases. +- Learning Record Store: xAPI statements and document resources. +- Psychometrics Commons: assessment sessions, responses, and score snapshots. + +Consumers integrate through versioned contracts; cross-repository database access is not part of the architecture. diff --git a/docs/PRD.md b/docs/PRD.md new file mode 100644 index 0000000..d5ac103 --- /dev/null +++ b/docs/PRD.md @@ -0,0 +1,109 @@ +# Product requirements document + +## Product + +**Learning Interoperability Contracts** is the provider-neutral contract authority for the ContextualWisdomLab learning ecosystem. It gives product teams and external integrators immutable, versioned definitions for exchanging learning-domain data without sharing product databases or leaking one runtime's internal model into another. + +## Customer problem + +Learning products fail to compose commercially when every service independently interprets xAPI, cmi5, assessment, credential, content and learning-platform payloads. The resulting schema drift produces silent semantic loss, brittle point-to-point adapters, version ambiguity and buyer-visible integration failures. + +The product must make the safe integration path easier than copying a schema or inferring another product's database model. + +## Primary customers and jobs to be done + +### ContextualWisdomLab product teams + +- select a released contract and know exactly which semantic/version boundary it represents; +- validate produced and consumed payloads against executable positive and negative evidence; +- distinguish canonical contracts from explicitly supported compatibility surfaces; +- upgrade contracts without silently changing historical meaning; +- generate or consume typed SDK surfaces without importing another product's runtime state. + +### External integrators and platform operators + +- pin an immutable supported contract release; +- identify breaking versus compatible changes before deployment; +- reproduce validation results from public fixtures and release provenance; +- understand which standards are adopted, implemented, conformant, certified or intentionally unsupported without marketing ambiguity. + +## Product principles + +1. **Contracts, not runtime truth.** Learner, enrollment, content-authoring, xAPI statement-store, assessment and payment truth remain in owning bounded contexts. +2. **Immutable release identity.** A logical schema/profile identity is not a supported release until an immutable artifact and provenance receipt bind that identity to exact bytes. +3. **No silent translation.** Compatibility mappings must preserve the source protocol/version boundary; cmi5 Quartz/xAPI 1.0.3 may not be relabelled as xAPI 2.0 history. +4. **Fail closed.** Unknown versions, unsupported fields, semantic loss and missing evidence reject rather than degrade silently. +5. **Evidence-qualified claims.** Adoption, implementation, conformance and certification are distinct states. +6. **Provider neutrality.** Shared contracts must not encode a specific service's storage layout, internal class hierarchy or deployment topology. +7. **Public-safe fixtures.** Tests and documentation use synthetic/non-identifying examples and do not redistribute licensed specification text beyond permitted use. + +## Core product capabilities + +### Versioned contract authority + +- semantic-versioned JSON Schema/OpenAPI/AsyncAPI/profile artifacts where appropriate; +- immutable logical identifiers derived from contract identity and semantic version; +- explicit compatibility and deprecation policy; +- deterministic release bundle/provenance mapping. + +### Conformance evidence + +- machine-valid schemas; +- positive and deliberately invalid fixtures for every owned invariant; +- consumer-driven cross-language fixtures where format behavior can differ by validator/runtime; +- requirement-level traceability before an `Implemented` or `Conformant` standards claim. + +### Compatibility boundaries + +- canonical xAPI 2.0 contract family; +- explicit cmi5 Quartz/xAPI 1.0.3 compatibility family; +- future LTI, QTI, CASE, credentials and accessibility-related mappings kept version-specific; +- anti-corruption boundaries in consumers rather than a shared runtime/database kernel. + +### Generated client contracts + +Rust, TypeScript and Python package boundaries may be generated only from released reusable contract authority. Generated output must be reproducible, version-bound and covered by consumer conformance evidence before it is advertised as supported. + +## Current commercialization slice + +The bootstrap parent establishes repository authority, a versioned learning-event envelope candidate, Draft 2020-12 validation, timestamp edge cases, architecture/ADR/standards evidence, explicit PRD/TRD and exact-head quality gates. Issue #3 / PR #7 adds a separate internal protocol-selection candidate for xAPI 2.0 versus cmi5 Quartz without claiming statement/profile conformance. + +Neither surface is a released supported contract until the protected integration/release gates below complete. + +## Release gates + +A contract surface is commercially supportable only when the exact release candidate has: + +- machine-valid schemas and required positive/negative fixtures; +- immutable logical version identity plus immutable release artifact mapping; +- applicable requirement-level standards traceability; +- successful exact-head repository quality, security/SAST and independent review evidence; +- reproducible package/bundle output and provenance/SBOM when executable/generated dependencies exist; +- compatibility/deprecation notes and a CHANGELOG entry; +- no unresolved substantive review thread. + +## Success measures + +- zero production integrations depend on cross-repository database reads; +- every supported contract is pinned by immutable version/artifact identity; +- every breaking contract change is mechanically detectable or deliberately versioned; +- every standards implementation claim has executable requirement-level evidence; +- consumer teams can reproduce contract validation without private infrastructure; +- no buyer-facing documentation represents an unreleased candidate as a supported release. + +## Non-goals + +- operating an LMS, LCMS, LRS or assessment service; +- storing authoritative learner/content/statement/score state; +- psychometric or mathematical computation; +- silently upgrading historical protocol records; +- copying proprietary or licensed normative text into fixtures; +- providing a generic integration database or enterprise service bus. + +## Roadmap and issue linkage + +1. **Issue #2 / PR #1:** protected bootstrap authority, PRD/TRD, release/provenance baseline. +2. **Issue #3 / PR #7:** explicit protocol selection, then provider-neutral xAPI 2.0 statement/profile conformance evidence. +3. **Issue #4 / PR #5:** CEFR assessment profile after parent authority is protected truth. +4. **Issue #6:** generated SDKs and cross-repository consumer conformance. +5. First immutable public contract release only after the complete release gates are evidenced on the protected candidate. diff --git a/docs/TRD.md b/docs/TRD.md new file mode 100644 index 0000000..72c31da --- /dev/null +++ b/docs/TRD.md @@ -0,0 +1,119 @@ +# Technical requirements document + +## System responsibility + +`learning-interoperability-contracts` is an artifact-oriented **Learning Contract Authority** bounded context. It produces versioned, provider-neutral schemas/profiles/mappings, fixtures and generated-client contracts. It is not a network service, runtime database or owner of learning-domain transactional state. + +## Architecture + +```text + Learning Contract Authority + / | \ + schema/profile fixtures release artifacts + | | | + +-------------+--------------+ + | + released version + | + +---------------+----------------+ + | | | + LMS/Platform Content Studio LRS/other + ACL/adapter ACL/adapter ACL/adapter + | | | + owning state owning state owning state +``` + +Shared-kernel scope is deliberately minimal: immutable contract artifacts only. Each consumer owns its anti-corruption layer, transaction boundaries and persistence. + +## Domain model + +### Core value objects + +- `contract_version`: semantic version of one contract surface; +- `schema_identity`: immutable logical identifier derived from contract name and semantic version; +- `profile_version`: explicit version of a reusable profile surface; +- `compatibility_surface`: named version-specific compatibility boundary; +- `conformance_fixture`: positive or negative executable evidence for an owned invariant; +- `provenance_reference`: immutable identity of the exact released artifact/build evidence. + +### Aggregate boundary + +A **Contract Release Bundle** is the artifact-level aggregate. Once released, its contract identities, manifest and bytes are immutable. Mutable authoring of contracts occurs in Git branches/PRs; there is no runtime relational aggregate or database repository. + +### Domain invariants + +- a released logical contract version maps to exactly one immutable artifact identity; +- a contract artifact never claims ownership of another bounded context's runtime state; +- incompatible protocol versions cannot be silently coerced into one surface; +- unsupported/unknown versions fail closed; +- release metadata cannot claim `Implemented`, `Conformant` or `Certified` without the required evidence class; +- fixtures contain no real person/institution identifiers and no impermissibly copied normative text. + +## Repository layout + +- `schemas//...` — versioned general contract schemas; +- `profiles///...` — versioned profile/compatibility contracts; +- `fixtures//{valid,invalid}/...` — public conformance/contract fixtures; +- `tests/` — executable repository/consumer contract tests; +- `docs/adr/` — architecture decisions; +- `docs/doctoring/` — standards/research traceability; +- future `release/` or equivalent — machine-readable bundle manifests/provenance only after release contract is specified; +- future generated SDK directories — generated from released contract authority, never hand-maintained as divergent truth. + +## Versioning and compatibility + +Semantic version is explicit for every reusable public contract. Major versions represent incompatible contract identity. Minor/patch compatibility policy must be encoded per surface before the first supported release. + +Logical `$id`/contract identifiers are immutable names, not mutable branch URLs. Support requires a separate immutable release mapping from logical version to exact artifact bytes/provenance. + +Compatibility adapters remain version-specific. The issue #3 xAPI protocol-binding candidate keeps canonical xAPI 2.0 distinct from cmi5 Quartz/xAPI 1.0.3 and carries no xAPI statement payload. + +## Validation + +Current repository Quality must: + +1. check required product/technical/architecture/traceability documents; +2. validate JSON Schema Draft 2020-12 metaschema semantics rather than JSON syntax only; +3. execute date-time format assertion plus lexical/calendar edge cases for the learning-event envelope; +4. execute additional surface-specific valid/invalid fixtures as they are introduced; +5. run on stacked pull requests as well as protected-default-branch PRs; +6. check out the exact PR head with persisted credentials disabled. + +Executable SDK/conformance code introduced later must reach 100% production statement/branch coverage for touched surfaces and public documentation coverage, with warnings treated as defects rather than suppressed. + +## Standards evidence + +`docs/doctoring/STANDARD_TRACEABILITY.md` is the current evidence ledger. A standard may be adopted without implementation. Before `Implemented`/`Conformant` language is allowed, traceability must bind: + +- precise versioned normative requirement; +- implementation location; +- executable positive/negative fixture or test; +- terminal-success exact-head CI receipt. + +External certification is a separate state and cannot be inferred from local validation. + +## Security and supply chain + +- GitHub Actions use least-privilege read permissions unless a write is materially required; +- external actions and executable tooling are version/checksum pinned where practical; +- protected integration requires current-head central security/SAST/review evidence; +- generated packages/releases require provenance and SBOM appropriate to their dependency surface; +- no secrets or PII belong in contract fixtures; +- there is no runtime service attack surface in the current product boundary. + +## Persistence + +No relational persistence belongs to this bounded context. If an operational release registry is ever required, the authoritative source remains immutable release artifacts; registry/cache storage must be a projection behind an ACL. Generic one-word persistence object names are disallowed if such storage is introduced, and any relational design must remain normalized rather than becoming a cross-product shared kernel. + +## Delivery and operability + +No web service, compose stack, k6 target, GPU/CPU math path or Kubernetes runtime is warranted by the current artifact-only architecture. Those requirements become applicable only if the product boundary intentionally adds an executable service; such a decision requires a new ADR rather than incidental infrastructure. + +## Current technical gaps + +- no protected immutable release bundle/provenance mapping yet; +- no complete xAPI 2.0 statement/profile conformance surface; +- no portable cross-language timestamp fixture runner across supported consumer languages; +- no generated Rust/TypeScript/Python SDK release artifacts; +- no OpenAPI/AsyncAPI surface where a concrete reusable protocol endpoint/event contract warrants one; +- no consumer-driven cross-repository compatibility matrix. diff --git a/docs/adr/0001-contract-authority-boundary.md b/docs/adr/0001-contract-authority-boundary.md new file mode 100644 index 0000000..de3b8bd --- /dev/null +++ b/docs/adr/0001-contract-authority-boundary.md @@ -0,0 +1,16 @@ +# ADR 0001: Contract authority boundary + +## Status + +Accepted + +Approved by: ContextualWisdomLab repository owner +Approval date: 2026-08-19 + +## Decision + +This repository is the single CWL authority for shared learning interoperability schemas, profiles, generated clients, and conformance fixtures. It does not own runtime learner, content, assessment, or learning-record state. + +## Consequences + +Consumer repositories may depend on released contracts without acquiring this repository's implementation internals. A breaking semantic change requires an explicit contract version rather than an in-place reinterpretation. diff --git a/docs/doctoring/STANDARD_TRACEABILITY.md b/docs/doctoring/STANDARD_TRACEABILITY.md new file mode 100644 index 0000000..33502fe --- /dev/null +++ b/docs/doctoring/STANDARD_TRACEABILITY.md @@ -0,0 +1,21 @@ +# Standards traceability + +Adoption status and implementation/conformance evidence are intentionally separate. `Adopt` records a product decision pinned to an identified specification revision; it does not imply implementation conformance or third-party certification. `Not evidenced (adoption only)` is therefore the expected bootstrap state until a consumer-facing contract surface has requirement-level executable evidence on an exact head. + +| Standard | Revision | Normative source | Scope | Adoption status | Evidence status | +|---|---|---|---|---|---| +| xAPI / ISO/IEC/IEEE 39274-1-1 | xAPI 2.0; ISO/IEC/IEEE 39274-1-1:2025 | https://www.iso.org/standard/91131.html | Canonical learning-experience record contract | Adopt | Not evidenced (adoption only) | +| cmi5 Quartz | Quartz, 1st Edition (2016), xAPI 1.0.3 compatibility | https://github.com/AICC/CMI-5_Spec_Current/blob/984a9b8/cmi5_spec.md | Version-pinned LMS launch and package compatibility | Adopt as compatibility profile | Not evidenced (adoption only) | +| LTI Core | 1.3.0 Final | https://standards.1edtech.org/lti/specifications/core/lti-spec1p3p1 | External learning-tool launch and security contract | Adopt | Not evidenced (adoption only) | +| LTI Assignment and Grade Services | 2.0 Final | https://standards.1edtech.org/lti/specifications/services/assignments_grades/assignment-grade-services-spec | Gradebook/result service interoperability | Adopt | Not evidenced (adoption only) | +| LTI Names and Role Provisioning Services | 2.0 Final | https://standards.1edtech.org/lti/specifications/services/names_roles/names-role-provisioning-spec | Context-scoped membership and role provisioning | Adopt | Not evidenced (adoption only) | +| LTI Deep Linking | 2.0 Final | https://standards.1edtech.org/lti/specifications/launch_messages/deep_linking/lti-deep-linking-spec | Tool-mediated content selection and return | Adopt | Not evidenced (adoption only) | +| QTI Assessment, Section, and Item | 3.0.1 | https://www.imsglobal.org/sites/default/files/spec/qti/v3/info/imsqti_asi_v3p0p1_infomodel_v1p0.html | Assessment item/test interchange | Adopt | Not evidenced (adoption only) | +| QTI Metadata | 3.0 | https://www.1edtech.org/standards/qti/index | Assessment metadata interchange | Adopt | Not evidenced (adoption only; requirement-level source must be pinned before implementation) | +| CASE Service | 1.1 Final | https://standards.1edtech.org/case/ | Competency and learning-outcome interchange | Adopt | Not evidenced (adoption only) | +| Open Badges | 3.0 Final | https://standards.1edtech.org/open-badges/ | Portable achievement credential | Adopt | Not evidenced (adoption only) | +| Comprehensive Learner Record | 2.0 Final | https://standards.1edtech.org/clr/ | Portable learner achievement record | Adopt | Not evidenced (adoption only) | +| WCAG | 2.2, W3C Recommendation 2024-12-12 | https://www.w3.org/TR/WCAG22/ | Accessible learning and contract-facing web content | Adopt | Not evidenced (adoption only) | +| ATAG | 2.0, W3C Recommendation 2015-09-24 | https://www.w3.org/TR/ATAG20/ | Accessible authoring-tool contract | Adopt | Not evidenced (adoption only) | + +An adoption row may remain `Not evidenced (adoption only)` indefinitely if no implementation surface is introduced. Before an implementation PR can claim `Implemented`, `Conformant`, or equivalent language, it must pin the precise normative requirement, implementation location, executable fixture/test path, and exact-head CI receipt. A moving overview page is insufficient evidence for a requirement-level implementation claim and must be replaced by the applicable versioned specification section when that surface is implemented. Certification claims additionally require the applicable external certification process and may not be inferred from adoption, implementation, passing local tests, or documentation alone. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..dad441d --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +--- +title: Learning Interoperability Contracts +--- + +# Learning Interoperability Contracts + +Learning Interoperability Contracts is the provider-neutral contract authority for shared learning schemas, profiles, mappings, conformance fixtures, and generated-client contracts across the ContextualWisdomLab learning ecosystem. + +## Start here + +The repository owns interoperability contracts rather than learner/application runtime state or product databases. Start with the [README](https://github.com/ContextualWisdomLab/learning-interoperability-contracts#readme) for scope and branch authority, then use the product requirements, technical requirements, architecture and standards traceability documents for contract changes. + +## Contract responsibility + +The current standards portfolio includes xAPI 2.0, cmi5 Quartz compatibility, LTI 1.3, QTI 3, CASE 1.1, Open Badges 3.0, CLR 2.0, and accessibility-related contract metadata. Adoption intent is kept distinct from implementation, conformance, certification, and protected-release evidence. + +## Documentation + +- [README](https://github.com/ContextualWisdomLab/learning-interoperability-contracts#readme) — repository scope and branch model. +- [Product requirements](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/blob/develop/docs/PRD.md) — customer problem, product principles, support gates and roadmap. +- [Technical requirements](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/blob/develop/docs/TRD.md) — bounded-context architecture, invariants, validation, supply-chain and release requirements. +- [Architecture](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/blob/develop/docs/ARCHITECTURE.md) — contract architecture and ownership boundaries. +- [Standards traceability](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/blob/develop/docs/doctoring/STANDARD_TRACEABILITY.md) — normative standards evidence and adoption status. +- [Product and technical gap baseline](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/blob/develop/docs/product-technical-gap-baseline.md) — remaining evidence and commercialization gaps. +- [Releases](https://github.com/ContextualWisdomLab/learning-interoperability-contracts/releases) — immutable published contract releases when available. +- [Ask DeepWiki](https://deepwiki.com/ContextualWisdomLab/learning-interoperability-contracts) — repository-grounded questions and code navigation. + +## Evidence boundary + +A schema or profile in an open pull request is not an immutable protected release. A standards name in documentation is not conformance or certification evidence. Customer- and integrator-facing claims should be backed by the current protected revision and the applicable immutable release, fixture, and CI evidence. + +This file is a public documentation landing source. GitHub Pages publication is a separate repository-facing state and must be verified live before it is claimed available. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md new file mode 100644 index 0000000..11b9056 --- /dev/null +++ b/docs/product-technical-gap-baseline.md @@ -0,0 +1,46 @@ +# Product and technical gap baseline + +Last reconciled: 2026-09-02 + +This ledger is derived from the current product boundary, ADRs, standards traceability, open issues, open pull requests, and exact-head GitHub evidence. It is a commercialization planning artifact, not a conformance or certification claim. Live GitHub Check state is intentionally not persisted as `queued`/`running`/`passed` here because that state changes outside the repository; merge decisions must re-fetch the current PR head and live required Checks. + +## Product responsibility + +`learning-interoperability-contracts` is the ContextualWisdomLab authority for versioned, provider-neutral learning interoperability contracts, schemas, profiles, mappings, conformance fixtures, and reproducible generated-client contracts. It owns no learner/application runtime state and no product database. Learning Management Platform owns enrollment/progression/completion policy; Learning Content Studio owns authored content and releases; Learning Record Store owns xAPI records and document resources; Psychometrics Commons and mathematical engines own assessment state and numerical measurement work. + +## Current baseline + +| Area | Evidence | Status | Commercialization gap | Next verification | +| --- | --- | --- | --- | --- | +| Product/technical authority | `docs/PRD.md`, `docs/TRD.md`, ADR 0001, README, ARCHITECTURE | **Defined on bootstrap writer branch and required by repository Quality** | Product support claims remain candidates until protected integration/release evidence exists | Exact-head Quality must prove the documents and implementation remain mutually consistent; future scope changes require PRD/TRD/ADR updates in the same PR | +| Learning event envelope | `schemas/v1/learning-event.schema.json` uses versioned path `v1`, `x-cwl-schema-version: 1.0.0`, and immutable logical `$id` `urn:contextualwisdomlab:learning-interoperability-contracts:learning-event:1.0.0` | Bootstrap candidate, not released/implemented evidence | The logical identifier is no longer mutable, but no protected release bundle currently binds version `1.0.0` to an immutable supported artifact | Establish the first protected immutable release and publish a machine-readable version-to-artifact/provenance mapping before consumers treat the URN as a supported release | +| JSON Schema validity | Quality workflow pins `jsonschema==4.26.0` and `rfc3339-validator==0.1.4`, runs `Draft202012Validator.check_schema`, and includes a negative metaschema regression | Candidate validation; live external merge gate | A passing predecessor head cannot establish current-head evidence; portable consumer behavior still depends on an explicit format-assertion policy | At merge time re-fetch the exact current head and require successful quality/security/SAST/review evidence; add consumer conformance fixtures before release | +| Quality runner admission | Pre-repair exact head `2fe6057a8e184b7aeb5466a216c1fce002556c73` had Learning Contracts Quality run `33519534179` / job `99894993068` queued with no executed steps while using `ubuntu-latest`; sibling Learning Content Studio exact-head quality had already completed successfully on explicit `ubuntu-24.04` | **Causal selector repair committed on the canonical bootstrap writer branch** | A selector change is not itself a green check and predecessor runner evidence is non-transferable | Fresh exact-head Quality must acquire `ubuntu-24.04`, execute immutable checkout and all schema/timestamp/document gates, then complete terminal-success without weakening central security/review gates | +| Stacked PR repository quality | Original workflow limited `pull_request` bases to `develop` and `main`; issue #3 is intentionally stacked on the bootstrap branch | **Repaired at the reusable owner:** canonical bootstrap workflow uses `pull_request: {}` while protected-branch push triggers remain unchanged; issue #3 PR #7 independently demonstrated that the generic trigger schedules repository Quality on a feature-branch base | Scheduled is not the same as successful, and central organization review/security gates remain distinct | Require terminal-success exact-head repository Quality on stacked PR #7 and retain ordinary central review/security/protected integration gates | +| Timestamp contract | Range-constrained lexical pattern plus repository `Draft202012Validator(..., format_checker=FormatChecker())`, an activation check for impossible dates, parser-backed calendar checks, and positive/negative edge cases | **Blocked for portable consumer contract; repository gate implemented** | The committed lexical pattern intentionally does not encode month-specific/leap-year calendars, and JSON Schema 2020-12 `format` may be annotation-only for consumers that do not enable format assertion. The repository gate rejects impossible dates, but that alone does not prove equivalent cross-language consumer behavior | Keep the repository negative fixtures for invalid dates, leap-year boundaries, times and UTC offsets; define and execute a portable consumer format-assertion/conformance fixture contract before promoting this surface to released candidate | +| Standards portfolio | `docs/doctoring/STANDARD_TRACEABILITY.md`, AGENTS.md | Adoption decisions recorded; conformance not evidenced on the bootstrap parent | Adoption and implementation evidence are separated; requirement-level executable evidence is still absent for unimplemented surfaces and QTI Metadata still needs a requirement-level source before implementation | Pin exact normative requirements/test paths as each surface becomes executable; never promote adoption to conformance without exact-head evidence | +| xAPI/cmi5 interoperability | Issue #3; stacked PR #7 carries a test-first explicit protocol-binding slice | Active stacked implementation | Bootstrap parent itself still has no protected released xAPI contract; PR #7 is intentionally partial and must not be treated as statement/profile conformance | Complete PR #7 exact-head review/checks, integrate parent first, then retarget/restack and reverify the issue #3 slice through protected `develop` | +| CEFR assessment profile | PR #5 stacked on bootstrap; issue #4 | Candidate on stacked draft branch | Cannot be merge-ready until bootstrap lands and the stack is deliberately rebased/retargeted and reverified | Merge bootstrap first, restack PR #5 onto protected `develop`, rerun exact-head checks and independent review | +| Generated SDKs and cross-repository conformance | Issue #6 | Planned | No released Rust/TypeScript/Python generated contracts or consumer-driven interoperability proof | Implement after the core CEFR profile, preserving contract-only repository boundary | +| Release/package evidence | No protected released contract baseline yet | Missing | Consumers cannot pin an immutable supported contract release even though the schema has an immutable logical URN | Establish first release, changelog/version policy, version-to-artifact mapping, provenance/SBOM where applicable, and immutable release receipts | +| Operability/security | Security/SAST workflows exist; repository-local quality pins `ubuntu-24.04` and no longer excludes stacked PR bases | Live external gate | No runtime service belongs here; committed CI status would become stale immediately and central security/review lanes remain independent gates | Keep repository read-only at runtime and require current-head supply-chain/security/generated-artifact evidence at merge/release time | + +## DDD/context map + +This repository is a generic interoperability subdomain. Its bounded context is **Learning Contract Authority**. Its ubiquitous language includes `contract_version`, `schema_version`, `profile_version`, `provenance_reference`, `compatibility_surface`, and `conformance_fixture`. Contract schemas and profile definitions are versioned value objects; released contract bundles are immutable release aggregates. Consumer repositories integrate through released artifacts only and must not acquire this repository's internal build tooling or cross-read another product database. + +No shared-kernel database is permitted. Compatibility adapters belong in the consuming/owning runtime boundary unless the output is itself a reusable versioned interoperability mapping; such mappings may live here but remain non-authoritative for source application state. + +## Release gates + +A commercialization claim for a contract surface requires all of the following on the exact candidate head: schema/metaschema validation, positive and deliberately invalid fixtures, provenance/version invariants, applicable standards traceability, security/SAST checks, independent review, and an immutable release identifier bound to an immutable released artifact. A product adoption decision is not implementation conformance, and implementation conformance is not third-party certification. + +## Active gap order + +1. Land bootstrap PR #1 only after its live current-head checks and unresolved review gates are satisfied. +2. Establish the first immutable release bundle and version-to-artifact/provenance mapping for the already-versioned schema URN. +3. Complete issue #3 executable xAPI 2.0/profile conformance while retaining the cmi5 Quartz/xAPI 1.0.3 compatibility boundary; PR #7 is only the protocol-selection slice. +4. Add portable/cross-language timestamp conformance fixtures that make the required format-assertion behavior executable for consumers. +5. Restack and verify PR #5 for issue #4 after the bootstrap parent is protected-branch truth. +6. Implement issue #6 generated SDKs and cross-repository consumer conformance. +7. Continue replacing moving standards overview links with revision/requirement-level normative evidence as each surface becomes executable. diff --git a/schemas/v1/learning-event.schema.json b/schemas/v1/learning-event.schema.json new file mode 100644 index 0000000..73b6bb3 --- /dev/null +++ b/schemas/v1/learning-event.schema.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:contextualwisdomlab:learning-interoperability-contracts:learning-event:1.0.0", + "x-cwl-schema-version": "1.0.0", + "title": "CWL Learning Domain Event Envelope", + "type": "object", + "additionalProperties": false, + "required": ["event_id", "event_type", "event_version", "tenant_id", "occurred_at", "recorded_at", "provenance_reference"], + "properties": { + "event_id": {"type": "string", "minLength": 1}, + "event_type": {"type": "string", "minLength": 3}, + "event_version": {"type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"}, + "tenant_id": {"type": "string", "minLength": 1}, + "subject_reference": {"type": ["string", "null"]}, + "occurred_at": { + "type": "string", + "format": "date-time", + "description": "RFC 3339 timestamp. Upper- or lower-case T/Z separators are accepted. This v1 contract rejects leap-second lexical forms (:60); executable validation also checks calendar validity.", + "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])[Tt](?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]+)?(?:[Zz]|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$" + }, + "recorded_at": { + "type": "string", + "format": "date-time", + "description": "RFC 3339 timestamp. Upper- or lower-case T/Z separators are accepted. This v1 contract rejects leap-second lexical forms (:60); executable validation also checks calendar validity.", + "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])[Tt](?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]+)?(?:[Zz]|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$" + }, + "correlation_id": {"type": ["string", "null"]}, + "causation_id": {"type": ["string", "null"]}, + "provenance_reference": {"type": "string", "minLength": 1}, + "data": {"type": "object"} + } +}