Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

One wire, three languages

Almost everything before this part was Rust (Tic-tac-toe, VI borrowed these faces ahead of time), and the model never depended on it. A resolution is a request and a representation crossing a boundary, and the boundary is a wire protocol with a version number: ikigai-ipc speaks it over a Unix socket in Rust, and so do two other implementations of the same codec — ikigai-python (standard library, and one dependency: blake3, for the digests in a served door’s contract IRIs) and ikigai-deno (TypeScript, with one dependency, @std/crypto, for the same digests, and zod only for its optional ./zod entry point). Each is both halves at once: a client that drives a running kernel, and a servable peer that a Rust host mounts as a space.

That pairing is called L0 of the polyglot ladder, and the name is honest about what it is. A Python or TypeScript process can resolve any name a kernel binds, be described, be cached and traced by that kernel, and be refused by its capabilities. What it cannot do is what a Rust endpoint does with inv.source(..) — reach back into the kernel from inside its own invocation. An L0 peer is a leaf: it answers, it does not compose. There is no back-channel yet, and the two tracks below say so where it bites rather than pretending the ladder is taller than it is.

The two tracks

Both tracks mirror Part I chapter for chapter, in a language with no kernel in it:

Part Iin Python and TypeScript
Resolutionconnect() and source(): a name resolved over the wire, a representation back
Hello, resourcean endpoint as a decorated function, served on a socket
Why an endpoint describes itselfthe signature is the contract: ArgSpecs derived from annotations, describe() as data
Binding, and a host of your ownikigai --mount urn:py:=<socket> — a mount is a binding, and the host owns the name
What resolution buys youis_cached, source_traced: the kernel’s cache and trace, seen from outside
capabilitiesa scoped connect(), and a typed DeniedError
Multi-verb endpointsa family: one URI template, a contract per verb (Source, Sink, Delete, Exists), and which door answers a name

Then a notebook: the catalog as a graph, in rdflib, with one SPARQL query. And for a whole application served this way, you have already seen the same game in Python and TypeScript: a store in each language under a Rust host, and an app in each language that serves the host’s board.

What you need

A running kernel to talk to — ikigai serve <socket>, from the CLI the front door installed — and one of the two client packages. Neither is published to PyPI or JSR yet; both install from a checkout (pip install <path>, or a Deno import by path), and the listings in this part say so where it matters. The listings themselves live in this repository under examples/, modeled on the sibling repositories’ own examples (read-only for this book) so that the book builds from a clone of this repository alone. The client listings were run against ikigai-cli 0.1.18 as they were written (one refusal line shown in the Python track carries a later kernel’s wording, and says so). The steps that start a peer and mount it are replayed against the book’s pinned ikigai-cli on every change to this repository, by scripts/polyglot-tracks.sh, and each track says which those are.

⚠ Names under urn:py: and urn:ts: in this part are served by your peer process and resolve only while it runs and is mounted. They are not in the CLI, and the book’s URN gate declares them as such rather than claiming otherwise.