feat(ml): exercise-family blocks byte-identical to source, enforced in code; encode the ml#12 answers (glossary v0.5.0, rules 24 → 23, E2E scenario 28) - #303
Conversation
…ce, enforced in code; encode the ml#12 answers The editor of record answered QuantEcon/lecture-python-programming.ml#12 (2026-09-01): until he has ruled on each exercise individually, every exercise-related block stays in English, byte-for-byte identical to the source. That reverses the 09-01 scope ruling shipped in v0.27.0 (whose rule text told the model pure-programming exercises MUST NOT be left in English) and, being a rule with no judgement boundary, belongs in code rather than the prompt. - src/verbatim-directives.ts (new): nesting-aware fence walk (backtick, tilde, colon; literal bodies opaque via typography's PROSE_DIRECTIVES, now exported) locating {exercise}, {exercise-start}…{exercise-end}, {hint}, {solution}, {solution-start}…{solution-end} as outermost regions; applyVerbatimDirectives restores them from the source for policy languages (ml), pairing by position and refusing to guess on a differing block sequence; findVerbatimViolations reports divergence. - Wired into sync-orchestrator (both seams), translate init and translate forward, each immediately before checkStructuralParity so parity checks the bytes written. - diff-checks: checkVerbatimDirectives + optional targetLanguage on runDeterministicDiffChecks; reviewer surfaces failures as blocker findings in the gating diff-check category — additive, verdict schema unchanged. - ml rules 24 → 23: the 09-01 and 08-17 scope rules replaced by one verbatim statement; "For example," joins the English-retained connectives (not ഉദാഹരണത്തിന്); the light-verb rule names the refer calque (never സൂചിപ്പിക്കുന്നു); headings byte-identical including possessives (the Matplotlib-യുടെ miss on ml#13). - glossary/ml.json v0.5.0: already, example, examples, name (noun; naming stays പേര്), work (light-verb form). - E2E scenario 28 (28-add-exercise-lecture): the suite's first exercise-family directives; README and prefix message updated. - Decision record D-2026-09-03-ml-all-exercise-content-stays-english; supersession note atop D-2026-09-01. The ex5 "over-read" logged on #296 is withdrawn. Suite 1553 green; lint, format and dev-ref checks clean; dist and dist-action rebuilt. Refs: #296, #189, #260, QuantEcon/lecture-python-programming.ml#12, QuantEcon/lecture-python-programming.ml#14 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
There are a few concrete maintainability/documentation issues in the new/modified code paths (notably misattached JSDoc and forward-compat gaps) that should be corrected before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR codifies a deterministic “verbatim exercise-family” policy for Malayalam (ml) by restoring exercise/hint/solution directive blocks byte-identically from the English source on all write paths, and by adding a review-time diff-check that escalates divergences as blocking findings. It also encodes the editor’s round-2 answers by updating the Malayalam glossary/rules and extends the E2E harness with a new scenario covering exercise directives.
Changes:
- Add
src/verbatim-directives.tsto extract/restore exercise-family directive regions and wire it into sync/init/forward immediately before structural parity checks. - Add deterministic review support (
checkVerbatimDirectives) gated by an optionaltargetLanguageparameter and surface violations asblockerfindings inreviewer.tswithout changing the published verdict schema. - Update
mllanguage rules + glossary to v0.5.0, add harness scenario 28, update docs/changelog/decision log, and rebuilddist-action/.
File summaries
| File | Description |
|---|---|
| tool-test-action-on-github/test-action-on-github.sh | Adds scenario 28 and updates scenario prefix validation/help text. |
| tool-test-action-on-github/test-action-on-github-data/28-add-exercise-lecture.md | New fixture that introduces exercise/hint/solution directives to validate verbatim behavior. |
| tool-test-action-on-github/README.md | Documents the new 28th scenario and updates scenario counts. |
| src/verbatim-directives.ts | Implements extraction, restoration, and violation detection for exercise-family verbatim blocks. |
| src/typography.ts | Exports PROSE_DIRECTIVES so verbatim extraction can reuse the directive classification logic. |
| src/sync-orchestrator.ts | Applies verbatim restoration on sync write paths before structural parity checks. |
| src/reviewer.ts | Passes targetLanguage into deterministic diff checks and escalates verbatim violations as blocking findings. |
| src/language-config.ts | Updates Malayalam rule set (24→23), folds in ml#12 answers, and replaces prior exercise-scope rule with verbatim policy statement. |
| src/diff-checks.ts | Adds optional verbatimDirectives deterministic check (enabled only for policy languages). |
| src/cli/commands/init.ts | Applies verbatim restoration in translate init before structural parity. |
| src/cli/commands/forward.ts | Applies verbatim restoration in forward resync before structural parity. |
| src/tests/verbatim-directives.test.ts | New tests covering extraction/restoration and deterministic diff-check wiring. |
| src/tests/language-config.test.ts | Updates assertions to match the new ml rules and removed prior scope ruling. |
| glossary/ml.json | Bumps glossary to v0.5.0 and adds the editor-answered pins (already/example(s)/name/work). |
| docs/developer/architecture.md | Registers the new module in the architecture map. |
| dist-action/index.js | Updates the committed action bundle to include the new verbatim policy logic and reviewer changes. |
| CHANGELOG.md | Documents the new deterministic verbatim policy, new diff-check behavior, and scenario 28. |
| .dev/STATE.md | Updates verified date to 2026-09-03. |
| .dev/log/2026-09-03-ml-round2-answers.md | New dev log entry recording the encoded ml#12 answers and deterministic scope change. |
| .dev/decisions/D-2026-09-03-ml-all-exercise-content-stays-english.md | New decision record superseding prior exercise-scope rulings and specifying deterministic enforcement. |
| .dev/decisions/D-2026-09-01-ml-exercise-statements-stay-english.md | Adds a superseded notice pointing to the new 2026-09-03 decision record. |
Review details
- Files reviewed: 21/22 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Harness validation (local bundle from
Two recipe notes for Release gate at the tag will run 28 × 3 = 84 sync runs. |
…patible deterministic findings, reattach the processMarkdownFile JSDoc - diff-checks: checkVerbatimDirectives breaks the outer loop once MAX_DETAILS is reached and slices the return, so the cap is a guarantee rather than an inner-loop courtesy. - reviewer: minor/structure findings are derived from every deterministic result except verbatimDirectives (which gates on its own as a blocker), so a check added later surfaces without editing this list. - sync-orchestrator: the processMarkdownFile JSDoc sits above processMarkdownFile again; restoreVerbatimDirectives carries only its own. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Encodes the editor's answers on QuantEcon/lecture-python-programming.ml#12 (2026-09-01) — the items #296 held back — and, larger than expected, his exercise ruling, which reverses the 09-01 scope rule shipped in v0.27.0: every exercise-family block stays byte-identical to the English source until he rules on each exercise individually. Decision record
D-2026-09-03-ml-all-exercise-content-stays-english(supersedesD-2026-09-01-ml-exercise-statements-stay-english, note atop it).Why in code, not prompt
The v0.27.0 rule told the model that a pure-programming exercise "MUST NOT be left in English"; the editor now wants the opposite, with no judgement boundary at all. A rule with no boundary is a copy step.
src/verbatim-directives.tslocates{exercise},{exercise-start}…{exercise-end},{hint},{solution}and{solution-start}…{solution-end}as outermost regions with a nesting-aware fence walk (backtick, tilde and colon fences; literal bodies such as code cells are opaque, reusing typography'sPROSE_DIRECTIVES, now exported) and restores them from the source for policy languages (ml, aMaplike typography's rule table). Blocks pair by position; a differing block sequence is left untouched and logged rather than guessed. It runs on all three write paths — sync-orchestrator (both seams),translate init,translate forward— immediately beforecheckStructuralParity, so parity checks the bytes that are written. This is the first fully mechanical ml scope rule, the shape #260 (W2) and the #189 Phase 3 graduation ask for.Review side
checkVerbatimDirectivesindiff-checks.ts, carried byrunDeterministicDiffChecksthrough a new optionaltargetLanguageparameter (present only for policy languages). A divergent block surfaces inreviewer.tsas ablockerfinding in the gatingdiff-checkcategory, so the PR routes to the editor. It is deliberately not a fifthDIFF_CHECK_NAMESentry: the verdict schema and the diff score divisor are unchanged.The held items
work ചെയ്യുന്നുണ്ടോrefercalque (both v0.27.0 draws)The ex5 "over-read" logged on #296 for the v0.27.0 regeneration arm was correct behaviour under the new ruling and is withdrawn.
Harness
The fixture suite carried no exercise, hint or solution directive anywhere, so nothing could exercise this end-to-end. Scenario 28 (
28-add-exercise-lecture) appends an Exercises section with{exercise-start}/{hint}/{solution-start}blocks tolecture.md; on the.mllane the sync output must carry them byte-identical, on.zh-cn/.fathey translate as before. Validation record for this PR follows in a comment (local bundle against a scenario-28 harness PR).Lecture side
QuantEcon/lecture-python-programming.ml#14 restores
functions(4 of 10 blocks) andpython_by_example(7 of 10) to byte-identical English plus the line-159 typo;matplotlib(ml#13) was already compliant.Suite 1553 green; lint, format and dev-ref checks clean;
dist-action/rebuilt.Refs: #296, #189, #260. Supersedes the exercise half of #297's encoding.
🤖 Generated with Claude Code