From 8392e29ba5923274b60f9d480ce23c8c11ca44a6 Mon Sep 17 00:00:00 2001 From: Mark Schaller Date: Sat, 26 Sep 2026 02:30:11 -0400 Subject: [PATCH 1/2] Require parity for the default bazel invocation bazel_args records the extra args aquery runs with to mirror the real build. Nothing said where settings the migration itself introduces should live, so parity could be established for a named --config that a plain `bazel build //...` never applies: the claim then holds for a command no user runs. Measured in any2bazel-lab: one pono migration put the reference's Release settings behind --config=release, recorded it in bazel_args, and converged. A plain `bazel build //...` produced an assertion-enabled binary that crashes on an input where the reference prints an error and exits. The four other runs on the same project put the settings in .bazelrc's build lines and were equivalent. Adds one bullet to the "invoke aquery the way the project is built" list: settings the migration adds go in `.bazelrc` build lines, and parity must hold for the project's documented build command, which is a plain `bazel build //...` unless the project documents flags; only those documented flags go in bazel_args. The bazel_args field description now says the same, and that the example config (a project config plus the top-level -fno-exceptions BoringSSL expects) is that kind of entry. In the lab's later pono and lensfun runs with this change, bazel_args was empty and the settings were in .bazelrc build lines. Lab-Proposal: P10 Co-Authored-By: Claude Opus 5.5 --- SKILL.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/SKILL.md b/SKILL.md index 6a1a30d..5fe4a77 100644 --- a/SKILL.md +++ b/SKILL.md @@ -127,12 +127,11 @@ whether its frontend reads it: ``` Fields: -- **`bazel_args`** — the extra **flags** aquery must run with to mirror the - real build (see [Extract the Bazel action graph](#extract-bazel-graph)), e.g. - `["--config=release"]` or `["-c", "opt"]`; never a command - (`["aquery", "mnemonic(...)", ...]` is wrong). Recorded so the comparison is - reproducible; `diff.py` refuses an entry that is neither a flag nor a flag's - value. +- **`bazel_args`** — the extra **flags** aquery must run with (see + [Extract the Bazel action graph](#extract-bazel-graph)): only what the + project's documented build passes, as in the example (BoringSSL expects + `-fno-exceptions` at top level). Never a command (`["aquery", ...]`): + `diff.py` refuses it. Recorded so the comparison is reproducible. - **`target_map`** — `reference_name → bazel_name` for intentionally renamed **executables**, or when two Bazel packages share the basename. The value is the label without `//`: `:name` at the root, `pkg:name` elsewhere (e.g. @@ -275,6 +274,10 @@ instead of being a warning nobody reads. > - Use the **same platform/options** as the reference build in > [Extract the reference model](#extract-reference-model), or the two sides > aren't comparable. +> - For settings **you** add to mirror the reference (e.g. Release's level), +> use `.bazelrc` `build` lines, not a named `--config`. Parity must hold for +> the project's documented build command: a plain `bazel build //...` unless +> the project documents flags, and only those go in `bazel_args`. > - **Always** call aquery with `--features=-compiler_param_file` and > `--features=-linker_param_file` to disable use of param files. Param files > are never generated during `aquery` calls, so when they're in use they'll From a0b6b207450d54d9d9e78fe70643abbd8f7ca1bd Mon Sep 17 00:00:00 2001 From: Mark Schaller Date: Sat, 26 Sep 2026 02:30:29 -0400 Subject: [PATCH 2/2] Pin the reference configuration and record its command Nothing in the procedure said which CMake configuration the reference should use, or that choosing one is a decision. An agent can turn options off before extracting the reference and then reach parity with that narrower build; both sides of the comparison move together, so no error count shows it. Measured in any2bazel-lab: a MySQL Server migration configured the reference with Router, NDB, the unit tests and the distribution's package compiler flags all turned off, recorded only in a comment in any2bazel.json. Against the project's default configuration the result showed 4,928 differences; against its own, 13. The reason given for the package flags was defensible; the problem was that the choice was silent. Agents redefined the reference with and without the skill, on small projects as well as large. "Extract the reference model" now says to configure with the project's documented default options, to surface any change as a scope decision, and to record the exact command in any2bazel.json as reference.configure_command (added to the example and the field list as record-only; config.load ignores it, like any unknown key) and never change it after the first diff. The optional test step reconfigures with tests on; that command is recorded separately, as reference.test_configure_command, so it does not count as changing the reference. In the lab's later runs with this change, every migrating agent recorded its configure command. Lab-Proposal: P13 Co-Authored-By: Claude Opus 5.5 --- SKILL.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SKILL.md b/SKILL.md index 5fe4a77..372974d 100644 --- a/SKILL.md +++ b/SKILL.md @@ -110,6 +110,7 @@ whether its frontend reads it: "dep_map": { "Catch2Main": "catch2_main" }, "exclude_targets": ["benchmark", "some_tool"], "include_tests": false, + "reference": { "configure_command": "cmake -S . -B build -G Ninja" }, "ignore": { "defines": ["BORINGSSL_DISPATCH_TEST"], "flags": ["-fvisibility=hidden"], @@ -145,6 +146,11 @@ Fields: third-party/vendored code Bazel pulls as an external module, or tooling out of scope. The **only** lever for `missing_tu`/`missing_target` on whole subtrees. Excluded targets still appear under `excluded.config_excluded`. +- **`reference.configure_command`** — the exact configure command the + reference model came from (see + [Extract the reference model](#extract-reference-model)); + `reference.test_configure_command` holds the test-inclusive one + ([Diff tests](#diff-tests)). Recorded for reviewers; not read by the diff. - **`include_tests`** (default `false`) — opt in to also diffing **test** targets. OFF by default because it requires BOTH models to be extracted with tests enabled and the **same** test scope (symmetric configure + aquery); @@ -242,6 +248,14 @@ python3 scripts/extract_.py <…> model..json Note the platform and options the reference build was configured with; the Bazel side must mirror them. +Configure the reference build with the project's **documented default** +options: turning anything off (a product, the tests, distribution flags) +changes what "migrated" means, so surface it when +[confirming scope](#confirm-scope). Record the exact command as +`any2bazel.json`'s `reference.configure_command` and never change it after the +first diff; the test-inclusive configure for [Diff tests](#diff-tests) is +recorded apart, as `test_configure_command`. + ### Create initial BUILD.bazel files Read `model..json`. For each production target emit a `cc_library` /