OER Schema Audit (Read-Only Diagnostic)
SkillDocs & knowledgeREAD-ONLY diagnostic: review authored HAX page HTML, site.json outline nodes, VitePress markdown directives, JSON-LD blocks, and Google Docs export HTML against the OER Schema vocabulary (Course/Unit/Module/Lesson, LearningObjective, Assessment/Quiz/Activity/Project, Task/Practice, Rubric family, SupportingMaterial, TableOfContents, ActionType verbs) and emit a report with the recommended class, properties, and markup surface for every finding. Use when the user says "audit this page for OER schema", "what schema should this lesson have", "is this quiz marked up as the right oer class", "does my site.json map to oerschema", "check my VitePress directives against the vocabulary", "scan my site for content missing oerschema", or "which of these pages need oer schema" — even if they don't say "audit" or "oerschema". Diagnoses only; hands off to hax-claudehax / hax-site-building to apply remediation and to oerschema-integration-finder when the gap is in a component (code), not the content.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the OER Schema Audit (Read-Only Diagnostic) skill
What this skill tells your AI
The instructions your AI receives, as published by haxtheweb/haxcms-php in .well-known/agent-skills/oerschema-audit/SKILL.md and read by ahel’s review.
Review authored content on an existing HAX site/page (or VitePress / JSON-LD / Docs-export content)
against the OER Schema vocabulary and emit a diagnostic + remediation report. This skill
diagnoses and recommends only — it does not edit pages, mutate site.json, or insert markup.
It mirrors the hax-a11y-audit / hax-udl-audit pattern but operates through the OER Schema lens:
does the authored content carry the correct semantic pedagogical structure that makes it
discoverable and interoperable as an open educational resource?
The worldview in one paragraph
OER Schema is a vocabulary that extends schema.org with education-specific terms (Course,
LearningObjective, Assessment, Rubric, etc.) so educational content is machine-readable and
interoperable. The HAX ecosystem commits to applying OER Schema metadata to educational elements,
and the UbD skill family already produces OER-schema-tagged unit skeletons — but no existing skill
audits authored content to see whether the schema is present and correct. This skill fills that
gap. It is distinct from a11y (technical access for people with disabilities), from UDL
(pedagogical inclusivity), from content chunking (cognitive load), and from UbD unit audit
(instructional-design alignment). It is also distinct from component-internal schema support
(an element's own code not emitting microdata), which oerschema-integration-finder owns. This
audit reports what is missing or mis-classified, cites the class/property, and recommends only real
remediation in the right markup surface — never an invented tag or property.
When to Use
Trigger conditions:
- "Audit this page for OER schema" / "what schema should this lesson have"
- "Is this quiz marked up as the right OER class" / "does my site.json map to oerschema"
- "Check my VitePress directives against the vocabulary" / "is this JSON-LD valid OER schema"
- "Scan my site for content missing oerschema" / "which of these pages need OER schema"
- "What OER class should I use for a group project" (when the user is reviewing authored content)
- even when the user does not say "OER schema" or "audit" — if they question whether authored educational content carries the right semantic metadata, this is the skill
When NOT to use (with redirect):
- A web component's own code doesn't emit schema (the gap is in the element, not the page) →
oerschema-integration-finder - Technical WCAG access of the content →
hax-a11y-audit - Pedagogical inclusivity / multiple means →
hax-udl-audit - Page-scope cognitive load / chunking →
hax-content-chunking-audit - Unit alignment / backward design / are assessments aligned →
hax-ubd-unit-audit - Cognitive level of an objective/assessment (Bloom's) →
grad-blooms - Editing the OER Schema vocabulary itself (
schema.ts) →oerschema-schema-author(repo-local) - Validating
schema.tsinternal consistency →oerschema-validation(repo-local)
Scope: this skill is READ-ONLY
This skill diagnoses and recommends only. It produces a report. To apply remediation, hand off
to the related skills and the hax CLI / hax-claudehax (see "Implementing the Recommendations"
below). Never edit pages/*.html, site.json, VitePress markdown, or source files from within
this skill.
Inputs
- a HAX site path:
site.json(JOS tree) +pages/*.html, or a single page (JOS node / raw HTML / markdown) - or a VitePress markdown file using
::: learning-objective/::: assessment/::: rubric/::: practice/::: instructional-patterndirectives - or a JSON-LD block (a
<script type="application/ld+json">or a standalone.jsonld) - or Google Docs export HTML (the
itemscope itemtype="http://oerschema.org/..."microdata the Apps Script add-on emits) - optional
pageSlugto scope the audit to one page (else audit every page and report site-level patterns)
Methodology
- Ingest structure. Locate the content and identify which markup surface(s) are present:
- HAX:
site.json(JOS tree + metadata) +pages/<slug>.html(rendered content) - VitePress:
:::container directives (seereferences/markup-surfaces.md) - JSON-LD:
<script type="application/ld+json">blocks - Docs export:
itemscope/itemtype/itempropmicrodata
- HAX:
- Load the vocabulary. Consult
references/vocabulary.mdfor the class hierarchy and the property domain/range tables (derived fromschema.tsv1.2.0). This is the single source of truth for what classes and properties exist and where each property is valid. - Run the OER Schema checks across authored content. For each page/block, evaluate:
- Presence: pedagogical structures are present in the content but carry no OER Schema
markup at all. A lesson page with heading "Lesson 3", a quiz section, learning objectives
stated in prose, and a rubric table — but no
itemscope/itemtype/itempropor directives — is a presence gap. Identify the most specific class for each structure (see mapping refs). - Classification: schema is present but the class is wrong or too generic. A quiz tagged
itemtype="http://oerschema.org/Task"should beAssessment(orQuiz, which subclassesAssessment). A unit page taggedLearningComponentcould be the more specificInstructionalPattern→Unit. Report the current type and the recommended type. - Property/domain validity: a property is used on a class outside its
domain.skillis domainLearningObjective— usingitemprop="skill"on anAssessmentis invalid.hasLearningObjectiveis domainInstructionalPattern— using it on a bareTaskis invalid (aTaskis anInstructionalPatternsubclass, so it is valid via inheritance — usereferences/vocabulary.mdand the inheritance rule before flagging). Report the property, the class it was used on, and the declared domain. - Range validity: a property's value type doesn't match its
range.gradingFormatrange isGradeFormat | Text— a raw number ongradingFormatshould be aPointGradeFormator text.assessingrange isActivity— pointingassessingat aQuizis invalid (Quizis anAssessment, not anActivity). Report the property, the value, and the declared range. - subClassOf chain: a declared
itemtypedoesn't resolve.itemtype="http://oerschema.org/Foo"whereFoois not a class in the vocabulary. Report the unresolved type. - Inverse consistency: an inverse pair is used one-directionally without its partner, or a
relationship that should be reciprocal is dangling (e.g.
forComponentwithout a matchinghasComponenton the parent). Note:forComponent/hasComponentdeclare themselves inverses in their comments but do not set theinverseOffield inschema.ts— flag the content gap (missing reciprocal link), not the vocabulary gap (which isoerschema-validation's job). - Rubric family integrity: a
Rubricshould havehasCriterion→RubricCriterionandrubricScale→RubricScale→hasLevel→RubricLevel. A rubric directive with levels but no scale, or criteria with nocriterionWeight, is a structural gap. - ActionType usage: a
Task/Practice/Activitywith atypeOfActionvalue that is not one of theActionTypesubclasses (Reading, Writing, Making, Researching, Listening, Watching, Reflecting, Discussing, Observing, Presenting, Assess). Report the invalid action value.
- Presence: pedagogical structures are present in the content but carry no OER Schema
markup at all. A lesson page with heading "Lesson 3", a quiz section, learning objectives
stated in prose, and a rubric table — but no
- Map each finding to a concrete remediation in the right surface. Use
references/markup-surfaces.mdto pick the surface the content is already in (microdata for HAX pages / Docs export,:::directives for VitePress, JSON-LD for structured-data blocks). Usereferences/hax-outline-mapping.mdfor site.json → class mapping andreferences/ubd-mapping.mdwhen the content originated from a UbD unit. Every recommendation names the exact class, the exact properties, and the exact surface — so the post-audit conversation can apply it directly without re-deriving. - Apply the overlap / defer rules:
- Component-internal schema gap: if the reason content lacks schema is that the rendering
element doesn't emit microdata (e.g. a
quiz-elementwith noitemtype), defer tooerschema-integration-finder(code fix), not this skill (content fix). - Vocabulary bug: if the schema is wrong because
schema.tsitself has a brokensubClassOfor missinginverseOf, defer tooerschema-validation/oerschema-schema-author. - Pedagogical alignment: if the issue is that the objectives/assessments don't align with
desired understandings (not a schema problem), defer to
hax-ubd-unit-audit. - Cognitive level: if the issue is the Bloom's level of an objective, defer to
grad-blooms.
- Component-internal schema gap: if the reason content lacks schema is that the rendering
element doesn't emit microdata (e.g. a
- Determine the overall rating:
- Covered: all pedagogical structures carry correct, domain/range-valid schema. Minor
advisories (e.g. "consider the more specific
Quizover genericAssessment") may be noted but do not affect the rating. - Partial: some structures lack schema, or some properties are mis-classified, but the page has a recognizable semantic skeleton. Remediation is surgical.
- Uncovered: a pedagogically dense page (lessons, objectives, assessments, rubrics) with
zero OER Schema markup, or a structural break (every
itemtypeunresolved, or a rubric with no criteria/scale).
- Covered: all pedagogical structures carry correct, domain/range-valid schema. Minor
advisories (e.g. "consider the more specific
- Emit the report (format below), then an "Implementation handoff" block.
Expected Output Format
Format findings exactly like this structure (mirrors hax-a11y-audit / hax-udl-audit):
### 📊 OER Schema Diagnostics
* **Coverage Rating:** [Covered / Partial / Uncovered]
* **Primary Gap:** [the worst offender — one sentence, e.g. "Lesson 3 page has learning objectives, a quiz, and a rubric in prose but zero OER Schema markup."]
### 🔍 Findings & Remediation
* **{page slug / block / site-level} — {check name}**
* **Status:** [Fail / Partial / Pass-with-advisory]
* **Issue:** [the exact failing markup, e.g. "Quiz section uses itemtype='http://oerschema.org/Task' but a quiz is an Assessment (specifically a Quiz subclass)."]
* **OER Schema Rationale:** [cite the class/property, e.g. "Quiz subClassOf Assessment subClassOf InstructionalPattern; Task is a sibling of Assessment under InstructionalPattern, not a parent of Quiz."]
* **Recommended markup:** [exact class + properties + surface, e.g. "Use itemtype='http://oerschema.org/Quiz' with itemprop='gradingFormat' (range GradeFormat|Text) and itemprop='assessing' (range Activity) pointing at the activity being assessed. Surface: microdata in pages/lesson-3.html."]
* **{page slug / block / site-level} — {check name}**
* ...
### 🛠 Implementation handoff
* [one-line action per fix → skill/CLI + surface, e.g. "Add itemscope itemtype=Quiz to the quiz section in pages/lesson-3.html via direct edit or /hax."]
Worked example
Input — a HAX page (pages/lesson-3.html) containing:
<h2>Lesson 3: Photosynthesis</h2>
<p>Students will be able to explain the process of photosynthesis.</p>
<div class="quiz">
<h3>Quick Check</h3>
<ol><li>What are the reactants of photosynthesis?</li></ol>
</div>
<table class="rubric">
<tr><th>Criterion</th><th>Level 4</th><th>Level 1</th></tr>
<tr><td>Explanation accuracy</td><td>Complete</td><td>Fragmentary</td></tr>
</table>
Output:
### 📊 OER Schema Diagnostics
* **Coverage Rating:** Uncovered
* **Primary Gap:** Lesson 3 page has a learning objective, a quiz, and a rubric in prose/HTML but
zero OER Schema markup — none of the pedagogical structures are machine-readable.
### 🔍 Findings & Remediation
* **Page "lesson-3" — Presence (lesson + objective)**
* **Status:** Fail
* **Issue:** The page is a Lesson with a stated learning objective, but neither is tagged.
`h2 "Lesson 3: Photosynthesis"` implies `Lesson`; the objective paragraph implies
`LearningObjective`.
* **OER Schema Rationale:** `Lesson` subClassOf `InstructionalPattern` subClassOf
`LearningComponent`; `hasLearningObjective` (domain `InstructionalPattern`, range
`LearningObjective`) relates them. Without markup the lesson is not discoverable as an OER.
* **Recommended markup:** Wrap the lesson in
`<div itemscope itemtype="http://oerschema.org/Lesson">`; wrap the objective in
`<div itemprop="hasLearningObjective" itemscope itemtype="http://oerschema.org/LearningObjective">`
with `<meta itemprop="skill" content="explain the process of photosynthesis">` and
`<meta itemprop="description" content="...">`. Surface: microdata in pages/lesson-3.html.
* **Page "lesson-3" — Presence (quiz)**
* **Status:** Fail
* **Issue:** The `.quiz` div is an untyped quiz. It should be a `Quiz` (subClassOf `Assessment`).
* **OER Schema Rationale:** `Quiz` subClassOf `Assessment` subClassOf `InstructionalPattern`.
`Assessment` carries `assessing` (range `Activity`) and `gradingFormat` (range
`GradeFormat | Text`).
* **Recommended markup:** `<div itemscope itemtype="http://oerschema.org/Quiz">` on the quiz div;
add `<meta itemprop="gradingFormat" content="...">` if points are specified. Surface: microdata
in pages/lesson-3.html. (If this quiz is rendered by a HAX quiz element that emits no
microdata, also hand to oerschema-integration-finder for the component-level fix.)
* **Page "lesson-3" — Rubric family integrity**
* **Status:** Fail
* **Issue:** The `.rubric` table is a rubric with one criterion and two levels, but no
`Rubric`/`RubricCriterion`/`RubricScale`/`RubricLevel` markup.
* **OER Schema Rationale:** `Rubric` has `hasCriterion` → `RubricCriterion` and `rubricScale` →
`RubricScale` → `hasLevel` → `RubricLevel`. The two-level table maps to a scale with two levels.
* **Recommended markup:** Wrap in `<div itemscope itemtype="http://oerschema.org/Rubric">` with
`<meta itemprop="rubricType" content="analytic">`; nest
`<div itemprop="hasCriterion" itemscope itemtype="http://oerschema.org/RubricCriterion">`; nest
a `<div itemprop="rubricScale" itemscope itemtype="http://oerschema.org/RubricScale">` with two
`<div itemprop="hasLevel" itemscope itemtype="http://oerschema.org/RubricLevel">` carrying
`levelOrdinal` and `levelPoints`. Surface: microdata in pages/lesson-3.html, or convert the
page to VitePress and use the `::: rubric` / `::: rubric-criterion` / `::: rubric-scale` /
`::: rubric-level` directives (see references/markup-surfaces.md).
### 🛠 Implementation handoff
* Lesson + objective: add itemscope markup in pages/lesson-3.html (direct edit or /hax).
* Quiz: add itemtype=Quiz to the quiz div (direct edit); if a HAX quiz element renders it, also
file oerschema-integration-finder for the component to emit Assessment microdata.
* Rubric: add the Rubric family microdata, or migrate to VitePress rubric directives.
Implementing the Recommendations
This audit is the diagnosis step. Apply fixes with the related skills and the hax CLI:
hax-claudehax— insert/replace schema-tagged components in existing pages:/hax wrap the quiz in pages/lesson-3 with itemscope itemtype=http://oerschema.org/Quiz
hax-site-building— owns page structure; edit page content atpages/<slug>.htmlfor microdata; add pages viahax site node:add ... --y --no-i; never hand-editsite.json.oerschema-integration-finder— when the gap is a rendering element not emitting microdata (a code gap, not a content gap).hax-ubd-unit-audit— if the real concern is objective/assessment alignment, not schema.grad-blooms— cognitive level of an objective/assessment.
CLI rules (from PRAW RULES.md):
- Use the local/global
haxcommand — notnpx hax(resolves to a different package). - When scripting, pass automation flags to avoid prompts/new windows:
--y --no-i. - Never hand-edit
site.jsonfor structure — use the CLI.
Acceptance criteria (for the audit report itself)
- Every finding names the exact OER Schema class and/or property (from
references/vocabulary.md) and the markup surface to use. - Every recommended class is a real class in the v1.2.0 vocabulary; every recommended property is
in the declared
domainof that class (accounting forsubClassOfinheritance). - The rating is one of: Covered / Partial / Uncovered.
- A page whose pedagogical structures all carry correct, domain/range-valid schema is not rated Uncovered even if advisories (use a more specific subclass) are present.
- Component-internal schema gaps are handed to
oerschema-integration-finder, not double-reported as content findings. - Vocabulary-internal bugs (broken
subClassOf, missinginverseOfinschema.ts) are handed tooerschema-validation/oerschema-schema-author, not reported as content findings.
Gotchas
- Inheritance makes many uses valid that look invalid.
hasLearningObjectiveis domainInstructionalPattern, butLesson,Unit,Module,Assessment,Task,Activity,Project,Practiceare allInstructionalPatternsubclasses — so using it on any of them is valid. Always walk thesubClassOfchain inreferences/vocabulary.mdbefore flagging a domain violation. - Quiz vs. Task vs. Assessment.
QuizandTaskare siblings (both subclassInstructionalPatternvia different paths:Quiz→Assessment,Taskdirectly). A quiz is NOT a Task.Submissionis the otherAssessmentsibling. Get this right — it is the most common mis-classification. forComponent/hasComponentare inverses by comment, not by theinverseOffield. Do not flag this as a content error; it is a vocabulary-internal gap foroerschema-validation. In content, flag a missing reciprocal link (aforComponentwith no matchinghasComponenton the parent) as a structural advisory, not a hard fail.mainEntityOfPage.inverseOf = "mainEntity"references an external schema.org property that is not defined in this vocabulary. This is intentional (it aligns to schema.org), not a bug — do not flag it.- Pick the most specific class.
itemtype=".../InstructionalPattern"on a lesson is valid butLessonis more specific and more discoverable. Report as an advisory, not a fail. - Surface matters. Don't recommend microdata inside a VitePress markdown file — recommend the
matching
:::directive. Don't recommend a:::directive inside a HAXpages/*.html— recommend microdata. Seereferences/markup-surfaces.md. - ActionType values are classes, not strings.
typeOfActionrange isActionType; the valid values are theActionTypesubclasses (Reading, Writing, Making, etc.), referenced ashttp://oerschema.org/Readingetc. AtypeOfAction="reading"lowercase string is invalid. - Don't edit here. This skill emits a report. Edits belong in
pages/<slug>.html(viahax-site-buildingor direct edit /hax-claudehax); structural edits belong to thehaxCLI.
Dependencies
- Reads:
site.json/pages/*.html/ a JOS node / raw HTML / markdown / VitePress.md/ JSON-LD / Docs export HTML - Consults:
references/vocabulary.md(class + property tables — single source of truth),references/markup-surfaces.md,references/hax-outline-mapping.md,references/ubd-mapping.md - Hands off to:
hax-claudehax/hax-site-building(apply remediation),oerschema-integration-finder(component-internal schema gaps) - Defers to:
hax-ubd-unit-audit(alignment),grad-blooms(cognitive level),oerschema-validation/oerschema-schema-author(vocabulary-internal bugs)
References
references/vocabulary.md— OER Schema v1.2.0 class hierarchy + property domain/range tables (the iron rule; verify every recommendation against this)references/markup-surfaces.md— microdata vs JSON-LD vs VitePress directives vs Docs export, with exact syntax for each classreferences/hax-outline-mapping.md— site.json JOS node → OER class + relationship propertiesreferences/ubd-mapping.md— UbD artifacts (EU, GRASPS, WHERETO) → OER classes/properties- OER Schema vocabulary source:
oerschemarepoapp/lib/schema.ts - PRAW RULES.md:
~/Documents/git/haxtheweb/praw/RULES.md
Signals
- GitHub stars
- 129
- Forks
- 57
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
oerschema-audit- Source
- github.com/haxtheweb/haxcms-php