feat(token-quota): add distributed quota topology - #84
Conversation
Add the provider-selection contract to GridNetwork and routing overlays. Support deterministic, random, and round-robin selection while keeping request-time choice in Praxis AI. Carry selection groups and policy fields through semantic digests, overlay-sync validation, gateway configuration, CRDs, and Helm. Keep admission, locality, freshness, and scoring separate from request selection. Add focused equal-selection coverage and document session affinity, multi-consumer behavior, failure boundaries, and upgrade considerations. Signed-off-by: Brent Salisbury <bsalisbu@redhat.com>
Add a Forge topology for validating shared token quota enforcement across multiple Praxis consumer gateways while Grid independently distributes admitted traffic across provider gateways. Configure Secret-backed Valkey connectivity, restricted network access, provider trust, explicit image overrides, and readiness barriers. Keep quota admission and state ownership in Praxis AI. Grid continues to publish provider routing state and does not contact the quota backend. Signed-off-by: Brent Salisbury <bsalisbu@redhat.com>
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review
Summary: Adds provider-selection contract (selectionPolicy.mode) to GridNetwork CRD with deterministic, roundRobin, and random modes; adds selection-group assignment to overlay candidates; includes overlay-sync validation, Helm/CRD support, and a distributed token-quota Forge topology.
Overall: The design is well-structured with clear separation between operator-side rendering and data-plane selection. Tests cover round-trip serialization, unknown-field rejection, digest semantics, and group assignment. Two issues found: one indentation bug in the consumer config renderer that produces malformed YAML, and one forward-compatibility concern in overlay-sync.
| Severity | Count |
|---|---|
| Critical | 0 |
| Large | 1 |
| Medium | 1 |
| SelectionMode::RoundRobin => "roundRobin", | ||
| SelectionMode::Random => "random", | ||
| }; | ||
| format!(" selection_policy:\n mode: {mode}\n") |
There was a problem hiding this comment.
[Large] YAML indentation mismatch: selection_policy: is rendered with 9 leading spaces, but its sibling properties (local_site:, model_header:, candidates:) all use 8 spaces (via \x20 + 7 literal spaces in the format string at line 172-175). This 1-space offset will produce malformed YAML when selection_policy is present -- the YAML parser will reject the config or misinterpret the structure because selection_policy: appears at a different indentation level than its mapping siblings.
Change to 8 spaces for selection_policy: and 10 for mode: to match the existing \x20 + 7-space pattern:
format!(" selection_policy:\n mode: {mode}\n")The test at line 674 only checks config.contains("selection_policy:") which passes regardless of indentation -- consider adding a YAML parse assertion.
|
|
||
| /// Selection policy copied without interpretation by overlay-sync. | ||
| #[derive(Clone, Debug, Deserialize, Serialize)] | ||
| #[serde(rename_all = "camelCase", deny_unknown_fields)] |
There was a problem hiding this comment.
[Medium] deny_unknown_fields on SelectionPolicy creates a forward-compatibility asymmetry with RoutingCandidate (which intentionally accepts unknown fields, tested by additive_candidate_field_is_digest_significant_and_accepted). If a future operator version adds a field to SelectionPolicyConfig, overlay-sync with the current code will reject the envelope as Malformed, requiring overlay-sync to be upgraded before the operator.
Either remove deny_unknown_fields from SelectionPolicy to match the open candidate contract, or document in a code comment that this struct is intentionally strict and that overlay-sync must be upgraded before the operator when new selection-policy fields are added.
Summary
This PR adds the Grid-side provider-selection contract used by Praxis AI for request-time load distribution and introduces a Forge topology for validating distributed token quotas alongside Grid routing.
Grid remains the asynchronous control plane:
This PR does not add token quota enforcement to Grid. The included quota topology demonstrates that Praxis AI can enforce one shared quota while Grid independently distributes admitted requests across provider gateways.
Project Stack
The responsibility boundaries are explicit:
Grid does not read quota state, contact Valkey, or place quota enforcement in its reconciliation loop.
Related Work
The AI PR implements request-time selection from the Grid-produced contract. This Grid PR publishes that contract and supplies the integration topology. The distributed quota behavior is demonstrated separately in the experimental repository.
Provider-Selection Contract
The GridNetwork API gains an explicit selection policy:
Supported modes are:
The rendered routing overlay carries the resolved mode using the wire contract consumed by Praxis AI:
{ "selection_policy": { "mode": "roundRobin" } }Each candidate can also carry a selection group:
{ "cluster": "provider-a", "selection_group": 0 }The two fields answer different questions:
selection_group
Which candidates may actively share traffic?
selection_policy.mode
How should Praxis choose among candidates in that group?
Grid determines the groups. Praxis performs the selected operation locally on the request path.
Selection Modes
Deterministic
Praxis chooses the first viable candidate in the best active group.
This supports strict provider preference, ordered failover, and configurations where one provider should receive new traffic until it becomes ineligible.
Round Robin
Praxis takes turns across viable candidates in the best active group.
This provides equal active-active distribution without requiring EPP, Prometheus, or inference-specific metrics.
Stacked on Provider Selection
This branch is stacked on Grid PR #65, the provider-selection foundation.
PR #65 provides:
selectionPolicy.mode;deterministic,roundRobin, andrandomselection modes;This branch adds only the distributed token-quota integration topology and the gateway configuration needed to validate it. It does not duplicate or modify the provider-selection implementation from PR #65.
The quota topology exercises:
roundRobinprovider-selection contract;Quota enforcement remains owned by Praxis AI. Grid publishes provider routing state but does not read Valkey, reserve tokens, or enforce quota.
Random
Praxis selects uniformly among viable candidates in the best active group.
This provides stateless equal-probability distribution without converting Grid scores into traffic weights.
Routing and Scoring Policies
Selection remains separate from routing and scoring.
Geography First
geographyFirst groups candidates using:
Praxis can balance among equivalent providers in the closest viable locality tier. Remote providers remain available in lower-priority groups.
Score First
scoreFirst groups candidates using:
Eligible providers from different sites can therefore share the active group.
Scoring
Existing scoring strategies remain independent from request distribution:
For metric-aware strategies, Grid asynchronously obtains the configured signals from the llm-d EPP Prometheus-compatible metrics endpoint.
Scores affect ordering and observability. A score difference:
For example:
Queue pressure may affect provider preference and group ordering, while traffic remains equally distributed within the active group.
Selection-Group Construction
Selection groups are assigned after the existing deterministic candidate sort.
Groups are scoped independently by capability and capability name. Candidates for different models or tools do not share selection state.
The grouping rules preserve operational boundaries:
Candidate identity is not itself a grouping boundary. Multiple equivalent provider gateways can therefore share one active group.
Scores remain available for ordering and explanation, but metric noise does not create a new group on every score change.
Session Affinity and Admission
Grid publishes provider admission state as part of the candidate contract.
Praxis applies that state as follows:
Session affinity is evaluated before the configured selection mode.
A provider can therefore stop receiving new sessions without immediately breaking valid existing sessions.
Overlay Integrity
The selection policy and candidate selection groups are part of the semantic routing contract.
They are included in overlay digest calculation so that changes to request-distribution behavior produce a new semantic revision.
The operator and overlay-sync agree on the digest-significant payload:
Overlay-sync validates the raw semantic JSON rather than reconstructing candidates through an older typed representation. This preserves additive fields for forward-compatible consumers.
Credential and Secret-reference structures remain strict and continue to reject unknown security-sensitive fields.
Compatibility
selectionPolicy is optional in the Grid CRD.
When it is omitted, the operator omits selection_policy from the generated overlay. Consumers that do not understand the new fields can ignore the additive candidate metadata, while
compatible Praxis AI versions retain deterministic behavior for an omitted selection policy.
New deployments can explicitly select round-robin behavior:
gridNetwork:
selectionPolicy:
mode: roundRobin
The policy is not inferred from:
This avoids silently changing traffic distribution during a partial upgrade.
The Helm chart continues to render provider admissionPolicy independently of selectionPolicy. Admission stabilization and request distribution are separate controls and can be configured together.
Multiple Consumer Gateways
The overlay contract can be consumed by multiple Praxis consumer gateways.
Each gateway performs selection from its own in-memory snapshot. No centralized request-time coordinator is required.
Important behavior:
This design avoids placing Grid, Kubernetes, or a distributed counter in the request hot path.
Distributed Token-Quota Topology
The PR includes a Forge topology for exercising shared token quota enforcement together with Grid provider selection.
The topology contains:
The two consumer gateways share one Valkey-backed quota. Grid publishes the three eligible providers and round-robin selection mode.
The topology proves that:
The topology uses Forge’s existing manifest, Helm, template, and readiness primitives. It does not introduce quota functionality into the Grid operator.
Image Configuration
The topology must not depend on contributor-owned registry images.
Gateway, operator, overlay-sync, tracing, and supporting images are supplied through explicit configuration and the existing image-override mechanism.
Example local validation:
Published demonstrations may provide pinned images separately, but Grid repository defaults remain organization-owned or explicitly overridden.
Security Considerations
Provider selection does not consume credentials, request bodies, prompts, completions, authorization headers, or raw session identifiers.
The quota topology uses Secret-backed configuration for:
The topology is intended for integration validation, not as a production security reference. Production deployments should use:
No raw user identity, quota key, credential, request ID, or trace ID is introduced as a Prometheus label by the Grid changes.
Performance and Hot-Path Behavior
All Grid work remains asynchronous.
Grid may:
Praxis performs request-time selection from an already loaded in-memory snapshot.
This PR does not add the following to the request path:
The group index and selection state belong to Praxis AI and are constructed when the overlay is loaded.
Observability
The overlay exposes bounded routing context suitable for logs, metrics, and traces:
This allows an operator to distinguish:
The token-quota demo can additionally show the AI-owned admission result, remaining quota, selected provider for admitted requests, and the absence of a provider hop for denied requests.
Documentation
The provider-selection architecture is documented in the repository and covers:
The research demonstration and video are linked from Grid issue #31 (#31).
Current Scope
This PR implements:
It does not implement:
Weighted provider distribution remains a separate extension to the selection contract.
Validation
Static and focused validation should include:
cargo +nightly fmt --all -- --check
git diff --check
cargo clippy --workspace --all-targets --locked -- -D warnings
make lint
make test
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
Focused coverage includes:
Runtime provider-selection validation covers:
The distributed quota validation is maintained separately and covers shared quota across consumer gateway replicas while Grid continues to distribute admitted traffic.
Checklist
Breaking Changes
No breaking change is intended.
selectionPolicy and selection_group are additive. Existing Grid resources may omit the policy, and compatible consumers retain deterministic selection.
Deployments must upgrade Praxis AI to a version that understands the selection contract before enabling a non-deterministic selection mode. Older consumers may ignore additive candidate fields, but operators should not assume they will perform round-robin or random selection.
Quota enforcement remains an independent Praxis AI capability and is not enabled by this Grid change.