Repository navigation
[QTI] Perseus archive of a mixed exercise keeps legacy input questions with no numeric answer #6208
Description
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Overview
An exercise that mixes native QTI items with legacy items publishes a Perseus archive containing legacy input questions that no answer can satisfy. A legacy input question whose answers are blank or not numbers becomes a Perseus numeric-input with answers: []. After #6196, the QTI package leaves the blank ones out, and an exercise holding a native string text entry publishes QTI only. The Perseus archive of a mixed exercise still carries both kinds.
Complexity: Low
Target branch: unstable
Context
_node_is_perseus_derivableaccepts every legacyinput_question:studio/contentcuration/contentcuration/utils/publish.py
Lines 264 to 274 in c87debc
def _node_is_perseus_derivable(node): """True iff the node has >=1 native QTI item and every item is Perseus-expressible.""" has_native_qti = False for item in node.assessment_items.all(): if item.type == exercises.QTI: has_native_qti = True if not is_perseus_derivable(item.raw_data): return False elif item.type not in PERSEUS_EXPRESSIBLE_LEGACY_TYPES: return False return has_native_qti _process_input_answersdrops every answerextract_valuedoes not read as a number:studio/contentcuration/contentcuration/utils/assessment/perseus.py
Lines 74 to 82 in c87debc
def _process_input_answers(self, processed_data): """Extract input answer processing logic""" non_empty_answers = [] for answer in processed_data["answers"]: answer["answer"] = extract_value(answer["answer"]) if answer["answer"] or answer["answer"] == 0: non_empty_answers.append(answer) return {**processed_data, "answers": non_empty_answers} - An exercise with native choice
item_1, a legacy input question answered""(<blank>) and one answeredSphere(<sphere>), published with the [QTI] Legacy input question conversion produces wrong or unanswerable QTI #6196 fix:QTI package items: item_1, K…(<sphere>) Perseus archive items: item_1.json, <blank>.json, <sphere>.json exercise.json all_assessment_items: item_1, <blank>, <sphere> <blank>.json, <sphere>.json: numeric-input, answers []
The Change
- An exercise mixing native QTI items with a legacy input question that has a non-numeric answer should publish QTI only, as one holding a native
stringtext entry does. - A legacy input question with no accepted answer should be left out of the exercise's Perseus archive, as it is left out of its QTI package.
How to Get There
- Publish an exercise holding one question saved from the QTI editor and two legacy input questions never opened in it, one answered
""and one answeredSphere. Then list the Perseus archive's item files and theirnumeric-inputanswers.
Acceptance Criteria
- An exercise holding a native QTI item and a legacy input question answered
["Sphere"]publishes a QTI package and no Perseus archive. - For an exercise holding a native QTI item and a legacy input question answered
[""], neither the Perseus archive's item files norexercise.jsonall_assessment_itemsinclude that question. - No Perseus archive of an exercise mixing native QTI and legacy items contains a
numeric-inputwithanswers: []. -
test_exportchannel.pycovers both exercises.
AI usage
Claude Code found this during an automated self-review of the #6196 branch, reproduced it with a scratch publish test on that branch, and drafted this issue.

Activity
rtibblesbot commentedon Sep 30, 2026
rtibbles Blocked on #6209 (the #6196 fix), which is still open.
Sphereconverted to astringtext entry.test_exportchannel.py, and Convert legacy input questions to answerable QTI #6209 changesperseus_derive.py, which the derivability gate calls.Should I wait for #6209 to merge, or branch from it?
rtibbles commentedon Sep 30, 2026
This has now been merged.
rtibblesbot commentedon Oct 1, 2026
Plan: A mixed native-QTI + legacy exercise's Perseus archive never ships a
numeric-inputthat no answer satisfies (#6208).Assumptions — the issue did not settle these; say so if one is wrong.
4fixture QTI only instead._process_answersinto the base generator; if reviewers object, Perseus duplicates the override.@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
rtibblesbot commentedon Oct 1, 2026
#6262 leaves answerless input questions out of every exercise Perseus archive, dual-published ones included (
test_answerless_input_left_out_of_dual_published_archives). Drop the "Leave answerless input questions out of a dual-published Perseus archive" task and build on #6262 rather than adding a second skip.