# Audio classification event format
Pure Rust structural encoding for audio-classification transaction events. The library performs no filesystem I/O, canonical-transaction ordering, Peering submission, immutable Object work, provider calls, retry execution, status projection, identity decisions, training, persistence, or networking.
## Public API
The library re-exports `FormatError`, `TxId`, `ExecutedAnalysis`, `FeatureVector24`, and `LocalSpeakerLabel`.
```rust
pub enum FragmentStageV1 {
Queue,
Transcript,
SpeakerLabels,
SpeakerFeatures,
Structuring,
LabelConfirmation,
}
pub struct QueueV2 {
pub audio_object_id: TxId,
}
pub struct ProgressV1 {
pub fragment_id: TxId,
pub update: ProgressUpdateV1,
}
pub enum ProgressUpdateV1 {
LlmJobStarted {
sequence: u64,
stage: FragmentStageV1,
name: String,
},
LlmJobSucceeded { sequence: u64 },
LlmJobFailed { sequence: u64, error: String },
StageCompleted { stage: FragmentStageV1 },
}
pub struct TranscriptionCompleteV1 {
pub fragment_id: TxId,
pub analysis: ExecutedAnalysis,
}
pub struct FailedV2 {
pub fragment_id: TxId,
pub stage: FragmentStageV1,
pub llm_job_sequence: Option<u64>,
pub error: String,
}
pub struct DiscardedV2 {
pub fragment_id: TxId,
}
pub struct SpeakerLabelV1 {
pub speaker: LocalSpeakerLabel,
pub person_id: Option<kcode_k1_person_types::PersonId>,
}
pub struct LabelConfirmationV1 {
pub fragment_id: TxId,
pub interim_txid: TxId,
pub speakers: Vec<SpeakerLabelV1>,
}
pub enum AudioClassificationEventV3 {
Queue(QueueV2),
Progress(ProgressV1),
TranscriptionComplete(TranscriptionCompleteV1),
Failed(FailedV2),
Discarded(DiscardedV2),
LabelConfirmation(LabelConfirmationV1),
}
pub fn encode_event(event: &AudioClassificationEventV3) -> Result<Vec<u8>, FormatError>;
pub fn decode_event(bytes: &[u8]) -> Result<AudioClassificationEventV3, FormatError>;
```
`FragmentStageV1` implements `Debug`, `Clone`, `Copy`, `PartialEq`, `Eq`, `Serialize`, and `Deserialize`. `QueueV2`, `ProgressUpdateV1`, `FailedV2`, `DiscardedV2`, `SpeakerLabelV1`, and `LabelConfirmationV1` implement `Debug`, `Clone`, `PartialEq`, `Eq`, `Serialize`, and `Deserialize`. `ProgressV1` and `TranscriptionCompleteV1` implement `Debug`, `Clone`, `PartialEq`, `Serialize`, and `Deserialize`. `AudioClassificationEventV3` implements `Debug`, `Clone`, and `PartialEq`. The re-exported traits and operations of `FormatError`, `TxId`, `ExecutedAnalysis`, `FeatureVector24`, and `LocalSpeakerLabel` are defined by their owning libraries.
## Encoding contract
An event is envelope version byte `5`, one stable tag byte, and one postcard body for the selected payload. Tags are `1` Queue, `2` TranscriptionComplete, `3` Failed, `4` Discarded, `5` LabelConfirmation, and `6` Progress. Every event `TxId` and every known `PersonId` is encoded as its canonical 12 raw bytes. A label's `Some(PersonId)` means a known person; `None` explicitly means Unknown.
Label confirmations are structural: encoding and decoding preserve arbitrary speaker-vector ordering and duplicate labels. Downstream consumers own any semantic completeness or assignment validation.
`decode_event` accepts only version 5, a known tag, one valid body, and no trailing bytes. It reports inputs shorter than the version and tag as `FormatError::Truncated`, a different version as `UnsupportedVersion`, an unknown tag as `UnknownEventTag`, an invalid body as `InvalidEventBody`, and an otherwise valid body followed by bytes as `TrailingBytes`. It does not validate blank strings, state references, event ordering, or label assignment semantics.
Encoding and decoding take O(input plus output) work and temporary memory proportional to the encoded or decoded event. The library is stateless and performs no I/O or synchronization.