worm-blossom

worm-blossom

The endeavours of Aljoscha Meyer and Sammy Gwilym.

2026Week 1510 Apr

“pininit”

A four panel comic.
        
In the first panel, Aljoscha shields his eyes with his hand and asks: "ugh... where am I?"

In the second panel, we see many screens displaying silhouetted figures. One of them says "Aljoscha! You have been brought before the super secret p2p shadow council so that you may join our ranks..."

In the third panel, Aljoscha says: "I accept your invitation. I look forward to making many theoretical contributions to th-"

In the fourth panel, one of the silhouetted councilmembers interjects: "Woah! Hold on! We just want someone to write our grant proposals". Another council member adds: "that shit is tedious". Aljoscha says oh.
A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

At the workshop in Prague, a surprising number of people had been on Secure Scuttlebutt (SSB) at some point, and SSB also kept popping up as a reference point in conversations. And a few days ago, someone on our Discord was asking about the relation between Willow and SSB. So I'd like to reflect a bit on how SSB still influences my design work.

I still subscribe to several of the mantras of SSB. The most important ones:

  • No global singletons: if a system depends on any kind of global singleton — be it a server, a network, a legal entity, or a blockchain — it is brittle and can will be co-opted.
  • Against consensus: those parts of a system that depend on global consensus between all participants will be unable to evolve as needs change. My personal take on this mantra is more nuanced than its classic formulation: I believe that there is value in a minimal foundation that is guaranteed to remain unchanging. Eventually it will have to be replaced because of its inability to adapt. But until that point, it will provide a stable foundation, superior to a continuously moving target that accrues complexity over time. As long as such foundations are clearly labeled and allowed to retire eventually, things are great. But: these foundations should be minimal. And everywhere where evolution is desirable, there should be no need for global consensus.
  • Free listening: free speech has to be counterbalanced by the ability not to listen. Listening should be opt-in, not opt-out.

Many other aspects of SSB have not aged well. I've detailed my views on immutability-by-default elsewhere. Another pattern I would not want to see repeated on top of Willow is the public follow-graph of SSB: everyone publicly recording whose data they want to follow. While this enables a nice replication mechanism with the ability to transitively fetch data for improved reliability and discovery, the public nature of this graph also enables spidering and surveillance. This tradeoff feels inacceptable to me by now.

More generally speaking, SSB was emphasising discoverability and interlinked data, in order to optimise for network effects and virality. The public follow graph, immutability, a single multi-purpose log per user... many SSB design decisions are in support of fostering network effects. But these are also the design decisions that make the protocol unsuitable for vulnerable users.

The tradeoff certainly payed off, chances are SSB would not have reached its level of adoption without these deliberate design choices. Perhaps projects such as Willow are fated to being crowded out by projects that emphasise virality over privacy. At least as long as the majority of tech users are not vulnerable users themselves. This feels sobering, but it cannot change the kind of technology we are building — because we desperately need this tech to be available and reliable.

So while the average techie is safe and confortable, I guess we'll simply have to rattle a tin can every once in a while.

~Aljoscha

Shout-outs!

Aescsocket opened not one, not two, but three pull requests to willow-rs this week. We now have a typesafe EntryBuilder, can derive the Display and Error traits, and will soon have some convenient tooling for running a whole bunch of cargo commands in one go. I don't quite know whether they are a polygonal dog or a markov chain, but in either case, thank you!

This Danmw person keeps contributing to Ufotofu. And here I thought making them a maintainer would pacify them. Now we have nicer skip adaptors, and new filter adaptors. Yay!

Here's a clean version of the lightning talk I gave at the Dweb virtual meetup the week before last. ~sammy

Why is it called worm-blossom?!

← Previous instalment

why is this website called ‘worm-blossom’? In this series we will explain why in a concise manner.

Let's talk about sets, baby

It is late 2019. Aljoscha Meyer has a scheduled call with someone who reached out from Secure Scuttlebutt. gwyl? Something like that. They want to learn about ‘Bamboo’, a kind of append-only log Aljoscha had designed some time ago. They’re clearly keen to build something with it, but Aljoscha gives it to them straight: append-only logs aren’t really good because you can’t use the same identity across multiple devices. Okay then. Predictably, the call doesn’t really go anywhere, and the two of them shall not interact for a long while.

When Sammy ends the call, she can’t help but feel like she still doesn’t have any idea how this peer-to-peer stuff works. And didn’t that Aljoscha guy seem a bit… disillusioned?

But Aljoscha is not going to let a little thing like disillusionment get in the way of what he’s really interested in: abstract nonsense! With regular expressions, choice and concatenation are dual. Doesn’t this suggest that unordered sets are dual to logs? And whereas you cannot easily combine two logs into a new log, two sets certainly combine into a new set. If only there was an efficient algorithm for computing set unions across two devices (i.e., to efficiently sync), then you could easily achieve composable multi-device identities.

A few months later, Aljoscha presents his set union algorithm at p2p-basel. Originally his session had an hour allotted to it, but discussion runs over to two hours. There’s clearly a deep interest in the notion of sets, but no implementations come of it yet. And Aljoscha is certainly not going to write any code himself.

Months later still, Aljoscha is browsing Secure Scuttlebutt, and on a whim joins a kind of virtual hangout which another user named Cinnamon has organised. Aljoscha joins the call, and listens in on a showcasing of… React components? But it turns out Cinnamon also has an interest in sets, and soon Aljoscha and Cinnamon are the only ones left in the call. Cinnamon is working on something called Earthstar, and has yet to figure out how to efficiently synchronise their mutable, unlinked datasets.

