@traqr/memory 0.2.20 → 0.2.22

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/index.d.ts CHANGED
@@ -6,6 +6,8 @@
6
6
  */
7
7
  export { createMemoryServer } from './server.js';
8
8
  export { getVectorDB, resetVectorDB } from './vectordb/index.js';
9
+ export { checkDbHealth } from './lib/health.js';
10
+ export type { DbHealthResult } from './lib/health.js';
9
11
  export type { VectorDBProvider, Memory, MemoryInput, MemorySearchResult, MemoryUpdate, MemoryExport, MemoryDomain, SearchOptions, MemoryCategory, MemorySourceType, MemoryDurability, MemoryType, MemoryClassification, MemoryAccessLevel, MemoryRetentionPolicy, BM25SearchResult, TemporalSearchResult, GraphSearchResult, BrowseResult, ProviderConfig, } from './vectordb/types.js';
10
12
  export { BOOTSTRAP_CONFIDENCE, DECAY_CONFIG, ACCESS_LEVEL_MAX_CLASSIFICATION, CLASSIFICATION_RANK } from './vectordb/types.js';
11
13
  export { deriveAll, deriveDomain, deriveCategory, deriveTopic, deriveSummary, deriveTags, deriveMemoryType, deriveForgetAfter, extractEntityCandidates, } from './lib/auto-derive.js';
package/dist/index.js CHANGED
@@ -8,6 +8,8 @@
8
8
  export { createMemoryServer } from './server.js';
9
9
  // VectorDB layer
10
10
  export { getVectorDB, resetVectorDB } from './vectordb/index.js';
11
+ // Liveness health probe (bounded DB ping for HTTP /health endpoints)
12
+ export { checkDbHealth } from './lib/health.js';
11
13
  export { BOOTSTRAP_CONFIDENCE, DECAY_CONFIG, ACCESS_LEVEL_MAX_CLASSIFICATION, CLASSIFICATION_RANK } from './vectordb/types.js';
12
14
  // Auto-derive v2
13
15
  export { deriveAll, deriveDomain, deriveCategory, deriveTopic, deriveSummary, deriveTags, deriveMemoryType, deriveForgetAfter, extractEntityCandidates, } from './lib/auto-derive.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAuBhE,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAE9H,iBAAiB;AACjB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AAG7B,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAGxD,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9C,+BAA+B;AAC/B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,MAAM,EACN,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AAExB,sBAAsB;AACtB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAG3B,6BAA6B;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAcnE,gCAAgC;AAChC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,oBAAoB,CAAA;AAS3B,aAAa;AACb,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAG5B,aAAa;AACb,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAA;AAE5B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAG7I,kBAAkB;AAClB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAE1E,mBAAmB;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAGzD,qBAAqB;AACrB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEhE,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAwB/C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,+BAA+B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAE9H,iBAAiB;AACjB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AAG7B,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAGxD,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9C,+BAA+B;AAC/B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,MAAM,EACN,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AAExB,sBAAsB;AACtB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAG3B,6BAA6B;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAcnE,gCAAgC;AAChC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,oBAAoB,CAAA;AAS3B,aAAa;AACb,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAG5B,aAAa;AACb,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAA;AAE5B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAG7I,kBAAkB;AAClB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAE1E,mBAAmB;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAGzD,qBAAqB;AACrB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,EAC3B,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,6BAA6B,CAAA"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Liveness health probe for the memory DB.
