Formal verification for policy module: 3 bugs fixed, 44 Z3 proofs, 100% MC/DC #7932
probelabs / Visor: performance
succeeded
Apr 20, 2026 in 54s
✅ Check Passed (Warnings Found)
performance check passed. Found 1 warning, but fail_if condition was not met.
Details
📊 Summary
- Total Issues: 1
- Warning Issues: 1
🔍 Failure Condition Results
Passed Conditions
- global_fail_if: Condition passed
Issues by Category
Performance (1)
⚠️ internal/policy/apply.go:422 - The logic for mergingRestrictedTypeswithin theapplyPartitionsfunction uses a nested loop, resulting in O(N*M) time complexity, where N is the number of types in the session-so-far and M is the number of types in the policy being applied. This can be inefficient if an API has a large number of GraphQL types defined in its access rights across multiple policies. A similar inefficient loop exists for mergingAllowedTypesstarting at line 449.
Powered by Visor from Probelabs
💡 TIP: You can chat with Visor using /visor ask <your question>
Annotations
Check warning on line 435 in internal/policy/apply.go
probelabs / Visor: performance
performance Issue
The logic for merging `RestrictedTypes` within the `applyPartitions` function uses a nested loop, resulting in O(N*M) time complexity, where N is the number of types in the session-so-far and M is the number of types in the policy being applied. This can be inefficient if an API has a large number of GraphQL types defined in its access rights across multiple policies. A similar inefficient loop exists for merging `AllowedTypes` starting at line 449.
Raw output
To optimize the merge operation, convert the slice of types into a map before the loop for O(1) lookups. This would reduce the overall complexity from O(N*M) to O(N+M).
Example for `RestrictedTypes`:
```go
// Before line 422
restrictedTypesMap := make(map[string]*graphql.Type, len(r.RestrictedTypes))
for i := range r.RestrictedTypes {
restrictedTypesMap[r.RestrictedTypes[i].Name] = &r.RestrictedTypes[i]
}
for _, rt := range v.RestrictedTypes {
if existing, ok := restrictedTypesMap[rt.Name]; ok {
existing.Fields = appendIfMissing(existing.Fields, rt.Fields...)
} else {
newType := rt
r.RestrictedTypes = append(r.RestrictedTypes, newType)
restrictedTypesMap[newType.Name] = &r.RestrictedTypes[len(r.RestrictedTypes)-1]
}
}
```
Loading