Syndicated Actors feed for tag "syndicate"2024-02-19T21:31:57+00:00https://syndicate-lang.org/journal/tag/syndicate/index.atomUsing Noise Protocol tunnels in Syndicate systems2024-01-20T12:09:58+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2024/01/20/noiseprotocol<p>The Syndicate ecosystem includes a few ways of gluing together dataspaces over a network.</p>
<p>To begin with, there was no authentication or authorization framework involved at all: programs
just exchanged assertions and messages using an ancestor of <a href="https://synit.org/book/protocol.html">the Syndicate
protocol</a> over a plain socket. There was no way of
referring to entities/objects/actors at all: Syndicate at this point was data-only. (It turns
out this is sufficient for a surprisingly large range of programs!)</p>
<p>Then, I figured out how to use ideas from
<a href="https://synit.org/book/glossary.html#macaroon">Macaroons</a> to introduce <a href="https://synit.org/book/protocol.html#capabilities-on-the-wire">capabilities on the
wire</a>. This allows recovery of
session-local object references from long-lived cryptographic names for use in a protocol
session. Programs “upgrade” a name like</p>
<pre><code class="language-preserves"><ref {oid: a-service, sig: #[JTTGQeYCgohMXW/2S2XH8g]}>
</code></pre>
<p>to a real pointer they can use to send assertions and messages to.</p>
<p>Finally, I incorporated the <a href="https://noiseprotocol.org/">Noise Protocol Framework</a>, making it
possible to use Syndicate to open encrypted, authenticated tunnels across untrusted links. The
idea is to use a cleartext socket or websocket (or anything else!) to bootstrap communication,
and then use <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-protocols/src/commit/97876335ba8d37575e17481be6bdc40a1bd4959d/schemas/noise.prs">assertions and messages related to
Noise</a>
to open a Noise session across that foundation.</p>
<h2 id="a-small-example">A small example</h2>
<p>Here’s a small example from a real system I’m running.</p>
<p>I run a <a href="https://hub.docker.com/r/leastfixedpoint/syndicate-server"><code class="language-plaintext highlighter-rouge">syndicate-server</code> Docker
container</a> configured with, among
other stanzas, the following service definition (these are fresh random keys, not the ones I’m
using live):</p>
<pre><code class="language-preserves">let ?shared = dataspace
let ?sk = #[0LFU4CAWxrz0VVS9nY2uSc7EWJTusZUcOP0HUpkwSkE]
let ?pk = #[Y3NCy2ZPbmaH62fFI0sl0YOZmM7K7PhVTmRFmgCAgVA]
@<connect-using # <-- this is just a comment, really
<route [<ws "ws://LOCATION.TO.MY.SERVER.WEBSOCKET/">]
<noise {service: a-service key: #[Y3NCy2ZPbmaH62fFI0sl0YOZmM7K7PhVTmRFmgCAgVA]}>>
>
<bind <noise { service: a-service, key: $pk, secretKey: $sk }> $shared #f>
</code></pre>
<p>Then I can securely access the <code class="language-plaintext highlighter-rouge">$shared</code> dataspace from a remote <code class="language-plaintext highlighter-rouge">syndicate-server</code> instance
using a stanza like this:</p>
<pre><code class="language-preserves">? <resolve-path
<route [<ws "ws://LOCATION.TO.MY.SERVER.WEBSOCKET/">]
<noise {service: a-service key: #[Y3NCy2ZPbmaH62fFI0sl0YOZmM7K7PhVTmRFmgCAgVA]}>>
_
_
<accepted ?sharedDs>>
<the-shared-dataspace-is $sharedDs>
</code></pre>
<p>A lightly tricky piece of the puzzle is that the
<a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-protocols/src/commit/97876335ba8d37575e17481be6bdc40a1bd4959d/schemas/gatekeeper.prs#L30"><code class="language-plaintext highlighter-rouge">resolve-path</code></a>
handler isn’t built-in to <code class="language-plaintext highlighter-rouge">syndicate-server</code> yet: for that part, I’m using a tiny node.js
service until I have a chance to implement the <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-js/src/commit/794837f40301223c6f76140cf734b7ec201d7f30/packages/ws-relay/src/index.ts#L126-L181">resolution
logic</a>
in Rust. Watch this space.</p>
In-browser JavaScript+Syndicate, round two2023-12-20T07:56:38+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2023/12/20/syndicate-browser-compiler-2<p>Since <a href="/journal/2023/12/01/syndicate-browser-compiler">last time</a>, I’ve managed to shrink
the boilerplate for experimenting with Syndicate in the browser a little further.</p>
<p>Save the following in an HTML file, and open it:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="rouge-code"><pre><span class="cp"><!DOCTYPE html></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@syndicate-lang/browser-stdenv"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"syndicate"</span><span class="nt">></span>
<span class="nx">spawn</span> <span class="nx">named</span> <span class="dl">'</span><span class="s1">clicker</span><span class="dl">'</span> <span class="p">{</span>
<span class="nx">field</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">b</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SyndicateHtml2</span><span class="p">.</span><span class="nx">Widget</span><span class="p">(</span><span class="nx">t</span> <span class="o">=></span> <span class="nx">t</span><span class="s2">`<button>clicks: </span><span class="p">${</span><span class="nx">counter</span><span class="p">.</span><span class="nx">value</span><span class="p">}</span><span class="s2"></button>`</span><span class="p">)</span>
<span class="p">.</span><span class="nx">setParent</span><span class="p">(</span><span class="dl">'</span><span class="s1">body</span><span class="dl">'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="nx">counter</span><span class="p">.</span><span class="nx">value</span><span class="o">++</span><span class="p">);</span>
<span class="p">}</span>
<span class="nt"></script></span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>You should be greeted with a click-counter button.</p>
<p>Here’s the same as a codepen:</p>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYaPjeJ" data-editable="true" data-user="leastfixedpoint" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
<span>See the Pen <a href="https://codepen.io/leastfixedpoint/pen/LYaPjeJ">
Untitled</a> by Tony Garnock-Jones (<a href="https://codepen.io/leastfixedpoint">@leastfixedpoint</a>)
on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async="" src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
In-browser compiler for JavaScript+Syndicate to plain JavaScript2023-12-01T14:27:44+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2023/12/01/syndicate-browser-compiler<p>To make experimenting with Syndicate/JS a bit easier, I’ve just dusted off an old idea: getting
the compiler from JavaScript with Syndicate DSL extensions down to plain JavaScript to run in
the browser.</p>
<p>It’s (relatively) simple. Load a few modules, perhaps via a CDN:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@preserves/core/dist/preserves.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@syndicate-lang/core/dist/syndicate.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@syndicate-lang/compiler/dist/syndicate-compiler.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@syndicate-lang/html/dist/syndicate-html.js"</span><span class="nt">></script></span>
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdn.jsdelivr.net/npm/@syndicate-lang/compiler/dist/syndicate-browser-compiler.js"</span><span class="nt">></script></span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>Then, add <code class="language-plaintext highlighter-rouge"><script type="syndicate"></code> tags with Syndicate/JS code in them:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="nt"><script </span><span class="na">type=</span><span class="s">"syndicate"</span><span class="nt">></span>
<span class="nx">spawn</span> <span class="p">{</span>
<span class="nx">assert</span> <span class="dl">"</span><span class="s2">Hello, world!</span><span class="dl">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt"></script></span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>The
<a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-js/src/branch/main/packages/compiler/syndicate-browser-compiler.js"><code class="language-plaintext highlighter-rouge">syndicate-browser-compiler.js</code></a>
script automatically translates such scripts into plain JavaScript:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="nt"><script></span>
<span class="kd">const</span> <span class="nx">__SYNDICATE__</span> <span class="o">=</span> <span class="nx">Syndicate</span><span class="p">;</span>
<span class="nx">__SYNDICATE__</span><span class="p">.</span><span class="nx">Turn</span><span class="p">.</span><span class="nx">active</span><span class="p">.</span><span class="nx">_spawn</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">__SYNDICATE__</span><span class="p">.</span><span class="nx">Turn</span><span class="p">.</span><span class="nx">active</span><span class="p">.</span><span class="nx">assertDataflow</span><span class="p">(()</span> <span class="o">=></span> <span class="p">({</span> <span class="na">target</span><span class="p">:</span> <span class="nx">currentSyndicateTarget</span><span class="p">,</span> <span class="na">assertion</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Hello, world!</span><span class="dl">"</span> <span class="p">}));</span>
<span class="p">});</span>
<span class="nt"></script></span>
</pre></td></tr></tbody></table></code></pre></div></div>
<p>Here’s a small (live!) example, <a href="https://codepen.io/leastfixedpoint/pen/PoVyxbE?editors=1000">hosted at codepen</a>:</p>
<p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="PoVyxbE" data-editable="true" data-user="leastfixedpoint" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
<span>See the Pen <a href="https://codepen.io/leastfixedpoint/pen/PoVyxbE">
Standalone Syndicate/JS page, December 2023</a> by Tony Garnock-Jones (<a href="https://codepen.io/leastfixedpoint">@leastfixedpoint</a>)
on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async="" src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<p>It’s still too hard to get started with Syndicate, but this is at least a step in the right
direction.</p>
<hr />
<p>(Just in case the codepen goes away, <a href="/simple-example-standalone-2023-12-01.html">here is the same example as a standalone webpage</a>.)</p>
syndicate-pty-driver: Interactive subprocesses over Syndicate2023-11-24T10:03:13+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2023/11/24/syndicate-pty-driver
<p>I’ve just released <a href="https://git.syndicate-lang.org/tonyg/syndicate-pty-driver">syndicate-pty-driver</a>, a small Rust program that responds to a
Syndicate <a href="https://git.syndicate-lang.org/tonyg/syndicate-pty-driver/src/commit/40ed59e06847cbfc5db48f4120558c270f421064/protocols/schemas/pty.prs">protocol</a> for allocating PTYs and spawning subprocesses attached to them.</p>
<p>This allows programs collaborating using Syndicate to run interactive subprocesses on the
machine that’s running the PTY driver.</p>
<p>As an example, I’m playing around with a “VR”-like environment for use in a browser on a
cellphone with a Cardboard headset and a bluetooth keyboard, loosely based on an idea by <a href="https://stanford.edu/class/ee267/Spring2019/report_dean_creuscosta.pdf">John
Dean and Joan Creus-Costa</a> (<a href="https://stanford.edu/class/ee267/Spring2019/report_dean_creuscosta.pdf">“BonelessVR: A lightweight, high-productivity
desktop environment for Google Cardboard”</a>):</p>
<p><img src="/img/boneless-vr-syndicate-20231124.png" alt="Screenshot of my little VR project running on my phone" /></p>
<p>The phone runs Syndicate/js in the browser, speaks <a href="https://synit.org/book/protocol.html">the Syndicate
protocol</a> across a websocket, and a <code class="language-plaintext highlighter-rouge">syndicate-server</code>
instance at the other end supervises a <code class="language-plaintext highlighter-rouge">syndicate-pty-driver</code>. The whole thing is secured by
Syndicate’s object capabilities and <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-protocols/src/branch/main/schemas/noise.prs">its use of the Noise
protocol</a>
for secure transport.</p>
TypeScript IDE Syndicate plugin: good news and bad news2023-04-29T08:34:51+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2023/04/29/syndicate-ts-plugin<p>Because the TypeScript implementation has been moving on along its own roadmap, the IDE-support
(Language Server Protocol, LSP) part of the <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-js/src/branch/main/packages/ts-plugin">TypeScript compiler plugin</a> that I
wrote (<a href="https://www.npmjs.com/package/@syndicate-lang/ts-plugin">npm</a>, <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-js/src/branch/main/packages/ts-plugin">git</a>) has stopped working properly with recent
TypeScript releases.</p>
<p><code class="language-plaintext highlighter-rouge">ts-plugin</code> versions older than 0.15.2 don’t work well with TypeScript 4.9; it’s possible they
haven’t worked well since TypeScript 4.5.</p>
<h2 id="the-good-news">The good news</h2>
<p>The good news is that <a href="https://www.npmjs.com/package/@syndicate-lang/ts-plugin"><code class="language-plaintext highlighter-rouge">@syndicate-lang/ts-plugin</code></a> version 0.15.2 includes a
few changes that make it work much better with TypeScript 4.9. So if you update to 0.15.2, you
should see good support for the Syndicate DSL overlaid atop the normal TypeScript support in
Emacs, VSCode, etc.</p>
<h2 id="the-bad-news">The bad news</h2>
<p>The bad news is that the monkeypatching I’ve been doing to hook into the necessary parts of the
TypeScript <code class="language-plaintext highlighter-rouge">tsserver</code> will no longer work for TypeScript versions 5.0 and higher. The problem
is that, in <code class="language-plaintext highlighter-rouge">tsserver</code> 4.9, simple properties were used for values like <code class="language-plaintext highlighter-rouge">ts.createSourceFile</code>
and <code class="language-plaintext highlighter-rouge">ts.server.ScriptInfo</code>, so the <code class="language-plaintext highlighter-rouge">ts-plugin</code> was able to hook them to insert the Syndicate
DSL expansion process. In 5.0, by contrast,
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code class="language-plaintext highlighter-rouge">Object.defineProperty</code></a>
is used to define a non-writable, non-configurable property. It’s essentially game over for the
existing <code class="language-plaintext highlighter-rouge">ts-plugin</code> approach at this point.</p>
<h2 id="so-what-now">So what now?</h2>
<p>Having <code class="language-plaintext highlighter-rouge">ts-plugin</code> IDE support is <em>really nice</em> for Syndicate programming. So I feel compelled
to find <em>some</em> kind of solution.</p>
<p>Perhaps I need to write a real LSP implementation, backing into a captive <code class="language-plaintext highlighter-rouge">tsserver</code> instance?</p>
<p>I’ve <a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-js/issues/2">opened an issue on the <code class="language-plaintext highlighter-rouge">ts-plugin</code> repository about this</a>.</p>
Questions from IRC2023-03-27T19:43:03+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2023/03/27/questions-from-irc<p>A few days ago, on the <a href="/community/">#syndicate IRC channel</a>, user
<code class="language-plaintext highlighter-rouge">observeSynd</code> (maybe <code class="language-plaintext highlighter-rouge">observeSyndicate</code>?) asked a few good questions:</p>
<ol>
<li>Can I take <a href="https://syndicate-lang.org/tonyg-dissertation/html/#CHAP:COMPUTATIONAL-MODEL-II:SYNDICATE">‘endpoints’ as discussed in the dissertation</a> to be the same thing as <a href="https://synit.org/book/syndicated-actor-model.html#actors-entities-assertions-and-messages">‘entities’ as outlined in the Synit SAM (chapter 18) theory section</a>?</li>
<li>Are there any examples in any of the implemetations showcasing how (nested) facets work?</li>
<li>Have any of the implementations documented their DSL as would be found at <a href="https://syndicate-lang.org/doc/syndicate/">https://syndicate-lang.org/doc/syndicate/</a> ?</li>
</ol>
<p>Here are my (short) answers:</p>
<ol>
<li>
<p>Endpoints aren’t quite entities, but they’re related. Entities are a later development.
They’re much closer to traditional actor references or, even closer still, to E-style object
references. Endpoints are a kind of intermediate concept: they’re a combination of a
pattern, a subscription, and an object reference. I think the entity-based approach is
cleaner, and in hindsight, they were not well described in my dissertation. Perhaps this was
a clue that there was something simpler lurking underneath, waiting to be discovered and
described.</p>
</li>
<li>
<p>Nested facets: yes, throughout the available examples. However, nesting of facets isn’t
<em>lexically</em> apparent, so you have to read the program while imagining the dynamics.</p>
</li>
<li>
<p>Sadly, there’s no documentation of the DSLs yet. I’m embarrassed about this. Hopefully I’ll
find time to rectify the situation soon! I’m afraid the various example programs are the
only references out there right now.</p>
</li>
</ol>
Synit and SqueakPhone demo video2022-10-29T11:00:00+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2022/10/29/squeak-phone-demo<p>I’ve just finished a demo of the SqueakPhone and Synit running on real phones. You can see it
<a href="https://www.youtube.com/watch?v=aEfssFQ1X1M">on youtube</a>, or watch it embedded directly below
<a href="/img/squeakphone-demo-20221029.mp4">from an mp4 file hosted on this webserver</a>:</p>
<video controls="" style="width: 100%; margin-top: 2rem; border: solid black 1px;">
<source type="video/mp4" src="/img/squeakphone-demo-20221029.mp4" />
</video>
State of the SqueakPhone2022-06-03T20:01:56+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2022/06/03/phone-progress<style>
.story.p-2022-06-03-phone-progress .captioned {
display: table;
margin-bottom: 1rem;
}
.story.p-2022-06-03-phone-progress .captioned > small {
display: table-caption;
caption-side: bottom;
}
.story.p-2022-06-03-phone-progress .picturerow {
clear: both;
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 0;
padding: 0;
flex-wrap: wrap;
}
.story.p-2022-06-03-phone-progress .picturerow > li {
display: block;
margin: 0;
padding: 0;
}
</style>
<p>One of my projects over the past couple of years has been <a href="https://synit.org">Synit</a>, a
<em>Syn</em>dicate <em>init</em> (really, <code class="language-plaintext highlighter-rouge">systemd</code> and <code class="language-plaintext highlighter-rouge">D-Bus</code>) replacement. Synit underpins another
project, <em>#squeak-phone</em>, a sketch of an alternative to Android for personal computing on a
mobile device.</p>
<p>These are one-person projects at present, and the current round of development is coming to a
close. This is a summary of where things stand.</p>
<blockquote class="margin-note">
<p><strong>Goals.</strong> Aim for a hackable, tweakable, pocket-sized Smalltalk system that’s also a phone.
Also, see what happens if we replace <code class="language-plaintext highlighter-rouge">systemd</code>, <code class="language-plaintext highlighter-rouge">D-Bus</code> etc with Syndicate-style
alternatives.</p>
<p><strong>Outcomes.</strong> It runs! Smalltalk on a phone. Weird but fun alternative universe, not Android,
not systemd. You can make calls, send/receive SMS, use cellular data, WIFI, look at maps,
etc. No browser yet.</p>
</blockquote>
<p> </p>
<p><span class="leftfloat captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195230949.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195230949.jpg" alt="" /></a><small>Synit on PostmarketOS boot splash screen.</small></span></p>
<p><a href="https://synit.org">Synit</a> is my experimental alternative “system layer” for Linux. I chose to
use my <em>#squeak-phone</em> project as the initial vehicle for exploring the idea.</p>
<p>Squeak-phone uses the <a href="https://synit.org/book/syndicated-actor-model.html">Syndicated Actor
Model</a> in conjunction with <a href="https://squeak.org/">Squeak
Smalltalk</a> and a few other bits of software to have a foundation for
exploring an alternative universe of mobile personal computing.</p>
<h2 class="noclear" id="links">Links</h2>
<p>I’ve written a few posts about it both <a href="/journal/tag/squeak-phone/">on this site</a> and <a href="https://eighty-twenty.org/tag/squeak-phone/">on
eighty-twenty.org</a>). <a href="/projects/2021/system-layer/">This page</a> outlines the portion of the project that was funded by
<a href="https://nlnet.nl/">NLNet</a>’s <a href="https://nlnet.nl/NGI0/">NGI Zero</a>. (Thanks, NLNet!) The Synit
project has <a href="https://synit.org/">a homepage at synit.org</a> now, with links to
<a href="https://synit.org/book/">documentation</a> and <a href="https://git.syndicate-lang.org/synit/">code</a>.
Common Syndicate parts of the project of course remain here at
<a href="https://syndicate-lang.org/">syndicate-lang.org</a> and in the <a href="https://git.syndicate-lang.org/syndicate-lang/">Syndicate git
repositories</a>.</p>
<h2 id="booting-linux-into-a-syndicated-world">Booting Linux into a Syndicated world</h2>
<p>The prototype Synit system is based on <a href="https://postmarketos.org/">postmarketOS</a>, which is an
<a href="https://www.alpinelinux.org/">Alpine Linux</a> distribution for cellphones. Synit adds a few
custom Alpine packages, <a href="https://git.syndicate-lang.org/synit/synit/src/branch/main/packaging/packages/synit-config">one of
which</a>
does unspeakable things to the normal postmarketOS packages to outright replace <code class="language-plaintext highlighter-rouge">/sbin/init</code>
with a Syndicate replacement.</p>
<p>The first thing the Syndicated <a href="https://git.syndicate-lang.org/synit/synit/src/branch/main/synit-pid1/src/main.rs">PID
1</a> does is
start a <a href="https://synit.org/book/operation/system-bus.html">syndicate-server</a> instance as the
root <em>system bus</em>, which then uses Erlang-style supervision patterns to spawn the rest of the
system.</p>
<h2 id="smalltalk-as-the-phone-ui">Smalltalk as the phone UI</h2>
<p><span class="rightfloat captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195314653.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195314653.jpg" alt="" /></a><small>After booting, the most-recently-saved Smalltalk image comes back to life.</small></span></p>
<p>One of the actors started by the system bus is a Squeak Smalltalk image. The photo here shows
the Smalltalk image just after the phone completes booting: it has a Smalltalk workspace
visible, containing useful snippets of Smalltalk code for interacting with the phone that I can
execute with the tap of a (couple of) finger(s).</p>
<p>It’s a regular Smalltalk image, so I can make changes to the code, save snapshots, and so on.
When I reboot the phone, the most recent image snapshot is loaded.</p>
<h2 class="noclear" id="lots-of-languages-working-together">Lots of languages working together</h2>
<p>Both PID 1 and syndicate-server are written in Rust, but system actors can be written in any
language that speaks the <a href="https://synit.org/book/protocol.html">Syndicate protocol</a>; this
currently means TypeScript/JavaScript, Bash (!), Smalltalk, Python, Nim, Rust, and Racket.</p>
<h2 class="noclear" id="reactivity">Reactivity</h2>
<p>The system is <em>reactive</em>. It self-organises around the information placed in the system
dataspace. <a href="https://synit.org/book/guide/preserves.html">Schemas</a> are used to strongly
(dynamically) type the system.
<a href="https://synit.org/book/syndicated-actor-model.html#object-capabilities-for-access-control">Object-capabilities</a>
are used to secure the system. Various system actors react to changes in the machine’s
environment, such as (dis)appearance of WIFI SSIDs, hotplugging of devices, and so on.</p>
<p>For example, placing a <a href="https://preserves.dev/preserves.html#records">record</a>
<code class="language-plaintext highlighter-rouge"><configure-interface "lo" <static "127.0.0.1/8">></code> into the dataspace triggers an actor that
uses the <code class="language-plaintext highlighter-rouge">ip</code> command-line tool to set up the interface. Removing the record causes the same
actor to use <code class="language-plaintext highlighter-rouge">ip</code> again to tear the interface down. Likewise, addition of <code class="language-plaintext highlighter-rouge"><configure-interface
"eth0" <dhcp>></code> causes startup of a DHCP client daemon; subsequent removal terminates the
daemon and removes the interface.</p>
<h2 id="squeak-phone-applications">Squeak-phone Applications</h2>
<p>One of the schemas,
<a href="https://git.syndicate-lang.org/synit/synit/src/branch/main/protocols/schemas/ui.prs">ui.prs</a>,
describes a Syndicate protocol for user interfaces. It’s a very rough sketch at the moment, and
woefully underdocumented - but here are a few “applications” written using it:</p>
<ul class="picturerow">
<li><span class="captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195339403.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195339403.jpg" alt="" /></a><small>The dialer screen.</small></span></li>
<li><span class="captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195354186.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195354186.jpg" alt="" /></a><small>The SMS composition window.</small></span></li>
<li><span class="captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195408879.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195408879.jpg" alt="" /></a><small>The brightness control.</small></span></li>
<li><span class="captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195428842.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195428842.jpg" alt="" /></a><small>The battery and power display.</small></span></li>
</ul>
<p>Each application is a Syndicate actor running either inside the Smalltalk image or as a
neighbouring process on the system, interacting with a Smalltalk UI daemon that speaks the
protocol defined in ui.prs.</p>
<p>The UI-presenting actors are separate from the actors that manage the underlying information,
such as the brightness status and control, or the details of the system’s current power status.</p>
<p>The on-screen keyboard is <a href="https://eighty-twenty.org/2021/04/20/on-screen-keyboard-morph">a simple Smalltalk
program</a>. The red, blue, and
yellow rectangles beneath the keyboard are shift-like keys used to change the interpretation of
a finger tap: they correspond to left, middle, and right-clicks, respectively.</p>
<p><span class="leftfloat captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195511261.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195511261.jpg" alt="" /></a><small>A tiled-map (“slippy map”) widget.</small></span>
<span class="rightfloat captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195528917.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195528917.jpg" alt="" /></a><small>The placeholder “apps” menu, including both SqueakPhone and ordinary Squeak “applications”.</small></span>
<span class="rightfloat captioned"><a href="/img/2022-06-03-phone-progress/edited/PXL_20220603_195553756.jpg"><img src="/img/2022-06-03-phone-progress/scaled/PXL_20220603_195553756.jpg" alt="" /></a><small>The ordinary Squeak preference browser.</small></span></p>
<p>A little Smalltalk program wraps a
<a href="https://eighty-twenty.org/2018/02/11/squeak-tiledmaps">TiledMapMorph</a> I wrote a few years ago
to provide a “map” application, backed by <a href="https://www.openstreetmap.org/">OpenStreetMap</a> by
default.</p>
<p>The system enables cellular data by default, so the maps can be used when you’re out and about.
You can configure WIFI SSID/password information, too, but you have to do it using a text
editor at the moment. There’s only one of me!</p>
<p>Finally, it’s still very much a regular Smalltalk system, with only the lightest of
customisation for handheld use. All the normal Squeak “applications” are available, such as
version control, code editing, font management, preference settings etc.</p>
<h2 id="lessons-learned">Lessons learned</h2>
<p>I think the experiment so far has been a success.</p>
<p>The big reusable pieces, likely to find application in other projects besides the continuation
of this one, are <a href="https://preserves.dev/">Preserves</a>, <a href="https://preserves.dev/preserves-schema.html">Preserves
Schema</a>, the <a href="https://synit.org/book/syndicated-actor-model.html">Syndicated Actor
Model</a> itself, and the
<a href="https://git.syndicate-lang.org/syndicate-lang/syndicate-rs/">syndicate-server</a> program.</p>
<p>The idea of synit—using Syndicate as a system layer, replacing <code class="language-plaintext highlighter-rouge">D-Bus</code>, <code class="language-plaintext highlighter-rouge">systemd</code> and so on—has
worked out really well, and I want to try it out for desktop and server systems, too.</p>
<p>Smalltalk-on-a-phone is also really promising, and it’s super fun to be able to hack about with
the phone without needing a separate desktop/laptop system to develop on. However, careful
design of both the user interfaces as well as the underlying system protocols will be crucial
to actually make a usable and securable system. The system-layer stuff is simple in comparison.</p>
<p>Lots remains to be done. I’m looking forward to it!</p>
SqueakPhone code available2022-03-09T16:07:48+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2022/03/09/squeak-phone<p>Last post for today! Now that the <a href="/journal/2022/03/09/syndicate-network-protocol">protocol specification</a>, the <a href="https://synit.org/">Synit
website</a>, the <a href="https://synit.org/book/">Synit manual</a>, and the <a href="/journal/2022/03/09/synit">Synit
codebase</a> are all published and live, the final
piece of the puzzle is the SqueakPhone codebase.</p>
<h2 id="getting-the-code">Getting the code</h2>
<p>It comes in two parts:</p>
<ul>
<li>a git-based piece, at <a href="https://git.syndicate-lang.org/tonyg/squeak-phone">https://git.syndicate-lang.org/tonyg/squeak-phone</a>, and</li>
<li>a <a href="https://wiki.squeak.org/squeak/1287">Monticello</a>-based piece, at
<a href="https://squeaksource.com/SqueakPhone.html">https://squeaksource.com/SqueakPhone.html</a>.</li>
</ul>
<p>Follow the instructions in the
<a href="https://git.syndicate-lang.org/tonyg/squeak-phone/src/branch/main/README.md">README</a> to give
it a try.</p>
<p>It’s quite likely the instructions are not detailed enough, or that I’ve accidentally left the
code in a “works on my machine but only on my machine” state, so if you try it out and it
doesn’t work, or you have questions, please <a href="/community/">stop by on IRC</a> or
just <a href="mailto:tonyg@leastfixedpoint.com">email me</a> directly.</p>
Synit: a Reactive Operating System2022-03-09T12:11:41+00:00Tony Garnock-Joneshttps://syndicate-lang.org/journal/2022/03/09/synit<p>I’m really pleased to announce the first public release of <a href="https://synit.org/">Synit</a>. From the site:</p>
<blockquote>
<p>Synit is an experiment in applying <strong>pervasive reactivity</strong> and <strong>object capabilities</strong> to
the <a href="https://synit.org/book/glossary.html#system-layer">System Layer</a> of an operating system for
personal computers, including laptops, desktops, and mobile phones. Its
<a href="https://synit.org/book/architecture.html">architecture</a> follows the principles of the
<a href="https://synit.org/book/glossary.html#syndicated-actor-model">Syndicated Actor Model</a>.</p>
</blockquote>
<p>Synit is the foundation of the <a href="/projects/2021/system-layer/">squeak-on-a-cellphone system-layer experiment</a> I’ve been working on for the past year or so.</p>
<p>To go along with the software, there’s a draft <a href="https://synit.org/book/">manual</a>, including</p>
<ul>
<li>
<p>an <a href="https://synit.org/book/syndicated-actor-model.html">essay giving a good overview of the Syndicated Actor Model</a>;</p>
</li>
<li>
<p>a <a href="https://synit.org/book/glossary.html">Syndicated Actor Model glossary</a>;</p>
</li>
<li>
<p>a quick description of the <a href="https://synit.org/book/architecture.html">architecture</a> of the system;</p>
</li>
<li>
<p>the <a href="https://synit.org/book/protocol.html">protocol specification</a> that I <a href="/journal/2022/03/09/syndicate-network-protocol">just announced</a>;</p>
</li>
<li>
<p>and more.</p>
</li>
</ul>
<p><a href="/community/">Come hang out on IRC!</a> Or, just <a href="mailto:tonyg@leastfixedpoint.com">email
me</a> directly.</p>