diff --git a/.dev/STATE.md b/.dev/STATE.md index fb812a08..bcd0e161 100644 --- a/.dev/STATE.md +++ b/.dev/STATE.md @@ -1,4 +1,4 @@ -verified: 2026-07-22 +verified: 2026-07-23 # STATE @@ -12,6 +12,37 @@ Roadmap detail lives in [PLAN.md](PLAN.md), not here. ## Recently landed +- **v0.23.0** (2026-07-23) — **the glossary pair plus the diff-check provenance split**; all + three were "fix before shadow mode" blockers, so shadow calibration is now unblocked. + #150 fixed the CLI half of the glossary defect: `forward` and `init` resolved glossary + candidates only against `process.cwd()`, and **no edition repo carries a glossary** — they ship + inside this package — so a resync launched from the target repo translated with no glossary and + logged nothing either way. Production signature matched exactly: the `init`-seeded lectures in + lecture-python.zh-cn all use the glossary's 边缘分布 for "Marginal distribution" while the + 2026-07-19 `forward` wave took `prob_matrix.md` from 12 wrong / 28 correct to 25 wrong / 35 + correct. Resolution is now package-relative and reported, with `forward --glossary` added. + #151 fixed the Action half (#146: review mode never read `glossary-path`) and, in doing so, + surfaced a deeper defect the issue did not describe — the shared loader tried the built-in + glossary **first** and treated the custom path as a fallback, so `glossary-path` was silently + dead in **all three modes** for every language that ships a glossary, i.e. the whole estate. + It is now an override that fails the run when unreadable. + #152 (#148) split measured fact from model opinion in the four `diffChecks`, which gate + absolutely but were all model output — a hallucinated boolean routed a correct PR to `editor` + on the second organic production PR under verdict v2. `structurePreserved` and + `headingMapCorrect` are computed from ground truth the engine already holds; + `scopeCorrect`/`positionCorrect` stay model-asserted, are tagged in a new optional + `diffCheckSources` field, and gate through a `diff-check` finding instead of the boolean. + **Routing is unchanged**; the win is that Stage 4 can report the two precisions separately. + Note what it does *not* do: `positionCorrect` — the check that actually misfired — is still + model-driven, made visible rather than fixed, because deterministic change attribution across a + translated document would swap model false-gates for engine false-gates that are harder to spot. + **Verified against the live estate before shipping**: 248 of 249 production files with sections + carry a heading map, so the new deterministic check gates exactly one file fleet-wide — + lecture-python-programming.fa's `autodiff.md`, a genuine gap fixed in that edition's #142. + Harness-validated end to end on both target languages, including that `auto-merge` is still + reachable (the 2026-07-23 fixture trap) and that the check reads the **legacy** `heading-map:` + frontmatter key, so it will not false-gate an unmigrated repo. + - **v0.22.0** (2026-07-22) — #144 delivered **reviewer verdict v2**, the machine-readable review contract (#103 prerequisite, specified in #66): every review comment now ends with a `translation-review-verdict` JSON block carrying per-criterion scores, the composite that was diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 04e1abef..9929ceb2 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -9,7 +9,7 @@ - **Review Mode**: Runs in TARGET repo, posts quality review comments on translation PRs - **Rebase Mode**: Runs in TARGET repo, rebases conflicted translation PRs when a sibling PR is merged -**Current Version**: v0.22.0 | **Tests**: 1,249+ (52 suites; exact count in CI) | **Glossary**: 357 terms (zh-cn, fa), 364 (fr) +**Current Version**: v0.23.0 | **Tests**: 1,297+ (55 suites; exact count in CI) | **Glossary**: 357 terms (zh-cn, fa), 364 (fr) --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b569f4..e124df06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.23.0] - 2026-07-23 + ### Changed - **Two of the four `diffChecks` are now computed, not asserted by the model, and every check declares its provenance** (#148): the four booleans gate the auto-merge recommendation absolutely, which is right for *missing* data — but they were all model output, so a confidently wrong boolean was indistinguishable, to the gate, from a genuine structural failure. That fired on the **second** organic production PR ever reviewed under verdict v2: QuantEcon/lecture-python.zh-cn#199 routed to `editor` on `positionCorrect`, with findings asserting the source's code change had never been applied to the target — it had. The direction is safe (it fails toward a human), but Stage 4 chooses the per-criterion floors from shadow data, and reviewer error is indistinguishable from translation defects in that data unless somebody hand-diffs every PR. `structurePreserved` and `headingMapCorrect` are now computed from ground truth the engine already holds — the structural parity guard (directive openings and target anchors) plus the section-tree heading-level sequence, and the frontmatter heading map compared against what `buildHeadingMap` derives from the two documents. `scopeCorrect` and `positionCorrect` stay model-asserted deliberately: `positionCorrect` needs change attribution across a translated document, and inventing that logic would replace model false-gates with engine false-gates that are harder to spot. **Routing is unchanged** — a model check that reports failure now gates through a `minor`/`diff-check` finding rather than the boolean, so it still reaches a human, but it is no longer recorded in the same field Stage 4 will treat as measured fact. New verdict field `diffCheckSources` (a pure, **optional** addition, so `schemaVersion` stays 1; absent on pre-v0.23.0 blocks, where absence means *treat every check as gating* — those checks were model-derived but they also gated absolutely, so reading absence as "model, therefore advisory" would turn historical data fail-open) and a new gating finding category `diff-check`. The published `scores.diff` and the action's `diff-score` output are derived from the **merged** checks rather than the model's originals, so the block cannot report `diff: 10` beside a `false` boolean, and a deterministic structural failure now moves the overall score and the PASS/WARN/FAIL threshold as it should. Verified against the live estate before shipping: of 249 production files with sections, **248 carry a heading map**, so the new deterministic check gates exactly one file fleet-wide — `lecture-python-programming.fa`'s `autodiff.md`, an in-`_toc` lecture with 16 sections and no map, which is a genuine defect the check surfaced on first contact rather than a false gate. diff --git a/package-lock.json b/package-lock.json index 8f1175a1..674c5760 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "action-translation", - "version": "0.22.0", + "version": "0.23.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "action-translation", - "version": "0.22.0", + "version": "0.23.0", "license": "MIT", "dependencies": { "@actions/core": "^2.0.3", diff --git a/package.json b/package.json index 6c99c65b..a50fb50a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "action-translation", - "version": "0.22.0", + "version": "0.23.0", "private": true, "type": "module", "description": "GitHub Action to sync and review translations across repositories",