Skip to content

Add a hard CI gate for stale tommy/peg codegen drift #265

@sfriedenberg-etsy

Description

@sfriedenberg-etsy

Problem

Generated Go codegen (*_tommy.go, *_string.go, *_stringer.go) can
silently drift out of sync with the generator that produced it, and
nothing in the pre-merge lane catches it.

Today (2026-06-12) a nix flake update bumped tommy from 0.4.3
(1ae69d3) to 0.4.4 (054f61d). Running just build regenerated 27
*_tommy.go files — version-comment bumps plus a generated internal
handle-type rename (fieldDefinitionHandle -> tomlV2FieldsHandle in
go/internal/alfa/type_blobs/toml_v2_tommy.go). The drift was only
noticed because a human eyeballed git status after the build. There is
no automated gate that would have failed if those regenerated files had
not been committed.

Why current gates miss it

  • go/check-treelint (the conformist formatting gate, wired into the
    pre-merge lint lane) only checks formatting drift — it runs
    goimports/gofumpt/nixfmt/shfmt and fails if any file would be
    reformatted
    . It does not re-run go generate, so a generator-output
    change that is already gofumpt-clean sails through.
  • go/build-go-generate regenerates codegen but is a build step, not
    a check. Nothing in go/check re-runs go generate and diffs the
    result against the committed tree.

Net effect: a generator version bump that changes output, committed
without regenerating, would leave stale codegen in the tree with zero
CI signal.

Desired behavior

A hard conformist (or check-lane) failure when the committed codegen
does not match a fresh go generate. Sketch:

  1. Run go generate ./... (the same invocations as
    go/build-go-generate) in a scratch checkout / sandbox.
  2. git diff --exit-code over *_tommy.go, *_string.go,
    *_stringer.go.
  3. Non-zero exit (with the offending paths) if anything changed.

Wire this into the go/check recipe so it runs in the spinclass
pre-merge hook (bare just), the same lane that runs check-treelint.
Open question for the implementer: whether this belongs as a new
conformist check or a standalone check-go-codegen recipe — the comment
on build-go-generate notes the generators emit non-gofumpt-clean
output that codemod-go-fmt canonicalizes afterward, so the gate must
diff after the format step to avoid false positives.

Environment

  • dodder: master @ dc602cabe (tommy codegen regenerate commit)
  • tommy: 0.4.4 (054f61d), bumped from 0.4.3 (1ae69d3) via flake update
  • Relevant recipes: go/build-go-generate, go/codemod-go-fmt,
    go/check-treelint, go/check (all in go/justfile)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions