Skip to content

Commit 9ae8c05

Browse files
committed
fix(unify): enforce atomic workspace-member cohorts to prevent split
local/registry graphs (Tokio)
1 parent d91a776 commit 9ae8c05

File tree

14 files changed

+439
-85
lines changed

14 files changed

+439
-85
lines changed

.gitignore

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,4 @@ AGENTS.md
2121

2222
# Personal - Notes, Docs, Examples, Testing, etc.
2323
notes/
24-
**/demo.cast
2524
distribution/
26-
todo.md
27-
MERGE_CHECKLIST.md
28-
VALIDATION_REPORT.md
29-
examples/unify/unify-results.md
30-
dominance-plan.md
31-
upgrades.md
32-
tokio_lesson.md

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ cargo rail unify --explain # understand each decision
9696

9797
| Repository | Crates | Deps Unified | Undeclared Features | MSRV Computed |
9898
|---|---:|---:|---:|---|
99-
| [tokio-rs/tokio](https://github.com/loadingalias/cargo-rail-testing/tree/main/tokio) | 10 | 9 | 7 | 1.85.0 |
100-
| [helix-editor/helix](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix) | 14 | 15 | 19 | 1.87.0 |
101-
| [meilisearch/meilisearch](https://github.com/loadingalias/cargo-rail-testing/tree/main/meilisearch) | 23 | 54 | 215 | 1.88.0 |
102-
| [helixdb/helix-db](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix-db) | 6 | 18 | 17 | 1.88.0 |
99+
| [tokio-rs/tokio](https://github.com/loadingalias/cargo-rail-testing/tree/unify/tokio) | 10 | 9 | 7 | 1.85.0 |
100+
| [helix-editor/helix](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix) | 14 | 15 | 19 | 1.87.0 |
101+
| [meilisearch/meilisearch](https://github.com/loadingalias/cargo-rail-testing/tree/unify/meilisearch) | 23 | 54 | 215 | 1.88.0 |
102+
| [helixdb/helix-db](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix-db) | 6 | 18 | 17 | 1.88.0 |
103103
| **Aggregate** | **53** | **96** | **258** ||
104104

105105
Config files and validation artifacts: [Examples](examples/unify/) | [Validation Forks](https://github.com/loadingalias/cargo-rail-testing)
@@ -171,10 +171,10 @@ All core workflows (`plan`/`run`, `unify`) validated on production repos with fu
171171

172172
| Repository | Crates | Validation | Fork |
173173
|---|---:|---|---|
174-
| tokio-rs/tokio | 10 | Unify (9 deps, 7 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/main/tokio) |
175-
| helix-editor/helix | 14 | Unify (15 deps, 19 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix) |
176-
| meilisearch/meilisearch | 23 | Unify (54 deps, 215 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/main/meilisearch) |
177-
| helixdb/helix-db | 6 | Unify (18 deps, 17 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix-db) |
174+
| tokio-rs/tokio | 10 | Unify (9 deps, 7 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/unify/tokio) |
175+
| helix-editor/helix | 14 | Unify (15 deps, 19 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix) |
176+
| meilisearch/meilisearch | 23 | Unify (54 deps, 215 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/unify/meilisearch) |
177+
| helixdb/helix-db | 6 | Unify (18 deps, 17 features), Plan/run | [Fork](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix-db) |
178178

179179
**Validation forks**: [cargo-rail-testing](https://github.com/loadingalias/cargo-rail-testing) — full configs, integration guides, and reproducible artifacts.
180180

@@ -199,7 +199,7 @@ Each workflow includes working config files and reproducible command sequences:
199199

200200
| Workflow | Examples | Real-World Configs |
201201
|---|---|---|
202-
| Change detection | [examples/change_detection/](examples/change_detection/) | [tokio](https://github.com/loadingalias/cargo-rail-testing/blob/main/tokio/.config/rail.toml), [helix](https://github.com/loadingalias/cargo-rail-testing/blob/main/helix/.config/rail.toml), [meilisearch](https://github.com/loadingalias/cargo-rail-testing/blob/main/meilisearch/.config/rail.toml) |
202+
| Change detection | [examples/change_detection/](examples/change_detection/) | [tokio](https://github.com/loadingalias/cargo-rail-testing/blob/unify/tokio/.config/rail.toml), [helix](https://github.com/loadingalias/cargo-rail-testing/blob/unify/helix/.config/rail.toml), [meilisearch](https://github.com/loadingalias/cargo-rail-testing/blob/unify/meilisearch/.config/rail.toml) |
203203
| Unify | [examples/unify/](examples/unify/) | [Validation results](examples/unify/unify-results.md) |
204204
| Split/sync | [examples/split-sync/](examples/split-sync/) ||
205205
| Release | [examples/release/](examples/release/) ||

docs/config.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ major_version_conflict = "bump"
161161
|--------|------|---------|-------------|
162162
| `include_paths` | `bool` | `true` | Include path dependencies in unification. If `false`, path dependencies are excluded. |
163163
| `include_renamed` | `bool` | `false` | Include renamed dependencies (`package = "..."`). When enabled, features are aggregated across all variants using union. Opt-in due to complexity. |
164-
| `exclude` | `string[]` | `[]` | Dependencies to skip from unification (safety hatch). Useful for platform-specific or problematic dependencies. |
165-
| `include` | `string[]` | `[]` | Force-include specific dependencies in unification, even if they're single-use. |
164+
| `exclude` | `string[]` | `[]` | Dependencies to skip from unification (safety hatch). Useful for platform-specific or problematic dependencies. For workspace-member dependency cohorts, excluding one member excludes the full cohort atomically to prevent local-vs-registry splits. |
165+
| `include` | `string[]` | `[]` | Force-include specific dependencies in unification, even if they're single-use. Workspace-member cohorts are auto-included by cargo-rail to avoid threshold-based cohort splits. |
166166

167167
**Example:**
168168

@@ -174,6 +174,8 @@ exclude = ["openssl", "windows-sys"] # Platform-specific
174174
include = ["my-special-dep"] # Force include
175175
```
176176

177+
**Workspace-member cohort rule:** cargo-rail unifies connected workspace-member dependency sets atomically. A partial outcome (some members local, siblings from crates.io) is blocked automatically.
178+
177179
#### Transitive Pinning
178180

179181
Advanced feature for replacing workspace-hack crates. Only enable if you currently use `cargo-hakari`.

examples/README.md

Lines changed: 0 additions & 46 deletions
This file was deleted.

examples/unify/README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ Dependency unification validated on production Rust workspaces.
2020

2121
| Repository | Crates | Deps Unified | Undeclared Features | MSRV |
2222
|------------|-------:|-------------:|--------------------:|------|
23-
| [tokio](https://github.com/loadingalias/cargo-rail-testing/tree/main/tokio) | 10 | 9 | 7 | 1.85.0 |
24-
| [helix](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix) | 14 | 15 | 19 | 1.87.0 |
25-
| [meilisearch](https://github.com/loadingalias/cargo-rail-testing/tree/main/meilisearch) | 23 | 54 | 215 | 1.88.0 |
26-
| [helix-db](https://github.com/loadingalias/cargo-rail-testing/tree/main/helix-db) | 6 | 18 | 17 | 1.88.0 |
23+
| [tokio](https://github.com/loadingalias/cargo-rail-testing/tree/unify/tokio) | 10 | 9 | 7 | 1.85.0 |
24+
| [helix](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix) | 14 | 15 | 19 | 1.87.0 |
25+
| [meilisearch](https://github.com/loadingalias/cargo-rail-testing/tree/unify/meilisearch) | 23 | 54 | 215 | 1.88.0 |
26+
| [helix-db](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix-db) | 6 | 18 | 17 | 1.88.0 |
2727
| **Total** | **53** | **96** | **258** ||
2828

2929
**Full results:** [unify-results.md](unify-results.md)
@@ -71,6 +71,8 @@ pin_transitives = false # Enable for cargo-hakari replacement
7171
exclude = ["thiserror"] # Skip specific dependencies
7272
```
7373

74+
Workspace-member dependencies are unified as atomic cohorts. Excluding one member excludes its connected member cohort to prevent local-vs-registry split graphs.
75+
7476
## Trust Checklist
7577

7678
Before running `unify` (without `--check`):
@@ -90,7 +92,7 @@ Analyzing 50 dependencies...
9092
Computing MSRV from dependency graph...
9193
Detecting unused dependencies...
9294
Checking for undeclared feature dependencies...
93-
Generating fixes for 19 undeclared feature issues...
95+
Generating fixes for 5 undeclared feature issues...
9496
9597
=== Unification Plan ===
9698
@@ -100,10 +102,10 @@ Dependencies to unify: 9
100102
- tracing = "^0.1.44", features = [std] (used by 3 crates)
101103
...
102104
103-
Undeclared features to fix: 113 features across 10 crates
105+
Undeclared features to fix: 7 features across 5 crates
104106
Computed MSRV: 1.85.0 (from 132 deps with rust-version)
105107
106-
ready: 9 dependencies, 52 member edits
108+
ready: 9 dependencies, 44 member edits
107109
Changes detected. Run without --check to apply.
108110
```
109111

examples/unify/rail.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ exact_pin_handling = "warn"
1515
major_version_conflict = "warn" # warn = skip, bump = force highest
1616

1717
msrv = true
18-
msrv_source = "max" # deps | workspace | max
18+
msrv_source = "workspace" # deps | workspace | max
1919
enforce_msrv_inheritance = false # Ensure members inherit workspace rust-version
2020

2121
detect_unused = true
@@ -33,7 +33,7 @@ skip_undeclared_patterns = [
3333
"*_impl",
3434
]
3535

36-
exclude = []
37-
include = []
36+
exclude = [] # excluding one workspace member excludes its whole member cohort
37+
include = [] # workspace-member cohorts are auto-included
3838
max_backups = 3
39-
sort_dependencies = true # false to preserve existing order
39+
sort_dependencies = false # false to preserve existing order

examples/unify/unify-results.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Unify Validation
2+
3+
Validation Forks:
4+
- [tokio](https://github.com/loadingalias/tokio)
5+
- [helix](https://github.com/loadingalias/helix)
6+
- [meilisearch](https://github.com/loadingalias/meilisearch)
7+
- [helix-db](https://github.com/loadingalias/helix-db)
8+
9+
## Aggregate Results
10+
11+
| Metric | Count |
12+
|---|---:|
13+
| Total crates | 53 |
14+
| Dependencies unified | 96 |
15+
| Dead features pruned | 2 |
16+
| Unused deps detected | 0 |
17+
| Undeclared features fixed | 258 |
18+
19+
## Per-Repository Results
20+
21+
| Repository | Crates | Deps Unified | Dead Features | Undeclared Features | MSRV | Exclusions |
22+
|---|---:|---:|---:|---:|---|---|
23+
| [tokio](https://github.com/loadingalias/cargo-rail-testing/tree/unify/tokio) | 10 | 9 | 0 | 7 | 1.85.0 ||
24+
| [helix](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix) | 14 | 15 | 1 | 19 | 1.87.0 ||
25+
| [meilisearch](https://github.com/loadingalias/cargo-rail-testing/tree/unify/meilisearch) | 23 | 54 | 1 | 215 | 1.88.0 | `thiserror` |
26+
| [helix-db](https://github.com/loadingalias/cargo-rail-testing/tree/unify/helix-db) | 6 | 18 | 0 | 17 | 1.88.0 | `dirs` |
27+
28+
## Validation Status
29+
30+
All repositories pass `cargo check --workspace` and `cargo test --workspace` after unification.
31+
32+
## Exclusions Explained
33+
34+
| Repository | Excluded | Reason |
35+
|---|---|---|
36+
| meilisearch | `thiserror` | v1 → v2 breaks `{type}` syntax in error macros |
37+
| helix-db | `dirs` | Intentional multi-major-version in transitive deps |
38+
39+
## Dead Features Pruned
40+
41+
| Crate | Feature | Why Dead |
42+
|---|---|---|
43+
| helix-core | `integration` | Empty feature (no-op) |
44+
| meilisearch | `test-ollama` | Empty feature (no-op) |
45+
46+
Note: These can be skipped by using the `preserve_features` option in your `rail.toml` file.
47+
48+
## Configuration Used
49+
50+
Validation run used these settings:
51+
52+
```toml
53+
[unify]
54+
major_version_conflict = "warn" # Keep multi-major deps separate
55+
sort_dependencies = false # Preserve upstream ordering
56+
prune_dead_features = true # Remove empty no-op features
57+
fix_undeclared_features = true # Auto-fix borrowed features
58+
# Per-repo overrides:
59+
# - meilisearch: exclude = ["thiserror"]
60+
# - helix-db: exclude = ["dirs"]
61+
```
62+
63+
## Tools Replaced
64+
65+
`cargo rail unify` replaces:
66+
67+
| Tool | Purpose |
68+
|---|---|
69+
| cargo-hakari | Dependency unification + workspace-hack |
70+
| cargo-udeps | Unused dependency detection |
71+
| cargo-machete | Unused dependency detection |
72+
| cargo-shear | Unused dependency detection |
73+
| cargo-features-manager | Feature management |
74+
| cargo-msrv | MSRV computation |
75+
| cargo-sort | Sorting Cargo.toml manifests |
76+
77+
**Single command:** `cargo rail unify --check`
78+
79+
## Reproducing
80+
81+
```bash
82+
# Clone validation forks
83+
git clone https://github.com/loadingalias/tokio
84+
git clone https://github.com/loadingalias/helix
85+
git clone https://github.com/loadingalias/meilisearch
86+
git clone https://github.com/loadingalias/helix-db
87+
88+
cd tokio # or helix, meilisearch, helix-db
89+
90+
# Install cargo-rail
91+
cargo install cargo-rail
92+
93+
# Initialize cargo-rail
94+
cargo rail init
95+
96+
# Adjusted `rail.toml` to the workspace (generally)
97+
.config/rail.toml
98+
99+
# Preview changes
100+
cargo rail unify --check
101+
102+
# Apply changes
103+
cargo rail unify
104+
105+
# Verify
106+
cargo check --workspace
107+
cargo test --workspace
108+
```

0 commit comments

Comments
 (0)