> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# KV storage

> Use the Kernel's shared in-memory key-value store from a service.

The Kernel provides a shared key-value store to all running services. A
service can use it for small pieces of state that must be read or updated
through the Kernel, such as cached values, service state, or data shared
with another service.

KV values are raw bytes. The Kernel does not assign a data format to them, so
you can encode a value as JSON, text, a binary structure, or any other format
your service understands.

## Storage model

The store has a two-level layout:

```text theme={null}
namespace → key → byte value
```

For example:

```text theme={null}
namespace: preferences
key:       theme
value:     dark
```

The KV store belongs to the Kernel, not to an individual service instance.
All services connected to the same Kernel use the same store. A service
namespace is an organizational convention; it is not a permission boundary.
In the current implementation, a service can read and write another
service's namespace unless that namespace is read-only.

Use a namespace owned by your service by convention, usually derived from the
service name. If multiple services intentionally share a namespace, document
the key names and value format they agree to use.

## Operations

The operations are defined by the Host contract described in
[Protocol](./protocol).

### Read a value

The read request contains:

| Field       | Type     | Meaning                       |
| ----------- | -------- | ----------------------------- |
| `namespace` | `string` | Namespace containing the key. |
| `key`       | `string` | Key to read.                  |

The response contains a `found` boolean and a `value` byte sequence. A missing
key is not an error: `found` is `false` and no value is returned.

Reading a value does not create its namespace or key.

### Write a value

The write request contains the same `namespace` and `key` fields plus:

| Field   | Type    | Meaning             |
| ------- | ------- | ------------------- |
| `value` | `bytes` | Raw value to store. |

Writing an existing key replaces its value. The operation returns an error
string when the write is rejected, for example when the namespace is
read-only.

### Delete a value

The delete request contains `namespace` and `key`. Deleting an existing key
removes its value. Deleting a key that does not exist succeeds without changing
the store.

The operation returns an error string when deletion is rejected, including an
attempt to delete from a read-only namespace.

### List keys

The list request contains a `namespace` field:

* When `namespace` is non-empty, the response contains the keys currently
  present in that namespace.
* When `namespace` is empty, the response contains the names of all namespaces
  currently present in the store.

The returned names are sorted by the Kernel. Listing does not return values.

## Lifecycle and persistence

The Kernel creates the KV store when it creates the service manager. The
store is in memory:

* stopping or restarting a service does not clear its KV values;
* loading a new version of the same service does not clear its KV values; and
* restarting the Kernel creates a new empty store and clears all values.

KV is therefore not a durable database. Persist data elsewhere when it must
survive a Kernel restart, and treat KV as runtime state or a shared cache.

## Concurrency and value ownership

The Kernel synchronizes individual KV operations. Reads, writes, deletes, and
lists are safe when multiple service calls happen concurrently.

There is no transaction or compare-and-swap operation. A sequence such as
"read, modify, write" is not atomic with respect to another service. If
several services update the same key, coordinate ownership or design the
value so that lost updates do not corrupt the application state.

The Kernel copies byte values when storing and reading them. Mutating a byte
buffer after a write does not change the stored value, and mutating a returned
buffer does not change the value in the store.

## The `sys` namespace

`sys` is a Kernel-managed, read-only namespace. Services can read and list
it, but writes and deletes through the service host boundary return an
error.

The Kernel uses this namespace for host-managed state, including service
registry information — for example, `sys/service/catalog/<name>` for scanned
package metadata and `sys/service/<instance-id>` for a running instance's
registered routes and transports. Do not write to `sys`, and do not depend on
undocumented system keys unless the Kernel documentation explicitly defines
them.

## Backend behavior

WASM and gRPC services use the same KV contract:

* a WASM service reaches the store through the generated host bindings; and
* a gRPC service reaches the store through the Kernel's host callback
  channel.

The storage semantics are the same for both runtime types. The runtime
changes how the request crosses the service boundary, not how the Kernel
stores or returns the value. A `static` service has no code and never calls
these operations itself.

## Recommended usage

Use a predictable namespace and key scheme:

```text theme={null}
namespace: my-service
keys:
  config/theme
  cache/user/<id>
  state/last-sync
```

Keep values small enough for the calling path and define their encoding before
other components consume them. Check the `found` result before decoding a
value, handle write and delete errors, and avoid treating a successful write
as durable persistence.
