Problem
#634 adds GENERATED-TRACKED to the Makefile: the committed generated
artifacts that make check-generated stashes, regenerates, and compares. The comment says "keep this list in step with scripts/generate.lg" and nothing checks that it is.
If generate.lg grows a sixth committed output and the Makefile list is not updated, the gate silently under-covers it. That is the failure #634 exists to fix, reintroduced one level up. Before #634 the gate compared only core_compiled.lgb, which is how zz_primitives_generated.go sat drifted from its generator without anything noticing.
Where the outputs are declared
Four of the five outputs are already named at their call site:
(gen-go "…/op_generated.head" "pkg/ir/ir_ops.lg" "pkg/ir/op_generated.go")
(gen-go "…/ir_bridge_generated.head" "pkg/ir/ir_bridge.lg" "pkg/rt/ir_bridge_generated.go")
(gen-lisp "pkg/ir/ir_data.lg" "pkg/rt/core/ir/data/generated.lg")
(run! … "./cmd/lginterop" … "-primitives-out" "pkg/rt/zz_primitives_generated.go")
Only core_compiled.lgb is implicit, written inside lgbgen --target=both along with generated.sums and the gitignored lowered tree.
Proposal
Have the pipeline record what it wrote, and have the gate audit its own list against that record.
gen-go and gen-lisp already funnel through helpers, so they can append their out path to an atom. generate.lg writes the collected list beside generated.provenance, which it already emits. check-generated regenerates before it compares, so the record is fresh by the time it reads it: the gate fails if any recorded path is missing from GENERATED-TRACKED.
No git, no filename heuristics, and it works under jj — the record comes from the pipeline rather than from the VCS.
A missing or empty record must be an error, not a pass. Otherwise the check degrades into exactly the silent under-coverage it exists to catch.
Residual gap: core_compiled.lgb still has to be named by hand, because lgbgen does not report its outputs. That shrinks a five-entry list in the Makefile to a one-entry declaration next to the lgbgen call, in the file that invokes it. Closing it fully means teaching lgbgen to report what it wrote, which is a separate change.
Happy to implement this once #634 lands, or to hear that the list is small enough that a comment is sufficient.
Alternatives considered
A Go test that parses generate.lg for output literals. No runtime changes, but it sees only the four declared paths and misses core_compiled.lgb — the one most likely to drift, since it is invisible at the call site.
Deriving GENERATED-TRACKED from the record via $(shell cat …). Removes the duplication, but on a fresh clone the record does not exist, the list comes back empty, and the gate passes vacuously. Worse than the problem.
Problem
#634 adds
GENERATED-TRACKEDto the Makefile: the committed generatedartifacts that
make check-generatedstashes, regenerates, and compares. The comment says "keep this list in step withscripts/generate.lg" and nothing checks that it is.If
generate.lggrows a sixth committed output and the Makefile list is not updated, the gate silently under-covers it. That is the failure #634 exists to fix, reintroduced one level up. Before #634 the gate compared onlycore_compiled.lgb, which is howzz_primitives_generated.gosat drifted from its generator without anything noticing.Where the outputs are declared
Four of the five outputs are already named at their call site:
Only
core_compiled.lgbis implicit, written insidelgbgen --target=bothalong withgenerated.sumsand the gitignored lowered tree.Proposal
Have the pipeline record what it wrote, and have the gate audit its own list against that record.
gen-goandgen-lispalready funnel through helpers, so they can append theiroutpath to an atom.generate.lgwrites the collected list besidegenerated.provenance, which it already emits.check-generatedregenerates before it compares, so the record is fresh by the time it reads it: the gate fails if any recorded path is missing fromGENERATED-TRACKED.No git, no filename heuristics, and it works under jj — the record comes from the pipeline rather than from the VCS.
A missing or empty record must be an error, not a pass. Otherwise the check degrades into exactly the silent under-coverage it exists to catch.
Residual gap:
core_compiled.lgbstill has to be named by hand, becauselgbgendoes not report its outputs. That shrinks a five-entry list in the Makefile to a one-entry declaration next to thelgbgencall, in the file that invokes it. Closing it fully means teachinglgbgento report what it wrote, which is a separate change.Happy to implement this once #634 lands, or to hear that the list is small enough that a comment is sufficient.
Alternatives considered
A Go test that parses
generate.lgfor output literals. No runtime changes, but it sees only the four declared paths and missescore_compiled.lgb— the one most likely to drift, since it is invisible at the call site.Deriving
GENERATED-TRACKEDfrom the record via$(shell cat …). Removes the duplication, but on a fresh clone the record does not exist, the list comes back empty, and the gate passes vacuously. Worse than the problem.