Enhanced LanceDB memory plugin for OpenClaw — Hybrid Retrieval (Vector + BM25), Cross-Encoder Rerank, Multi-Scope Isolation, Management CLI
This report summarizes scanner evidence for CortexReach/memory-lancedb-pro, a JavaScript project with 4,453 GitHub stars. SynthScan examined 61,189 lines of code across 102 source files, recording 312 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 5.2 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 274 finding(s).
Are imports declared and package/API names verified? 34 finding(s).
Are wrappers, guards, and repeated structures necessary? 230 finding(s).
Which changes need focused human review? 312 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 312 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cli.ts | 92 | function resolveOpenClawConfigPath(explicit?: string): string { | CODE |
| LOW | cli.ts | 120 | function resolveConfiguredOauthPath(configPath: string, rawPath: unknown): string { | CODE |
| LOW | cli.ts | 153 | function extractRestorableApiKeyLlmConfig(value: unknown): RestorableApiKeyLlmConfig { | CODE |
| LOW | cli.ts | 177 | function extractOauthSafeLlmConfig(value: unknown): RestorableApiKeyLlmConfig { | CODE |
| LOW | cli.ts | 192 | function hasRestorableApiKeyLlmConfig(value: RestorableApiKeyLlmConfig): boolean { | CODE |
| LOW | cli.ts | 196 | function buildLogoutFallbackLlmConfig(value: unknown): RestorableApiKeyLlmConfig { | CODE |
| LOW | cli.ts | 263 | async function promptOauthProviderSelection( | CODE |
| LOW | cli.ts | 361 | async function resolveOauthProviderSelection( | CODE |
| LOW | cli.ts | 512 | function formatRetrievalDiagnosticsLines(diagnostics: { | CODE |
| LOW | cli.ts | 2505 | function registerConsolidateCommand(memory: Command, context: CLIContext) { | CODE |
| LOW⚡ | index.ts | 581 | function getEffectiveAutoRecallMaxItems(config: PluginConfig): number { | CODE |
| LOW⚡ | index.ts | 587 | function getAutoRecallRetrieveLimit(autoRecallMaxItems: number): number { | CODE |
| LOW⚡ | index.ts | 591 | function getAutoRecallRerankInputLimit(retrieveLimit: number): number { | CODE |
| LOW⚡ | index.ts | 595 | function getAutoRecallRerankTimeoutMs( | CODE |
| LOW⚡ | index.ts | 2376 | function isSessionBoundaryReflectionAction(action: unknown): boolean { | CODE |
| LOW⚡ | index.ts | 2383 | function getReflectionEmptyEventGuardMap(): Map<string, ReflectionEmptyEventGuardEntry> { | CODE |
| LOW⚡ | index.ts | 2389 | function pruneReflectionEmptyEventGuard(now = Date.now()): void { | CODE |
| LOW | index.ts | 24 | export function isCliMetadataRegistration(api: OpenClawPluginApi): boolean { | CODE |
| LOW | index.ts | 419 | function resolveWorkspaceDirFromContext(context: Record<string, unknown> | undefined): string { | CODE |
| LOW | index.ts | 441 | function isSupportedSecretRefSource(value: unknown): value is SecretRefSource { | CODE |
| LOW | index.ts | 491 | function resolveSecretCredentialArray( | CODE |
| LOW | index.ts | 513 | function resolveOptionalPathWithEnv( | CODE |
| LOW | index.ts | 610 | export function buildAutoRecallRerankCostWarning( | CODE |
| LOW | index.ts | 685 | function resolveSourceFromSessionKey(sessionKey: string | undefined): string { | CODE |
| LOW | index.ts | 692 | function summarizeAgentEndMessages(messages: unknown[]): string { | CODE |
| LOW | index.ts | 877 | export function getExtensionApiImportSpecifiers( | CODE |
| LOW | index.ts | 927 | export function resolveEmbeddedRunnerExportName(candidate: unknown): EmbeddedRunnerExportName | undefined { | CODE |
| LOW | index.ts | 935 | export function getEmbeddedRunnerExportName(): EmbeddedRunnerExportName | undefined { | CODE |
| LOW | index.ts | 1009 | async function loadSelfImprovementReminderContent(workspaceDir?: string): Promise<string> { | CODE |
| LOW | index.ts | 1023 | function resolveAgentPrimaryModelRef(cfg: unknown, agentId: string): string | undefined { | CODE |
| LOW | index.ts | 1111 | export function resolveRuntimeLlmComplete(api: OpenClawPluginApi): RuntimeLlmCompleteFn | undefined { | CODE |
| LOW | index.ts | 1122 | function isInternalReflectionSessionKey(sessionKey: unknown): boolean { | CODE |
| LOW | index.ts | 1181 | function shouldSkipReflectionMessage(role: string, text: string): boolean { | CODE |
| LOW | index.ts | 1215 | function isSubstantiveUserReferent(turn: ConversationTurn): boolean { | CODE |
| LOW | index.ts | 1249 | function prunePairWindowEpochsCoupled( | CODE |
| LOW | index.ts | 1266 | function isExplicitRememberCommand(text: string): boolean { | CODE |
| LOW | index.ts | 1271 | export function buildAutoCaptureConversationKeyFromIngress( | CODE |
| LOW | index.ts | 1290 | function autoCaptureRetainedTextCap(minMessages: number): number { | CODE |
| LOW | index.ts | 1294 | function buildAutoCaptureConversationKeyFromSessionKey(sessionKey: string): string | null { | CODE |
| LOW | index.ts | 1365 | function extractTextFromToolResult(result: unknown): string { | CODE |
| LOW | index.ts | 1395 | function summarizeRecentConversationMessages( | CODE |
| LOW | index.ts | 1434 | function conversationFromHookSessionMemory( | CODE |
| LOW | index.ts | 1456 | async function readSessionConversationForReflection(filePath: string, messageCount: number, format: ConversationTranscri | CODE |
| LOW | index.ts | 1477 | export async function readSessionConversationWithResetFallback(sessionFilePath: string, messageCount: number, format: Co | CODE |
| LOW | index.ts | 1512 | function trimTranscriptToTagBoundary(transcript: string, maxChars: number): string { | CODE |
| LOW | index.ts | 1674 | function buildReflectionFallbackText(): string { | CODE |
| LOW | index.ts | 1736 | function resolveReflectionModelTarget( | CODE |
| LOW | index.ts | 1792 | async function generateReflectionTextUnbounded( | CODE |
| LOW | index.ts | 2252 | function createAdmissionRejectionAuditWriter( | CODE |
| LOW | index.ts | 2403 | async function getReflectionEmptyEventGuardKey(params: { | CODE |
| LOW | index.ts | 2921 | function isPluginExplicitlyDisabled(config: Record<string, unknown>, pluginName: string): boolean { | CODE |
| LOW | index.ts | 2931 | export function warnForDisabledChannelPlugin( | CODE |
| LOW | index.ts | 6915 | function scheduleNextDreamingSweep() { | CODE |
| LOW | src/workspace-boundary.ts | 44 | export function resolveUserMdExclusiveConfig( | CODE |
| LOW | src/workspace-boundary.ts | 58 | export function shouldFilterUserMdExclusiveRecall( | CODE |
| LOW | src/batch-dedup.ts | 140 | export function createExtractionCostStats(): ExtractionCostStats { | CODE |
| LOW | src/auto-capture-cleanup.ts | 28 | function stripLeadingInboundMetadata(text: string): string { | CODE |
| LOW | src/auto-capture-cleanup.ts | 47 | function stripAutoCaptureSessionResetPrefix(text: string): string { | CODE |
| LOW | src/auto-capture-cleanup.ts | 65 | function stripAutoCaptureAddressingPrefix(text: string): string { | CODE |
| LOW | src/auto-capture-cleanup.ts | 69 | function stripRuntimeWrapperBoilerplate(text: string): string { | CODE |
| 166 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | openclaw.plugin.json | 1780 | "placeholder": "sk-proj-... or [\"key1\", \"key2\"] for rotation", | CODE |
| LOW⚡ | openclaw.plugin.json | 1785 | "placeholder": "text-embedding-3-small", | CODE |
| LOW⚡ | openclaw.plugin.json | 1790 | "placeholder": "https://api.openai.com/v1", | CODE |
| LOW⚡ | openclaw.plugin.json | 1796 | "placeholder": "auto-detected from model", | CODE |
| LOW⚡ | openclaw.plugin.json | 1802 | "placeholder": "omit by default", | CODE |
| LOW⚡ | openclaw.plugin.json | 1868 | "placeholder": "24", | CODE |
| LOW⚡ | openclaw.plugin.json | 1874 | "placeholder": "7", | CODE |
| LOW⚡ | openclaw.plugin.json | 1880 | "placeholder": "300000", | CODE |
| LOW⚡ | openclaw.plugin.json | 1886 | "placeholder": "0", | CODE |
| LOW⚡ | openclaw.plugin.json | 1892 | "placeholder": "redis://localhost:6379", | CODE |
| LOW⚡ | openclaw.plugin.json | 1904 | "placeholder": "redis://localhost:6379", | CODE |
| LOW⚡ | openclaw.plugin.json | 1911 | "placeholder": "memory-lancedb-pro:write-lock", | CODE |
| LOW⚡ | openclaw.plugin.json | 1917 | "placeholder": "60000", | CODE |
| LOW⚡ | openclaw.plugin.json | 1923 | "placeholder": "5000", | CODE |
| LOW⚡ | openclaw.plugin.json | 1929 | "placeholder": "50", | CODE |
| LOW⚡ | openclaw.plugin.json | 1935 | "placeholder": "1000", | CODE |
| LOW⚡ | openclaw.plugin.json | 1946 | "placeholder": "sk-... or ${GROQ_API_KEY}", | CODE |
| LOW⚡ | openclaw.plugin.json | 1951 | "placeholder": "openai/gpt-oss-120b", | CODE |
| LOW⚡ | openclaw.plugin.json | 1956 | "placeholder": "https://api.groq.com/openai/v1", | CODE |
| LOW⚡ | openclaw.plugin.json | 2116 | "placeholder": "jina_... / sk-... / pcsk_...", | CODE |
| LOW⚡ | openclaw.plugin.json | 2122 | "placeholder": "jina-reranker-v3", | CODE |
| LOW⚡ | openclaw.plugin.json | 2128 | "placeholder": "https://api.jina.ai/v1/rerank", | CODE |
| LOW⚡ | openclaw.plugin.json | 2134 | "placeholder": "5000", | CODE |
| LOW | openclaw.plugin.json | 1813 | "placeholder": "retrieval.query", | CODE |
| LOW | openclaw.plugin.json | 1819 | "placeholder": "retrieval.passage", | CODE |
| LOW | openclaw.plugin.json | 1830 | "placeholder": "model-specific default", | CODE |
| LOW | openclaw.plugin.json | 1851 | "placeholder": "30000", | CODE |
| LOW | openclaw.plugin.json | 1857 | "placeholder": "~/.openclaw/memory/lancedb-pro", | CODE |
| LOW | openclaw.plugin.json | 2289 | "placeholder": "anthropic/claude-sonnet-4-6", | CODE |
| LOW | openclaw.plugin.json | 2406 | "placeholder": "30000", | CODE |
| LOW | openclaw.plugin.json | 2445 | "placeholder": "0 3 * * *", | CODE |
| LOW | openclaw.plugin.json | 2450 | "placeholder": "anthropic/claude-sonnet-4-6", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | index.ts | 2321 | export function _getRegisteredApisForTest(): Map<OpenClawPluginApi, boolean> { | COMMENT |
| LOW | index.ts | 2961 | register(api: OpenClawPluginApi) { | COMMENT |
| LOW | index.ts | 3301 | reflectionByAgentCache.set(cacheKey, next); | COMMENT |
| LOW | index.ts | 3601 | COMMENT | |
| LOW | index.ts | 4101 | // remember command. The pending-ingress queue is deliberately NOT | COMMENT |
| LOW | index.ts | 4481 | // known; the builder's no-correlation fallback would re-tag them | COMMENT |
| LOW | index.ts | 4521 | } | COMMENT |
| LOW | index.ts | 4801 | // every upstream selector (session compression and the embedding | COMMENT |
| LOW | index.ts | 4821 | // flow (prepended referent) bypasses the prepend for its own | COMMENT |
| LOW | index.ts | 4841 | ? finalConversationTurns | COMMENT |
| LOW | index.ts | 4861 | // an enabled-era run possibly in flight) is bumped so that | COMMENT |
| LOW | index.ts | 4981 | // their counter is a pure accumulator of new texts toward | COMMENT |
| LOW | index.ts | 5041 | // Below-threshold turns are deferred, never handed to the raw | COMMENT |
| LOW | index.ts | 5341 | // registered hook like __lastRun rather than the package's export list: | COMMENT |
| LOW | .github/workflows/claude.yml | 41 | actions: read | COMMENT |
| LOW | src/corpus-indexer.ts | 581 | staleDeleted: 0, | COMMENT |
| LOW | src/auto-recall-tier1.ts | 1 | import type { SmartMemoryMetadata } from "./smart-metadata.ts"; | COMMENT |
| LOW | src/tools.ts | 1561 | action: "duplicate", | COMMENT |
| LOW | src/tools.ts | 1581 | // nothing and both plain-store, leaving two active rows for one | COMMENT |
| LOW | src/manual-echo-guard.ts | 261 | // whole tokens. A raw substring test would accept "has a cat" inside "has | COMMENT |
| LOW | src/consolidate.ts | 801 | // primitive applySupersedeVerdict uses (invalidated_at + superseded_by + | COMMENT |
| LOW | src/consolidate.ts | 1221 | // pre-sorted candidate array makes both which rows end up in the same | COMMENT |
| LOW | src/reflection-store.ts | 541 | // below, which now requires an exact owner match (no more universal main fallback) | COMMENT |
| LOW | src/store.ts | 161 | // @lancedb/lancedb's napi-rs loader (dist/native.js) detects musl via | COMMENT |
| LOW | src/store.ts | 1301 | COMMENT | |
| LOW | src/store.ts | 1441 | // 等 flushLock 釋放(即上一個 doFlush 完成後) | COMMENT |
| LOW | src/store.ts | 1681 | // 【MR4 fix】設定 destroyed flag,阻止後續 bulkStore() 呼叫 | COMMENT |
| LOW | src/store.ts | 3221 | // A systemic failure (version refresh unavailable, lock unacquirable, | COMMENT |
| LOW | src/store.ts | 3641 | .map((scope) => `scope = '${escapeSqlLiteral(scope)}'`) | COMMENT |
| LOW | src/smart-extractor.ts | 861 | } catch (err) { | COMMENT |
| LOW | src/smart-extractor.ts | 1841 | // Batch-level register signal, judged once per extraction. The model | COMMENT |
| LOW | src/smart-extractor.ts | 1881 | return !!cat && DURABLE_CATEGORIES.has(cat); | COMMENT |
| LOW | src/smart-extractor.ts | 2141 | this.debugLog( | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/memory-upgrader.ts | 494 | // Step 1: Reverse-map category | COMMENT |
| LOW⚡ | src/memory-upgrader.ts | 497 | // Step 2: Generate L0/L1/L2 | COMMENT |
| LOW | src/memory-upgrader.ts | 546 | // Step 3: Build enriched metadata | COMMENT |
| LOW | src/smart-extractor.ts | 725 | // Step 1: LLM extraction | COMMENT |
| LOW | src/smart-extractor.ts | 815 | // Step 2: Process each surviving candidate through dedup pipeline. | COMMENT |
| LOW | src/smart-extractor.ts | 1733 | // Step 1: LLM Extraction | COMMENT |
| LOW | src/smart-extractor.ts | 2272 | // Step 2: Dedup + Persist | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | src/memory-upgrader.ts | 494 | // Step 1: Reverse-map category | COMMENT |
| LOW⚡ | src/memory-upgrader.ts | 497 | // Step 2: Generate L0/L1/L2 | COMMENT |
| LOW | src/memory-upgrader.ts | 546 | // Step 3: Build enriched metadata | COMMENT |
| LOW | src/smart-extractor.ts | 725 | // Step 1: LLM extraction | COMMENT |
| LOW | src/smart-extractor.ts | 815 | // Step 2: Process each surviving candidate through dedup pipeline. | COMMENT |
| LOW | src/smart-extractor.ts | 1733 | // Step 1: LLM Extraction | COMMENT |
| LOW | src/smart-extractor.ts | 2272 | // Step 2: Dedup + Persist | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | scripts/jsonl_distill.py | 436 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | cli.ts | 971 | // ── Deduplication check (scope-aware exact match) ─────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/jsonl_distill.py | 312 | except Exception: | CODE |
| LOW | scripts/jsonl_distill.py | 436 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/jsonl_distill.py | 17 | CODE | |
| LOW | scripts/jsonl_distill.py | 24 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/jsonl_distill.py | 98 | CODE |