kcode-k1-objects 0.2.0

Stateless canonical object storage for Kennedy K1
Documentation
# Public API

```rust
use std::sync::Arc;
use kcode_k1_peering::K1Peering;
use kcode_k1_txn_ordering::K1TxnOrdering;
pub use kcode_k1_transaction_id::TxId;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Object {
    pub filename: String,
    pub file_type: String,
    pub description: String,
    pub data: Vec<u8>,
}

pub struct K1Objects;

impl K1Objects {
    pub fn open(
        ordering: Arc<K1TxnOrdering>,
        peering: Arc<K1Peering>,
    ) -> Result<Self, String>;

    pub fn save(
        &self,
        filename: &str,
        file_type: &str,
        description: &str,
        data: &[u8],
    ) -> Result<TxId, String>;

    pub fn load(&self, id: TxId) -> Result<Option<Object>, String>;
}
```

# State and lifecycle

`open` registers the exact subsystem ID `k1-objects-subsystem` directly with KTO at `REGISTER_AT_TIP`. The registration receives no historical callbacks and its callback owns no materialized state. The supplied peering instance must use the same live `K1TxnOrdering` instance supplied to `open`.

Objects creates no files, index, checkpoint, cursor, cache, worker, or background task. KTO's canonical transaction bytes are the only object persistence. Historical objects remain loadable by transaction ID without replay. A canonical reorganization follows KTO's registration lifecycle and may take the Objects registration out of commission; reopening at the current tip restores submission capability. This release proves single-node local composition and does not provide networking, replication, deployment, or peering identity hardening.

# Saving and loading

`save` encodes one object payload, submits it only through peering, waits for KTO's canonical callback, and returns the exact committed transaction ID supplied by peering. It does not calculate the ID itself or mutate local state. Empty metadata and empty data are accepted. Filename semantics, file type or MIME, description contents, and binary data are not validated.

Every successful call creates a new transaction. Equal metadata and data are not deduplicated and produce separately addressable objects. There is no update, deletion, listing, streaming, migration, or second binary copy owned by Objects.

`load` queries the current canonical KTO chain. An unknown or noncanonical ID, or a canonical transaction owned by another subsystem, returns `Ok(None)`. A canonical Objects transaction with valid framing returns the complete owned `Object`. Unsupported versions, malformed framing, out-of-bounds lengths, or non-UTF-8 metadata return `Err`. The file type and data remain opaque.

# Payload format

Objects payload version 1 is:

| Byte range | Value |
| --- | --- |
| `0` | Version byte `1` |
| `1..9` | Filename UTF-8 byte length as little-endian `u64` |
| `9..17` | File-type UTF-8 byte length as little-endian `u64` |
| `17..25` | Description UTF-8 byte length as little-endian `u64` |
| following bytes | Filename, file type, description, then all remaining bytes as opaque data |

Encoding accepts every input whose lengths fit `u64`, whose complete payload length fits `usize`, and whose allocation succeeds. It uses checked arithmetic and imposes no lower size limit or arbitrary upper cap.

# Failures, concurrency, and performance

All operations are synchronous and perform no retry or timeout. `open` returns KTO registration errors. `save` returns framing/allocation, clock, signing, KTO, callback, and peering errors unchanged or with local framing context. An error identifying a transaction ID as committed is not retry permission. `load` returns KTO retrieval errors and contextual structural decoding errors.

Objects has no locks or mutable shared state. Independent loads and saves call the shared KTO and peering instances directly. KTO owns commit serialization and the Objects callback lane; one blocked Objects callback can delay later Objects saves but does not block unrelated subsystem lanes. The stateless callback performs bounded constant work. Recursive save from the Objects callback is unsupported by KTO, though this package's callback never does so.

For total metadata bytes `M`, binary bytes `B`, and complete transaction bytes `T`, `open` performs bounded in-memory registration work with no historical scan or payload read. `save` performs `O(M + B)` encoding, one `25 + M + B` byte payload allocation, and one copy of each caller byte before peering and KTO perform their documented signing and persistence work. `load` performs KTO's `O(T)` retrieval, then `O(M + B)` validation and copying into the returned strings and data; peak memory includes the retrieved transaction plus the returned object. No finite wall-clock guarantee applies to allocation, storage, signing, KTO lane wait, callback, or retrieval latency.