pub(crate) mod query;
pub(crate) mod request;
pub(crate) mod resolve;
pub(crate) mod store;
pub(crate) mod wire;
use std::collections::BTreeSet;
use std::path::PathBuf;
use anyhow::Context;
use crate::observation::store::Store;
use crate::observation::wire::{
Diagnostic, Envelope, ObservationKind, Payload, SCHEMA, SCHEMA_VERSION,
};
#[derive(Debug, Clone)]
pub(crate) struct SourceRegistry {
#[cfg_attr(not(test), expect(dead_code, reason = "test-only"))]
sources: BTreeSet<String>,
}
impl SourceRegistry {
pub(crate) fn empty() -> Self {
SourceRegistry {
sources: BTreeSet::new(),
}
}
#[cfg_attr(not(test), expect(dead_code, reason = "test-only"))]
pub(crate) fn register(&mut self, name: &str) {
self.sources.insert(name.to_string());
}
#[cfg_attr(not(test), expect(dead_code, reason = "test-only"))]
pub(crate) fn is_registered(&self, name: &str) -> bool {
self.sources.contains(name)
}
}
#[derive(Debug)]
pub(crate) struct Service {
store: Store,
#[cfg_attr(not(test), expect(dead_code, reason = "test-only until QUE-176"))]
registry: SourceRegistry,
}
impl Service {
pub(crate) fn new(root: PathBuf, registry: SourceRegistry) -> Self {
Service {
store: Store::new(root),
registry,
}
}
pub(crate) fn record_friction(
&self,
envelope: &Envelope,
) -> anyhow::Result<store::CreateReceipt> {
if envelope.kind() != ObservationKind::Friction {
anyhow::bail!(
"record_friction called with non-friction kind: {:?}",
envelope.kind()
);
}
self.store.create(envelope)
}
#[cfg_attr(not(test), expect(dead_code, reason = "test-only until QUE-176"))]
pub(crate) fn record_measurement(
&self,
envelope: &Envelope,
) -> anyhow::Result<store::CreateReceipt> {
if envelope.kind() != ObservationKind::Measurement {
anyhow::bail!(
"record_measurement called with non-measurement kind: {:?}",
envelope.kind()
);
}
let source = match &envelope.payload {
crate::observation::wire::Payload::Measurement { source, .. } => source.clone(),
_ => anyhow::bail!("record_measurement requires a measurement payload"),
};
if !self.registry.is_registered(&source) {
anyhow::bail!("measurement source '{source}' is not a registered machine source");
}
self.store.create(envelope)
}
pub(crate) fn record_supersession(
&self,
uid: &str,
recorded_at: &str,
old_uid: &str,
replacement_uid: &str,
reason: Option<&str>,
) -> anyhow::Result<store::CreateReceipt> {
let old_env = self
.load_one(old_uid)
.with_context(|| format!("supersession target {old_uid} does not exist"))?;
if !old_env.is_primary() {
anyhow::bail!("supersession target {old_uid} is a control, not a primary observation");
}
let replacement_env = self.load_one(replacement_uid).with_context(|| {
format!("supersession replacement {replacement_uid} does not exist")
})?;
if !replacement_env.is_primary() {
anyhow::bail!(
"supersession replacement {replacement_uid} is a control, not a primary observation"
);
}
if old_env.kind() != replacement_env.kind() {
anyhow::bail!(
"supersession replacement kind {:?} is incompatible with target kind {:?}",
replacement_env.kind(),
old_env.kind()
);
}
let envelope = Envelope {
schema: SCHEMA.to_string(),
schema_version: SCHEMA_VERSION,
uid: uid.to_string(),
recorded_at: recorded_at.to_string(),
facets: None,
payload: Payload::Supersession {
old_uid: old_uid.to_string(),
replacement_uid: replacement_uid.to_string(),
reason: reason.map(std::string::ToString::to_string),
},
};
self.store.create(&envelope)
}
pub(crate) fn record_retraction(
&self,
uid: &str,
recorded_at: &str,
target_uid: &str,
reason: Option<&str>,
) -> anyhow::Result<store::CreateReceipt> {
let target_env = self
.load_one(target_uid)
.with_context(|| format!("retraction target {target_uid} does not exist"))?;
if !target_env.is_primary() {
anyhow::bail!("retraction target {target_uid} is a control, not a primary observation");
}
let envelope = Envelope {
schema: SCHEMA.to_string(),
schema_version: SCHEMA_VERSION,
uid: uid.to_string(),
recorded_at: recorded_at.to_string(),
facets: None,
payload: Payload::Retraction {
target_uid: target_uid.to_string(),
reason: reason.map(std::string::ToString::to_string),
},
};
self.store.create(&envelope)
}
pub(crate) fn load_one(&self, uid: &str) -> anyhow::Result<Envelope> {
let rel = store::record_path(uid);
let abs = self.store.root.join(&rel);
Store::load_one(&abs)
}
pub(crate) fn load_all(&self) -> (Vec<Envelope>, Vec<Diagnostic>) {
self.store.load_all()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::observation::wire::{Payload, SCHEMA, SCHEMA_VERSION};
use std::collections::BTreeMap;
fn test_service() -> (tempfile::TempDir, Service) {
let dir = tempfile::tempdir().unwrap();
let registry = SourceRegistry::empty();
let svc = Service::new(dir.path().to_path_buf(), registry);
(dir, svc)
}
fn test_service_with_source(source_name: &str) -> (tempfile::TempDir, Service) {
let dir = tempfile::tempdir().unwrap();
let mut registry = SourceRegistry::empty();
registry.register(source_name);
let svc = Service::new(dir.path().to_path_buf(), registry);
(dir, svc)
}
fn friction_envelope(uid: &str, summary: &str) -> Envelope {
Envelope {
schema: SCHEMA.to_string(),
schema_version: SCHEMA_VERSION,
uid: uid.to_string(),
recorded_at: "2026-01-01T00:00:00Z".to_string(),
facets: None,
payload: Payload::Friction {
summary: summary.to_string(),
detail: None,
},
}
}
fn measurement_envelope(uid: &str, source: &str) -> Envelope {
Envelope {
schema: SCHEMA.to_string(),
schema_version: SCHEMA_VERSION,
uid: uid.to_string(),
recorded_at: "2026-01-01T00:00:00Z".to_string(),
facets: None,
payload: Payload::Measurement {
source: source.to_string(),
counters: BTreeMap::new(),
gauges: BTreeMap::new(),
scope: None,
units: None,
completeness: None,
},
}
}
#[test]
fn public_capture_refuses_measurement() {
let (_dir, svc) = test_service();
let env = measurement_envelope("019f1234-5678-7abc-8def-0123456789ab", "claude-p");
let err = svc.record_measurement(&env).unwrap_err();
assert!(
err.to_string().contains("not a registered machine source"),
"must refuse unregistered source, got: {err}"
);
}
#[test]
fn registered_machine_source_admits_measurement() {
let (_dir, svc) = test_service_with_source("claude-p");
let env = measurement_envelope("019f1234-5678-7abc-8def-0123456789ab", "claude-p");
let receipt = svc.record_measurement(&env).unwrap();
assert_eq!(receipt.uid, "019f1234-5678-7abc-8def-0123456789ab");
}
#[test]
fn asserted_source_cannot_open_measurement_gate() {
let (_dir, svc) = test_service();
let env = measurement_envelope("019f1234-5678-7abc-8def-0123456789ab", "claude-p");
let err = svc.record_measurement(&env).unwrap_err();
assert!(
err.to_string().contains("not a registered machine source"),
"caller-asserted source metadata must not open the gate, got: {err}"
);
}
#[test]
fn friction_is_always_admitted() {
let (_dir, svc) = test_service();
let env = friction_envelope("019f1234-5678-7abc-8def-0123456789ab", "test friction");
let receipt = svc.record_friction(&env).unwrap();
assert_eq!(receipt.uid, "019f1234-5678-7abc-8def-0123456789ab");
}
}