Skip to content

[QTI] Carry legacy hints into generated QTI items as dormant catalog content #6011

Closed

Description

@rtibbles

Overview

Legacy assessment items carry progressively-revealed hints (AssessmentItem.hints) that the QTI generator drops. Emit them into the generated QTI item as a qti-catalog-info catalog of support="ext:kolibri-hint" cards — dormant content the QTI 3.0 schema excludes from default delivery — carried in raw_data through publish so Kolibri can render them. Legacy-only; the new editor does not author hints.

Complexity: Medium
Target branch: unstable

Context

  • Legacy hints: AssessmentItem.hints is a JSON list [{"hint": <markdown>, "order": N}]; base.py:_process_hints converts markdown→HTML and extracts images.
  • The QTI generator (utils/assessment/qti/) emits nothing for hints today.
  • XSD validation ([QTI] QTI 3.0 schema XML validation utilities #6005) is authoritative and runs on save/publish.

The Change

Emit legacy hints into the generated QTI item as a dormant qti-catalog-info catalog — rendered by Kolibri, ignored by default players.

<qti-catalog-info>
  <qti-catalog id="kolibri-hints">
    <qti-card support="ext:kolibri-hint"><qti-html-content><p>First hint…</p></qti-html-content></qti-card>
    <qti-card support="ext:kolibri-hint"><qti-html-content><p>…solution.</p></qti-html-content></qti-card>
  </qti-catalog>
</qti-catalog-info>

Acceptance Criteria

References

AI usage

Claude verified the carrier against the QTI 3.0 ASI XSD — confirming qti-catalog-info holds dormant, non-delivered content, accepts a custom ext:kolibri-hint support value, and that HTML <template> is restricted to custom-interaction markup — then drafted the issue section by section. The maintainer chose the catalog approach and the ext:kolibri-hint value and steered each section.

Activity

  1. added theissue type on Jun 30, 2026
  2. rtibblesbot commented on Jul 8, 2026

    @rtibblesbot
    Contributor

    support="kolibri:hint" fails XSD validation.

    The vendored XSD (imsqti_itemv3p0p1_v1p0.xsd) restricts CardDType/@support to a union of two options. Option 1 is a fixed enumeration (additional-directions, audio-description, braille, glossary-on-screen, high-contrast, keyboard-directions, keyword-translation, linguistic-guidance, long-description, sign-language, simplified-language-portions, simplified-graphics, spoken, tactile, transcript) — no hint value. Option 2 is SupportExtStringDType:

    <xs:simpleType name="SupportExtStringDType">
        <xs:restriction base="xs:normalizedString">
            <xs:pattern value="(ext:)[a-zA-Z0-9_\.\-]+" />
        </xs:restriction>
    </xs:simpleType>

    This pattern requires the literal prefix ext:. No colon is allowed after it. kolibri:hint matches neither option, so a qti-card support="kolibri:hint" fails XSD validation — contradicting the acceptance criterion "Generated items validate against the QTI 3.0 XSD (#6005)".

    Question: what exact support value should this use instead, e.g. ext:kolibri-hint?

  3. rtibblesbot commented on Jul 8, 2026

    @rtibblesbot
    Contributor

    The bot has been waiting for a response for 2 hour(s). It will resume automatically when someone replies.

  4. rtibbles commented on Jul 8, 2026

    @rtibbles
    MemberAuthor

    Question: what exact support value should this use instead, e.g. ext:kolibri-hint?

    Yes - I have updated the issue accordingly!

  5. rtibblesbot commented on Jul 9, 2026

    @rtibblesbot
    Contributor

    Plan: Emit legacy AssessmentItem.hints into generated QTI items as a dormant qti-catalog-info catalog (support="ext:kolibri-hint" cards), carried through both the webapp publish path and the ricecooker ingest path, so Kolibri can render progressively-revealed hints that the QTI generator currently drops.

    • catalog.py — HtmlContent, Card, Catalog, CatalogInfo element classes
    • Wire catalog_info into AssessmentItem
    • _create_catalog_info in convert.py
    • Wire hints through archive.py (webapp publish path)
    • Wire hints through ingest.py (ricecooker ingest path)

    @rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

    How was this generated?
    • Implemented code following the pre-approved plan using test-driven development (red-green-refactor)
    • Ran the project's full test suite and linter before committing
    • For UI changes: captured live screenshots to verify rendering
    • For backend changes: verified with example API/CLI output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions