# Clean-sheet celld workspace. `crates/logic` owns all behavioral state and # decisions; `crates/celld` is only an effect executor and adapter host. [workspace] resolver = "2" members = ["crates/*"] # Size-tuned: fat LTO prunes unused dependency code, panic=abort drops # unwind tables. opt-level "s" (not "z") — measure RPS before trading further. [profile.release] lto = "fat" codegen-units = 1 opt-level = "s" panic = "abort" strip = true # The lab fast loop: release optimization minus the fat-LTO relink that # dominates rebuild time, plus incremental compilation. Shipped artifacts # stay on `release`. [profile.lab] inherits = "release" lto = "thin" codegen-units = 16 incremental = true # The lab image keeps symbols so `perf` on a node attributes CPU by function; # the shipped release profile stays stripped. strip = false debug = "line-tables-only" [profile.dev.package.sha2] opt-level = 3 [profile.dev.package.rsa] opt-level = 3 # Every direct dependency lives here so the crates can never drift onto two # versions of the same crate; members add their own features. [workspace.dependencies] aes = "0.8" aes-gcm = "0.10" cbc = { version = "0.1", features = ["alloc"] } ctr = "0.9" anyhow = "1" async-trait = "0.1" axum = { version = "0.7", features = ["multipart"] } base64 = "0.22" bytes = "1" celld-logic = { path = "crates/logic" } celld-ltx = { path = "crates/ltx" } chrono = { version = "0.4", default-features = false, features = ["std"] } ed25519-dalek = { version = "2", features = ["pkcs8"] } encoding_rs = "0.8" # unstable-split gives the read and write halves as separate objects. The # tunnel needs them: a WebSocket read is not cancel-safe, so a live read # future must survive while the same socket is written, and that is only # possible when the halves are not one borrow. # # The feature is unstable by name, so a 0.8.x release can rename or drop it # without upstream calling that a break, and a caret range would take it. Deno # Land maintains fastwebsockets, so celld carries that risk knowingly; the # version is exact to keep the upgrade a decision rather than a surprise. fastwebsockets = { version = "=0.8.1", default-features = false, features = ["upgrade", "with_axum", "unstable-split"] } flate2 = "1" futures-util = "0.3" getrandom = "0.3" glob = "0.3" hex = "0.4" # The two node:crypto KDFs. Both crates already reach this build without a # line here -- `pbkdf2` through `pkcs5`, `hkdf` through `elliptic-curve` -- # so declaring them costs no compile time and adds no supply-chain surface. hkdf = "0.12" hmac = "0.12" pbkdf2 = "0.12" http-body-util = "0.1" # hyper also accepts h2 releases before 0.4.18, which retain the remotely # triggerable resource-exhaustion advisory. Keep a direct floor here because a # lockfile-only update does not preserve that security boundary when resolved. h2 = "0.4.18" hyper = { version = "1", features = ["client", "server", "http1"] } httpdate = "1" lol_html = "3.0" hyper-util = { version = "0.1", features = ["tokio"] } libc = "0.2" lz4_flex = { version = "0.11", features = ["frame"] } md-5 = "0.10" nix = { version = "0.31", features = ["feature", "fs"] } notify = "8" nu-ansi-term = "0.50" object_store = { version = "0.12", default-features = false } # The native column-writer API only: no `arrow` feature, so the arrow # crate stack stays out of the binary. Revisit only if the telemetry # schema ever grows nested columns. parquet = { version = "59.2.0", default-features = false, features = ["zstd"] } p256 = { version = "0.13", features = ["ecdh", "ecdsa", "pkcs8"] } # The other NIST curves the Workers key surface accepts. Node-compatible key # derivation and signatures use them beside the Web Crypto parsing surface. # Versions follow deno's workspace. p384 = { version = "0.13", features = ["ecdh", "ecdsa", "pkcs8"] } p521 = { version = "0.13", features = ["ecdh", "ecdsa", "pkcs8"] } # Encrypted PKCS#8, for private keys that arrive password-protected. `rsa` # already pulls pkcs8 in; naming it here adds the pkcs5 cipher suite on top. # Feature set follows deno's ext/node_crypto. pkcs8 = { version = "0.10", features = ["std", "pkcs5", "encryption"] } # X25519 key parsing and generation. `static_secrets` gives the owned # StaticSecret that a stored key needs; the ephemeral default cannot be # serialized. Version and feature follow deno's ext/node_crypto. x25519-dalek = { version = "2", features = ["static_secrets"] } # DSA, for reading legacy keys. Signing with DSA is not offered; the suite # only parses these. Version follows deno's ext/node_crypto. dsa = "0.6" # CRC32/CRC32C/CRC64-NVME for DigestStream. Cloudflare accepts these # alongside the real digests because S3 and the AWS SDKs checksum with them. crc = "3" # LTX uses CRC-64/GO-ISO for every file and for snapshot page checksums. The # generic `crc` crate above does not use the SIMD folding path that large-cell # restore needs. crc-fast = { version = "1.10", default-features = false, features = ["std"] } percent-encoding = "2" proptest = "1" rand = "0.8" regex = "1" reqwest = { version = "0.12", default-features = false } rsa = { version = "0.9", features = ["sha2"] } rusqlite = "0.31" rustls = { version = "0.23", default-features = false, features = ["ring"] } serde = { version = "1", features = ["derive"] } serde_json = { version = "1", features = ["raw_value"] } sha1 = "0.10" sha2 = "0.10" # sqlite-vec is pre-v1, and its Rust binding is outside its compatibility # policy. Pin the audited C amalgamation exactly. sqlite-vec = "=0.1.9" subtle = "2" tempfile = "3" thiserror = "2" # `stats` makes `stats.allocated` and `stats.resident` readable. The pressure # classifier needs their difference: the pages jemalloc keeps but no cell uses. # `background_threads` makes the shipped allocator purge those freed pages on # its timer. Runtime enablement alone failed in the Linux image, so the cgroup # hard-cap latch stayed closed after a node shed its cells. tikv-jemalloc-ctl = { version = "0.6", features = ["stats"] } tikv-jemallocator = { version = "0.6", features = ["background_threads", "stats"] } tokio = "1" tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] } tokio-stream = "0.1" tokio-util = { version = "0.7", features = ["io", "time"] } tracing = "0.1" tracing-appender = "0.2" tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = "2" urlpattern = "=0.4.2" # Shared isolates need v8::Locker and Send Globals: # denoland/rusty_v8#2044 and #2045. Both ship in 152.1.0, so this is an # ordinary dependency again — no path override, and no hand-built archive. v8 = "152.1" webpki-roots = "1"