Skip to content

fix(deps): the monorepo pulled its own siblings from crates.io, and the gate that should have caught it could not fail - #2471

Merged
noahgift merged 1 commit into
mainfrom
integration/dedupe-batch
Aug 14, 2026
Merged

fix(deps): the monorepo pulled its own siblings from crates.io, and the gate that should have caught it could not fail#2471
noahgift merged 1 commit into
mainfrom
integration/dedupe-batch

Conversation

@noahgift

Copy link
Copy Markdown
Contributor

fix(deps): the monorepo pulled its own siblings from crates.io, and the gate that should have caught it could not fail

CLAUDE.md states the rule: the workspace is a self-contained DAG and every sibling
must be a path alias consumed as { workspace = true }, because "pulling a
crates.io copy reintroduces a duplicate crate + the published-crate dependency
cycle the consolidation removed".

36 declarations violated it. trueno — the SIMD/GPU foundation — resolved at
0.16, 0.16.5 AND the in-tree 0.63.0 simultaneously. jugar-probar spanned seven
declared versions. All now resolve to the in-tree path.

The gate that should have caught this exited 0 by construction

Makefile:485 was:

@cargo tree --duplicate | grep -v "^$$" || echo "✅ No duplicate dependencies"
@cargo audit || echo "⚠️  Security issues found"

|| reads GREP's status, not cargo's. Measured on the unfixed tree: 1,828 lines
of duplicates printed, exit code 0
. The second line swallows cargo audit
failures the same way. And nothing in .github/workflows/ or any tier target
invokes deps-validate at all, so even a working version was never run.

Third instance of this exact class here (#2336 qwen-story-daily, #2360 make
publish's POST-PUBLISH VERIFICATION). Both lines now redirect to a file and read
the real status; make deps-validate returns non-zero on the current tree, where
it returned 0 before.

The guard, and why it ships in the same commit

scripts/check_workspace_siblings_pathed.sh fails any manifest declaring a
workspace-local crate with a registry version =. It matches on BOTH [package] name and [lib] name, which is not optional here: package aprender-compute has
[lib] name = "trueno", so a checker comparing only package names is blind to the
single most important violation.

PASS: 100 manifest(s) scanned against 272 workspace-local crate name(s)
      (positive control flagged, so this absence is a measurement, not a blind spot)

self-test: 30 cases from a table file, plus 6 end-to-end tree probes.

Landing order was a real hazard. The guard is wired into guard-runner-labels,
which gate hard-requires with an explicit exit 1. Merged before the 36 manifest
fixes it would turn main RED and block every PR. Verified they pass together: with
both applied, the guard exits 0.

Numbers, and why the headline one understates it

cargo tree --workspace --duplicates: 57 -> 56 distinct duplicated names.

That is a poor measure of this change and should not be quoted as its value.
cargo tree --duplicates is structurally blind to the class being fixed: the
in-tree packages were RENAMED during consolidation (aprender-compute, aprender-serve),
so a registry trueno and a path aprender-compute are different names and no
collision exists for the duplicate detector to see. The verifier proved this —
cargo tree -p aprender-rag --features transcription lists crates.io
aprender v0.27.8 and trueno v0.17.5, a stale published copy of this monorepo,
while --duplicates on the same invocation reports nothing.

Cargo.lock is the honest measure: 1493 -> 1402 packages, 91 removed, 0 added.

Not in this commit

  • The third-party version unification (57 -> 41) conflicts with this change on
    eight manifests. Hand-merging two sets of manifest edits is how a silent defect
    ships, so it rebases and lands separately.
  • whisper-apr still transitively re-imports crates.io aprender 0.27.8,
    realizar 0.8.6, trueno 0.17.5 via apr-cli's whisper feature. Real, and
    invisible to --duplicates for the renaming reason above. Its own ticket.
  • crates/aprender-test/Cargo.toml:102 declares probar = { path = "crates/probar" }
    pointing at a directory that does not exist. That crate is workspace-EXCLUDED
    and unbuildable already (APR-MONO consolidation debt: 126 verified findings — a member that will not compile, 9 orphans, guards scanning the wrong directory #2470).

cargo check --workspace: clean, 0 errors.

Refs #2463, #2470

…he gate that should have caught it could not fail

CLAUDE.md states the rule: the workspace is a self-contained DAG and every sibling
must be a path alias consumed as `{ workspace = true }`, because "pulling a
crates.io copy reintroduces a duplicate crate + the published-crate dependency
cycle the consolidation removed".

36 declarations violated it. `trueno` — the SIMD/GPU foundation — resolved at
0.16, 0.16.5 AND the in-tree 0.63.0 simultaneously. `jugar-probar` spanned seven
declared versions. All now resolve to the in-tree path.

## The gate that should have caught this exited 0 by construction

`Makefile:485` was:

    @Cargo tree --duplicate | grep -v "^$$" || echo "✅ No duplicate dependencies"
    @Cargo audit || echo "⚠️  Security issues found"

`||` reads GREP's status, not cargo's. Measured on the unfixed tree: **1,828 lines
of duplicates printed, exit code 0**. The second line swallows `cargo audit`
failures the same way. And nothing in .github/workflows/ or any tier target
invokes `deps-validate` at all, so even a working version was never run.

Third instance of this exact class here (#2336 qwen-story-daily, #2360 make
publish's POST-PUBLISH VERIFICATION). Both lines now redirect to a file and read
the real status; `make deps-validate` returns non-zero on the current tree, where
it returned 0 before.

## The guard, and why it ships in the same commit

`scripts/check_workspace_siblings_pathed.sh` fails any manifest declaring a
workspace-local crate with a registry `version =`. It matches on BOTH `[package]
name` and `[lib] name`, which is not optional here: package `aprender-compute` has
`[lib] name = "trueno"`, so a checker comparing only package names is blind to the
single most important violation.

    PASS: 100 manifest(s) scanned against 272 workspace-local crate name(s)
          (positive control flagged, so this absence is a measurement, not a blind spot)

self-test: 30 cases from a table file, plus 6 end-to-end tree probes.

**Landing order was a real hazard.** The guard is wired into `guard-runner-labels`,
which `gate` hard-requires with an explicit `exit 1`. Merged before the 36 manifest
fixes it would turn main RED and block every PR. Verified they pass together: with
both applied, the guard exits 0.

## Numbers, and why the headline one understates it

`cargo tree --workspace --duplicates`: 57 -> 56 distinct duplicated names.

That is a poor measure of this change and should not be quoted as its value.
`cargo tree --duplicates` is **structurally blind** to the class being fixed: the
in-tree packages were RENAMED during consolidation (aprender-compute, aprender-serve),
so a registry `trueno` and a path `aprender-compute` are different names and no
collision exists for the duplicate detector to see. The verifier proved this —
`cargo tree -p aprender-rag --features transcription` lists crates.io
`aprender v0.27.8` and `trueno v0.17.5`, a stale published copy of this monorepo,
while `--duplicates` on the same invocation reports nothing.

Cargo.lock is the honest measure: 1493 -> 1402 packages, 91 removed, 0 added.

## Not in this commit

- The third-party version unification (57 -> 41) conflicts with this change on
  eight manifests. Hand-merging two sets of manifest edits is how a silent defect
  ships, so it rebases and lands separately.
- `whisper-apr` still transitively re-imports crates.io `aprender 0.27.8`,
  `realizar 0.8.6`, `trueno 0.17.5` via apr-cli's `whisper` feature. Real, and
  invisible to `--duplicates` for the renaming reason above. Its own ticket.
- `crates/aprender-test/Cargo.toml:102` declares `probar = { path = "crates/probar" }`
  pointing at a directory that does not exist. That crate is workspace-EXCLUDED
  and unbuildable already (#2470).

`cargo check --workspace`: clean, 0 errors.

Refs #2463, #2470
@noahgift
noahgift enabled auto-merge August 14, 2026 11:13
@noahgift
noahgift added this pull request to the merge queue Aug 14, 2026
Merged via the queue into main with commit c3825da Aug 14, 2026
12 checks passed
@noahgift
noahgift deleted the integration/dedupe-batch branch August 14, 2026 14:08
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