-
Notifications
You must be signed in to change notification settings - Fork 307
Description
Context
From security audit discussion #21454 (Sergo Run 24, 2026-03-17).
Problem
GetSupportedEngines() and GetEngineByPrefix() in pkg/workflow/agentic_engine.go iterate the r.engines map[string]CodingAgentEngine directly using for range, producing non-deterministic results due to Go's randomized map iteration order.
GetEngineByPrefix() specifically returns the first matching engine whose ID is a prefix of the query string — since iteration order is random, the same prefix string can resolve to different engines across runs.
// Lines 459-465 — non-deterministic order
func (r *EngineRegistry) GetSupportedEngines() []string {
var engines []string
for id := range r.engines {
engines = append(engines, id)
}
return engines
}
// Lines 480-487 — first match wins, order is random
func (r *EngineRegistry) GetEngineByPrefix(prefix string) (CodingAgentEngine, error) {
for id, engine := range r.engines {
if strings.HasPrefix(prefix, id) {
return engine, nil
}
}
...
}Severity: HIGH — Non-deterministic engine selection, potential intermittent test failures, inconsistent --engine flag behavior.
Confirmed unfixed since: Run 2 (2026-02-22) — 23 consecutive runs.
Files to Modify
pkg/workflow/agentic_engine.go— fixGetSupportedEngines()andGetEngineByPrefix()
Approach
GetSupportedEngines(): Sort the result before returning:
func (r *EngineRegistry) GetSupportedEngines() []string {
var engines []string
for id := range r.engines {
engines = append(engines, id)
}
sort.Strings(engines)
return engines
}GetEngineByPrefix(): Collect all matching candidates, sort by ID, return the first (longest or alphabetically first):
func (r *EngineRegistry) GetEngineByPrefix(prefix string) (CodingAgentEngine, error) {
type candidate struct{ id string; engine CodingAgentEngine }
var candidates []candidate
for id, engine := range r.engines {
if strings.HasPrefix(prefix, id) {
candidates = append(candidates, candidate{id, engine})
}
}
if len(candidates) == 0 {
return nil, fmt.Errorf("no engine found matching prefix: %s", prefix)
}
sort.Slice(candidates, func(i, j int) bool { return candidates[i].id < candidates[j].id })
return candidates[0].engine, nil
}Also check if GetAllEngines() or similar functions in the same file have the same issue and fix them as well.
Acceptance Criteria
-
GetSupportedEngines()returns engines in consistent (sorted) order -
GetEngineByPrefix()deterministically resolves the same prefix to the same engine - Tests in
agentic_engine_test.goand related engine tests pass -
make agent-finishpasses with no errors
Generated by Plan Command for issue #discussion #21454 · ◷
- expires on Mar 19, 2026, 11:44 PM UTC