forgo.cloud
Sign in
Repo workspace

forkjoin-ai/gnosis

Resonance Knot — Rust Module Contracts (Phase 1 + 2)

distributed-inference/RKNOT_RUST_CONTRACTS.md
forkjoin-ai/gnosis

Resonance Knot — Rust Module Contracts (Phase 1 + 2)

Six modules. Each subagent writes exactly one file. The format module (src/rknot/format.rs) is the SSOT — every signature below references its types verbatim. If a subagent diverges, the parallel build breaks.

Already shipped

  • src/rknot/mod.rs — module surface
  • src/rknot/format.rsSpectralManifest, QuantBlock, ResonanceKnotLayer, Rknot, DenseTensor, RknotHeader, RknotLayerRef, RknotBlockRef, ArchMeta, magic = b"RKNOT\x02". 5 unit tests pass.
  • src/rknot/manifest.rsstub_first_k_manifest, stub_strided_manifest.
  • src/rknot/encoder.rsencode_tensor, encode_ffn_tensor, quantize_value, pack_codes. 6 unit tests pass.

All three modules wired into src/lib.rs via pub mod rknot; and pub mod format; pub mod manifest; pub mod encoder; inside mod.rs.

Module 1 — src/rknot/writer.rs

Owner: subagent-1. Imports: super::format::{Rknot, RknotHeader, RknotLayerRef, RknotBlockRef, ArchMeta, RKNOT_MAGIC}, serde_json, std::io::Write.

use std::io::{self, Write};
use super::format::*;

/// Errors emitted during writing.
#[derive(Debug)]
pub enum WriteError {
    Io(io::Error),
    Serde(serde_json::Error),
    MalformedManifest { layer_idx: u32 },
}

impl From<io::Error> for WriteError { ... }
impl From<serde_json::Error> for WriteError { ... }

/// Serialize a `Rknot` value into RKNOT_v2 bytes.
///
/// Layout:
///   magic (6 bytes) | header_len (u32 LE) | header_json (N bytes) | body
///
/// The body is the concatenation of `q_block.payload || k_block.payload
/// || v_block.payload || ffn_block.payload` for each layer in order.
/// The `RknotLayerRef` entries in the header carry per-block byte
/// offsets so the loader can mmap and pull individual blocks.
///
/// Asserts each layer's manifest is well-formed via
/// `SpectralManifest::is_well_formed`.
pub fn write_rknot<W: Write>(w: &mut W, knot: &Rknot) -> Result<u64, WriteError>;

/// Convenience: write to a file path. Returns total bytes written.
pub fn write_rknot_to_file(path: &std::path::Path, knot: &Rknot)
    -> Result<u64, WriteError>;

Tests (in #[cfg(test)] mod tests):

  • magic_bytes_emitted_first — first 6 bytes of output == RKNOT_MAGIC
  • header_length_field_matches_actual_header — bytes 6..10 (u32 LE) == JSON length
  • body_offsets_are_monotonic_and_match_payloads — each body_offset in the header points to the start of the corresponding payload bytes
  • malformed_manifest_returns_error — encoder rejects k > d
  • synthetic_70b_layer_writes_under_expected_bound — a stub layer with d=8192, k=2458, bits=4 writes ~3 MB body for the layer (k² × 4 bits = 6.04M bits ≈ 755 KB per Q/K/V block + k×h FFN)

Module 2 — src/rknot/reader.rs

Owner: subagent-2. Imports: same plus std::io::{Read, Seek, SeekFrom}.

use std::io::{self, Read, Seek};
use super::format::*;

#[derive(Debug)]
pub enum ReadError {
    Io(io::Error),
    Serde(serde_json::Error),
    BadMagic { found: [u8; 6] },
    HeaderTooLong { len: u32, file_size: u64 },
    BodyOffsetOutOfBounds { layer_idx: u32, offset: u64 },
}

/// Read just the JSON header from a `.rknot` reader. Body is left
/// unread — caller can `seek_to_body` for selective block loads.
pub fn read_rknot_header<R: Read>(r: &mut R) -> Result<RknotHeader, ReadError>;

/// Read a single block payload from the body using the reference's
/// byte offset and length. Caller is responsible for the `seek_origin`
/// pointing at the start of the body region.
pub fn read_block_payload<R: Read + Seek>(
    r: &mut R,
    body_origin: u64,
    block_ref: &RknotBlockRef,
) -> Result<Vec<u8>, ReadError>;

/// Read the entire `.rknot` file into an in-memory `Rknot`. For
/// large models prefer `read_rknot_header` + selective block loads.
pub fn read_rknot_from_file(path: &std::path::Path) -> Result<Rknot, ReadError>;

Tests:

  • round_trip_synthetic_layer — write-then-read on a small Rknot recovers identical header and payloads
  • bad_magic_rejected — file starting with b"KNOT" + ... fails
  • header_too_long_rejected — bogus header_len > file size returns error
  • selective_block_load_matches_full_load — reading a single block via read_block_payload matches the same block from the full read

Module 3 — src/rknot/decoder.rs

Owner: subagent-3. Imports: super::format::{DenseTensor, QuantBlock, SpectralManifest}.

Inverse of encoder.rs::encode_tensor. Mirrors Lean ResonanceKnotDecoder.decode_block and dequantize_value.

use super::format::*;

/// Inverse of `encoder::quantize_value`. Returns `f32` reconstruction.
pub fn dequantize_value(code: u32, bits: u8) -> f32;

/// Decode a quantized block back into a dense d×d tensor. Non-standing
/// positions are exactly 0.0 (mirrors Lean
/// `decode_block_zero_off_standing` — the structural compression
/// guarantee).
///
/// Output dimensions: `rows = cols = manifest.d`.
pub fn decode_block(block: &QuantBlock, manifest: &SpectralManifest) -> DenseTensor;

/// Decode an FFN block back into a dense d×h tensor. Rows outside the
/// standing set are zero.
pub fn decode_ffn_block(
    block: &QuantBlock,
    manifest: &SpectralManifest,
    intermediate_h: u32,
) -> DenseTensor;

Tests:

  • dequantize_inverse_of_quantize_within_bound — for every code in [0, 2^bits), quantize(dequantize(code, bits), bits) == code
  • decode_block_dimensions — output is manifest.d × manifest.d
  • decode_block_zero_off_standing — every (i, j) not in standing × standing decodes to exactly 0.0
  • decode_block_round_trip_on_standing_subspace — for entries t.get(i, j) with i, j ∈ standing_indices, the round-trip decode(encode(t)) reproduces the value within 1.0 / 2^(bits - 1) (quantization error bound)

Module 4 — src/bin/encode-rknot.rs

Owner: subagent-4. Add to Cargo.toml [[bin]] block:

[[bin]]
name = "encode-rknot"
path = "src/bin/encode-rknot.rs"

CLI tool. Phase 1 takes synthetic input only (no real .knot reading yet — Phase 2 adds that). Goal: end-to-end measurement of file size and packing throughput.

//! encode-rknot — Resonance Knot encoder (Phase 1: synthetic input)
//!
//! Usage:
//!   encode-rknot --synthetic \
//!     --d 8192 --layers 80 --intermediate-h 28672 \
//!     --target-k 0.30 --bits-qk 4 --bits-v 8 --bits-ffn 4 \
//!     --output /tmp/llama-70b-synthetic.rknot
//!
//! Phase 2 will add `--input <dense.knot>` to take a real
//! Llama-70B Q4_K_M dense knot as input. Phase 1 generates a
//! synthetic tensor (uniform 0.5 fill) of Llama-70B-shaped
//! dimensions to measure file size end-to-end.

CLI args via std::env::args (no extra crate dependencies — keep the Phase 1 binary minimal):

  • --synthetic (required for Phase 1)
  • --d <u32> (default 8192 = Llama-70B hidden_dim)
  • --layers <u32> (default 80 = Llama-70B layer count)
  • --intermediate-h <u32> (default 28672 = Llama-70B FFN intermediate)
  • --target-k <f32> (default 0.30)
  • --bits-qk <u8> (default 4)
  • --bits-v <u8> (default 8)
  • --bits-ffn <u8> (default 4)
  • --output <path> (required)

Output to stderr:

  • expected dense baseline size (Lean dense_baseline_byte_size)
  • actual .rknot size
  • compression ratio
  • per-block timing breakdown
  • cascade-ratio prediction (Lean cascade_ratio(d, k))

Exit code 0 on success.

Module 5 — src/rknot/calibration.rs (Phase 2 stub)

Owner: subagent-5.

Provides the Phase 2 hook surface. Phase 1 ships only the data structures and a stub probe; Phase 2 fills in the real attention tap.

use super::format::*;

/// Per-dimension attention measurement captured during a forward pass.
/// Mirrors Lean `AttentionQKVPattern` (the Float fields).
#[derive(Debug, Clone)]
pub struct AttentionMeasurement {
    pub frequency: u32,         // dimension index in [0, d)
    pub query_amplitude: f32,
    pub key_amplitude: f32,
    pub value_amplitude: f32,
    pub query_phase_variance: f32,
    pub key_phase_variance: f32,
    pub value_phase_variance: f32,
    pub qk_phase_alignment: f32,
    pub output_amplitude: f32,
}

/// Per-layer measurement bundle. The Phase 2 calibration runner
/// produces one of these per layer per probe-corpus token.
#[derive(Debug, Clone)]
pub struct LayerMeasurement {
    pub layer_idx: u32,
    pub measurements: Vec<AttentionMeasurement>,
}

/// Reduce per-token measurements into per-layer aggregates (mean
/// amplitudes, mean phase alignment). Phase 2 calibration code
/// pipes its raw output through this before manifest extraction.
pub fn aggregate_measurements(
    per_token: &[LayerMeasurement],
) -> Vec<LayerMeasurement>;

/// Apply `value_standing_and_gated`-style filtering to produce a
/// SpectralManifest from one layer's aggregated measurements.
/// Mirrors Lean `extract_value_gated`.
pub fn manifest_from_measurements(
    layer: &LayerMeasurement,
    d: u32,
    threshold: f32,  // amplitude threshold, default 0.5
) -> SpectralManifest;

/// STUB Phase 2 hook: synthesize a measurement by sampling the
/// dimension space uniformly. Returns measurements with
/// `query_amplitude = key_amplitude = value_amplitude = 0.5`. Replaced
/// in Phase 2 by a real attention tap into the existing kernel.
pub fn stub_calibration_probe(d: u32, num_layers: u32) -> Vec<LayerMeasurement>;

Tests:

  • manifest_from_measurements_well_formed
  • aggregate_preserves_dim_count
  • stub_probe_produces_expected_layer_count
  • manifest_from_measurements_threshold_zero_keeps_all — threshold=0 keeps every dimension
  • manifest_from_measurements_threshold_max_keeps_none

Module 6 — src/rknot/bitwise_pack.rs + measurement test

Owner: subagent-6.

Bitwise/fp48-style packing for the spectral residual. This is the "shape regularity bonus" measurement from the brainstorm — does the standing-residual block compress further when the payload bytes go through a value-distribution-aware packer?

use super::format::QuantBlock;

/// Lifted/contracted split: take a QuantBlock payload and re-pack it
/// using the fp48-style bi-sided bit pattern. The lifted-low-48 holds
/// the value payload; the contracted-high-16 holds parity / index
/// hints (which are typically near-constant on standing residuals).
///
/// Returns the re-packed payload bytes (typically smaller than input).
pub fn bitwise_pack(payload: &[u8], bits_per_entry: u8) -> Vec<u8>;

/// Inverse of `bitwise_pack`. Round-trip property: for any input
/// payload `p`, `bitwise_unpack(bitwise_pack(p, bits), bits, p.len()) == p`.
pub fn bitwise_unpack(packed: &[u8], bits_per_entry: u8, expected_byte_len: usize) -> Vec<u8>;

/// Measurement helper: encode the same data path twice (once with
/// bitwise pack, once without), report the bonus ratio.
pub struct BonusMeasurement {
    pub raw_byte_len: usize,
    pub bitwise_byte_len: usize,
    pub bonus_ratio: f32,  // raw / bitwise
}

pub fn measure_bonus(payload: &[u8], bits_per_entry: u8) -> BonusMeasurement;

Tests:

  • pack_unpack_round_trip_preserves_bytes
  • pack_of_constant_payload_is_smaller — a payload of all-zeros packs to less than its raw length
  • bonus_ratio_at_least_one_on_random_input — random input gets no bonus, ratio ≥ 1.0

Anchors

After Modules 1-6 land:

  • src/rknot/mod.rs updated to pub mod {writer, reader, decoder, calibration, bitwise_pack};
  • Cargo.toml updated with the [[bin]] name = "encode-rknot" entry
  • cargo test --lib rknot:: passes all module tests
  • cargo run --bin encode-rknot -- --synthetic ... --output /tmp/test.rknot produces a file and exits 0

Common pitfalls

  • u64 for body offsets: wasm32 has usize = u32 (4.29 GB cap) but a 70B .rknot body even at 8× compression is multi-GB. See loader.rs::TensorInfo for the same issue.
  • #[serde(skip)] on QuantBlock.payload: payload bytes go to the body, NOT the JSON header. The format module already does this — readers must be careful to populate the field after reading the body.
  • No extra crate dependencies: stick to serde, serde_json, std. The Cargo.toml already has serde and serde_json.
  • Test isolation: don't write to /tmp in tests — use tempfile (already a dev-dep) or in-memory Vec<u8> buffers.