pub struct CeremonyInstance { /* private fields */ }Implementations§
Source§impl CeremonyInstance
impl CeremonyInstance
pub fn children_completed_guard_is_satisfied( &self, condition: &ChildrenCompletedCondition, ) -> bool
Source§impl CeremonyInstance
impl CeremonyInstance
pub fn host_handoffs(&self) -> &BTreeMap<IdempotencyKey, HostHandoffRecorded>
Source§impl CeremonyInstance
impl CeremonyInstance
pub fn lease_renewal(&self, id: &IdempotencyKey) -> Option<&StepLeaseRenewed>
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn decide_start(
id: CeremonyId,
definition: &CeremonyDefinition,
context: CeremonyContext,
recollection: Option<SessionRecollection>,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start( id: CeremonyId, definition: &CeremonyDefinition, context: CeremonyContext, recollection: Option<SessionRecollection>, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
The opening of a ceremony run from a definition supplied for it.
A constructor rather than a command: there is no instance yet
to decide against. Required inputs are checked against this run’s
context before any opening event is built. The event carries everything
Self::from_started needs to open the same instance without
the definition in hand.
A batch rather than one event, because an opening is sometimes
two facts: what was started, and what it was told. See
Self::opening_batch.
Sourcepub fn decide_start_bound(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
recollection: Option<SessionRecollection>,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start_bound( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, recollection: Option<SessionRecollection>, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
The opening of a ceremony bound to a published definition, its digest recorded so a later reader can check which one ran.
Sourcepub fn decide_start_bound_child(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
lineage: CeremonyLineage,
recollection: Option<SessionRecollection>,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start_bound_child( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, lineage: CeremonyLineage, recollection: Option<SessionRecollection>, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
Open a published child using the exact recollection and lineage sealed by its parent plan.
Sourcepub fn decide_start_bound_budgeted(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
budget_account_id: BudgetAccountId,
recollection: Option<SessionRecollection>,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start_bound_budgeted( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, budget_account_id: BudgetAccountId, recollection: Option<SessionRecollection>, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
Open a root ceremony and seal the shared ledger account for its whole tree.
Sourcepub fn decide_start_bound_budgeted_child(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
lineage: CeremonyLineage,
budget_account_id: BudgetAccountId,
recollection: Option<SessionRecollection>,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start_bound_budgeted_child( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, lineage: CeremonyLineage, budget_account_id: BudgetAccountId, recollection: Option<SessionRecollection>, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
Open a child with the exact shared ledger account sealed by its parent plan.
Sourcepub fn decide_start_successor(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
succession: CeremonySuccession,
plan: &SuccessionPlan,
now: OffsetDateTime,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide_start_successor( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, succession: CeremonySuccession, plan: &SuccessionPlan, now: OffsetDateTime, ) -> Result<Vec<CeremonyEvent>, DomainError>
Open a successor: the opening the plan settled, and what it was given to start from.
The second append of a succession, and the one that may be made twice. Everything here is derived from facts already sealed in the predecessor, so the batch a retry builds is byte for byte the batch the first attempt built — which is what lets a caller that crashed between the two appends verify the existing stream instead of opening a second one.
The successor seals its own deadlines from its own definition. Inheriting the predecessor’s would carry a clock the new definition never agreed to.
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn decide(
&self,
command: &CeremonyCommand,
definition: &CeremonyDefinition,
) -> Result<Vec<CeremonyEvent>, DomainError>
pub fn decide( &self, command: &CeremonyCommand, definition: &CeremonyDefinition, ) -> Result<Vec<CeremonyEvent>, DomainError>
Decide a command against this session and its definition.
Pure: reads the session, writes nothing, and returns the events
that would change it — usually one; two where one act has two
facts to record, as a transition into a terminal state also
completes the ceremony. Fold them with Self::apply to get
the state the corresponding mutator would have left.
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn from_imported(imported: &InstanceImported) -> Self
pub fn from_imported(imported: &InstanceImported) -> Self
The session the import carried, as it was carried.
No derivation and no definition: an imported session is not opened, it is restored. What the legacy store held is what the stream now says, and the fold of the stream is that snapshot — which is exactly the equality the migration verifies before it installs anything.
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn from_started(started: &CeremonyInstanceStarted) -> Self
pub fn from_started(started: &CeremonyInstanceStarted) -> Self
Open the session the event describes: its initial state, one pending record per step the definition declared, and nothing else yet. Needs no definition, because the event carries what starting derived from one.
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn apply(&mut self, event: &CeremonyEvent)
pub fn apply(&mut self, event: &CeremonyEvent)
Write one event into this session.
Infallible and total: an event the session cannot honour —
a response to an item it does not hold, a second opening —
leaves it untouched rather than failing, because a fold is
not where a bad stream gets refused. updated_at becomes the
event’s own timestamp.
Sourcepub fn rehydrate<'a>(
events: impl IntoIterator<Item = &'a CeremonyEvent>,
) -> Result<Self, DomainError>
pub fn rehydrate<'a>( events: impl IntoIterator<Item = &'a CeremonyEvent>, ) -> Result<Self, DomainError>
Fold a whole stream into the session it describes.
The first event opens the session: either it was started here, or it was imported from a store written before ceremonies were streams (ADR-012). A stream that opens with anything else is not a ceremony’s stream and is refused, and so is one that carries an import anywhere but at its first position — an import replaces the whole session, so a second one would silently discard everything between them.
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn approve_guard(
&mut self,
definition: &CeremonyDefinition,
guard_name: &GuardName,
approved_by: RoleId,
approved_by_kind: AuditActorKind,
now: OffsetDateTime,
) -> Result<(), DomainError>
pub fn approve_guard( &mut self, definition: &CeremonyDefinition, guard_name: &GuardName, approved_by: RoleId, approved_by_kind: AuditActorKind, now: OffsetDateTime, ) -> Result<(), DomainError>
Approving is checked the way deferring is. It used to take no definition at all, so any name at all could be “approved” — which wrote that name into the session context, told the caller it had succeeded, and left a session that would never move.
pub fn defer_guard( &mut self, definition: &CeremonyDefinition, guard_name: GuardName, content: CeremonyGuardDeferralContent, deferred_by: RoleId, deferred_by_kind: AuditActorKind, now: OffsetDateTime, ) -> Result<(), DomainError>
Source§impl CeremonyInstance
impl CeremonyInstance
pub fn request_intervention_as( &mut self, definition: &CeremonyDefinition, intervention_id: CeremonyInterventionId, role_id: RoleId, kind: CeremonyInterventionKind, target: CeremonyInterventionTarget, content: CeremonyInterventionContent, now: OffsetDateTime, ) -> Result<(), DomainError>
pub fn request_intervention_with_provenance_as( &mut self, definition: &CeremonyDefinition, intervention_id: CeremonyInterventionId, role_id: RoleId, kind: CeremonyInterventionKind, target: CeremonyInterventionTarget, content: CeremonyInterventionContent, provenance: Option<CeremonyInterventionProvenance>, now: OffsetDateTime, ) -> Result<(), DomainError>
pub fn respond_to_intervention_as( &mut self, definition: &CeremonyDefinition, intervention_id: &CeremonyInterventionId, role_id: RoleId, content: CeremonyInterventionContent, now: OffsetDateTime, ) -> Result<(), DomainError>
Sourcepub fn prepare_evidence_request_as(
&self,
definition: &CeremonyDefinition,
intervention_id: CeremonyInterventionId,
role_id: RoleId,
source_id: CeremonyEvidenceSourceId,
query: CeremonyInterventionContent,
) -> Result<CeremonyEvidenceRequest, DomainError>
pub fn prepare_evidence_request_as( &self, definition: &CeremonyDefinition, intervention_id: CeremonyInterventionId, role_id: RoleId, source_id: CeremonyEvidenceSourceId, query: CeremonyInterventionContent, ) -> Result<CeremonyEvidenceRequest, DomainError>
A query, not a command: what a source should be asked to answer an item, checked against the same rules a response is. It changes nothing, so it decides no event.
pub fn respond_to_intervention_with_evidence_as( &mut self, definition: &CeremonyDefinition, intervention_id: &CeremonyInterventionId, role_id: RoleId, evidence_pack: CeremonyEvidencePack, now: OffsetDateTime, ) -> Result<(), DomainError>
Sourcepub fn assert_reason_as(
&mut self,
definition: &CeremonyDefinition,
role_id: RoleId,
from: CeremonyRecordRef,
to: CeremonyRecordRef,
kind: CeremonyReasonKind,
why: impl Into<String>,
confidence: MemoryConfidence,
now: OffsetDateTime,
) -> Result<(), DomainError>
pub fn assert_reason_as( &mut self, definition: &CeremonyDefinition, role_id: RoleId, from: CeremonyRecordRef, to: CeremonyRecordRef, kind: CeremonyReasonKind, why: impl Into<String>, confidence: MemoryConfidence, now: OffsetDateTime, ) -> Result<(), DomainError>
State why one thing here led to another.
Its own act rather than a field on contributing, because a
reason is often known later — “in fact I did that because…” is
how people reason — and because a field gets filled in by
inertia while an act is chosen. What it refuses is decided in
Self::decide; the reason itself is built first, so a why
that is empty or an edge from a thing to itself is refused by
the reason before the session is consulted.
pub fn close_intervention_as( &mut self, definition: &CeremonyDefinition, intervention_id: &CeremonyInterventionId, role_id: &RoleId, now: OffsetDateTime, ) -> Result<(), DomainError>
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn bind_participant(
&mut self,
definition: &CeremonyDefinition,
role_id: RoleId,
specialty: Specialty,
now: OffsetDateTime,
) -> Result<(), DomainError>
pub fn bind_participant( &mut self, definition: &CeremonyDefinition, role_id: RoleId, specialty: Specialty, now: OffsetDateTime, ) -> Result<(), DomainError>
Seat a role for this session.
Rebinding is allowed and deliberate: a panel can become unavailable halfway through a working session, and a ceremony that could not be re-seated would have to be abandoned and started again, losing everything already decided. What was seated before stays in the journal; the instance carries who is seated now, which is what the next step needs.
pub fn participant_bindings( &self, ) -> &BTreeMap<RoleId, CeremonyParticipantBinding>
Sourcepub fn bound_specialty(&self, role_id: &RoleId) -> Option<&Specialty>
pub fn bound_specialty(&self, role_id: &RoleId) -> Option<&Specialty>
The specialty a role’s work should be put to, if this session
seated one. None means the definition decides, as usual.
Source§impl CeremonyInstance
impl CeremonyInstance
pub fn resolved_step_role( &self, definition: &CeremonyDefinition, step_id: &StepId, ) -> Result<RoleId, DomainError>
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn claimable_step_ids_at<'a>(
&self,
definition: &'a CeremonyDefinition,
now: OffsetDateTime,
host_ceiling: MaxParallel,
) -> Result<Vec<&'a StepId>, DomainError>
pub fn claimable_step_ids_at<'a>( &self, definition: &'a CeremonyDefinition, now: OffsetDateTime, host_ceiling: MaxParallel, ) -> Result<Vec<&'a StepId>, DomainError>
Steps a caller may claim from the current state at one observed instant.
Concurrent results contain every eligible alternative while capacity remains. They are not truncated to the number of free slots: whichever caller wins is persisted first and every optimistic retry recomputes the set against that new state.
pub fn has_live_step_leases_at( &self, definition: &CeremonyDefinition, now: OffsetDateTime, ) -> bool
Source§impl CeremonyInstance
The step mutators, as wrappers over CeremonyInstance::decide
and CeremonyInstance::apply: each decides its command, folds
the events, and returns what its callers always got.
impl CeremonyInstance
The step mutators, as wrappers over CeremonyInstance::decide
and CeremonyInstance::apply: each decides its command, folds
the events, and returns what its callers always got.
pub fn start_step_as( &mut self, definition: &CeremonyDefinition, role_id: &RoleId, step_id: &StepId, lease: StepLease, now: OffsetDateTime, ) -> Result<StepAttempt, DomainError>
pub fn start_step( &mut self, definition: &CeremonyDefinition, step_id: &StepId, lease: StepLease, now: OffsetDateTime, ) -> Result<StepAttempt, DomainError>
Sourcepub fn step_claim_fence(
&self,
step_id: &StepId,
) -> Result<StepClaimFence, DomainError>
pub fn step_claim_fence( &self, step_id: &StepId, ) -> Result<StepClaimFence, DomainError>
Capture this identity from the accepted claim before starting work.
pub fn apply_step_result( &mut self, definition: &CeremonyDefinition, step_id: &StepId, claim_fence: StepClaimFence, result: StepResult, now: OffsetDateTime, ) -> Result<(), DomainError>
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn transition_is_enabled(
&self,
definition: &CeremonyDefinition,
transition: &CeremonyTransition,
) -> bool
pub fn transition_is_enabled( &self, definition: &CeremonyDefinition, transition: &CeremonyTransition, ) -> bool
A terminal move also requires every open intervention to be resolved.
Sourcepub fn transition_requirements_are_satisfied(
&self,
definition: &CeremonyDefinition,
transition: &CeremonyTransition,
) -> bool
pub fn transition_requirements_are_satisfied( &self, definition: &CeremonyDefinition, transition: &CeremonyTransition, ) -> bool
Whether every transition requirement other than its declared history budget is satisfied. A driver uses this only after no budget-enabled edge exists, so the aggregate can issue the same stable cap refusal as an explicit transition command.
pub fn guard_is_satisfied_for_transition( &self, definition: &CeremonyDefinition, transition: &CeremonyTransition, guard: &CeremonyGuard, ) -> bool
pub fn transition_is_enabled_at( &self, definition: &CeremonyDefinition, transition: &CeremonyTransition, now: OffsetDateTime, ) -> bool
pub fn apply_transition_as( &mut self, definition: &CeremonyDefinition, role_id: &RoleId, trigger: &TransitionTrigger, now: OffsetDateTime, ) -> Result<StateId, DomainError>
pub fn apply_transition( &mut self, definition: &CeremonyDefinition, trigger: &TransitionTrigger, now: OffsetDateTime, ) -> Result<StateId, DomainError>
Source§impl CeremonyInstance
impl CeremonyInstance
Sourcepub fn start(
id: CeremonyId,
definition: &CeremonyDefinition,
context: CeremonyContext,
now: OffsetDateTime,
) -> Result<Self, DomainError>
pub fn start( id: CeremonyId, definition: &CeremonyDefinition, context: CeremonyContext, now: OffsetDateTime, ) -> Result<Self, DomainError>
Start from a definition supplied for this run.
Nothing binds the instance to a definition that can be looked up
later; that is what Self::start_bound is for. The instance
is the fold of the opening event Self::decide_start yields.
Sourcepub fn start_bound(
id: CeremonyId,
published: &PublishedCeremonyDefinition,
context: CeremonyContext,
now: OffsetDateTime,
) -> Result<Self, DomainError>
pub fn start_bound( id: CeremonyId, published: &PublishedCeremonyDefinition, context: CeremonyContext, now: OffsetDateTime, ) -> Result<Self, DomainError>
Start from a published definition, recording its digest.
The digest travels with the instance so a later reader can verify which definition ran instead of taking the name and version on trust.
Sourcepub fn bound_definition(&self) -> Option<CeremonyDefinitionDigest>
pub fn bound_definition(&self) -> Option<CeremonyDefinitionDigest>
The digest of the published definition this instance runs, if it was started from one.
pub fn lineage(&self) -> Option<&CeremonyLineage>
Sourcepub fn succession(&self) -> Option<&CeremonySuccession>
pub fn succession(&self) -> Option<&CeremonySuccession>
Which ceremony this one succeeds, if it succeeds one.
Sourcepub fn successor_plan(&self) -> Option<&SuccessionPlan>
pub fn successor_plan(&self) -> Option<&SuccessionPlan>
The handoff this ceremony sealed, if it sealed one.
Sourcepub fn is_superseded(&self) -> bool
pub fn is_superseded(&self) -> bool
Whether this ceremony has named the one that replaces it.
pub fn budget_account_id(&self) -> Option<&BudgetAccountId>
pub fn child_groups(&self) -> &BTreeMap<ChildGroupId, ChildGroupState>
pub fn child_group(&self, group_id: &ChildGroupId) -> Option<&ChildGroupState>
Sourcepub fn recollection(&self) -> Option<&SessionRecollection>
pub fn recollection(&self) -> Option<&SessionRecollection>
What earlier sessions in this session’s scope decided, as this session was told when it opened.
Sourcepub fn is_bound_to_a_published_definition(&self) -> bool
pub fn is_bound_to_a_published_definition(&self) -> bool
Whether this instance runs a definition that can be looked up and checked, rather than one supplied for the run.
pub fn id(&self) -> &CeremonyId
pub fn definition_name(&self) -> &CeremonyName
pub fn definition_version(&self) -> &CeremonyVersion
pub fn current_state(&self) -> &StateId
pub fn current_state_visit(&self) -> StateVisit
pub fn current_state_iteration(&self) -> StateIteration
pub fn state_work_is_complete(&self, definition: &CeremonyDefinition) -> bool
pub fn state_repeat_condition_is_satisfied( &self, definition: &CeremonyDefinition, ) -> bool
pub fn state_repeat_permits_transition( &self, definition: &CeremonyDefinition, ) -> bool
pub fn state_repeat_limit_reached( &self, definition: &CeremonyDefinition, ) -> bool
pub fn step_records(&self) -> &BTreeMap<StepId, StepExecutionRecord>
pub fn step_record(&self, step_id: &StepId) -> Option<&StepExecutionRecord>
pub fn execution_receipt_links( &self, ) -> &BTreeMap<ExecutionOperationId, ExecutionReceiptLink>
pub fn execution_receipt_link( &self, operation_id: &ExecutionOperationId, ) -> Option<&ExecutionReceiptLink>
pub fn execution_receipt_adoptions( &self, ) -> &BTreeMap<ExecutionOperationId, BTreeMap<StepClaimFence, ExecutionReceiptLink>>
pub fn execution_receipt_adoption( &self, operation_id: &ExecutionOperationId, applied_claim_fence: &StepClaimFence, ) -> Option<&ExecutionReceiptLink>
Sourcepub fn step_record_history(&self, step_id: &StepId) -> &[StepExecutionRecord]
pub fn step_record_history(&self, step_id: &StepId) -> &[StepExecutionRecord]
Finished iterations before the current record, in execution order.
Sourcepub fn step_repeat_limit_reached(
&self,
definition: &CeremonyDefinition,
step_id: &StepId,
) -> bool
pub fn step_repeat_limit_reached( &self, definition: &CeremonyDefinition, step_id: &StepId, ) -> bool
Whether a repeating step consumed its last permitted iteration without satisfying its declared stop condition.
pub fn interventions(&self) -> &[CeremonyIntervention]
pub fn guard_deferrals(&self) -> &[CeremonyGuardDeferral]
Sourcepub fn guard_approvals(&self) -> &[CeremonyGuardApproval]
pub fn guard_approvals(&self) -> &[CeremonyGuardApproval]
Who let each human guard through, in the order they did.
Empty for a session written before approvals recorded an approver, which is the truth about those sessions rather than a gap to paper over.
Sourcepub fn transitions(&self) -> &[CeremonyTransitionRecord]
pub fn transitions(&self) -> &[CeremonyTransitionRecord]
Every move this session made, in the order it made them.
Sourcepub fn reasons(&self) -> &[CeremonyReason]
pub fn reasons(&self) -> &[CeremonyReason]
Why one thing here led to another.