Skip to content

Per-group Ladybug files and library helpers - #5

Merged
renezander030 merged 1 commit into
mainfrom
feat/multi-user-files
Sep 23, 2026
Merged

renezander030 merged 1 commit into
mainfrom
feat/multi-user-files

Conversation

@renezander030

Copy link
Copy Markdown
Owner

What

  • database.ladybug.layout: per-group stores each configured group in its own Ladybug file inside database.ladybug.directory, named by the SHA-256 of the group. No group or user id can address a path outside the directory. single remains the default.
  • Ingest, drain and restore write each record into its group's file, under that file's writer lock and embedder record. The first write creates the file.
  • The MCP tools, kg ask, kg nodes, kg episodes and kg export read one group per call and open only that group's file. A bearer token may be scoped to a subset of groups in this layout; a token scoped to one group never opens another group's file. kg status, kg edge, get_entity_edge and get_status visit every group file the caller may read.
  • Library helpers that need no configuration file:
    • kg_mcp.fingerprint.record_embedder, recorded_embedder, embedder_drift: the embedder record keyed by database path (<file>.embedder.json). Configured writes keep it too, and the configured drift check reads it.
    • kg_mcp.retrieval.keyword_edge_search_config, keyword_node_search_config: the BM25-only search behind kg ask --keyword and kg-demo.
    • kg_mcp.ladybug.extension_status: whether FTS and VECTOR are installed for the running engine version, with the install command.
    • kg_mcp.ladybug.group_database_path: the contained per-group path.
  • kg export on Ladybug exports every record when a named group holds no edges.
  • README: "Multiple users on Ladybug". docs/reference.md: the layout and a library table. Changelog under 0.5.0 (unreleased).

Verification

  • uv run pytest -q: 117 passed (90 before). The 27 new tests run offline against real Ladybug files with a fake embedder: two users in two files, each holding only its own facts; a one-group token reads its own facts, is refused the other group, and never opens the other file; kg ask reads the named group's file; ingest routes each domain to its own file and embedder record; export and restore between group files; 12 hostile ids (../, absolute paths, NUL, 5000 characters, a lone surrogate) stay inside the directory; single layout unchanged; the path-keyed embedder record; the keyword configs; the extension check.
  • uv run ruff check . and scripts/release_audit.py . --allow-remote --identity-base origin/main pass.
  • uvx --from <checkout> kg-demo answers the README question.

database.ladybug.layout: per-group keeps every configured group in a separate
file named by its SHA-256, so no id can address a path outside the directory.
Ingest, drain and restore write into the group's file; the MCP tools and kg
reads open only the file of the group they address, and a token scoped to one
group never opens another. single stays the default.

Library helpers: a path-keyed embedder record, public BM25-only search
configs, an extension check for the running Ladybug engine, and the
contained per-group path. kg export on Ladybug now exports every record when
a named group holds no edges.
@renezander030
renezander030 merged commit 04e8df3 into main Sep 23, 2026
4 checks passed
@renezander030
renezander030 deleted the feat/multi-user-files branch September 23, 2026 09:54
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