Rewrite as a Rust, Apache-2.0 workspace
Supersedes the Go + embed-Mox design. The Go tree is removed; its
architecture doc is preserved at docs/archive/ARCHITECTURE-go-embed-mox.md
because its competitive analysis and data model still hold.
Five decisions recorded as ADRs:
0001 Rust, not Go — accepting ~5,500 lines of protocol code that Mox
would have given us free, to get the first permissively licensed
Rust mail server. Costs stated plainly.
0002 Apache-2.0, not MIT or AGPL — patent grant, trademark, CLA-free
contribution. Public on GitHub; Gitea stays as the private fallback.
0003 Stalwart's primitive crates (Apache-2.0/MIT) yes; its AGPL server
crates never. DANE and MTA-STS sit on the AGPL side of that line,
which is why we write our own.
0004 Milestones, reordered: embedded inbound is required at launch.
0005 Oracle Cloud blocks outbound :25, so direct-to-MX is impossible on
the launch host. Split delivery is mandatory, not an on-ramp.
Twelve crates in three tiers. Tier 1 (mail-dane, mail-mta-sts, mail-dsn)
is standalone and publishable — no `dane` or `mta-sts` crate exists on
crates.io at all today.
openmail-relay ships the provider table as data, with SES and Oracle from
the start. Oracle's and Resend's SPF includes are deliberately None: a
guessed include turns the DNS check green against a mechanism the provider
does not honour, and mail still fails SPF silently.
cargo check/test/clippy/fmt all green; unsafe_code is forbidden workspace
wide; cargo-deny enforces the licence policy in CI.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JkyvfNJGTshJNE9FtwPLk7
This commit is contained in:
co-authored by
Claude Opus 5
parent
428040d964
commit
36b15ddcaf
+78
@@ -0,0 +1,78 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = [
|
||||
# Tier 1 — standalone, publishable to crates.io. No openmail-* dependencies.
|
||||
"crates/mail-dane",
|
||||
"crates/mail-mta-sts",
|
||||
"crates/mail-dsn",
|
||||
# Tier 2 — OpenMail mail engine.
|
||||
"crates/openmail-guard",
|
||||
"crates/openmail-junk",
|
||||
"crates/openmail-smtpd",
|
||||
"crates/openmail-relay",
|
||||
# Tier 3 — the agent-native layer. The product.
|
||||
"crates/openmail-core",
|
||||
"crates/openmail-store",
|
||||
"crates/openmail-api",
|
||||
"crates/openmail-mcp",
|
||||
"crates/openmail",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.90"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/karti-ai/openmail"
|
||||
homepage = "https://openmail.karti.ai"
|
||||
authors = ["Karti Tripathi"]
|
||||
|
||||
[workspace.dependencies]
|
||||
# --- internal ---
|
||||
mail-dane = { version = "0.1.0", path = "crates/mail-dane" }
|
||||
mail-mta-sts = { version = "0.1.0", path = "crates/mail-mta-sts" }
|
||||
mail-dsn = { version = "0.1.0", path = "crates/mail-dsn" }
|
||||
openmail-guard = { version = "0.1.0", path = "crates/openmail-guard" }
|
||||
openmail-junk = { version = "0.1.0", path = "crates/openmail-junk" }
|
||||
openmail-smtpd = { version = "0.1.0", path = "crates/openmail-smtpd" }
|
||||
openmail-relay = { version = "0.1.0", path = "crates/openmail-relay" }
|
||||
openmail-core = { version = "0.1.0", path = "crates/openmail-core" }
|
||||
openmail-store = { version = "0.1.0", path = "crates/openmail-store" }
|
||||
openmail-api = { version = "0.1.0", path = "crates/openmail-api" }
|
||||
openmail-mcp = { version = "0.1.0", path = "crates/openmail-mcp" }
|
||||
|
||||
# --- third party (all Apache-2.0 or MIT; see NOTICE) ---
|
||||
mail-parser = { version = "0.11", features = ["full_encoding"] }
|
||||
mail-builder = "0.5"
|
||||
mail-auth = { version = "0.12", features = ["generate"] }
|
||||
smtp-proto = "0.2"
|
||||
hickory-resolver = { version = "0.26", features = ["dnssec-ring"] }
|
||||
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
axum = "0.8"
|
||||
tower-http = { version = "0.6", features = ["trace", "limit"] }
|
||||
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres", "uuid", "chrono", "json", "migrate"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
thiserror = "2"
|
||||
anyhow = "1"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
||||
uuid = { version = "1", features = ["v7", "serde"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
clap = { version = "4", features = ["derive", "env"] }
|
||||
rustls = "0.23"
|
||||
sha2 = "0.10"
|
||||
base64 = "0.22"
|
||||
|
||||
[workspace.lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
all = { level = "deny", priority = -1 }
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
codegen-units = 1
|
||||
strip = true
|
||||
Reference in New Issue
Block a user