# 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.