Skip to content

Triage 2026-07-20: priority order for the 33 open issues — silent-corruption class first #120

Description

@mmcky

Triage of all 33 open issues as of 2026-07-20, with a priority order to work from tomorrow. This supersedes the ordering in #113 (2026-07-18) — not its content, which still holds, but its sequence, because five issues opened after it (#115#119) land squarely on the argument #94 made and change what should go first.

Why the order changed

#94's second ordering rule was detection before repair: "fixing five silent bugs without a check that would catch the sixth is worse value than building the check." That was written on 2026-07-15 against five known defects. Since then the lecture-python.zh-cn resync wave produced the sixth, seventh and eighth — #118, #119, #117 — and every one of them followed the predicted shape exactly: the run reported success, the output looked plausible, and the corruption surfaced only weeks later on a cold strict build in a downstream repo.

#118 is the sharpest case. The resync wrapped an entire 1,465-line document in a code fence and wrote V, σ, μ as its title — a Python tuple-unpacking line lifted from line 686 of the source. It presented downstream as 13 × "headings start at H2, not H1", and the fix recommended there would have restored an H1 and left the swallowed {include} broken. Nothing in our pipeline noticed; nothing in our pipeline could have noticed. That is the whole case for Phase 2 in one file.

The three fresh defects also sharpen the shape of the fix. #118 (structure parse fell through to a degraded path), #119 ({raw} jupyter{raw}) and #65 ((label)= anchors dropped) are all one class — structural MyST mutated by a path that should have passed it through verbatim — and #119 proposes a guard that is cheap, deterministic, and catches the class: assert every directive info string in the output matches its counterpart in the source, argument included. Those lines are never legitimately translated, so any divergence is a defect by definition.

Priority table

P Issues Theme Why this band
P0 #118, #119, #65, #90, #94 Phase 2 Silent corruption + the detection layer Output is wrong and the run says success. Eight instances now, discovered downstream every time.
P1 #117, #107, #106 Resync correctness gaps Deterministic, known-reproducible, each has evidence attached; #117 and #106 have cheap first-cut fixes.
P2 #113 item 1, #115, #116, #109, #95 Delivery and mechanical polish Small, unblocking. The estate bump is the one that decides whether any P0 fix reaches a target repo.
P3 #82, #92, #103, #91, #66, #53, #94 Phase 6 Measurement, contracts, consolidation Real value, no active bleeding. #82 gains its first metric free from P1.
P4 #70, #56, #55, #61, #74, #73, #81, #48, #1, #2, #3, #4, #6, #7 Features, design, long-horizon Nothing here is blocked by anything above.

P0 — the corruption class

The four items are one piece of work, and the order matters:

  1. Directive-shape assertion on write (forward resync stripped a MyST directive argument: {raw} jupyter -> {raw} (sir_model, v0.17.0) #119, Translator drops MyST label anchors like (label)= before headings #65). Cheapest, most immediate. For every fenced directive in the output, the info string must match the source's, argument included. Fail the file loudly on divergence. This is a guard we can ship before understanding forward resync wrapped an entire document in a code fence and mis-derived its title (ak_aiyagari, v0.17.0) #118, and it independently closes the Translator drops MyST label anchors like (label)= before headings #65 production breakage that has been open since May.
  2. Round-trip invariant reconstruct(parse(doc)) === doc (Work plan: suggested order for the post-review backlog #94 Phase 2). The detection layer. Work plan: suggested order for the post-review backlog #94 already establishes it catches three of Silent data loss in the sync merge path — five ways translations vanish while the run reports success #90's five defects as a class, plus the typography bug that shipped. On the evidence of forward resync wrapped an entire document in a code fence and mis-derived its title (ak_aiyagari, v0.17.0) #118 it would also have caught a document that came back fence-wrapped.
  3. Root-cause forward resync wrapped an entire document in a code fence and mis-derived its title (ak_aiyagari, v0.17.0) #118. Why did structure parsing fall through to a degraded path that both mis-derived the title and treated the body as opaque? The file is the largest in its edition (1,465 lines, 59 code cells) and a JAX rewrite — size, a parse timeout, or a truncated model response are the starting hypotheses. A sweep of all 8 edition clones found no second instance, so this is rare, which makes it more dangerous, not less: rare and silent means it lands unnoticed.
  4. Real validateMyST + canonicalizeHeading(), then the Silent data loss in the sync merge path — five ways translations vanish while the run reports success #90 remainder. Unchanged from Work plan: suggested order for the post-review backlog #94 §3–4. validateMyST validates nothing today because parseSections never throws, so the gates cannot fire.

Also relevant to P0 and outside our repo: the downstream editions lacked -n -W on the notebook build, which is why #118 and #119 survived merge. That has been fixed in QuantEcon/lecture-python.zh-cn#185. Worth confirming the same guard exists across the other editions — it is our last line of defence and it was absent where it mattered.

P1 — resync correctness

Issue Cheapest useful fix Evidence
#117 Lint: extract every {cite} key from the resynced file, assert it resolves in the target .bib, pull or flag if not 4 of 36 lectures in one tier; all four keys present upstream, absent downstream
#107 Validation wave first — the prompt change is live but unmeasured 11 hand-fixed intro.zh-cn branches are the ground truth
#106 --from-status so forward can consume a check-sync run; fix summary to bucket by outcome not verdict Discovery found 12 of 41 stale files; summary reported files as skipped that it had resynced

#107 is the one to be careful with. The prompt change shipped in v0.18.0 and nobody has measured it. #113 item 2 already specifies the wave — re-run forward -f on long_run_growth, inequality, heavy_tails, diff against the hand-fixed branches, count CJK-bearing code lines per file. Run it before layering more prompt changes on top, and it seeds #82 with its first real metric as a side effect.

P2 — delivery

The estate bump is listed first for a reason: the estate sits at v0.16.1 on 9 explicit ref: pins across 4 repos, two releases behind. Every fix in P0 and P1 lands in a repo that is not running it until those pins move. Repos on @v0 are already current.

#115 and #116 are both small and both bite during exactly the drift-recovery waves that are surfacing everything else — #115 leaves 60+ resync PRs with no rebase trigger because the template filter only matches translation-sync-* and forward writes resync/*; #116 is a one-line trailing-newline fix that dirtied all 69 branches in the Track B wave. #109 carries one decision worth making deliberately rather than by default: whether createForwardPR should also apply action-translation so review triggers on resync PRs at all. #113's recommendation is yes.

Suggested order for tomorrow

Start at P0 item 1 — the directive-shape assertion is a contained, shippable guard that closes #119 and #65 together and gives immediate protection while the larger Phase 2 work proceeds. Then the #117 cite lint, which is the same shape of cheap deterministic check on a different surface. Both are small enough to land in one release with the P2 mechanical items (#115, #116), which would make the estate bump worth doing once, afterwards, carrying everything.

The #107 validation wave can run in parallel with any of the above — it is measurement, not code, and it does not conflict.

Gardening

Refs

#113 (post-v0.18.0 plan, superseded in sequence only), #94 (standing work plan, still the reasoning of record), #114 (2026-07-18 session handoff).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions