HeddlePolicy
The reference EEVDF allocation policy — a pure function from edge summaries, demand, and immutable attachment policy to a single delegation choice (design §7). It inspects nothing else: no global queues, no descendants, no wall clock, no randomness, no floating point. Purity is what makes it testable at virtual time and safe to run divergently on partitioned peers — a bad local decision only misplaces entitlement, it can never create any.
"EEVDF" = Earliest Eligible Virtual Deadline First: among the children that both want service and are not running ahead of their fair share (eligible), serve the one whose next grant would finish soonest in virtual time (earliest virtual deadline), breaking ties by a stable identity so every replica picks the same winner.
Samples
fun edge(id: String, weight: Weight, issued: Long) = PolicyEdge(
record = AttachmentRecord(AttachmentId(id), GroupId("root"), GroupId(id), weight),
summary = EdgeSummary(AttachmentId(id), issued = issued, returned = 0L, spent = issued),
demand = Demand(targetOutstanding = 100L, maximumUsefulGrant = 100L),
gauge = null, // nothing has seated it yet, so it reads from its own origin
baseIssued = issued, // the gauge's fold axis — the base counter, not the effective one
)
// Both start level (no service yet); the heavier-weighted child has the earliest
// virtual deadline, so it is served first.
val grant = HeddlePolicy.pick(
edges = listOf(edge("heavy", Weight.of(3), issued = 0L), edge("light", Weight.of(1), issued = 0L)),
config = PolicyConfig(quantum = 6L),
localHoldings = 1_000L,
)
check(grant == Grant(AttachmentId("heavy"), 6L))
// A child with no appetite advertises Demand.NONE and is never a candidate.
val idle = HeddlePolicy.pick(
edges = listOf(
PolicyEdge(
AttachmentRecord(AttachmentId("idle"), GroupId("root"), GroupId("idle"), Weight.ONE),
EdgeSummary(AttachmentId("idle"), 0L, 0L, 0L),
Demand.NONE,
gauge = null,
baseIssued = 0L,
),
),
config = PolicyConfig(quantum = 6L),
localHoldings = 1_000L,
)
check(idle == null)Functions
The parent's current virtual time — the front of the set of children competing under it right now (design §7.2, §7.3 step 2). This is the value a joiner is seated at, under one rule for both kinds of joiner: EntitlementLedger.seat writes it into a newborn's Gauge floor, and wakeOffset clamps a waking child up to it.
Pick the single child to delegate the next quantum to, or null when no child is both eligible and demanding.
Raw virtual service of an edge, design §7.1's b + committedService / weight — read off the replicated Gauge rather than off any field of the record (issue #1752):
The forward clamp applied when a child transitions idle→demanding (design §7.2): max(0, front − vRaw − sleeperCredit / weight). Adding this offset to virtualService clamps the waker up to the current front (with default sleeperCredit = 0, exactly to the front), so it cannot claim a backlog of idle virtual time. The result is the PolicyEdge.virtualOffset the caller stores.