Summary
scripts/codelens.py:977 calls pr.store_scan_result(result) after every successful scan, but PersistentRegistry (in scripts/persistent_registry.py) does not define this method. The resulting AttributeError is swallowed by a bare except Exception, so the failure is silent.
Evidence
scripts/codelens.py (post-scan block, ~L971-983):
from persistent_registry import PersistentRegistry, is_sqlite_available
if is_sqlite_available():
pr = PersistentRegistry(workspace, db_path=getattr(args,'db_path',None))
pr.store_scan_result(result) # <- method does not exist
result["sqlite_persisted"] = True # <- never reached
scripts/persistent_registry.py only defines:
store_frontend_registry(self, registry_data) (L658)
store_backend_registry(self, registry_data) (L670)
There is no store_scan_result method on the class.
Impact
- The
analysis_cache SQLite table — designed (per the module docstring at persistent_registry.py:11-16) to cache command results keyed by (command, file_set_hash) — is never populated by scan results.
- The user-facing success message
"[CodeLens] Scan results persisted to SQLite database." (L979) is never printed.
- The
result["sqlite_persisted"] = True flag is never set, so downstream code/MCP clients that read this flag receive stale/missing data.
- The bug is invisible — the surrounding
except Exception as e: logging.warning(...) swallows the AttributeError. No CI test catches it because no test asserts result["sqlite_persisted"] == True or queries analysis_cache after scan.
Repro
python3 scripts/codelens.py init /tmp/demo && \
python3 scripts/codelens.py scan /tmp/demo && \
sqlite3 /tmp/demo/.codelens/codelens.db "SELECT COUNT(*) FROM analysis_cache;"
# Expected (per design): >=1 row for the scan command
# Actual: 0 rows
Suggested fix
Either:
- (A) Implement
PersistentRegistry.store_scan_result(self, result: Dict[str, Any]) -> None that persists a normalized subset of the scan result into analysis_cache (keyed by command="scan", file_set_hash derived from scanned file paths).
- (B) If persisting the full scan result is not intended, delete the call and the dead
result["sqlite_persisted"] assignment + success message — and update the persistent_registry.py module docstring to reflect the actual contract.
Either way, add a regression test that:
- Runs
scan on a fixture workspace.
- Asserts
result.get("sqlite_persisted") is True (option A) OR asserts the call site no longer references the method (option B).
- Asserts no warning is logged by the post-scan SQLite block.
Files
scripts/codelens.py (~L971-983)
scripts/persistent_registry.py (needs new method, or docstring fix)
tests/test_persistent_registry.py (new test)
Summary
scripts/codelens.py:977callspr.store_scan_result(result)after every successfulscan, butPersistentRegistry(inscripts/persistent_registry.py) does not define this method. The resultingAttributeErroris swallowed by a bareexcept Exception, so the failure is silent.Evidence
scripts/codelens.py(post-scan block, ~L971-983):scripts/persistent_registry.pyonly defines:store_frontend_registry(self, registry_data)(L658)store_backend_registry(self, registry_data)(L670)There is no
store_scan_resultmethod on the class.Impact
analysis_cacheSQLite table — designed (per the module docstring atpersistent_registry.py:11-16) to cache command results keyed by(command, file_set_hash)— is never populated by scan results."[CodeLens] Scan results persisted to SQLite database."(L979) is never printed.result["sqlite_persisted"] = Trueflag is never set, so downstream code/MCP clients that read this flag receive stale/missing data.except Exception as e: logging.warning(...)swallows theAttributeError. No CI test catches it because no test assertsresult["sqlite_persisted"] == Trueor queriesanalysis_cacheafter scan.Repro
Suggested fix
Either:
PersistentRegistry.store_scan_result(self, result: Dict[str, Any]) -> Nonethat persists a normalized subset of the scan result intoanalysis_cache(keyed bycommand="scan",file_set_hashderived from scanned file paths).result["sqlite_persisted"]assignment + success message — and update thepersistent_registry.pymodule docstring to reflect the actual contract.Either way, add a regression test that:
scanon a fixture workspace.result.get("sqlite_persisted") is True(option A) OR asserts the call site no longer references the method (option B).Files
scripts/codelens.py(~L971-983)scripts/persistent_registry.py(needs new method, or docstring fix)tests/test_persistent_registry.py(new test)