# Audio classification projection state
Persisted status types, validation, bounded error retention, and label-confirmation helpers for K1 audio classification.
Version 0.2.1 exact-pins audio-classification format 0.6.1 and uses `kcode-speaker-v3-analysis` 0.3.0 for test fixtures. This dependency-only cutover preserves persisted state formats, schemas, public APIs, and behavior.
## Public API
```rust
pub use kcode_k1_audio_classification_format::{
ExecutedAnalysis, FragmentStageV1, PersonId, SpeakerLabelV1, TxId,
};
pub const MAX_ERRORS: usize = 5_000;
pub type FragmentId = TxId;
pub enum OverallState { Queued, Running, Failed, Completed, Confirmed, Discarded }
pub enum StageState { Pending, Running, Succeeded, Failed }
pub enum LlmJobState { Running, Succeeded, Failed }
pub struct StageStatus { pub stage: FragmentStageV1, pub state: StageState }
pub struct LlmJobStatus {
pub attempt: u32,
pub sequence: u64,
pub stage: FragmentStageV1,
pub name: String,
pub state: LlmJobState,
}
pub struct FragmentStatus {
pub state: OverallState,
pub queue: StageStatus,
pub transcript: StageStatus,
pub speaker_labels: StageStatus,
pub speaker_features: StageStatus,
pub structuring: StageStatus,
pub label_confirmation: StageStatus,
pub attempt_count: u32,
pub jobs: Vec<LlmJobStatus>,
pub interim_txid: Option<FragmentId>,
pub analysis: Option<ExecutedAnalysis>,
pub confirmed_labels: Vec<SpeakerLabelV1>,
pub final_transcript: Option<String>,
pub errors: Vec<String>,
pub errors_truncated: bool,
}
pub fn append_error(status: &mut FragmentStatus, error: String);
pub fn validate_labels(status: &FragmentStatus, labels: &[SpeakerLabelV1]) -> Result<FragmentId, String>;
pub fn final_transcript(status: &FragmentStatus, labels: &[SpeakerLabelV1]) -> Result<(FragmentId, String), String>;
pub fn actionable_state(state: OverallState) -> i64;
pub fn interrupted_stage(status: &FragmentStatus) -> FragmentStageV1;
pub fn validate_status(status: &FragmentStatus, stored_actionable_state: i64) -> Result<(), String>;
```
The state enums implement `Clone`, `Copy`, `Debug`, `PartialEq`, `Eq`, `Serialize`, and `Deserialize`. `StageStatus` and `LlmJobStatus` implement `Clone`, `Debug`, `PartialEq`, `Eq`, `Serialize`, and `Deserialize`. `FragmentStatus` implements `Clone`, `Debug`, `PartialEq`, `Serialize`, and `Deserialize`. Its field order, enum variant order, and optional fragment-ID representation are persisted; confirmed-label identities use the format facade's `Option<PersonId>` representation and do not decode legacy strings.
`append_error` retains the first, oldest `MAX_ERRORS`; later errors only set `errors_truncated`. `validate_labels` verifies that labels can confirm a completed status and returns its interim transaction ID. `final_transcript` performs the same validation and returns that ID with the derived transcript. Labels must be one-to-one with analysis speakers in exact analysis order. Transcript derivation replaces only exact `Speaker N` tokens in lines beginning `[high] `, `[medium] `, or `[low] ` and followed by `:` or ` [overlap]:`; `Some(PersonId)` becomes its canonical lowercase 24-hex display, `None` becomes `Unknown`, and all other bytes are preserved.
`actionable_state` returns `1` for `Queued`, `2` for `Running`, and `0` otherwise. `interrupted_stage` returns the latest running analysis stage in structuring, speaker-features, speaker-labels, transcript priority, or Queue when none is running. `validate_status` checks field-stage identities, actionable-state agreement, the error bound, job validity and order, Queue-stage validity, and required completion and confirmation fields.
Operations use work linear in the addressed status, jobs, labels, transcript, and capped errors and perform no I/O or synchronization.
## Version 0.2.2
Version 0.2.2 advances the compatible audio-classification-format 0.6.2 and Speaker Analysis 0.3.1 lines and changes every internal `kcode-*` dependency requirement to a Cargo-compatible lower bound. Public APIs, persisted state, schema, and runtime behavior remain unchanged.