@x12i/memorix-retrieval 1.5.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +1 -0
  2. package/dist/client/create-client.d.ts.map +1 -1
  3. package/dist/client/create-client.js +17 -12
  4. package/dist/client/create-client.js.map +1 -1
  5. package/dist/client/create-from-env.d.ts +4 -0
  6. package/dist/client/create-from-env.d.ts.map +1 -1
  7. package/dist/client/create-from-env.js +10 -3
  8. package/dist/client/create-from-env.js.map +1 -1
  9. package/dist/client/create-xronox-from-env.d.ts +16 -0
  10. package/dist/client/create-xronox-from-env.d.ts.map +1 -0
  11. package/dist/client/create-xronox-from-env.js +17 -0
  12. package/dist/client/create-xronox-from-env.js.map +1 -0
  13. package/dist/client/types.d.ts +7 -5
  14. package/dist/client/types.d.ts.map +1 -1
  15. package/dist/client/xronox-adapter.d.ts +14 -0
  16. package/dist/client/xronox-adapter.d.ts.map +1 -0
  17. package/dist/client/xronox-adapter.js +69 -0
  18. package/dist/client/xronox-adapter.js.map +1 -0
  19. package/dist/client/xronox-like.d.ts +24 -0
  20. package/dist/client/xronox-like.d.ts.map +1 -1
  21. package/dist/data/memorix-count.d.ts +11 -0
  22. package/dist/data/memorix-count.d.ts.map +1 -0
  23. package/dist/data/memorix-count.js +38 -0
  24. package/dist/data/memorix-count.js.map +1 -0
  25. package/dist/data/memorix-read.d.ts +1 -1
  26. package/dist/data/memorix-read.d.ts.map +1 -1
  27. package/dist/data/memorix-read.js +21 -16
  28. package/dist/data/memorix-read.js.map +1 -1
  29. package/dist/explorer/collection-inventory.d.ts +77 -0
  30. package/dist/explorer/collection-inventory.d.ts.map +1 -0
  31. package/dist/explorer/collection-inventory.js +302 -0
  32. package/dist/explorer/collection-inventory.js.map +1 -0
  33. package/dist/explorer/entity-graph.d.ts +35 -12
  34. package/dist/explorer/entity-graph.d.ts.map +1 -1
  35. package/dist/explorer/entity-graph.js +117 -55
  36. package/dist/explorer/entity-graph.js.map +1 -1
  37. package/dist/explorer/health.d.ts +1 -0
  38. package/dist/explorer/health.d.ts.map +1 -1
  39. package/dist/explorer/health.js +53 -0
  40. package/dist/explorer/health.js.map +1 -1
  41. package/dist/explorer/raw-reads.d.ts.map +1 -1
  42. package/dist/explorer/raw-reads.js +4 -12
  43. package/dist/explorer/raw-reads.js.map +1 -1
  44. package/dist/explorer/scoped-workspace.d.ts.map +1 -1
  45. package/dist/explorer/scoped-workspace.js +20 -58
  46. package/dist/explorer/scoped-workspace.js.map +1 -1
  47. package/dist/index.d.ts +5 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/retrieval/fetch-list.d.ts.map +1 -1
  52. package/dist/retrieval/fetch-list.js +5 -8
  53. package/dist/retrieval/fetch-list.js.map +1 -1
  54. package/dist/tests/collection-inventory.test.d.ts +2 -0
  55. package/dist/tests/collection-inventory.test.d.ts.map +1 -0
  56. package/dist/tests/collection-inventory.test.js +207 -0
  57. package/dist/tests/collection-inventory.test.js.map +1 -0
  58. package/dist/tests/entity-graph.test.d.ts +2 -0
  59. package/dist/tests/entity-graph.test.d.ts.map +1 -0
  60. package/dist/tests/entity-graph.test.js +148 -0
  61. package/dist/tests/entity-graph.test.js.map +1 -0
  62. package/dist/tests/fetch-list.test.js +1 -1
  63. package/dist/tests/fetch-list.test.js.map +1 -1
  64. package/dist/tests/package-json.test.d.ts +2 -0
  65. package/dist/tests/package-json.test.d.ts.map +1 -0
  66. package/dist/tests/package-json.test.js +14 -0
  67. package/dist/tests/package-json.test.js.map +1 -0
  68. package/docs/DATA-TIER-CONTRACT.md +16 -8
  69. package/docs/EXPLORER-HOST-APIS.md +16 -2
  70. package/docs/MEMORIX-CATALOX-CONTRACTS.md +8 -4
  71. package/docs/XRONOX-DATA-TIER-REQUIREMENTS.md +132 -0
  72. package/docs/fr/README.md +15 -0
  73. package/docs/fr/xronox-fr-list-collections.md +196 -0
  74. package/docs/fr/xronox-fr-memorix-env-preset.md +69 -0
  75. package/docs/fr/xronox-fr-per-role-selftest.md +60 -0
  76. package/package.json +3 -12
