Struct AttributedApprovalResponse
#[non_exhaustive]pub struct AttributedApprovalResponse {
pub response: ChannelApprovalResponse,
pub decided_by: Option<String>,
pub source: ApprovalSource,
}Expand description
An approval response together with the back-channel that produced it.
When a channel fans one approval request out to several back-channels,
decided_by names the back-channel that actually answered, so the audit
trail attributes the decision to the deciding surface. The attribution
travels with the returned decision, so concurrent approvals on the same
channel instance cannot cross-wire it. Single channels leave it None.
#[non_exhaustive] so a future provenance field is an additive change
rather than another source break. Out-of-tree code must construct this
value through the dedicated constructors on this type — #[non_exhaustive]
forbids struct-literal construction from another crate, so the
..Default::default() wildcard is not a workaround. The constructors
(operator, from_runtime, with_decider, with_decider_opt) below are
the public contract.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.response: ChannelApprovalResponse§decided_by: Option<String>§source: ApprovalSourceWHO produced this response — an operator, or the runtime failing closed.
This cannot be inferred from the other two fields, which is why it is carried explicitly:
Option::is_none()on the whole response does not work, because a fail-closed route returnsSome(Deny)with no decider.decided_by.is_none()does not work either, because a single (non-fan-out) channel leaves itNonefor a genuine operator answer.
Conflating the two produced a tool result that told the model “Denied by user.” on runs where no human was ever asked.
Implementations§
Source§impl AttributedApprovalResponse
impl AttributedApprovalResponse
Sourcepub fn operator(response: ChannelApprovalResponse) -> Self
pub fn operator(response: ChannelApprovalResponse) -> Self
An operator answered through a channel.
Use this at the boundary that actually observed a person’s answer. A
synthesized deny (drop, timeout, unreachable approver) must use
AttributedApprovalResponse::from_runtime instead — that distinction
is the whole point of carrying ApprovalSource.
Sourcepub fn from_runtime(
response: ChannelApprovalResponse,
source: ApprovalSource,
) -> Self
pub fn from_runtime( response: ChannelApprovalResponse, source: ApprovalSource, ) -> Self
The runtime produced this outcome itself; no operator decided.
Sourcepub fn with_decider(self, decider: impl Into<String>) -> Self
pub fn with_decider(self, decider: impl Into<String>) -> Self
Name the back-channel that produced this decision (fan-out attribution).
Deliberately not called decided_by: that is the field’s name, and a
same-named method reads as a getter at the call site.
Sourcepub fn with_decider_opt(self, decider: Option<String>) -> Self
pub fn with_decider_opt(self, decider: Option<String>) -> Self
Same as with_decider but accepts the fan-out
shape where the decider is known to be an Option<String>. Some
names the back-channel; None leaves decided_by unset. Callers that
already carry Option<String> from a routed decision reach for this
rather than a match that rebuilds the value.
Trait Implementations§
Source§impl Clone for AttributedApprovalResponse
impl Clone for AttributedApprovalResponse
Source§fn clone(&self) -> AttributedApprovalResponse
fn clone(&self) -> AttributedApprovalResponse
1.0.0 (const: unstable) · §fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AttributedApprovalResponse
impl Debug for AttributedApprovalResponse
impl Eq for AttributedApprovalResponse
Source§impl PartialEq for AttributedApprovalResponse
impl PartialEq for AttributedApprovalResponse
Source§fn eq(&self, other: &AttributedApprovalResponse) -> bool
fn eq(&self, other: &AttributedApprovalResponse) -> bool
self and other values to be equal, and is used by ==.