pub struct BudgetSplit {
pub parent_token_id: String,
pub parent_share_bps: u16,
pub children: BTreeMap<String, ChildAdmission>,
}Expand description
A live record of how much of a parent’s budget has already been delegated to admitted children.
The struct is owned by a BudgetRegistry implementation. Each verified
delegation either admits a new child (incrementing the running sum) or
fails closed because the proposed share would push the sum past the
parent’s own share.
Fields§
§parent_token_id: StringCapability ID of the parent token whose budget is being split.
The parent’s own share in basis points. Bounded by
MAX_BUDGET_SHARE_BPS.
children: BTreeMap<String, ChildAdmission>Map from child capability ID to its admitted share and active-holder
reference count. See ChildAdmission for why the count is required.
Implementations§
Source§impl BudgetSplit
impl BudgetSplit
Sourcepub fn new(parent_token_id: String, parent_share_bps: u16) -> Self
pub fn new(parent_token_id: String, parent_share_bps: u16) -> Self
Build an empty split for parent_token_id with the given parent
share. The parent share is clamped to MAX_BUDGET_SHARE_BPS by the
per-token validator before this constructor is called; it is the
caller’s responsibility not to fabricate a higher value here.
Sourcepub fn current_total_child_bps(&self) -> u32
pub fn current_total_child_bps(&self) -> u32
Return the running sum of admitted sibling shares as a u32 to avoid
overflow even on a maximally adversarial set of admitted children.
Each present edge counts its share exactly once regardless of how many overlapping evaluations hold it: the share is charged against the parent per edge, not per holder.
Return the share currently recorded for child_id, if this child has
an admitted edge under this parent (at least one active holder).
Sourcepub fn child_holders(&self, child_id: &str) -> Option<usize>
pub fn child_holders(&self, child_id: &str) -> Option<usize>
Return the number of active evaluations currently holding a lease on
child_id under this parent, or None when no edge exists. Used by
tests and operator dashboards to inspect concurrent-holder depth.
Sourcepub fn try_admit_child(
&mut self,
child_id: String,
share_bps: u16,
) -> Result<(), BudgetSplitError>
pub fn try_admit_child( &mut self, child_id: String, share_bps: u16, ) -> Result<(), BudgetSplitError>
Try to admit a child under this parent, acquiring one holder lease.
Returns Ok(()) when the child is admitted. A fresh child inserts a new
edge with one holder and increments the running sum. Re-admitting the
same child id with the same share is idempotent for the running sum but
takes an ADDITIONAL holder lease (holders += 1) so an overlapping
evaluation’s later release cannot free an edge another live evaluation
still depends on.
Returns BudgetSplitError - acquiring NO lease - when the child share
alone exceeds the per-token cap, when the proposed share would
oversubscribe the parent, or when a different share has already been
recorded for this child id.
Sourcepub fn verify_child_admission(
&mut self,
child_id: String,
share_bps: u16,
) -> Result<(), BudgetSplitError>
pub fn verify_child_admission( &mut self, child_id: String, share_bps: u16, ) -> Result<(), BudgetSplitError>
Check whether child_id at share_bps would admit under this parent
WITHOUT acquiring a holder lease (see AdmitMode::VerifyOnly).
Runs the same per-token cap, sibling-sum oversubscription, and
duplicate-share checks as Self::try_admit_child. A fresh admissible
child commits its share (so a later sibling sees it in the running sum)
but records holders == 0; an already-present child is left untouched.
This is the entry point for verifier-only surfaces (portable/preflight
verdicts, adapter one-shot evaluations) that produce a verdict but have
no cleanup path to release a lease. Because it never increments
holders, a later real dispatch that unwinds its own lease can still
drive the edge back to zero and free it.
Sourcepub fn release_child(
&mut self,
child_id: &str,
expected_share_bps: u16,
) -> Result<(), BudgetSplitError>
pub fn release_child( &mut self, child_id: &str, expected_share_bps: u16, ) -> Result<(), BudgetSplitError>
Release one holder lease on a child admission recorded under this parent.
Missing children are treated as already released so pre-dispatch cleanup paths can call this after both admission failures and later denial failures without branching on partial state. A mismatched share is still rejected because it indicates the caller is trying to unwind a different child edge; a mismatch drops NO lease.
The edge is removed - returning its share to the parent - only when the
LAST holder releases (holders reaches 0). A non-last release just
decrements the count, keeping the share charged so an overlapping
evaluation that still holds the edge stays protected against an
oversubscribing sibling. Fail-closed: over-releasing another
evaluation’s live share (a budget bypass) is the worse failure, so the
edge is never freed while a holder remains.
Trait Implementations§
Source§impl Clone for BudgetSplit
impl Clone for BudgetSplit
Source§fn clone(&self) -> BudgetSplit
fn clone(&self) -> BudgetSplit
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more