Context
The update-gateway-score API (POST /update-gateway-score) is the feedback channel used by callers to let the decision engine know the outcome of a transaction so that gateway scores can be updated. Today this flow is heavily biased toward the SR-based routing path.
Relevant entry points:
Inside update_gateway_score, the routing approach is read from transaction metadata via get_routing_approach and then compared using two substring helpers:
// gateway_scoring_service.rs
pub fn is_routing_approach_in_srv3(maybe_text: Option<String>) -> bool {
match maybe_text {
Some(text) => text.contains(\"V3\"),
None => false,
}
}
pub fn is_routing_approach_in_explore(maybe_text: Option<String>) -> bool {
match maybe_text {
Some(text) => text.contains(\"HEDGING\"),
None => false,
}
}
These gate should_isolate_srv3_producer and should_update_explore_txn, which in turn control whether GatewayScoringData is loaded from Redis and used to update scores.
However, the GatewayDeciderApproach enum in src/decider/gatewaydecider/types.rs has many non-SR variants that callers legitimately use, notably:
PriorityLogic (i.e. rule-based / Euclid routing)
NtwBasedRouting
MerchantPreference
Default
When routing was done via PRIORITY_LOGIC (rule-based), the routing approach string does not contain V3 or HEDGING, so the scoring pipeline short-circuits and no score updates are applied for the selected gateway. Merchants using rule-based routing therefore get no benefit from the feedback loop, and gateway health signals collected via update-gateway-score are silently dropped.
Motivation
- Rule-based routing is a first-class routing strategy in the decision engine (see the
Rule-Based (Euclid) entry in the dashboard sidebar and the EuclidRulesPage).
- Gateway scores (SR / elimination / latency) are useful regardless of how the gateway was originally selected — the score reflects the health of the gateway, not the selector that picked it.
- Users reasonably expect that if they hit
/update-gateway-score with a successful or failed transaction, the engine will update its view of that gateway's health.
Proposal
- Decouple "which scoring dimensions to update" from "which routing approach selected this txn". Scoring updates should run whenever the caller hits
update-gateway-score, independent of whether the original decision came from SR, rule-based, network-based, or merchant-preference routing.
- Replace the substring checks (
contains(\"V3\"), contains(\"HEDGING\")) with explicit matches on GatewayDeciderApproach variants where gating is truly needed (e.g. SRv3-producer isolation should check SrSelectionV3Routing / SrV3* variants explicitly).
- For rule-based routing specifically, ensure
should_update_gateway_score and SRv3 score updates are allowed so that the Redis GatewayScoringData is read and scores (SR, elimination, latency) are updated.
- Add unit/integration tests that call
update-gateway-score for a transaction originally routed via PRIORITY_LOGIC and assert that the expected Redis keys are updated.
Acceptance Criteria
Context
The
update-gateway-scoreAPI (POST /update-gateway-score) is the feedback channel used by callers to let the decision engine know the outcome of a transaction so that gateway scores can be updated. Today this flow is heavily biased toward the SR-based routing path.Relevant entry points:
src/routes/update_gateway_score.rsupdate_gateway_scoreinsrc/feedback/gateway_scoring_service.rs(around L566)Inside
update_gateway_score, the routing approach is read from transaction metadata viaget_routing_approachand then compared using two substring helpers:These gate
should_isolate_srv3_producerandshould_update_explore_txn, which in turn control whetherGatewayScoringDatais loaded from Redis and used to update scores.However, the
GatewayDeciderApproachenum insrc/decider/gatewaydecider/types.rshas many non-SR variants that callers legitimately use, notably:PriorityLogic(i.e. rule-based / Euclid routing)NtwBasedRoutingMerchantPreferenceDefaultWhen routing was done via
PRIORITY_LOGIC(rule-based), the routing approach string does not containV3orHEDGING, so the scoring pipeline short-circuits and no score updates are applied for the selected gateway. Merchants using rule-based routing therefore get no benefit from the feedback loop, and gateway health signals collected viaupdate-gateway-scoreare silently dropped.Motivation
Rule-Based (Euclid)entry in the dashboard sidebar and theEuclidRulesPage)./update-gateway-scorewith a successful or failed transaction, the engine will update its view of that gateway's health.Proposal
update-gateway-score, independent of whether the original decision came from SR, rule-based, network-based, or merchant-preference routing.contains(\"V3\"),contains(\"HEDGING\")) with explicit matches onGatewayDeciderApproachvariants where gating is truly needed (e.g. SRv3-producer isolation should checkSrSelectionV3Routing/SrV3*variants explicitly).should_update_gateway_scoreand SRv3 score updates are allowed so that the RedisGatewayScoringDatais read and scores (SR, elimination, latency) are updated.update-gateway-scorefor a transaction originally routed viaPRIORITY_LOGICand assert that the expected Redis keys are updated.Acceptance Criteria
update-gateway-scoreupdates gateway scores for transactions whoserouting_approachisPRIORITY_LOGIC(rule-based), not just SR-based variants.gateway_scoring_service.rsare replaced with explicit enum matches (or a well-documented helper) so the gating is type-safe.SrSelectionV3Routing,SrV3Hedging, etc.) continue to behave identically — no regression in SRv3 producer isolation or explore/exploit behavior.update-gateway-scoreendpoint (docs/api-reference/endpoint/updateGatewayScore.mdx) note that all routing approaches are supported.