Skip to main content

agent_policy/model/
normalized.rs

1// Normalized model — stable internal representation consumed by all renderers.
2
3use indexmap::IndexMap;
4use serde::Serialize;
5
6/// The fully normalized, validated policy model.
7///
8/// All `Option`s from the raw model are resolved to concrete values with
9/// defaults applied. This is the type renderers and commands work with.
10#[derive(Debug, Clone, Serialize)]
11pub struct Policy {
12    pub project: Project,
13    pub commands: Commands,
14    pub paths: Paths,
15    /// Roles in declaration order (`IndexMap` preserves insertion order).
16    pub roles: IndexMap<String, Role>,
17    pub constraints: Constraints,
18    pub outputs: crate::model::targets::OutputTargets,
19}
20
21#[derive(Debug, Clone, Serialize)]
22pub struct Project {
23    pub name: String,
24    pub summary: Option<String>,
25}
26
27#[derive(Debug, Clone, Default, Serialize)]
28pub struct Commands {
29    pub install: Option<String>,
30    pub dev: Option<String>,
31    pub lint: Option<String>,
32    pub test: Option<String>,
33    pub build: Option<String>,
34}
35
36impl Commands {
37    /// Returns `true` if no commands are defined.
38    #[must_use]
39    pub fn is_empty(&self) -> bool {
40        self.install.is_none()
41            && self.dev.is_none()
42            && self.lint.is_none()
43            && self.test.is_none()
44            && self.build.is_none()
45    }
46}
47
48#[derive(Debug, Clone, Default, Serialize)]
49pub struct Paths {
50    pub editable: Vec<String>,
51    pub protected: Vec<String>,
52    pub generated_policy: Vec<String>,
53    pub generated_project: Vec<String>,
54}
55
56#[derive(Debug, Clone, Serialize)]
57pub struct Role {
58    /// The role identifier as declared in the YAML.
59    pub name: String,
60    pub editable: Vec<String>,
61    pub forbidden: Vec<String>,
62}
63
64#[derive(Debug, Clone, Default, Serialize)]
65pub struct Constraints {
66    pub require_tests_for_code_changes: bool,
67    pub forbid_secrets: bool,
68    pub require_human_review_for_protected_paths: bool,
69}