Contents
Installing pgmnemo
Compatibility
PostgreSQL
| Version | Status |
|---|---|
| PostgreSQL 17 | Supported — CI-tested on every merge |
| PostgreSQL 14, 15, 16 | Best-effort — untested in CI; known runtime issues on 14/15 fixed in v0.2.0.1 (see Troubleshooting) |
| PostgreSQL 13 and older | Not supported — generated columns (GENERATED ALWAYS AS … STORED) require PG 12+; HNSW requires pgvector ≥ 0.7.0 which requires PG 12+ |
pgvector
| Version | Status |
|---|---|
| ≥ 0.7.0 | Required — HNSW index support added in 0.7.0 |
| 0.5.x, 0.6.x | Not supported — extension will install but CREATE INDEX … USING hnsw fails |
Prerequisites
# Debian/Ubuntu — install PostgreSQL 17 + pgvector together
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
> /etc/apt/sources.list.d/pgdg.list'
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
sudo apt-get update
sudo apt-get install -y postgresql-17 postgresql-17-pgvector postgresql-server-dev-17 build-essential
# macOS (Homebrew)
brew install postgresql@17 pgvector
# From pgvector source (any platform)
git clone https://github.com/pgvector/pgvector.git
cd pgvector && make && sudo make install
Verify pgvector version before proceeding:
SELECT extversion FROM pg_extension WHERE extname = 'vector';
-- must be >= 0.7.0
Build and install
git clone https://github.com/pgmnemo/pgmnemo.git
cd pgmnemo/extension
# Build (pg_config must point to your target PostgreSQL)
make
# Install extension files into PostgreSQL's extension directory
sudo make install
# Verify files are in place
ls $(pg_config --sharedir)/extension/pgmnemo*
Fresh install (any supported version of PostgreSQL)
Connect to the target database as a superuser or a role with CREATE EXTENSION privilege:
-- Installs pgvector (vector) automatically if not present
CREATE EXTENSION pgmnemo CASCADE;
-- Verify
SELECT pgmnemo.version();
-- returns: 0.2.1
CASCADE handles the vector dependency. If you prefer explicit control:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION pgmnemo;
Configuration GUCs
Set in postgresql.conf, via ALTER SYSTEM, or per-session with SET.
| GUC | Type | Default | Valid range / values | Effect |
|---|---|---|---|---|
pgmnemo.gate_strict |
TEXT | enforce |
enforce | warn | off |
Provenance gate on INSERT |
pgmnemo.include_unverified |
BOOL | false |
true | false |
Include ghost lessons in recall_lessons() |
pgmnemo.recency_weight |
FLOAT | 0.08 |
0.0–1.0 |
Recency decay weight (γ) in scoring formula |
pgmnemo.ef_search |
INT | 100 |
10–500 |
HNSW ef_search applied via SET LOCAL per query |
pgmnemo.graph_proximity_weight |
FLOAT | 0.2 |
0.0–0.5 |
Graph-proximity weight (δ) in scoring formula |
pgmnemo.tenant_id |
TEXT | '' (empty) |
any project_id as text | Multi-tenant row isolation; empty = bypass |
Gate modes (pgmnemo.gate_strict):
enforce— INSERT raises an error when neithercommit_shanorartifact_hashis supplied (production default)warn— INSERT succeeds but emits aWARNING;verified_atremainsNULL(development / backfill)off— gate disabled; all inserts pass through unchecked
Typical setup after install:
-- Apply persistent GUC defaults
ALTER SYSTEM SET pgmnemo.ef_search = '100';
ALTER SYSTEM SET pgmnemo.recency_weight = '0.08';
ALTER SYSTEM SET pgmnemo.gate_strict = 'enforce';
SELECT pg_reload_conf();
-- During a bulk backfill: temporarily relax the gate
SET pgmnemo.gate_strict = 'warn';
-- ... INSERT rows ...
RESET pgmnemo.gate_strict;
Upgrade paths
PostgreSQL resolves the upgrade chain automatically from the installed migration scripts. Run:
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1';
This works from any installed version listed below. PostgreSQL chains through intermediate scripts automatically (e.g., 0.1.2 → 0.1.3 → 0.1.4 → … → 0.2.1).
Complete upgrade chain
0.0.1 → 0.1.0 → 0.1.1 → 0.1.2 → 0.1.3 → 0.1.4 ─┬─→ 0.1.4.1 ─→ 0.2.0 ─→ 0.2.0.1 → 0.2.1
│
└──────────────→ 0.2.0 (shortcut)
Shortcut paths
| From | To | Note |
|---|---|---|
| 0.1.4 | 0.2.0 | pgmnemo--0.1.4--0.2.0.sql available — skip 0.1.4.1 |
| 0.1.4.1 | 0.2.0 | pgmnemo--0.1.4.1--0.2.0.sql available |
| 0.2.0 | 0.2.1 | must pass through 0.2.0.1 (pgmnemo--0.2.0--0.2.0.1.sql + pgmnemo--0.2.0.1--0.2.1.sql) |
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1' resolves all shortcut paths automatically.
Per-version upgrade notes
0.0.1 → 0.1.0
ALTER EXTENSION pgmnemo UPDATE TO '0.1.0';
Adds: HNSW index (replaces IVFFlat), pgmnemo.ingest(), recall_lessons() with hybrid scoring.
0.1.0 → 0.1.1
ALTER EXTENSION pgmnemo UPDATE TO '0.1.1';
Adds: pgmnemo.recency_weight GUC.
Post-upgrade optional:
ALTER SYSTEM SET pgmnemo.recency_weight = '0.08';
SELECT pg_reload_conf();
0.1.1 → 0.1.2
ALTER EXTENSION pgmnemo UPDATE TO '0.1.2';
Adds: prov_strength tri-state column, recall_lessons_pooled().
0.1.2 → 0.1.3
ALTER EXTENSION pgmnemo UPDATE TO '0.1.3';
Adds: verifier_role TEXT column on agent_lesson.
0.1.3 → 0.1.4
ALTER EXTENSION pgmnemo UPDATE TO '0.1.4';
Adds: lifecycle state machine (state, state_changed_at, transition_lesson()), provenance FK columns (source_run_id, source_task_id), TTL (expires_at, evict_expired_lessons()).
No data migration required. New columns are nullable or have defaults.
0.1.4 → 0.1.4.1
ALTER EXTENSION pgmnemo UPDATE TO '0.1.4.1';
P0 fix (INS-029): recall_lessons() raised ERROR: parameter name "role" used more than once on every call. If you are on 0.1.4, apply this immediately — recall_lessons() is broken at 0.1.4.
Also: idempotent upgrade DDL guards added throughout.
0.1.4.1 → 0.2.0 (or 0.1.4 → 0.2.0 shortcut)
ALTER EXTENSION pgmnemo UPDATE TO '0.2.0';
Adds: pgmnemo.mem_edge table (directed typed edges), traverse_causal_chain(), traverse_temporal_window(), graph-proximity mixin in recall_lessons() scoring.
New GUC:
ALTER SYSTEM SET pgmnemo.graph_proximity_weight = '0.2';
SELECT pg_reload_conf();
0.2.0 → 0.2.0.1
ALTER EXTENSION pgmnemo UPDATE TO '0.2.0.1';
Hotfix (INS-030): fixes NUMERIC → DOUBLE PRECISION cast error in traverse_temporal_window() that caused runtime failures on PostgreSQL 14/15. Version bump only — no schema changes. Apply before upgrading to 0.2.1.
0.2.0.1 → 0.2.1
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1';
Adds: pgmnemo.tenant_id GUC for row-level security, pgmnemo.ef_search GUC, traverse_causal_chain(direction) parameter. Fixes project_id param collision in recall_lessons(). Lowers recency_weight default from 0.20 to 0.08.
Post-upgrade required actions:
ALTER SYSTEM SET pgmnemo.ef_search = '100';
ALTER SYSTEM SET pgmnemo.recency_weight = '0.08'; -- or keep 0.20 if you prefer old behaviour
SELECT pg_reload_conf();
Verify current version after upgrade
SELECT pgmnemo.version();
Check available upgrade paths (before running)
SELECT name, installed_version, default_version
FROM pg_available_extensions
WHERE name = 'pgmnemo';
-- List all registered migration scripts PostgreSQL knows about
SELECT name, installed_version, default_version
FROM pg_available_extension_versions
WHERE name = 'pgmnemo'
ORDER BY installed_version;
Rollback limitations
There are no downgrade scripts. pgmnemo does not ship pgmnemo--0.2.1--0.1.x.sql files.
| Scenario | Recovery path |
|---|---|
| Upgrade fails mid-script (DDL error) | Run ALTER EXTENSION pgmnemo UPDATE TO '<target>' again — all DDL is idempotent (CREATE OR REPLACE, ADD COLUMN IF NOT EXISTS, CREATE INDEX IF NOT EXISTS). The re-run will skip already-applied changes and complete the remaining steps. |
| Upgrade succeeds but new behaviour is wrong | Roll back to a pre-upgrade PostgreSQL base backup (pg_basebackup / snapshot). No SQL-level downgrade path exists. |
| Data written under new schema must be preserved | Export with pg_dump, restore to old version database, migrate data manually. |
| Emergency: revert to 0.1.4.1 after 0.2.1 upgrade | Not possible via SQL. Requires restoring from backup taken before the upgrade. |
Backup recommendation: always take a pg_dump of the target database before applying any ALTER EXTENSION pgmnemo UPDATE.
pg_dump -Fc -f pgmnemo_pre_upgrade_$(date +%Y%m%d).dump <dbname>
Troubleshooting
ERROR: type "vector" does not exist
pgvector is not installed. Install it and retry:
CREATE EXTENSION IF NOT EXISTS vector;
-- then retry:
CREATE EXTENSION pgmnemo;
-- or:
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1';
ERROR: index method "hnsw" does not exist
Your pgvector is older than 0.7.0. HNSW was added in 0.7.0.
SELECT extversion FROM pg_extension WHERE extname = 'vector';
-- if < 0.7.0: upgrade pgvector, then retry
ERROR: embedding dimension mismatch — expected 1024, got N
pgmnemo.ingest() requires 1024-dimensional vectors. Either use a 1024-dim embedder (e.g., BAAI/bge-m3) or omit p_embedding to store the lesson text-only (full-text search still works without a vector).
ERROR: pgmnemo provenance gate [enforce]: INSERT rejected
pgmnemo.gate_strict = 'enforce' (default). Supply p_commit_sha or p_artifact_hash to pgmnemo.ingest(), or relax during development:
SET pgmnemo.gate_strict = 'warn';
ERROR: parameter name "role" used more than once (on 0.1.4)
This is INS-029, a P0 bug in v0.1.4. Upgrade immediately:
ALTER EXTENSION pgmnemo UPDATE TO '0.1.4.1';
-- or go straight to current:
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1';
ERROR: operator does not exist: numeric = double precision (PostgreSQL 14/15, on traverse_temporal_window)
This is INS-030, fixed in v0.2.0.1. Upgrade:
ALTER EXTENSION pgmnemo UPDATE TO '0.2.1';
ALTER EXTENSION pgmnemo UPDATE fails with could not find upgrade path
The extension files for intermediate versions are not installed in PostgreSQL’s sharedir. Re-run make install from the full pgmnemo source tree, which installs all migration scripts, then retry the ALTER EXTENSION command.
RLS blocks all rows after setting pgmnemo.tenant_id
If pgmnemo.tenant_id is set to a value that matches no project_id, all rows are hidden. Reset to empty to bypass:
SET pgmnemo.tenant_id = '';