Skip to content

Crate fan-out five-whys: affected crates 49.6/85 per PR (READERS 50 + dev-edge cycle) #5842

Closed as not planned

Description

@noahgift

Crate fan-out five-whys (read-only; cargo metadata --no-deps --offline, no build)

Method: 85 packages, 257 workspace-internal edges (190 normal, 37 build, 30 dev). Transitive reverse-dependency closure per crate over all edge kinds (script: awk over cargo metadata edges; scratch /mnt/nvme-raid0/tmp/w5382-fan.awk).

Why 1 - affected crates 49.6/85 per PR. scripts/affected_set.sh unions (a) the reverse closure of the changed crate and (b) READERS, which is 50 crates added to every non-ALL set. Mean reverse closure alone is 20.2 crates (over 77 crates with edges); READERS is the larger term.
Why 2 - the closure is large because of a dev-dependency cycle. aprender-core, aprender-compute, aprender-serve and aprender-train each reach 44 crates, because of dev edges (aprender-compute -> aprender-core (dev), aprender-core -> aprender-train (dev), ...) which make one big strongly connected group. Ignoring dev edges the mean closure falls from 20.2 to 11.1.
Why 3 - READERS is large because any crate that can read another's files at run time (CARGO_MANIFEST_DIR parents, include_str of ../..) must be listed (#5802 guard).
Why 4 (hypothesis, not measured) - those readers read because tests scan the tree (e.g. aprender-core falsification scans every crate's src).
Why 5 (hypothesis, not measured) - tree-scanning tests are in the per-crate lib/test targets, not in a separate scan job keyed to the files they read.

Top 10 by transitive fan-in (crates affected when it changes, incl. dev edges)

closure direct crate
57 11 aprender-contracts-macros
55 20 aprender-contracts
53 27 aprender-build-sha
53 13 aprender-present-core
48 1 aprender-present-test-macros
47 2 aprender-present-test
46 2 aprender-rand
46 11 aprender-common
46 10 aprender-present-terminal
45 5 aprender-simulate
(aprender-quant, aprender-profile-core, apr-format, aprender-test-derive, aprender-sparse: 45. aprender-core/compute/serve/train: 44 each.)

Cut proposal, ranked by mean affected-crates saved per changed crate (single edge removed, recomputed)

saved edge kind move
4.52 aprender-test-lib -> aprender-compute normal make the compute use in test-lib a feature or split a compute-free test-lib-core
3.53 aprender-compute -> aprender-core dev move those dev tests to aprender-core or an integration crate
2.49 aprender-gpu -> aprender-test-lib dev gpu tests use test-lib-core
1.99 aprender-zram-core -> aprender-gpu normal feature-gate the gpu path
1.60 aprender-core -> aprender-train dev move the train-using tests to aprender-train
1.23 aprender-qa-runner -> aprender-test-lib normal use test-lib-core
1.19 aprender-simulate -> aprender-present-test dev move test helper
Edges are measured one at a time; savings are not additive (removing the first two cuts the cycle). Biggest single lever outside edges: shrink READERS (50) by moving tree-scanning tests to one scan job, which removes ~50 from every PR's set.
Caveat: affected set is a test-selection superset; cutting a dev edge changes what tests run for a change, so each cut needs the owning crate's tests moved, not deleted.

Activity

  1. modified the milestones: 0.73.0, 0.72.0 on Oct 21, 2026
  2. noahgift commented on Oct 22, 2026

    @noahgift
    MemberAuthor

    tracked in #3997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions