Feature ask with the consumer evidence up front, because the consumer already exists and is computing around the absence.
What we built to compensate for pull-only quota
Our dispatch-guard stack carries two pieces of machinery that exist only because window state can change between polls:
- a 5-minute TTL on lane verdicts (a cache of "is this provider/account dispatchable"), invalidated on wall clock because nothing else can invalidate it;
- a fail-closed freshness gate that denies dispatches outright when the quota snapshot is older than 10 minutes — because acting on stale quota spends real money against depleted windows.
Both have fired in production. The sharpest instance: a seat hit a 58-minute-stale snapshot and had its dispatch blocked — correct behavior, wasted round-trip. The staleness was real; the change it guarded against mostly wasn't. That's the signature of a missing wire: consumers building fail-closed timers to approximate events the producer could emit precisely.
The ask
Emit an event on window-state transitions, per (provider, account, window):
threshold_crossed (a small ordered set — e.g. 80/95/100 — or producer-chosen),
went_dead (exhausted, and for fixed-reset windows: until when),
reset_occurred (window rolled over / credits refilled to a dispatchable level).
Current-state semantics only — each event carries the same entry shape usage.get already returns, so a consumer treats it as "your cached read of this entry is now wrong, here's the fresh one". No history claim, no delivery guarantee beyond live-subscriber push: a consumer that missed events falls back to the poll it already does today. Insula stays the facts producer; verdicts stay ours (the F-A boundary, kept).
On transport
We'd consume this from the subc event seam the moment one exists — subconscious#4's ruling puts live module facts in core scope with consumers classifying, which is exactly the shape these are. If that seam's timeline makes this premature, a poll-side alternative (changed_since=<cursor> on usage.get, returning only entries whose state moved) buys most of the value with no push machinery at all — the lane cache invalidates on a cheap cursor poll instead of a full sweep. Either shape retires both pieces of compensating machinery; we'd delete them and be the reference consumer.
Feature ask with the consumer evidence up front, because the consumer already exists and is computing around the absence.
What we built to compensate for pull-only quota
Our dispatch-guard stack carries two pieces of machinery that exist only because window state can change between polls:
Both have fired in production. The sharpest instance: a seat hit a 58-minute-stale snapshot and had its dispatch blocked — correct behavior, wasted round-trip. The staleness was real; the change it guarded against mostly wasn't. That's the signature of a missing wire: consumers building fail-closed timers to approximate events the producer could emit precisely.
The ask
Emit an event on window-state transitions, per
(provider, account, window):threshold_crossed(a small ordered set — e.g. 80/95/100 — or producer-chosen),went_dead(exhausted, and for fixed-reset windows: until when),reset_occurred(window rolled over / credits refilled to a dispatchable level).Current-state semantics only — each event carries the same entry shape
usage.getalready returns, so a consumer treats it as "your cached read of this entry is now wrong, here's the fresh one". No history claim, no delivery guarantee beyond live-subscriber push: a consumer that missed events falls back to the poll it already does today. Insula stays the facts producer; verdicts stay ours (the F-A boundary, kept).On transport
We'd consume this from the subc event seam the moment one exists — subconscious#4's ruling puts live module facts in core scope with consumers classifying, which is exactly the shape these are. If that seam's timeline makes this premature, a poll-side alternative (
changed_since=<cursor>onusage.get, returning only entries whose state moved) buys most of the value with no push machinery at all — the lane cache invalidates on a cheap cursor poll instead of a full sweep. Either shape retires both pieces of compensating machinery; we'd delete them and be the reference consumer.