Skip to content

feat(content): cloze pick-the-right-word exercises across the story ladder (learn uplift t11)#4

Merged
OriNachum merged 1 commit into
mainfrom
agent/c1-t11
Jul 11, 2026
Merged

feat(content): cloze pick-the-right-word exercises across the story ladder (learn uplift t11)#4
OriNachum merged 1 commit into
mainfrom
agent/c1-t11

Conversation

@OriNachum

Copy link
Copy Markdown
Contributor

What

11 pick-the-right-word cloze exercises across the full story ladder (one per story, A1–C1), implementing the new optional cloze variant from the learn subject-plugin contract §3.6.1 (text with {{blank_id}} placeholders + blanks: [{id, options, answer}]).

  • Distractors are pedagogically deliberate: same-word-class confusions, gender/number agreement traps, subjunctive after s'inquiéter que, deviner/devenir near-homophones.
  • Every new exercise reuses an existing item_id from its own story — no new item_ids, no existing exercise touched, learner mastery preserved.
  • No engine code change needed (story_read_payload() embeds stories verbatim); what WAS stale: the cited contract copy (french/contract_cite/schemas/{story,practice}.json + _validate.py) predated the cloze fields — re-synced from learn-cli per docs/contract-provenance.md. Contract stays 1.0, additive only.
  • Version 0.5.0 → 0.6.0 with changelog.

Verification

  • uv run pytest -n auto → 113 passed; black/isort/flake8/bandit clean; teken cli doctor . --strict 26/26.
  • Against the uplift learn-cli (feat/consent-tutoring-uplift): learn subject doctor french --json → healthy, all 9 checks including cloze-items: "11 pick-the-right-word cloze item(s) verified".

Part of the learn content workstream: agentculture/learn-cli#9 (umbrella), contract change in learn-cli PR #12's plan (task t11).

  • french-cli (Claude)

…adder (t11, contract §3.6.1)

Add one pick-the-right-word cloze exercise (contract v1.0 §3.6.1's second
`cloze` variant: text + blanks, checkable without a driver) to each of the 11
graded-reader stories, covering all five CEFR rungs (A1-C1) and all three
coarse levels. Each exercise's text is lifted near-verbatim from its story's
body so it stays answerable from the reading alone, with level-graded
distractors (same-word-class confusions for A1/A2; gender/number agreement
and idiom traps for B1; subjunctive-mood and lexical-register contrasts for
B2; a deviner/devenir near-homophone reading trap for C1). Every new exercise
reuses an existing exercise's item_id from its own story, so results accrue
to already-tracked curriculum items; no existing item_id or exercise changed.

Re-sync french/contract_cite/{schemas/{story,practice}.json,_validate.py}
from learn-cli (source commit cdac077) to pick up the text/blanks fields and
the new cloze_blank def the variant needs — purely additive, contract stays
1.0. `learn subject doctor french --json` (built from the learn-cli uplift
branch) reports healthy with the new cloze-items check: "11 pick-the-right-
word cloze item(s) verified: well-formed blanks". Bumped 0.5.0 -> 0.6.0 per
the version-bump-every-PR convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QpvZY8K67Q9uGA6keFhTz
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
69.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add pick-the-right-word cloze exercises across all story levels (A1–C1)

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add 11 pick-the-right-word cloze exercises (one per story) using text+blanks format.
• Re-sync cited contract schemas/validator to validate the new cloze variant fields.
• Bump version to 0.6.0 and document changes in changelog/provenance.
Diagram

graph TD
  A["content/stories/*.json"] --> P["story_read_payload()"] --> L{{"Learn consumer"}}
  S["contract_cite/schemas/*.json"] --> V(["contract_cite/_validate.py"]) --> D["subject doctor"] --> A
  Docs["docs/contract-provenance.md"] --> S

  subgraph Legend
    direction LR
    _file["File"] ~~~ _mod(["Module"]) ~~~ _ext{{"External"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use a standard JSON Schema validator dependency
  • ➕ More complete Draft 2020-12 support (less bespoke keyword handling)
  • ➕ Less maintenance burden vs. a vendored/trimmed validator
  • ➖ Introduces a runtime dependency the project may be intentionally avoiding
  • ➖ Potentially larger footprint and dependency-management overhead
2. Vendor the entire contract package as a git submodule/subtree
  • ➕ Avoids manual resync drift across schemas and validator
  • ➕ Keeps contract cite updates mechanically reproducible
  • ➖ Adds repo management complexity (submodule/subtree workflows)
  • ➖ Still requires pinning and update discipline; may not fit current conventions
3. Generate cloze exercises via a templating pipeline
  • ➕ Reduces copy/paste and enforces consistent cloze formatting
  • ➕ Could systematically ensure placeholder/blanks alignment
  • ➖ Adds tooling complexity for a small, curated set of exercises
  • ➖ May reduce editorial control over pedagogically deliberate distractors

Recommendation: The PR’s approach is appropriate: keep the change fully additive (new per-story exercises + updated cited schemas/validator) and avoid engine/runtime changes. Given the explicit constraint that french-cli must not depend on learn-cli, a local schema/validator resync is the lowest-risk way to stay aligned with contract §3.6.1 while preserving existing learner mastery via reused item_ids.

Files changed (17) +450 / -79

Enhancement (11) +173 / -0
fr-a1-la-rentree.jsonAdd A1 cloze q5 using text+blanks placeholders +11/-0

Add A1 cloze q5 using text+blanks placeholders

• Introduces a new 'cloze' exercise ('q5') using 'text' with a '{{blank_id}}' placeholder and a 'blanks' array with options/answer. Reuses an existing story 'item_id' to preserve progress continuity.

content/stories/fr-a1-la-rentree.json

fr-a1-le-marche.jsonAdd A1 cloze q5 (unit-of-measure distractors) +11/-0

Add A1 cloze q5 (unit-of-measure distractors)

• Adds a pick-the-right-word 'cloze' exercise with 'text'+'blanks', targeting a common measure-word confusion. The exercise reuses an existing 'item_id' from the same story.

content/stories/fr-a1-le-marche.json

fr-a2-le-cafe-du-coin.jsonAdd A2 cloze q5 (flavor noun distractors) +11/-0

Add A2 cloze q5 (flavor noun distractors)

• Adds a new 'cloze' exercise using the contract’s optional 'text'/'blanks' shape, with multiple-choice options for the blank. Keeps mastery tracking stable by reusing a prior 'item_id'.

content/stories/fr-a2-le-cafe-du-coin.json

fr-a2-le-weekend-a-la-montagne.jsonAdd A2 cloze q5 (snowman vocabulary distractors) +11/-0

Add A2 cloze q5 (snowman vocabulary distractors)

• Introduces a new pick-the-right-word cloze exercise ('q5') with a single placeholder in 'text' and corresponding 'blanks' options. Uses an existing story 'item_id'.

content/stories/fr-a2-le-weekend-a-la-montagne.json

fr-b1-entretien-embauche.jsonAdd B1 cloze q5 (agreement + idiom traps) +15/-0

Add B1 cloze q5 (agreement + idiom traps)

• Adds a two-blank cloze exercise using 'text' placeholders and 'blanks' entries to test participle agreement and a fixed expression choice. Reuses an existing 'item_id'.

content/stories/fr-b1-entretien-embauche.json

fr-b1-la-fete-des-voisins.jsonAdd B1 cloze q5 (verb form + adverb choice) +19/-0

Add B1 cloze q5 (verb form + adverb choice)

• Adds a multi-blank pick-the-right-word cloze exercise with options designed to catch common conjugation and adverb confusions. Keeps item tracking intact via an existing 'item_id'.

content/stories/fr-b1-la-fete-des-voisins.json

fr-b1-la-recherche-appartement.jsonAdd B1 cloze q5 (housing vocabulary + adjective agreement) +19/-0

Add B1 cloze q5 (housing vocabulary + adjective agreement)

• Adds a two-blank cloze exercise using 'text'/'blanks', focusing on rental vocabulary and adjective agreement. Reuses an existing story 'item_id'.

content/stories/fr-b1-la-recherche-appartement.json

fr-b1-le-covoiturage.jsonAdd B1 cloze q5 (breakdown/assistance vocabulary) +19/-0

Add B1 cloze q5 (breakdown/assistance vocabulary)

• Introduces a two-blank cloze exercise with multiple-choice distractors aligned to the story context. Uses an existing 'item_id' to avoid disrupting mastery history.

content/stories/fr-b1-le-covoiturage.json

fr-b2-la-transition-ecologique.jsonAdd B2 cloze q5 (register/meaning contrasts) +19/-0

Add B2 cloze q5 (register/meaning contrasts)

• Adds a two-blank pick-the-right-word cloze exercise using the new contract shape, emphasizing nuanced lexical choices. Reuses an existing story 'item_id'.

content/stories/fr-b2-la-transition-ecologique.json

fr-b2-le-teletravail.jsonAdd B2 cloze q5 (subjunctive trigger + verb agreement) +19/-0

Add B2 cloze q5 (subjunctive trigger + verb agreement)

• Adds a two-blank cloze exercise that includes a subjunctive selection after "s'inquiéter que" and a second verb-choice blank. Preserves learner tracking by reusing an existing 'item_id'.

content/stories/fr-b2-le-teletravail.json

fr-c1-le-vieux-libraire.jsonAdd C1 cloze q5 (near-homophone distractor) +19/-0

Add C1 cloze q5 (near-homophone distractor)

• Adds a two-blank cloze exercise using 'text' placeholders and 'blanks', including a near-homophone distractor choice. Reuses an existing story 'item_id'.

content/stories/fr-c1-le-vieux-libraire.json

Refactor (1) +175 / -75
_validate.pyRefactor local schema validator and generalize $defs handling +175/-75

Refactor local schema validator and generalize $defs handling

• Re-syncs and refactors the vendored validator: introduces a '$defs' constant, splits '_check' into focused helpers, and improves keyword walking logic. Updates header provenance to the new upstream commit and task context.

french/contract_cite/_validate.py

Documentation (2) +34 / -2
CHANGELOG.mdDocument 0.6.0: new cloze variant exercises + contract cite resync +27/-0

Document 0.6.0: new cloze variant exercises + contract cite resync

• Adds a 0.6.0 entry describing the new pick-the-right-word cloze exercises across the story ladder and notes the schema/validator re-sync to support 'text'/'blanks' and 'cloze_blank'.

CHANGELOG.md

contract-provenance.mdUpdate contract cite provenance to new upstream commit +7/-2

Update contract cite provenance to new upstream commit

• Updates the cited learn-cli source commit to reflect the re-sync that includes the pick-the-right-word cloze fields ('text'/'blanks') and 'cloze_blank'. Clarifies that the contract version remains 1.0 and changes are additive.

docs/contract-provenance.md

Other (3) +68 / -2
practice.jsonExtend practice schema with cloze text/blanks + cloze_blank definition +34/-1

Extend practice schema with cloze text/blanks + cloze_blank definition

• Adds optional 'text' and 'blanks' fields to the exercise definition for the pick-the-right-word cloze variant, plus a new '$defs.cloze_blank' object schema. The change is additive and keeps older payloads valid.

french/contract_cite/schemas/practice.json

story.jsonExtend story schema with cloze text/blanks + cloze_blank definition +33/-0

Extend story schema with cloze text/blanks + cloze_blank definition

• Adds the same optional 'text'/'blanks' fields and '$defs.cloze_blank' definition to support the pick-the-right-word cloze variant in story exercises. Designed to be backward-compatible for preexisting story payloads.

french/contract_cite/schemas/story.json

pyproject.tomlBump package version to 0.6.0 +1/-1

Bump package version to 0.6.0

• Updates the project version from 0.5.0 to 0.6.0 to reflect the newly added cloze content and contract cite updates.

pyproject.toml

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 7 rules
✅ Skills: doc-test-alignment

Grey Divider


Remediation recommended

1. Provenance stamps diverged 🐞 Bug ⚙ Maintainability
Description
The contract provenance stamp was updated to upstream commit cdac077 in the ledger doc and
_validate.py, but french/contract_cite/__init__.py still advertises the older ed81b87. This
creates an inconsistent provenance trail that makes future contract re-syncs harder to audit
correctly.
Code

docs/contract-provenance.md[R28-35]

+- **Source commit:** `cdac077` (2026-07-11)
- **Cited on:** 2026-07-11
-- **Cited by:** french-cli (task t4 of the learn uplift)
+- **Cited by:** french-cli (task t4 of the learn uplift; re-synced by task t11 to
+  pick up the pick-the-right-word cloze variant fields — `text`/`blanks` on the
+  exercise def and the new `cloze_blank` def — added to `story.json` and
+  `practice.json`, contract §3.6.1. Purely additive: contract version stays
+  `1.0`, and every payload that predates these fields keeps validating
+  unchanged.)
Evidence
The provenance ledger and the cited validator were re-stamped to cdac077, but the contract package
header still reports ed81b87, leaving the repo with conflicting provenance for what is intended to
be a single re-sync point-in-time.

docs/contract-provenance.md[26-35]
french/contract_cite/_validate.py[7-14]
french/contract_cite/init.py[5-12]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The contract provenance stamp is inconsistent across the cited contract files: docs and `_validate.py` point at commit `cdac077`, while `french/contract_cite/__init__.py` still claims `ed81b87`.

### Issue Context
This repo treats `french/contract_cite/*` as a cite-don’t-import mirror of learn-cli’s contract, so keeping provenance stamps consistent is important for auditability and repeatable re-syncs.

### Fix Focus Areas
- french/contract_cite/__init__.py[5-12]
- docs/contract-provenance.md[26-35]
- french/contract_cite/_validate.py[7-14]

### What to change
- Update the provenance header in `french/contract_cite/__init__.py` to match the new upstream commit (`cdac077`) and the updated “cited by” context (task t11), OR remove/centralize the duplicated provenance text so there is only one authoritative stamp.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +28 to +35
- **Source commit:** `cdac077` (2026-07-11)
- **Cited on:** 2026-07-11
- **Cited by:** french-cli (task t4 of the learn uplift)
- **Cited by:** french-cli (task t4 of the learn uplift; re-synced by task t11 to
pick up the pick-the-right-word cloze variant fields — `text`/`blanks` on the
exercise def and the new `cloze_blank` def — added to `story.json` and
`practice.json`, contract §3.6.1. Purely additive: contract version stays
`1.0`, and every payload that predates these fields keeps validating
unchanged.)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Provenance stamps diverged 🐞 Bug ⚙ Maintainability

The contract provenance stamp was updated to upstream commit cdac077 in the ledger doc and
_validate.py, but french/contract_cite/__init__.py still advertises the older ed81b87. This
creates an inconsistent provenance trail that makes future contract re-syncs harder to audit
correctly.
Agent Prompt
### Issue description
The contract provenance stamp is inconsistent across the cited contract files: docs and `_validate.py` point at commit `cdac077`, while `french/contract_cite/__init__.py` still claims `ed81b87`.

### Issue Context
This repo treats `french/contract_cite/*` as a cite-don’t-import mirror of learn-cli’s contract, so keeping provenance stamps consistent is important for auditability and repeatable re-syncs.

### Fix Focus Areas
- french/contract_cite/__init__.py[5-12]
- docs/contract-provenance.md[26-35]
- french/contract_cite/_validate.py[7-14]

### What to change
- Update the provenance header in `french/contract_cite/__init__.py` to match the new upstream commit (`cdac077`) and the updated “cited by” context (task t11), OR remove/centralize the duplicated provenance text so there is only one authoritative stamp.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@OriNachum OriNachum merged commit 3628880 into main Jul 11, 2026
6 of 8 checks passed
@OriNachum OriNachum deleted the agent/c1-t11 branch July 11, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant