Skip to content

ci: enforce workspace-level dependency declarations - #2514

Draft
yannham wants to merge 1 commit into
mainfrom
ci/workspace-deps-lint
Draft

ci: enforce workspace-level dependency declarations#2514
yannham wants to merge 1 commit into
mainfrom
ci/workspace-deps-lint

Conversation

@yannham

@yannham yannham commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds a CI check that enforces our dependency declaration policy:

  1. external dependencies of a workspace member are declared in the root [workspace.dependencies] and inherited with workspace = true;
  2. workspace entries are version-only — default-features = false and no features.

Exceptions are allowed per dependency, clippy-allow style: rule 1 needs a # allow(workspace-deps): <justification> comment above the dependency, rule 2 needs a comment above the workspace entry explaining why every member gets that feature.

The check is a small linter in the existing .github/actions CI workspace, run from a new job in lint.yml. It reports file and line, and annotates the PR diff. A handful of manifests are brought in line with the rules so the check passes.

Motivation

The workspace-dependency migration is essentially done, but nothing stops it from regressing: a new crate can quietly pin its own version, and a workspace entry can quietly turn a feature on for everyone. This makes the policy checkable instead of a review convention, while keeping room for justified exceptions.

No existing tool fits — cargo-autoinherit and friends only cover rule 1 and have no notion of documented exceptions, and clippy has no manifest lints.

Additional Notes

A few pre-existing cases genuinely cannot inherit yet (Windows crates pinned to older major versions); they are documented exceptions rather than migrations, which would need a Windows build to validate. Resolved feature sets are unchanged on both Linux and Windows targets.

How to test the change?

CI: the new "Workspace dependency declarations" job must pass.

Locally:

(cd .github/actions && cargo run -p workspace-deps-lint)

To see it fail, drop a dependency with its own version into any member manifest, or enable a feature on a workspace entry, and re-run.

The linter has unit tests for its own rules, run with (cd .github/actions && cargo test -p workspace-deps-lint) when editing it. Like the other crates under .github/actions, they are not wired into CI.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 5 issue(s) found, showing only errors (advisories, bans, sources)

📦 build_common - ✅ No issues

📦 datadog-sidecar - 2 error(s)

Show output
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:36:1
   │
36 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     ├── datadog-sidecar v0.0.1
     ├── (dev) libdd-ffe v2.0.0
     │   └── datadog-sidecar v0.0.1 (*)
     └── libdd-ipc v2.0.0
         └── datadog-sidecar v0.0.1 (*)

