axonos-protocol is the wire-level consent layer of AxonOS — the reference
implementation of the AxonOS Consent Protocol (ACP), specified in SPEC.md.
It carries a person's consent — grant, suspend, withdraw — across the AxonOS cognitive
mesh as bounded CBOR frames, enforces it with an exhaustive state machine, and engages a
hardware StimGuard the instant consent is withdrawn. The default build is no_std,
allocates nothing, and forbids unsafe at compile time.
ACP is an AxonOS protocol end to end: the specification and this implementation are
developed and maintained entirely within the AxonOS project. Where
axonos-consent is the kernel-level
consent primitive — an in-process FSM with formally-bounded withdrawal latency —
axonos-protocol is the network-level layer that makes that consent interoperable
between independent nodes on the wire.
Frozen vectors. Any change to the files under
tests/vectors/changes the protocol — the vectors are the contract, not a fixture.
| Repository | Role |
|---|---|
axonos-kernel |
The real-time no_std kernel — scheduler, SPSC, time, capability |
axonos-consent |
Kernel-level consent FSM, formally-bounded withdrawal latency |
axonos-protocol (this crate) |
Network-level consent — the AxonOS Consent Protocol, on the wire |
axonos-swarm |
The cognitive mesh transport ACP travels over |
axonos-conformance |
Byte-exact wire-format vectors + codecs in seven languages |
axonos-standard |
The normative AxonOS Standard and claims catalogue |
let result = engine.process_raw(&peer_id, cbor_bytes, now_us)?;A single entry point. It executes the full pipeline (SPEC §5.1):
process_raw → CBOR decode (bounded) → invariant check (MUST/SHOULD) → state transition (3×3) → StimGuard
┌─────────┐ consent-suspend ┌───────────┐
│ GRANTED │ ─────────────────→ │ SUSPENDED │
│ │ ←───────────────── │ │
└────┬────┘ consent-resume └─────┬─────┘
│ │
│ consent-withdraw │ consent-withdraw
▼ ▼
┌──────────────────────────────────────┐
│ WITHDRAWN (terminal) │
└──────────────────────────────────────┘
| Withdraw | Suspend | Resume | |
|---|---|---|---|
| GRANTED | → WITHDRAWN | → SUSPENDED | → GRANTED (idempotent) |
| SUSPENDED | → WITHDRAWN | → SUSPENDED (idempotent) | → GRANTED |
| WITHDRAWN |
apply_frame() is an exhaustive 3×3 match with zero wildcards. A new state variant is a
compile error, not a silent fall-through.
| Threat | Mitigation | Bound |
|---|---|---|
| Map bomb | MAX_MAP_FIELDS |
8 |
| String bomb | MAX_STRING_LEN |
128 B |
| Stack overflow | MAX_NESTING_DEPTH |
4 |
| Type confusion | Bitmask duplicate-key detection | 7 keys |
| Unsupported CBOR | Explicit reject: major types 1, 2, 4, 6, 7 | — |
| Buffer overflow | Err(BufferTooSmall) |
256 B |
| State violation | apply_frame() reject |
Compiler |
L1 (Wire) → Error::Decode — malformed CBOR, bounds, unsupported types
L2 (Struct) → Error::Invariant — MUST violations
L3 (State) → Error::Transition — WITHDRAWN→any, peer not found
L4 (System) → Error::Encode — buffer too small
Every module maps to a section of SPEC.md; the spec and the implementation
are a single contract.
| SPEC § | Module | Enforcement |
|---|---|---|
| §3 | frames |
Type-safe frame enum |
| §3.1 | ConsentWithdraw |
scope non-optional |
| §3.4 | reason |
Reason-code registry (0x00–0x0F spec / 0x10–0xFF AxonOS) |
| §4 | state::apply_frame |
Exhaustive 3×3 |
| §5.1 | engine::process_raw |
Single entry point |
| §6.1 | engine::allows_cognitive_frames |
false for SUSPENDED / WITHDRAWN |
| §6.4 | state::to_gossip_bits |
2-bit state propagation |
| §7 | codec::cbor / codec::json |
CBOR wire format, forward-compatible |
| §7.2 | Error |
Status 2002 CONSENT_WITHDRAWN |
| §8 | stim_guard |
DacGate, < 1 µs |
| §10 | invariants |
MUST → violation, SHOULD → warning |
| §11 | engine (peer) |
consent-withdraw → peer DISCONNECTED on the mesh |
| Code | Name | Range |
|---|---|---|
0x00 |
UNSPECIFIED | spec |
0x01 |
USER_INITIATED | spec |
0x02 |
SAFETY_VIOLATION | spec |
0x03 |
HARDWARE_FAULT | spec |
0x10 |
STIMGUARD_LOCKOUT | AxonOS |
0x11 |
SESSION_ATTESTATION_FAILURE | AxonOS |
0x12 |
EMERGENCY_BUTTON | AxonOS |
0x13 |
SWARM_FAULT_DETECTED | AxonOS |
Codes 0x00–0x0F are reserved by the specification; 0x10–0xFF are AxonOS extensions.
src/
├── lib.rs # crate root, protocol version, spec mapping
├── state.rs # ConsentState + apply_frame (exhaustive 3×3)
├── engine.rs # ConsentEngine, process_raw, process_frame
├── frames.rs # Frame types, ReasonBuf (zero-alloc)
├── reason.rs # ReasonCode registry (§3.4)
├── invariants.rs # MUST/SHOULD/MAY (§10), check_transition
├── error.rs # Layered error taxonomy (L1–L4)
├── stim_guard.rs # DacGate trait, timing contract (§8)
└── codec/
├── cbor.rs # Bounded encoder/decoder, security-hardened (§7, §9)
└── json.rs # JSON codec (feature-gated: alloc + std)
tests/
├── consent_interop.rs # 60+ tests
└── vectors/ # canonical interop vectors (frozen)
fuzz/
└── fuzz_targets/ # cargo-fuzz: decode + roundtrip
cargo test # no_std: CBOR, state machine, engine, invariants
cargo test --features json # + JSON round-trip vectors
cargo +nightly fuzz run fuzz_cbor_decode
cargo +nightly fuzz run fuzz_cbor_roundtripLicensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.
The AxonOS Project · axonos.org · connect@axonos.org · security@axonos.org medium.com/@AxonOS · github.com/AxonOS-org Singapore · Zurich · Berlin · Milano · San Mateo