@x12i/memorix-descriptors 0.1.0

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 (96) hide show
  1. package/README.md +96 -0
  2. package/dist/admin/create-admin.d.ts +74 -0
  3. package/dist/admin/create-admin.d.ts.map +1 -0
  4. package/dist/admin/create-admin.js +102 -0
  5. package/dist/admin/create-admin.js.map +1 -0
  6. package/dist/catalog/ids.d.ts +12 -0
  7. package/dist/catalog/ids.d.ts.map +1 -0
  8. package/dist/catalog/ids.js +32 -0
  9. package/dist/catalog/ids.js.map +1 -0
  10. package/dist/catalox/client.d.ts +19 -0
  11. package/dist/catalox/client.d.ts.map +1 -0
  12. package/dist/catalox/client.js +51 -0
  13. package/dist/catalox/client.js.map +1 -0
  14. package/dist/cli/index.d.ts +3 -0
  15. package/dist/cli/index.d.ts.map +1 -0
  16. package/dist/cli/index.js +191 -0
  17. package/dist/cli/index.js.map +1 -0
  18. package/dist/collections/env-bridge.d.ts +3 -0
  19. package/dist/collections/env-bridge.d.ts.map +1 -0
  20. package/dist/collections/env-bridge.js +8 -0
  21. package/dist/collections/env-bridge.js.map +1 -0
  22. package/dist/collections/resolve.d.ts +20 -0
  23. package/dist/collections/resolve.d.ts.map +1 -0
  24. package/dist/collections/resolve.js +49 -0
  25. package/dist/collections/resolve.js.map +1 -0
  26. package/dist/index.d.ts +11 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +9 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/integrity/graph.d.ts +19 -0
  31. package/dist/integrity/graph.d.ts.map +1 -0
  32. package/dist/integrity/graph.js +65 -0
  33. package/dist/integrity/graph.js.map +1 -0
  34. package/dist/integrity/validate.d.ts +4 -0
  35. package/dist/integrity/validate.d.ts.map +1 -0
  36. package/dist/integrity/validate.js +278 -0
  37. package/dist/integrity/validate.js.map +1 -0
  38. package/dist/mutations/common.d.ts +9 -0
  39. package/dist/mutations/common.d.ts.map +1 -0
  40. package/dist/mutations/common.js +108 -0
  41. package/dist/mutations/common.js.map +1 -0
  42. package/dist/mutations/content-type.d.ts +21 -0
  43. package/dist/mutations/content-type.d.ts.map +1 -0
  44. package/dist/mutations/content-type.js +278 -0
  45. package/dist/mutations/content-type.js.map +1 -0
  46. package/dist/mutations/entity.d.ts +21 -0
  47. package/dist/mutations/entity.d.ts.map +1 -0
  48. package/dist/mutations/entity.js +276 -0
  49. package/dist/mutations/entity.js.map +1 -0
  50. package/dist/mutations/item.d.ts +16 -0
  51. package/dist/mutations/item.d.ts.map +1 -0
  52. package/dist/mutations/item.js +131 -0
  53. package/dist/mutations/item.js.map +1 -0
  54. package/dist/mutations/list.d.ts +16 -0
  55. package/dist/mutations/list.d.ts.map +1 -0
  56. package/dist/mutations/list.js +143 -0
  57. package/dist/mutations/list.js.map +1 -0
  58. package/dist/mutations/mapping.d.ts +12 -0
  59. package/dist/mutations/mapping.d.ts.map +1 -0
  60. package/dist/mutations/mapping.js +104 -0
  61. package/dist/mutations/mapping.js.map +1 -0
  62. package/dist/mutations/property.d.ts +18 -0
  63. package/dist/mutations/property.d.ts.map +1 -0
  64. package/dist/mutations/property.js +256 -0
  65. package/dist/mutations/property.js.map +1 -0
  66. package/dist/mutations/relation.d.ts +31 -0
  67. package/dist/mutations/relation.d.ts.map +1 -0
  68. package/dist/mutations/relation.js +195 -0
  69. package/dist/mutations/relation.js.map +1 -0
  70. package/dist/reconcile/index.d.ts +29 -0
  71. package/dist/reconcile/index.d.ts.map +1 -0
  72. package/dist/reconcile/index.js +58 -0
  73. package/dist/reconcile/index.js.map +1 -0
  74. package/dist/seeds/index.d.ts +33 -0
  75. package/dist/seeds/index.d.ts.map +1 -0
  76. package/dist/seeds/index.js +186 -0
  77. package/dist/seeds/index.js.map +1 -0
  78. package/dist/store/snapshot.d.ts +6 -0
  79. package/dist/store/snapshot.d.ts.map +1 -0
  80. package/dist/store/snapshot.js +49 -0
  81. package/dist/store/snapshot.js.map +1 -0
  82. package/dist/tests/validation.test.d.ts +2 -0
  83. package/dist/tests/validation.test.d.ts.map +1 -0
  84. package/dist/tests/validation.test.js +114 -0
  85. package/dist/tests/validation.test.js.map +1 -0
  86. package/dist/types/index.d.ts +151 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/index.js +2 -0
  89. package/dist/types/index.js.map +1 -0
  90. package/dist/validation/descriptor-validation.d.ts +20 -0
  91. package/dist/validation/descriptor-validation.d.ts.map +1 -0
  92. package/dist/validation/descriptor-validation.js +148 -0
  93. package/dist/validation/descriptor-validation.js.map +1 -0
  94. package/docs/MEMORIX-CATALOX-CONTRACTS.md +591 -0
  95. package/docs/MEMORIX-DATABASE-CONVENTIONS.md +338 -0
  96. package/package.json +43 -0
