From 825a2cb23fbf388263782b22e1d0d6f60351316d Mon Sep 17 00:00:00 2001 From: Michael Czechowski Date: Sat, 28 Mar 2026 20:10:04 +0100 Subject: [PATCH] fix: rewrite validation messages to guide learning instead of revealing answers (#4) --- lessons/01-box-model.json | 20 +++---- lessons/03-colors.json | 8 +-- lessons/ar/01-box-model.json | 20 +++---- lessons/de/01-box-model.json | 20 +++---- lessons/es/01-box-model.json | 20 +++---- lessons/pl/01-box-model.json | 20 +++---- lessons/uk/01-box-model.json | 20 +++---- specs/004-validation-messages/plan.md | 77 ++++++++++++++++++++++++++ specs/004-validation-messages/spec.md | 57 +++++++++++++++++++ specs/004-validation-messages/tasks.md | 20 +++++++ 10 files changed, 218 insertions(+), 64 deletions(-) create mode 100644 specs/004-validation-messages/plan.md create mode 100644 specs/004-validation-messages/spec.md create mode 100644 specs/004-validation-messages/tasks.md diff --git a/lessons/01-box-model.json b/lessons/01-box-model.json index ed32a0d..4b61e6e 100644 --- a/lessons/01-box-model.json +++ b/lessons/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Set padding: 1rem" + "message": "Which property adds space between content and the element's edge?" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "Set border-left: 4px solid steelblue", + "message": "Use the shorthand that sets a border on just one side", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "Set margin-bottom: 1rem" + "message": "Which property pushes neighboring elements away from the bottom?" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "Set box-sizing: border-box" + "message": "Which sizing mode includes padding and border in the element's width?" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "Set padding: 8px 1rem", + "message": "Use the two-value shorthand: vertical first, then horizontal", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "Set margin: 0 auto", + "message": "Use the shorthand that auto-calculates equal horizontal margins", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "Set border-radius: 50%" + "message": "Which property rounds corners? Think about what percentage makes a circle" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Set padding: 1rem" + "message": "Add inner spacing to the notification" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "Set border-left: 4px solid coral", + "message": "Add a colored accent on the left edge", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "Set border-radius: 4px" + "message": "Soften the corners of the notification" } ] } diff --git a/lessons/03-colors.json b/lessons/03-colors.json index 11f0884..e4c31ba 100644 --- a/lessons/03-colors.json +++ b/lessons/03-colors.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "background-color", "expected": "seashell" }, - "message": "Set background-color: seashell" + "message": "Which property fills the area behind the content?" } ] }, @@ -43,7 +43,7 @@ { "type": "property_value", "value": { "property": "color", "expected": "coral" }, - "message": "Set color: coral" + "message": "Which property changes the text color?" } ] }, @@ -64,7 +64,7 @@ { "type": "property_value", "value": { "property": "border-color", "expected": "coral" }, - "message": "Set border-color: coral" + "message": "Which property changes just the border's color without redefining the whole border?" } ] }, @@ -85,7 +85,7 @@ { "type": "property_value", "value": { "property": "background-color", "expected": "#ffd700" }, - "message": "Set background-color: #ffd700" + "message": "Use the same background property, but with a hex code this time" } ] } diff --git a/lessons/ar/01-box-model.json b/lessons/ar/01-box-model.json index 0b9ca38..efa5439 100644 --- a/lessons/ar/01-box-model.json +++ b/lessons/ar/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "اضبط padding: 1rem" + "message": "أي خاصية تضيف مساحة بين المحتوى وحافة العنصر؟" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "اضبط border-left: 4px solid steelblue", + "message": "استخدم الاختصار الذي يحدد حداً على جانب واحد فقط", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "اضبط margin-bottom: 1rem" + "message": "أي خاصية تدفع العناصر المجاورة بعيداً من الأسفل؟" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "اضبط box-sizing: border-box" + "message": "أي وضع تحجيم يشمل padding والحدود في عرض العنصر؟" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "اضبط padding: 8px 1rem", + "message": "استخدم اختصار القيمتين: العمودي أولاً، ثم الأفقي", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "اضبط margin: 0 auto", + "message": "استخدم الاختصار الذي يحسب هوامش أفقية متساوية تلقائياً", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "اضبط border-radius: 50%" + "message": "أي خاصية تدوّر الزوايا؟ فكر في النسبة المئوية التي تصنع دائرة" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "اضبط padding: 1rem" + "message": "أضف مساحة داخلية للإشعار" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "اضبط border-left: 4px solid coral", + "message": "أضف لمسة ملونة على الحافة اليسرى", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "اضبط border-radius: 4px" + "message": "نعّم زوايا الإشعار" } ] } diff --git a/lessons/de/01-box-model.json b/lessons/de/01-box-model.json index 641529c..1cb1140 100644 --- a/lessons/de/01-box-model.json +++ b/lessons/de/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Setze padding: 1rem" + "message": "Welche Eigenschaft fügt Abstand zwischen Inhalt und Elementrand hinzu?" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "Setze border-left: 4px solid steelblue", + "message": "Verwende die Kurzschreibweise, die einen Rahmen auf nur einer Seite setzt", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "Setze margin-bottom: 1rem" + "message": "Welche Eigenschaft schiebt benachbarte Elemente nach unten weg?" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "Setze box-sizing: border-box" + "message": "Welcher Größenmodus bezieht Padding und Rahmen in die Breite des Elements ein?" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "Setze padding: 8px 1rem", + "message": "Verwende die Zwei-Werte-Kurzschreibweise: vertikal zuerst, dann horizontal", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "Setze margin: 0 auto", + "message": "Verwende die Kurzschreibweise, die gleiche horizontale Abstände automatisch berechnet", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "Setze border-radius: 50%" + "message": "Welche Eigenschaft rundet Ecken? Denke daran, welcher Prozentwert einen Kreis ergibt" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Setze padding: 1rem" + "message": "Füge inneren Abstand zur Benachrichtigung hinzu" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "Setze border-left: 4px solid coral", + "message": "Füge einen farbigen Akzent an der linken Kante hinzu", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "Setze border-radius: 4px" + "message": "Runde die Ecken der Benachrichtigung ab" } ] } diff --git a/lessons/es/01-box-model.json b/lessons/es/01-box-model.json index 6a6c3c8..27de759 100644 --- a/lessons/es/01-box-model.json +++ b/lessons/es/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Establece padding: 1rem" + "message": "¿Qué propiedad añade espacio entre el contenido y el borde del elemento?" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "Establece border-left: 4px solid steelblue", + "message": "Usa el atajo que define un borde en un solo lado", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "Establece margin-bottom: 1rem" + "message": "¿Qué propiedad empuja los elementos vecinos hacia abajo?" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "Establece box-sizing: border-box" + "message": "¿Qué modo de tamaño incluye padding y borde en el ancho del elemento?" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "Establece padding: 8px 1rem", + "message": "Usa el atajo de dos valores: vertical primero, luego horizontal", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "Establece margin: 0 auto", + "message": "Usa el atajo que calcula márgenes horizontales iguales automáticamente", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "Establece border-radius: 50%" + "message": "¿Qué propiedad redondea las esquinas? Piensa en qué porcentaje crea un círculo" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Establece padding: 1rem" + "message": "Añade espacio interior a la notificación" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "Establece border-left: 4px solid coral", + "message": "Añade un acento de color en el borde izquierdo", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "Establece border-radius: 4px" + "message": "Suaviza las esquinas de la notificación" } ] } diff --git a/lessons/pl/01-box-model.json b/lessons/pl/01-box-model.json index 55db4fc..1e78215 100644 --- a/lessons/pl/01-box-model.json +++ b/lessons/pl/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Ustaw padding: 1rem" + "message": "Która właściwość dodaje przestrzeń między treścią a krawędzią elementu?" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "Ustaw border-left: 4px solid steelblue", + "message": "Użyj skrótu, który ustawia ramkę tylko po jednej stronie", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "Ustaw margin-bottom: 1rem" + "message": "Która właściwość odpycha sąsiednie elementy w dół?" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "Ustaw box-sizing: border-box" + "message": "Który tryb rozmiaru uwzględnia padding i ramkę w szerokości elementu?" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "Ustaw padding: 8px 1rem", + "message": "Użyj skrótu dwuwartościowego: najpierw pionowo, potem poziomo", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "Ustaw margin: 0 auto", + "message": "Użyj skrótu, który automatycznie oblicza równe marginesy poziome", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "Ustaw border-radius: 50%" + "message": "Która właściwość zaokrągla rogi? Pomyśl, jaki procent tworzy koło" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Ustaw padding: 1rem" + "message": "Dodaj wewnętrzny odstęp do powiadomienia" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "Ustaw border-left: 4px solid coral", + "message": "Dodaj kolorowy akcent na lewej krawędzi", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "Ustaw border-radius: 4px" + "message": "Wygładź rogi powiadomienia" } ] } diff --git a/lessons/uk/01-box-model.json b/lessons/uk/01-box-model.json index 8478ba0..ca09f63 100644 --- a/lessons/uk/01-box-model.json +++ b/lessons/uk/01-box-model.json @@ -22,7 +22,7 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Встановіть padding: 1rem" + "message": "Яка властивість додає простір між контентом і краєм елемента?" } ] }, @@ -43,7 +43,7 @@ { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+steelblue", - "message": "Встановіть border-left: 4px solid steelblue", + "message": "Використайте скорочення, яке встановлює межу лише з одного боку", "options": { "caseSensitive": false } } ] @@ -65,7 +65,7 @@ { "type": "property_value", "value": { "property": "margin-bottom", "expected": "1rem" }, - "message": "Встановіть margin-bottom: 1rem" + "message": "Яка властивість відштовхує сусідні елементи знизу?" } ] }, @@ -86,7 +86,7 @@ { "type": "property_value", "value": { "property": "box-sizing", "expected": "border-box" }, - "message": "Встановіть box-sizing: border-box" + "message": "Який режим розміру включає padding і межу в ширину елемента?" } ] }, @@ -107,7 +107,7 @@ { "type": "regex", "value": "padding:\\s*8px\\s+1rem", - "message": "Встановіть padding: 8px 1rem", + "message": "Використайте скорочення з двома значеннями: спочатку вертикальне, потім горизонтальне", "options": { "caseSensitive": false } } ] @@ -129,7 +129,7 @@ { "type": "regex", "value": "margin:\\s*0\\s+auto", - "message": "Встановіть margin: 0 auto", + "message": "Використайте скорочення, яке автоматично розраховує рівні горизонтальні поля", "options": { "caseSensitive": false } } ] @@ -151,7 +151,7 @@ { "type": "property_value", "value": { "property": "border-radius", "expected": "50%" }, - "message": "Встановіть border-radius: 50%" + "message": "Яка властивість заокруглює кути? Подумайте, який відсоток створює коло" } ] }, @@ -172,18 +172,18 @@ { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, - "message": "Встановіть padding: 1rem" + "message": "Додайте внутрішній відступ до сповіщення" }, { "type": "regex", "value": "border-left:\\s*4px\\s+solid\\s+coral", - "message": "Встановіть border-left: 4px solid coral", + "message": "Додайте кольоровий акцент на лівому краю", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "border-radius", "expected": "4px" }, - "message": "Встановіть border-radius: 4px" + "message": "Згладьте кути сповіщення" } ] } diff --git a/specs/004-validation-messages/plan.md b/specs/004-validation-messages/plan.md new file mode 100644 index 0000000..ff4fd98 --- /dev/null +++ b/specs/004-validation-messages/plan.md @@ -0,0 +1,77 @@ +# Implementation Plan + +## Objective + +Rewrite validation error messages in the box-model and colors lesson modules (and their localizations) so they guide learners toward the answer instead of revealing it. This breaks the "fail-then-copy" loop identified in the pedagogy audit. + +## Approach + +1. Rewrite each validation `message` field in the English box-model and colors JSON files using question/hint phrasing that describes the *concept* without stating the exact property-value pair +2. Use the flexbox module's existing messages as the style guide +3. Apply equivalent translations to all 5 localized box-model files (ar, de, es, pl, uk) +4. Run the format-lessons script and tests to verify nothing breaks +5. Commit as a docs/content fix (`fix:` conventional commit) + +## File Mapping + +### Files to Modify + +| File | Action | Changes | +|------|--------|---------| +| `lessons/01-box-model.json` | modify | Rewrite 11 validation messages | +| `lessons/03-colors.json` | modify | Rewrite 4 validation messages | +| `lessons/ar/01-box-model.json` | modify | Translate 11 new guiding messages to Arabic | +| `lessons/de/01-box-model.json` | modify | Translate 11 new guiding messages to German | +| `lessons/es/01-box-model.json` | modify | Translate 11 new guiding messages to Spanish | +| `lessons/pl/01-box-model.json` | modify | Translate 11 new guiding messages to Polish | +| `lessons/uk/01-box-model.json` | modify | Translate 11 new guiding messages to Ukrainian | + +### Files NOT Changed + +- `lessons/flexbox.json` — already uses guiding messages +- All localized flexbox files — already correct +- No colors localizations exist + +## Architecture Decisions + +1. **Message style**: Use the same imperative hint style as flexbox ("Use the property that...", "Try the property that...") rather than pure questions. This is consistent with the existing codebase and gives just enough direction without revealing the answer. + +2. **No `` tags in new messages**: The current answer-revealing messages use `` to format exact code. The new guiding messages should avoid `` since they won't contain code literals — they describe concepts. + +3. **Preserve validation logic**: Only the `message` field changes. The `type`, `value`, `options`, and all other fields remain untouched. + +4. **Localization approach**: Translate the English guiding messages into each target language, maintaining the same hint/question style. Keep CSS property names untranslated (they are code). + +## Message Mapping (English) + +| Lesson | Current Message | New Message | +|--------|----------------|-------------| +| box-model-1 | Set `padding: 1rem` | Which property adds space between content and the element's edge? | +| box-model-2 | Set `border-left: 4px solid steelblue` | Use the shorthand that sets a border on just one side | +| box-model-3 | Set `margin-bottom: 1rem` | Which property pushes neighboring elements away from the bottom? | +| box-model-4 | Set `box-sizing: border-box` | Which sizing mode includes padding and border in the element's width? | +| box-model-5 | Set `padding: 8px 1rem` | Use the two-value shorthand: vertical first, then horizontal | +| box-model-6 | Set `margin: 0 auto` | Use the shorthand that auto-calculates equal horizontal margins | +| box-model-7 | Set `border-radius: 50%` | Which property rounds corners? Think about what percentage makes a circle | +| box-model-8 v1 | Set `padding: 1rem` | Add inner spacing to the notification | +| box-model-8 v2 | Set `border-left: 4px solid coral` | Add a colored accent on the left edge | +| box-model-8 v3 | Set `border-radius: 4px` | Soften the corners of the notification | +| colors-1 | Set `background-color: seashell` | Which property fills the area behind the content? | +| colors-2 | Set `color: coral` | Which property changes the text color? | +| colors-3 | Set `border-color: coral` | Which property changes just the border's color without redefining the whole border? | +| colors-4 | Set `background-color: #ffd700` | Use the same background property, but with a hex code this time | + +## Risks + +| Risk | Likelihood | Mitigation | +|------|-----------|------------| +| Translation quality for 5 languages | Medium | Use consistent patterns; CSS property names stay in English; keep messages short | +| Messages too vague, frustrating learners | Low | Each message still hints at the concept/direction; task descriptions already contain the answer for early lessons | +| Schema validation failure | Very Low | Only `message` string changes; no structural changes | + +## Testing Strategy + +1. **Automated**: Run `npm run test` — existing unit tests validate the validator logic, not message content, so they should pass unchanged +2. **Automated**: Run `npm run format.lessons` — ensures JSON formatting is correct +3. **Manual verification**: Spot-check that each new message conceptually matches its lesson without revealing the answer +4. **Schema validation**: JSON files reference the schema; any structural errors would be caught by the editor/tooling diff --git a/specs/004-validation-messages/spec.md b/specs/004-validation-messages/spec.md new file mode 100644 index 0000000..34fb058 --- /dev/null +++ b/specs/004-validation-messages/spec.md @@ -0,0 +1,57 @@ +# fix: validation error messages reveal the solution instead of guiding learning + +**Issue:** [#4](https://git.librete.ch/public/code-crispies/issues/4) +**Repository:** public/code-crispies +**Author:** libretech +**State:** open +**Labels:** none + +## Issue Body + +Pedagogy audit: 88% of exercises reveal the answer in error messages, creating a fail-then-copy loop. Change validation messages from 'Set padding: 1rem' to 'Which property adds space between content and the element edge?' This applies across all modules — start with flexbox, box-model, and colors (the 3 worst offenders). + +## Scope + +The three priority modules: + +1. **Flexbox** (`lessons/flexbox.json`) — already uses guiding messages (0 messages need changes) +2. **Box Model** (`lessons/01-box-model.json`) — 11 validation messages reveal exact answers +3. **Colors** (`lessons/03-colors.json`) — 4 validation messages reveal exact answers + +Localized versions that need corresponding updates: +- `lessons/ar/01-box-model.json` +- `lessons/de/01-box-model.json` +- `lessons/es/01-box-model.json` +- `lessons/pl/01-box-model.json` +- `lessons/uk/01-box-model.json` + +No localized versions exist for colors. + +## Acceptance Criteria + +- [ ] All validation messages in box-model module guide the learner instead of revealing the answer +- [ ] All validation messages in colors module guide the learner instead of revealing the answer +- [ ] Messages use question or hint phrasing (e.g., "Which property..." or "Try the property that...") +- [ ] Messages never include the exact property-value pair that solves the exercise +- [ ] All 5 localized box-model files receive equivalent translated guiding messages +- [ ] Existing tests continue to pass (message content is not tested, only validation logic) +- [ ] Lesson JSON files remain valid against the module schema + +## Current vs Desired Pattern + +**Current (answer-revealing):** +``` +"message": "Set padding: 1rem" +``` + +**Desired (guiding):** +``` +"message": "Which property adds space between the content and the element's edge?" +``` + +## Prior Art + +The flexbox module already follows the desired pattern. Its messages serve as the style reference: +- "Try changing the display mode to create a flex container" +- "Use the property that adds spacing between flex items" +- "Use the property that distributes items along the main axis" diff --git a/specs/004-validation-messages/tasks.md b/specs/004-validation-messages/tasks.md new file mode 100644 index 0000000..42b1bf2 --- /dev/null +++ b/specs/004-validation-messages/tasks.md @@ -0,0 +1,20 @@ +# Tasks + +## Phase 1: English Lesson Files +- [X] Task 1.1: Rewrite 11 validation messages in `lessons/01-box-model.json` +- [X] Task 1.2: Rewrite 4 validation messages in `lessons/03-colors.json` + +## Phase 2: Localized Box-Model Files +- [X] Task 2.1: Update validation messages in `lessons/ar/01-box-model.json` (Arabic) [P] +- [X] Task 2.2: Update validation messages in `lessons/de/01-box-model.json` (German) [P] +- [X] Task 2.3: Update validation messages in `lessons/es/01-box-model.json` (Spanish) [P] +- [X] Task 2.4: Update validation messages in `lessons/pl/01-box-model.json` (Polish) [P] +- [X] Task 2.5: Update validation messages in `lessons/uk/01-box-model.json` (Ukrainian) [P] + +## Phase 3: Validation +- [X] Task 3.1: Run `npm run format.lessons` to normalize JSON formatting +- [X] Task 3.2: Run `npm run test` to verify no regressions +- [X] Task 3.3: Spot-check that no message reveals the exact answer + +## Phase 4: Commit +- [X] Task 4.1: Commit all changes with conventional commit message