kcode-k1-audio-classification-format 0.4.0

Binary formats for K1 audio-classification events and fragments
Documentation
# kcode-k1-audio-classification-format 0.4.0

Pure Rust structural binary formats for K1 audio-classification transaction payloads and local fragment values. The crate performs no filesystem I/O, provider calls, KTO work, retry execution, persistence, classification, training, or network work.

## Public values

The crate re-exports `TxId`, `ExecutedAnalysis`, `FeatureVector24`, and `LocalSpeakerLabel`.

Transaction events are `AudioClassificationEventV3` values. `QueueV2` contains only `audio_object_id`. `ProgressV1` contains a fragment ID and `ProgressUpdateV1`; job lifecycle updates carry a sequence and starts also carry a `FragmentStageV1` and name. `TranscriptionCompleteV1` contains a fragment ID and `ExecutedAnalysis`. `FailedV2` contains a fragment ID, stage, optional LLM job sequence, and error. `DiscardedV2` contains a fragment ID. `LabelConfirmationV1` contains a fragment ID, interim transaction ID, and ordered `SpeakerLabelV1` values.

`FragmentStageV1` stages are `Queue`, `Transcript`, `SpeakerLabels`, `SpeakerFeatures`, `Structuring`, and `LabelConfirmation`.

`StagedSpeakerV1`, `StagedFragmentV1`, `FinalSpeakerV1`, and `FinalFragmentV1` retain their existing public API.

## Transaction event bytes

`encode_event` and `decode_event` use envelope version byte `4`, followed by one stable tag byte and one postcard body for the selected variant. Tags are `1` Queue, `2` TranscriptionComplete, `3` Failed, `4` Discarded, `5` LabelConfirmation, and `6` Progress. Every event `TxId` uses a local Serde adapter and serializes as exactly `[u8; 12]`.

Decoding accepts only version 4, a known tag, one structurally valid body, and no trailing bytes; it rejects version 3. It is structural only and does not reject blank strings, duplicate labels, invalid state references, or ordering.

## Local fragment bytes

The staged and final fragment codecs retain format version 1. Bytes 0..16 are a header: version `1`, kind `1` staged or `2` final, then fourteen zero reserved bytes. Bytes 16..32 contain the aligned analysis `TxIdSlot`. Bytes 32..48 are zero for staged values and contain the aligned confirmation `TxIdSlot` for final values. The body starts at byte 48.

Variable lengths and speaker counts are little-endian `u64`. The body contains transcript UTF-8, speaker count, and ordered speakers. Speakers contain canonical labels, final-only person IDs, language, length-prefixed postcard `FeatureVector24`, and one usability byte restricted to 0 or 1.

`TxIdSlot` has `LEN` 16, `PADDING_LEN` 4, `new`, `txid`, `encode`, and `decode`. It stores 12 ID bytes followed by four zero bytes. Fragment decoding rejects truncation, overflow, unsupported versions or kinds, nonzero reserved bytes or padding, malformed UTF-8/labels/features, invalid booleans, and trailing bytes. It does not call Speaker V3 semantic validators.

## Paths and non-goals

`txid_path` maps a `TxId` to `<first>/<remaining15>.dat` using a 16-character URL-safe unpadded base64 name. `txid_from_path` accepts only that two-component relative form. Neither accesses a filesystem.

Fallible operations return `FormatError`. Encoding and decoding take O(input plus output) work and O(output) encoding or decoded-value memory; untrusted speaker counts are not eagerly allocated. The crate is stateless: it owns no locks, queues, waits, callbacks, or backpressure.