Skip to main content

converge_core/
truth.rs

1// Copyright 2024-2026 Reflective Labs
2// SPDX-License-Identifier: MIT
3
4//! Truth catalog primitives.
5//!
6//! Truths describe jobs, policies, and invariants above domain packs.
7//! Applications provide the catalog content; the runtime consumes a common
8//! shape for intent construction, guardrails, and pack participation.
9
10use serde::{Deserialize, Serialize};
11
12use crate::{Context, Criterion, FactId, TypesIntentConstraint};
13
14/// What class of truth is being described.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16pub enum TruthKind {
17    /// A job-to-be-done spanning multiple packs.
18    Job,
19    /// A cross-cutting policy or guardrail.
20    Policy,
21    /// A module-local or pack-local invariant.
22    Invariant,
23}
24
25/// Portable truth definition.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct TruthDefinition {
28    /// Stable truth identifier.
29    pub key: String,
30    /// Truth class.
31    pub kind: TruthKind,
32    /// Human-readable summary.
33    pub summary: String,
34    /// Required or optional success criteria.
35    pub success_criteria: Vec<Criterion>,
36    /// Hard and soft constraints derived from the truth.
37    pub constraints: Vec<TypesIntentConstraint>,
38    /// Human approval points that the runtime must respect.
39    pub approval_points: Vec<String>,
40    /// Which packs should participate when this truth is active.
41    pub participating_packs: Vec<String>,
42}
43
44/// Machine-evaluable outcome for a single criterion.
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46pub enum CriterionResult {
47    /// The criterion was satisfied, with fact IDs that justify the result.
48    Met { evidence: Vec<FactId> },
49    /// The criterion is currently blocked on human intervention.
50    Blocked {
51        /// Why the criterion is blocked.
52        reason: String,
53        /// Optional approval or workflow reference the host can surface.
54        approval_ref: Option<String>,
55    },
56    /// The criterion was evaluated and is not satisfied.
57    Unmet { reason: String },
58    /// The runtime could not determine whether the criterion was satisfied.
59    Indeterminate,
60}
61
62/// Evaluated outcome for a specific criterion.
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct CriterionOutcome {
65    /// The criterion that was evaluated.
66    pub criterion: Criterion,
67    /// The result of the evaluation.
68    pub result: CriterionResult,
69}
70
71/// Application-provided boundary for evaluating success criteria.
72pub trait CriterionEvaluator: Send + Sync {
73    /// Evaluate a criterion against the converged context.
74    fn evaluate(&self, criterion: &Criterion, context: &Context) -> CriterionResult;
75}
76
77/// Application-provided truth catalog boundary.
78pub trait TruthCatalog: Send + Sync {
79    /// List all truths known to the application.
80    fn list_truths(&self) -> Vec<TruthDefinition>;
81
82    /// Resolve a truth by key.
83    fn find_truth(&self, key: &str) -> Option<TruthDefinition> {
84        self.list_truths()
85            .into_iter()
86            .find(|truth| truth.key == key)
87    }
88}