Problem
Candidate info metadata can be written as either a YAML mapping:
info :
employer : Example
slack : example
or a sequence of one-key mappings:
info :
- employer : Example
- slack : example
The low-level parser has tests for both forms from #114 , but support is not end-to-end:
Desired behavior
Normalize mapping and sequence forms before candidate fields are rendered.
Update the candidate bio validator to accept both forms.
Validate fields generically against show_candidate_fields.
Add model/controller regression tests that render candidate profiles using both forms.
Keep the documented/template format consistent with the chosen canonical representation.
References
Production failure: Links to candidate bios are not working for 2026 Kubernetes Steering Election #144
Parser-only compatibility tests: Add tests for yaml object format #114
Profile-rendering assumption:
def candidate (self , cid ):
path = os .path .join (self .path , 'candidate-{}.md' .format (cid ))
if not os .path .exists (path ) or not os .path .isfile (path ):
return F .abort (404 )
md = open (path ).read ()
candidate = utils .extract_candidate_info (md )
candidate ['key' ] = cid
candidate ['description' ] = utils .parse_md (
utils .extract_candidate_description (md ), False )
# return only the candidate optional fields that are listed in show_candidate_fields
# unfilled fields are returned as '' so the label still displays
candidate ['fields' ] = self .showfields ()
for info in candidate ['info' ]:
field = list (info .keys ())[0 ]
if field in candidate ['fields' ]:
candidate ['fields' ][field ] = info [field ]
return candidate
Validator type assumption:
type CandidateHeader struct {
Name string `yaml:"name"`
ID string `yaml:"ID"`
Info []map [string ]string `yaml:"info"`
}
Related Kubernetes metadata compatibility change: Update candidate bios format kubernetes/community#9116
Problem
Candidate
infometadata can be written as either a YAML mapping:or a sequence of one-key mappings:
The low-level parser has tests for both forms from #114, but support is not end-to-end:
Election.candidate()assumes the sequence form and calls.keys()on each item. A mapping therefore raises an exception while rendering the candidate profile, as seen in Links to candidate bios are not working for 2026 Kubernetes Steering Election #144.scripts/validate-biosmodelsinfoas[]map[string]string, so the validator onmainalso does not accept both forms.Desired behavior
show_candidate_fields.References
elekto/elekto/models/meta.py
Lines 163 to 180 in da4c19c
elekto/scripts/validate-bios/main.go
Lines 37 to 41 in da4c19c