From a0e28f9c30b7b5dc396eae120de96eab52de8c12 Mon Sep 17 00:00:00 2001 From: Josh Stevenson Date: Mon, 28 Sep 2026 08:55:25 -0500 Subject: [PATCH 1/2] fix(episode): forward-sync metadata equality trait --- .github/workflows/paired-root.yml | 1 + src/types.rs | 2 +- tests/episode_meta_trait.rs | 35 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/episode_meta_trait.rs diff --git a/.github/workflows/paired-root.yml b/.github/workflows/paired-root.yml index 89b65b7..e69d254 100644 --- a/.github/workflows/paired-root.yml +++ b/.github/workflows/paired-root.yml @@ -83,4 +83,5 @@ jobs: cargo clippy --locked -p semantic-memory --all-targets -- -D warnings cargo test --locked -q -p semantic-memory --lib cargo test --locked -q -p semantic-memory --test foreign_key_integrity + cargo test --locked -q -p semantic-memory --test episode_meta_trait cargo package --locked -p semantic-memory --allow-dirty diff --git a/src/types.rs b/src/types.rs index 40e16a1..f192ff9 100755 --- a/src/types.rs +++ b/src/types.rs @@ -1144,7 +1144,7 @@ impl SearchSource { // ─── Episode Types ───────────────────────────────────────────── /// Metadata for a causal episode (PRIMITIVES_CONTRACT §4). -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct EpisodeMeta { /// IDs of the facts/chunks/messages that caused this episode. pub cause_ids: Vec, diff --git a/tests/episode_meta_trait.rs b/tests/episode_meta_trait.rs new file mode 100644 index 0000000..e222c04 --- /dev/null +++ b/tests/episode_meta_trait.rs @@ -0,0 +1,35 @@ +//! The mirror exposes the owner-owned EpisodeMeta equality trait without changing its wire form. +use semantic_memory::{EpisodeMeta, EpisodeOutcome, VerificationStatus}; +use serde_json::{json, Value}; + +#[test] +fn episode_meta_equality_and_serialization_are_distinct_contracts( +) -> Result<(), Box> { + let meta = EpisodeMeta { + cause_ids: vec!["cause:1".to_owned()], + effect_type: "test_failure".to_owned(), + outcome: EpisodeOutcome::Pending, + confidence: 0.5, + verification_status: VerificationStatus::Unverified, + experiment_id: None, + valid_time: None, + fact_digest: None, + }; + let expected: Value = json!({ + "cause_ids": ["cause:1"], + "effect_type": "test_failure", + "outcome": "pending", + "confidence": 0.5, + "verification_status": {"status": "unverified"}, + "experiment_id": null, + "valid_time": null, + "fact_digest": null + }); + assert_eq!(serde_json::to_value(&meta)?, expected); + let restored: EpisodeMeta = serde_json::from_value(expected)?; + assert_eq!(meta, restored); + let mut changed = restored.clone(); + changed.effect_type = "regression".to_owned(); + assert_ne!(meta, changed); + Ok(()) +} From f2df66bd0001fabf8675e250f3fa3f5a2fbe52de Mon Sep 17 00:00:00 2001 From: Josh Stevenson Date: Mon, 28 Sep 2026 09:15:00 -0500 Subject: [PATCH 2/2] ci: test extracted semantic-memory package independently --- .github/workflows/paired-root.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/paired-root.yml b/.github/workflows/paired-root.yml index e69d254..490da05 100644 --- a/.github/workflows/paired-root.yml +++ b/.github/workflows/paired-root.yml @@ -85,3 +85,18 @@ jobs: cargo test --locked -q -p semantic-memory --test foreign_key_integrity cargo test --locked -q -p semantic-memory --test episode_meta_trait cargo package --locked -p semantic-memory --allow-dirty + # Cargo normalizes the release archive's workspace dependencies and + # path dependencies. Prove that archive independently of the paired + # Libraries source tree; do not claim the raw mirror checkout builds. + standalone="$RUNNER_TEMP/semantic-memory-package-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + test ! -e "$standalone" + mkdir "$standalone" + shopt -s nullglob + archives=("$CARGO_TARGET_DIR"/package/semantic-memory-*.crate) + test "${#archives[@]}" -eq 1 + package_name="$(basename "${archives[0]}" .crate)" + tar -xzf "${archives[0]}" -C "$standalone" + manifest="$standalone/$package_name/Cargo.toml" + test -f "$manifest" + cargo metadata --locked --no-deps --format-version 1 --manifest-path "$manifest" > /dev/null + cargo test --locked -q --manifest-path "$manifest" --all-targets