fix(author): a licence's version and a gap's marks are said where a chat reads, and what the build can prove wrong is a problem

Merged
AL
9h ago
+272-3

Closes #187.

Haiku with a shell and the skill built each of the 32 content types that need no media twice: 64 packages, all built, all passing h5p-verify, and four played wrong with no word from either. Two were a text's own marks: a Fill in the Blanks asked for the answers 1/2, 10:30 and km/h, where *10:30* is the answer 10 with the tip 30 and *km/h* takes km or h; and a Drag the Words with a colon in a gap's feedback, where the learner drags the word with its tip still in it. In the chat position, of 30 first replies on 0.9.3, none wrote the licence's version in its own field, and the build's own problem for it had every reply drop the version (#187 has the numbers).

What changes

  • SKILL.md, step 2, for the chat that has no type file:
    • a CC BY licence's version, CC BY-SA's and the others' too, is a field of its own, written where the user gave one: "CC BY 4.0" is "license": "CC BY", "licenseVersion": "4.0", and CC0 1.0 is one code, as it stands;
    • in a gap of H5P.Blanks / separates answers and : starts a tip, in a gap of H5P.DragText : starts a tip, and where one belongs to the answer itself it is written / or :. A backslash escapes nothing.
  • The two type files say it with their own examples: *km/h* takes km/h where *km/h* takes km or h; in Drag the Words : stands once in a gap, before the tip, and feedback holds none.
  • The licence's problem names the licence it read and where the version goes, the SPDX spelling too: license: "CC BY 4.0" holds the version too: write "license": "CC BY" and "licenseVersion": "4.0". A name that is no licence gets the list as before.
  • A backslash before / or : in a gap's answers is a problem, the gap written out as the library takes it: params.questions[0]: `*1\/2*`: a backslash escapes nothing in a gap, so H5P.Blanks takes "1\" or "2" here. In an answer write `/` as `/` and `:` as `:`: `*1/2*` . An answer that is a backslash and no more is left alone.
  • A gap of Drag the Words whose tip or feedback pattern matches twice is a problem, with the word as the library would leave it: params.textField: gap 1, `*hablo:primera persona\+Correcto: termina en -o.\-No: la fo…`: its feedback holds a `:`, where H5P.DragText ends the feedback and starts another tip, and it then leaves them in the word: the learner would drag "hablo:primera persona: termina en -o.: la forma es «hablo».". Write `:` once in a gap, before the tip, and none in the feedback. A colon in the tip itself is none: the tip runs on over it.
  • Both checks are layouts (LAYOUTS['H5P.Blanks'], LAYOUTS['H5P.DragText']), so they run wherever the type sits, in a Column or a Question Set too, and in checkContent on saved content. Each finds its gaps as its library does: handleBlanks and parseSolution of H5P.Blanks 1.14, parseText and lex of H5P.DragText 1.10.
  • design/author.md says why, and what was measured.

*10:30* as written is not refused. It is a tip to the library and may be one to its author, and a build cannot tell which. Nor is a Drag the Words gap with one colon after \+ or \- and no tip before it: played, *habla\+Bien.:tercera persona* has the feedback "Bien." and the tip "tercera persona", a tip written after the feedback, which the build cannot tell from a colon meant for the feedback.

cubic's review

  • A colon after \+ with no tip before it (P2, types.mjs): not refused, as above. Refusing it would refuse a source that plays as its author meant; the type file and SKILL.md say feedback holds no colon, and the layout's test now holds a tip written after the feedback to be taken.
  • CC0 1.0 is one code (P2 SKILL.md, P2 and P3 design/author.md): right. The sentence now names CC BY and its family and says CC0 1.0 is one code; the design note says the same; a test holds CC0 1.0 to build as it is, and "CC0" with "licenseVersion": "1.0" to two problems. Checked on Haiku in the chat position with the new sentence: 11 of 11 right: "CC0 1.0" kept whole 4 of 4, "CC BY 4.0" split 4 of 4, "CC BY-SA" with no version left without one 3 of 3.
  • CodeQL (js/incomplete-multi-character-sanitization, types.mjs): a Blanks gap's tags are taken out until none is left, where the library takes them out in one pass; the two differ only for a tag written inside a tag.

The entity

"Nothing escapes a gap's marks" is not so, which the first cut of this assumed: parseSolution decodes each answer's entities, and : is no colon as the gap is split. Played in the verifier's browser:

  • Fill in the Blanks with *10:30*, *km/h*, *1/2:a fraction* and *3:1/3 to 1:…*: the key is 10:30, km/h, 1/2 and 3:1 or "3 to 1"; those answers typed score 4 of 4; "10", "km" and "1" typed are wrong.
  • Drag the Words with the word *7:45* and : in feedback: the word is drawn 7:45 and scores, the feedback shows a colon, and no attribute or text in the frame holds the entity as written. The key in its xAPI statement does: 7:45.
  • Mark the Words with *10:30*, *km/h* and *1/2*: each is one word, and the right one. Neither character is a mark there, so the skill's line names the two other types only.

Tested

  • pnpm --filter @missing-elements/h5p-author test passes, 184 tests with the browser one, and so does the typecheck. The tags in a Blanks gap are taken out until none is left, where the library takes them out in one pass, for CodeQL's js/incomplete-multi-character-sanitization (a tag inside a tag is the only difference). New: the licence's four messages; the two checks' problems word for word, in a Column too; and what both must take, alternatives, a tip, an answer that is a backslash, a tip that holds a colon, the entities.

  • pnpm --filter @missing-elements/h5p-skills test passes, 77 tests: every type file is current with the generator, and every example builds and plays.

  • False alarms. The two checks over the 94 real packages of the owner's corpus and the demo, 53 of these two types in them with 266 gaps: nothing reported. Over the 524 distinct sources these tests stored, 199 of the two types with 765 gaps: only the 14 known to play wrong.

  • Haiku as a chat, the skill's text and no tool, each reply built with this branch, played, and the library's own key held against the request. First replies that wrote a source:

    0.9.3This branch
    The licence's version in its own field0 of 3047 of 47
    Fill in the Blanks, the three answers taken as asked0 of 1023 of 23
    Drag the Words with its type file, its words whole3 of 59 of 9
    Built at the first try2 of 2041 of 47
    Plays wrong once it builds9 of 200 of the 41 that built

    0.9.3's column counts 30 replies for the licence, which SKILL.md alone decides, and for the rest the 20 written with 0.9.3's own files.

    • A licence the user skipped was U in 5 of 5. A licence named without a version got none in 5 of 5; with the version in SKILL.md's example, as first written, 3 of 7 added "4.0", which is why it is in the sentence and not the example.
    • Three Mark the Words kept a sentence with 10:30 and km/h in it word for word, its words marked as they stand.
    • The six that did not build at the first try, none of them for a gap or a licence: three Drag the Words without the type file, distractors written as a list twice and a field of the chat's own making once, and the three Mark the Words, for the task description the type requires.
  • The replies that had gone wrong, the build's problems pasted back in the build page's words: 8 of 8 right in one round, 4 Blanks with the answers asked for and 4 Drag the Words, and the licence right in all. With 0.9.3's problems, 1 of 12 gaps fixed and the version dropped in 12 of 12.

  • Where the build cannot prove it, a first reply with *10:30*: the type file handed back beside the licence's problem had 1 of 3 write the entities; the two others built and play wrong, as before.

  • The first twenty chats of the last round were started with another line than the earlier rounds' and 6 asked a question before writing; 0.9.3's text under that line did the same in 2 of 10, and this branch's text under the old line in 0 of 10. The counts above are of replies that wrote a source.

Not verified

  • A text edited afterwards in H5P's own editor: its rich-text widget may write an entity back as its character, and the gap would then be a tip again.
  • An LMS's report of a Drag the Words whose word holds an entity: the statement's key has it as written.

To release

h5p-author 0.9.4, a patch: no export added or removed. A source that built still builds unless it holds one of the two gaps, which played wrong. Then the site's pin moves to it, for /h5p/skill/ and the build page. Installed copies of the skill need npx skills update -g and a new upload to the Claude app.