From f4cc91940150adee6ac14cd5f30da0fd92acb737 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Thu, 27 Aug 2026 03:15:07 +0800 Subject: [PATCH] docs(architecture): adjudicate the io-metrics leaf dependency on the s3-ops contract crate (#6683) --- ARCHITECTURE.md | 9 +++++++-- docs/architecture/crate-boundaries.md | 13 +++++++++++++ scripts/check_architecture_migration_rules.sh | 10 ++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ce6b1dad3..541e9d892 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -115,8 +115,13 @@ default build (lifecycle: 1. **Layers flow downward.** Server → Admin/App → Storage → ecstore → rio/io-core. No upward imports. -2. **Leaf crates have zero internal dependencies.** `config`, `credentials`, `crypto`, - `io-metrics`, and `madmin` should depend only on external crates. +2. **Leaf crates depend only on external crates, with one adjudicated exception.** + `config`, `credentials`, `crypto`, `io-metrics`, and `madmin` take no internal + dependency except `io-metrics → rustfs-s3-ops` (transitively `rustfs-s3-types`), + a pure contract crate with no I/O and no global state. Adjudicated in + rustfs/backlog#1834 and pinned by the leaf allowlist in + `scripts/check_architecture_migration_rules.sh`; any other internal dependency + fails the guard ([crate boundaries](docs/architecture/crate-boundaries.md)). - ✅ RESOLVED: the historical `utils → config` and `common → filemeta`/`madmin` edges were removed; do not reintroduce them (see Known Structural Issues). diff --git a/docs/architecture/crate-boundaries.md b/docs/architecture/crate-boundaries.md index accf68b4e..a8851caa2 100644 --- a/docs/architecture/crate-boundaries.md +++ b/docs/architecture/crate-boundaries.md @@ -35,6 +35,19 @@ wire types still live in `rustfs-filemeta`. This keeps the temporary dependency centralized until those wire contracts can move without introducing a `rustfs-replication` / `rustfs-storage-api` cycle. +Leaf crates carry exactly one adjudicated allowed edge: +`io-metrics -> rustfs-s3-ops` (transitively `rustfs-s3-types`). Both are pure +contract crates — types and enums only, no I/O, no global state, no non-contract +internal dependencies — so `io-metrics` reuses the `S3Operation` vocabulary +instead of copying it. The allowance covers that edge and nothing else: the +leaf-crate allowlist in `scripts/check_architecture_migration_rules.sh` fails any +other `rustfs-*` dependency in `config`, `credentials`, `crypto`, `io-metrics`, +or `madmin`. Adjudicated in +[`rustfs/backlog#1834`](https://github.com/rustfs/backlog/issues/1834); a further +exception must meet the same criterion — pure contract crate, no I/O, no globals, +no non-contract internal dependencies — and land its guard allowlist entry +alongside the dependency. + Dependency direction also applies to compile-time source reads: `include_str!`/`include!` of a `.rs` file must not resolve outside the including crate's own directory (`scripts/check_layer_dependencies.sh` diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index b7af64cf7..99c1d87e1 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -5454,9 +5454,11 @@ require_source_contains \ # --- Leaf crates must stay free of internal dependencies (backlog#1834) --- # ARCHITECTURE.md invariant 2 names config, credentials, crypto, io-metrics, # and madmin as leaf crates that depend only on external crates. Allowlist: -# io-metrics -> rustfs-s3-ops (contract crate; leaf-allowance adjudication is -# tracked as backlog#1834 PR2). Adding any other rustfs-* dependency to a leaf -# crate needs a maintainer decision, not a quiet Cargo.toml edit. +# io-metrics -> rustfs-s3-ops. That edge is DECIDED in backlog#1834: allowed as a +# pure-contract-crate exception (types/enums only, no I/O, no globals, no +# non-contract internal deps), narrowed to exactly this edge. Adding any other +# rustfs-* dependency to a leaf crate needs its own adjudication, not a quiet +# Cargo.toml edit. LEAF_CRATE_DEP_HITS_FILE="${TMP_DIR}/leaf_crate_dep_hits.txt" : >"$LEAF_CRATE_DEP_HITS_FILE" ( @@ -5478,7 +5480,7 @@ LEAF_CRATE_DEP_HITS_FILE="${TMP_DIR}/leaf_crate_dep_hits.txt" ) if [[ -s "$LEAF_CRATE_DEP_HITS_FILE" ]]; then - report_failure "leaf crates (config/credentials/crypto/io-metrics/madmin) must not depend on internal rustfs-* crates (allowlist: io-metrics -> rustfs-s3-ops, backlog#1834): $(paste -sd '; ' "$LEAF_CRATE_DEP_HITS_FILE")" + report_failure "leaf crates (config/credentials/crypto/io-metrics/madmin) must not depend on internal rustfs-* crates (sole adjudicated exception, decided in backlog#1834: io-metrics -> rustfs-s3-ops, a pure contract crate; any new edge needs its own adjudication): $(paste -sd '; ' "$LEAF_CRATE_DEP_HITS_FILE")" fi # --- ecstore module-level lint blankets (backlog#1823 step 9) ---