You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observed 2026-08-18 on lecture-python-programming: commenting \translate-resync on PR #595 (merged 2026-08-12) regenerated sync PRs whose translated sections were built from #595's merge-time snapshot of the source, not from current source main. Anything the source changed in those sections after #595 — in this case the test_pwt.csv repoint from lecture-python-programming#612 (merged earlier the same day) — gets reverted in the regenerated target content.
Concrete evidence, from the regenerated PRs before any merge: lecture-python-programming.zh-cn#93's only lecture-content change was reverting two already-repointed polars.md reads back to the old own-repo raw URL (a URL scheduled for deletion), and lecture-python-programming.fa#154 carries the same two reversions plus a rewrite of three pandas_panel.md data reads from the github.com/QuantEcon/data-lectures/raw/main/… form to the raw.githubusercontent.com/… form — i.e. whatever URL form the snapshot happened to hold. The French regeneration (fr#34) was clean only because that target had not yet received the newer edits, so its sections still matched the snapshot.
The trap is sharpest exactly when resync is most needed: a queued sync PR conflicts because later source changes touched the same lectures, someone resyncs to regenerate it, and the regeneration quietly re-applies the pre-conflict content the rebase refused to. The failure is silent — the PR looks like a normal retranslation and merges cleanly.
Suggested direction: in resync mode, rebase the source diff onto current source main before translating (or diff old-source-at-PR against current main rather than against the PR's own head), so a regenerated section can never carry source content older than what main serves. A cheaper guard: after generating, diff the code cells (not prose) of the regenerated sections against current source main and fail the run if any code cell differs — code cells are language-invariant, so any mismatch is stale-snapshot content by construction.
The state files regenerated in these PRs share the problem: they record hashes against the stale snapshot, so merging one also corrupts the baseline the next sync diffs against.
Fallout ledger (2026-08-19, measured)
Triage: labeled bug + high-priority; W1 (#259) carries a deterministic detection box for this; the regeneration repair stays here. Operating rule until it lands: do not use \translate-resync.Superseded 2026-08-20 — see the ruling comment below. The blanket moratorium is replaced by a measured precondition: \translate-resync is permitted only when git rev-list --count <mergeSha>..origin/main -- <path> is 0 for every file in the source PR (not just the file named in a failure issue). The documented recovery route also moves off resync onto the CLI (translate forward -f / init -f), which reads source off the local filesystem and cannot exhibit this defect.
Method: for all 21 state files across the three targets (7 lectures × 3), the recorded source-sha was compared against the source repo's true last-touch commit for that lecture, plus content probes for each #595/#612 edit (the PyTorch casing fix, the DiscreteRV seed docstring, qe.Timer mentions, and the data-read URL forms). Reference commits on source main: d35eb831 = the #595 batch (last touch for about_py, autodiff, numpy, pandas_panel, python_by_example), 55c87c9f = the #612 repoint (last touch for pandas, polars).
Fully consistent, nothing outstanding. The original batch PR (#89 there) merged at 03:11 before the repoint; the stale regeneration (#93) was correctly closed unmerged.
fr
6 of 7 match; numpy records a2b929f1 (2026-05-13) vs actual d35eb831
numpy is missing both #595 edits: docstring still the pre-#595 text, 2 of 3 qe.Timer mentions
numpy.md never received #595. The original batch PR (#30) was closed unmerged and the regeneration (#34) silently omitted the file. State is honest — it flags numpy as pending.
fa
pandas and polars record d35eb831 vs actual 55c87c9f — the regeneration overwrote the repoint sync's correct state; about_py records 3213613a (2026-05-09, pre-dates this incident)
lectures current except pandas_panel: three data reads carry github.com/QuantEcon/data-lectures/raw/main/… while source at its own last touch uses raw.githubusercontent.com/QuantEcon/data-lectures/main/…
Two stale state files (effect: isSourceChanged over-reports — the fail-safe direction) plus a three-line pandas_panel divergence introduced by the #155 restore, which restored a URL form the source itself had moved off. fa about_py is effectively current in content (PyTorch ×3 already correct); its ordinary pending-state heals on the next organic touch.
Corrections to this issue's original account, from the measurement: (1) the pandas_panel rewrite in fa#154 was correct sync content, not snapshot damage — the #595 batch itself moved the source's URL form to raw.githubusercontent, and the hand-restore then overcorrected it; (2) state files record a per-file source-sha (a commit id), not content hashes, and the stale values sit on the fail-safe side — tools over-report staleness rather than mask it; (3) the incident has a second mechanism, distinct from the stale snapshot: a regeneration can silently drop a file of the PR it replaces (fr numpy), which feeds W1's declared-vs-delivered assertion directly.
Repairs — merged and verified 2026-08-19 (both deterministic, no re-translation). The fallout is fully remediated; what stays open here is the bug itself.
fr: ported #595's two numpy edits by hand — the docstring addition verbatim (fr keeps docstrings in English) and the one prose sentence (tic/toc → qe.Timer()), advancing numpy's state to d35eb831. forward was not used, deliberately: numpy.md is one of the two natively-reviewed fr lectures (fr#24) and whole-file regeneration would discard the review. Landed via Port the numpy.md edits the resync regeneration dropped (seed docstring, qe.Timer) lecture-python-programming.fr#38 (merge 4eb56d6e, 03:33Z). Post-merge byte-check on main: seed docstring present, qe.Timer ×3 (matching fa/zh-cn), state records d35eb831.
Post-merge, the recorded-vs-actual mismatch set across all 21 state files is zero, modulo fa about_py's benign pre-incident pending-state, which self-heals on the next organic touch. Still open on this issue: the regeneration repair. Re-specified 2026-08-20: compare the source snapshot against current source main — English against English, one repos.compareCommits call over the PR's file set — and fail closed on drift, rather than comparing the regenerated target's code cells against source (which is dominated by legitimate localisation divergence). Note a naive move to current main re-opens the inverse defect that #44 repaired; a correct fix splits the pair, base at merge_commit^ and head at main.
Design note for the W1 guard, measured on numpy.md: code cells are not wholly language-invariant — fa and zh-cn localize docstrings and comments inside code cells; fr keeps them English. The invariance check must strip comment/docstring lines or key off the per-language code-comments rule.
Observed 2026-08-18 on lecture-python-programming: commenting
\translate-resyncon PR #595 (merged 2026-08-12) regenerated sync PRs whose translated sections were built from #595's merge-time snapshot of the source, not from current source main. Anything the source changed in those sections after #595 — in this case the test_pwt.csv repoint from lecture-python-programming#612 (merged earlier the same day) — gets reverted in the regenerated target content.Concrete evidence, from the regenerated PRs before any merge: lecture-python-programming.zh-cn#93's only lecture-content change was reverting two already-repointed polars.md reads back to the old own-repo raw URL (a URL scheduled for deletion), and lecture-python-programming.fa#154 carries the same two reversions plus a rewrite of three pandas_panel.md data reads from the
github.com/QuantEcon/data-lectures/raw/main/…form to theraw.githubusercontent.com/…form — i.e. whatever URL form the snapshot happened to hold. The French regeneration (fr#34) was clean only because that target had not yet received the newer edits, so its sections still matched the snapshot.The trap is sharpest exactly when resync is most needed: a queued sync PR conflicts because later source changes touched the same lectures, someone resyncs to regenerate it, and the regeneration quietly re-applies the pre-conflict content the rebase refused to. The failure is silent — the PR looks like a normal retranslation and merges cleanly.
Suggested direction: in resync mode, rebase the source diff onto current source main before translating (or diff old-source-at-PR against current main rather than against the PR's own head), so a regenerated section can never carry source content older than what main serves. A cheaper guard: after generating, diff the code cells (not prose) of the regenerated sections against current source main and fail the run if any code cell differs — code cells are language-invariant, so any mismatch is stale-snapshot content by construction.
The state files regenerated in these PRs share the problem: they record hashes against the stale snapshot, so merging one also corrupts the baseline the next sync diffs against.
Fallout ledger (2026-08-19, measured)
Triage: labeled
bug+high-priority; W1 (#259) carries a deterministic detection box for this; the regeneration repair stays here.Operating rule until it lands: do not useSuperseded 2026-08-20 — see the ruling comment below. The blanket moratorium is replaced by a measured precondition:\translate-resync.\translate-resyncis permitted only whengit rev-list --count <mergeSha>..origin/main -- <path>is 0 for every file in the source PR (not just the file named in a failure issue). The documented recovery route also moves off resync onto the CLI (translate forward -f/init -f), which reads source off the local filesystem and cannot exhibit this defect.Method: for all 21 state files across the three targets (7 lectures × 3), the recorded
source-shawas compared against the source repo's true last-touch commit for that lecture, plus content probes for each #595/#612 edit (the PyTorch casing fix, the DiscreteRV seed docstring,qe.Timermentions, and the data-read URL forms). Reference commits on sourcemain:d35eb831= the #595 batch (last touch for about_py, autodiff, numpy, pandas_panel, python_by_example),55c87c9f= the #612 repoint (last touch for pandas, polars).raw.githubusercontentform ✓ · polars/pandas URLs ✓a2b929f1(2026-05-13) vs actuald35eb831qe.Timermentionsd35eb831vs actual55c87c9f— the regeneration overwrote the repoint sync's correct state; about_py records3213613a(2026-05-09, pre-dates this incident)github.com/QuantEcon/data-lectures/raw/main/…while source at its own last touch usesraw.githubusercontent.com/QuantEcon/data-lectures/main/…isSourceChangedover-reports — the fail-safe direction) plus a three-line pandas_panel divergence introduced by the #155 restore, which restored a URL form the source itself had moved off. fa about_py is effectively current in content (PyTorch×3 already correct); its ordinary pending-state heals on the next organic touch.Corrections to this issue's original account, from the measurement: (1) the pandas_panel rewrite in fa#154 was correct sync content, not snapshot damage — the #595 batch itself moved the source's URL form to
raw.githubusercontent, and the hand-restore then overcorrected it; (2) state files record a per-filesource-sha(a commit id), not content hashes, and the stale values sit on the fail-safe side — tools over-report staleness rather than mask it; (3) the incident has a second mechanism, distinct from the stale snapshot: a regeneration can silently drop a file of the PR it replaces (fr numpy), which feeds W1's declared-vs-delivered assertion directly.Repairs — merged and verified 2026-08-19 (both deterministic, no re-translation). The fallout is fully remediated; what stays open here is the bug itself.
.translate/state/pandas.md.ymland.translate/state/polars.md.ymlto the repoint sync's versions (source-sha: 55c87c9f…), and reverted the pandas_panel half of the Decide whether positionCorrect should be deterministic — #148's deliberate residual, now measurable #155 restore (three URL lines back to the source'sraw.githubusercontentform). Landed via Repair the #154 regeneration residue: repoint state for pandas/polars, pandas_panel URL form lecture-python-programming.fa#158 (merge905bab7f, 03:33Z). Post-merge byte-check onmain: both state files record55c87c9f, pandas_panelraw.githubusercontent×3.qe.Timer()), advancing numpy's state tod35eb831.forwardwas not used, deliberately: numpy.md is one of the two natively-reviewed fr lectures (fr#24) and whole-file regeneration would discard the review. Landed via Port the numpy.md edits the resync regeneration dropped (seed docstring, qe.Timer) lecture-python-programming.fr#38 (merge4eb56d6e, 03:33Z). Post-merge byte-check onmain: seed docstring present,qe.Timer×3 (matching fa/zh-cn), state recordsd35eb831.Post-merge, the recorded-vs-actual mismatch set across all 21 state files is zero, modulo fa about_py's benign pre-incident pending-state, which self-heals on the next organic touch. Still open on this issue: the regeneration repair. Re-specified 2026-08-20: compare the source snapshot against current source
main— English against English, onerepos.compareCommitscall over the PR's file set — and fail closed on drift, rather than comparing the regenerated target's code cells against source (which is dominated by legitimate localisation divergence). Note a naive move to current main re-opens the inverse defect that #44 repaired; a correct fix splits the pair, base atmerge_commit^and head at main.Design note for the W1 guard, measured on numpy.md: code cells are not wholly language-invariant — fa and zh-cn localize docstrings and comments inside code cells; fr keeps them English. The invariance check must strip comment/docstring lines or key off the per-language code-comments rule.