Skip to content

feat(namespaces): propagate namespace through public surfaces (Sprint C.2, #16)#101

Merged
salishforge merged 1 commit into
mainfrom
feat/memory-namespaces-api
Apr 18, 2026
Merged

feat(namespaces): propagate namespace through public surfaces (Sprint C.2, #16)#101
salishforge merged 1 commit into
mainfrom
feat/memory-namespaces-api

Conversation

@salishforge
Copy link
Copy Markdown
Owner

Summary

Exposes the memory `namespace` argument through every public surface. Backend support shipped in Sprint C.1 (PR #100); this PR makes it reachable from HTTP, MCP tools, TS SDK, Python SDK, and OpenAPI. Completes #16 Memory Namespaces.

Sleep is intentionally agent-wide (not namespace-scoped). Making it namespace-aware would require every phase in the 10-phase cycle to filter by namespace — deeper than this PR. `SleepSchema` explicitly does not accept `namespace` so the API doesn't claim behavior it can't deliver.

Surfaces updated

Surface Routes / methods
HTTP (`src/app.ts`) add, query, consolidate, import, export, timeline, resume, stats — all accept `namespace`. Cache keys for timeline/stats/resume now namespace-suffixed.
MemoryManager (`src/memory-manager.ts`) timeline, stats, resume, exportMemory gained `namespace?` param beyond C.1's coverage. Entities/relationships stay agent-scoped (knowledge graph shared across namespaces by design, per migration-v3.1 header).
MCP (`src/mcp.ts`, `src/tool-definitions.ts`) `memforge_add/query/timeline/consolidate/stats` accept `namespace`. `memforge_sleep` documented as agent-wide.
TS SDK (`src/client.ts`) `MemForgeClient` + `ResilientMemForgeClient` — non-breaking positional signatures.
OpenAPI (`src/openapi.ts`) `namespace` documented with regex pattern; `/sleep`, `/resume`, `/export`, `/import` added (they were missing).
Python SDK `python/memforge/client.py` + `resilient.py`: matching `namespace` kwarg.

Tests

`tests/http-api.test.ts` — new "Namespace support" suite (5 tests): add+consolidate to non-default namespace, scoped query, cross-namespace isolation, 400s on invalid namespace input (POST and GET).

Python SDK tests out of scope — Python test infrastructure isn't in CI.

Design notes

  • Entities & relationships NOT namespaced — a single "User Sarah" can appear across namespaces for an agent; duplicating per namespace would fragment the knowledge graph. Same decision as C.1.
  • Export is self-contained — entities + relationships included in every namespace-scoped export so a JSONL dump can be re-imported anywhere (even into a fresh agent).
  • Cache keys include namespace — stats/timeline/resume cached responses no longer leak across namespaces.
  • Sleep is agent-wide — documented in SleepSchema comment, MCP tool description, and SDK docstrings.

Test plan

  • CI `type-check`, `lint`, `build` pass
  • CI `test-integration` (Node 20 + 22) — includes HTTP suite with new namespace tests
  • CI `test-rls` still passes
  • Load tests skipped on PR
  • Next tag (beta.4+) will validate Trusted Publishing E2E

ROADMAP

#16 marked ✅ DONE (backend via PR #100, public surface via this PR).

…I (C.2, #16)

Exposes the memory `namespace` argument through every public surface
so callers can scope operations to a single domain. Backend support
shipped in Sprint C.1 (PR #100); this PR makes it reachable.

HTTP API (src/app.ts):
- POST /memory/:id/add — body field `namespace`
- GET  /memory/:id/query — query param
- POST /memory/:id/consolidate — body field
- POST /memory/:id/import — body field + per-record fallback
- GET  /memory/:id/export — query param
- GET  /memory/:id/timeline — query param
- GET  /memory/:id/resume — query param
- GET  /memory/:id/stats — query param (with namespace folded into cache key)
Cache keys for timeline/stats/resume now include namespace so cached
responses don't leak across namespaces.

Sleep is intentionally agent-wide and NOT namespace-scoped: the 10-phase
cycle would need every phase to filter by namespace, which is a deeper
change than C.2. The SleepSchema no longer accepts a `namespace` field
so the API doesn't lie about behavior it cannot yet deliver. Future
work can re-add it once sleep phases are all namespace-aware.

MemoryManager extensions beyond C.1:
- timeline() — 5th positional `namespace?` param, WHERE filter
- stats()   — 2nd positional `namespace?` param. Entity/relationship
  counts remain agent-scoped (knowledge graph is shared across
  namespaces by design, see migration-v3.1 header); warm/hot/cold/
  reflection counts filter by (agent_id, namespace).
- resume()  — 3rd positional `namespace?` param, filters warm_tier,
  procedures, reflections, and the memory health summary.
- exportMemory() — 2nd positional `namespace?` param. Warm-tier rows,
  procedures, and reflections are namespace-scoped in the export;
  entities + relationships are included in every export so a JSONL
  dump is self-contained for re-import.

MCP (src/mcp.ts) + tool-definitions (src/tool-definitions.ts):
- `memforge_add`, `memforge_query`, `memforge_timeline`,
  `memforge_consolidate`, `memforge_stats` gain optional
  `namespace` arg with terse descriptions noting default 'default'.
- `memforge_sleep` does NOT take namespace (agent-wide, documented).

TypeScript SDK (src/client.ts):
- MemForgeClient and ResilientMemForgeClient: `namespace` param on
  add/query/consolidate/timeline/stats/resume/exportMemory. Non-breaking
  — existing positional call sites still compile.

OpenAPI spec (src/openapi.ts):
- namespace parameter documented on each applicable route with the
  regex pattern (^[a-z0-9][a-z0-9_-]*$). Routes that were missing
  from the spec (/sleep, /resume, /export, /import) are added.

Python SDK (python/memforge/client.py + resilient.py):
- Matching `namespace` kwarg on add/query/consolidate/timeline/stats/
  resume. `sleep` does not take namespace (parity with TS).

Tests (tests/http-api.test.ts):
- New "Namespace support" suite: 5 tests for add+consolidate in a
  non-default namespace, namespace-scoped query, cross-namespace
  isolation, and 400s on invalid namespace input for both POST and GET.

ROADMAP.md: #16 marked ✅ DONE — shipped in PR #100 (backend) + this
PR (public surface).
@salishforge salishforge merged commit 01f60be into main Apr 18, 2026
12 checks passed
@salishforge salishforge deleted the feat/memory-namespaces-api branch April 18, 2026 03:42
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