Repository navigation
fix(brainbar): resolve brain_entity case-insensitively before substring fallback (Fixes #663) - #1632
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 26 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| Python | Nov 5, 2026 7:03p.m. | Review ↗ | |
| Swift | Nov 5, 2026 7:03p.m. | Review ↗ | |
| JavaScript | Nov 5, 2026 7:03p.m. | Review ↗ | |
| Shell | Nov 5, 2026 7:03p.m. | Review ↗ | |
| Secrets | Nov 5, 2026 7:03p.m. | Review ↗ |
Important
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
BrainLayer ratchetEvery Value below was measured by this run. A row this machine cannot measure says Hosted success gives no verdict on mapped bytes, search p50/p95, idle CPU, hotlane backlog CPU, or fallback replay debt.
🟢 GREEN measured, within budget · 🔴 RED measured, out of budget — a finding to clear before merge · ⚪ n/a not measurable on this machine, never guessed. No RED rows. Measured on Linux/x86_64 · measured |
a072785 to
b44d463
Compare
…ng fallback
lookupEntity tried an exact, case-sensitive name match and then an unordered
`LIKE '%q%' LIMIT 1`. A differently-cased query ("nimbus" for "Nimbus") skipped
the real entity and could return whichever row merely contained the query,
which showed up as an empty card.
Add a middle tier: exact name with COLLATE NOCASE, ordered by importance DESC,
binary name, id so ambiguous case variants resolve deterministically. Exact
spelling still wins, the stored canonical name is returned, the entity-type
filter applies, and the substring fallback is unchanged. Lookup never creates
entities.
Fixes #663
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3NoZEq6gr2o3cqCyd6ZTs
b44d463 to
51c8bb3
Compare
TASK MARKER:
cloud-credit-20261104-brainlayer-more-issue-663Fixes #663
Change and evidence
origin/main@2f87dc7e9646db5fea46235720efb5bacc2bb50a(fetched and checked inside the cloud container before any edits)claude/cloud-worker-auth-setup-wf11kpa0727854cda412786384297d044b0b70832f76e4brain-bar/Sources/BrainBar/BrainDatabase.swift(+32/−58),brain-bar/Tests/BrainBarTests/DatabaseTests.swift(+60)Root cause
brain_entityis served by BrainBar:MCPRouter.handleBrainEntitycallsBrainDatabase.lookupEntity. On main, that function runs two tiers:WHERE name = ?, which is case-sensitive.WHERE name LIKE '%q%' LIMIT 1, with no ORDER BY.A query in a different case (
nimbusforNimbus) misses tier 1. Tier 2 then returns whichever row the table scan reaches first that contains the query, for example an olderOld Nimbus Notesrow with no relations. That is the "empty card" in the issue. The Python library path (kg_repo.resolve_entity) already matches names case-insensitively, but agents can't reach it because BrainBar doesn't serve it.Fix (smallest root correction)
Adds a middle tier between the two:
WHERE name = ? COLLATE NOCASE ... ORDER BY importance DESC, name COLLATE BINARY ASC, id ASC LIMIT 1. The three tiers now share one prepare/bind/step loop instead of copy-pasted blocks.nameis the stored canonical spelling, never the query text.NimbusandNIMBUS, whichUNIQUE(entity_type, name)allows) resolve deterministically: highest importance, then binary name order, then id.entityTypefilter applies to the new tier.Tests added (Swift, synthetic names only)
testEntityLookupResolvesDifferentCaseToCanonicalEntity:Nimbus/nimbus/NIMBUS/nImBuSall resolveent-nimbuswith its canonical name and relation, even though a substring decoy was inserted first. The substring fallback still findsold nimbus.testEntityLookupExactCasePrecedesAndCaseVariantsAreDeterministic: exact spelling beats higher importance. Without an exact spelling, importance decides; on a tie, binary name order decides, and the answer is stable across repeated calls. The type filter is respected.testEntityLookupMissingDifferentCaseDoesNotCreateEntity:nimbuz/NIMBUZreturn nil and the entity count stays at 1.Exact commands and observed output
1. Before/after/mutant SQL replay (RUN, Linux, SQLite 3.53.1, in-memory synthetic fixture). A throwaway script (not committed) extracts the
lookupEntitySQL from the Swift source text:git show origin/main:brain-bar/Sources/BrainBar/BrainDatabase.swiftfor before, the working tree for after. It runs the tier sequence exactly aslookupEntitybinds it:This reproduces the bug: on main,
nimbusreturns the unrelatedOld Nimbus Notescard. The fix passes every check, and both mutants are caught.2. Swift XCTest: RUN in CI on macOS, not locally. This Linux container has no Swift toolchain, and BrainBar needs macOS 14 and AppKit. The job
swift (macos-15)on heada0727854succeeded. Its log shows:DatabaseTestshas 95func test…onorigin/mainand 98 on this head (grep -c "^ func test"), so the 98 executed tests include the 3 new ones. The log lists per-suite counts, not test names. The 23 skipped are elsewhere:DatabaseTestsreports 0 skipped.3. Python tests that read the Swift sources: RUN, Linux.
4. CI on head
a0727854: every check run completed green or skipped by path filter. That includeslint,test (3.11/3.12/3.13),swift (macos-15),installed wheel imports,crash sweeps,ratchet tableand CodeQLAnalyze (swift). DeepSource Swift reports issues outside this diff only, with no inline threads; its Security, Reliability, Complexity and Hygiene grades are all A.Limitations / risks
COLLATE NOCASEfolds ASCII only. That matches SQLiteLIKEand the existingLOWER()inlookupEntityFacts, butÉvséis still case-sensitive. Hebrew has no case, so it is unaffected.HappyCamprentity: entity-creation lag) is not addressed. Per the dispatch, this PR does not create entities, does not fabricate profile or employer facts, and does not touch real data.normalize_case_variantson the Python path was not changed.behindmain, with no conflict. I did not update it, to avoid re-running CI for nothing; the lead can update it before merge.Cost / time
About 55 minutes wall clock, mostly waiting on CI. No cost meter is visible in this session. No paid API calls, subagents or LLM inference.
Crash sweep / feature batch
Swift-only change; no sweep-triggering paths are touched (
crash sweepspassed).Loop-record: implementer=anthropic/claude-code-cloud/high; reviewer=none; rounds=0; defects=0
@Orc handoff (for import into
collab.md)@brainlayer-lead— #663 draft PR ready for your review. I did not merge it or mark it ready.cloud-credit-20261104-brainlayer-more-issue-663. Start2f87dc7e, HEADa0727854. Branchclaude/cloud-worker-auth-setup-wf11kp. PR fix(brainbar): resolve brain_entity case-insensitively before substring fallback (Fixes #663) #1632.lookupEntitygains an ASCII case-insensitive exact tier with deterministic ordering, between the exact andLIKEtiers. There are 3 new XCTests.swift (macos-15):DatabaseTests98/98 (95 existing + 3 new), all 1541 Swift tests with 0 failures.HappyCamprentity-creation lag is out of scope. It needs a separate decision.LIKEtier in a follow-up.🤖 Generated with Claude Code
https://claude.ai/code/session_01L3NoZEq6gr2o3cqCyd6ZTs
Note
Fix
BrainDatabase.lookupEntityto resolvebrain_entitycase-insensitivelyMacroscope summarized 51c8bb3.