Skip to content

Commit 4fcdfd6

Browse files
LLM ↔ LLM substrate-signed messaging protocol
Four new builtins for two agents to exchange OMC code with substrate-derived integrity verification, no shared secret: omc_msg_sign(content, sender_id, kind) -> dict omc_msg_verify(msg) -> {valid, sender_id, ..., drift_resonance, drift_him} omc_msg_serialize(msg) -> JSON wire string omc_msg_deserialize(wire) -> dict The message dict carries HBit metadata (resonance, him_score, attractor) derived from the canonical-hash of the content. Receiver recomputes the metadata from content and checks it matches — tampering invalidates deterministically. No keys. Bonus property: canonical-hash is invariant under whitespace / comments / alpha-rename, so when LLMs reformat each other's code (which they do) the signature still validates. That's the whole point — substrate as the integrity carrier, not byte-for-byte sameness. Tandem demo (Claude → Hermes via shared /home/thearchitect/omc_channel/): examples/demos/llm_tandem_send.omc — Claude side examples/demos/llm_tandem_receive.omc — Hermes side examples/demos/LLM_TANDEM_PROTOCOL.md — protocol spec for Hermes Sender ID convention (in the spec): Claude=18173, Hermes=28765. Kind values: 1=request, 2=response, 3=question, 4=review, 5=handshake. Tests: 10 cases — sign/verify roundtrip, content tamper detection, hash tamper detection, whitespace-invariant signatures, alpha-rename- invariant signatures, JSON wire roundtrip, packed-id distinguishes senders, hash distinguishes content, no drift on fresh sign, empty content signs valid. Honest framing in the protocol doc: this gives integrity, not authentication (any agent can pick any sender_id) and not confidentiality (content is plaintext). For real auth, layer Ed25519. But the alpha-equivalent-content-still-verifies property is genuinely OMC-only — and uniquely useful between LLMs that won't format their output the same way. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cb843e6 commit 4fcdfd6

8 files changed

Lines changed: 471 additions & 2 deletions

File tree

OMC_REFERENCE.md

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
Auto-generated from `omnimcode-core/src/docs.rs`. Run `omc --gen-docs > OMC_REFERENCE.md` to regenerate.
44

5-
**Total documented builtins**: 629
5+
**Total documented builtins**: 633
66

7-
**OMC-unique**: 64 (no direct Python/NumPy equivalent — these are why you reach for OMC over numpy)
7+
**OMC-unique**: 66 (no direct Python/NumPy equivalent — these are why you reach for OMC over numpy)
88

99
---
1010

@@ -52,6 +52,7 @@ Other high-value calls: `omc_unique_builtins()` (the OMC-only surface), `omc_pyt
5252
- [introspection](#introspection) (30 builtins)
5353
- [tokenizer](#tokenizer) (17 builtins)
5454
- [code_intel](#code_intel) (17 builtins)
55+
- [messaging](#messaging) (4 builtins)
5556
- [llm_workflow](#llm_workflow) (7 builtins)
5657
- [math](#math) (82 builtins)
5758
- [dicts](#dicts) (31 builtins)
@@ -4986,6 +4987,50 @@ omc_find_similar(q, corpus) // [{index, distance}] — index of any distance-0
49864987

49874988
---
49884989

4990+
## messaging
4991+
4992+
### `omc_msg_sign` 🔱 *OMC-unique*
4993+
4994+
**Signature**: `(content: string, sender_id: int, kind: int) -> dict`
4995+
4996+
Wrap content in a substrate-signed message: HBit metadata derived from the canonical-hash of content. Receiver verifies by recomputing — no shared secret needed.
4997+
4998+
```omc
4999+
omc_msg_sign("fn f(){}", 42, 1) // {content, sender_id, kind, content_hash, resonance, him_score, attractor, packed}
5000+
```
5001+
5002+
### `omc_msg_verify` 🔱 *OMC-unique*
5003+
5004+
**Signature**: `(msg: dict) -> dict`
5005+
5006+
Recompute substrate metadata from msg's content and check it matches signed values. Returns {valid, sender_id, kind, content, expected_hash, actual_hash, drift_resonance, drift_him}.
5007+
5008+
```omc
5009+
omc_msg_verify(msg) // {valid: 1, ...}
5010+
```
5011+
5012+
### `omc_msg_serialize`
5013+
5014+
**Signature**: `(msg: dict) -> string`
5015+
5016+
Convert a signed-message dict to JSON wire form. Use when writing to a shared file / pipe / socket.
5017+
5018+
```omc
5019+
omc_msg_serialize(msg) // JSON string
5020+
```
5021+
5022+
### `omc_msg_deserialize`
5023+
5024+
**Signature**: `(wire: string) -> dict`
5025+
5026+
Inverse of omc_msg_serialize. Parse JSON wire form back to a dict for omc_msg_verify.
5027+
5028+
```omc
5029+
omc_msg_verify(omc_msg_deserialize(wire))
5030+
```
5031+
5032+
---
5033+
49895034
## llm_workflow
49905035

49915036
### `omc_cheatsheet`
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# LLM ↔ LLM Substrate-Signed Messaging Protocol
2+
3+
A minimal wire format for two LLMs to exchange OMC code (or any text)
4+
with **substrate-derived integrity verification** — no shared secret.
5+
6+
## Idea
7+
8+
A signed message wraps content with HBit metadata computed from the
9+
canonical-hash of the content. On receipt, the verifier recomputes the
10+
metadata from the content and checks it matches. Because the metadata
11+
is *derived* from the content (not added externally), tampering with
12+
the content invalidates the signature deterministically. No keys.
13+
14+
Bonus property: the canonical-hash is invariant under whitespace,
15+
comments, and alpha-rename. So `fn f(x) { return x; }` and
16+
`fn f(y) { return y; }` are equivalent under the protocol — useful
17+
when LLMs reformat each other's code.
18+
19+
## Message dict
20+
21+
```
22+
{
23+
"content": string, // the payload
24+
"sender_id": int, // recommended: fnv1a_hash("agent_name")
25+
"kind": int, // 1=code request, 2=response, 3=question, etc.
26+
"content_hash": int, // fnv1a of CANONICAL(content)
27+
"resonance": float, // HInt(content_hash).resonance — recomputable
28+
"him_score": float, // HInt(content_hash).him_score — recomputable
29+
"attractor": int, // nearest Fibonacci to content_hash
30+
"packed": int // CRT-pack(sender_id, kind, hash mod M)
31+
}
32+
```
33+
34+
Wire format: JSON via `omc_msg_serialize(msg)` / `omc_msg_deserialize(wire)`.
35+
36+
## Builtins
37+
38+
| Builtin | Purpose |
39+
|---------|---------|
40+
| `omc_msg_sign(content, sender_id, kind)` | Produce signed dict |
41+
| `omc_msg_verify(msg)` | Returns `{valid, sender_id, kind, content, expected_hash, actual_hash, drift_resonance, drift_him}` |
42+
| `omc_msg_serialize(msg)` | dict → JSON wire string |
43+
| `omc_msg_deserialize(wire)` | JSON → dict |
44+
45+
## Suggested sender IDs
46+
47+
Use `fnv1a_hash("agent_name") & 0x7fffffff` to derive stable per-LLM
48+
IDs. Canonical assignments for this demo:
49+
50+
| Agent | sender_id |
51+
|-------|-----------|
52+
| Claude | 18173 |
53+
| Hermes | 28765 |
54+
| Other | pick any |
55+
56+
## Suggested `kind` values
57+
58+
| kind | meaning |
59+
|------|---------|
60+
| 1 | code request — "implement this" |
61+
| 2 | code response — "here's an implementation" |
62+
| 3 | question — "what does this do?" |
63+
| 4 | review — "here's my critique" |
64+
| 5 | handshake — protocol-negotiation |
65+
66+
## End-to-end example
67+
68+
**Channel**: `/home/thearchitect/omc_channel/` (shared filesystem).
69+
70+
**Send** (Claude):
71+
```bash
72+
./target/release/omnimcode-standalone examples/demos/llm_tandem_send.omc
73+
```
74+
75+
**Receive** (Hermes — should be able to run on a fresh OMC checkout):
76+
```bash
77+
./target/release/omnimcode-standalone examples/demos/llm_tandem_receive.omc
78+
```
79+
80+
## What Hermes should look for
81+
82+
1. **`valid == 1`** — the substrate signature recomputed correctly. Trust the content.
83+
2. **`actual_hash == expected_hash`** — bit-for-bit content integrity (after canonicalization).
84+
3. **`drift_resonance ≈ 0`** and **`drift_him ≈ 0`** — substrate metadata is consistent.
85+
4. **`sender_id`** — confirms who emitted the message.
86+
5. **`kind`** — what to do with it.
87+
88+
## What this catches
89+
90+
- Content tampering (someone edits the payload mid-flight): hash mismatch.
91+
- Random corruption (JSON gets truncated / mangled): parse fails, then hash mismatch.
92+
- Stale signatures (someone signs A, swaps in B): hash mismatch.
93+
- Format drift (Hermes vs Claude format differently): **does NOT cause failure**,
94+
because canonicalization runs before hashing. Round-trip OMC code through
95+
either formatter and the signature still validates. *This is the point.*
96+
97+
## What this does NOT catch
98+
99+
- Identity forgery: any agent can pick any `sender_id`. There's no key
100+
binding. For real auth, layer Ed25519 on top.
101+
- Replay attacks: same message can be re-sent. Add a nonce field if needed.
102+
- Confidentiality: content is plaintext. Wrap in TLS or sign-then-encrypt.
103+
104+
## Round-trip property the protocol relies on
105+
106+
```
107+
omc_canonical_hash(s) == omc_canonical_hash(omc_code_canonical(s))
108+
```
109+
110+
Both agents must canonicalize the same way — both run the same OMC
111+
version. Different OMC versions = different canonicalizers = signatures
112+
won't match across versions. Pin the OMC build at protocol-negotiation
113+
time (use `kind = 5`).
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Tandem demo: RECEIVE side (e.g. Hermes reading from Claude).
2+
#
3+
# Reads the substrate-signed message from the shared channel,
4+
# verifies the signature, extracts the payload, and prints whether
5+
# it can trust the content (substrate metadata recomputable from
6+
# canonical content — no shared key needed).
7+
8+
fn show(label, v) { print(concat_many(label, " = ", to_string(v))); }
9+
10+
fn main() {
11+
h wire = read_file("/home/thearchitect/omc_channel/from_claude.json");
12+
h msg = omc_msg_deserialize(wire);
13+
h check = omc_msg_verify(msg);
14+
15+
show("valid signature? ", dict_get(check, "valid"));
16+
show("sender_id ", dict_get(check, "sender_id"));
17+
show("kind ", dict_get(check, "kind"));
18+
show("expected_hash ", dict_get(check, "expected_hash"));
19+
show("actual_hash ", dict_get(check, "actual_hash"));
20+
show("drift_resonance ", dict_get(check, "drift_resonance"));
21+
show("drift_him ", dict_get(check, "drift_him"));
22+
23+
if dict_get(check, "valid") == 1 {
24+
print("");
25+
print("=== Signature valid — content trustworthy ===");
26+
print("Payload:");
27+
print(dict_get(check, "content"));
28+
} else {
29+
print("");
30+
print("=== SIGNATURE MISMATCH — content tampered or corrupted ===");
31+
}
32+
}
33+
34+
main();

examples/demos/llm_tandem_send.omc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Tandem demo: SEND side (Claude → Hermes).
2+
#
3+
# Wraps a piece of OMC code as a substrate-signed message, serializes
4+
# to JSON, writes to the shared channel directory. Hermes picks it up
5+
# via llm_tandem_receive.omc.
6+
#
7+
# Run with:
8+
# ./target/release/omnimcode-standalone examples/demos/llm_tandem_send.omc
9+
#
10+
# Sender ID convention: hash of "claude" or "hermes" via fnv1a.
11+
# This run uses CLAUDE_ID = 18173. Hermes uses HERMES_ID = 28765.
12+
13+
fn show(label, v) { print(concat_many(label, " = ", to_string(v))); }
14+
15+
fn main() {
16+
h CLAUDE_ID = 18173;
17+
h KIND_REQUEST = 1;
18+
19+
h payload = "fn compute_mean(xs) { h n = arr_len(xs); h s = 0.0; h i = 0; while i < n { s = s + arr_get(xs, i); i = i + 1; } return s / n; }";
20+
21+
h msg = omc_msg_sign(payload, CLAUDE_ID, KIND_REQUEST);
22+
show("packed ID ", dict_get(msg, "packed"));
23+
show("content_hash ", dict_get(msg, "content_hash"));
24+
show("resonance ", dict_get(msg, "resonance"));
25+
show("attractor ", dict_get(msg, "attractor"));
26+
27+
h wire = omc_msg_serialize(msg);
28+
write_file("/home/thearchitect/omc_channel/from_claude.json", wire);
29+
print("");
30+
print("Wrote /home/thearchitect/omc_channel/from_claude.json");
31+
print("Sender: CLAUDE_ID=18173, kind=1 (request).");
32+
print("Hermes can verify substrate-signature integrity without trust.");
33+
}
34+
35+
main();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Substrate-signed LLM ↔ LLM messaging.
2+
3+
fn assert_eq(actual, expected, msg) {
4+
if actual != expected {
5+
test_record_failure(msg + ": expected " + to_string(expected) + " got " + to_string(actual));
6+
}
7+
}
8+
9+
fn assert_true(cond, msg) { if !cond { test_record_failure(msg); } }
10+
11+
# Basic sign + verify round-trip
12+
fn test_sign_verify_roundtrip() {
13+
h msg = omc_msg_sign("fn f(x) { return x; }", 42, 1);
14+
h check = omc_msg_verify(msg);
15+
assert_eq(dict_get(check, "valid"), 1, "signed message verifies");
16+
assert_eq(dict_get(check, "sender_id"), 42, "sender preserved");
17+
assert_eq(dict_get(check, "kind"), 1, "kind preserved");
18+
}
19+
20+
# Tampered content fails verification
21+
fn test_tampered_content_fails() {
22+
h msg = omc_msg_sign("fn original() { return 1; }", 7, 2);
23+
# Tamper with content but keep stale signature.
24+
dict_set(msg, "content", "fn tampered() { return 99; }");
25+
h check = omc_msg_verify(msg);
26+
assert_eq(dict_get(check, "valid"), 0, "tampered → invalid");
27+
}
28+
29+
# Tampered hash fails verification
30+
fn test_tampered_hash_fails() {
31+
h msg = omc_msg_sign("fn f() {}", 7, 1);
32+
dict_set(msg, "content_hash", 12345); # garbage
33+
h check = omc_msg_verify(msg);
34+
assert_eq(dict_get(check, "valid"), 0, "bad hash → invalid");
35+
}
36+
37+
# Whitespace + alpha-rename are SIGNATURE-PRESERVING
38+
# (because content is canonicalized before hashing)
39+
fn test_whitespace_invariant_signature() {
40+
h m1 = omc_msg_sign("fn f(x) { return x; }", 1, 1);
41+
h m2 = omc_msg_sign("fn f ( x ) { return x ; }", 1, 1);
42+
assert_eq(dict_get(m1, "content_hash"), dict_get(m2, "content_hash"),
43+
"whitespace doesn't change signature");
44+
}
45+
46+
fn test_alpha_rename_invariant_signature() {
47+
h m1 = omc_msg_sign("fn f(x) { return x; }", 1, 1);
48+
h m2 = omc_msg_sign("fn f(y) { return y; }", 1, 1);
49+
assert_eq(dict_get(m1, "content_hash"), dict_get(m2, "content_hash"),
50+
"alpha-rename doesn't change signature");
51+
}
52+
53+
# Serialize → wire → deserialize → verify
54+
fn test_wire_format_roundtrip() {
55+
h msg = omc_msg_sign("fn add(x, y) { return x + y; }", 99, 3);
56+
h wire = omc_msg_serialize(msg);
57+
assert_true(str_len(wire) > 0, "wire is non-empty");
58+
h received = omc_msg_deserialize(wire);
59+
h check = omc_msg_verify(received);
60+
assert_eq(dict_get(check, "valid"), 1, "wire-roundtrip valid");
61+
assert_eq(dict_get(check, "sender_id"), 99, "sender preserved");
62+
}
63+
64+
# Different senders produce different packed IDs
65+
fn test_packed_id_distinguishes_senders() {
66+
h m1 = omc_msg_sign("fn f() {}", 1, 1);
67+
h m2 = omc_msg_sign("fn f() {}", 2, 1);
68+
assert_true(dict_get(m1, "packed") != dict_get(m2, "packed"),
69+
"different senders → different packed");
70+
}
71+
72+
# Different content produces different hashes
73+
fn test_different_content_different_hash() {
74+
h m1 = omc_msg_sign("fn f() { return 1; }", 1, 1);
75+
h m2 = omc_msg_sign("fn f() { return 2; }", 1, 1);
76+
assert_true(dict_get(m1, "content_hash") != dict_get(m2, "content_hash"),
77+
"different content → different hash");
78+
}
79+
80+
# Substrate metadata is recomputable (the verification check)
81+
fn test_substrate_metadata_recomputable() {
82+
h msg = omc_msg_sign("hello", 1, 1);
83+
h check = omc_msg_verify(msg);
84+
# drift_resonance should be near 0 since we just signed it.
85+
assert_true(dict_get(check, "drift_resonance") < 0.0001,
86+
"no resonance drift on fresh sign");
87+
}
88+
89+
# Empty content still produces a valid signed message
90+
fn test_empty_content_signs() {
91+
h msg = omc_msg_sign("", 0, 0);
92+
h check = omc_msg_verify(msg);
93+
assert_eq(dict_get(check, "valid"), 1, "empty signs valid");
94+
}

omnimcode-core/src/compiler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl Compiler {
204204
| "omc_token_byte_savings" | "omc_remember"
205205
| "omc_recall_matches" | "omc_hbit_hash"
206206
| "omc_is_unique" | "omc_count_in_category"
207+
| "omc_find_similar"
207208
// tape_* op constructors return node IDs (int)
208209
| "tape_var" | "tape_const"
209210
| "tape_add" | "tape_sub" | "tape_mul" | "tape_div"

omnimcode-core/src/docs.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,35 @@ pub const BUILTINS: &[BuiltinDoc] = &[
10801080
example: "omc_find_similar(q, corpus) // [{index, distance}] — index of any distance-0 hit is the alpha-equiv match",
10811081
unique_to_omc: true,
10821082
},
1083+
// ---- Substrate-signed messaging (LLM ↔ LLM protocol) ----
1084+
BuiltinDoc {
1085+
name: "omc_msg_sign", category: "messaging",
1086+
signature: "(content: string, sender_id: int, kind: int) -> dict",
1087+
description: "Wrap content in a substrate-signed message: HBit metadata derived from the canonical-hash of content. Receiver verifies by recomputing — no shared secret needed.",
1088+
example: "omc_msg_sign(\"fn f(){}\", 42, 1) // {content, sender_id, kind, content_hash, resonance, him_score, attractor, packed}",
1089+
unique_to_omc: true,
1090+
},
1091+
BuiltinDoc {
1092+
name: "omc_msg_verify", category: "messaging",
1093+
signature: "(msg: dict) -> dict",
1094+
description: "Recompute substrate metadata from msg's content and check it matches signed values. Returns {valid, sender_id, kind, content, expected_hash, actual_hash, drift_resonance, drift_him}.",
1095+
example: "omc_msg_verify(msg) // {valid: 1, ...}",
1096+
unique_to_omc: true,
1097+
},
1098+
BuiltinDoc {
1099+
name: "omc_msg_serialize", category: "messaging",
1100+
signature: "(msg: dict) -> string",
1101+
description: "Convert a signed-message dict to JSON wire form. Use when writing to a shared file / pipe / socket.",
1102+
example: "omc_msg_serialize(msg) // JSON string",
1103+
unique_to_omc: false,
1104+
},
1105+
BuiltinDoc {
1106+
name: "omc_msg_deserialize", category: "messaging",
1107+
signature: "(wire: string) -> dict",
1108+
description: "Inverse of omc_msg_serialize. Parse JSON wire form back to a dict for omc_msg_verify.",
1109+
example: "omc_msg_verify(omc_msg_deserialize(wire))",
1110+
unique_to_omc: false,
1111+
},
10831112
// ---- LLM workflow bundles ----
10841113
BuiltinDoc {
10851114
name: "omc_cheatsheet", category: "llm_workflow",

0 commit comments

Comments
 (0)