docs(bazel): propose consolidating onto a single Bazel module#445
docs(bazel): propose consolidating onto a single Bazel module#445balajinvda wants to merge 7 commits into
Conversation
The repository builds as 19 independent Bazel modules, one per service. That layout is inherited from the pre-monorepo history, when each service was its own repository, and it is the direct cause of several recurring failures rather than a style preference. Documents the evidence measured on the current tree: configuration copied 19 times and drifting, rule versions identical across every module so the isolation is unused, more than 20 unchosen Go dependency version conflicts so the isolation is actively harmful, and 18 registry fetches per full matrix to obtain 3 distinct base images. Proposes one module with services as packages, keeping release granularity per service, and deriving CI scheduling from the build graph instead of a hand-maintained subtree list. Includes phases, costs, the parallel-migration constraint on the cloud-tasks labels an external project builds against, and adjacent cleanups that share the same root cause. Explicit non-goal: splitting the Java tree into standalone modules. It is already in the target shape. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughExpands the proposal to consolidate first-party service Bazel modules into one root module, adds phased migration and CI controls, and introduces a tested inventory script for measuring Bazel, visibility, toolchain, and OCI configuration. ChangesBazel consolidation
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
🌿 Preview your docs: https://nvidia-preview-docs-bazel-consolidation-plan.docs.buildwithfern.com/nvcf |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/dev/bazel-consolidation.md`:
- Around line 132-135: Update the fenced code block containing the nvct_core
Bazel targets to specify an explicit language, using text or another appropriate
language identifier in the opening fence, while leaving the block contents
unchanged.
- Around line 76-89: The CI migration plan in the documentation incorrectly
describes scheduling as static and proposes replacing functionality already
present in the workflow. Update the rationale and the Phase 5 section to
acknowledge the existing changed-file labeling, bazel query rdeps logic, and
full-build fallback, and focus the remaining work on consolidating the
multi-module layout while preserving current CI behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 48412079-3085-42c8-8a47-236d9a5c6126
📒 Files selected for processing (1)
docs/dev/bazel-consolidation.md
|
Thanks -- this is a better plan than what I wrote. I verified every factual claim against main The correction that matteredYou are right that CI already combines changed-file mapping, The revision distinguishes two layers rather than simply retracting, because I think the distinction is load-bearing:
So consolidation does not add Accepted as written
I adopted your phase order over mine. Visibility policy and OCI equivalence gates before any service moves is right, and I had both as afterthoughts. One thing I did not change: the |
Corrects the plan on the points raised in review, and adds tools/ci/bazel-consolidation-inventory so the quoted measurements can be regenerated instead of trusted. The material correction is the CI section. The first draft claimed CI scheduling is a hand-maintained approximation of the dependency graph and proposed replacing it with bazel query rdeps. That was wrong: the workflow already maps changed files to labels, queries reverse dependencies, and falls back to a full build for changes it does not model. The revision distinguishes the two layers, notes that only job selection across the matrix is static, and says the existing hybrid must be extended during every phase rather than replaced at the end. Other corrections: - Refreshed inventory. All 19 service subtrees now pin a Bazel version, 15 on 8.6.0 and 4 on 9.1.1; the previous draft said four were missing. Added a measurement stamp, since an in-flight change invalidated the first draft within hours. - Scoped the proposal: one Bazel module does not mean one Go module, one Cargo workspace, or one lockfile per language. Component go.mod and Cargo workspaces stay; the target is one root MODULE.bazel.lock. - Added label rebasing and visibility as the primary migration risk, with counts: 156 root-relative __subpackages__ declarations, 639 public-visibility occurrences, and zero package_group definitions. - Dropped the claim that dependency conflicts mostly resolve by taking the newer version. Kubernetes families carry conflicting replace directives and toolchains span major versions. - Rust moves into the root module while retaining separate Cargo workspaces and crate hubs; merging them is a later, separately justified optimization. - NVCA gets its own phase (1261 vendored BUILD files with //vendor labels that do not survive a root move), with ESS and BYOO as further exceptions. - Added OCI and stamping equivalence gates before any service moves, and noted the nested-module guard needs an allowlist for the intentional helper and vendored modules. - Qualified the fetch and compile savings: one repository definition and one digest pin, not one fetch across isolated runners. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
|
Correction to my previous comment: the revision is PR now shows 2 files, +277: the revised |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tools/ci/bazel-consolidation-inventory`:
- Around line 16-71: The inventory tool lacks focused coverage for its parsing
and filtering behavior. Add fixture-based tests for the vendored-module
exclusion, trailing-comma oci.pull block parsing, and empty/no-match inputs,
covering the relevant commands and embedded Python logic in the inventory
entrypoint; alternatively document in the change why such tests are not
applicable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: e2f77516-6d74-4ca6-b4a1-0d82dc6ee7a3
📒 Files selected for processing (2)
docs/dev/bazel-consolidation.mdtools/ci/bazel-consolidation-inventory
Second review pass. Six findings, all confirmed against the tree before being acted on. The inventory tool had a real bug that made its output wrong rather than merely imprecise. It filtered vendored trees with a git ':(exclude)' pathspec combined with a wildcard positive pathspec, a combination git silently ignores. Every first-party count therefore included nvca's 1261 vendored BUILD files: the public-visibility count was 2721 instead of 639. A second defect used an unanchored '/rules/oci/' pattern that could not match the root-level copy, since that path has no leading slash. Both are now explicit anchored greps over git-tracked files, and both are covered by fixture tests that fail when either defect is reintroduced. The tool now also reads tracked files rather than the working tree, so its measurements correspond to the commit it stamps, warns when the tree is dirty, and computes every measurement into a variable before printing so a failed measurement aborts instead of yielding partial output with a success status. Go SDK provenance is now reported separately. The 1.23.0 pin the plan quoted comes only from a vendored module; first-party code spans 1.25.0 through 1.25.11. OCI pull reporting was scoped to nvcr.io and undercounted. There are 23 declarations across 8 distinct images and 7 digests, not 18 and 3. The one tag-only pull is now named in the output rather than asserted in prose. Doc corrections: - nvsnap is excluded by the non-goals but was counted in the 19 modules converging on the root. The end state is now stated as 18 publicly buildable modules plus nvsnap as an allowlisted exception, and Phase 1 and Phase 8 are scoped accordingly. - The claim that one module makes "which subtrees" a non-question was too broad. Consolidation retires the static module-root list, but affected targets still need routing to Docker-host, Java component, Cargo parity, BYOO generation, and release lanes. Root-scoped Java already routes this way on component_kind and ci_lane. - The phase invariant now requires every declared lane to pass, not only bazel build and test at the root. - Added per-component exit criteria, with root-local //src/... label resolution as the criterion that cannot be waived. - NVCA, ESS, and BYOO were named as special but never scheduled. They are now subphases 6a through 6c, each with an owner and the option to move to the exception allowlist rather than stay open. - 639 public-visibility declarations with zero package_group definitions means a very broad expressed API surface, not the absence of one. - Phase 7 now says to add and retain the Cargo parity lane. GitHub CI has no cargo test lane today. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
|
All six addressed in 4 is the one that mattered, and it was worse than reportedYou flagged the inventory tool as needing "a small correctness pass." It had a bug that made its output wrong, not imprecise. Vendor filtering used a git So every first-party count silently included nvca's 1261 vendored BUILD files. The public-visibility count was 2721, not 639. The exclusion works with a literal positive pathspec, which is why it looked fine in isolation. A second defect: Both are now explicit anchored greps over Also fixed as you described: tracked files rather than the working tree, a dirty-tree warning on the stamp line, and every measurement computed into a variable before printing so a failed measurement aborts instead of producing partial output with exit 0. Tests live at Two measurements changed as a result:
The rest
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/dev/bazel-consolidation.md`:
- Around line 159-161: Update the Go-label correctness criterion in the
consolidation document to apply only to in-scope, non-exception components,
while explicitly preserving the allowlisted vendored and nested-module
exceptions such as nvsnap and the NVCA vendored tree. Define the exit evidence
required for those exceptions instead of requiring them to resolve to root-local
//src/... labels.
In `@tools/scripts/test/test-bazel-consolidation-inventory`:
- Around line 40-45: Update make_tempdir and both command-substitution call
sites so the created temporary directory is recorded in TEMP_DIRS in the parent
shell, not a subshell. Preserve the existing EXIT-trap cleanup behavior and
ensure callers still receive the directory path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 7588276e-644c-489f-9e9a-972d744f21ba
📒 Files selected for processing (3)
docs/dev/bazel-consolidation.mdtools/ci/bazel-consolidation-inventorytools/scripts/test/test-bazel-consolidation-inventory
🚧 Files skipped from review as they are similar to previous changes (1)
- tools/ci/bazel-consolidation-inventory
… contract Third review pass. The inventory tool stamped HEAD while reading file contents from the working tree, so an uncommitted edit to a tracked file changed the measurements without changing the stamp. Verified: touching one tracked BUILD.bazel moved the public-visibility count from 639 to 640 with the stamp unchanged. The tool now refuses to run on a dirty tree and offers --allow-dirty, which stamps the output as a working-tree measurement instead of a commit. The fixture suite leaked two temporary directories per run. make_tempdir was called through command substitution, so it ran in a subshell and its append to TEMP_DIRS never reached the parent shell's cleanup trap. It now assigns to a variable. Verified zero leaked directories after the fix. Separately, the tool only scanned paths under src/, so it never read the root BUILD.bazel. That is where the repository's first package_group appears, which means the plan's headline "zero package_group definitions" evidence was measured somewhere it could not observe a change. Now repository-wide, which also moves the public-visibility count from 639 to 644. Both new behaviors have fixture coverage: a modified tracked file must be rejected, and --allow-dirty must both stamp differently and actually observe the uncommitted occurrence. Doc corrections: - BYOO already builds through a declared Bazel genrule. Phase 6c said the generator must become one. The real problem is that the action uses host Go with local and no-sandbox, so it is neither hermetic nor remotely cacheable. - Added an exception contract. Retaining a nested module now requires an owner, the retained CI entry point, the first-party dependency-source strategy, residual correctness risk, and a dated revisit trigger. An entry missing any of these is unfinished work, not an exception. - Reconciled the exception list with the summary: moving NVCA, ESS, or BYOO to the allowlist lowers the count of converging modules and keeps that component's lockfile and module-root CI lane, so the summary is updated when it happens. - Scoped the root-local-label criterion to migrated components, without waiving it for vendored first-party code. NVCA has 80 BUILD files referring to vendored copies of NVCF Go libraries, which is the false-green condition this proposal exists to remove. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
e8148d9 to
39aa7e5
Compare
|
All five blockers addressed in Tracking issues opened as requested: #448 (epic, carries the plan), #449 through #452 (phases 1 to 4), #453 through #455 (adjacent cleanup). All labeled 3 and 4 were both real, and 4 was mine to have caughtThe tempdir leak reproduces exactly as described: On the dirty-tree stamp, you are right that That fix exposed something worse that I should have found myself. The tool only scanned paths under New fixture coverage: a modified tracked file must be rejected, and 5, and the BYOO correctionYour BYOO correction is right and I verified it: On the exception contract, I adopted your five evidence fields as a named section, and reconciled it with the summary: moving a component to the allowlist lowers the count of converging modules and keeps that component's lockfile and module-root CI lane, so the summary is updated when it happens. The root-local-label criterion is now scoped to migrated components without being waived for vendored first-party code. I measured 80 NVCA BUILD files referring to vendored NVCF Go libraries rather than your 69, which is pattern-dependent, but the point stands unchanged: that is the false-green condition the proposal exists to remove, so a component can be excepted from moving but not from the correctness goal while claiming to be done. 1 and 2All four commits carry PR body rewritten against |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
docs/dev/bazel-consolidation.md (1)
159-175: 🎯 Functional Correctness | 🟠 MajorDo not make the root-label criterion impossible for exceptions.
This repeats the previous unresolved issue: the text scopes the criterion to migrated components, then says a component may remain unmigrated but cannot be excepted from the correctness goal. That makes retained modules such as
nvsnapunable to satisfy the definition of done. Qualify the criterion for in-scope, non-exception components and define exit evidence for exceptions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/dev/bazel-consolidation.md` around lines 159 - 175, Revise the root-local-label criterion and definition of done so it applies only to in-scope components that are required to migrate, explicitly excluding approved exceptions such as nvsnap. Add concrete exit evidence required for exceptions, such as documented approval, rationale, and tracking of remaining vendored references, while preserving the existing criteria for migrated components.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/dev/bazel-consolidation.md`:
- Around line 132-133: Update the prose sentence in the dependency-bump section
to hyphenate “repository-wide,” preserving the existing meaning and surrounding
wording.
- Around line 190-192: Reconcile the retained-module accounting throughout this
document: explicitly define whether the deliberate helper and vendored modules
join nvsnap as retained exceptions, then update every related summary count,
target end state, and migration criterion consistently across this section and
Phase 1.
---
Duplicate comments:
In `@docs/dev/bazel-consolidation.md`:
- Around line 159-175: Revise the root-local-label criterion and definition of
done so it applies only to in-scope components that are required to migrate,
explicitly excluding approved exceptions such as nvsnap. Add concrete exit
evidence required for exceptions, such as documented approval, rationale, and
tracking of remaining vendored references, while preserving the existing
criteria for migrated components.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: efb9ff90-662e-4ae9-a3df-ec714e660445
📒 Files selected for processing (3)
docs/dev/bazel-consolidation.mdtools/ci/bazel-consolidation-inventorytools/scripts/test/test-bazel-consolidation-inventory
🚧 Files skipped from review as they are similar to previous changes (2)
- tools/scripts/test/test-bazel-consolidation-inventory
- tools/ci/bazel-consolidation-inventory
…rrent evidence Fourth review pass. The three visibility measurements appended `|| true` to the whole pipeline, so a failure to read the files was converted into a silent zero. Confirmed by deleting a tracked BUILD.bazel: the tool reported 640 instead of failing, and exited 0. The first attempt at a fix was wrong and the negative control caught it. Relying on `set -e` to propagate a failed command substitution out of a shell function running as a pipeline stage does not work here; the tool still exited 0. It now checks the read status explicitly, and a single preflight verifies every tracked file the tool will read is present and readable. That covers every measurement rather than only the three that were reported. nvsnap was carried as a standing exception on the grounds that its base image is not publicly pullable. That rationale is stale. The workflow comment still says it, but the code disagrees: nvsnap pins public gcr.io/distroless/static, docker.io/library/ubuntu, and docker.io/library/alpine bases by digest, builds its images on @distroless_static, and its CONTRIBUTING documents a public-input source build. Private NGC is the publish destination, not the base. The plan no longer asserts the exception. All 19 first-party service modules are in scope, and Phase 1 decides nvsnap on current evidence rather than inheriting a comment. The retained-module accounting conflated three categories. The 22 tracked MODULE.bazel files are 19 first-party services, the root, one migration scaffolding module used by five nested modules and retired once they migrate, and one vendored third-party module that is a guard exclusion rather than an architectural decision. Only the first category can hold an exception. Also corrected: - ESS retains its Go workspace while the root Bazel graph ingests its modules. Collapsing it contradicted the scope boundary stated earlier in the document. - Remote caching does not reduce analysis-graph growth. Caching avoids re-executing actions; the analysis phase still processes whatever the invocation asks for, so target selection is the mitigation. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/dev/bazel-consolidation.md`:
- Around line 227-235: Update the Phase 1 inventory statement in the opening
paragraph to say “Three of the 22” instead of “Two of the 22,” matching the 19
service modules plus root, migration-scaffolding, and vendored modules described
immediately afterward.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 2131c465-c10d-474b-b392-b8c27bcf3149
📒 Files selected for processing (3)
docs/dev/bazel-consolidation.mdtools/ci/bazel-consolidation-inventorytools/scripts/test/test-bazel-consolidation-inventory
🚧 Files skipped from review as they are similar to previous changes (2)
- tools/ci/bazel-consolidation-inventory
- tools/scripts/test/test-bazel-consolidation-inventory
|
All three blocking findings and all four follow-ups addressed in 1, and a wrong first fixConfirmed by deleting a tracked My first fix was wrong, and the negative control is what caught it. I replaced the blanket The tool now checks the read status explicitly rather than depending on 2, which was the most useful findingYou are right and the evidence is unambiguous. The stale claim originates in a This is the second time in this review cycle that a number or claim I carried forward turned out to be inherited rather than verified, which is the argument for the inventory tool existing at all. 3Adopted. The 22 tracked modules are now presented as four categories with distinct end states: 19 first-party services that converge, the root, Follow-ups
|
…anisms Fifth review pass. Two more false-green paths, both reproduced by injecting the failure and both previously printing a complete 23-line report and exiting 0: - `git status` failing was indistinguishable from a clean tree, because its output was consumed inside a test rather than captured and checked. - `git ls-files` failing in the preflight was discarded by process substitution, leaving an empty file list that every count read as a plausible zero. Rather than patch each call site, the tracked-file list is now enumerated once into a temporary file with its status checked, and every helper reads from that. This removes the whole class: no helper re-invokes git inside a pipeline where a failure becomes an empty result. Test coverage was also incomplete. The missing-file case only exercised the preflight, never count_occurrences, which is where the original masking lived. A tracked symlink pointing at a directory passes the readability check and then fails on read, which reaches count_occurrences directly. Both injected git failures are covered too, asserting not only a non-zero exit but that no measurements are printed. Document corrections: - Migration completion and exception completion contradicted each other. There are now two explicit closure paths: a migrated component satisfies the root module criteria, a retained service exception satisfies the exception contract, falls outside the migrated count, and records residual correctness risk. - The nested-module guard needs three mechanisms rather than one allowlist: exact vendored-path exclusions, a migration ledger that must shrink monotonically, and permanent service exceptions. Requiring a permanent exception contract for every entry from Phase 2 was incompatible with incremental migration, because it cannot distinguish "not yet" from "never". - Added a source-of-truth prerequisite phase. A subtree that is still upstream-authoritative in imports.yaml can have a later import restore its nested module and old labels, silently undoing the migration. stargate is in that position today. - Only the root row on a pull request narrows through rdeps; every per-service row builds its whole workspace. Corrected, and noted as an argument for consolidation rather than against it. - The nvsnap statement is qualified to its current Bazel targets. The legacy Dockerfile path still defaults to a private base, which is the likely origin of the original claim. - Three of the 22 modules are not first-party services, not two. Also repository-wide, a language on the code fence, and Rust toolchain versions rather than major versions. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
|
All four blockers and all four small corrections addressed in 1, and why I stopped patching call sitesBoth reproduce exactly as you describe: injecting each failure gave a complete 23-line report and exit 0. I fixed them at the source rather than individually, because the pattern was going to keep recurring. Every helper was re-invoking You are also right that the missing-file test only exercised the preflight. To reach Verified after each fix: 2 and 3Both accepted, and 3 is a correction to my reasoning rather than my wording. I had collapsed "not yet migrated" and "never migrating" into one allowlist, which cannot express incremental migration: nothing would ever force the first category to resolve. The guard now has three mechanisms, with the migration ledger required to shrink monotonically so a phase that adds an entry or omits a target phase fails. For 2, the document now states two closure paths in a table. A retained exception is a legitimate outcome but not a quiet one: it lowers the migrated count, keeps a lockfile and module-root lane alive, and puts a stated correctness risk on the record. 4Good catch, and it is the kind of thing that would have silently undone the work. A subtree that stays upstream-authoritative can have a later import restore its nested module and old labels. Added as a prerequisite phase ahead of the Rust move, requiring either a native ownership cutover or upstream Bazel changes landed and synchronized. That renumbered the final phase, so remaining references now say "the final phase" rather than a number. Small correctionsAll four verified before applying. On the last two:
Also fixed: three of the 22 rather than two, repository-wide, a language on the code fence, and Rust toolchain versions. |
…sure models Sixth review pass. The tool could dirty the checkout it was about to inspect. mktemp honours TMPDIR, and the scratch file was created before the cleanliness check, so running with a TMPDIR inside the repository made a clean tree report as dirty and refuse to run. Reproduced with TMPDIR set to the repository root. The cleanliness check now runs first, and a fixture covers it: a clean tree with TMPDIR inside the repository must produce measurements, must not stamp itself as a working-tree measurement, and must leave no scratch file behind. Reverting the ordering fails that fixture. Two statements still contradicted the closure and guard models added last pass: - The exit criteria said a phase is not complete until every component it touched satisfies the migration criteria, which excluded the retained-exception path that the same document had just introduced. It now reads as the criteria for a migrated component, with phase closure requiring either those criteria or the exception contract. - Phase 1 still required an exception contract for every allowlist entry, which contradicts the three-mechanism guard and would make the guard unusable during the migration itself. Only permanent service exceptions carry a contract. Also corrected: - The exception contract applies to retained first-party service modules. The vendored module is a guard exclusion and carries no contract. - The private nvsnap default is in docker/agent/Dockerfile.app, not the criuv2 variant, which documents public inputs. I named the wrong file. - imports.yaml is not part of the public tree, so the source-of-truth prerequisite now refers to subtrees synchronized from an upstream repository. The stargate cutover requirement is unchanged. - Other CI rows build their full declared scope, which is a whole workspace only for nested modules; a root-scoped Java row builds its subtree of the root graph. - Rust toolchains span releases from 1.91.1 to 1.97.0, not major releases. - One cross-reference pointed below to a contract that is above it. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
|
All addressed in 1Reproduced with The check now runs first, and the fixture asserts three things rather than just an exit code: measurements are produced, the stamp does not claim a working-tree measurement, and no scratch file is left in the repository. Reverting the ordering fails it: Worth noting my own first attempt at verifying this was invalid. I tested with a freshly created 2Both contradictions were mine, introduced by the fixes from the previous pass rather than surviving from before, which is the more annoying kind. The exit criteria still said a phase is not complete until every component it touched satisfies the migration criteria, immediately after the same document introduced a second closure path. It now reads as the criteria for a migrated component, with phase closure requiring either those criteria or the exception contract. Phase 1 still demanded a contract for every allowlist entry, which contradicts the three-mechanism guard and would make the guard unusable during the migration. Only permanent service exceptions carry a contract. And the contract now applies to retained first-party service modules, since the vendored module is a guard exclusion with nothing to justify. Factual correctionsAll verified before applying.
|
TL;DR
Bazel arrived here service by service, so first-party code builds as 19 nested modules plus the root. That has a correctness cost: services consume in-repository libraries through published Go pseudoversions, so a library and its consumer can change together in one commit while Bazel still tests the consumer against the older published copy. Green build, broken code.
This adds the consolidation proposal and the tooling that keeps its numbers honest. Documentation and tooling only.
docs/dev/bazel-consolidation.md(proposal; mirrored in Consolidate first-party Bazel code onto a single root module #448)tools/ci/bazel-consolidation-inventory(regenerates every quoted measurement)tools/scripts/test/test-bazel-consolidation-inventory(fixture tests)Additional Details
See #448 for the full proposal, inventory, phases, and CI analysis.
The tool exists because prose counts go stale silently: the first draft was invalidated within hours by an unrelated change. The document carries a measurement stamp.
Merging this commits to the analysis, not to the migration.
For the Reviewer
Closest attention on
tools/ci/bazel-consolidation-inventory. Several defects were found by review; each now has a fixture test that fails when the defect is reintroduced::(exclude)pathspec combined with a wildcard positive pathspec is silently ignored, so vendored files leaked into every first-party count.rules/oci/copy.|| trueon whole pipelines turned an unreadable file into a silent zero, and uncheckedgitexit statuses did the same.The last one took two attempts: relying on
set -eto propagate out of a function running as a pipeline stage does not work here. It now checks status explicitly, with a preflight covering every measurement.For QA
Not applicable. No runtime or deployment behavior changes.
Issues
Relates to #448
Checklist