Skip to main content

made_core/entities/
agentic_system_analysis.rs

1//! [`AgenticSystemAnalysis`] — one pass over a design, against the
2//! ceremonies that are actually published.
3//!
4//! The analysis is the only thing standing between a design somebody
5//! wrote and a run that would discover its defects one stall at a
6//! time. It therefore collects every finding rather than stopping at
7//! the first, and every finding names the element it is about, so an
8//! author — human or agent — can fix a design in one pass.
9//!
10//! It resolves nothing itself. The pins are looked up by the
11//! application through the publication port and handed in, so the
12//! domain stays a function of what it was given.
13
14use std::collections::BTreeMap;
15
16use crate::value_objects::SystemCeremonyId;
17
18use super::{
19    AgenticSystem, AgenticSystemParts, AgenticSystemValidationReport, PublishedCeremonyDefinition,
20};
21
22mod capabilities;
23mod compositions;
24mod dependencies;
25mod independence;
26mod references;
27
28/// A design, the published definitions it pinned, and the checks that
29/// compare them.
30#[derive(Debug, Clone, Copy)]
31pub struct AgenticSystemAnalysis<'design> {
32    parts: AgenticSystemParts<'design>,
33    resolved: &'design BTreeMap<SystemCeremonyId, PublishedCeremonyDefinition>,
34}
35
36impl<'design> AgenticSystemAnalysis<'design> {
37    #[must_use]
38    pub fn of(
39        design: &'design AgenticSystem,
40        resolved: &'design BTreeMap<SystemCeremonyId, PublishedCeremonyDefinition>,
41    ) -> Self {
42        Self {
43            parts: AgenticSystemParts::of(design),
44            resolved,
45        }
46    }
47
48    /// Every defect, in check order.
49    ///
50    /// References first, because a check that reasoned about a name
51    /// nothing declares would produce a second finding about the same
52    /// mistake in a vocabulary the author never used.
53    #[must_use]
54    pub fn report(&self) -> AgenticSystemValidationReport {
55        let mut findings = Vec::new();
56        references::collect(self.parts, &mut findings);
57        dependencies::collect(self.parts, &mut findings);
58        compositions::collect(self.parts, self.resolved, &mut findings);
59        capabilities::collect(self.parts, &mut findings);
60        independence::collect(self.parts, &mut findings);
61        AgenticSystemValidationReport::new(
62            findings,
63            self.resolved.iter().map(|(ceremony, published)| {
64                (
65                    ceremony.clone(),
66                    crate::value_objects::DefinitionPin::new(
67                        published.name().clone(),
68                        published.version().clone(),
69                        published.digest(),
70                    ),
71                )
72            }),
73        )
74    }
75}
76
77impl AgenticSystem {
78    /// Analyse this design against the definitions its pins resolved
79    /// to.
80    #[must_use]
81    pub fn analyze(
82        &self,
83        resolved: &BTreeMap<SystemCeremonyId, PublishedCeremonyDefinition>,
84    ) -> AgenticSystemValidationReport {
85        AgenticSystemAnalysis::of(self, resolved).report()
86    }
87}