docs: add IdentityDB space isolation plan
This commit is contained in:
157
docs/plans/2026-05-11-identitydb-space-isolation.md
Normal file
157
docs/plans/2026-05-11-identitydb-space-isolation.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# IdentityDB Space Isolation Implementation Plan
|
||||
|
||||
> **For Hermes:** Use the `writing-plans` and `test-driven-development` skills. Implement this feature in small TDD steps with meaningful commits.
|
||||
|
||||
**Goal:** Add first-class memory spaces so callers can keep unrelated topic/fact graphs isolated from each other while still using one physical database.
|
||||
|
||||
**Architecture:** Introduce a `spaces` table plus `space_id` scoping on the canonical topic/fact records that define graph ownership. Treat the unnamed/default behavior as a built-in `default` space so existing API usage keeps working, while allowing any write/query path to target a named space explicitly.
|
||||
|
||||
**Tech Stack:** TypeScript, Bun, Vitest, Kysely, SQLite/PostgreSQL/MySQL/MariaDB-compatible schema primitives.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
1. A caller must be able to write memory into independent spaces such as `A` and `B`.
|
||||
2. Topic lookups, alias resolution, hierarchy traversal, connected-topic queries, fact queries, ingestion, and semantic search must only see data from the requested space.
|
||||
3. Existing callers that do not specify a space must continue to work inside a built-in `default` space.
|
||||
4. Space names must be normalized/canonicalized similarly to topics.
|
||||
5. Documentation must explain both the isolation model and the default-space compatibility behavior.
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Add failing tests for schema-level space support
|
||||
|
||||
**Objective:** Define the storage contract for spaces and per-space uniqueness before implementation.
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/migrations.test.ts`
|
||||
|
||||
**Step 1: Write failing tests**
|
||||
- Assert that initialization creates a `spaces` table.
|
||||
- Assert that `topics`, `facts`, and `topic_aliases` now include `space_id`.
|
||||
- Assert that `spaces` includes `id`, `name`, `normalized_name`, `description`, `metadata`, `created_at`, `updated_at`.
|
||||
|
||||
**Step 2: Run red test**
|
||||
- Run: `bun run test tests/migrations.test.ts`
|
||||
- Expect: failure because the schema does not yet contain space support.
|
||||
|
||||
**Step 3: Commit later with implementation**
|
||||
- Do not commit yet; continue only after implementation turns the test green.
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Add failing behavioral tests for isolated spaces
|
||||
|
||||
**Objective:** Lock in the public API behavior for separate memory spaces.
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/identity-db.test.ts`
|
||||
- Modify: `tests/queries.test.ts`
|
||||
- Modify: `tests/semantic-search.test.ts`
|
||||
- Optionally create: `tests/spaces.test.ts` if separation makes the scenarios clearer.
|
||||
|
||||
**Step 1: Write failing tests**
|
||||
- Verify the same topic name can exist in two spaces without deduplicating together.
|
||||
- Verify facts added in `spaceName: 'A'` are invisible from `spaceName: 'B'`.
|
||||
- Verify alias resolution only resolves inside the same space.
|
||||
- Verify hierarchy parent/child traversal only stays within the same space.
|
||||
- Verify semantic search and duplicate-aware ingestion only search within the same space.
|
||||
- Verify callers that omit `spaceName` still operate in the `default` space.
|
||||
|
||||
**Step 2: Run red tests**
|
||||
- Run the most targeted files first, then the whole suite slice.
|
||||
- Example: `bun run test tests/identity-db.test.ts tests/queries.test.ts tests/semantic-search.test.ts`
|
||||
- Expect: failure due to missing API fields and missing isolation logic.
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Implement schema and type support
|
||||
|
||||
**Objective:** Add the underlying data model required for spaces.
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/core/schema.ts`
|
||||
- Modify: `src/types/domain.ts`
|
||||
- Modify: `src/types/database.ts`
|
||||
- Modify: `src/core/migrations.ts`
|
||||
|
||||
**Implementation notes:**
|
||||
- Add `SPACES_TABLE` and `SPACE_COLUMNS` constants.
|
||||
- Add `SpaceRecord` domain type.
|
||||
- Add `spaces` to `IdentityDatabaseSchema`.
|
||||
- Create the `spaces` table.
|
||||
- Add `space_id` columns to `topics`, `facts`, and `topic_aliases`.
|
||||
- Make topic uniqueness per-space, not global.
|
||||
- Make alias uniqueness per-space, not global.
|
||||
- Seed or upsert a built-in `default` space during initialization via normal application flow, not hard-coded SQL assumptions.
|
||||
|
||||
**Verification:**
|
||||
- Re-run: `bun run test tests/migrations.test.ts`
|
||||
- Expect: green.
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Implement space-aware API contracts and query helpers
|
||||
|
||||
**Objective:** Thread `spaceName` through the high-level API and low-level query layer.
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/types/api.ts`
|
||||
- Modify: `src/ingestion/types.ts`
|
||||
- Modify: `src/queries/topics.ts`
|
||||
- Modify: `src/queries/facts.ts`
|
||||
- Modify: `src/core/identity-db.ts`
|
||||
- Modify: `src/index.ts` if new exported types are added
|
||||
|
||||
**Implementation notes:**
|
||||
- Add public `Space` and `UpsertSpaceInput` types if needed.
|
||||
- Add optional `spaceName` on write/query inputs where the caller targets a graph.
|
||||
- Add helpers to resolve or create the requested space inside transactions.
|
||||
- Ensure all existing topic lookup helpers filter by `space_id`.
|
||||
- Ensure semantic search candidates are restricted to facts in the requested space.
|
||||
- Preserve existing no-space API calls by mapping them to `default`.
|
||||
|
||||
**Verification:**
|
||||
- Re-run the failing behavior tests.
|
||||
- Expect: green for the new targeted tests.
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Refine ergonomics and update documentation
|
||||
|
||||
**Objective:** Make the feature understandable and safe to use.
|
||||
|
||||
**Files:**
|
||||
- Modify: `README.md`
|
||||
- Optionally modify: wiki docs later if requested
|
||||
|
||||
**Implementation notes:**
|
||||
- Document the default space behavior.
|
||||
- Add examples for `spaceName: 'A'` and `spaceName: 'B'`.
|
||||
- Explain that spaces are hard isolation boundaries for topic/fact traversal and semantic retrieval.
|
||||
|
||||
**Verification:**
|
||||
- Run: `bun run test && bun run check && bun run build`
|
||||
- Confirm docs/examples align with the final public API.
|
||||
|
||||
---
|
||||
|
||||
## Suggested commit boundaries
|
||||
|
||||
1. `docs: add IdentityDB space isolation plan`
|
||||
2. `test: specify isolated memory spaces`
|
||||
3. `feat: add space-aware memory graph isolation`
|
||||
4. `docs: document space-scoped memory usage`
|
||||
|
||||
---
|
||||
|
||||
## Acceptance checklist
|
||||
|
||||
- [ ] `spaces` table exists.
|
||||
- [ ] Topics with the same normalized name can exist in different spaces.
|
||||
- [ ] Facts from one space do not appear in another space’s queries.
|
||||
- [ ] Alias and hierarchy traversal are space-aware.
|
||||
- [ ] Semantic search and duplicate detection are space-aware.
|
||||
- [ ] Existing callers still work via the `default` space.
|
||||
- [ ] Full test/build/typecheck suite passes.
|
||||
Reference in New Issue
Block a user