Skip to main content

made_api/
start_ceremony_request.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5/// Start a ceremony instance from a published definition.
6///
7/// Published only, by design. A consumer reaches authoring — drafts, analysis,
8/// publication — through the engine's own surfaces, where every defect is
9/// reported and every version is immutable. What a consumer may *start* is
10/// what was published, which is why every instance started through this
11/// contract carries a definition digest: "this exact procedure ran" is
12/// provable for all of them, with no draft-shaped exception to remember.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14pub struct StartCeremonyRequest {
15    /// The identity the new instance will answer to.
16    pub ceremony_id: String,
17    pub definition_name: String,
18    pub definition_version: String,
19    /// The consumer's own keys, carried opaquely. This is where a consuming
20    /// product ties the instance to its own aggregate; the engine does not
21    /// know what the keys mean and is not asked to.
22    pub context: BTreeMap<String, serde_json::Value>,
23    /// Who is opening the session, in the caller's own terms. Not a role from
24    /// the definition: whoever opens a session may be a participant, an
25    /// operator, or a scheduler that never takes part.
26    pub actor_id: String,
27    /// One of `human`, `agent`, `service`, `engine`. Carried, never worked
28    /// out; anything else is refused rather than guessed at.
29    pub actor_kind: String,
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn a_request_survives_the_wire() {
38        let request = StartCeremonyRequest {
39            ceremony_id: "c-1".to_owned(),
40            definition_name: "scope_discovery".to_owned(),
41            definition_version: "1.0".to_owned(),
42            context: BTreeMap::from([(
43                "requested_by".to_owned(),
44                serde_json::Value::String("consumer-1".to_owned()),
45            )]),
46            actor_id: "operator-1".to_owned(),
47            actor_kind: "service".to_owned(),
48        };
49        let bytes = serde_json::to_vec(&request).expect("serializes");
50        assert_eq!(
51            serde_json::from_slice::<StartCeremonyRequest>(&bytes).expect("deserializes"),
52            request
53        );
54    }
55}