summaryrefslogtreecommitdiffstats
path: root/news/cli-daemon-rpc/index.html
blob: a1ca0c1d5d45cff9a1e24349f4a145620672601c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>CLI Meets Network: Publish, Fetch, and Status Commands — Tesseras</title>
    <meta name="description" content="The tesseras CLI can now publish tesseras to the network, fetch them from peers, and monitor replication status — all through a new Unix socket RPC bridge to the daemon.">
    <!-- Open Graph -->
    <meta property="og:type" content="article">
    <meta property="og:title" content="CLI Meets Network: Publish, Fetch, and Status Commands">
    <meta property="og:description" content="The tesseras CLI can now publish tesseras to the network, fetch them from peers, and monitor replication status — all through a new Unix socket RPC bridge to the daemon.">
    <meta property="og:image" content="https://tesseras.net/images/social.jpg">
    <meta property="og:image:width" content="1200">
    <meta property="og:image:height" content="630">
    <meta property="og:site_name" content="Tesseras">
    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:title" content="CLI Meets Network: Publish, Fetch, and Status Commands">
    <meta name="twitter:description" content="The tesseras CLI can now publish tesseras to the network, fetch them from peers, and monitor replication status — all through a new Unix socket RPC bridge to the daemon.">
    <meta name="twitter:image" content="https://tesseras.net/images/social.jpg">
    <link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690">
    
        
            <link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml">
        
    
    <link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d">
    
</head>
<body>
    <header>
        <h1>
            <a href="https:&#x2F;&#x2F;tesseras.net/">
                <img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo">
                Tesseras
            </a>
        </h1>
        <nav>
            
                <a href="https://tesseras.net/about/">About</a>
                <a href="https://tesseras.net/news/">News</a>
                <a href="https://tesseras.net/releases/">Releases</a>
                <a href="https://tesseras.net/faq/">FAQ</a>
                <a href="https://tesseras.net/subscriptions/">Subscriptions</a>
                <a href="https://tesseras.net/contact/">Contact</a>
            
        </nav>
        <nav class="lang-switch">
            
                <strong>English</strong> | <a href="/pt-br&#x2F;news&#x2F;cli-daemon-rpc&#x2F;">Português</a>
            
        </nav>
    </header>

    <main>
        
<article>
    <h2>CLI Meets Network: Publish, Fetch, and Status Commands</h2>
    <p class="news-date">2026-02-15</p>
    <p>Until now the CLI operated in isolation: create a tessera, verify it, export it,
list what you have. Everything stayed on your machine. With this release, <code>tes</code>
gains three commands that bridge the gap between local storage and the P2P
network — <code>publish</code>, <code>fetch</code>, and <code>status</code> — by talking to a running <code>tesd</code> over
a Unix socket.</p>
<h2 id="what-was-built">What was built</h2>
<p><strong><code>tesseras-rpc</code> crate</strong> — A new shared crate that both the CLI and daemon
depend on. It defines the RPC protocol using MessagePack serialization with
length-prefixed framing (4-byte big-endian size header, 64 MiB max). Three
request types (<code>Publish</code>, <code>Fetch</code>, <code>Status</code>) and their corresponding responses.
A sync <code>DaemonClient</code> handles the Unix socket connection with configurable
timeouts. The protocol is deliberately simple — one request, one response,
connection closed — to keep the implementation auditable.</p>
<p><strong><code>tes publish &lt;hash&gt;</code></strong> — Publishes a tessera to the network. Accepts full
hashes or short prefixes (e.g., <code>tes publish a1b2</code>), which are resolved against
the local database. The daemon reads all tessera files from storage, packs them
into a single MessagePack buffer, and hands them to the replication engine.
Small tesseras (&lt; 4 MB) are replicated as a single fragment; larger ones go
through Reed-Solomon erasure coding. Output shows the short hash and fragment
count:</p>
<pre><code>Published tessera 9f2c4a1b (24 fragments created)
Distribution in progress — use `tes status 9f2c4a1b` to track.
</code></pre>
<p><strong><code>tes fetch &lt;hash&gt;</code></strong> — Retrieves a tessera from the network using its full
content hash. The daemon collects locally available fragments, reconstructs the
original data via erasure decoding if needed, unpacks the files, and stores them
in the content-addressable store. Returns the number of memories and total size
fetched.</p>
<p><strong><code>tes status &lt;hash&gt;</code></strong> — Displays the replication health of a tessera. The
output maps directly to the replication engine's internal health model:</p>
<table><thead><tr><th>State</th><th>Meaning</th></tr></thead><tbody>
<tr><td>Local</td><td>Not yet published — exists only on your machine</td></tr>
<tr><td>Publishing</td><td>Fragments being distributed, critical redundancy</td></tr>
<tr><td>Replicated</td><td>Distributed but below target redundancy</td></tr>
<tr><td>Healthy</td><td>Full redundancy achieved</td></tr>
</tbody></table>
<p><strong>Daemon RPC listener</strong> — The daemon now binds a Unix socket (default:
<code>$XDG_RUNTIME_DIR/tesseras/daemon.sock</code>) with proper directory permissions
(0700), stale socket cleanup, and graceful shutdown. Each connection is handled
in a Tokio task — the listener converts the async stream to sync I/O for the
framing layer, dispatches to the RPC handler, and writes the response back.</p>
<p><strong>Pack/unpack in <code>tesseras-core</code></strong> — A small module that serializes a list of
file entries (path + data) into a single MessagePack buffer and back. This is
the bridge between the tessera's directory structure and the replication
engine's opaque byte blobs.</p>
<h2 id="architecture-decisions">Architecture decisions</h2>
<ul>
<li><strong>Unix socket over TCP</strong>: RPC between CLI and daemon happens on the same
machine. Unix sockets are faster, don't need port allocation, and filesystem
permissions provide access control without TLS.</li>
<li><strong>MessagePack over JSON</strong>: the same wire format used everywhere else in
Tesseras. Compact, schema-less, and already a workspace dependency. A typical
publish request/response round-trip is under 200 bytes.</li>
<li><strong>Sync client, async daemon</strong>: the <code>DaemonClient</code> uses blocking I/O because
the CLI doesn't need concurrency — it sends one request and waits. The daemon
listener is async (Tokio) to handle multiple connections. The framing layer
works with any <code>Read</code>/<code>Write</code> impl, bridging both worlds.</li>
<li><strong>Hash prefix resolution on the client side</strong>: <code>publish</code> and <code>status</code> resolve
short prefixes locally before sending the full hash to the daemon. This keeps
the daemon stateless — it doesn't need access to the CLI's database.</li>
<li><strong>Default data directory alignment</strong>: the CLI default changed from
<code>~/.tesseras</code> to <code>~/.local/share/tesseras</code> (via <code>dirs::data_dir()</code>) to match
the daemon. A migration hint is printed when legacy data is detected.</li>
</ul>
<h2 id="what-comes-next">What comes next</h2>
<ul>
<li><strong>DHT peer count</strong>: the <code>status</code> command currently reports 0 peers — wiring
the actual peer count from the DHT is the next step</li>
<li><strong><code>tes show</code></strong>: display the contents of a tessera (memories, metadata) without
exporting</li>
<li><strong>Streaming fetch</strong>: for large tesseras, stream fragments as they arrive
rather than waiting for all of them</li>
</ul>

</article>

    </main>

    <footer>
        <p>&copy; 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
    </footer>
</body>
</html>