Skip to content

MPEdb becomes the store, and the graph becomes tables SQL can ask - #28

Merged
punnerud merged 2 commits into
mainfrom
feat/mpedb-store
Aug 12, 2026
Merged

MPEdb becomes the store, and the graph becomes tables SQL can ask#28
punnerud merged 2 commits into
mainfrom
feat/mpedb-store

Conversation

@punnerud

Copy link
Copy Markdown
Owner

Phase 3 of the approved plan.

The engine swap

mpedb speaks the sqlite3 DB-API and opens existing embeddings.db files in place — no migration, verified by test. The swap changed an import and nothing a caller can see. Four real differences surfaced, each pinned:

difference fix
PRAGMA table_info answers with nothing cursor.description, the portable way
lastrowid is None on file databases (in-memory reports it fine — which is how it hid from every probe) INSERT ... RETURNING id, answered by both
ADD COLUMN does not backfill the DEFAULT into existing rows explicit UPDATE per migration
BY refused as a column name; ambiguous join columns refused renamed / qualified — the second refusal is better than sqlite's silence

The graph as tables

GraphDB records what the RDF serialises — runs, steps, edges, facts, findings, votes, agreement — per session, from the same job events by the same extraction. ":memory:" gives the identical schema for single-run analysis. Recording is idempotent per job id and never breaks a delivered answer.

GET /sessions now carries the graph's numbers per session: runs, agreed runs, exact facts. Canned queries only — no raw SQL over HTTP.

Verified live against qwen3

reason  done: 42.5                                  rdf valid, 44 triples
settle  done: There are 20,160 minutes in a fortnight.   rdf valid, 162 triples
session stats: {'runs': 2, 'agreed': 1, 'exact_facts': 7}

One near-miss caught during testing: the sessions endpoint recorded into the repository root until the fixtures set GRAPH_DB_PATH — the stray-file mistake this project has already committed once, now also gitignored.

8 new tests, 415 in all.

The engine swap first. mpedb speaks the sqlite3 DB-API and opens this project's
existing embeddings.db files in place, so the swap changed an import and nothing
a caller can see -- but four real differences surfaced on the way, each now
pinned by a test or a comment at the site:

* PRAGMA table_info answers with nothing, so the migration re-added existing
  columns. cursor.description is the portable way to ask.
* lastrowid is None on FILE databases while the in-memory engine reports it
  fine, which is how it hid from every probe. INSERT ... RETURNING id is
  answered by both.
* ALTER TABLE ADD COLUMN does not backfill the DEFAULT into existing rows the
  way sqlite3 does, so every pre-migration row silently vanished from queries
  filtering on the new column. Each ADD COLUMN now carries an explicit UPDATE.
* BY is a reserved word its parser refuses as a column name, and it refuses
  ambiguous unqualified columns in joins -- both stricter than sqlite3, the
  second one better.

Then the tables. GraphDB records what the RDF serialises -- runs, steps, edges,
facts, findings, votes, agreement -- per session, from the same job events by
the same extraction. ":memory:" gives the identical schema for single-run
analysis. Recording happens when a job finishes, is idempotent per job id, and
failures log rather than break: the answer has already been delivered, and
bookkeeping must not cost it.

The sessions listing now carries what the graph knows: runs, agreed runs and
exact facts per session, from canned queries. No raw SQL over HTTP.

Verified live through the job API against qwen3: a reason run and a settle run,
both correct, RDF valid with the session literal, and the tables answering
"what did this session do" in SQL: 2 runs, 1 agreed, 7 exact facts.

One near-miss caught by its own test run: the sessions endpoint recorded into
the repository root until the fixtures set GRAPH_DB_PATH -- the stray-file
mistake this project has already committed once, now also in .gitignore.

8 tests here, 415 in all.
The previous commit's pyproject edit silently failed to apply -- its replace
target matched a comment that had since been rewritten -- and the local venv hid
it, because mpedb had been installed there by hand. Every CI job failed on
ModuleNotFoundError within a minute, which is the system working.
@punnerud
punnerud merged commit d657b44 into main Aug 12, 2026
6 checks passed
@punnerud
punnerud deleted the feat/mpedb-store branch August 12, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant