# Audio classification formats
This crate directly re-exports the audio-classification transaction-event and local-fragment formats. Every callable below is owned by a re-exported format crate; this facade declares no callable and adds no implementation.
Version 0.6.1 exact-pins event-format 0.2.1 and fragment-format 0.2.2. Those leaves select `kcode-speaker-v3-analysis` 0.3.0 with default features disabled. Compatibility tests retain 0.2.0 as the byte reference and prove that the version-5 event bytes and version-2 fragment bytes are unchanged; the facade's wire schema versions and production implementation are unchanged.
## Public API
`PersonId`, `TxId`, `ExecutedAnalysis`, `FeatureVector24`, and `LocalSpeakerLabel` are also direct re-exports and are defined by their owning libraries.
```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<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 struct StagedSpeakerV1 { pub speaker: LocalSpeakerLabel, pub language: String, pub features: FeatureVector24, pub usable_for_training: bool }
pub struct StagedFragmentV1 { pub analysis_txid: TxId, pub transcript: String, pub speakers: Vec<StagedSpeakerV1> }
pub struct FinalSpeakerV1 { pub speaker: LocalSpeakerLabel, pub person_id: Option<PersonId>, pub language: String, pub features: FeatureVector24, pub usable_for_training: bool }
pub struct FinalFragmentV1 { pub analysis_txid: TxId, pub confirmation_txid: TxId, pub transcript: String, pub speakers: Vec<FinalSpeakerV1> }
pub enum FormatError {
Truncated,
LengthOverflow,
UnsupportedVersion(u8),
UnknownEventTag(u8),
InvalidEventBody,
InvalidFragmentKind(u8),
NonZeroReserved,
NonZeroPadding,
NonZeroStagedConfirmation,
InvalidTxIdSlotLength(usize),
InvalidUtf8,
InvalidSpeakerLabel,
InvalidFeatureBody,
InvalidBoolean(u8),
TrailingBytes,
InvalidPath,
}
pub struct TxIdSlot { /* private fields */ }
impl TxIdSlot {
pub const LEN: usize = 16;
pub const PADDING_LEN: usize = 4;
pub const fn new(txid: TxId) -> Self;
pub const fn txid(self) -> TxId;
pub fn encode(self) -> [u8; Self::LEN];
pub fn decode(bytes: &[u8]) -> Result<Self, FormatError>;
}
pub fn encode_event(event: &AudioClassificationEventV3) -> Result<Vec<u8>, FormatError>;
pub fn decode_event(bytes: &[u8]) -> Result<AudioClassificationEventV3, FormatError>;
pub fn encode_staged_fragment(value: &StagedFragmentV1) -> Result<Vec<u8>, FormatError>;
pub fn decode_staged_fragment(bytes: &[u8]) -> Result<StagedFragmentV1, FormatError>;
pub fn encode_final_fragment(value: &FinalFragmentV1) -> Result<Vec<u8>, FormatError>;
pub fn decode_final_fragment(bytes: &[u8]) -> Result<FinalFragmentV1, FormatError>;
pub fn txid_path(txid: TxId) -> PathBuf;
pub fn txid_from_path(path: impl AsRef<Path>) -> Result<TxId, 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`, `StagedSpeakerV1`, `StagedFragmentV1`, `FinalSpeakerV1`, and `FinalFragmentV1` implement `Debug`, `Clone`, and `PartialEq`. `FormatError` implements `Debug`, `Clone`, `PartialEq`, `Eq`, `Display`, and `Error`. `TxIdSlot` implements `Debug`, `Clone`, `Copy`, `PartialEq`, and `Eq`.
## Transaction events
`encode_event` and `decode_event` use envelope version byte `5`, followed by one stable tag byte and one postcard body. Tags are `1` Queue, `2` TranscriptionComplete, `3` Failed, `4` Discarded, `5` LabelConfirmation, and `6` Progress. Every event `TxId` and known `PersonId` serializes as exactly 12 raw bytes; `Some(PersonId)` is known and `None` is explicitly Unknown.
`decode_event` accepts only version 5, a known tag, one structurally valid body, and no trailing bytes. It returns the documented `FormatError` variants for malformed input and performs no semantic assignment or ordering validation.
## Local fragments and paths
The staged and final fragment codecs accept only format version 2. Bytes 0 through 15 contain version `2`, kind `1` staged or `2` final, and fourteen zero reserved bytes. Transaction slots retain their offsets and the body starts at byte 48.
Variable lengths and speaker counts are little-endian `u64`. Staged speakers and non-identity final-speaker fields retain their established order and encodings. A final identity is byte `0` for Unknown or byte `1` followed by the known `PersonId`'s 12 raw transaction-ID bytes.
`TxIdSlot` stores 12 ID bytes followed by four zero padding bytes. Fragment decoding returns the applicable `FormatError` for malformed input and performs no semantic validation of analysis values.
`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 function accesses a filesystem.
Event and fragment encoding and decoding use O(input plus output) work and output-proportional allocation; slot and path operations use bounded work and memory. The operations are stateless.