Fixes a type-assertion panic when a workspace has an empty role string.
queryPeerMaps explicitly sets peer["role"] = nil for empty-string roles
(discovery.go:340), and filterPeersByQuery did p["role"].(string) without
guarding for nil. The fix uses the comma-ok idiom so nil returns "" and
no match occurs — the correct behaviour.
Test files added (all pure functions, no DB/side effects):
- discovery_filter_test.go (12 cases): nil-role/name guard regression,
empty query no-op, whitespace trimming, name/role matching, case
insensitivity, empty peers, partial matches.
- org_helpers_walk_test.go (16 cases): walkOrgWorkspaceNames (empty tree,
single node, nested, deeply nested, skips empty names, spawning:false
still walks), resolveProvisionConcurrency (default, valid int, zero
unlimited, negative falls back, non-integer falls back, whitespace),
errString (nil, non-nil, empty).
- delegation_extract_response_text_test.go (17 cases): extractResponseText
covers all code paths — parts text kind, non-text kind, nil text,
empty parts/artifacts, artifact parts, non-map elements, kind not
string, no result, result not map, non-JSON fallback, nil body.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>