7 releases (4 breaking)
| 0.5.2 | May 6, 2026 |
|---|---|
| 0.5.1 | May 6, 2026 |
| 0.4.0 | May 6, 2026 |
| 0.3.0 | May 6, 2026 |
| 0.1.0 | May 5, 2026 |
#843 in Encoding
710KB
10K
SLoC
OSMP Rust SDK
Rust implementation of the Octid Semantic Mesh Protocol. Encodes, decodes, composes, and validates agentic AI instructions using SAL (Semantic Assembly Language). 356 opcodes across 26 namespaces (v15.1) with the v16 namespace expansion (3-character primaries with v15 single-letter siblings) bundled in. Deterministic decode to structured instructions. No inference. Cross-SDK byte-identical with the Python, TypeScript, and Go SDKs.
Status
Pre-1.0 (0.5.2). Full feature parity with Python / TypeScript / Go: core encode/decode, ASD dictionary, v16 namespace mapping, SAL grammar, validator, macro registry, SALBridge, FNP packet codec (40-byte ADV / 38-byte ACK with ADR-004 basis-manifest extended-form), overflow protocol (Tier 1/2/3 DAG), BAEL bridge-layer mode selector, ADP session protocol (A:ASD version identity / query / alert / REQ / DELTA / DEF / HASH plus A:MDR corpus version family with priority classification and pending-queue resolution), D:PACK encode (raw blocks) + decode (raw blocks AND zstd-compressed blocks; reads shipped MDR corpora end-to-end), EML fast-mode math (pure-Rust port of Sun fdlibm, byte-identical with the Python / Go / TypeScript fdlibm modules), the 89-macro EML MDR registry with ParametricChain::evaluate, restricted/wide chain wire codec (encode_chain_restricted/wide + decode_chain_restricted/wide), paper tree wire codec (EMLNode + encode_tree + decode_tree with f32 / f64 leaf modes), and SHA-256 corpus fingerprint (corpus_fingerprint_mdr + corpus_fingerprint_envelope_bounded), and the unified wire codec (SAILCodec binary + SecCodec ChaCha20-Poly1305 + Ed25519 envelope with inbound replay protection + OSMPWireCodec mode router across {Mnemonic, SAIL, SEC, SAILSEC}) all ship at parity.
Notes from 0.4.0
0.4.0 introduced the breaking signature changes documented below. 0.5.x is purely additive over 0.4.0: ADP session protocol, EML chain wire codec, ParametricChain::evaluate, paper tree codec (EMLNode + encode_tree + decode_tree), and corpus-fingerprint API are all new public surfaces; nothing already shipped in 0.4.0 changes shape.
Breaking from 0.3.0
SecCodec::unpackis now&mut self(was&self). The unpack path advances per-sender replay-protection state on success; replay attempts returnSecError::ReplayDetected { node_id, seq_counter, last_accepted }.OSMPWireCodec::decodeis now&mut selffor the same reason (theSECandSAILSECmodes route throughSecCodec::unpack).eml::fdlibm::expandeml::fdlibm::logare no longer wrappers aroundf64::exp/f64::ln. They are now a faithful pure-Rust port of Sun fdlibm with the same constants and the same operations as the Python / Go / TypeScript fdlibm modules. Output for ordinary inputs is byte-identical with those SDKs and 1-ULP-accurate against the true mathematical value.
The SHA-256 ASD fingerprint is byte-identical with the other three SDKs: 9ecc507e2c24c4a7. The fingerprint_cross_sdk_identical test in CI fails the build if Rust ever diverges.
Install
[dependencies]
osmp = "0.5"
MSRV: Rust 1.70 (uses std::sync::OnceLock, stabilized in 1.70). Runtime crypto deps for the SEC envelope (chacha20poly1305, ed25519-dalek, rand) are pulled in when the wire layer is constructed; ruzstd (pure-Rust, no C build deps) is pulled in for D:PACK zstd decompression on shipped MDR corpora; the SAL text encoder/decoder requires only sha2, serde, serde_json, and regex.
Quick Start
use osmp::AdaptiveSharedDictionary;
let asd = AdaptiveSharedDictionary::new();
// Lookup an opcode definition
let definition = asd.lookup("H", "HR"); // Some("heart_rate")
// Cross-SDK fingerprint
let fp = asd.fingerprint();
assert_eq!(fp, "9ecc507e2c24c4a7");
Decode
use osmp::Decoder;
let dec = Decoder::new(None);
let result = dec.decode_frame("H:HR@NODE1>120").expect("valid SAL");
assert_eq!(result.namespace, "H");
assert_eq!(result.opcode, "HR");
assert_eq!(result.opcode_meaning.as_deref(), Some("heart_rate"));
assert_eq!(result.target.as_deref(), Some("NODE1>120"));
Encode
use osmp::Encoder;
let enc = Encoder::new(None);
let sal = enc.encode_sequence(&["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"]);
// "H:HR@NODE1>120;H:CASREP;M:EVA@*"
Validate
Eight deterministic rules enforced before any instruction hits the wire:
use osmp::{validate_composition, Severity};
let result = validate_composition("R:MOV@BOT1⚠", "", None, true, None);
assert!(!result.valid()); // ⚠ requires I:§ precondition
for issue in result.errors() {
println!("{:?}: {}", issue.rule, issue.message);
}
The eight rules are: hallucinated opcode, namespace-as-target, R-namespace consequence class, I:§ precondition for ⚠/⊘, BAEL byte floor, slash rejection, mixed-mode, and regulatory dependency (REQUIRES rules from loaded MDR corpora).
v16 Namespace Mapping
The v16 namespace expansion makes 3-character primaries the canonical form (e.g. AGT for agentic instead of A) while preserving v15 single-letter forms as deprecated siblings. The split letters C/D/K/Q resolve via the bridge composer disambiguation table (e.g. C:ALLOC → CMP, C:QUOTA → RES, D:STAT → XFR).
use osmp::disambiguate_to_v16;
assert_eq!(disambiguate_to_v16("A", "ACK"), Some("AGT"));
assert_eq!(disambiguate_to_v16("C", "ALLOC"), Some("CMP"));
assert_eq!(disambiguate_to_v16("D", "STAT"), Some("XFR"));
assert_eq!(disambiguate_to_v16("Q", "FLAG"), Some("QLT")); // default-to-QLT
assert_eq!(disambiguate_to_v16("AGT", "ACK"), Some("AGT")); // pass-through
SALBridge — Propagation by Contact
When your agents communicate with non-OSMP peers, the bridge handles boundary translation. Outbound SAL is decoded to annotated natural language; inbound messages are scanned for SAL acquisition. Peers that learn SAL through contextual exposure transition from FALLBACK to ACQUIRED. OSMP spreads by contact, not installation.
use osmp::SALBridge;
let mut bridge = SALBridge::new("MY_NODE", None, true);
bridge.register_peer("GPT_AGENT", false);
// Outbound: SAL decoded to NL, annotated with SAL equivalent
let out = bridge.send("H:HR@NODE1>120", "GPT_AGENT");
// Inbound: scanned for SAL acquisition
let result = bridge.receive("A:ACK", "GPT_AGENT");
EML — Universal Binary Operator Evaluator
A companion math-evaluation submodule. Based on Odrzywołek (2026, arXiv:2603.21852): a single binary operator eml(x, y) = exp(x) − ln(y), together with the constant 1, generates the standard calculator function basis as compact expression trees.
Byte-exact evaluation across Python, TypeScript, Go, and Rust on every IEEE-754-conformant platform.
use osmp::{eml, eml_macro_count, eml_mdr_lookup};
// The operator itself
let v = eml(2.0, 1.0); // exp(2) - ln(1) = 7.389056...
// 89-macro registry (cross-SDK byte-identical with Python / TS / Go)
assert_eq!(eml_macro_count(), 89);
// Look up a macro by 3-character shorthand ID
if let Some(m) = eml_mdr_lookup("EXP") {
println!("{} ({:?}): {}", m.shorthand_id, m.function_class, m.description);
}
Precision Modes
Two modes:
- Fast (default) — fdlibm-derived, 1-ULP accurate, ships publicly. Correct for LoRa/BLE/edge-ML, drone swarm coordination, and general scientific computation.
- Precision — crlibm-derived, correctly-rounded, audit-grade. For regulated industries (medical IEC 62304, aerospace DO-178C, nuclear IEC 61513), audit-grade finance, and cryptographic protocol-frame hash inputs. Available under commercial license — contact
ack@octid.io.
use osmp::eml::{eml_precise, EmlError};
match eml_precise(2.0, 1.0) {
Ok(v) => println!("precision result: {v}"),
Err(EmlError::PrecisionUnavailable) => {
println!("precision mode requires the commercial precision pack");
}
}
Wire Codec — Four Modes
Four wire modes selectable per message via WireMode:
| Mode | Byte | Description |
|---|---|---|
Mnemonic |
0x00 |
UTF-8 SAL text (human-readable) |
SAIL |
0x01 |
Binary SAIL (single-byte tokens + intern table) |
SEC |
0x02 |
SAL text + ChaCha20-Poly1305 + Ed25519 envelope |
SAILSEC |
0x03 |
Binary SAIL + ChaCha20-Poly1305 + Ed25519 envelope |
OSMPWireCodec routes per-mode encode and decode. Cross-SDK byte-identical with Python wire.py, Go wire.go, and TypeScript osmp_wire.ts.
use osmp::{OSMPWireCodec, WireMode};
// Loopback codec — fresh keys generated; pass Some(&seed)/Some(&key) for fixed identity.
let mut codec = OSMPWireCodec::new(&[0x00, 0x01], None, None).expect("construct");
// Mnemonic — pass-through UTF-8.
let m = codec.encode("H:HR@NODE1", WireMode::Mnemonic).unwrap();
// SAIL — binary SAL, one-byte tokens + intern table built from the v15 ASD basis.
let s = codec.encode("H:HR@NODE1\u{2192}H:CASREP", WireMode::SAIL).unwrap();
let back = codec.decode(&s, WireMode::SAIL).unwrap();
assert_eq!(back, "H:HR@NODE1\u{2192}H:CASREP");
// SEC — 87 bytes overhead for 2-byte node_id (89 for 4-byte).
let envelope = codec.encode("H:HR@NODE1", WireMode::SEC).unwrap();
let plain = codec.decode(&envelope, WireMode::SEC).unwrap();
// SAILSEC — binary + envelope; minimal wire form for HAZARDOUS payloads.
let sec_sail = codec.encode("R:MOV@BOT1\u{26A0}", WireMode::SAILSEC).unwrap();
The SEC envelope derives its 12-byte ChaCha20-Poly1305 nonce from the envelope header padded with the canonical salt b"OSMP-SEC-v1\x00" (byte-identical across all four SDKs). Ed25519 signs header || ciphertext || auth_tag.
FNP — Frame Negotiation Protocol
Two-message handshake completing in 78 bytes total (40-byte ADV + 38-byte ACK), designed for the LoRa SF12 51-byte payload floor. ADR-004 extended-form ADV (msg_type 0x81) carries an 8-byte basis fingerprint at offset 32 for EstablishedSAIL capability grading.
use osmp::{AdaptiveSharedDictionary, FNPSession, FNPState, FNP_CAP_FLOOR};
let asd = AdaptiveSharedDictionary::new();
let mut a = FNPSession::new_with_version(&asd, "NODE_A", 1, FNP_CAP_FLOOR);
let mut b = FNPSession::new_with_version(&asd, "NODE_B", 1, FNP_CAP_FLOOR);
let adv = a.initiate().expect("A initiates"); // 40 bytes
let ack = b.receive(&adv).unwrap().expect("B replies"); // 38 bytes
assert_eq!(b.state, FNPState::EstablishedSAIL);
a.receive(&ack).unwrap();
assert_eq!(a.state, FNPState::EstablishedSAIL);
ADR-004 basis-manifest mode is enabled by passing FNPSessionOptions { basis_fingerprint: Some(vec![..; 8]), .. } to FNPSession::new_with_options.
Test
cd sdk/rust
cargo test
cargo clippy --all-targets -- -D warnings
The cross-SDK fingerprint test is the runtime gate for byte-identical compatibility with Python, TypeScript, and Go.
License
Apache 2.0.
Dependencies
~5.5–8.5MB
~160K SLoC