Skip to content

Say what convergence does not cover: configure-time files and shared-library link lines - #41

Open
anakanemison wants to merge 3 commits into
mschaller/u05-report-levels-flags-definesfrom
mschaller/u06-say-what-convergence-covers
Open

anakanemison wants to merge 3 commits into
mschaller/u05-report-levels-flags-definesfrom
mschaller/u06-say-what-convergence-covers

Conversation

@anakanemison

Copy link
Copy Markdown

Part 6 of 23 of a stacked series (tracking issue: #35). Based on U05-report-levels-flags-defines, the previous part: review and merge that first.

Kind: report. Lab proposal: P1, P2, P8.

What the migration runs showed

A lensfun config.h differed from the reference in 3 of 7 converged migrations; a pono shared library converged but lacked MPFR and crashed at load. With the warning, agents byte-compared every listed file (later runs on lensfun, cmake and qgis).

The change (3 commits)

Warn in diff.json when configure-time generated files are not compared

A configure_file() output never reaches a command line, so a value that
differs only inside one (a config.h define, a version string) is invisible
to the diff. The skill said so in a note beside the CMake extraction
commands, but diff.json, the artifact people act on, said nothing, and
converged: true read as covering them.

Measured in any2bazel-lab: lensfun's generated config.h differed from the
reference in 3 of 7 migrations with the skill, each with a converged diff.
configured_files does populate (the lab saw it on another project); the
empty lists on lensfun, which spells the command CONFIGURE_FILE, come from
the uppercase bug fixed earlier in this series.

diff_models now appends one WARN discrepancy, kind
configured_files_not_compared, target "", when the CMake model
records configured files: cmake_only lists them, and the detail gives the
count and how many land on a compile include path. It never blocks
converged. One aggregated entry rather than one per file keeps a large
project's worklist readable (MySQL Server has about 200). All project-owned
configured files are listed, not only those flagged as compile inputs,
because that flag depends on the output sitting under a known include
directory and can miss a header reached another way. A new end-to-end test
covers the path from a trace through extract_cmake and the model to the
diff.

In the lab's later runs with this series, agents byte-compared the listed
files on lensfun, CMake and QGIS; the QGIS agent wrote eleven Bazel tests
that do it, and CMake's three configure headers that had differed from the
reference came out identical in all three CMake runs.

State the convergence boundary where convergence is defined

SKILL.md said that configure_file outputs are "recorded but not yet
diffed" only in a note beside the CMake extraction commands. The paragraph
that defines done ("Done when both stages converge") carried no such
caveat, so a reader who lands there reads converged: true as covering the
whole build.

Measured in any2bazel-lab: a lensfun migration converged with its generated
config.h differing from the reference (a GLIB_VERSION_MIN_REQUIRED value
that appears in no command line), and the same divergence recurred in later
runs, each alongside a converged diff.

Adds a short "what converged does not cover" list directly under the
definition of done, starting with generated file contents and the
instruction to byte-compare them. Later commits add the other boundaries
to the same list.

Say that shared-library link lines are not compared

SKILL.md described link consistency as covering "every name-aligned
executable/shared-lib". diff.py does not do that: shared libraries are in
the library TU union, only executables reach the link-flag comparison, and
the external-dependency check is a project-wide union, so a dependency one
.so is missing passes if any other target links it. A clean diff says
nothing about how a shared library links.

Measured in any2bazel-lab: a pono migration converged while libpono.so
lacked its MPFR link, and the Bazel-built binary crashed at load. The agent
found it only by running the binary.

Corrects the two places in SKILL.md and the four comments in
scripts/diff.py (the module docstring, LINK_FLAGS_DIFF, _diff_link_flags
and _diff_tests) that claimed shared-library link parity, and adds the
boundary to the "what converged does not cover" list with the remedy: run a
binary that loads each shared library. Comparing shared libraries' link
lines is a larger design change (they would need identity alignment like
executables) and is left to the maintainers.

No later run exercised this change on the project that motivated it. On
lensfun, an agent following it loaded the built shared library, found it
missing a GLib symbol, and fixed the link.

Testing

pytest tests/ at this commit: 180 passed (130 on main).

🤖 Generated with Claude Code

anakanemison and others added 3 commits October 18, 2026 14:18
A configure_file() output never reaches a command line, so a value that
differs only inside one (a config.h define, a version string) is invisible
to the diff. The skill said so in a note beside the CMake extraction
commands, but diff.json, the artifact people act on, said nothing, and
`converged: true` read as covering them.

Measured in any2bazel-lab: lensfun's generated config.h differed from the
reference in 3 of 7 migrations with the skill, each with a converged diff.
configured_files does populate (the lab saw it on another project); the
empty lists on lensfun, which spells the command CONFIGURE_FILE, come from
the uppercase bug fixed earlier in this series.

diff_models now appends one WARN discrepancy, kind
configured_files_not_compared, target "<configure>", when the CMake model
records configured files: cmake_only lists them, and the detail gives the
count and how many land on a compile include path. It never blocks
`converged`. One aggregated entry rather than one per file keeps a large
project's worklist readable (MySQL Server has about 200). All project-owned
configured files are listed, not only those flagged as compile inputs,
because that flag depends on the output sitting under a known include
directory and can miss a header reached another way. A new end-to-end test
covers the path from a trace through extract_cmake and the model to the
diff.

In the lab's later runs with this series, agents byte-compared the listed
files on lensfun, CMake and QGIS; the QGIS agent wrote eleven Bazel tests
that do it, and CMake's three configure headers that had differed from the
reference came out identical in all three CMake runs.

Lab-Proposal: P2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SKILL.md said that configure_file outputs are "recorded but not yet
diffed" only in a note beside the CMake extraction commands. The paragraph
that defines done ("Done when both stages converge") carried no such
caveat, so a reader who lands there reads converged: true as covering the
whole build.

Measured in any2bazel-lab: a lensfun migration converged with its generated
config.h differing from the reference (a GLIB_VERSION_MIN_REQUIRED value
that appears in no command line), and the same divergence recurred in later
runs, each alongside a converged diff.

Adds a short "what converged does not cover" list directly under the
definition of done, starting with generated file contents and the
instruction to byte-compare them. Later commits add the other boundaries
to the same list.

Lab-Proposal: P1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SKILL.md described link consistency as covering "every name-aligned
executable/shared-lib". diff.py does not do that: shared libraries are in
the library TU union, only executables reach the link-flag comparison, and
the external-dependency check is a project-wide union, so a dependency one
.so is missing passes if any other target links it. A clean diff says
nothing about how a shared library links.

Measured in any2bazel-lab: a pono migration converged while libpono.so
lacked its MPFR link, and the Bazel-built binary crashed at load. The agent
found it only by running the binary.

Corrects the two places in SKILL.md and the four comments in
scripts/diff.py (the module docstring, LINK_FLAGS_DIFF, _diff_link_flags
and _diff_tests) that claimed shared-library link parity, and adds the
boundary to the "what converged does not cover" list with the remedy: run a
binary that loads each shared library. Comparing shared libraries' link
lines is a larger design change (they would need identity alignment like
executables) and is left to the maintainers.

No later run exercised this change on the project that motivated it. On
lensfun, an agent following it loaded the built shared library, found it
missing a GLib symbol, and fixed the link.

Lab-Proposal: P8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant