#![forbid(unsafe_code)]
pub use kcode_speaker_dataset::{
Dataset, DatasetError, FoldConfig, OpenSetFold, RepeatabilityGroup,
};
pub use kcode_speaker_eval::{
AggregateMetrics, CandidateEvaluation, EvalError, EvaluationPlan, EvaluationResult,
};
pub use kcode_speaker_extract::{ExtractError, ExtractionContract};
pub use kcode_speaker_model::{
ALL_24, CandidateScore, Decision, Identification, ModelConfig, ModelError, ModelSnapshot,
};
pub use kcode_speaker_store::{AttemptSnapshot, SampleState, StoreError};
pub use kcode_speaker_types::{
FEATURE_COUNT, FeatureMask, FeatureVector, Key, LabeledSample, ObjectId, RecordingKind,
SegmentRef,
};
use kcode_speaker_store::{
AttemptRecord, AttemptSelection, Event, EventEnvelope, InventorySnapshot, Query, Request,
Response, ResponseKind, SampleStateChange, SegmentRegistration, Store, StoredAdditionalSpeaker,
StoredAttemptOutcome, StoredSpeaker,
};
use std::{collections::BTreeSet, error::Error, fmt, path::Path};
const _: [(); 24] = [(); FEATURE_COUNT];
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SegmentBinding {
pub event_id: Key,
pub clip_object: ObjectId,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SourceRegistration {
pub source_object: ObjectId,
pub source_duration_ms: u64,
pub group_id: Key,
pub recording_kind: RecordingKind,
pub segments: Vec<SegmentBinding>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct NormalizedAttempt<'a> {
pub event_id: Key,
pub attempt_id: Key,
pub cohort_id: Key,
pub source_object: ObjectId,
pub clip_object: ObjectId,
pub segment_ordinal: u16,
pub provider_result_object: ObjectId,
pub recording_quality: Option<u8>,
pub normalized_response: &'a str,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AttemptSelectionRequest {
pub event_id: Key,
pub attempt_id: Key,
pub cohort_id: Key,
pub clip_object: ObjectId,
pub reason: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SampleStateRequest {
pub event_id: Key,
pub sample_id: Key,
pub state: SampleState,
pub reason: String,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CommitReceipt {
pub revision: u64,
pub applied: u64,
}
#[derive(Debug)]
pub enum SystemError {
Boundary(&'static str),
ProjectionRevisionChanged {
active_revision: u64,
repeatability_revision: u64,
},
UnexpectedStoreResponse(&'static str),
Extract(ExtractError),
Store(StoreError),
Dataset(DatasetError),
Model(ModelError),
Eval(EvalError),
}
impl fmt::Display for SystemError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Boundary(message) => write!(formatter, "boundary: {message}"),
Self::ProjectionRevisionChanged {
active_revision,
repeatability_revision,
} => write!(
formatter,
"store projection revision changed between reads ({active_revision} then {repeatability_revision})"
),
Self::UnexpectedStoreResponse(message) => {
write!(formatter, "unexpected store response: {message}")
}
Self::Extract(error) => error.fmt(formatter),
Self::Store(error) => error.fmt(formatter),
Self::Dataset(error) => error.fmt(formatter),
Self::Model(error) => error.fmt(formatter),
Self::Eval(error) => error.fmt(formatter),
}
}
}
impl Error for SystemError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Extract(error) => Some(error),
Self::Store(error) => Some(error),
Self::Dataset(error) => Some(error),
Self::Model(error) => Some(error),
Self::Eval(error) => Some(error),
Self::Boundary(_)
| Self::ProjectionRevisionChanged { .. }
| Self::UnexpectedStoreResponse(_) => None,
}
}
}
impl From<ExtractError> for SystemError {
fn from(error: ExtractError) -> Self {
Self::Extract(error)
}
}
impl From<StoreError> for SystemError {
fn from(error: StoreError) -> Self {
Self::Store(error)
}
}
impl From<DatasetError> for SystemError {
fn from(error: DatasetError) -> Self {
Self::Dataset(error)
}
}
impl From<ModelError> for SystemError {
fn from(error: ModelError) -> Self {
Self::Model(error)
}
}
impl From<EvalError> for SystemError {
fn from(error: EvalError) -> Self {
Self::Eval(error)
}
}
pub struct SpeakerSystem {
store: Store,
}
pub fn cohort_id() -> &'static Key {
&extraction_contract().normalized_schema_key
}
pub fn extraction_contract() -> &'static ExtractionContract {
kcode_speaker_extract::contract()
}
pub fn normalization_prompt(raw_analysis: &str) -> Result<String, SystemError> {
kcode_speaker_extract::normalization_prompt(raw_analysis).map_err(SystemError::from)
}
pub fn open(path: impl AsRef<Path>) -> Result<SpeakerSystem, SystemError> {
Ok(SpeakerSystem {
store: kcode_speaker_store::open(path)?,
})
}
impl SpeakerSystem {
pub fn register_source(
&self,
request: SourceRegistration,
) -> Result<CommitReceipt, SystemError> {
let SourceRegistration {
source_object,
source_duration_ms,
group_id,
recording_kind,
segments,
} = request;
let plan = kcode_speaker_extract::plan_segments(source_duration_ms)?;
if segments.len() != plan.segments.len() {
return Err(SystemError::Boundary(
"clip bindings must exactly match the planned segment count",
));
}
let mut event_ids = BTreeSet::new();
let mut clip_objects = BTreeSet::new();
for binding in &segments {
if !event_ids.insert(binding.event_id.clone()) {
return Err(SystemError::Boundary(
"source registration event IDs must be unique",
));
}
if !clip_objects.insert(binding.clip_object.clone()) {
return Err(SystemError::Boundary(
"source registration clip object IDs must be unique",
));
}
}
let segment_count = u16::try_from(plan.segments.len()).map_err(|_| {
SystemError::Boundary("planned segment count exceeds the shared u16 boundary")
})?;
let events = segments
.into_iter()
.zip(plan.segments)
.map(|(binding, planned)| EventEnvelope {
event_id: binding.event_id,
event: Event::RegisterSegment(SegmentRegistration {
segment: SegmentRef {
source_object: source_object.clone(),
clip_object: binding.clip_object,
ordinal: planned.ordinal,
segment_count,
start_ms: planned.start_ms,
end_ms: planned.end_ms,
policy: plan.policy.clone(),
},
group_id: group_id.clone(),
recording_kind,
}),
})
.collect();
self.commit(events)
}
pub fn record_normalized_attempt(
&self,
request: NormalizedAttempt<'_>,
) -> Result<CommitReceipt, SystemError> {
let NormalizedAttempt {
event_id,
attempt_id,
cohort_id: requested_cohort,
source_object,
clip_object,
segment_ordinal,
provider_result_object,
recording_quality,
normalized_response,
} = request;
require_frozen_cohort(&requested_cohort)?;
let registration =
self.registered_segment(&source_object, &clip_object, segment_ordinal)?;
let clip_duration_ms = registration.segment.end_ms - registration.segment.start_ms;
let parsed = kcode_speaker_extract::parse(normalized_response, clip_duration_ms)?;
let outcome = match parsed {
kcode_speaker_extract::ExtractionOutcome::Scored(scored) => {
let recording_quality = recording_quality.ok_or(SystemError::Boundary(
"scored outcomes require caller-supplied recording quality",
))?;
if recording_quality > 100 {
return Err(SystemError::Boundary(
"recording quality must be at most 100",
));
}
StoredAttemptOutcome::Scored {
recording_quality,
speakers: scored
.speakers
.into_iter()
.map(|speaker| StoredSpeaker {
speaker_ordinal: speaker.speaker_ordinal,
primary_language: speaker.primary_language,
closest_dialect: speaker.closest_dialect,
usable_speech_ms: speaker.usable_speech_ms,
features: speaker.features,
})
.collect(),
additional_speakers: scored
.additional_speakers
.into_iter()
.map(|speaker| StoredAdditionalSpeaker {
speaker_ordinal: speaker.speaker_ordinal,
description: speaker.description,
})
.collect(),
}
}
kcode_speaker_extract::ExtractionOutcome::Unscorable {
reason,
additional_speakers,
} => {
if recording_quality.is_some() {
return Err(SystemError::Boundary(
"unscorable outcomes must not discard recording quality",
));
}
StoredAttemptOutcome::Unscorable {
reason,
additional_speakers: additional_speakers
.into_iter()
.map(|speaker| StoredAdditionalSpeaker {
speaker_ordinal: speaker.speaker_ordinal,
description: speaker.description,
})
.collect(),
}
}
};
self.commit(vec![EventEnvelope {
event_id,
event: Event::RecordAttempt(AttemptRecord {
attempt_id,
clip_object,
extraction_key: requested_cohort,
provider_result_object: Some(provider_result_object),
outcome,
}),
}])
}
pub fn select_attempt(
&self,
request: AttemptSelectionRequest,
) -> Result<CommitReceipt, SystemError> {
let AttemptSelectionRequest {
event_id,
attempt_id,
cohort_id: requested_cohort,
clip_object,
reason,
} = request;
require_frozen_cohort(&requested_cohort)?;
let snapshot = self
.attempt(&attempt_id)?
.ok_or(SystemError::Boundary("selected attempt does not exist"))?;
if snapshot.attempt.clip_object != clip_object
|| snapshot.attempt.extraction_key != requested_cohort
|| !matches!(
&snapshot.attempt.outcome,
StoredAttemptOutcome::Scored { .. }
)
{
return Err(SystemError::Boundary(
"selection must match a scored attempt, clip, and cohort",
));
}
self.commit(vec![EventEnvelope {
event_id,
event: Event::SelectAttempt(AttemptSelection {
clip_object,
extraction_key: requested_cohort,
attempt_id,
reason,
}),
}])
}
pub fn change_sample_state(
&self,
request: SampleStateRequest,
) -> Result<CommitReceipt, SystemError> {
let SampleStateRequest {
event_id,
sample_id,
state,
reason,
} = request;
let response = self.store.execute(Request::Read(Query::Attempts {
extraction_key: Some(cohort_id().clone()),
source_object: None,
}))?;
let ResponseKind::Attempts(attempts) = response.result else {
return Err(SystemError::UnexpectedStoreResponse(
"attempt-list query returned another result kind",
));
};
if !attempts
.iter()
.any(|attempt| attempt.sample_ids.contains(&sample_id))
{
return Err(SystemError::Boundary(
"sample does not belong to a complete speaker in the frozen cohort",
));
}
self.commit(vec![EventEnvelope {
event_id,
event: Event::SetSampleState(SampleStateChange {
sample_id,
state,
reason,
}),
}])
}
pub fn attempt(&self, attempt_id: &Key) -> Result<Option<AttemptSnapshot>, SystemError> {
let response = self.store.execute(Request::Read(Query::Attempt {
attempt_id: attempt_id.clone(),
}))?;
match response.result {
ResponseKind::Attempt(snapshot) => Ok(snapshot),
_ => Err(SystemError::UnexpectedStoreResponse(
"attempt query returned another result kind",
)),
}
}
pub fn dataset(&self, requested_cohort: &Key) -> Result<Dataset, SystemError> {
require_frozen_cohort(requested_cohort)?;
let active_response = self.store.execute(Request::Read(Query::TrainingRows {
cohort_id: requested_cohort.clone(),
}))?;
let active_revision = active_response.revision;
let ResponseKind::TrainingRows(active_rows) = active_response.result else {
return Err(SystemError::UnexpectedStoreResponse(
"training-row query returned another result kind",
));
};
let repeatability_response =
self.store.execute(Request::Read(Query::RepeatabilityRows {
cohort_id: requested_cohort.clone(),
}))?;
let repeatability_revision = repeatability_response.revision;
if active_revision != repeatability_revision {
return Err(SystemError::ProjectionRevisionChanged {
active_revision,
repeatability_revision,
});
}
let ResponseKind::RepeatabilityRows(repeatability_rows) = repeatability_response.result
else {
return Err(SystemError::UnexpectedStoreResponse(
"repeatability-row query returned another result kind",
));
};
kcode_speaker_dataset::build(active_rows, repeatability_rows).map_err(SystemError::from)
}
fn registered_segment(
&self,
source_object: &ObjectId,
clip_object: &ObjectId,
segment_ordinal: u16,
) -> Result<SegmentRegistration, SystemError> {
let response = self.store.execute(Request::Read(Query::Inventory {
extraction_key: None,
}))?;
let ResponseKind::Inventory(inventory) = response.result else {
return Err(SystemError::UnexpectedStoreResponse(
"inventory query returned another result kind",
));
};
validate_registered_segment(&inventory, source_object, clip_object, segment_ordinal)
}
fn commit(&self, events: Vec<EventEnvelope>) -> Result<CommitReceipt, SystemError> {
let Response { revision, result } = self.store.execute(Request::Commit(events))?;
match result {
ResponseKind::Commit { applied } => Ok(CommitReceipt { revision, applied }),
_ => Err(SystemError::UnexpectedStoreResponse(
"commit returned another result kind",
)),
}
}
}
pub fn open_set_folds(
dataset: &Dataset,
config: FoldConfig,
) -> Result<Vec<OpenSetFold>, SystemError> {
kcode_speaker_dataset::open_set_folds(dataset, config).map_err(SystemError::from)
}
pub fn repeatability_groups(dataset: &Dataset) -> Vec<RepeatabilityGroup> {
kcode_speaker_dataset::repeatability_groups(dataset)
}
pub fn fit(
dataset: &Dataset,
requested_cohort: &Key,
config: ModelConfig,
) -> Result<ModelSnapshot, SystemError> {
require_frozen_cohort(requested_cohort)?;
let samples = kcode_speaker_dataset::active_rows(dataset);
if samples
.iter()
.any(|sample| sample.cohort_id != *requested_cohort)
{
return Err(SystemError::Boundary(
"dataset rows must all match the requested frozen cohort",
));
}
kcode_speaker_model::fit(kcode_speaker_model::FitInput {
cohort_id: requested_cohort,
samples,
config,
})
.map_err(SystemError::from)
}
pub fn identify(
model: &ModelSnapshot,
requested_cohort: &Key,
features: &FeatureVector,
) -> Result<Identification, SystemError> {
require_frozen_cohort(requested_cohort)?;
kcode_speaker_model::identify(model, requested_cohort, features).map_err(SystemError::from)
}
pub fn snapshot_bytes(model: &ModelSnapshot) -> Result<Vec<u8>, SystemError> {
kcode_speaker_model::encode(model).map_err(SystemError::from)
}
pub fn snapshot_from_bytes(bytes: &[u8]) -> Result<ModelSnapshot, SystemError> {
kcode_speaker_model::decode(bytes).map_err(SystemError::from)
}
pub fn evaluate(plan: EvaluationPlan<'_>) -> Result<EvaluationResult, SystemError> {
let rows = kcode_speaker_dataset::active_rows(plan.dataset);
let dataset_cohort = rows
.first()
.ok_or(SystemError::Boundary(
"evaluation dataset has no active rows",
))?
.cohort_id
.clone();
require_frozen_cohort(&dataset_cohort)?;
if rows.iter().any(|row| row.cohort_id != dataset_cohort) {
return Err(SystemError::Boundary(
"evaluation dataset rows must share the frozen cohort",
));
}
kcode_speaker_eval::evaluate(plan).map_err(SystemError::from)
}
fn require_frozen_cohort(requested: &Key) -> Result<(), SystemError> {
if requested != cohort_id() {
return Err(SystemError::Boundary(
"cohort ID must equal the frozen normalized extraction schema key",
));
}
Ok(())
}
fn validate_registered_segment(
inventory: &InventorySnapshot,
source_object: &ObjectId,
clip_object: &ObjectId,
segment_ordinal: u16,
) -> Result<SegmentRegistration, SystemError> {
let target = inventory
.registrations
.iter()
.find(|registration| registration.segment.clip_object == *clip_object)
.cloned()
.ok_or(SystemError::Boundary("clip object is not registered"))?;
if target.segment.source_object != *source_object || target.segment.ordinal != segment_ordinal {
return Err(SystemError::Boundary(
"source object, clip object, and segment ordinal do not match",
));
}
let source_registrations = inventory
.registrations
.iter()
.filter(|registration| registration.segment.source_object == *source_object)
.collect::<Vec<_>>();
if source_registrations.len() != usize::from(target.segment.segment_count) {
return Err(SystemError::Boundary(
"registered source does not contain its complete segment plan",
));
}
let source_duration_ms = source_registrations
.iter()
.map(|registration| registration.segment.end_ms)
.max()
.ok_or(SystemError::Boundary(
"registered source has no segment ranges",
))?;
let plan = kcode_speaker_extract::plan_segments(source_duration_ms)?;
if plan.segments.len() != source_registrations.len() {
return Err(SystemError::Boundary(
"registered source segment count differs from deterministic planning",
));
}
for planned in &plan.segments {
let registration = source_registrations
.iter()
.find(|registration| registration.segment.ordinal == planned.ordinal)
.ok_or(SystemError::Boundary(
"registered source is missing a planned segment ordinal",
))?;
if registration.segment.segment_count != target.segment.segment_count
|| registration.segment.policy != plan.policy
|| registration.segment.start_ms != planned.start_ms
|| registration.segment.end_ms != planned.end_ms
{
return Err(SystemError::Boundary(
"registered source ranges differ from deterministic planning",
));
}
}
Ok(target)
}
#[cfg(test)]
mod tests {
use super::*;
use kcode_speaker_store::StoredAttemptOutcome;
use std::{
fs,
path::PathBuf,
sync::atomic::{AtomicU64, Ordering},
};
static NEXT_PATH: AtomicU64 = AtomicU64::new(0);
fn key(value: &str) -> Key {
Key::parse(value).unwrap()
}
fn object(value: &str) -> ObjectId {
ObjectId::parse(value).unwrap()
}
fn path() -> PathBuf {
std::env::temp_dir().join(format!(
"kcode-speaker-system-{}-{}.db",
std::process::id(),
NEXT_PATH.fetch_add(1, Ordering::Relaxed)
))
}
fn feature_values(seed: u8) -> String {
(0..FEATURE_COUNT)
.map(|index| (usize::from(seed) + index).to_string())
.collect::<Vec<_>>()
.join(",")
}
fn scored_response(seed: u8, has_additional_speaker: bool) -> String {
let features = feature_values(seed);
let additional = if has_additional_speaker {
r#"[{"speakerOrdinal":1,"description":"Brief background interjection."}]"#
} else {
"[]"
};
format!(
r#"{{"status":"scored","speakers":[{{"speakerOrdinal":0,"primaryLanguage":"en-US","closestDialect":"General American English","usableSpeechMs":20000,"features":[{features}]}}],"additionalSpeakers":{additional}}}"#
)
}
fn register(system: &SpeakerSystem, source: &str, clip: &str, event_id: &str, group: &str) {
system
.register_source(SourceRegistration {
source_object: object(source),
source_duration_ms: 100_000,
group_id: key(group),
recording_kind: RecordingKind::VoiceNote,
segments: vec![SegmentBinding {
event_id: key(event_id),
clip_object: object(clip),
}],
})
.unwrap();
}
fn record(
system: &SpeakerSystem,
source: &str,
clip: &str,
event_id: &str,
attempt_id: &str,
result_object: &str,
response: &str,
) {
system
.record_normalized_attempt(NormalizedAttempt {
event_id: key(event_id),
attempt_id: key(attempt_id),
cohort_id: cohort_id().clone(),
source_object: object(source),
clip_object: object(clip),
segment_ordinal: 0,
provider_result_object: object(result_object),
recording_quality: Some(87),
normalized_response: response,
})
.unwrap();
}
fn select_and_confirm(
system: &SpeakerSystem,
attempt_id: &str,
clip: &str,
select_event: &str,
state_event: &str,
) -> Key {
let snapshot = system.attempt(&key(attempt_id)).unwrap().unwrap();
assert_eq!(snapshot.sample_ids.len(), 1);
let sample_id = snapshot.sample_ids[0].clone();
system
.select_attempt(AttemptSelectionRequest {
event_id: key(select_event),
attempt_id: key(attempt_id),
cohort_id: cohort_id().clone(),
clip_object: object(clip),
reason: "reviewed complete profile".into(),
})
.unwrap();
system
.change_sample_state(SampleStateRequest {
event_id: key(state_event),
sample_id: sample_id.clone(),
state: SampleState::Confirmed {
speaker_id: key("speaker/alice"),
},
reason: "confirmed caller label".into(),
})
.unwrap();
sample_id
}
#[test]
fn exact_extraction_store_dataset_and_model_contracts_compose() {
let direct_contract = kcode_speaker_extract::contract();
assert!(std::ptr::eq(extraction_contract(), direct_contract));
assert_eq!(
extraction_contract().schema_key.as_ref(),
"gemini-speaker-24-freeform/1"
);
assert_eq!(
extraction_contract().normalized_schema_key.as_ref(),
"gemini-speaker-24-normalized/1"
);
assert_eq!(extraction_contract().response_mime, "text/plain");
assert_eq!(extraction_contract().normalized_mime, "application/json");
assert!(
extraction_contract()
.prompt
.starts_with("Analyze the attached audio directly and separate")
);
assert!(
extraction_contract()
.prompt
.contains("24. sibilant_sharpness")
);
assert!(!extraction_contract().prompt.contains("recording_quality"));
let raw_analysis = "Speaker 1: complete profile. Speaker 2: too brief.";
assert_eq!(
normalization_prompt(raw_analysis).unwrap(),
kcode_speaker_extract::normalization_prompt(raw_analysis).unwrap()
);
let database = path();
let system = open(&database).unwrap();
register(
&system,
"SOURCE01",
"CLIP0001",
"event/register/1",
"group/source/1",
);
register(
&system,
"SOURCE02",
"CLIP0002",
"event/register/2",
"group/source/2",
);
let first_response = scored_response(10, true);
let second_response = scored_response(60, false);
record(
&system,
"SOURCE01",
"CLIP0001",
"event/attempt/1",
"attempt/1",
"RESULT01",
&first_response,
);
record(
&system,
"SOURCE02",
"CLIP0002",
"event/attempt/2",
"attempt/2",
"RESULT02",
&second_response,
);
let first = system.attempt(&key("attempt/1")).unwrap().unwrap();
assert_eq!(first.sample_ids.len(), 1);
let StoredAttemptOutcome::Scored {
recording_quality,
speakers,
additional_speakers,
} = &first.attempt.outcome
else {
panic!("expected scored stored outcome");
};
assert_eq!(*recording_quality, 87);
assert_eq!(speakers.len(), 1);
assert_eq!(speakers[0].speaker_ordinal, 0);
assert_eq!(speakers[0].features.as_ref().len(), FEATURE_COUNT);
assert_eq!(additional_speakers.len(), 1);
assert_eq!(additional_speakers[0].speaker_ordinal, 1);
let first_sample = select_and_confirm(
&system,
"attempt/1",
"CLIP0001",
"event/select/1",
"event/state/1",
);
let second_sample = select_and_confirm(
&system,
"attempt/2",
"CLIP0002",
"event/select/2",
"event/state/2",
);
assert_ne!(first_sample, second_sample);
let dataset = system.dataset(cohort_id()).unwrap();
let rows = kcode_speaker_dataset::active_rows(&dataset);
assert_eq!(rows.len(), 2);
assert!(
rows.iter()
.all(|row| row.speaker_id.as_ref() == "speaker/alice")
);
assert!(
rows.iter()
.all(|row| row.features.as_ref().len() == FEATURE_COUNT)
);
let model = fit(
&dataset,
cohort_id(),
ModelConfig {
mask: ALL_24,
components: 1,
relevance: 2.0,
variance_floor: 0.01,
absolute_threshold: -1.0e9,
margin_threshold: -1.0e9,
},
)
.unwrap();
let before = identify(&model, cohort_id(), &rows[0].features).unwrap();
assert!(matches!(
before.decision,
Decision::Known { ref speaker_id }
if speaker_id.as_ref() == "speaker/alice"
));
let bytes = snapshot_bytes(&model).unwrap();
let decoded = snapshot_from_bytes(&bytes).unwrap();
assert_eq!(bytes, snapshot_bytes(&decoded).unwrap());
assert_eq!(
before,
identify(&decoded, cohort_id(), &rows[0].features).unwrap()
);
drop(system);
fs::remove_file(database).unwrap();
}
#[test]
fn incompatible_boundary_inputs_fail_closed() {
let database = path();
let system = open(&database).unwrap();
register(
&system,
"SOURCE11",
"CLIP0011",
"event/register/11",
"group/source/11",
);
register(
&system,
"SOURCE12",
"CLIP0012",
"event/register/12",
"group/source/12",
);
let response = scored_response(20, false);
record(
&system,
"SOURCE11",
"CLIP0011",
"event/attempt/original",
"attempt/original",
"RESULT11",
&response,
);
let wrong_cohort = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/wrong/cohort"),
attempt_id: key("attempt/wrong/cohort"),
cohort_id: key("different/cohort"),
source_object: object("SOURCE11"),
clip_object: object("CLIP0011"),
segment_ordinal: 0,
provider_result_object: object("RESULT12"),
recording_quality: Some(80),
normalized_response: &response,
});
assert!(matches!(wrong_cohort, Err(SystemError::Boundary(_))));
assert!(
system
.attempt(&key("attempt/wrong/cohort"))
.unwrap()
.is_none()
);
let wrong_ordinal = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/wrong/ordinal"),
attempt_id: key("attempt/wrong/ordinal"),
cohort_id: cohort_id().clone(),
source_object: object("SOURCE11"),
clip_object: object("CLIP0011"),
segment_ordinal: 1,
provider_result_object: object("RESULT13"),
recording_quality: Some(80),
normalized_response: &response,
});
assert!(matches!(wrong_ordinal, Err(SystemError::Boundary(_))));
let wrong_source = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/wrong/source"),
attempt_id: key("attempt/wrong/source"),
cohort_id: cohort_id().clone(),
source_object: object("SOURCE12"),
clip_object: object("CLIP0011"),
segment_ordinal: 0,
provider_result_object: object("RESULT14"),
recording_quality: Some(80),
normalized_response: &response,
});
assert!(matches!(wrong_source, Err(SystemError::Boundary(_))));
let wrong_speaker_ordinal =
response.replace("\"speakerOrdinal\":0", "\"speakerOrdinal\":1");
let ordinal_result = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/wrong/speaker"),
attempt_id: key("attempt/wrong/speaker"),
cohort_id: cohort_id().clone(),
source_object: object("SOURCE11"),
clip_object: object("CLIP0011"),
segment_ordinal: 0,
provider_result_object: object("RESULT15"),
recording_quality: Some(80),
normalized_response: &wrong_speaker_ordinal,
});
assert!(matches!(ordinal_result, Err(SystemError::Extract(_))));
let short_features = (0..FEATURE_COUNT - 1)
.map(|_| "50")
.collect::<Vec<_>>()
.join(",");
let wrong_feature_count = format!(
r#"{{"status":"scored","speakers":[{{"speakerOrdinal":0,"primaryLanguage":"en-US","closestDialect":"General American English","usableSpeechMs":20000,"features":[{short_features}]}}],"additionalSpeakers":[]}}"#
);
let feature_result = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/wrong/features"),
attempt_id: key("attempt/wrong/features"),
cohort_id: cohort_id().clone(),
source_object: object("SOURCE11"),
clip_object: object("CLIP0011"),
segment_ordinal: 0,
provider_result_object: object("RESULT16"),
recording_quality: Some(80),
normalized_response: &wrong_feature_count,
});
assert!(matches!(feature_result, Err(SystemError::Extract(_))));
let duplicate_attempt = system.record_normalized_attempt(NormalizedAttempt {
event_id: key("event/duplicate/attempt"),
attempt_id: key("attempt/original"),
cohort_id: cohort_id().clone(),
source_object: object("SOURCE12"),
clip_object: object("CLIP0012"),
segment_ordinal: 0,
provider_result_object: object("RESULT17"),
recording_quality: Some(80),
normalized_response: &response,
});
assert!(matches!(
duplicate_attempt,
Err(SystemError::Store(StoreError::Conflict(_)))
));
let mismatched_selection = system.select_attempt(AttemptSelectionRequest {
event_id: key("event/wrong/selection"),
attempt_id: key("attempt/original"),
cohort_id: cohort_id().clone(),
clip_object: object("CLIP0012"),
reason: "wrong clip must not select".into(),
});
assert!(matches!(
mismatched_selection,
Err(SystemError::Boundary(_))
));
let original = system.attempt(&key("attempt/original")).unwrap().unwrap();
assert_eq!(original.attempt.clip_object, object("CLIP0011"));
assert!(!original.selected);
drop(system);
fs::remove_file(database).unwrap();
}
}