You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A PR #575 follow-up end-to-end trace surfaced a mental-model gap cluster in namespace handling. The Index-tab input → _resolve_namespace() priority → Search/Sources display looks like one coherent path, but placeholder vs. actually-applied NS vs. default-handling asymmetry breaks in different directions on each leg. A user meeting NS for the first time loses the input → result → rediscovery journey at every seam.
This issue bundles the corrective work into a single PR. Splitting it touches the same function area four separate times, forces the UX writer through four passes, and asks the user to learn "what is a namespace" across four release notes instead of one. (Surfacing the Search NS filter in prod — 4.10a — is on a different decision axis ("NS CRUD model") and lives in #5.2.)
Tasks
4.3 Auto-NS preview echo + honest placeholder
New GET /api/index/preview-namespace?path=... (server-side, calls _resolve_namespace(), single round-trip)
On namespace input focus, call preview with the current path (300ms debounce) and show the resolved NS as a dynamic hint
Add a Namespace row to #index-result echoing the actually-applied NS
Replace placeholder text default (auto-ns active) with something honest like auto-determined from path so users don't trust the placeholder as the actual default
4.13 Hot-reload placeholder when Settings change
Re-invoke _syncIndexHints() (web/static/settings-config.js) on Settings save success (event bus or STATE.serverConfig update hook)
Toggling enable_auto_ns in Settings → Config updates the placeholder without a page reload
4.14 Document the default_namespace == "default" backward-compat asymmetry
Add to the Default NS field guide text in settings-config.js: "Leaving this as 'default' results in untagged chunks (backward compatibility)."
4.15 Memory_dir root edge case — no separate work; the 4.3 echo surfaces it automatically.
Decisions made
Why a single PR (cluster)
The cluster framing itself says "the legs disagree" — fixing one leg at a time leaves the disagreement in another shape.
UX writer makes one consistent pass — splitting produces placeholder/toast/helper text in different tones at different times.
Users learn "what NS is" from one release note, not four.
The footprint is the same code area: _syncIndexHints(), _resolve_namespace(), the Default NS helper text, and the #index-result NS row.
Preview default — server-side endpoint
Option A (server /api/index/preview-namespace) vs option B (client-side inference). Option A. Same trust model as #5.1b — the server is source-of-truth for resolution rules; reimplementing rule-glob matching in the client introduces drift on every server change. Throttled (300ms debounce) input-focus calls absorb the round-trip cost.
4.14 helper text default — avoids migration
The code-unification option (have "default" also be a tag) carries a data migration cost:
Existing chunks indexed under default_namespace="default" are stored as NS=None.
After unification, new chunks get NS="default" → the same user's chunks split across two NS values in search.
A backfill SQL (UPDATE chunks SET namespace='default' WHERE namespace IS NULL) or query-time COALESCE(namespace, 'default') is required.
Helper-text path is migration-zero; documenting backward-compat intent is itself the value. Code unification ships in a future PR with its own migration plan.
Why
A PR #575 follow-up end-to-end trace surfaced a mental-model gap cluster in namespace handling. The Index-tab input →
_resolve_namespace()priority → Search/Sources display looks like one coherent path, but placeholder vs. actually-applied NS vs. default-handling asymmetry breaks in different directions on each leg. A user meeting NS for the first time loses the input → result → rediscovery journey at every seam.This issue bundles the corrective work into a single PR. Splitting it touches the same function area four separate times, forces the UX writer through four passes, and asks the user to learn "what is a namespace" across four release notes instead of one. (Surfacing the Search NS filter in prod — 4.10a — is on a different decision axis ("NS CRUD model") and lives in #5.2.)
Tasks
GET /api/index/preview-namespace?path=...(server-side, calls_resolve_namespace(), single round-trip)path(300ms debounce) and show the resolved NS as a dynamic hintNamespacerow to#index-resultechoing the actually-applied NSdefault (auto-ns active)with something honest likeauto-determined from pathso users don't trust the placeholder as the actual default_syncIndexHints()(web/static/settings-config.js) on Settings save success (event bus orSTATE.serverConfigupdate hook)enable_auto_nsin Settings → Config updates the placeholder without a page reloaddefault_namespace == "default"backward-compat asymmetryDefault NSfield guide text insettings-config.js: "Leaving this as 'default' results in untagged chunks (backward compatibility)."Decisions made
Why a single PR (cluster)
_syncIndexHints(),_resolve_namespace(), theDefault NShelper text, and the#index-resultNS row.Preview default — server-side endpoint
Option A (server
/api/index/preview-namespace) vs option B (client-side inference). Option A. Same trust model as #5.1b — the server is source-of-truth for resolution rules; reimplementing rule-glob matching in the client introduces drift on every server change. Throttled (300ms debounce) input-focus calls absorb the round-trip cost.4.14 helper text default — avoids migration
The code-unification option (have "default" also be a tag) carries a data migration cost:
default_namespace="default"are stored asNS=None.NS="default"→ the same user's chunks split across two NS values in search.UPDATE chunks SET namespace='default' WHERE namespace IS NULL) or query-timeCOALESCE(namespace, 'default')is required.Helper-text path is migration-zero; documenting backward-compat intent is itself the value. Code unification ships in a future PR with its own migration plan.
References
All paths under
packages/memtomem/src/memtomem/.indexing/engine.py: IndexEngine._resolve_namespace()(~474)web/routes/system.py: trigger_index()(~807)web/static/settings-config.js: _syncIndexHints()(~125)web/static/index.html: <div id="tab-index">#index-resulttable: folder panel inweb/static/index.htmldocs/adr/0004-*.mdTest plan
_resolve_namespace()covers all four priority cases (explicit / rules / auto / default)/api/index/preview-namespacereturns the documented JSON shape (resolved_namespace)enable_auto_ns=trueanddefault_namespace="personal", entering/work/notesshows preview hintnotesenable_auto_nsin Settings updates the placeholder without reload#index-resultwith the applied NS rowOut of scope
🤖 Generated with Claude Code