zoe/dockerfile-handle-build-error #8

Open
s1lv3r wants to merge 340 commits from zoe/dockerfile-handle-build-error into main

340 commits

Author SHA1 Message Date
3849702208
ci: Add test workflow that only runs manually and doesn't overwrite packages
All checks were successful
Auto Labeler / Apply labels based on changed files (pull_request_target) Successful in 5s
Checks / Changelog / Check changelog is added (pull_request_target) Successful in 7s
2026-07-10 18:51:07 +02:00
0eaefcf939
chore: Use CARGO_LOG=debug for cargo build 2026-07-10 17:17:58 +02:00
b1d26d6145
fix: Ensure docker builds stop on failed compilation 2026-07-10 16:56:24 +02:00
bed80964fd chore: Update changelog 2026-07-10 13:44:59 +00:00
bc7e3185ef chore(deps): Update to resolvematrix 1.1.0 2026-07-10 13:44:59 +00:00
7082914d7d chore: Update resolvematrix dependency rev hash 2026-07-10 13:44:59 +00:00
8fb14f666f chore: Add changelog 2026-07-10 13:44:59 +00:00
8b6a176901 fix: Use correct DNS caching for SNI to function properly
This removes the old (broken) DNS caching method for reqwest, and replaces
it with resolvematrix' `MatrixDnsResolver`, as it correctly implements
caching and overrides for correct SNI behavior.
2026-07-10 13:44:59 +00:00
2e1015846d
fix: Add missing whitespace between feature flags in nix build command 2026-07-09 22:16:28 -04:00
5d2e840859
feat: Enable direct_tls and more logging by default
Disables additional logging on maxperf builds
2026-07-09 22:44:26 +01:00
2fabf18451
style: Fix comment 2026-07-09 17:36:56 -04:00
63a26141f8
fix: Make depth cap a bit more thorough 2026-07-09 17:33:13 -04:00
cc1f667c2b
fix: Cap max_depth to 50 in hierarchy endpoint 2026-07-09 17:22:36 -04:00
89dcda4c3c
feat: Kill roomsynctoken_shortstatehash dead 2026-07-09 16:43:10 -04:00
62730e861a style: Use string literals instead of u8s 2026-07-09 19:40:11 +00:00
68d018bd37 style: Use string literals instead of u8s 2026-07-09 19:40:11 +00:00
959370169a chore: Rename changelog file 2026-07-09 19:40:11 +00:00
f71f6e922c feat: Allow configuring the desired client IP source 2026-07-09 19:40:11 +00:00
ce185aff13 docs: Update docs to match new resolver query command 2026-07-09 19:21:59 +00:00
ea06acd401
chore: Release 2026-07-09 20:19:11 +01:00
3ad229a2bc
ci: Remove Fedora packaging workflow
No longer needed because Terra now distributes both stable and nightly
releases for Fedora- & EL-family distributions.
2026-07-09 14:38:35 -04:00
f46e62e3bf chore: Update resolvematrix to 1.0.0 2026-07-09 18:22:25 +00:00
164ea9532f chore: Add changelog 2026-07-09 18:22:25 +00:00
edbaceafaa fix: Cargo clippy messages 2026-07-09 18:22:25 +00:00
0d5789f727 chore: Merge resolver service into client service 2026-07-09 18:22:25 +00:00
2a342bcbc9 fix: Move manual delegation warning 2026-07-09 18:20:37 +00:00
ad00562c66 docs: Fix nitpicks 2026-07-09 18:20:37 +00:00
3492045890 docs: Add a note about setting the client URL in the delegation docs 2026-07-09 18:20:37 +00:00
316482f077 fix: Fix dead links 2026-07-09 18:20:37 +00:00
acb046274b docs: Add guide on configuring OIDC 2026-07-09 18:20:37 +00:00
bdb29a7f51 docs: Rename "Advanced" section to "Guides" 2026-07-09 18:20:37 +00:00
7e6bb7822e fix: Make "remove device" link on device details page more obvious 2026-07-09 18:11:26 +00:00
5f9d609029 fix: Horizontally scroll overflowing pres 2026-07-09 18:11:26 +00:00
f866b94818 fix: Explicitly constrain avatar size 2026-07-09 18:11:26 +00:00
8714fa2ea7 fix: Minor CSS and layout tweaks 2026-07-09 18:11:26 +00:00
021dfc2424 fix: Fix error page on small screens 2026-07-09 18:11:26 +00:00
f9b532162f
fix: SEC20
Reviewed-By: Ginger <ginger@gingershaped.computer>
2026-07-09 17:58:59 +01:00
f5be5748f0 chore(deps): update rust-zerover-patch-updates 2026-07-09 16:39:49 +00:00
57cf8220a5 chore(deps): update node-patch-updates to v2.0.17 2026-07-09 16:38:54 +00:00
3d833eb010 chore(deps): update ruma digest to fca1dbc 2026-07-09 05:02:46 +00:00
71e5c3b49c chore(deps): update pre-commit hook crate-ci/typos to v1.48.0 2026-07-08 05:05:06 +00:00
4454e54092
fix: Fix dead link 2026-07-07 11:34:04 -04:00
f148975260
chore: News fragment 2026-07-07 11:33:47 -04:00
431ff348c3
docs: Update docs 2026-07-07 11:33:47 -04:00
ad4f7973cb
refactor: Remove list_local_users function 2026-07-07 11:33:47 -04:00
431fb7330e
refactor: Remove /_conduwuit/ routes 2026-07-07 11:33:47 -04:00
6619e6a20a
chore(deps): Update ruma digest to 89cce34
Co-Authored-By: Ginger <ginger@gingershaped.computer>
2026-07-07 11:25:13 -04:00
f205e2f890 docs: Fix errant link, add prek hook to require compilable docs 2026-07-07 14:57:11 +00:00
e9e0db8bab
fix: Stop advertising support for the stable MSC2666 endpoint 2026-07-07 14:29:14 +00:00
b7a3a2f567 chore(deps): update github-actions-digest 2026-07-07 05:01:59 +00:00
fbee5d1f7c chore: Add changelog for !1912 2026-07-06 16:08:14 +00:00
7e64bb2e13 docs(deploying): Update former Fedora deploy docs to generic RPM
Includes new OS support and external repos
2026-07-06 16:08:14 +00:00
992b7303fa
chore: Upgrade resolvematrix 2026-07-06 15:49:51 +01:00
fc5a6286fe
revert d7c32c78c7
revert chore(deps): update rust crate aws-lc-sys to 0.42.0
2026-07-06 13:16:46 +00:00
7aed7e87da chore(deps): update rust crate serde-saphyr to 0.0.29 2026-07-06 13:11:10 +00:00
d7c32c78c7 chore(deps): update rust crate aws-lc-sys to 0.42.0 2026-07-06 05:22:35 +00:00
2c9caee016 chore(deps): update ghcr.io/renovatebot/renovate docker tag to v43.252.1 2026-07-06 05:05:20 +00:00
6f76b0a593
fix: Don't bail out when changing profile data if membership cache is wrong 2026-07-05 10:51:36 -04:00
b1bbf0f465 fix: Pin aws-lc-rs and aws-lc-sys to older version
works around build issue:
https://github.com/aws/aws-lc-rs/issues/1168
2026-07-04 20:53:12 -07:00
3467dffd94 fix: Adjust sync watcher logic to be more explicit 2026-07-05 00:42:44 +00:00
3adeee04d7
chore: Fix all the bugs 2026-07-04 22:51:10 +01:00
632d90921b
fix: Fix circular service dependency 2026-07-04 17:04:01 -04:00
6aab456466 fix: appservice masquerading requirement check 2026-07-04 18:21:51 +00:00
7fac885a98
Merge branch 'main' into rewrite-resolver 2026-07-04 19:55:28 +02:00
d2b795d8cf
refactor: Logic cleanup 2026-07-04 13:15:54 -04:00
e0a754483a
fix: Give invitees creator status when creating a trusted private v12 room 2026-07-04 13:06:49 -04:00
b61f0af98a chore(deps): update rust crate bytesize to v2.4.2 2026-07-04 15:19:04 +00:00
649f16aa14 chore(deps): update node-patch-updates to v2.0.16 2026-07-04 15:18:58 +00:00
54b63327d5 chore(deps): update rust crate arrayvec to v0.7.8 2026-07-04 15:18:44 +00:00
58507aa99b
chore: Fix dependencies, prek errors 2026-07-03 10:59:14 +02:00
e58ad49d11
fix: Remove unused code, use builder when not using cache 2026-07-03 10:59:13 +02:00
44087d8c09
chore: Fix more merge issues and removed methods 2026-07-03 10:59:13 +02:00
fb74da21d9
style: Cargo fmt 2026-07-03 10:59:13 +02:00
76aa54770d
chore: Fix somehow broken cargo.toml 2026-07-03 10:59:13 +02:00
f6d43a9cf3
chore: Update news fragment 2026-07-03 10:59:12 +02:00
eb078ee6dd
chore: Pass http client into resolver 2026-07-03 10:59:12 +02:00
d8eb01bf74
fix: Apply prek fixes 2026-07-03 10:59:12 +02:00
5b5ba53980
fix: Fix merge problems, update to resolvematrix 0.1.0 2026-07-03 10:59:12 +02:00
0a12d40625
chore: clippy
diff --git c/src/admin/query/resolver.rs i/src/admin/query/resolver.rs
index add4c70de..37d6797ff 100644
--- c/src/admin/query/resolver.rs
+++ i/src/admin/query/resolver.rs
@@ -96,7 +96,10 @@ async fn flush_cache(&self, name: Option<OwnedServerName>, all: bool) -> Result
 		    self.services.resolver.dns.cache.clear().await;
 		    writeln!(self, "Resolver caches cleared!").await
 	    } else if let Some(name) = name {
-		    self.services.resolver.resolver.remove_cache_entry(&name.as_str());
+		    self.services
+                .resolver
+                .resolver
+                .remove_cache_entry(name.as_str());
 			self.services.resolver.dns.cache.del_destination(&name);
 			self.services.resolver.dns.cache.del_override(&name);
 			self.write_str(&format!("Cleared {name} from resolver caches!"))
2026-07-03 10:59:12 +02:00
3d521c8898
feat: Add cache clearing
diff --git c/Cargo.lock i/Cargo.lock
index 4a8b1e273..239932c62 100644
--- c/Cargo.lock
+++ i/Cargo.lock
@@ -4601,9 +4601,9 @@ checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"

 [[package]]
 name = "resolvematrix"
-version = "0.0.3"
+version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52dfcc6f56a81348db1fc6591356cfea9dc840408c75553b2fe225f86de43274"
+checksum = "ea2b9bc3cb1220455bf50519f315c27257859059cb1b0f1643758afd03cbef8a"
 dependencies = [
  "hickory-resolver",
  "reqwest 0.13.2",
diff --git c/Cargo.toml i/Cargo.toml
index f89a5e010..d6260177a 100644
--- c/Cargo.toml
+++ i/Cargo.toml
@@ -45,7 +45,7 @@ version = "1.0.6"
 version = "1.0.0"

 [workspace.dependencies.cargo_toml]
-version = "1.0"
+version = "0.22"
 default-features = false
 features = ["features"]

@@ -164,7 +164,7 @@ features = ["raw_value"]

 # Used for appservice registration files
 [workspace.dependencies.serde-saphyr]
-version = "0.0.28"
+version = "0.0.27"

 # Used to load forbidden room/user regex from config
 [workspace.dependencies.serde_regex]
@@ -356,7 +356,6 @@ features = [
     "ring-compat",
     "compat-upload-signatures",
     "compat-optional-txn-pdus",
-    "compat-get-3pids",
     "unstable-msc2666",
     "unstable-msc2867",
     "unstable-msc2870",
@@ -561,10 +560,7 @@ features = ["std"]
 version = "0.3.0"

 [workspace.dependencies.resolvematrix]
-version = "0.1.0"
-
-[workspace.dependencies.serde_urlencoded]
-version = "0.7.1"
+version = "0.0.4"

 #
 # Patches
diff --git c/src/admin/query/resolver.rs i/src/admin/query/resolver.rs
index 4a88650f8..add4c70de 100644
--- c/src/admin/query/resolver.rs
+++ i/src/admin/query/resolver.rs
@@ -92,9 +92,11 @@ async fn overrides_cache(&self, server_name: Option<String>) -> Result {

 	async fn flush_cache(&self, name: Option<OwnedServerName>, all: bool) -> Result {
 		if all {
-			self.services.resolver.dns.cache.clear().await;
-			writeln!(self, "Resolver caches cleared!").await
-		} else if let Some(name) = name {
+		    self.services.resolver.resolver.clear_cache();
+		    self.services.resolver.dns.cache.clear().await;
+		    writeln!(self, "Resolver caches cleared!").await
+	    } else if let Some(name) = name {
+		    self.services.resolver.resolver.remove_cache_entry(&name.as_str());
 			self.services.resolver.dns.cache.del_destination(&name);
 			self.services.resolver.dns.cache.del_override(&name);
 			self.write_str(&format!("Cleared {name} from resolver caches!"))
diff --git c/src/service/resolver/mod.rs i/src/service/resolver/mod.rs
index c24b8ba60..6b57013dd 100644
--- c/src/service/resolver/mod.rs
+++ i/src/service/resolver/mod.rs
@@ -45,7 +45,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 	}

 	async fn clear_cache(&self) {
-		// No ability to clean resolvematrix cache at the moment
+		self.resolver.clear_cache();
 		self.dns.resolver.clear_cache();
 		self.dns.cache.clear().await;
 	}
2026-07-03 10:59:11 +02:00
f8ad323a1e
chore: Lockfile update
diff --git c/Cargo.lock i/Cargo.lock
index 9f1d6b35d..4a8b1e273 100644
--- c/Cargo.lock
+++ i/Cargo.lock
@@ -39,6 +39,24 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "aligned"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685"
+dependencies = [
+ "as-slice",
+]
+
+[[package]]
+name = "aligned-vec"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
+dependencies = [
+ "equator",
+]
+
 [[package]]
 name = "alloc-no-stdlib"
 version = "2.0.4"
@@ -47,9 +65,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"

 [[package]]
 name = "alloc-stdlib"
-version = "0.2.4"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
 dependencies = [
  "alloc-no-stdlib",
 ]
@@ -71,9 +89,9 @@ dependencies = [

 [[package]]
 name = "annotate-snippets"
-version = "0.12.16"
+version = "0.12.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1"
+checksum = "92570a3f9c98e7e84df84b71d0965ac99b1871fcd75a3773a3bd1bad13f64cf7"
 dependencies = [
  "anstyle",
  "memchr",
@@ -101,6 +119,12 @@ version = "1.0.102"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"

+[[package]]
+name = "arbitrary"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
+
 [[package]]
 name = "arc-swap"
 version = "1.9.1"
@@ -110,6 +134,17 @@ dependencies = [
  "rustversion",
 ]

+[[package]]
+name = "arg_enum_proc_macro"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "argon2"
 version = "0.5.3"
@@ -130,13 +165,22 @@ checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"

 [[package]]
 name = "arrayvec"
-version = "0.7.7"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
 dependencies = [
  "serde",
 ]

+[[package]]
+name = "as-slice"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
+dependencies = [
+ "stable_deref_trait",
+]
+
 [[package]]
 name = "as_variant"
 version = "1.3.0"
@@ -145,9 +189,9 @@ checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a"

 [[package]]
 name = "askama"
-version = "0.16.0"
+version = "0.15.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc"
+checksum = "9b8246bcbf8eb97abef10c2d92166449680d41d55c0fc6978a91dec2e3619608"
 dependencies = [
  "askama_macros",
  "itoa",
@@ -158,13 +202,12 @@ dependencies = [

 [[package]]
 name = "askama_derive"
-version = "0.16.0"
+version = "0.15.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738"
+checksum = "2f9670bc84a28bb3da91821ef74226949ab63f1265aff7c751634f1dd0e6f97c"
 dependencies = [
  "askama_parser",
  "basic-toml",
- "glob",
  "memchr",
  "proc-macro2",
  "quote",
@@ -176,24 +219,63 @@ dependencies = [

 [[package]]
 name = "askama_macros"
-version = "0.16.0"
+version = "0.15.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a"
+checksum = "f0756b45480437dded0565dfc568af62ccce146fb6cfe902e808ba86e445f44f"
 dependencies = [
  "askama_derive",
 ]

 [[package]]
 name = "askama_parser"
-version = "0.16.0"
+version = "0.15.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da"
+checksum = "5d0af3691ba3af77949c0b5a3925444b85cb58a0184cc7fec16c68ba2e7be868"
 dependencies = [
  "rustc-hash",
  "serde",
  "serde_derive",
  "unicode-ident",
- "winnow 1.0.3",
+ "winnow 1.0.1",
+]
+
+[[package]]
+name = "asn1-rs"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60"
+dependencies = [
+ "asn1-rs-derive",
+ "asn1-rs-impl",
+ "displaydoc",
+ "nom 7.1.3",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror 2.0.18",
+ "time",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]

 [[package]]
@@ -215,9 +297,9 @@ dependencies = [

 [[package]]
 name = "async-compression"
-version = "0.4.42"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac"
+checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1"
 dependencies = [
  "compression-codecs",
  "compression-core",
@@ -253,15 +335,58 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"

 [[package]]
 name = "autocfg"
-version = "1.5.1"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "av-scenechange"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394"
+dependencies = [
+ "aligned",
+ "anyhow",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "log",
+ "num-rational",
+ "num-traits",
+ "pastey",
+ "rayon",
+ "thiserror 2.0.18",
+ "v_frame",
+ "y4m",
+]
+
+[[package]]
+name = "av1-grain"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8"
+dependencies = [
+ "anyhow",
+ "arrayvec",
+ "log",
+ "nom 8.0.0",
+ "num-rational",
+ "v_frame",
+]
+
+[[package]]
+name = "avif-serialize"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d"
+dependencies = [
+ "arrayvec",
+]

 [[package]]
 name = "aws-lc-rs"
-version = "1.17.0"
+version = "1.16.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00"
+checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc"
 dependencies = [
  "aws-lc-sys",
  "zeroize",
@@ -269,9 +394,9 @@ dependencies = [

 [[package]]
 name = "aws-lc-sys"
-version = "0.41.0"
+version = "0.39.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4"
+checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399"
 dependencies = [
  "cc",
  "cmake",
@@ -281,9 +406,9 @@ dependencies = [

 [[package]]
 name = "axum"
-version = "0.8.9"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
+checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
 dependencies = [
  "axum-core",
  "bytes",
@@ -314,12 +439,12 @@ dependencies = [

 [[package]]
 name = "axum-client-ip"
-version = "1.3.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8ba1af5b620232acf37f2eb6d22151ea465491e0b4c25f552d1990f64ec5a67"
+checksum = "dff8ee1869817523c8f91c20bf17fd932707f66c2e7e0b0f811b29a227289562"
 dependencies = [
  "axum",
- "client-ip",
+ "forwarded-header-value",
  "serde",
 ]

@@ -344,9 +469,9 @@ dependencies = [

 [[package]]
 name = "axum-extra"
-version = "0.12.6"
+version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be44683b41ccb9ab2d23a5230015c9c3c55be97a25e4428366de8873103f7970"
+checksum = "fef252edff26ddba56bbcdf2ee3307b8129acb86f5749b68990c168a6fcc9c76"
 dependencies = [
  "axum",
  "axum-core",
@@ -367,13 +492,12 @@ dependencies = [

 [[package]]
 name = "axum-server"
-version = "0.8.0"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1df331683d982a0b9492b38127151e6453639cd34926eb9c07d4cd8c6d22bfc"
+checksum = "c1ab4a3ec9ea8a657c72d99a03a824af695bd0fb5ec639ccbd9cd3543b41a5f9"
 dependencies = [
  "arc-swap",
  "bytes",
- "either",
  "fs-err",
  "http",
  "http-body",
@@ -381,6 +505,7 @@ dependencies = [
  "hyper-util",
  "pin-project-lite",
  "rustls",
+ "rustls-pemfile",
  "rustls-pki-types",
  "tokio",
  "tokio-rustls",
@@ -389,8 +514,9 @@ dependencies = [

 [[package]]
 name = "axum-server-dual-protocol"
-version = "0.8.0"
-source = "git+https://github.com/vinchona/axum-server-dual-protocol.git?rev=ca6db055254255b74238673ce4135698e347d71c#ca6db055254255b74238673ce4135698e347d71c"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2164551db024e87f20316d164eab9f5ad342d8188b08051ceb15ca92a60ea7b7"
 dependencies = [
  "axum-server",
  "bytes",
@@ -461,15 +587,30 @@ dependencies = [
  "quote",
  "regex",
  "rustc-hash",
- "shlex 1.3.0",
+ "shlex",
  "syn",
 ]

 [[package]]
-name = "bitflags"
-version = "2.13.0"
+name = "bit_field"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
+
+[[package]]
+name = "bitflags"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
+
+[[package]]
+name = "bitstream-io"
+version = "4.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757"
+dependencies = [
+ "core2",
+]

 [[package]]
 name = "blake2"
@@ -477,7 +618,7 @@ version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
 dependencies = [
- "digest 0.10.7",
+ "digest",
 ]

 [[package]]
@@ -489,15 +630,6 @@ dependencies = [
  "generic-array",
 ]

-[[package]]
-name = "block-buffer"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
-dependencies = [
- "hybrid-array",
-]
-
 [[package]]
 name = "block2"
 version = "0.6.2"
@@ -508,10 +640,19 @@ dependencies = [
 ]

 [[package]]
-name = "brotli"
-version = "8.0.4"
+name = "blurhash"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3"
+checksum = "e79769241dcd44edf79a732545e8b5cec84c247ac060f5252cd51885d093a8fc"
+dependencies = [
+ "image",
+]
+
+[[package]]
+name = "brotli"
+version = "8.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -520,9 +661,9 @@ dependencies = [

 [[package]]
 name = "brotli-decompressor"
-version = "5.0.3"
+version = "5.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -530,15 +671,15 @@ dependencies = [

 [[package]]
 name = "built"
-version = "0.8.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9"
+checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64"

 [[package]]
 name = "bumpalo"
-version = "3.20.3"
+version = "3.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
+checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"

 [[package]]
 name = "bytemuck"
@@ -560,15 +701,15 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"

 [[package]]
 name = "bytes"
-version = "1.12.0"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"

 [[package]]
 name = "bytesize"
-version = "2.4.0"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49e78e506b9d7633710dab98996f22f95f3d0f488e8f1aa162830556ed9fc14d"
+checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3"

 [[package]]
 name = "bzip2-sys"
@@ -591,9 +732,9 @@ dependencies = [

 [[package]]
 name = "cargo-platform"
-version = "0.3.3"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba"
+checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082"
 dependencies = [
  "serde",
  "serde_core",
@@ -610,32 +751,37 @@ dependencies = [
  "semver",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
 ]

 [[package]]
 name = "cargo_toml"
-version = "1.0.0"
+version = "0.22.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520"
+checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
 dependencies = [
- "semver",
  "serde",
- "toml 1.1.2+spec-1.1.0",
+ "toml 0.9.12+spec-1.1.0",
 ]

 [[package]]
 name = "cc"
-version = "1.2.64"
+version = "1.2.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f"
+checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
 dependencies = [
  "find-msvc-tools",
  "jobserver",
  "libc",
- "shlex 2.0.1",
+ "shlex",
 ]

+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
 [[package]]
 name = "cexpr"
 version = "0.6.0"
@@ -665,7 +811,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.3.0",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
 ]

 [[package]]
@@ -679,9 +825,9 @@ dependencies = [

 [[package]]
 name = "chrono"
-version = "0.4.45"
+version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
+checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
 dependencies = [
  "num-traits",
 ]
@@ -699,9 +845,9 @@ dependencies = [

 [[package]]
 name = "clap"
-version = "4.6.1"
+version = "4.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
+checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -719,9 +865,9 @@ dependencies = [

 [[package]]
 name = "clap_derive"
-version = "4.6.1"
+version = "4.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
+checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -735,15 +881,6 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"

-[[package]]
-name = "client-ip"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39d2056bf065c8b4bce5a8898d40e175211ff4410add2a84d695845d3937c729"
-dependencies = [
- "http",
-]
-
 [[package]]
 name = "cmake"
 version = "0.1.58"
@@ -753,12 +890,6 @@ dependencies = [
  "cc",
 ]

-[[package]]
-name = "cmov"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
-
 [[package]]
 name = "color_quant"
 version = "1.1.0"
@@ -777,9 +908,9 @@ dependencies = [

 [[package]]
 name = "compression-codecs"
-version = "0.4.38"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf"
+checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7"
 dependencies = [
  "brotli",
  "compression-core",
@@ -791,9 +922,9 @@ dependencies = [

 [[package]]
 name = "compression-core"
-version = "0.4.32"
+version = "0.4.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789"
+checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"

 [[package]]
 name = "concurrent-queue"
@@ -806,9 +937,8 @@ dependencies = [

 [[package]]
 name = "conduwuit"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "aws-lc-rs",
  "clap",
  "conduwuit_admin",
  "conduwuit_api",
@@ -821,15 +951,12 @@ dependencies = [
  "console-subscriber",
  "const-str",
  "ctor",
- "dtor",
  "hardened_malloc-rs",
  "log",
  "opentelemetry",
  "opentelemetry-otlp",
  "opentelemetry_sdk",
  "parking_lot",
- "reqwest 0.13.4",
- "rustls",
  "sentry",
  "sentry-tower",
  "sentry-tracing",
@@ -844,9 +971,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_admin"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "clap",
  "conduwuit_api",
  "conduwuit_core",
@@ -855,10 +981,10 @@ dependencies = [
  "conduwuit_service",
  "const-str",
  "ctor",
- "dtor",
  "futures",
  "lettre",
  "log",
+ "resolvematrix",
  "ruma",
  "serde-saphyr",
  "serde_json",
@@ -869,9 +995,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_api"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "async-trait",
  "axum",
  "axum-client-ip",
@@ -883,31 +1008,29 @@ dependencies = [
  "conduwuit_service",
  "const-str",
  "ctor",
- "dtor",
  "futures",
  "hmac",
  "http",
  "http-body-util",
  "hyper",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "lettre",
  "log",
  "rand 0.10.1",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
  "ruma",
- "ruminuwuity",
  "serde",
  "serde_html_form",
  "serde_json",
- "sha1 0.11.0",
+ "sha1",
  "tokio",
  "tracing",
 ]

 [[package]]
 name = "conduwuit_build_metadata"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "built",
  "cargo_metadata",
@@ -915,11 +1038,10 @@ dependencies = [

 [[package]]
 name = "conduwuit_core"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "argon2",
  "arrayvec",
- "assign",
  "axum",
  "axum-extra",
  "bytes",
@@ -934,7 +1056,6 @@ dependencies = [
  "core_affinity",
  "ctor",
  "cyborgtime",
- "dtor",
  "either",
  "figment",
  "futures",
@@ -943,36 +1064,37 @@ dependencies = [
  "http-body-util",
  "hyper-util",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "lettre",
  "libc",
  "libloading 0.9.0",
  "lock_api",
  "log",
  "maplit",
- "nix",
+ "nix 0.31.2",
  "num-traits",
  "parking_lot",
  "rand 0.10.1",
  "rand_core 0.6.4",
  "regex",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
+ "resolvematrix",
+ "ring",
  "ruma",
  "sanitize-filename",
  "serde",
  "serde-saphyr",
  "serde_json",
  "serde_regex",
- "sha2 0.11.0",
  "smallstr",
  "smallvec",
- "thiserror",
+ "thiserror 2.0.18",
  "tikv-jemalloc-ctl",
  "tikv-jemalloc-sys",
  "tikv-jemallocator",
  "tokio",
  "tokio-metrics",
- "toml 1.1.2+spec-1.1.0",
+ "toml 0.9.12+spec-1.1.0",
  "tracing",
  "tracing-core",
  "tracing-subscriber",
@@ -981,14 +1103,13 @@ dependencies = [

 [[package]]
 name = "conduwuit_database"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "async-channel",
  "conduwuit_core",
  "conduwuit_macros",
  "const-str",
  "ctor",
- "dtor",
  "futures",
  "log",
  "minicbor",
@@ -1002,10 +1123,10 @@ dependencies = [

 [[package]]
 name = "conduwuit_macros"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "cargo_toml",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "proc-macro2",
  "quote",
  "syn",
@@ -1013,9 +1134,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_router"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "axum",
  "axum-client-ip",
  "axum-server",
@@ -1029,7 +1149,6 @@ dependencies = [
  "conduwuit_web",
  "const-str",
  "ctor",
- "dtor",
  "futures",
  "http",
  "http-body-util",
@@ -1045,25 +1164,24 @@ dependencies = [
  "serde_json",
  "tokio",
  "tower",
- "tower-http 0.7.0",
+ "tower-http",
  "tracing",
 ]

 [[package]]
 name = "conduwuit_service"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
- "assign",
  "async-trait",
  "base64 0.22.1",
+ "blurhash",
  "bytes",
  "conduwuit_core",
  "conduwuit_database",
  "conduwuit_macros",
  "const-str",
  "ctor",
- "dtor",
  "either",
  "futures",
  "governor",
@@ -1071,7 +1189,8 @@ dependencies = [
  "http",
  "image",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
+ "ldap3",
  "lettre",
  "log",
  "loole",
@@ -1081,16 +1200,14 @@ dependencies = [
  "recaptcha-verify",
  "regex",
  "reqwest 0.12.28",
- "reqwest 0.13.4",
+ "resolvematrix",
  "ruma",
- "ruminuwuity",
  "rustyline-async",
  "sd-notify",
  "serde",
  "serde-saphyr",
  "serde_json",
- "serde_urlencoded",
- "sha2 0.11.0",
+ "sha2",
  "termimad",
  "tokio",
  "tracing",
@@ -1101,37 +1218,25 @@ dependencies = [

 [[package]]
 name = "conduwuit_web"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
- "assign",
  "async-trait",
  "axum",
  "axum-extra",
  "base64 0.22.1",
- "conduwuit_api",
  "conduwuit_build_metadata",
  "conduwuit_core",
- "conduwuit_database",
  "conduwuit_service",
- "form_urlencoded",
  "futures",
- "lettre",
  "memory-serve",
  "rand 0.10.1",
- "recaptcha-verify",
- "reqwest 0.12.28",
  "ruma",
  "serde",
- "serde_json",
- "serde_urlencoded",
- "thiserror",
- "tower-http 0.7.0",
+ "thiserror 2.0.18",
+ "tower-http",
  "tower-sec-fetch",
- "tower-sessions",
- "tower-sessions-core",
  "tracing",
- "url",
  "validator",
 ]

@@ -1183,9 +1288,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"

 [[package]]
 name = "const-str"
-version = "1.1.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f"
+checksum = "b0664d2867b4a32697dfe655557f5c3b187e9b605b38612a748e5ec99811d160"

 [[package]]
 name = "const_panic"
@@ -1196,6 +1301,16 @@ dependencies = [
  "typewit",
 ]

+[[package]]
+name = "continuwuity-admin-api"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "ruma-common",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "convert_case"
 version = "0.10.0"
@@ -1225,16 +1340,6 @@ dependencies = [
  "crossterm",
 ]

-[[package]]
-name = "core-foundation"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "core-foundation"
 version = "0.10.1"
@@ -1251,6 +1356,15 @@ version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"

+[[package]]
+name = "core2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "core_affinity"
 version = "0.8.3"
@@ -1404,6 +1518,12 @@ dependencies = [
  "winapi",
 ]

+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
 [[package]]
 name = "crypto-common"
 version = "0.1.7"
@@ -1414,33 +1534,21 @@ dependencies = [
  "typenum",
 ]

-[[package]]
-name = "crypto-common"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
-dependencies = [
- "hybrid-array",
-]
-
 [[package]]
 name = "ctor"
-version = "1.0.7"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
+checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e"
 dependencies = [
- "link-section",
- "linktime-proc-macro",
+ "ctor-proc-macro",
+ "dtor",
 ]

 [[package]]
-name = "ctutils"
-version = "0.4.2"
+name = "ctor-proc-macro"
+version = "0.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
-dependencies = [
- "cmov",
-]
+checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"

 [[package]]
 name = "curve25519-dalek"
@@ -1451,7 +1559,7 @@ dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
  "curve25519-dalek-derive",
- "digest 0.10.7",
+ "digest",
  "fiat-crypto",
  "rustc_version",
  "subtle",
@@ -1512,9 +1620,9 @@ dependencies = [

 [[package]]
 name = "data-encoding"
-version = "2.11.0"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
+checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"

 [[package]]
 name = "date_header"
@@ -1542,13 +1650,27 @@ dependencies = [
  "zeroize",
 ]

+[[package]]
+name = "der-parser"
+version = "10.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6"
+dependencies = [
+ "asn1-rs",
+ "displaydoc",
+ "nom 7.1.3",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
 [[package]]
 name = "deranged"
 version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
 dependencies = [
- "serde_core",
+ "powerfmt",
 ]

 [[package]]
@@ -1579,22 +1701,11 @@ version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
 dependencies = [
- "block-buffer 0.10.4",
- "crypto-common 0.1.7",
+ "block-buffer",
+ "crypto-common",
  "subtle",
 ]

-[[package]]
-name = "digest"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
-dependencies = [
- "block-buffer 0.12.1",
- "crypto-common 0.2.2",
- "ctutils",
-]
-
 [[package]]
 name = "dispatch2"
 version = "0.3.1"
@@ -1607,9 +1718,9 @@ dependencies = [

 [[package]]
 name = "displaydoc"
-version = "0.2.6"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1626,14 +1737,30 @@ dependencies = [
 ]

 [[package]]
-name = "dtor"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d738e43aa64edab57c983d56de890d65fea7dc05605490c74451ce721dfd84b"
+name = "draupnir-antispam"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
- "linktime-proc-macro",
+ "ruma-common",
+ "serde",
+ "serde_json",
 ]

+[[package]]
+name = "dtor"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301"
+dependencies = [
+ "dtor-proc-macro",
+]
+
+[[package]]
+name = "dtor-proc-macro"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
+
 [[package]]
 name = "dunce"
 version = "1.0.5"
@@ -1658,17 +1785,18 @@ checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
 dependencies = [
  "curve25519-dalek",
  "ed25519",
+ "rand_core 0.6.4",
  "serde",
- "sha2 0.10.9",
+ "sha2",
  "subtle",
  "zeroize",
 ]

 [[package]]
 name = "either"
-version = "1.16.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
 dependencies = [
  "serde",
 ]
@@ -1707,6 +1835,38 @@ dependencies = [
  "encoding_rs",
 ]

+[[package]]
+name = "enum-as-inner"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "equator"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
+dependencies = [
+ "equator-macro",
+]
+
+[[package]]
+name = "equator-macro"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "equivalent"
 version = "1.0.2"
@@ -1742,12 +1902,47 @@ dependencies = [
  "pin-project-lite",
 ]

+[[package]]
+name = "exr"
+version = "1.74.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be"
+dependencies = [
+ "bit_field",
+ "half",
+ "lebe",
+ "miniz_oxide",
+ "rayon-core",
+ "smallvec",
+ "zune-inflate",
+]
+
 [[package]]
 name = "fastrand"
 version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"

+[[package]]
+name = "fax"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab"
+dependencies = [
+ "fax_derive",
+]
+
+[[package]]
+name = "fax_derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "fdeflate"
 version = "0.3.7"
@@ -1838,6 +2033,16 @@ dependencies = [
  "percent-encoding",
 ]

+[[package]]
+name = "forwarded-header-value"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9"
+dependencies = [
+ "nonempty",
+ "thiserror 1.0.69",
+]
+
 [[package]]
 name = "fs-err"
 version = "3.3.0"
@@ -1937,9 +2142,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"

 [[package]]
 name = "futures-timer"
-version = "3.0.4"
+version = "3.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968"
+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"

 [[package]]
 name = "futures-util"
@@ -2004,7 +2209,7 @@ dependencies = [
  "cfg-if",
  "libc",
  "r-efi 6.0.0",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
  "wasip2",
  "wasip3",
 ]
@@ -2050,21 +2255,11 @@ dependencies = [
  "web-time",
 ]

-[[package]]
-name = "granit-parser"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14668345710c92cb04181d9268407067689327d4b055273e3c4179a0777ee6a1"
-dependencies = [
- "arraydeque",
- "smallvec",
-]
-
 [[package]]
 name = "h2"
-version = "0.4.15"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155"
+checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -2107,6 +2302,17 @@ dependencies = [
  "tokio-util",
 ]

+[[package]]
+name = "half"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+ "zerocopy",
+]
+
 [[package]]
 name = "hardened_malloc-rs"
 version = "0.1.2+12"
@@ -2135,9 +2341,9 @@ dependencies = [

 [[package]]
 name = "hashbrown"
-version = "0.17.1"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"

 [[package]]
 name = "hdrhistogram"
@@ -2164,7 +2370,7 @@ dependencies = [
  "http",
  "httpdate",
  "mime",
- "sha1 0.10.6",
+ "sha1",
 ]

 [[package]]
@@ -2195,84 +2401,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"

 [[package]]
-name = "hickory-net"
-version = "0.26.1"
+name = "hickory-proto"
+version = "0.25.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183"
+checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502"
 dependencies = [
  "async-trait",
  "cfg-if",
  "data-encoding",
+ "enum-as-inner",
  "futures-channel",
  "futures-io",
  "futures-util",
- "hickory-proto",
  "idna",
  "ipnet",
- "jni",
- "rand 0.10.1",
- "thiserror",
- "tinyvec",
- "tokio",
- "tracing",
- "url",
-]
-
-[[package]]
-name = "hickory-proto"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643"
-dependencies = [
- "data-encoding",
- "idna",
- "ipnet",
- "jni",
  "once_cell",
- "prefix-trie",
- "rand 0.10.1",
+ "rand 0.9.3",
  "ring",
  "serde",
- "thiserror",
+ "thiserror 2.0.18",
  "tinyvec",
+ "tokio",
  "tracing",
  "url",
 ]

 [[package]]
 name = "hickory-resolver"
-version = "0.26.1"
+version = "0.25.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c"
+checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a"
 dependencies = [
  "cfg-if",
  "futures-util",
- "hickory-net",
  "hickory-proto",
  "ipconfig",
- "ipnet",
- "jni",
  "moka",
- "ndk-context",
  "once_cell",
  "parking_lot",
- "rand 0.10.1",
+ "rand 0.9.3",
  "resolv-conf",
  "serde",
  "smallvec",
- "system-configuration",
- "thiserror",
+ "thiserror 2.0.18",
  "tokio",
  "tracing",
 ]

 [[package]]
 name = "hmac"
-version = "0.13.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
 dependencies = [
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -2302,9 +2484,9 @@ dependencies = [

 [[package]]
 name = "http"
-version = "1.4.2"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
+checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
 dependencies = [
  "bytes",
  "itoa",
@@ -2360,20 +2542,11 @@ version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"

-[[package]]
-name = "hybrid-array"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
-dependencies = [
- "typenum",
-]
-
 [[package]]
 name = "hyper"
-version = "1.10.1"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
+checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -2393,18 +2566,20 @@ dependencies = [

 [[package]]
 name = "hyper-rustls"
-version = "0.27.9"
+version = "0.27.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
+checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
 dependencies = [
  "http",
  "hyper",
  "hyper-util",
  "rustls",
  "rustls-native-certs",
+ "rustls-pki-types",
  "tokio",
  "tokio-rustls",
  "tower-service",
+ "webpki-roots",
 ]

 [[package]]
@@ -2549,9 +2724,9 @@ dependencies = [

 [[package]]
 name = "idna_adapter"
-version = "1.2.2"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -2566,11 +2741,17 @@ dependencies = [
  "bytemuck",
  "byteorder-lite",
  "color_quant",
+ "exr",
  "gif",
  "image-webp",
  "moxcms",
  "num-traits",
  "png",
+ "qoi",
+ "ravif",
+ "rayon",
+ "rgb",
+ "tiff",
  "zune-core",
  "zune-jpeg",
 ]
@@ -2585,6 +2766,12 @@ dependencies = [
  "quick-error",
 ]

+[[package]]
+name = "imgref"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
+
 [[package]]
 name = "indexmap"
 version = "2.14.0"
@@ -2592,7 +2779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
 dependencies = [
  "equivalent",
- "hashbrown 0.17.1",
+ "hashbrown 0.17.0",
  "serde",
  "serde_core",
 ]
@@ -2603,6 +2790,17 @@ version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"

+[[package]]
+name = "interpolate_name"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "ipaddress"
 version = "0.1.3"
@@ -2635,7 +2833,14 @@ name = "ipnet"
 version = "2.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
+
+[[package]]
+name = "iri-string"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20"
 dependencies = [
+ "memchr",
  "serde",
 ]

@@ -2657,15 +2862,6 @@ dependencies = [
  "either",
 ]

-[[package]]
-name = "itertools"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
-dependencies = [
- "either",
-]
-
 [[package]]
 name = "itoa"
 version = "1.0.18"
@@ -2674,32 +2870,27 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"

 [[package]]
 name = "jni"
-version = "0.22.4"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
 dependencies = [
+ "cesu8",
  "cfg-if",
  "combine",
- "jni-macros",
- "jni-sys",
+ "jni-sys 0.3.1",
  "log",
- "simd_cesu8",
- "thiserror",
+ "thiserror 1.0.69",
  "walkdir",
- "windows-link",
+ "windows-sys 0.45.0",
 ]

 [[package]]
-name = "jni-macros"
-version = "0.22.4"
+name = "jni-sys"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
+checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
 dependencies = [
- "proc-macro2",
- "quote",
- "rustc_version",
- "simd_cesu8",
- "syn",
+ "jni-sys 0.4.1",
 ]

 [[package]]
@@ -2733,12 +2924,13 @@ dependencies = [

 [[package]]
 name = "js-sys"
-version = "0.3.102"
+version = "0.3.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
+checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
 dependencies = [
  "cfg-if",
  "futures-util",
+ "once_cell",
  "wasm-bindgen",
 ]

@@ -2753,20 +2945,30 @@ dependencies = [

 [[package]]
 name = "js_option"
-version = "0.2.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7dd3e281add16813cf673bf74a32249b0aa0d1c8117519a17b3ada5e8552b3c"
+checksum = "68421373957a1593a767013698dbf206e2b221eefe97a44d98d18672ff38423c"
 dependencies = [
- "serde_core",
+ "serde",
 ]

 [[package]]
 name = "konst"
-version = "0.4.3"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f660d5f887e3562f9ab6f4a14988795b694099d66b4f5dedc02d197ba9becb1d"
+checksum = "4381b9b00c55f251f2ebe9473aef7c117e96828def1a7cb3bd3f0f903c6894e9"
 dependencies = [
  "const_panic",
+ "konst_kernel",
+ "typewit",
+]
+
+[[package]]
+name = "konst_kernel"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c"
+dependencies = [
  "typewit",
 ]

@@ -2799,6 +3001,41 @@ version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"

+[[package]]
+name = "lber"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbcf559624bfd9fe8d488329a8959766335a43a9b8b2cdd6a2c379fca02909a5"
+dependencies = [
+ "bytes",
+ "nom 7.1.3",
+]
+
+[[package]]
+name = "ldap3"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01fe89f5e7cfb7e4701e3a38ff9f00358e026a9aee940355d88ee9d81e5c7503"
+dependencies = [
+ "async-trait",
+ "bytes",
+ "futures",
+ "futures-util",
+ "lber",
+ "log",
+ "nom 7.1.3",
+ "percent-encoding",
+ "rustls",
+ "rustls-native-certs",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tokio-util",
+ "url",
+ "x509-parser",
+]
+
 [[package]]
 name = "leb128fmt"
 version = "0.1.0"
@@ -2806,10 +3043,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"

 [[package]]
-name = "lettre"
-version = "0.11.22"
+name = "lebe"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0da65617f6cb926332d039cb578aad56178da86e128db6a1b09f4c94fa5b3349"
+checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
+
+[[package]]
+name = "lettre"
+version = "0.11.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dabda5859ee7c06b995b9d1165aa52c39110e079ef609db97178d86aeb051fa7"
 dependencies = [
  "async-trait",
  "base64 0.22.1",
@@ -2837,9 +3080,19 @@ dependencies = [

 [[package]]
 name = "libc"
-version = "0.2.186"
+version = "0.2.184"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
+
+[[package]]
+name = "libfuzzer-sys"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
+dependencies = [
+ "arbitrary",
+ "cc",
+]

 [[package]]
 name = "libloading"
@@ -2863,33 +3116,21 @@ dependencies = [

 [[package]]
 name = "libz-sys"
-version = "1.1.29"
+version = "1.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9"
+checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22"
 dependencies = [
  "cc",
  "pkg-config",
  "vcpkg",
 ]

-[[package]]
-name = "link-section"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2b1dd6fe32e55c0fc0ea9493aa57459ca3cf4ff3c857c7d0302290150da6e4f"
-
 [[package]]
 name = "linked-hash-map"
 version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"

-[[package]]
-name = "linktime-proc-macro"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c7b0a3383c2a1002d11349c92c85a666a5fb679e96c79d782cf0dbe557fd6ee"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.12.1"
@@ -2919,9 +3160,9 @@ dependencies = [

 [[package]]
 name = "log"
-version = "0.4.33"
+version = "0.4.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"

 [[package]]
 name = "loole"
@@ -2933,6 +3174,15 @@ dependencies = [
  "futures-sink",
 ]

+[[package]]
+name = "loop9"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
+dependencies = [
+ "imgref",
+]
+
 [[package]]
 name = "lru-cache"
 version = "0.1.2"
@@ -3012,10 +3262,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"

 [[package]]
-name = "memchr"
-version = "2.8.2"
+name = "maybe-rayon"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
+dependencies = [
+ "cfg-if",
+ "rayon",
+]
+
+[[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"

 [[package]]
 name = "memory-serve"
@@ -3033,6 +3293,16 @@ dependencies = [
  "walkdir",
 ]

+[[package]]
+name = "meowlnir-antispam"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "ruma-common",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "mime"
 version = "0.3.17"
@@ -3051,15 +3321,15 @@ dependencies = [

 [[package]]
 name = "minicbor"
-version = "2.2.2"
+version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b7a5041e12946f8b7d3f5a9d96383a19d694b9335457c522be7815b9abafb02"
+checksum = "e70eae6d4f18f7d76877fe7b13f0bc21f7c2b7239d2041c338335f7b388d0dd7"

 [[package]]
 name = "minicbor-serde"
-version = "0.7.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "293c7245401f035e2dcc4b12ebdb5c9d8847247fc79fe1b5b0a0d58d7275324c"
+checksum = "80047f75e28e3b38f6ab2ec3c2c7669f6b411fa6f8424e1a90a3fd784b19a3f4"
 dependencies = [
  "minicbor",
  "serde",
@@ -3092,9 +3362,9 @@ dependencies = [

 [[package]]
 name = "mio"
-version = "1.2.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
 dependencies = [
  "libc",
  "log",
@@ -3129,12 +3399,6 @@ dependencies = [
  "pxfm",
 ]

-[[package]]
-name = "ndk-context"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
-
 [[package]]
 name = "new_debug_unreachable"
 version = "1.0.6"
@@ -3143,9 +3407,21 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"

 [[package]]
 name = "nix"
-version = "0.31.3"
+version = "0.30.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+]
+
+[[package]]
+name = "nix"
+version = "0.31.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -3178,12 +3454,24 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "nonempty"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
+
 [[package]]
 name = "nonzero_ext"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"

+[[package]]
+name = "noop_proc_macro"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
+
 [[package]]
 name = "nu-ansi-term"
 version = "0.50.3"
@@ -3228,9 +3516,20 @@ dependencies = [

 [[package]]
 name = "num-conv"
-version = "0.2.2"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
+checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
+
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]

 [[package]]
 name = "num-integer"
@@ -3450,6 +3749,15 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "oid-registry"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7"
+dependencies = [
+ "asn1-rs",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.21.4"
@@ -3468,36 +3776,36 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"

 [[package]]
 name = "opentelemetry"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682"
+checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
 dependencies = [
  "futures-core",
  "futures-sink",
  "js-sys",
  "pin-project-lite",
- "thiserror",
+ "thiserror 2.0.18",
  "tracing",
 ]

 [[package]]
 name = "opentelemetry-http"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331"
+checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
 dependencies = [
  "async-trait",
  "bytes",
  "http",
  "opentelemetry",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
 ]

 [[package]]
 name = "opentelemetry-otlp"
-version = "0.32.0"
+version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35"
+checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f"
 dependencies = [
  "http",
  "opentelemetry",
@@ -3505,18 +3813,18 @@ dependencies = [
  "opentelemetry-proto",
  "opentelemetry_sdk",
  "prost",
- "reqwest 0.13.4",
- "thiserror",
+ "reqwest 0.12.28",
+ "thiserror 2.0.18",
  "tokio",
  "tonic",
- "tonic-types",
+ "tracing",
 ]

 [[package]]
 name = "opentelemetry-proto"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638"
+checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
 dependencies = [
  "opentelemetry",
  "opentelemetry_sdk",
@@ -3527,31 +3835,30 @@ dependencies = [

 [[package]]
 name = "opentelemetry_sdk"
-version = "0.32.1"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9"
+checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
 dependencies = [
  "futures-channel",
  "futures-executor",
  "futures-util",
  "opentelemetry",
  "percent-encoding",
- "portable-atomic",
- "rand 0.9.4",
- "thiserror",
+ "rand 0.9.3",
+ "thiserror 2.0.18",
  "tokio",
  "tokio-stream",
 ]

 [[package]]
 name = "os_info"
-version = "3.15.0"
+version = "3.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b"
+checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224"
 dependencies = [
  "android_system_properties",
  "log",
- "nix",
+ "nix 0.30.1",
  "objc2",
  "objc2-foundation",
  "objc2-ui-kit",
@@ -3607,6 +3914,12 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"

+[[package]]
+name = "pastey"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
+
 [[package]]
 name = "pear"
 version = "0.2.9"
@@ -3672,7 +3985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
  "phf_shared",
- "rand 0.8.6",
+ "rand 0.8.5",
 ]

 [[package]]
@@ -3686,18 +3999,18 @@ dependencies = [

 [[package]]
 name = "pin-project"
-version = "1.1.13"
+version = "1.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
+checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
 dependencies = [
  "pin-project-internal",
 ]

 [[package]]
 name = "pin-project-internal"
-version = "1.1.13"
+version = "1.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
+checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3722,9 +4035,9 @@ dependencies = [

 [[package]]
 name = "pkg-config"
-version = "0.3.33"
+version = "0.3.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"

 [[package]]
 name = "png"
@@ -3775,17 +4088,6 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"

-[[package]]
-name = "prefix-trie"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7"
-dependencies = [
- "either",
- "ipnet",
- "num-traits",
-]
-
 [[package]]
 name = "prettyplease"
 version = "0.2.37"
@@ -3802,7 +4104,7 @@ version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
 dependencies = [
- "toml_edit 0.25.12+spec-1.1.0",
+ "toml_edit 0.25.11+spec-1.1.0",
 ]

 [[package]]
@@ -3850,10 +4152,29 @@ dependencies = [
 ]

 [[package]]
-name = "prost"
-version = "0.14.4"
+name = "profiling"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
+checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
+dependencies = [
+ "profiling-procmacros",
+]
+
+[[package]]
+name = "profiling-procmacros"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
 dependencies = [
  "bytes",
  "prost-derive",
@@ -3861,9 +4182,9 @@ dependencies = [

 [[package]]
 name = "prost-derive"
-version = "0.14.4"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
+checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
 dependencies = [
  "anyhow",
  "itertools 0.14.0",
@@ -3874,18 +4195,18 @@ dependencies = [

 [[package]]
 name = "prost-types"
-version = "0.14.4"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a"
+checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
 dependencies = [
  "prost",
 ]

 [[package]]
 name = "pulldown-cmark"
-version = "0.13.4"
+version = "0.13.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
+checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad"
 dependencies = [
  "bitflags",
  "memchr",
@@ -3901,9 +4222,18 @@ checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"

 [[package]]
 name = "pxfm"
-version = "0.1.29"
+version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
+checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d"
+
+[[package]]
+name = "qoi"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
+dependencies = [
+ "bytemuck",
+]

 [[package]]
 name = "quick-error"
@@ -3926,7 +4256,7 @@ dependencies = [
  "rustc-hash",
  "rustls",
  "socket2",
- "thiserror",
+ "thiserror 2.0.18",
  "tokio",
  "tracing",
  "web-time",
@@ -3942,13 +4272,13 @@ dependencies = [
  "bytes",
  "getrandom 0.3.4",
  "lru-slab",
- "rand 0.9.4",
+ "rand 0.9.3",
  "ring",
  "rustc-hash",
  "rustls",
  "rustls-pki-types",
  "slab",
- "thiserror",
+ "thiserror 2.0.18",
  "tinyvec",
  "tracing",
  "web-time",
@@ -3970,9 +4300,9 @@ dependencies = [

 [[package]]
 name = "quote"
-version = "1.0.46"
+version = "1.0.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
 dependencies = [
  "proc-macro2",
 ]
@@ -3997,18 +4327,18 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"

 [[package]]
 name = "rand"
-version = "0.8.6"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "rand_core 0.6.4",
 ]

 [[package]]
 name = "rand"
-version = "0.9.4"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
+checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166"
 dependencies = [
  "rand_chacha",
  "rand_core 0.9.5",
@@ -4022,7 +4352,7 @@ checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
 dependencies = [
  "chacha20",
  "getrandom 0.4.2",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
 ]

 [[package]]
@@ -4055,9 +4385,79 @@ dependencies = [

 [[package]]
 name = "rand_core"
-version = "0.10.1"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
+
+[[package]]
+name = "rav1e"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b"
+dependencies = [
+ "aligned-vec",
+ "arbitrary",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "av-scenechange",
+ "av1-grain",
+ "bitstream-io",
+ "built",
+ "cfg-if",
+ "interpolate_name",
+ "itertools 0.14.0",
+ "libc",
+ "libfuzzer-sys",
+ "log",
+ "maybe-rayon",
+ "new_debug_unreachable",
+ "noop_proc_macro",
+ "num-derive",
+ "num-traits",
+ "paste",
+ "profiling",
+ "rand 0.9.3",
+ "rand_chacha",
+ "simd_helpers",
+ "thiserror 2.0.18",
+ "v_frame",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ravif"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45"
+dependencies = [
+ "avif-serialize",
+ "imgref",
+ "loop9",
+ "quick-error",
+ "rav1e",
+ "rayon",
+ "rgb",
+]
+
+[[package]]
+name = "rayon"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]

 [[package]]
 name = "recaptcha-verify"
@@ -4081,9 +4481,9 @@ dependencies = [

 [[package]]
 name = "regex"
-version = "1.12.4"
+version = "1.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -4104,52 +4504,15 @@ dependencies = [

 [[package]]
 name = "regex-syntax"
-version = "0.8.11"
+version = "0.8.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"

 [[package]]
 name = "reqwest"
 version = "0.12.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-core",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-util",
- "js-sys",
- "log",
- "percent-encoding",
- "pin-project-lite",
- "rustls",
- "rustls-native-certs",
- "rustls-pki-types",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "tokio",
- "tokio-rustls",
- "tower",
- "tower-http 0.6.11",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.13.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
 dependencies = [
  "base64 0.22.1",
  "bytes",
@@ -4173,6 +4536,47 @@ dependencies = [
  "pin-project-lite",
  "quinn",
  "rustls",
+ "rustls-native-certs",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tokio-rustls",
+ "tokio-util",
+ "tower",
+ "tower-http",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+ "webpki-roots",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-rustls",
+ "hyper-util",
+ "js-sys",
+ "log",
+ "percent-encoding",
+ "pin-project-lite",
+ "quinn",
+ "rustls",
  "rustls-pki-types",
  "rustls-platform-verifier",
  "serde",
@@ -4180,14 +4584,12 @@ dependencies = [
  "sync_wrapper",
  "tokio",
  "tokio-rustls",
- "tokio-util",
  "tower",
- "tower-http 0.6.11",
+ "tower-http",
  "tower-service",
  "url",
  "wasm-bindgen",
  "wasm-bindgen-futures",
- "wasm-streams",
  "web-sys",
 ]

@@ -4197,6 +4599,25 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"

+[[package]]
+name = "resolvematrix"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52dfcc6f56a81348db1fc6591356cfea9dc840408c75553b2fe225f86de43274"
+dependencies = [
+ "hickory-resolver",
+ "reqwest 0.13.2",
+ "serde",
+ "thiserror 2.0.18",
+ "tracing",
+]
+
+[[package]]
+name = "rgb"
+version = "0.8.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
+
 [[package]]
 name = "ring"
 version = "0.17.14"
@@ -4213,27 +4634,31 @@ dependencies = [

 [[package]]
 name = "ruma"
-version = "0.15.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.10.1"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "assign",
+ "continuwuity-admin-api",
+ "draupnir-antispam",
  "js_int",
  "js_option",
+ "meowlnir-antispam",
  "ruma-appservice-api",
  "ruma-client-api",
  "ruma-common",
  "ruma-events",
  "ruma-federation-api",
+ "ruma-identifiers-validation",
+ "ruma-identity-service-api",
  "ruma-push-gateway-api",
  "ruma-signatures",
- "ruma-state-res",
  "web-time",
 ]

 [[package]]
 name = "ruma-appservice-api"
-version = "0.15.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.10.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -4244,12 +4669,13 @@ dependencies = [

 [[package]]
 name = "ruma-client-api"
-version = "0.23.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.18.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "assign",
  "bytes",
+ "date_header",
  "http",
  "js_int",
  "js_option",
@@ -4259,22 +4685,21 @@ dependencies = [
  "serde",
  "serde_html_form",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "url",
  "web-time",
 ]

 [[package]]
 name = "ruma-common"
-version = "0.18.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.13.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "base64 0.22.1",
  "bytes",
- "date_header",
  "form_urlencoded",
- "getrandom 0.4.2",
+ "getrandom 0.2.17",
  "http",
  "indexmap",
  "js_int",
@@ -4287,41 +4712,45 @@ dependencies = [
  "serde",
  "serde_html_form",
  "serde_json",
- "thiserror",
+ "smallvec",
+ "thiserror 2.0.18",
  "time",
  "tracing",
  "url",
  "uuid",
  "web-time",
  "wildmatch",
- "zeroize",
 ]

 [[package]]
 name = "ruma-events"
-version = "0.33.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.28.1"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "indexmap",
  "js_int",
  "js_option",
+ "percent-encoding",
  "pulldown-cmark",
+ "regex",
  "ruma-common",
+ "ruma-identifiers-validation",
  "ruma-macros",
  "serde",
  "serde_json",
- "thiserror",
+ "smallvec",
+ "thiserror 2.0.18",
  "tracing",
+ "url",
  "web-time",
  "wildmatch",
- "zeroize",
 ]

 [[package]]
 name = "ruma-federation-api"
-version = "0.14.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "bytes",
  "headers",
@@ -4334,28 +4763,36 @@ dependencies = [
  "rand 0.10.1",
  "ruma-common",
  "ruma-events",
- "ruma-signatures",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "tracing",
 ]

 [[package]]
 name = "ruma-identifiers-validation"
-version = "0.12.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.5"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
- "thiserror",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "ruma-identity-service-api"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "js_int",
+ "ruma-common",
+ "serde",
 ]

 [[package]]
 name = "ruma-macros"
-version = "0.18.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.13.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
- "as_variant",
  "cfg-if",
  "proc-macro-crate",
  "proc-macro2",
@@ -4363,13 +4800,13 @@ dependencies = [
  "ruma-identifiers-validation",
  "serde",
  "syn",
- "toml 1.1.2+spec-1.1.0",
+ "toml 0.8.23",
 ]

 [[package]]
 name = "ruma-push-gateway-api"
-version = "0.14.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -4380,50 +4817,25 @@ dependencies = [

 [[package]]
 name = "ruma-signatures"
-version = "0.20.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.15.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "base64 0.22.1",
  "ed25519-dalek",
- "memchr",
  "pkcs8",
  "rand 0.10.1",
+ "rand_core 0.6.4",
  "ruma-common",
  "serde_json",
- "sha2 0.10.9",
- "thiserror",
-]
-
-[[package]]
-name = "ruma-state-res"
-version = "0.16.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
-dependencies = [
- "js_int",
- "ruma-common",
- "ruma-events",
- "ruma-signatures",
- "serde",
- "serde_json",
- "thiserror",
- "tracing",
-]
-
-[[package]]
-name = "ruminuwuity"
-version = "26.6.0-alpha.1"
-dependencies = [
- "assign",
- "ruma",
- "serde",
- "serde_json",
- "wildmatch",
+ "sha2",
+ "subslice",
+ "thiserror 2.0.18",
 ]

 [[package]]
 name = "rust-librocksdb-sys"
-version = "0.45.1+11.1.1"
-source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=0a25ff92f7c09b55eec496b9c192c7d5136ab2b8#0a25ff92f7c09b55eec496b9c192c7d5136ab2b8"
+version = "0.42.0+10.10.1"
+source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9#31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9"
 dependencies = [
  "bindgen",
  "bzip2-sys",
@@ -4439,8 +4851,8 @@ dependencies = [

 [[package]]
 name = "rust-rocksdb"
-version = "0.49.1"
-source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=0a25ff92f7c09b55eec496b9c192c7d5136ab2b8#0a25ff92f7c09b55eec496b9c192c7d5136ab2b8"
+version = "0.46.0"
+source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9#31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9"
 dependencies = [
  "libc",
  "parking_lot",
@@ -4468,6 +4880,15 @@ dependencies = [
  "semver",
 ]

+[[package]]
+name = "rusticata-macros"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
+dependencies = [
+ "nom 7.1.3",
+]
+
 [[package]]
 name = "rustix"
 version = "1.1.4"
@@ -4483,9 +4904,9 @@ dependencies = [

 [[package]]
 name = "rustls"
-version = "0.23.41"
+version = "0.23.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
+checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
 dependencies = [
  "aws-lc-rs",
  "log",
@@ -4499,9 +4920,9 @@ dependencies = [

 [[package]]
 name = "rustls-native-certs"
-version = "0.8.4"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
+checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
 dependencies = [
  "openssl-probe",
  "rustls-pki-types",
@@ -4510,10 +4931,19 @@ dependencies = [
 ]

 [[package]]
-name = "rustls-pki-types"
-version = "1.14.1"
+name = "rustls-pemfile"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
 dependencies = [
  "web-time",
  "zeroize",
@@ -4521,11 +4951,11 @@ dependencies = [

 [[package]]
 name = "rustls-platform-verifier"
-version = "0.7.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
+checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
 dependencies = [
- "core-foundation 0.10.1",
+ "core-foundation",
  "core-foundation-sys",
  "jni",
  "log",
@@ -4548,9 +4978,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"

 [[package]]
 name = "rustls-webpki"
-version = "0.103.13"
+version = "0.103.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
+checksum = "20a6af516fea4b20eccceaf166e8aa666ac996208e8a644ce3ef5aa783bc7cd4"
 dependencies = [
  "aws-lc-rs",
  "ring",
@@ -4574,7 +5004,7 @@ dependencies = [
  "futures-util",
  "pin-project",
  "thingbuf",
- "thiserror",
+ "thiserror 2.0.18",
  "unicode-segmentation",
 ]

@@ -4602,6 +5032,17 @@ dependencies = [
  "regex",
 ]

+[[package]]
+name = "saphyr-parser-bw"
+version = "0.0.611"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67dec0c833db75dc98957956b303fe447ffc5eb13f2325ef4c2350f7f3aa69e3"
+dependencies = [
+ "arraydeque",
+ "smallvec",
+ "thiserror 2.0.18",
+]
+
 [[package]]
 name = "schannel"
 version = "0.1.29"
@@ -4619,9 +5060,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"

 [[package]]
 name = "sd-notify"
-version = "0.5.0"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e4ef7359e694bfaf1dd27a30f9d760b54c00dfae9f19bd0c05a39bc9128fe76"
+checksum = "b943eadf71d8b69e661330cb0e2656e31040acf21ee7708e2c238a0ec6af2bf4"
 dependencies = [
  "libc",
 ]
@@ -4633,7 +5074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
 dependencies = [
  "bitflags",
- "core-foundation 0.10.1",
+ "core-foundation",
  "core-foundation-sys",
  "libc",
  "security-framework-sys",
@@ -4661,13 +5102,14 @@ dependencies = [

 [[package]]
 name = "sentry"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1975064d9f3d9d87a7c8f0371f7fac10d876906ca3e39faad72e61c263ff9b87"
+checksum = "d92d893ba7469d361a6958522fa440e4e2bc8bf4c5803cd1bf40b9af63f8f9a8"
 dependencies = [
  "cfg_aliases",
  "httpdate",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
+ "rustls",
  "sentry-backtrace",
  "sentry-contexts",
  "sentry-core",
@@ -4677,13 +5119,14 @@ dependencies = [
  "sentry-tower",
  "sentry-tracing",
  "tokio",
+ "ureq",
 ]

 [[package]]
 name = "sentry-backtrace"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "134f552b6b147f77aeee46ece875d67a8bfc1d56fe3860d78446ed4c25bb5f9f"
+checksum = "5f8784d0a27b5cd4b5f75769ffc84f0b7580e3c35e1af9cd83cb90b612d769cc"
 dependencies = [
  "backtrace",
  "regex",
@@ -4692,9 +5135,9 @@ dependencies = [

 [[package]]
 name = "sentry-contexts"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98482b938fb1f31ecd23506fb7f08b2ba20d60b9cc72581b1205a9acd31d32fa"
+checksum = "0e5eb42f4cd4f9fdfec9e3b07b25a4c9769df83d218a7e846658984d5948ad3e"
 dependencies = [
  "hostname",
  "libc",
@@ -4706,11 +5149,11 @@ dependencies = [

 [[package]]
 name = "sentry-core"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cff96247f4dc36867511d108709e703eb354143e7893319d763d2dd1edb4f48"
+checksum = "b0b1e7ca40f965db239da279bf278d87b7407469b98835f27f0c8e59ed189b06"
 dependencies = [
- "rand 0.9.4",
+ "rand 0.9.3",
  "sentry-types",
  "serde",
  "serde_json",
@@ -4719,9 +5162,9 @@ dependencies = [

 [[package]]
 name = "sentry-debug-images"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b603a51b083141062a142d73e36391b14244b4bd0bfe28bcd80e8327bb1d7698"
+checksum = "002561e49ea3a9de316e2efadc40fae553921b8ff41448f02ea85fd135a778d6"
 dependencies = [
  "findshlibs",
  "sentry-core",
@@ -4729,9 +5172,9 @@ dependencies = [

 [[package]]
 name = "sentry-log"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74df4d09a38fd59da258269ffd7f344bd308470117d68eda5a95b4fbd65683d0"
+checksum = "e200860daf76e09f9ad111bce25928f96bedbb84bc5934b37f05bb445727c70e"
 dependencies = [
  "bitflags",
  "log",
@@ -4740,9 +5183,9 @@ dependencies = [

 [[package]]
 name = "sentry-panic"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61de3f4a1fc77d4c57e8bacd8ef064c26aaa88ea5b2541a761d37c7c3703b9a9"
+checksum = "8906f8be87aea5ac7ef937323fb655d66607427f61007b99b7cb3504dc5a156c"
 dependencies = [
  "sentry-backtrace",
  "sentry-core",
@@ -4750,9 +5193,9 @@ dependencies = [

 [[package]]
 name = "sentry-tower"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d5cb61301e328cbd42d2fede094aca746674b359fcd9c44691f027820e8fe59"
+checksum = "56aebe376310840b49dad4cca55c7b32d9abdc14946cd071d4158ecb149b63a4"
 dependencies = [
  "http",
  "pin-project",
@@ -4764,9 +5207,9 @@ dependencies = [

 [[package]]
 name = "sentry-tracing"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc59b27dae3bb495e37e6d62d252214840a2e7e1875531ee9fa2953df8985537"
+checksum = "5b07eefe04486316c57aba08ab53dd44753c25102d1d3fe05775cc93a13262d9"
 dependencies = [
  "bitflags",
  "sentry-backtrace",
@@ -4777,16 +5220,16 @@ dependencies = [

 [[package]]
 name = "sentry-types"
-version = "0.48.3"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d7e78132ccfb4a1c777b959fb2944d1f6d5145bffe6be2a98ee6b25d244f72c"
+checksum = "567711f01f86a842057e1fc17779eba33a336004227e1a1e7e6cc2599e22e259"
 dependencies = [
  "debugid",
  "hex",
- "rand 0.9.4",
+ "rand 0.9.3",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "time",
  "url",
  "uuid",
@@ -4804,19 +5247,20 @@ dependencies = [

 [[package]]
 name = "serde-saphyr"
-version = "0.0.28"
+version = "0.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a15e3bc297370dc9c526bcf0986f29167a9286cfaad404f2f572b3074dabe5ec"
+checksum = "09fbdfe7a27a1b1633dfc0c4c8e65940b8d819c5ddb9cca48ebc3223b00c8b14"
 dependencies = [
  "ahash",
  "annotate-snippets",
  "base64 0.22.1",
  "encoding_rs_io",
  "getrandom 0.3.4",
- "granit-parser",
  "nohash-hasher",
  "num-traits",
- "serde_core",
+ "regex",
+ "saphyr-parser-bw",
+ "serde",
  "smallvec",
  "zmij",
 ]
@@ -4843,9 +5287,9 @@ dependencies = [

 [[package]]
 name = "serde_html_form"
-version = "0.4.0"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0946d52b4b7e28823148aebbeceb901012c595ad737920d504fa8634bb099e6f"
+checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f"
 dependencies = [
  "form_urlencoded",
  "indexmap",
@@ -4856,9 +5300,9 @@ dependencies = [

 [[package]]
 name = "serde_json"
-version = "1.0.150"
+version = "1.0.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
 dependencies = [
  "itoa",
  "memchr",
@@ -4880,9 +5324,9 @@ dependencies = [

 [[package]]
 name = "serde_regex"
-version = "1.2.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bafc8d0c5330cecff10f16b459b479fd9acaa5b4acd7167301414e21b0057012"
+checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf"
 dependencies = [
  "regex",
  "serde",
@@ -4926,18 +5370,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
- "digest 0.10.7",
-]
-
-[[package]]
-name = "sha1"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.3.0",
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -4948,18 +5381,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
- "digest 0.10.7",
-]
-
-[[package]]
-name = "sha2"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.3.0",
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -4971,7 +5393,7 @@ dependencies = [
  "async-trait",
  "bytes",
  "hex",
- "sha2 0.10.9",
+ "sha2",
  "tokio",
 ]

@@ -4990,12 +5412,6 @@ version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"

-[[package]]
-name = "shlex"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
-
 [[package]]
 name = "signal-hook"
 version = "0.3.18"
@@ -5043,26 +5459,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"

 [[package]]
-name = "simd_cesu8"
-version = "1.1.1"
+name = "simd_helpers"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
+checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
 dependencies = [
- "rustc_version",
- "simdutf8",
+ "quote",
 ]

-[[package]]
-name = "simdutf8"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
-
 [[package]]
 name = "siphasher"
-version = "1.0.3"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"

 [[package]]
 name = "slab"
@@ -5082,18 +5491,18 @@ dependencies = [

 [[package]]
 name = "smallvec"
-version = "1.15.2"
+version = "1.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
 dependencies = [
  "serde",
 ]

 [[package]]
 name = "socket2"
-version = "0.6.4"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
+checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
 dependencies = [
  "libc",
  "windows-sys 0.61.2",
@@ -5161,6 +5570,15 @@ version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"

+[[package]]
+name = "subslice"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a8e4809a3bb02de01f1f7faf1ba01a83af9e8eabcd4d31dd6e413d14d56aae"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "subtle"
 version = "2.6.1"
@@ -5169,9 +5587,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"

 [[package]]
 name = "syn"
-version = "2.0.118"
+version = "2.0.117"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5198,27 +5616,6 @@ dependencies = [
  "syn",
 ]

-[[package]]
-name = "system-configuration"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
-dependencies = [
- "bitflags",
- "core-foundation 0.9.4",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "tagptr"
 version = "0.2.0"
@@ -5248,7 +5645,7 @@ dependencies = [
  "lazy-regex",
  "minimad",
  "serde",
- "thiserror",
+ "thiserror 2.0.18",
  "unicode-width 0.1.14",
 ]

@@ -5262,13 +5659,33 @@ dependencies = [
  "pin-project",
 ]

+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
 [[package]]
 name = "thiserror"
 version = "2.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
 dependencies = [
- "thiserror-impl",
+ "thiserror-impl 2.0.18",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]

 [[package]]
@@ -5291,6 +5708,20 @@ dependencies = [
  "cfg-if",
 ]

+[[package]]
+name = "tiff"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"
+dependencies = [
+ "fax",
+ "flate2",
+ "half",
+ "quick-error",
+ "weezl",
+ "zune-jpeg",
+]
+
 [[package]]
 name = "tikv-jemalloc-ctl"
 version = "0.6.1"
@@ -5321,11 +5752,12 @@ dependencies = [

 [[package]]
 name = "time"
-version = "0.3.49"
+version = "0.3.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
 dependencies = [
  "deranged",
+ "itoa",
  "num-conv",
  "powerfmt",
  "serde_core",
@@ -5335,15 +5767,15 @@ dependencies = [

 [[package]]
 name = "time-core"
-version = "0.1.9"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"

 [[package]]
 name = "time-macros"
-version = "0.2.29"
+version = "0.2.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
 dependencies = [
  "num-conv",
  "time-core",
@@ -5376,9 +5808,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"

 [[package]]
 name = "tokio"
-version = "1.52.3"
+version = "1.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c"
 dependencies = [
  "bytes",
  "libc",
@@ -5404,9 +5836,9 @@ dependencies = [

 [[package]]
 name = "tokio-metrics"
-version = "0.5.0"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9e81d53caf955549b1dec7af4ac2149e94cc25ed97b4a545151140281e2f528"
+checksum = "0e0410015c6db7b67b9c9ab2a3af4d74a942d637ff248d0d055073750deac6f9"
 dependencies = [
  "futures-util",
  "pin-project-lite",
@@ -5462,17 +5894,17 @@ dependencies = [

 [[package]]
 name = "toml"
-version = "1.1.2+spec-1.1.0"
+version = "0.9.12+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
+checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
 dependencies = [
  "indexmap",
  "serde_core",
  "serde_spanned 1.1.1",
- "toml_datetime 1.1.1+spec-1.1.0",
+ "toml_datetime 0.7.5+spec-1.1.0",
  "toml_parser",
  "toml_writer",
- "winnow 1.0.3",
+ "winnow 0.7.15",
 ]

 [[package]]
@@ -5484,6 +5916,15 @@ dependencies = [
  "serde",
 ]

+[[package]]
+name = "toml_datetime"
+version = "0.7.5+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
+dependencies = [
+ "serde_core",
+]
+
 [[package]]
 name = "toml_datetime"
 version = "1.1.1+spec-1.1.0"
@@ -5509,14 +5950,14 @@ dependencies = [

 [[package]]
 name = "toml_edit"
-version = "0.25.12+spec-1.1.0"
+version = "0.25.11+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7"
+checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b"
 dependencies = [
  "indexmap",
  "toml_datetime 1.1.1+spec-1.1.0",
  "toml_parser",
- "winnow 1.0.3",
+ "winnow 1.0.1",
 ]

 [[package]]
@@ -5525,7 +5966,7 @@ version = "1.1.2+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
 dependencies = [
- "winnow 1.0.3",
+ "winnow 1.0.1",
 ]

 [[package]]
@@ -5542,9 +5983,9 @@ checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"

 [[package]]
 name = "tonic"
-version = "0.14.6"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
+checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
 dependencies = [
  "async-trait",
  "axum",
@@ -5571,26 +6012,15 @@ dependencies = [

 [[package]]
 name = "tonic-prost"
-version = "0.14.6"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
+checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
 dependencies = [
  "bytes",
  "prost",
  "tonic",
 ]

-[[package]]
-name = "tonic-types"
-version = "0.14.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8"
-dependencies = [
- "prost",
- "prost-types",
- "tonic",
-]
-
 [[package]]
 name = "tower"
 version = "0.5.3"
@@ -5610,27 +6040,11 @@ dependencies = [
  "tracing",
 ]

-[[package]]
-name = "tower-cookies"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "151b5a3e3c45df17466454bb74e9ecedecc955269bdedbf4d150dfa393b55a36"
-dependencies = [
- "axum-core",
- "cookie",
- "futures-util",
- "http",
- "parking_lot",
- "pin-project-lite",
- "tower-layer",
- "tower-service",
-]
-
 [[package]]
 name = "tower-http"
-version = "0.6.11"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
+checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
 dependencies = [
  "async-compression",
  "bitflags",
@@ -5640,30 +6054,7 @@ dependencies = [
  "http",
  "http-body",
  "http-body-util",
- "pin-project-lite",
- "tokio",
- "tokio-util",
- "tower",
- "tower-layer",
- "tower-service",
- "url",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233"
-dependencies = [
- "async-compression",
- "bitflags",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "percent-encoding",
+ "iri-string",
  "pin-project-lite",
  "tokio",
  "tokio-util",
@@ -5697,44 +6088,6 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"

-[[package]]
-name = "tower-sessions"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "518dca34b74a17cadfcee06e616a09d2bd0c3984eff1769e1e76d58df978fc78"
-dependencies = [
- "async-trait",
- "http",
- "time",
- "tokio",
- "tower-cookies",
- "tower-layer",
- "tower-service",
- "tower-sessions-core",
- "tracing",
-]
-
-[[package]]
-name = "tower-sessions-core"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "568531ec3dfcf3ffe493de1958ae5662a0284ac5d767476ecdb6a34ff8c6b06c"
-dependencies = [
- "async-trait",
- "axum-core",
- "base64 0.22.1",
- "futures",
- "http",
- "parking_lot",
- "rand 0.9.4",
- "serde",
- "serde_json",
- "thiserror",
- "time",
- "tokio",
- "tracing",
-]
-
 [[package]]
 name = "tracing"
 version = "0.1.44"
@@ -5803,9 +6156,9 @@ dependencies = [

 [[package]]
 name = "tracing-opentelemetry"
-version = "0.33.0"
+version = "0.32.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26"
+checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc"
 dependencies = [
  "js-sys",
  "opentelemetry",
@@ -5843,15 +6196,24 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"

 [[package]]
 name = "typenum"
-version = "1.20.1"
+version = "1.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"

 [[package]]
 name = "typewit"
-version = "1.15.2"
+version = "1.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "214ca0b2191785cbc06209b9ca1861e048e39b5ba33574b3cedd58363d5bb5f6"
+checksum = "bc19094686c694eb41b3b99dcc2f2975d4b078512fa22ae6c63f7ca318bdcff7"
+dependencies = [
+ "typewit_proc_macros",
+]
+
+[[package]]
+name = "typewit_proc_macros"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6"

 [[package]]
 name = "uname"
@@ -5885,9 +6247,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"

 [[package]]
 name = "unicode-segmentation"
-version = "1.13.3"
+version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
+checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"

 [[package]]
 name = "unicode-width"
@@ -5913,6 +6275,34 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"

+[[package]]
+name = "ureq"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0"
+dependencies = [
+ "base64 0.22.1",
+ "log",
+ "percent-encoding",
+ "rustls",
+ "rustls-pki-types",
+ "ureq-proto",
+ "utf8-zero",
+ "webpki-roots",
+]
+
+[[package]]
+name = "ureq-proto"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c"
+dependencies = [
+ "base64 0.22.1",
+ "http",
+ "httparse",
+ "log",
+]
+
 [[package]]
 name = "url"
 version = "2.5.8"
@@ -5938,6 +6328,12 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"

+[[package]]
+name = "utf8-zero"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
+
 [[package]]
 name = "utf8_iter"
 version = "1.0.4"
@@ -5946,9 +6342,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"

 [[package]]
 name = "uuid"
-version = "1.23.3"
+version = "1.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
+checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
 dependencies = [
  "getrandom 0.4.2",
  "js-sys",
@@ -5956,6 +6352,17 @@ dependencies = [
  "wasm-bindgen",
 ]

+[[package]]
+name = "v_frame"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
+dependencies = [
+ "aligned-vec",
+ "num-traits",
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "validator"
 version = "0.20.0"
@@ -6031,11 +6438,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"

 [[package]]
 name = "wasip2"
-version = "1.0.4+wasi-0.2.12"
+version = "1.0.2+wasi-0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
 dependencies = [
- "wit-bindgen 0.57.1",
+ "wit-bindgen",
 ]

 [[package]]
@@ -6044,14 +6451,14 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
 dependencies = [
- "wit-bindgen 0.51.0",
+ "wit-bindgen",
 ]

 [[package]]
 name = "wasm-bindgen"
-version = "0.2.125"
+version = "0.2.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
+checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -6062,9 +6469,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.75"
+version = "0.4.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
+checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -6072,9 +6479,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.125"
+version = "0.2.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
+checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -6082,9 +6489,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.125"
+version = "0.2.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
+checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
 dependencies = [
  "bumpalo",
  "proc-macro2",
@@ -6095,9 +6502,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.125"
+version = "0.2.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
+checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
 dependencies = [
  "unicode-ident",
 ]
@@ -6126,9 +6533,9 @@ dependencies = [

 [[package]]
 name = "wasm-streams"
-version = "0.5.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
+checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
 dependencies = [
  "futures-util",
  "js-sys",
@@ -6151,9 +6558,9 @@ dependencies = [

 [[package]]
 name = "web-sys"
-version = "0.3.102"
+version = "0.3.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
+checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -6183,9 +6590,18 @@ dependencies = [

 [[package]]
 name = "webpki-root-certs"
-version = "1.0.7"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c"
+checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
 dependencies = [
  "rustls-pki-types",
 ]
@@ -6274,6 +6690,15 @@ dependencies = [
  "windows-link",
 ]

+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
 [[package]]
 name = "windows-sys"
 version = "0.52.0"
@@ -6301,6 +6726,21 @@ dependencies = [
  "windows-link",
 ]

+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.52.6"
@@ -6334,6 +6774,12 @@ dependencies = [
  "windows_x86_64_msvc 0.53.1",
 ]

+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.52.6"
@@ -6346,6 +6792,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"

+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
@@ -6358,6 +6810,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"

+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
@@ -6382,6 +6840,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"

+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
@@ -6394,6 +6858,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"

+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
@@ -6406,6 +6876,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"

+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
@@ -6418,6 +6894,12 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"

+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
@@ -6441,9 +6923,9 @@ dependencies = [

 [[package]]
 name = "winnow"
-version = "1.0.3"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
+checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5"
 dependencies = [
  "memchr",
 ]
@@ -6457,12 +6939,6 @@ dependencies = [
  "wit-bindgen-rust-macro",
 ]

-[[package]]
-name = "wit-bindgen"
-version = "0.57.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
-
 [[package]]
 name = "wit-bindgen-core"
 version = "0.51.0"
@@ -6548,6 +7024,23 @@ version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"

+[[package]]
+name = "x509-parser"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202"
+dependencies = [
+ "asn1-rs",
+ "data-encoding",
+ "der-parser",
+ "lazy_static",
+ "nom 7.1.3",
+ "oid-registry",
+ "rusticata-macros",
+ "thiserror 2.0.18",
+ "time",
+]
+
 [[package]]
 name = "xml5ever"
 version = "0.18.1"
@@ -6561,7 +7054,7 @@ dependencies = [

 [[package]]
 name = "xtask"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
  "cargo_metadata",
@@ -6570,6 +7063,12 @@ dependencies = [
  "conduwuit_admin",
 ]

+[[package]]
+name = "y4m"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448"
+
 [[package]]
 name = "yansi"
 version = "1.0.1"
@@ -6578,9 +7077,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"

 [[package]]
 name = "yoke"
-version = "0.8.3"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
+checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
 dependencies = [
  "stable_deref_trait",
  "yoke-derive",
@@ -6601,18 +7100,18 @@ dependencies = [

 [[package]]
 name = "zerocopy"
-version = "0.8.52"
+version = "0.8.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
+checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
 dependencies = [
  "zerocopy-derive",
 ]

 [[package]]
 name = "zerocopy-derive"
-version = "0.8.52"
+version = "0.8.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
+checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6621,9 +7120,9 @@ dependencies = [

 [[package]]
 name = "zerofrom"
-version = "0.1.8"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
+checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
 dependencies = [
  "zerofrom-derive",
 ]
@@ -6642,9 +7141,9 @@ dependencies = [

 [[package]]
 name = "zeroize"
-version = "1.9.0"
+version = "1.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"

 [[package]]
 name = "zerotrie"
@@ -6719,6 +7218,15 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"

+[[package]]
+name = "zune-inflate"
+version = "0.2.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
+dependencies = [
+ "simd-adler32",
+]
+
 [[package]]
 name = "zune-jpeg"
 version = "0.5.15"
2026-07-03 10:59:11 +02:00
a66267b495
chore: Add news fragment 2026-07-03 10:59:11 +02:00
3dbe6a5817
fix: Make clippy not be angry 2026-07-03 10:59:11 +02:00
b5cd069d85
refactor: Rewrite resolver with resolvematrix
diff --git c/Cargo.lock i/Cargo.lock
index 081dc19e7..5b6b6fe4e 100644
--- c/Cargo.lock
+++ i/Cargo.lock
@@ -39,6 +39,24 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "aligned"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685"
+dependencies = [
+ "as-slice",
+]
+
+[[package]]
+name = "aligned-vec"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
+dependencies = [
+ "equator",
+]
+
 [[package]]
 name = "alloc-no-stdlib"
 version = "2.0.4"
@@ -47,9 +65,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"

 [[package]]
 name = "alloc-stdlib"
-version = "0.2.4"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
 dependencies = [
  "alloc-no-stdlib",
 ]
@@ -71,9 +89,9 @@ dependencies = [

 [[package]]
 name = "annotate-snippets"
-version = "0.12.16"
+version = "0.12.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1"
+checksum = "74fc7650eedcb2fee505aad48491529e408f0e854c2d9f63eb86c1361b9b3f93"
 dependencies = [
  "anstyle",
  "memchr",
@@ -102,14 +120,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"

 [[package]]
-name = "arc-swap"
-version = "1.9.1"
+name = "ar_archive_writer"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207"
+checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b"
+dependencies = [
+ "object",
+]
+
+[[package]]
+name = "arbitrary"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
+
+[[package]]
+name = "arc-swap"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5"
 dependencies = [
  "rustversion",
 ]

+[[package]]
+name = "arg_enum_proc_macro"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "argon2"
 version = "0.5.3"
@@ -137,6 +181,15 @@ dependencies = [
  "serde",
 ]

+[[package]]
+name = "as-slice"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
+dependencies = [
+ "stable_deref_trait",
+]
+
 [[package]]
 name = "as_variant"
 version = "1.3.0"
@@ -145,9 +198,9 @@ checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a"

 [[package]]
 name = "askama"
-version = "0.16.0"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc"
+checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57"
 dependencies = [
  "askama_macros",
  "itoa",
@@ -158,13 +211,12 @@ dependencies = [

 [[package]]
 name = "askama_derive"
-version = "0.16.0"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738"
+checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37"
 dependencies = [
  "askama_parser",
  "basic-toml",
- "glob",
  "memchr",
  "proc-macro2",
  "quote",
@@ -176,24 +228,63 @@ dependencies = [

 [[package]]
 name = "askama_macros"
-version = "0.16.0"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a"
+checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b"
 dependencies = [
  "askama_derive",
 ]

 [[package]]
 name = "askama_parser"
-version = "0.16.0"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da"
+checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c"
 dependencies = [
  "rustc-hash",
  "serde",
  "serde_derive",
  "unicode-ident",
- "winnow 1.0.3",
+ "winnow 0.7.15",
+]
+
+[[package]]
+name = "asn1-rs"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60"
+dependencies = [
+ "asn1-rs-derive",
+ "asn1-rs-impl",
+ "displaydoc",
+ "nom 7.1.3",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror 2.0.18",
+ "time",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]

 [[package]]
@@ -215,9 +306,9 @@ dependencies = [

 [[package]]
 name = "async-compression"
-version = "0.4.42"
+version = "0.4.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac"
+checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1"
 dependencies = [
  "compression-codecs",
  "compression-core",
@@ -253,15 +344,58 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"

 [[package]]
 name = "autocfg"
-version = "1.5.1"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "av-scenechange"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394"
+dependencies = [
+ "aligned",
+ "anyhow",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "log",
+ "num-rational",
+ "num-traits",
+ "pastey",
+ "rayon",
+ "thiserror 2.0.18",
+ "v_frame",
+ "y4m",
+]
+
+[[package]]
+name = "av1-grain"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8"
+dependencies = [
+ "anyhow",
+ "arrayvec",
+ "log",
+ "nom 8.0.0",
+ "num-rational",
+ "v_frame",
+]
+
+[[package]]
+name = "avif-serialize"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d"
+dependencies = [
+ "arrayvec",
+]

 [[package]]
 name = "aws-lc-rs"
-version = "1.17.0"
+version = "1.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00"
+checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf"
 dependencies = [
  "aws-lc-sys",
  "zeroize",
@@ -269,9 +403,9 @@ dependencies = [

 [[package]]
 name = "aws-lc-sys"
-version = "0.41.0"
+version = "0.38.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4"
+checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e"
 dependencies = [
  "cc",
  "cmake",
@@ -281,9 +415,9 @@ dependencies = [

 [[package]]
 name = "axum"
-version = "0.8.9"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
+checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
 dependencies = [
  "axum-core",
  "bytes",
@@ -314,12 +448,12 @@ dependencies = [

 [[package]]
 name = "axum-client-ip"
-version = "1.3.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8ba1af5b620232acf37f2eb6d22151ea465491e0b4c25f552d1990f64ec5a67"
+checksum = "dff8ee1869817523c8f91c20bf17fd932707f66c2e7e0b0f811b29a227289562"
 dependencies = [
  "axum",
- "client-ip",
+ "forwarded-header-value",
  "serde",
 ]

@@ -344,9 +478,9 @@ dependencies = [

 [[package]]
 name = "axum-extra"
-version = "0.12.6"
+version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be44683b41ccb9ab2d23a5230015c9c3c55be97a25e4428366de8873103f7970"
+checksum = "fef252edff26ddba56bbcdf2ee3307b8129acb86f5749b68990c168a6fcc9c76"
 dependencies = [
  "axum",
  "axum-core",
@@ -367,13 +501,12 @@ dependencies = [

 [[package]]
 name = "axum-server"
-version = "0.8.0"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1df331683d982a0b9492b38127151e6453639cd34926eb9c07d4cd8c6d22bfc"
+checksum = "c1ab4a3ec9ea8a657c72d99a03a824af695bd0fb5ec639ccbd9cd3543b41a5f9"
 dependencies = [
  "arc-swap",
  "bytes",
- "either",
  "fs-err",
  "http",
  "http-body",
@@ -381,6 +514,7 @@ dependencies = [
  "hyper-util",
  "pin-project-lite",
  "rustls",
+ "rustls-pemfile",
  "rustls-pki-types",
  "tokio",
  "tokio-rustls",
@@ -389,8 +523,9 @@ dependencies = [

 [[package]]
 name = "axum-server-dual-protocol"
-version = "0.8.0"
-source = "git+https://github.com/vinchona/axum-server-dual-protocol.git?rev=ca6db055254255b74238673ce4135698e347d71c#ca6db055254255b74238673ce4135698e347d71c"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2164551db024e87f20316d164eab9f5ad342d8188b08051ceb15ca92a60ea7b7"
 dependencies = [
  "axum-server",
  "bytes",
@@ -461,15 +596,30 @@ dependencies = [
  "quote",
  "regex",
  "rustc-hash",
- "shlex 1.3.0",
+ "shlex",
  "syn",
 ]

 [[package]]
-name = "bitflags"
-version = "2.13.0"
+name = "bit_field"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
+
+[[package]]
+name = "bitflags"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
+
+[[package]]
+name = "bitstream-io"
+version = "4.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757"
+dependencies = [
+ "core2",
+]

 [[package]]
 name = "blake2"
@@ -477,7 +627,7 @@ version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
 dependencies = [
- "digest 0.10.7",
+ "digest",
 ]

 [[package]]
@@ -489,15 +639,6 @@ dependencies = [
  "generic-array",
 ]

-[[package]]
-name = "block-buffer"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
-dependencies = [
- "hybrid-array",
-]
-
 [[package]]
 name = "block2"
 version = "0.6.2"
@@ -508,10 +649,19 @@ dependencies = [
 ]

 [[package]]
-name = "brotli"
-version = "8.0.4"
+name = "blurhash"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3"
+checksum = "e79769241dcd44edf79a732545e8b5cec84c247ac060f5252cd51885d093a8fc"
+dependencies = [
+ "image",
+]
+
+[[package]]
+name = "brotli"
+version = "8.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -520,9 +670,9 @@ dependencies = [

 [[package]]
 name = "brotli-decompressor"
-version = "5.0.3"
+version = "5.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -530,15 +680,15 @@ dependencies = [

 [[package]]
 name = "built"
-version = "0.8.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9"
+checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64"

 [[package]]
 name = "bumpalo"
-version = "3.20.3"
+version = "3.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
+checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"

 [[package]]
 name = "bytemuck"
@@ -560,15 +710,15 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"

 [[package]]
 name = "bytes"
-version = "1.12.0"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"

 [[package]]
 name = "bytesize"
-version = "2.4.0"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49e78e506b9d7633710dab98996f22f95f3d0f488e8f1aa162830556ed9fc14d"
+checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3"

 [[package]]
 name = "bzip2-sys"
@@ -591,9 +741,9 @@ dependencies = [

 [[package]]
 name = "cargo-platform"
-version = "0.3.3"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba"
+checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082"
 dependencies = [
  "serde",
  "serde_core",
@@ -610,7 +760,7 @@ dependencies = [
  "semver",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
 ]

 [[package]]
@@ -625,16 +775,22 @@ dependencies = [

 [[package]]
 name = "cc"
-version = "1.2.64"
+version = "1.2.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f"
+checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
 dependencies = [
  "find-msvc-tools",
  "jobserver",
  "libc",
- "shlex 2.0.1",
+ "shlex",
 ]

+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
 [[package]]
 name = "cexpr"
 version = "0.6.0"
@@ -664,7 +820,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.3.0",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
 ]

 [[package]]
@@ -678,13 +834,23 @@ dependencies = [

 [[package]]
 name = "chrono"
-version = "0.4.45"
+version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
+checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
 dependencies = [
  "num-traits",
 ]

+[[package]]
+name = "chumsky"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9"
+dependencies = [
+ "hashbrown 0.14.5",
+ "stacker",
+]
+
 [[package]]
 name = "clang-sys"
 version = "1.8.1"
@@ -698,9 +864,9 @@ dependencies = [

 [[package]]
 name = "clap"
-version = "4.6.1"
+version = "4.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
+checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -718,9 +884,9 @@ dependencies = [

 [[package]]
 name = "clap_derive"
-version = "4.6.1"
+version = "4.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
+checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -734,30 +900,15 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"

-[[package]]
-name = "client-ip"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39d2056bf065c8b4bce5a8898d40e175211ff4410add2a84d695845d3937c729"
-dependencies = [
- "http",
-]
-
 [[package]]
 name = "cmake"
-version = "0.1.58"
+version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
+checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
 dependencies = [
  "cc",
 ]

-[[package]]
-name = "cmov"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
-
 [[package]]
 name = "color_quant"
 version = "1.1.0"
@@ -776,9 +927,9 @@ dependencies = [

 [[package]]
 name = "compression-codecs"
-version = "0.4.38"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf"
+checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7"
 dependencies = [
  "brotli",
  "compression-core",
@@ -790,9 +941,9 @@ dependencies = [

 [[package]]
 name = "compression-core"
-version = "0.4.32"
+version = "0.4.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789"
+checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"

 [[package]]
 name = "concurrent-queue"
@@ -805,30 +956,24 @@ dependencies = [

 [[package]]
 name = "conduwuit"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "aws-lc-rs",
  "clap",
  "conduwuit_admin",
  "conduwuit_api",
  "conduwuit_build_metadata",
  "conduwuit_core",
  "conduwuit_database",
- "conduwuit_macros",
  "conduwuit_router",
  "conduwuit_service",
  "console-subscriber",
  "const-str",
- "ctor",
- "dtor",
  "hardened_malloc-rs",
  "log",
  "opentelemetry",
  "opentelemetry-otlp",
  "opentelemetry_sdk",
  "parking_lot",
- "reqwest 0.13.4",
- "rustls",
  "sentry",
  "sentry-tower",
  "sentry-tracing",
@@ -843,9 +988,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_admin"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "clap",
  "conduwuit_api",
  "conduwuit_core",
@@ -853,11 +997,10 @@ dependencies = [
  "conduwuit_macros",
  "conduwuit_service",
  "const-str",
- "ctor",
- "dtor",
  "futures",
  "lettre",
  "log",
+ "resolvematrix",
  "ruma",
  "serde-saphyr",
  "serde_json",
@@ -868,9 +1011,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_api"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "async-trait",
  "axum",
  "axum-client-ip",
@@ -878,47 +1020,41 @@ dependencies = [
  "base64 0.22.1",
  "bytes",
  "conduwuit_core",
- "conduwuit_macros",
  "conduwuit_service",
  "const-str",
- "ctor",
- "dtor",
  "futures",
  "hmac",
  "http",
  "http-body-util",
  "hyper",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "lettre",
  "log",
- "rand 0.10.1",
- "reqwest 0.13.4",
+ "rand 0.10.0",
+ "reqwest 0.12.28",
  "ruma",
- "ruminuwuity",
  "serde",
  "serde_html_form",
  "serde_json",
- "sha1 0.11.0",
+ "sha1",
  "tokio",
  "tracing",
 ]

 [[package]]
 name = "conduwuit_build_metadata"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "built",
- "cargo_metadata",
 ]

 [[package]]
 name = "conduwuit_core"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "argon2",
  "arrayvec",
- "assign",
  "axum",
  "axum-extra",
  "bytes",
@@ -933,7 +1069,6 @@ dependencies = [
  "core_affinity",
  "ctor",
  "cyborgtime",
- "dtor",
  "either",
  "figment",
  "futures",
@@ -942,36 +1077,37 @@ dependencies = [
  "http-body-util",
  "hyper-util",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "lettre",
  "libc",
  "libloading 0.9.0",
  "lock_api",
  "log",
  "maplit",
- "nix",
+ "nix 0.31.2",
  "num-traits",
  "parking_lot",
- "rand 0.10.1",
+ "rand 0.10.0",
  "rand_core 0.6.4",
  "regex",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
+ "resolvematrix",
+ "ring",
  "ruma",
  "sanitize-filename",
  "serde",
  "serde-saphyr",
  "serde_json",
  "serde_regex",
- "sha2 0.11.0",
  "smallstr",
  "smallvec",
- "thiserror",
+ "thiserror 2.0.18",
  "tikv-jemalloc-ctl",
  "tikv-jemalloc-sys",
  "tikv-jemallocator",
  "tokio",
  "tokio-metrics",
- "toml 1.1.2+spec-1.1.0",
+ "toml 0.9.12+spec-1.1.0",
  "tracing",
  "tracing-core",
  "tracing-subscriber",
@@ -980,14 +1116,11 @@ dependencies = [

 [[package]]
 name = "conduwuit_database"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "async-channel",
  "conduwuit_core",
- "conduwuit_macros",
  "const-str",
- "ctor",
- "dtor",
  "futures",
  "log",
  "minicbor",
@@ -1001,10 +1134,9 @@ dependencies = [

 [[package]]
 name = "conduwuit_macros"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "cargo_toml",
- "itertools 0.15.0",
+ "itertools 0.14.0",
  "proc-macro2",
  "quote",
  "syn",
@@ -1012,9 +1144,8 @@ dependencies = [

 [[package]]
 name = "conduwuit_router"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
- "assign",
  "axum",
  "axum-client-ip",
  "axum-server",
@@ -1023,12 +1154,9 @@ dependencies = [
  "conduwuit_admin",
  "conduwuit_api",
  "conduwuit_core",
- "conduwuit_macros",
  "conduwuit_service",
  "conduwuit_web",
  "const-str",
- "ctor",
- "dtor",
  "futures",
  "http",
  "http-body-util",
@@ -1044,25 +1172,22 @@ dependencies = [
  "serde_json",
  "tokio",
  "tower",
- "tower-http 0.7.0",
+ "tower-http",
  "tracing",
 ]

 [[package]]
 name = "conduwuit_service"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
- "assign",
  "async-trait",
  "base64 0.22.1",
+ "blurhash",
  "bytes",
  "conduwuit_core",
  "conduwuit_database",
- "conduwuit_macros",
  "const-str",
- "ctor",
- "dtor",
  "either",
  "futures",
  "governor",
@@ -1070,25 +1195,25 @@ dependencies = [
  "http",
  "image",
  "ipaddress",
- "itertools 0.15.0",
+ "itertools 0.14.0",
+ "ldap3",
  "lettre",
  "log",
  "loole",
  "lru-cache",
  "nonzero_ext",
- "rand 0.10.1",
+ "rand 0.10.0",
  "recaptcha-verify",
  "regex",
  "reqwest 0.12.28",
- "reqwest 0.13.4",
+ "resolvematrix",
  "ruma",
- "ruminuwuity",
  "rustyline-async",
  "sd-notify",
  "serde",
  "serde-saphyr",
  "serde_json",
- "sha2 0.11.0",
+ "sha2",
  "termimad",
  "tokio",
  "tracing",
@@ -1099,10 +1224,9 @@ dependencies = [

 [[package]]
 name = "conduwuit_web"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
- "assign",
  "async-trait",
  "axum",
  "axum-extra",
@@ -1112,11 +1236,11 @@ dependencies = [
  "conduwuit_service",
  "futures",
  "memory-serve",
- "rand 0.10.1",
+ "rand 0.10.0",
  "ruma",
  "serde",
- "thiserror",
- "tower-http 0.7.0",
+ "thiserror 2.0.18",
+ "tower-http",
  "tower-sec-fetch",
  "tracing",
  "validator",
@@ -1170,9 +1294,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"

 [[package]]
 name = "const-str"
-version = "1.1.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f"
+checksum = "b0664d2867b4a32697dfe655557f5c3b187e9b605b38612a748e5ec99811d160"

 [[package]]
 name = "const_panic"
@@ -1183,6 +1307,16 @@ dependencies = [
  "typewit",
 ]

+[[package]]
+name = "continuwuity-admin-api"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "ruma-common",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "convert_case"
 version = "0.10.0"
@@ -1212,16 +1346,6 @@ dependencies = [
  "crossterm",
 ]

-[[package]]
-name = "core-foundation"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "core-foundation"
 version = "0.10.1"
@@ -1238,6 +1362,15 @@ version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"

+[[package]]
+name = "core2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "core_affinity"
 version = "0.8.3"
@@ -1391,6 +1524,12 @@ dependencies = [
  "winapi",
 ]

+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
 [[package]]
 name = "crypto-common"
 version = "0.1.7"
@@ -1401,33 +1540,21 @@ dependencies = [
  "typenum",
 ]

-[[package]]
-name = "crypto-common"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
-dependencies = [
- "hybrid-array",
-]
-
 [[package]]
 name = "ctor"
-version = "1.0.7"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
+checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e"
 dependencies = [
- "link-section",
- "linktime-proc-macro",
+ "ctor-proc-macro",
+ "dtor",
 ]

 [[package]]
-name = "ctutils"
-version = "0.4.2"
+name = "ctor-proc-macro"
+version = "0.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
-dependencies = [
- "cmov",
-]
+checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"

 [[package]]
 name = "curve25519-dalek"
@@ -1438,7 +1565,7 @@ dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
  "curve25519-dalek-derive",
- "digest 0.10.7",
+ "digest",
  "fiat-crypto",
  "rustc_version",
  "subtle",
@@ -1499,9 +1626,9 @@ dependencies = [

 [[package]]
 name = "data-encoding"
-version = "2.11.0"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
+checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"

 [[package]]
 name = "date_header"
@@ -1529,11 +1656,28 @@ dependencies = [
  "zeroize",
 ]

+[[package]]
+name = "der-parser"
+version = "10.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6"
+dependencies = [
+ "asn1-rs",
+ "displaydoc",
+ "nom 7.1.3",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
 [[package]]
 name = "deranged"
 version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
+dependencies = [
+ "powerfmt",
+]

 [[package]]
 name = "derive_more"
@@ -1563,22 +1707,11 @@ version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
 dependencies = [
- "block-buffer 0.10.4",
- "crypto-common 0.1.7",
+ "block-buffer",
+ "crypto-common",
  "subtle",
 ]

-[[package]]
-name = "digest"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
-dependencies = [
- "block-buffer 0.12.1",
- "crypto-common 0.2.2",
- "ctutils",
-]
-
 [[package]]
 name = "dispatch2"
 version = "0.3.1"
@@ -1591,9 +1724,9 @@ dependencies = [

 [[package]]
 name = "displaydoc"
-version = "0.2.6"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1610,14 +1743,30 @@ dependencies = [
 ]

 [[package]]
-name = "dtor"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d738e43aa64edab57c983d56de890d65fea7dc05605490c74451ce721dfd84b"
+name = "draupnir-antispam"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
- "linktime-proc-macro",
+ "ruma-common",
+ "serde",
+ "serde_json",
 ]

+[[package]]
+name = "dtor"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301"
+dependencies = [
+ "dtor-proc-macro",
+]
+
+[[package]]
+name = "dtor-proc-macro"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
+
 [[package]]
 name = "dunce"
 version = "1.0.5"
@@ -1642,17 +1791,18 @@ checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
 dependencies = [
  "curve25519-dalek",
  "ed25519",
+ "rand_core 0.6.4",
  "serde",
- "sha2 0.10.9",
+ "sha2",
  "subtle",
  "zeroize",
 ]

 [[package]]
 name = "either"
-version = "1.16.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
 dependencies = [
  "serde",
 ]
@@ -1691,6 +1841,38 @@ dependencies = [
  "encoding_rs",
 ]

+[[package]]
+name = "enum-as-inner"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "equator"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
+dependencies = [
+ "equator-macro",
+]
+
+[[package]]
+name = "equator-macro"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "equivalent"
 version = "1.0.2"
@@ -1727,10 +1909,45 @@ dependencies = [
 ]

 [[package]]
-name = "fastrand"
-version = "2.4.1"
+name = "exr"
+version = "1.74.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be"
+dependencies = [
+ "bit_field",
+ "half",
+ "lebe",
+ "miniz_oxide",
+ "rayon-core",
+ "smallvec",
+ "zune-inflate",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "fax"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab"
+dependencies = [
+ "fax_derive",
+]
+
+[[package]]
+name = "fax_derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]

 [[package]]
 name = "fdeflate"
@@ -1822,6 +2039,16 @@ dependencies = [
  "percent-encoding",
 ]

+[[package]]
+name = "forwarded-header-value"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9"
+dependencies = [
+ "nonempty",
+ "thiserror 1.0.69",
+]
+
 [[package]]
 name = "fs-err"
 version = "3.3.0"
@@ -1921,9 +2148,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"

 [[package]]
 name = "futures-timer"
-version = "3.0.4"
+version = "3.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968"
+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"

 [[package]]
 name = "futures-util"
@@ -1988,16 +2215,16 @@ dependencies = [
  "cfg-if",
  "libc",
  "r-efi 6.0.0",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
  "wasip2",
  "wasip3",
 ]

 [[package]]
 name = "gif"
-version = "0.14.2"
+version = "0.14.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159"
+checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e"
 dependencies = [
  "color_quant",
  "weezl",
@@ -2034,21 +2261,11 @@ dependencies = [
  "web-time",
 ]

-[[package]]
-name = "granit-parser"
-version = "0.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f50ba32164f9e098d5da618776a32afbb32270adcbe3d3d006107dae11e37c91"
-dependencies = [
- "arraydeque",
- "smallvec",
-]
-
 [[package]]
 name = "h2"
-version = "0.4.15"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155"
+checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -2091,12 +2308,33 @@ dependencies = [
  "tokio-util",
 ]

+[[package]]
+name = "half"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+ "zerocopy",
+]
+
 [[package]]
 name = "hardened_malloc-rs"
 version = "0.1.2+12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "647deb1583b14d160f85f3ff626f20b6edd366e3852c9843b06077388f794cb6"

+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+dependencies = [
+ "ahash",
+ "allocator-api2",
+]
+
 [[package]]
 name = "hashbrown"
 version = "0.15.5"
@@ -2117,12 +2355,6 @@ dependencies = [
  "foldhash 0.2.0",
 ]

-[[package]]
-name = "hashbrown"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
-
 [[package]]
 name = "hdrhistogram"
 version = "7.5.4"
@@ -2148,7 +2380,7 @@ dependencies = [
  "http",
  "httpdate",
  "mime",
- "sha1 0.10.6",
+ "sha1",
 ]

 [[package]]
@@ -2179,84 +2411,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"

 [[package]]
-name = "hickory-net"
-version = "0.26.1"
+name = "hickory-proto"
+version = "0.25.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183"
+checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502"
 dependencies = [
  "async-trait",
  "cfg-if",
  "data-encoding",
+ "enum-as-inner",
  "futures-channel",
  "futures-io",
  "futures-util",
- "hickory-proto",
  "idna",
  "ipnet",
- "jni",
- "rand 0.10.1",
- "thiserror",
- "tinyvec",
- "tokio",
- "tracing",
- "url",
-]
-
-[[package]]
-name = "hickory-proto"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643"
-dependencies = [
- "data-encoding",
- "idna",
- "ipnet",
- "jni",
  "once_cell",
- "prefix-trie",
- "rand 0.10.1",
+ "rand 0.9.2",
  "ring",
  "serde",
- "thiserror",
+ "thiserror 2.0.18",
  "tinyvec",
+ "tokio",
  "tracing",
  "url",
 ]

 [[package]]
 name = "hickory-resolver"
-version = "0.26.1"
+version = "0.25.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c"
+checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a"
 dependencies = [
  "cfg-if",
  "futures-util",
- "hickory-net",
  "hickory-proto",
  "ipconfig",
- "ipnet",
- "jni",
  "moka",
- "ndk-context",
  "once_cell",
  "parking_lot",
- "rand 0.10.1",
+ "rand 0.9.2",
  "resolv-conf",
  "serde",
  "smallvec",
- "system-configuration",
- "thiserror",
+ "thiserror 2.0.18",
  "tokio",
  "tracing",
 ]

 [[package]]
 name = "hmac"
-version = "0.13.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
 dependencies = [
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -2286,9 +2494,9 @@ dependencies = [

 [[package]]
 name = "http"
-version = "1.4.2"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
+checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
 dependencies = [
  "bytes",
  "itoa",
@@ -2344,20 +2552,11 @@ version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"

-[[package]]
-name = "hybrid-array"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
-dependencies = [
- "typenum",
-]
-
 [[package]]
 name = "hyper"
-version = "1.10.1"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
+checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -2370,6 +2569,7 @@ dependencies = [
  "httpdate",
  "itoa",
  "pin-project-lite",
+ "pin-utils",
  "smallvec",
  "tokio",
  "want",
@@ -2377,18 +2577,20 @@ dependencies = [

 [[package]]
 name = "hyper-rustls"
-version = "0.27.9"
+version = "0.27.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
+checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
 dependencies = [
  "http",
  "hyper",
  "hyper-util",
  "rustls",
  "rustls-native-certs",
+ "rustls-pki-types",
  "tokio",
  "tokio-rustls",
  "tower-service",
+ "webpki-roots",
 ]

 [[package]]
@@ -2420,7 +2622,7 @@ dependencies = [
  "libc",
  "percent-encoding",
  "pin-project-lite",
- "socket2",
+ "socket2 0.6.3",
  "tokio",
  "tower-service",
  "tracing",
@@ -2428,13 +2630,12 @@ dependencies = [

 [[package]]
 name = "icu_collections"
-version = "2.2.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
+checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
 dependencies = [
  "displaydoc",
  "potential_utf",
- "utf8_iter",
  "yoke",
  "zerofrom",
  "zerovec",
@@ -2442,9 +2643,9 @@ dependencies = [

 [[package]]
 name = "icu_locale_core"
-version = "2.2.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
+checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
 dependencies = [
  "displaydoc",
  "litemap",
@@ -2455,9 +2656,9 @@ dependencies = [

 [[package]]
 name = "icu_normalizer"
-version = "2.2.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
+checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
 dependencies = [
  "icu_collections",
  "icu_normalizer_data",
@@ -2469,15 +2670,15 @@ dependencies = [

 [[package]]
 name = "icu_normalizer_data"
-version = "2.2.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
+checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"

 [[package]]
 name = "icu_properties"
-version = "2.2.0"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
+checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
 dependencies = [
  "icu_collections",
  "icu_locale_core",
@@ -2489,15 +2690,15 @@ dependencies = [

 [[package]]
 name = "icu_properties_data"
-version = "2.2.0"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
+checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"

 [[package]]
 name = "icu_provider"
-version = "2.2.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
+checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
 dependencies = [
  "displaydoc",
  "icu_locale_core",
@@ -2533,9 +2734,9 @@ dependencies = [

 [[package]]
 name = "idna_adapter"
-version = "1.2.2"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -2550,11 +2751,17 @@ dependencies = [
  "bytemuck",
  "byteorder-lite",
  "color_quant",
+ "exr",
  "gif",
  "image-webp",
  "moxcms",
  "num-traits",
  "png",
+ "qoi",
+ "ravif",
+ "rayon",
+ "rgb",
+ "tiff",
  "zune-core",
  "zune-jpeg",
 ]
@@ -2570,13 +2777,19 @@ dependencies = [
 ]

 [[package]]
-name = "indexmap"
-version = "2.14.0"
+name = "imgref"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
+
+[[package]]
+name = "indexmap"
+version = "2.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
 dependencies = [
  "equivalent",
- "hashbrown 0.17.1",
+ "hashbrown 0.16.1",
  "serde",
  "serde_core",
 ]
@@ -2587,6 +2800,17 @@ version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"

+[[package]]
+name = "interpolate_name"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "ipaddress"
 version = "0.1.3"
@@ -2603,15 +2827,14 @@ dependencies = [

 [[package]]
 name = "ipconfig"
-version = "0.3.4"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222"
+checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
 dependencies = [
- "socket2",
+ "socket2 0.5.10",
  "widestring",
- "windows-registry",
- "windows-result",
- "windows-sys 0.61.2",
+ "windows-sys 0.48.0",
+ "winreg",
 ]

 [[package]]
@@ -2619,7 +2842,14 @@ name = "ipnet"
 version = "2.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
+
+[[package]]
+name = "iri-string"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
 dependencies = [
+ "memchr",
  "serde",
 ]

@@ -2641,49 +2871,35 @@ dependencies = [
  "either",
 ]

-[[package]]
-name = "itertools"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
-dependencies = [
- "either",
-]
-
 [[package]]
 name = "itoa"
-version = "1.0.18"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"

 [[package]]
 name = "jni"
-version = "0.22.4"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
 dependencies = [
+ "cesu8",
  "cfg-if",
  "combine",
- "jni-macros",
- "jni-sys",
+ "jni-sys 0.3.1",
  "log",
- "simd_cesu8",
- "thiserror",
+ "thiserror 1.0.69",
  "walkdir",
- "windows-link",
+ "windows-sys 0.45.0",
 ]

 [[package]]
-name = "jni-macros"
-version = "0.22.4"
+name = "jni-sys"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
+checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
 dependencies = [
- "proc-macro2",
- "quote",
- "rustc_version",
- "simd_cesu8",
- "syn",
+ "jni-sys 0.4.1",
 ]

 [[package]]
@@ -2717,12 +2933,11 @@ dependencies = [

 [[package]]
 name = "js-sys"
-version = "0.3.102"
+version = "0.3.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
+checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
 dependencies = [
- "cfg-if",
- "futures-util",
+ "once_cell",
  "wasm-bindgen",
 ]

@@ -2737,20 +2952,30 @@ dependencies = [

 [[package]]
 name = "js_option"
-version = "0.2.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7dd3e281add16813cf673bf74a32249b0aa0d1c8117519a17b3ada5e8552b3c"
+checksum = "68421373957a1593a767013698dbf206e2b221eefe97a44d98d18672ff38423c"
 dependencies = [
- "serde_core",
+ "serde",
 ]

 [[package]]
 name = "konst"
-version = "0.4.3"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f660d5f887e3562f9ab6f4a14988795b694099d66b4f5dedc02d197ba9becb1d"
+checksum = "4381b9b00c55f251f2ebe9473aef7c117e96828def1a7cb3bd3f0f903c6894e9"
 dependencies = [
  "const_panic",
+ "konst_kernel",
+ "typewit",
+]
+
+[[package]]
+name = "konst_kernel"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4b1eb7788f3824c629b1116a7a9060d6e898c358ebff59070093d51103dcc3c"
+dependencies = [
  "typewit",
 ]

@@ -2783,6 +3008,41 @@ version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"

+[[package]]
+name = "lber"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbcf559624bfd9fe8d488329a8959766335a43a9b8b2cdd6a2c379fca02909a5"
+dependencies = [
+ "bytes",
+ "nom 7.1.3",
+]
+
+[[package]]
+name = "ldap3"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01fe89f5e7cfb7e4701e3a38ff9f00358e026a9aee940355d88ee9d81e5c7503"
+dependencies = [
+ "async-trait",
+ "bytes",
+ "futures",
+ "futures-util",
+ "lber",
+ "log",
+ "nom 7.1.3",
+ "percent-encoding",
+ "rustls",
+ "rustls-native-certs",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tokio-util",
+ "url",
+ "x509-parser",
+]
+
 [[package]]
 name = "leb128fmt"
 version = "0.1.0"
@@ -2790,13 +3050,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"

 [[package]]
-name = "lettre"
-version = "0.11.22"
+name = "lebe"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0da65617f6cb926332d039cb578aad56178da86e128db6a1b09f4c94fa5b3349"
+checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
+
+[[package]]
+name = "lettre"
+version = "0.11.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e13e10e8818f8b2a60f52cb127041d388b89f3a96a62be9ceaffa22262fef7f"
 dependencies = [
  "async-trait",
  "base64 0.22.1",
+ "chumsky",
  "email-encoding",
  "email_address",
  "fastrand",
@@ -2812,7 +3079,7 @@ dependencies = [
  "rustls",
  "rustls-native-certs",
  "serde",
- "socket2",
+ "socket2 0.6.3",
  "tokio",
  "tokio-rustls",
  "tracing",
@@ -2821,9 +3088,19 @@ dependencies = [

 [[package]]
 name = "libc"
-version = "0.2.186"
+version = "0.2.183"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
+
+[[package]]
+name = "libfuzzer-sys"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
+dependencies = [
+ "arbitrary",
+ "cc",
+]

 [[package]]
 name = "libloading"
@@ -2847,33 +3124,21 @@ dependencies = [

 [[package]]
 name = "libz-sys"
-version = "1.1.29"
+version = "1.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9"
+checksum = "d52f4c29e2a68ac30c9087e1b772dc9f44a2b66ed44edf2266cf2be9b03dafc1"
 dependencies = [
  "cc",
  "pkg-config",
  "vcpkg",
 ]

-[[package]]
-name = "link-section"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2b1dd6fe32e55c0fc0ea9493aa57459ca3cf4ff3c857c7d0302290150da6e4f"
-
 [[package]]
 name = "linked-hash-map"
 version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"

-[[package]]
-name = "linktime-proc-macro"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c7b0a3383c2a1002d11349c92c85a666a5fb679e96c79d782cf0dbe557fd6ee"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.12.1"
@@ -2882,9 +3147,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"

 [[package]]
 name = "litemap"
-version = "0.8.2"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
+checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"

 [[package]]
 name = "litrs"
@@ -2903,9 +3168,9 @@ dependencies = [

 [[package]]
 name = "log"
-version = "0.4.32"
+version = "0.4.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"

 [[package]]
 name = "loole"
@@ -2917,6 +3182,15 @@ dependencies = [
  "futures-sink",
 ]

+[[package]]
+name = "loop9"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
+dependencies = [
+ "imgref",
+]
+
 [[package]]
 name = "lru-cache"
 version = "0.1.2"
@@ -2996,10 +3270,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"

 [[package]]
-name = "memchr"
-version = "2.8.2"
+name = "maybe-rayon"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
+dependencies = [
+ "cfg-if",
+ "rayon",
+]
+
+[[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"

 [[package]]
 name = "memory-serve"
@@ -3017,6 +3301,16 @@ dependencies = [
  "walkdir",
 ]

+[[package]]
+name = "meowlnir-antispam"
+version = "0.1.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "ruma-common",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "mime"
 version = "0.3.17"
@@ -3035,15 +3329,15 @@ dependencies = [

 [[package]]
 name = "minicbor"
-version = "2.2.2"
+version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b7a5041e12946f8b7d3f5a9d96383a19d694b9335457c522be7815b9abafb02"
+checksum = "e70eae6d4f18f7d76877fe7b13f0bc21f7c2b7239d2041c338335f7b388d0dd7"

 [[package]]
 name = "minicbor-serde"
-version = "0.7.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "293c7245401f035e2dcc4b12ebdb5c9d8847247fc79fe1b5b0a0d58d7275324c"
+checksum = "80047f75e28e3b38f6ab2ec3c2c7669f6b411fa6f8424e1a90a3fd784b19a3f4"
 dependencies = [
  "minicbor",
  "serde",
@@ -3076,9 +3370,9 @@ dependencies = [

 [[package]]
 name = "mio"
-version = "1.2.1"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
 dependencies = [
  "libc",
  "log",
@@ -3088,9 +3382,9 @@ dependencies = [

 [[package]]
 name = "moka"
-version = "0.12.15"
+version = "0.12.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046"
+checksum = "85f8024e1c8e71c778968af91d43700ce1d11b219d127d79fb2934153b82b42b"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-epoch",
@@ -3113,12 +3407,6 @@ dependencies = [
  "pxfm",
 ]

-[[package]]
-name = "ndk-context"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
-
 [[package]]
 name = "new_debug_unreachable"
 version = "1.0.6"
@@ -3127,9 +3415,21 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"

 [[package]]
 name = "nix"
-version = "0.31.3"
+version = "0.30.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+]
+
+[[package]]
+name = "nix"
+version = "0.31.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -3162,12 +3462,24 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "nonempty"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
+
 [[package]]
 name = "nonzero_ext"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"

+[[package]]
+name = "noop_proc_macro"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
+
 [[package]]
 name = "nu-ansi-term"
 version = "0.50.3"
@@ -3212,9 +3524,20 @@ dependencies = [

 [[package]]
 name = "num-conv"
-version = "0.2.2"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
+checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
+
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]

 [[package]]
 name = "num-integer"
@@ -3434,6 +3757,15 @@ dependencies = [
  "memchr",
 ]

+[[package]]
+name = "oid-registry"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7"
+dependencies = [
+ "asn1-rs",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.21.4"
@@ -3452,36 +3784,36 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"

 [[package]]
 name = "opentelemetry"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682"
+checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
 dependencies = [
  "futures-core",
  "futures-sink",
  "js-sys",
  "pin-project-lite",
- "thiserror",
+ "thiserror 2.0.18",
  "tracing",
 ]

 [[package]]
 name = "opentelemetry-http"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331"
+checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
 dependencies = [
  "async-trait",
  "bytes",
  "http",
  "opentelemetry",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
 ]

 [[package]]
 name = "opentelemetry-otlp"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35"
+checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
 dependencies = [
  "http",
  "opentelemetry",
@@ -3489,18 +3821,18 @@ dependencies = [
  "opentelemetry-proto",
  "opentelemetry_sdk",
  "prost",
- "reqwest 0.13.4",
- "thiserror",
+ "reqwest 0.12.28",
+ "thiserror 2.0.18",
  "tokio",
  "tonic",
- "tonic-types",
+ "tracing",
 ]

 [[package]]
 name = "opentelemetry-proto"
-version = "0.32.0"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638"
+checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
 dependencies = [
  "opentelemetry",
  "opentelemetry_sdk",
@@ -3511,31 +3843,30 @@ dependencies = [

 [[package]]
 name = "opentelemetry_sdk"
-version = "0.32.1"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9"
+checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
 dependencies = [
  "futures-channel",
  "futures-executor",
  "futures-util",
  "opentelemetry",
  "percent-encoding",
- "portable-atomic",
- "rand 0.9.4",
- "thiserror",
+ "rand 0.9.2",
+ "thiserror 2.0.18",
  "tokio",
  "tokio-stream",
 ]

 [[package]]
 name = "os_info"
-version = "3.15.0"
+version = "3.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b"
+checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224"
 dependencies = [
  "android_system_properties",
  "log",
- "nix",
+ "nix 0.30.1",
  "objc2",
  "objc2-foundation",
  "objc2-ui-kit",
@@ -3591,6 +3922,12 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"

+[[package]]
+name = "pastey"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
+
 [[package]]
 name = "pear"
 version = "0.2.9"
@@ -3656,7 +3993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
  "phf_shared",
- "rand 0.8.6",
+ "rand 0.8.5",
 ]

 [[package]]
@@ -3670,18 +4007,18 @@ dependencies = [

 [[package]]
 name = "pin-project"
-version = "1.1.13"
+version = "1.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
+checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
 dependencies = [
  "pin-project-internal",
 ]

 [[package]]
 name = "pin-project-internal"
-version = "1.1.13"
+version = "1.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
+checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3694,6 +4031,12 @@ version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"

+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
 [[package]]
 name = "pkcs8"
 version = "0.10.2"
@@ -3706,9 +4049,9 @@ dependencies = [

 [[package]]
 name = "pkg-config"
-version = "0.3.33"
+version = "0.3.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"

 [[package]]
 name = "png"
@@ -3731,9 +4074,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"

 [[package]]
 name = "potential_utf"
-version = "0.1.5"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
+checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
 dependencies = [
  "zerovec",
 ]
@@ -3759,17 +4102,6 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"

-[[package]]
-name = "prefix-trie"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7"
-dependencies = [
- "either",
- "ipnet",
- "num-traits",
-]
-
 [[package]]
 name = "prettyplease"
 version = "0.2.37"
@@ -3786,7 +4118,7 @@ version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
 dependencies = [
- "toml_edit 0.25.12+spec-1.1.0",
+ "toml_edit 0.25.5+spec-1.1.0",
 ]

 [[package]]
@@ -3834,10 +4166,29 @@ dependencies = [
 ]

 [[package]]
-name = "prost"
-version = "0.14.4"
+name = "profiling"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
+checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
+dependencies = [
+ "profiling-procmacros",
+]
+
+[[package]]
+name = "profiling-procmacros"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
 dependencies = [
  "bytes",
  "prost-derive",
@@ -3845,9 +4196,9 @@ dependencies = [

 [[package]]
 name = "prost-derive"
-version = "0.14.4"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
+checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
 dependencies = [
  "anyhow",
  "itertools 0.14.0",
@@ -3858,18 +4209,28 @@ dependencies = [

 [[package]]
 name = "prost-types"
-version = "0.14.4"
+version = "0.14.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a"
+checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
 dependencies = [
  "prost",
 ]

 [[package]]
-name = "pulldown-cmark"
-version = "0.13.4"
+name = "psm"
+version = "0.1.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
+checksum = "3852766467df634d74f0b2d7819bf8dc483a0eb2e3b0f50f756f9cfe8b0d18d8"
+dependencies = [
+ "ar_archive_writer",
+ "cc",
+]
+
+[[package]]
+name = "pulldown-cmark"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83c41efbf8f90ac44de7f3a868f0867851d261b56291732d0cbf7cceaaeb55a6"
 dependencies = [
  "bitflags",
  "memchr",
@@ -3885,9 +4246,18 @@ checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"

 [[package]]
 name = "pxfm"
-version = "0.1.29"
+version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
+checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d"
+
+[[package]]
+name = "qoi"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
+dependencies = [
+ "bytemuck",
+]

 [[package]]
 name = "quick-error"
@@ -3909,8 +4279,8 @@ dependencies = [
  "quinn-udp",
  "rustc-hash",
  "rustls",
- "socket2",
- "thiserror",
+ "socket2 0.6.3",
+ "thiserror 2.0.18",
  "tokio",
  "tracing",
  "web-time",
@@ -3926,13 +4296,13 @@ dependencies = [
  "bytes",
  "getrandom 0.3.4",
  "lru-slab",
- "rand 0.9.4",
+ "rand 0.9.2",
  "ring",
  "rustc-hash",
  "rustls",
  "rustls-pki-types",
  "slab",
- "thiserror",
+ "thiserror 2.0.18",
  "tinyvec",
  "tracing",
  "web-time",
@@ -3947,25 +4317,25 @@ dependencies = [
  "cfg_aliases",
  "libc",
  "once_cell",
- "socket2",
+ "socket2 0.6.3",
  "tracing",
  "windows-sys 0.60.2",
 ]

 [[package]]
 name = "quote"
-version = "1.0.46"
+version = "1.0.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
 dependencies = [
  "proc-macro2",
 ]

 [[package]]
 name = "quoted_printable"
-version = "0.5.2"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "478e0585659a122aa407eb7e3c0e1fa51b1d8a870038bd29f0cf4a8551eea972"
+checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73"

 [[package]]
 name = "r-efi"
@@ -3981,18 +4351,18 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"

 [[package]]
 name = "rand"
-version = "0.8.6"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "rand_core 0.6.4",
 ]

 [[package]]
 name = "rand"
-version = "0.9.4"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
 dependencies = [
  "rand_chacha",
  "rand_core 0.9.5",
@@ -4000,13 +4370,13 @@ dependencies = [

 [[package]]
 name = "rand"
-version = "0.10.1"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
+checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
 dependencies = [
  "chacha20",
  "getrandom 0.4.2",
- "rand_core 0.10.1",
+ "rand_core 0.10.0",
 ]

 [[package]]
@@ -4039,9 +4409,79 @@ dependencies = [

 [[package]]
 name = "rand_core"
-version = "0.10.1"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
+
+[[package]]
+name = "rav1e"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b"
+dependencies = [
+ "aligned-vec",
+ "arbitrary",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "av-scenechange",
+ "av1-grain",
+ "bitstream-io",
+ "built",
+ "cfg-if",
+ "interpolate_name",
+ "itertools 0.14.0",
+ "libc",
+ "libfuzzer-sys",
+ "log",
+ "maybe-rayon",
+ "new_debug_unreachable",
+ "noop_proc_macro",
+ "num-derive",
+ "num-traits",
+ "paste",
+ "profiling",
+ "rand 0.9.2",
+ "rand_chacha",
+ "simd_helpers",
+ "thiserror 2.0.18",
+ "v_frame",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ravif"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45"
+dependencies = [
+ "avif-serialize",
+ "imgref",
+ "loop9",
+ "quick-error",
+ "rav1e",
+ "rayon",
+ "rgb",
+]
+
+[[package]]
+name = "rayon"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]

 [[package]]
 name = "recaptcha-verify"
@@ -4065,9 +4505,9 @@ dependencies = [

 [[package]]
 name = "regex"
-version = "1.12.4"
+version = "1.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -4088,52 +4528,15 @@ dependencies = [

 [[package]]
 name = "regex-syntax"
-version = "0.8.11"
+version = "0.8.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"

 [[package]]
 name = "reqwest"
 version = "0.12.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-core",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-util",
- "js-sys",
- "log",
- "percent-encoding",
- "pin-project-lite",
- "rustls",
- "rustls-native-certs",
- "rustls-pki-types",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "tokio",
- "tokio-rustls",
- "tower",
- "tower-http 0.6.11",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.13.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
 dependencies = [
  "base64 0.22.1",
  "bytes",
@@ -4157,6 +4560,47 @@ dependencies = [
  "pin-project-lite",
  "quinn",
  "rustls",
+ "rustls-native-certs",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tokio-rustls",
+ "tokio-util",
+ "tower",
+ "tower-http",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+ "webpki-roots",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-rustls",
+ "hyper-util",
+ "js-sys",
+ "log",
+ "percent-encoding",
+ "pin-project-lite",
+ "quinn",
+ "rustls",
  "rustls-pki-types",
  "rustls-platform-verifier",
  "serde",
@@ -4164,14 +4608,12 @@ dependencies = [
  "sync_wrapper",
  "tokio",
  "tokio-rustls",
- "tokio-util",
  "tower",
- "tower-http 0.6.11",
+ "tower-http",
  "tower-service",
  "url",
  "wasm-bindgen",
  "wasm-bindgen-futures",
- "wasm-streams",
  "web-sys",
 ]

@@ -4181,6 +4623,25 @@ version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"

+[[package]]
+name = "resolvematrix"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52dfcc6f56a81348db1fc6591356cfea9dc840408c75553b2fe225f86de43274"
+dependencies = [
+ "hickory-resolver",
+ "reqwest 0.13.2",
+ "serde",
+ "thiserror 2.0.18",
+ "tracing",
+]
+
+[[package]]
+name = "rgb"
+version = "0.8.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
+
 [[package]]
 name = "ring"
 version = "0.17.14"
@@ -4197,27 +4658,31 @@ dependencies = [

 [[package]]
 name = "ruma"
-version = "0.15.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.10.1"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "assign",
+ "continuwuity-admin-api",
+ "draupnir-antispam",
  "js_int",
  "js_option",
+ "meowlnir-antispam",
  "ruma-appservice-api",
  "ruma-client-api",
  "ruma-common",
  "ruma-events",
  "ruma-federation-api",
+ "ruma-identifiers-validation",
+ "ruma-identity-service-api",
  "ruma-push-gateway-api",
  "ruma-signatures",
- "ruma-state-res",
  "web-time",
 ]

 [[package]]
 name = "ruma-appservice-api"
-version = "0.15.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.10.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -4228,12 +4693,13 @@ dependencies = [

 [[package]]
 name = "ruma-client-api"
-version = "0.23.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.18.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "assign",
  "bytes",
+ "date_header",
  "http",
  "js_int",
  "js_option",
@@ -4243,69 +4709,72 @@ dependencies = [
  "serde",
  "serde_html_form",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "url",
  "web-time",
 ]

 [[package]]
 name = "ruma-common"
-version = "0.18.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.13.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "base64 0.22.1",
  "bytes",
- "date_header",
  "form_urlencoded",
- "getrandom 0.4.2",
+ "getrandom 0.2.17",
  "http",
  "indexmap",
  "js_int",
  "konst",
  "percent-encoding",
- "rand 0.10.1",
+ "rand 0.10.0",
  "regex",
  "ruma-identifiers-validation",
  "ruma-macros",
  "serde",
  "serde_html_form",
  "serde_json",
- "thiserror",
+ "smallvec",
+ "thiserror 2.0.18",
  "time",
  "tracing",
  "url",
  "uuid",
  "web-time",
  "wildmatch",
- "zeroize",
 ]

 [[package]]
 name = "ruma-events"
-version = "0.33.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.28.1"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "as_variant",
  "indexmap",
  "js_int",
  "js_option",
+ "percent-encoding",
  "pulldown-cmark",
+ "regex",
  "ruma-common",
+ "ruma-identifiers-validation",
  "ruma-macros",
  "serde",
  "serde_json",
- "thiserror",
+ "smallvec",
+ "thiserror 2.0.18",
  "tracing",
+ "url",
  "web-time",
  "wildmatch",
- "zeroize",
 ]

 [[package]]
 name = "ruma-federation-api"
-version = "0.14.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "bytes",
  "headers",
@@ -4315,31 +4784,39 @@ dependencies = [
  "js_int",
  "memchr",
  "mime",
- "rand 0.10.1",
+ "rand 0.10.0",
  "ruma-common",
  "ruma-events",
- "ruma-signatures",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "tracing",
 ]

 [[package]]
 name = "ruma-identifiers-validation"
-version = "0.12.1"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.5"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
- "thiserror",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "ruma-identity-service-api"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
+dependencies = [
+ "js_int",
+ "ruma-common",
+ "serde",
 ]

 [[package]]
 name = "ruma-macros"
-version = "0.18.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.13.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
- "as_variant",
  "cfg-if",
  "proc-macro-crate",
  "proc-macro2",
@@ -4347,13 +4824,13 @@ dependencies = [
  "ruma-identifiers-validation",
  "serde",
  "syn",
- "toml 1.1.2+spec-1.1.0",
+ "toml 0.8.23",
 ]

 [[package]]
 name = "ruma-push-gateway-api"
-version = "0.14.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.9.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "js_int",
  "ruma-common",
@@ -4364,50 +4841,25 @@ dependencies = [

 [[package]]
 name = "ruma-signatures"
-version = "0.20.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
+version = "0.15.0"
+source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
 dependencies = [
  "base64 0.22.1",
  "ed25519-dalek",
- "memchr",
  "pkcs8",
- "rand 0.10.1",
+ "rand 0.10.0",
+ "rand_core 0.6.4",
  "ruma-common",
  "serde_json",
- "sha2 0.10.9",
- "thiserror",
-]
-
-[[package]]
-name = "ruma-state-res"
-version = "0.16.0"
-source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
-dependencies = [
- "js_int",
- "ruma-common",
- "ruma-events",
- "ruma-signatures",
- "serde",
- "serde_json",
- "thiserror",
- "tracing",
-]
-
-[[package]]
-name = "ruminuwuity"
-version = "26.6.0-alpha.1"
-dependencies = [
- "assign",
- "ruma",
- "serde",
- "serde_json",
- "wildmatch",
+ "sha2",
+ "subslice",
+ "thiserror 2.0.18",
 ]

 [[package]]
 name = "rust-librocksdb-sys"
-version = "0.45.1+11.1.1"
-source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=0a25ff92f7c09b55eec496b9c192c7d5136ab2b8#0a25ff92f7c09b55eec496b9c192c7d5136ab2b8"
+version = "0.42.0+10.10.1"
+source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9#31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9"
 dependencies = [
  "bindgen",
  "bzip2-sys",
@@ -4423,8 +4875,8 @@ dependencies = [

 [[package]]
 name = "rust-rocksdb"
-version = "0.49.1"
-source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=0a25ff92f7c09b55eec496b9c192c7d5136ab2b8#0a25ff92f7c09b55eec496b9c192c7d5136ab2b8"
+version = "0.46.0"
+source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9#31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9"
 dependencies = [
  "libc",
  "parking_lot",
@@ -4439,9 +4891,9 @@ checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"

 [[package]]
 name = "rustc-hash"
-version = "2.1.2"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"

 [[package]]
 name = "rustc_version"
@@ -4452,6 +4904,15 @@ dependencies = [
  "semver",
 ]

+[[package]]
+name = "rusticata-macros"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
+dependencies = [
+ "nom 7.1.3",
+]
+
 [[package]]
 name = "rustix"
 version = "1.1.4"
@@ -4467,9 +4928,9 @@ dependencies = [

 [[package]]
 name = "rustls"
-version = "0.23.40"
+version = "0.23.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
+checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
 dependencies = [
  "aws-lc-rs",
  "log",
@@ -4483,9 +4944,9 @@ dependencies = [

 [[package]]
 name = "rustls-native-certs"
-version = "0.8.4"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
+checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
 dependencies = [
  "openssl-probe",
  "rustls-pki-types",
@@ -4494,10 +4955,19 @@ dependencies = [
 ]

 [[package]]
-name = "rustls-pki-types"
-version = "1.14.1"
+name = "rustls-pemfile"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
 dependencies = [
  "web-time",
  "zeroize",
@@ -4505,11 +4975,11 @@ dependencies = [

 [[package]]
 name = "rustls-platform-verifier"
-version = "0.7.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
+checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
 dependencies = [
- "core-foundation 0.10.1",
+ "core-foundation",
  "core-foundation-sys",
  "jni",
  "log",
@@ -4532,9 +5002,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"

 [[package]]
 name = "rustls-webpki"
-version = "0.103.13"
+version = "0.103.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
+checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
 dependencies = [
  "aws-lc-rs",
  "ring",
@@ -4558,7 +5028,7 @@ dependencies = [
  "futures-util",
  "pin-project",
  "thingbuf",
- "thiserror",
+ "thiserror 2.0.18",
  "unicode-segmentation",
 ]

@@ -4586,6 +5056,17 @@ dependencies = [
  "regex",
 ]

+[[package]]
+name = "saphyr-parser-bw"
+version = "0.0.608"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d55ae5ea09894b6d5382621db78f586df37ef18ab581bf32c754e75076b124b1"
+dependencies = [
+ "arraydeque",
+ "smallvec",
+ "thiserror 2.0.18",
+]
+
 [[package]]
 name = "schannel"
 version = "0.1.29"
@@ -4603,9 +5084,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"

 [[package]]
 name = "sd-notify"
-version = "0.5.0"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e4ef7359e694bfaf1dd27a30f9d760b54c00dfae9f19bd0c05a39bc9128fe76"
+checksum = "b943eadf71d8b69e661330cb0e2656e31040acf21ee7708e2c238a0ec6af2bf4"
 dependencies = [
  "libc",
 ]
@@ -4617,7 +5098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
 dependencies = [
  "bitflags",
- "core-foundation 0.10.1",
+ "core-foundation",
  "core-foundation-sys",
  "libc",
  "security-framework-sys",
@@ -4635,9 +5116,9 @@ dependencies = [

 [[package]]
 name = "semver"
-version = "1.0.28"
+version = "1.0.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
 dependencies = [
  "serde",
  "serde_core",
@@ -4645,13 +5126,14 @@ dependencies = [

 [[package]]
 name = "sentry"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "931a20b0da02350676e3d6d3c9028d58eaa448cf42a866712eec5845a505421e"
+checksum = "d92d893ba7469d361a6958522fa440e4e2bc8bf4c5803cd1bf40b9af63f8f9a8"
 dependencies = [
  "cfg_aliases",
  "httpdate",
- "reqwest 0.13.4",
+ "reqwest 0.12.28",
+ "rustls",
  "sentry-backtrace",
  "sentry-contexts",
  "sentry-core",
@@ -4661,13 +5143,14 @@ dependencies = [
  "sentry-tower",
  "sentry-tracing",
  "tokio",
+ "ureq",
 ]

 [[package]]
 name = "sentry-backtrace"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "911ee36abf5b7fa335fccd5f54361ba9c16baea5f0c3bb361a687b6c195c21cf"
+checksum = "5f8784d0a27b5cd4b5f75769ffc84f0b7580e3c35e1af9cd83cb90b612d769cc"
 dependencies = [
  "backtrace",
  "regex",
@@ -4676,9 +5159,9 @@ dependencies = [

 [[package]]
 name = "sentry-contexts"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b9d7d469e9e22741c17ca23fb8b42d79861590eb7cf330f3da34fc1e4bc1bc6"
+checksum = "0e5eb42f4cd4f9fdfec9e3b07b25a4c9769df83d218a7e846658984d5948ad3e"
 dependencies = [
  "hostname",
  "libc",
@@ -4690,11 +5173,11 @@ dependencies = [

 [[package]]
 name = "sentry-core"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "545dc562b6758d646ac19e1407f4ebc26d452111386743e03323464bc48bb2e0"
+checksum = "b0b1e7ca40f965db239da279bf278d87b7407469b98835f27f0c8e59ed189b06"
 dependencies = [
- "rand 0.9.4",
+ "rand 0.9.2",
  "sentry-types",
  "serde",
  "serde_json",
@@ -4703,9 +5186,9 @@ dependencies = [

 [[package]]
 name = "sentry-debug-images"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "660e9def38a573a869a182f7e90f58aaaa460f38b92b31fd1755ec537193bb48"
+checksum = "002561e49ea3a9de316e2efadc40fae553921b8ff41448f02ea85fd135a778d6"
 dependencies = [
  "findshlibs",
  "sentry-core",
@@ -4713,9 +5196,9 @@ dependencies = [

 [[package]]
 name = "sentry-log"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c13b9313bdd6a9db19e65ac0e4754e64dea6f18cdd15444656abb050db4538d"
+checksum = "e200860daf76e09f9ad111bce25928f96bedbb84bc5934b37f05bb445727c70e"
 dependencies = [
  "bitflags",
  "log",
@@ -4724,9 +5207,9 @@ dependencies = [

 [[package]]
 name = "sentry-panic"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "772d9de150c8ca910c835353c85f434457348fdd21208f9b3da3574202b1dc5d"
+checksum = "8906f8be87aea5ac7ef937323fb655d66607427f61007b99b7cb3504dc5a156c"
 dependencies = [
  "sentry-backtrace",
  "sentry-core",
@@ -4734,9 +5217,9 @@ dependencies = [

 [[package]]
 name = "sentry-tower"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2abea154597936d5df2d39fbe8aac16d584de6b3572c70c39558764d9d2efe15"
+checksum = "56aebe376310840b49dad4cca55c7b32d9abdc14946cd071d4158ecb149b63a4"
 dependencies = [
  "http",
  "pin-project",
@@ -4748,9 +5231,9 @@ dependencies = [

 [[package]]
 name = "sentry-tracing"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51ec9620a4d398dcdf7ee90effbf8d8691cfa24e91978bfa8565cac039d4980"
+checksum = "5b07eefe04486316c57aba08ab53dd44753c25102d1d3fe05775cc93a13262d9"
 dependencies = [
  "bitflags",
  "sentry-backtrace",
@@ -4761,16 +5244,16 @@ dependencies = [

 [[package]]
 name = "sentry-types"
-version = "0.48.2"
+version = "0.46.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "041359745a44dd2e14fe21b7510fe7ca8b5beffce6636a0b52e5bc7d5f736887"
+checksum = "567711f01f86a842057e1fc17779eba33a336004227e1a1e7e6cc2599e22e259"
 dependencies = [
  "debugid",
  "hex",
- "rand 0.9.4",
+ "rand 0.9.2",
  "serde",
  "serde_json",
- "thiserror",
+ "thiserror 2.0.18",
  "time",
  "url",
  "uuid",
@@ -4788,18 +5271,19 @@ dependencies = [

 [[package]]
 name = "serde-saphyr"
-version = "0.0.27"
+version = "0.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5897b4c3faadadd35fdb6689f015641f3bc481d5adaaac56231ea15aeb243db3"
+checksum = "4a6fc4aa0da972ba0f51cf5c1bb16e9dba35334adc6831b09b3ffb0ec20bb264"
 dependencies = [
  "ahash",
  "annotate-snippets",
  "base64 0.22.1",
  "encoding_rs_io",
  "getrandom 0.3.4",
- "granit-parser",
  "nohash-hasher",
  "num-traits",
+ "regex",
+ "saphyr-parser-bw",
  "serde",
  "smallvec",
  "zmij",
@@ -4827,9 +5311,9 @@ dependencies = [

 [[package]]
 name = "serde_html_form"
-version = "0.4.0"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0946d52b4b7e28823148aebbeceb901012c595ad737920d504fa8634bb099e6f"
+checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f"
 dependencies = [
  "form_urlencoded",
  "indexmap",
@@ -4840,9 +5324,9 @@ dependencies = [

 [[package]]
 name = "serde_json"
-version = "1.0.150"
+version = "1.0.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
 dependencies = [
  "itoa",
  "memchr",
@@ -4864,9 +5348,9 @@ dependencies = [

 [[package]]
 name = "serde_regex"
-version = "1.2.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bafc8d0c5330cecff10f16b459b479fd9acaa5b4acd7167301414e21b0057012"
+checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf"
 dependencies = [
  "regex",
  "serde",
@@ -4883,9 +5367,9 @@ dependencies = [

 [[package]]
 name = "serde_spanned"
-version = "1.1.1"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
+checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
 dependencies = [
  "serde_core",
 ]
@@ -4910,18 +5394,7 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
- "digest 0.10.7",
-]
-
-[[package]]
-name = "sha1"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.3.0",
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -4932,18 +5405,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
  "cfg-if",
  "cpufeatures 0.2.17",
- "digest 0.10.7",
-]
-
-[[package]]
-name = "sha2"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
-dependencies = [
- "cfg-if",
- "cpufeatures 0.3.0",
- "digest 0.11.3",
+ "digest",
 ]

 [[package]]
@@ -4955,7 +5417,7 @@ dependencies = [
  "async-trait",
  "bytes",
  "hex",
- "sha2 0.10.9",
+ "sha2",
  "tokio",
 ]

@@ -4974,12 +5436,6 @@ version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"

-[[package]]
-name = "shlex"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
-
 [[package]]
 name = "signal-hook"
 version = "0.3.18"
@@ -5022,31 +5478,24 @@ dependencies = [

 [[package]]
 name = "simd-adler32"
-version = "0.3.9"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
+checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"

 [[package]]
-name = "simd_cesu8"
-version = "1.1.1"
+name = "simd_helpers"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
+checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
 dependencies = [
- "rustc_version",
- "simdutf8",
+ "quote",
 ]

-[[package]]
-name = "simdutf8"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
-
 [[package]]
 name = "siphasher"
-version = "1.0.3"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"

 [[package]]
 name = "slab"
@@ -5066,18 +5515,28 @@ dependencies = [

 [[package]]
 name = "smallvec"
-version = "1.15.2"
+version = "1.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
 dependencies = [
  "serde",
 ]

 [[package]]
 name = "socket2"
-version = "0.6.4"
+version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "socket2"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
 dependencies = [
  "libc",
  "windows-sys 0.61.2",
@@ -5108,6 +5567,19 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"

+[[package]]
+name = "stacker"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d74a23609d509411d10e2176dc2a4346e3b4aea2e7b1869f19fdedbc71c013"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "libc",
+ "psm",
+ "windows-sys 0.59.0",
+]
+
 [[package]]
 name = "strict"
 version = "0.2.0"
@@ -5145,6 +5617,15 @@ version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"

+[[package]]
+name = "subslice"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a8e4809a3bb02de01f1f7faf1ba01a83af9e8eabcd4d31dd6e413d14d56aae"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "subtle"
 version = "2.6.1"
@@ -5153,9 +5634,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"

 [[package]]
 name = "syn"
-version = "2.0.118"
+version = "2.0.117"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5182,27 +5663,6 @@ dependencies = [
  "syn",
 ]

-[[package]]
-name = "system-configuration"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
-dependencies = [
- "bitflags",
- "core-foundation 0.9.4",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "tagptr"
 version = "0.2.0"
@@ -5232,7 +5692,7 @@ dependencies = [
  "lazy-regex",
  "minimad",
  "serde",
- "thiserror",
+ "thiserror 2.0.18",
  "unicode-width 0.1.14",
 ]

@@ -5246,13 +5706,33 @@ dependencies = [
  "pin-project",
 ]

+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
 [[package]]
 name = "thiserror"
 version = "2.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
 dependencies = [
- "thiserror-impl",
+ "thiserror-impl 2.0.18",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
 ]

 [[package]]
@@ -5275,6 +5755,20 @@ dependencies = [
  "cfg-if",
 ]

+[[package]]
+name = "tiff"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"
+dependencies = [
+ "fax",
+ "flate2",
+ "half",
+ "quick-error",
+ "weezl",
+ "zune-jpeg",
+]
+
 [[package]]
 name = "tikv-jemalloc-ctl"
 version = "0.6.1"
@@ -5305,11 +5799,12 @@ dependencies = [

 [[package]]
 name = "time"
-version = "0.3.49"
+version = "0.3.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
 dependencies = [
  "deranged",
+ "itoa",
  "num-conv",
  "powerfmt",
  "serde_core",
@@ -5319,15 +5814,15 @@ dependencies = [

 [[package]]
 name = "time-core"
-version = "0.1.9"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"

 [[package]]
 name = "time-macros"
-version = "0.2.29"
+version = "0.2.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
 dependencies = [
  "num-conv",
  "time-core",
@@ -5335,9 +5830,9 @@ dependencies = [

 [[package]]
 name = "tinystr"
-version = "0.8.3"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
+checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
 dependencies = [
  "displaydoc",
  "zerovec",
@@ -5360,16 +5855,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"

 [[package]]
 name = "tokio"
-version = "1.52.3"
+version = "1.50.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
 dependencies = [
  "bytes",
  "libc",
  "mio",
  "pin-project-lite",
  "signal-hook-registry",
- "socket2",
+ "socket2 0.6.3",
  "tokio-macros",
  "tracing",
  "windows-sys 0.61.2",
@@ -5377,9 +5872,9 @@ dependencies = [

 [[package]]
 name = "tokio-macros"
-version = "2.7.0"
+version = "2.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
+checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5388,9 +5883,9 @@ dependencies = [

 [[package]]
 name = "tokio-metrics"
-version = "0.5.0"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9e81d53caf955549b1dec7af4ac2149e94cc25ed97b4a545151140281e2f528"
+checksum = "0e0410015c6db7b67b9c9ab2a3af4d74a942d637ff248d0d055073750deac6f9"
 dependencies = [
  "futures-util",
  "pin-project-lite",
@@ -5452,26 +5947,13 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
 dependencies = [
  "indexmap",
  "serde_core",
- "serde_spanned 1.1.1",
+ "serde_spanned 1.0.4",
  "toml_datetime 0.7.5+spec-1.1.0",
  "toml_parser",
  "toml_writer",
  "winnow 0.7.15",
 ]

-[[package]]
-name = "toml"
-version = "1.1.2+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
-dependencies = [
- "serde_core",
- "serde_spanned 1.1.1",
- "toml_datetime 1.1.1+spec-1.1.0",
- "toml_parser",
- "winnow 1.0.3",
-]
-
 [[package]]
 name = "toml_datetime"
 version = "0.6.11"
@@ -5492,9 +5974,9 @@ dependencies = [

 [[package]]
 name = "toml_datetime"
-version = "1.1.1+spec-1.1.0"
+version = "1.0.1+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
+checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9"
 dependencies = [
  "serde_core",
 ]
@@ -5515,23 +5997,23 @@ dependencies = [

 [[package]]
 name = "toml_edit"
-version = "0.25.12+spec-1.1.0"
+version = "0.25.5+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7"
+checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1"
 dependencies = [
  "indexmap",
- "toml_datetime 1.1.1+spec-1.1.0",
+ "toml_datetime 1.0.1+spec-1.1.0",
  "toml_parser",
- "winnow 1.0.3",
+ "winnow 1.0.0",
 ]

 [[package]]
 name = "toml_parser"
-version = "1.1.2+spec-1.1.0"
+version = "1.0.10+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
+checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420"
 dependencies = [
- "winnow 1.0.3",
+ "winnow 1.0.0",
 ]

 [[package]]
@@ -5542,15 +6024,15 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"

 [[package]]
 name = "toml_writer"
-version = "1.1.1+spec-1.1.0"
+version = "1.0.7+spec-1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
+checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d"

 [[package]]
 name = "tonic"
-version = "0.14.6"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
+checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
 dependencies = [
  "async-trait",
  "axum",
@@ -5565,7 +6047,7 @@ dependencies = [
  "hyper-util",
  "percent-encoding",
  "pin-project",
- "socket2",
+ "socket2 0.6.3",
  "sync_wrapper",
  "tokio",
  "tokio-stream",
@@ -5577,26 +6059,15 @@ dependencies = [

 [[package]]
 name = "tonic-prost"
-version = "0.14.6"
+version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
+checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
 dependencies = [
  "bytes",
  "prost",
  "tonic",
 ]

-[[package]]
-name = "tonic-types"
-version = "0.14.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8"
-dependencies = [
- "prost",
- "prost-types",
- "tonic",
-]
-
 [[package]]
 name = "tower"
 version = "0.5.3"
@@ -5618,9 +6089,9 @@ dependencies = [

 [[package]]
 name = "tower-http"
-version = "0.6.11"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
+checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
 dependencies = [
  "async-compression",
  "bitflags",
@@ -5630,30 +6101,7 @@ dependencies = [
  "http",
  "http-body",
  "http-body-util",
- "pin-project-lite",
- "tokio",
- "tokio-util",
- "tower",
- "tower-layer",
- "tower-service",
- "url",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233"
-dependencies = [
- "async-compression",
- "bitflags",
- "bytes",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "percent-encoding",
+ "iri-string",
  "pin-project-lite",
  "tokio",
  "tokio-util",
@@ -5755,9 +6203,9 @@ dependencies = [

 [[package]]
 name = "tracing-opentelemetry"
-version = "0.33.0"
+version = "0.32.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26"
+checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc"
 dependencies = [
  "js-sys",
  "opentelemetry",
@@ -5795,15 +6243,24 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"

 [[package]]
 name = "typenum"
-version = "1.20.1"
+version = "1.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"

 [[package]]
 name = "typewit"
-version = "1.15.2"
+version = "1.14.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "214ca0b2191785cbc06209b9ca1861e048e39b5ba33574b3cedd58363d5bb5f6"
+checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71"
+dependencies = [
+ "typewit_proc_macros",
+]
+
+[[package]]
+name = "typewit_proc_macros"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6"

 [[package]]
 name = "uname"
@@ -5837,9 +6294,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"

 [[package]]
 name = "unicode-segmentation"
-version = "1.13.3"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"

 [[package]]
 name = "unicode-width"
@@ -5865,6 +6322,34 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"

+[[package]]
+name = "ureq"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdc97a28575b85cfedf2a7e7d3cc64b3e11bd8ac766666318003abbacc7a21fc"
+dependencies = [
+ "base64 0.22.1",
+ "log",
+ "percent-encoding",
+ "rustls",
+ "rustls-pki-types",
+ "ureq-proto",
+ "utf-8",
+ "webpki-roots",
+]
+
+[[package]]
+name = "ureq-proto"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f"
+dependencies = [
+ "base64 0.22.1",
+ "http",
+ "httparse",
+ "log",
+]
+
 [[package]]
 name = "url"
 version = "2.5.8"
@@ -5898,9 +6383,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"

 [[package]]
 name = "uuid"
-version = "1.23.3"
+version = "1.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
+checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
 dependencies = [
  "getrandom 0.4.2",
  "js-sys",
@@ -5908,6 +6393,17 @@ dependencies = [
  "wasm-bindgen",
 ]

+[[package]]
+name = "v_frame"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
+dependencies = [
+ "aligned-vec",
+ "num-traits",
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "validator"
 version = "0.20.0"
@@ -5983,11 +6479,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"

 [[package]]
 name = "wasip2"
-version = "1.0.4+wasi-0.2.12"
+version = "1.0.2+wasi-0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
 dependencies = [
- "wit-bindgen 0.57.1",
+ "wit-bindgen",
 ]

 [[package]]
@@ -5996,14 +6492,14 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
 dependencies = [
- "wit-bindgen 0.51.0",
+ "wit-bindgen",
 ]

 [[package]]
 name = "wasm-bindgen"
-version = "0.2.125"
+version = "0.2.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
+checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -6014,19 +6510,23 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.75"
+version = "0.4.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
+checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8"
 dependencies = [
+ "cfg-if",
+ "futures-util",
  "js-sys",
+ "once_cell",
  "wasm-bindgen",
+ "web-sys",
 ]

 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.125"
+version = "0.2.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
+checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -6034,9 +6534,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.125"
+version = "0.2.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
+checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
 dependencies = [
  "bumpalo",
  "proc-macro2",
@@ -6047,9 +6547,9 @@ dependencies = [

 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.125"
+version = "0.2.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
+checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
 dependencies = [
  "unicode-ident",
 ]
@@ -6078,9 +6578,9 @@ dependencies = [

 [[package]]
 name = "wasm-streams"
-version = "0.5.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
+checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
 dependencies = [
  "futures-util",
  "js-sys",
@@ -6103,9 +6603,9 @@ dependencies = [

 [[package]]
 name = "web-sys"
-version = "0.3.102"
+version = "0.3.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
+checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -6135,9 +6635,18 @@ dependencies = [

 [[package]]
 name = "webpki-root-certs"
-version = "1.0.7"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c"
+checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
 dependencies = [
  "rustls-pki-types",
 ]
@@ -6198,32 +6707,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"

 [[package]]
-name = "windows-registry"
-version = "0.6.1"
+name = "windows-sys"
+version = "0.45.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
 dependencies = [
- "windows-link",
- "windows-result",
- "windows-strings",
+ "windows-targets 0.42.2",
 ]

 [[package]]
-name = "windows-result"
-version = "0.4.1"
+name = "windows-sys"
+version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
-dependencies = [
- "windows-link",
+ "windows-targets 0.48.5",
 ]

 [[package]]
@@ -6235,6 +6733,15 @@ dependencies = [
  "windows-targets 0.52.6",
 ]

+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
 [[package]]
 name = "windows-sys"
 version = "0.60.2"
@@ -6253,6 +6760,36 @@ dependencies = [
  "windows-link",
 ]

+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.52.6"
@@ -6286,6 +6823,18 @@ dependencies = [
  "windows_x86_64_msvc 0.53.1",
 ]

+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.52.6"
@@ -6298,6 +6847,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"

+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
@@ -6310,6 +6871,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"

+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
@@ -6334,6 +6907,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"

+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
@@ -6346,6 +6931,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"

+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
@@ -6358,6 +6955,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"

+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
@@ -6370,6 +6979,18 @@ version = "0.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"

+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
@@ -6393,13 +7014,23 @@ dependencies = [

 [[package]]
 name = "winnow"
-version = "1.0.3"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
+checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8"
 dependencies = [
  "memchr",
 ]

+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "wit-bindgen"
 version = "0.51.0"
@@ -6409,12 +7040,6 @@ dependencies = [
  "wit-bindgen-rust-macro",
 ]

-[[package]]
-name = "wit-bindgen"
-version = "0.57.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
-
 [[package]]
 name = "wit-bindgen-core"
 version = "0.51.0"
@@ -6496,9 +7121,26 @@ dependencies = [

 [[package]]
 name = "writeable"
-version = "0.6.3"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
+checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
+
+[[package]]
+name = "x509-parser"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202"
+dependencies = [
+ "asn1-rs",
+ "data-encoding",
+ "der-parser",
+ "lazy_static",
+ "nom 7.1.3",
+ "oid-registry",
+ "rusticata-macros",
+ "thiserror 2.0.18",
+ "time",
+]

 [[package]]
 name = "xml5ever"
@@ -6513,7 +7155,7 @@ dependencies = [

 [[package]]
 name = "xtask"
-version = "26.6.0-alpha.1"
+version = "0.5.7-alpha.1"
 dependencies = [
  "askama",
  "cargo_metadata",
@@ -6522,6 +7164,12 @@ dependencies = [
  "conduwuit_admin",
 ]

+[[package]]
+name = "y4m"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448"
+
 [[package]]
 name = "yansi"
 version = "1.0.1"
@@ -6530,9 +7178,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"

 [[package]]
 name = "yoke"
-version = "0.8.3"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
+checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
 dependencies = [
  "stable_deref_trait",
  "yoke-derive",
@@ -6541,9 +7189,9 @@ dependencies = [

 [[package]]
 name = "yoke-derive"
-version = "0.8.2"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
+checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6553,18 +7201,18 @@ dependencies = [

 [[package]]
 name = "zerocopy"
-version = "0.8.52"
+version = "0.8.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
+checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3"
 dependencies = [
  "zerocopy-derive",
 ]

 [[package]]
 name = "zerocopy-derive"
-version = "0.8.52"
+version = "0.8.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
+checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6573,18 +7221,18 @@ dependencies = [

 [[package]]
 name = "zerofrom"
-version = "0.1.8"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
 dependencies = [
  "zerofrom-derive",
 ]

 [[package]]
 name = "zerofrom-derive"
-version = "0.1.7"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6594,15 +7242,15 @@ dependencies = [

 [[package]]
 name = "zeroize"
-version = "1.9.0"
+version = "1.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"

 [[package]]
 name = "zerotrie"
-version = "0.2.4"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
+checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
 dependencies = [
  "displaydoc",
  "yoke",
@@ -6611,9 +7259,9 @@ dependencies = [

 [[package]]
 name = "zerovec"
-version = "0.11.6"
+version = "0.11.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
+checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
 dependencies = [
  "yoke",
  "zerofrom",
@@ -6622,9 +7270,9 @@ dependencies = [

 [[package]]
 name = "zerovec-derive"
-version = "0.11.3"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
+checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6672,10 +7320,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"

 [[package]]
-name = "zune-jpeg"
-version = "0.5.15"
+name = "zune-inflate"
+version = "0.2.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
+checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "zune-jpeg"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec5f41c76397b7da451efd19915684f727d7e1d516384ca6bd0ec43ec94de23c"
 dependencies = [
  "zune-core",
 ]
diff --git c/Cargo.toml i/Cargo.toml
index 519de9d2d..131aa6bf6 100644
--- c/Cargo.toml
+++ i/Cargo.toml
@@ -559,6 +559,9 @@ features = ["std"]
 [workspace.dependencies.nonzero_ext]
 version = "0.3.0"

+[workspace.dependencies.resolvematrix]
+version = "0.0.3"
+
 #
 # Patches
 #
diff --git c/src/admin/Cargo.toml i/src/admin/Cargo.toml
index 4afed12b4..1f82978a4 100644
--- c/src/admin/Cargo.toml
+++ i/src/admin/Cargo.toml
@@ -92,6 +92,7 @@ serde-saphyr.workspace = true
 tokio.workspace = true
 tracing-subscriber.workspace = true
 tracing.workspace = true
+resolvematrix.workspace = true

 [lints]
 workspace = true
diff --git c/src/admin/debug/commands.rs i/src/admin/debug/commands.rs
index 1aa9cb062..b6bf16ae0 100644
--- c/src/admin/debug/commands.rs
+++ i/src/admin/debug/commands.rs
@@ -20,6 +20,7 @@
 };
 use futures::{FutureExt, StreamExt, TryStreamExt};
 use lettre::message::Mailbox;
+use resolvematrix::server::{MatrixResolver, ResolvedDestination};
 use ruma::{
 	CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId,
 	OwnedRoomOrAliasId, OwnedServerName, RoomId, RoomVersionId, UInt,
@@ -1007,13 +1008,20 @@ pub(super) async fn resolve_true_destination(
 		);
 	}

-	let actual = self
-		.services
-		.resolver
-		.resolve_actual_dest(&server_name, !no_cache)
-		.await?;
+	let resolver: &MatrixResolver = if no_cache {
+		&MatrixResolver::new()?
+	} else {
+		&self.services.resolver.resolver
+	};

-	let msg = format!("Destination: {}\nHostname URI: {}", actual.dest, actual.host);
+	let actual = resolver.resolve_server(&server_name.as_str()).await?;
+
+	let destination = match actual.destination {
+		| ResolvedDestination::Literal(addr) => addr.to_string(),
+		| ResolvedDestination::Named(host, port) => format!("{host}:{port}"),
+	};
+
+	let msg = format!("Destination: {}\nHostname URI (SNI): {}", destination, actual.host);
 	self.write_str(&msg).await
 }

diff --git c/src/admin/query/resolver.rs i/src/admin/query/resolver.rs
index d651e5bff..e2cb5eca3 100644
--- c/src/admin/query/resolver.rs
+++ i/src/admin/query/resolver.rs
@@ -46,7 +46,7 @@ async fn destinations_cache(&self, server_name: Option<OwnedServerName>) -> Resu
 	writeln!(self, "| Server Name | Destination | Hostname | Expires |").await?;
 	writeln!(self, "| ----------- | ----------- | -------- | ------- |").await?;

-	let mut destinations = self.services.resolver.cache.destinations().boxed();
+	let mut destinations = self.services.resolver.dns.cache.destinations().boxed();

 	while let Some((name, CachedDest { dest, host, expire })) = destinations.next().await {
 		if let Some(server_name) = server_name.as_ref() {
@@ -70,7 +70,7 @@ async fn overrides_cache(&self, server_name: Option<String>) -> Result {
 	writeln!(self, "| Server Name | IP  | Port | Expires | Overriding |").await?;
 	writeln!(self, "| ----------- | --- | ----:| ------- | ---------- |").await?;

-	let mut overrides = self.services.resolver.cache.overrides().boxed();
+	let mut overrides = self.services.resolver.dns.cache.overrides().boxed();

 	while let Some((name, CachedOverride { ips, port, expire, overriding })) =
 		overrides.next().await
@@ -92,11 +92,11 @@ async fn overrides_cache(&self, server_name: Option<String>) -> Result {
 #[admin_command]
 async fn flush_cache(&self, name: Option<OwnedServerName>, all: bool) -> Result {
 	if all {
-		self.services.resolver.cache.clear().await;
+		self.services.resolver.dns.cache.clear().await;
 		writeln!(self, "Resolver caches cleared!").await
 	} else if let Some(name) = name {
-		self.services.resolver.cache.del_destination(&name);
-		self.services.resolver.cache.del_override(&name);
+		self.services.resolver.dns.cache.del_destination(&name);
+		self.services.resolver.dns.cache.del_override(&name);
 		self.write_str(&format!("Cleared {name} from resolver caches!"))
 			.await
 	} else {
diff --git c/src/core/Cargo.toml i/src/core/Cargo.toml
index 093b50f71..d99184b9d 100644
--- c/src/core/Cargo.toml
+++ i/src/core/Cargo.toml
@@ -117,6 +117,7 @@ url.workspace = true
 parking_lot.workspace = true
 lock_api.workspace = true
 hyper-util.workspace = true
+resolvematrix.workspace = true

 [target.'cfg(unix)'.dependencies]
 nix.workspace = true
diff --git c/src/core/error/mod.rs i/src/core/error/mod.rs
index 703726043..af7520c02 100644
--- c/src/core/error/mod.rs
+++ i/src/core/error/mod.rs
@@ -87,6 +87,8 @@ pub enum Error {
 	YamlDe(#[from] serde_saphyr::Error),
 	#[error(transparent)]
 	YamlSer(#[from] serde_saphyr::ser_error::Error),
+	#[error(transparent)]
+	ResolveServer(#[from] resolvematrix::server::ResolveServerError),

 	// ruma/conduwuit
 	#[error("Arithmetic operation failed: {0}")]
diff --git c/src/service/Cargo.toml i/src/service/Cargo.toml
index a0568db0b..0f63bd8ed 100644
--- c/src/service/Cargo.toml
+++ i/src/service/Cargo.toml
@@ -119,6 +119,7 @@ recaptcha-verify = { version = "0.2.0", default-features = false }
 reqwest_recaptcha = { package = "reqwest", version = "0.12.28", default-features = false, features = ["rustls-tls-native-roots-no-provider"]  } # As long as recaptcha-verify's reqwest is outdated
 yansi.workspace = true
 lettre.workspace = true
+resolvematrix.workspace = true

 [target.'cfg(all(unix, target_os = "linux"))'.dependencies]
 sd-notify.workspace = true
diff --git c/src/service/client/mod.rs i/src/service/client/mod.rs
index 4792bd7ad..b17aab9ab 100644
--- c/src/service/client/mod.rs
+++ i/src/service/client/mod.rs
@@ -43,7 +43,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {

 		Ok(Arc::new(Self {
 			default: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.build()?,

 			url_preview: base(config)
@@ -51,19 +51,19 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 					builder_interface(builder, url_preview_bind_iface.as_deref())
 				})?
 				.local_address(url_preview_bind_addr)
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.timeout(Duration::from_secs(config.url_preview_timeout))
 				.redirect(redirect::Policy::limited(3))
 				.user_agent(url_preview_user_agent)
 				.build()?,

 			extern_media: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.redirect(redirect::Policy::limited(3))
 				.build()?,

 			well_known: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(config.well_known_conn_timeout))
 				.read_timeout(Duration::from_secs(config.well_known_timeout))
 				.timeout(Duration::from_secs(config.well_known_timeout))
@@ -72,7 +72,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			federation: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.federation_timeout))
 				.timeout(Duration::from_secs(
@@ -86,7 +86,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			synapse: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.federation_timeout.saturating_mul(6)))
 				.timeout(Duration::from_secs(
@@ -100,7 +100,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			sender: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.sender_timeout))
 				.timeout(Duration::from_secs(config.sender_timeout))
@@ -110,7 +110,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			appservice: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(5))
 				.read_timeout(Duration::from_secs(config.appservice_timeout))
 				.timeout(Duration::from_secs(config.appservice_timeout))
@@ -120,7 +120,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			pusher: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(config.pusher_conn_timeout))
 				.timeout(Duration::from_secs(config.pusher_timeout))
 				.pool_max_idle_per_host(1)
diff --git c/src/service/federation/execute.rs i/src/service/federation/execute.rs
index 0c147c1ef..4318bb016 100644
--- c/src/service/federation/execute.rs
+++ i/src/service/federation/execute.rs
@@ -7,6 +7,7 @@
 };
 use ipaddress::IPAddress;
 use reqwest::{Client, Method, Request, Response, Url};
+use resolvematrix::server::Resolution;
 use ruma::{
 	ServerName,
 	api::{
@@ -132,7 +133,7 @@ pub async fn execute_on<'i, T, PathBuilderInput>(
 async fn perform<T>(
 	&self,
 	dest: &ServerName,
-	actual: &ActualDest,
+	actual: &Resolution,
 	request: Request,
 	client: &Client,
 ) -> Result<T::IncomingResponse>
@@ -168,7 +169,7 @@ fn validate_url(&self, url: &Url) -> Result<()> {
 async fn handle_response<T>(
 	&self,
 	dest: &ServerName,
-	actual: &ActualDest,
+	actual: &Resolution,
 	method: &Method,
 	url: &Url,
 	response: Response,
@@ -199,7 +200,7 @@ async fn handle_response<T>(

 async fn into_http_response(
 	dest: &ServerName,
-	actual: &ActualDest,
+	actual: &Resolution,
 	method: &Method,
 	url: &Url,
 	mut response: Response,
@@ -211,7 +212,7 @@ async fn into_http_response(
 		request_url = %url,
 		response_url = %response.url(),
 		"Received response from {}",
-		actual.string(),
+		actual.base_url(),
 	);

 	let mut http_response_builder = http::Response::builder()
@@ -248,7 +249,7 @@ async fn into_http_response(
 }

 fn handle_error(
-	actual: &ActualDest,
+	actual: &Resolution,
 	method: &Method,
 	url: &Url,
 	mut e: reqwest::Error,
diff --git c/src/service/resolver/actual.rs i/src/service/resolver/actual.rs
index 1ca3b595c..e69de29bb 100644
--- c/src/service/resolver/actual.rs
+++ i/src/service/resolver/actual.rs
@@ -1,441 +0,0 @@
-use std::fmt::Debug;
-
-use conduwuit::{Err, Result, debug, debug_info, err, error, trace};
-use futures::{FutureExt, TryFutureExt};
-use hickory_resolver::{
-	net::{DnsError, NetError},
-	proto::rr::rdata::SRV,
-};
-use ipaddress::IPAddress;
-use ruma::ServerName;
-
-use super::{
-	cache::{CachedDest, CachedOverride, MAX_IPS},
-	fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
-};
-
-const DEFAULT_PORT: u16 = 8448;
-
-#[derive(Clone, Debug)]
-pub(crate) struct ActualDest {
-	pub(crate) dest: FedDest,
-	pub(crate) host: String,
-}
-
-impl ActualDest {
-	#[inline]
-	pub(crate) fn string(&self) -> String { self.dest.https_string() }
-}
-
-impl super::Service {
-	#[tracing::instrument(skip_all, level = "debug", name = "resolve")]
-	pub(crate) async fn get_actual_dest(&self, server_name: &ServerName) -> Result<ActualDest> {
-		let (CachedDest { dest, host, .. }, _cached) =
-			self.lookup_actual_dest(server_name).await?;
-
-		Ok(ActualDest { dest, host })
-	}
-
-	pub(crate) async fn lookup_actual_dest(
-		&self,
-		server_name: &ServerName,
-	) -> Result<(CachedDest, bool)> {
-		if let Ok(result) = self.cache.get_destination(server_name).await {
-			return Ok((result, true));
-		}
-
-		let _dedup = self.resolving.lock(server_name.as_str());
-		if let Ok(result) = self.cache.get_destination(server_name).await {
-			return Ok((result, true));
-		}
-
-		self.resolve_actual_dest(server_name, true)
-			.inspect_ok(|result| self.cache.set_destination(server_name, result))
-			.map_ok(|result| (result, false))
-			.boxed()
-			.await
-	}
-
-	/// Returns: `actual_destination` + `Host` http header
-	#[tracing::instrument(name = "actual", level = "debug", skip(self, cache))]
-	pub async fn resolve_actual_dest(
-		&self,
-		dest: &ServerName,
-		cache: bool,
-	) -> Result<CachedDest> {
-		debug!(
-			dest = %dest,
-			cache = %cache,
-			"Resolving server name and port"
-		);
-		// Ensure dest is a valid connection endpoint
-		self.validate_dest(dest)?;
-
-		// Clippy believes this can be a clone, however we are actually converting
-		// ServerName to String
-		#[allow(clippy::implicit_clone)]
-		let mut host_header = dest.to_string().to_owned();
-		let actual_dest = self
-			.resolve_server_name(dest, cache, &mut host_header)
-			.await?;
-
-		host_header = ensure_host_has_port(&host_header).to_string();
-
-		debug!(
-			dest = %dest,
-			actual_dest = %actual_dest,
-			host = %host_header,
-			"Finished resolving server name"
-		);
-		Ok(CachedDest {
-			dest: actual_dest,
-			host: host_header,
-			expire: CachedDest::default_expire(),
-		})
-	}
-
-	/// Performs the server resolution steps as per the specification:
-	/// <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
-	async fn resolve_server_name(
-		&self,
-		dest: &ServerName,
-		cache: bool,
-		host: &mut String,
-	) -> Result<FedDest> {
-		// 1. If `dest` is an IP, use it directly. If a port is provided as well
-		//    (IP:port socket pair) use that, otherwise default to port 8448
-		if let Some(fed_dest) = get_ip_with_port(dest.as_str()) {
-			debug!("1: IP literal with provided or default port");
-			return Ok(fed_dest);
-		}
-
-		// 2. If `dest` is a hostname and has a provided port (format of `host:port`),
-		//    resolve the hostname to an IP address and connect it and the provided port
-		if dest.as_str().contains(':') {
-			return self.resolve_2_host_port(dest, cache).await;
-		}
-
-		// Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed
-		// either way https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
-		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, true)
-			.await?;
-
-		// Ensure server is running (not shutting down) before continuing resolution
-		self.services.server.check_running()?;
-
-		// 3. If `dest` is a hostname with no port, send GET to `https://<dest>/.well-known/matrix/server`.
-		//    If invalid JSON (throws error), skip to step 4. Otherwise, parse
-		//    `delegated` as `<hostname>[:<port>]` and...
-		if let Some(delegated) = self.request_well_known(dest.as_str()).await? {
-			return self.resolve_3_well_known(host, cache, delegated).await;
-		}
-
-		// 4. if .well-known errored, perform SRV (see 3.3)
-		if let Some(overrider) = self.query_srv_record(dest.as_str()).await? {
-			return self.resolve_4_srv_lookup(host, cache, overrider).await;
-		}
-
-		// 5. if .well-known errored and no SRV exists, resolve IP and connect on
-		//    default port (8448)
-		self.resolve_5_direct(dest, cache).await
-	}
-
-	/// Parse a host:port socket pair into separate parts, and resolve the
-	/// hostname into an IP address
-	async fn resolve_2_host_port(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
-		debug!("2: Hostname with included port");
-		let (host, port) = dest.as_str().split_once(':').unwrap();
-
-		self.conditional_query_and_cache(
-			host,
-			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		Ok(FedDest::Named(
-			host.to_owned(),
-			port.try_into().unwrap_or_else(|_| FedDest::default_port()),
-		))
-	}
-
-	async fn resolve_3_well_known(
-		&self,
-		host: &mut String,
-		cache: bool,
-		delegated: String,
-	) -> Result<FedDest> {
-		debug!("3: A .well-known file is available");
-		*host = add_port_to_hostname(&delegated).uri_string();
-
-		// 3.1 - If <delegated> is IP:port, connect to that,
-		//       or IP with default port if no port provided (8448)
-		if let Some(host_and_port) = get_ip_with_port(&delegated) {
-			debug!("3.1: IP with port in .well-known file");
-			return Ok(host_and_port);
-		}
-
-		// 3.2 - If <delegated> is hostname:port, lookup IP for hostname and connect
-		if delegated.contains(':') {
-			return self.resolve_3_2_hostname_port(cache, &delegated).await;
-		}
-
-		// 3.3 - If <delegated> is not an IP and there is no port, lookup SRV
-		// `_matrix._tcp.<delegated>` (which may provide a new hostname + port to use,
-		// see steps 3.1 and 3.2)
-		trace!("Delegated hostname has no port, querying SRV");
-		if let Some(overrider) = self.query_srv_record(&delegated).await? {
-			return self.resolve_3_3_use_srv(cache, &delegated, overrider).await;
-		}
-
-		self.resolve_3_4_use_default_port(cache, delegated).await
-	}
-
-	async fn resolve_3_2_hostname_port(&self, cache: bool, delegated: &str) -> Result<FedDest> {
-		debug!("3.2: Hostname with port in .well-known file");
-		let (host, port) = &delegated.split_once(':').unwrap();
-		self.conditional_query_and_cache(
-			host,
-			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		trace!("Successfully resolved IP for {delegated}");
-		Ok(FedDest::Named(
-			host.to_owned().to_owned(),
-			port.to_owned()
-				.try_into()
-				.unwrap_or_else(|_| FedDest::default_port()),
-		))
-	}
-
-	async fn resolve_3_3_use_srv(
-		&self,
-		cache: bool,
-		delegated: &String,
-		overrider: FedDest,
-	) -> Result<FedDest> {
-		debug!("3.3: SRV lookup successful");
-
-		let force_port = overrider.port();
-		self.conditional_query_and_cache_override(
-			delegated,
-			&overrider.hostname(),
-			force_port.unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		if let Some(port) = force_port {
-			return Ok(FedDest::Named(
-				delegated.to_owned(),
-				format!(":{port}")
-					.as_str()
-					.try_into()
-					.unwrap_or_else(|_| FedDest::default_port()),
-			));
-		}
-
-		Ok(add_port_to_hostname(delegated))
-	}
-
-	async fn resolve_3_4_use_default_port(
-		&self,
-		cache: bool,
-		delegated: String,
-	) -> Result<FedDest> {
-		debug!("3.4: No SRV records found, use the hostname from .well-known with default port");
-		self.conditional_query_and_cache(&delegated, DEFAULT_PORT, cache)
-			.await?;
-		Ok(add_port_to_hostname(&delegated))
-	}
-
-	async fn resolve_4_srv_lookup(
-		&self,
-		host: &str,
-		cache: bool,
-		overrider: FedDest,
-	) -> Result<FedDest> {
-		debug!("4: No .well-known; SRV record found");
-		let force_port = overrider.port();
-		self.conditional_query_and_cache_override(
-			host,
-			&overrider.hostname(),
-			force_port.unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		if let Some(port) = force_port {
-			let port = format!(":{port}");
-
-			return Ok(FedDest::Named(
-				host.to_owned(),
-				PortString::from(port.as_str()).unwrap_or_else(|_| FedDest::default_port()),
-			));
-		}
-
-		Ok(add_port_to_hostname(host))
-	}
-
-	async fn resolve_5_direct(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
-		debug!("5: No port provided and no SRV record found");
-		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, cache)
-			.await?;
-
-		Ok(add_port_to_hostname(dest.as_str()))
-	}
-
-	#[inline]
-	async fn conditional_query_and_cache(
-		&self,
-		hostname: &str,
-		port: u16,
-		cache: bool,
-	) -> Result {
-		self.conditional_query_and_cache_override(hostname, hostname, port, cache)
-			.await
-	}
-
-	#[inline]
-	async fn conditional_query_and_cache_override(
-		&self,
-		untername: &str,
-		hostname: &str,
-		port: u16,
-		cache: bool,
-	) -> Result {
-		if !cache {
-			return Ok(());
-		}
-
-		if self.cache.has_override(untername).await {
-			return Ok(());
-		}
-
-		self.query_and_cache_override(untername, hostname, port)
-			.await
-	}
-
-	#[tracing::instrument(name = "ip", level = "debug", skip(self))]
-	async fn query_and_cache_override(
-		&self,
-		untername: &'_ str,
-		hostname: &'_ str,
-		port: u16,
-	) -> Result {
-		self.services.server.check_running()?;
-
-		debug!("querying IP for {untername:?} ({hostname:?}:{port})");
-		match self.resolver.resolver.lookup_ip(hostname.to_owned()).await {
-			| Err(e) => Self::handle_resolve_error(&e, hostname),
-			| Ok(override_ip) => {
-				self.cache.set_override(untername, &CachedOverride {
-					ips: override_ip.into_iter().take(MAX_IPS).collect(),
-					port,
-					expire: CachedOverride::default_expire(),
-					overriding: (hostname != untername)
-						.then_some(hostname.into())
-						.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
-				});
-
-				Ok(())
-			},
-		}
-	}
-
-	#[tracing::instrument(name = "srv", level = "debug", skip(self))]
-	async fn query_srv_record(&self, hostname: &'_ str) -> Result<Option<FedDest>> {
-		let hostnames =
-			[format!("_matrix-fed._tcp.{hostname}."), format!("_matrix._tcp.{hostname}.")];
-
-		for hostname in hostnames {
-			self.services.server.check_running()?;
-
-			debug!("querying SRV for {hostname:?}");
-			let hostname = hostname.trim_end_matches('.');
-			match self.resolver.resolver.srv_lookup(hostname).await {
-				| Err(e) => Self::handle_resolve_error(&e, hostname)?,
-				| Ok(result) => {
-					return Ok(result.answers().iter().next().map(|result| {
-						let data = result.try_borrow::<SRV>().expect("should be SRV response");
-
-						FedDest::Named(
-							data.data()
-								.target
-								.to_string()
-								.trim_end_matches('.')
-								.to_owned(),
-							format!(":{}", data.data().port)
-								.as_str()
-								.try_into()
-								.unwrap_or_else(|_| FedDest::default_port()),
-						)
-					}));
-				},
-			}
-		}
-
-		Ok(None)
-	}
-
-	fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> {
-		match err {
-			| NetError::NoConnections => {
-				error!(
-					"Your DNS server is overloaded and has ran out of connections. It is \
-					 strongly recommended you remediate this issue to ensure proper federation \
-					 connectivity."
-				);
-
-				Err!(error!(%host, "DNS error: {err}"))
-			},
-			| NetError::Timeout => Err!(error!(%host, "DNS query timed out")),
-			| NetError::Dns(DnsError::NoRecordsFound(..)) => {
-				// Raise to debug_warn if we can find out the result wasn't from cache
-				debug!(%host, "No DNS records found: {err}");
-				Ok(())
-			},
-			| _ => Err!(error!(%host, "DNS error: {err}")),
-		}
-	}
-
-	/// Ensure `dest` is a valid destination (valid ip if it is an IP), and not
-	/// ourselves (unless in config)
-	fn validate_dest(&self, dest: &ServerName) -> Result<()> {
-		if dest == self.services.server.name && !self.services.server.config.federation_loopback {
-			return Err!("Won't send federation request to ourselves");
-		}
-
-		if dest.is_ip_literal() || IPAddress::is_valid(dest.host()) {
-			self.validate_dest_ip_literal(dest)?;
-		}
-
-		debug!(dest = %dest, "Valid destination for resolution");
-		Ok(())
-	}
-
-	fn validate_dest_ip_literal(&self, dest: &ServerName) -> Result<()> {
-		trace!("Destination is an IP literal, checking against IP range denylist.",);
-		debug_assert!(
-			dest.is_ip_literal() || !IPAddress::is_valid(dest.host()),
-			"Destination is not an IP literal."
-		);
-		let ip = IPAddress::parse(dest.host()).map_err(|e| {
-			err!(BadServerResponse(debug_error!("Failed to parse IP literal from string: {e}")))
-		})?;
-
-		self.validate_ip(&ip)?;
-
-		Ok(())
-	}
-
-	pub(crate) fn validate_ip(&self, ip: &IPAddress) -> Result<()> {
-		if !self.services.client.valid_cidr_range(ip) {
-			return Err!(BadServerResponse("Not allowed to send requests to this IP"));
-		}
-
-		Ok(())
-	}
-}
diff --git c/src/service/resolver/cache.rs i/src/service/resolver/cache.rs
index 6bad6402d..e775a72ac 100644
--- c/src/service/resolver/cache.rs
+++ i/src/service/resolver/cache.rs
@@ -4,7 +4,7 @@
 	Result,
 	arrayvec::ArrayVec,
 	at, err, implement,
-	utils::{math::Expected, rand, stream::TryIgnore},
+	utils::{math::Expected, stream::TryIgnore},
 };
 use database::{Cbor, Deserialized, Map};
 use futures::{Stream, StreamExt, future::join};
@@ -127,11 +127,6 @@ impl CachedDest {
 	#[must_use]
 	pub fn valid(&self) -> bool { self.expire > SystemTime::now() }

-	#[must_use]
-	pub(crate) fn default_expire() -> SystemTime {
-		rand::time_from_now_secs(60 * 60 * 18..60 * 60 * 36)
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn size(&self) -> usize {
@@ -147,11 +142,6 @@ impl CachedOverride {
 	#[must_use]
 	pub fn valid(&self) -> bool { self.expire > SystemTime::now() }

-	#[must_use]
-	pub(crate) fn default_expire() -> SystemTime {
-		rand::time_from_now_secs(60 * 60 * 6..60 * 60 * 12)
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn size(&self) -> usize { size_of_val(self) }
diff --git c/src/service/resolver/fed.rs i/src/service/resolver/fed.rs
index 83601a98a..f8068f596 100644
--- c/src/service/resolver/fed.rs
+++ i/src/service/resolver/fed.rs
@@ -1,8 +1,4 @@
-use std::{
-	borrow::Cow,
-	fmt,
-	net::{IpAddr, SocketAddr},
-};
+use std::{fmt, net::SocketAddr};

 use conduwuit::{arrayvec::ArrayString, utils::math::Expected};
 use serde::{Deserialize, Serialize};
@@ -18,50 +14,7 @@ pub enum FedDest {

 const DEFAULT_PORT: &str = ":8448";

-/// Attempt to parse `dest_str` as either an IP:port socket pair or as a plain
-/// IP (adding the default port), returning `None` if dest_str is neither a
-/// socket pair nor a plain IP.
-pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
-	if let Ok(dest) = dest_str.parse::<SocketAddr>() {
-		Some(FedDest::Literal(dest))
-	} else if let Ok(ip_addr) = dest_str.parse::<IpAddr>() {
-		Some(FedDest::Literal(SocketAddr::new(ip_addr, 8448)))
-	} else {
-		None
-	}
-}
-
-/// Convert a `dest` string with or without port into a FedDest with either
-/// the provided port (if host:port format) or the default port (8448)
-pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
-	let (host, port) = match dest.find(':') {
-		| None => (dest, DEFAULT_PORT),
-		| Some(pos) => dest.split_at(pos),
-	};
-
-	FedDest::Named(
-		host.to_owned(),
-		PortString::from(port).unwrap_or_else(|_| FedDest::default_port()),
-	)
-}
-
-/// Ensure `host` always has a port
-///
-/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain
-/// IP, in which case `add_port_to_hostname` adds it instead
-#[inline]
-pub(crate) fn ensure_host_has_port(host: &str) -> FedDest {
-	get_ip_with_port(host).unwrap_or_else(|| add_port_to_hostname(host))
-}
-
 impl FedDest {
-	pub(crate) fn https_string(&self) -> String {
-		match self {
-			| Self::Literal(addr) => format!("https://{addr}"),
-			| Self::Named(host, port) => format!("https://{host}{port}"),
-		}
-	}
-
 	pub(crate) fn uri_string(&self) -> String {
 		match self {
 			| Self::Literal(addr) => addr.to_string(),
@@ -69,23 +22,6 @@ pub(crate) fn uri_string(&self) -> String {
 		}
 	}

-	#[inline]
-	pub(crate) fn hostname(&self) -> Cow<'_, str> {
-		match &self {
-			| Self::Literal(addr) => addr.ip().to_string().into(),
-			| Self::Named(host, _) => host.into(),
-		}
-	}
-
-	#[inline]
-	#[allow(clippy::string_slice)]
-	pub(crate) fn port(&self) -> Option<u16> {
-		match &self {
-			| Self::Literal(addr) => Some(addr.port()),
-			| Self::Named(_, port) => port[1..].parse().ok(),
-		}
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn default_port() -> PortString {
diff --git c/src/service/resolver/mod.rs i/src/service/resolver/mod.rs
index c513cec9a..c24b8ba60 100644
--- c/src/service/resolver/mod.rs
+++ i/src/service/resolver/mod.rs
@@ -1,33 +1,31 @@
-pub mod actual;
 pub mod cache;
 mod dns;
 pub mod fed;
-#[cfg(test)]
-mod tests;
-mod well_known;

 use std::sync::Arc;

 use async_trait::async_trait;
-use conduwuit::{Result, Server, arrayvec::ArrayString, utils::MutexMap};
+use conduwuit::{Err, Result, implement};
+use ipaddress::IPAddress;
+use resolvematrix::server::MatrixResolver;

 use self::{cache::Cache, dns::Resolver};
 use crate::{Dep, client};

 pub struct Service {
-	pub cache: Arc<Cache>,
-	pub resolver: Arc<Resolver>,
-	resolving: Resolving,
+	pub resolver: MatrixResolver,
+	pub dns: Dns,
 	services: Services,
 }

 struct Services {
-	server: Arc<Server>,
 	client: Dep<client::Service>,
 }

-type Resolving = MutexMap<NameBuf, ()>;
-type NameBuf = ArrayString<256>;
+pub struct Dns {
+	pub cache: Arc<Cache>,
+	pub resolver: Arc<Resolver>,
+}

 #[async_trait]
 impl crate::Service for Service {
@@ -35,20 +33,31 @@ impl crate::Service for Service {
 	fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 		let cache = Cache::new(&args);
 		Ok(Arc::new(Self {
-			cache: cache.clone(),
-			resolver: Resolver::build(args.server, cache)?,
-			resolving: MutexMap::new(),
+			resolver: MatrixResolver::new()?,
+			dns: Dns {
+				cache: cache.clone(),
+				resolver: Resolver::build(args.server, cache)?,
+			},
 			services: Services {
-				server: args.server.clone(),
 				client: args.depend::<client::Service>("client"),
 			},
 		}))
 	}

 	async fn clear_cache(&self) {
-		self.resolver.clear_cache();
-		self.cache.clear().await;
+		// No ability to clean resolvematrix cache at the moment
+		self.dns.resolver.clear_cache();
+		self.dns.cache.clear().await;
 	}

-	fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
+	fn name(&self) -> &str { crate::service::make_name(module_path!()) }
+}
+
+#[implement(Service)]
+pub fn validate_ip(&self, ip: &IPAddress) -> Result<()> {
+	if !self.services.client.valid_cidr_range(ip) {
+		return Err!(BadServerResponse("Not allowed to send requests to this IP"));
+	}
+
+	Ok(())
 }
diff --git c/src/service/resolver/tests.rs i/src/service/resolver/tests.rs
deleted file mode 100644
index 068e08bd0..000000000
--- c/src/service/resolver/tests.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use super::fed::{FedDest, add_port_to_hostname, get_ip_with_port};
-
-#[test]
-fn ips_get_default_ports() {
-	assert_eq!(
-		get_ip_with_port("1.1.1.1"),
-		Some(FedDest::Literal("1.1.1.1:8448".parse().unwrap()))
-	);
-	assert_eq!(
-		get_ip_with_port("dead:beef::"),
-		Some(FedDest::Literal("[dead:beef::]:8448".parse().unwrap()))
-	);
-}
-
-#[test]
-fn ips_keep_custom_ports() {
-	assert_eq!(
-		get_ip_with_port("1.1.1.1:1234"),
-		Some(FedDest::Literal("1.1.1.1:1234".parse().unwrap()))
-	);
-	assert_eq!(
-		get_ip_with_port("[dead::beef]:8933"),
-		Some(FedDest::Literal("[dead::beef]:8933".parse().unwrap()))
-	);
-}
-
-#[test]
-fn hostnames_get_default_ports() {
-	assert_eq!(
-		add_port_to_hostname("example.com"),
-		FedDest::Named(String::from("example.com"), ":8448".try_into().unwrap())
-	);
-}
-
-#[test]
-fn hostnames_keep_custom_ports() {
-	assert_eq!(
-		add_port_to_hostname("example.com:1337"),
-		FedDest::Named(String::from("example.com"), ":1337".try_into().unwrap())
-	);
-}
diff --git c/src/service/resolver/well_known.rs i/src/service/resolver/well_known.rs
deleted file mode 100644
index 237c5cd09..000000000
--- c/src/service/resolver/well_known.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use conduwuit::{
-	Result, debug, debug_error, debug_info, implement, trace, utils::response::LimitReadExt,
-};
-use ruma::ServerName;
-
-#[implement(super::Service)]
-#[tracing::instrument(name = "well-known", level = "debug", skip(self, dest))]
-pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<String>> {
-	trace!("Requesting well known for {dest}");
-	let response = self
-		.services
-		.client
-		.well_known
-		.get(format!("https://{dest}/.well-known/matrix/server"))
-		.send()
-		.await;
-
-	trace!("response: {response:?}");
-	if let Err(e) = &response {
-		debug!("error: {e:?}");
-		return Ok(None);
-	}
-
-	let response = response?;
-	if !response.status().is_success() {
-		debug!("response not 2XX");
-		return Ok(None);
-	}
-
-	let Ok(text) = response.limit_read_text(8192).await else {
-		debug!("failed to read well-known response (too large or non-text content)");
-		return Ok(None);
-	};
-	trace!("response text: {text:?}");
-
-	let body: serde_json::Value = serde_json::from_str(&text).unwrap_or_default();
-
-	let m_server = body
-		.get("m.server")
-		.unwrap_or(&serde_json::Value::Null)
-		.as_str()
-		.unwrap_or_default();
-
-	if ServerName::parse(m_server).is_err() {
-		debug_error!("response content missing or invalid");
-		return Ok(None);
-	}
-
-	debug_info!("{dest:?} found at {m_server:?}");
-	Ok(Some(m_server.to_owned()))
-}

# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	src/admin/debug/commands.rs
#	src/admin/query/resolver.rs
#	src/service/Cargo.toml
#	src/service/client/mod.rs
#	src/service/federation/execute.rs
#	src/service/resolver/cache.rs
#	src/service/resolver/well_known.rs

diff --git c/Cargo.toml i/Cargo.toml
index 09e2f93cb..f89a5e010 100644
--- c/Cargo.toml
+++ i/Cargo.toml
@@ -560,6 +560,9 @@ features = ["std"]
 [workspace.dependencies.nonzero_ext]
 version = "0.3.0"

+[workspace.dependencies.resolvematrix]
+version = "0.1.0"
+
 [workspace.dependencies.serde_urlencoded]
 version = "0.7.1"

diff --git c/src/admin/Cargo.toml i/src/admin/Cargo.toml
index 4afed12b4..1f82978a4 100644
--- c/src/admin/Cargo.toml
+++ i/src/admin/Cargo.toml
@@ -92,6 +92,7 @@ serde-saphyr.workspace = true
 tokio.workspace = true
 tracing-subscriber.workspace = true
 tracing.workspace = true
+resolvematrix.workspace = true

 [lints]
 workspace = true
diff --git c/src/admin/debug/commands.rs i/src/admin/debug/commands.rs
index d1e5c2544..290189859 100644
--- c/src/admin/debug/commands.rs
+++ i/src/admin/debug/commands.rs
@@ -20,6 +20,7 @@
 };
 use futures::{FutureExt, StreamExt, TryStreamExt};
 use lettre::message::Mailbox;
+use resolvematrix::server::{MatrixResolver, ResolvedDestination};
 use ruma::{
 	CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId,
 	OwnedRoomOrAliasId, OwnedServerName, RoomId, RoomVersionId, UInt,
@@ -1005,15 +1006,22 @@ pub(super) async fn resolve_true_destination(
 			);
 		}

-		let actual = self
-			.services
-			.resolver
-			.resolve_actual_dest(&server_name, !no_cache)
-			.await?;
+	let resolver: &MatrixResolver = if no_cache {
+		&MatrixResolver::new()?
+	} else {
+		&self.services.resolver.resolver
+	};

-		let msg = format!("Destination: {}\nHostname URI: {}", actual.dest, actual.host);
-		self.write_str(&msg).await
-	}
+	let actual = resolver.resolve_server(&server_name.as_str()).await?;
+
+	let destination = match actual.destination {
+		| ResolvedDestination::Literal(addr) => addr.to_string(),
+		| ResolvedDestination::Named(host, port) => format!("{host}:{port}"),
+	};
+
+	let msg = format!("Destination: {}\nHostname URI (SNI): {}", destination, actual.host);
+	self.write_str(&msg).await
+}

 	pub(super) async fn memory_stats(&self, opts: Option<String>) -> Result {
 		const OPTS: &str = "abcdefghijklmnopqrstuvwxyz";
diff --git c/src/admin/query/resolver.rs i/src/admin/query/resolver.rs
index 7e5a4b40d..4a88650f8 100644
--- c/src/admin/query/resolver.rs
+++ i/src/admin/query/resolver.rs
@@ -46,7 +46,7 @@ async fn destinations_cache(&self, server_name: Option<OwnedServerName>) -> Resu
 		writeln!(self, "| Server Name | Destination | Hostname | Expires |").await?;
 		writeln!(self, "| ----------- | ----------- | -------- | ------- |").await?;

-		let mut destinations = self.services.resolver.cache.destinations().boxed();
+	    let mut destinations = self.services.resolver.dns.cache.destinations().boxed();

 		while let Some((name, CachedDest { dest, host, expire })) = destinations.next().await {
 			if let Some(server_name) = server_name.as_ref() {
@@ -69,7 +69,7 @@ async fn overrides_cache(&self, server_name: Option<String>) -> Result {
 		writeln!(self, "| Server Name | IP  | Port | Expires | Overriding |").await?;
 		writeln!(self, "| ----------- | --- | ----:| ------- | ---------- |").await?;

-		let mut overrides = self.services.resolver.cache.overrides().boxed();
+		let mut overrides = self.services.resolver.dns.cache.overrides().boxed();

 		while let Some((name, CachedOverride { ips, port, expire, overriding })) =
 			overrides.next().await
@@ -92,11 +92,11 @@ async fn overrides_cache(&self, server_name: Option<String>) -> Result {

 	async fn flush_cache(&self, name: Option<OwnedServerName>, all: bool) -> Result {
 		if all {
-			self.services.resolver.cache.clear().await;
+			self.services.resolver.dns.cache.clear().await;
 			writeln!(self, "Resolver caches cleared!").await
 		} else if let Some(name) = name {
-			self.services.resolver.cache.del_destination(&name);
-			self.services.resolver.cache.del_override(&name);
+			self.services.resolver.dns.cache.del_destination(&name);
+			self.services.resolver.dns.cache.del_override(&name);
 			self.write_str(&format!("Cleared {name} from resolver caches!"))
 				.await
 		} else {
diff --git c/src/core/Cargo.toml i/src/core/Cargo.toml
index 093b50f71..d99184b9d 100644
--- c/src/core/Cargo.toml
+++ i/src/core/Cargo.toml
@@ -117,6 +117,7 @@ url.workspace = true
 parking_lot.workspace = true
 lock_api.workspace = true
 hyper-util.workspace = true
+resolvematrix.workspace = true

 [target.'cfg(unix)'.dependencies]
 nix.workspace = true
diff --git c/src/core/error/mod.rs i/src/core/error/mod.rs
index d61867b01..813324912 100644
--- c/src/core/error/mod.rs
+++ i/src/core/error/mod.rs
@@ -87,6 +87,8 @@ pub enum Error {
 	YamlDe(#[from] serde_saphyr::Error),
 	#[error(transparent)]
 	YamlSer(#[from] serde_saphyr::ser_error::Error),
+	#[error(transparent)]
+	ResolveServer(#[from] resolvematrix::server::ResolveServerError),

 	// ruma/conduwuit
 	#[error("Arithmetic operation failed: {0}")]
diff --git c/src/service/Cargo.toml i/src/service/Cargo.toml
index e302ff6c9..923fef2cb 100644
--- c/src/service/Cargo.toml
+++ i/src/service/Cargo.toml
@@ -119,6 +119,7 @@ recaptcha-verify = { version = "0.2.0", default-features = false }
 reqwest_recaptcha = { package = "reqwest", version = "0.12.28", default-features = false, features = ["rustls-tls-native-roots-no-provider"]  } # As long as recaptcha-verify's reqwest is outdated
 yansi.workspace = true
 lettre.workspace = true
+resolvematrix.workspace = true
 serde_urlencoded.workspace = true

 [target.'cfg(all(unix, target_os = "linux"))'.dependencies]
diff --git c/src/service/client/mod.rs i/src/service/client/mod.rs
index b4c645ba2..4a299fee3 100644
--- c/src/service/client/mod.rs
+++ i/src/service/client/mod.rs
@@ -43,7 +43,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {

 		Ok(Arc::new(Self {
 			default: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.build()?,

 			url_preview: base(config)
@@ -51,19 +51,19 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 					builder_interface(builder, url_preview_bind_iface.as_deref())
 				})?
 				.local_address(url_preview_bind_addr)
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.timeout(Duration::from_secs(config.url_preview_timeout))
 				.redirect(redirect::Policy::limited(3))
 				.user_agent(url_preview_user_agent)
 				.build()?,

 			extern_media: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.redirect(redirect::Policy::limited(3))
 				.build()?,

 			well_known: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(config.well_known_conn_timeout))
 				.read_timeout(Duration::from_secs(config.well_known_timeout))
 				.timeout(Duration::from_secs(config.well_known_timeout))
@@ -72,7 +72,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			federation: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.federation_timeout))
 				.timeout(Duration::from_secs(
@@ -86,7 +86,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			federation_slow: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.federation_timeout.saturating_mul(6)))
 				.timeout(Duration::from_secs(
@@ -100,7 +100,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			sender: base(config)?
-				.dns_resolver(resolver.resolver.hooked.clone())
+				.dns_resolver(resolver.dns.resolver.hooked.clone())
 				.connect_timeout(Duration::from_secs(config.federation_conn_timeout))
 				.read_timeout(Duration::from_secs(config.sender_timeout))
 				.timeout(Duration::from_secs(config.sender_timeout))
@@ -110,7 +110,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			appservice: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(5))
 				.read_timeout(Duration::from_secs(config.appservice_timeout))
 				.timeout(Duration::from_secs(config.appservice_timeout))
@@ -120,7 +120,7 @@ fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 				.build()?,

 			pusher: base(config)?
-				.dns_resolver(resolver.resolver.clone())
+				.dns_resolver(resolver.dns.resolver.clone())
 				.connect_timeout(Duration::from_secs(config.pusher_conn_timeout))
 				.timeout(Duration::from_secs(config.pusher_timeout))
 				.pool_max_idle_per_host(1)
diff --git c/src/service/federation/execute.rs i/src/service/federation/execute.rs
index 70bef2f0e..d843f9ad4 100644
--- c/src/service/federation/execute.rs
+++ i/src/service/federation/execute.rs
@@ -7,6 +7,7 @@
 };
 use ipaddress::IPAddress;
 use reqwest::{Client, Method, Request, Response, Url};
+use resolvematrix::resolution::Resolution;
 use ruma::{
 	ServerName,
 	api::{
@@ -150,7 +151,7 @@ pub async fn execute_on<'i, T, PathBuilderInput>(
 	async fn perform<T>(
 		&self,
 		dest: &ServerName,
-		actual: &ActualDest,
+		actual: &Resolution,
 		request: Request,
 		client: &Client,
 	) -> Result<T::IncomingResponse>
@@ -198,7 +199,7 @@ fn validate_url(&self, url: &Url) -> Result<()> {
 	async fn handle_response<T>(
 		&self,
 		dest: &ServerName,
-		actual: &ActualDest,
+		actual: &Resolution,
 		method: &Method,
 		url: &Url,
 		response: Response,
@@ -231,7 +232,7 @@ async fn handle_response<T>(

 async fn into_http_response(
 	dest: &ServerName,
-	actual: &ActualDest,
+	actual: &Resolution,
 	method: &Method,
 	url: &Url,
 	mut response: Response,
@@ -243,7 +244,7 @@ async fn into_http_response(
 		request_url = %url,
 		response_url = %response.url(),
 		"Received response from {}",
-		actual.string(),
+		actual.base_url(),
 	);

 	let mut http_response_builder = http::Response::builder()
@@ -280,7 +281,7 @@ async fn into_http_response(
 }

 fn handle_error(
-	actual: &ActualDest,
+	actual: &Resolution,
 	method: &Method,
 	url: &Url,
 	mut e: reqwest::Error,
diff --git c/src/service/resolver/actual.rs i/src/service/resolver/actual.rs
index 1ca3b595c..e69de29bb 100644
--- c/src/service/resolver/actual.rs
+++ i/src/service/resolver/actual.rs
@@ -1,441 +0,0 @@
-use std::fmt::Debug;
-
-use conduwuit::{Err, Result, debug, debug_info, err, error, trace};
-use futures::{FutureExt, TryFutureExt};
-use hickory_resolver::{
-	net::{DnsError, NetError},
-	proto::rr::rdata::SRV,
-};
-use ipaddress::IPAddress;
-use ruma::ServerName;
-
-use super::{
-	cache::{CachedDest, CachedOverride, MAX_IPS},
-	fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
-};
-
-const DEFAULT_PORT: u16 = 8448;
-
-#[derive(Clone, Debug)]
-pub(crate) struct ActualDest {
-	pub(crate) dest: FedDest,
-	pub(crate) host: String,
-}
-
-impl ActualDest {
-	#[inline]
-	pub(crate) fn string(&self) -> String { self.dest.https_string() }
-}
-
-impl super::Service {
-	#[tracing::instrument(skip_all, level = "debug", name = "resolve")]
-	pub(crate) async fn get_actual_dest(&self, server_name: &ServerName) -> Result<ActualDest> {
-		let (CachedDest { dest, host, .. }, _cached) =
-			self.lookup_actual_dest(server_name).await?;
-
-		Ok(ActualDest { dest, host })
-	}
-
-	pub(crate) async fn lookup_actual_dest(
-		&self,
-		server_name: &ServerName,
-	) -> Result<(CachedDest, bool)> {
-		if let Ok(result) = self.cache.get_destination(server_name).await {
-			return Ok((result, true));
-		}
-
-		let _dedup = self.resolving.lock(server_name.as_str());
-		if let Ok(result) = self.cache.get_destination(server_name).await {
-			return Ok((result, true));
-		}
-
-		self.resolve_actual_dest(server_name, true)
-			.inspect_ok(|result| self.cache.set_destination(server_name, result))
-			.map_ok(|result| (result, false))
-			.boxed()
-			.await
-	}
-
-	/// Returns: `actual_destination` + `Host` http header
-	#[tracing::instrument(name = "actual", level = "debug", skip(self, cache))]
-	pub async fn resolve_actual_dest(
-		&self,
-		dest: &ServerName,
-		cache: bool,
-	) -> Result<CachedDest> {
-		debug!(
-			dest = %dest,
-			cache = %cache,
-			"Resolving server name and port"
-		);
-		// Ensure dest is a valid connection endpoint
-		self.validate_dest(dest)?;
-
-		// Clippy believes this can be a clone, however we are actually converting
-		// ServerName to String
-		#[allow(clippy::implicit_clone)]
-		let mut host_header = dest.to_string().to_owned();
-		let actual_dest = self
-			.resolve_server_name(dest, cache, &mut host_header)
-			.await?;
-
-		host_header = ensure_host_has_port(&host_header).to_string();
-
-		debug!(
-			dest = %dest,
-			actual_dest = %actual_dest,
-			host = %host_header,
-			"Finished resolving server name"
-		);
-		Ok(CachedDest {
-			dest: actual_dest,
-			host: host_header,
-			expire: CachedDest::default_expire(),
-		})
-	}
-
-	/// Performs the server resolution steps as per the specification:
-	/// <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
-	async fn resolve_server_name(
-		&self,
-		dest: &ServerName,
-		cache: bool,
-		host: &mut String,
-	) -> Result<FedDest> {
-		// 1. If `dest` is an IP, use it directly. If a port is provided as well
-		//    (IP:port socket pair) use that, otherwise default to port 8448
-		if let Some(fed_dest) = get_ip_with_port(dest.as_str()) {
-			debug!("1: IP literal with provided or default port");
-			return Ok(fed_dest);
-		}
-
-		// 2. If `dest` is a hostname and has a provided port (format of `host:port`),
-		//    resolve the hostname to an IP address and connect it and the provided port
-		if dest.as_str().contains(':') {
-			return self.resolve_2_host_port(dest, cache).await;
-		}
-
-		// Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed
-		// either way https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
-		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, true)
-			.await?;
-
-		// Ensure server is running (not shutting down) before continuing resolution
-		self.services.server.check_running()?;
-
-		// 3. If `dest` is a hostname with no port, send GET to `https://<dest>/.well-known/matrix/server`.
-		//    If invalid JSON (throws error), skip to step 4. Otherwise, parse
-		//    `delegated` as `<hostname>[:<port>]` and...
-		if let Some(delegated) = self.request_well_known(dest.as_str()).await? {
-			return self.resolve_3_well_known(host, cache, delegated).await;
-		}
-
-		// 4. if .well-known errored, perform SRV (see 3.3)
-		if let Some(overrider) = self.query_srv_record(dest.as_str()).await? {
-			return self.resolve_4_srv_lookup(host, cache, overrider).await;
-		}
-
-		// 5. if .well-known errored and no SRV exists, resolve IP and connect on
-		//    default port (8448)
-		self.resolve_5_direct(dest, cache).await
-	}
-
-	/// Parse a host:port socket pair into separate parts, and resolve the
-	/// hostname into an IP address
-	async fn resolve_2_host_port(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
-		debug!("2: Hostname with included port");
-		let (host, port) = dest.as_str().split_once(':').unwrap();
-
-		self.conditional_query_and_cache(
-			host,
-			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		Ok(FedDest::Named(
-			host.to_owned(),
-			port.try_into().unwrap_or_else(|_| FedDest::default_port()),
-		))
-	}
-
-	async fn resolve_3_well_known(
-		&self,
-		host: &mut String,
-		cache: bool,
-		delegated: String,
-	) -> Result<FedDest> {
-		debug!("3: A .well-known file is available");
-		*host = add_port_to_hostname(&delegated).uri_string();
-
-		// 3.1 - If <delegated> is IP:port, connect to that,
-		//       or IP with default port if no port provided (8448)
-		if let Some(host_and_port) = get_ip_with_port(&delegated) {
-			debug!("3.1: IP with port in .well-known file");
-			return Ok(host_and_port);
-		}
-
-		// 3.2 - If <delegated> is hostname:port, lookup IP for hostname and connect
-		if delegated.contains(':') {
-			return self.resolve_3_2_hostname_port(cache, &delegated).await;
-		}
-
-		// 3.3 - If <delegated> is not an IP and there is no port, lookup SRV
-		// `_matrix._tcp.<delegated>` (which may provide a new hostname + port to use,
-		// see steps 3.1 and 3.2)
-		trace!("Delegated hostname has no port, querying SRV");
-		if let Some(overrider) = self.query_srv_record(&delegated).await? {
-			return self.resolve_3_3_use_srv(cache, &delegated, overrider).await;
-		}
-
-		self.resolve_3_4_use_default_port(cache, delegated).await
-	}
-
-	async fn resolve_3_2_hostname_port(&self, cache: bool, delegated: &str) -> Result<FedDest> {
-		debug!("3.2: Hostname with port in .well-known file");
-		let (host, port) = &delegated.split_once(':').unwrap();
-		self.conditional_query_and_cache(
-			host,
-			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		trace!("Successfully resolved IP for {delegated}");
-		Ok(FedDest::Named(
-			host.to_owned().to_owned(),
-			port.to_owned()
-				.try_into()
-				.unwrap_or_else(|_| FedDest::default_port()),
-		))
-	}
-
-	async fn resolve_3_3_use_srv(
-		&self,
-		cache: bool,
-		delegated: &String,
-		overrider: FedDest,
-	) -> Result<FedDest> {
-		debug!("3.3: SRV lookup successful");
-
-		let force_port = overrider.port();
-		self.conditional_query_and_cache_override(
-			delegated,
-			&overrider.hostname(),
-			force_port.unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		if let Some(port) = force_port {
-			return Ok(FedDest::Named(
-				delegated.to_owned(),
-				format!(":{port}")
-					.as_str()
-					.try_into()
-					.unwrap_or_else(|_| FedDest::default_port()),
-			));
-		}
-
-		Ok(add_port_to_hostname(delegated))
-	}
-
-	async fn resolve_3_4_use_default_port(
-		&self,
-		cache: bool,
-		delegated: String,
-	) -> Result<FedDest> {
-		debug!("3.4: No SRV records found, use the hostname from .well-known with default port");
-		self.conditional_query_and_cache(&delegated, DEFAULT_PORT, cache)
-			.await?;
-		Ok(add_port_to_hostname(&delegated))
-	}
-
-	async fn resolve_4_srv_lookup(
-		&self,
-		host: &str,
-		cache: bool,
-		overrider: FedDest,
-	) -> Result<FedDest> {
-		debug!("4: No .well-known; SRV record found");
-		let force_port = overrider.port();
-		self.conditional_query_and_cache_override(
-			host,
-			&overrider.hostname(),
-			force_port.unwrap_or(DEFAULT_PORT),
-			cache,
-		)
-		.await?;
-
-		if let Some(port) = force_port {
-			let port = format!(":{port}");
-
-			return Ok(FedDest::Named(
-				host.to_owned(),
-				PortString::from(port.as_str()).unwrap_or_else(|_| FedDest::default_port()),
-			));
-		}
-
-		Ok(add_port_to_hostname(host))
-	}
-
-	async fn resolve_5_direct(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
-		debug!("5: No port provided and no SRV record found");
-		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, cache)
-			.await?;
-
-		Ok(add_port_to_hostname(dest.as_str()))
-	}
-
-	#[inline]
-	async fn conditional_query_and_cache(
-		&self,
-		hostname: &str,
-		port: u16,
-		cache: bool,
-	) -> Result {
-		self.conditional_query_and_cache_override(hostname, hostname, port, cache)
-			.await
-	}
-
-	#[inline]
-	async fn conditional_query_and_cache_override(
-		&self,
-		untername: &str,
-		hostname: &str,
-		port: u16,
-		cache: bool,
-	) -> Result {
-		if !cache {
-			return Ok(());
-		}
-
-		if self.cache.has_override(untername).await {
-			return Ok(());
-		}
-
-		self.query_and_cache_override(untername, hostname, port)
-			.await
-	}
-
-	#[tracing::instrument(name = "ip", level = "debug", skip(self))]
-	async fn query_and_cache_override(
-		&self,
-		untername: &'_ str,
-		hostname: &'_ str,
-		port: u16,
-	) -> Result {
-		self.services.server.check_running()?;
-
-		debug!("querying IP for {untername:?} ({hostname:?}:{port})");
-		match self.resolver.resolver.lookup_ip(hostname.to_owned()).await {
-			| Err(e) => Self::handle_resolve_error(&e, hostname),
-			| Ok(override_ip) => {
-				self.cache.set_override(untername, &CachedOverride {
-					ips: override_ip.into_iter().take(MAX_IPS).collect(),
-					port,
-					expire: CachedOverride::default_expire(),
-					overriding: (hostname != untername)
-						.then_some(hostname.into())
-						.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
-				});
-
-				Ok(())
-			},
-		}
-	}
-
-	#[tracing::instrument(name = "srv", level = "debug", skip(self))]
-	async fn query_srv_record(&self, hostname: &'_ str) -> Result<Option<FedDest>> {
-		let hostnames =
-			[format!("_matrix-fed._tcp.{hostname}."), format!("_matrix._tcp.{hostname}.")];
-
-		for hostname in hostnames {
-			self.services.server.check_running()?;
-
-			debug!("querying SRV for {hostname:?}");
-			let hostname = hostname.trim_end_matches('.');
-			match self.resolver.resolver.srv_lookup(hostname).await {
-				| Err(e) => Self::handle_resolve_error(&e, hostname)?,
-				| Ok(result) => {
-					return Ok(result.answers().iter().next().map(|result| {
-						let data = result.try_borrow::<SRV>().expect("should be SRV response");
-
-						FedDest::Named(
-							data.data()
-								.target
-								.to_string()
-								.trim_end_matches('.')
-								.to_owned(),
-							format!(":{}", data.data().port)
-								.as_str()
-								.try_into()
-								.unwrap_or_else(|_| FedDest::default_port()),
-						)
-					}));
-				},
-			}
-		}
-
-		Ok(None)
-	}
-
-	fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> {
-		match err {
-			| NetError::NoConnections => {
-				error!(
-					"Your DNS server is overloaded and has ran out of connections. It is \
-					 strongly recommended you remediate this issue to ensure proper federation \
-					 connectivity."
-				);
-
-				Err!(error!(%host, "DNS error: {err}"))
-			},
-			| NetError::Timeout => Err!(error!(%host, "DNS query timed out")),
-			| NetError::Dns(DnsError::NoRecordsFound(..)) => {
-				// Raise to debug_warn if we can find out the result wasn't from cache
-				debug!(%host, "No DNS records found: {err}");
-				Ok(())
-			},
-			| _ => Err!(error!(%host, "DNS error: {err}")),
-		}
-	}
-
-	/// Ensure `dest` is a valid destination (valid ip if it is an IP), and not
-	/// ourselves (unless in config)
-	fn validate_dest(&self, dest: &ServerName) -> Result<()> {
-		if dest == self.services.server.name && !self.services.server.config.federation_loopback {
-			return Err!("Won't send federation request to ourselves");
-		}
-
-		if dest.is_ip_literal() || IPAddress::is_valid(dest.host()) {
-			self.validate_dest_ip_literal(dest)?;
-		}
-
-		debug!(dest = %dest, "Valid destination for resolution");
-		Ok(())
-	}
-
-	fn validate_dest_ip_literal(&self, dest: &ServerName) -> Result<()> {
-		trace!("Destination is an IP literal, checking against IP range denylist.",);
-		debug_assert!(
-			dest.is_ip_literal() || !IPAddress::is_valid(dest.host()),
-			"Destination is not an IP literal."
-		);
-		let ip = IPAddress::parse(dest.host()).map_err(|e| {
-			err!(BadServerResponse(debug_error!("Failed to parse IP literal from string: {e}")))
-		})?;
-
-		self.validate_ip(&ip)?;
-
-		Ok(())
-	}
-
-	pub(crate) fn validate_ip(&self, ip: &IPAddress) -> Result<()> {
-		if !self.services.client.valid_cidr_range(ip) {
-			return Err!(BadServerResponse("Not allowed to send requests to this IP"));
-		}
-
-		Ok(())
-	}
-}
diff --git c/src/service/resolver/cache.rs i/src/service/resolver/cache.rs
index b0268a3cd..6ec0b5b4d 100644
--- c/src/service/resolver/cache.rs
+++ i/src/service/resolver/cache.rs
@@ -4,7 +4,7 @@
 	Result,
 	arrayvec::ArrayVec,
 	at, err,
-	utils::{math::Expected, rand, stream::TryIgnore},
+	utils::{math::Expected, stream::TryIgnore},
 };
 use database::{Cbor, Deserialized, Map};
 use futures::{Stream, StreamExt, future::join};
@@ -114,11 +114,6 @@ impl CachedDest {
 	#[must_use]
 	pub fn valid(&self) -> bool { self.expire > SystemTime::now() }

-	#[must_use]
-	pub(crate) fn default_expire() -> SystemTime {
-		rand::time_from_now_secs(60 * 60 * 18..60 * 60 * 36)
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn size(&self) -> usize {
@@ -134,11 +129,6 @@ impl CachedOverride {
 	#[must_use]
 	pub fn valid(&self) -> bool { self.expire > SystemTime::now() }

-	#[must_use]
-	pub(crate) fn default_expire() -> SystemTime {
-		rand::time_from_now_secs(60 * 60 * 6..60 * 60 * 12)
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn size(&self) -> usize { size_of_val(self) }
diff --git c/src/service/resolver/fed.rs i/src/service/resolver/fed.rs
index 83601a98a..f8068f596 100644
--- c/src/service/resolver/fed.rs
+++ i/src/service/resolver/fed.rs
@@ -1,8 +1,4 @@
-use std::{
-	borrow::Cow,
-	fmt,
-	net::{IpAddr, SocketAddr},
-};
+use std::{fmt, net::SocketAddr};

 use conduwuit::{arrayvec::ArrayString, utils::math::Expected};
 use serde::{Deserialize, Serialize};
@@ -18,50 +14,7 @@ pub enum FedDest {

 const DEFAULT_PORT: &str = ":8448";

-/// Attempt to parse `dest_str` as either an IP:port socket pair or as a plain
-/// IP (adding the default port), returning `None` if dest_str is neither a
-/// socket pair nor a plain IP.
-pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
-	if let Ok(dest) = dest_str.parse::<SocketAddr>() {
-		Some(FedDest::Literal(dest))
-	} else if let Ok(ip_addr) = dest_str.parse::<IpAddr>() {
-		Some(FedDest::Literal(SocketAddr::new(ip_addr, 8448)))
-	} else {
-		None
-	}
-}
-
-/// Convert a `dest` string with or without port into a FedDest with either
-/// the provided port (if host:port format) or the default port (8448)
-pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
-	let (host, port) = match dest.find(':') {
-		| None => (dest, DEFAULT_PORT),
-		| Some(pos) => dest.split_at(pos),
-	};
-
-	FedDest::Named(
-		host.to_owned(),
-		PortString::from(port).unwrap_or_else(|_| FedDest::default_port()),
-	)
-}
-
-/// Ensure `host` always has a port
-///
-/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain
-/// IP, in which case `add_port_to_hostname` adds it instead
-#[inline]
-pub(crate) fn ensure_host_has_port(host: &str) -> FedDest {
-	get_ip_with_port(host).unwrap_or_else(|| add_port_to_hostname(host))
-}
-
 impl FedDest {
-	pub(crate) fn https_string(&self) -> String {
-		match self {
-			| Self::Literal(addr) => format!("https://{addr}"),
-			| Self::Named(host, port) => format!("https://{host}{port}"),
-		}
-	}
-
 	pub(crate) fn uri_string(&self) -> String {
 		match self {
 			| Self::Literal(addr) => addr.to_string(),
@@ -69,23 +22,6 @@ pub(crate) fn uri_string(&self) -> String {
 		}
 	}

-	#[inline]
-	pub(crate) fn hostname(&self) -> Cow<'_, str> {
-		match &self {
-			| Self::Literal(addr) => addr.ip().to_string().into(),
-			| Self::Named(host, _) => host.into(),
-		}
-	}
-
-	#[inline]
-	#[allow(clippy::string_slice)]
-	pub(crate) fn port(&self) -> Option<u16> {
-		match &self {
-			| Self::Literal(addr) => Some(addr.port()),
-			| Self::Named(_, port) => port[1..].parse().ok(),
-		}
-	}
-
 	#[inline]
 	#[must_use]
 	pub fn default_port() -> PortString {
diff --git c/src/service/resolver/mod.rs i/src/service/resolver/mod.rs
index c513cec9a..c24b8ba60 100644
--- c/src/service/resolver/mod.rs
+++ i/src/service/resolver/mod.rs
@@ -1,33 +1,31 @@
-pub mod actual;
 pub mod cache;
 mod dns;
 pub mod fed;
-#[cfg(test)]
-mod tests;
-mod well_known;

 use std::sync::Arc;

 use async_trait::async_trait;
-use conduwuit::{Result, Server, arrayvec::ArrayString, utils::MutexMap};
+use conduwuit::{Err, Result, implement};
+use ipaddress::IPAddress;
+use resolvematrix::server::MatrixResolver;

 use self::{cache::Cache, dns::Resolver};
 use crate::{Dep, client};

 pub struct Service {
-	pub cache: Arc<Cache>,
-	pub resolver: Arc<Resolver>,
-	resolving: Resolving,
+	pub resolver: MatrixResolver,
+	pub dns: Dns,
 	services: Services,
 }

 struct Services {
-	server: Arc<Server>,
 	client: Dep<client::Service>,
 }

-type Resolving = MutexMap<NameBuf, ()>;
-type NameBuf = ArrayString<256>;
+pub struct Dns {
+	pub cache: Arc<Cache>,
+	pub resolver: Arc<Resolver>,
+}

 #[async_trait]
 impl crate::Service for Service {
@@ -35,20 +33,31 @@ impl crate::Service for Service {
 	fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
 		let cache = Cache::new(&args);
 		Ok(Arc::new(Self {
-			cache: cache.clone(),
-			resolver: Resolver::build(args.server, cache)?,
-			resolving: MutexMap::new(),
+			resolver: MatrixResolver::new()?,
+			dns: Dns {
+				cache: cache.clone(),
+				resolver: Resolver::build(args.server, cache)?,
+			},
 			services: Services {
-				server: args.server.clone(),
 				client: args.depend::<client::Service>("client"),
 			},
 		}))
 	}

 	async fn clear_cache(&self) {
-		self.resolver.clear_cache();
-		self.cache.clear().await;
+		// No ability to clean resolvematrix cache at the moment
+		self.dns.resolver.clear_cache();
+		self.dns.cache.clear().await;
 	}

-	fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
+	fn name(&self) -> &str { crate::service::make_name(module_path!()) }
+}
+
+#[implement(Service)]
+pub fn validate_ip(&self, ip: &IPAddress) -> Result<()> {
+	if !self.services.client.valid_cidr_range(ip) {
+		return Err!(BadServerResponse("Not allowed to send requests to this IP"));
+	}
+
+	Ok(())
 }
diff --git c/src/service/resolver/tests.rs i/src/service/resolver/tests.rs
deleted file mode 100644
index 068e08bd0..000000000
--- c/src/service/resolver/tests.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use super::fed::{FedDest, add_port_to_hostname, get_ip_with_port};
-
-#[test]
-fn ips_get_default_ports() {
-	assert_eq!(
-		get_ip_with_port("1.1.1.1"),
-		Some(FedDest::Literal("1.1.1.1:8448".parse().unwrap()))
-	);
-	assert_eq!(
-		get_ip_with_port("dead:beef::"),
-		Some(FedDest::Literal("[dead:beef::]:8448".parse().unwrap()))
-	);
-}
-
-#[test]
-fn ips_keep_custom_ports() {
-	assert_eq!(
-		get_ip_with_port("1.1.1.1:1234"),
-		Some(FedDest::Literal("1.1.1.1:1234".parse().unwrap()))
-	);
-	assert_eq!(
-		get_ip_with_port("[dead::beef]:8933"),
-		Some(FedDest::Literal("[dead::beef]:8933".parse().unwrap()))
-	);
-}
-
-#[test]
-fn hostnames_get_default_ports() {
-	assert_eq!(
-		add_port_to_hostname("example.com"),
-		FedDest::Named(String::from("example.com"), ":8448".try_into().unwrap())
-	);
-}
-
-#[test]
-fn hostnames_keep_custom_ports() {
-	assert_eq!(
-		add_port_to_hostname("example.com:1337"),
-		FedDest::Named(String::from("example.com"), ":1337".try_into().unwrap())
-	);
-}
diff --git c/src/service/resolver/well_known.rs i/src/service/resolver/well_known.rs
deleted file mode 100644
index 2a4ecf222..000000000
--- c/src/service/resolver/well_known.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use conduwuit::{Result, debug, debug_error, debug_info, trace, utils::response::LimitReadExt};
-use ruma::ServerName;
-
-impl super::Service {
-	#[tracing::instrument(name = "well-known", level = "debug", skip(self, dest))]
-	pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<String>> {
-		trace!("Requesting well known for {dest}");
-		let response = self
-			.services
-			.client
-			.well_known
-			.get(format!("https://{dest}/.well-known/matrix/server"))
-			.send()
-			.await;
-
-		trace!("response: {response:?}");
-		if let Err(e) = &response {
-			debug!("error: {e:?}");
-			return Ok(None);
-		}
-
-		let response = response?;
-		if !response.status().is_success() {
-			debug!("response not 2XX");
-			return Ok(None);
-		}
-
-		let Ok(text) = response.limit_read_text(8192).await else {
-			debug!("failed to read well-known response (too large or non-text content)");
-			return Ok(None);
-		};
-		trace!("response text: {text:?}");
-
-		let body: serde_json::Value = serde_json::from_str(&text).unwrap_or_default();
-
-		let m_server = body
-			.get("m.server")
-			.unwrap_or(&serde_json::Value::Null)
-			.as_str()
-			.unwrap_or_default();
-
-		if ServerName::parse(m_server).is_err() {
-			debug_error!("response content missing or invalid");
-			return Ok(None);
-		}
-
-		debug_info!("{dest:?} found at {m_server:?}");
-		Ok(Some(m_server.to_owned()))
-	}
-}
2026-07-03 10:59:11 +02:00
3a90e4eaac
chore: Rename variables, fix comments, misc cleanup 2026-07-03 10:59:10 +02:00
a3ffd4d9c4
fix: Improve splitting of hostname:port, fixed returns 2026-07-03 10:59:10 +02:00
da03baa063
fix: Ensure codeflow returns at correct locations 2026-07-03 10:59:10 +02:00
f075e1ce5b
chore: Remove useless comments 2026-07-03 10:59:10 +02:00
03e312f2b4
chore: Formatting + Commenting
diff --git c/src/service/resolver/actual.rs i/src/service/resolver/actual.rs
index 9cd1aec15..495d83172 100644
--- c/src/service/resolver/actual.rs
+++ i/src/service/resolver/actual.rs
@@ -1,9 +1,5 @@
 use std::fmt::Debug;

-use super::{
-	cache::{CachedDest, CachedOverride, MAX_IPS},
-	fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
-};
 use conduwuit::{Err, Result, debug, debug_info, err, error, trace};
 use futures::{FutureExt, TryFutureExt};
 use hickory_resolver::{
@@ -15,9 +11,11 @@

 use super::{
 	cache::{CachedDest, CachedOverride, MAX_IPS},
-	fed::{FedDest, PortString, add_port_to_hostname, get_ip_with_port},
+	fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
 };

+const DEFAULT_PORT: u16 = 8448;
+
 #[derive(Clone, Debug)]
 pub(crate) struct ActualDest {
 	pub(crate) dest: FedDest,
@@ -26,9 +24,7 @@ pub(crate) struct ActualDest {

 impl ActualDest {
 	#[inline]
-	pub(crate) fn string(&self) -> String {
-		self.dest.https_string()
-	}
+	pub(crate) fn string(&self) -> String { self.dest.https_string() }
 }

 impl super::Service {
@@ -75,7 +71,8 @@ pub async fn resolve_actual_dest(
 		// Ensure dest is a valid connection endpoint
 		self.validate_dest(dest)?;

-		// Clippy believes this can be a clone, however we are actually converting ServerName to String
+		// Clippy believes this can be a clone, however we are actually converting
+		// ServerName to String
 		#[allow(clippy::implicit_clone)]
 		let mut host = dest.to_string().to_owned();
 		let actual_dest = self.resolve_server_name(dest, cache, &mut host).await?;
@@ -103,8 +100,8 @@ async fn resolve_server_name(
 		cache: bool,
 		host: &mut String,
 	) -> Result<FedDest> {
-		// 1. If `dest` is an IP, use it directly. If a port is provided as well (IP:port socket pair)
-		//    use that, otherwise default to port 8448
+		// 1. If `dest` is an IP, use it directly. If a port is provided as well
+		//    (IP:port socket pair) use that, otherwise default to port 8448
 		if let Some(fed_dest) = get_ip_with_port(dest.as_str()) {
 			debug!("1: IP literal with provided or default port");
 			return Ok(fed_dest);
@@ -117,8 +114,8 @@ async fn resolve_server_name(
 				.await?;
 		}

-		// Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed either way
-		// https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
+		// Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed
+		// either way https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
 		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, true)
 			.await?;

@@ -126,7 +123,8 @@ async fn resolve_server_name(
 		self.services.server.check_running()?;

 		// 3. If `dest` is a hostname with no port, send GET to `https://<dest>/.well-known/matrix/server`.
-		// If invalid JSON (throws error), skip to step 4. Otherwise, parse `delegated` as `<hostname>[:<port>]` and...
+		// If invalid JSON (throws error), skip to step 4. Otherwise, parse `delegated`
+		// as `<hostname>[:<port>]` and...
 		if let Some(delegated) = self.request_well_known(dest.as_str()).await? {
 			// delegated=matrix-federation.matrix.org:443 // host=matrix.org
 			self.resolve_3_well_known(host, cache, delegated).await?;
@@ -137,11 +135,13 @@ async fn resolve_server_name(
 			self.resolve_4_srv_lookup(host, cache, overrider).await?;
 		}

-		// 5. if .well-known errored and no SRV exists, resolve IP and connect on default port (8448)
+		// 5. if .well-known errored and no SRV exists, resolve IP and connect on
+		//    default port (8448)
 		self.resolve_5_direct(dest, cache).await
 	}

-	/// Parse a host:port socket pair into separate parts, and resolve the hostname into an IP address
+	/// Parse a host:port socket pair into separate parts, and resolve the
+	/// hostname into an IP address
 	async fn resolve_2_host_port(
 		&self,
 		dest: &ServerName,
@@ -180,14 +180,16 @@ async fn resolve_3_well_known(
 			return Ok(host_and_port);
 		}

-		// 3.2 - If <delegated> is not an IP and a port is present, lookup IP for hostname and connect
+		// 3.2 - If <delegated> is not an IP and a port is present, lookup IP for
+		// hostname and connect
 		if let Some(pos) = &delegated.find(':') {
 			self.resolve_3_2_hostname_port(cache, &delegated, *pos)
 				.await?;
 		}

-		// 3.3 - If <delegated> is not an IP and there is no port, lookup SRV `_matrix._tcp.<delegated>`
-		// (which may provide a new hostname + port to use, see steps 3.1 and 3.2)
+		// 3.3 - If <delegated> is not an IP and there is no port, lookup SRV
+		// `_matrix._tcp.<delegated>` (which may provide a new hostname + port to use,
+		// see steps 3.1 and 3.2)
 		trace!("Delegated hostname has no port, querying SRV");
 		if let Some(overrider) = self.query_srv_record(&delegated).await? {
 			self.resolve_3_3_use_srv(cache, &delegated, overrider)
@@ -342,17 +344,14 @@ async fn query_and_cache_override(
 		match self.resolver.resolver.lookup_ip(hostname.to_owned()).await {
 			| Err(e) => Self::handle_resolve_error(&e, hostname),
 			| Ok(override_ip) => {
-				self.cache.set_override(
-					untername,
-					&CachedOverride {
-						ips: override_ip.iter().take(MAX_IPS).collect(),
-						port,
-						expire: CachedOverride::default_expire(),
-						overriding: (hostname != untername)
-							.then_some(hostname.into())
-							.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
-					},
-				);
+				self.cache.set_override(untername, &CachedOverride {
+					ips: override_ip.into_iter().take(MAX_IPS).collect(),
+					port,
+					expire: CachedOverride::default_expire(),
+					overriding: (hostname != untername)
+						.then_some(hostname.into())
+						.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
+				});

 				Ok(())
 			},
@@ -415,7 +414,8 @@ fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> {
 		}
 	}

-	/// Ensure `dest` is a valid destination (valid ip if it is an IP), and not ourselves (unless in config)
+	/// Ensure `dest` is a valid destination (valid ip if it is an IP), and not
+	/// ourselves (unless in config)
 	fn validate_dest(&self, dest: &ServerName) -> Result<()> {
 		if dest == self.services.server.name && !self.services.server.config.federation_loopback {
 			return Err!("Won't send federation request to ourselves");
diff --git c/src/service/resolver/fed.rs i/src/service/resolver/fed.rs
index b43f62eed..83601a98a 100644
--- c/src/service/resolver/fed.rs
+++ i/src/service/resolver/fed.rs
@@ -9,8 +9,8 @@

 #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
 pub enum FedDest {
-	Literal(SocketAddr),
-	Named(String, PortString),
+	Literal(SocketAddr),       // "ip:port"
+	Named(String, PortString), // ("hostname", ":port")
 }

 /// numeric or service-name
@@ -18,6 +18,9 @@ pub enum FedDest {

 const DEFAULT_PORT: &str = ":8448";

+/// Attempt to parse `dest_str` as either an IP:port socket pair or as a plain
+/// IP (adding the default port), returning `None` if dest_str is neither a
+/// socket pair nor a plain IP.
 pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
 	if let Ok(dest) = dest_str.parse::<SocketAddr>() {
 		Some(FedDest::Literal(dest))
@@ -28,6 +31,8 @@ pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
 	}
 }

+/// Convert a `dest` string with or without port into a FedDest with either
+/// the provided port (if host:port format) or the default port (8448)
 pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
 	let (host, port) = match dest.find(':') {
 		| None => (dest, DEFAULT_PORT),
@@ -42,8 +47,8 @@ pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {

 /// Ensure `host` always has a port
 ///
-/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain IP,
-/// in which case `add_port_to_hostname` adds it instead
+/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain
+/// IP, in which case `add_port_to_hostname` adds it instead
 #[inline]
 pub(crate) fn ensure_host_has_port(host: &str) -> FedDest {
 	get_ip_with_port(host).unwrap_or_else(|| add_port_to_hostname(host))
2026-07-03 10:59:10 +02:00
cb031aef84
refactor: Rewrite resolver service
No functional changes, only visual and slight logic updates.
All inputs should return the same outputs.

# Conflicts:
#	src/service/resolver/actual.rs

diff --git c/src/service/resolver/actual.rs i/src/service/resolver/actual.rs
index 7eaeb96ab..9cd1aec15 100644
--- c/src/service/resolver/actual.rs
+++ i/src/service/resolver/actual.rs
@@ -1,8 +1,9 @@
-use std::{
-	fmt::Debug,
-	net::{IpAddr, SocketAddr},
-};
+use std::fmt::Debug;

+use super::{
+	cache::{CachedDest, CachedOverride, MAX_IPS},
+	fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
+};
 use conduwuit::{Err, Result, debug, debug_info, err, error, trace};
 use futures::{FutureExt, TryFutureExt};
 use hickory_resolver::{
@@ -25,7 +26,9 @@ pub(crate) struct ActualDest {

 impl ActualDest {
 	#[inline]
-	pub(crate) fn string(&self) -> String { self.dest.https_string() }
+	pub(crate) fn string(&self) -> String {
+		self.dest.https_string()
+	}
 }

 impl super::Service {
@@ -57,71 +60,103 @@ pub(crate) async fn lookup_actual_dest(
 			.await
 	}

-	/// Returns: `actual_destination`, host header
-	/// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
-	/// Numbers in comments below refer to bullet points in linked section of
-	/// specification
+	/// Returns: `actual_destination` + `host` variable used for logging
 	#[tracing::instrument(name = "actual", level = "debug", skip(self, cache))]
 	pub async fn resolve_actual_dest(
 		&self,
 		dest: &ServerName,
 		cache: bool,
 	) -> Result<CachedDest> {
+		debug!(
+			dest = %dest,
+			cache = %cache,
+			"Resolving server name and port"
+		);
+		// Ensure dest is a valid connection endpoint
 		self.validate_dest(dest)?;
-		let mut host = dest.as_str().to_owned();
-		let actual_dest = match get_ip_with_port(dest.as_str()) {
-			| Some(host_port) => Self::actual_dest_1(host_port)?,
-			| None =>
-				if let Some(pos) = dest.as_str().find(':') {
-					self.actual_dest_2(dest, cache, pos).await?
-				} else {
-					self.services.server.check_running()?;
-					match self.request_well_known(dest.as_str()).await? {
-						| Some(delegated) =>
-							self.actual_dest_3(&mut host, cache, delegated).await?,
-						| _ => match self.query_srv_record(dest.as_str()).await? {
-							| Some(overrider) =>
-								self.actual_dest_4(&host, cache, overrider).await?,
-							| _ => self.actual_dest_5(dest, cache).await?,
-						},
-					}
-				},
-		};

-		// Can't use get_ip_with_port here because we don't want to add a port
-		// to an IP address if it wasn't specified
-		let host = if let Ok(addr) = host.parse::<SocketAddr>() {
-			FedDest::Literal(addr)
-		} else if let Ok(addr) = host.parse::<IpAddr>() {
-			FedDest::Named(addr.to_string(), FedDest::default_port())
-		} else if let Some(pos) = host.find(':') {
-			let (host, port) = host.split_at(pos);
-			FedDest::Named(
-				host.to_owned(),
-				port.try_into().unwrap_or_else(|_| FedDest::default_port()),
-			)
-		} else {
-			FedDest::Named(host, FedDest::default_port())
-		};
+		// Clippy believes this can be a clone, however we are actually converting ServerName to String
+		#[allow(clippy::implicit_clone)]
+		let mut host = dest.to_string().to_owned();
+		let actual_dest = self.resolve_server_name(dest, cache, &mut host).await?;

-		debug!("Actual destination: {actual_dest:?} hostname: {host:?}");
+		host = ensure_host_has_port(&host).to_string();
+
+		debug!(
+			dest = %dest, // matrix.org
+			actual_dest = %actual_dest, // FedDest::Named(server.matrix.org, 443)
+			host = %host, // matrix.org
+			"Finished resolving server name"
+		);
 		Ok(CachedDest {
 			dest: actual_dest,
-			host: host.uri_string(),
+			host,
 			expire: CachedDest::default_expire(),
 		})
 	}

-	fn actual_dest_1(host_port: FedDest) -> Result<FedDest> {
-		debug!("1: IP literal with provided or default port");
-		Ok(host_port)
+	/// Performs the server resolution steps as per the specification:
+	/// <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
+	async fn resolve_server_name(
+		&self,
+		dest: &ServerName,
+		cache: bool,
+		host: &mut String,
+	) -> Result<FedDest> {
+		// 1. If `dest` is an IP, use it directly. If a port is provided as well (IP:port socket pair)
+		//    use that, otherwise default to port 8448
+		if let Some(fed_dest) = get_ip_with_port(dest.as_str()) {
+			debug!("1: IP literal with provided or default port");
+			return Ok(fed_dest);
+		}
+
+		// 2. If `dest` is a hostname and has a provided port (format of `host:port`),
+		//    resolve the hostname to an IP address and connect it and the provided port
+		if let Some(colon_position) = dest.as_str().find(':') {
+			self.resolve_2_host_port(dest, cache, colon_position)
+				.await?;
+		}
+
+		// Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed either way
+		// https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
+		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, true)
+			.await?;
+
+		// Ensure server is running (not shutting down) before continuing resolution
+		self.services.server.check_running()?;
+
+		// 3. If `dest` is a hostname with no port, send GET to `https://<dest>/.well-known/matrix/server`.
+		// If invalid JSON (throws error), skip to step 4. Otherwise, parse `delegated` as `<hostname>[:<port>]` and...
+		if let Some(delegated) = self.request_well_known(dest.as_str()).await? {
+			// delegated=matrix-federation.matrix.org:443 // host=matrix.org
+			self.resolve_3_well_known(host, cache, delegated).await?;
+		}
+
+		// 4. if .well-known errored, perform SRV (see 3.3)
+		if let Some(overrider) = self.query_srv_record(dest.as_str()).await? {
+			self.resolve_4_srv_lookup(host, cache, overrider).await?;
+		}
+
+		// 5. if .well-known errored and no SRV exists, resolve IP and connect on default port (8448)
+		self.resolve_5_direct(dest, cache).await
 	}

-	async fn actual_dest_2(&self, dest: &ServerName, cache: bool, pos: usize) -> Result<FedDest> {
+	/// Parse a host:port socket pair into separate parts, and resolve the hostname into an IP address
+	async fn resolve_2_host_port(
+		&self,
+		dest: &ServerName,
+		cache: bool,
+		pos: usize,
+	) -> Result<FedDest> {
 		debug!("2: Hostname with included port");
 		let (host, port) = dest.as_str().split_at(pos);
-		self.conditional_query_and_cache(host, port.parse::<u16>().unwrap_or(8448), cache)
-			.await?;
+
+		self.conditional_query_and_cache(
+			host,
+			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
+			cache,
+		)
+		.await?;

 		Ok(FedDest::Named(
 			host.to_owned(),
@@ -129,7 +164,7 @@ async fn actual_dest_2(&self, dest: &ServerName, cache: bool, pos: usize) -> Res
 		))
 	}

-	async fn actual_dest_3(
+	async fn resolve_3_well_known(
 		&self,
 		host: &mut String,
 		cache: bool,
@@ -137,63 +172,75 @@ async fn actual_dest_3(
 	) -> Result<FedDest> {
 		debug!("3: A .well-known file is available");
 		*host = add_port_to_hostname(&delegated).uri_string();
-		match get_ip_with_port(&delegated) {
-			| Some(host_and_port) => Self::actual_dest_3_1(host_and_port),
-			| None =>
-				if let Some(pos) = delegated.find(':') {
-					self.actual_dest_3_2(cache, delegated, pos).await
-				} else {
-					trace!("Delegated hostname has no port in this branch");
-					match self.query_srv_record(&delegated).await? {
-						| Some(overrider) =>
-							self.actual_dest_3_3(cache, delegated, overrider).await,
-						| _ => self.actual_dest_3_4(cache, delegated).await,
-					}
-				},
+
+		// 3.1 - If <delegated> is of IP:port format, connect to that,
+		//       or IP with default port if no port provided (8448)
+		if let Some(host_and_port) = get_ip_with_port(&delegated) {
+			debug!("3.1: IP with port in .well-known file");
+			return Ok(host_and_port);
 		}
+
+		// 3.2 - If <delegated> is not an IP and a port is present, lookup IP for hostname and connect
+		if let Some(pos) = &delegated.find(':') {
+			self.resolve_3_2_hostname_port(cache, &delegated, *pos)
+				.await?;
+		}
+
+		// 3.3 - If <delegated> is not an IP and there is no port, lookup SRV `_matrix._tcp.<delegated>`
+		// (which may provide a new hostname + port to use, see steps 3.1 and 3.2)
+		trace!("Delegated hostname has no port, querying SRV");
+		if let Some(overrider) = self.query_srv_record(&delegated).await? {
+			self.resolve_3_3_use_srv(cache, &delegated, overrider)
+				.await?;
+		}
+
+		self.resolve_3_4_use_default_port(cache, delegated).await
 	}

-	fn actual_dest_3_1(host_and_port: FedDest) -> Result<FedDest> {
-		debug!("3.1: IP literal in .well-known file");
-		Ok(host_and_port)
-	}
-
-	async fn actual_dest_3_2(
+	async fn resolve_3_2_hostname_port(
 		&self,
 		cache: bool,
-		delegated: String,
+		delegated: &str,
 		pos: usize,
 	) -> Result<FedDest> {
 		debug!("3.2: Hostname with port in .well-known file");
-		let (host, port) = delegated.split_at(pos);
-		self.conditional_query_and_cache(host, port.parse::<u16>().unwrap_or(8448), cache)
-			.await?;
+		let (host, port) = &delegated.split_at(pos);
+		self.conditional_query_and_cache(
+			host,
+			port.parse::<u16>().unwrap_or(DEFAULT_PORT),
+			cache,
+		)
+		.await?;

+		trace!("Successfully resolved IP for {delegated}");
 		Ok(FedDest::Named(
-			host.to_owned(),
-			port.try_into().unwrap_or_else(|_| FedDest::default_port()),
+			host.to_owned().to_owned(),
+			port.to_owned()
+				.try_into()
+				.unwrap_or_else(|_| FedDest::default_port()),
 		))
 	}

-	async fn actual_dest_3_3(
+	async fn resolve_3_3_use_srv(
 		&self,
 		cache: bool,
-		delegated: String,
+		delegated: &String,
 		overrider: FedDest,
 	) -> Result<FedDest> {
 		debug!("3.3: SRV lookup successful");
+
 		let force_port = overrider.port();
 		self.conditional_query_and_cache_override(
-			&delegated,
+			delegated,
 			&overrider.hostname(),
-			force_port.unwrap_or(8448),
+			force_port.unwrap_or(DEFAULT_PORT),
 			cache,
 		)
 		.await?;

 		if let Some(port) = force_port {
 			return Ok(FedDest::Named(
-				delegated,
+				delegated.to_owned(),
 				format!(":{port}")
 					.as_str()
 					.try_into()
@@ -201,17 +248,21 @@ async fn actual_dest_3_3(
 			));
 		}

-		Ok(add_port_to_hostname(&delegated))
+		Ok(add_port_to_hostname(delegated))
 	}

-	async fn actual_dest_3_4(&self, cache: bool, delegated: String) -> Result<FedDest> {
-		debug!("3.4: No SRV records, just use the hostname from .well-known");
-		self.conditional_query_and_cache(&delegated, 8448, cache)
+	async fn resolve_3_4_use_default_port(
+		&self,
+		cache: bool,
+		delegated: String,
+	) -> Result<FedDest> {
+		debug!("3.4: No SRV records found, use the hostname from .well-known with default port");
+		self.conditional_query_and_cache(&delegated, DEFAULT_PORT, cache)
 			.await?;
 		Ok(add_port_to_hostname(&delegated))
 	}

-	async fn actual_dest_4(
+	async fn resolve_4_srv_lookup(
 		&self,
 		host: &str,
 		cache: bool,
@@ -222,7 +273,7 @@ async fn actual_dest_4(
 		self.conditional_query_and_cache_override(
 			host,
 			&overrider.hostname(),
-			force_port.unwrap_or(8448),
+			force_port.unwrap_or(DEFAULT_PORT),
 			cache,
 		)
 		.await?;
@@ -239,9 +290,9 @@ async fn actual_dest_4(
 		Ok(add_port_to_hostname(host))
 	}

-	async fn actual_dest_5(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
-		debug!("5: No SRV record found");
-		self.conditional_query_and_cache(dest.as_str(), 8448, cache)
+	async fn resolve_5_direct(&self, dest: &ServerName, cache: bool) -> Result<FedDest> {
+		debug!("5: No port provided and no SRV record found");
+		self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, cache)
 			.await?;

 		Ok(add_port_to_hostname(dest.as_str()))
@@ -261,9 +312,9 @@ async fn conditional_query_and_cache(
 	#[inline]
 	async fn conditional_query_and_cache_override(
 		&self,
-		untername: &str,
-		hostname: &str,
-		port: u16,
+		untername: &str, // matrix.org
+		hostname: &str,  // server.matrix.org
+		port: u16,       // 443
 		cache: bool,
 	) -> Result {
 		if !cache {
@@ -281,9 +332,9 @@ async fn conditional_query_and_cache_override(
 	#[tracing::instrument(name = "ip", level = "debug", skip(self))]
 	async fn query_and_cache_override(
 		&self,
-		untername: &'_ str,
-		hostname: &'_ str,
-		port: u16,
+		untername: &'_ str, // matrix.org
+		hostname: &'_ str,  // server.matrix.org
+		port: u16,          // 443
 	) -> Result {
 		self.services.server.check_running()?;

@@ -291,14 +342,17 @@ async fn query_and_cache_override(
 		match self.resolver.resolver.lookup_ip(hostname.to_owned()).await {
 			| Err(e) => Self::handle_resolve_error(&e, hostname),
 			| Ok(override_ip) => {
-				self.cache.set_override(untername, &CachedOverride {
-					ips: override_ip.iter().take(MAX_IPS).collect(),
-					port,
-					expire: CachedOverride::default_expire(),
-					overriding: (hostname != untername)
-						.then_some(hostname.into())
-						.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
-				});
+				self.cache.set_override(
+					untername,
+					&CachedOverride {
+						ips: override_ip.iter().take(MAX_IPS).collect(),
+						port,
+						expire: CachedOverride::default_expire(),
+						overriding: (hostname != untername)
+							.then_some(hostname.into())
+							.inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
+					},
+				);

 				Ok(())
 			},
@@ -361,6 +415,7 @@ fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> {
 		}
 	}

+	/// Ensure `dest` is a valid destination (valid ip if it is an IP), and not ourselves (unless in config)
 	fn validate_dest(&self, dest: &ServerName) -> Result<()> {
 		if dest == self.services.server.name && !self.services.server.config.federation_loopback {
 			return Err!("Won't send federation request to ourselves");
@@ -370,6 +425,7 @@ fn validate_dest(&self, dest: &ServerName) -> Result<()> {
 			self.validate_dest_ip_literal(dest)?;
 		}

+		debug!(dest = %dest, "Valid destination for resolution");
 		Ok(())
 	}

diff --git c/src/service/resolver/fed.rs i/src/service/resolver/fed.rs
index e5bee9ac2..b43f62eed 100644
--- c/src/service/resolver/fed.rs
+++ i/src/service/resolver/fed.rs
@@ -40,6 +40,15 @@ pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
 	)
 }

+/// Ensure `host` always has a port
+///
+/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain IP,
+/// in which case `add_port_to_hostname` adds it instead
+#[inline]
+pub(crate) fn ensure_host_has_port(host: &str) -> FedDest {
+	get_ip_with_port(host).unwrap_or_else(|| add_port_to_hostname(host))
+}
+
 impl FedDest {
 	pub(crate) fn https_string(&self) -> String {
 		match self {
2026-07-03 10:59:06 +02:00
f1b7710984
fix: Mobile styling improvements 2026-07-02 17:13:14 -04:00
514c3bbcbf
fix: Properly show email in account page when OIDC email_claim is set 2026-07-02 16:57:21 -04:00
da7d8c9821
fix: Prevent register page from being accessible when OIDC is enabled 2026-07-02 16:34:56 -04:00
45809b7970
feat: Add support for reading the OIDC client secret from a file 2026-07-02 16:34:56 -04:00
910925b906
fix: Config file formatting 2026-07-02 16:34:38 -04:00
28263982cd
feat: Add support for requesting additional scopes 2026-07-02 16:34:38 -04:00
52a4b9d586
chore: News fragment 2026-07-02 16:34:38 -04:00
786890baa0
feat: Add support for importing email addresses from the IDP 2026-07-02 16:34:38 -04:00
3282ba8eab
fix: Miscellaneous fixes 2026-07-02 16:34:38 -04:00
f66c1d8f35
fix: Hide bare oidc config option 2026-07-02 16:34:38 -04:00
3d004b1923
fix: Adjust OIDC config section comment position 2026-07-02 16:34:38 -04:00
06afe4f1a3
feat: Add support for importing profile data from claims 2026-07-02 16:34:38 -04:00
53d6887b86
refactor: Move profile field setting logic into users service 2026-07-02 16:34:38 -04:00
8c77bd61e5
fix: Hide password change link when OIDC is enabled 2026-07-02 16:34:38 -04:00
e649af33b9
feat: Send account selection prompt to IDP when account switch link is clicked 2026-07-02 16:34:38 -04:00
e2fe166d63
feat: Speedbump when logging in with OIDC with no next target 2026-07-02 16:34:38 -04:00
4ee0bb7533
feat: Allow existing legacy accounts to be linked interactively 2026-07-02 16:34:38 -04:00
9a9cc94702
chore: Update admin command docs 2026-07-02 16:34:38 -04:00
58a6e1232c
feat: Implement !admin oidc unlink 2026-07-02 16:34:38 -04:00
c0cb4afd8a
feat: Initial implementation of OIDC 2026-07-02 16:34:38 -04:00
69163b5391
refactor: Split remote and deactivated users into their own columns 2026-07-02 16:24:07 -04:00
d4f6c053bc
fix: Log the set password when creating users
Closes #1894
2026-07-02 16:41:33 +01:00
4f72326b07 chore(deps): update rust crate rand to v0.10.2 2026-07-02 10:19:35 +00:00
b7e449f490 chore(deps): update actions/cache action to v6 2026-07-02 10:14:57 +00:00
2a1d7e49d9 chore(Nix): Updated flake hashes 2026-07-02 10:14:36 +00:00
b7792f9e86 chore(deps): update rust to v1.96.1 2026-07-02 10:14:36 +00:00
adfe9f9f53
chore: disable doctests in conduwuit_core
These aren't wanted and are failing anyways. Fixes nix package build.
2026-07-01 23:39:28 -04:00
8fe1715019 chore(deps): update rust crate aws-lc-rs to v1.17.1 2026-07-01 19:46:32 +00:00
9a91dce600 chore(deps): update rust crate serde_html_form to v0.4.1 2026-07-01 19:45:14 +00:00
eee4ef50d2
chore: merge 1818 nex/perf/get-missing-events 2026-07-01 18:45:08 +00:00
62e0b53f52
feat: Prioritise sending dummy events when the extremity count reaches 20 or more 2026-07-01 19:15:35 +01:00
5fa3d5f6c8
fix: Don't create fake objects when defaulting a partial PDU build 2026-07-01 19:15:35 +01:00
9b80a99aa7
style: De-duplicate build_local_dag definitions, replace outdated comment on unwrap safety 2026-07-01 19:15:22 +01:00
bd525c100f
style: Re-use room_id parameter instead of potentially recalculating 2026-07-01 16:31:59 +01:00
e6225f3265
fix: Use infallible room ID getter 2026-07-01 16:13:55 +01:00
54c94ca9ad
fix(appservice): Re-add room membership conditions for event sending
They accidentally got removed in a recent refactor

Fixes #1890
2026-07-01 10:20:57 +01:00
017d4b3894
fix: Enable compat-get-3pids ruma feature 2026-06-30 12:27:49 -04:00
3b3eaf8744 chore(deps): update rust crate cargo_toml to v1 2026-06-30 13:51:11 +00:00
0a634907f2 chore(deps): update github-actions-digest 2026-06-30 05:03:24 +00:00
2f2848728f fix: add missing brackets in nix devshell 2026-06-30 01:24:33 +00:00
19a83c6891
style: Add docstrings to squasher functions 2026-06-29 18:37:04 +01:00
2bfd678c71
feat: Add jitter to extremity squasher 2026-06-29 18:29:04 +01:00
e936d18324
feat: Don't panic in build_local_dag
Previously the function assumed the caller had performed proper validation on the inputs (and all current callers do), but this is a poor reason to panic when sane error handling is available.
Events with no prev events now return an error, and prev events which are illegal are simply skipped.
2026-06-29 18:12:16 +01:00
90797fa3cd
fix: Avoid string roundtrip when fetching timestamps in build_local_dag 2026-06-29 17:44:13 +01:00
5eea8fe880
chore: News fragment 2026-06-29 16:46:47 +01:00
12491dcc26
feat: Mark spec version 1.17 as supported 2026-06-29 16:46:39 +01:00
2eff454787
feat: Finish implementing MSC4190 2026-06-29 16:46:07 +01:00
e5dc5bedfc fix: MSC2666 is stable but not yet in a release 2026-06-29 13:56:22 +00:00
496ca52987 style: Missing semicolon on line 50 2026-06-29 13:56:22 +00:00
72f4c3cc53 chore: Remove unstable features that are now stable or abandoned 2026-06-29 13:56:22 +00:00
6a8a114197 feat: Update capabilities and advertise spec version v1.18 2026-06-29 13:56:22 +00:00
549864a052 feat: Support MSC4323 locking endpoints 2026-06-29 13:56:22 +00:00
52026bb0f1
chore: Formatting 2026-06-29 09:41:59 -04:00
aed8e7d769
fix: Adjust error code 2026-06-29 09:35:51 -04:00
32fb6f247a
fix: Use a LRU cache for storing pending auth code grants 2026-06-29 09:35:51 -04:00
90e14abecb
fix: Spacing 2026-06-29 09:35:51 -04:00
6ced2511e4
chore: Clippy fixes 2026-06-29 09:35:51 -04:00
93407ade03
fix: Accessibility improvements 2026-06-29 09:35:51 -04:00
6742d9237a
fix: More CSS tweaks 2026-06-29 09:35:51 -04:00
a32c7d0d9a
fix: Set correct default for registration terms config section 2026-06-29 09:35:51 -04:00
761a6a53d0
fix: Check for existing device when creating oauth session 2026-06-29 09:35:51 -04:00
c56c035c15
fix: Use RFC-compliant error responses for OAuth endpoints 2026-06-29 09:35:51 -04:00
c804bf5780
fix: Force trusted flow UI for first-run registration 2026-06-29 09:35:51 -04:00
b87afeef80
fix: Panic when trying to check an unknown UIAA stage type 2026-06-29 09:35:51 -04:00
d0c7a62ce7
fix: Use the right error code for CAPTCHA errors 2026-06-29 09:35:50 -04:00
47582d1922
refactor: Update logic for checking if a username is available 2026-06-29 09:35:50 -04:00
36a30f16b1
fix: CSS adjustments 2026-06-29 09:35:50 -04:00
52ec6bc6da
fix: Adjust error codes to comply with MSC4190 2026-06-29 09:35:50 -04:00
74788dcb19
feat: Mark spec version 1.15 as supported 2026-06-29 09:35:50 -04:00
b35b72c34a
feat: Add a page with some information about the server 2026-06-29 09:35:50 -04:00
c1fc76040a
fix: Correct config file example section name 2026-06-29 09:35:50 -04:00
d1449d6575
chore: My Giant Future 2026-06-29 09:35:50 -04:00
9fdeb61c1a
feat: Improve account panel UI for locked and suspended accounts 2026-06-29 09:35:50 -04:00
7c7d6762e2
fix: Include query parameters in link back to login on register page 2026-06-29 09:35:50 -04:00
eda46d63a8
fix: CSS tweaks 2026-06-29 09:35:50 -04:00
9fc9063c83
feat: Improve registration UI in first-run mode 2026-06-29 09:35:50 -04:00
430347fc66
fix: Minor wording improvements 2026-06-29 09:35:50 -04:00
9df5c68d3c
fix: Set default for allow_deactivation 2026-06-29 09:35:50 -04:00
3ca068c985
fix: Fix registration terms example in config 2026-06-29 09:35:50 -04:00
138ec05cf2
feat: Implement support for prompt=create in the authorization code flow 2026-06-29 09:35:50 -04:00
c7e5c8df22
fix: Don't let logged-in users access the registration page 2026-06-29 09:35:50 -04:00
91afbd122f
feat: Allow self-service deactivation to be disabled 2026-06-29 09:35:50 -04:00
daaf09cb26
refactor: Use more consistent terminology for email validation pages 2026-06-29 09:35:50 -04:00
e8d6fa565e
feat: Add support for registering accounts with the web UI 2026-06-29 09:35:50 -04:00
47af5d3a39
refactor: Change template context to allow using a CSP nonce 2026-06-29 09:35:49 -04:00
63b5fd04be
fix: Minor CSS improvements 2026-06-29 09:35:49 -04:00
d59a5c63f9
fix: Remove errant whitespace in device details 2026-06-29 09:35:48 -04:00
16aaeae21c
chore: News fragment 2026-06-29 09:35:48 -04:00
e60310eacc
feat: Allow configuring the OAuth compatibility mode 2026-06-29 09:35:48 -04:00
7b98ae54b5
fix: Use button styling for account management link on index page 2026-06-29 09:35:48 -04:00
d67d6ca895
fix: Use the right text color on input elements 2026-06-29 09:35:48 -04:00
86d9e9e6a9
feat: Add support for account management deeplinks 2026-06-29 09:35:48 -04:00
b37480d6b2
fix: Return the correct error code for expired access tokens 2026-06-29 09:35:48 -04:00
0d806a2038
feat: Add a page for viewing a device's details 2026-06-29 09:35:48 -04:00
19700a081e
fix: Use SameSite=Lax for session cookie 2026-06-29 09:35:48 -04:00
ed1b175fa4
feat: Allow devices to be removed from the account panel 2026-06-29 09:35:48 -04:00
a91fc7041a
feat: Implement oauth token revocation 2026-06-29 09:35:48 -04:00
18c59e036f
chore: Clippy fixes 2026-06-29 09:35:48 -04:00
df3f646c92
feat: Implement oauth auth code and refresh token flows 2026-06-29 09:35:48 -04:00
fb6e5d2838
chore: Clippy fixes 2026-06-29 09:35:48 -04:00
33be65a865
feat: Implement a web-based account management dashboard 2026-06-29 09:35:45 -04:00
975ec24167
feat: Implement oauth service and client registration 2026-06-29 09:03:54 -04:00
e8378e86fd chore(deps): update rust-zerover-patch-updates 2026-06-29 13:02:39 +00:00
57366ac90a chore(deps): update rust crate serde-saphyr to 0.0.28 2026-06-29 13:02:24 +00:00
9f8a716dc1 chore(deps): update node-patch-updates to v2.0.15 2026-06-29 13:01:10 +00:00
27367bac18 chore(deps): update github-actions-non-major 2026-06-29 05:03:03 +00:00
5199cde870
feat: Allow sending dummy events to clients 2026-06-28 03:44:23 +01:00
b6bc7dfc16
feat: Debounce extremity squashing
Additionaly circuit-breaks it if the squash would have only
b triggered by dummy events / other squashes
2026-06-28 01:29:52 +01:00
945ea5a78a
chore: Box large futures 2026-06-28 01:29:52 +01:00
d719fe2048
chore: Merge origin/main into nex/perf/get-missing-events 2026-06-28 01:29:23 +01:00
458e0b53ac
style: Reformat 2026-06-27 18:41:43 +01:00
2d65d47498
fix: Load bearing mut refs 2026-06-27 18:37:33 +01:00
e4922814b9
refactor: Add better documentation to sender service, add additional logging traces
This is a surprise tool that will help us later!
2026-06-27 18:37:33 +01:00
064028689c
style: Add documentation to execute module of sender service 2026-06-27 18:37:33 +01:00
124241238e
refactor: Rename "synapse"-related federation methods to "slow"
I won't even comment on how stupid that naming was.
2026-06-27 18:37:33 +01:00
967e2cc54f
refactor: Split the users service into several modules
Also resolvers several lints, including needless async on create_user
2026-06-27 18:37:33 +01:00
6fdeadc356
style: Refactor admin crate, drop admin_command macro
`admin_command` depended on `implement`, which is now gone.
2026-06-27 18:37:26 +01:00
478560daae
style: Remove now dead code 2026-06-27 18:36:44 +01:00
0310b4b2c5
style: Remove implement entirely 2026-06-27 18:36:44 +01:00
3eb4257ae8
style: Remove remaining implement imports 2026-06-27 18:36:44 +01:00
f1d3db0ea3
style: Eliminate implement 2026-06-27 18:36:44 +01:00
e7b302955f
style: Eliminate implement database 2026-06-27 18:36:44 +01:00
85122c62cd
style: Eliminate implement in database map keys 2026-06-27 18:36:44 +01:00
ba0ffee7cf
fix: Style errors and compile problems 2026-06-27 18:36:44 +01:00
86e1101b40
style: Remove implement for database pool 2026-06-27 18:36:44 +01:00
fdcb7e3957
style: Remove implement for config Manager 2026-06-27 18:36:44 +01:00
c54e56a73e
style: Remove implement for AccessCheck, rename check to assert 2026-06-27 18:36:44 +01:00
fed9a599d9
style: Refactor remaining parts of admin service 2026-06-27 18:36:44 +01:00
0bb97a53c5
style: Refactor account_data service 2026-06-27 18:36:44 +01:00
9b76c9a085
feat: Support arbitrary room versions while creating the admin room
Also changes the default power levels so people stop shooting their feet off
2026-06-27 18:36:44 +01:00
6f20b7bc3f
style: Refactor config service 2026-06-27 18:36:44 +01:00
580d9b0318
style: Refactor federation service 2026-06-27 18:36:44 +01:00
ae572ec108
style: Refactor key_backups service 2026-06-27 18:36:44 +01:00
b1c5b3d000
style: Refactor media service 2026-06-27 18:36:44 +01:00
0c9230f35e
style: Document & refactor resolver service
good riddance to this thing
2026-06-27 18:36:44 +01:00
77dab8fd20
style: Document & refactor rooms/alias service 2026-06-27 18:36:44 +01:00
10b5ca8e3a
style: Document & refactor rooms/directory service 2026-06-27 18:36:44 +01:00
f9eed42cb7
style: Document & refactor rooms/directory service 2026-06-27 18:36:44 +01:00
19f4c24c00
style: Document & refactor rooms/event_handler service 2026-06-27 18:36:44 +01:00
0a162b7bc4
style: Document & refactor rooms/lazy_loading service 2026-06-27 18:36:44 +01:00
0d1b130127
style: Document & refactor rooms/metadata service 2026-06-27 18:36:44 +01:00
5e0e82e7e8
style: Document & refactor rooms/outlier service 2026-06-27 18:36:44 +01:00
4bf0816bcc
style: Document & refactor rooms/search service 2026-06-27 18:36:44 +01:00
ecbe035b36
style: Document & refactor rooms/short service 2026-06-27 18:36:44 +01:00
4d30ee5d33
style: Document & refactor rooms/state_accessor service 2026-06-27 18:36:44 +01:00
4844c6ae3e
style: Document & refactor rooms/state_cache service 2026-06-27 18:36:44 +01:00
6603798d60
style: Document & refactor rooms/state_compressor service 2026-06-27 18:36:44 +01:00
199f6eb67b
style: Document & refactor rooms/user and rooms/timeline services 2026-06-27 18:36:44 +01:00
aa2f506996
style: Document & refactor sending service 2026-06-27 18:36:44 +01:00
a3994fe1a3
style: Document & refactor server_keys service 2026-06-27 18:36:44 +01:00
6312ff8088
style: Document & refactor sync service 2026-06-27 18:36:44 +01:00
17cff1fb36
style: Document & refactor users service 2026-06-27 18:36:44 +01:00
aff6315ae1
style: Document moderation service 2026-06-27 18:36:44 +01:00
574d3e9164
style: Use impl instead of implement in moderation service 2026-06-27 18:36:44 +01:00
21e93f8feb
chore: changelog 2026-06-27 01:05:53 +01:00
4b2f032ae6
feat: get-state-at admin command 2026-06-27 01:05:48 +01:00
8a495a7d7f
fix(ci): Correct remote ref fetch 2026-06-27 01:00:33 +01:00
cee51d5717
fix(ci): Correct remote ref fetch 2026-06-27 00:57:45 +01:00
0483d3e155
ci: Don't checkout repo in pull_request_target 2026-06-27 00:54:31 +01:00
2a4b9f9323
fix: Check are_all_blocked in server_filter_level 2026-06-24 20:13:17 +01:00
63a1a3d9ab
feat: Advertise stable prefix in unstable features 2026-06-24 20:05:34 +01:00
f19f5c71a5
chore(1875): Remove extra changelog entry 2026-06-24 19:13:35 +01:00
b009ffd31c
chore(1875): Add changelogs 2026-06-24 19:03:38 +01:00
b6baf66399
feat: Support MSC4380 invite blocking
fix: Re-add silently dropped support for MSC4155
2026-06-24 18:59:49 +01:00
6dac46e1ad
Update SECURITY.md 2026-06-24 13:00:27 +00:00
4d40e20fdd
docs: Fix typo 2026-06-23 14:56:14 +00:00
3b6858e936
perf: Throttle dummy events to prevent stampeding 2026-06-23 15:26:28 +01:00
3b455218f5 chore(deps): update rust crate itertools to 0.15.0 2026-06-23 13:53:25 +00:00
de24fcbb8c chore(deps): update dependency cargo-bins/cargo-binstall to v1.20.1 2026-06-23 13:38:23 +00:00
2adb9a7941 chore(deps): update actions/checkout action to v7 2026-06-23 13:20:40 +00:00
d81f4df61c chore(deps): update rust crate itertools to 0.15.0 2026-06-23 13:20:22 +00:00
6b259d15ee chore(deps): update rust-non-major 2026-06-23 13:20:10 +00:00
eeef60d540 chore(deps): update github-actions-digest 2026-06-23 05:01:57 +00:00
a01035e63a chore(deps): update github-actions-non-major to v43.234.0 2026-06-22 05:03:19 +00:00
52c1544e6f fix: Correct date in announcements 2026-06-21 02:36:32 +00:00
ed38212391
fix(ci): Correct version regex in debian build 2026-06-21 01:03:14 +01:00
86fe98c90d
chore: Admin announcement 2026-06-20 23:32:56 +00:00
4078062331
fix: change the update-flake-hashes repo to work with the new rust.nix structure 2026-06-20 15:35:09 -04:00
40935cf96a
fix: use toolchain declared in rust-toolchain.toml for cross rust-std 2026-06-20 15:32:33 -04:00
182c5a120e
fix: add rocksdb as a flake package
This fixes the flake-hashes workflow.
2026-06-20 13:45:25 -04:00
7ca00e4ab9
chore: Drop unused param from handle_outlier_pdu 2026-06-20 17:08:00 +01:00
b8ca06029f
perf: Use a hashmap for full-state filtering 2026-06-20 17:08:00 +01:00
2efe8f2ec0
fix: Inverted power level check in extremity squash 2026-06-20 17:08:00 +01:00
d1aa911739
fix: Rename variables in auth event fetcher
Also fixes a couple bugs where events were being misattributed
2026-06-20 17:08:00 +01:00
4673282ca1
perf: Don't try to fetch prevs we already fetched
graphs are hard
2026-06-20 17:08:00 +01:00
0c03195aec
fix: Fall back to legacy behaviour when prev events are missed from get_missing_events 2026-06-20 17:08:00 +01:00
439bc2784d
style: Use more explicit variable names 2026-06-20 17:08:00 +01:00
689a1ce59b
style: Use user_can_send_message 2026-06-20 17:08:00 +01:00
c141503ccb
style: Re-use GET_MISSING_EVENTS_MAX_BATCH_SIZE 2026-06-20 17:08:00 +01:00
bcadecdc3b
feat: Add !admin debug rooms-by-extremity-count command 2026-06-20 17:08:00 +01:00
ab3be337cb
chore: Reformat 2026-06-20 17:08:00 +01:00
aa1281a9e0
fix: Prevent arbitrary state injection attack 2026-06-20 17:08:00 +01:00
115a2e802e
style: Check power levels before attempting to send extremity squashes
Solves a problem where the console screams in agony when local users can't send dummy events
2026-06-20 17:08:00 +01:00
968328d788
perf: Squash weird mutable variable 2026-06-20 17:08:00 +01:00
f1cde5f323
style: Fix up some TODOs 2026-06-20 17:08:00 +01:00
832ee8650b
style: Adjust docstrings and dodgy comment 2026-06-20 17:08:00 +01:00
c0666a1793
fix: Default PDU content to empty object instead of literal NULL 2026-06-20 17:08:00 +01:00
ddb4ef539f
fix: un-forget how streams work 2026-06-20 17:08:00 +01:00
3faedc4581
perf: Remove huge clone and tackle TODOs 2026-06-20 17:08:00 +01:00
a3544353ba
feat: Automatically squash extremities when they exceed a threshold
Attempts to tackle #1844
2026-06-20 17:08:00 +01:00
b0612397d3
style: Tidy up 2026-06-20 17:08:00 +01:00
31737e127e
fix: Make fetch_state_ids_from_backfill_servers candidate-free safe 2026-06-20 17:08:00 +01:00
486dcd208c
style: Resolve lint complaints 2026-06-20 17:08:00 +01:00
a945a4b2ad
fix: Correctly handle still-missing state, always fetch full state atomically if regular fetch fails 2026-06-20 17:08:00 +01:00
c28ea44e11
fix: Correct inverted boolean condition, add explicit timeout on /state fetch 2026-06-20 17:08:00 +01:00
3e4d6b2565
perf: Always fetch at least N events per GME 2026-06-20 17:08:00 +01:00
29ce21cd2e
fix: Correctly pre-populate state events vec with known events 2026-06-20 17:08:00 +01:00
d461c6977a
fix: Friendly assertations 2026-06-20 17:08:00 +01:00
5a0d6461d1
perf: Don't try to re-persist non-outliers we already have 2026-06-20 17:08:00 +01:00
2ec7394785
perf: Don't add trees we already have to latest boundary 2026-06-20 17:08:00 +01:00
8a5708b9f9
fix: Be noisy when there's no incoming state 2026-06-20 17:08:00 +01:00
cd46070bd3
fix: Elide auth chain from fetch_and_handle_outliers 2026-06-20 17:08:00 +01:00
9930e549a0
fix: Progress log in fetch_prev 2026-06-20 17:08:00 +01:00
36ed20cb04
fix: Downgrade safe assert to debug assert 2026-06-20 17:08:00 +01:00
3907589b6c
fix: Don't download the world 2026-06-20 17:08:00 +01:00
2a598af888
feat: Make logging more verbose to diagnose the aranjesplosion 2026-06-20 17:08:00 +01:00
f34f84832b
feat: Include timing information in debug logs 2026-06-20 17:08:00 +01:00
0efa6ed1f2
fix: Don't treat prev outlier upgrades as fetch failures 2026-06-20 17:08:00 +01:00
2bf5876778
fix: Ask more servers for state_ids when origin fails to provide
Some servers reference events in prev_events that they might not yet have finished processing, so this allows us to at least attempt to get the state from another trustworthy server in the room that might be faster. I don't think this is too effective, however it's more effective than giving up immediately.
2026-06-20 17:08:00 +01:00
31982e84de
fix: Remove redundant check 2
This may look scary, but this is safe because event auth performs the same check, and will reject the event if it doesn't reference the create event correctly.
2026-06-20 17:08:00 +01:00
970958652a
fix: Remove redundant check that accidentally banned everyone 2026-06-20 17:08:00 +01:00
c94a395bf0
fix: Make PDU handle errors noisier & correct error types 2026-06-20 17:08:00 +01:00
43adff926f
fix: Make dedupe noisy, don't allow non-create event as create event 2026-06-20 17:07:59 +01:00
04fce56381
fix: Don't silence PDU handle logs 2026-06-20 17:07:59 +01:00
4df2097e6c
style: Rename gapfill helpers instruments 2026-06-20 17:07:59 +01:00
8b85b04d10
fix: Properly remove event_id from the PDU JSON before upgrading it 2026-06-20 17:07:59 +01:00
9e0bcd3be8
fix: Hold a federation room lock while remotely joining a room 2026-06-20 17:07:59 +01:00
9509080e0d
fix: Replace our local extremity tracking when joining a disconnected room remotely 2026-06-20 17:07:59 +01:00
61066bb0c6
fix: Don't try and fetch zero events 2026-06-20 17:07:59 +01:00
573d5bc50e
fix: Fall back to atomic fetch when full-state fetch fails 2026-06-20 17:07:59 +01:00
162e6eb92f
fix: Remove short-term memory loss
I keep writing forgetful code, it's a problem
2026-06-20 17:07:59 +01:00
cef4ebe38e
fix: Don't try to fetch the same event endlessly 2026-06-20 17:07:59 +01:00
316a0b7d58
fix: Don't repeat already-included metadata in fetch_state instrument 2026-06-20 17:07:59 +01:00
2bcc56704b
feat: Enhance reliability by fetching full state when we're missing a lot of auth events 2026-06-20 17:07:59 +01:00
7f64de9727
fix: Calculate max iterations dynamically, and bump max prevs 2026-06-20 17:07:59 +01:00
aea03f2f99
perf(wip): Improve individual events fetcher 2026-06-20 17:07:59 +01:00
8edf9552b8
fix: Don't lie about using already-known content 2026-06-20 17:07:59 +01:00
d5f69c8a31
fix: Be smarter when re-receiving already-seen PDUs 2026-06-20 17:07:59 +01:00
9ea9b0e04c
perf: Don't re-process events as outliers 2026-06-20 17:07:59 +01:00
e8db01fc8d
style: Improve logging 2026-06-20 17:07:59 +01:00
f80e1e89a5
fix: Lower floor for min depth 2026-06-20 17:07:59 +01:00
b9dca84acf
fix: Only increment mindepth on state events 2026-06-20 17:07:59 +01:00
e3ec1066c4
chore: Add newsfrag 2026-06-20 17:07:59 +01:00
1445a8d446
feat: Keep track of a min_depth value
Should prevent weird situations where we accidentally gapfill into backfill territory
2026-06-20 17:07:59 +01:00
9547c438d6
perf: Increase default max_fetch_prev_events to 256 2026-06-20 17:07:59 +01:00
51d0e615f5
perf: Make max gap depth fetch configurable 2026-06-20 17:07:59 +01:00
eeb937416c
perf: Improve gap filling, handle missing auth events better 2026-06-20 17:07:59 +01:00
0d5aa7ede1
fix: This is some bullshit I tell you 2026-06-20 17:07:59 +01:00
ba9dc27773
feat: Better prev event fetching
fix: Don't panic in debug mode when making an empty notary query
2026-06-20 17:07:59 +01:00
abf5a155ba
feat: Add backfill_missing_events helper 2026-06-20 17:07:59 +01:00