error[unsound]: Potential use-after-free due to lack of panic safety in `LruCache::pop()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:231:1
    │
231 │ lru 0.16.4 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0253
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0253
    ├ `LruCache::pop()` in `lru` was not panic-safe. If the `Drop` implementation of a stored key panics during `pop()`, `self.detach()` is never called, leaving dangling pointers in the internal doubly-linked list.
      
      A subsequent cache operation that triggers eviction can then dereference these dangling pointers:
      - The node is freed from the map, but remains linked in the LRU list due to the skipped `detach()` call
      - When a new insertion causes eviction, the LRU traversal encounters the dangling pointer
      - This results in a write to already-freed memory during the eviction process
      
      ## Impact
      
      - **CWE-416 (Use-After-Free):** memory corruption when subsequent cache operations access freed node pointers in the linked list
      - **CWE-415 (Double Free):** potential heap corruption when the same memory is freed multiple times
      
      Both types of undefined behavior can be invoked in safe Rust, but only if unwinding panics are enabled and `std::panic::catch_unwind` is used with key types that have potentially-panicking `Drop` implementations.
      
      ## Fix
      
      Fixed in `lru` 0.18.2 by detaching the node from the linked list before freeing it and dropping the key ([lru-rs#238](https://github.com/jeromefroe/lru-rs/pull/238)).
    ├ Announcement: https://github.com/jeromefroe/lru-rs/pull/238
    ├ Solution: Upgrade to >=0.18.2 (try `cargo update -p lru`)
    ├ lru v0.16.4
      └── libdd-ffe v2.0.0
          └── datadog-sidecar v0.0.1

advisories FAILED, bans ok, sources ok

📦 libdd-alloc - ✅ No issues

📦 libdd-common - 2 error(s)

Show output
error[vulnerability]: NSEC3 closest-encloser proof validation enters unbounded loop on cross-zone responses
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:66:1
   │
66 │ hickory-proto 0.25.2 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0118
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0118
   ├ The NSEC3 closest-encloser proof validation in `hickory-proto`'s
     `DnssecDnsHandle` walks from the QNAME up to the SOA owner name, building a
     list of candidate encloser names. The iterator used assumes the
     QNAME is a descendant of the SOA owner, terminating only when the current
     candidate equals the SOA name. When the SOA in a response's authority section
     is not an ancestor of the QNAME, the loop stalls at the DNS root and never
     terminates, repeatedly calling `Name::base_name()` and pushing newly allocated
     `Name` and hashed-name entries into the candidate `Vec`.
     
     The bug is reachable by any caller of `DnssecDnsHandle` — including the
     resolver, recursor, and client — when built with the `dnssec-ring` or
     `dnssec-aws-lc-rs` feature and configured to perform DNSSEC validation. It is
     triggered while validating a NoData or NXDomain response whose authority
     section contains an SOA record from a zone other than an ancestor of the
     QNAME, on a code path that requires NSEC3 closest-encloser proof. In practice
     this can be reached through an insecure CNAME chain that crosses zone
     boundaries into a DNSSEC-signed zone returning NoData, but the minimum
     condition is just a mismatched SOA owner on a response requiring NSEC3
     validation.
     
     A `debug_assert_ne!(name, Name::root())` guards the loop body, so debug builds
     abort with a panic on the first iteration past the root. Release builds
     compile the assertion out and run the loop unbounded, allocating until the
     process exhausts available memory (OOM). A reachable upstream attacker who
     can return such a response can therefore crash a debug-built validator or
     exhaust memory on a release-built one.
     
     The affected code was migrated from `hickory-proto` to `hickory-net` as part of
     the 0.26.0 release. The `hickory-proto` 0.26.x release no longer offers
     `DnssecDnsHandle` and so we recommend all affected users update to `hickory-net`
     0.26.1 when the implementation of that type is required.
   ├ Announcement: https://github.com/hickory-dns/hickory-dns/security/advisories/GHSA-3v94-mw7p-v465
   ├ Solution: No safe upgrade is available!
   ├ hickory-proto v0.25.2
     └── hickory-resolver v0.25.2
         └── reqwest v0.13.2
             └── libdd-common v6.0.0

error[vulnerability]: CPU exhaustion during message encoding due to O(n²) name compression
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:66:1
   │
66 │ hickory-proto 0.25.2 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0119
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0119
   ├ During message encoding, `hickory-proto`'s `BinEncoder` stores pointers to
     labels that are candidates for name compression in a `Vec<(usize, Vec<u8>)>`.
     The name compression logic then searches for matches with a linear scan.
     
     A malicious message with many records can both introduce many candidate labels,
     and invoke this linear scan many times. This can amplify CPU exhaustion in DoS
     attacks.
     
     This is similar to
     [CVE-2024-8508](https://www.nlnetlabs.nl/downloads/unbound/CVE-2024-8508.txt).
     
     We recommend all affected users update to `hickory-proto` 0.26.1 for the fix.
   ├ Announcement: https://github.com/hickory-dns/hickory-dns/security/advisories/GHSA-q2qq-hmj6-3wpp
   ├ Solution: Upgrade to >=0.26.1 (try `cargo update -p hickory-proto`)
   ├ hickory-proto v0.25.2
     └── hickory-resolver v0.25.2
         └── reqwest v0.13.2
             └── libdd-common v6.0.0

advisories FAILED, bans ok, sources ok

📦 libdd-crashtracker-ffi - ✅ No issues

📦 libdd-crashtracker - ✅ No issues

📦 libdd-ipc - 1 error(s)

Show output
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:24:1
   │
24 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     └── libdd-ipc v2.0.0

advisories FAILED, bans ok, sources ok

📦 spawn_worker - ✅ No issues

📦 symbolizer-ffi - ✅ No issues


Updated: 2026-09-11 15:39:28 UTC | Commit: ac1ea6c | dependency-check job results

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 6618 documentation warning(s) found

📦 build_common - 3 warning(s)

📦 datadog-sidecar - 2938 warning(s)

📦 libdd-alloc - 3 warning(s)

📦 libdd-common - 169 warning(s)

📦 libdd-crashtracker-ffi - 1284 warning(s)

📦 libdd-crashtracker - 1113 warning(s)

📦 libdd-ipc - 1029 warning(s)

📦 spawn_worker - 74 warning(s)

📦 symbolizer-ffi - 5 warning(s)


Updated: 2026-09-11 15:41:28 UTC | Commit: ac1ea6c | missing-docs job results

@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Sep 11, 2026

Copy link
Copy Markdown

Tests

All CI checks and tests passed.

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 77.78% (+0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: bc0189d | Docs | View more details | Give us feedback!

@dd-octo-sts

dd-octo-sts Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 96.01 MB 96.01 MB +0% (+176 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 9.02 MB 9.02 MB 0% (0 B) 👌
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 107.42 MB 107.42 MB -0% (-936 B) 👌
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.19 MB 12.19 MB -0% (-24 B) 👌
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 29.04 MB 29.04 MB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 96.08 KB 96.08 KB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 191.77 MB 191.77 MB 0% (0 B) 👌
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 818.18 MB 818.55 MB +.04% (+375.76 KB) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 9.69 MB 9.69 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 96.08 KB 96.08 KB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 27.51 MB 27.51 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 55.57 MB 55.57 MB -0% (-1.16 KB) 👌
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 25.41 MB 25.41 MB -0% (-1.00 KB) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 97.58 KB 97.58 KB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 197.08 MB 197.10 MB +0% (+16.00 KB) 👌
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 800.48 MB 799.25 MB --.15% (-1.22 MB) 💪
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 7.51 MB 7.51 MB +0% (+512 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 97.58 KB 97.58 KB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 29.63 MB 29.63 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 52.55 MB 52.55 MB -0% (-460 B) 👌
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 85.97 MB 85.96 MB -0% (-2.91 KB) 👌
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 10.03 MB 10.03 MB 0% (0 B) 👌
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 101.85 MB 101.85 MB +0% (+1.46 KB) 👌
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.25 MB 12.25 MB +0% (+8 B) 👌

@yannham
yannham force-pushed the ci/workspace-deps-lint branch from 72f03b6 to a7186ee Compare September 11, 2026 15:26
@pr-commenter

pr-commenter Bot commented Sep 11, 2026

Copy link
Copy Markdown

Benchmarks

Comparison

Benchmark execution time: 2026-09-11 16:10:07

Comparing candidate commit a7186ee in PR branch ci/workspace-deps-lint with baseline commit 3f833f8 in branch main.

📊 Benchmarking dashboard

Found 2 performance improvements and 12 performance regressions! Performance is the same for 162 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:vec_map/as_deduped_map/needs_dedup_1_in_2/8

  • 🟩 execution_time [-23.773ns; -23.300ns] or [-4.864%; -4.767%]

scenario:vec_map/as_deduped_map/needs_dedup_1_in_4/8

  • 🟩 execution_time [-18.194ns; -17.935ns] or [-4.409%; -4.346%]

scenario:vec_map/dedup/dup_1_in_10/128

  • 🟥 execution_time [+1.941µs; +1.977µs] or [+32.839%; +33.446%]

scenario:vec_map/dedup/dup_1_in_10/16

  • 🟥 execution_time [+220.194ns; +230.544ns] or [+27.857%; +29.166%]

scenario:vec_map/dedup/dup_1_in_10/64

  • 🟥 execution_time [+940.610ns; +964.690ns] or [+30.865%; +31.655%]

scenario:vec_map/dedup/dup_1_in_10/8

  • 🟥 execution_time [+114.521ns; +120.875ns] or [+28.463%; +30.042%]

scenario:vec_map/dedup/dup_1_in_2/128

  • 🟥 execution_time [+2.751µs; +2.799µs] or [+32.094%; +32.651%]

scenario:vec_map/dedup/dup_1_in_2/16

  • 🟥 execution_time [+313.904ns; +323.014ns] or [+28.337%; +29.159%]

scenario:vec_map/dedup/dup_1_in_2/64

  • 🟥 execution_time [+1.312µs; +1.341µs] or [+30.127%; +30.804%]

scenario:vec_map/dedup/dup_1_in_2/8

  • 🟥 execution_time [+155.341ns; +160.385ns] or [+27.382%; +28.271%]

scenario:vec_map/dedup/dup_1_in_4/128

  • 🟥 execution_time [+2.262µs; +2.305µs] or [+32.594%; +33.212%]

scenario:vec_map/dedup/dup_1_in_4/16

  • 🟥 execution_time [+263.462ns; +272.069ns] or [+29.759%; +30.731%]

scenario:vec_map/dedup/dup_1_in_4/64

  • 🟥 execution_time [+1.057µs; +1.082µs] or [+29.652%; +30.339%]

scenario:vec_map/dedup/dup_1_in_4/8

  • 🟥 execution_time [+125.711ns; +129.323ns] or [+27.250%; +28.033%]

Benchmark execution time: 2026-09-11 16:04:16

Comparing candidate commit a7186ee in PR branch ci/workspace-deps-lint with baseline commit 3f833f8 in branch main.

📊 Benchmarking dashboard

Found 2 performance improvements and 3 performance regressions! Performance is the same for 160 metrics, 11 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:alloc_free/system/4096

  • 🟩 execution_time [-9.722ns; -9.580ns] or [-10.468%; -10.315%]

scenario:no_profiler/short_circuit/4096

  • 🟥 execution_time [+7.542ns; +7.711ns] or [+7.779%; +7.952%]

scenario:profiler_attached/fast_path_system/4096

  • 🟥 execution_time [+10.500ns; +10.683ns] or [+11.010%; +11.201%]

scenario:profiler_attached/slow_path_system/4096

  • 🟩 execution_time [-9.856ns; -9.686ns] or [-6.296%; -6.187%]

scenario:trace_buffer/4_senders/no_delay

  • 🟥 execution_time [+148.165µs; +159.085µs] or [+4.120%; +4.423%]

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:datadog_sample_span/parent_not_sampled_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/parent_sampled_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+556.896%; -556.281%]

scenario:flagevaluation_evp/coalescer/typical/100flags_50users_10fields

  • unstable execution_time [-8.128µs; +15.343µs] or [-4.373%; +8.255%]

scenario:glob_matcher/ascii_case_insensitive_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:glob_matcher/ascii_exact_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.602%; -555.202%]

scenario:glob_matcher/ascii_exact_miss/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+553.860%; -554.853%]

scenario:glob_matcher/ascii_wildcard_backtrack_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.957%; -555.369%]

scenario:glob_matcher/ascii_wildcard_heavy_backtrack/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+518.761%; -538.716%]

scenario:glob_matcher/ascii_wildcard_question_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.968%; -555.374%]

scenario:glob_matcher/ascii_wildcard_star_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.967%; -555.373%]

scenario:glob_matcher/star_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.395%; -555.575%]

Candidate

Omitted due to size.

Baseline

Omitted due to size.

Add a `workspace-deps-lint` helper to the `.github/actions` CI workspace and
run it from a new "Workspace dependency declarations" job in `lint.yml`. It
enforces two rules:

1. every external dependency of a workspace member is declared in the root
   `[workspace.dependencies]` and inherited with `workspace = true`;
2. every `[workspace.dependencies]` entry is version-only, i.e.
   `default-features = false` and no `features`.

Exceptions are per dependency and justified in a comment, clippy-allow style:
rule 1 needs `# allow(workspace-deps): <justification>` directly above the
dependency, rule 2 needs at least one comment line above the workspace entry
explaining why every member gets that feature (which the existing `flate2`,
`httpmock`, `libc`, `criterion`, `serde_json` and `tempfile` notes already
provide). Path dependencies are crates of this repository and are exempt.

No off-the-shelf tool covers this: cargo-autoinherit, cargo-workspace-deps and
cargo-workspace-inheritance-check only handle rule 1 and have no notion of
documented exceptions, and clippy has no manifest lints. The linter parses
manifests with toml_edit spans so it can tie each finding to a line, and emits
GitHub error annotations on top of the human-readable report.

Also make the tree comply. `blazesym-c`, `cbindgen`, `kernel32-sys`, `winapi`,
`windows` and `windows-sys` move to the workspace level, and members inherit
them while spelling out the features they used to get from default features
(`windows`' `std`, `blazesym-c`'s `dwarf`). Four declarations that genuinely
cannot inherit yet are documented exceptions: `windows` 0.51 in
`datadog-sidecar` and `spawn_worker`, `windows-sys` 0.48 in `libdd-ipc` and the
legacy `winapi` 0.2 in `spawn_worker`. Resolved feature sets are unchanged for
both the linux and windows targets, except that `build_common` no longer pulls
clap in through cbindgen's default features.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yannham
yannham force-pushed the ci/workspace-deps-lint branch from a7186ee to bc0189d Compare September 11, 2026 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant