YUME Internet freedom by FixCraft
On this page

YUME implementation status

This page is the public support boundary for the live source tree. It uses three terms deliberately:

  • Implemented means code exists in this repository.
  • Tested means a named executable or integration path exercises it.
  • Qualified means the exact candidate passed the complete gate for the named platform and environment.

YUME 0.3.0-dev1 composes native YTP/1 as yume and yumed, using schema-1 configuration. The C ABI is an experimental interface. Release qualification is tracked by surface below: the native programs, SDK, installed packages and GUI each need evidence for their own environment.

Current 0.3 foundation

The experimental ABI implements explicit client credential-file validation through yume_config_validate_client_credentials, without starting an endpoint. It returns the private-key-derived local composite fingerprint after native credential and key-pair checks. Its output is distinct from an authenticated peer identity and server admission. See ABI for caller confinement, file lifetime and buffer requirements.

Foundation components

Implemented and covered by focused tests:

  • a dependency-pure C++20 engine foundation with move-only bounded buffers, cancellation, executor affinity, byte-channel, secure-channel, carrier, stream-handler, route-provider, exact provider descriptors, and an instance-local freezing builder;
  • a role-neutral, one-session bootstrap coordinator that composes the frozen client provider chain or a server front door’s typed ready-carrier promotion, validates TLS 1.3 suite provenance and exact carrier/affinity continuity, waits for cancellation settlement, cleans every rejected layer, and reports success only after the YTP session becomes active in focused in-memory tests;
  • a bounded h2-duplex carrier provider over SecureChannel, with genuine client priming plus extended-CONNECT acceptance, a typed live-state server-promotion seam, carrier-private record framing, move-owned outer credit, and flow-controlled send completion. Focused fake-channel tests and the H2 carrier regression (yume_h2_carrier_test) pass, and they do not establish a complete YTP session runtime;
  • 31-bit YTP stream identifiers with stream zero reserved for control, odd client ownership, even server ownership, and exhaustion checks;
  • a dependency-pure YTP/1 protocol kernel with bounded canonical frame, OPEN, destination, capability, credit, AUTH-TLV, mandatory-security-parameter, and key-schedule-input codecs;
  • entirely new yume/ytp/1/... domains plus checked-in canonical encoding vectors;
  • an OpenSSL 3.5 session-security provider candidate with exact Ed25519 plus ML-DSA-87 authentication, X25519 plus ML-KEM-1024 establishment, per-identity access PSKs, exporter/transcript/capability binding, one-use AES-256-GCM record keys, and crossed directional rekey tests. It is wired to the source-level native endpoint composition, with production qualification still open;
  • a Boost.Asio client TCP ByteChannel provider with bounded DNS/connect work, socket-protection-before-connect, bounded ordered operation queues, per-operation and provider cancellation, real TCP half-close, and explicit executor affinity. An accepted-channel owner shares the same channel implementation for connected server sockets. Listening belongs to the separate native FrontDoor. NativeEndpoint composes these providers for the development CLI and schema-1 ABI backend. Both use the caller-owned single-runner AsioExecutionContext and reserved control dispatch. Initiation occurs on its context, while cancel/close can cross threads; the runtime must close owners and drain completions before stopping execution. Provider regressions exercise sustained allocation failure during control dispatch, read/write initiation and queue reuse, active read/write cleanup, owner destruction and resolver delivery under allocation failure. The native runtime contains Asio delivery exceptions and resumes cleanup. Endpoint integration tests are described below;
  • a SystemResolver that runs system name lookup in a killable helper process, one thread per lookup, with bounded outstanding and abandoned work. Cancellation settles at once, and closing the resolver kills and reaps the helper. The helper inherits only its standard streams and socketpair and drops every capability. Resolver, provider and endpoint tests use a helper whose test name never resolves: cancellation, helper replacement after abandoned lookups and endpoint close all settle, and final drain finishes within two seconds. The development programs are their own helper. The ABI names an installed yume-resolver through resolver_program, and without one a client that dials a name fails to start;
  • an OpenSSL 3.5 TLS 1.3 secure channel which wraps arbitrary engine byte channels through memory BIOs, enforces exact TLS 1.3 plus ALPN h2, verifies client-side hostname/trust, exposes bounded outer certificate evidence and exporter binding, and keeps its provider provenance immutable. Its client applies the shared browser profile through patched OpenSSL, while refusing negotiated TLS 1.2 or HTTP/1.1 before publication. The separate server-cover entry accepts ordinary TLS 1.2/1.3 H2 cover, refuses HTTP/1.1-only ALPN offers and sends a fixed HTTP/1.0 403 response to clients without ALPN. NativeEndpoint composes both paths. Full-session stealth qualification remains open.
  • exporter-bound H2 admission helpers with a separate YTP domain, exact 32-byte key, strict name/path encoding, and client-carrier proof generation. Shared replay reservations use monotonic expiry and refuse saturation or allocation failure. The native FrontDoor composes these checks with cover and connection-lifetime promotion policy;
  • strict immutable numeric config schema 1 with closed objects, duplicate-key rejection, exact provider values, file-only credential references, bounded services/adapters/resources, canonical direct-adapter destination networks, and RFC 6901 error locations;
  • the experimental role-neutral C ABI v1 candidate header, symbol allowlist, typed metadata and diagnostics, and exception-contained handle scaffolding;
  • an explicitly enabled unversioned libyume.so build-tree library with build-tree C and C++ consumers that verify metadata, schema-1 configuration, handle lifecycle, registration ordering, and a real transport start reaching the runtime rather than a stub, plus an integration probe that provisions a real server and client and moves bytes both directions over an authenticated named service stream. A client’s socket protector sees its TCP dial to the server, or to its SOCKS5 proxy, and a refusal fails the dial. A server refuses a protector. The candidate has no frozen ABI package. YUME_INSTALL_EXPERIMENTAL_SDK=ON enables development installation of the unversioned library, C header, CMake package and pkg-config metadata. The clean-prefix consumer gate runs when installation and tests are enabled. With the native daemon built, both CMake and pkg-config consumers exchange authenticated named streams/packets and routed TCP/UDP using the original probes and staged programs. Selected consumer language, C++ runtime and sanitizer options are preserved across both discovery paths. tests/abi/install_consumer/consumer.c is not idle: the shared-ABI build compiles it as yume_c_abi_consumer_c, which checks that the public header still parses as strict C11 rather than C++;
  • one compatibility manifest reporting product, YTP, config, ABI, logical suite components, concrete providers, cryptographic backend, and evidence-profile versions without treating an unwired component as active;
  • deterministic validation of declared source dependencies and regeneration of a source-dependency SPDX SBOM. This inventory is not proof of source ancestry.

Ingress front door

The native H2WebFrontDoor implements a TCP listener over the accepted-channel owner, ordinary TLS 1.2/1.3 H2 cover traffic and strict TLS 1.3/H2 admission promotion. Its operator-supplied immutable static site uses confined FileRoot reads and has no fallback content. Invalid, missing, replayed or saturated admission stays in cover handling. GET and HEAD serve static routes. Other methods receive the fixed 405. Actual received SNI and locally derived TLS exporter bytes bind verification; a shared bounded replay cache and permanent per-connection state allow at most one promotion during the TLS connection’s lifetime.

Promotion transfers the same TLS and H2 objects after output and timer drain. The carrier retains parser and flow-credit state, queued output, cover handling, provider provenance, executor affinity and accepted TCP ownership independently of the listener. The caller supplies and drains the execution context, contains runner exceptions and resumes cleanup. The front door binds H2 ordinary dispatch and reserved control delivery to that context. H2 close, cancellation and credit return use the same allocation-free mailbox as TCP; TLS/H2 failure settlement preserves callbacks when diagnostics cannot allocate. Ingress resolves no names. The source-level native endpoint now connects this ingress to session bootstrap, and the experimental schema-1 ABI backend composes that endpoint.

yume_h2_web_front_door_test exercises real loopback TLS/H2 ingress, configured cover responses, invalid-then-valid admission on one connection, exporter mismatch, replay expiry, cache and promotion-capacity saturation, bidirectional carrier records larger than the initial H2 window, cancellation, handshake deadline cleanup and listener-independent carrier lifetime. A real occupied-port test preserves the original listener. Linux GNU/Clang tests inject bind errors at the syscall boundary to verify classification and retry without changing host privileges or resource limits. The cover-site, TLS and H2 tests cover their separate parsing and ownership boundaries. These focused checks do not establish AUTH, a complete YTP session or a YTP ABI path.

Automated evidence

The lasting automated evidence includes warning-as-error builds, strict C and C++ ABI consumers, exact built/header/map/candidate-symbol agreement, schema examples and negative parser cases, real-key hybrid handshake/record/rekey tests, malformed canonical-codec cases, fake-channel TLS/H2 provider tests, real loopback TCP and connected-UDP route tests, the H2 carrier regression, and the end-to-end ABI named-stream probe. Exact candidate run results belong to CI or private qualification artifacts rather than this current-behavior document. Passing focused tests does not qualify the replacement end to end.

Native endpoint

runtime::NativeEndpoint loads protected schema-1 credentials, builds role-aware provider graphs, wraps application handlers with immutable per-identity service policy, and owns bounded bootstrap and session slots. Client startup bounds dial/TLS/carrier/AUTH together; server session creation/AUTH is bounded from validated carrier promotion, leaving idle accept waiting outside that budget. FrontDoor separately bounds pre-promotion connections and work. An optional endpoint-owned accept loop keeps a sized number of starts pending on every listener and retries refused or immediately failed starts after a delay. When a listener stops, or a retry cannot be scheduled for a listener with nothing pending, it closes the endpoint and reports once. The standalone server uses a reserved control task to carry a served endpoint’s terminal failure to its first context without allocating, retaining its state through the callback. Descriptor or memory exhaustion in the native FrontDoor pauses accepting for one second before retrying. Other accept failures, or failure to schedule that retry, close the listener. Listener publication follows credential, mapped-limit and static-cover validation. Static directory snapshots include nested assets and require the browser profile’s priming paths. loopback_http_fetch.* fetches one GET or HEAD from a loopback web server within fixed header, body and time bounds, with cancellation that settles once, and probes such a server at startup. It is the first part of a reverse-proxy cover. The FrontDoor does not use it yet, so cover.reverse_proxy still fails start. Duplicate terminal cleanup does not queue work after final executor drain. Explicit destination handlers may supply one endpoint-owned route provider, subject to exact suite validation and their application authorization policy. The native route provider shares the ingress execution context and reserved cancellation ownership. It requires explicit numeric-address authorization before opening any socket, including every selected DNS candidate and IPv4-mapped IPv6. Policy errors and reentrant cancellation settle the OPEN without connecting. The provider also caps each authenticated route identity at half of its pending and active limits, rounded up, across sessions and TCP/UDP services; failed, canceled and closed opens release those reservations. A circuit exit counts the authenticated previous hop, not the hidden client.

Session teardown notifies the endpoint through reserved control dispatch. The endpoint frees the session slot before its optional session_ended callback runs on the endpoint context. The native client uses this notification to start reconnecting without polling. Failed attempts, and sessions that end sooner than the longest backoff after authenticating, retain bounded exponential backoff. Pending starts report failure through their own completion. NativeClientRuntime::status() gives embedding applications a thread-safe snapshot: connecting, connected, waiting or closed, the last failure, the verified server fingerprint, attempt counts and traffic totals across sessions. An optional callback reports each state change on the runtime context. SessionEngine::traffic() supplies the per-session payload and record byte counts. The endpoint test checks both across a reconnect.

Control socket and reload

With control.socket or yume --control-socket, both programs serve control protocol 1 on an owner-only UNIX socket: this snapshot with the fixed posture and tuning limits, circuits and route proposals, route acceptance, the last 256 lines the program printed and, for yume, a stop request. yume_native_control_socket_test covers each request, its refusals and bounds, and the native runtime test stops a running client over the socket.

A server endpoint reloads its credential stores on request, and yumed does so on SIGHUP. Reload replaces the security factory that every later session takes its credentials from, including sessions on accepts armed before the reload, and swaps the authorization policy that every service wrapper consults, so established sessions apply changed grants to their next OPEN. It ends sessions of removed identities and those beyond a lowered max_sessions, and refuses a store that fails validation or a changed admission key. The endpoint test covers grant changes, refusal of a malformed store, revocation of a live session and a client added while an accept was armed.

Clusters and circuits

Servers of one operator form a cluster (cluster 1). A server with a cluster section verifies the operator’s signed list and its peer store, keeps one outbound link to every peer with the client’s backoff, and admits peers’ links, granting them only yume.circuit. An expired list closes the links and ends the peers’ sessions. A reload keeps every link whose inputs did not change and replaces or closes the others, and the server saves the highest serial it has loaded so that an older list is refused after a restart too. yumed --status reports the list and each link over the control socket. yume_cluster_list_test and the credential test cover the list, store and saved-serial refusals, and yume_native_cluster_test runs three daemons from yume-setup’s cluster commands: links in both directions, recovery after a stop, a refused wrong PSK, a reload that restores a link, a newer list that keeps every link, a removed server and a restart refused for an older list.

The links carry circuit 1. Its codec (circuit/) and its handshake and layer constructions (providers/circuit_crypto.*) are checked by yume_circuit1_codec_test and yume_circuit_crypto_test against vectors from an independent Python generator, with real-key handshakes and their refusals, and yume_fuzz_circuit1 fuzzes the codec. Every member serves yume.circuit, answering CREATE, extending circuits over its links, relaying cells and, when its cluster.exit names a direct_tcp service, carrying circuits’ streams through that service’s destination policy, within the bounds in cluster 1. It also serves the operator-signed routes view on yume.routes, which names servers, exits and network tags without addresses. A client needs the yume.circuit grant, which yume-setup add-client --circuits writes. Circuit streams’ receive windows are capped at an eighth of the session budget on yume.circuit and on links, and yumed --status counts circuits per link and refusals by bound. The in-memory yume_circuit_runtime_test covers the node service and the client builder, including an even share for a circuit’s downloads and uploads over a slow link, queued middle-hop failure delivery while an upstream write is held, and bounded cleanup when the previous hop does not end the failed stream, and yume_native_circuit_test runs four daemons with a test client: two- and three-hop circuits carrying a stream both ways, an exit policy and a non-exit refusing streams, a client without the grant, the per-client bound, a reload under load, a stopped middle and its return, a client that leaves while its circuit waits at the entry, a link rekey that a frozen middle never acknowledges, a refused reload, a changed link PSK and a removed node, each beside a circuit that must keep running.

A client with a circuits section sends every SOCKS5 CONNECT and every forward to a destination through circuits it builds itself: it verifies the routes view its entry serves against the kit’s copy and a saved serial, chooses routes by the rules in cluster 1, builds a circuit when its session starts, keeps a spare, rotates circuits, opens streams as soon as BEGIN is on its way and refuses UDP, packet adapters and plain HTTP. It never shortens a route on its own: a proposal waits for yume --accept-route over the control socket, unless circuits.min_hops approves it in advance, and yume --status shows routes and proposals. yume_circuit_routes_test, yume_plain_http_guard_test and the credential, config, control socket and setup tests cover the parts. yume_circuit_pool_test runs the circuit pool over an in-memory session with real circuit nodes: the build at session start, rotation, idle closing, the spare-failure rule, exclusion of a failed node and its use again once it returns, the configured length coming back after a proposal without an answer, cancellation, closing and a new session during a build, and circuits closing inside the pool’s own loops. yume_circuit_record_fit_test checks that a full cell of either direction leaves as one 16384-byte TLS write. The four-daemon test runs the real yume through three hops, the plain HTTP refusal, a proposal accepted after the exits stopped and a pre-approved direct route. It also stops one stream’s reader and another’s destination: healthy streams on the same circuit and another client’s circuit keep moving, no node ends a circuit, and both stalled streams then deliver every byte. The C ABI refuses a circuits section.

Egress and listeners

A server configuration may set limits.max_egress_mbps. The endpoint then paces the payload of every stream it serves, in both directions and for every service, through one limiter that splits the rate between busy identities by the weight in their authorized-keys entries. Each identity’s clock runs at its share, and the shares of busy identities sum to the rate. Weights are read at each transfer, so a reload reaches open streams. A held transfer checks its stream every 250 ms and ends at once on close, so pacing cannot hold teardown or the final drain. Transfers already scheduled keep their share when another identity starts sending, so the total can briefly exceed the rate. Unit tests cover shares, weights, idle identities and every settlement path, and the endpoint test measures pacing on a live stream in both directions.

Listener socket setup preserves OS permission refusal, address conflict, invalid-address and resource-exhaustion status through the runtime and embedding seams. Unknown socket failures remain generic I/O failures; an unexpected exception is not reported as memory exhaustion. The C ABI probe exercises a conflicting listener, failed-start state, retry after port release, and restart of the original endpoint before exchanging authenticated traffic.

Integration tests

Native integration tests provision actual setup credentials and exercise loopback TLS/H2, composite AUTH, named bytes in both directions, simultaneous directional rekeys, half-close, refused service opens with a surviving session, idle accept survival, stalled AUTH deadlines and final handle cleanup. Lifecycle regressions cover closure from another thread, pending-read settlement before notification, reentrant slot reuse, callback exceptions, client reconnect with SOCKS traffic through the replacement session, and backoff after a session that ends right after AUTH. Engine regressions retain closing entries through crossed FIN, abort and settlement in both roles, reject invalid peer barriers and keep withheld settlement within the existing stream bound. The established endpoint rekey cases explicitly initiate rotation. The session engine also rotates on its own. An epoch ends at the session’s epoch size of directional payload, one protected record per 2 KiB of it, or 500 ms of sending. Its rotation starts at half of any of these, and the epoch keeps carrying records while REKEY_ACK is outstanding until a limit is reached. The receiver keeps the old inbound root only until the peer’s first record of the new epoch. The epoch size is the smaller limits.max_epoch_bytes of the two capability manifests, 1 MiB by default and at most 64 MiB, and engine and endpoint tests cover a pair of sides that advertise different sizes. With limits.idle_epoch_rotation, which the fast and max presets set, the native endpoint’s rekey timer also starts the rotation of a used epoch once it is 250 ms old, so a request after an idle moment does not wait for REKEY_ACK. It is off by default, because that exchange after every burst of traffic is visible in the stealth captures. It reserves outbound space for rekey controls and for one of its own credit or CLOSE records. Credit, FIN, terminal CLOSE and settlement records that do not fit wait as bounded obligations, and engine tests cover them behind held data, pending writes, stream churn and PONG traffic. Focused engine tests cover byte, record and send-age thresholds, idle rotation, crossed rotation, synchronous ACK delivery, reserved queue capacity, peer overshoot refusal, deferred publication and ACK deadline expiry. The native endpoint also tests its unanswered-ACK watchdog. Competing-stream tests cover credit changes, stalled readers, callback reentry and release after rekey. Receive windows batch consumed credit and grow while the application drains them within two round trips. Connection credit also returns below the batch threshold when the peer has less than one maximum frame left. Receiver tests in both roles keep one stream unread while three others consume checked data, then drain or close the held stream and verify continued progress within the original windows. They cover queued and application-held records, including useful consumption before the unread stream spends the final connection grants. Engine tests cover the return point, growth to the bound, a slow reader whose window stays, a peer that cannot buffer past its credit and grants above the local maxima. An endpoint test covers a client whose byte budget is smaller than the server’s. The admitted H2 carrier’s receive window is twice the budget, from 8 MiB to 128 MiB. Carrier tests cover its bounds and a peer that may send the whole window before any credit returns. These cases do not establish sustained real-carrier fairness or high-RTT behavior. Automatic rotation remains an open security-preservation gate despite the changed build default. Deterministic pacing tests cover accept refusal, unschedulable retries, re-entrant completion, stopped listeners and close. Socket tests cover loop exclusivity, capacity recovery and a promoted carrier that never authenticates, plus two listeners and an injected OS accept failure on Linux. Enabling the Asio route provider also exercises real TCP and UDP destination traffic through configured direct_tcp/direct_udp adapters, packet boundaries, refusal by credentials, configured destinations, request policy and resolved-address policy before socket creation, and retained route/credit destruction after endpoint drain. Native composition requires an explicit provider, enforces each direct adapter’s schema-1 destinations before an optional application policy, refuses duplicate binding ownership, and preserves the caller’s provider on failed creation. NativeEgressPolicy tests cover public and explicit networks, never-permitted addresses, IPv4-mapped IPv6 and per-protocol rules. egress_lists.* reads egress lists (JSON lists, the binary VPN provider database and MaxMind country databases) into disjoint address ranges, where the most specific range decides and Deny wins a tie. Direct adapters take them through destinations.lists and country_database, and they only narrow what the adapter permits. NativeEgressPolicy reads the files at start and in --validate, adapters with identical lists share one copy, and the endpoint and its route provider share one policy, so the request and resolved stages decide with the same lists. The runtime test shows a list refusing a destination that the adapter’s networks permit. yume-doctor checks each list file’s type and size but not its contents, and SIGHUP does not reload lists. The canonical network grammar shares test vectors with yume-doctor. Engine dispatch supplies the selected provider to the handler; it cannot accidentally validate one instance while the built-in handler uses another. The public ABI backend still rejects adapter declarations, and carries a device’s traffic through its device bridge instead. Engine tests separately exercise acceptance and ordered terminal acknowledgement; bootstrap allocation sweeps cover client and server startup and selected teardown paths. These checks are not comprehensive allocation-failure, application-adapter, sanitizer or security qualification.

Embedding ABI

Enabling the shared ABI builds every native provider. Its experimental yume_embed backend runs NativeEndpoint on its own execution thread behind the blocking C ABI. Schema-1 clients open, and servers accept, authenticated named byte streams and packet channels with the composite peer identity. Clients also open TCP/UDP destinations through a native daemon’s declared direct services. A server holds each authorized OPEN until the application accepts it, and a client opens only services its configuration declares. Configured services the application did not register are refused, and declared adapters or reverse-proxy cover fail start explicitly. Engine reads report the peer’s authenticated FIN with a dedicated EndOfStream status. The responder’s thread-safe terminal observation overrides retained EOF and unread adapter records after abort or session loss. Accept transfers local ownership without waiting for execution-thread dispatch; shutdown deadlines cover that dispatch as well as prior writes. An escaped runner exception closes the endpoint and drains accepted work. The native FrontDoor enables address reuse on POSIX, so a restarted server can rebind its port. yume_abi_stream_integration exercises setup-generated credentials, peer identity, refused opens, deadlines, half-close, stop, restart and stream handles that outlive their endpoint. yume_native_backend_test also pauses execution to check deadline handling, acceptance rollback, partial-read credit lifetime and cleanup after an escaped delivery exception. yume_native_backend_open_integration also stops device-backed startup against a peer that accepts TCP without answering TLS, checks that the startup waiter returns Cancelled after final drain, and verifies release of its run ownership. It repeats authenticated client lifetimes with two runs apiece and checks that startup, run, session and context owners expire after close, with stable event-loop descriptor counts after warm-up on Linux. The standalone programs compose NativeEndpoint directly. This embedding backend has no production qualification.

A client endpoint of the ABI can carry a TUN device the application owns, such as an Android VpnService’s. runtime/device_bridge.* turns each TCP connection into a stream OPEN and each UDP destination into a packet OPEN on the kit’s ordinary services, as the SOCKS5 adapter does for a local application, so no packet service or TUN is needed on the server. runtime/device_nat.* rewrites TCP segments so the host’s kernel terminates each connection on the bridge’s listener, and the library contains no TCP implementation. Such an endpoint keeps its session up with the SessionKeeper that yume uses. yume_device_nat_test checks the rewriting and its checksums against a full computation, and yume_abi_device_integration sends real TCP and UDP of sockets in one network namespace through a real yumed in another: 300 connections at once, shared name lookups, refused destinations, a lost and replaced session, an immediate retry, a path that stops answering, which ends the session at YTP/1’s 30 s rotation acknowledgement deadline, a restart and a stop. IPv6 legs need a host kernel with IPv6. The Android client, in its own repository, runs on this bridge, and one device cycle on a Pixel 9 Pro with Android 17 against a real yumed passed the legs the leak-tight page lists. Android links libc++, so the native suite was also run with clang and libc++ on the build host. CI’s libcxx job builds the same native and module graph with libc++ and runs the shared-ABI and native tests. Retry-timer failure fixtures cover Asio’s POSIX aligned allocation route as well as its C++ and aligned_alloc routes, so a fault cannot silently miss timer initiation on that library.

The ABI also reports an endpoint’s status snapshot and the lines it has said, cancels a client start from another thread, and opens a sealed kit in memory. yume_abi_stream_integration reads the snapshot and the feed at each step of a real session and cancels a start against a server that never answers, and yume_abi_kit_integration opens a kit that the yume program sealed and checks what the library refuses instead. The status snapshot retains successful authentications through session end, intentional stop and stopped backend replacement. An accepted STARTING transition begins a new counter generation at zero; a call rejected before that transition preserves the previous one. Failed, cancelled and expired starts report zero counters in their new generation. Device reconnections accumulate within that generation, with failed_attempts reset at each authentication; both counts survive stop. Sticky last_failure and handle-wide traffic totals keep their separate lifetimes. yume_native_backend_open_integration pauses notification delivery for both stream and packet sessions to check that ENDED is published with its typed reason and lifecycle line, and that intentional stop records no failure. Its counter assertions retain authenticated sessions through pending and delivered end notifications and stop. The public stream fixture also checks counter generations across failed, cancelled and expired starts, stop, stopped backend replacement and restart; the device fixture checks counts across reconnects, stop and restart.

Native programs

The native executables yumed and yume run schema-1 configurations. YUME_BUILD_NATIVE_APPLICATION=ON builds the complete provider graph, as does YUME_BUILD_SHARED_ABI=ON. Providers have no individual build switches. --config selects the file, --validate checks configuration and credentials, and security policy has no CLI override. The client’s --connect, --socks-address and --socks-port each replace one configuration key for a run and pass that key’s checks. The daemon serves configured direct_tcp/direct_udp adapters and refuses a service without one, because only an embedding application can supply a named-service handler. The client keeps one authenticated session and starts a replacement when the endpoint reports closure. Failed attempts and short sessions use bounded exponential backoff. It refuses server-initiated OPENs and runs the configured loopback SOCKS5 listeners. A CONNECT becomes an authenticated OPEN, and after the peer accepts it the socket and stream share the direct-route bridge. Payload sent with CONNECT stays unread in the socket until that bridge takes ownership. Only the no-authentication method, CONNECT and UDP ASSOCIATE are offered, and a request without an active session is refused rather than queued. A client may set connect_address to dial a numeric address while TLS and admission still authenticate host. socks5_upstream.* can reach the server through a SOCKS5 proxy instead: another byte-channel provider connects to the proxy, which is then asked to CONNECT to the server by name or address, with or without username and password authentication, reading no byte past the proxy’s reply and bounded by one deadline. A client configuration’s endpoint.socks5_proxy selects it, with credentials read like the other protected files, and a managed TUN then keeps the proxy’s route outside the tunnel. The runtime test runs a second client through an authenticating proxy. yume_native_runtime_test provisions a kit, runs both processes, moves a payload through SOCKS5, checks refusal by configured destinations and by an unreachable route, and requires clean SIGTERM exits. It also checks early binary payload with CONNECT or greeting+CONNECT, split request writes, exact byte delivery and responses after the client half-closes. An early payload cannot bypass destination policy or replace the session. The adapter cancels a CONNECT whose OPEN deadline expires and replies with SOCKS5 0x06 (TTL expired). Late acceptance cannot revive it. The native endpoint test holds acceptance open to check expiry, later requests on the same session, ordinary refusal, adapter shutdown and an accepted stream outliving its OPEN deadline. On Linux with GCC or Clang, yume_native_runtime_dns_test also checks allowed, denied and mixed DNS answer sets in both orders. Its test daemon wraps the OS resolver and observes socket creation while running the production runtime. Refused sets open no sockets, return SOCKS5 reply 0x02, and leave the session usable. Asynchronous permission refusal uses the existing unauthorized CLOSE code instead of reporting a handler failure. A client forward adapter turns each connection to its loopback TCP port or UNIX socket into an authenticated byte-stream OPEN on its service, carrying its optional fixed destination, and joins them with the same route bridge. SOCKS5 and forwards share LocalListener, which owns the accept retry and pause rules and the UNIX socket checks: a directory owned by the user and closed to others’ writes, a 0600 socket file, peer credentials of the same user, replacement of a stale file and removal on close. The accepted-channel owner adopts UNIX stream sockets with the TCP channel implementation and capacity. The endpoint test checks an accepted forward in both directions with its destination and early payload, OPEN expiry, a refused service, no active session and a UNIX listener. The client runtime test forwards through a configured UNIX socket after a reconnect. Unit tests cover the UNIX path rules and channel adoption. A server module adapter binds its stream service to a ModuleConnector. At startup and with --validate, the daemon checks the module’s socket: a UNIX socket of its own user with no group or other access, in a directory that only root and that user can change. Each connection also requires a listener created by root or that user. Each authorized OPEN without a destination becomes a connection that starts with a yume-module 1 header naming the client identity, joined to the stream by the route bridge. A service manager owns the module’s process and socket. The Debian package ships yume-module@.socket and yume-module@.service templates, which run each module as a dynamic user of its own in a sandbox without a network. Unit tests cover the socket checks, a module restart with half-close and a stream that waits in the socket’s queue, a removed socket and allocation failures. The endpoint test reaches the echo module through a client forward, and the runtime test serves it under the real yumed and checks that --validate refuses a socket open to the group. The installed units have not run on a qualified host. With YUME_BUILD_BASEFWX_MODULES, yume_module_relay builds the relay v2 end-to-end channel apart from transport v2: the composite-identity handshake with ML-KEM-1024, X25519 and an optional PSK, the sealed record format and the hybrid ratchet with its rekey records. Its tests check known answers produced by the transport-v2 code for epoch roots, ciphertexts and whole records, so the copy keeps every label and wire value. A known-answer test also checks every handshake and ratchet label on the relay channel page against an independent Python reference. The same library holds the stores a relay user keeps: chat history encrypted at rest, the relay secret derived from a password with PBKDF2, and peer trust with first-use and pinned fingerprints. Peer fingerprints are now YTP/1 identity fingerprints, the value yume-setup prints for a key. It also holds the relay’s invite, endpoint and directory records with their strict JSON parsers, the message policy that decides which relay message may follow which, and the bounds on pending invites. History records require exactly ts_ms, peer_id, peer_name, direction and text, with no duplicate or nested fields. Timestamps fit signed 64-bit integers, the other fields are strings, peer IDs are nonempty, and direction is in or out. Invalid records make the list unavailable and return no items. YUME’s guarded plaintext buffers are wiped on release as best effort. JSON-library parsing and serialization can retain ordinary-memory copies outside those guards. yume_module_files adds relay file transfer: a source pinned to one opened file that hashes and sends the same bytes, and a receiver that writes into a private staging file and publishes it without replacing anything, only after the declared size and SHA-256 match. It rejects unrepresentable receive deadlines before creating state, and cleans up failures before allocating diagnostics. The relay channel reference owns the history layout and trust-commit durability rules. yume_module_codecs holds the application codec core without BaseFWX: the HTTP request and response envelope, backend dialing rules and the Monero RPC descriptor with its request allow-list. No module uses these libraries yet. Client kits move between devices as sealed kits, which need only the core’s OpenSSL 3.5 and replaced the BaseFWX .yss container library. UDP ASSOCIATE uses the SOCKS5 adapter’s configured udp_service. A loopback relay accepts datagrams only from the requesting client and gives each destination its own authenticated packet OPEN, so identity grants and direct_udp destinations apply as they do to CONNECT. Backlogs follow the shared UDP policy of 64 datagrams and 1 MiB per budget, dropping the newest datagram when full. Destinations close after an idle timeout, refused ones wait a retry delay, and the association ends with its TCP connection. The route bridge drops an empty datagram from a destination instead of closing the flow, because a YTP packet cannot be empty, and drops one larger than the session’s packet bound the same way. The native endpoint test runs UDP ASSOCIATE over the production daemon composition with real UDP sockets. It checks traffic both ways, an empty datagram from the destination, refusal by configured destinations and by a missing identity grant, source locking, the unsupported reply without a UDP service, relay closure, and the 64-datagram budget while an OPEN is held. yume_native_runtime_test repeats the traffic, refusal and closure checks between the two processes, which start from the generated setup kit’s services and adapters. CMake installs these development programs together with the native schema-1 yume-setup and yume-doctor programs, which make and check kits with the same OpenSSL release and credential readers. The Debian 13 package and systemd integration covers disabled installation, provisioning and doctor, checked loopback TCP and module streams, permission/configuration refusals, credential reload, stop, crash restart and client reconnection. Package checks also cover same-version upgrades, removal and purge, and refusal to replace the patched OpenSSL dependency with stock. Production and real-network qualification remain separate.

An unrecoverable reconnect timer or SOCKS listener retry failure closes the client runtime and reports a typed terminal status. Both CLIs exit with failure after draining owned work. Explicit shutdown does not emit that failure, and ordinary connection failures still retry with backoff. After a runner exception, the CLI uses a reserved control task to close every runtime on its execution context, then drains accepted completions. The runner regression covers live accept/timer cancellation during sustained allocation failure and a second exception during drain.

The native Linux runtimes also compose named IP packet services through NativePacketAdapter, IpPacketChannel and LinuxTunNetwork. They own an ephemeral TUN, explicit addresses/routes and optional systemd-resolved per-link DNS. An exclusive session lease drains OS callbacks before reconnect; shutdown checks network cleanup. See the native guide for address policy, routing exclusions and qualification limits. The optional yume_native_resolved_test runs an actual systemd-resolved service and a private D-Bus inside unprivileged user, mount and network namespaces. It verifies per-link DNS servers, routing domains, default-route policy, DNS queries through the tunnel, reconnect and shutdown cleanup. The regular TUN test still exercises DNS-free configurations. Service deployment and managed TUN DNS have separate lifetime and privilege boundaries.

Remaining qualification and integration

These qualification and integration tasks remain open:

  • complete-session qualification of the native FrontDoor, including external comparison of ordinary and rejected-admission cover behavior;
  • production qualification of yume, yumed and the experimental schema-1 ABI backend;
  • extended real-carrier rekey, close-ordering and credit/backpressure qualification beyond the focused native-session regressions;
  • acceptance evidence for automatic directional root rotation and competing-stream scheduling, including stalled readers, cancellation and real-carrier pressure;
  • production qualification of module adapters and managed TUN;
  • circuits: held-out classifier comparisons of client sessions and node links, sustained cross-host loss and latency testing, upload window growth at the exit, UDP and IP carriage, and a consent interface in the C ABI;
  • complete installed-SDK qualification across the supported build/toolchain matrix;
  • distribution publication of the patched OpenSSL dependency and qualification of each exact candidate package, remaining consumer migration around native yume and yumed, and a qualified setup-to-first-SOCKS path over a real network;
  • a release-workflow run with the configured signing secret and existing release target. Local rejection tests cover trusted commit/tag verification, required signatures, manifest consistency and refusal of existing asset names, as operations describes;
  • complete-session active-probe, classifier, performance, soak, fuzz and sanitizer qualification.

Across-operator transit and decentralized discovery are later design work.

Existing integration coverage

Native CTest registration includes the schema-1 setup and doctor negative cases, a sweep of one allocation failure across key generation, init, secret copies and the doctor that checks every released buffer for an unwiped secret, project metadata and Linux release-archive checks. The Clang fuzz profile instruments the YTP frame/OPEN/capability codecs, AUTH TLVs and schema-1 parser, including their source libraries. Numeric overflow in JSON is a typed validation failure.

