Skip to content

Commit 20196db

Browse files
omc-kernel: content-addressed code DAG keyed by canonical hash
A standalone CLI that maintains a file-system content-addressed store at ~/.omc/kernel/store/<canonical_hash_hex>.omc. Every OMC fn has a 64-bit canonical-hash identity (whitespace-stripped, comments removed, parameter binding normalized), and the store is keyed on that. Subcommands: ingest DIR walk DIR, extract every fn, store one entry per canonical hash; sidecar JSON carries substrate metadata (attractor, dist, fn name, origin file) fetch HASH retrieve stored source by canonical hash (hex) stat HASH pretty-print substrate metadata ls list stored entries + fn names sign FILE emit substrate-signed wire message for OMC source (codec format: sampled_tokens + content_hash) verify read wire msg from stdin, recover content via store lookup; defends against store tampering by recomputing canonical hash and comparing demo end-to-end alpha-rename invariant recovery End-to-end proof (in this commit): $ omc-kernel ingest examples/lib/ → 206 fns, 184 unique $ cat > /tmp/x.omc <<<"fn commit(handle) { ... handle ... }" $ omc-kernel sign /tmp/x.omc | omc-kernel verify → STORE HIT — recovered "fn commit(conn) { ... conn ... }" Sender used `handle`, store has `conn` — same canonical address. Alpha-rename + whitespace + comment invariance is intrinsic to the addressing; no shared key, no certificate authority. Substrate metadata sidecar (~/.omc/kernel/store/<hash>.json) gives O(1) `stat` without re-canonicalizing. OMC_KERNEL_ROOT env overrides the store location. Honest limits documented in docs/omc_kernel.md: - No daemon yet (CLI-level only) - No peer-to-peer discovery (single-node) - No outgoing-edge graph (Merkle DAG edges are a one-pass extension) - No GC, no on-disk compression Each is a separable extension that doesn't require redesigning the address scheme. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 0d4ceb9 commit 20196db

5 files changed

Lines changed: 577 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ These are concrete, present-in-the-code features, not aspirations:
3636

3737
- **`omc-grep`: alpha-rename-invariant duplicate finder.** A standalone CLI ([`docs/omc_grep.md`](docs/omc_grep.md)) that walks a tree, extracts every top-level fn, canonicalizes, and clusters by canonical hash. `--body-only` mode strips the fn signature so duplicates with *different names* surface — something text-grep, ast-grep, and tree-sitter queries can't do. On OMC's own examples tree (151 files / 2388 fns): **31.7%** redundancy with name-sensitive hashing, **33.0%** with body-only — surfacing renamed-but-identical fns like `_bucket_discrete``endpoint_bucket``status_bucket` that share no token in their names.
3838

39+
- **`omc-kernel`: content-addressed code DAG keyed by canonical hash.** A persistence layer for distributed-agent code exchange ([`docs/omc_kernel.md`](docs/omc_kernel.md)). Every fn gets stored at `~/.omc/kernel/store/<hex_hash>.omc`. `omc-kernel sign FILE` emits a substrate-signed wire message; `omc-kernel verify` (stdin) recovers the original canonical form from the store — proven end-to-end with alpha-rename: sender's `fn commit(handle)` recovers as store's `fn commit(conn)`. Code becomes a content-addressed Merkle DAG over substrate addresses; version it the way IPFS versions files, except the addressing is semantic.
40+
3941
- **Substrate-keyed code codec + compressed substrate-signed messaging.** `omc_codec_encode` produces a sampled-token payload addressed by the canonical AST hash (invariant under whitespace, comments, alpha-rename). `omc_codec_decode_lookup` returns the exact library entry on hash match. `omc_msg_sign_compressed` / `omc_msg_recover_compressed` carry the codec payload inside the substrate-signed wire format with lossless library recovery and full signature integrity. **Wire-byte sizing is honest**: token-count compression is ~N×, but wire-byte savings only appear at payloads ≳500 B with N≥8 (single-message). The always-on value is **library-lookup recovery** — alpha-rename invariant content addressing on the receiver, no shared key. 13 tests pass ([`test_codec.omc`](examples/tests/test_codec.omc), [`test_compressed_messaging.omc`](examples/tests/test_compressed_messaging.omc)). See [`experiments/seed_expansion/FINDINGS.md`](experiments/seed_expansion/FINDINGS.md).
4042

4143
---
@@ -264,7 +266,7 @@ fn coherent_loop(n) {
264266
|---|---|
265267
| `omnimcode-core/` | Parser, AST, interpreter, bytecode VM, substrate (`phi_pi_fib`), HBit, harmonic types, 50+ substrate builtins, substrate-routed heal pass |
266268
| `omnimcode-codegen/` | LLVM-backed JIT, dual-band lowerer, L1.6 array bridges, 22 harmonic-primitive intrinsics (table-driven) |
267-
| `omnimcode-cli/` | Standalone binary (`omnimcode-standalone`) + `omc-bench` + `omc-grep` |
269+
| `omnimcode-cli/` | Standalone binary (`omnimcode-standalone`) + `omc-bench` + `omc-grep` + `omc-kernel` |
268270
| `omnimcode-wasm/` | WebAssembly target (no LLVM, no Python) |
269271
| `omnimcode-lsp/` | LSP server for editor integration |
270272
| `omnimcode-gdextension/` | Godot 4 GDExtension binding |
@@ -354,6 +356,7 @@ Submit a package: PR an entry to [`registry/index.json`](registry/index.json).
354356
| **Substrate-keyed code codec + compressed messaging** | **shipped**, `omc_codec_encode/decode_lookup` + `omc_msg_sign_compressed/recover`, alpha-rename invariant, token-count ~N× (wire-byte breaks even at ≥500 B + N≥8); always-on win is library-lookup recovery; 13 tests, lossless on in-library content |
355357
| **Inline error-fix hints** | **shipped**, `Undefined function` errors now carry the suggested fn's signature inline (eliminates a separate `omc_help` round-trip after a typo) |
356358
| **`omc-grep`: alpha-rename-invariant code archaeology** | **shipped** ([docs/omc_grep.md](docs/omc_grep.md)) — standalone CLI; on OMC's examples: 31.7% redundancy (name-sensitive), 33.0% (body-only); surfaces renamed-but-identical fns that text-grep and ast-grep can't catch |
359+
| **`omc-kernel`: content-addressed code DAG** | **shipped** ([docs/omc_kernel.md](docs/omc_kernel.md)) — store at ~/.omc/kernel/store/<hash>.omc; alpha-rename invariant sign/verify proven end-to-end; the persistence layer for the codec wire format |
357360
| Two-engine parity (tree-walk + VM) | shipped, 44/45 byte-identical |
358361
| Embedded CPython + callbacks | shipped, 6 wrapper libs |
359362
| WASM + LSP + GDExtension targets | shipped |

docs/omc_kernel.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# omc-kernel — content-addressed code DAG over canonical hashes
2+
3+
> **Code as a content-addressed Merkle DAG over substrate-canonical
4+
> addresses.** Version code the way IPFS versions files, except the
5+
> addressing is semantic instead of byte-level — alpha-rename,
6+
> whitespace, and comment edits all collapse to the same address.
7+
8+
## What it does
9+
10+
A standalone CLI that maintains a file-system content-addressed
11+
store at `~/.omc/kernel/store/<canonical_hash_hex>.omc`. Every OMC
12+
fn has a 64-bit canonical-hash identity (whitespace-stripped,
13+
comments removed, parameter binding normalized), and the store is
14+
keyed on that.
15+
16+
Subcommands:
17+
18+
| Command | Purpose |
19+
|---|---|
20+
| `omc-kernel ingest DIR` | walk DIR, extract every top-level fn from `.omc` files, store one entry per canonical hash |
21+
| `omc-kernel fetch HASH` | retrieve stored source by canonical hash (hex) |
22+
| `omc-kernel stat HASH` | substrate metadata: attractor, distance, fn name, origin file |
23+
| `omc-kernel ls` | list stored hashes + fn names |
24+
| `omc-kernel sign FILE` | emit a substrate-signed wire message for the OMC source in FILE |
25+
| `omc-kernel verify` | read a wire message from stdin, recover content via store lookup |
26+
| `omc-kernel demo` | end-to-end alpha-rename invariant recovery |
27+
28+
## End-to-end proof (the actual run)
29+
30+
```bash
31+
$ omc-kernel ingest examples/lib/
32+
ingested 206 fns: 184 new, 22 already present in store
33+
34+
$ cat > /tmp/renamed.omc <<'EOF'
35+
fn commit(handle) { return py_call(handle, "commit", []); }
36+
EOF
37+
38+
$ omc-kernel sign /tmp/renamed.omc | tee wire.json > /dev/null
39+
# wire is a JSON dict with content_hash + sampled_tokens
40+
41+
$ omc-kernel verify < wire.json
42+
verify: content_hash = 02158af4e9935df8
43+
verify: store hash matches; recovered 59 bytes
44+
fn commit(conn) {
45+
return py_call(conn, "commit", []);
46+
}
47+
```
48+
49+
Sender wrote `fn commit(handle)`; receiver recovered `fn commit(conn)`
50+
— the canonical form already stored. Same canonical-hash address, no
51+
shared key, no certificate authority. Alpha-rename + whitespace
52+
invariance is intrinsic to the addressing.
53+
54+
## Why this is a kernel primitive
55+
56+
The store is a "kernel" in the OS sense: a single shared substrate
57+
that holds canonical-form content and serves it to any agent that
58+
asks for it by hash. The codec we shipped earlier (`omc_msg_*`)
59+
produces wire messages keyed on the same canonical hash; the kernel
60+
is the backing store that makes recovery work.
61+
62+
Combined, you get the building blocks for a distributed code DAG:
63+
- Each fn has a 64-bit stable identity (canonical hash)
64+
- Each fn's dependencies (callees) form an outgoing-edge set — also
65+
hashes
66+
- The DAG is content-addressed end-to-end; no naming conflicts,
67+
no version-string negotiation
68+
- Substrate signature verifies content integrity without a key
69+
(recompute and compare)
70+
71+
## What's NOT shipped (honest limits)
72+
73+
- **No daemon yet.** All operations are CLI-level on the store
74+
directly. Multi-process/multi-host access requires a wrapper
75+
(Unix domain socket / HTTP / gRPC — pick later).
76+
- **No peer-to-peer discovery.** Single-node only. Cross-host
77+
replication is a follow-on layer: each peer holds its own store,
78+
fetches can fall back to peers on miss.
79+
- **No outgoing-edge graph.** Each store entry has a sidecar with
80+
substrate metadata but no callee list. Building the Merkle DAG
81+
edges requires parsing each fn's calls and recording their
82+
canonical hashes. One-pass extension.
83+
- **Garbage collection.** No reference counting; entries persist
84+
until manually deleted. Reasonable for the prototype.
85+
- **Compression on disk.** Each entry is stored as raw source for
86+
human inspection. Could swap to the codec payload for ~5–7× disk
87+
savings on larger libraries (with the store itself as the
88+
recovery library — circular but the recovery path is unchanged).
89+
90+
Each limit is a separable extension that doesn't require redesign
91+
of the address scheme.
92+
93+
## Building
94+
95+
```bash
96+
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 cargo build --release --bin omc-kernel
97+
./target/release/omc-kernel demo
98+
```
99+
100+
No JIT or Python deps required.
101+
102+
## Environment
103+
104+
| Var | Purpose | Default |
105+
|---|---|---|
106+
| `OMC_KERNEL_ROOT` | override store location | `~/.omc/kernel` |
107+
108+
## Relationship to the existing pieces
109+
110+
| Layer | Provides | Used by |
111+
|---|---|---|
112+
| `canonical::canonicalize` | the canonical-form normalizer | omc-kernel, omc-grep, codec |
113+
| `tokenizer::fnv1a_64` | 64-bit canonical hash | all three |
114+
| `phi_pi_fib::nearest_attractor_with_dist` | Fibonacci-attractor metadata | omc-kernel `stat`, codec messages |
115+
| `omc_msg_sign_compressed` / `_recover_*` | OMC-builtin wire codec | sender side of the kernel |
116+
| **`omc-kernel`** | **persistent content-addressed store** | **receiver side** |
117+
118+
The four-layer stack: substrate primitives → tokenizer → codec →
119+
kernel-store. Everything below the kernel exists already; the
120+
kernel is the persistence + retrieval layer that makes them
121+
compose into a real distributed-agent system.

omnimcode-cli/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ required-features = ["llvm-jit"]
2828
name = "omc-grep"
2929
path = "src/bin/omc_grep.rs"
3030

31+
# Content-addressed store keyed by canonical hash. The distributed-agent
32+
# kernel primitive: code as a content-addressed Merkle DAG over
33+
# substrate-canonical addresses. Uses serde_json for wire format.
34+
[[bin]]
35+
name = "omc-kernel"
36+
path = "src/bin/omc_kernel.rs"
37+
3138
[features]
3239
default = ["python-embed"]
3340
# CPython embedding for `py_*` builtins. Forwards to core.
@@ -40,6 +47,7 @@ llvm-jit = ["dep:omnimcode-codegen", "dep:inkwell"]
4047
[dependencies]
4148
omnimcode-core = { path = "../omnimcode-core", default-features = false }
4249
omnimcode-codegen = { path = "../omnimcode-codegen", optional = true, features = ["llvm-jit"] }
50+
serde_json = "1.0" # used by omc-kernel for wire-format messages
4351
# inkwell is needed at the CLI level only because we leak the LLVM
4452
# Context for process-lifetime; the dispatch closure lives on the
4553
# Interpreter and references the engine memory.

0 commit comments

Comments
 (0)