Cinnamon also tells Aljoscha about their terminal diagnosis. Cancer. Aljoscha doesn’t really know how to respond to that, but the call leaves a deep impression on him. When he selects the topic for his masters thesis in early 2021, Aljoscha decides to flesh out his set union algorithm, as a present to Cinnamon.

Meanwhile, Cinnamon has been figuring out what to do with an enthusiastic new contributor to their project.

A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

A prominent topic of last week’s gathering in Prague were sneakernets. There is something about this method of transporting data — the ultimate fallback mode of peer-to-peer transport — that seems to capture people’s imaginations. Embodied control of where data is, and tacit recognition of whose hands it is in, understandable to anyone.

On the first day I found my own understanding (and implementation!) of sneakernets being interrogated. What is Willow’s view of the sneakernet? Oh, so a user needs to choose what is in this ‘drop’? How do user's express what they want from others? They can’t? I see.

By the next morning, my view of sneakernets was dismantled (alongside a few others) to construct a new view, one where sneakernets take on an almost homeostatic nature. In this model of the sneakernet, data is not only pushed into the world, but the need for certain data is also expressed. The overlap between these two forces creates a hot zone of data worth transporting.

Reeling a little from this model, I started wondering if there was a way to make it so that users could query a Willow drop, shifting its design from linear access to a random access (thus neatly nerd-sniping Aljoscha, who mentioned this idea first thing last week).

Then Aljoscha announced at breakfast that sneakernets were really about congestion control. As I understood it (while trying to carefully eat from a bowl I’d filled with entirely too much yoghurt and fruit), if you have a USB drive filled with data from many people, at some point you’re going to hit storage constraints and have to choose what’s worth sending. This is analogous to throttling, and is effectively congestion control.

But here’s the tricky (Aljoscha: fun) part: sneakernets are non-interactive, so you have the problem of congestion control without explicit feedback. But perhaps you could use implicit feedback of tracking which data you receive from other people, and use that to prioritise what to send yourself?

A day after the event ended, we received this message:

We are the Memory Commons, just that nobody told us about this when we met in Prague. It is memory that we care about. Some call it replicas, other fancy about USB sticks. When discussing Sneakernets, Aljoscha suggested that this is a discussion on congestion control, which now makes even more sense as congestion control is about memory of the router packet queues, managed by a social contract that can't be technically enforced. Memory commons all over the place.

When we take this view, we must be mindful of the distinction between a commons and a hoard. We spent the last thirty years building the memory hoard. This hoard’s purpose went far beyond archival, and into the wholesale weaponisation of data. While the constraints of peer-to-peer certainly encourage us to prune and forget data, we should still steward the memory commons mindful of the fact that the value of data is in how it affects us, and nothing more.

~sammy

2026Week 1403 Apr

“you say beep, we say boop”

An illustration of many overlaid images, vignettes from Sammy and Aljoscha's busy week in Prague.
A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

I went to a workshop, and I was not immediately struck down by illness. Yay! I am completely exhausted as I am writing this on the train back: the workshop was well-facilitated and the participants were great, so I ended up overexerting myself quite a bit. I do want to share some notes I took during a fun session of discussing the limits of CRDTs.

Also, I may have gotten nerd-sniped into sketching an alternate version of the Willow Drop Format (with the creative working title “Super Drop Format”) that supports efficient seeking within encoded drops: a super drop file would store a three-dimensional search tree, so you would be able to obtain all entries in a given area in time logarithmic in the total number of entries in the whole drop, or linear in the number of entries in the area (whichever is worse). But I'll be pragmatic and give this format extremely low priority. Probably.

~Aljoscha

A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

Like Aljoscha, I am completely spent after a very good week. It has been 24 hours since I got back home and I think I could still do with another big sleep. Was this because of all of the thought-provoking discussions we had, or the inevitable fallout of ingesting more sugar in four days than I have in the last two months? Who can say.

A cartoon frog wanders in a quasi-realistic airport.
Life be like that sometimes.

For that reason, I am going to shower you in drawings today, and go in depth in the coming weeks. I have so much material on sneakernets, designing new kinds of UIs for p2p systems, and thoughts on collaboration in our little niche space that we're good until May probably.

But, if the other attendees — or especially the organisers — of the event are reading this: thank you so much for a wonderful week.

~sammy

2026Week 1327 Mar

“it is working — in reverse”

A single panel comic, in the style of Stan Kelly of The Onion.
        
  The Statue of Liberty and a girl with long hair, wearing a t-shirt labelled "Honest Coders", weep at a laptop in front of them. Behind them, someone who looks a lot like Aljoscha peers in through the window, wearing a t-shirt saying "ufotofu sickos". He say "Yes...hahah...sey!".
  
  In the corner, Sammy comments: "Open source *pain*tainer.
A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

This week I did some admin things, and took care of some teaching obligations (as fun as worm-blossom is, I still have this actual job of mine). So not much to report on my side.

I did open some issues in the Bab repository, ranging from the pretty specific and contributor-friendly over more vague problems to the document-now-and-then-forget-about-it-for-a-long-while. Just writing a whole bunch of stuff down so I can focus on other things. Foremost among those other things being a test setup for our persistent store implementation.

With the workshop in Prague and then the Easter holidays, progress might be a bit slow over the next weeks. But we’ll see how it goes.

