Files
jcoffey-dev b2453d066b Merge upstream v0.16.24
Eight conflicted files resolved, plus the lock file and the schema:

- crates/services/src/task_manager/spam_classifier.rs: upstream's rules
  update now replaces existing rules, DNSBL servers, lookups and file
  extensions, keeping only whether each is on. Taken, with one difference:
  an object an admin edited is kept as it is. Every object an update writes
  is fingerprinted (content without `enable`, SHA-256, stored under
  SUBSPACE_INBUXA "Sf"), and only one that still matches is replaced.
  Scores are never replaced, as upstream has it. The AU-1.10 summary record
  now names what was added, replaced and kept, and the bundled rules are
  marked applied only when the update fully succeeded, so a failure runs
  again on the next start. The marker becomes "3.0.2+2", which runs the
  update once on upgrade to fingerprint every rule still as bundled.
- crates/common/src/network/autoconfig/autodiscover.rs: upstream's rewrite
  (implicit TLS first, labeled SSL), with the per-protocol switches (LP-7,
  LP-14a) passed in as a filter.
- crates/store/src/backend/mysql/{search,write}.rs: upstream's chunked
  deletes (no unbounded first DELETE, stop on a short chunk, halve the
  chunk on the new chunk-too-large errors) inside the fork's query timeout.
- crates/smtp/src/lib.rs: the fork's queue spawn kept. It already fixed the
  stall upstream fixes here (a node without outboundMta stops accepting
  mail at about 1024 queued messages), and follows role changes live.
- crates/jmap/src/registry/mapping/bootstrap.rs: the log path stays
  /var/log/inbuxa/; upstream's PowerDNS mapping taken.
- crates/main/Cargo.toml: the AGPL-only license kept, version 0.16.24.
- tests/src/jmap/principal/get.rs: the fork's capabilities kept.
- resources/schema/schema.json.gz: merged as JSON; upstream relabeled the
  vendor Sieve extensions "(Stalwart)", kept as "(vnd.inbuxa)".
- Cargo.lock: upstream's, with the fork's crates added by Cargo.

Also:

- tests/src/smtp/inbound/spam_rules_kept.rs: an edited rule survives an
  update, an unedited one is updated, rules from before fingerprints are
  handled, and the audit summary says so. Upstream's own spam_rules test
  passes unchanged.
- tests/src/smtp/reporting/reschedule.rs moves to port 19058; upstream's
  new spam_rules test took 19057.
- tools/fork/renames.py renames the "(Stalwart)" labels and the default
  log path, so neither conflicts again.
- tools/fork/notice-check.py compares against the newest snapshot in the
  checked-out history instead of the upstream branch head, so moving the
  branch no longer fails other open pull requests.
- tests/src/directory/issuer.rs (since v0.16.23) stays out, and is on the
  build check's known list: it tests issuer-based directory routing, which
  the fork doesn't have (DIR-2).
- Strip report: docs/fork/strip-reports/v0.16.24.{md,json}.
2026-09-28 06:30:20 -07:00

21 KiB

Strip report: upstream v0.16.24 (af37a2349817)

  • Enterprise-only files removed or emptied: 63
  • Enterprise-only snippets removed: 118 in 50 files
  • Cargo edits turning enterprise off: 25
  • Dangling module declarations removed: 5
  • Verification: 3 problems
  • Left for the rebuilt features to replace: 19 enterprise feature gates in 18 files; 0 is_enterprise_edition() checks in 0 files
  • Third-party code: 14 files, 0 not in THIRD-PARTY.md
  • Renamed identifiers: 62 in 18 files
  • Build check: 3 errors, 16 expected errors in 7 rebuilt-feature tests, 14 imports left unused
  • Upstream schema flags 9 objects and 30 fields as Enterprise

