test: cross-library .cmi regression baselines (4 fixtures)#14584
Merged
Conversation
7e57b43 to
1b7d59d
Compare
1b7d59d to
3c4514f
Compare
There was a problem hiding this comment.
Pull request overview
Adds blackbox regression fixtures under per-module-lib-deps/ to pin today’s “wide .cmi glob” behavior for cross-library compilation dependencies in cases where ocamldep can’t see the full transitive .cmi chain (preprocess/action, ppx runtime deps, instrumentation backend, and -open flags). These baselines are intended to guard upcoming per-module dependency narrowing work (#14492).
Changes:
- Add a preprocess
(action ...)fixture ensuring a consumer build succeeds under--sandbox=copywhen only transitive.cmiloads make the leaf needed. - Add a ppx runtime-libraries fixture ensuring the consumer build succeeds under
--sandbox=copyeven when the runtime library is never named in consumer source. - Add an instrumentation-backend fixture that snapshots the current
.cmiglob present indune rulesJSON output.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-preprocess-barrier.t | New blackbox test for .cmi dep tracking across an action-preprocessed library under sandbox copy. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-pps-runtime-no-ocamldep-barrier.t/run.t | New blackbox test exercising ppx_runtime_libraries-induced compile-time .cmi needs under sandbox copy. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-instrumentation-barrier.t/run.t | New blackbox test pinning current instrumentation-disabled behavior and .cmi glob presence in dune rules output. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-instrumentation-barrier.t/ppx/hello.ml | Support library for the instrumentation backend fixture. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-instrumentation-barrier.t/ppx/hello_ppx.ml | Support ppx rewriter for the instrumentation backend fixture. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-instrumentation-barrier.t/ppx/dune-project | Defines the nested hello package for the instrumentation backend fixture. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-instrumentation-barrier.t/ppx/dune | Declares the instrumentation backend and its ppx/runtime library. |
| test/blackbox-tests/test-cases/per-module-lib-deps/cross-lib-open-flag-barrier.t | New blackbox test intended to cover -open-hidden transitive .cmi needs under sandbox copy. |
3c4514f to
3fb5e95
Compare
Collaborator
Author
|
@Alizter This is more code that I have factored out of the 9-layer PR 14492. |
3fb5e95 to
6b999b2
Compare
Four fixtures pinning the consumer-compile cmi-dep behaviour today, when the cctx-wide cmi glob over a dep lib's objdir covers the consumer's transitive `.cmi` needs regardless of whether `ocamldep` can see the chain syntactically. Each fixture hides the leaf's name from `ocamldep` through a different mechanism: - `cross-lib-preprocess-barrier.t` — `(preprocess (action ...))` - `cross-lib-pps-runtime-no-ocamldep-barrier.t` — `(preprocess (pps X))` + `ppx_runtime_libraries` - `cross-lib-instrumentation-barrier.t` — `(instrumentation (backend X))` - `cross-lib-open-flag-barrier.t` — `(flags (-open M))` Three of the four assert build success under `--sandbox=copy`. The instrumentation case additionally pins today's wide cmi glob over `middle`'s objdir in `dune rules` output. The forthcoming per-module narrowing work (#14492) will validate that each construct continues to work soundly under tighter per-module dep tracking, and will flip the instrumentation case's `jq` expected output from "glob present" to "glob absent". Signed-off-by: Robin Bate Boerop <me@robinbb.com>
6b999b2 to
7e326e9
Compare
Alizter
approved these changes
May 27, 2026
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
May 29, 2026
Closes a soundness gap in the per-module narrowing pipeline missed by the wrapped / ppx-runtime / virtual-impl recoveries: when a dependency library's effective flags inject [-open M], its source can reference [M]'s identifiers without naming [M], and ocamldep emits no token to drive the cross-library walker. Both the library stanza's own [(flags ...)] and any [(env ...)] stanza that contributes default flags to the dep lib's directory can inject [-open] entries. Reported by RyanJamesStewart on ocaml#14517 with this fixture: an unwrapped [middle] depending on unwrapped [prelude] with [(flags (:standard -open Prelude))], exposing [val pick : unit -> color] (where [color] resolves through the open to [Prelude.color]). The consumer pattern-matches the result against bare constructors. The compile genuinely needs [prelude.cmi] to resolve the constructors; the BFS over [ocamldep -modules] cannot reach [prelude] (no syntactic [Prelude] token on either side); the three existing recoveries do not catch it ([prelude] is not wrapped, not a ppx-runtime lib, not a virtual-impl). [Module_compilation.cross_lib_tight_set]: - Add [~mode] (the consumer's compile mode) so we can expand a dep lib's effective flags via [Ocaml_flags.get]. - Extend [read_entry_deps] to compute [read_lib_opens] for the visited lib and union the result into the BFS frontier. Localised in the BFS rather than the initial-frontier computation so the reachability rule reads as: a module is reachable iff the consumer references it, or some reached module's ocamldep names it, or some reached module's owning lib's effective flags open it. - [read_lib_opens] short-circuits to empty for non-local libs; their [src_dir] is not a build path, and env stanzas cannot inject flags into already-compiled artifacts. For local libs we evaluate [Ocaml_flags_db.ocaml_flags] which folds env-stanza flags under the library stanza's spec, so both injection paths are captured even when the library stanza is [:standard]. [Lib_info]: - Add [stanza_flags : Dune_lang.Ocaml_flags.Spec.t] field plus accessor. Local libs carry their stanza's [conf.buildable.flags]; external libs ([findlib], [dune_package]) carry [Spec.standard]. Regression tests on `main` that this patch makes pass under the per-module narrowing stack: - [cross-lib-open-flag-barrier.t] (added by ocaml#14584) pins the stanza-flag injection path. Fails on L4 and L5 head before this patch (Unbound constructor Green under [--sandbox=copy]); passes after. - [cross-lib-env-open-flag-barrier.t] (added by ocaml#14776) pins the env-stanza injection path: same shape, but [-open Prelude] is supplied by an [(env ...)] stanza while the library stanza uses [:standard]. Fails on the pre-ocaml#14517 [:standard]-short-circuit variant of this patch (same Unbound constructor error); passes after. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
Alizter
pushed a commit
that referenced
this pull request
May 30, 2026
Fifth fixture in the cross-lib `.cmi` regression baseline family (#14584): pins consumer-compile cmi-dep behaviour when `-open M` is injected by an `(env ...)` stanza rather than the intermediate library's own `(flags ...)` field. The intermediate's library stanza uses `:standard`. Asserts build success under `--sandbox=copy`. The forthcoming per-module narrowing work (#14492) will validate that this construct continues to work soundly under tighter per-module dep tracking. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
Alizter
added a commit
that referenced
this pull request
May 30, 2026
…14776) ## Summary Fifth fixture in the cross-lib `.cmi` regression baseline family started by #14584. Pins consumer-compile `.cmi` dep behaviour when `-open M` is injected by an `(env ...)` stanza rather than the intermediate library's own `(flags ...)` field. The intermediate's library stanza uses `:standard`. Asserts build success under `--sandbox=copy`. Pairs with the stanza-flag variant `cross-lib-open-flag-barrier.t` already on `main` from #14584, covering the second of the two `-open` injection paths. The forthcoming per-module narrowing work (#14492) will validate that this construct continues to work soundly under tighter per-module dep tracking.
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
Closes a soundness gap in the per-module narrowing pipeline missed by the wrapped / ppx-runtime / virtual-impl recoveries: when a dependency library's effective flags inject [-open M], its source can reference [M]'s identifiers without naming [M], and ocamldep emits no token to drive the cross-library walker. Both the library stanza's own [(flags ...)] and any [(env ...)] stanza that contributes default flags to the dep lib's directory can inject [-open] entries. Reported by RyanJamesStewart on #14517 with this fixture: an unwrapped [middle] depending on unwrapped [prelude] with [(flags (:standard -open Prelude))], exposing [val pick : unit -> color] (where [color] resolves through the open to [Prelude.color]). The consumer pattern-matches the result against bare constructors. The compile genuinely needs [prelude.cmi] to resolve the constructors; the BFS over [ocamldep -modules] cannot reach [prelude] (no syntactic [Prelude] token on either side); the three existing recoveries do not catch it ([prelude] is not wrapped, not a ppx-runtime lib, not a virtual-impl). [Module_compilation.cross_lib_tight_set]: - Add [~mode] (the consumer's compile mode) so we can expand a dep lib's effective flags via [Ocaml_flags.get]. - Extend [read_entry_deps] to compute [read_lib_opens] for the visited lib and union the result into the BFS frontier. Localised in the BFS rather than the initial-frontier computation so the reachability rule reads as: a module is reachable iff the consumer references it, or some reached module's ocamldep names it, or some reached module's owning lib's effective flags open it. - [read_lib_opens] short-circuits to empty for non-local libs; their [src_dir] is not a build path, and env stanzas cannot inject flags into already-compiled artifacts. For local libs we evaluate [Ocaml_flags_db.ocaml_flags] which folds env-stanza flags under the library stanza's spec, so both injection paths are captured even when the library stanza is [:standard]. [Lib_info]: - Add [stanza_flags : Dune_lang.Ocaml_flags.Spec.t] field plus accessor. Local libs carry their stanza's [conf.buildable.flags]; external libs ([findlib], [dune_package]) carry [Spec.standard]. Regression tests on `main` that this patch makes pass under the per-module narrowing stack: - [cross-lib-open-flag-barrier.t] (added by #14584) pins the stanza-flag injection path. Fails on L4 and L5 head before this patch (Unbound constructor Green under [--sandbox=copy]); passes after. - [cross-lib-env-open-flag-barrier.t] (added by #14776) pins the env-stanza injection path: same shape, but [-open Prelude] is supplied by an [(env ...)] stanza while the library stanza uses [:standard]. Fails on the pre-#14517 [:standard]-short-circuit variant of this patch (same Unbound constructor error); passes after. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
Closes a soundness gap in the per-module narrowing pipeline missed by the wrapped / ppx-runtime / virtual-impl recoveries: when a dependency library's effective flags inject [-open M], its source can reference [M]'s identifiers without naming [M], and ocamldep emits no token to drive the cross-library walker. Both the library stanza's own [(flags ...)] and any [(env ...)] stanza that contributes default flags to the dep lib's directory can inject [-open] entries. Reported by RyanJamesStewart on #14517 with this fixture: an unwrapped [middle] depending on unwrapped [prelude] with [(flags (:standard -open Prelude))], exposing [val pick : unit -> color] (where [color] resolves through the open to [Prelude.color]). The consumer pattern-matches the result against bare constructors. The compile genuinely needs [prelude.cmi] to resolve the constructors; the BFS over [ocamldep -modules] cannot reach [prelude] (no syntactic [Prelude] token on either side); the three existing recoveries do not catch it ([prelude] is not wrapped, not a ppx-runtime lib, not a virtual-impl). [Module_compilation.cross_lib_tight_set]: - Add [~mode] (the consumer's compile mode) so we can expand a dep lib's effective flags via [Ocaml_flags.get]. - Extend [read_entry_deps] to compute [read_lib_opens] for the visited lib and union the result into the BFS frontier. Localised in the BFS rather than the initial-frontier computation so the reachability rule reads as: a module is reachable iff the consumer references it, or some reached module's ocamldep names it, or some reached module's owning lib's effective flags open it. - [read_lib_opens] short-circuits to empty for non-local libs; their [src_dir] is not a build path, and env stanzas cannot inject flags into already-compiled artifacts. For local libs we evaluate [Ocaml_flags_db.ocaml_flags] which folds env-stanza flags under the library stanza's spec, so both injection paths are captured even when the library stanza is [:standard]. [Lib_info]: - Add [stanza_flags : Dune_lang.Ocaml_flags.Spec.t] field plus accessor. Local libs carry their stanza's [conf.buildable.flags]; external libs ([findlib], [dune_package]) carry [Spec.standard]. Regression tests on `main` that this patch makes pass under the per-module narrowing stack: - [cross-lib-open-flag-barrier.t] (added by #14584) pins the stanza-flag injection path. Fails on L4 and L5 head before this patch (Unbound constructor Green under [--sandbox=copy]); passes after. - [cross-lib-env-open-flag-barrier.t] (added by #14776) pins the env-stanza injection path: same shape, but [-open Prelude] is supplied by an [(env ...)] stanza while the library stanza uses [:standard]. Fails on the pre-#14517 [:standard]-short-circuit variant of this patch (same Unbound constructor error); passes after. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Jun 8, 2026
A fifth sibling to the cross-library `.cmi` regression baselines (ocaml#14584), covering `(flags (-open Prelude.Color))` where the intermediate library opens a *dotted* module path naming a submodule of a wrapped dependency, rather than a bare top-level module. As in `cross-lib-open-flag-barrier.t`, the intermediate's source never names `Prelude` (the open hides it) and the consumer never names it either, so `ocamldep` sees no syntactic chain to `prelude`. The fixture asserts build success under `--sandbox=copy`, pinning that the consumer's compile tracks `prelude`'s `.cmi`s. The forthcoming per-module narrowing work (ocaml#14492) must key its effective-`-open` detection on the head component of the path (`Prelude` from `Prelude.Color`), since only top-level module names map to libraries; without that, the dotted open would be dropped from the cross-library frontier and the sandboxed build would regress. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
A fifth sibling to the cross-library `.cmi` regression baselines (#14584), covering `(flags (-open Prelude.Color))` where the intermediate library opens a *dotted* module path naming a submodule of a wrapped dependency, rather than a bare top-level module. As in `cross-lib-open-flag-barrier.t`, the intermediate's source never names `Prelude` (the open hides it) and the consumer never names it either, so `ocamldep` sees no syntactic chain to `prelude`. The fixture asserts build success under `--sandbox=copy`, pinning that the consumer's compile tracks `prelude`'s `.cmi`s. The forthcoming per-module narrowing work (#14492) must key its effective-`-open` detection on the head component of the path (`Prelude` from `Prelude.Color`), since only top-level module names map to libraries; without that, the dotted open would be dropped from the cross-library frontier and the sandboxed build would regress. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
Closes a soundness gap in the per-module narrowing pipeline missed by the wrapped / ppx-runtime / virtual-impl recoveries: when a dependency library's effective flags inject [-open M], its source can reference [M]'s identifiers without naming [M], and ocamldep emits no token to drive the cross-library walker. Both the library stanza's own [(flags ...)] and any [(env ...)] stanza that contributes default flags to the dep lib's directory can inject [-open] entries. Reported by RyanJamesStewart on #14517 with this fixture: an unwrapped [middle] depending on unwrapped [prelude] with [(flags (:standard -open Prelude))], exposing [val pick : unit -> color] (where [color] resolves through the open to [Prelude.color]). The consumer pattern-matches the result against bare constructors. The compile genuinely needs [prelude.cmi] to resolve the constructors; the BFS over [ocamldep -modules] cannot reach [prelude] (no syntactic [Prelude] token on either side); the three existing recoveries do not catch it ([prelude] is not wrapped, not a ppx-runtime lib, not a virtual-impl). [Module_compilation.cross_lib_tight_set]: - Add [~mode] (the consumer's compile mode) so we can expand a dep lib's effective flags via [Ocaml_flags.get]. - Extend [read_entry_deps] to compute [read_lib_opens] for the visited lib and union the result into the BFS frontier. Localised in the BFS rather than the initial-frontier computation so the reachability rule reads as: a module is reachable iff the consumer references it, or some reached module's ocamldep names it, or some reached module's owning lib's effective flags open it. - [read_lib_opens] short-circuits to empty for non-local libs; their [src_dir] is not a build path, and env stanzas cannot inject flags into already-compiled artifacts. For local libs we evaluate [Ocaml_flags_db.ocaml_flags] which folds env-stanza flags under the library stanza's spec, so both injection paths are captured even when the library stanza is [:standard]. [Lib_info]: - Add [stanza_flags : Dune_lang.Ocaml_flags.Spec.t] field plus accessor. Local libs carry their stanza's [conf.buildable.flags]; external libs ([findlib], [dune_package]) carry [Spec.standard]. Regression tests on `main` that this patch makes pass under the per-module narrowing stack: - [cross-lib-open-flag-barrier.t] (added by #14584) pins the stanza-flag injection path. Fails on L4 and L5 head before this patch (Unbound constructor Green under [--sandbox=copy]); passes after. - [cross-lib-env-open-flag-barrier.t] (added by #14776) pins the env-stanza injection path: same shape, but [-open Prelude] is supplied by an [(env ...)] stanza while the library stanza uses [:standard]. Fails on the pre-#14517 [:standard]-short-circuit variant of this patch (same Unbound constructor error); passes after. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
to robinbb/dune
that referenced
this pull request
Jun 8, 2026
A sibling to the cross-library `.cmi` regression baselines (ocaml#14584), covering two chained opens `(flags (-open Prelude -open Color))` where the second argument resolves through the first: `Color` is the `Color` submodule of the wrapped dependency `prelude`, brought into scope by `-open Prelude`, not a top-level module. As in `cross-lib-open-flag-barrier.t`, the intermediate's source names neither `Prelude` nor `Color`, so `ocamldep` sees no syntactic chain to `prelude`. The fixture asserts build success under `--sandbox=copy`, pinning that the consumer's compile tracks `prelude`'s `.cmi`s. Per-module narrowing (ocaml#14492) must stay sound when an `-open` argument is not a compilation unit: here `-open Prelude` already reaches `prelude`, covering `Color`'s contents. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
A sibling to the cross-library `.cmi` regression baselines (#14584), covering two chained opens `(flags (-open Prelude -open Color))` where the second argument resolves through the first: `Color` is the `Color` submodule of the wrapped dependency `prelude`, brought into scope by `-open Prelude`, not a top-level module. As in `cross-lib-open-flag-barrier.t`, the intermediate's source names neither `Prelude` nor `Color`, so `ocamldep` sees no syntactic chain to `prelude`. The fixture asserts build success under `--sandbox=copy`, pinning that the consumer's compile tracks `prelude`'s `.cmi`s. Per-module narrowing (#14492) must stay sound when an `-open` argument is not a compilation unit: here `-open Prelude` already reaches `prelude`, covering `Color`'s contents. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 8, 2026
Closes a soundness gap in the per-module narrowing pipeline missed by the wrapped / ppx-runtime / virtual-impl recoveries: when a dependency library's effective flags inject [-open M], its source can reference [M]'s identifiers without naming [M], and ocamldep emits no token to drive the cross-library walker. Both the library stanza's own [(flags ...)] and any [(env ...)] stanza that contributes default flags to the dep lib's directory can inject [-open] entries. Reported by RyanJamesStewart on #14517 with this fixture: an unwrapped [middle] depending on unwrapped [prelude] with [(flags (:standard -open Prelude))], exposing [val pick : unit -> color] (where [color] resolves through the open to [Prelude.color]). The consumer pattern-matches the result against bare constructors. The compile genuinely needs [prelude.cmi] to resolve the constructors; the BFS over [ocamldep -modules] cannot reach [prelude] (no syntactic [Prelude] token on either side); the three existing recoveries do not catch it ([prelude] is not wrapped, not a ppx-runtime lib, not a virtual-impl). [Module_compilation.cross_lib_tight_set]: - Add [~mode] (the consumer's compile mode) so we can expand a dep lib's effective flags via [Ocaml_flags.get]. - Extend [read_entry_deps] to compute [read_lib_opens] for the visited lib and union the result into the BFS frontier. Localised in the BFS rather than the initial-frontier computation so the reachability rule reads as: a module is reachable iff the consumer references it, or some reached module's ocamldep names it, or some reached module's owning lib's effective flags open it. - [read_lib_opens] short-circuits to empty for non-local libs; their [src_dir] is not a build path, and env stanzas cannot inject flags into already-compiled artifacts. For local libs we evaluate [Ocaml_flags_db.ocaml_flags] which folds env-stanza flags under the library stanza's spec, so both injection paths are captured even when the library stanza is [:standard]. [Lib_info]: - Add [stanza_flags : Dune_lang.Ocaml_flags.Spec.t] field plus accessor. Local libs carry their stanza's [conf.buildable.flags]; external libs ([findlib], [dune_package]) carry [Spec.standard]. Regression tests on `main` that this patch makes pass under the per-module narrowing stack: - [cross-lib-open-flag-barrier.t] (added by #14584) pins the stanza-flag injection path. Fails on L4 and L5 head before this patch (Unbound constructor Green under [--sandbox=copy]); passes after. - [cross-lib-env-open-flag-barrier.t] (added by #14776) pins the env-stanza injection path: same shape, but [-open Prelude] is supplied by an [(env ...)] stanza while the library stanza uses [:standard]. Fails on the pre-#14517 [:standard]-short-circuit variant of this patch (same Unbound constructor error); passes after. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
robinbb
added a commit
that referenced
this pull request
Jun 9, 2026
## Summary A fifth sibling to the cross-library `.cmi` regression baselines from #14584, covering an intermediate library compiled with `(flags (-open Prelude.Color))` — a *dotted* module path naming a submodule of a wrapped dependency, rather than a bare top-level module. The fixture asserts build success under `--sandbox=copy`. It builds on `main` today (no per-module narrowing) and pins behaviour that the per-module narrowing work in #14492 must preserve: the effective-`-open` detection has to key on the head component of the path (`Prelude` from `Prelude.Color`), since only top-level module names map to libraries. Without that, the dotted open is dropped from the cross-library frontier and the sandboxed build regresses. Test-only; no changelog. --------- Signed-off-by: Robin Bate Boerop <me@robinbb.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four fixtures pinning the consumer-compile cmi-dep behaviour today, when the cctx-wide cmi glob over a dep lib's objdir covers the consumer's transitive
.cmineeds regardless of whetherocamldepcan see the chain syntactically. Each fixture hides the leaf's name fromocamldepthrough a different mechanism:cross-lib-preprocess-barrier.t—(preprocess (action ...))cross-lib-pps-runtime-no-ocamldep-barrier.t—(preprocess (pps X))+ppx_runtime_librariescross-lib-instrumentation-barrier.t—(instrumentation (backend X))cross-lib-open-flag-barrier.t—(flags (-open M))Three of the four assert build success under
--sandbox=copy. The instrumentation case additionally pins today's wide cmi glob overmiddle's objdir indune rulesoutput.The forthcoming per-module narrowing work (#14492) will validate that each construct continues to work soundly under tighter per-module dep tracking, and will flip the instrumentation case's
jqexpected output from "glob present" to "glob absent".