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

What a module is

Part I built an endpoint and linked it in: your crate exposed a space(), the host depended on it at compile time, and the endpoints ended up in the binary. That is how nearly all of ikigai works today, including every endpoint in the ikigai CLI.

This part is about the other shape — a module: an independently compiled space() that a host routes some names to without linking it.

Read this part for one idea

A module is not a remote kernel, and the difference is not a matter of degree.

When you resolve against an IPC or QUIC peer, that peer resolves every sub-request on its own side. It has its own catalog, its own cache, its own spaces. You hand it a name and it hands you back an answer; nothing crosses back.

A module is the opposite arrangement. Its endpoints must resolve their resource references — an XSLT stylesheet, a SHACL shapes graph, a configuration file — against the host’s kernel, because the host owns the catalog and the cache. So a module has to call back into the host in the middle of its own invocation.

Everything else here is consequences of that one asymmetry.

What you will build

A module with one endpoint, a host with one resource, and a greeting that can only be produced by the module asking the host a question mid-invocation:

cargo run -p loadable-module
host    resolves urn:greet:hello name=urn:host:name
module  asks the host for urn:host:name
out     Hello, Peter!

Before you start

This part assumes Part I — what a space() is, and why binding is separate from defining.

The code is in crates/loadable-module, and as in Part I the listings are pulled from it by anchor rather than copied.

Read Where this actually stands before you plan around any of this. ikigai-module (0.2.0) still describes itself as “Phase 1: in-process proof”. The callback machinery is real and exercised; the isolation is not there yet.