Removed files

  • crates/common/src/enterprise/alerts.rs
  • crates/common/src/enterprise/config.rs
  • crates/common/src/enterprise/license.rs
  • crates/common/src/enterprise/llm.rs
  • crates/common/src/enterprise/masked.rs
  • crates/common/src/enterprise/mod.rs
  • crates/common/src/telemetry/metrics/store.rs
  • crates/common/src/telemetry/metrics/test_data.rs
  • crates/common/src/telemetry/tracers/store.rs
  • crates/http/src/api/telemetry.rs
  • crates/jmap/src/registry/mapping/archived_item.rs
  • crates/jmap/src/registry/mapping/masked_email.rs
  • crates/jmap/src/registry/mapping/telemetry.rs
  • crates/scim-proto/src/attributes.rs
  • crates/scim-proto/src/etag.rs
  • crates/scim-proto/src/filter.rs
  • crates/scim-proto/src/json.rs
  • crates/scim-proto/src/lib.rs
  • crates/scim-proto/src/message/bulk.rs
  • crates/scim-proto/src/message/error.rs
  • crates/scim-proto/src/message/list.rs
  • crates/scim-proto/src/message/mod.rs
  • crates/scim-proto/src/message/patch.rs
  • crates/scim-proto/src/message/search.rs
  • crates/scim-proto/src/path.rs
  • crates/scim-proto/src/schema/group.rs
  • crates/scim-proto/src/schema/mod.rs
  • crates/scim-proto/src/schema/spc.rs
  • crates/scim-proto/src/schema/user.rs
  • crates/scim/src/auth.rs
  • crates/scim/src/bulk.rs
  • crates/scim/src/context.rs
  • crates/scim/src/discovery.rs
  • crates/scim/src/error.rs
  • crates/scim/src/groups/get.rs
  • crates/scim/src/groups/mod.rs
  • crates/scim/src/groups/patch.rs
  • crates/scim/src/groups/set.rs
  • crates/scim/src/lib.rs
  • crates/scim/src/query/cursor.rs
  • crates/scim/src/query/mod.rs
  • crates/scim/src/request.rs
  • crates/scim/src/users/get.rs
  • crates/scim/src/users/mod.rs
  • crates/scim/src/users/patch.rs
  • crates/scim/src/users/set.rs
  • crates/spam-filter/src/analysis/llm.rs
  • crates/store/src/backend/composite/mod.rs
  • crates/store/src/backend/composite/read_replica.rs
  • crates/store/src/backend/composite/sharded_blob.rs
  • crates/store/src/backend/composite/sharded_lookup.rs
  • crates/trc/src/serializers/binary.rs
  • tests/src/directory/oidc.rs
  • tests/src/scim/auth.rs
  • tests/src/scim/bulk.rs
  • tests/src/scim/discovery.rs
  • tests/src/scim/groups.rs
  • tests/src/scim/limits.rs
  • tests/src/scim/mod.rs
  • tests/src/scim/query.rs
  • tests/src/scim/users.rs
  • tests/src/system/archiving.rs
  • tests/src/system/tenant.rs

Removed snippets

  • crates/common/src/auth/authentication.rs: 3
  • crates/common/src/auth/mod.rs: 2
  • crates/common/src/auth/permissions.rs: 1
  • crates/common/src/cache/directory.rs: 6
  • crates/common/src/cache/invalidate.rs: 1
  • crates/common/src/cache/principals.rs: 2
  • crates/common/src/cache/reload.rs: 1
  • crates/common/src/config/mod.rs: 2
  • crates/common/src/config/telemetry.rs: 4
  • crates/common/src/lib.rs: 2
  • crates/common/src/manager/boot.rs: 1
  • crates/common/src/network/mta.rs: 1
  • crates/common/src/scripts/plugins/llm_prompt.rs: 1
  • crates/common/src/storage/quota.rs: 2
  • crates/common/src/telemetry/metrics/mod.rs: 1
  • crates/common/src/telemetry/metrics/prometheus.rs: 1
  • crates/common/src/telemetry/mod.rs: 1
  • crates/common/src/telemetry/tracers/mod.rs: 1
  • crates/http/src/api/mod.rs: 4
  • crates/http/src/auth/permissions.rs: 1
  • crates/http/src/request.rs: 4
  • crates/jmap/src/registry/get.rs: 1
  • crates/jmap/src/registry/mapping/mod.rs: 1
  • crates/jmap/src/registry/mapping/principal.rs: 3
  • crates/jmap/src/registry/mapping/queued_message.rs: 1
  • crates/jmap/src/registry/mapping/task.rs: 1
  • crates/jmap/src/registry/mod.rs: 1
  • crates/jmap/src/registry/query.rs: 1
  • crates/jmap/src/registry/set.rs: 2
  • crates/main/src/main.rs: 1
  • crates/services/src/task_manager/alarm.rs: 1
  • crates/services/src/task_manager/imip.rs: 1
  • crates/services/src/task_manager/index.rs: 2
  • crates/services/src/task_manager/maintenance.rs: 3
  • crates/services/src/task_manager/scheduler.rs: 8
  • crates/spam-filter/src/analysis/mod.rs: 1
  • crates/spam-filter/src/analysis/score.rs: 2
  • crates/store/src/backend/mod.rs: 1
  • crates/store/src/backend/mysql/main.rs: 1
  • crates/store/src/backend/postgres/main.rs: 1
  • crates/store/src/build/blob.rs: 2
  • crates/store/src/build/lookup.rs: 1
  • crates/store/src/build/memory.rs: 2
  • crates/store/src/dispatch/blob.rs: 6
  • crates/store/src/dispatch/lookup.rs: 10
  • crates/store/src/dispatch/mod.rs: 1
  • crates/store/src/dispatch/search.rs: 6
  • crates/store/src/dispatch/store.rs: 8
  • crates/store/src/lib.rs: 6
  • crates/trc/src/serializers/mod.rs: 1

