made_api/ceremony_engine_api.rs
1use crate::{
2 ApiCapabilities, ApiError, BudgetLimits, BudgetReport, BudgetReservation, CeremonySummary,
3 DefinitionAnalysisView, PublishedDefinitionView, RaiseInterventionRequest,
4 RespondToInterventionRequest, StartCeremonyRequest,
5};
6
7/// What a consuming product may ask of the embedded engine.
8///
9/// Reads, plus one mutation: starting an instance from a **published**
10/// definition. Advancing and publishing stay behind the engine's own surfaces,
11/// where their transactionality and audit live; the contract grows by adding
12/// named capabilities, never by widening what an existing one means (ADR-004).
13/// A consumer checks the capability report before relying on any of this — and
14/// keeps working, with a stub, when the engine is absent.
15#[async_trait::async_trait]
16pub trait CeremonyEngineApi: Send + Sync {
17 /// What this implementation is and what it can do. Checked by consumers at
18 /// startup, before anything is at stake.
19 fn capabilities(&self) -> ApiCapabilities;
20
21 /// Every ceremony instance the engine holds.
22 ///
23 /// The consumer filters by its own context keys; the engine does not know
24 /// what they mean and is not asked to.
25 async fn ceremonies(&self) -> Result<Vec<CeremonySummary>, ApiError>;
26
27 /// One ceremony instance by identity.
28 async fn ceremony(&self, ceremony_id: &str) -> Result<CeremonySummary, ApiError>;
29
30 /// Start an instance from a published definition. Capability
31 /// `start_ceremony`.
32 ///
33 /// `CeremonyNotFound` when nothing is published under that name and
34 /// version — publishing is the remedy, not retrying. A taken instance
35 /// identity is `Refused`: an identity is one instance forever, and the
36 /// answer is a new identity, never a restart of someone else's.
37 async fn start_ceremony(
38 &self,
39 request: StartCeremonyRequest,
40 ) -> Result<CeremonySummary, ApiError>;
41
42 /// Start a published ceremony and open one durable budget account shared by its descendants.
43 async fn start_budgeted_ceremony(
44 &self,
45 request: StartCeremonyRequest,
46 limits: BudgetLimits,
47 ) -> Result<CeremonySummary, ApiError>;
48
49 /// Current durable budget balance for a ceremony tree.
50 async fn budget_report(&self, ceremony_id: &str) -> Result<BudgetReport, ApiError>;
51
52 /// Bounded global recovery view of reservations awaiting a terminal receipt.
53 async fn pending_budget_reservations(
54 &self,
55 after_reservation_id: Option<&str>,
56 limit: usize,
57 ) -> Result<Vec<BudgetReservation>, ApiError>;
58
59 /// Put a question, investigation or proposed action to the table.
60 /// Capability `raise_intervention`.
61 async fn raise_intervention(
62 &self,
63 request: RaiseInterventionRequest,
64 ) -> Result<CeremonySummary, ApiError>;
65
66 /// Answer an open intervention. Capability `respond_to_intervention`.
67 ///
68 /// A closed intervention refuses: the answer arrived after the table moved
69 /// on, and recording it as if it had been heard would misstate the
70 /// conversation the audit trail exists to keep.
71 async fn respond_to_intervention(
72 &self,
73 request: RespondToInterventionRequest,
74 ) -> Result<CeremonySummary, ApiError>;
75
76 /// Analyze a definition draft, reporting every defect at once.
77 /// Capability `analyze_definition`.
78 ///
79 /// A draft that does not even parse is `Refused` — it is not a defective
80 /// definition, it is not a definition. Anything that parses gets the full
81 /// report, publishable or not.
82 async fn analyze_definition(
83 &self,
84 definition_yaml: &str,
85 ) -> Result<DefinitionAnalysisView, ApiError>;
86
87 /// Publish a definition, immutably. Capability `publish_definition`.
88 ///
89 /// Idempotent on identical content: republishing the same bytes under the
90 /// same name and version answers `already_published` rather than refusing,
91 /// which is what makes a retry safe. A version taken by *different*
92 /// content is `Refused` — a published version is immutable, and the
93 /// answer is a new version, never an overwrite.
94 async fn publish_definition(
95 &self,
96 definition_yaml: &str,
97 ) -> Result<PublishedDefinitionView, ApiError>;
98}