This reference explains the direct third-party dependencies, their enabled features and licences, and their impact on Scribe's formats. Dependency choices keep storage and protocol code separate and use maintained libraries for cryptography and platform integration.
Inspect the resolved dependency graphs from the repository root:
cargo tree -p scribe-server-cli -e normal,build --locked
cargo tree -p scribe-cli -e normal,build --locked
cargo tree --workspace -e features --locked
cargo tree --workspace --duplicates --lockedVersions correspond to the checked-in Cargo.lock. The unsafe column records
source-text counts of unsafe in each crate's own sources, including comments
and conditional code. These counts indicate implementation size; they are not
a security audit or a count of reachable unsafe operations.
| crate | version | why std is insufficient | features | class | licence | unsafe | replacement / format impact |
|---|---|---|---|---|---|---|---|
| rpassword | 7.5.4 | hidden terminal password input and terminal-mode restoration on Unix/Windows; std cannot disable echo portably | defaults off; optional scribe-platform/password-prompt, enabled by client executable | normal (scribe-platform only) | Apache-2.0 | OS calls in upstream Unix/Windows terminal adapters; Scribe also wraps Carbon Secure Input in its macOS platform adapter; uses existing libc/windows-sys plus rtoolbox | replace behind scribe-platform::terminal; no stored/wire format changes |
| argon2 | 0.5.3 | salted and peppered, memory-hard password hashing and verification; std and fast content hashes cannot provide password storage | alloc, password-hash, defaults off; OS salt from existing getrandom | optional (scribe-auth/server) | MIT OR Apache-2.0 | 2 unsafe occurrences in own Rust sources for x86 AVX2 dispatch; transitive primitives have separate implementations | maintained Argon2id/PHC-compatible implementation; pins v19, m=19456, t=2, p=1, 16-byte salt, 32-byte result; adds password records, no repository/object format changes |
| lz4_flex | 0.14.0 (exact) | LZ4 compression/decompression for object storage, transfer, and independent metadata pages; std has no compression codec | std, safe-encode, safe-decode; defaults off, no frame dependency | normal (scribe-format) | MIT | safe encoder and decoder selected; no application unsafe or native C; other disabled implementations contain unsafe | replace with a conforming LZ4 block implementation; block framing is specified by Scribe; identities hash original bytes, never compressor output |
| blake3 | 1.8.7 | optimized, tree-hashing content digest; std has no hash | std only (SIMD via build-time cc) | normal (scribe-core only; scribe-format dev-dependency for golden identity tests) | CC0-1.0 OR Apache-2.0 | 231 (SIMD) | never for existing data: every identity depends on it. Every call goes through scribe_core::HashAlgorithm, so a second algorithm (a FIPS digest, say) is one new variant applied to newly created repositories; the envelope algorithm byte refuses objects a binary cannot verify |
| redb | 4.2.0 | transactional embedded store with immediate durability | std | normal | MIT OR Apache-2.0 | 47 (mmap-free, file I/O) | logical export/import exists for engine replacement |
| fastcdc | 5.0.0 | maintained streaming FastCDC 2020 | none (no futures/tokio) | normal | MIT | 0 | profile 1 cut points are pinned; a new chunker is a new profile id |
| ignore | 0.4.33 | Git-style ignore rules and shared lock-policy globs; std has no glob compiler | none | normal (workspace and API, shared by clients/server) | Unlicense OR MIT | 0 | replace behind IgnoreSet / LockPolicy; lock matching is specified in the client guide, no stored object encoding change |
| getrandom | 0.4.3 | OS randomness for opaque ids | std | normal | MIT OR Apache-2.0 | 114 (OS calls) | any CSPRNG source; no format impact |
| libc (unix targets only) | 0.2.189 | declarations for sendfile, fallocate/F_PREALLOCATE, posix_fadvise/F_RDAHEAD, FICLONE/clonefile, none of which std exposes | std | normal (scribe-platform only) | MIT OR Apache-2.0 | 0 | every call is one audited unsafe FFI block in crates/scribe-platform/src/sys/ with a std fallback in the same crate; no format impact |
| unicode-normalization | 0.1.25 | NFC for cross-platform path collision keys | none | normal | MIT OR Apache-2.0 | 5 | tables frozen per version; shared collision snapshots require the pinned path profile |
| tracing | 0.1.44 | structured diagnostics | std, attributes | normal | MIT | 7 | none |
| tracing-subscriber | 0.3.23 | Targets filter, fmt and JSON layers | fmt, std, json, ansi (no env-filter/regex) | normal (executables + scribe-log) | MIT | 26 | none |
| anstream | 1.0.0 | std detects terminals but does not adapt ANSI output to Windows consoles or strip styling from redirected streams | auto, wincon | normal (scribe-log; also shared with Clap) | MIT OR Apache-2.0 | 3 occurrences in own Rust sources; transitive platform bindings are separate | replace terminal stream adapter; no stored/wire format impact |
| tracing-appender | 0.2.5 | bounded non-blocking sink, daily rotation with retention | none | normal (scribe-log) | MIT | 0 | small; could be replaced by an in-tree channel writer |
| clap | 4.6.6 | argument parsing with usable errors | std, derive, help, usage, error-context, suggestions, color | normal (executables and shared scribe-log CLI parsing) | MIT OR Apache-2.0 | 0 | proc-macro at build time only |
| serde / serde_json | 1.0.229 / 1.0.151 | configuration and JSON diagnostics/reports; not wire or archive format | std, derive / std | normal (executables, scribe-api configuration, scribe-log json, saved TLS trust in scribe-tls, native FFI JSON in scribe-ffi, perf) | MIT OR Apache-2.0 | 2 / 15 | none on formats |
| toml | 1.1.5 | service configuration and shared typed .scribe/config.toml parsing; std has no TOML parser | std, serde, parse, display (unchanged) | normal (service executables and scribe-api, shared by clients/server/workspace) | MIT OR Apache-2.0 | (parser crates; unchanged dependency version/features) | replace behind repository_config::RepositoryConfig; versioned TOML schema, no binary object/index layout change |
| ctrlc | 3.5.2 | SIGINT/SIGTERM for graceful shutdown and client password-prompt cancellation; std has no signal API | termination | normal (executables and perf helper) | MIT OR Apache-2.0 | 15 (signal handlers) | shutdown-request file and cooperative stop checks replace handlers; no format impact |
| rustls | 0.23.45 | std provides no TLS or certificate verification; storage servers, gateways and the auth service need maintained TLS with client certificates | std, aws_lc_rs, defaults off; TLS 1.3 only, and every Scribe endpoint offers and accepts only the hybrid post-quantum key exchange X25519MLKEM768; 0.23.45 is the first release whose aws-lc-rs provider signs and verifies ML-DSA handshakes and certificates | normal (scribe-tls) | Apache-2.0 / ISC / MIT | 5 unsafe occurrences in rustls Rust sources; cryptography comes from the aws-lc-rs provider (see its row) | replace transport/provider behind scribe-tls; a replacement must offer X25519MLKEM768 and ML-DSA (ring offers neither); storage protocol 4 and SAU2 transport only, existing content identities and persisted formats unchanged |
| aws-lc-rs | 1.18.1 | P-256 device key generation, PKCS#8 and SubjectPublicKeyInfo encoding and ECDSA signing for client certificates; ML-DSA-65 generation, PKCS#8 encoding, signing and verification for every CA and server key Scribe creates (scribe_tls::MlDsaKey); the same provider rustls uses, and the one that implements X25519MLKEM768; std has no cryptography | aws-lc-sys, prebuilt-nasm, alloc, defaults off (no FIPS, no ring-io/ring-sig-verify compatibility layers); prebuilt-nasm uses the crate's prebuilt NASM objects on Windows x86-64 only, so building there needs no NASM | normal (scribe-tls) | ISC AND (Apache-2.0 OR ISC); the aws-lc-sys C library it builds is ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND (Apache-2.0 OR ISC OR MIT) AND (Apache-2.0 OR ISC OR MIT-0) | 367 unsafe occurrences in own Rust sources (FFI calls into AWS-LC); transitive aws-lc-sys 0.45.0 has 12539, nearly all in its generated per-target bindings, and builds the AWS-LC C and assembly library from source at compile time (grep counts, not a security audit) | replace behind scribe_tls::DeviceKey and scribe_tls::MlDsaKey with any maintained provider that generates P-256 and ML-DSA keys and supplies X25519MLKEM768 to rustls; device keys are standard PKCS#8 and certificates standard X.509, and each credential row records the algorithm (p256), so another key algorithm is a new recorded value, not a change to existing credentials |
| zeroize | 1.9.0 | wipes buffers holding private keys (device keys, CA keys, key PEM and credential text) when they are dropped, in a way the optimizer cannot remove; std has no guaranteed wipe, and writing one needs unsafe volatile writes | alloc, defaults off | normal (scribe-tls, re-exported as scribe_tls::Zeroizing for other crates; already transitive through rustls, rustls-pki-types and aws-lc-rs; rcgen's optional zeroize feature is enabled so CA key pairs can be wiped too) | Apache-2.0 OR MIT | 18 unsafe occurrences in own Rust sources (volatile writes and a compiler fence, the minimum a guaranteed wipe needs) | replace behind scribe_tls::Zeroizing with any wipe-on-drop wrapper; memory handling only, no format impact |
rustls-webpki (as webpki) | 0.103.15 | reads the one SPIFFE URI SAN and the SubjectPublicKeyInfo of a client certificate; client certificate path validation runs through rustls' WebPkiClientVerifier, built on the same crate; std parses no X.509 | std, aws-lc-rs, defaults off | normal (scribe-tls; already transitive through rustls) | ISC | 0 unsafe occurrences in own Rust sources | replace behind scribe_tls::identity::peer_identity with an X.509 reader that yields the same URI SAN and byte-identical SubjectPublicKeyInfo DER. The key id (full BLAKE3 of that DER, 64 hex) and the identity URI spiffe://<trust domain>/user/<user id>/credential/<credential id> (or …/server/<server id>/…) are Scribe formats stored at auth and carried in certificates; a parser that re-encoded the key would change every key id, and a different identity layout would need new certificates for every credential |
| tokio | 1.53.1 | scalable readiness-driven sockets, TLS waits, timers, tasks and bounded admission; std has no cross-platform async reactor | rt-multi-thread, net, io-util, sync, time, macros; no full/filesystem/process features | optional, server adapters only | MIT | 1068 unsafe occurrences in own src/**/*.rs (including comments/cfg modules); transitive mio/socket2/bytes have separate unsafe implementations | replace scheduler/transport behind adapters; synchronous RemoteOps, canonical frames and stored formats unchanged |
| tokio-rustls | 0.26.5 | maintained async rustls transport; std and blocking rustls streams cannot yield while waiting for TLS bytes | aws_lc_rs, defaults off (no TLS 1.2, no logging) | optional, scribe-tls/server only | MIT OR Apache-2.0 | 0 unsafe occurrences in own src/**/*.rs; shares the rustls aws-lc-rs provider | replace behind scribe-tls; same TLS 1.3 configuration and SAU2/storage bytes, no identity or format impact |
| ureq | 3.4.2 | synchronous HTTPS client for scribe-runner's calls to the web API: connection pool, proxies, chunked and keep-alive handling; std has no HTTP client, and the web API is the one HTTP service a Scribe executable talks to | rustls-no-provider, rustls-webpki-roots, defaults off: rustls without a compiled-in provider, the aws-lc-rs provider supplied at runtime by scribe-tls (offers X25519MLKEM768 first and also accepts X25519, which a proxy in front of the web API may offer alone), Mozilla roots via webpki-roots; no gzip, cookies, JSON or platform verifier | normal (scribe-runner only; the explicit exception to the no-HTTP rule in AGENTS.md) | MIT OR Apache-2.0 | 0 in ureq's own sources; transitive ureq-proto, http, httparse, percent-encoding, utf8-zero, webpki-roots, all Rust | replace behind scribe_runner::http::Client (one post_json); --ca swaps the public roots for private issuers; no format impact |
Per executable (cargo tree -p ... -e normal,build): scribe links no
scribe-server, scribe-metadata, or redb-based server code, because the
TCP crate's server adapter is behind the server feature, and no auth
database or service, which sit behind scribe-auth/server and
scribe-auth/admin. scribe-runner links the client crates, scribe-tls and
ureq, and no server code. All six executables share tracing,
tracing-subscriber, clap, and serde_json through scribe-log.
Tokio and tokio-rustls are enabled only through service features; a standalone
cargo tree -p scribe-cli -e normal,build --locked has neither. Workspace
builds may unify features with the server packages.
The blocking pool has an explicit thread cap and a semaphore acquired before
spawn_blocking, with one queued request per admitted connection. Storage
transfers take an additional permit before the shared worker permit so bulk
traffic cannot occupy every mutation worker. A separate query semaphore
reserves read capacity when mutations wait for publication or the database
writer; both capacities are included in the blocking-thread cap. redb and its immediate durability are
unchanged; async networking does not remove filesystem flush latency.
Duplicates: syn 2 and 3 (proc-macro build dependencies of tracing-attributes
versus clap_derive/serde_derive); build-time only, no runtime duplication.
Feature graph inspection (cargo tree -e features): tracing-subscriber
resolves without env-filter or regex; its ansi feature is enabled because
with_ansi(true) requires it. Clap enables color, sharing the anstream
adapter used by command output and stderr logs. Color support uses the following transitive packages: anstream, anstyle-parse, anstyle-query,
anstyle-wincon, colorchoice, is_terminal_polyfill, nu-ansi-term,
once_cell_polyfill, and utf8parse;
fastcdc resolves without futures/tokio; redb without logging.
Toolchain: pinned 1.96.0 in rust-toolchain.toml; MSRV declared 1.90
(File::try_lock, let-chains); Cargo.lock committed; CI builds --locked.
Updates to fastcdc, blake3, unicode-normalization, and redb need a
review against the pinned fixtures (cut points, digests, collision keys, and
the engine version recorded in descriptors).
Path case folding uses committed Unicode 17.0.0 data, not an additional Cargo
dependency. tools/generate-path-case-fold.js regenerates the table from the
official CaseFolding.txt only after checking its pinned SHA-256. Its data is
licensed under Unicode-3.0; the license accompanies the generated table in
crates/scribe-core/src/path/UNICODE-LICENSE.txt. This supplies full folding
that std's case conversion cannot provide, adds no unsafe code or runtime I/O,
and has no enabled features. Its replacement or upgrade must retain the
specified collision profile or intentionally change that profile and its
index fixtures. Normalization and folding both use Unicode 17.0.0; exhaustive
scalar tests enforce normalization and idempotence.
Cryptography: rustls with the aws-lc-rs provider handles TLS 1.3, the hybrid
X25519MLKEM768 key exchange, certificate chains, hostnames, and handshake
signatures, including the client certificates that carry every identity;
aws-lc-rs generates the P-256 device keys and the ML-DSA-65 keys of every CA
and server; rcgen, inside scribe-cert, issues server certificates and auth's
credential and access certificates, signing through those ML-DSA keys; rustls-webpki reads the SPIFFE
identity and public key of a verified client certificate; BLAKE3, always
through scribe_core::HashAlgorithm, produces public-key ids and CA
fingerprints plus keyed password-intent commitments; getrandom produces
peppers, salts and ids. RustCrypto argon2 hashes passwords and verifies PHC
strings on the auth server, using Argon2::new_with_secret for the server-only
pepper; Scribe implements no cryptographic primitive. Argon2 and its PHC
encoding and digest dependencies are absent from the client executable's
normal dependency graph. TLS uses rustls, aws-lc-rs, and the webpki crates.
Cargo.lock still lists ring as an optional dependency of rustls-webpki, but
no enabled feature selects it: ring is not compiled.
Certificate provisioning
scribe-cert, linked by both service CLIs and scribe-ctl, generates certificates
in process; the auth service also issues its credential and access certificates
through it. It exposes init_ca and issue_server library functions; CLI parsing
is a thin adapter. There is no external certificate executable, path setting, or
system installation requirement. The normal client build does not link rcgen or
x509-parser (client trust integration tests use the helper as a dev dependency).
| crate | version | why std is insufficient | features | class | licence | unsafe | replacement / format impact |
|---|---|---|---|---|---|---|---|
| rcgen | 0.14.10 | X.509 certificate generation and CA signing, for server certificates and for auth's credential and access certificates; it can generate but not load ML-DSA keys, so scribe-cert signs through scribe_tls::MlDsaKey via rcgen's SigningKey trait; std and rustls do not issue certificates | defaults off; aws_lc_rs, pem, x509-parser, zeroize (wipes CA key pairs on drop) | normal (scribe-cert); dev-only in scribe-tls, whose tests issue CA handover (cross) certificates | MIT OR Apache-2.0 | 0 unsafe occurrences in own Rust sources; cryptography shares the aws-lc-rs provider | maintained certificate issuer behind scribe-cert; PEM remains standard X.509/PKCS#8, no repository/object/wire encoding changes |
| x509-parser | 0.18.1 | inspect imported CA constraints, validity, public key, and self-signature; rcgen's issuer import does not validate eligibility | defaults off; verify-aws (signature verification with aws-lc-rs for classical algorithms; it does not know ML-DSA, which scribe-cert verifies through scribe_tls::MlDsa) | normal (scribe-cert) | MIT OR Apache-2.0 | 0 unsafe occurrences in own Rust sources; signature verification uses aws-lc-rs | maintained X.509 inspector behind scribe-cert; no repository/object/wire encoding changes |
| time | 0.3.55 | rcgen uses calendar-aware X.509 validity dates; std SystemTime does not represent these parameters | defaults off; std; other workspace users also enable formatting | normal (scribe-cert); already transitive via logging | MIT OR Apache-2.0 | 272 unsafe occurrences in own Rust sources, including comments and feature-gated code; count is not an audit | date conversion library compatible with issuer API; no repository/object/wire encoding changes |
Certificate provisioning uses transitive PEM/ASN.1 encoding and X.509 inspection
dependencies. x509-parser internally uses nom;
Scribe does not introduce a general-purpose parser framework for its own formats.
CA inspection checks signing permission, lifetime coverage, key pairing, and a
self-signature. Server certificate verification stays inside scribe-tls using
the rustls verifier for the chain, server purpose, validity, and each DNS/IP name;
client certificates are verified there too, against auth's CAs.
Certificate tests and managed scenarios require no external certificate tools.
scribe-ctl reuses the listed TOML, Clap, serde/JSON, ctrlc, getrandom, and tracing
dependencies, plus the existing certificate, TLS, auth-admin, and platform crates.
Process detachment is isolated in
scribe-platform using its existing libc dependency on Unix.
scribe-gateway reuses the existing TCP server adapter, TLS, platform, metadata,
format, redb, TOML, Clap, serde/JSON, ctrlc, and tracing dependencies.
The gateway ledger uses redb immediate durability with a
separate canonical routing record. Live instance disk-space
queries use scribe-platform through scribe-server. The client
contract suite uses the gateway as a dev dependency; the shipped client does not
link gateway or server implementation code.
scribe-ctl also reuses the internal scribe-gateway configuration API to
validate and supervise an optional gateway.
The shared repository configuration reuses the already pinned toml and serde
packages in scribe-api; it adds no third-party package or feature. Workspace
selection validation also calls this shared module. Profile and lock text are
validated as one TOML document; canonical object hashing still uses the exact
file bytes, and wire snapshots carry that text without serde-based binary encoding.
TypeScript web workspace
The user-facing web application is a separate npm workspace. Its explicitly
requested HTTP frameworks and database clients do not add dependencies to the
Rust crates or alter their boundaries. Resolved versions and transitive packages
are pinned in apps/web/package-lock.json; inspect with npm ls --all from apps/web/.
The footprint below describes managed versus native code, not a security audit.
JavaScript has no Rust unsafe keyword; Node's TLS, cryptography and I/O still
use maintained native runtime libraries. No custom cryptographic primitive is
implemented. Feature selections refer to APIs used, since npm has no Cargo-style
feature gates.
| Package | Version | Purpose / why platform APIs are insufficient | Selected features | Licence | Native / unsafe footprint | Replacement / format impact |
|---|---|---|---|---|---|---|
| next | 16.3.4 | React routing, bundling and standalone production server; no equivalent in browser/Node std | App Router, client pages, standalone output | MIT | Native SWC compiler/build tooling; Node runtime | Another React host; HTTP URLs/contracts retained, no Scribe format impact |
| react | 19.2.8 | Declarative interactive UI and lifecycle | Client hooks, context | MIT | Managed JS | UI rewrite; no Scribe format impact |
| react-dom | 19.2.8 | React browser rendering/hydration | DOM renderer | MIT | Managed JS | Paired with React; no Scribe format impact |
| babel-plugin-react-compiler (dev) | 1.0.0 | Automatic React memoization through Next's compiler integration; platform APIs cannot analyze component dependencies | Next reactCompiler, React 19 runtime | MIT | Managed JS build tooling | Disable compiler and retain ordinary React rendering; no stored/wire format impact |
| @tanstack/react-query | 5.102.8 | Request deduplication, pagination, invalidation and query lifecycle | Queries, infinite queries, query client | MIT | Managed JS | Browser fetch/cache adapter; no Scribe format impact |
| motion | 13.2.0 | Coordinated React animation and reduced-motion integration | motion/react | MIT | Managed JS/browser animation APIs | CSS/Web Animations; no Scribe format impact |
| iconoir-react | 7.12.1 | Consistent accessible icon components | Individually imported React SVG icons | MIT | Managed JS/SVG | Alternate icon set; no Scribe format impact |
| react-markdown | 10.1.0 | Safe CommonMark rendering into React elements; platform APIs do not parse Markdown | HTML disabled, custom pinned repository URL handling | MIT | Managed JS | Another safe Markdown renderer; no stored/wire format impact |
| remark-gfm | 4.0.1 | Familiar tables, task lists, strikethrough and autolinks | GFM plugin for README rendering | MIT | Managed JS | Another GFM parser; no stored/wire format impact |
| codemirror | 6.0.2 | Full file editing: undo, selection, gutters, search, bracket matching; textarea lacks these behaviors | Lazy editor module, basicSetup, EditorView, no Tab focus trap | MIT | Managed JS/DOM | Another text editor or textarea; no stored/wire format impact |
| @codemirror/state | 6.7.4 | Immutable editor state and compartment reconfiguration without resetting undo history | Read-only facet, language/theme/options compartments | MIT | Managed JS | Paired editor state adapter; no stored/wire format impact |
| @codemirror/language-data | 6.5.2 | File-extension grammar discovery; browser APIs have no code grammars | Load only the selected file's language support | MIT | Managed JS and Lezer grammars | Explicit language bundles or plain text; no stored/wire format impact |
| @codemirror/theme-one-dark | 6.1.3 | Dark-mode syntax colors that remain legible on the editor surface | Theme compartment follows resolved application theme | MIT | Managed JS/CSS | Local syntax theme; no stored/wire format impact |
| sharp | 0.35.4 | Decode, validate, strip metadata and resize avatar uploads in the API; in the assets-derive sandbox, decode untrusted repository images (and tool and render output) for facts, thumbnails, placeholders and view.webp; Node has no image codec | API: bounded static JPEG/PNG/WebP input, WebP output. Sandbox: failOn: "error", metadata and stats, auto-orient, resize, WebP output, run only in a network-less child process | Apache-2.0; its prebuilt @img/sharp-libvips-* binaries (libvips and codecs, 1.3.3) are LGPL-3.0-or-later, dynamically linked and shipped unmodified in the api and assets-derive images | Native libvips and image codecs; Node native addon | Image processing adapter or service; web avatar bytes and derived preview data only, no Scribe format impact |
| @rainbowatcher/toml-edit-js | 0.6.5 | Edit mount declarations without losing TOML comments; Node has no TOML document editor | API only, bounded 64 KiB configuration, parse/edit via Rust toml_edit in WASM | MIT | Sandboxed WASM and generated JS bindings; no native executable | Replace the configuration editing adapter; no canonical Scribe byte-format change |
| react-easy-crop | 6.2.3 | Accessible mouse/touch crop positioning and zoom without a custom gesture engine | Lazy-loaded square crop with circular preview | MIT | Managed JS/DOM | Another crop UI; no stored/wire format impact |
| lowlight | 3.3.0 | Syntax tokens without injecting generated HTML; no platform code grammars | Common grammars, dedicated worker, bounded text and timeout | MIT | Managed JS and highlight.js grammars | Another tokenizer; plain-text fallback; no stored/wire format impact |
| highlight.js | 11.11.2 | Explicit PowerShell and Windows batch grammars missing from lowlight's common set; no platform grammar API | DOS/PowerShell modules plus local Zig and Odin grammars, reused by the bounded highlighting worker | BSD-3-Clause | Managed JavaScript; already used transitively by lowlight | Replace tokenizer modules; no stored/wire format impact |
| tailwindcss | 4.3.3 | Utility styles and theme compilation | v4 CSS import | MIT | Build chain includes native Rust oxide scanner | CSS compiler/styles; no Scribe format impact |
| @tailwindcss/postcss | 4.3.3 | Tailwind integration with Next's CSS pipeline | PostCSS plugin | MIT | Transitive native scanner/CSS tooling | Alternate build integration; no Scribe format impact |
| fastify | 5.12.3 | HTTP route schemas, hooks, serialization and bounded requests | HTTP v1 routes, JSON Schema validation, pre-handlers | MIT | Managed JS; Node native HTTP underneath | Another HTTP adapter preserving v1 contracts |
| @fastify/swagger | 9.8.1 | Generate OpenAPI from live route schemas; platform has no OpenAPI generator | Dynamic OpenAPI 3, response schemas | MIT | Managed JS | Replace generator preserving v1 contract; no Scribe byte impact |
| @modelcontextprotocol/server | 2.0.0 | Maintained MCP protocol validation and stateless HTTP serving; no platform MCP implementation | McpServer, createMcpHandler | MIT | Managed JS with Node HTTP/crypto | Standards-compatible server; MCP transport only |
| @modelcontextprotocol/node | 2.0.0 | Adapt MCP web-standard handler to Node/Fastify with backpressure | toNodeHandler | MIT | Node streams/HTTP | Equivalent transport adapter; no canonical Scribe impact |
| zod | 4.5.4 | Typed validation of untrusted structured input; absent from platform APIs. MCP arguments and their generated JSON Schema, .scribe/flows definitions and job payloads in the shared service, and every message the assets-derive sandbox child returns to its supervisor | v4 object schemas, JSON Schema export (MCP) | MIT | Managed JS | Standard Schema-compatible validator; MCP, flow-definition, job-payload and sandbox-protocol contracts only, no Scribe byte impact |
| @modelcontextprotocol/client (dev) | 2.0.0 | Exercise MCP interoperability with official client rather than a simulated protocol | Client, StreamableHTTPClientTransport | MIT | Managed JS/Node fetch | External protocol conformance suite; no stored-format impact |
| @fastify/cookie | 11.1.2 | Correct cookie parsing/serialization and attributes | HttpOnly, Secure, SameSite cookies | MIT | Managed JS | Standards-conforming cookie adapter; browser session cookies only |
| @fastify/rate-limit | 11.2.0 | Bounded request admission per source | Global and route limits | MIT | Managed JS | Edge/shared limiter; no Scribe format impact |
| jose | 6.2.12 | Maintained JOSE/JWT/JWE encoding, verification and encryption | HS256 JWT; dir/A256GCM JWE | MIT | WebCrypto/Node native crypto; managed JOSE | JOSE-compatible implementation; web token/session format only |
| redis | 6.2.1 | Maintained RESP client with reconnect and command encoding | Valkey GET/SET with expiry | MIT | Managed JS; Node sockets | RESP client; disposable cache only |
| surrealdb | 2.0.8 | Typed maintained SurrealDB RPC, connection and query results | WebSocket RPC and parameterized SurrealQL, no ORM | Apache-2.0 | Managed client, Node network/crypto | DataStore repositories; sessions, profiles and durable web submit intents |
| yaml | 2.9.0 | YAML 1.2 parsing for .scribe/flows definitions; Node has no YAML parser | parse with alias and duplicate-key limits, YAML 1.2 core schema | ISC | Managed JS | Any YAML 1.2 parser; definition content is validated by zod afterwards, not by the parser |
| @noble/hashes | 2.4.0 | BLAKE3 is absent from Node crypto; verify Scribe canonical identities | BLAKE3, worker-thread content verification | MIT | Managed JS typed arrays | Conforming BLAKE3 implementation with fixtures; exact Scribe identities must remain unchanged |
| typescript | 5.9.3 | Static checking and compilation | Strict TS, declaration emit for SDK | Apache-2.0 | Managed build tooling | Compatible compiler; no stored/wire format impact |
| tsx | 4.23.13 | Execute TypeScript tests and watch API sources | Test runner, watch mode | MIT | Transitive native esbuild (Go) | Compile tests with tsc; no stored/wire format impact |
| oxfmt | 0.67.0 | Fast consistent TS/React/CSS/YAML formatting absent from platform APIs | Shared config, web/API overrides, check mode | MIT | Native Rust executable with upstream native dependencies | Another formatter; no canonical Scribe format impact |
| oxlint | 1.82.0 | Static correctness, React hooks, accessibility and Node lint checks | Root rules plus web React/Next/browser and API Node configs | MIT | Native Rust executable with upstream native dependencies | Another linter; no stored/wire format impact |
| @types/node | 26.6.3 | Node API type definitions | Node 26 | MIT | Type declarations only | Runtime-matched definitions; no format impact |
| @types/react | 19.2.18 | React API type definitions | React 19 | MIT | Type declarations only | Runtime-matched definitions; no format impact |
| @types/react-dom | 19.2.7 | DOM renderer type definitions | React DOM 19 | MIT | Type declarations only | Runtime-matched definitions; no format impact |
| three | 0.185.1 | Lazy WebGPU/WebGL 2 model viewer and maintained TGA/DDS/EXR/HDR parsers; model loaders for @scribe/models; model thumbnails in the assets-derive sandbox. Neither browsers nor Node have model or game-texture parsers | Browser: WebGPURenderer (WebGL 2 fallback), GLTFLoader with the meshopt decoder, RoomEnvironment, OrbitControls, ViewHelper; texture loaders in a disposable worker. @scribe/models (browser preview worker and sandbox): GLTF, FBX, OBJ/MTL, STL, PLY, USD and VOX loaders. Sandbox: three/webgpu renderer on the webgpu package | MIT | JavaScript; rendering uses the browser GPU driver, or Dawn in the sandbox; no native addon of its own | Replace the built-in viewers and model conversion; view.glb and thumbnails are derived, so no Scribe wire or stored-format impact |
| @types/three | 0.185.4 | Compile-time Three.js and addon contracts | Type declarations only | MIT | No executable/native code | Runtime-matched declarations; no format impact |
| @gltf-transform/core, /extensions, /functions | 4.5.0 | Read, write and optimise glTF 2.0 documents for @scribe/models, in the assets-derive sandbox and the browser's preview worker (facts from one document whatever the source format, the sandbox's view.glb, the browser's converted GLB); no platform glTF library | Document model, every KHR extension, meshopt compression and simplification, texture re-encoding through an injected encoder; /functions loaded only when optimising | MIT | Managed JS; no native code | Another glTF writer; view.glb is derived and swept, so no stored-format impact |
| meshoptimizer | 1.3.0 | Mesh simplification and EXT_meshopt_compression for view.glb; no platform mesh codec | Encoder and simplifier (WebAssembly) in the sandbox; decoder for EXT_meshopt_compression input in @scribe/models; the viewer uses three's bundled decoder | MIT | WebAssembly, no native addon | glTF Transform's other encoders; derived data only |
| draco3dgltf | 1.5.7 | Decode KHR_draco_mesh_compression input in the assets-derive sandbox | Decoder module only | Apache-2.0 | WebAssembly | Refuse Draco input; derived data only |
| webgpu (Dawn) | 0.6.1 | Render model thumbnails in the network-less sandbox with three's WebGPU renderer, on Mesa lavapipe without a GPU; Node has no graphics API | create() navigator.gpu, one device per child, read back one frame | MIT (Dawn BSD-3-Clause) | Native Node addon (Dawn) and the Vulkan loader, confined to the sandbox child | A software rasteriser for thumbnails; derived data only |
Bundled artwork, not an npm dependency: nineteen Noto Emoji SVGs in
apps/web/apps/web/public/emoji/ (Copyright Google LLC, SIL Open Font License 1.1, licence
and notice alongside) draw quick reactions and profile status emoji identically on every operating system
instead of through the platform emoji font. They are static files served as
images, run no code and have no Scribe format impact; swap the directory to change
the artwork.
Docker service versions are pinned separately in their Dockerfiles. These are
independent executables, not Rust library dependencies: Node 26
(node:26-bookworm-slim; its OpenSSL 3.5 provides the X25519MLKEM768 key
exchange every Scribe TLS endpoint requires) hosts web, API, content, worker
and assets-index;
SurrealDB 3.0.4 stores web sessions, flows and job records; Valkey 9.0.3
provides disposable caching, live events and job queues; OpenSearch 2.19.2
(opensearchproject/opensearch, Apache-2.0) holds the asset catalog, rebuilt
from Scribe when lost; SeaweedFS 4.47 (chrislusf/seaweedfs, Apache-2.0)
provides S3 object storage for run bundles and preview files; and nginx 1.29.6
routes the single browser origin. The assets-derive image (also run as
assets-derive-sandbox-image and assets-derive-sandbox-scene) is
node:26-trixie-slim with Debian's ffmpeg, openimageio-tools,
mesa-vulkan-drivers (lavapipe, a CPU Vulkan device for Dawn), libvulkan1
and bubblewrap (LGPL-2.0-or-later, not setuid), which jails each decoding
child in namespaces of its own (Node has no process jail). Trixie for OpenImageIO 2.5,
ffmpeg 7 and Mesa 25. They decode untrusted files only in the network-less
sandbox containers, each child inside its jail. Their own upstream licences
and native implementation footprints apply; Debian's ffmpeg is a GPL build. No
web image includes a Scribe binary.
Editor support tooling
The VS Code extension has no bundled runtime npm dependencies. Its separately locked build/type/test tools and their purpose, licence, native footprint, and replacement paths are documented in editor dependency rationale. These tools are independent of the Rust workspace and web application.
macOS presentation dependency
The native app pins HighlighterSwift
to 3.1.0 in apps/macos/project.yml. This is a UI-only Swift package, with no
Rust dependency or storage/protocol effect.
| dependency | purpose / why platform APIs are insufficient | features | licence | unsafe footprint | replacement / format impact |
|---|---|---|---|---|---|
HighlighterSwift 3.1.0 (product Highlighter), bundled highlight.js 11.11.1 | Multilanguage syntax colors for native read-only diffs; AppKit lays out text but supplies no source-language grammars | Library and bundled JS/CSS only; fast attributed-string renderer; explicit filename language selection; no WebView, network, or execution of source text | MIT; highlight.js BSD-3-Clause; notices bundled in the app | No Scribe unsafe code; upstream Swift uses JavaScriptCore and Foundation/AppKit and has force unwraps; instantiated and serialized inside a dedicated actor, known-language and exact-source checks at boundary | Replace behind ReviewSyntax; source text and diff model remain independent; no disk/wire format impact |
Highlighting is bounded to 512 KiB combined. Failures display a plain-source notice and never modify code or its line mapping. Full native text selection, line gutters, edit alignment and navigation do not depend on syntax colors.