3
+ *
4
+ * The HTTP `/health` endpoints must answer "can this service actually reach the
5
+ * DB it exists to serve?" — not "is the process up" or "are env vars set". A
6
+ * static `{status:'ok'}` false-passes a resource-starved DB (the 2026-06-14
7
+ * traqr-db starvation outage: every real query timed out for ~3h while the
8
+ * cheap probes stayed green — TD-862). Feature4 closed this at the raw-pg
9
+ * `ping()` level (#1974); this closes it at the HTTP layer the fleet polls.
10
+ *
11
+ * The probe is BOUNDED: under starvation the underlying `ping()` (a `LIMIT 1`
12
+ * read of the memories table) can block until the pg statement timeout (~25s
13
+ * observed). A health endpoint that hangs that long is itself a degraded
14
+ * signal, so we race the ping against a short budget and report `degraded`
15
+ * fast. The default (1800ms) sits below the only in-repo consumer's patience —
16
+ * the CLI `status` command aborts its fetch at 2000ms (status.ts pingEndpoint)
17
+ * — so the route's honest 503 wins the race and reaches the client.
18
+ *
19
+ * The `ping` fn is injected so this is pure/deterministic and unit-testable
20
+ * without a live DB (mirrors `timedSearch`'s injected-searcher convention).
21
+ */
22
+ export interface DbHealthResult {
23
+ status: 'healthy' | 'degraded';
24
+ db: 'ok' | 'unreachable';
25
+ }
26
+ export declare function checkDbHealth(ping: () => Promise<boolean>, timeoutMs?: number): Promise<DbHealthResult>;
27
+ /**
28
+ * HTTP status for a health result: 200 healthy, 503 degraded. Pulled out so the
29
+ * load-bearing "degraded must surface as 503, not 200" contract is unit-tested
30
+ * independent of a live DB / HTTP layer — a route silently regressing to 200
31
+ * would re-hide a starved DB, which is the exact 6/14 failure this fix targets.
32
+ */
33
+ export declare function healthStatusCode(result: DbHealthResult): 200 | 503;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Liveness health probe for the memory DB.
3
+ *
4
+ * The HTTP `/health` endpoints must answer "can this service actually reach the
5
+ * DB it exists to serve?" — not "is the process up" or "are env vars set". A
6
+ * static `{status:'ok'}` false-passes a resource-starved DB (the 2026-06-14
7
+ * traqr-db starvation outage: every real query timed out for ~3h while the
8
+ * cheap probes stayed green — TD-862). Feature4 closed this at the raw-pg
9
+ * `ping()` level (#1974); this closes it at the HTTP layer the fleet polls.
10
+ *
11
+ * The probe is BOUNDED: under starvation the underlying `ping()` (a `LIMIT 1`
12
+ * read of the memories table) can block until the pg statement timeout (~25s
13
+ * observed). A health endpoint that hangs that long is itself a degraded
14
+ * signal, so we race the ping against a short budget and report `degraded`
15
+ * fast. The default (1800ms) sits below the only in-repo consumer's patience —
16
+ * the CLI `status` command aborts its fetch at 2000ms (status.ts pingEndpoint)
17
+ * — so the route's honest 503 wins the race and reaches the client.
18
+ *
19
+ * The `ping` fn is injected so this is pure/deterministic and unit-testable
20
+ * without a live DB (mirrors `timedSearch`'s injected-searcher convention).
21
+ */
22
+ const TIMEOUT = Symbol('db-health-timeout');
23
+ export async function checkDbHealth(ping, timeoutMs = 1800) {
24
+ let timer;
25
+ try {
26
+ // Defer invocation so a SYNCHRONOUS throw from `ping` (e.g. getVectorDB()
27
+ // throwing on missing config) and an async rejection BOTH route into the
28
+ // .catch. The .catch stays attached regardless of who wins the race, so a
29
+ // late rejection (after the timeout already won) can never surface as an
30
+ // unhandled rejection. Probes fail honest as `degraded`, never silent.
31
+ const probe = Promise.resolve().then(ping).catch(() => false);
32
+ const timeout = new Promise((resolve) => {
33
+ timer = setTimeout(() => resolve(TIMEOUT), timeoutMs);
34
+ });
35
+ const result = await Promise.race([probe, timeout]);
36
+ return result === true
37
+ ? { status: 'healthy', db: 'ok' }
38
+ : { status: 'degraded', db: 'unreachable' };
39
+ }
40
+ finally {
41
+ if (timer)
42
+ clearTimeout(timer);
43
+ }
44
+ }
45
+ /**
46
+ * HTTP status for a health result: 200 healthy, 503 degraded. Pulled out so the
47
+ * load-bearing "degraded must surface as 503, not 200" contract is unit-tested
48
+ * independent of a live DB / HTTP layer — a route silently regressing to 200
49
+ * would re-hide a starved DB, which is the exact 6/14 failure this fix targets.
50
+ */
51
+ export function healthStatusCode(result) {
52
+ return result.status === 'healthy' ? 200 : 503;
53
+ }
54
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/lib/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAA4B,EAC5B,SAAS,GAAG,IAAI;IAEhB,IAAI,KAAgD,CAAA;IACpD,IAAI,CAAC;QACH,0EAA0E;QAC1E,yEAAyE;QACzE,0EAA0E;QAC1E,yEAAyE;QACzE,uEAAuE;QACvE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;QAC7D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,EAAE;YACtD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;QACnD,OAAO,MAAM,KAAK,IAAI;YACpB,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE;YACjC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,CAAA;IAC/C,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;AAChD,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Health — checkDbHealth liveness-probe tests (lying-probe class, TD-862 lineage).
3
+ *
4
+ * The HTTP `/health` endpoints (memory + combined server) returned a static
5
+ * `{status:'ok'}` based on nothing (memory) or on env-var presence (server) —
6
+ * so during the 2026-06-14 traqr-db starvation outage they reported green while
7
+ * the DB couldn't serve a `count(*)`. That's the same "SELECT-1 false-passes a
8
+ * sick DB" class Feature4 closed at the raw-pg ping() level (#1974), still open
9
+ * at the HTTP layer that `traqr status` + any monitor polls. checkDbHealth is
10
+ * the shared, bounded liveness primitive the routes call.
11
+ *
12
+ * Load-bearing case: a HANGING db (ping never resolves within the budget) must
13
+ * yield `degraded` FAST — not block the health endpoint for the pg statement
14
+ * timeout (~25s observed on 6/14). The ping fn is injected, so no live DB.
15
+ *
16
+ * Run: npx tsx packages/memory/src/lib/health.test.ts
17
+ */
18
+ export {};
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Health — checkDbHealth liveness-probe tests (lying-probe class, TD-862 lineage).
3
+ *
4
+ * The HTTP `/health` endpoints (memory + combined server) returned a static
5
+ * `{status:'ok'}` based on nothing (memory) or on env-var presence (server) —
6
+ * so during the 2026-06-14 traqr-db starvation outage they reported green while
7
+ * the DB couldn't serve a `count(*)`. That's the same "SELECT-1 false-passes a
8
+ * sick DB" class Feature4 closed at the raw-pg ping() level (#1974), still open
9
+ * at the HTTP layer that `traqr status` + any monitor polls. checkDbHealth is
10
+ * the shared, bounded liveness primitive the routes call.
11
+ *
12
+ * Load-bearing case: a HANGING db (ping never resolves within the budget) must
13
+ * yield `degraded` FAST — not block the health endpoint for the pg statement
14
+ * timeout (~25s observed on 6/14). The ping fn is injected, so no live DB.
15
+ *
16
+ * Run: npx tsx packages/memory/src/lib/health.test.ts
17
+ */
18
+ import { checkDbHealth, healthStatusCode } from './health.js';
19
+ let passed = 0;
20
+ let failed = 0;
21
+ function assert(label, condition) {
22
+ if (condition) {
23
+ console.log(` PASS ${label}`);
24
+ passed++;
25
+ }
26
+ else {
27
+ console.log(` FAIL ${label}`);
28
+ failed++;
29
+ }
30
+ }
31
+ console.log('\n--- checkDbHealth liveness probe ---');
32
+ // 1. Reachable DB → healthy.
33
+ {
34
+ const r = await checkDbHealth(async () => true);
35
+ assert('ping true → status healthy', r.status === 'healthy');
36
+ assert('ping true → db ok', r.db === 'ok');
37
+ }
38
+ // 2. ping returns false (honest "I touched the table and it failed") → degraded.
39
+ {
40
+ const r = await checkDbHealth(async () => false);
41
+ assert('ping false → status degraded', r.status === 'degraded');
42
+ assert('ping false → db unreachable', r.db === 'unreachable');
43
+ }
44
+ // 3. THE load-bearing case: a hanging DB. The ping would eventually resolve true
45
+ // but only after a delay that dwarfs the budget. checkDbHealth must return
46
+ // degraded within ~the timeout, not wait for the slow ping.
47
+ {
48
+ const slowPing = () => new Promise((resolve) => setTimeout(() => resolve(true), 5000));
49
+ const start = Date.now();
50
+ const r = await checkDbHealth(slowPing, 50);
51
+ const elapsed = Date.now() - start;
52
+ assert('hanging ping → status degraded (does not false-pass)', r.status === 'degraded');
53
+ assert('hanging ping → returns within the budget, not the 5s ping', elapsed < 1000);
54
+ }
55
+ // 4. Defensive: a ping that throws (shouldn't happen — ping() catches internally,
56
+ // but the probe must never propagate) → degraded, not an unhandled rejection.
57
+ {
58
+ const r = await checkDbHealth(async () => {
59
+ throw new Error('connection terminated due to connection timeout');
60
+ });
61
+ assert('throwing ping → status degraded (no propagation)', r.status === 'degraded');
62
+ }
63
+ // 5. The load-bearing HTTP contract: degraded MUST map to 503, healthy to 200.
64
+ // A route regressing to 200-on-degraded silently re-hides a starved DB —
65
+ // the exact 6/14 failure. This locks it independent of the live DB/HTTP layer.
66
+ {
67
+ assert('healthy → HTTP 200', healthStatusCode({ status: 'healthy', db: 'ok' }) === 200);
68
+ assert('degraded → HTTP 503', healthStatusCode({ status: 'degraded', db: 'unreachable' }) === 503);
69
+ }
70
+ console.log(`\n${passed} passed, ${failed} failed`);
71
+ if (failed > 0)
72
+ process.exit(1);
73
+ //# sourceMappingURL=health.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.test.js","sourceRoot":"","sources":["../../src/lib/health.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE7D,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,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;AAErD,6BAA6B;AAC7B,CAAC;IACC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAA;IAC/C,MAAM,CAAC,4BAA4B,EAAE,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;IAC5D,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;AAC5C,CAAC;AAED,iFAAiF;AACjF,CAAC;IACC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAA;IAChD,MAAM,CAAC,8BAA8B,EAAE,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAA;IAC/D,MAAM,CAAC,6BAA6B,EAAE,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,CAAA;AAC/D,CAAC;AAED,iFAAiF;AACjF,8EAA8E;AAC9E,+DAA+D;AAC/D,CAAC;IACC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;IAC/F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;IAClC,MAAM,CAAC,sDAAsD,EAAE,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAA;IACvF,MAAM,CAAC,2DAA2D,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;AACrF,CAAC;AAED,kFAAkF;AAClF,iFAAiF;AACjF,CAAC;IACC,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,kDAAkD,EAAE,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAA;AACrF,CAAC;AAED,+EAA+E;AAC/E,4EAA4E;AAC5E,kFAAkF;AAClF,CAAC;IACC,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,GAAG,CAAC,CAAA;IACvF,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,KAAK,GAAG,CAAC,CAAA;AACpG,CAAC;AAED,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/server.js CHANGED
@@ -35,6 +35,8 @@
35
35
  */
36
36
  import { Hono } from 'hono';
37
37
  import { serve } from '@hono/node-server';
38
+ import { getVectorDB } from './vectordb/index.js';
39
+ import { checkDbHealth, healthStatusCode } from './lib/health.js';
38
40
  import searchRoutes from './routes/search.js';
39
41
  import storeRoutes from './routes/store.js';
40
42
  import crudRoutes from './routes/crud.js';
@@ -57,8 +59,15 @@ import forgetCronRoutes from './routes/forget-cron.js';
57
59
  import entityCronRoutes from './routes/entity-cron.js';
58
60
  export function createMemoryServer() {
59
61
  const app = new Hono();
60
- // Health check
61
- app.get('/health', (c) => c.json({ status: 'ok', service: '@traqr/memory' }));
62
+ // Health check — a real bounded liveness probe, not a static `ok`. The memory
63
+ // service exists to serve the vector DB, so "healthy" must mean "the DB is
64
+ // reachable", not "the process is up". A static ok false-passed the 6/14
65
+ // starvation outage; this exercises the same LIMIT-1 path store/search use and
66
+ // returns 503 (degraded) so `traqr status` + monitors read it as DOWN.
67
+ app.get('/health', async (c) => {
68
+ const health = await checkDbHealth(() => getVectorDB().ping());
69
+ return c.json({ ...health, service: '@traqr/memory' }, healthStatusCode(health));
70
+ });
62
71
  // Core routes (existing)
63
72
  app.route('/search', searchRoutes);
64
73
  app.route('/store', storeRoutes);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.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.20",
3
+ "version": "0.2.22",
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/context.test.ts && tsx src/lib/pii-detection.test.ts",
18
+ "test": "tsx src/lib/quality-gate.test.ts && tsx src/lib/retrieval.test.ts && tsx src/lib/context.test.ts && tsx src/lib/pii-detection.test.ts && tsx src/lib/health.test.ts",
19
19
  "migrate": "tsx src/migrate.ts"
20
20
  },
21
21
  "files": [