This commit is contained in:
2026-05-19 11:48:32 +02:00
parent 3da01156a0
commit fad7ec5107
19 changed files with 218 additions and 64 deletions

View File

@@ -186,16 +186,16 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");
assert!(dex_id > 0);
let dex = crate::query_dexs_get_by_code(&database, "raydium")
let dex = crate::query_dexs_get_by_code(&database, "raydium_amm_v4")
.await
.expect("get dex must succeed");
assert!(dex.is_some());
assert_eq!(dex.expect("dex must exist").name, "Raydium");
assert_eq!(dex.expect("dex must exist").name, "Raydium AMM v4");
let dexes = crate::query_dexs_list(&database).await.expect("list dexes must succeed");
assert_eq!(dexes.len(), 1);
}

View File

@@ -225,7 +225,7 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");

View File

@@ -181,7 +181,7 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");

View File

@@ -202,7 +202,7 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");

View File

@@ -140,7 +140,7 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");

View File

@@ -167,7 +167,7 @@ mod tests {
.expect("database init must succeed");
let dex_id = crate::query_dexs_upsert(
&database,
&crate::DexDto::new("raydium".to_string(), "Raydium".to_string(), None, None, true),
&crate::DexDto::new("raydium_amm_v4".to_string(), "Raydium AMM v4".to_string(), None, None, true),
)
.await
.expect("dex upsert must succeed");

View File

@@ -353,8 +353,8 @@ mod tests {
let dex_id = crate::query_dexs_upsert(
service.database().as_ref(),
&crate::DexDto::new(
"raydium".to_string(),
"Raydium".to_string(),
"raydium_amm_v4".to_string(),
"Raydium AMM v4".to_string(),
Some("DexProgram111111111111111111111111111111111".to_string()),
None,
true,

View File

@@ -1009,8 +1009,8 @@ mod tests {
let dex_id = crate::query_dexs_upsert(
persistence.database().as_ref(),
&crate::DexDto::new(
"raydium".to_string(),
"Raydium".to_string(),
"raydium_amm_v4".to_string(),
"Raydium AMM v4".to_string(),
Some("DexProgram111111111111111111111111111111111".to_string()),
None,
true,

View File

@@ -92,7 +92,7 @@ mod tests {
#[test]
fn known_active_dexes_are_available_from_catalog() {
let codes = [
"raydium",
"raydium_amm_v4",
"raydium_cpmm",
"raydium_clmm",
"pump_fun",

View File

@@ -149,7 +149,7 @@ impl DexDetectService {
decoded_event: &crate::DexDecodedEventDto,
) -> Result<crate::DexPoolDetectionResult, crate::Error> {
let dex_id_result =
crate::dex_catalog::ensure_known_dex(self.database.as_ref(), "raydium").await;
crate::dex_catalog::ensure_known_dex(self.database.as_ref(), "raydium_amm_v4").await;
let dex_id = match dex_id_result {
Ok(dex_id) => dex_id,
Err(error) => return Err(error),

View File

@@ -19,8 +19,10 @@ pub struct DexSupportMatrixEntry {
pub family: &'static str,
/// Protocol version or `unknown` when not verified locally.
pub version: &'static str,
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
/// Technical surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
pub surface_type: &'static str,
/// Strategic surface role used by the DEX-first roadmap: `dex_effective`, `aggregator_router`, `launch_surface` or `to_verify`.
pub surface_role: &'static str,
/// Primary Solana program id, when verified in local constants or docs.
pub program_id: std::option::Option<&'static str>,
/// Optional router program id, when this entry uses a distinct router.
@@ -63,8 +65,10 @@ pub struct DexSupportMatrixEntryDto {
pub family: std::string::String,
/// Protocol version or `unknown` when not verified locally.
pub version: std::string::String,
/// Surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
/// Technical surface type: `launch`, `bonding_curve`, `AMM`, `CLMM`, `DLMM`, `router`, `aggregator` or `unknown`.
pub surface_type: std::string::String,
/// Strategic surface role used by the DEX-first roadmap: `dex_effective`, `aggregator_router`, `launch_surface` or `to_verify`.
pub surface_role: std::string::String,
/// Primary Solana program id, when verified in local constants or docs.
pub program_id: std::option::Option<std::string::String>,
/// Optional router program id, when this entry uses a distinct router.
@@ -104,6 +108,7 @@ impl DexSupportMatrixEntryDto {
family: entry.family.to_string(),
version: entry.version.to_string(),
surface_type: entry.surface_type.to_string(),
surface_role: entry.surface_role.to_string(),
program_id: match entry.program_id {
Some(program_id) => Some(program_id.to_string()),
None => None,
@@ -138,6 +143,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "pump",
version: "bonding_curve",
surface_type: "launch",
surface_role: "launch_surface",
program_id: Some(crate::PUMP_FUN_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -159,6 +165,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "pump",
version: "amm",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::PUMP_SWAP_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -180,6 +187,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "cpmm",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::RAYDIUM_CPMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -201,6 +209,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "clmm",
surface_type: "CLMM",
surface_role: "dex_effective",
program_id: Some(crate::RAYDIUM_CLMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -222,6 +231,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "amm_v4",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -237,33 +247,13 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
skip_reason: Some("not_observed_in_0_7_28_replay"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium",
display_name: "Raydium AMM v4",
family: "raydium",
version: "amm_v4_alias",
surface_type: "AMM",
program_id: Some(crate::RAYDIUM_AMM_V4_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
observed: false,
decoded: true,
materialized: true,
trade_candidate: true,
candle_candidate: true,
pair_candidate: true,
pool_candidate: true,
status: "partial",
confidence: "medium",
skip_reason: Some("legacy_catalog_alias_for_raydium_amm_v4"),
catalog_enabled: true,
},
DexSupportMatrixEntry {
code: "raydium_launchlab",
display_name: "Raydium LaunchLab",
family: "raydium",
version: "launchlab",
surface_type: "launch",
surface_role: "launch_surface",
program_id: Some(crate::RAYDIUM_LAUNCHLAB_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -285,6 +275,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
@@ -306,6 +297,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "router",
surface_type: "router",
surface_role: "aggregator_router",
program_id: Some(crate::RAYDIUM_AMM_ROUTING_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -327,6 +319,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "raydium",
version: "stable_swap",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::RAYDIUM_STABLE_SWAP_AMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -348,6 +341,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "meteora",
version: "dlmm",
surface_type: "DLMM",
surface_role: "dex_effective",
program_id: Some(crate::METEORA_DLMM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -369,6 +363,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "meteora",
version: "unknown",
surface_type: "unknown",
surface_role: "to_verify",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
@@ -390,6 +385,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "meteora",
version: "damm_v1",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::METEORA_DAMM_V1_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -411,6 +407,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "meteora",
version: "damm_v2",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::METEORA_DAMM_V2_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -432,6 +429,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "meteora",
version: "dbc",
surface_type: "bonding_curve",
surface_role: "dex_effective",
program_id: Some(crate::METEORA_DBC_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -453,6 +451,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "orca",
version: "whirlpools",
surface_type: "CLMM",
surface_role: "dex_effective",
program_id: Some(crate::ORCA_WHIRLPOOLS_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -474,6 +473,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "fluxbeam",
version: "unknown",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::FLUXBEAM_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -495,6 +495,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "dexlab",
version: "unknown",
surface_type: "AMM",
surface_role: "dex_effective",
program_id: Some(crate::DEXLAB_PROGRAM_ID),
router_program_id: None,
program_id_status: "known",
@@ -516,6 +517,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "bags",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -537,6 +539,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "bonk",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -558,6 +561,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "bonk",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -579,6 +583,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "bonk",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -600,6 +605,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "okx",
version: "unknown",
surface_type: "aggregator",
surface_role: "aggregator_router",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -621,6 +627,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "boop",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -642,6 +649,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "moonshot",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -663,6 +671,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "believe",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -678,12 +687,57 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
skip_reason: Some("program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "metadao",
display_name: "metaDAO",
family: "metadao",
version: "unknown",
surface_type: "unknown",
surface_role: "to_verify",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "to_verify",
confidence: "low",
skip_reason: Some("surface_and_program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "printr",
display_name: "Printr",
family: "printr",
version: "unknown",
surface_type: "unknown",
surface_role: "to_verify",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
observed: false,
decoded: false,
materialized: false,
trade_candidate: false,
candle_candidate: false,
pair_candidate: false,
pool_candidate: false,
status: "to_verify",
confidence: "low",
skip_reason: Some("surface_and_program_id_to_verify"),
catalog_enabled: false,
},
DexSupportMatrixEntry {
code: "zora",
display_name: "Zora",
family: "zora",
version: "unknown",
surface_type: "unknown",
surface_role: "to_verify",
program_id: None,
router_program_id: None,
program_id_status: "to_verify",
@@ -705,6 +759,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "moonit",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -726,6 +781,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "launchbeam",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -747,6 +803,7 @@ const DEX_SUPPORT_MATRIX_ENTRIES: &[DexSupportMatrixEntry] = &[
family: "heaven",
version: "unknown",
surface_type: "launch",
surface_role: "launch_surface",
program_id: None,
router_program_id: None,
program_id_status: "unknown",
@@ -812,7 +869,7 @@ pub fn dex_support_matrix_entry_by_program_id(
#[cfg(test)]
mod tests {
#[test]
fn matrix_contains_required_0_7_29_entries() {
fn matrix_contains_required_0_7_39_dex_first_entries() {
let codes = [
"pump_fun",
"pump_swap",
@@ -837,6 +894,8 @@ mod tests {
"launchbeam",
"heaven",
"dexlab",
"metadao",
"printr",
];
for code in codes {
let entry = crate::dex_support_matrix_entry_by_code(code);
@@ -860,6 +919,8 @@ mod tests {
"moonit",
"launchbeam",
"heaven",
"metadao",
"printr",
];
for code in codes {
let entry = match crate::dex_support_matrix_entry_by_code(code) {
@@ -932,7 +993,7 @@ mod tests {
}
#[test]
fn matrix_keeps_0_7_39_launch_surfaces_non_trade_materialized() {
fn matrix_keeps_0_7_39_deferred_surfaces_non_trade_materialized() {
let codes = [
"raydium_launchlab",
"raydium_launchpad",
@@ -958,6 +1019,50 @@ mod tests {
}
}
#[test]
fn matrix_marks_effective_dexes_for_dex_first_work() {
let codes = [
"pump_swap",
"raydium_cpmm",
"raydium_clmm",
"raydium_amm_v4",
"raydium_stable_swap",
"meteora_dlmm",
"meteora_damm_v1",
"meteora_damm_v2",
"meteora_dbc",
"orca_whirlpools",
"fluxbeam",
"dexlab",
];
for code in codes {
let entry = match crate::dex_support_matrix_entry_by_code(code) {
Some(entry) => entry,
None => panic!("missing matrix entry for {}", code),
};
assert_eq!(entry.surface_role, "dex_effective", "{} must be DEX-first", code);
}
}
#[test]
fn matrix_keeps_metadao_and_printr_unverified_without_program_id() {
let codes = ["metadao", "printr"];
for code in codes {
let entry = match crate::dex_support_matrix_entry_by_code(code) {
Some(entry) => entry,
None => panic!("missing matrix entry for {}", code),
};
assert_eq!(entry.surface_role, "to_verify");
assert_eq!(entry.program_id_status, "to_verify");
assert!(entry.program_id.is_none());
assert!(!entry.decoded);
assert!(!entry.materialized);
assert!(!entry.trade_candidate);
assert!(!entry.candle_candidate);
assert!(!entry.catalog_enabled);
}
}
#[test]
fn matrix_dto_preserves_core_fields() {
let entry = match crate::dex_support_matrix_entry_by_code("pump_swap") {
@@ -967,6 +1072,7 @@ mod tests {
let dto = crate::DexSupportMatrixEntryDto::from_entry(entry);
assert_eq!(dto.code, "pump_swap");
assert_eq!(dto.program_id, Some(crate::PUMP_SWAP_PROGRAM_ID.to_string()));
assert_eq!(dto.surface_role, "dex_effective");
assert!(dto.trade_candidate);
assert!(dto.candle_candidate);
}

View File

@@ -104,7 +104,7 @@ impl LaunchOriginService {
return Self { database, persistence };
}
/// Ensures that every built-in launch surface tracked by `0.7.39` exists.
/// Ensures that every deferred built-in launch surface exists.
pub async fn ensure_target_launch_surfaces(&self) -> Result<std::vec::Vec<i64>, crate::Error> {
let mut surface_ids = std::vec::Vec::new();
for spec in BUILTIN_LAUNCH_SURFACE_SPECS {

View File

@@ -278,18 +278,26 @@ impl LocalPipelineValidationConfig {
return config;
}
/// Builds the `0.7.39` launch surface origin baseline validation config.
/// Builds the `0.7.39` DEX-first effective swap surfaces validation config.
///
/// This profile keeps the `0.7.38` metadata-gap semantics and requires the
/// static DEX matrix invariants that prevent planned launch surfaces from
/// being treated as priced trade/candle producers before corpus-backed
/// decoders are available.
pub fn v0_7_39_launch_surface_origin_baseline() -> Self {
/// static DEX matrix invariants that distinguish effective swap surfaces,
/// routers/aggregators, deferred launch surfaces and unverified candidates.
pub fn v0_7_39_dex_first_effective_swap_surfaces() -> Self {
let mut config = Self::v0_7_38_token_metadata_gap_prioritization();
config.profile_code = "0.7.39_launch_surface_origin_baseline".to_string();
config.profile_code = "0.7.39_dex_first_effective_swap_surfaces".to_string();
config.require_dex_support_matrix_semantics = true;
return config;
}
/// Builds the legacy `0.7.39` launch-surface validation alias.
///
/// The implementation now delegates to the DEX-first profile so callers that
/// still pass the previous profile code do not accidentally revive the old
/// launch-surface priority.
pub fn v0_7_39_launch_surface_origin_baseline() -> Self {
return Self::v0_7_39_dex_first_effective_swap_surfaces();
}
}
/// A single local pipeline validation issue.
@@ -519,11 +527,11 @@ impl LocalPipelineValidationService {
return self.validate_current_database(&config).await;
}
/// Diagnoses the current database with the `0.7.39` launch-origin baseline profile.
/// Diagnoses the current database with the `0.7.39` DEX-first profile.
pub async fn validate_v0_7_39_current_database(
&self,
) -> Result<crate::LocalPipelineValidationRunDto, crate::Error> {
let config = crate::LocalPipelineValidationConfig::v0_7_39_launch_surface_origin_baseline();
let config = crate::LocalPipelineValidationConfig::v0_7_39_dex_first_effective_swap_surfaces();
return self.validate_current_database(&config).await;
}
}
@@ -649,6 +657,7 @@ pub fn validate_local_pipeline_diagnostics_summary(
|| config.profile_code == "0.7.36_meteora_family_consolidation"
|| config.profile_code == "0.7.37_token_metadata_catalog_enrichment"
|| config.profile_code == "0.7.38_token_metadata_gap_prioritization"
|| config.profile_code == "0.7.39_dex_first_effective_swap_surfaces"
|| config.profile_code == "0.7.39_launch_surface_origin_baseline";
if config.require_all_expected_dexes || missing_expected_dex_is_warning {
for expected_dex_code in &expected_dex_codes {
@@ -898,16 +907,48 @@ fn validate_dex_support_matrix_semantics(
});
}
if (entry.status == "planned" || entry.status == "to_verify" || entry.status == "unknown")
&& entry.surface_type == "launch"
&& (entry.surface_role == "launch_surface" || entry.surface_role == "to_verify")
&& (entry.decoded
|| entry.materialized
|| entry.trade_candidate
|| entry.candle_candidate)
{
issues.push(crate::LocalPipelineValidationIssueDto {
code: "inactive_launch_surface_matrix_entry_actionable".to_string(),
code: "inactive_deferred_surface_matrix_entry_actionable".to_string(),
message: format!(
"inactive launch surface '{}' must not be decoded, materialized, or priced as trade/candle candidate",
"inactive deferred surface '{}' must not be decoded, materialized, or priced as trade/candle candidate",
entry_code
),
subject: Some(entry_code.clone()),
blocking: true,
});
}
if entry.surface_role == "aggregator_router"
&& (entry.trade_candidate || entry.candle_candidate || entry.catalog_enabled)
{
issues.push(crate::LocalPipelineValidationIssueDto {
code: "aggregator_router_matrix_entry_direct_trade_enabled".to_string(),
message: format!(
"aggregator/router '{}' must not be enabled as a direct trade/candle surface before proof",
entry_code
),
subject: Some(entry_code.clone()),
blocking: true,
});
}
if entry.surface_role == "to_verify"
&& (entry.program_id.is_some()
|| entry.program_id_status != "to_verify"
|| entry.catalog_enabled
|| entry.decoded
|| entry.materialized
|| entry.trade_candidate
|| entry.candle_candidate)
{
issues.push(crate::LocalPipelineValidationIssueDto {
code: "to_verify_matrix_entry_promoted_without_proof".to_string(),
message: format!(
"to-verify surface '{}' must not expose program id, catalog activation, decoding or trade/candle materialization without corpus proof",
entry_code
),
subject: Some(entry_code.clone()),
@@ -1397,12 +1438,12 @@ mod tests {
}
#[test]
fn validation_accepts_0_7_39_launch_surface_origin_baseline() {
fn validation_accepts_0_7_39_dex_first_effective_swap_surfaces() {
let summary = make_0_7_28_summary_with_meteora();
let config = crate::LocalPipelineValidationConfig::v0_7_39_launch_surface_origin_baseline();
let config = crate::LocalPipelineValidationConfig::v0_7_39_dex_first_effective_swap_surfaces();
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
assert!(report.validation_passed);
assert_eq!(report.validation_profile_code, "0.7.39_launch_surface_origin_baseline");
assert_eq!(report.validation_profile_code, "0.7.39_dex_first_effective_swap_surfaces");
assert_eq!(report.blocking_issue_count, 0);
}