trustee 0.9.30

A general-purpose agent that can morph into different specialized agents using WASM lifecycle plugins
# Handoff — Trustee tools-order fix (nghr 1494b6fe) — DONE, awaiting install

## Status
Root cause found, fixed, tested, and all crates published to crates.io.
The live trustee on port 3000 (pid 426410, v0.9.28) was NOT touched.

## What was wrong
`cats::ToolRegistry` stores tools in a `HashMap`. Rust's RandomState seeds
each process differently, so `list_tools()`/`get_all_schemas()` returned the
native tools in a per-process random order. Trustee sent the same 98 tools in
a different order each run → first prompt tokens changed → ninfer prefix cache
missed at every run boundary (~90–120s full prefill).

## Fix (two layers)
1. **cats 0.1.30**`src/core.rs`: `list_tools()` and `get_all_schemas()`
   now return sorted order. Regression test added.
2. **abk 0.14.4**`src/provider/openai/tools.rs`: `tools_to_openai()`
   sorts by name before serializing (chokepoint guarantee). Regression test
   added (any input order → same output).

## Cross-process proof (published crates, two separate processes)
```
TOOLS_HASH=aa42b1998d3c30959258bc2f1b8567c3 TOOL_COUNT=12  (both runs)
diff → TOOLS_ARRAYS_BYTE_IDENTICAL
order → bash edit glob grep list multiedit read todoread todowrite webfetch websearch write
```
Harness source: /tmp/tools_det_check (deps abk 0.14.4 from crates.io).

## Published (all verified live on crates.io)
- cats 0.1.30
- abk 0.14.4 (cats dep 0.1.30)
- trustee-core 0.6.21 (abk 0.14.4)
- trustee-tui 0.3.13 (abk 0.14.4, core 0.6.21)
- trustee-api 0.7.27 (core 0.6.21)
- trustee 0.9.29 (abk 0.14.4, core 0.6.21, tui 0.3.13, api 0.7.27)

Commits: cats `1f09fd6`, abk `9d3e5b6`, trustee `68a878c` (all on main).
Changelogs updated (cats, abk, trustee, trustee-tui).

## NEXT ACTION (user)
Install trustee 0.9.29 (`cargo install trustee --version 0.9.29` or the
usual release path), restart the service on :3000.

## THEN verify (this session can do it)
1. Capture: `tcpdump -i any -s 0 -nn -w /tmp/http_capture2.pcap "tcp port 8080"` on g11-gpu.
2. Run two agent runs; extract with /tmp/pcap_extract.py; diff with /tmp/diff_bodies.py
   → run B vs run C `tools` arrays must be identical.
3. JSONL: `docker exec ninfer-serve cat /workspace/requests.jsonl`
   → first call of run N+1 = restore_turn_checkpoint/append_frontier,
   cached_tokens ≈ prior prompt, TTFT < 5s.
4. Close nghr issue 1494b6fe.

## Notes
- Do NOT re-add --no-prefix-reuse (saves zero VRAM; see doc 61da6248 correction).
- GPU headroom ~1 GiB; don't raise --max-context/--max-concurrency.
- Engine source untouched; ninfer-4090:sm89 image unchanged.