use std::collections::BTreeSet;
use std::path::Path;
use crate::SUPPORTED_EKF_VERSION;
use crate::model::*;
use crate::paths::{manifest_source_paths, resolve_path};
pub(crate) fn validate_manifest(
manifest: &Manifest,
manifest_path: Option<&Path>,
root: Option<&Path>,
diagnostics: &mut Vec<EkfDiagnostic>,
) {
match manifest.ekf_version.as_deref() {
Some(SUPPORTED_EKF_VERSION) => {}
Some(version) => diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unsupported_version".into(),
message: format!(
"EKF version '{version}' is not the supported v{SUPPORTED_EKF_VERSION}; attempting v0.1 subset"
),
source: manifest_path.map(|p| p.display().to_string()),
}),
None => diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "version_missing".into(),
message: "EKF manifest is missing ekf_version".into(),
source: manifest_path.map(|p| p.display().to_string()),
}),
}
if !manifest.sources.workflows.is_empty() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "legacy_workflows_source".into(),
message: "sources.workflows is a legacy alias; prefer sources.brief_profiles for Eidos brief profiles".into(),
source: Some("sources.workflows".into()),
});
}
let mut partition_ids = BTreeSet::new();
for partition in &manifest.partitions {
if partition.id.trim().is_empty() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "partition_missing_id".into(),
message: "EKF partition is missing id".into(),
source: Some("partitions".into()),
});
} else if !partition_ids.insert(partition.id.clone()) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "duplicate_partition".into(),
message: format!("duplicate EKF partition id '{}'", partition.id),
source: Some(format!("partitions.{}", partition.id)),
});
}
if partition.source.trim().is_empty() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "partition_missing_source".into(),
message: format!("EKF partition '{}' is missing source", partition.id),
source: Some(format!("partitions.{}", partition.id)),
});
} else if !is_supported_partition_source(&partition.source) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unsupported_partition_source".into(),
message: format!(
"unsupported EKF partition source '{}' (supported: aun, glyph, aether, eval, brief_profile)",
partition.source
),
source: Some(format!("partitions.{}", partition.id)),
});
}
if partition.roots.is_empty() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "partition_missing_roots".into(),
message: format!("EKF partition '{}' has no roots", partition.id),
source: Some(format!("partitions.{}", partition.id)),
});
}
}
let Some(root) = root else {
return;
};
let mut seen = BTreeSet::new();
for (kind, path, _languages) in manifest_source_paths(manifest) {
let resolved = resolve_path(root, Path::new(&path));
let key = resolved.to_string_lossy().into_owned();
if !seen.insert(key.clone()) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "duplicate_root".into(),
message: format!("duplicate EKF source root: {key}"),
source: Some(kind.to_string()),
});
}
if !resolved.exists() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "missing_source_root".into(),
message: format!("{kind} source root does not exist: {}", resolved.display()),
source: Some(path),
});
}
}
for partition in &manifest.partitions {
for path in &partition.roots {
let resolved = resolve_path(root, Path::new(path));
let key = resolved.to_string_lossy().into_owned();
if !seen.insert(key.clone()) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "duplicate_root".into(),
message: format!("duplicate EKF source root: {key}"),
source: Some(format!("partitions.{}", partition.id)),
});
}
if !resolved.exists() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "missing_source_root".into(),
message: format!(
"partition '{}' root does not exist: {}",
partition.id,
resolved.display()
),
source: Some(path.clone()),
});
}
}
}
for code in &manifest.sources.code {
if code.path.trim().is_empty() {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "code_source_missing_path".into(),
message: "code source entry is missing path".into(),
source: None,
});
}
if let Some(source) = &code.source
&& source != "glyph"
{
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unsupported_code_source".into(),
message: format!("unsupported code source '{source}' (supported: glyph)"),
source: Some(code.path.clone()),
});
}
}
for key in manifest.trust.keys() {
if !matches!(
key.as_str(),
"default_authority"
| "gold_ground_threshold"
| "stale_after_days"
| "agent_accepted_ttl_days"
) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unknown_trust_field".into(),
message: format!("unknown EKF trust field '{key}'"),
source: manifest_path.map(|p| p.display().to_string()),
});
}
}
for (section, metrics) in &manifest.gates {
if !known_gate_sections().contains(§ion.as_str()) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unknown_gate_section".into(),
message: format!("unknown EKF gate section '{section}'"),
source: Some(format!("gates.{section}")),
});
continue;
}
for metric in metrics.keys() {
if !known_gate_metric(section, metric) {
diagnostics.push(EkfDiagnostic {
severity: DiagnosticSeverity::Warning,
kind: "unknown_gate_metric".into(),
message: format!("unknown EKF gate metric '{metric}' in section '{section}'"),
source: Some(format!("gates.{section}.{metric}")),
});
}
}
}
}
pub(crate) fn is_supported_partition_source(source: &str) -> bool {
matches!(
source,
"aun" | "glyph" | "aether" | "eval" | "brief_profile"
)
}
pub(crate) fn known_gate_sections() -> &'static [&'static str] {
&[
"graph",
"route",
"context",
"brief",
"brief_profile",
"brief_profiles",
"combo",
"workflow",
"dogfood",
"coverage",
"eval_coverage",
]
}
pub(crate) fn known_gate_metric(section: &str, metric: &str) -> bool {
match section {
"graph" => matches!(
metric,
"min_node_receipt_coverage"
| "min_edge_evidence_coverage"
| "min_edge_evidence_source_coverage"
| "min_edge_evidence_span_coverage"
| "max_orphan_nodes"
| "max_orphan_node_ratio"
| "max_dangling_edges"
| "max_dangling_edge_ratio"
| "max_missing_edge_endpoints"
| "max_unpartitioned_compiled_nodes"
| "max_unpartitioned_nodes"
| "max_unpartitioned_compiled_node_ratio"
| "max_unpartitioned_node_ratio"
| "max_relation_constraint_violations"
| "max_lexical_edges"
| "min_traversable_edges"
| "min_trusted_traversable_edges"
| "min_trusted_traversable_edge_ratio"
| "min_resolved_edge_ratio"
),
"coverage" | "eval_coverage" => matches!(
metric,
"min_suites"
| "min_eval_suites"
| "min_cases"
| "min_eval_cases"
| "min_garbage_cases"
| "min_context_judged_cases"
| "min_context_noise_judged_cases"
| "min_context_must_not_judged_cases"
| "min_context_edge_judged_cases"
| "min_omitted_context_judged_cases"
| "min_omitted_compound_anchor_judged_cases"
| "min_omitted_compound_anchors_judged_cases"
| "min_vocabulary_gap_judged_cases"
| "min_vocab_gap_judged_cases"
| "min_no_vocabulary_gap_judged_cases"
| "min_no_vocab_gap_judged_cases"
| "min_vocab_editable_target_judged_cases"
| "min_vocabulary_editable_target_judged_cases"
| "min_vocab_non_editable_target_judged_cases"
| "min_vocabulary_non_editable_target_judged_cases"
| "min_route_relation_judged_cases"
| "min_route_relation_expectations"
| "min_partition_judged_cases"
| "min_code_context_judged_cases"
| "min_docs_context_judged_cases"
| "min_operator_judged_cases"
| "min_required_check_judged_cases"
| "min_risk_hint_judged_cases"
| "min_brief_inspection_judged_cases"
| "min_workflow_inspection_judged_cases"
| "min_inspection_judged_cases"
| "min_profile_judged_cases"
),
"route" | "context" | "brief" | "brief_profile" | "brief_profiles" | "combo"
| "workflow" | "dogfood" => {
known_eval_metric(metric) || known_suite_coverage_metric(metric)
}
_ => false,
}
}
pub(crate) fn known_eval_metric(metric: &str) -> bool {
matches!(
metric,
"min_p_at_1"
| "min_hit_at_k"
| "min_mrr"
| "min_relation_evidence_recall"
| "min_route_relation_recall"
| "min_route_relation_evidence_recall"
| "min_confidence_expectation_rate"
| "min_route_confidence_expectation_rate"
| "min_garbage_rejected"
| "min_answer_precision"
| "min_context_recall"
| "max_context_noise"
| "min_receipt_coverage"
| "min_edge_recall"
| "min_context_edge_recall"
| "min_focus_route_match"
| "min_focus_route_match_rate"
| "min_omitted_context_match"
| "min_omitted_context_match_rate"
| "min_compound_primary_match"
| "min_compound_primary_match_rate"
| "min_omitted_compound_anchor_match"
| "min_omitted_compound_anchor_match_rate"
| "min_omitted_compound_anchors_match"
| "min_omitted_compound_anchors_match_rate"
| "min_vocabulary_gap_match"
| "min_vocabulary_gap_match_rate"
| "min_vocab_gap_match"
| "min_vocab_gap_match_rate"
| "min_no_vocabulary_gap_match"
| "min_no_vocabulary_gap_match_rate"
| "min_no_vocab_gap_match"
| "min_no_vocab_gap_match_rate"
| "min_vocab_editable_target_match"
| "min_vocab_editable_target_match_rate"
| "min_vocabulary_editable_target_match"
| "min_vocabulary_editable_target_match_rate"
| "min_vocab_non_editable_target_match"
| "min_vocab_non_editable_target_match_rate"
| "min_vocabulary_non_editable_target_match"
| "min_vocabulary_non_editable_target_match_rate"
| "min_partition_match"
| "min_partition_match_rate"
| "max_mean_pack_size"
| "min_brief_valid"
| "min_brief_valid_rate"
| "min_workflow_valid"
| "min_workflow_valid_rate"
| "min_brief_bounded"
| "min_brief_bounded_rate"
| "min_workflow_bounded"
| "min_workflow_bounded_rate"
| "min_brief_chain"
| "min_brief_required_chain"
| "min_workflow_chain"
| "min_workflow_required_chain"
| "min_required_chain_rate"
| "min_brief_ready"
| "min_workflow_ready"
| "min_initial_ready_rate"
| "min_brief_inspection_recall"
| "min_brief_required_check_recall"
| "min_brief_risk_hint_recall"
| "min_brief_profile_match"
| "min_brief_profile_match_rate"
| "min_workflow_inspection_recall"
| "min_workflow_required_check_recall"
| "min_workflow_risk_hint_recall"
| "min_workflow_profile_match"
| "min_workflow_profile_match_rate"
| "min_dogfood_score"
| "min_dogfood_mean_score"
| "min_dogfood_pass_rate"
| "min_dogfood_profile_match"
| "min_dogfood_profile_match_rate"
| "min_ekf_quality_preservation_rate"
| "min_ekf_route_hit_rate"
| "min_ekf_context_recall"
| "min_ekf_confidence_coverage_rate"
| "min_ekf_trust_tier_coverage_rate"
| "min_ekf_response_token_savings_rate"
| "min_ekf_total_token_savings_rate"
| "min_route_hit_rate"
| "min_code_context_rate"
| "min_docs_context_rate"
| "min_operator_coverage_rate"
| "min_task_context_rate"
| "min_run_advancement_rate"
| "min_combo_pass_rate"
| "min_combo_ground_gate_pass_rate"
| "min_combo_verify_receipt_pass_rate"
| "min_combo_vocab_loop_pass_rate"
| "min_combo_gap_propose_pass_rate"
| "min_combo_aun_repair_pass_rate"
| "min_combo_ryn_reconcile_pass_rate"
| "min_combo_vyre_queue_pass_rate"
| "min_combo_trust_review_pass_rate"
| "min_combo_aether_stale_pass_rate"
| "min_combo_navigation_packet_pass_rate"
| "min_combo_glyph_navigation_pass_rate"
| "max_combo_invalid_cases"
| "max_combo_unsupported_cases"
)
}
pub(crate) fn known_suite_coverage_metric(metric: &str) -> bool {
matches!(
metric,
"min_cases"
| "min_eval_cases"
| "min_garbage_cases"
| "min_context_judged_cases"
| "min_context_noise_judged_cases"
| "min_context_must_not_judged_cases"
| "min_context_edge_judged_cases"
| "min_omitted_context_judged_cases"
| "min_omitted_compound_anchor_judged_cases"
| "min_omitted_compound_anchors_judged_cases"
| "min_vocabulary_gap_judged_cases"
| "min_vocab_gap_judged_cases"
| "min_no_vocabulary_gap_judged_cases"
| "min_no_vocab_gap_judged_cases"
| "min_vocab_editable_target_judged_cases"
| "min_vocabulary_editable_target_judged_cases"
| "min_vocab_non_editable_target_judged_cases"
| "min_vocabulary_non_editable_target_judged_cases"
| "min_route_relation_judged_cases"
| "min_route_relation_expectations"
| "min_partition_judged_cases"
| "min_code_context_judged_cases"
| "min_docs_context_judged_cases"
| "min_operator_judged_cases"
| "min_required_check_judged_cases"
| "min_risk_hint_judged_cases"
| "min_brief_inspection_judged_cases"
| "min_workflow_inspection_judged_cases"
| "min_inspection_judged_cases"
| "min_profile_judged_cases"
)
}
pub fn gate_intent(section: &str, metric: &str) -> Option<GateIntent> {
if !known_gate_metric(section, metric) {
return None;
}
if known_suite_coverage_metric(metric) {
let (capability, signal, description) = coverage_gate_intent(metric);
return Some(GateIntent {
capability: capability.to_string(),
signal: signal.to_string(),
description: description.to_string(),
});
}
let (capability, signal, description) = match section {
"graph" => graph_gate_intent(metric),
"coverage" | "eval_coverage" => coverage_gate_intent(metric),
"route" => route_gate_intent(metric),
"context" => context_gate_intent(metric),
"brief" | "brief_profile" | "brief_profiles" | "workflow" => brief_gate_intent(metric),
"dogfood" => dogfood_gate_intent(metric),
"combo" => combo_gate_intent(metric),
_ => eval_gate_intent(metric),
};
Some(GateIntent {
capability: capability.to_string(),
signal: signal.to_string(),
description: description.to_string(),
})
}
fn graph_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"min_node_receipt_coverage" => (
"graph_evidence",
"node_receipts",
"protects provenance coverage for graph nodes used as agent evidence",
),
"min_edge_evidence_coverage"
| "min_edge_evidence_source_coverage"
| "min_edge_evidence_span_coverage" => (
"graph_evidence",
"edge_receipts",
"protects relation edges by requiring source-backed evidence",
),
"max_unpartitioned_compiled_nodes"
| "max_unpartitioned_nodes"
| "max_unpartitioned_compiled_node_ratio"
| "max_unpartitioned_node_ratio" => (
"package_boundaries",
"partition_provenance",
"protects EKF partition boundaries for compiled graph nodes",
),
"max_relation_constraint_violations" => (
"graph_ontology",
"relation_constraints",
"protects typed relation domain and range constraints",
),
"min_traversable_edges"
| "min_trusted_traversable_edges"
| "min_trusted_traversable_edge_ratio"
| "min_resolved_edge_ratio"
| "max_lexical_edges" => (
"graph_traversal",
"trusted_walkable_edges",
"protects the traversable relation surface agents can follow",
),
_ => (
"graph_quality",
"graph_metric",
"protects graph quality required by the package contract",
),
}
}
fn coverage_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"min_context_noise_judged_cases" | "min_context_must_not_judged_cases" => (
"anti_noise",
"negative_context_coverage",
"protects eval coverage for context_must_not leakage checks",
),
"min_context_judged_cases" => (
"context_recall",
"context_judgment_coverage",
"protects eval coverage for focused context recall and noise checks",
),
"min_context_edge_judged_cases" => (
"graph_context",
"context_edge_coverage",
"protects eval coverage for relation edges included in focus packs",
),
"min_omitted_context_judged_cases" => (
"focus_transparency",
"omitted_context_coverage",
"protects eval coverage for focus-pack candidates omitted by selection limits",
),
"min_omitted_compound_anchor_judged_cases"
| "min_omitted_compound_anchors_judged_cases" => (
"compound_routing",
"omitted_anchor_coverage",
"protects eval coverage for compound anchors omitted after query-term coverage",
),
"min_vocabulary_gap_judged_cases" | "min_vocab_gap_judged_cases" => (
"knowledge_growth",
"vocabulary_gap_coverage",
"protects eval coverage for compound-query vocabulary gap detection",
),
"min_no_vocabulary_gap_judged_cases" | "min_no_vocab_gap_judged_cases" => (
"knowledge_growth",
"no_vocabulary_gap_coverage",
"protects eval coverage against false-positive vocabulary gaps on fully grounded compound queries",
),
"min_vocab_editable_target_judged_cases"
| "min_vocabulary_editable_target_judged_cases" => (
"knowledge_growth",
"editable_vocab_target_coverage",
"protects eval coverage for Markdown nodes that can accept vocabulary growth",
),
"min_vocab_non_editable_target_judged_cases"
| "min_vocabulary_non_editable_target_judged_cases" => (
"knowledge_growth",
"non_editable_vocab_target_coverage",
"protects eval coverage for anchors that should not be auto-edited",
),
"min_route_relation_judged_cases" | "min_route_relation_expectations" => (
"relation_evidence",
"route_relation_coverage",
"protects eval coverage for relation evidence on route hits",
),
"min_partition_judged_cases"
| "min_code_context_judged_cases"
| "min_docs_context_judged_cases" => (
"package_boundaries",
"partition_context_coverage",
"protects eval coverage for EKF partition and source-plane routing",
),
"min_operator_judged_cases"
| "min_required_check_judged_cases"
| "min_risk_hint_judged_cases"
| "min_brief_inspection_judged_cases"
| "min_workflow_inspection_judged_cases"
| "min_inspection_judged_cases"
| "min_profile_judged_cases" => (
"brief_planning",
"planner_coverage",
"protects eval coverage for task briefs, inspections, and profile selection",
),
"min_garbage_cases" => (
"routing_precision",
"garbage_rejection_coverage",
"protects eval coverage for rejecting unrelated queries",
),
_ => (
"eval_coverage",
"suite_coverage",
"protects minimum package eval suite and case coverage",
),
}
}
fn route_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"min_garbage_rejected" | "min_answer_precision" => (
"routing_precision",
"garbage_rejection",
"protects routing from confident answers on unrelated queries",
),
"min_relation_evidence_recall"
| "min_route_relation_recall"
| "min_route_relation_evidence_recall" => (
"relation_evidence",
"route_relation_recall",
"protects structured relation evidence returned with route hits",
),
"min_confidence_expectation_rate" | "min_route_confidence_expectation_rate" => (
"confidence_calibration",
"route_confidence",
"protects calibrated route confidence bands",
),
_ => (
"routing",
"rank_quality",
"protects retrieval ranking quality for package queries",
),
}
}
fn context_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"max_context_noise" => (
"anti_noise",
"context_leakage",
"protects focus packs from leaking explicitly forbidden context",
),
"min_edge_recall" | "min_context_edge_recall" => (
"graph_context",
"context_edge_recall",
"protects relation-edge recall inside focused context packs",
),
"min_focus_route_match" | "min_focus_route_match_rate" => (
"routing_context_alignment",
"focus_route_match",
"protects agreement between route selection and focus-pack anchor",
),
"min_omitted_context_match" | "min_omitted_context_match_rate" => (
"focus_transparency",
"omitted_context_match",
"protects explicit reasons for focus-pack candidates omitted by selection limits",
),
"min_compound_primary_match" | "min_compound_primary_match_rate" => (
"compound_routing",
"compound_primary_match",
"protects multi-anchor focus routing for faceted queries",
),
"min_omitted_compound_anchor_match"
| "min_omitted_compound_anchor_match_rate"
| "min_omitted_compound_anchors_match"
| "min_omitted_compound_anchors_match_rate" => (
"compound_routing",
"omitted_anchor_match",
"protects explicit reasons for compound anchors omitted after query-term coverage",
),
"min_vocabulary_gap_match"
| "min_vocabulary_gap_match_rate"
| "min_vocab_gap_match"
| "min_vocab_gap_match_rate" => (
"knowledge_growth",
"vocabulary_gap_match",
"protects detection of unmatched query terms on otherwise grounded compound results",
),
"min_no_vocabulary_gap_match"
| "min_no_vocabulary_gap_match_rate"
| "min_no_vocab_gap_match"
| "min_no_vocab_gap_match_rate" => (
"knowledge_growth",
"no_vocabulary_gap_match",
"protects fully grounded compound queries from unnecessary vocabulary-growth pressure",
),
"min_vocab_editable_target_match"
| "min_vocab_editable_target_match_rate"
| "min_vocabulary_editable_target_match"
| "min_vocabulary_editable_target_match_rate" => (
"knowledge_growth",
"editable_vocab_target_match",
"protects ranking of safe Markdown targets for vocabulary growth proposals",
),
"min_vocab_non_editable_target_match"
| "min_vocab_non_editable_target_match_rate"
| "min_vocabulary_non_editable_target_match"
| "min_vocabulary_non_editable_target_match_rate" => (
"knowledge_growth",
"non_editable_vocab_target_match",
"protects surfacing non-editable anchors without sending auto-edit proposals to them",
),
"min_partition_match" | "min_partition_match_rate" => (
"package_boundaries",
"partition_match",
"protects EKF partition provenance for focused results",
),
"min_receipt_coverage" => (
"context_evidence",
"receipt_coverage",
"protects receipt coverage for focused context items",
),
_ => (
"context_recall",
"context_recall",
"protects required node recall in focused context packs",
),
}
}
fn brief_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"min_brief_profile_match"
| "min_brief_profile_match_rate"
| "min_workflow_profile_match"
| "min_workflow_profile_match_rate" => (
"brief_profiles",
"profile_selection",
"protects EKF brief-profile selection for task packets",
),
"min_brief_inspection_recall" | "min_workflow_inspection_recall" => (
"brief_planning",
"inspection_recall",
"protects required inspection hints in grounded task briefs",
),
"min_brief_required_check_recall" | "min_workflow_required_check_recall" => (
"brief_profiles",
"required_check_recall",
"protects domain required checks in selected brief profiles",
),
"min_brief_risk_hint_recall" | "min_workflow_risk_hint_recall" => (
"brief_profiles",
"risk_hint_recall",
"protects domain risk hints in selected brief profiles",
),
"min_required_chain_rate" | "min_brief_chain" | "min_workflow_chain" => (
"brief_planning",
"required_chain",
"protects task decomposition dependency ordering",
),
"min_initial_ready_rate" | "min_brief_ready" | "min_workflow_ready" => (
"brief_planning",
"initial_ready_tasks",
"protects executable initial task readiness in generated briefs",
),
_ => (
"brief_planning",
"brief_validity",
"protects validity and boundedness of generated task briefs",
),
}
}
fn dogfood_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"max_context_noise" => (
"anti_noise",
"dogfood_context_leakage",
"protects dogfood focus packs from leaking explicitly forbidden context",
),
"min_route_hit_rate" => (
"routing",
"dogfood_route_hit",
"protects route hit coverage inside multi-capability dogfood scenarios",
),
"min_route_relation_evidence_recall" => (
"relation_evidence",
"dogfood_route_relation_recall",
"protects relation evidence inside multi-capability dogfood scenarios",
),
"min_context_edge_recall" => (
"graph_context",
"dogfood_context_edge_recall",
"protects relation-edge recall in dogfood context packs",
),
"min_code_context_rate" | "min_docs_context_rate" | "min_task_context_rate" => (
"dogfood_context",
"cross_plane_context",
"protects dogfood cases that require code, docs, and task context together",
),
"min_operator_coverage_rate" | "min_run_advancement_rate" => (
"dogfood_workflows",
"operator_and_run_progress",
"protects end-to-end agent workflow decomposition and advancement",
),
"min_dogfood_profile_match" | "min_dogfood_profile_match_rate" => (
"brief_profiles",
"dogfood_profile_selection",
"protects profile selection during multi-capability dogfood scenarios",
),
"min_ekf_quality_preservation_rate"
| "min_ekf_route_hit_rate"
| "min_ekf_context_recall"
| "min_ekf_confidence_coverage_rate"
| "min_ekf_trust_tier_coverage_rate" => (
"mcp_protocol",
"ekf_quality_parity",
"protects EKF-shaped compact requests from losing route, context, confidence, or trust visibility",
),
"min_ekf_response_token_savings_rate" | "min_ekf_total_token_savings_rate" => (
"mcp_protocol",
"ekf_token_economics",
"tracks whether EKF-shaped compact requests reduce response or total token cost",
),
_ => (
"dogfood_system",
"end_to_end_score",
"protects combined route, focus, brief, and operator behavior",
),
}
}
fn combo_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"min_combo_ground_gate_pass_rate" => (
"tool_combos",
"ground_gate",
"protects ground_gate confidence checks in tool-loop scenarios",
),
"min_combo_verify_receipt_pass_rate" => (
"tool_combos",
"verify_receipt",
"protects receipt drift checks in tool-loop scenarios",
),
"min_combo_vocab_loop_pass_rate" => (
"knowledge_growth",
"vocab_loop",
"protects vocabulary proposal loops for weak-but-found queries",
),
"min_combo_gap_propose_pass_rate" => (
"knowledge_growth",
"gap_propose",
"protects gap-to-proposal growth flow",
),
"min_combo_aun_repair_pass_rate" => (
"authored_knowledge",
"aun_repair",
"protects Aun diagnostics becoming actionable Vyre repair suggestions",
),
"min_combo_ryn_reconcile_pass_rate" => (
"runtime_memory",
"ryn_reconcile",
"protects graph-backed Ryn memory reconciliation for stale remembered node ids",
),
"min_combo_vyre_queue_pass_rate" => (
"knowledge_growth",
"vyre_queue",
"protects Vyre librarian suggestions queuing into Sigil without accepting writes",
),
"min_combo_trust_review_pass_rate" | "min_combo_aether_stale_pass_rate" => (
"trust_and_staleness",
"trust_review",
"protects stale and expired knowledge review behavior",
),
"min_combo_navigation_packet_pass_rate" => (
"graph_navigation",
"navigation_packet",
"protects EKF-shaped evidence packets for code graph navigation tools",
),
"min_combo_glyph_navigation_pass_rate" => (
"code_grounding",
"glyph_navigation",
"protects Glyph navigation precision across resolved edges, lexical edge rejection, and partitioned code identity",
),
"max_combo_invalid_cases" | "max_combo_unsupported_cases" => (
"eval_contract",
"combo_case_validity",
"protects combo eval suites from malformed or unsupported cases",
),
_ => (
"tool_combos",
"combo_pass_rate",
"protects package tool-loop combo behavior",
),
}
}
fn eval_gate_intent(metric: &str) -> (&'static str, &'static str, &'static str) {
match metric {
"max_context_noise" => context_gate_intent(metric),
"min_dogfood_score" | "min_dogfood_mean_score" | "min_dogfood_pass_rate" => {
dogfood_gate_intent(metric)
}
metric if metric.starts_with("min_combo_") || metric.starts_with("max_combo_") => {
combo_gate_intent(metric)
}
metric if metric.contains("brief") || metric.contains("workflow") => {
brief_gate_intent(metric)
}
metric if metric.contains("context") || metric.contains("receipt") => {
context_gate_intent(metric)
}
metric
if metric.contains("route") || metric.contains("p_at_1") || metric.contains("mrr") =>
{
route_gate_intent(metric)
}
_ => (
"eval_quality",
"suite_metric",
"protects package eval behavior for the declared suite",
),
}
}