# WASM Phase 1: DValue C ABI and UCEB1

Phase 1 freezes the native DValue ABI that the future WASM core and units use
as their shared structured-value contract. The implementation is in
`src/lib/dvalue.{h,cpp}` and is available in the native runtime before any WASM
backend is enabled.

## Opaque handle

```c
typedef struct DValue uce_dvalue;
```

`uce_dvalue*` is a borrowed pointer owned by the active request/workspace. It
must not be freed by ABI callers and it must not be retained beyond that
workspace lifetime.

## Accessors

```c
uce_dvalue* uce_dv_root(void);
uce_dvalue* uce_dv_get(uce_dvalue* value, const char* key, size_t key_len);
uce_dvalue* uce_dv_find(uce_dvalue* value, const char* key, size_t key_len);
const char* uce_dv_value(uce_dvalue* value, size_t* len_out);
void uce_dv_set_value(uce_dvalue* value, const char* bytes, size_t len);
size_t uce_dv_count(uce_dvalue* value);
int uce_dv_is_list(uce_dvalue* value);
```

- `uce_dv_root()` returns the current native request's `context.call` root.
  The WASM core will later map this to the decoded request context root.
- `uce_dv_get()` creates the child if absent. `uce_dv_find()` returns `NULL`
  if absent.
- String inputs and outputs are length-delimited and binary-safe.
- `uce_dv_value()` returns a borrowed pointer valid until the next ABI value
  call on the same thread.
- Bad `NULL` inputs return `NULL`, zero, or no-op rather than trapping.

## Iteration

```c
typedef struct uce_dv_iter { size_t position; size_t reserved[3]; } uce_dv_iter;

uce_dv_iter uce_dv_iter_begin(uce_dvalue* value);
int uce_dv_iter_next(uce_dvalue* value, uce_dv_iter* iter,
                     const char** key_out, size_t* key_len_out,
                     uce_dvalue** child_out);
```

Map iteration follows DValue's native order. List-shaped maps iterate in numeric
index order (`0`, `1`, ...), matching `DValue::each()`, `dv_values()`, and the
serializers. The reserved iterator fields are caller-opaque and must be
zero-preserved by callers that copy the iterator; they provide ABI headroom for
future non-linear keyed-map iteration without changing the struct size.

## UCEB1 wire format

UCEB1 is the membrane/cross-instance binary DValue encoding.

```
document := "UCEB" version node
version  := 0x01
node     := flags scalar children
flags    := u8 bitset; bit0 = list-shaped map
scalar   := varuint length, bytes
children := varuint count, count * (key, node)
key      := varuint length, bytes
```

Varuint is unsigned LEB128. Strings are byte sequences; the codec does not
assume NUL termination and preserves embedded NUL bytes. The Phase 1 layout stores scalar values as their native string representation
plus child nodes and the list-shape flag. Floating-point values use
`max_digits10` precision so numeric scalars can round-trip through the string
form. Pointer/reference identity is intentionally not part of the wire contract;
pointer nodes encode as an empty scalar rather than leaking process addresses.
An empty non-list map has no wire distinction from an empty scalar in UCEB1 v1.
Documents that contain both scalar bytes and child nodes are reserved for future
use; the v1 decoder accepts the children and ignores the scalar.

## Codec APIs

C++/UCE-visible helpers:

```cpp
String ucb_encode(const DValue& value);
DValue ucb_decode(const String& encoded);
bool ucb_decode(const String& encoded, DValue& out, String* error_out = 0);
```

C ABI helpers:

```c
size_t uce_dv_encode(uce_dvalue* value, char* buf, size_t cap);
uce_dvalue* uce_dv_decode(const char* buf, size_t len);
const char* uce_dv_last_error(void);
```

`uce_dv_encode()` returns the required byte length even when `buf` is `NULL` or
`cap` is zero. `uce_dv_decode()` returns a thread-local decoded root, or `NULL`
with `uce_dv_last_error()` populated. The returned decoded root is valid until
the next `uce_dv_decode()` call on the same thread. Decoding rejects documents
deeper than 1024 nested nodes so malformed input cannot recurse without bound.

## Test coverage

`site/tests/core.uce` covers:

- UCEB1 round-trip for maps, nested values, lists, empty lists, and embedded NUL
  scalar bytes.
- C ABI get/find/value/count/list/iteration/encode/decode behavior.
