Expand description
Standing authority: a ceiling that outlives a run and is narrower than a tenant.
§The gap this fills
Two ceilings exist and neither has this shape. A Budget bounds one
run; a TenantQuota bounds one tenant over a billing period. Both
are resource controls — they answer how much may this computation consume.
What neither answers is how much was this authorization good for. A customer approves up to €500 of purchases. A purchase order covers three draws against one supplier. A subscriber authorizes a recurring charge until they cancel. Each is a ceiling that
- spans many runs, so a per-run budget cannot hold it;
- is narrower than the tenant and has no billing period, so a quota cannot;
- is bound to an artifact somebody agreed to, and can be revoked when they change their mind.
That last property is what makes this an authorization rather than a
throttle, and it is why this is not a third field on TenantQuota. A quota
that is exhausted refuses for now; a standing authority that is revoked
refuses from here on, and conflating them teaches a caller to retry a
decision that will never change — the same distinction QuotaError draws
against a policy denial.
§Drawing is an effect, and it has to be
The remaining balance is mutable state outside the journal. Reading it inside
the deterministic zone would make a replay depend on what the store happens
to hold now: a run replayed after a later draw would see a different
balance, reach a different verdict, and produce a history that disagrees with
itself. So StepCtx::draw journals the draw, and replay reads the recorded
receipt rather than consuming again.
§Idempotent by dispatch identifier — not by effect key, and not by amount
A draw is a mutation, so a retry has to be safe. The store keys each draw by the identifier of the logical call that made it and returns the original receipt for a repeat, which is the same shape as the journal’s own exactly-once guarantee and works for the same reason: a read-then-write leaves a window two instances draw through, and that window is the whole guarantee when a ceiling is nearly spent.
Which identifier is load-bearing, and the two wrong answers are instructive.
- The effect key hashes the attempt number — it must, or a retry would
collide with the journaled failure before it and replay would read back the
failure. That makes it exactly wrong here: two attempts at one draw would
carry two keys and consume the authority twice. The type below is still an
EffectKey, becauseProvenance::dispatchis one — it is the same key with the attempt pinned to zero. Same type, different question. - The amount would collapse two legitimate €20 draws against one authority into one.
§What this is not
It is not a payments protocol, an escrow, or a settlement record. It holds no payment instrument and speaks no wire. It is the ceiling and the revocation — the part a runtime can enforce — and it is deliberately domain-neutral so a purchase mandate, a spend envelope and a support-credit allowance are one mechanism rather than three.
Structs§
- Authority
Id - Identifies one standing authority.
- Authority
State - What one authority has consumed, and whether it still stands.
- Drawn
- One draw, as the store recorded it.
- Revocation
- Why an authority was withdrawn, and when.
- Standing
Authority - What somebody authorized, and how far it goes.
Enums§
- Authority
Error - Why a draw was refused.
- Holder
- On whose behalf an authority may be drawn.
Traits§
- Authority
Store - Durable accounting for standing authorities.