Skip to content

drift-check: a normalised-equal source copy is reported as drift when it moves in lockstep with the canonical copy #15

Closed

Description

@quantecon-services

Follow-up from the review of #14.

What is inconsistent

Since #14, tools/promote treats two same-name copies as one lecture when they are identical after each copy's asset references are normalised to their pool paths (normalised_text). Such a copy is recorded as a source with its own, different digest. tools/drift-check still compares a non-canonical source byte-for-byte: when the source's digest has changed it checks cur == can_bytes and otherwise raises a diverged drift finding, whose detail text says the copy "was byte-identical at promotion".

Reproduction (with the tools/tests harness)

repo = make_repo(["intro", "intermediate"])
for s in ("intro", "intermediate"):
    repo.mirror_file(s, "_static/lecture_specific/short_path/graph.png", b"png")
repo.lecture("intro", "short_path", lecture_text("Shortest Paths", refs=["/_static/lecture_specific/short_path/graph.png"]))
repo.lecture("intermediate", "short_path", lecture_text("Shortest Paths", refs=["_static/lecture_specific/short_path/graph.png"]))
assert repo.promote("short_path").returncode == 0
assert repo.drift_check().returncode == 0
# the same upstream edit lands in both series, path spelling still differs
repo.lecture("intro", "short_path", lecture_text("Shortest Paths", "edited", refs=["/_static/lecture_specific/short_path/graph.png"]))
repo.lecture("intermediate", "short_path", lecture_text("Shortest Paths", "edited", refs=["_static/lecture_specific/short_path/graph.png"]))
res = repo.drift_check()

Output:

[diverged] lectures/short_path.md: the intermediate copy lectures/short_path.md no longer matches its canonical home in intro
[canonical-moved] lectures/short_path.md: canonical copy in intro changed upstream

The diverged finding opens a drift issue that is false; it clears once the refresh PR merges and re-records the digests. So this is noise, not data loss.

Exposure today

None: every source in the committed ledger is byte-identical to its canonical copy, because promote only admitted byte-identical sources before #14. The first candidates are short_path and ifp_egm once jax is dropped from PROMOTE_EXCLUDE, and any intro/intermediate pair that differs only in /_static/ versus _static/ spelling.

Suggested fix

Give drift-check the same comparison promote uses: before calling a moved source copy diverged, compare its normalised text with the normalised canonical text (promote's normalised_text logic, which only needs the mirror and the slug). A moved copy that is normalised-equal should count as converged/unchanged, and the diverged detail text should stop claiming byte identity at promotion. Alternatively, record in the ledger which sources were admitted by normalisation, so drift-check can tell the two cases apart without re-parsing.

Activity

  1. mmcky commented on Oct 8, 2026

    @mmcky
    Contributor

    #17, now part of #14, settles the lockstep case described here, so this issue closes when #14 lands. The review found one related case that #17 does not reach: a source that is equal to the canonical copy only after normalisation, catches up in its own asset-path spelling, and then falls behind again. That case is filed as #18, together with a copy that caught up to a canonical version that was never recorded.

  2. added a commit that references this issue on Oct 8, 2026
    f5f39cd
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