Resonance Knot — Phase 3 Module Contracts
Six modules, dispatched in parallel. Each subagent writes exactly one file. Phase 1 + Phase 2 modules are SSOT — read them before writing.
Phase 3 goal
Take Llama-70B's actual Q4_K_M weights from R2 → dequantize → spectral encode against real weights → upload back. Plus the first stub of the Paris probe (Phase 4 will wire real inference; Phase 3 ships the loader + smoke).
Module 1 — src/rknot/dense_reader.rs (Phase 3 update)
Owner: subagent-1.
Two changes to the existing file:
A. Body-origin reconciliation (task #14)
Production .knot files written by the existing pipeline use 4-byte
aligned body origin + 1 codec marker byte:
let aligned = (10 + meta_len + 3) & !3;
let body_origin = aligned + 1; // +1 for codec markerReplace the current body_origin = 10 + meta_len with the production
formula. Read loader.rs::HttpBackend::open for the canonical
implementation reference. Add a unit test that exercises both an
unaligned meta_len (e.g. 17) and an aligned one (e.g. 20) — both must
read the same body bytes that the production loader would.
B. K-quant dequantization
Port the Q4_0, Q8_0, Q4_K_M decoder logic from loader.rs (or its
implementation in model.rs) into a new dequantize_kquant_block
function. Wire load_tensor to dispatch on tensor_info.tensor_type:
"f32"→ existing fp32 path"f16"→ existing fp16 path"q4_0"→ 32-element blocks: 1 fp16 scale + 16 bytes (32 × 4-bit)"q8_0"→ 32-element blocks: 1 fp16 scale + 32 bytes (32 × 8-bit)"q4_k"/"q4_k_m"→ 256-element blocks: super-block scale + 12 scales/mins + 128 bytes (256 × 4-bit). This is the Llama-70B format.
Be honest: if Q4_K_M is too painful, implement Q4_0 and Q8_0 fully
and leave Q4_K_M as UnsupportedQuantType with a clear message
("Q4_K_M decoder lands in Phase 3.5"). Llama-70B Q4_K_M is the goal,
but if pulling the decoder cleanly requires more than half a day of
work, partial coverage is honest.
Tests:
body_origin_matches_production_loader_at_unaligned_meta_lenbody_origin_matches_production_loader_at_aligned_meta_lendequantize_q4_0_round_trip_within_scale_error— synthesize a Q4_0 block with known scale and codes, dequantize, verify floats are withinscale × 0.5of expected.dequantize_q8_0_round_trip_within_scale_error- (optional)
dequantize_q4_k_known_block— if Q4_K_M is implemented
Module 2 — src/rknot/encoder.rs (Phase 3 update)
Owner: subagent-2.
Add an amplitude-graded quantizer that uses the manifest's
phase_alignment vector to allocate bits per row.
/// Encode a tensor with per-row amplitude-graded bit widths.
/// Each standing row's bits = base_bits + (extra_bits × phase_alignment[row]).round()
/// Clamped to [1, 16]. Mirrors Lean `recommended_quantization` from
/// AttentionQKVDecomposition.
pub fn encode_tensor_graded(
tensor: &DenseTensor,
manifest: &SpectralManifest,
base_bits: u8,
extra_bits: u8, // 0..=8; max additional bits for highest-aligned rows
) -> QuantBlock;For the FFN equivalent: encode_ffn_tensor_graded.
The output QuantBlock carries a single bits_per_entry field — for
graded mode, store the MAX bits used (so the decoder can size the
unpack buffer correctly). Per-row actual bit widths are encoded into
the payload as a small header table at the start of payload:
[u8; k]: per-row bit width- followed by per-row variable-bit-width packed codes
Decoder side update (in decoder.rs): decode_block_graded reads the
per-row table and unpacks accordingly. Add a flag in the block that
indicates "uniform" vs "graded" mode — easiest is to use bits 7 of
bits_per_entry as a "graded" flag (bits 0..6 = max bit width). Or
add a pub mode: BlockMode { Uniform, Graded } enum to QuantBlock —
this changes the format struct, so think carefully.
Lower-friction option: keep the format unchanged, add a parallel
GradedQuantBlock struct that wraps QuantBlock + per-row widths,
serialize the per-row widths into the block payload prefix.
Tests:
graded_falls_back_to_uniform_when_extra_bits_zerograded_uses_more_bits_for_high_alignmentgraded_round_trip_preserves_high_alignment_better
Module 3 — src/bin/probe-rknot.rs
Owner: subagent-3.
New binary: load a .rknot, decode every layer, run a SMOKE forward
pass that just verifies dimensions + non-NaN outputs. Phase 4 will add
real inference; Phase 3 just proves the .rknot can be loaded and decoded
end-to-end.
probe-rknot --rknot <path.rknot> [--probe "What is the capital of France?"]Output:
- per-layer decode time
- per-layer max abs value (sanity: NaN check)
- summary: total decoded bytes, total decode time, mean / max / non-zero fraction across all decoded blocks
- Phase 4 placeholder: print "would generate text from probe" with the decoded weights as a stub
This is the smoke binary that lets us run encode → decode → check on Llama-70B end-to-end. Real inference is Phase 4.
Add [[bin]] name = "probe-rknot" to Cargo.toml.
Tests (unit only — can't run on a real .rknot in CI):
decode_summary_dimensions_match_layer_countdecode_detects_nan— synthetic block with NaN payload triggers warning
Module 4 — cloudbuild-llama-70b-end-to-end.yaml
Owner: subagent-4.
New cloudbuild that does the FULL pipeline in one yaml: HF download → dense .knot encode → R2 upload (existing pipeline) PLUS rknot repack
- verify + R2 upload (Phase 2 pipeline) chained. Single submission, both .knot and .rknot land in R2.
Reference: cloudbuild-llama-70b-to-knot.yaml (dense steps) and
cloudbuild-llama-70b-to-rknot.yaml (rknot steps). Combine.
Use waitFor to parallelize where possible:
build-encoder(cargo build) runs in parallel withfetch-from-hfrepack-rknotwaits for bothverify-knotandbuild-encoderupload-knotandupload-rknotupload in parallel
Wall-clock estimate: ~3 hours total (vs ~5 hours sequential).
Verify YAML parses:
python3 -c "import yaml; yaml.safe_load(open('./cloudbuild-llama-70b-end-to-end.yaml'))"Module 5 — src/rknot/calibration.rs (Phase 3 update)
Owner: subagent-5.
Add a real attention probe stub that hooks the existing inference kernel. Phase 3 ships the wiring and a synthetic "fake forward pass" that returns deterministic measurements. Phase 4 wires the real model forward pass.
/// Attention probe interface — anything that can produce per-layer
/// AttentionMeasurement vectors from a probe corpus. Phase 3 ships
/// FakeAttentionProbe; Phase 4 swaps in RealKernelProbe.
pub trait AttentionProbe {
fn probe(&mut self, corpus: &[u32]) -> Result<Vec<LayerMeasurement>, String>;
}
/// Phase 3 stub: returns deterministic measurements derived from the
/// corpus token IDs. Not a real attention probe — the surface exists
/// so encode-rknot can have a `--calibration-probe <fake|real>` flag
/// in Phase 4 without rewiring.
pub struct FakeAttentionProbe {
pub d: u32,
pub num_layers: u32,
}
impl AttentionProbe for FakeAttentionProbe { ... }
/// Phase 4 placeholder: returns NotImplementedError. Module 6's
/// integration will swap this in once the model.rs forward pass tap
/// lands.
pub struct RealKernelProbe<'a> {
pub model_path: &'a std::path::Path,
}
impl AttentionProbe for RealKernelProbe<'_> {
fn probe(&mut self, _corpus: &[u32]) -> Result<Vec<LayerMeasurement>, String> {
Err("RealKernelProbe lands in Phase 4 — wire model.rs forward-pass tap first".to_string())
}
}Tests:
fake_probe_produces_deterministic_measurementsfake_probe_layer_count_matches_configreal_probe_returns_phase_4_error
Module 6 — src/rknot/bitwise_fp48.rs (Phase 3 update)
Owner: subagent-6.
Replace the 8-byte codebook RLE-style packer with real fp48 bi-sided
splitting from open-source/bitwise/. The existing crate has the
"lifted (low-48) + contracted (high-16)" pattern documented in
feedback_bw_dimensional_decomposition.
Read open-source/bitwise/src/ (esp bisided-bit.ts — there may be a
Rust port; if not, port the algorithm). The pattern:
For 8-byte words:
lifted = word & 0x0000_ffff_ffff_ffff (low 48 bits = payload)
contracted = (word >> 48) & 0xffff (high 16 bits = parity/index)The compression bonus comes from observing that on standing residuals,
contracted is near-constant (the standing dimensions cluster in
parity-space). So the encoder:
- Splits each 8-byte word into (lifted, contracted)
- Run-length encodes the contracted stream (huge bonus when constant)
- Emits lifted as raw fp48 bytes (or further codebook-compressed)
pub struct Fp48BiSidedPacked {
pub lifted_payload: Vec<u8>, // packed 6-byte values
pub contracted_runs: Vec<(u16, u32)>, // (value, run_length)
pub original_byte_len: u32,
}
pub fn fp48_bisided_pack(payload: &[u8]) -> Fp48BiSidedPacked;
pub fn fp48_bisided_unpack(packed: &Fp48BiSidedPacked) -> Vec<u8>;
pub fn fp48_bisided_bonus_ratio(payload: &[u8]) -> f32;Keep the existing fp48_pack / fp48_unpack (codebook variant) — add
the bi-sided version as a sibling. --apply-fp48 in encode-rknot can
later choose between them via a sub-flag.
Tests:
bisided_pack_unpack_round_tripbisided_bonus_constant_contracted_high— payload where every 8-byte word has the same high-16 bits should achieve ~3-5× bonusbisided_bonus_random_under_one_okbisided_bonus_on_standing_residual_synthetic— synthetic standing residual (peaky value distribution, low-entropy contracted axis) achieves 2-4× bonus
Anchors
After all 6 modules land:
cargo build --releaseproduces 3 binaries (encode-rknot, verify-rknot, probe-rknot)cargo test --lib rknot::passes everythingcloudbuild-llama-70b-end-to-end.yamlparses- Smoke:
encode-rknot --synthetic ...still works - Smoke:
probe-rknot --rknot /tmp/rknot-phase2-smoke.rknotruns and reports per-layer decode
Common pitfalls
- Don't break the existing format byte layout —
QuantBlock's field order is canon. New format extensions go in NEW structs. - K-quant block sizes are 32 or 256 elements — make sure the dispatcher uses the right one. Q4_K's block size is 256, not 32.
- Body-origin bug WILL bite if not fixed before running on real R2 knots — flag prominently in the encode-rknot error path.
- fp48 bi-sided:
(u16, u32)for run-length encoding caps run length at 4G — fine for any layer; just be honest if you cap it lower. - No new crate dependencies — only what's already in
Cargo.toml.