didbot_policy_records/record.rs
1//! The declaration one policy statement becomes between the operator's
2//! record and [`didbot_policy::PolicyDeclaration`].
3//!
4//! [`crate::set::declarations`] reads a `bot.did.policy` record and produces
5//! one [`ParsedPolicy`] per statement per action the statement can decide.
6//! [`crate::compile`] takes it from there, resolving `language` against the
7//! evaluators this build carries and registering the result on a tree.
8//!
9//! # Applicability is declarative data, outside the predicate
10//!
11//! The core validates `applicability` at its boundary and builds the tree
12//! from it, so a policy whose applicability is known-good can be scoped even
13//! when its predicate cannot be used -- see `didbot_policy::Predicate`'s own
14//! doc comment. `predicate` is opaque JSON here: only the evaluator named by
15//! `language` reads it, and only that evaluator can say whether its own
16//! syntax is well formed. That split is why [`crate::compile`] is a separate
17//! step.
18
19use didbot_policy::{Applicability, Revision, Staleness};
20
21/// One policy statement, ready to compile.
22#[derive(Debug, Clone, PartialEq)]
23pub struct ParsedPolicy {
24 /// What this policy may be asked to decide.
25 pub applicability: Applicability,
26 /// What this policy is told about.
27 pub observes: Applicability,
28 /// How stale this policy's evaluator's view may be.
29 pub staleness: Staleness,
30 /// Which evaluator language this policy names -- `"regex"` for
31 /// `didbot-policy-regex`, and open to whatever else a build carries.
32 /// Opaque to this crate; see [`crate::compile`].
33 pub language: String,
34 /// The predicate document, typed by `language` and opaque here.
35 pub predicate: serde_json::Value,
36 /// The records in other repositories this policy's record declared it
37 /// reads -- see [`crate::records::Lookup`]. Every statement of one
38 /// record carries the whole record's list, because the write path
39 /// reads them before it knows which statement will ask for one.
40 pub lookups: Vec<crate::records::Lookup>,
41 /// Which revision of this declaration this is -- a label whoever
42 /// declares it chooses. [`crate::set::declarations`] stamps every
43 /// declaration [`Revision`]`(0)`, so an operator's records all carry the
44 /// same one; nothing here orders by it, and
45 /// [`crate::last_good::LastGoodPolicies`] keys on the declaration's id.
46 /// It reaches an operator through [`crate::merge::LastGoodFallback`].
47 /// See [`didbot_policy::Revision`]'s own doc comment for why a revision
48 /// carries no timestamp.
49 pub revision: Revision,
50}