Finally, I thought a bit about what a stateless protocol for exchanging data between mutually untrusting peers could look like (the WTP is stateless and assumes a trusted peer, Willow Confidential Sync is stateful and does not assume a trusted peer; these thoughts were about exploring a different quadrant). And there seem to be some inherent limitations: our techniques for working with untrusted peers (while still keeping data safe from active eavesdroppers) rely on establishing a shared context between the two peers and later referencing that shared context. This is an inherently stateful business, so these techniques will not translate to a stateless protocol. Even when weakening “stateless” to “stateful client but stateless server”, I’m at a loss how to achieve this. My intuition is that this might actually be impossible. But that’s a problem for future Aljoscha, like so many other problems these days.

~Aljoscha

A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

Last Saturday I was sitting on the sidelines of my kid’s kendo lesson, listening to the soothing sounds of screaming children hitting each other with sticks. Just a few months before, I’d been sitting here fretting about my then-upcoming FOSDEM talk, when suddenly the whole concept for the talk came spilling out. And as luck would have it, the same thing happened again this week, just as I was preparing a lightning talk for Dweb’s virtual meetup on “The Latest in P2P and Mesh Technologies”.

The final storyline: how data first came to be grouped together; how unscrupulous people figured out how to capitalise upon these groupings; how nearly all collections of data are now modelled on this extractive design; and Willow as a kind of anti-design to that.

Really, this loops back to last week’s thought of data as a byproduct, but having been elevated to the product. How do we devalue data? Make it illegible, disposable, impose a half-life on it through mutability and forgetfulness. (whispering in your ear): Willow

Okay I’ll stop. The approximately ~80 people attending the call seemed to enjoy it, though! I’m pretty sure people like the idea of Willow. It would be really nice if we could give people a chance to like using it.

Which is… going to happen? Sooner than ever? Aljoscha and I have a persistent store and drop format implementation within reach. We also now have a secret project. It is secret in the sense that you do not yet know what it is, but not so secret that I won’t tease its existence on my blog. Can I give any hints yet? Well… the image I chose for the super secret Signal group chat for it was this:

No, you won't find any extra hints in the alt text.

That’s cryptic enough, I think.

Oh, and this coming week Aljoscha and I will meet in Prague to collaborate with many of our peers in the P2P / networking space. Hopefully this time Aljoscha won’t immediately be struck down by illness and we might even get to hang out. So next week we’ll hopefully have some interesting stories to share.

~sammy

2026Week 1220 Mar

“very organic, shaped by psychopathologies”

A four panel comic, titled BLOSSOQUEST.
        
In the first panel, The Bottleneck looms over the dressed figure who was just pointing a gun at him. "Well?" he asks.

In the second panel, everyone hears a distant "choo choo". The Bottleneck turns his head to listen.

In the third panel, a close up of the gun wielder's face. She says "There's a *train* a-comin'".

In the final panel, we see a train making it's way along a long straight track. Text on the background says "And I need you to be on it".
A teeny megaphone blaring out noise

Bab 0.5.0-alpha.1 Released

Finally, a new release announcement! There’s a new version of our Bab crate, exposing verifiable streaming and data storage. You can create new storage backends for strings of some known hash, and then feed data into those backends piece by piece. As long as that data is a prefix of the expected string, it gets added to the backend. If it isn’t a prefix, you get an error, and can later resume at that point.

This release is an alpha prerelease instead of a proper new version. The reason is that not all functionality is tested yet: everything to do with the k-grouping optimisation of Bab is untested and very, very likely to be broken. Also, the persistent storage backend is still untested. But in-memory incremental verification works!

By next week, we will test the persistent backend, and then we can move on to testing our new Willow store implementation. Fingers cross that we can release persistent Willow storage next Friday!

Shout-outs!

Ben Frye has added some helpful new adaptors to Ufotofu. And caused a bit of an oh-no-do-we-need-to-break-the-core-trait-designs-again moment in the process, but later found a non-breaking solution to the problem. Phew! And then Ben also stumbled upon an issue with some of the built-in consumers of ufotofu that will need fixing. So quite a fruitful contribution. Thank you!

Also on the ufotofu side of things, Danmw has implemented another pair of adaptors. This was the most recent in a series of contributions, all of which demonstrated a deep care for the codebase (not to mention our symmetry-pondering discussions on Discord). So I went ahead and gave Dan full access to the ufotofu repo and publishing rights on crates.io. Version 0.10.1 of ufotofu was published by Dan! bus_factor += 1 =)

A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

This Monday I took the train to Rotterdam to go speak at XPUB.

Before we started, Doriane (who had invited me after we’d met at FOSDEM) gave me a quick tour of the XPUB facilities, way up on the top floor of a building overlooking the Nieuwe Maas. I was really enamoured with the atmosphere of their space, which had zine-filled shelves, boards crowded with posters, and students working away in cosy, personal spaces. It didn’t at all have the feeling of a curated display case, but rather a living, breathing space with work flowing through it. Nice.

And as for my part: we neatly avoided a sammy slideshow situation (thank you doriane) and instead had a kind of guided discussion for two hours, in which we hardly talked about Willow. It was great. I had a big chalkboard behind me on which we assembled a timeline of nearly three decades of peer-to-peer trials and tribulations, from Napster’s legal dismantling to the state-sanctioned deactivation of Apple’s Airdrop. Interjections from the rest of the room were frequent and always thoughtful, and when we finished at 19:30 it felt like we could have kept on going.

