@traqr/memory 0.2.35 → 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/migration-files.d.ts +18 -0
- package/dist/lib/migration-files.js +22 -0
- package/dist/lib/migration-files.js.map +1 -0
- package/dist/lib/migration-files.test.d.ts +11 -0
- package/dist/lib/migration-files.test.js +44 -0
- package/dist/lib/migration-files.test.js.map +1 -0
- package/dist/migrate.js +7 -4
- package/dist/migrate.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a migrations-directory listing into forward migrations (run in
|
|
3
|
+
* lexicographic order) and rollback scripts (manual recovery only, never
|
|
4
|
+
* auto-run).
|
|
5
|
+
*
|
|
6
|
+
* Rollback files MUST be excluded from the forward run: they sort AFTER
|
|
7
|
+
* their forward file (`011_memory_engine_v2_schema.sql` < `011_rollback.sql`),
|
|
8
|
+
* so a naive `*.sql` glob on a fresh database applies a migration and then
|
|
9
|
+
* immediately reverts it — and against an already-provisioned database whose
|
|
10
|
+
* tracking table is missing rows, the very first "unapplied" file the runner
|
|
11
|
+
* would execute is `011_rollback.sql`, which drops the live v2 schema
|
|
12
|
+
* (search_memories and friends). Caught 2026-07-02 during the
|
|
13
|
+
* `_traqr_migrations` ledger reconcile.
|
|
14
|
+
*/
|
|
15
|
+
export declare function selectForwardMigrations(files: string[]): {
|
|
16
|
+
forward: string[];
|
|
17
|
+
rollbacks: string[];
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a migrations-directory listing into forward migrations (run in
|
|
3
|
+
* lexicographic order) and rollback scripts (manual recovery only, never
|
|
4
|
+
* auto-run).
|
|
5
|
+
*
|
|
6
|
+
* Rollback files MUST be excluded from the forward run: they sort AFTER
|
|
7
|
+
* their forward file (`011_memory_engine_v2_schema.sql` < `011_rollback.sql`),
|
|
8
|
+
* so a naive `*.sql` glob on a fresh database applies a migration and then
|
|
9
|
+
* immediately reverts it — and against an already-provisioned database whose
|
|
10
|
+
* tracking table is missing rows, the very first "unapplied" file the runner
|
|
11
|
+
* would execute is `011_rollback.sql`, which drops the live v2 schema
|
|
12
|
+
* (search_memories and friends). Caught 2026-07-02 during the
|
|
13
|
+
* `_traqr_migrations` ledger reconcile.
|
|
14
|
+
*/
|
|
15
|
+
export function selectForwardMigrations(files) {
|
|
16
|
+
const sql = files.filter(f => f.endsWith('.sql')).sort();
|
|
17
|
+
return {
|
|
18
|
+
forward: sql.filter(f => !f.endsWith('_rollback.sql')),
|
|
19
|
+
rollbacks: sql.filter(f => f.endsWith('_rollback.sql')),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=migration-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-files.js","sourceRoot":"","sources":["../../src/lib/migration-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAe;IAIrD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACxD,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACtD,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;KACxD,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* migration-files — the forward/rollback split the migration runner relies on.
|
|
3
|
+
*
|
|
4
|
+
* The hazard this guards (2026-07-02 ledger-reconcile finding): rollback
|
|
5
|
+
* files sort after their forward migration, so a naive `*.sql` glob would
|
|
6
|
+
* run `011_rollback.sql` as a "pending migration" — against the live DB that
|
|
7
|
+
* drops search_memories and the whole v2 function set.
|
|
8
|
+
*
|
|
9
|
+
* Run: npx tsx packages/memory/src/lib/migration-files.test.ts
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* migration-files — the forward/rollback split the migration runner relies on.
|
|
3
|
+
*
|
|
4
|
+
* The hazard this guards (2026-07-02 ledger-reconcile finding): rollback
|
|
5
|
+
* files sort after their forward migration, so a naive `*.sql` glob would
|
|
6
|
+
* run `011_rollback.sql` as a "pending migration" — against the live DB that
|
|
7
|
+
* drops search_memories and the whole v2 function set.
|
|
8
|
+
*
|
|
9
|
+
* Run: npx tsx packages/memory/src/lib/migration-files.test.ts
|
|
10
|
+
*/
|
|
11
|
+
import { selectForwardMigrations } from './migration-files.js';
|
|
12
|
+
let passed = 0;
|
|
13
|
+
let failed = 0;
|
|
14
|
+
function assert(label, condition) {
|
|
15
|
+
if (condition) {
|
|
16
|
+
console.log(` PASS ${label}`);
|
|
17
|
+
passed++;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.log(` FAIL ${label}`);
|
|
21
|
+
failed++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// The real directory shape at the time of the incident.
|
|
25
|
+
const listing = [
|
|
26
|
+
'011_memory_engine_v2_schema.sql',
|
|
27
|
+
'011_rollback.sql',
|
|
28
|
+
'015_archival_protected_tag_guard.sql',
|
|
29
|
+
'015_optimize_find_duplicate_memory_pairs.sql',
|
|
30
|
+
'015_rollback.sql',
|
|
31
|
+
'018_search_memories_compute_once.sql',
|
|
32
|
+
'README.md',
|
|
33
|
+
];
|
|
34
|
+
const { forward, rollbacks } = selectForwardMigrations(listing);
|
|
35
|
+
assert('rollback files are excluded from the forward run', !forward.some(f => f.endsWith('_rollback.sql')));
|
|
36
|
+
assert('both rollback files are reported for visibility', rollbacks.length === 2 && rollbacks.includes('011_rollback.sql') && rollbacks.includes('015_rollback.sql'));
|
|
37
|
+
assert('all forward migrations survive the split', forward.length === 4);
|
|
38
|
+
assert('non-sql files are ignored entirely', !forward.includes('README.md') && !rollbacks.includes('README.md'));
|
|
39
|
+
assert('forward order is lexicographic even from an unsorted listing', selectForwardMigrations([...listing].reverse()).forward.join(',') === forward.join(','));
|
|
40
|
+
assert('a lone rollback file never becomes a forward migration', selectForwardMigrations(['023_rollback.sql']).forward.length === 0);
|
|
41
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
42
|
+
if (failed > 0)
|
|
43
|
+
process.exit(1);
|
|
44
|
+
//# sourceMappingURL=migration-files.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-files.test.js","sourceRoot":"","sources":["../../src/lib/migration-files.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,IAAI,MAAM,GAAG,CAAC,CAAA;AACd,IAAI,MAAM,GAAG,CAAC,CAAA;AAEd,SAAS,MAAM,CAAC,KAAa,EAAE,SAAkB;IAC/C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAA;QAC/B,MAAM,EAAE,CAAA;IACV,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAA;QAC/B,MAAM,EAAE,CAAA;IACV,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,MAAM,OAAO,GAAG;IACd,iCAAiC;IACjC,kBAAkB;IAClB,sCAAsC;IACtC,8CAA8C;IAC9C,kBAAkB;IAClB,sCAAsC;IACtC,WAAW;CACZ,CAAA;AAED,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAE/D,MAAM,CAAC,kDAAkD,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;AAC3G,MAAM,CAAC,iDAAiD,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAA;AACrK,MAAM,CAAC,0CAA0C,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAA;AACxE,MAAM,CAAC,oCAAoC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAA;AAChH,MAAM,CACJ,8DAA8D,EAC9D,uBAAuB,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CACxF,CAAA;AACD,MAAM,CAAC,wDAAwD,EAAE,uBAAuB,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAA;AAEpI,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,YAAY,MAAM,SAAS,CAAC,CAAA;AACnD,IAAI,MAAM,GAAG,CAAC;IAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA"}
|
package/dist/migrate.js
CHANGED
|
@@ -18,6 +18,7 @@ import { createClient } from '@supabase/supabase-js';
|
|
|
18
18
|
import { readFileSync, readdirSync } from 'fs';
|
|
19
19
|
import { join, dirname } from 'path';
|
|
20
20
|
import { fileURLToPath } from 'url';
|
|
21
|
+
import { selectForwardMigrations } from './lib/migration-files.js';
|
|
21
22
|
const MIGRATIONS_TABLE = '_traqr_migrations';
|
|
22
23
|
async function migrate() {
|
|
23
24
|
const supabaseUrl = process.env.SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
@@ -42,12 +43,14 @@ async function migrate() {
|
|
|
42
43
|
console.warn(`exec_sql RPC unavailable (${error.message}) — assuming ${MIGRATIONS_TABLE} already exists`);
|
|
43
44
|
}
|
|
44
45
|
});
|
|
45
|
-
// Find migration files
|
|
46
|
+
// Find migration files. Rollback scripts are manual-recovery tools and
|
|
47
|
+
// must never run as forward migrations — see selectForwardMigrations.
|
|
46
48
|
const migrationsDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'migrations');
|
|
47
|
-
const files = readdirSync(migrationsDir)
|
|
48
|
-
.filter(f => f.endsWith('.sql'))
|
|
49
|
-
.sort();
|
|
49
|
+
const { forward: files, rollbacks } = selectForwardMigrations(readdirSync(migrationsDir));
|
|
50
50
|
console.log(`Found ${files.length} migration files`);
|
|
51
|
+
if (rollbacks.length > 0) {
|
|
52
|
+
console.log(`Ignoring ${rollbacks.length} rollback script(s): ${rollbacks.join(', ')}`);
|
|
53
|
+
}
|
|
51
54
|
// Check which have been applied. An unreadable tracking table must be
|
|
52
55
|
// fatal: treating it as "nothing applied" would re-run every migration.
|
|
53
56
|
const { data: applied, error: trackingError } = await client
|
package/dist/migrate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,IAAI,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@traqr/memory",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.36",
|
|
4
4
|
"description": "Persistent memory for AI agents. Multi-strategy retrieval (semantic + BM25 + RRF), 3-zone cosine triage, type-aware lifecycle, entity canonicalization. Postgres + pgvector.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"dev": "tsc --watch",
|
|
18
|
-
"test": "tsx src/lib/quality-gate.test.ts && tsx src/lib/retrieval.test.ts && tsx src/lib/classification-ceiling.test.ts && tsx src/lib/classification-enforcement.integration.test.ts && tsx src/vectordb/converters.test.ts && tsx src/lib/context.test.ts && tsx src/lib/pii-detection.test.ts && tsx src/lib/health.test.ts && tsx src/lib/stdout-hygiene.test.ts",
|
|
18
|
+
"test": "tsx src/lib/quality-gate.test.ts && tsx src/lib/retrieval.test.ts && tsx src/lib/classification-ceiling.test.ts && tsx src/lib/classification-enforcement.integration.test.ts && tsx src/vectordb/converters.test.ts && tsx src/lib/context.test.ts && tsx src/lib/pii-detection.test.ts && tsx src/lib/health.test.ts && tsx src/lib/stdout-hygiene.test.ts && tsx src/lib/migration-files.test.ts",
|
|
19
19
|
"migrate": "tsx src/migrate.ts"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|