@theokit/sdk-memory 0.2.0 → 0.2.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog — @theokit/sdk-memory
2
2
 
3
+ ## 0.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 453ad2d: SE43 — system-design audit fixes (public-surface changes).
8
+
9
+ - **`@theokit/sdk` (minor):** the shared persistence kernel is now reachable from the sanctioned public `@theokit/sdk/persistence` barrel — `withCwdMutex`, `sanitizeFts5Query`, and `PersistenceSchema` are added (joining `replaceFileAtomic` / `openSqliteResilient` / `atomicWriteText` / `atomicWriteJson`). The `@theokit/sdk/internal/persistence` export is now **deprecated**: it re-exports its full surface unchanged for one release (back-compat) and is scheduled for removal in a future major. No breaking change; existing imports keep working.
10
+ - **Satellites (patch):** `sdk-tools` / `sdk-memory` / `sdk-cache` / `sdk-handoff` / `sdk-budget` tightened their `@theokit/sdk` peer-range floor from `>=1.7.0` to `>=4.0.0`, matching the v4-only surfaces they import (prevents a non-workspace install resolving an incompatible old sdk).
11
+
12
+ ## 0.2.1
13
+
14
+ ### Patch Changes
15
+
16
+ - 826bca0: Security (#56) — close two residual cross-tenant active-recall cache leaks found by adversarial review.
17
+
18
+ - `@theokit/sdk-memory` (publishable) called `cache.get`/`cache.set` with no tenant context, so two callers with the same query text but different identity shared a cached recall — a cross-tenant leak for every consumer of the package. The cache read/write are now keyed by the `{namespace, userId, scope}` tenant tuple (the primitive already supported it).
19
+ - In `@theokit/sdk` the production caller hardcoded `namespace: "default"` and dropped `memoryContext.tenantId`, so two tenants sharing a `userId` collided on one cache entry. The caller now threads `memoryContext.tenantId` into the tenant partition (`namespace`). `sessionId` is intentionally not a key dimension — recall is cross-session by design.
20
+
3
21
  ## 0.2.0
4
22
 
5
23
  ### Minor Changes
@@ -15,7 +15,7 @@
15
15
  * can call to persist a fact mid-conversation.
16
16
  * - `recordSessionSummary()` writes a markdown summary to
17
17
  * `${cwd}/.theokit/memory/sessions/${runId}.md` (real disk write
18
- * via `@theokit/sdk/internal/persistence` per ADR-008).
18
+ * via `@theokit/sdk/persistence` per ADR-008).
19
19
  * - `dispose()` clears the handle's per-agent map (releases memory).
20
20
  *
21
21
  * @public
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  var promises = require('fs/promises');
4
4
  var path = require('path');
5
5
  var sdk = require('@theokit/sdk');
6
- var persistence = require('@theokit/sdk/internal/persistence');
6
+ var persistence = require('@theokit/sdk/persistence');
7
7
  var pathSafety = require('@theokit/sdk/path-safety');
8
8
  var crypto = require('crypto');
9
9
  var errors = require('@theokit/sdk/errors');
@@ -387,7 +387,12 @@ async function runActiveMemory(args) {
387
387
  hits: []
388
388
  });
389
389
  }
390
- const cached = args.cache?.get(args.userText, cfg.queryMode);
390
+ const tenantCtx = {
391
+ namespace: args.namespace,
392
+ userId: args.userId,
393
+ scope: args.scope
394
+ };
395
+ const cached = args.cache?.get(args.userText, cfg.queryMode, tenantCtx);
391
396
  if (cached !== void 0) return endRecallSpan(span, args, cached);
392
397
  const query = buildQuery(args.userText, args.priorMessages, cfg.queryMode, cfg.recentUserTurns);
393
398
  if (query.trim().length === 0) {
@@ -484,7 +489,12 @@ function notifyBreaker(breaker, key, status) {
484
489
  else if (status === "ok" || status === "no-recall") breaker.recordSuccess(key);
485
490
  }
486
491
  async function finalize(args, queryMode, result) {
487
- args.cache?.set(args.userText, queryMode, result);
492
+ const tenantCtx = {
493
+ namespace: args.namespace,
494
+ userId: args.userId,
495
+ scope: args.scope
496
+ };
497
+ args.cache?.set(args.userText, queryMode, result, tenantCtx);
488
498
  if (args.persistTranscripts === true && args.cwd !== void 0) {
489
499
  await persistActiveMemoryTranscript(args.cwd, {
490
500
  runId: args.runId ?? `run-${Date.now()}`,