🐾 feat(library): per-app managed_by replaces hardcoded Daedalus badge #7

Merged
r merged 1 commits from feature/managed-by into main 2026-08-03 01:55:16 +00:00
Owner

What

Mnemosyne only had a concept of a Daedalus-managed library: any Library with a non-null workspace_id was badged "Daedalus workspace" regardless of which app actually manages it — so Kairos mail libraries were mislabeled, and Spelunker's global libraries carried no managed marker at all.

  • Library.managed_by (neomodel StringProperty, no Django migration): stamped at create time with the name of the UserToken used on the API call, on both POST /library/api/workspaces/ and POST /library/api/libraries/. Web-session creates stay null → unmanaged. Never changed by edits or token rotation; the idempotent workspace re-POST lazily fills it when null.
  • managed_by_display drives the UI: falls back to inference for legacy rows (kairos-mail-* → Kairos, other workspace → Daedalus) so badges are correct before and after backfill.
  • Templates: the 5 hardcoded "Daedalus" blocks (list badge, detail badge + alert, delete warning) now render "Managed by {app}", with workspace-specific copy kept inside workspace_id guards. Advisory only, as before.
  • Scope filter: ?scope=all|managed|unmanaged; legacy daedalus/global values alias for existing bookmarks.
  • Plain create 409: duplicate library names previously hit the Neo4j unique index as a raw 500. Now an explicit name_conflict 409 with the existing library's uid and manager.
  • backfill_managed_by management command (idempotent, --dry-run, --*-label overrides): labels workspace libraries by inference and Spelunker's global libraries via IngestJob.source="spelunker" provenance.
  • Token-create form help text now notes the token name becomes the "Managed by" label.

Testing

  • library.tests.test_managed_by (new), rewritten test_views scope tests, request_token_label coverage in test_drf_auth54 tests green on the touched modules against a throwaway postgres:17.
  • Full library + mcp_server suite: 444 tests; the only failures (8F/1E in test_search_api / test_tasks.test_embed_item_failure) also fail on clean origin/main — pre-existing, unrelated.
  • Cypher-touching paths (live stamping, backfill) are on the manual e2e checklist per repo test policy.

Deploy

  1. Merge + deploy Mnemosyne.
  2. python manage.py backfill_managed_by --dry-run, inspect, then run with --daedalus-label/--kairos-label/--spelunker-label matching real production token names.
  3. Companion client PRs follow (Spelunker dedupe scoping; Kairos2/Daedalus token-naming guidance).

🤖 Generated with Claude Code

## What Mnemosyne only had a concept of a *Daedalus*-managed library: any `Library` with a non-null `workspace_id` was badged "Daedalus workspace" regardless of which app actually manages it — so Kairos mail libraries were mislabeled, and Spelunker's global libraries carried no managed marker at all. - **`Library.managed_by`** (neomodel StringProperty, no Django migration): stamped at create time with the **name of the UserToken** used on the API call, on both `POST /library/api/workspaces/` and `POST /library/api/libraries/`. Web-session creates stay null → unmanaged. Never changed by edits or token rotation; the idempotent workspace re-POST lazily fills it when null. - **`managed_by_display`** drives the UI: falls back to inference for legacy rows (`kairos-mail-*` → Kairos, other workspace → Daedalus) so badges are correct before and after backfill. - **Templates**: the 5 hardcoded "Daedalus" blocks (list badge, detail badge + alert, delete warning) now render "Managed by {app}", with workspace-specific copy kept inside `workspace_id` guards. Advisory only, as before. - **Scope filter**: `?scope=all|managed|unmanaged`; legacy `daedalus`/`global` values alias for existing bookmarks. - **Plain create 409**: duplicate library names previously hit the Neo4j unique index as a raw 500. Now an explicit `name_conflict` 409 with the existing library's `uid` and manager. - **`backfill_managed_by`** management command (idempotent, `--dry-run`, `--*-label` overrides): labels workspace libraries by inference and Spelunker's global libraries via `IngestJob.source="spelunker"` provenance. - Token-create form help text now notes the token name becomes the "Managed by" label. ## Testing - `library.tests.test_managed_by` (new), rewritten `test_views` scope tests, `request_token_label` coverage in `test_drf_auth` — **54 tests green** on the touched modules against a throwaway postgres:17. - Full `library` + `mcp_server` suite: 444 tests; the only failures (8F/1E in `test_search_api` / `test_tasks.test_embed_item_failure`) **also fail on clean origin/main** — pre-existing, unrelated. - Cypher-touching paths (live stamping, backfill) are on the manual e2e checklist per repo test policy. ## Deploy 1. Merge + deploy Mnemosyne. 2. `python manage.py backfill_managed_by --dry-run`, inspect, then run with `--daedalus-label/--kairos-label/--spelunker-label` matching real production token names. 3. Companion client PRs follow (Spelunker dedupe scoping; Kairos2/Daedalus token-naming guidance). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
r added 1 commit 2026-08-02 16:39:29 +00:00
Libraries created through the API are now stamped with the name of the
UserToken that created them (Library.managed_by), on both the workspace
and plain create endpoints; web-session creates stay null/unmanaged. The
idempotent workspace re-POST lazily backfills null managed_by, and a
one-off backfill_managed_by command labels pre-existing rows (workspace
inference: kairos-mail-* → Kairos, else Daedalus; Spelunker via ingest
job provenance).

UI badges and warnings now render "Managed by <app>" via
managed_by_display (inference fallback keeps legacy rows accurate before
backfill). The list scope filter becomes all/managed/unmanaged with the
old daedalus/global values aliased for bookmarks. The plain create
endpoint also gains an explicit 409 name_conflict (previously a raw
UniqueProperty 500) reporting the existing library's uid and manager.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
r merged commit acf829e5ca into main 2026-08-03 01:55:16 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: r/mnemosyne#7