Thanks to Tommi for the photo.

Like I said last week, I couldn’t leave it on a downcast note. After all, what are we going to all this trouble for? I argued that we had an opportunity to remember that data is just a byproduct, and that the point is for it to change us somehow. Peer-to-peer protocols have some unique features which encourage us to learn to become conscious stewards — rather than hoarders — of data.

Anyway. Great time, great people, hope to be invited back again some day.


But that’s not all I got up to this week. I also implemented payload storage in the new Willow persistent store, using the Bab implementation Aljoscha has been working on. Streaming, verified storage! It’s a beautiful thing. Or it will be a beautiful thing once we’ve got all the bugs ironed out.

~sammy

A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

Do I write a thoughtful editorial, or do I simply finalise this rather late update? While I have no idea about the identity of the BOTTLENECK in Blossoquest, I sure know that for this week’s update I was the bottleneck. But maybe there is time for sharing a few fun ideas still.

  1. A live-coding environment for shaping the sound of digital instruments. Basically, you edit a function that takes as inputs a frequency, a volume level, the time since the note was triggered, and the time since it was released, and you return a value between -1 and 1. This function is called 44000 times per second to produce sound. Oh, and the function has access to the samples it produced for the past x seconds, so that you can employ feedback and self-reference in shaping the sound. (shoutout to the best repo on github, but this would have a live-refreshable js interface instead of compiling rust programs into command line utilities)
  2. A theremin-like, mouse-based (or touch-pen!) UI for playing the live-coded instruments. Should have a toggle for switching between continuous frequencies and a mode that discretises into the 12 notes of well-tempered tuning. And while you move the right hand on the frequency-volume domain, the left hand can do key-presses: one key functions as a sustain pedal, another represents whether to produce sounds at all (pressing and holding that key is like pressing and holding a note on a piano).
  3. A language for writing down instructions for triggering the digital instuments. Basically, what happens if you take the good parts of Lilypond notation and free it from the complexities of score engraving. You end up with a language for structuring events in a flow of time. The language would “compile” into a stream of MIDI or OSC signals. And, the theremin-like UI has a recording function that saves live input in the form of that written language.
  4. Also, for something completely different: cellular automata (think game of life), but with a notion of continuous force fields. Cells can emit a force field, and the values of the field instantaneously propagates between cell updates, with a configurable decay based on distance to the emitter(s). Imagine a tree-drawing automaton where each cell of tree trunk acts as an emitter on the force field of treeness, and when picking a direction for growth, cells of low treeness are more likely to be picked.
  5. And how do I turn the oscillations of a cellular automaton into music?

ALSO: I have taken some work-in-progress drafts of other ideas of mine and moved them from obscure branches into a work-in-progress directory here at the deployment of worm-blossom.org. There is an incomplete but already informative spec draft of the media file formats I wrote about some weeks ago. There is a sketch of a bit-level variable length integer encoding for usage in the media formats. And there’s a draft of the website for Macromania. Without styling, and without most of the content, but the getting-started guide and the introduction-to-macros writeup are functional. You could start using Macromania today!

Oops, I suppose I did end up writing a full editorial.

~Aljoscha

2026Week 1113 Mar

“does that satisfy your little platonic heart?”

A three panel comic, titled BLOSSOQUEST.

In the first panel, the small figure in a dress is pointing a gun towards the viewer. She says: "One more time. Where is-"

In the second panel, she is looking upwards, a shadow cast on her. She mutters "the..."

In the final panel, we see an huge figure looming over her, with a peculiarly shaped neck. He says "I *am* the bottleneck. What do you *want*?".
A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

I’ve had repetition on my mind this week, most explicitly triggered by Lu Wilson’s writing on the subject, but also earlier through some reflection on the music I’ve been making. My commentary for last week’s background music track was simply I feel like I'm repeating myself too much with these =/. By now, I’m much more willing to embrace the repetition.

Later, I went to a free improvisation concert played by Fred Frith and Liz Albee, and the weakest passages by far were those where they did not feel comfortable to simply repeat themselves.

And later still, a book I’m reading had the following A. N. Whitehead quote:

[..] no rhythm can be a mere pattern; for the rhythmic quality depends equally upon the differences involved in each exhibition of the pattern. [..] A mere recurrence kills rhythm as surely as does a mere confusion of differences.

I don’t think this makes a lot of sense, at least not when applied to music. No sound happens in isolation, everything is shaped by the sounds that came before. Even when repeating a pattern verbatim, the effect on the listener does not repeat: the first time you hear it, it is new. The second time you hear it, the impression drastically changes, because it is not new. The third time, it is a repetition of something that was already familiar. And so on.

Each repetition has a different quality, because it was preceded by a different context. The quality of change arguably decreases (the difference between the first and the second repetition is more pronounced than that between the 50st and the 51st repetition), but it keeps changing. After 400 repetitions you get a completely different effect than after 32 repetitions. Just like you cannot step into the same river twice, you cannot truly repeat the same pattern.


Oh, wait, this is supposed to be a dev diary, right?

Our Bab implementation now has a well-documented public API, and Sammy has started coding against it! I will spend the upcoming week writing more thorough tests, and next Friday I think we will release it properly. Writing tests is well and good, but I need to accept that I’ll release buggy libraries anyway. So might as well put a disclaimer on the release and ask for bug reports.

~Aljoscha

A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

Early this week I made a few wireframes for a kind of generic Willow management UI (with Penpot, which is nice).

Discord’s ‘server’ UIs have always mapped very cleanly to Willow’s namespaces, and it seems negligent not to appropriate their work. But as soon as you start wading into the more unfamiliar concepts like keypair and capabilities the difficulty begins to reveal itself.

What's a root pass? What's a path? What does it mean that this pass was granted by a root pass? Which chatrooms am I allowed to use?

One of the most beautiful ideas about systems like Willow is using a single namespace as a bucket for all kinds of data. What if your Discord server also stored a wiki, a webpage, or anything else its users wanted to put into it? What if you could easily inline your wiki pages into your chats, and weave your data together? And had decentralised permissions which could stay on top of this menagerie of data?

Do you interface with that data in a single mega interface, or many seperate ones? If the latter, does each interface manage its own personas and passes (keypairs and capabilities)? In that case, do you reveal those nitty gritty details like being granted access to /chat/general or something aware of its context, like “General discussion”?

We've bonked our heads against this many times over the years. We tried a reusable React component that you could drop into your (presumably React-powered) app. We tried a kind of web-based mini-OS with different interfaces running inside a managed UI frame. And now I am just starting to think that the solution is a set of agreed conventions, spanning from representation to UI. I uttered the cursed phrase “cultural API” earlier, but I suspect this might just be a rubbish way to say pattern language.

A screenshot of 'CinnamonOS', a web app which sandboxed mini-apps inside of it while providing the UI for managing keypairs and Earthstar shares.

Next week I’ll make an appearance at XPUB (a two-year master in experimental publishing in Rotterdam) to talk about p2p, Willow, and how we communicate our work. I’m really looking forward to this, and I’m challenging myself to find different ways to tell a story about peer-to-peer and Willow. For this one, it’s going to be a timeline, thirty years of lessons learnt the hard way. I feel like it would be irresponsible to only conclude we need to march on with grim hypervigilance. Surely we’re guarding something precious with that vigilance? It’s not just our safety, but something precious, joyful, and unrealised?

~sammy

2026Week 1006 Mar

“is there a homomorphism from your opinions to our opinions?”

A five panel comic, titled BLOSSOQUEST.
        
In the first panel, we see a kind of saloon, light pouring in through the open doorway and spilling onto the floor. A large figure sits hunched over the bar.

In the second panel, it's the same scene except now someone is standing in the doorway.

In the third panel, we close in on the figure in the doorway. They have a round head, a face hemmed in by some kind of bonnet. They say "I'm lookin' for The Bottleneck".

In the fourth panel, we see the figure at the bar close up, his face tilted downwards, his eyes closed under his wide brimmed hat. He says: "Gone".

In the fifth panel, it's the same shot except a revolver has now been raised against the large figure's head. He does not look pleased.
A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

Let’s start with nuts and bolts dev diary stuff: I started working on a new persistent store for Willow. It’s a straightforward port of the previous persistent store, which used sled under the hood. Except things were just different enough that I could justify switching to Fjall instead. Translating from sled’s APIs to fjall’s was pretty straightforward! This store is missing a few pieces still, as the Store trait needs to be updated with a few methods for storing and retrieving payloads, which depends on the Bab work Aljoscha has been feverishly boshing away at. So: we’re getting there!

While that bubbles away, what else to do but learn about Tauri, and seeing what I can glue together with our Willow Rust APIs? I got about as far as creating one button before my head filled with question about how we’re going to present all of this to human beings. Like the keypairs which are used to sign entries, for instance. they’re just not anything like user accounts on something like Discord, or even Mastodon.

Since the earthstar days, we’ve referred to the set of features keypairs confer as an ‘identity’. But to me, identity smacks of some kind of vague proving humanity rubbish. But that’s kind of exactly the opposite of what we want Willow’s keypairs to do:

  • they can be used to prove authorship
  • but you can have a lot of them
  • and they have as much or as little identifying information attached to them as you want.

So how about ‘persona’? Data can be verified to be written by a persona, you can have as few or as many as you like, and you can attach as much ‘identity’ information (e.g. display name, avatar) you want… or not. Miaourt suggested using little masks as the iconography for this, which I really love.

I'm not the only working on Willow GUIs right now, so expect more of this!

~sammy

We're listening to...

LOSTAGE

Sami (yay!) shared this video on our Discord server, and I’ve listened to it several times by now. In searching for the band on the web, I found this interview with the lead singer, where they primarily talk about the band’s unconventional decision to not sell their music via larger digital platforms. The philosophy behind that is a lot more nuanced than “Spotify bad!”, I greatly enjoyed reading this. ~Aljoscha

Gorillaz

And something completely different to Aljoscha's pick: animated mega-band Gorillaz. I remember seeing one of their animated music videos as a kid and being completely captured by Hewlett's style and the project's concept. As the years went by, it seemed that the animated aspect of Gorillaz became less and less pronounced. So last week's release of their new eight minute video was such a treat. As for the music: I have been humming the sweetly lilting flute melody from the album's initial track the whole month. And Black Thought's section in The Moon Cave imbues its animated adaptation with all its kinetic power. ~sammy

A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

So much has happened this week! This calls for bullet points!

  • Good progress on the Bab implementation: we have well-documented public API for (persistent) single-slice-per-string storage with support for partial verification. Still requires better tests, but then it can be released. Before that, I’m creating a Bab-aware trait for Willow stores in the willow25 crate though, to unblock Sammy’s implementations of a persistent store and the Willow Drop Format.
  • I attended a DWeb preparation event on Saturday. Was nice to run into many familiar faces, and to get to know some new ones. Went home with renewed motivation to get Willow out into the world.
  • I met with Zelf to record an episode of her podcast. It will probably be a while until editing is finished and this episode is released, though.
  • On Tuesday, a bunch of us p2p nerds ended up in a bar with Olivia Jack of Hydra fame. Hydra is a super cool environment for creating 2d graphics — basically a synthesizer for graphics. I may have spent too much time playing around with it afterwards. It is so easy to get something fun going. I also may have started reading the source code and begun sketching a WebGPU-based implementation. The chances for that ever getting anywhere near useable are close to zero, but at least I had a very fun day of rest.
  • I have strong opinions on variable-length integer encodings. So I was happy when I read Brooklyn Zelenka’s new bijou64 spec, which is an interesting variation on my older VARU64 specification. Slightly more complicated, but also slightly more efficient, and arguably easier to detect non-nanonic encodings. An interesting read for the other three people who care about varints.
  • This week I finished a super secret side-project that I will reveal... later :>

~Aljoscha

Shout-outs!

Remember the fruitful discussion about error cases of bulk processors in Ufotofu? Danmw has implemented all resulting changes. Somebody should give them a medal or something! (Sammy, you can draw a mushroom person with a medal, right?)

And the commit messages deserve a special message. Sammy and I appear to have been the worst kind of role models. Nicely wrought, Dan.

We have a new first-time contributor: 🐈‍⬛ added default parameters to our Rust implementation of Willow’25, allowing Sammy to progress the Willow Drop Format format a bit further. And I could finally put the signature for the default entry into the specification.

I give rather pedantic feedback on pull requests to our Rust repositories, and I’m often scared I’m overdoing it. So thank you for putting up with my nitpicking. And thank you for contributing the code in the first place, of course!

2026Week 927 Feb

“bread-first search”

A four panel comic, titled "Blossoquest (continues)".
      
In the first panel, we are closed in on a screen of strange green and grey waveforms and static.

In the second panel, we zoom out a little, seeing a monitor displaying this static fixed to the corner of a wall.

In the third panel, we pull back even more, seeing a strange figure with a wide-brimmed hat on sitting at a bar, alone. The monitor buzzes in the corner.

In the fourth panel, we are outside, looking at a lone building with the sign "LAST CHANCE" above it, and saloon doors. There is some kind of a platform and a railtrack behind it. In the foreground, a figure stands bearing a revolver held ready, looking at the saloon.
A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

When last week's update went up, I was at the Internet Archive Europe HQ in Amsterdam ('HQ' makes it sound like a big shiny building. It's really a cute little house by a canal). Remember last week when I said I felt like a frog finding their special frog habitat? Well this was more frogs. Many people who I'd been looking forward to meeting, and (somewhat amazingly to me) a fair number who'd heard of Willow before. After a lot of conversation, a sensible amount of cheese, and maybe a little bit of schmoozing, I left feeling energised. For years I've been trying to find a local network of people interested in this niche field, and either I was too much of a shut-in (likely), or this community in the Netherlands has finally reached a kind of critical mass and level of interconnectedness with the broader network.

Meanwhile, I worked on willow_rs. Unfortunately (and kind of intriguingly) my work finally presented a dead end in how well Rust is able to accommodate Willow's generic and parametrised ambitions. Aljoscha has (hopefully) done a write up on this below (don't leave me hanging aljoscha). I've started working on an implementation of the Willow Drop Format (WIP pull request here), where I am practicing liberal use of the todo! macro to implement as much as possible without letting little things like not having that dependency yet weigh me down. This is like taking a breadth-first approach where instead I've always taken a depth-first approach to missing bits and pieces.

~sammy

Why is it called worm-blossom?!

← Previous instalment

why is this website called ‘worm-blossom’? In this series we will explain why in a concise manner.

Part 6: Abuse Audit

It is 2018. A cloaked figure sits in their garden in Berkeley, California, typing away on a laptop. Upon their screen is Patchwork, an application for browsing and publishing on the Secure Scuttlebutt network. Cinnamon, a SSB regular, hits the publish buttion. Their latest post is titled “Useful idea: Abuse audit”. They propose to collectively pore through Secure Scuttlebutt “to find every single way it could be used to harm others and then go through that list one at a time and come up with ways (or list the ways that already exist) to stop or deter that behavior.”

Over the next two years, Cinnamon spearheads an abuse audit of Secure Scuttlebutt, eventually identifying 76 potential abuse vectors and compiling them to a now public spreadsheet.

Privately, Cinnamon faces resistance to their audit: this is the internet, you can’t have the benefits of open communication and expect to be sheltered from all its potential harms.

For example: “P2: Revenge porn”:

Person A publishes an image of person B without their consent.

The ideal resolution is to remove this content from the scuttle world completely, which isn't really possible.

or “P3: Doxxing”:

Person A publishes contact info of person B without their consent, with the intent to intimidate them or lead others to harm them.

The ideal resolution is to remove this content from the scuttle world completely, which isn't really possible.

Among worsening and inexplicable health symptoms, Cinnamon becomes frustrated and burnt out by the abuse audit and the apparent reluctance to — or outright impossibility of — addressing any of its identified issues. They work on an alternative safety-focused client for Secure Scuttlebutt called Oasis. But this still isn’t enough to stave off Cinnamon’s dissatisfaction with Secure Scuttlebutt.

In mid-2020, Cinnamon announces Earthstar:

I've been thinking hard about how to improve the user experience of #Oasis, and I kept finding deep things about SSB that I wanted to change:

  • You can't delete messages
  • You can't just download recent things first, you have to wait a long time
  • You can't re-use the same account on multiple devices

That's enough to keep most people from wanting to use SSB. When people say "why can't it be better?" the answer is "sorry, it just wasn't designed to do that ¯\(ツ)/¯"

These 3 constraints all arise from SSB's security properties as an immutable append-only log with hash backlinks. But what if we didn't need immutability? Is it appropriate for a social network?

By relaxing that security property, we solve all 3 problems:

  • You can delete or edit messages
  • You can download any subset of things in any order
  • You can use the same keypair on multiple devices. Now a keypair represents a person, not a device.

Earthstar addresses the key abuse vectors Cinnamon has identified over the past two years, and eschews big-world immutability for a plurality of small-world mutable networks. Cinnamon takes a pragmatic, productive approach to Earthstar, opting for the use of ‘boring’ technologies and a simple implementation which can run in a web browser.

But there’s one little problem. In rejecting the append-only log, Earthstar has adopted unlinked sets of items. In doing so, Earthstar has traded away Secure Scuttlebutt’s relatively simple and efficient synchronisation, with no obvious replacement. How to efficiently figure out what’s different between two devices when all you have is a bag of stuff?

Next time we head to Basel, where the imagination of a familiar bespectacled friend is captured by this puzzle.

Next instalment →

We're listening to...

Nikolai Kapustin

I have not been this tempted to sit down and practice a piano piece in a long while (thanks, my dearest sister). But rest easy, I’m dead inside being responsible and will work on worm-blossom things instead (not that I have the required piano technique anyways). ~Aljoscha

A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

What is going on in Blossoquest? Since when did it even have that name? Why are we suddenly in a Western? Does the crack in the wall have any meaning? How can Sammy claim dislike for Homestuck and unfamiliarity with Hussy’s work, and yet the third panel looks like Problem Sleuth and the name like a play on Bard Quest? What is going on?!

Anyway, apparently I am supposed to write about the limitations of the Rust type system instead of investigating these mysteries. So here we go!

The Willow specs are highly generic. So naturally, our Rust implementation is full of generics as well. Because this is rather cumbersome, we are also providing a non-generic implementation of Willow’25 for application developers who shouldn’t need to care about the flexibility offered by the parameterisability of Willow.

In our previous codebase, the willow25 implementation merely provided type aliases, with the consequence that compiler messages bombard developers with all those hidden generics. So in the reboot of the codebase, we went for proper wrapper types. We even have a wrapper! macro that automatically generates the structs that wrap the underlying generic types. So far, so good.

The first problem that stems from this arrangement is that of converting between references. Suppose our generic implementation has a function that requires a &Entry<Lots, Of, Generics>. To implement the willow25 version of that function by calling the original function, we need to convert &Willow25Entry into a &Entry<Lots, Of, Generics>. Reference-to-reference conversions are not exactly the most idiomatic Rust. But this was doable, with the `wrapper!` macro even completely hiding the required unsafe and #[repr(transparent)] shenanigans that make it work. And up until Sammy’s recent implementation work, this was good enough.

A tiny figure loses their balance atop a tower of haphazardly balanced blocks, bearing parameter names such as N, S, PD, AT... it'll make sense to Aljoscha, at leastThe real trouble started however once we needed willow25 wrappers for generic types made up from other generic types. For example, a generic AuthorisedEntry struct consists of a generic Entry struct and a generic AuthorisationToken struct. A Willow25 wrapper around AuthorisedEntry would internally still use generic components. But for some code, we would need it to consist of (or at least to be interpreted as consisting of) a non-generic Willow25Entry and a non-generic Willow25AuthorisationToken. But for this interpret-the-generic-components-as-being-non-generic-wrapper-types business, the generics must be instantiated with types that satisfy certain constraints regarding their memory layouts. The exact details are gnarly and do not really matter, the important part is that we ended up in a situation where there would be unsafe code galore. This in itself is bad but not a showstopper, but the real problem was that the safety of this unsafe code would depend on whether you instantiated the generics in a certain way.

The compiler has no way of enforcing any invariants here. And I have never seen any code whose safety depended on properly instantiating type parameters. Calling this situation unidiomatic would not do it justice, I’d rather reach for an unholy abomination whose creators should be barred from writing Rust code ever again.

So what now? We will keep the generic code base for now, but new work will only provide willow25 APIs. Where possible, those will still make use of the underlying generic implementation, but where that does not work we will simply duplicate the generic code and then rip out the type parameters. Long-term, we will probably phase out the generic code base completely, doing concrete willow25-based implementations directly instead.

This is a bit of a shame. The genericity of the specs is a decision I still stand by, and generic implementations do have a certain elegance. But it turns out that (idiomatic) Rust is just not particularly well-suited to it. And we want to keep the codebase accessible and high-quality. The decision to move to non-generic implementations for now stings, but everything else would lead to an idiosyncratic code base that would have made Dominic Tarr proud, and scared off everyone else.

(Also, writing docs for two almost identical versions of our APIs was a pain from the very start, so I cannot truthfully report that I am entirely unhappy.)

~Aljoscha

A friendly computer waving his mouse, beckoning you to come contribute!!!

Contributions Welcome: ufotofu Limit adaptors (Rust)

https://codeberg.org/worm-blossom/ufotofu/issues/15

Sammy needs an Ufotofu adaptor that limits how many items a wrapped producer will emit. We had an open issue for this for a while. This is a great opportunity to dive into the ufotofu codebase: small scope, not too difficult, and there even is an implementation in an older version of ufotofu to use as a basis. It would be a shame if such a good first issue had to be wasted by us implementing it ourselves. So if anyone wants to give it a try, now is the chance!

2026Week 820 Feb

“be kind (non-hypothetically)”

An illustration of two playing cards, one slightly overrlapping the other.
        
        The two cards show illustrations of Aljoscha and Sammy, styled as face cards.
        
        Aljoscha's card shows him playing music, and coding seriously on a computer.
        
        Sammy's card shows her drawing, and working at a computer with some displeasure.
A drawing of Sammy, one arm holding up her head with a pencil in it, the other resting on a piece of paper.

Recently I’ve felt like a weird little frog who is finally finding their weird little microhabitat. The perfect temperature! Exactly the kind of slime I like! Other weird frogs like me! January put me in the path of lots of people who do and make things I’m excited about, and who seem excited about the work I’m doing too.

The only problem being that I actually have to do that work.

Our immediate goal with Willow is to implement the means to save and retrieve Willow data, and to have at least one way to exchange that data. For the latter, we’re going with the Willow Drop Format, which collects lots of Willow data into a single file that you can deliver with whichever way you like to send files.

Since I started working on private encodings last week, we’ve merged implementations of private path encoding, private area encoding, and private authorisation token encoding to willow_rs’s main branch. I had to get all these past the relentless scrutiny of our fuzz testing apparatus (and Aljoscha), so I’m fairly confident these new implementations are robust and well documented. Which feels great! There is definitely some kind of maladjusted satisfaction I get from merging code, which is something I should probably watch out for.

A drawing of Sammy in a frog suit.With that out the way I can get back to the important work of being a weird little frog. This weekend I’ll be heading to the Internet Archive’s new European Headquarters in Amsterdam for a little borrel, where I guess I’ll do borrel-y things like eat little cubes of cheese... and with any luck, meet some more frogs.

~sammy

A drawing of Aljoscha, fingers interlaced, eager to deliver some interesting news.

I finally made good progress on the persistent backend of the Bab implementation. All the logic is in place; the remaining steps are to rearrange the public API, document it, and then to add more thorough tests.

And instead of writing a long editorial, I’ll continue programming now.

~Aljoscha

Why is it called worm-blossom?!

← Previous instalment

why is this website called ‘worm-blossom’? In this series we will explain why in a concise manner.

Part 5: Disconnected, but never alone

It is 2014. Dominic Tarr stands on the deck of his boat, surveying the horizon. There is nothing in sight but bright, blue ocean. Tarr is a sailor and programmer, one with a particular interest in distributed systems.

Tarr’s boat, alone at sea, has little to zero internet connectivity. But why should that stop the flow of data? What if a device could opportunistically send and receive data when a connection was available, storing it for later? It could even make entirely new kinds of networks possible, ones without middlemen dictating the terms of network usage.

This approach brings its own different problems, of course. How do two devices determine which data to exchange? How do they know the data they’re exchanging can even be trusted?

No problem is without a solution, however. Tarr has chosen the append-only log as the foundational data structure for his latest experiment. Append-only logs can be efficiently compared and merged, and the power of content-addressing makes their constituent data verifiable. There’s even some precedent: Git, the most popular system for decentralised version control, has content-addressing at its heart.

Tarr’s experiments coalesce into a new protocol known as Secure Scuttlebutt. Over time, SSB attracts thousands of users, each of their devices transformed into their own little boat all at sea, perhaps disconnected, but never alone. SSB’s users comment on each others posts, play chess, and chart a course into a new decentralised future together. And with content-addressing quietly powering it all.

Two years prior, Tarr had written that “The biggest problems facing humanity are really software problems”:

Currently, humanity stands at a crossroads like never before. Great power and great changes are looming on the horizon - genetic engineering, nano technology. Yet also great dangers - Climate Change, peak oil, and the fact that western governments are getting stupider and more corrupt. We need better software to solve these problems.

Perhaps Secure Scuttlebutt was Tarr’s own attempt to solve some of the world’s problems with better software, software which would bring about a new vision of the world through its superior design choices.

But the systems underpinning our software often bring about their own vision of the world whether we want them to or not. Any user of Git will wince at the thought of accidentally committing some secret key to a repository, and the subsequent scramble to undo it. Git’s view of the world is one of a canonic, immutable history, where every change can be tracked down and replayed, and even blame assigned. And with content-addressing quietly powering it all.

But why is worm-blossom called that? Next time, we’ll travel to Berkeley, California, where someone is starting to feel nervous about all this.

Next instalment →

The Surfers’ Review

“just finished reading (and listening to the soundtrack of) the latest Worm Blossom “graceful_producer.slurp()” [...] If this project is not on your radar, you are missing out cause they are doing amazing things!”
“such a lovely website, I really love how hand-made its stuff is. The music and artwork and everything [...] Wait a minute is 'worm-blossom' a pun on 'brainworms'”

worm-blossom.org thanks you for your continued patronage!