use std::collections::BTreeSet;
use serde_json::Value;
use super::test_log::{EventKind, TestEvent, log_event, test_id_or};
pub const VOLATILE_FIELD_NAMES: &[&str] = &[
"generatedAt",
"generated_at",
"createdAt",
"created_at",
"updatedAt",
"completedAt",
"finishedAt",
"expiresAt",
"capturedAt",
"captured_at",
"computedAt",
"computed_at",
"observedAt",
"recordedAt",
"refreshedAt",
"selectedAt",
"decidedAt",
"estimatedAt",
"exposedAt",
"lastValidatedAt",
"last_accessed",
"last_accessed_at",
"last_seen_at",
"last_used_at",
"audit_ts",
"elapsedMs",
"elapsed_ms",
"elapsedMsBucket",
"durationMs",
"wallClockMs",
"startedAt",
"started_at",
"endedAt",
"ended_at",
"ts",
"timestamp",
"runIndex",
"run_index",
"runDurationMs",
"run_duration_ms",
"ee_binary_hash",
"capsule_id",
"integrity",
"swarm_brief_summary",
"swarm_incident_summary",
"swarm_replay_summary",
"environment_attestation_summary",
"pack_replay_summary",
"proof_broker_summary",
"regression_causality_summary",
"shadow_policy_summary",
"contention_summary",
"databasePath",
"workspacePath",
"indexDir",
"snapshotRefreshedAt",
"witnessElapsedMs",
"witnessRecordedAt",
"algorithmStartedAt",
"projectionMs",
"pagerankMs",
"betweennessMs",
"totalMs",
"selfNodeKey",
"selfTailscaleIp",
"selfMagicDnsName",
"tailnetId",
"tailnetDisplayName",
"selfAdvertisedTags",
"peerNodeKey",
"peerTailscaleIps",
"peerMagicDnsName",
"peerHostname",
"peerAdvertisedTags",
"binaryVersionRaw",
"binaryAbsolutePath",
];
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VolatileStripReport {
pub fields_stripped_count: usize,
pub fields_stripped: Vec<&'static str>,
pub input_bytes: usize,
pub output_bytes: usize,
}
#[must_use]
pub fn is_volatile_field_name(field_name: &str) -> bool {
canonical_field_name(field_name).is_some()
}
pub fn strip_volatile_fields(value: &mut Value) -> VolatileStripReport {
let input_bytes = serialized_len(value);
let mut stripped = BTreeSet::new();
strip_volatile_fields_inner(value, &mut stripped);
let output_bytes = serialized_len(value);
let fields_stripped = VOLATILE_FIELD_NAMES
.iter()
.copied()
.filter(|field| stripped.contains(field))
.collect::<Vec<_>>();
let report = VolatileStripReport {
fields_stripped_count: fields_stripped.len(),
fields_stripped,
input_bytes,
output_bytes,
};
log_volatile_strip(&report);
report
}
fn strip_volatile_fields_inner(value: &mut Value, stripped: &mut BTreeSet<&'static str>) {
match value {
Value::Object(object) => {
let keys = object
.keys()
.filter_map(|key| canonical_field_name(key))
.collect::<Vec<_>>();
for key in keys {
object.remove(key);
stripped.insert(key);
}
for child in object.values_mut() {
strip_volatile_fields_inner(child, stripped);
}
}
Value::Array(items) => {
for item in items {
strip_volatile_fields_inner(item, stripped);
}
}
_ => {}
}
}
fn canonical_field_name(field_name: &str) -> Option<&'static str> {
VOLATILE_FIELD_NAMES
.iter()
.copied()
.find(|registered| *registered == field_name)
}
fn serialized_len(value: &Value) -> usize {
serde_json::to_vec(value).map_or(0, |bytes| bytes.len())
}
fn log_volatile_strip(report: &VolatileStripReport) {
let fields = report
.fields_stripped
.iter()
.map(|field| Value::String((*field).to_owned()))
.collect::<Vec<_>>();
let event = TestEvent::new(test_id_or("volatile_field_strip"), EventKind::VolatileStrip)
.with_field(
"fields_stripped_count",
u64::try_from(report.fields_stripped_count).unwrap_or(u64::MAX),
)
.with_field("fields_stripped", Value::Array(fields))
.with_field(
"input_bytes",
u64::try_from(report.input_bytes).unwrap_or(u64::MAX),
)
.with_field(
"output_bytes",
u64::try_from(report.output_bytes).unwrap_or(u64::MAX),
);
log_event(event);
}
#[cfg(test)]
mod tests {
use super::{VOLATILE_FIELD_NAMES, is_volatile_field_name, strip_volatile_fields};
type TestResult = Result<(), String>;
#[test]
fn registry_names_are_unique() -> TestResult {
let mut names = std::collections::BTreeSet::new();
for name in VOLATILE_FIELD_NAMES {
if name.trim().is_empty() {
return Err("empty volatile field name".to_owned());
}
if !names.insert(name) {
return Err(format!("duplicate volatile field name: {name}"));
}
}
Ok(())
}
#[test]
fn strip_volatile_fields_recurses_and_reports() -> TestResult {
let mut value = serde_json::json!({
"schema": "ee.response.v2",
"generatedAt": "2026-05-13T00:00:00Z",
"data": {
"createdAt": "2026-05-13T00:00:00Z",
"updatedAt": "2026-05-13T00:00:01Z",
"computed_at": "2026-05-13T00:00:01Z",
"observedAt": "2026-05-13T00:00:02Z",
"items": [
{"id": "mem_a", "elapsedMs": 12, "durationMs": 11, "content": "keep"},
{"id": "mem_b", "last_seen_at": "2026-05-13T00:00:01Z"}
],
"workspacePath": "/tmp/ws"
}
});
let report = strip_volatile_fields(&mut value);
if value.pointer("/generatedAt").is_some()
|| value.pointer("/data/createdAt").is_some()
|| value.pointer("/data/updatedAt").is_some()
|| value.pointer("/data/computed_at").is_some()
|| value.pointer("/data/observedAt").is_some()
|| value.pointer("/data/items/0/elapsedMs").is_some()
|| value.pointer("/data/items/0/durationMs").is_some()
|| value.pointer("/data/items/1/last_seen_at").is_some()
|| value.pointer("/data/workspacePath").is_some()
{
return Err(format!("volatile fields were not stripped: {value}"));
}
if value
.pointer("/data/items/0/content")
.and_then(|v| v.as_str())
!= Some("keep")
{
return Err("non-volatile content was stripped".to_owned());
}
for expected in [
"generatedAt",
"createdAt",
"updatedAt",
"computed_at",
"observedAt",
"elapsedMs",
"durationMs",
"last_seen_at",
"workspacePath",
] {
if !report.fields_stripped.contains(&expected) {
return Err(format!("report missing stripped field {expected}"));
}
}
Ok(())
}
#[test]
fn registry_predicate_matches_list() {
assert!(is_volatile_field_name("generatedAt"));
assert!(is_volatile_field_name("createdAt"));
assert!(is_volatile_field_name("created_at"));
assert!(is_volatile_field_name("updatedAt"));
assert!(is_volatile_field_name("completedAt"));
assert!(is_volatile_field_name("expiresAt"));
assert!(is_volatile_field_name("observedAt"));
assert!(is_volatile_field_name("recordedAt"));
assert!(is_volatile_field_name("selectedAt"));
assert!(is_volatile_field_name("lastValidatedAt"));
assert!(is_volatile_field_name("durationMs"));
assert!(is_volatile_field_name("captured_at"));
assert!(is_volatile_field_name("last_accessed_at"));
assert!(is_volatile_field_name("capsule_id"));
assert!(is_volatile_field_name("integrity"));
assert!(is_volatile_field_name("swarm_brief_summary"));
assert!(is_volatile_field_name("swarm_incident_summary"));
assert!(is_volatile_field_name("swarm_replay_summary"));
assert!(!is_volatile_field_name("content"));
}
#[test]
fn strip_volatile_fields_covers_handoff_capsule_names() -> TestResult {
let mut value = serde_json::json!({
"schema": "ee.handoff.capsule.v1",
"capsule_id": "cap_a",
"created_at": "2026-05-16T00:00:00Z",
"integrity": {"hmac": "secret"},
"swarm_brief_summary": {"hostname": "agent-host"},
"swarm_incident_summary": {"summaryHash": "blake3:volatile"},
"swarm_replay_summary": {"summaryHash": "blake3:volatile-replay"},
"memory_snapshot": {"captured_at": "2026-05-16T00:00:00Z"},
"sections": [
{
"id": "objective",
"content": "keep this"
}
]
});
let report = strip_volatile_fields(&mut value);
for pointer in [
"/capsule_id",
"/created_at",
"/integrity",
"/swarm_brief_summary",
"/swarm_incident_summary",
"/swarm_replay_summary",
"/memory_snapshot/captured_at",
] {
if value.pointer(pointer).is_some() {
return Err(format!("{pointer} was not stripped: {value}"));
}
}
if value
.pointer("/sections/0/content")
.and_then(|v| v.as_str())
!= Some("keep this")
{
return Err("non-volatile handoff section content was stripped".to_owned());
}
for expected in [
"capsule_id",
"created_at",
"captured_at",
"integrity",
"swarm_brief_summary",
"swarm_incident_summary",
"swarm_replay_summary",
] {
if !report.fields_stripped.contains(&expected) {
return Err(format!("report missing stripped capsule field {expected}"));
}
}
Ok(())
}
#[test]
fn strip_volatile_fields_covers_tailscale_local_probe_identity() -> TestResult {
let mut value = serde_json::json!({
"schema": "ee.response.v2",
"data": {
"mesh": {
"tailscale": {
"schema": "ee.tailscale.local.v1",
"tailnetId": "tailnet-alpha",
"tailnetDisplayName": "alpha.example",
"selfNodeKey": "nodekey:selfalpha",
"selfTailscaleIp": "100.64.0.10",
"selfMagicDnsName": "ee-local.tailnet.test.",
"selfAdvertisedTags": ["tag:ee-mesh"],
"peers": [{
"peerNodeKey": "nodekey:peeralpha",
"peerTailscaleIps": ["100.64.0.20"],
"peerMagicDnsName": "peer-alpha.tailnet.test.",
"peerHostname": "peer-alpha",
"peerAdvertisedTags": ["tag:ee-mesh"],
"online": true
}],
"binaryVersionRaw": "1.66.0\n tailscale commit: abc",
"binaryAbsolutePath": "/opt/homebrew/bin/tailscale",
"probeMethod": "cli"
}
}
}
});
let report = strip_volatile_fields(&mut value);
for pointer in [
"/data/mesh/tailscale/tailnetId",
"/data/mesh/tailscale/tailnetDisplayName",
"/data/mesh/tailscale/selfNodeKey",
"/data/mesh/tailscale/selfTailscaleIp",
"/data/mesh/tailscale/selfMagicDnsName",
"/data/mesh/tailscale/selfAdvertisedTags",
"/data/mesh/tailscale/peers/0/peerNodeKey",
"/data/mesh/tailscale/peers/0/peerTailscaleIps",
"/data/mesh/tailscale/peers/0/peerMagicDnsName",
"/data/mesh/tailscale/peers/0/peerHostname",
"/data/mesh/tailscale/peers/0/peerAdvertisedTags",
"/data/mesh/tailscale/binaryVersionRaw",
"/data/mesh/tailscale/binaryAbsolutePath",
] {
if value.pointer(pointer).is_some() {
return Err(format!("{pointer} was not stripped: {value}"));
}
}
if value
.pointer("/data/mesh/tailscale/probeMethod")
.and_then(|v| v.as_str())
!= Some("cli")
{
return Err("non-volatile tailscale field was stripped".to_owned());
}
for expected in [
"tailnetId",
"tailnetDisplayName",
"selfNodeKey",
"selfTailscaleIp",
"selfMagicDnsName",
"selfAdvertisedTags",
"peerNodeKey",
"peerTailscaleIps",
"peerMagicDnsName",
"peerHostname",
"peerAdvertisedTags",
"binaryVersionRaw",
"binaryAbsolutePath",
] {
if !report.fields_stripped.contains(&expected) {
return Err(format!(
"report missing stripped tailscale field {expected}"
));
}
}
Ok(())
}
}