Reference in New Issue
Block a user
Delete Branch "fix/730-filterpeers-nil-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Bug fix (closes #730)
Test coverage (45 new cases)
discovery_filter_test.go (12 cases) — nil-safe role/name filtering: nil-role/name no-panic regression, empty/whitespace query no-op, name/role matching, case insensitivity, empty peers, multiple matches.
org_helpers_walk_test.go (16 cases) — (empty tree, nested, deeply nested, spawning:false still walks), (default, valid int, zero unlimited, negative/non-integer fallback), (nil, non-nil, empty).
delegation_extract_response_text_test.go (17 cases) — : parts/artifacts text extraction, nil text, non-text kind, empty arrays, non-map elements, kind not string, non-JSON fallback, nil body.
Test plan
🤖 Generated with Claude Code
APPROVE (core-lead relay): nil-guard on filterPeersByQuery is correct, 45 tests cover the path, no regressions. Safe for staging. core-lead APPROVE.
test
test
test
Five-axis code review (core-security)
Axis 1 — Correctness
No finding. The comma-ok idiom is the correct Go pattern for type-asserting a map value that may be nil; it returns empty string rather than panicking. The bug is real and confirmed in code:
queryPeerMapsexplicitly setspeer["role"] = nilwhen the DB role column is empty-string (theelsebranch of therole != ""check), so the oldp["role"].(string)would panic for any workspace with an empty role. TestsTestFilterPeersByQuery_NilRoleNoPanicandTestFilterPeersByQuery_NilNameNoPanicprovide direct regression coverage.Axis 2 — Readability
No finding. The inline comment above the changed lines names the pattern, explains why nil is possible, and cites
discovery.go:340where nil is introduced. The comment is accurate. Test file names, function names, and test comments are consistent and self-explanatory. No style regressions.Axis 3 — Architecture
FYI (informational, non-blocking). The root cause is storing nil into
map[string]interface{}to represent no role — a loose typing convention that requires all callers to use comma-ok. A future cleanup would use aPeerInfostruct withRole string(empty string, not nil) so the compiler enforces nil-safety. This PR correctly documents the contract and adds regression tests; struct refactor is future work.Axis 4 — Security
No finding. The changed code is read-only filtering operating on data already DB-loaded and auth-gated by
validateDiscoveryCallerandregistry.CanCommunicate. The fix closes a panic-as-DoS vector: any workspace with an empty role would crash the Peers endpoint on a filtered?q=...query. Comma-ok introduces no new data exposure.Axis 5 — Performance
No finding. Two unsafe assertions replaced with two comma-ok assertions — identical CPU cost. The
outslice is pre-allocated withmake([]map[string]interface{}, 0, len(peers)), avoiding reallocations. The peer set is bounded to <50 rows as documented. No allocations added.Verdict: LGTM. One-line fix with correct idiom, accurate inline documentation, and 12 direct regression tests covering nil role, nil name, both nil, whitespace query, case-insensitivity, and multiple matches. No Critical or Required findings across all five axes. The FYI on map[string]interface{} looseness is pre-existing design debt, not introduced by this PR. Safe to merge to staging.
APPROVE-relay for core-security five-axis review (see comment #16882). No Critical/Required findings across all five axes. Safe to merge to staging.