Skip to content

feat(api): namespace management β€” move, rename/merge, delete with strategy (#1181) - #1183

Merged
ajianaz merged 2 commits into
developfrom
feat/1181-namespace-management
Sep 5, 2026
Merged

feat(api): namespace management β€” move, rename/merge, delete with strategy (#1181)#1183
ajianaz merged 2 commits into
developfrom
feat/1181-namespace-management

Conversation

@ajianaz

@ajianaz ajianaz commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

What

Namespace management across all surfaces (#1181) β€” namespaces are a derived view over the memories.namespace column, and this adds the sanctioned operations the issue proposed (additive, non-breaking):

  • Core: Uteke::move_memory(id, ns) (plain column update, no re-embed β€” embeddings are content-based), Uteke::rename_namespace(from, to) (single atomic UPDATE; existing target = merge, returns {from, to, moved, target_existed}), Uteke::delete_namespace(name, strategy, target) with explicit memory-fate strategies: refuse (default β€” validation error while any memory incl. deprecated references the name), merge (move all memories to target, the name vanishes naturally), deprecate (soft-delete via the feat: deprecate_with_reason() + promote() + Store undeprecateΒ #929 lifecycle β€” restorable via promote, never hard-deleted). Shared name validation (non-empty, ≀128 chars), recall-cache invalidation for old+new namespaces, vector-index removal on deprecate.
  • Server: PUT /memory accepts optional namespace; new POST /namespaces/rename and POST /namespaces/delete (refuse β†’ 409 Conflict, other validation β†’ 400); GET /namespaces?with_counts=true now returns additive active/deprecated fields while count stays the total (deprecated-only ghost namespaces become visible for what they are).
  • CLI: uteke namespace move|rename|delete β€” delete requires --confirm (same guard as the destructive-command convention).
  • MCP: uteke_namespace_rename, uteke_namespace_delete, and a namespace field on uteke_update.
  • Docs: docs/api-reference.md regenerated via docgen; docs/cli-reference.md namespace section updated; CHANGELOG under [Unreleased] β†’ Added.

Why

#1181: agents (or humans) writing to a typo'd namespace had no sanctioned fix path β€” the name only disappeared when its last memory was manually moved, and listings could not distinguish active from deprecated-only namespaces. The design keeps the derived-view model (no new tables, no schema change) and follows the soft-delete lifecycle philosophy: there is deliberately no hard-delete path.

Testing

  • Core (3 new tests, operations.rs): move updates namespace + old name vanishes from listings + unknown ID β†’ Ok(false); rename moves all memories, merge reports target_existed, same-name/unknown-source rejected; all three delete strategies β€” refuse blocks non-empty, merge relocates and removes the name, deprecate soft-deletes without data loss (memory stays stored, deprecated = true, lifecycle counts show 0 active / N deprecated), unknown strategy rejected.
  • Server (5 new tests, router-level with tiny_http::TestRequest, embedder-free): PUT /memory namespace move verified via GET /memory + listings; rename/merge endpoint contract (moved, target_existed); refuse β†’ 409 with "refus*" message; merge delete removes namespace from listings; with_counts=true lifecycle split (0 active / 1 deprecated / count 1).
  • cargo fmt --all βœ“ Β· cargo clippy --workspace --all-targets -- -D warnings βœ“ Β· cargo test --workspace βœ“ (0 failures) Β· cora review --staged βœ“ (No issues found) Β· docgen regenerated (freshness check will verify).

…ategy (#1181)

Namespaces are a derived view over the memories.namespace column, but
there was no sanctioned path to fix mistakes: no move, rename, or delete
operation existed anywhere, and deprecated-only ghost namespaces looked
identical to active ones in listings.

- PUT /memory accepts namespace (move β€” plain column update, no re-embed)
- POST /namespaces/rename: atomic rename; existing target = merge
- POST /namespaces/delete: explicit strategy β€” refuse (default, 409),
  merge (move to target, name vanishes), deprecate (soft-delete only)
- GET /namespaces?with_counts=true adds active/deprecated breakdown
- CLI: uteke namespace move|rename|delete (delete requires --confirm)
- MCP: uteke_namespace_rename, uteke_namespace_delete, namespace field
  on uteke_update
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

πŸ” Cora AI Code Review

βœ… No issues found. Code looks good!


Review powered by cora-code Β· BYOK Β· MIT

CI builds enable the onnx feature (via uteke-server's dependency
declaration) but the runner has no ORT model file, so Uteke::open()'s
default onnx backend fails at first remember(). Use
open_with_backend(None) β€” the same storage-only pattern the server tests
use β€” so the namespace tests exercise DB semantics without an embedder.
@ajianaz
ajianaz merged commit 0f75a96 into develop Sep 5, 2026
16 checks passed
@ajianaz
ajianaz deleted the feat/1181-namespace-management branch September 5, 2026 11:08
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