@@ -0,0 +1,338 @@
1
+ # Memorix Database Conventions
2
+
3
+ This document defines the shared MongoDB naming and layout conventions for Memorix. All services, pipelines, and tools in the x12i ecosystem should follow these rules so entity data, event data, and source enrichment stay consistent across peers.
4
+
5
+ ## Overview
6
+
7
+ Memorix uses **three logical database roles**:
8
+
9
+ | Role | Purpose | Default database name |
10
+ |------|---------|------------------------|
11
+ | **Entities** | Canonical entity records (vulnerabilities, assets, groups, …) | `memorix-entities` |
12
+ | **Events** | Event records derived from or linked to entities | `memorix-events` |
13
+ | **Source** | Upstream operational / enrichment data used to extend Memorix records | *(environment-specific)* |
14
+
15
+ All three may live on the **same MongoDB cluster** (single `MONGO_URI`). They are separated by **database name**, not by connection string.
16
+
17
+ ### Simple mode (default)
18
+
19
+ Most peers only need:
20
+
21
+ ```bash
22
+ MONGO_URI=mongodb://localhost:27017
23
+ ```
24
+
25
+ Packages resolve `memorix-entities`, `memorix-events`, collection names, and entity vs event routing internally. Override with `MEMORIX_ENTITIES_DB`, `MEMORIX_EVENTS_DB`, or per-type collection env vars only when required.
26
+
27
+ ```
28
+ ┌─────────────────────────────────────────────────────────────┐
29
+ │ MongoDB cluster │
30
+ │ ┌──────────────────┐ ┌──────────────────┐ │
31
+ │ │ memorix-entities │ │ memorix-events │ ← Memorix │
32
+ │ │ vulnerabilities │ │ vulnerability- │ targets │
33
+ │ │ assets │ │ events │ │
34
+ │ └────────▲─────────┘ └────────▲─────────┘ │
35
+ │ │ │ │
36
+ │ └───────────┬───────────┘ │
37
+ │ │ join / enrich │
38
+ │ ┌────────▼─────────┐ │
39
+ │ │ source-db │ ← source databases │
40
+ │ │ *-information │ │
41
+ │ └──────────────────┘ │
42
+ └─────────────────────────────────────────────────────────────┘
43
+ ```
44
+
45
+ ## Target types
46
+
47
+ Every Memorix record belongs to exactly one **target**:
48
+
49
+ | Target | Database | Typical use |
50
+ |--------|----------|-------------|
51
+ | `entity` | `memorix-entities` | Stable domain objects (vulnerability, asset, group, …) |
52
+ | `event` | `memorix-events` | Occurrences, detections, or timeline entries |
53
+
54
+ Tools must declare which target they read or write. Do not mix entity and event documents in the same collection.
55
+
56
+ ## Environment variables
57
+
58
+ ### Connection
59
+
60
+ | Variable | Aliases | Required | Description |
61
+ |----------|---------|----------|-------------|
62
+ | `MONGO_URI` | `MONGO_CONNECTION_STRING` | Yes | MongoDB connection string for the cluster |
63
+
64
+ ### Memorix target databases
65
+
66
+ Resolution order matters: **first non-empty value wins**.
67
+
68
+ #### Entity database (`target: entity`)
69
+
70
+ | Priority | Variable |
71
+ |----------|----------|
72
+ | 1 | `MEMORIX_ENTITIES_DB` |
73
+ | 2 | `MEMORIX_DB_ENTITIES` |
74
+ | 3 | `memorix_entities_db` |
75
+ | 4 | `MEMORIX_DB` *(legacy fallback)* |
76
+ | 5 | **Default:** `memorix-entities` |
77
+
78
+ #### Event database (`target: event`)
79
+
80
+ | Priority | Variable |
81
+ |----------|----------|
82
+ | 1 | `MEMORIX_EVENTS_DB` |
83
+ | 2 | `MEMORIX_DB_EVENTS` |
84
+ | 3 | `memorix_events_db` |
85
+ | 4 | `MEMORIX_DB` *(legacy fallback)* |
86
+ | 5 | **Default:** `memorix-events` |
87
+
88
+ > **Peer rule:** Prefer `MEMORIX_ENTITIES_DB` and `MEMORIX_EVENTS_DB`. Treat `MEMORIX_DB` as a legacy single-database override only.
89
+
90
+ #### Neo / non-default deployments
91
+
92
+ Some clusters store Memorix data under non-default database names (for example `memorix-neo-entities` / `memorix-neo-events` instead of `memorix-entities` / `memorix-events`). Set:
93
+
94
+ ```bash
95
+ MEMORIX_ENTITIES_DB=memorix-neo-entities
96
+ MEMORIX_EVENTS_DB=memorix-neo-events
97
+ ```
98
+
99
+ `@x12i/memorix-retrieval` bridges these into Xronox role DB vars on bootstrap (`MONGO_MEMORY_ENTITIES_DB`, `MONGO_MEMORY_EVENTS_DB`, …) via `syncMemorixEnvToXronox` / `createMemorixXronoxFromEnv`. Host apps only need the Memorix vars unless they intentionally override Xronox role env directly.
100
+
101
+ **Record counts** for entities like `assets` come from the **snapshots** content type (`assets-snapshots` collection). See [EXPLORER-HOST-APIS.md](./EXPLORER-HOST-APIS.md#snapshot-record-counts-explorer-records).
102
+
103
+ ### Source databases
104
+
105
+ Source databases hold upstream data that Memorix tools use to **fill in or extend** entity/event `data` fields. They are never the write target for completion pipelines.
106
+
107
+ | Priority | Variable | Description |
108
+ |----------|----------|-------------|
109
+ | 1 | `MEMORIX_SOURCE_DB` | Preferred default source database name |
110
+ | 2 | `SOURCE_DATABASE_NAME` | Alternative default |
111
+ | 3 | `SOURCEDATABASENAME` / `sourceDatabaseName` / `source_database_name` | Legacy aliases |
112
+
113
+ Per-job overrides are allowed via mapping config or application code. When using JSON mappings with `@x12i/env-tokens`, reference env vars as `"databaseName": "{{ENV.sourceDatabaseName}}"`.
114
+
115
+ ### Collection overrides (per entity type)
116
+
117
+ Normalize `entityType` by replacing `-` with `_` and uppercasing.
118
+
119
+ | Target | Env key pattern | Example (`entityType: vulnerability`) |
120
+ |--------|-----------------|----------------------------------------|
121
+ | `entity` | `MEMORIX_ENTITIES_COLLECTION_<ENTITY_TYPE>` | `MEMORIX_ENTITIES_COLLECTION_VULNERABILITY` |
122
+ | `event` | `MEMORIX_EVENTS_COLLECTION_<ENTITY_TYPE>` | `MEMORIX_EVENTS_COLLECTION_VULNERABILITY` |
123
+
124
+ ## Collection naming
125
+
126
+ ### Memorix entity collections (`memorix-entities`)
127
+
128
+ Use **plural, kebab-case** collection names that describe the entity domain.
129
+
130
+ | `entityType` | Recommended collection | Accepted fallbacks |
131
+ |--------------|------------------------|--------------------|
132
+ | `vulnerability` | `vulnerabilities` | `vulnerability` |
133
+ | `variabilities-group` | `vulnerability-groups` | `vulnerabilities-groups`, `variabilities-groups` |
134
+ | `assets` | `assets` | — |
135
+
136
+ **Default heuristic** when nothing else is configured:
137
+
138
+ ```
139
+ <entityType> → e.g. vulnerability
140
+ ```
141
+
142
+ Prefer explicit names in config over heuristics.
143
+
144
+ ### Memorix event collections (`memorix-events`)
145
+
146
+ Use `<domain>-events` or `<domain>s-events`.
147
+
148
+ | `entityType` | Recommended collection | Accepted fallbacks |
149
+ |--------------|------------------------|--------------------|
150
+ | `vulnerability` | `vulnerability-events` | `vulnerabilities-events` |
151
+ | `assets` | `asset-events` | `assets-events` |
152
+
153
+ **Default heuristic:**
154
+
155
+ ```
156
+ <entityType>-events → e.g. vulnerability-events
157
+ ```
158
+
159
+ ### Source collections
160
+
161
+ Source collections typically use an **`-information`** suffix to distinguish them from Memorix canonical stores:
162
+
163
+ | Source collection | Feeds entity type | Notes |
164
+ |-------------------|-------------------|-------|
165
+ | `vulnerabilities-information` | `vulnerability` | Raw / enriched vulnerability facts |
166
+ | `vulnerability-groups-information` | `variabilities-group` | Group-level enrichment |
167
+ | `assets-information` | `assets` | Asset metadata |
168
+
169
+ **Peer rule:** Source collection names are referenced in `targetSelector.sourceCollection` on Memorix records and in completion mappings. Keep these strings stable — they are the join key for mapping selection.
170
+
171
+ ## Collection name resolution order
172
+
173
+ When a tool needs to pick a Memorix collection, resolve in this order:
174
+
175
+ 1. Explicit override (CLI flag, API option, or code parameter)
176
+ 2. Mapping / config field `targetCollection`
177
+ 3. Environment variable (`MEMORIX_ENTITIES_COLLECTION_*` or `MEMORIX_EVENTS_COLLECTION_*`)
178
+ 4. `targetCollectionCandidates` from mapping config
179
+ 5. Built-in defaults for known `entityType` values (see tables above)
180
+ 6. Heuristic default (`<entityType>` or `<entityType>-events`)
181
+ 7. Verify the collection exists in the target database; fail clearly if not
182
+
183
+ All peers should implement the same precedence so local, CI, and production behave identically given the same env.
184
+
185
+ ## Document shape
186
+
187
+ ### Memorix entity / event document
188
+
189
+ Documents in `memorix-entities` and `memorix-events` share this layout:
190
+
191
+ ```json
192
+ {
193
+ "_id": "<ObjectId>",
194
+ "recordId": "<optional stable id>",
195
+ "entityId": "<for entity records>",
196
+ "eventId": "<for event records>",
197
+ "capturedAt": "<ISO-8601 timestamp>",
198
+ "data": {
199
+ "... domain fields ..."
200
+ }
201
+ }
202
+ ```
203
+
204
+ | Field | Entity | Event | Notes |
205
+ |-------|--------|-------|-------|
206
+ | `_id` | Required | Required | MongoDB primary key |
207
+ | `recordId` | Recommended | Recommended | Logical id; falls back to `_id` string |
208
+ | `entityId` | Required* | Optional | Join key for entity completion |
209
+ | `eventId` | — | Required* | Join key for event completion |
210
+ | `data` | Required | Required | Payload; completion writes here |
211
+ | `modifiedAt` | Optional | Optional | Set by writers on update (ISO-8601) |
212
+
213
+ \*Required for completion pipelines that match on these paths.
214
+
215
+ Legacy field `snapshotId` is still read as a fallback for `recordId` but **must not** be written by new code.
216
+
217
+ ### Provenance (logical, not always stored)
218
+
219
+ Completion and ingestion tools track provenance in memory using:
220
+
221
+ | Field | Description |
222
+ |-------|-------------|
223
+ | `sourceCollection` | Which source collection this record was enriched from |
224
+ | `sourceDatabase` | Source database name |
225
+ | `sourceId` | Id in the source system |
226
+ | `idField` | Which id field was used when the record was created |
227
+
228
+ These align with `targetSelector` in completion mappings.
229
+
230
+ ### Source document
231
+
232
+ Source documents are ordinary MongoDB documents in the source database. There is no required Memorix envelope — tools match on configured paths (e.g. `vulnerabilityId`, `ip_address`).
233
+
234
+ Do **not** write completion results back to source collections unless a separate, explicit pipeline owns that source.
235
+
236
+ ## Entity types
237
+
238
+ `entityType` is a **kebab-case** string identifying the domain object:
239
+
240
+ ```
241
+ vulnerability
242
+ variabilities-group
243
+ assets
244
+ ```
245
+
246
+ Rules:
247
+
248
+ - Use lowercase letters and hyphens only.
249
+ - One `entityType` maps to one primary entity collection and optionally one event collection.
250
+ - Env vars and config keys derive from `entityType` by replacing `-` with `_` and uppercasing.
251
+
252
+ ## Completion mapping conventions
253
+
254
+ Tools that enrich Memorix from source data (e.g. `@x12i/memorix-completion`) use JSON mappings with these conventions:
255
+
256
+ ```json
257
+ {
258
+ "name": "complete-vulnerability-entity-missing-data",
259
+ "entityType": "vulnerability",
260
+ "target": "entity",
261
+ "targetCollection": "vulnerabilities",
262
+ "targetSelector": {
263
+ "sourceCollection": "vulnerabilities-information",
264
+ "idField": "vulnerabilityId"
265
+ },
266
+ "source": {
267
+ "databaseName": "{{ENV.sourceDatabaseName}}",
268
+ "collection": "vulnerabilities-information"
269
+ },
270
+ "match": {
271
+ "targetPath": "entityId",
272
+ "sourcePath": "vulnerabilityId"
273
+ },
274
+ "writeRoot": "data",
275
+ "fields": [
276
+ { "sourcePath": "enrichment", "targetPath": "enrichment" }
277
+ ]
278
+ }
279
+ ```
280
+
281
+ | Field | Convention |
282
+ |-------|------------|
283
+ | `target` | `"entity"` or `"event"` — selects Memorix database |
284
+ | `targetCollection` | Explicit Memorix collection (recommended) |
285
+ | `targetSelector.sourceCollection` | Must match record's source lineage |
286
+ | `source.databaseName` | Source DB; use `{{ENV.*}}` for env-driven deploys |
287
+ | `source.collection` | Source collection to read from |
288
+ | `match.targetPath` | Path on Memorix record (usually `entityId` or `eventId`) |
289
+ | `match.sourcePath` | Path on source document |
290
+ | `writeRoot` | Always `"data"` — never overwrite envelope fields via completion |
291
+
292
+ Default completion mode: **fill missing fields only** (`onlyFillMissing: true`, `overwriteExisting: false`).
293
+
294
+ ## `.env` example
295
+
296
+ ```bash
297
+ # Cluster
298
+ MONGO_URI=mongodb://localhost:27017
299
+
300
+ # Memorix targets (defaults shown — omit to use defaults)
301
+ MEMORIX_ENTITIES_DB=memorix-entities
302
+ MEMORIX_EVENTS_DB=memorix-events
303
+
304
+ # Source database for enrichment pipelines
305
+ MEMORIX_SOURCE_DB=poc-data-mapping
306
+ # or: SOURCE_DATABASE_NAME=poc-data-mapping
307
+
308
+ # Optional per-type collection overrides
309
+ MEMORIX_ENTITIES_COLLECTION_VULNERABILITY=vulnerabilities
310
+ MEMORIX_EVENTS_COLLECTION_VULNERABILITY=vulnerability-events
311
+ ```
312
+
313
+ ## Checklist for new peers
314
+
315
+ When building a new service or tool that touches Memorix:
316
+
317
+ - [ ] Connect with `MONGO_URI` / `MONGO_CONNECTION_STRING`
318
+ - [ ] Select database via `target`: `entity` → `memorix-entities`, `event` → `memorix-events`
319
+ - [ ] Respect env precedence documented above
320
+ - [ ] Use recommended collection names or set explicit env overrides
321
+ - [ ] Store domain payload under `data`
322
+ - [ ] Read enrichment from source databases; write only to Memorix target databases
323
+ - [ ] Use stable `sourceCollection` strings for mapping / provenance
324
+ - [ ] Use kebab-case `entityType` values consistently
325
+ - [ ] Fail with a clear error when a collection cannot be resolved
326
+
327
+ ## Reference implementation
328
+
329
+ Shared env resolution is mirrored across peers:
330
+
331
+ | Concern | Module |
332
+ |---------|--------|
333
+ | Database name from env | `@x12i/memorix-completion` / `@x12i/memorix-retrieval` → `src/mongo/env.ts` → `resolveMemorixDbName`, `resolveDefaultSourceDbName` |
334
+ | Completion collection resolution | `@x12i/memorix-completion` → `src/mongo/resolve-collection.ts` → `resolveTargetCollectionName` |
335
+ | Retrieval collection resolution | `@x12i/memorix-retrieval` → `src/data/collection-name.ts` → `resolveMemorixCollectionName` (descriptor + env override + prefix/postfix heuristic) |
336
+ | Record document shape | `@x12i/memorix-completion` → `src/types.ts` → `MemorixRecord`, `CompletionMapping` |
337
+
338
+ If this document and a package disagree, **update this document and the package together** — they are intended to stay in sync.
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@x12i/memorix-descriptors",
3
+ "version": "0.1.0",
4
+ "description": "Manage Memorix entity, list, and item descriptors in Catalox",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "memorix-descriptors": "./dist/cli/index.js"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "docs"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "test": "vitest run",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "engines": {
27
+ "node": ">=18.0.0"
28
+ },
29
+ "dependencies": {
30
+ "@x12i/catalox": ">=5.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.14.0",
34
+ "@x12i/catalox": "^5.0.0",
35
+ "@x12i/memorix-retrieval": "file:../memorix-retrieval",
36
+ "@x12i/xronox": "^3.9.0",
37
+ "typescript": "^5.6.0",
38
+ "vitest": "^2.1.0"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ }
43
+ }