Skip to content

consolidate on SQLite: four wiki passes fail on every run with 'SqliteMemoryStore' object has no attribute 'batch_pool', while status stays ok #636

Closed

Description

@BillOTheWild

Summary

On the SQLite backend, four maintenance passes run by consolidate fail on every run. All four access store.batch_pool, a psycopg_pool.ConnectionPool that only PgMemoryStore provides:

  • wiki_source_backfill_pass
  • wiki_domain_backfill_pass
  • wiki_citation_seed_pass
  • wiki_backlog_pass._lesson_promotion_backlog

consolidate still returns "status": "ok" and "failed_stages": []. On the default backend, these four features are off, and nothing says so.

This is the same family as #206 (wiki pipeline dead on SQLite) and #596 (procedural skills PostgreSQL-only): a PostgreSQL-only capability reached by attribute access on a store that does not have it.

Environment

OS Windows 11 Pro 26200
Python 3.13.4
Plugin hypermnesia-mcp@cortex-plugins 4.23.1, git 95f3bec
Backend SQLite (backend.json = {"backend": "sqlite"}), 87 memories, 6 wiki pages

Observed

consolidate output, 2026-09-22 (abridged; field names as returned):

"wiki": {
  "source_backfill": {"pages_scanned": 0, "primaries_written": 0,
    "status": "error: AttributeError: 'SqliteMemoryStore' object has no attribute 'batch_pool'"},
  "domain_backfill": {"pages_scanned": 0, "domains_reassigned": 0,
    "status": "error: AttributeError: 'SqliteMemoryStore' object has no attribute 'batch_pool'"},
  "citation_seed": {"scanned_rows": 0, "seeded": 0,
    "status": "error: AttributeError: 'SqliteMemoryStore' object has no attribute 'batch_pool'"},
  "lesson_promotion_backlog": null,
  "status": "ok"
},
"failed_stages": [],
"status": "ok"

The background run logs the same four failures in ~/.claude/methodology/consolidate.log, on every run:

wiki_source_backfill_pass failed (non-fatal): 'SqliteMemoryStore' object has no attribute 'batch_pool'
wiki_domain_backfill_pass failed (non-fatal): 'SqliteMemoryStore' object has no attribute 'batch_pool'
wiki_citation_seed_pass failed (non-fatal): 'SqliteMemoryStore' object has no attribute 'batch_pool'
wiki_backlog_pass.lesson_promotion_backlog failed (fallback active, this component is now degraded; ...): AttributeError: 'SqliteMemoryStore' object ...
[bg-consolidate] finished status=ok duration_ms=7853

Root cause

The passes state the requirement themselves. wiki_source_backfill_pass.py, for example:

Pre-condition:  ``store`` exposes ``batch_pool``
                (``psycopg_pool.ConnectionPool``) — the long-running
                writer pool, ...

wiki_domain_backfill_pass.py states the same precondition. wiki_maintenance.py then calls all of them unconditionally, whatever the store.

wiki_backlog_pass._lesson_promotion_backlog treats the case as test-only:

... when ``store`` lacks ``batch_pool`` (SQLite fallback in tests) ...

But SQLite is not a test fallback. It is the zero-config default for plugin installs.

Why the status stays ok

wiki_maintenance.py escalates out["status"] only when a pass raises:

except Exception as exc:
    ...
    out["source_backfill"] = {"status": f"error: ..."}
    if out["status"] == "ok":
        out["status"] = f"source_backfill_error: ..."

Here the passes catch the AttributeError internally and return a stanza with status: "error: ...". The outer escalation never fires, so wiki.status stays ok, and consolidate reports no failed stage.

Other call sites, by code inspection only (not run)

store.batch_pool.connection() is also used, unguarded, in:

  • memory_dedup_exact_pass, memory_domain_backfill_pass, memory_reheat_pass, near_dup_calibration_pass, write_class_backfill_pass, run through scripts/memory_dedup_exact.py, memory_domain_backfill.py, memory_reheat.py, near_dup_calibrate.py and backfill_write_class.py;
  • handlers/ingest_codebase.py (entity and edge sinks).

I expect these to fail the same way on SQLite. I have not run them.

Suggested fixes

  1. Declare the capability. embedding_upgrade.py already does this with _FallbackWorklistStore: a runtime_checkable Protocol, and an explicit {"reason": "store has no fallback worklist"} skip when the store lacks it. The same pattern here would turn a crash into a named skip.
  2. Give SQLite an implementation where the feature should exist. Source/domain backfill and citation seeding are wiki features. Since Wiki pipeline does not run on the SQLite backend: no wiki schema and no PsycopgCompatConnection.cursor() #206 the wiki runs on SQLite, so these passes presumably should too.
  3. Propagate returned errors. Escalate wiki.status (and failed_stages) when a pass returns an error: status, not only when it raises.
  4. Add a contract test. Run consolidate on a fresh SqliteMemoryStore built through the real composition root, and assert that no stanza status starts with error:. That single test would have caught this issue, Wiki pipeline does not run on the SQLite backend: no wiki schema and no PsycopgCompatConnection.cursor() #206 and [bug] procedural skills are PostgreSQL-only, so the default SQLite install stores none #596.
  5. Fix the docstring. _lesson_promotion_backlog calls SQLite a "fallback in tests", which is inaccurate.

Impact

On the default backend:

  • wiki pages never get documents_primary derived;
  • catch-all pages are never re-domained;
  • wiki.citations rows are never reconciled;
  • the lesson-promotion backlog is always null.

Every consolidate run costs a few log lines. And the ok status tells the user everything is healthy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions