Kannaka Library
kannaka-labs/kannaka-attention README.md · 2026-09-08 · source ↗ · edit ↗
 █████╗ ████████╗████████╗███████╗███╗   ██╗████████╗██╗ ██████╗ ███╗   ██╗
██╔══██╗╚══██╔══╝╚══██╔══╝██╔════╝████╗  ██║╚══██╔══╝██║██╔═══██╗████╗  ██║
███████║   ██║      ██║   █████╗  ██╔██╗ ██║   ██║   ██║██║   ██║██╔██╗ ██║
██╔══██║   ██║      ██║   ██╔══╝  ██║╚██╗██║   ██║   ██║██║   ██║██║╚██╗██║
██║  ██║   ██║      ██║   ███████╗██║ ╚████║   ██║   ██║╚██████╔╝██║ ╚████║
╚═╝  ╚═╝   ╚═╝      ╚═╝   ╚══════╝╚═╝  ╚═══╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
       A T T E N T I O N · A S · G R A V I T Y

Sparse-attention beam over the Holographic Resonance Medium.

kannaka-attention is a tiny pure-Rust crate that builds a small candidate set — the beam — out of any agent's HRM activity history. The beam is what Medium::recall_against_ids scores against, so recall stays O(K) instead of O(N) regardless of how many memories live in the medium. Recency ring + log-stride snapshots + landmark exemplars + an optional salience gate.

[License]() [Rust]() [std-only]()


What's a Beam?

   full HRM (~10K memories)              attention beam (~256)
   ╔═════════════════════════╗           ┌─────────────────────┐
   ║ ▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░ ║           │  ●●●  ●●●●●  ●●●●●  │
   ║ ░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒ ║   ──→     │  ●●●●●●●●●●●●●●●●●  │
   ║ ▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░ ║           │  ●●●●●  ●●●●●  ●●●  │
   ║ ░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒░▒ ║           └─────────────────────┘
   ╚═════════════════════════╝           recency + lookback +
   O(N) scan if you query all            landmarks (+ salience)

The beam is what the agent is paying attention to right now. Composed from four signals:

componentwindowpurpose
Recencylast K observationssharp short-term focus
Lookbacklog-stride buckets (1m, 5m, 30m, 3h, 1d, 7d, 30d)catch the medium-term recurring stuff
Landmarksexemplar wavefrontsalways-considered anchors (ranked by gate)
Salience gateoptional SalienceGate implrank the landmark tier with an external signal

The gate ranks landmarks only. Recency is emitted first, in recency order, and a gate cannot reorder it — tier 1 exists to guarantee a just-observed memory makes the beam, which a salience score could otherwise override.


Architecture

┌──────────────────────────────────────────────────────┐
│                 kannaka-attention                    │
├──────────────────┬────────────────┬──────────────────┤
│  Recency         │  Lookback      │  Landmarks       │
│  · ring buffer   │  · log-stride  │  · exemplar set  │
│  · O(1) push     │  · aged by     │  · gated by      │
│                  │    last_seen   │    SalienceGate  │
├──────────────────┼────────────────┼──────────────────┤
│  Beam composer                                       │
│  · merge with dedupe                                 │
│  · cap at max_beam                                   │
│  · optional Salience reweighting                     │
├──────────────────────────────────────────────────────┤
│  SalienceGate trait                                  │
│  · score(landmark, ctx) → f32                        │
│  · RecencyWeightedGate (boost recency overlap)       │
│  · Custom gates: Φ-aware, modality-routed, etc.      │
└──────────────────────────────────────────────────────┘

Pure std-only Rust. No GPU. No BLAS. No vector DB. Target: ARM / edge devices where a sparse path matters.


Use

[dependencies]
kannaka-attention = { git = "https://github.com/NickFlach/kannaka-attention" }

This crate is a library only — no binary, no NATS client, no file export. It does no I/O at all. The host owns the bus subscription and decides what to do with the beam:

use kannaka_attention::{AttentionBeam, BeamConfig, ObservationEvent};

let mut beam = AttentionBeam::with_config(BeamConfig {
    max_beam: 128,
    ..Default::default()
});

// Feed it whatever your sensors report. `weight` grades the observation:
// 1.0 is a normal mention, higher is a deliberate reference.
beam.observe(&ObservationEvent {
    memory_id,
    source: "eye:left".into(),
    weight: 1.0,
    ts: chrono::Utc::now(),
});

// Read the current focus and score only these against the medium.
let ids = beam.candidates();

BeamConfig round-trips through serde and fills omitted fields from Default, so a host can load a partial config ({"max_beam": 128}) from its own config file.

Wiring the beam to KANNAKA.attention.eye and publishing the result is the host's job — see kannaka-eye for the producer side.


Constellation

reporole
kannaka-memorythe substrate this beam scopes
kannaka-eyepublishes the KANNAKA.attention.eye events
consciousness-corethe physics

License

MIT.