gioser

tawasuyu/card

Sovereign content-addressed identity primitive (card-core + WIT-typed flows) in Rust.

Markdown 9Rust 7TOML 4HTML 1165 Definiciones

chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0)

Regenerado con scripts/actualizar-standalone.py. Cargo.toml raíz nuevo (el
anterior tenía marcadores de conflicto sin resolver). cargo check verde.

58c483eb2fefeb68d02cc572e9c29698277a5f68 · por Sergio · (hace 2 meses) · padre c1a3a711f · ver el árbol en este commit

Delta semántico · 39

shared/card/card-core/src/lib.rs

shared/card/card-net/src/lib.rs

14 archivos · +1526 −791

diff --git a/Cargo.lock b/Cargo.lock
index f99711c..3f59096 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,9 +39,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.102"
+version = "1.0.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
 
 [[package]]
 name = "arrayref"
@@ -51,9 +51,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
 
 [[package]]
 name = "arrayvec"
-version = "0.7.6"
+version = "0.7.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
 
 [[package]]
 name = "asn1-rs"
@@ -67,7 +67,7 @@ dependencies = [
  "nom",
  "num-traits",
  "rusticata-macros",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "time",
 ]
 
@@ -79,7 +79,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
  "synstructure",
 ]
 
@@ -91,7 +91,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -114,13 +114,13 @@ dependencies = [
 
 [[package]]
 name = "async-trait"
-version = "0.1.89"
+version = "0.1.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 3.0.3",
 ]
 
 [[package]]
@@ -185,6 +185,12 @@ dependencies = [
  "match-lookup",
 ]
 
+[[package]]
+name = "base45"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240e56f4d3c453c36faacb695c535a4d5f8c7d23dac175014f32eb0a71012a03"
+
 [[package]]
 name = "base64"
 version = "0.22.1"
@@ -199,9 +205,9 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
 
 [[package]]
 name = "bitflags"
-version = "2.12.1"
+version = "2.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
 
 [[package]]
 name = "blake2"
@@ -258,18 +264,19 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.11.1"
+version = "1.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
 
 [[package]]
 name = "card-core"
 version = "0.1.0"
 dependencies = [
+ "format",
  "postcard",
  "serde",
  "serde_json",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "toml",
  "ulid",
 ]
@@ -284,10 +291,9 @@ dependencies = [
  "libp2p-allow-block-list",
  "libp2p-stream",
  "serde",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tokio",
  "tokio-util",
- "tracing",
 ]
 
 [[package]]
@@ -296,15 +302,15 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "card-core",
- "thiserror 2.0.18",
- "wit-parser 0.230.0",
+ "thiserror 2.0.19",
+ "wit-parser",
 ]
 
 [[package]]
 name = "cc"
-version = "1.2.63"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
+checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
 dependencies = [
  "find-msvc-tools",
  "shlex",
@@ -318,9 +324,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
 
 [[package]]
 name = "cfg_aliases"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
 
 [[package]]
 name = "chacha20"
@@ -333,6 +339,17 @@ dependencies = [
  "cpufeatures 0.2.17",
 ]
 
+[[package]]
+name = "chacha20"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "rand_core 0.10.1",
+]
+
 [[package]]
 name = "chacha20poly1305"
 version = "0.10.1"
