kcode-k1-kmap 0.3.0

K1 Kmap transaction facade and attention-budgeted loader
Documentation
# Public API

`K1Kmap` is the synchronous public facade.

```rust
pub struct K1Kmap;

impl K1Kmap {
    pub fn open(
        root: &std::path::Path,
        ordering: std::sync::Arc<kcode_k1_txn_ordering::K1TxnOrdering>,
        peering: std::sync::Arc<kcode_k1_peering::K1Peering>,
    ) -> Result<Self, String>;
    pub fn create_node(
        &self,
        title: impl Into<String>,
        navigation_hint: impl Into<String>,
        narrative: impl Into<String>,
        connections: Vec<ConnectionSpec>,
    ) -> Result<TxId, String>;
    pub fn update_node(
        &self,
        node_id: NodeId,
        title: Option<String>,
        navigation_hint: Option<String>,
        narrative: Option<String>,
        connection_updates: Vec<ConnectionSpec>,
    ) -> Result<TxId, String>;
    pub fn apply_measurements(
        &self,
        measurements: Vec<ConnectionMeasurement>,
    ) -> Result<TxId, String>;
    pub fn get_node(&self, node_id: NodeId) -> Result<Option<Node>, String>;
    pub fn open_node(
        &self,
        node_id: NodeId,
        budget: f64,
        temperature: f64,
        mode: OpenMode,
        access_filter: impl FnMut(NodeId) -> bool,
    ) -> Result<OpenResult, String>;
}
```

The facade reexports these loader declarations:

```rust
pub const PREVIEW_COST: f64 = 0.3;
pub const NARRATIVE_COST: f64 = 1.0;
pub const DEPTH_DECAY: f64 = 0.7;
pub enum OpenMode { Full, NavigationOnly }
pub struct LoadedNode {
    pub node_id: NodeId,
    pub title: String,
    pub navigation_hint: String,
    pub narrative: Option<String>,
}
pub struct OpenResult {
    pub nodes: Vec<LoadedNode>,
    pub automatic_attention_spent: f64,
}
```

`OpenMode` implements `Clone + Copy + Debug + Eq + PartialEq`; `LoadedNode` and `OpenResult` implement `Clone + Debug + PartialEq`.

The facade reexports these format declarations:

```rust
pub struct NodeId(pub [u8; 12]);
pub enum ConnectionTier { Navigation, Automated }
pub struct Weight { pub value: f64, pub mass: f64 }
pub struct Connection {
    pub target: NodeId,
    pub tier: ConnectionTier,
    pub weight: Weight,
}
pub struct ConnectionSpec { pub target: NodeId, pub tier: ConnectionTier }
pub enum MeasurementImportance { Critical, NonCritical }
pub struct ConnectionMeasurement {
    pub source: NodeId,
    pub target: NodeId,
    pub useful: bool,
    pub importance: MeasurementImportance,
}
pub enum MeasurementOutcome { Updated, Pruned, Absent }
pub struct Node {
    pub title: String,
    pub navigation_hint: String,
    pub narrative: String,
    pub connections: Vec<Connection>,
}
pub enum KmapAction {
    CreateNode {
        title: String,
        navigation_hint: String,
        narrative: String,
        connections: Vec<ConnectionSpec>,
    },
    UpdateNode {
        node_id: NodeId,
        title: Option<String>,
        navigation_hint: Option<String>,
        narrative: Option<String>,
        connection_updates: Vec<ConnectionSpec>,
    },
    ApplyMeasurements { measurements: Vec<ConnectionMeasurement> },
}
pub struct KmapError(pub String);
pub type Result<T> = std::result::Result<T, KmapError>;
```

`Weight` exposes `new(value, mass)`, `initial()`, and `update(value, mass)`. `Connection` exposes `new(target, tier)`. `ConnectionMeasurement::new(source, target, useful, importance)` is infallible. `Node` exposes `new`, `from_specs`, `validate`, `apply_connection_updates`, `apply_measurement`, `encode`, and `decode`. `KmapAction` exposes `create_node`, `update_node`, `apply_measurements`, `validate`, `encode`, and `decode`. Their argument and result types follow the fields above; node/action validation and encoding methods return the reexported format `Result`.

`NodeId` converts losslessly to and from the reexported 12-byte `TxId`. `NodeId` implements `Clone + Copy + Debug + Deserialize + Eq + Hash + PartialEq + Serialize`. Connection and measurement enums/specifications implement `Clone + Copy + Debug + Deserialize + Eq + PartialEq + Serialize`; `Weight`, `Connection`, `Node`, and `KmapAction` implement their source types' public `Clone + Debug + Deserialize + PartialEq + Serialize` traits. `MeasurementOutcome` implements `Clone + Copy + Debug + Eq + PartialEq`. `KmapError` implements `Clone + Debug + Display + Error + Eq + PartialEq`.

## Semantics

Each mutation submits one encoded action once through Peering. Only ordered callbacks alter the derived projection. Applied, unchanged, and semantically rejected callbacks advance its checkpoint; malformed callbacks and infrastructure failures fault the instance. Reorganization faults the instance and clears the projection. A fresh open is the recovery path.

Connection targets are unique and at most 12 may be `Navigation`. `update_node` atomically changes supplied text and upserts each connection target: existing targets are retiered without changing weight or position, while missing targets are appended with initial weight. There is no explicit connection-removal operation.

Measurements contain only semantic feedback. `useful` maps to numeric value 1 or 0; `Critical` maps to mass 3 and `NonCritical` to mass 1. Measurements apply in listed order. Missing sources and targets are no-ops. Learned weights use evidence-mass exponential averaging and a connection is pruned only when its updated value is below 0.1.

The caller authorizes the traversal root and supplies target access decisions. Budget and temperature must be finite and nonnegative. `Full` returns the root narrative, provides accessible root Navigation previews free, then uses two-hit preview/narrative loading. `NavigationOnly` returns no narratives and atomically loads a selected node with its accessible unseen Navigation children; its first unaffordable selected bundle stops traversal without resampling. Duplicate frontier paths remain weighted tickets in both modes.

Operations are synchronous and have no finite wall-clock bound because callbacks, storage, entropy, and caller-supplied access predicates may block.