With Linux namespace tests enabled, YUME_TEST_NATIVE_STRESS=ON adds a delayed carrier workload with an unread destination, competing transfers, ordered recovery, half-close, stable carrier sockets and RSS/descriptor growth guards. Address-sanitized builds select the fixture’s --asan profile: a 16 MiB global quarantine and 64 KiB per-thread quarantine, with leak detection and fatal sanitizer errors enabled. This bounds deliberately retained freed storage without raising the 256 MiB RSS growth guard. Other sanitizer tests keep their existing options. This finite workload does not measure live queue ownership, prove a memory plateau or observe automatic rekeys.

The optional desktop GUI, yume-gui (YUME_BUILD_GUI=ON, Qt 6.4 or later), starts each kit’s yume detached, stops it with the control socket’s stop request and shows its status, printed lines, posture and route proposals. It imports sealed kits through yume --import-kit and accepts a shorter route only from a review of that exact proposal. yume_gui_test, yume_gui_ui_test, yume_gui_ui_rtl_test and yume_gui_live_test cover the lifecycle, keyboard access, right-to-left layout and a live connect, stop, reconnect and stop against a real daemon. Its tray icon shows the selected kit’s state. The GUI is not packaged, runs only on Linux, starts nothing at login and does not restart a crashed client. See the desktop GUI. CodeQL analyzes the native programs, libyume and the module libraries. Debian definitions use the native config-only daemon, validate configuration before startup and leave the service disabled after installation. Native release archives carry the native setup and doctor programs and enforce native executable identities; packaging regression checks do not qualify a distribution or an installed service.

The C ABI attaches the native runtime through its one backend and accepts only schema-1 documents. yume_endpoint_start starts a client or server, yume_endpoint_register_service, yume_endpoint_open_stream and yume_endpoint_accept_stream carry authenticated named byte streams, and yume_stream_read, write, shutdown_write and close move real bytes with typed transport failures. Native packet channels support named services and routed UDP with bounded whole-packet batches.

IpPacketChannel validates IPv4/IPv6 lengths, exact packet size, MTU and directional address policy before forwarding through the native route bridge. The Linux packet adapter puts it behind a managed TUN device, which owns addresses, routes and per-link DNS.

Security boundary

The YTP/1 design requires all of the following:

  • Ed25519 and ML-DSA-87 authentication;
  • X25519 and ML-KEM-1024 establishment;
  • a distinct per-identity random access PSK;
  • the live TLS 1.3 exporter and exact roles, identities, transcript, capabilities, suite, and fixed security parameters in the key schedule;
  • independent directional ratcheting, one-use AES-256-GCM keys for protected records, and a candidate-new-root authenticated rekey acknowledgement;
  • bounded work and allocation before attacker-controlled parsing, KEM, stream creation, queueing, or rekey preparation;
  • hard failure on a missing component, provider mismatch, role confusion, replay, malformed canonical encoding, or authentication failure.

The provider selected by the native application implements the cryptographic portions and has focused tests with real keys; dependency-pure engine tests cover the matching record and resource contracts. Native endpoint integration connects the live TLS exporter, carrier and session security. Published synthetic construction vectors check deterministic transcript, key schedule, record protection and rekey calculations against an independent generator. Independent-peer interoperability, broader qualification and an independent security review remain open. Review is planned alongside development and is not a release prerequisite. Ratchet recovery depends on fresh uncompromised contributions and erasure, as the threat model describes.

Ingress evidence boundary

The retained transport-profile capture pipeline and immutable Chrome/Node fixture are evidence inputs, not a claim of universal indistinguishability. Any release claim must name the exact profile, capture, candidate binary, environment, TLS/H2 semantic results, active-probe cover results, and held-out classifier result. ALPN, JA3/JA4, or a short successful navigation is insufficient.

Performance boundary

Throughput tuning has matched measurements of carrier buffering and event-loop scaling on loopback and emulated paths, including the preset measurements in the configuration reference. Those measurements do not establish real-path speed, latency, or fairness. A comparison must report its connection geometry: YUME multiplexes streams inside one session, while an unmultiplexed reference uses a connection per stream. A claim such as “faster” requires at least five matched runs with throughput, p50/p99 latency, CPU/byte, allocations, peak memory, and 1/32/256-stream fairness plus reported uncertainty.

Freeze gates

Before 0.3.0-rc1, the exact candidate must pass:

  • clean supported-platform builds and target/include layering checks;
  • YTP/1 vectors, mutation/component-stripping/replay/role/provider tests, and parser fuzzing;
  • ASan, UBSan, TSan, failure injection, flood/resource-pressure, and sustained soak qualification;
  • clean-prefix SDK installation and C/C++ stream and packet consumers through both CMake and pkg-config;
  • clean-machine setup, permissions, doctor, cover-browser, and first-stream smoke tests;
  • immutable ingress/profile evidence and reproducible performance evidence;
  • synchronized source, tests, help, manual pages, package metadata, website, declared-dependency/SBOM, and documentation drift checks.

Record each gate against the exact candidate, platform and environment. Use the implemented and tested descriptions above when reporting a narrower check.