@@ -0,0 +1,14 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import pkg from "../../package.json" with { type: "json" };
3
+ describe("package.json sanity", () => {
4
+ it("does not list @x12i/memorix-retrieval as its own dependency", () => {
5
+ const deps = pkg.dependencies;
6
+ const devDeps = pkg.devDependencies;
7
+ const peerDeps = pkg
8
+ .peerDependencies;
9
+ expect(deps?.["@x12i/memorix-retrieval"]).toBeUndefined();
10
+ expect(devDeps?.["@x12i/memorix-retrieval"]).toBeUndefined();
11
+ expect(peerDeps?.["@x12i/memorix-retrieval"]).toBeUndefined();
12
+ });
13
+ });
14
+ //# sourceMappingURL=package-json.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-json.test.js","sourceRoot":"","sources":["../../src/tests/package-json.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,GAAG,MAAM,oBAAoB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAE3D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,IAAI,GAAG,GAAG,CAAC,YAAkD,CAAC;QACpE,MAAM,OAAO,GAAG,GAAG,CAAC,eAAqD,CAAC;QAC1E,MAAM,QAAQ,GAAI,GAAqD;aACpE,gBAAgB,CAAC;QAEpB,MAAM,CAAC,IAAI,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1D,MAAM,CAAC,OAAO,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC7D,MAAM,CAAC,QAAQ,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -9,6 +9,8 @@ See also:
9
9
  - [MEMORIX-CATALOX-CONTRACTS.md](./MEMORIX-CATALOX-CONTRACTS.md) — descriptor catalogs and JSON formats
10
10
  - [MEMORIX-DATABASE-CONVENTIONS.md](./MEMORIX-DATABASE-CONVENTIONS.md) — Mongo layout and env vars
11
11
  - [EXPLORER-HOST-APIS.md](./EXPLORER-HOST-APIS.md) — graph, raw reads, scoped workspace (Explorer-oriented)
12
+ - [XRONOX-DATA-TIER-REQUIREMENTS.md](./XRONOX-DATA-TIER-REQUIREMENTS.md) — what `@x12i/xronox` must provide as Memorix data tier
13
+ - [fr/README.md](./fr/README.md) — **open feature requests for `@x12i/xronox`** (implement there first)
12
14
 
13
15
  ---
14
16
 
@@ -16,13 +18,16 @@ See also:
16
18
 
17
19
  | Export | Purpose |
18
20
  |--------|---------|
19
- | `createMemorixRetrieval(options)` | Build client with Catalox (+ lazy Mongo from `MONGO_URI`) |
20
- | `createMemorixRetrievalFromEnv(options)` | Same, connects Mongo up front |
21
+ | `createMemorixRetrieval(options)` | Build client with Catalox + optional Xronox data tier |
22
+ | `createMemorixRetrievalFromEnv(options)` | Catalox + Xronox from env (default for hosts) |
23
+ | `createMemorixXronoxFromEnv(options?)` | Xronox zero-config bootstrap only |
21
24
  | `createMemorixRetrievalStackFromEnv(options?)` | Catalox from env + adapter + retrieval client (recommended for hosts) |
22
25
  | `createCataloxAdapterFromBound(bound)` | Wrap a bound Catalox client for descriptor loads |
23
26
  | `resolveMemorixAppId(options?, processEnv?)` | Resolve app id: option → `CATALOX_APP_ID` → `MEMORIX_APP_ID` → `memorix` |
24
27
 
25
- **Required env (simple mode):** `MONGO_URI`. Catalox credentials per `@x12i/catalox` when using the stack helper.
28
+ **Required env (default stack):** `MONGO_URI` (used by Xronox zero-config). Catalox credentials per `@x12i/catalox` when using the stack helper.
29
+
30
+ Data reads and counts go through **Xronox** (`role: memorix_entities` for entity descriptors, `role: memorix_events` for event descriptors). Direct Mongo is an advanced test-only escape hatch.
26
31
 
27
32
  ---
28
33
 
@@ -62,8 +67,10 @@ List descriptor `filters` with `operator` + `value` are **always applied**; requ
62
67
 
63
68
  | Export | Purpose |
64
69
  |--------|---------|
65
- | `buildMemorixEntityGraph(client, options?)` | Discovery + counts + relation graph |
66
- | `buildMemorixEntitySlices(client, entityName)` | Per–content-type counts for drill-down |
70
+ | `buildMemorixEntityGraph(client, options?)` | Discovery + counts + relation graph (per–content-type metadata, both DBs) |
71
+ | `buildMemorixEntitySlices(client, entityName)` | Per–content-type counts for drill-down (includes zero counts) |
72
+ | `buildMemorixCollectionInventory(client, options?)` | Reconcile Catalox-declared collections with Mongo in both databases via Xronox `listCollections` (≥ 3.9.0) |
73
+ | `orphanNodesFromInventory(entries)` | Group inventory orphans for entity graph canvas |
67
74
  | `getMemorixRetrievalHealth(client)` | Mongo ping + discovery sample |
