Skip to content

Untrack pkg/rt/generated.sums once #683 merges #635

Description

@mparrett

Untrack pkg/rt/generated.sums once #683 merges

Summary

pkg/rt/generated.sums is a committed digest of every .lg and generator source. #217 introduced it to replace mtime-based freshness checks, which are unreliable after a git or jj checkout, and it solved that problem.

This proposes retiring the committed copy: gitignore the file, have make generate write it locally, and remove the merge driver that reconciles it. The digest stays. It stops being shared state in the repository.

What the committed copy costs

The digest records a claim about history, and a rebase invalidates that claim by construction. The recorded value means "the artifacts were generated when the sources hashed to X". A rebase rewrites history while leaving artifacts and digest untouched, so the claim goes false with nothing in the tree wrong. The PR goes red on a healthy checkout.

The merge=sums driver only fires when git reports a conflict on the file. When a rebase drops or collapses the digest commit instead, no conflict occurs, the driver never runs, and the digest goes stale silently. That is why the failure reads as intermittent, and why "run make install-hooks" does not help the people hitting it.

The digest hashes sources whose artifact is not tracked. pkg/rt/core_go_lowered/ is gitignored. Editing pkg/rt/core/ir/passes/dce.lg turns CI red while changing no committed artifact. The IR workstream sits in that path, which is where the friction concentrates.

Three CI gates enforce it today, so partial measures do not help: the build job's make check-generated-manifest step, TestGeneratedArtifactsAreFresh in the test lanes, and make check-generated.
#683 removes the third. The remaining two read the committed file directly, and
only untracking clears both.

Measured. #614 and #625 went red on inherited digests with healthy trees.
#630 and #634 each needed a manual regenerate-and-push after their base moved,
#634 twice.

Why now rather than at #217

The original guardrail matched the project it was written for. With two contributors and same-day merges, a hash-everything digest costs nothing: regenerate, push, move on. With multiple contributors, forty-plus merges a week, and PRs open across days of upstream movement, the same file becomes shared mutable state that every compiler-adjacent PR collides on. The guardrail did not get worse; the traffic through it changed.

Ordering: #683 first

The digest is currently the only signal covering op_generated.go, ir_bridge_generated.go, zz_primitives_generated.go and core/ir/data/generated.lg. Untracking it now would remove real protection.

With #683 in, make check-generated compares all five committed artifacts byte for byte — a direct check rather than a proxy.

Proposed change

  • Gitignore pkg/rt/generated.sums and remove it from the index.
  • Keep make generate writing it and scripts/pre-commit reading it as a local fast probe, where answering in milliseconds is the point.
  • Remove .gitattributes merge=sums, scripts/git-merge-sums.sh, and the merge.sums.* half of make install-hooks. Existing clones keep a dead merge.sums.* entry until cleared by hand — harmless, worth noting in the PR.
  • Drop the build job's manifest step and TestGeneratedArtifactsAreFresh, both of which read the committed file. See the open question for what replaces the local signal.

Open question: the local baseline

Untracking removes the baseline that two local checks read. scripts/pre-commit has nothing to compare against on a fresh clone, and TestGeneratedArtifactsAreFresh fails outright with no manifest present. That test is #217's real safety net, and the reason staleness surfaces in a plain go test ./... instead of a 67-second gate.

So this has a cost at the inner loop: after the change, editing a .lg without regenerating gives no local signal until make check-generated or CI. Both checks need the same baseline, so I would settle it once. Three options, no strong preference:

  1. Regenerate once on first run and cache locally.
  2. Fall back to the full content gate when no local digest exists, paying that cost on the first commit only.
  3. No-op until a local digest exists, making it opt-in.

Option 1 keeps the fast path but puts a full regeneration in front of someone's first commit. Option 3 is least surprising and weakens both checks for anyone who never runs make generate. Worth settling before the PR.

Not in scope

core_compiled.lgb stays tracked and still conflicts on rebase — it is //go:embed-ed and go install needs it in the tree. The lgb merge driver stays. This covers the digest only.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions