[PIG] Salami: Serverless, storable programming language for scripting the Web

– by Valentin Golev, Alexandru Sasu

Salami is a “serverless”, storable programming language: its process is just a binary string. This string contains all the information on what the process expects next, and what it should do afterwards. One can easily store it in a database, waiting for the next event; send it to a different server, or even a different actor; change it to adapt to some new circumstances. You could compare it to Ethereum’s smart contracts, without the blockchain; or to “worse is better” Urbit: it’s the most flexible, simple substrate of those ideas.

Salami aims to support scripts like this: “Send an email to propose a meeting, wait a week for a reply and follow-up if needed (let me approve the draft), cross-check my calendar in response, if needed contact me for the next steps”. Such ad-hoc instructions, and the massive flexibility they demand, are the future of the AI interfaces. This is not a script that can simply be transformed to JS and run somewhere. The usual programming languages don’t support a week-long await safely and reliably. They aren’t helpful when we want to let our users revise and confirm the next steps. They’d require a complicated sandbox and API design to give users affordances for safe and reliable outcomes. It’d be an unbearable expense to maintain the infrastructure and the systems of trust needed to run multitudes of such scripts for our users simultaneously in a conventional way.

Such a script is as an ad-hoc protocol of revisable communication between several parties: the users, the systems, and the AI agents. Turing completeness of such a meta-protocol requires the power of a programming-language-like solution, but with a vastly different execution model: the “serverless”, location-agnostic computation Salami proposes.

Apart from the new execution model, Salami has affordances for undoable, revisable, controllable, safe async APIs. Those are a necessity for amateur-user-driven scripting. The ultimate aim is the minimization of regret for all the parties (read more here).

Salami aims to make any existing app scriptable, no matter how simple or unusual its architecture is, and able to take part in the meta-protocol network in a very advanced and safe way – to empower the users. In just a few lines of code, Salami can be embedded into the existing apps, including Python, JS, or browser-only ones. It’s also a great compilation target for workflows and visual programming tools. This radical ease of embedding Salami into existing apps is what sets it apart from many spiritually close projects that typically would require massive buy-in on the architectural level to integrate.

  • Existing target protocol – Salami is an evolution of the classical “C” process model with insights from the blockchain VMs, Urbit, and linear-logic-based formal systems.
  • Core idea – the storable process: one that can pause on awaiting and turn themselves into cold-storable binary strings that can continue executing elsewhere.
  • Discovery methodology – Interviewing potential integrators and end-users, LLM-based experiments with code writing.
  • Prototype – an end-to-end prototype of the system (cutting a lot of corners at first), and a cool demo.
  • Field-test – we’ll start with a couple of demos, and try to find interested external users.
  • Judges – we have some interested app developers, who themselves, along with their users, would be the best judges of the tool.
  • Output – a completely open-source library (Rust core, MIT license) + papers.
  • Success vision – Salami to power the newly-scriptable, multi-actor Web.
2 Likes

trying to understand if there’s some better conceptual approach here, something along the lines of: notion of a process as an ad hoc but structured protocol for communication between a mixed, open set of actors (humans, APIs, AIs).

start with an embodiment of the concept and something you have experience with

This is a great idea, and is being worked on by the Spritely Goblins [https://spritely.institute/] crew, using object capabilities. Each agent can be run in a distributed manner in encrypted serialized (storable) process environments called vats. These agents (Goblins) can communicate to each other over a capability transport layer (ie the ability for one agent to communicate to another must be granted through unforgeable secrets that can be layered to provide different levels of remote procedure calls). Currently this is being done over tor rendezvous points (onion routing), I believe.

And it’s written in Scheme! And will soon be compiled to WASM to work in the browser.

2 Likes

Interesting! I’ll try to understand if my idea is different and explain how, if that’s the case

1 Like

I will probably have to actually try it to make sure that I am not completely wrong about this, but I think the conceptual difference would be the following, and it seems very huge to me:

A goblins’ actor is a continuous process, and it lives somewhere. The process itself is still a part of the OS-process (of the vat). So you have many vats, that can be anywhere on the net, those run and own actors, just in the same way as servers run processes. So I think it’s reasonable to say goblin is a pretty cool futuristic communication protocol for communication between essentially normal processes (their sub-processes).

This implies that vats run continuously as OS-processes on some kind of server (or there’s another system on top of this system to manage vats, start/snapshot/restore them on-demand).

Salami’s process doesn’t “live” (in the OS-process way) anywhere in particular, it’s simply a binary blob. It encodes therein its state and whatever it awaits. So you can query if it wants something from you, provide it and run it a little. Or you can send it somewhere else, like your database, or another server, or even another trusted party to your higher-level protocol. It’s a complete inside-out turning of the whole idea of the process-vs-state. A salami process can wait its hour as a cold binary blob for as long as needed, and thus has completely different infrastructural requirements: just a database, or even a blockchain, or any other kind of storage like browser storage.

(Anyway, goblin is definitely something for me to study and learn from in my endeavor…)

1 Like

Goblins follow the Unum pattern, and are distributed abstract objects with many different presences, which sounds pretty similar to what you’re shooting for.

Anyways, it’s a concept that is quite needed in distributed and decentralized computing. Let a thousand flowers bloom!

1 Like

I think the problem I’m trying to solve is just a bit different. Purely distributed, but mostly static configurations is what all those protocols do best. They’re an improvement over the typical, already ubiquitous OS-process-based process model, and most of what they propose is easily simulated using existing ubiquitous message passing and queuing protocols.

But I’m more interested in enabling custom and mostly end-user-provided scripts that would have no permanent home and no additional locational requirements. Like if you have some kind of a normal webapp, and you want to add scripting to it, and you want this scripting to be powerful enough to express things like “every event” or “wait for a particular event” or “wait for a week”, and yet you don’t want to have a server with processes literally waiting for a week, because that would be too brittle. Think “ChatGPT code interpreter”, but with events support and without any time limits. And with additional communcation capabilities back to the user, to your app, perhaps to others.

This is a very different problem and approach, and it’s something that the contemporary runtimes, programming languages and communication protocols just don’t allow. Smart contract is the closest thing actually – I’m just thinking smart contracts without blockchain but still without being tied to a particular machine.

Interesting. So closer to an AWS Lambda that runs on which ever distributed compute node happens to consume the event, and be aware that there is a continuation function set for that event? Would there be an incentive to contributing to this ecosystem? Are there schedulers, or mutexes to set, indicating that a node is completing the computation, so that others don’t reproduce their work? Or is reproducing work a means of verification?

1 Like

Yes. I would say in many cases – yes, but I’m also thinking that this approach can lead to the same process-blob to be sent between different parties to execute a little from each side.

yes, be aware that there is a continuation function set for that event

Yes! Since one executes this continuation, one also get the information on what it’s blocked on (“it wants to wait an hour”, “it wants to receive this piece of information”, “it waits for this event”), and perhaps take according actions. Also btw, this continuation function can also be replaced (in some cases, if allowed explicitly, etc) – so like at any step if you realize that the script doesn’t go the way you wanted, you can change what it’ll do.

Are there schedulers, or mutexes to set, indicating that a node is completing the computation, so that others don’t reproduce their work?

It’s purposedly architecture-agnostic, so the solution would be to solve it at the level of whatever underlying storage/protocol you have. But it’s obviously important, and if I realize that this is something that needs to have support at the level of salami itself, I’ll have to add it. There are some techniques from “durable executions” that might need to be integrated. I’d say, slightly outside the scope of the first prototype, but something definitely to keep in mind.

Or is reproducing work a means of verification?

Solving trust (in this way) is also not part of the idea, and it would lead to a different set of compromises (already focused on by blockchain I’d say).

The first immediate real-world trust problem Salami solves is like: how do you let your users, who are not professional coders and have no idea about your app’s internals, to run arbitrary computation minimizing regrets and extra infrastructrural work for both of you. It can (and should) be slow, hand-holding, ask a lot of permission – but still very expressible, if only simply because LLMs allow it to be that way. (I think you can get much more interesting, symmetrical and general use-cases than this, but it’s a good area of focus).

Then at the later stage, another cool problem comes up: let’s say several apps integrate Salami, how do we let those two cooperate within one Salami script in a way that doesn’t require trust between the developers? Still far from clarity on this one.

Salesforce is doing personal AIs in a way that might be an interesting simple use case for such a process. Salesforce Futures: Personal AI Agents Will 'Forever Change' Customer-Company Relationships - Salesforce

The execution model also reminds me of the secure microVMs that bromium was using, except in a locus-agnostic way Bromium - Wikipedia

Vaguely reminds me of urbit concepts too.

2 Likes

Oh, on first glance I read LLVM, as in the compiler backend…now I see you’re meaning to utilize LLM (“AI”) to help with the code creation.

Perhaps you should define the “problem” as you see it and how your protocol concept will offer a unique solution? As it stands it’s a little vague, as one can easily publish code in the form of wasm or js to be run async processes on client’s machines when they trigger events.

1 Like

@timbeiko @Venkat I wrote a small piece about Siri, and the game of bluff of natural language interfaces, that we touched upon for a bit The game of semantic promises (Or, why you are not using Siri) . (Still working on the RFC rewrite)

This is a bit like the work we’ve done with IPVM → IPVM Working Group · GitHub

And yes, to Spritely as mentioned elsewhere in this thread. Capability-based systems are needed as the basis for delegation across decentralized systems.

2 Likes

We rewrote the RFC substantially to address all the feedback, thank you so much @nanomonkey @boris @Timber @Venkat

2 Likes