68
75
  | `countMemorixEntityContentTypeDocuments` | Count by entity + content type (descriptor-resolved collection) |
69
76
  | `listMemorixEntityContentTypeDocuments` | Paginated raw documents (descriptor-resolved) |
@@ -111,12 +118,13 @@ Scripts (not imported by hosts at runtime):
111
118
 
112
119
  | Export | Purpose |
113
120
  |--------|---------|
114
- | `memorixRead` | Low-level read with entity context (Mongo default; optional Xronox) |
115
- | `readMemorixCollection` / `countMemorixCollection` / `connectMemorixMongo` | Direct Mongo helpers |
121
+ | `memorixRead` | Routed read via Xronox (entity context + collection + role) |
122
+ | `memorixCount` | Routed count via Xronox (`countDocuments` on adapter) |
123
+ | `readMemorixCollection` / `countMemorixCollection` / `connectMemorixMongo` | **Test-only** — not used by production inventory or list/item paths |
116
124
  | `resolveMemorixCollectionName` / `resolveMemorixDbNameForEntity` | Resolution utilities |
117
125
  | Env helpers: `resolveMemorixDbName`, `resolveMongoUri`, `targetCollectionEnvKey` | Advanced overrides |
118
126
 
119
- Pass `xronox` to `createMemorixRetrieval` only when injecting a pre-configured Xronox client.
127
+ Pass `mongo` to `createMemorixRetrieval` only for tests or legacy hosts. Production hosts should use `createMemorixRetrievalFromEnv` / `createMemorixRetrievalStackFromEnv` (Xronox data tier).
120
128
 
121
129
  ---
122
130
 
@@ -19,8 +19,22 @@ Uses `createCataloxFromEnv` + `createCataloxAdapterFromBound` + `createMemorixRe
19
19
  ## Entity discovery
20
20
 
21
21
  - `discoverMemorixEntities(client)` — lists `memorix-entity-descriptors` via Catalox only (`source: "catalox" | "none"`). No env entity list fallback.
22
- - `buildMemorixEntityGraph(client)` — discovery + per–content-type counts + **relations from entity descriptors**.
23
- - `buildMemorixEntitySlices(client, entityName)` — slice counts for canvas drill-down.
22
+ - `buildMemorixEntityGraph(client)` — discovery + per–content-type counts + **relations from entity descriptors**. Each entity includes `target`, `memorixDatabase`, and `contentTypes[]` (collection, database, count, status). `discovery.memorixDatabases` names both entity and event stores.
23
+ - `buildMemorixEntitySlices(client, entityName)` — slice counts for canvas drill-down; includes **all** declared content types (zero counts use `status: "empty"`).
24
+ - `buildMemorixCollectionInventory(client, options?)` — bidirectional Mongo ↔ Catalox inventory across both databases (`matched`, `empty`, `orphan`, `unresolved`). Options: `includeExactCounts`, `scopedNamespace`.
25
+ - `orphanNodesFromInventory(entries)` — group orphan inventory rows into graph nodes for Explorer entities canvas.
26
+
27
+ ## Collection inventory
28
+
29
+ Requires `@x12i/xronox` ≥ 3.9.0 (`listCollections`).
30
+
31
+ - Declared counts: `countMemorixEntityContentTypeDocuments` (Xronox)
32
+ - DB scan: `xronox.listCollections({ role })` for `memorix_entities` and `memorix_events`
33
+ - Orphan counts: `xronox.countDocuments({ estimated: true })`
34
+
35
+ Smoke: `npm run smoke:retrieval -- --inventory`
36
+
37
+ Response: `entries`, `summary.byTarget`, `discovery`.
24
38
 
25
39
  ## Raw collection reads (Explorer compatibility)
26
40
 
@@ -481,12 +481,16 @@ When `discovery.source` is `"none"`, returns empty rows with a hint — no env e
481
481
  5. Resolve `includeRelations` and optional full content fetches.
482
482
  6. Return `{ identity, sections, relations?, issues? }`.
483
483
 
484
- ### 5.6 Entity graph (Explorer)
484
+ ### 5.6 Entity graph and collection inventory (Explorer)
485
485
 
486
- `buildMemorixEntityGraph` uses discovery + entity descriptors only:
486
+ Retrieval exports (see [EXPLORER-HOST-APIS.md](./EXPLORER-HOST-APIS.md)):
487
487
 
488
- - Per entity: label, counts, content-type labels, **`relations` → connections**, default list/item ids.
489
- - `discovery.source` is `"catalox"` or `"none"` never `"env"`.
488
+ - `buildMemorixEntityGraph` — discovery + entity descriptors; per entity: label, counts, **`contentTypes[]`**, **`relations` → connections**, default list/item ids, `target`, `memorixDatabase`.
489
+ - `buildMemorixEntitySlices` all declared content types including zero counts.
490
+ - `buildMemorixCollectionInventory` — reconcile declared collections with Mongo in both databases.
491
+ - `orphanNodesFromInventory` — orphan groups for entities canvas.
492
+
493
+ `discovery.source` is `"catalox"` or `"none"` — never `"env"`. `discovery.memorixDatabases` names both entity and event stores.
490
494
 
491
495
  ---
492
496
 
@@ -0,0 +1,132 @@
1
+ # Xronox data tier requirements — `@x12i/memorix-retrieval`
2
+
3
+ **Audience:** `@x12i/xronox` maintainers
4
+ **Consumer:** `@x12i/memorix-retrieval` (v1.5+) and hosts (Memorix Explorer, APIs, tools)
5
+ **Status:** Active — open FRs in [`docs/fr/`](./fr/README.md). **No Mongo workarounds in production paths.**
6
+
7
+ Related docs:
8
+
9
+ - [DATA-TIER-CONTRACT.md](./DATA-TIER-CONTRACT.md) — public retrieval API
10
+ - [MEMORIX-DATABASE-CONVENTIONS.md](./MEMORIX-DATABASE-CONVENTIONS.md) — Mongo layout and env vars
11
+ - [MEMORIX-CATALOX-CONTRACTS.md](./MEMORIX-CATALOX-CONTRACTS.md) — descriptor metadata (Catalox, not Xronox)
12
+ - **[Feature requests for `@x12i/xronox`](./fr/README.md)** — implement here first; retrieval waits
13
+
14
+ ---
15
+
16
+ ## 1. Why Xronox is the Memorix data tier
17
+
18
+ Memorix separates **metadata** from **payload**:
19
+
20
+ | Layer | Package | Owns |
21
+ |-------|---------|------|
22
+ | Metadata | **Catalox** | Entity/list/item descriptors, discovery, column layout |
23
+ | Payload | **Xronox** | Routed Mongo reads/counts by role + collection |
24
+ | Composition | **memorix-retrieval** | Join descriptors + Xronox I/O → list/item rows |
25
+
26
+ Hosts must **not** connect to Mongo directly in production. Retrieval’s default bootstrap is:
27
+
28
+ ```ts
29
+ createMemorixRetrievalFromEnv({ catalox })
30
+ → createMemorixXronoxFromEnv()
31
+ → createMemorixXronoxAdapter(createXronox())
32
+ ```
33
+
34
+ All list/item/workspace reads and counts flow through Xronox routing.
35
+
36
+ ---
37
+
38
+ ## 2. Integration contract (today)
39
+
40
+ ### 2.1 Read routing key
41
+
42
+ Every Memorix Mongo read uses this Xronox routing shape:
43
+
44
+ ```ts
45
+ {
46
+ dataType: "metadata",
47
+ sourceType: "database",
48
+ subSourceType: "mongo",
49
+ role: "<xronox-role>",
50
+ source: "<collection-name>",
51
+ query?: Record<string, unknown>,
52
+ project?: string[],
53
+ sort?: string | string[] | Record<string, 1 | -1>,
54
+ limit?: number,
55
+ skip?: number,
56
+ }
57
+ ```
58
+
59
+ ### 2.2 Role mapping (Memorix target → Xronox role)
60
+
61
+ | Entity descriptor `target` | Memorix database (logical) | Default Xronox `role` (3.8+) |
62
+ |--------------------------|----------------------------|------------------------------|
63
+ | `"entity"` (default) | `memorix-entities` | `memorix_entities` |
64
+ | `"event"` | `memorix-events` | `memorix_events` |
65
+
66
+ Constants in retrieval: `DEFAULT_MEMORIX_XRONOX_ROLES` (`src/data/memorix-read.ts`).
67
+
68
+ ### 2.3 Operations retrieval performs via Xronox
69
+
70
+ | Operation | Retrieval API | Xronox usage | Blocked? |
71
+ |-----------|---------------|--------------|----------|
72
+ | Paginated list | `fetchMemorixList` | `read` / `readArray` | — |
73
+ | List total | `fetchMemorixList` | `countDocuments` | — |
74
+ | Entity graph counts | `buildMemorixEntityGraph` | `countDocuments` per content type | — |
75
+ | **Collection inventory scan** | `buildMemorixCollectionInventory` | **`listCollections` + `countDocuments`** | — (3.9.0+) |
76
+ | Raw explorer reads | `listMemorixEntityContentTypeDocuments` | `read` + `countDocuments` | — |
77
+ | Health | `getMemorixRetrievalHealth` | `selfTest` | Partial — [FR](./fr/xronox-fr-per-role-selftest.md) |
78
+
79
+ ---
80
+
81
+ ## 3. Shipped in Xronox (retrieval uses today)
82
+
83
+ | Capability | Xronox API | Since |
84
+ |------------|------------|-------|
85
+ | Routed read | `read` / `readArray` | 3.8+ |
86
+ | Routed count | `countDocuments` (incl. `estimated: true`) | 3.8+ |
87
+ | Offset pagination | `skip` + `limit` | 3.8+ |
88
+ | Object sort | `sort: Record<string, 1 \| -1>` | 3.8+ |
89
+ | Role-based DB routing | `role` on params | 3.8+ |
90
+ | Database collection listing | `listCollections({ role, source: "_db" })` | **3.9+** |
91
+ | Connectivity | `selfTest({ testConnectivity })` | 3.8+ |
92
+
93
+ ---
94
+
95
+ ## 4. Open — implement in Xronox (see FRs)
96
+
97
+ | Priority | FR | Blocks |
98
+ |----------|-----|--------|
99
+ | P1 | [Memorix env preset](./fr/xronox-fr-memorix-env-preset.md) | `MEMORIX_*_DB`-only zero-config |
100
+ | P2 | [Per-role selfTest](./fr/xronox-fr-per-role-selftest.md) | Health detail for both DBs |
101
+
102
+ ~~P0 listCollections~~ — **shipped 3.9.0**. See [FR](./fr/xronox-fr-list-collections.md).
103
+
104
+ **Do not** implement these in retrieval with `connectMemorixMongo` or other driver bypasses.
105
+
106
+ ---
107
+
108
+ ## 5. Retrieval policy (no workarounds)
109
+
110
+ | Rule | Detail |
111
+ |------|--------|
112
+ | Production I/O | Xronox only |
113
+ | `buildMemorixCollectionInventory` | Uses Xronox `listCollections` + `countDocuments` (requires `@x12i/xronox` ≥ 3.9.0) |
114
+ | Tests | Mock `xronox.listCollections` / inject test `mongo` only in unit tests — not production bootstrap |
115
+ | Explorer host shims | Delete `memorix-explorer/server/collection-inventory.ts` after bumping to retrieval 1.6.1+ |
116
+
117
+ ---
118
+
119
+ ## 6. Version alignment
120
+
121
+ | Package | Current | Notes |
122
+ |---------|---------|-------|
123
+ | `@x12i/memorix-retrieval` | 1.6.1 | Inventory via Xronox `listCollections` |
124
+ | `@x12i/xronox` | ^3.9.0 | `listCollections` required for inventory |
125
+
126
+ ---
127
+
128
+ ## 7. Out of scope for Xronox
129
+
130
+ Entity discovery, list columns, row composition, Catalox seed, orphan name parsing — stay in Catalox / memorix-retrieval.
131
+
132
+ Xronox remains a **database routing + I/O layer**, not Memorix-aware.
@@ -0,0 +1,15 @@
1
+ # Feature requests — `@x12i/xronox` (Memorix data tier)
2
+
3
+ **Audience:** `@x12i/xronox` maintainers
4
+ **Consumer:** `@x12i/memorix-retrieval`, Memorix Explorer, APIs, tools
5
+ **Policy:** Retrieval and hosts **must not** bypass Xronox with direct Mongo for production paths. Open FRs block retrieval features until Xronox ships the generic API.
6
+
7
+ | FR | Status | Blocks |
8
+ |----|--------|--------|
9
+ | [xronox-fr-list-collections.md](./xronox-fr-list-collections.md) | **Shipped** (`@x12i/xronox` 3.9.0) | — |
10
+ | [xronox-fr-memorix-env-preset.md](./xronox-fr-memorix-env-preset.md) | **Open** | Zero-config with `MEMORIX_*_DB` only |
11
+ | [xronox-fr-per-role-selftest.md](./xronox-fr-per-role-selftest.md) | **Open** | Health reporting both entity + event DBs |
12
+
13
+ **Already in Xronox 3.8+ (no FR):** `countDocuments`, `skip`, `sort` as Mongo object, `countDocuments({ estimated: true })`.
14
+
15
+ See also: [XRONOX-DATA-TIER-REQUIREMENTS.md](../XRONOX-DATA-TIER-REQUIREMENTS.md) (integration index).
@@ -0,0 +1,196 @@
1
+ # Feature request — routed `listCollections` (`@x12i/xronox`)
2
+
3
+ **Date:** 2026-05-22
4
+ **Status:** **Shipped** — `@x12i/xronox@3.9.0`
5
+ **Consumer:** `@x12i/memorix-retrieval@1.6.1+`
6
+
7
+ ---
8
+
9
+ ## Summary
10
+
11
+ Memorix **collection inventory** lists all Mongo collections in **both** Memorix databases (`memorix-entities`, `memorix-events`) using the same **role → database** routing as `read` and `countDocuments`. Implemented in Xronox 3.9.0; retrieval uses it with **no direct Mongo bypass**.
12
+
13
+ ---
14
+
15
+ ## Why this belongs in Xronox (not retrieval)
16
+
17
+ | Concern | Host/retrieval bypass problem |
18
+ |---------|-------------------------------|
19
+ | Role routing | Must use same `role` → DB resolution as reads (`memorix_entities`, `memorix_events`) |
20
+ | Multi-DB | Inventory scans **both** databases; routing must stay in Xronox |
21
+ | Contract | [DATA-TIER-CONTRACT.md](../DATA-TIER-CONTRACT.md): production I/O through Xronox only |
22
+ | Reuse | Any x12i app with role-based Mongo needs collection discovery, not only Memorix |
23
+
24
+ ---
25
+
26
+ ## Product requirement
27
+
28
+ Expose a routed API that returns collection names (and optional types) for the **database resolved from `role`**, without targeting a single collection in `source`.
29
+
30
+ Orphan scan flow (retrieval consumer):
31
+
32
+ 1. `listCollections({ role: "memorix_entities" })` → all non-system collections in entity DB
33
+ 2. `listCollections({ role: "memorix_events" })` → all non-system collections in event DB
34
+ 3. For each collection not in Catalox descriptor map: `countDocuments({ role, source: collectionName, estimated: true })` (already in Xronox 3.8+)
35
+
36
+ Declared slot counts continue to use descriptor-routed `countDocuments` via `countMemorixEntityContentTypeDocuments` (retrieval).
37
+
38
+ ---
39
+
40
+ ## Proposed API
41
+
42
+ ```ts
43
+ listCollections(params: ListCollectionsParams): Promise<ListCollectionsResult>;
44
+
45
+ export interface ListedCollection {
46
+ name: string;
47
+ type?: string; // "collection" | "view" | ...
48
+ }
49
+
50
+ export interface ListCollectionsResult {
51
+ /** Resolved database name after role + tenancy (same as countDocuments/read) */
52
+ database: string;
53
+ collections: ListedCollection[];
54
+ }
55
+
56
+ export interface ListCollectionsParams extends RoutingKey {
57
+ subSourceType: "mongo";
58
+ /**
59
+ * Binding match token only — not a collection name.
60
+ * Zero-config bindings with no `match` accept any source (e.g. `"_db"`).
61
+ */
62
+ source: string;
63
+ role?: string;
64
+ /** Forwarded to Mongo db.listCollections({ filter }) */
65
+ filter?: Record<string, unknown>;
66
+ /** Default true — omit names starting with `system.` */
67
+ excludeSystem?: boolean;
68
+ /** Default true — use driver nameOnly for lighter responses */
69
+ nameOnly?: boolean;
70
+ }
71
+ ```
72
+
73
+ Add to `Xronox` interface and `Engine` (nxMongo engine only; xronoxCore may omit like `countDocuments`).
74
+
75
+ ---
76
+
77
+ ## Algorithm (normative)
78
+
79
+ 1. `resolveBinding(config, params)` — **same as `countDocuments` and `read`**.
80
+ 2. Resolve `connection` → `SimpleMongoHelper`.
81
+ 3. Resolve `db` from binding + `params.role` (role overrides binding default db).
82
+ 4. `sanitizeDatabaseName(db)` — same as existing count path.
83
+ 5. `mongoDb.listCollections(filter, { nameOnly })`.
84
+ 6. If `excludeSystem !== false`, filter out `system.*` names.
85
+ 7. Return `{ database: db, collections }`.
86
+
87
+ **Do not** use `params.source` as a collection name. `source` exists only for binding selection.
88
+
89
+ ---
90
+
91
+ ## Example calls (Memorix)
92
+
93
+ ```ts
94
+ // Entity store
95
+ const entityDb = await xronox.listCollections({
96
+ dataType: "metadata",
97
+ sourceType: "database",
98
+ subSourceType: "mongo",
99
+ source: "_db",
100
+ role: "memorix_entities",
101
+ });
102
+
103
+ // Event store
104
+ const eventDb = await xronox.listCollections({
105
+ dataType: "metadata",
106
+ sourceType: "database",
107
+ subSourceType: "mongo",
108
+ source: "_db",
109
+ role: "memorix_events",
110
+ });
111
+
112
+ // Orphan count (existing API)
113
+ const count = await xronox.countDocuments({
114
+ dataType: "metadata",
115
+ sourceType: "database",
116
+ subSourceType: "mongo",
117
+ role: "memorix_entities",
118
+ source: "orphan-entity-records",
119
+ estimated: true,
120
+ });
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Implementation guidance (`@x12i/xronox`)
126
+
127
+ | Layer | Change |
128
+ |-------|--------|
129
+ | `src/types.ts` | `ListCollectionsParams`, `ListCollectionsResult`, `ListedCollection`; extend `Xronox` |
130
+ | `src/engines/interface.ts` | `listCollections?(params, resolved)` |
131
+ | `src/engines/nxMongoEngine.ts` | Implement via `getDatabase` / `listCollections` (same helper lookup as `countDocuments`) |
132
+ | `src/index.ts` | `XronoxImpl.listCollections` → `resolveBinding` → engine |
133
+ | `README.md` | Document next to `countDocuments` example |
134
+ | Tests | Routing unit test (no Mongo); optional integration test with fixture DB |
135
+
136
+ Mirror error codes from count path: `CONNECTION_NOT_FOUND`, `DATABASE_NOT_RESOLVED`, `ROUTING_NOT_FOUND`.
137
+
138
+ ---
139
+
140
+ ## Retrieval integration (after Xronox ships)
141
+
142
+ | Step | Action |
143
+ |------|--------|
144
+ | 1 | Bump `@x12i/xronox` minimum (e.g. `^3.9.0`) |
145
+ | 2 | Extend `XronoxLike` + adapter to delegate `listCollections` |
146
+ | 3 | `buildMemorixCollectionInventory` calls Xronox only — **throws** if `listCollections` missing |
147
+ | 4 | Delete Explorer host shim `server/collection-inventory.ts` |
148
+ | 5 | `npm run smoke:retrieval -- --inventory` |
149
+
150
+ **No Mongo fallback in retrieval.** Tests may inject a mock `xronox` with `listCollections`; production requires real Xronox.
151
+
152
+ ---
153
+
154
+ ## Acceptance criteria
155
+
156
+ ### Xronox
157
+
158
+ - [ ] `listCollections({ role: "memorix_entities" })` returns collections from `MEMORIX_ENTITIES_DB` / role map default
159
+ - [ ] `listCollections({ role: "memorix_events" })` returns collections from events DB
160
+ - [ ] `excludeSystem: true` (default) omits `system.*`
161
+ - [ ] `database` in result matches DB used for `countDocuments` on same role + collection
162
+ - [ ] Wrong/missing role → typed routing error (not empty list)
163
+ - [ ] nxMongo engine only; clear error on xronoxCore
164
+
165
+ ### Retrieval (downstream)
166
+
167
+ - [ ] `buildMemorixCollectionInventory` completes without `connectMemorixMongo`
168
+ - [ ] Inventory `summary.byTarget` matches entries filtered by `target`
169
+ - [ ] Vitest mocks `xronox.listCollections` only (no Mongo client for scan)
170
+
171
+ ---
172
+
173
+ ## Non-goals
174
+
175
+ | Item | Reason |
176
+ |------|--------|
177
+ | Catalox orphan → descriptor seeding | Ops / Catalox tooling |
178
+ | Memorix-specific parsing in Xronox | Stays in retrieval (`parseOrphanCollection`) |
179
+ | List documents across all collections | Use inventory + per-collection `read` |
180
+
181
+ ---
182
+
183
+ ## Version
184
+
185
+ | Package | Minimum after FR |
186
+ |---------|------------------|
187
+ | `@x12i/xronox` | `3.9.0` (proposed minor) |
188
+ | `@x12i/memorix-retrieval` | Requires published Xronox with this FR |
189
+
190
+ ---
191
+
192
+ ## References
193
+
194
+ - Retrieval inventory: `src/explorer/collection-inventory.ts`
195
+ - Role constants: `src/data/memorix-read.ts` (`DEFAULT_MEMORIX_XRONOX_ROLES`)
196
+ - Explorer shim (delete after ship): `memorix-explorer/server/collection-inventory.ts`
@@ -0,0 +1,69 @@
1
+ # Feature request — Memorix deployment preset / env aliases (`@x12i/xronox`)
2
+
3
+ **Date:** 2026-05-22
4
+ **Status:** **Open**
5
+ **Requested by:** `@x12i/memorix-retrieval`, Memorix Explorer smoke scripts
6
+ **Target package:** `@x12i/xronox`
7
+ **Priority:** P1 (ergonomics — not blocking inventory if roles + DB vars are set explicitly)
8
+
9
+ ---
10
+
11
+ ## Summary
12
+
13
+ Memorix documents **`MEMORIX_ENTITIES_DB`** and **`MEMORIX_EVENTS_DB`**. Xronox zero-config resolves databases via **`MONGO_OPERATIONAL_DB`**, **`MONGO_LOGS_DB`**, and role maps (`memorix_entities`, `memorix_events`). Deployments must duplicate env vars today.
14
+
15
+ This FR aligns Xronox zero-config with Memorix conventions so smoke and Explorer work with **`MONGO_URI` + `MEMORIX_*_DB` only**.
16
+
17
+ ---
18
+
19
+ ## Product requirement
20
+
21
+ When resolving Mongo database names for roles:
22
+
23
+ | Xronox role | Memorix target | Fallback chain should include |
24
+ |-------------|----------------|------------------------------|
25
+ | `memorix_entities` / `memory.entities` / `operational` | `entity` | `MEMORIX_ENTITIES_DB` → `memorix-entities` |
26
+ | `memorix_events` / `memory.events` / `logs` | `event` | `MEMORIX_EVENTS_DB` → `memorix-events` |
27
+
28
+ ---
29
+
30
+ ## Proposed options (pick one or both)
31
+
32
+ ### Option A — Env aliases in role resolution
33
+
34
+ In `resolveDatabaseNameFromRole` / `MONGO_ROLE_MAP` fallback chains:
35
+
36
+ ```
37
+ memorix_entities.database ← MEMORIX_ENTITIES_DB ← MONGO_OPERATIONAL_DB ← MONGO_DB
38
+ memorix_events.database ← MEMORIX_EVENTS_DB ← MONGO_LOGS_DB ← MONGO_DB
39
+ ```
40
+
41
+ ### Option B — Zero-config preset
42
+
43
+ ```ts
44
+ await xronox.init({ engine: "nxMongo", preset: "memorix", zeroConfig: true });
45
+ ```
46
+
47
+ Preset registers role map defaults and env aliases above. Document in Xronox README + `.env.example`.
48
+
49
+ ---
50
+
51
+ ## Acceptance criteria
52
+
53
+ - [ ] `npm run smoke:retrieval` in memorix-retrieval succeeds with only `MONGO_URI`, `MEMORIX_ENTITIES_DB`, `MEMORIX_EVENTS_DB`, Catalox creds
54
+ - [ ] No requirement to set `MONGO_OPERATIONAL_DB` / `MONGO_LOGS_DB` for Memorix deployments
55
+ - [ ] Existing non-Memorix zero-config behavior unchanged when preset not used
56
+
57
+ ---
58
+
59
+ ## Retrieval integration (after ship)
60
+
61
+ - Optionally simplify `createMemorixXronoxFromEnv` to pass `preset: "memorix"`.
62
+ - Update [MEMORIX-DATABASE-CONVENTIONS.md](../MEMORIX-DATABASE-CONVENTIONS.md) with single env table.
63
+
64
+ ---
65
+
66
+ ## Non-goals
67
+
68
+ - Catalox or descriptor env (stays in `@x12i/catalox`)
69
+ - Changing Memorix collection naming (retrieval + Catalox)
@@ -0,0 +1,60 @@
1
+ # Feature request — per-role `selfTest` detail (`@x12i/xronox`)
2
+
3
+ **Date:** 2026-05-22
4
+ **Status:** **Open**
5
+ **Requested by:** `@x12i/memorix-retrieval` (`getMemorixRetrievalHealth`)
6
+ **Target package:** `@x12i/xronox`
7
+ **Priority:** P2 (health UX — not blocking lists or inventory)
8
+
9
+ ---
10
+
11
+ ## Summary
12
+
13
+ Memorix runs **two** Mongo databases (entity + event). Health checks should report connectivity **per role**, not a single anonymous ping. Retrieval already passes `selfTestRoles: ["memorix_entities", "memorix_events"]` to the adapter when Xronox supports it.
14
+
15
+ ---
16
+
17
+ ## Product requirement
18
+
19
+ Extend `selfTest` result so hosts can show which Memorix store failed:
20
+
21
+ ```ts
22
+ type SelfTestResult = {
23
+ passed: boolean;
24
+ roles?: Array<{
25
+ role: string;
26
+ db: string;
27
+ ok: boolean;
28
+ latencyMs?: number;
29
+ error?: string;
30
+ }>;
31
+ };
32
+ ```
33
+
34
+ ```ts
35
+ await xronox.selfTest({
36
+ testConnectivity: true,
37
+ selfTestRoles: ["memorix_entities", "memorix_events"],
38
+ });
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Acceptance criteria
44
+
45
+ - [ ] Each role resolves DB name and attempts connectivity (e.g. listCollections or count on a lightweight op)
46
+ - [ ] `passed: false` if any requested role fails
47
+ - [ ] Works with Memorix env vars when [memorix-env-preset FR](./xronox-fr-memorix-env-preset.md) is also applied (or explicit DB vars)
48
+
49
+ ---
50
+
51
+ ## Retrieval integration (after ship)
52
+
53
+ - `getMemorixRetrievalHealth` surfaces per-role results in response (optional field)
54
+ - Remove direct Mongo ping fallback from health when Xronox reports both roles
55
+
56
+ ---
57
+
58
+ ## Non-goals
59
+
60
+ - Descriptor / Catalox health (retrieval discovers Catalox separately)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x12i/memorix-retrieval",
3
- "version": "1.5.0",
3
+ "version": "1.6.2",
4
4
  "description": "Descriptor-driven Memorix retrieval layer for lists, items, and content objects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,18 +30,9 @@
30
30
  "node": ">=18.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "@x12i/catalox": "^4.1.2",
33
+ "@x12i/catalox": "^5.0.0",
34
34
  "@x12i/helpers": "^1.7.0",
35
- "@x12i/memorix-retrieval": "^1.4.0",
36
- "mongodb": "^6.21.0"
37
- },
38
- "peerDependencies": {
39
- "@x12i/xronox": ">=3.7.0"
40
- },
41
- "peerDependenciesMeta": {
42
- "@x12i/xronox": {
43
- "optional": true
44
- }
35
+ "@x12i/xronox": "^3.9.0"
45
36
  },
46
37
  "devDependencies": {
47
38
  "@types/node": "^20.14.0",