@@ -340,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
 dependencies = [
  "aead",
- "chacha20",
+ "chacha20 0.9.1",
  "cipher",
  "poly1305",
  "zeroize",
@@ -363,7 +380,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
 dependencies = [
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
 ]
 
 [[package]]
@@ -435,27 +452,27 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.15"
+version = "0.5.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
+checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e"
 dependencies = [
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.18"
+version = "0.9.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
 dependencies = [
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.21"
+version = "0.8.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17"
 
 [[package]]
 name = "crunchy"
@@ -507,7 +524,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -533,7 +550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090"
 dependencies = [
  "data-encoding",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -565,9 +582,6 @@ name = "deranged"
 version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
-dependencies = [
- "powerfmt",
-]
 
 [[package]]
 name = "digest"
@@ -588,7 +602,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -623,9 +637,9 @@ dependencies = [
 
 [[package]]
 name = "either"
-version = "1.16.0"
+version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
 
 [[package]]
 name = "embedded-io"
@@ -648,7 +662,7 @@ dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -667,6 +681,18 @@ dependencies = [
  "windows-sys 0.61.2",
 ]
 
+[[package]]
+name = "fastbloom"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef975e30683b2d965054bb0a836f8973857c4ebf6acf274fe46617cd285060d8"
+dependencies = [
+ "foldhash 0.2.0",
+ "libm",
+ "portable-atomic",
+ "siphasher",
+]
+
 [[package]]
 name = "fiat-crypto"
 version = "0.2.9"
@@ -691,6 +717,12 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
 
+[[package]]
+name = "foldhash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
+
 [[package]]
 name = "form_urlencoded"
 version = "1.2.2"
@@ -700,11 +732,22 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "format"
+version = "0.1.0"
+source = "git+https://git.tawasuyu.net/tawasuyu/tawasuyu.git?tag=v0.2.0#a446bb3a73a0e022158cc0ec7deb65173859644b"
+dependencies = [
+ "blake3",
+ "postcard",
+ "serde",
+ "serde-big-array",
+]
+
 [[package]]
 name = "futures"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
+checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -727,9 +770,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
+checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -737,15 +780,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
+checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
+checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -754,9 +797,9 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
+checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
 
 [[package]]
 name = "futures-lite"
@@ -770,13 +813,13 @@ dependencies = [
 
 [[package]]
 name = "futures-macro"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
+checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -792,15 +835,15 @@ dependencies = [
 
 [[package]]
 name = "futures-sink"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
+checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
 
 [[package]]
 name = "futures-task"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
+checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
 
 [[package]]
 name = "futures-timer"
@@ -810,9 +853,9 @@ checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968"
 
 [[package]]
 name = "futures-util"
-version = "0.3.32"
+version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
+checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -855,24 +898,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
 dependencies = [
  "cfg-if",
- "js-sys",
  "libc",
  "r-efi 5.3.0",
  "wasip2",
- "wasm-bindgen",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
 dependencies = [
  "cfg-if",
+ "js-sys",
  "libc",
  "r-efi 6.0.0",
- "wasip2",
- "wasip3",
+ "rand_core 0.10.1",
+ "wasm-bindgen",
 ]
 
 [[package]]
@@ -887,9 +929,9 @@ dependencies = [
 
 [[package]]
 name = "h2"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
+checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -919,7 +961,7 @@ version = "0.15.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
 dependencies = [
- "foldhash",
+ "foldhash 0.1.5",
 ]
 
 [[package]]
@@ -985,10 +1027,10 @@ dependencies = [
  "idna",
  "ipnet",
  "once_cell",
- "rand 0.9.4",
+ "rand 0.9.5",
  "ring",
  "socket2 0.5.10",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tinyvec",
  "tokio",
  "tracing",
@@ -1008,10 +1050,10 @@ dependencies = [
  "moka",
  "once_cell",
  "parking_lot",
- "rand 0.9.4",
+ "rand 0.9.5",
  "resolv-conf",
  "smallvec",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tokio",
  "tracing",
 ]
@@ -1036,9 +1078,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "1.4.1"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0"
+checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
 dependencies = [
  "bytes",
  "itoa",
@@ -1046,9 +1088,9 @@ dependencies = [
 
 [[package]]
 name = "http-body"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
 dependencies = [
  "bytes",
  "http",
@@ -1056,9 +1098,9 @@ dependencies = [
 
 [[package]]
 name = "http-body-util"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
 dependencies = [
  "bytes",
  "futures-core",
@@ -1075,9 +1117,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
 
 [[package]]
 name = "hyper"
-version = "1.10.1"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
+checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
 dependencies = [
  "atomic-waker",
  "bytes",
@@ -1108,7 +1150,7 @@ dependencies = [
  "hyper",
  "libc",
  "pin-project-lite",
- "socket2 0.6.4",
+ "socket2 0.6.5",
  "tokio",
  "tower-service",
  "tracing",
@@ -1271,7 +1313,7 @@ dependencies = [
  "hyper",
  "hyper-util",
  "log",
- "rand 0.9.4",
+ "rand 0.9.5",
  "tokio",
  "url",
  "xmltree",
@@ -1304,7 +1346,7 @@ version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222"
 dependencies = [
- "socket2 0.6.4",
+ "socket2 0.6.5",
  "widestring",
  "windows-registry",
  "windows-result",
@@ -1334,13 +1376,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
 
 [[package]]
 name = "js-sys"
-version = "0.3.99"
+version = "0.3.103"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11"
+checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
 dependencies = [
  "cfg-if",
  "futures-util",
- "once_cell",
  "wasm-bindgen",
 ]
 
@@ -1351,16 +1392,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
-name = "leb128fmt"
-version = "0.1.0"
+name = "libc"
+version = "0.2.189"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
 
 [[package]]
-name = "libc"
-version = "0.2.186"
+name = "libm"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
 
 [[package]]
 name = "libp2p"
@@ -1394,7 +1435,7 @@ dependencies = [
  "multiaddr",
  "pin-project",
  "rw-stream-sink",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
 ]
 
 [[package]]
@@ -1426,9 +1467,9 @@ dependencies = [
  "libp2p-swarm",
  "quick-protobuf",
  "quick-protobuf-codec",
- "rand 0.8.6",
+ "rand 0.8.7",
  "rand_core 0.6.4",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "web-time",
 ]
@@ -1461,9 +1502,9 @@ dependencies = [
  "parking_lot",
  "pin-project",
  "quick-protobuf",
- "rand 0.8.6",
+ "rand 0.8.7",
  "rw-stream-sink",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "unsigned-varint 0.8.0",
  "web-time",
@@ -1486,7 +1527,7 @@ dependencies = [
  "libp2p-swarm",
  "quick-protobuf",
  "quick-protobuf-codec",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "web-time",
 ]
@@ -1524,7 +1565,7 @@ dependencies = [
  "quick-protobuf",
  "quick-protobuf-codec",
  "smallvec",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
 ]
 
@@ -1539,9 +1580,9 @@ dependencies = [
  "hkdf",
  "multihash",
  "prost",
- "rand 0.8.6",
+ "rand 0.8.7",
  "sha2",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "zeroize",
 ]
@@ -1564,10 +1605,10 @@ dependencies = [
  "libp2p-swarm",
  "quick-protobuf",
  "quick-protobuf-codec",
- "rand 0.8.6",
+ "rand 0.8.7",
  "sha2",
  "smallvec",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "uint",
  "web-time",
@@ -1585,7 +1626,7 @@ dependencies = [
  "libp2p-core",
  "libp2p-identity",
  "libp2p-swarm",
- "rand 0.8.6",
+ "rand 0.8.7",
  "smallvec",
  "socket2 0.5.10",
  "tokio",
@@ -1625,10 +1666,10 @@ dependencies = [
  "multiaddr",
  "multihash",
  "quick-protobuf",
- "rand 0.8.6",
+ "rand 0.8.7",
  "snow",
  "static_assertions",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "x25519-dalek",
  "zeroize",
@@ -1636,9 +1677,9 @@ dependencies = [
 
 [[package]]
 name = "libp2p-quic"
-version = "0.13.0"
+version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dc448b2de9f4745784e3751fe8bc6c473d01b8317edd5ababcb0dec803d843f"
+checksum = "9dcc597d70bf7f6f30cbe07081802c836184e48416e89e9ce73a0ba2c56a319e"
 dependencies = [
  "futures",
  "futures-timer",
@@ -1647,11 +1688,12 @@ dependencies = [
  "libp2p-identity",
  "libp2p-tls",
  "quinn",
- "rand 0.8.6",
+ "quinn-proto",
+ "rand 0.8.7",
  "ring",
  "rustls",
  "socket2 0.5.10",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tokio",
  "tracing",
 ]
@@ -1673,9 +1715,9 @@ dependencies = [
  "libp2p-swarm",
  "quick-protobuf",
  "quick-protobuf-codec",
- "rand 0.8.6",
+ "rand 0.8.7",
  "static_assertions",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "web-time",
 ]
@@ -1692,7 +1734,7 @@ dependencies = [
  "libp2p-core",
  "libp2p-identity",
  "libp2p-swarm",
- "rand 0.8.6",
+ "rand 0.8.7",
  "smallvec",
  "tracing",
 ]
@@ -1707,7 +1749,7 @@ dependencies = [
  "libp2p-core",
  "libp2p-identity",
  "libp2p-swarm",
- "rand 0.8.6",
+ "rand 0.8.7",
  "tracing",
 ]
 
@@ -1726,7 +1768,7 @@ dependencies = [
  "libp2p-identity",
  "libp2p-swarm-derive",
  "multistream-select",
- "rand 0.8.6",
+ "rand 0.8.7",
  "smallvec",
  "tokio",
  "tracing",
@@ -1741,7 +1783,7 @@ checksum = "dd297cf53f0cb3dee4d2620bb319ae47ef27c702684309f682bdb7e55a18ae9c"
 dependencies = [
  "heck",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -1755,7 +1797,7 @@ dependencies = [
  "if-watch",
  "libc",
  "libp2p-core",
- "socket2 0.6.4",
+ "socket2 0.6.5",
  "tokio",
  "tracing",
 ]
@@ -1774,7 +1816,7 @@ dependencies = [
  "ring",
  "rustls",
  "rustls-webpki",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "x509-parser",
  "yasna",
 ]
@@ -1803,7 +1845,7 @@ dependencies = [
  "either",
  "futures",
  "libp2p-core",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tracing",
  "yamux 0.12.1",
  "yamux 0.13.10",
@@ -1832,9 +1874,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.32"
+version = "0.4.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
+checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
 
 [[package]]
 name = "lru-slab"
@@ -1850,14 +1892,14 @@ checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
 name = "memchr"
-version = "2.8.1"
+version = "2.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
 
 [[package]]
 name = "minimal-lexical"
@@ -1867,9 +1909,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "mio"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
 dependencies = [
  "libc",
  "wasi",
@@ -1914,12 +1956,13 @@ dependencies = [
 
 [[package]]
 name = "multibase"
-version = "0.9.2"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77"
+checksum = "7e0e4a371cbf1dfd666b658ba137763edb23c45beb43cfe369b5593cd6b437b6"
 dependencies = [
  "base-x",
  "base256emoji",
+ "base45",
  "data-encoding",
  "data-encoding-macro",
 ]
@@ -1970,16 +2013,17 @@ dependencies = [
 
 [[package]]
 name = "netlink-proto"
-version = "0.12.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b65d130ee111430e47eed7896ea43ca693c387f097dd97376bffafbf25812128"
+checksum = "e6f7398dddf5f152d2a91a2921a134c6097056e292c0d4b9906007855e7cece6"
 dependencies = [
  "bytes",
- "futures",
+ "futures-channel",
+ "futures-util",
  "log",
  "netlink-packet-core",
  "netlink-sys",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
 ]
 
 [[package]]
@@ -2025,9 +2069,9 @@ dependencies = [
 
 [[package]]
 name = "num-bigint"
-version = "0.4.6"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
 dependencies = [
  "num-integer",
  "num-traits",
@@ -2150,7 +2194,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -2208,9 +2252,9 @@ dependencies = [
 
 [[package]]
 name = "portable-atomic"
-version = "1.13.1"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
+checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
 
 [[package]]
 name = "postcard"
@@ -2249,21 +2293,11 @@ dependencies = [
  "zerocopy",
 ]
 
-[[package]]
-name = "prettyplease"
-version = "0.2.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
-dependencies = [
- "proc-macro2",
- "syn",
-]
-
 [[package]]
 name = "proc-macro2"
-version = "1.0.106"
+version = "1.0.107"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
 dependencies = [
  "unicode-ident",
 ]
@@ -2288,14 +2322,14 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
 name = "prost"
-version = "0.14.3"
+version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
+checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
 dependencies = [
  "bytes",
  "prost-derive",
@@ -2303,15 +2337,15 @@ dependencies = [
 
 [[package]]
 name = "prost-derive"
-version = "0.14.3"
+version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
+checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
 dependencies = [
  "anyhow",
  "itertools",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -2338,9 +2372,9 @@ dependencies = [
 
 [[package]]
 name = "quinn"
-version = "0.11.9"
+version = "0.11.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
+checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
 dependencies = [
  "bytes",
  "cfg_aliases",
@@ -2350,8 +2384,8 @@ dependencies = [
  "quinn-udp",
  "rustc-hash",
  "rustls",
- "socket2 0.6.4",
- "thiserror 2.0.18",
+ "socket2 0.6.5",
+ "thiserror 2.0.19",
  "tokio",
  "tracing",
  "web-time",
@@ -2359,20 +2393,22 @@ dependencies = [
 
 [[package]]
 name = "quinn-proto"
-version = "0.11.14"
+version = "0.11.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
+checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560"
 dependencies = [
  "bytes",
- "getrandom 0.3.4",
+ "fastbloom",
+ "getrandom 0.4.3",
  "lru-slab",
- "rand 0.9.4",
+ "rand 0.10.2",
+ "rand_pcg",
  "ring",
  "rustc-hash",
  "rustls",
  "rustls-pki-types",
  "slab",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "tinyvec",
  "tracing",
  "web-time",
@@ -2380,23 +2416,23 @@ dependencies = [
 
 [[package]]
 name = "quinn-udp"
-version = "0.5.14"
+version = "0.5.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
+checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
 dependencies = [
  "cfg_aliases",
  "libc",
  "once_cell",
- "socket2 0.6.4",
+ "socket2 0.6.5",
  "tracing",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.45"
+version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
 dependencies = [
  "proc-macro2",
 ]
@@ -2415,9 +2451,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
 
 [[package]]
 name = "rand"
-version = "0.8.6"
+version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
+checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a"
 dependencies = [
  "libc",
  "rand_chacha 0.3.1",
@@ -2426,14 +2462,25 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.9.4"
+version = "0.9.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
+checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
 dependencies = [
  "rand_chacha 0.9.0",
  "rand_core 0.9.5",
 ]
 
+[[package]]
+name = "rand"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
+dependencies = [
+ "chacha20 0.10.1",
+ "getrandom 0.4.3",
+ "rand_core 0.10.1",
+]
+
 [[package]]
 name = "rand_chacha"
 version = "0.3.1"
@@ -2472,6 +2519,21 @@ dependencies = [
  "getrandom 0.3.4",
 ]
 
+[[package]]
+name = "rand_core"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+
+[[package]]
+name = "rand_pcg"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
+dependencies = [
+ "rand_core 0.10.1",
+]
+
 [[package]]
 name = "rcgen"
 version = "0.13.2"
@@ -2534,9 +2596,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-hash"
-version = "2.1.2"
+version = "2.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
+checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
 
 [[package]]
 name = "rustc_version"
@@ -2571,9 +2633,9 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.23.40"
+version = "0.23.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
+checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
 dependencies = [
  "once_cell",
  "ring",
@@ -2585,9 +2647,9 @@ dependencies = [
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.14.1"
+version = "1.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
 dependencies = [
  "web-time",
  "zeroize",
@@ -2606,9 +2668,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.22"
+version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
 
 [[package]]
 name = "rw-stream-sink"
@@ -2635,39 +2697,48 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
 
 [[package]]
 name = "serde"
-version = "1.0.228"
+version = "1.0.229"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
 dependencies = [
  "serde_core",
  "serde_derive",
 ]
 
+[[package]]
+name = "serde-big-array"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_core"
-version = "1.0.228"
+version = "1.0.229"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.228"
+version = "1.0.229"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 3.0.3",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.150"
+version = "1.0.151"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
 dependencies = [
  "itoa",
  "memchr",
@@ -2721,6 +2792,12 @@ dependencies = [
  "rand_core 0.6.4",
 ]
 
+[[package]]
+name = "siphasher"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+
 [[package]]
 name = "slab"
 version = "0.4.12"
@@ -2729,9 +2806,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
 
 [[package]]
 name = "smallvec"
-version = "1.15.1"
+version = "1.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
 
 [[package]]
 name = "snow"
@@ -2762,9 +2839,9 @@ dependencies = [
 
 [[package]]
 name = "socket2"
-version = "0.6.4"
+version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
+checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
 dependencies = [
  "libc",
  "windows-sys 0.61.2",
@@ -2772,9 +2849,9 @@ dependencies = [
 
 [[package]]
 name = "spin"
-version = "0.9.8"
+version = "0.9.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
 dependencies = [
  "lock_api",
 ]
@@ -2809,9 +2886,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 
 [[package]]
 name = "syn"
-version = "2.0.117"
+version = "2.0.119"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2826,7 +2914,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -2867,11 +2955,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.18"
+version = "2.0.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
 dependencies = [
- "thiserror-impl 2.0.18",
+ "thiserror-impl 2.0.19",
 ]
 
 [[package]]
@@ -2882,28 +2970,27 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.18"
+version = "2.0.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 3.0.3",
 ]
 
 [[package]]
 name = "time"
-version = "0.3.47"
+version = "0.3.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
+checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244"
 dependencies = [
  "deranged",
- "itoa",
  "num-conv",
  "powerfmt",
  "serde_core",
@@ -2913,15 +3000,15 @@ dependencies = [
 
 [[package]]
 name = "time-core"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
+checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
 
 [[package]]
 name = "time-macros"
-version = "0.2.27"
+version = "0.2.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
+checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85"
 dependencies = [
  "num-conv",
  "time-core",
@@ -2939,9 +3026,9 @@ dependencies = [
 
 [[package]]
 name = "tinyvec"
-version = "1.11.0"
+version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
+checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
 dependencies = [
  "tinyvec_macros",
 ]
@@ -2954,9 +3041,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.52.3"
+version = "1.53.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
 dependencies = [
  "bytes",
  "libc",
@@ -2964,32 +3051,33 @@ dependencies = [
  "parking_lot",
  "pin-project-lite",
  "signal-hook-registry",
- "socket2 0.6.4",
+ "socket2 0.6.5",
  "tokio-macros",
  "windows-sys 0.61.2",
 ]
 
 [[package]]
 name = "tokio-macros"
-version = "2.7.0"
+version = "2.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
+checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
 name = "tokio-util"
-version = "0.7.18"
+version = "0.7.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
+checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
 dependencies = [
  "bytes",
  "futures-core",
  "futures-io",
  "futures-sink",
+ "libc",
  "pin-project-lite",
  "tokio",
 ]
@@ -3047,6 +3135,7 @@ version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
 dependencies = [
+ "log",
  "pin-project-lite",
  "tracing-attributes",
  "tracing-core",
@@ -3060,7 +3149,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -3102,7 +3191,7 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe"
 dependencies = [
- "rand 0.9.4",
+ "rand 0.9.5",
  "serde",
  "web-time",
 ]
@@ -3167,11 +3256,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
 
 [[package]]
 name = "uuid"
-version = "1.23.2"
+version = "1.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7"
+checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
 dependencies = [
- "getrandom 0.4.2",
+ "getrandom 0.4.3",
  "js-sys",
  "wasm-bindgen",
 ]
@@ -3199,27 +3288,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
 
 [[package]]
 name = "wasip2"
-version = "1.0.3+wasi-0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
-dependencies = [
- "wit-bindgen 0.57.1",
-]
-
-[[package]]
-name = "wasip3"
-version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+version = "1.0.4+wasi-0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
 dependencies = [
- "wit-bindgen 0.51.0",
+ "wit-bindgen",
 ]
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.122"
+version = "0.2.126"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409"
+checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -3230,9 +3310,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.122"
+version = "0.2.126"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6"
+checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -3240,48 +3320,26 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.122"
+version = "0.2.126"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e"
+checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
 dependencies = [
  "bumpalo",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.122"
+version = "0.2.126"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437"
+checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
 dependencies = [
  "unicode-ident",
 ]
 
-[[package]]
-name = "wasm-encoder"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
-dependencies = [
- "leb128fmt",
- "wasmparser 0.244.0",
-]
-
-[[package]]
-name = "wasm-metadata"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
-dependencies = [
- "anyhow",
- "indexmap",
- "wasm-encoder",
- "wasmparser 0.244.0",
-]
-
 [[package]]
 name = "wasmparser"
 version = "0.230.0"
@@ -3293,18 +3351,6 @@ dependencies = [
  "semver",
 ]
 
-[[package]]
-name = "wasmparser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
-dependencies = [
- "bitflags",
- "hashbrown 0.15.5",
- "indexmap",
- "semver",
-]
-
 [[package]]
 name = "web-time"
 version = "1.1.0"
@@ -3374,7 +3420,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -3385,7 +3431,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -3439,16 +3485,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
-dependencies = [
- "windows-targets 0.53.5",
+ "windows-targets",
 ]
 
 [[package]]
@@ -3466,31 +3503,14 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm 0.52.6",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.53.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
-dependencies = [
- "windows-link",
- "windows_aarch64_gnullvm 0.53.1",
- "windows_aarch64_msvc 0.53.1",
- "windows_i686_gnu 0.53.1",
- "windows_i686_gnullvm 0.53.1",
- "windows_i686_msvc 0.53.1",
- "windows_x86_64_gnu 0.53.1",
- "windows_x86_64_gnullvm 0.53.1",
- "windows_x86_64_msvc 0.53.1",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
 [[package]]
@@ -3508,96 +3528,48 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
-
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
-
 [[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 
-[[package]]
-name = "windows_i686_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
-
 [[package]]
 name = "windows_i686_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
-
 [[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
-[[package]]
-name = "windows_i686_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
-
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
-
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
-
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
-
 [[package]]
 name = "winnow"
 version = "0.7.15"
@@ -3607,82 +3579,12 @@ dependencies = [
  "memchr",
 ]
 
-[[package]]
-name = "wit-bindgen"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
-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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
-dependencies = [
- "anyhow",
- "heck",
- "wit-parser 0.244.0",
-]
-
-[[package]]
-name = "wit-bindgen-rust"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
-dependencies = [
- "anyhow",
- "heck",
- "indexmap",
- "prettyplease",
- "syn",
- "wasm-metadata",
- "wit-bindgen-core",
- "wit-component",
-]
-
-[[package]]
-name = "wit-bindgen-rust-macro"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
-dependencies = [
- "anyhow",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn",
- "wit-bindgen-core",
- "wit-bindgen-rust",
-]
-
-[[package]]
-name = "wit-component"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
-dependencies = [
- "anyhow",
- "bitflags",
- "indexmap",
- "log",
- "serde",
- "serde_derive",
- "serde_json",
- "wasm-encoder",
- "wasm-metadata",
- "wasmparser 0.244.0",
- "wit-parser 0.244.0",
-]
-
 [[package]]
 name = "wit-parser"
 version = "0.230.0"
@@ -3698,25 +3600,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.230.0",
-]
-
-[[package]]
-name = "wit-parser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
-dependencies = [
- "anyhow",
- "id-arena",
- "indexmap",
- "log",
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
- "unicode-xid",
- "wasmparser 0.244.0",
+ "wasmparser",
 ]
 
 [[package]]
@@ -3750,7 +3634,7 @@ dependencies = [
  "nom",
  "oid-registry",
  "rusticata-macros",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
  "time",
 ]
 
@@ -3780,7 +3664,7 @@ dependencies = [
  "nohash-hasher",
  "parking_lot",
  "pin-project",
- "rand 0.8.6",
+ "rand 0.8.7",
  "static_assertions",
 ]
 
@@ -3795,7 +3679,7 @@ dependencies = [
  "nohash-hasher",
  "parking_lot",
  "pin-project",
- "rand 0.9.4",
+ "rand 0.9.5",
  "static_assertions",
  "web-time",
 ]
@@ -3828,28 +3712,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
  "synstructure",
 ]
 
 [[package]]
 name = "zerocopy"
-version = "0.8.50"
+version = "0.8.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1"
+checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb"
 dependencies = [
  "zerocopy-derive",
 ]
 
 [[package]]
 name = "zerocopy-derive"
-version = "0.8.50"
+version = "0.8.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639"
+checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -3869,28 +3753,28 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
  "synstructure",
 ]
 
 [[package]]
 name = "zeroize"
-version = "1.8.2"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
 dependencies = [
  "zeroize_derive",
 ]
 
 [[package]]
 name = "zeroize_derive"
-version = "1.4.3"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
+checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
@@ -3923,11 +3807,11 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
+ "syn 2.0.119",
 ]
 
 [[package]]
 name = "zmij"
-version = "1.0.21"
+version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
diff --git a/Cargo.toml b/Cargo.toml
index 3455027..e09890f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,13 +1,24 @@
-# Cargo.toml raíz STANDALONE de card — front-door sobre Llimphi.
-# Solo el código de card; Llimphi y lo fundacional por git-dep del monorepo gioser.git.
+# Cargo.toml raíz STANDALONE de card — front-door público.
+# GENERADO por scripts/actualizar-standalone.py desde el monorepo tawasuyu.git
+# (v0.2.0). No editar a mano: se regenera. Lo fundacional se consume por
+# git-dep al tag; sólo el código del dominio vive en este repo.
 [workspace]
 resolver = "2"
+
+# ============================================================
+# Cuadrantes — agregar a medida que se migran
+# ============================================================
 members = [
     "shared/card/card-core",
     "shared/card/card-net",
     "shared/card/card-wit",
 ]
 
+# `wawa/` se excluye del workspace global porque corre en target
+# `x86_64-unknown-none` y `panic = "abort"`, incompatibles con los
+# perfiles globales. Los crates compartidos se referencian por `path`
+# cruzando la frontera.
+
 [workspace.package]
 version = "0.1.0"
 edition = "2021"
@@ -15,20 +26,35 @@ rust-version = "1.80"
 license = "MIT"
 authors = ["Sergio <gerencia@jlsoltech.com>"]
 publish = false
-<<<<<<< HEAD
 repository = "https://git.tawasuyu.net/tawasuyu/card"
-=======
-repository = "https://gitea.tawasuyu.net/sergio/card"
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
 
 [workspace.dependencies]
-
+# === Configuración declarativa (vocabulario de esquemas) ===
+allichay = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+marca = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# Telemetría local de desarrollo (stderr+panics+tracing → $XDG_STATE_HOME/tawasuyu/<dominio>/<bin>.log)
+bitacora = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# default = [] (núcleo liviano sin vello); `bake` es opt-in. Declaramos
+# default-features = false aquí para que el `default-features = false` de los
+# consumidores (splash/greeter/compositor) se honre y no quede el warning.
+mirada-fondo = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+mirada-teclado-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+mirada-teclado-widget = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 # === Registro de apps / menú global ===
-<<<<<<< HEAD
-app-bus = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-=======
-app-bus = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
+app-bus = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+app-iconset = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# === Centro de eventos (notificaciones + capturas + clipboard + …) ===
+willay-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+willay-checkpoint = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+willay-hilo = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+willay-store = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+willay-emit = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+rag-motor = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+churay-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+churay-welcome = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+churay-welcome-runner = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# === Puente de drag-and-drop compositor → app (suple winit en Wayland) ===
+drop-bridge = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 # === Serialización ===
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
@@ -55,8 +81,12 @@ tracing = "0.1"
 tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
 
 # === Linux primitives (arje) ===
-nix = { version = "0.29", features = ["signal", "process", "sched", "mount", "fs", "socket", "net", "user"] }
+nix = { version = "0.29", features = ["signal", "process", "sched", "mount", "fs", "socket", "net", "user", "reboot"] }
 libc = "0.2"
+# DRM/KMS legacy (dumb buffer) para el splash nativo del arranque sin parpadeo.
+# Misma versión que reexporta smithay (mirada-compositor) — el lock ya la fija.
+drm = "0.14"
+font8x8 = { version = "0.3", default-features = false }
 
 # === IDs / Hash / Crypto ===
 ulid = { version = "1", features = ["serde"] }
@@ -70,10 +100,15 @@ argon2 = "0.5"
 rand = "0.8"
 
 # === WASM (arje) ===
-# wasmi 1.0: unifica la versión con renaser (su kernel ya corre 1.0), para
+# wasmi 1.0: unifica la versión con wawa (su kernel ya corre 1.0), para
 # que el ABI WASM del host sea idéntico en Linux y en bare-metal.
 wasmi = "1.0"
 wat = "1"
+# wasmtime 46 (Fase 1 del pipeline JS): tier 0 de puriy-js pasa de wasmi
+# (intérprete) a Wasmtime AOT (Cranelift → nativo) en Linux — quita la doble
+# interpretación de QuickJS.wasm. En wawa bare-metal el runtime es Pulley (spike
+# Q1 cerrado); mismo crate, distinto backend.
+wasmtime = "46"
 
 # === Storage / DB ===
 sled = "0.34"
@@ -88,6 +123,10 @@ bzip2 = "0.4"
 
 # === Compresión (minga multi-bundle) ===
 zstd = "0.13"
+xz2 = "0.1"
+# Contenedores adicionales del visor Archive de nahual (sólo listado).
+sevenz-rust = "0.6"
+unrar = "0.5"
 
 # === HTTP server (iniy-server) ===
 axum = "0.7"
@@ -97,7 +136,7 @@ tower = "0.5"
 instant-distance = "0.6"
 
 # === P2P (minga) ===
-libp2p = { version = "0.56", features = ["tokio", "tcp", "noise", "yamux", "macros", "kad", "identify", "relay", "dcutr", "autonat", "mdns"] }
+libp2p = { version = "0.56", features = ["tokio", "tcp", "dns", "noise", "yamux", "macros", "kad", "identify", "relay", "dcutr", "autonat", "mdns"] }
 libp2p-stream = "=0.4.0-alpha"
 libp2p-allow-block-list = "0.6"
 
@@ -112,7 +151,11 @@ libm = "0.2"
 midly = "0.5"
 
 # === Code parsing (minga) ===
-arboard = "3"
+# `wayland-data-control` trae el backend wl-clipboard-rs: bajo mirada (Wayland
+# propio, sin Xwayland para apps nativas) arboard-x11 fallaba a no-op silencioso
+# y el clipboard de los text-editor quedaba muerto. Con la feature habla
+# zwlr_data_control_manager_v1 (que mirada expone) y cae a X11 si no hay Wayland.
+arboard = { version = "3", features = ["wayland-data-control"] }
 ropey = "1.6"
 tree-sitter = "0.24"
 tree-sitter-rust = "0.23"
@@ -131,7 +174,19 @@ petgraph = "0.6"
 # default-features = false: nos quedamos con PNG + JPEG + WebP (lossless).
 # tullpu-render exporta a las tres; AVIF/TIFF/… los habilitamos si una app
 # los pide específicamente.
-image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp"] }
+# Decoders puro-Rust baratos; avif queda fuera (arrastra dav1d/rav1e).
+image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif", "bmp", "ico", "tiff", "tga", "qoi"] }
+# ONNX Runtime para los proveedores de píxel reales (pixel-verbo-onnx: segmentación
+# u2net/isnet, inpaint, restyle…). `download-binaries` (default) baja el runtime nativo
+# solo; ya lo arrastraba fastembed (rimay-verbo) transitivo — aquí lo declaramos directo.
+ort = "2.0.0-rc.9"
+
+# Rasterizador vectorial CPU (relleno/trazo anti-aliased) para capas vectoriales de tullpu.
+tiny-skia = "0.11"
+# Booleanos de polígonos robustos (union/intersection/difference/xor) para el
+# clipper vectorial de tullpu — restar/intersecar paths que se solapan
+# parcialmente, que la regla de relleno no expresa. Ya estaba en el lock.
+geo = "0.28"
 
 # === FUSE (minga-vfs) ===
 # default-features = false: prescinde de pkg-config/libfuse-dev en build.
@@ -153,166 +208,164 @@ tempfile = "3"
 
 # === Llimphi (motor gráfico soberano) ===
 # wgpu sobre Vulkan/Metal/DX12, winit para ventana en dev Linux.
-# raw-window-handle 0.6 alinea winit 0.30 con wgpu 24.
-# vello 0.5 = rasterizador vectorial sobre wgpu 24.
+# raw-window-handle 0.6 alinea winit 0.30 con wgpu 27.
+# vello 0.7 = rasterizador vectorial sobre wgpu 27 (renderer GPU "wgpu" + opt-in "hybrid" CPU+GPU).
 # taffy 0.9 = motor Flexbox/Grid puro Rust (ya pulled por transitivos, lo alineamos).
-# parley 0.2 = shaping/layout de texto compatible con peniko 0.4 (que vello 0.5 expone).
-wgpu = "24"
+# parley 0.6 = shaping/layout de texto compatible con peniko 0.6 (que vello 0.7 expone).
+wgpu = "27"
 winit = "0.30"
 raw-window-handle = "0.6"
 pollster = "0.4"
-vello = "0.5"
+vello = "0.7"
+# Renderer hybrid CPU+GPU sin compute shaders (mejor compat WebGL2/Adreno viejas).
+# Opt-in; el renderer "wgpu" sigue siendo el default.
+vello_hybrid = "0.0.9"
+# foreign-lottie = fork vendorizado de velato 0.9 (Lottie → vello::Scene),
+# completado para no paniquear ante features no soportadas. Lo consume
+# llimphi-lottie. Ver shared/foreign-lottie.
+foreign-lottie = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# Árbol de accesibilidad para lectores de pantalla (NVDA/VoiceOver/Orca/TalkBack).
+# Lo consume el runtime de Llimphi (iter 2/3 del plan AccessKit); el modelo
+# `SemanticsSpec` del compositor es independiente de estas crates.
+accesskit = "0.24"
+accesskit_winit = "0.33"
 taffy = "0.9"
 # parley = shaping completo (bidi, ligatures, fallback CJK/emoji vía fontique, line break).
-parley = "0.4"
+parley = "0.6"
 # Bucle Elm (input→update→view→layout→raster→present). Lo consumen las apps.
-<<<<<<< HEAD
-llimphi-ui = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-ui = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Tier 3 — apps WASM con UI Llimphi real. El guest pinta un WireNode (IR
+# serializable), el host (runner) lo materializa en View<Msg> y rebota los
+# eventos al update del guest. SDK = lado guest, runner = lado host.
+llimphi-wire-view = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-wasm-app-sdk = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-wasm-runner = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Núcleo puro de distribución (CAS + verificación + resolve), SIN runner/GPU.
+llimphi-wasm-core = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Cara con baterías: re-exporta core + puente al runner para correr la app.
+llimphi-wasm-dist = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-wasm-open = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-wasm-registry = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-wasm-wasi = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Transporte P2P del bytecode por hash sobre BrahmanNet (card-net).
+llimphi-wasm-net = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-3d = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Runner wlr-layer-shell: corre un `App` de Llimphi como barra anclada a un
+# borde (no como ventana), reusando la plumbing sctk+wgpu que pata probó.
+llimphi-layer = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Paleta semántica compartida por las apps y los widgets.
-llimphi-theme = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-theme = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Tweens y helpers de animación sobre el bucle Elm.
-llimphi-motion = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-motion = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Máquina de estados de animación (estilo Rive) clip-agnóstica. Núcleo puro;
+# el render lo cablea el consumidor (llimphi-lottie). Escalón sobre el playback.
+llimphi-anim = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Studio de animación «rive»: además del editor (bin), expone como lib los
+# documentos serializables (Doc + RigDoc + Project) que carga mirada-fondo.
+llimphi-anim-studio = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Render de mallas deformables (skel::Mesh) a vello Scene: vectorial y texturizada.
+llimphi-mesh = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Iconos vectoriales (BezPath en grid 24×24) compartidos por todas las apps.
-llimphi-icons = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-icons = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Puente fino vello_svg → Llimphi para SVG arbitrario (íconos .desktop, logos).
+llimphi-svg = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Puente fino velato (Lottie) → Llimphi para animación vectorial autorada (.json).
+llimphi-lottie = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-image = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Decodificador de protocolos de gráficos de terminal (kitty/sixel) → RGBA.
+llimphi-term-graphics = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Widgets reusables sobre llimphi-ui — uno por crate.
-llimphi-widget-app-header = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-banner = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-button = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-card = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-clipboard = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-context-menu = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-edit-menu = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-menubar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-list = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-grid = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-slider = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-scroll = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-splitter = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-stat-card = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tabs = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-command-palette = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-diff-viewer = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-fif = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-file-picker = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-bookmarks = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-mini-map = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-shuma-term = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-module-symbol-outline = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-plugin-host = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-theme-switcher = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-area = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor-core = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor-lsp = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-input = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tiled = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-nodegraph = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tree = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-navigator = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-widget-app-header = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-banner = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-button = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-rive-button = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-card = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-clipboard = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-context-menu = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-edit-menu = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-menubar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-list = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-grid = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-table = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-color-picker = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-slider = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-scroll = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-lazy-list = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-splitter = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-stat-card = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-tabs = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-allichay = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-command-palette = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-diff-viewer = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-fif = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-file-picker = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-bookmarks = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-mini-map = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-shuma-term = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-module-symbol-outline = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-plugin-host = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-theme-switcher = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-text-area = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-text-editor-core = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-text-editor = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-text-editor-lsp = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-text-input = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-tiled = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-nodegraph = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-tree = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+grafo-nav = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+llimphi-widget-navigator = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-detail-table = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-select = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-terminal = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Sello vectorial wawa (rombo + W implícita + Merkle Core).
-llimphi-widget-wawa-mark = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-widget-wawa-mark = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Widgets de elegancia transversal (tooltip, spinner, progress, toast,
 # modal, empty, status-bar, shortcuts-help, splash).
-llimphi-widget-tooltip = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-spinner = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-progress = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-toast = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-modal = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-empty = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-status-bar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-shortcuts-help = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-timeline = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-splash = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-widget-tooltip = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-spinner = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-progress = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-toast = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-modal = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-empty = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-status-bar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-shortcuts-help = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-timeline = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-transport = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-waveform = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-splash = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Controles de formulario y signaling (switch, segmented, breadcrumb,
 # badge, avatar, skeleton, field).
-llimphi-widget-switch = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-segmented = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-dock-rail = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-breadcrumb = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-badge = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-avatar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-skeleton = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-field = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-widget-switch = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-segmented = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-rag-sidebar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-dock-rail = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-toolbar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-breadcrumb = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-badge = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-avatar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-skeleton = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-field = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Firma visual transversal (gradient sutil + hairline accent).
-llimphi-widget-panel = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-panes = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-llimphi-workspace = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
+llimphi-widget-panel = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-panes = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+# Widgets Flutter-like — composición sobre primitivas Tier 1/3 ya
+# expuestas (sombra, gradient, animated, ripple).
+llimphi-widget-chip = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-fab = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-wrap = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-range-slider = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-calendar = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-fitted-box = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-carousel = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-rating = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-gauge = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-scaffold = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-hero = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-widget-router = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
+llimphi-workspace = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 # Abstracción Selector — host (paths) + wawa (khipus).
-llimphi-module-selector = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.1.0" }
-=======
-llimphi-ui = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Paleta semántica compartida por las apps y los widgets.
-llimphi-theme = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Tweens y helpers de animación sobre el bucle Elm.
-llimphi-motion = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Iconos vectoriales (BezPath en grid 24×24) compartidos por todas las apps.
-llimphi-icons = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Widgets reusables sobre llimphi-ui — uno por crate.
-llimphi-widget-app-header = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-banner = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-button = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-card = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-clipboard = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-context-menu = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-edit-menu = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-menubar = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-list = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-grid = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-slider = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-scroll = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-splitter = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-stat-card = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tabs = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-command-palette = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-diff-viewer = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-fif = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-file-picker = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-bookmarks = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-mini-map = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-shuma-term = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-module-symbol-outline = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-plugin-host = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-theme-switcher = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-area = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor-core = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-editor-lsp = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-text-input = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tiled = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-nodegraph = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-tree = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-navigator = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Sello vectorial wawa (rombo + W implícita + Merkle Core).
-llimphi-widget-wawa-mark = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Widgets de elegancia transversal (tooltip, spinner, progress, toast,
-# modal, empty, status-bar, shortcuts-help, splash).
-llimphi-widget-tooltip = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-spinner = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-progress = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-toast = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-modal = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-empty = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-status-bar = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-shortcuts-help = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-timeline = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-splash = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Controles de formulario y signaling (switch, segmented, breadcrumb,
-# badge, avatar, skeleton, field).
-llimphi-widget-switch = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-segmented = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-dock-rail = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-breadcrumb = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-badge = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-avatar = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-skeleton = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-field = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Firma visual transversal (gradient sutil + hairline accent).
-llimphi-widget-panel = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-widget-panes = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-llimphi-workspace = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
-# Abstracción Selector — host (paths) + wawa (khipus).
-llimphi-module-selector = { git = "https://gitea.tawasuyu.net/sergio/llimphi.git", tag = "v0.1.0" }
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
+llimphi-module-selector = { git = "https://git.tawasuyu.net/tawasuyu/llimphi.git", tag = "v0.2.0" }
 
 # === Filesystem helpers ===
 directories = "5"
@@ -346,7 +399,7 @@ hex = "0.4"
 portable-pty = "0.9"
 vt100 = "0.16"
 
-# === WASM web (gioser) ===
+# === WASM web (tawasuyu) ===
 wasm-bindgen = "0.2"
 wasm-bindgen-futures = "0.4"
 js-sys = "0.3"
@@ -371,117 +424,92 @@ ttf-parser = "0.25"
 # ============================================================
 # Intra-workspace deps de nahual (referenciadas por workspace = true)
 # ============================================================
-<<<<<<< HEAD
-nahual-text-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-image-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-thumb-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-gallery-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-video-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-card-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-audio-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-tree-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-hex-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-table-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-markdown-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-archive-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-font-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-map-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-geo-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-viewer-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-nahual-file-explorer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-=======
-nahual-text-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-image-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-thumb-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-gallery-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-video-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-card-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-audio-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-tree-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-hex-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-table-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-markdown-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-archive-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-font-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-map-viewer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-geo-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-viewer-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-nahual-file-explorer-llimphi = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
+nahual-text-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-image-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-pdf-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-cbz-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-thumb-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-gallery-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-video-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-card-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-audio-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+media-module = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-module = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-icon-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-icon-cli = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-icon-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-icon-llm = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+foreign-svg = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+foreign-pdf = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-render = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-render-gpu = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-ops = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+tullpu-paint = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-tree-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-hex-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-svg-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-sheet-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-dbf-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-table-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-markdown-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-pluma-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-cotejo-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-deck-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-archive-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-font-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-map-viewer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-geo-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-geo-voxel = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-iconos = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-viewer-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+nahual-file-explorer-llimphi = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 
 # ============================================================
 # Intra-workspace deps de pineal (módulo de gráficos)
 # ============================================================
-<<<<<<< HEAD
-pineal-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-render = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-cartesian = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-stream = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-mesh = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-financial = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-polar = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-heatmap = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-treemap = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-flow = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-phosphor = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-export = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-hexbin = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-contour = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal-bars = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-pineal = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-=======
-pineal-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-render = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-cartesian = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-stream = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-mesh = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-financial = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-polar = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-heatmap = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-treemap = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-flow = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-phosphor = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-export = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-hexbin = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-contour = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal-bars = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-pineal = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
+pineal-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-render = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-cartesian = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-stream = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-mesh = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-financial = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-polar = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-heatmap = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-treemap = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-flow = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-phosphor = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-export = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-hexbin = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-contour = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal-bars = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+pineal = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 
 # ============================================================
 # Intra-workspace deps de iniy (laboratorio semántico de creencias)
 # ============================================================
-<<<<<<< HEAD
-iniy-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-ingest = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-extract = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-nli = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-nli-llm = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-graph = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-iniy-store = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
+iniy-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-evidencia = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-derive = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-emisores = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-cache = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-daemon = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-ingest = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-extract = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-nli = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-nli-llm = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-graph = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+iniy-store = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+# la física de decaimiento de khipu la importa iniy-derive (SDD iniy §3)
+khipu-gravity = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 
 # === auto: declarados por crates internos faltantes ===
-cosmos-coords = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-cosmos-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-cosmos-ephemeris = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-cosmos-time = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-cosmos-wcs = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.1.0" }
-=======
-iniy-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-ingest = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-extract = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-nli = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-nli-llm = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-graph = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-iniy-store = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-
-# === auto: declarados por crates internos faltantes ===
-cosmos-coords = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-cosmos-core = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-cosmos-ephemeris = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-cosmos-time = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
-cosmos-wcs = { git = "https://gitea.tawasuyu.net/sergio/gioser.git", tag = "v0.1.0" }
->>>>>>> 19d635e (chore: migra host tawasuyu.net → tawasuyu.net (mismo repo, rebrand tawasuyu))
+cosmos-coords = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+cosmos-cities = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+cosmos-core = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+cosmos-ephemeris = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+cosmos-time = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+cosmos-wcs = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
 
 # === auto: externas de eternal ===
 celestial-eop-data = { version = "0.1"}
@@ -489,6 +517,7 @@ approx = "0.5"
 byteorder = "1.5"
 cc = "1.0"
 chrono = "0.4"
+chrono-tz = "0.10"
 crc32fast = "1.4"
 criterion = "0.5"
 csv = "1.4"
@@ -497,6 +526,11 @@ glob = "0.3"
 indicatif = "0.18"
 lz4_flex = "0.11"
 memmap2 = "0.9"
+# Cliente Wayland (lado cliente) — lo usa hapiy para hablar zwlr_screencopy
+# contra mirada (u otro compositor wlroots) y capturar la pantalla.
+wayland-client = "0.31"
+wayland-protocols-wlr = { version = "0.3", features = ["client"] }
+wayland-protocols-misc = { version = "0.3", features = ["client"] }
 mockito = "1.0"
 ndarray = "0.15"
 num-traits = "0.2"
@@ -530,6 +564,9 @@ markup5ever_rcdom = "0.39"
 cssparser = "0.35"
 url = "2"
 ureq = { version = "2", default-features = false, features = ["tls"] }
+# Charset de la web real: no todo es UTF-8 (google.com sirve ISO-8859-1).
+# Ya venía transitivo por el stack de Servo — aquí se hace explícito.
+encoding_rs = "0.8"
 
 # === takiy-synth (SoundFont MIDI) ===
 # rustysynth = sintetizador SF2 puro Rust, MIT. Reemplaza el oscilador
@@ -558,7 +595,7 @@ hound = "3.5"
 symphonia = { version = "0.5", default-features = false, features = ["mp3", "flac", "vorbis", "ogg"] }
 
 # === media-source-opus (decoder Opus NATIVO puro-Rust) ===
-# Opus es el formato de audio nativo de gioser (par del video AV1). ogg
+# Opus es el formato de audio nativo de tawasuyu (par del video AV1). ogg
 # demuxea las páginas Ogg; opus-wave es un port puro-Rust de libopus
 # (SILK+CELT, sin C ni FFI) — par del rav1d del lado video.
 ogg = "0.9"
@@ -569,3 +606,24 @@ opus-wave = "3"
 # paquetes de los tracks V_AV1 y A_OPUS para alimentar a media-source-av1
 # y media-source-opus — un .webm AV1+Opus se reproduce 100% nativo.
 matroska-demuxer = "0.7"
+
+# === Perfil `dist`: binarios de reparto livianos (equipos chicos / poca RAM) ===
+# Hereda de `release` pero prioriza HUELLA sobre tiempo de compilación: LTO thin
+# (poda código muerto entre crates), un solo codegen-unit (mejor inlining/DCE) y
+# `strip` de símbolos. Reduce el tamaño en disco Y el segmento de código mapeado
+# en RAM de cada binario (mirada, pata, apps Llimphi). No toca `cargo build
+# --release` de iteración diaria; se usa sólo al empaquetar:
+#   cargo build --profile dist -p mirada-compositor -p pata-host …
+# `panic = "unwind"` se mantiene a propósito: mirada-plugin-host aísla plugins
+# con `catch_unwind`, así que `abort` rompería el sandbox.
+# === Crates del monorepo consumidos por git-dep (pin del tag) ===
+format = { git = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git", tag = "v0.2.0" }
+
+[profile.dist]
+inherits = "release"
+lto = "thin"
+codegen-units = 1
+strip = "symbols"
+panic = "unwind"
+
+
diff --git a/shared/card/LEEME.md b/shared/card/LEEME.md
new file mode 100644
index 0000000..d06e224
--- /dev/null
+++ b/shared/card/LEEME.md
@@ -0,0 +1,36 @@
+# card — identidad agnóstica de transporte
+
+Contrato de identidad y membresía **independiente del transporte**: claves
+Ed25519, `EspinaId` (hash de la clave pública), firmas y handshake de membresía
+de una "espina" (red privada). El mismo contrato lo implementan dos transportes
+distintos: `card-net` (libp2p) y `wawa-akasha` (protocolo propio de wawa).
+
+## Subcrates
+
+- **`card-core`** — el contrato agnóstico real: par Ed25519 → `EspinaId`,
+  `Card` firmada, `handshake` de membresía (un miembro presenta su tarjeta
+  firmada; el anfitrión la verifica contra la raíz de confianza de la espina).
+  Sólo bytes firmados — no sabe de libp2p ni Akasha.
+- **`card-net`** — espina dorsal P2P sobre **libp2p**: discovery (mDNS +
+  Kademlia DHT), gossipsub, NAT traversal (Circuit Relay v2 + DCUtR + AutoNAT).
+  Implementa el contrato de `card-core` sobre libp2p. Lo consume `khipu`.
+- **`card-wit`** — **[DORMIDO]** binding WIT/wasm del contrato. Se reactiva
+  cuando `card` cruce a apps WASM; hoy el contrato real es `card-core`.
+
+## Estado (2026-05-31)
+
+### Hecho
+- `card-core`: identidad Ed25519 + `EspinaId` + handshake de membresía (contrato
+  agnóstico declarado como la fuente de verdad).
+- `card-net`: discovery (mDNS+DHT), gossipsub y NAT traversal completo
+  (Relay v2 + DCUtR + AutoNAT); discovery de personas por `DhtKey::Persona`.
+
+### Pendiente
+- `card-wit`: dormido — binding WASM pendiente de reactivación.
+- Espejo del contrato sobre `wawa-akasha` (transporte wawa) aún por cablear.
+- Endurecer revocación / rotación de membresía de espina.
+
+## Lugar en el repo
+
+`shared/card` — contrato de identidad. `card-net` lo lleva a libp2p (khipu);
+`agora` cubre firma/confianza de más alto nivel.
diff --git a/shared/card/README.md b/shared/card/README.md
index d06e224..edecd40 100644
--- a/shared/card/README.md
+++ b/shared/card/README.md
@@ -1,36 +1,36 @@
-# card — identidad agnóstica de transporte
+# card — transport-agnostic identity
 
-Contrato de identidad y membresía **independiente del transporte**: claves
-Ed25519, `EspinaId` (hash de la clave pública), firmas y handshake de membresía
-de una "espina" (red privada). El mismo contrato lo implementan dos transportes
-distintos: `card-net` (libp2p) y `wawa-akasha` (protocolo propio de wawa).
+Identity and membership contract **independent of the transport**: Ed25519
+keys, `EspinaId` (hash of the public key), signatures and the membership handshake
+of an "espina" (private network). The same contract is implemented by two different
+transports: `card-net` (libp2p) and `wawa-akasha` (wawa's own protocol).
 
 ## Subcrates
 
-- **`card-core`** — el contrato agnóstico real: par Ed25519 → `EspinaId`,
-  `Card` firmada, `handshake` de membresía (un miembro presenta su tarjeta
-  firmada; el anfitrión la verifica contra la raíz de confianza de la espina).
-  Sólo bytes firmados — no sabe de libp2p ni Akasha.
-- **`card-net`** — espina dorsal P2P sobre **libp2p**: discovery (mDNS +
+- **`card-core`** — the actual agnostic contract: Ed25519 pair → `EspinaId`,
+  signed `Card`, membership `handshake` (a member presents its signed
+  card; the host verifies it against the espina's root of trust).
+  Only signed bytes — it knows nothing of libp2p or Akasha.
+- **`card-net`** — P2P backbone over **libp2p**: discovery (mDNS +
   Kademlia DHT), gossipsub, NAT traversal (Circuit Relay v2 + DCUtR + AutoNAT).
-  Implementa el contrato de `card-core` sobre libp2p. Lo consume `khipu`.
-- **`card-wit`** — **[DORMIDO]** binding WIT/wasm del contrato. Se reactiva
-  cuando `card` cruce a apps WASM; hoy el contrato real es `card-core`.
+  Implements the `card-core` contract over libp2p. Consumed by `khipu`.
+- **`card-wit`** — **[DORMANT]** WIT/wasm binding of the contract. It reactivates
+  when `card` crosses to WASM apps; today the actual contract is `card-core`.
 
-## Estado (2026-05-31)
+## Status (2026-05-31)
 
-### Hecho
-- `card-core`: identidad Ed25519 + `EspinaId` + handshake de membresía (contrato
-  agnóstico declarado como la fuente de verdad).
-- `card-net`: discovery (mDNS+DHT), gossipsub y NAT traversal completo
-  (Relay v2 + DCUtR + AutoNAT); discovery de personas por `DhtKey::Persona`.
+### Done
+- `card-core`: Ed25519 identity + `EspinaId` + membership handshake (agnostic
+  contract declared as the source of truth).
+- `card-net`: discovery (mDNS+DHT), gossipsub and complete NAT traversal
+  (Relay v2 + DCUtR + AutoNAT); person discovery by `DhtKey::Persona`.
 
-### Pendiente
-- `card-wit`: dormido — binding WASM pendiente de reactivación.
-- Espejo del contrato sobre `wawa-akasha` (transporte wawa) aún por cablear.
-- Endurecer revocación / rotación de membresía de espina.
+### Pending
+- `card-wit`: dormant — WASM binding pending reactivation.
+- Mirror of the contract over `wawa-akasha` (wawa transport) still to be wired.
+- Harden espina membership revocation / rotation.
 
-## Lugar en el repo
+## Place in the repo
 
-`shared/card` — contrato de identidad. `card-net` lo lleva a libp2p (khipu);
-`agora` cubre firma/confianza de más alto nivel.
+`shared/card` — identity contract. `card-net` carries it to libp2p (khipu);
+`agora` covers higher-level signing/trust.
diff --git a/shared/card/card-core/Cargo.toml b/shared/card/card-core/Cargo.toml
index b012cde..14e8247 100644
--- a/shared/card/card-core/Cargo.toml
+++ b/shared/card/card-core/Cargo.toml
@@ -14,6 +14,9 @@ serde_json = { workspace = true }
 toml = { workspace = true }
 thiserror = { workspace = true }
 ulid = { workspace = true }
+# Atestación al arranque: la Seed Card lleva ConcesionCapacidad firmadas
+# (mismo tipo que agora/wawa verifican) sobre los binarios críticos.
+format = { workspace = true }
 
 [dev-dependencies]
 postcard = { workspace = true }
diff --git a/shared/card/card-core/LEEME.md b/shared/card/card-core/LEEME.md
new file mode 100644
index 0000000..5cbbea5
--- /dev/null
+++ b/shared/card/card-core/LEEME.md
@@ -0,0 +1,24 @@
+# card-core
+
+*Read this in English: [README.md](README.md).*
+
+`brahman-card` — Tarjeta de Presentación canónica de Brahman.
+
+Híbrida del `EntityCard` de arje (identidad ULID, capacidades tipadas,
+`Payload`/`SomaSpec`/`Supervision`/`genesis` recursivo) con flujos tipados,
+permisos enumerados explícitos y nivel de confianza derivado del modelo
+que veníamos diseñando en `core_protocol`. Una sola tarjeta sirve a:
+
+- **El Init** (encarnación): `payload` + `soma` + `supervision` + `genesis`.
+- **El Admin** (matching): `provides`/`requires` + `flow` + `permissions`.
+- **El runtime** (sandbox): `permissions` enumerados → seccomp / namespaces.
+
+Forward-compat: cualquier campo desconocido se preserva en `extensions`
+(raíz) o en `extra` (sub-secciones).
+
+Formatos soportados: JSON (canónico, compatible con arje) y TOML
+(humano-legible). Auto-detección por extensión.
+
+---
+
+Parte de **card** — ver [card](../LEEME.md).
diff --git a/shared/card/card-core/README.md b/shared/card/card-core/README.md
new file mode 100644
index 0000000..a66a3a5
--- /dev/null
+++ b/shared/card/card-core/README.md
@@ -0,0 +1,13 @@
+# card-core
+
+`brahman-card` — Brahman's canonical Presentation Card.
+
+A hybrid of arje's `EntityCard` (ULID identity, typed capabilities, recursive
+`Payload`/`SomaSpec`/`Supervision`/`genesis`) with typed flows, explicitly
+enumerated permissions and a trust level derived from the model designed in
+`core_protocol`. A single card serves the Init (incarnation): `payload` + `soma` +
+`supervision` + `genesis`.
+
+---
+
+Part of **card** — see [card](../README.md).
diff --git a/shared/card/card-core/src/lib.rs b/shared/card/card-core/src/lib.rs
index 1861d8d..33b097b 100644
--- a/shared/card/card-core/src/lib.rs
+++ b/shared/card/card-core/src/lib.rs
@@ -48,6 +48,10 @@ pub enum CardError {
     LabelTooLong(usize),
     #[error("capacidad presente en provides Y requires: {0:?}")]
     SelfDependency(Capability),
+    #[error("contrato Quorum inválido: at_least={at_least} fuera de [1, {of}]")]
+    InvalidQuorum { at_least: u32, of: usize },
+    #[error("contrato Conflicts contradice provides: {0:?}")]
+    ConflictsSelf(Capability),
     #[error("payload Native/Legacy con exec vacío")]
     EmptyExec,
     #[error("payload Wasm con sha256 sentinela (todo ceros)")]
@@ -96,9 +100,19 @@ pub struct Card {
     pub provides: BTreeSet<Capability>,
 
     /// Capacidades que necesita resolver el Init antes de encarnarla.
+    /// Semántica AND: TODAS deben estar disponibles. Para contratos más
+    /// expresivos (A **o** B, quórum N-de-M, exclusión, orden) usa `contracts`.
     #[serde(default)]
     pub requires: BTreeSet<Capability>,
 
+    /// Contratos de dependencia relacionales — más expresivos que `requires`
+    /// (que es un AND plano). `Any` ("al menos una"), `Quorum` (N-de-M),
+    /// `Conflicts` (exclusión mutua), `After` (sólo orden). El Init los evalúa
+    /// contra las capacidades disponibles y los usa para ordenar el arranque
+    /// (grafo topológico). `#[serde(default)]` ⇒ compat con Cards previas.
+    #[serde(default, skip_serializing_if = "Vec::is_empty")]
+    pub contracts: Vec<DepContract>,
+
     /// Permisos sandbox declarativos (más alto nivel que `Capability`).
     /// El Admin los compila a seccomp/namespaces/cgroups concretos.
     #[serde(default)]
@@ -162,6 +176,24 @@ pub struct Card {
     #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
     pub priority_contexts: BTreeMap<String, ContextBias>,
 
+    /// Manifiesto de atestación al arranque (A1): una `ConcesionCapacidad`
+    /// firmada por binario crítico, sobre `(blake3(binario), permisos)` bajo
+    /// la rootkey del seed. `arje-zero` las verifica antes de incarnar el
+    /// target gráfico. Vacío = sin atestación (compat con Cards previas).
+    #[serde(default, skip_serializing_if = "Vec::is_empty")]
+    pub attest: Vec<format::ConcesionCapacidad>,
+
+    /// Llave pública (Ed25519) de la rootkey que firmó `attest`. El gate
+    /// exige que cada concesión la declare como `autor`; `None` = no se pinó
+    /// (el gate sólo valida firma + hash, no la procedencia de la rootkey).
+    #[serde(default, skip_serializing_if = "Option::is_none")]
+    pub attest_rootkey: Option<format::AgoraId>,
+
+    /// Qué hacer cuando un binario crítico no atesta. Default `Warn` (sólo
+    /// registra): la atestación arranca observando y el operador la endurece.
+    #[serde(default)]
+    pub attest_policy: AttestPolicy,
+
     /// Campos JSON/TOML desconocidos preservados durante I/O de archivos
     /// (forward-compat). **No se transmiten por wire (postcard)** — la
     /// proyección a [`WireCard`] los descarta porque `serde_json::Value`
@@ -171,15 +203,32 @@ pub struct Card {
     pub extensions: BTreeMap<String, JsonValue>,
 }
 
+/// Política de atestación al arranque: qué hace `arje-zero` cuando un binario
+/// crítico no casa con su `ConcesionCapacidad` (firma inválida, autor no
+/// confiable, o hash distinto del atestado).
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
+#[serde(rename_all = "snake_case")]
+pub enum AttestPolicy {
+    /// Sólo registra el veredicto en el audit log; el boot continúa normal.
+    /// Default seguro: estrenar la atestación no debe poder dejar sin arranque.
+    #[default]
+    Warn,
+    /// Levanta el target igual, pero marca comprometida la unidad fallida
+    /// (queda visible en el brain / la shell).
+    Degraded,
+    /// Aborta la incarnación del target si un binario crítico no atesta.
+    Halt,
+}
+
 impl Default for Card {
     /// Default determinista pensado para el patrón `..Default::default()`
     /// en struct-literals donde el caller sobreescribe `id` y `label`.
     ///
-    /// **Trap conocida**: `id` queda en `Ulid::nil()`. Si construís una
+    /// **Trap conocida**: `id` queda en `Ulid::nil()`. Si construyes una
     /// Card "viva" para registrar en el broker, NUNCA dejes el `id`
     /// derivado de `Default` — todas las Cards default-construidas
     /// colisionarían bajo el mismo `00000000000000000000000000`. Para
-    /// Cards frescas usá [`Card::new`], que asigna `Ulid::new()`.
+    /// Cards frescas usa [`Card::new`], que asigna `Ulid::new()`.
     /// `Ulid::nil()` queda reservado para patterns de búsqueda y
     /// sentinel values en serialización.
     fn default() -> Self {
@@ -190,6 +239,7 @@ impl Default for Card {
             label: String::new(),
             provides: BTreeSet::new(),
             requires: BTreeSet::new(),
+            contracts: Vec::new(),
             permissions: Permissions::default(),
             soma: SomaSpec::default(),
             payload: Payload::Virtual,
@@ -203,6 +253,9 @@ impl Default for Card {
             kind: CardKind::default(),
             data: None,
             priority_contexts: BTreeMap::new(),
+            attest: Vec::new(),
+            attest_rootkey: None,
+            attest_policy: AttestPolicy::default(),
             extensions: BTreeMap::new(),
         }
     }
@@ -242,6 +295,56 @@ pub enum NetlinkFamily {
     Audit,
 }
 
+// =====================================================================
+// Contratos de dependencia relacionales
+// =====================================================================
+
+/// Contrato de dependencia entre Cards, más expresivo que el `requires` plano
+/// (que es un AND de capacidades). Se evalúa contra el conjunto de capacidades
+/// **disponibles** (las que proveen los Entes ya vivos + la Semilla).
+///
+/// Wire: externally-tagged (compatible con JSON/TOML/postcard). Ejemplo JSON:
+/// ```json
+/// { "Any": ["Journal", "LegacyLogind"] }
+/// { "Quorum": { "of": ["Spawn", "Journal"], "at_least": 1 } }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub enum DepContract {
+    /// Al menos UNA de estas capacidades debe estar disponible ("A o B"). Un
+    /// set vacío es trivialmente insatisfecho (se rechaza la Card).
+    Any(BTreeSet<Capability>),
+    /// Al menos `at_least` de las capacidades en `of` deben estar disponibles
+    /// (quórum N-de-M).
+    Quorum {
+        of: BTreeSet<Capability>,
+        at_least: u32,
+    },
+    /// NINGUNA de estas capacidades puede estar disponible (exclusión mutua).
+    Conflicts(BTreeSet<Capability>),
+    /// Sólo ORDEN: si hay proveedor, arrancar DESPUÉS; no es requisito (si nadie
+    /// la provee, no bloquea). Equivale al `After=` de systemd.
+    After(BTreeSet<Capability>),
+}
+
+/// Por qué un conjunto de capacidades NO satisface los contratos de una Card.
+/// Tipo de error de runtime (no viaja por wire): lo produce
+/// [`Card::deps_satisfied`].
+#[derive(Debug, Clone, PartialEq, Eq, Error)]
+pub enum UnmetContract {
+    /// Falta una capacidad del AND `requires`.
+    #[error("falta capacidad requerida: {0:?}")]
+    Missing(Capability),
+    /// Ninguna de las alternativas (`Any`) está disponible.
+    #[error("ninguna alternativa disponible: {0:?}")]
+    NoneOf(BTreeSet<Capability>),
+    /// Quórum no alcanzado.
+    #[error("quórum no alcanzado: hay {have}, se necesitan {need}")]
+    Quorum { need: u32, have: u32 },
+    /// Una capacidad excluida por `Conflicts` está presente.
+    #[error("conflicto: capacidad excluida presente: {0:?}")]
+    Conflict(Capability),
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
 pub enum DeviceClass {
     Block,
@@ -257,6 +360,23 @@ pub enum DeviceClass {
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
 pub struct InterfaceId(pub [u8; 16]);
 
+/// InterfaceId canónico del **"piso" gráfico**: el display Wayland que provee el
+/// compositor (mirada) y del que dependen los clientes de la sesión. Modelar el
+/// piso como `Capability::Endpoint { interface: WAYLAND_FLOOR_INTERFACE, version }`
+/// hace el contrato uniforme: el compositor lo `provides`, los clientes lo
+/// `requires`, y el re-floor del Init los re-erige cuando el piso vuelve. Bytes =
+/// ASCII de `"mirada-wl-floor0"` (= `[109,105,114,97,100,97,45,119,108,45,102,108,111,111,114,48]`).
+pub const WAYLAND_FLOOR_INTERFACE: InterfaceId = InterfaceId(*b"mirada-wl-floor0");
+
+/// Capacidad-piso canónica: el display Wayland del compositor (versión 1).
+/// Helper para no repetir el `Endpoint { … }` en código.
+pub fn wayland_floor() -> Capability {
+    Capability::Endpoint {
+        interface: WAYLAND_FLOOR_INTERFACE,
+        version: 1,
+    }
+}
+
 // =====================================================================
 // Permisos sandbox — más alto nivel que Capability
 // =====================================================================
@@ -311,6 +431,35 @@ pub struct SomaSpec {
     pub rlimits: ResourceLimits,
     pub cgroup: CgroupSpec,
     pub cpu_affinity: Option<Vec<u32>>,
+    /// Si `Some`, el Ente BAJA privilegios a este usuario antes de `execve`
+    /// (setgroups + setgid + setuid). `None` = corre con la identidad del Init
+    /// (root). Lo usa el session-manager para correr las apps del usuario logueado
+    /// como ese usuario, no como root. `#[serde(default)]` ⇒ compat con Cards
+    /// previas (deserializan a `None`). SIN `skip_serializing_if`: SomaSpec viaja
+    /// en `WireCard` y postcard exige layout fijo (igual que `cpu_affinity`).
+    #[serde(default)]
+    pub run_as: Option<RunAs>,
+    /// Plan de montajes del Ente: qué `$HOME` ve y qué archivos extra
+    /// (secretos, binds) se le inyectan DENTRO de su mount namespace. Vacío
+    /// (default) = hereda el FS del Init sin tocar. El Admin lo compila a ops
+    /// `tmpfs`/`bind` dentro del `CLONE_NEWNS` del Ente — por eso requiere
+    /// `namespaces.mount`. La frontera es física (el namespace), no una tabla
+    /// de permisos: coherente con la doctrina de wawa. `#[serde(default)]` ⇒
+    /// compat con Cards previas; SIN `skip_serializing_if` por el layout fijo
+    /// de postcard en `WireCard` (igual que `run_as`/`cpu_affinity`).
+    #[serde(default)]
+    pub mounts: MountPlan,
+}
+
+/// Identidad de usuario a la que un Ente baja privilegios antes de `execve`.
+/// `groups` (suplementarios) los calcula el CALLER —`getgrouplist` consulta NSS
+/// y no es async-signal-safe entre fork y exec—; vacío = sólo el `gid` primario.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RunAs {
+    pub uid: u32,
+    pub gid: u32,
+    #[serde(default)]
+    pub groups: Vec<u32>,
 }
 
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
@@ -324,11 +473,49 @@ pub struct NamespaceSet {
     pub cgroup: bool,
 }
 
+/// Límites de recursos del Ente, aplicados por el incarnator con `setrlimit`
+/// en el hijo post-clone (ver `arje-incarnate::child::apply_rlimits`).
+///
+/// Los tres primeros son **techos**: acotan lo que el Ente puede consumir.
+/// Los dos últimos son **elevaciones**: sólo sirven porque el Init es root y
+/// puede subir el límite DURO, cosa que un proceso sin privilegios no puede.
+/// Existen porque bajo arje **no hay PAM en el camino nativo**: `pam_limits`
+/// —que es la única fase donde se fijan los rlimits en un login clásico— sólo
+/// corre en el handoff a sesiones ajenas (`/etc/pam.d/mirada-session`). La
+/// sesión nativa la lanza el Init directo, así que TODO su árbol heredaba
+/// `rtprio 0` de PID 1 y ni PipeWire podía pedir SCHED_FIFO. Declararlo en la
+/// Card lo vuelve explícito y auditable, en vez de depender de qué stack de
+/// PAM haya corrido antes.
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
 pub struct ResourceLimits {
     pub mem_bytes: Option<u64>,
     pub nproc: Option<u32>,
     pub nofile: Option<u32>,
+    /// Prioridad de tiempo real máxima que el Ente (y sus hijos) pueden pedir
+    /// con `SCHED_FIFO`/`SCHED_RR`. `None` = hereda la del Init (`0` = no puede).
+    /// Paridad con `@audio rtprio 95` de `limits.d`. `#[serde(default)]` ⇒
+    /// compat con Cards previas; SIN `skip_serializing_if` por el layout fijo
+    /// de postcard en `WireCard` (igual que `run_as`/`mounts`).
+    #[serde(default)]
+    pub rtprio: Option<u32>,
+    /// Memoria que el Ente puede fijar en RAM (`mlock`), en bytes.
+    /// `Some(u64::MAX)` = ilimitado (`RLIM_INFINITY`). Sin esto los buffers de
+    /// audio pueden irse a swap → xruns. `None` = hereda la del Init.
+    #[serde(default)]
+    pub memlock_bytes: Option<u64>,
+    /// `RLIMIT_NICE`, en la codificación del kernel: el nice mínimo que el Ente
+    /// puede pedir es `20 - valor`. O sea `35` ⇒ hasta `nice -15` (paridad con
+    /// `@audio nice -15` de `limits.d`). `None` = hereda el del Init (`0`, que
+    /// significa «no puede bajar de nice 0»).
+    ///
+    /// No es un detalle cosmético: **PipeWire abandona el camino de rlimits
+    /// entero si `set_nice()` falla** y se cae a RTKit, que recorta la
+    /// prioridad a 20 y puede degradar los hilos después. Medido en metal
+    /// 2026-07-21: con `nice.level = -11` y `RLIMIT_NICE = 0`, `module-rt`
+    /// reporta «insufficient realtime privileges» AUNQUE `rtprio` sea 95;
+    /// con `nice.level = 0` toma el camino directo y consigue FIFO 88.
+    #[serde(default)]
+    pub nice_rlimit: Option<u32>,
 }
 
 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
@@ -339,6 +526,85 @@ pub struct CgroupSpec {
     pub io_weight: Option<u32>,
 }
 
+// =====================================================================
+// MountPlan — aislamiento de FS por Ente (Fase 1 de pacha-dotfiles)
+// =====================================================================
+
+/// Declaración de qué filesystem ve un Ente dentro de su mount namespace.
+/// Puramente declarativo: el incarnator (arje-incarnate) lo traduce a
+/// syscalls `mount` reales, en orden, ejecutadas en el hijo tras
+/// `make_root_private` y antes de bajar privilegios. Default = `is_empty()`
+/// = no se toca nada.
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct MountPlan {
+    /// Qué `$HOME` ve el Ente.
+    #[serde(default)]
+    pub home: HomeSpec,
+    /// Bind-mounts extra (inyectar archivos/dirs ya existentes: secretos en
+    /// claro hoy, descifrados a tmpfs en Fase 2). Se aplican DESPUÉS del home,
+    /// para poder apuntar dentro de un home tmpfs recién montado.
+    #[serde(default)]
+    pub binds: Vec<BindSpec>,
+    /// Tmpfs vacíos extra a montar (scratch, runtime dirs en RAM).
+    #[serde(default)]
+    pub tmpfs: Vec<TmpfsSpec>,
+    /// Monta un tmpfs vacío sobre el `$HOME` real para ocultarlo aunque no se
+    /// reemplace por uno propio (≈ `ProtectHome=tmpfs` de systemd). Lo aplica
+    /// el incarnator sólo si `home` es `Heredar` (si no, el home ya se reemplaza).
+    #[serde(default)]
+    pub hide_home_real: Option<String>,
+}
+
+impl MountPlan {
+    /// `true` si no pide ningún cambio de FS (el incarnator puede saltearse el
+    /// armado de ops). Un `MountPlan` vacío deja el FS del Init intacto.
+    pub fn is_empty(&self) -> bool {
+        matches!(self.home, HomeSpec::Heredar)
+            && self.binds.is_empty()
+            && self.tmpfs.is_empty()
+            && self.hide_home_real.is_none()
+    }
+}
+
+/// Qué `$HOME` ve el Ente.
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum HomeSpec {
+    /// Hereda el `$HOME` del Init sin aislar. Default.
+    #[default]
+    Heredar,
+    /// `$HOME` es un tmpfs vacío en RAM, propio del Ente; se evapora con el
+    /// namespace. `destino` es la ruta absoluta a montar (ej. `/home/sergio`).
+    Tmpfs {
+        destino: String,
+        /// Tope de tamaño en bytes; `None` = default del kernel. SIN
+        /// `skip_serializing_if`: viaja en `WireCard` (postcard, layout fijo).
+        #[serde(default)]
+        size_bytes: Option<u64>,
+    },
+    /// Bind-montar `origen` (un subdir, p.ej. del pacha) como `destino`
+    /// (`$HOME`). El contenido vive en `origen`; los cambios persisten ahí.
+    Subdir { origen: String, destino: String },
+}
+
+/// Un bind-mount: hacer visible `origen` en `destino` dentro del namespace.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct BindSpec {
+    pub origen: String,
+    pub destino: String,
+    /// Si `true`, remonta el bind como sólo-lectura (`MS_RDONLY`).
+    #[serde(default)]
+    pub ro: bool,
+}
+
+/// Un tmpfs vacío a montar en `destino`.
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct TmpfsSpec {
+    pub destino: String,
+    /// SIN `skip_serializing_if`: viaja en `WireCard` (postcard, layout fijo).
+    #[serde(default)]
+    pub size_bytes: Option<u64>,
+}
+
 // =====================================================================
 // Payload — qué encarnar (heredado de arje)
 // =====================================================================
@@ -615,7 +881,7 @@ impl Card {
     /// ```
     ///
     /// Para Cards de búsqueda/sentinel donde `nil` es semánticamente
-    /// significativo, usá `Card::default()` directamente.
+    /// significativo, usa `Card::default()` directamente.
     pub fn new(label: impl Into<String>) -> Self {
         Self {
             id: Ulid::new(),
@@ -655,6 +921,74 @@ impl Card {
         Ok(serde_json::to_string_pretty(self)?)
     }
 
+    /// ¿Satisface esta Card sus contratos de dependencia contra el conjunto de
+    /// capacidades `available`? Combina `requires` (AND) con cada `contract`.
+    /// `After` es sólo orden ⇒ NO afecta la satisfacción (siempre pasa).
+    ///
+    /// Fuente única de verdad para el gate de spawn del Init (tanto en el
+    /// arranque del genesis como en spawns dinámicos por el bus).
+    pub fn deps_satisfied(&self, available: &BTreeSet<Capability>) -> Result<(), UnmetContract> {
+        for cap in &self.requires {
+            if !available.contains(cap) {
+                return Err(UnmetContract::Missing(cap.clone()));
+            }
+        }
+        for c in &self.contracts {
+            match c {
+                DepContract::Any(set) => {
+                    if !set.iter().any(|cap| available.contains(cap)) {
+                        return Err(UnmetContract::NoneOf(set.clone()));
+                    }
+                }
+                DepContract::Quorum { of, at_least } => {
+                    let have = of.iter().filter(|cap| available.contains(cap)).count() as u32;
+                    if have < *at_least {
+                        return Err(UnmetContract::Quorum {
+                            need: *at_least,
+                            have,
+                        });
+                    }
+                }
+                DepContract::Conflicts(set) => {
+                    if let Some(cap) = set.iter().find(|cap| available.contains(cap)) {
+                        return Err(UnmetContract::Conflict(cap.clone()));
+                    }
+                }
+                DepContract::After(_) => {}
+            }
+        }
+        Ok(())
+    }
+
+    /// Capacidades de las que esta Card depende para el ORDEN de arranque
+    /// (`requires` + `Any` + `Quorum.of` + `After`). El planificador topológico
+    /// del Init las usa para colocar a la Card DESPUÉS de sus proveedores.
+    /// `Conflicts` NO ordena (es exclusión, no dependencia).
+    pub fn ordering_deps(&self) -> BTreeSet<Capability> {
+        let mut s = self.requires.clone();
+        for c in &self.contracts {
+            match c {
+                DepContract::Any(set)
+                | DepContract::Quorum { of: set, .. }
+                | DepContract::After(set) => s.extend(set.iter().cloned()),
+                DepContract::Conflicts(_) => {}
+            }
+        }
+        s
+    }
+
+    /// Capacidades que esta Card declara como conflictivas (unión de todos los
+    /// `Conflicts`). Si alguna está disponible, la Card no puede coexistir.
+    pub fn conflict_caps(&self) -> BTreeSet<Capability> {
+        let mut s = BTreeSet::new();
+        for c in &self.contracts {
+            if let DepContract::Conflicts(set) = c {
+                s.extend(set.iter().cloned());
+            }
+        }
+        s
+    }
+
     /// Validación semántica exhaustiva, recursiva sobre `genesis`.
     pub fn validate(&self) -> Result<(), CardError> {
         if self.schema_version != CARD_SCHEMA_VERSION {
@@ -674,6 +1008,27 @@ impl Card {
                 return Err(CardError::SelfDependency(cap.clone()));
             }
         }
+        for c in &self.contracts {
+            match c {
+                DepContract::Quorum { of, at_least } => {
+                    if *at_least == 0 || *at_least as usize > of.len() {
+                        return Err(CardError::InvalidQuorum {
+                            at_least: *at_least,
+                            of: of.len(),
+                        });
+                    }
+                }
+                DepContract::Conflicts(set) => {
+                    // Una Card no puede excluir una capacidad que ella misma provee.
+                    for cap in set {
+                        if self.provides.contains(cap) {
+                            return Err(CardError::ConflictsSelf(cap.clone()));
+                        }
+                    }
+                }
+                DepContract::Any(_) | DepContract::After(_) => {}
+            }
+        }
         validate_payload(&self.payload)?;
         validate_rlimits(&self.soma.rlimits)?;
         validate_cgroup(&self.soma.cgroup)?;
@@ -872,6 +1227,9 @@ pub struct WireCard {
     pub provides: BTreeSet<Capability>,
     #[serde(default)]
     pub requires: BTreeSet<Capability>,
+    /// Sin `skip_serializing_if`: postcard exige layout fijo (ver ContextBias).
+    #[serde(default)]
+    pub contracts: Vec<DepContract>,
     #[serde(default)]
     pub permissions: Permissions,
     #[serde(default)]
@@ -896,6 +1254,12 @@ pub struct WireCard {
     pub data: Option<DataFacet>,
     #[serde(default)]
     pub priority_contexts: BTreeMap<String, ContextBias>,
+    #[serde(default)]
+    pub attest: Vec<format::ConcesionCapacidad>,
+    #[serde(default)]
+    pub attest_rootkey: Option<format::AgoraId>,
+    #[serde(default)]
+    pub attest_policy: AttestPolicy,
 }
 
 impl From<Card> for WireCard {
@@ -907,6 +1271,7 @@ impl From<Card> for WireCard {
             label: c.label,
             provides: c.provides,
             requires: c.requires,
+            contracts: c.contracts,
             permissions: c.permissions,
             soma: c.soma,
             payload: c.payload,
@@ -920,6 +1285,9 @@ impl From<Card> for WireCard {
             kind: c.kind,
             data: c.data,
             priority_contexts: c.priority_contexts,
+            attest: c.attest,
+            attest_rootkey: c.attest_rootkey,
+            attest_policy: c.attest_policy,
         }
     }
 }
@@ -933,6 +1301,7 @@ impl From<WireCard> for Card {
             label: w.label,
             provides: w.provides,
             requires: w.requires,
+            contracts: w.contracts,
             permissions: w.permissions,
             soma: w.soma,
             payload: w.payload,
@@ -946,6 +1315,9 @@ impl From<WireCard> for Card {
             kind: w.kind,
             data: w.data,
             priority_contexts: w.priority_contexts,
+            attest: w.attest,
+            attest_rootkey: w.attest_rootkey,
+            attest_policy: w.attest_policy,
             extensions: BTreeMap::new(),
         }
     }
@@ -1185,6 +1557,53 @@ mod tests {
         assert!(c_back.extensions.is_empty(), "extensions sobreviven al wire");
     }
 
+    #[test]
+    fn attest_fields_roundtrip_json_y_wire() {
+        let concesion = format::ConcesionCapacidad {
+            bytecode: [1u8; 32],
+            permisos: 0b101,
+            autor: [2u8; 32],
+            firma: [3u8; 64],
+        };
+        let mut c = Card::new("seed-atestado");
+        c.attest = vec![concesion.clone()];
+        c.attest_rootkey = Some([2u8; 32]);
+        c.attest_policy = AttestPolicy::Halt;
+
+        // JSON: los tres campos sobreviven.
+        let json = serde_json::to_string(&c).unwrap();
+        let back: Card = serde_json::from_str(&json).unwrap();
+        assert_eq!(back.attest, vec![concesion.clone()]);
+        assert_eq!(back.attest_rootkey, Some([2u8; 32]));
+        assert_eq!(back.attest_policy, AttestPolicy::Halt);
+
+        // Wire (postcard vía WireCard): también cruzan.
+        let wire: WireCard = c.into();
+        let bytes = postcard::to_allocvec(&wire).unwrap();
+        let wire_back: WireCard = postcard::from_bytes(&bytes).unwrap();
+        let c_back: Card = wire_back.into();
+        assert_eq!(c_back.attest, vec![concesion]);
+        assert_eq!(c_back.attest_rootkey, Some([2u8; 32]));
+        assert_eq!(c_back.attest_policy, AttestPolicy::Halt);
+    }
+
+    #[test]
+    fn attest_default_vacio_y_compat() {
+        // Una Card sin campos attest (JSON viejo) deserializa con defaults
+        // seguros: sin manifiesto y política Warn.
+        let src = r#"{
+            "schema_version": 1,
+            "id": "01HQAR53D4M2NBV8KZTYXFGS01",
+            "label": "vieja",
+            "payload": "Virtual",
+            "supervision": "OneShot"
+        }"#;
+        let c = Card::from_json(src).unwrap();
+        assert!(c.attest.is_empty());
+        assert_eq!(c.attest_rootkey, None);
+        assert_eq!(c.attest_policy, AttestPolicy::Warn);
+    }
+
     #[test]
     fn wirecard_postcard_with_priority_contexts() {
         // Repro del bug que rompía chasqui-nous-mock: ContextBias con
@@ -1287,4 +1706,202 @@ mod tests {
         assert_eq!(d.id, Ulid::nil());
         assert!(d.label.is_empty());
     }
-}
+
+    // ----------------------------------------------------------------
+    // Contratos de dependencia (Any / Quorum / Conflicts / After)
+    // ----------------------------------------------------------------
+
+    fn caps(it: impl IntoIterator<Item = Capability>) -> BTreeSet<Capability> {
+        it.into_iter().collect()
+    }
+
+    #[test]
+    fn any_contract_a_o_b() {
+        let mut c = Card::new("greeter");
+        c.contracts = vec![DepContract::Any(caps([Capability::Spawn, Capability::Journal]))];
+        // Ninguna de las dos: no satisface.
+        assert_eq!(
+            c.deps_satisfied(&caps([])),
+            Err(UnmetContract::NoneOf(caps([Capability::Spawn, Capability::Journal])))
+        );
+        // Una sola alcanza ("A o B, al menos uno").
+        assert!(c.deps_satisfied(&caps([Capability::Journal])).is_ok());
+        assert!(c.deps_satisfied(&caps([Capability::Spawn])).is_ok());
+    }
+
+    #[test]
+    fn quorum_n_de_m() {
+        let mut c = Card::new("q");
+        c.contracts = vec![DepContract::Quorum {
+            of: caps([Capability::Spawn, Capability::Journal, Capability::LegacyLogind]),
+            at_least: 2,
+        }];
+        assert!(matches!(
+            c.deps_satisfied(&caps([Capability::Spawn])),
+            Err(UnmetContract::Quorum { need: 2, have: 1 })
+        ));
+        assert!(c
+            .deps_satisfied(&caps([Capability::Spawn, Capability::Journal]))
+            .is_ok());
+    }
+
+    #[test]
+    fn conflicts_exclusion_mutua() {
+        let mut c = Card::new("solo");
+        c.contracts = vec![DepContract::Conflicts(caps([Capability::LegacyLogind]))];
+        assert!(c.deps_satisfied(&caps([])).is_ok());
+        assert_eq!(
+            c.deps_satisfied(&caps([Capability::LegacyLogind])),
+            Err(UnmetContract::Conflict(Capability::LegacyLogind))
+        );
+    }
+
+    #[test]
+    fn after_es_solo_orden_no_requisito() {
+        let mut c = Card::new("late");
+        c.contracts = vec![DepContract::After(caps([Capability::Journal]))];
+        // After nunca falla la satisfacción (aunque nadie provea Journal)…
+        assert!(c.deps_satisfied(&caps([])).is_ok());
+        // …pero SÍ aparece en las deps de orden.
+        assert!(c.ordering_deps().contains(&Capability::Journal));
+    }
+
+    #[test]
+    fn ordering_deps_une_requires_any_quorum_after_sin_conflicts() {
+        let mut c = Card::new("x");
+        c.requires = caps([Capability::Spawn]);
+        c.contracts = vec![
+            DepContract::Any(caps([Capability::Journal])),
+            DepContract::After(caps([Capability::LegacyLogind])),
+            DepContract::Conflicts(caps([Capability::FilesystemRoot])),
+        ];
+        let d = c.ordering_deps();
+        assert!(d.contains(&Capability::Spawn));
+        assert!(d.contains(&Capability::Journal));
+        assert!(d.contains(&Capability::LegacyLogind));
+        // Conflicts NO ordena.
+        assert!(!d.contains(&Capability::FilesystemRoot));
+        assert_eq!(c.conflict_caps(), caps([Capability::FilesystemRoot]));
+    }
+
+    #[test]
+    fn quorum_invalido_se_rechaza_en_validate() {
+        let mut c = Card::new("bad");
+        c.payload = Payload::Virtual;
+        c.contracts = vec![DepContract::Quorum {
+            of: caps([Capability::Spawn]),
+            at_least: 2, // > of.len()
+        }];
+        assert!(matches!(c.validate(), Err(CardError::InvalidQuorum { .. })));
+    }
+
+    #[test]
+    fn conflicts_contra_propio_provides_se_rechaza() {
+        let mut c = Card::new("contradictoria");
+        c.provides = caps([Capability::Journal]);
+        c.contracts = vec![DepContract::Conflicts(caps([Capability::Journal]))];
+        assert!(matches!(c.validate(), Err(CardError::ConflictsSelf(_))));
+    }
+
+    #[test]
+    fn contracts_roundtrip_json_y_wire() {
+        let mut c = Card::new("con-contratos");
+        c.contracts = vec![
+            DepContract::Any(caps([Capability::Spawn, Capability::Journal])),
+            DepContract::Quorum {
+                of: caps([Capability::Spawn, Capability::Journal]),
+                at_least: 1,
+            },
+        ];
+        // JSON.
+        let json = serde_json::to_string(&c).unwrap();
+        let back: Card = serde_json::from_str(&json).unwrap();
+        assert_eq!(back.contracts, c.contracts);
+        // Wire (postcard).
+        let wire: WireCard = c.clone().into();
+        let bytes = postcard::to_allocvec(&wire).unwrap();
+        let wire_back: WireCard = postcard::from_bytes(&bytes).unwrap();
+        let c_back: Card = wire_back.into();
+        assert_eq!(c_back.contracts, c.contracts);
+    }
+
+    #[test]
+    fn run_as_roundtrip_json_y_wire_y_compat() {
+        let mut c = Card::new("app-de-usuario");
+        c.soma.run_as = Some(RunAs { uid: 1000, gid: 1000, groups: vec![1000, 27, 100] });
+        // JSON.
+        let json = serde_json::to_string(&c).unwrap();
+        let back: Card = serde_json::from_str(&json).unwrap();
+        assert_eq!(back.soma.run_as, c.soma.run_as);
+        // Wire (postcard): SomaSpec viaja en WireCard.
+        let wire: WireCard = c.clone().into();
+        let bytes = postcard::to_allocvec(&wire).unwrap();
+        let c_back: Card = postcard::from_bytes::<WireCard>(&bytes).unwrap().into();
+        assert_eq!(c_back.soma.run_as, c.soma.run_as);
+        // Card vieja (soma sin run_as) ⇒ None.
+        let viejo = r#"{
+            "schema_version": 1, "id": "01HQAR53D4M2NBV8KZTYXFGS01", "label": "v",
+            "soma": { "namespaces": {"mount":false,"pid":false,"net":false,"uts":false,"ipc":false,"user":false,"cgroup":false},
+                      "rlimits": {"mem_bytes":null,"nproc":null,"nofile":null},
+                      "cgroup": {"path":"x","cpu_weight":null,"io_weight":null}, "cpu_affinity": null },
+            "payload": "Virtual", "supervision": "OneShot"
+        }"#;
+        assert!(Card::from_json(viejo).unwrap().soma.run_as.is_none());
+    }
+
+    #[test]
+    fn mount_plan_default_es_vacio_y_compat() {
+        // Default no toca FS.
+        let mp = MountPlan::default();
+        assert!(mp.is_empty(), "MountPlan default debe ser is_empty");
+        assert_eq!(mp.home, HomeSpec::Heredar);
+
+        // Card vieja (soma sin `mounts`) ⇒ MountPlan vacío.
+        let viejo = r#"{
+            "schema_version": 1, "id": "01HQAR53D4M2NBV8KZTYXFGS01", "label": "v",
+            "soma": { "namespaces": {"mount":false,"pid":false,"net":false,"uts":false,"ipc":false,"user":false,"cgroup":false},
+                      "rlimits": {"mem_bytes":null,"nproc":null,"nofile":null},
+                      "cgroup": {"path":"x","cpu_weight":null,"io_weight":null}, "cpu_affinity": null },
+            "payload": "Virtual", "supervision": "OneShot"
+        }"#;
+        assert!(Card::from_json(viejo).unwrap().soma.mounts.is_empty());
+    }
+
+    #[test]
+    fn mount_plan_roundtrip_json_y_wire() {
+        let mut c = Card::new("app-aislada");
+        c.soma.namespaces.mount = true;
+        c.soma.mounts = MountPlan {
+            home: HomeSpec::Tmpfs { destino: "/home/sergio".into(), size_bytes: Some(64 << 20) },
+            binds: vec![BindSpec { origen: "/run/pacha/secret".into(), destino: "/home/sergio/.ssh/id".into(), ro: true }],
+            tmpfs: vec![TmpfsSpec { destino: "/home/sergio/.cache".into(), size_bytes: None }],
+            hide_home_real: None,
+        };
+        assert!(!c.soma.mounts.is_empty());
+        // JSON.
+        let json = serde_json::to_string(&c).unwrap();
+        let back: Card = serde_json::from_str(&json).unwrap();
+        assert_eq!(back.soma.mounts, c.soma.mounts);
+        // Wire (postcard) vía WireCard.
+        let wire: WireCard = c.clone().into();
+        let bytes = postcard::to_allocvec(&wire).unwrap();
+        let c_back: Card = postcard::from_bytes::<WireCard>(&bytes).unwrap().into();
+        assert_eq!(c_back.soma.mounts, c.soma.mounts);
+    }
+
+    #[test]
+    fn card_sin_contracts_compat() {
+        // Una Card vieja (sin el campo) deserializa con contracts vacío.
+        let src = r#"{
+            "schema_version": 1,
+            "id": "01HQAR53D4M2NBV8KZTYXFGS01",
+            "label": "vieja",
+            "payload": "Virtual",
+            "supervision": "OneShot"
+        }"#;
+        let c = Card::from_json(src).unwrap();
+        assert!(c.contracts.is_empty());
+        // Sin contratos y sin requires: satisface contra cualquier set.
+        assert!(c.deps_satisfied(&caps([])).is_ok());
+    }
+}
\ No newline at end of file
diff --git a/shared/card/card-net/Cargo.toml b/shared/card/card-net/Cargo.toml
index 36b63af..0d95773 100644
--- a/shared/card/card-net/Cargo.toml
+++ b/shared/card/card-net/Cargo.toml
@@ -15,7 +15,6 @@ libp2p-stream = { workspace = true }
 libp2p-allow-block-list = { workspace = true }
 thiserror = { workspace = true }
 tokio = { workspace = true }
-tracing = { workspace = true }
 blake3 = { workspace = true }
 serde = { workspace = true }
 
diff --git a/shared/card/card-net/LEEME.md b/shared/card/card-net/LEEME.md
new file mode 100644
index 0000000..24270c5
--- /dev/null
+++ b/shared/card/card-net/LEEME.md
@@ -0,0 +1,47 @@
+# card-net
+
+*Read this in English: [README.md](README.md).*
+
+`brahman-net` — capa P2P compartida de la red Brahman.
+
+Provee un nodo libp2p genérico que cualquier protocolo de la
+familia (handshake brahman remoto, sync minga, futuros) puede
+reusar. La idea: una sola malla, múltiples sub-protocolos
+multiplexados por `StreamProtocol`.
+
+## Stack
+
+- **TCP + Noise + Yamux**: transporte autenticado y multiplexado.
+- **`stream::Behaviour`**: streams bidireccionales por
+  `StreamProtocol`. Cada protocolo (`/brahman/handshake/1.0.0`,
+  `/minga/sync/1.0.0`, …) se registra independientemente vía el
+  `stream::Control` que `BrahmanNet` expone.
+- **`kad::Behaviour<MemoryStore>`**: Kademlia DHT en modo Server
+  para discovery (peers cercanos + content providers).
+- **`identify::Behaviour`**: cada peer anuncia sus listen-addrs
+  reales; las inyectamos automáticamente al routing table de Kad.
+
+## Modelo
+
+El swarm corre en una task tokio dedicada. La interfaz pública son:
+1. **Comandos** (canal mpsc): `dial`, `listen`, `add_dht_peer`,
+   `find_closest_peers`, `start_providing`, `find_providers`.
+2. **`stream::Control`** (acceso directo): para abrir/aceptar
+   streams de un protocolo concreto. Cada protocolo se ocupa de
+   su propia lógica sobre el stream resultante.
+
+La separación entre comandos y control permite que la lógica de
+red (DHT, dial, listen) y la lógica de protocolos (handshake/sync)
+evolucionen independientes — el protocolo no necesita conocer al
+swarm, sólo pide streams.
+
+## Identidad
+
+Por defecto se genera una keypair Ed25519 efímera. Para identidad
+persistente (la misma `peer_id` across reboots), pasar la keypair
+con `BrahmanNet::with_keypair`. Esa misma keypair puede ser la
+base para firmas de Cards (cuando se implemente trust remoto).
+
+---
+
+Parte de **card** — ver [card](../LEEME.md).
diff --git a/shared/card/card-net/README.md b/shared/card/card-net/README.md
new file mode 100644
index 0000000..49ca666
--- /dev/null
+++ b/shared/card/card-net/README.md
@@ -0,0 +1,11 @@
+# card-net
+
+`brahman-net` — the shared P2P layer of the Brahman network.
+
+It provides a generic libp2p node that any protocol of the family (the remote
+brahman handshake, minga sync, future ones) can reuse. The idea: a single mesh,
+multiple sub-protocols multiplexed by `StreamProtocol`.
+
+---
+
+Part of **card** — see [card](../README.md).
diff --git a/shared/card/card-net/src/lib.rs b/shared/card/card-net/src/lib.rs
index c10f29c..6918977 100644
--- a/shared/card/card-net/src/lib.rs
+++ b/shared/card/card-net/src/lib.rs
@@ -159,9 +159,9 @@ impl BrahmanNet {
         Self::with_keypair(identity::Keypair::generate_ed25519())
     }
 
-    /// Crea un nodo con una keypair libp2p específica. Usá esto para
+    /// Crea un nodo con una keypair libp2p específica. Usa esto para
     /// `peer_id` estable (por ejemplo si tu identidad se persiste a
-    /// disco, o si la derivás de la identidad criptográfica del
+    /// disco, o si la derivas de la identidad criptográfica del
     /// módulo).
     ///
     /// Sólo Ed25519 se soporta — la `keypair` se duplica internamente
@@ -185,6 +185,13 @@ impl BrahmanNet {
                 yamux::Config::default,
             )
             .map_err(|e| NodeError::Build(format!("{e}")))?
+            // Envuelve el transporte con resolución DNS: sin esto, marcar una
+            // multiaddr `/dns4/host/tcp/…` (hostname en vez de IP) falla en
+            // silencio con "timeout esperando conexión" — hallado sincronizando
+            // minga entre dos máquinas por internet (2026-07-16). Va JUSTO tras
+            // el transporte (antes del relay-client) por el type-state del builder.
+            .with_dns()
+            .map_err(|e| NodeError::Build(format!("{e}")))?
             // Inyecta el transporte de relay-client: habilita marcar y
             // escuchar direcciones `…/p2p-circuit`. Provee el
             // `relay_client` behaviour al closure de abajo.
@@ -452,7 +459,7 @@ impl BrahmanNet {
 
     /// Empieza a escuchar en `addr`. Bloquea hasta que el listener
     /// publique su dirección real (Multiaddr resuelta — útil cuando
-    /// pediste `/ip4/0.0.0.0/tcp/0` y querés saber qué puerto te tocó).
+    /// pediste `/ip4/0.0.0.0/tcp/0` y quieres saber qué puerto te tocó).
     pub async fn listen(&self, addr: Multiaddr) -> Multiaddr {
         self.cmd_tx
             .send(Command::Listen(addr))
diff --git a/shared/card/card-wit/LEEME.md b/shared/card/card-wit/LEEME.md
new file mode 100644
index 0000000..d6b3e3a
--- /dev/null
+++ b/shared/card/card-wit/LEEME.md
@@ -0,0 +1,36 @@
+# brahman-card-wit
+
+*Read this in English: [README.md](README.md).*
+
+> **DORMIDO (2026-05-30).** Capa 3 de Brahman. Ver `/BRAHMAN.md`.
+
+Parser opcional de contratos WIT (`.wit` texto → `Vec<card_core::WitInterface>`, uno por `world`),
+sobre `wit-parser` (sin `wasm-tools`/`wit-component`).
+
+## Estado: relegado, no borrado
+
+La visión original de Brahman incluía **módulos agnósticos descritos por interfaz WIT** (eventualmente WASM).
+Esa capa **nunca se ejecutó**:
+
+- No existe ningún archivo `.wit` en el workspace.
+- Ningún crate de producción depende de este crate — sólo `examples/brahman-wit-info.rs` y la
+  **dev-dependency** de `card-sidecar`.
+
+Se conserva (funciona, 210 LOC, reversible) por si algún día aparecen `.wit` reales. **No asumir que está
+en ninguna ruta de build.**
+
+## El contrato agnóstico real y vigente
+
+```
+shared/card (formato Card)  +  card-handshake (handshake nativo Rust)  +  DhtKey (namespacing en la DHT)
+```
+
+El tipo de metadata `WitInterface` vive en **`card-core`** (no aquí) y **sí** lo usa el broker
+(`chasqui-broker`) para matching estructural — es metadata opcional viva. Lo único dormido es *este parser*
+de archivos `.wit` inexistentes.
+
+## Si se decide revivir WIT
+
+Requeriría: (1) que el Init lea `<modulo>/wit/protocol.wit` en el descubrimiento y construya
+`ResolvedCard::from_conscious(card, wit)`; (2) que algún módulo de producción publique un `.wit`.
+Hasta entonces, este crate es tooling latente (`cargo run -p card-wit --example brahman-wit-info -- <archivo.wit>`).
diff --git a/shared/card/card-wit/README.md b/shared/card/card-wit/README.md
index 0568111..587b5f6 100644
--- a/shared/card/card-wit/README.md
+++ b/shared/card/card-wit/README.md
@@ -1,34 +1,34 @@
 # brahman-card-wit
 
-> **DORMIDO (2026-05-30).** Capa 3 de Brahman. Ver `/BRAHMAN.md`.
+> **DORMANT (2026-05-30).** Layer 3 of Brahman. See `/BRAHMAN.md`.
 
-Parser opcional de contratos WIT (`.wit` texto → `Vec<card_core::WitInterface>`, uno por `world`),
-sobre `wit-parser` (sin `wasm-tools`/`wit-component`).
+Optional parser for WIT contracts (`.wit` text → `Vec<card_core::WitInterface>`, one per `world`),
+over `wit-parser` (without `wasm-tools`/`wit-component`).
 
-## Estado: relegado, no borrado
+## Status: shelved, not deleted
 
-La visión original de Brahman incluía **módulos agnósticos descritos por interfaz WIT** (eventualmente WASM).
-Esa capa **nunca se ejecutó**:
+Brahman's original vision included **agnostic modules described by a WIT interface** (eventually WASM).
+That layer **never ran**:
 
-- No existe ningún archivo `.wit` en el workspace.
-- Ningún crate de producción depende de este crate — sólo `examples/brahman-wit-info.rs` y la
-  **dev-dependency** de `card-sidecar`.
+- No `.wit` file exists in the workspace.
+- No production crate depends on this crate — only `examples/brahman-wit-info.rs` and the
+  **dev-dependency** of `card-sidecar`.
 
-Se conserva (funciona, 210 LOC, reversible) por si algún día aparecen `.wit` reales. **No asumir que está
-en ninguna ruta de build.**
+It is kept (it works, 210 LOC, reversible) in case real `.wit`s ever appear. **Don't assume it's
+on any build path.**
 
-## El contrato agnóstico real y vigente
+## The real and current agnostic contract
 
 ```
 shared/card (formato Card)  +  card-handshake (handshake nativo Rust)  +  DhtKey (namespacing en la DHT)
 ```
 
-El tipo de metadata `WitInterface` vive en **`card-core`** (no aquí) y **sí** lo usa el broker
-(`chasqui-broker`) para matching estructural — es metadata opcional viva. Lo único dormido es *este parser*
-de archivos `.wit` inexistentes.
+The `WitInterface` metadata type lives in **`card-core`** (not here) and **is** used by the broker
+(`chasqui-broker`) for structural matching — it's live optional metadata. The only dormant thing is *this parser*
+of nonexistent `.wit` files.
 
-## Si se decide revivir WIT
+## If WIT is to be revived
 
-Requeriría: (1) que el Init lea `<modulo>/wit/protocol.wit` en el descubrimiento y construya
-`ResolvedCard::from_conscious(card, wit)`; (2) que algún módulo de producción publique un `.wit`.
-Hasta entonces, este crate es tooling latente (`cargo run -p card-wit --example brahman-wit-info -- <archivo.wit>`).
+It would require: (1) the Init reading `<modulo>/wit/protocol.wit` at discovery and building
+`ResolvedCard::from_conscious(card, wit)`; (2) some production module publishing a `.wit`.
+Until then, this crate is latent tooling (`cargo run -p card-wit --example brahman-wit-info -- <archivo.wit>`).