Dangling module declarations removed

  • crates/common/src/telemetry/metrics/mod.rs:12: mod test_data (#[cfg(any(feature = "dev_mode", feature = "test_mode"))] / pub mod test_data;)
  • tests/src/directory/mod.rs:11: mod oidc (pub mod oidc;)
  • tests/src/lib.rs:27: mod scim (#[cfg(test)] / pub mod scim;)
  • tests/src/system/mod.rs:8: mod archiving (pub mod archiving;)
  • tests/src/system/mod.rs:19: mod tenant (pub mod tenant;)

Cargo edits

  • crates/main/Cargo.toml:50: default = ["rocks", "enterprise"] → default = ["rocks"]
  • tests/Cargo.toml:22: store = { path = "../crates/store", features = ["test_mode", "enterprise"] } → store = { path = "../crates/store", features = ["test_mode"] }
  • tests/Cargo.toml:24: directory = { path = "../crates/directory", features = ["test_mode", "enterprise"] } → directory = { path = "../crates/directory", features = ["test_mode"] }
  • tests/Cargo.toml:25: coordinator = { path = "../crates/coordinator", features = ["test_mode", "enterprise"] } → coordinator = { path = "../crates/coordinator", features = ["test_mode"] }
  • tests/Cargo.toml:26: jmap = { path = "../crates/jmap", features = ["test_mode", "enterprise"] } → jmap = { path = "../crates/jmap", features = ["test_mode"] }
  • tests/Cargo.toml:35: http = { path = "../crates/http", features = ["test_mode", "enterprise"] } → http = { path = "../crates/http", features = ["test_mode"] }
  • tests/Cargo.toml:37: scim = { path = "../crates/scim", features = ["test_mode", "enterprise"] } → scim = { path = "../crates/scim", features = ["test_mode"] }
  • tests/Cargo.toml:39: services = { path = "../crates/services", features = ["test_mode", "enterprise"] } → services = { path = "../crates/services", features = ["test_mode"] }
  • tests/Cargo.toml:41: smtp = { path = "../crates/smtp", features = ["test_mode", "enterprise"] } → smtp = { path = "../crates/smtp", features = ["test_mode"] }
  • tests/Cargo.toml:42: common = { path = "../crates/common", features = ["test_mode", "enterprise"] } → common = { path = "../crates/common", features = ["test_mode"] }
  • tests/Cargo.toml:44: email = { path = "../crates/email", features = ["test_mode", "enterprise"] } → email = { path = "../crates/email", features = ["test_mode"] }
  • tests/Cargo.toml:45: spam-filter = { path = "../crates/spam-filter", features = ["test_mode", "enterprise"] } → spam-filter = { path = "../crates/spam-filter", features = ["test_mode"] }
  • tests/Cargo.toml:46: trc = { path = "../crates/trc", features = ["enterprise"] } → trc = { path = "../crates/trc", features = [] }
  • tests/Cargo.toml:47: managesieve = { path = "../crates/managesieve", features = ["test_mode", "enterprise"] } → managesieve = { path = "../crates/managesieve", features = ["test_mode"] }
  • .github/workflows/ci.yml:341: cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" → cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
  • .github/workflows/ci.yml:379: # cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "foundationdb s3 redis nats enterprise" → # cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "foundationdb s3 redis nats"
  • .github/workflows/ci.yml:386: cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" → cargo build --release --target ${{matrix.target}} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
  • .github/workflows/ci.yml:442: cargo build --release -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" → cargo build --release -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
  • Dockerfile:22: RUN RUSTFLAGS="$(cat /flags.txt)" cargo chef cook --target "$(cat /target.txt)" --release --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" --recipe-path /recipe.json → RUN RUSTFLAGS="$(cat /flags.txt)" cargo chef cook --target "$(cat /target.txt)" --release --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" --recipe-path /recipe.json
  • Dockerfile:24: RUN RUSTFLAGS="$(cat /flags.txt)" cargo build --target "$(cat /target.txt)" --release -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" → RUN RUSTFLAGS="$(cat /flags.txt)" cargo build --target "$(cat /target.txt)" --release -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
  • Dockerfile.build:111: RUSTFLAGS="-L /usr/lib" cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats enterprise"; \ → RUSTFLAGS="-L /usr/lib" cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats"; \
  • Dockerfile.build:119: cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" → cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
  • Dockerfile.build:132: RUSTFLAGS="-L /usr/lib" cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats enterprise" && \ → RUSTFLAGS="-L /usr/lib" cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats" && \
  • Dockerfile.build:142: cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats enterprise" && \ → cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" && \
  • Dockerfile.fdb:56: RUN cargo build -p stalwart --no-default-features --features "foundationdb s3 redis azure nats enterprise" --release → RUN cargo build -p stalwart --no-default-features --features "foundationdb s3 redis azure nats" --release

Flagged Enterprise in upstream's schema

Objects: x:AiModel, x:Alert, x:ArchivedItem, x:MaskedEmail, x:MetricsStore, x:SpamLlm, x:Tenant, x:Trace, x:TracingStore

Fields: x:AcmeProvider.memberTenantId, x:ArfExternalReport.memberTenantId, x:Authentication.defaultTenantRoleIds, x:CalendarAlarm.template, x:CalendarScheduling.emailTemplate, x:CalendarScheduling.httpRsvpTemplate, x:DataRetention.archiveDeletedAccountsFor, x:DataRetention.archiveDeletedItemsFor, x:DataRetention.holdMetricsFor, x:DataRetention.holdTracesFor, x:DataRetention.metricsCollectionInterval, x:Dkim1Signature.memberTenantId, x:Dkim2Signature.memberTenantId, x:DmarcExternalReport.memberTenantId, x:Domain.allowScimProvisioning, x:Domain.directoryId, x:Domain.logo, x:Domain.memberTenantId, x:Email.maxMaskedAddresses, x:Enterprise.logoUrl, x:GroupAccount.externalId, x:LdapDirectory.memberTenantId, x:MySqlStore.readReplicas, x:OidcDirectory.memberTenantId, x:PostgreSqlStore.readReplicas, x:Search.indexTelemetry, x:Search.indexTracingFields, x:SqlDirectory.memberTenantId, x:TlsExternalReport.memberTenantId, x:UserAccount.externalId

Third-party code

Comments in the stripped tree that name another copyright holder, another license, or a source the code came from. Files marked new aren't in THIRD-PARTY.md yet.

Renamed identifiers

  • "URL to download spam filter rules from" → "URL to download spam filter rules from. Empty uses the rules bundled with the server.": resources/schema/schema.json.gz (1)
  • "spamFilterRulesUrl":"https://github.com/stalwartlabs/spam-filter/releases/latest/download/spam-filter-rules.json.gz", → : resources/schema/schema.json.gz (1)
  • "stalwart" → "inbuxa": resources/schema/schema.json.gz (15)
  • "stalwart".to_string() → "inbuxa".to_string(): crates/jmap/src/registry/mapping/bootstrap.rs (1), crates/registry/src/schema/structs_impl.rs (12)
  • STALWART_SPAM_ → INBUXA_SPAM_: crates/common/src/manager/mod.rs (2)
  • spam_filter_rules_url: Some("https://github.com/stalwartlabs/spam-filter/releases/latest/download/spam-filter-rules.json.gz".to_string()), → spam_filter_rules_url: None,: crates/registry/src/schema/structs_impl.rs (1)
  • stalwart-webui → inbuxa-webui: crates/common/src/manager/application.rs (3)
  • urn:stalwart: → urn:inbuxa:: crates/dav/src/common/lock.rs (1), crates/dav/src/common/uri.rs (5), tests/src/webdav/lock.rs (2)
  • urn:stalwart:jmap → urn:inbuxa:jmap:registry: crates/jmap-proto/src/request/capability.rs (3), tests/resources/scripts/stress_test_prepare.py (1), tests/src/jmap/principal/get.rs (2), tests/src/utils/jmap.rs (1)
  • vnd.stalwart → vnd.inbuxa: resources/schema/schema.json.gz (2)
  • vnd.stalwart. → vnd.inbuxa.: crates/registry/src/schema/enums_impl.rs (4), tests/resources/jmap/sieve/test_mailbox.sieve (1), tests/resources/smtp/sieve/awl.sieve (1), tests/resources/smtp/sieve/awl_include.sieve (1), tests/resources/smtp/sieve/stage_mail.sieve (1), tests/resources/smtp/sieve/stage_rcpt.sieve (1)

Build check

Errors mean shared code calls something the strip removed: usually a dual-licensed file that only serves an Enterprise feature. Drop or rework it in the merge into main, never on upstream.

  • error tests/src/directory/issuer.rs:8: unresolved import crate::directory::oidc
  • error tests/src/directory/issuer.rs:67: the size for values of type str cannot be known at compilation time
  • error tests/src/directory/issuer.rs:74: the size for values of type str cannot be known at compilation time
  • unused crates/common/src/cache/invalidate.rs:20: unused imports: registry::RegistryQuery and roaring::RoaringBitmap
  • unused crates/common/src/cache/principals.rs:31: unused import: MaskedEmail
  • unused crates/common/src/cache/principals.rs:41: unused import: now
  • unused crates/common/src/network/mta.rs:27: unused import: structs::MaskedEmail
  • unused crates/common/src/network/mta.rs:36: unused import: now
  • unused crates/common/src/network/mta.rs:39: unused import: types::id::Id
  • unused crates/common/src/scripts/plugins/llm_prompt.rs:7: unused import: compiler::Number
  • unused crates/common/src/scripts/plugins/llm_prompt.rs:8: unused import: std::time::Instant
  • unused crates/common/src/scripts/plugins/llm_prompt.rs:9: unused imports: AiEvent and SecurityEvent
  • unused crates/jmap/src/registry/mapping/principal.rs:24: unused imports: RegistryObjectCounter and RegistryQuery
  • unused crates/jmap/src/registry/mapping/queued_message.rs:25: unused import: ObjectType
  • unused crates/jmap/src/registry/mapping/queued_message.rs:43: unused import: RegistryQuery
  • unused crates/services/src/task_manager/index.rs:14: unused imports: ObjectType and Property
  • unused crates/services/src/task_manager/index.rs:32: unused import: blob_hash::BlobHash

Expected: upstream's tests of features the fork rebuilt on main (tools/fork/build-check-known.txt).

  • tests/src/directory/mod.rs:19: cannot find module or crate oidc in this scope
  • tests/src/smtp/inbound/antispam.rs:17: cannot find enterprise in common
  • tests/src/smtp/inbound/antispam.rs:49: unresolved import spam_filter::analysis::llm
  • tests/src/smtp/inbound/antispam.rs:661: no method named spam_filter_analyze_llm found for reference &common::Server in the current scope
  • tests/src/system/mod.rs:63: cannot find module or crate tenant in this scope
  • tests/src/system/mod.rs:70: cannot find module or crate archiving in this scope
  • tests/src/telemetry/alerts.rs:89: no method named process_alerts found for struct common::Server in the current scope
  • tests/src/telemetry/metrics.rs:8: unresolved import common::telemetry::metrics::store
  • tests/src/telemetry/metrics.rs:33: no method named insert_test_metrics found for struct common::Server in the current scope
  • tests/src/telemetry/metrics.rs:190: no method named purge_metrics found for reference &store::Store in the current scope
  • tests/src/telemetry/tracing.rs:8: unresolved import common::telemetry::tracers::store
  • tests/src/telemetry/tracing.rs:35: no method named purge_spans found for reference &store::Store in the current scope
  • tests/src/telemetry/tracing.rs:89: no method named purge_spans found for reference &store::Store in the current scope
  • tests/src/telemetry/tracing.rs:152: no method named purge_spans found for reference &store::Store in the current scope
  • tests/src/telemetry/webhooks.rs:11: unresolved import common::telemetry::tracers::store
  • tests/src/telemetry/webhooks.rs:123: no method named purge_spans found for reference &store::Store in the current scope

Problems

  • tests/src/directory/issuer.rs:8: does not compile: unresolved import crate::directory::oidc
  • tests/src/directory/issuer.rs:67: does not compile: the size for values of type str cannot be known at compilation time
  • tests/src/directory/issuer.rs:74: does not compile: the size for values of type str cannot be known at compilation time