MESH ONLINE│CODENAME: Kickstart My Heart
v0.39

Move Artifacts

The bus is a coordination layer, not a file transfer. When work produces something large — a model checkpoint, a video frame, a directory tree — you move it as a content-addressed blob and put only a small reference on the bus.

Reference, don't embed

The event carries a BlobRef; the bytes travel separately, on demand, to whoever actually needs them. An event that carries the payload has turned a coordination message into a transfer, and every subscriber pays for it whether they wanted the bytes or not.

The address is the content

Blobs are addressed by their BLAKE3 hash. The address is the content, which has consequences worth stating rather than deriving:

  • There is no canonical home to provision. Blobs live on whichever nodes have capacity and drift toward the nodes that read them.
  • A reference is verifiable. Bytes that hash to the reference are the right bytes, from whichever peer served them.
  • Identical content is one blob. Storing the same bytes twice does not double the storage.

Three guarantees the transfer path makes

Peak memory is one chunk (~4 MiB), regardless of total size. A blob larger than RAM transfers fine; the transfer is streamed, not buffered.

A directory fetch is all-or-nothing. It either becomes the complete tree or leaves the destination untouched. There is no partially-materialized state to clean up.

A producer reading back its own write never sees a gap. The write path returns a token the read path waits on — read-your-own-writes, so the common write-then-immediately-read sequence is not a race.

Serving must be installed before fetching

A node cannot serve chunks, and in most bindings cannot issue fetches, until blob transfer has been installed on it with a storage adapter. This is one call and it is easy to omit, because omitting it produces a fetch that fails to find a holder rather than an error naming the missing install.

Bridged tools have no artifacts

Artifacts are a native capability. Tools brought in through the MCP bridge are mcp_bridge tier — request/response only, no artifacts. If the work needs to move bytes, it has to be a native capability, not a wrapped one. This is a tier boundary, not a limitation to route around.

Where the full surface lives

This page is the entry point per binding. The storage and gravity model, the adapter configuration, overflow behaviour and the operator CLI (net-mesh transfer send-blob / recv-blob / send-dir / recv-dir) are in Blob Storage (Dataforts) and the CLI Reference.

Move it — Python

The transfer verbs are methods on the node; the adapter and BlobRef types are in net_sdk.blob. (The same functions also exist module-level in net_sdk.transport, taking the native handle first.)

▸ python
from net import Redex
from net_sdk.blob import MeshBlobAdapter
 
adapter = MeshBlobAdapter(Redex(), "my-node")

The import can fail, and the message tells you why

▸ python
ImportError: Blob SDK symbols not present in `net._net`. Rebuild the wheel
with `--features dataforts`, e.g. `maturin develop --features dataforts`.

net_sdk.blob (and net_sdk.transport, with "Transport" in place of "Blob") re-export from net, and raise this at import time when the wheel was built without the dataforts feature. It is the clearest feature-gate message in any binding — treat it as instructions rather than a broken install.

Install, then fetch

▸ python
node.serve_blob_transfer(adapter)                 # once per node — fetchers too
 
data = node.fetch_blob(holder_id, blob_ref)       # from a known holder
data = node.fetch_blob_discovered(blob_ref)       # or let the mesh find one
 
manifest_ref = node.store_dir(adapter, "/tmp/src")
files, written = node.fetch_dir(source_id, manifest_ref, "/tmp/dest")

serve_blob_transfer installs the transfer engine, and a node needs it to fetch as well as to serve: without it a fetch raises "engine not installed".

These are synchronous calls that block the calling thread while the transfer runs on the substrate's runtime — they are not coroutines and there is no await. fetch_blob returns bytes; fetch_dir returns a plain (files_written, bytes_written) tuple rather than a stats object.

Reference, don't embed

▸ python
node.emit({"frame_id": "abc123", "blob": blob_ref})   # small event carries the ref

One shape discovery does not handle

fetch_blob_discovered supports BlobRef.Small and BlobRef.Manifest. A BlobRef.Tree raises — "BlobRef::Tree not supported by the transport bindings". Fetch a tree from a known holder with fetch_dir instead of discovering it.

Verify it worked

▸ python
data = node.fetch_blob_discovered(blob_ref)
assert len(data) > 0, "fetched nothing"
print(f"fetched: {len(data)} bytes")

Next: Errors and recovery.

§ parity · Dataforts — blobsfrom the capability record
Rust supportedNode / TS supportedPython supportedGo partialC supported