#![allow(deprecated)]
use schemars::JsonSchema;
use semantic_memory_forge::{
ClaimStateV13, ContradictionWitnessV1, EpisodeBundleV1, EvidenceBundle, ExecutionContextV1,
ExportRecordSemanticsV3, ForgeExportMeta, RetractionRecordV1, SupportSetV1,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use stack_ids::{
ClaimId, ClaimVersionId, ContentDigest, EntityId, EnvelopeId, EpisodeId, RelationVersionId,
ScopeKey, TraceCtx,
};
#[deprecated(
since = "0.2.0",
note = "ProjectionImportBatchV1 is compatibility-only. Use ProjectionImportBatchV3 for the canonical bridge output."
)]
pub const PROJECTION_IMPORT_BATCH_V1_SCHEMA: &str = "projection_import_batch_v1";
pub const PROJECTION_IMPORT_BATCH_V2_SCHEMA: &str = "projection_import_batch_v2";
pub const PROJECTION_IMPORT_BATCH_V3_SCHEMA: &str = "projection_import_batch_v3";
#[deprecated(
since = "0.2.0",
note = "ProjectionImportBatchV1 is compatibility-only. Use ProjectionImportBatchV3 for the canonical bridge output."
)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ProjectionImportBatchV1 {
pub source_envelope_id: EnvelopeId,
pub schema_version: String,
#[serde(default)]
pub export_schema_version: Option<String>,
pub content_digest: ContentDigest,
pub source_authority: String,
pub scope_key: ScopeKey,
pub trace_ctx: Option<TraceCtx>,
pub source_exported_at: String,
pub transformed_at: String,
pub records: Vec<ImportProjectionRecord>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ProjectionImportBatchV2 {
pub source_envelope_id: EnvelopeId,
pub schema_version: String,
#[serde(default)]
pub export_schema_version: Option<String>,
pub content_digest: ContentDigest,
pub source_authority: String,
pub scope_key: ScopeKey,
pub trace_ctx: Option<TraceCtx>,
pub source_exported_at: String,
pub transformed_at: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub export_meta: Option<ForgeExportMeta>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evidence_bundle: Option<EvidenceBundle>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub episode_bundle: Option<EpisodeBundleV1>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub execution_context: Option<ExecutionContextV1>,
pub records: Vec<ImportProjectionRecord>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ProjectionImportBatchV3 {
pub source_envelope_id: EnvelopeId,
pub schema_version: String,
#[serde(default)]
pub export_schema_version: Option<String>,
pub content_digest: ContentDigest,
pub source_authority: String,
pub scope_key: ScopeKey,
pub trace_ctx: Option<TraceCtx>,
pub source_exported_at: String,
pub transformed_at: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub export_meta: Option<ForgeExportMeta>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evidence_bundle: Option<EvidenceBundle>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub episode_bundle: Option<EpisodeBundleV1>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub execution_context: Option<ExecutionContextV1>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub support_sets: Vec<SupportSetV1>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub contradiction_witnesses: Vec<ContradictionWitnessV1>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub retraction_records: Vec<RetractionRecordV1>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub claim_states_v13: Vec<ClaimStateV13>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub intervention_bundles_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub outcome_schemas_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cohort_contracts_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub counterfactual_slices_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub experiment_cases_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub comparability_matrices_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub decision_traces_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub refuter_suites_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub refuter_results_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub experiment_budgets_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rollout_decisions_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub rollback_decisions_v14: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub attestation_envelopes_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub trust_root_sets_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub artifact_admission_policies_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub transparency_receipts_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub attestation_revocations_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub attestation_supersessions_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub remote_oracle_leases_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub remote_slice_requests_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub remote_slice_results_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cross_runtime_replay_tickets_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dispute_bundles_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub disclosure_policies_v15: Vec<Value>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub disclosure_budgets_v15: Vec<Value>,
pub records: Vec<ImportProjectionRecordV3>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportProjectionRecordV3 {
pub record: ImportProjectionRecord,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub semantics: Option<ExportRecordSemanticsV3>,
}
impl From<ProjectionImportBatchV1> for ProjectionImportBatchV2 {
fn from(value: ProjectionImportBatchV1) -> Self {
Self {
source_envelope_id: value.source_envelope_id,
schema_version: PROJECTION_IMPORT_BATCH_V2_SCHEMA.into(),
export_schema_version: value.export_schema_version,
content_digest: value.content_digest,
source_authority: value.source_authority,
scope_key: value.scope_key,
trace_ctx: value.trace_ctx,
source_exported_at: value.source_exported_at,
transformed_at: value.transformed_at,
export_meta: None,
evidence_bundle: None,
episode_bundle: None,
execution_context: None,
records: value.records,
}
}
}
impl From<ProjectionImportBatchV2> for ProjectionImportBatchV1 {
fn from(value: ProjectionImportBatchV2) -> Self {
Self {
source_envelope_id: value.source_envelope_id,
schema_version: PROJECTION_IMPORT_BATCH_V1_SCHEMA.into(),
export_schema_version: value.export_schema_version,
content_digest: value.content_digest,
source_authority: value.source_authority,
scope_key: value.scope_key,
trace_ctx: value.trace_ctx,
source_exported_at: value.source_exported_at,
transformed_at: value.transformed_at,
records: value.records,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ImportProjectionRecord {
ClaimVersion(ImportClaimVersion),
RelationVersion(ImportRelationVersion),
Episode(ImportEpisodeRecord),
EntityAlias(ImportEntityAlias),
EvidenceRef(ImportEvidenceRef),
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportClaimVersion {
pub claim_id: ClaimId,
pub claim_version_id: ClaimVersionId,
pub claim_state: ClaimState,
pub projection_family: String,
pub subject_entity_id: EntityId,
pub predicate: String,
pub object_anchor: serde_json::Value,
pub scope_key: ScopeKey,
pub valid_from: Option<String>,
pub valid_to: Option<String>,
pub preferred_open: bool,
pub source_envelope_id: EnvelopeId,
pub source_authority: String,
pub trace_ctx: Option<TraceCtx>,
pub freshness: ProjectionFreshness,
pub contradiction_status: ContradictionStatus,
pub supersedes_claim_version_id: Option<ClaimVersionId>,
pub content: String,
pub confidence: f32,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportRelationVersion {
pub relation_version_id: RelationVersionId,
pub subject_entity_id: EntityId,
pub predicate: String,
pub object_anchor: serde_json::Value,
pub scope_key: ScopeKey,
pub claim_id: Option<ClaimId>,
pub source_episode_id: Option<EpisodeId>,
pub valid_from: Option<String>,
pub valid_to: Option<String>,
pub preferred_open: bool,
pub supersedes_relation_version_id: Option<RelationVersionId>,
pub contradiction_status: ContradictionStatus,
pub source_confidence: f32,
pub projection_family: String,
pub source_envelope_id: EnvelopeId,
pub source_authority: String,
pub trace_ctx: Option<TraceCtx>,
pub freshness: ProjectionFreshness,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportEpisodeRecord {
pub episode_id: EpisodeId,
pub document_id: String,
pub cause_ids: Vec<String>,
pub effect_type: String,
pub outcome: String,
pub confidence: f32,
pub experiment_id: Option<String>,
pub source_envelope_id: EnvelopeId,
pub source_authority: String,
pub trace_ctx: Option<TraceCtx>,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportEntityAlias {
pub canonical_entity_id: EntityId,
pub alias_text: String,
pub alias_source: String,
pub match_evidence: Option<serde_json::Value>,
pub confidence: f32,
pub merge_decision: MergeDecision,
pub scope: ScopeKey,
pub review_state: ReviewState,
pub is_human_confirmed: bool,
pub is_human_confirmed_final: bool,
pub superseded_by_entity_id: Option<EntityId>,
pub split_from_entity_id: Option<EntityId>,
pub source_envelope_id: EnvelopeId,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ImportEvidenceRef {
pub claim_id: ClaimId,
pub claim_version_id: Option<ClaimVersionId>,
pub fetch_handle: String,
pub source_authority: String,
pub source_envelope_id: EnvelopeId,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ClaimState {
Active,
Superseded,
Retracted,
Archived,
PendingReview,
Disputed,
}
impl ClaimState {
pub fn as_str(&self) -> &'static str {
match self {
Self::Active => "active",
Self::Superseded => "superseded",
Self::Retracted => "retracted",
Self::Archived => "archived",
Self::PendingReview => "pending_review",
Self::Disputed => "disputed",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ProjectionFreshness {
Current,
Stale,
Superseded,
ImportFailed,
NeverImported,
ImportLagging,
}
impl ProjectionFreshness {
pub fn as_str(&self) -> &'static str {
match self {
Self::Current => "current",
Self::Stale => "stale",
Self::Superseded => "superseded",
Self::ImportFailed => "import_failed",
Self::NeverImported => "never_imported",
Self::ImportLagging => "import_lagging",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ContradictionStatus {
None,
PossibleContradiction { description: String },
Confirmed { contradicted_by: ClaimId },
Resolved { resolution: String },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum MergeDecision {
Automated { algorithm: String },
HumanReviewed { reviewer: String, at: String },
PendingReview,
Rejected { reason: String },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ReviewState {
Unreviewed,
PendingReview,
Approved { by: String, at: String },
Rejected {
by: String,
at: String,
reason: String,
},
}