@x12i/memorix-format 2.0.0 → 2.2.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.
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Transform pre-clean / transitional envelopes to present Memorix format.
3
+ */
4
+ import { buildExtIdentifierKey, DEFAULT_RECORD_STATE, isPlainObject, stringifyId, } from "@x12i/memorix-base-format";
5
+ const DROP_ROOTS = new Set([
6
+ "identity",
7
+ "lifecycle",
8
+ "sourceFacts",
9
+ "index",
10
+ "entityId",
11
+ "eventId",
12
+ "knowledgeId",
13
+ "displayName",
14
+ "question",
15
+ "answer",
16
+ "metadata",
17
+ "graphRunId",
18
+ "lastJobRunId",
19
+ ]);
20
+ function asObject(v) {
21
+ return isPlainObject(v) ? { ...v } : {};
22
+ }
23
+ function mapLifecycleStatusToState(status) {
24
+ const s = stringifyId(status)?.toLowerCase();
25
+ if (!s)
26
+ return undefined;
27
+ if (s === "active")
28
+ return "active";
29
+ if (s === "archived" || s === "archive" || s === "inactive")
30
+ return "archived";
31
+ if (s === "superseded" || s === "replaced" || s === "stale")
32
+ return "superseded";
33
+ return undefined;
34
+ }
35
+ function buildLifecycleEvents(legacy) {
36
+ const lifecycle = asObject(legacy.lifecycle);
37
+ const createdAt = stringifyId(lifecycle.createdAt);
38
+ const modifiedAt = stringifyId(lifecycle.modifiedAt) ?? stringifyId(lifecycle.capturedAt);
39
+ const events = [];
40
+ if (createdAt && modifiedAt && createdAt !== modifiedAt) {
41
+ events.push({ process: "created", processedAt: createdAt });
42
+ events.push({ process: "modified", processedAt: modifiedAt });
43
+ }
44
+ else if (createdAt || modifiedAt) {
45
+ events.push({ process: "enriched", processedAt: (createdAt ?? modifiedAt) });
46
+ }
47
+ return events.length > 0 ? events : undefined;
48
+ }
49
+ function migrateExtIdentifier(concept) {
50
+ if (isPlainObject(concept._extIdentifier)) {
51
+ const ext = { ...concept._extIdentifier };
52
+ if (!stringifyId(ext.key) && stringifyId(ext.identifierKey)) {
53
+ ext.key = String(ext.identifierKey);
54
+ }
55
+ delete ext.identifierKey;
56
+ if (!stringifyId(ext.key)) {
57
+ const built = buildExtIdentifierKey(ext);
58
+ if (built)
59
+ ext.key = built;
60
+ }
61
+ return ext;
62
+ }
63
+ const identifier = asObject(concept.identifier);
64
+ if (Object.keys(identifier).length === 0) {
65
+ return { kind: "recordId", recordId: "unknown", key: "recordId:unknown" };
66
+ }
67
+ const ext = { ...identifier };
68
+ if (stringifyId(ext.identifierKey) && !stringifyId(ext.key)) {
69
+ ext.key = String(ext.identifierKey);
70
+ }
71
+ delete ext.identifierKey;
72
+ const built = buildExtIdentifierKey(ext);
73
+ if (built)
74
+ ext.key = built;
75
+ return ext;
76
+ }
77
+ function migrateConcept(legacy) {
78
+ const concept = asObject(legacy.concept);
79
+ const title = stringifyId(concept.title) ??
80
+ stringifyId(concept.name) ??
81
+ stringifyId(legacy.displayName) ??
82
+ stringifyId(legacy.question) ??
83
+ "untitled";
84
+ const out = {
85
+ _extIdentifier: migrateExtIdentifier(concept),
86
+ title,
87
+ };
88
+ for (const [k, v] of Object.entries(concept)) {
89
+ if (k === "identifier" || k === "_extIdentifier" || k === "title" || k === "name")
90
+ continue;
91
+ if (k.startsWith("_"))
92
+ continue;
93
+ out[k] = v;
94
+ }
95
+ return out;
96
+ }
97
+ function migrateSystem(legacy) {
98
+ const system = asObject(legacy._system);
99
+ const rootLifecycle = asObject(legacy.lifecycle);
100
+ if (legacy._graphRuns !== undefined)
101
+ system._graphRuns = legacy._graphRuns;
102
+ if (legacy._jobTypeRuns !== undefined)
103
+ system._jobTypeRuns = legacy._jobTypeRuns;
104
+ const events = buildLifecycleEvents(legacy);
105
+ if (events)
106
+ system.lifecycle = events;
107
+ else if (Array.isArray(system.lifecycle) && system.lifecycle.length === 0) {
108
+ delete system.lifecycle;
109
+ }
110
+ if (system.state === undefined) {
111
+ const mapped = mapLifecycleStatusToState(rootLifecycle.status);
112
+ system.state = mapped ?? DEFAULT_RECORD_STATE;
113
+ }
114
+ return system;
115
+ }
116
+ /**
117
+ * Map a legacy / transitional record to the present envelope.
118
+ * Safe to re-run on already-clean records (fills `_system.state` if missing).
119
+ */
120
+ export function migrateMemorixRecord(input, _options = {}) {
121
+ if (!isPlainObject(input)) {
122
+ throw new Error("migrateMemorixRecord: input must be a plain object");
123
+ }
124
+ const legacy = input;
125
+ const identity = asObject(legacy.identity);
126
+ const out = {};
127
+ if (legacy._id !== undefined)
128
+ out._id = legacy._id;
129
+ const recordId = stringifyId(legacy.recordId) ??
130
+ stringifyId(identity.recordId) ??
131
+ stringifyId(identity.targetId) ??
132
+ stringifyId(legacy.entityId) ??
133
+ stringifyId(legacy.eventId) ??
134
+ stringifyId(legacy.knowledgeId);
135
+ if (recordId)
136
+ out.recordId = recordId;
137
+ out.concept = migrateConcept(legacy);
138
+ out.data = isPlainObject(legacy.data) ? { ...legacy.data } : {};
139
+ for (const [key, value] of Object.entries(legacy)) {
140
+ if (key === "_id" ||
141
+ key === "recordId" ||
142
+ key === "concept" ||
143
+ key === "data" ||
144
+ key === "_system" ||
145
+ key === "_graphRuns" ||
146
+ key === "_jobTypeRuns" ||
147
+ DROP_ROOTS.has(key)) {
148
+ continue;
149
+ }
150
+ // Open buckets + associated* + custom roots
151
+ out[key] = value;
152
+ }
153
+ out._system = migrateSystem(legacy);
154
+ return out;
155
+ }
156
+ export function migrateMemorixRecords(records, options = {}) {
157
+ return records.map((r) => migrateMemorixRecord(r, options));
158
+ }
159
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,WAAW,GAGZ,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,UAAU;IACV,WAAW;IACX,aAAa;IACb,OAAO;IACP,UAAU;IACV,SAAS;IACT,aAAa;IACb,aAAa;IACb,UAAU;IACV,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,cAAc;CACf,CAAC,CAAC;AAEH,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAe;IAChD,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7C,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACpC,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC;IAC/E,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,YAAY,CAAC;IACjF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAkB;IAElB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAoD,EAAE,CAAC;IACnE,IAAI,SAAS,IAAI,UAAU,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IAChE,CAAC;SAAM,IAAI,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,SAAS,IAAI,UAAU,CAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAmB;IAC/C,IAAI,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5D,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC,aAAa,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,KAAK;gBAAE,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC;QAC7B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,kBAAkB,EAAE,CAAC;IAC5E,CAAC;IAED,MAAM,GAAG,GAAe,EAAE,GAAG,UAAU,EAAE,CAAC;IAC1C,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC,aAAa,CAAC;IACzB,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,KAAK;QAAE,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,MAAkB;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,KAAK,GACT,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1B,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;QACzB,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC/B,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5B,UAAU,CAAC;IAEb,MAAM,GAAG,GAAe;QACtB,cAAc,EAAE,oBAAoB,CAAC,OAAO,CAAC;QAC7C,KAAK;KACN,CAAC;IAEF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,gBAAgB,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,MAAM;YAAE,SAAS;QAC5F,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAChC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,MAAkB;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAEjD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;QAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC3E,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAEjF,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,MAAM;QAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;SACjC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1E,OAAO,MAAM,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,yBAAyB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,GAAG,MAAM,IAAI,oBAAoB,CAAC;IAChD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,WAAiC,EAAE;IAEnC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC;IACrB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;QAAE,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAEnD,MAAM,QAAQ,GACZ,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5B,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC9B,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC9B,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5B,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;QAC3B,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAClC,IAAI,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAEtC,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACrC,GAAG,CAAC,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IACE,GAAG,KAAK,KAAK;YACb,GAAG,KAAK,UAAU;YAClB,GAAG,KAAK,SAAS;YACjB,GAAG,KAAK,MAAM;YACd,GAAG,KAAK,SAAS;YACjB,GAAG,KAAK,YAAY;YACpB,GAAG,KAAK,cAAc;YACtB,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EACnB,CAAC;YACD,SAAS;QACX,CAAC;QACD,4CAA4C;QAC5C,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IAED,GAAG,CAAC,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAAkB,EAClB,UAAgC,EAAE;IAElC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -1,12 +1,15 @@
1
1
  import type { ContentTypeMeta } from "@x12i/memorix-base-format";
2
- /** Minimal content type — identity + data only (no declared open buckets). */
3
- export declare function minimalContentTypeMeta(objectType: string, contentType: string): ContentTypeMeta;
2
+ export type MemorixProfileName = "snapshots" | "minimal";
4
3
  /**
5
- * Snapshot-style Memorix profile: known open buckets + allow extra association keys.
6
- * Association property names are still open buckets to base; profile validates shapes in validate.ts.
4
+ * Snapshot content-type conventions from meta/content-type-profiles.json + open-buckets.json.
5
+ * `objectType` is supplied by the caller (descriptor / catalog / write context).
7
6
  */
8
7
  export declare function snapshotsContentTypeMeta(objectType: string): ContentTypeMeta;
9
- export type MemorixProfileName = "snapshots" | "minimal";
10
- export declare function resolveMemorixProfile(name: MemorixProfileName, objectType?: string): ContentTypeMeta;
8
+ /** Minimal content type — identity + data only. */
9
+ export declare function minimalContentTypeMeta(objectType: string, contentType: string): ContentTypeMeta;
10
+ /**
11
+ * Resolve profile by name, or by content-type vocabulary (meta/content-types.json).
12
+ */
13
+ export declare function resolveMemorixProfile(name: MemorixProfileName | string, objectType?: string): ContentTypeMeta;
11
14
  export declare const BUILTIN_PROFILES: MemorixProfileName[];
12
15
  //# sourceMappingURL=profiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,8EAA8E;AAC9E,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,eAAe,CAQjB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CA6B5E;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,CAAC;AAEzD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,EACxB,UAAU,SAAY,GACrB,eAAe,CAGjB;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAA6B,CAAC"}
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAOjE,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAW5E;AAED,mDAAmD;AACnD,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,eAAe,CASjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,GAAG,MAAM,EACjC,UAAU,SAAY,GACrB,eAAe,CAWjB;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAA6B,CAAC"}
package/dist/profiles.js CHANGED
@@ -1,52 +1,47 @@
1
- import { KNOWN_OPEN_BUCKETS } from "./associated.js";
2
- /** Minimal content type — identity + data only (no declared open buckets). */
1
+ import { knownOpenBucketsFromMeta, loadContentTypeProfilesMeta, loadContentTypesMeta, } from "./load-meta.js";
2
+ /**
3
+ * Snapshot content-type conventions from meta/content-type-profiles.json + open-buckets.json.
4
+ * `objectType` is supplied by the caller (descriptor / catalog / write context).
5
+ */
6
+ export function snapshotsContentTypeMeta(objectType) {
7
+ const profiles = loadContentTypeProfilesMeta().profiles.snapshots;
8
+ const openBuckets = knownOpenBucketsFromMeta();
9
+ return {
10
+ objectType,
11
+ contentType: profiles?.contentType ?? "snapshots",
12
+ collectionPostfix: profiles?.collectionPostfix ?? "snapshots",
13
+ openBuckets,
14
+ policy: profiles?.policy ?? { unknownOpenBuckets: "allow", emptyBuckets: "reject" },
15
+ read: profiles?.read ?? { missingOptionalIsNa: true },
16
+ };
17
+ }
18
+ /** Minimal content type — identity + data only. */
3
19
  export function minimalContentTypeMeta(objectType, contentType) {
20
+ const profiles = loadContentTypeProfilesMeta().profiles.minimal;
4
21
  return {
5
22
  objectType,
6
23
  contentType,
7
24
  collectionPostfix: contentType,
8
- policy: { unknownOpenBuckets: "warn", emptyBuckets: "reject" },
9
- read: { missingOptionalIsNa: true },
25
+ policy: profiles?.policy ?? { unknownOpenBuckets: "warn", emptyBuckets: "reject" },
26
+ read: profiles?.read ?? { missingOptionalIsNa: true },
10
27
  };
11
28
  }
12
29
  /**
13
- * Snapshot-style Memorix profile: known open buckets + allow extra association keys.
14
- * Association property names are still open buckets to base; profile validates shapes in validate.ts.
30
+ * Resolve profile by name, or by content-type vocabulary (meta/content-types.json).
15
31
  */
16
- export function snapshotsContentTypeMeta(objectType) {
17
- return {
18
- objectType,
19
- contentType: "snapshots",
20
- collectionPostfix: "snapshots",
21
- openBuckets: {
22
- analytics: {
23
- ...KNOWN_OPEN_BUCKETS.analytics,
24
- title: "Analytics",
25
- description: "Numeric rollups about linked lists",
26
- },
27
- enrichment: {
28
- ...KNOWN_OPEN_BUCKETS.enrichment,
29
- title: "Enrichment",
30
- description: "External / prior-system sourced values",
31
- },
32
- insights: {
33
- ...KNOWN_OPEN_BUCKETS.insights,
34
- title: "Insights",
35
- description: "Interpreted judgments and recommendations",
36
- },
37
- },
38
- policy: {
39
- // Allow associated* and other custom open buckets without listing every name
40
- unknownOpenBuckets: "allow",
41
- emptyBuckets: "reject",
42
- },
43
- read: { missingOptionalIsNa: true },
44
- };
45
- }
46
32
  export function resolveMemorixProfile(name, objectType = "generic") {
47
33
  if (name === "snapshots")
48
34
  return snapshotsContentTypeMeta(objectType);
49
- return minimalContentTypeMeta(objectType, name === "minimal" ? "events" : name);
35
+ if (name === "minimal")
36
+ return minimalContentTypeMeta(objectType, "events");
37
+ const ctMeta = loadContentTypesMeta().contentTypes[name];
38
+ if (ctMeta?.profile === "snapshots")
39
+ return snapshotsContentTypeMeta(objectType);
40
+ if (ctMeta?.profile === "workflow") {
41
+ // Workflow uses a separate document format; treat as minimal for envelope checks.
42
+ return minimalContentTypeMeta(objectType, "workflow");
43
+ }
44
+ return minimalContentTypeMeta(objectType, name);
50
45
  }
51
46
  export const BUILTIN_PROFILES = ["snapshots", "minimal"];
52
47
  //# sourceMappingURL=profiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,8EAA8E;AAC9E,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,WAAmB;IAEnB,OAAO;QACL,UAAU;QACV,WAAW;QACX,iBAAiB,EAAE,WAAW;QAC9B,MAAM,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE;QAC9D,IAAI,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACpC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,OAAO;QACL,UAAU;QACV,WAAW,EAAE,WAAW;QACxB,iBAAiB,EAAE,WAAW;QAC9B,WAAW,EAAE;YACX,SAAS,EAAE;gBACT,GAAG,kBAAkB,CAAC,SAAS;gBAC/B,KAAK,EAAE,WAAW;gBAClB,WAAW,EAAE,oCAAoC;aAClD;YACD,UAAU,EAAE;gBACV,GAAG,kBAAkB,CAAC,UAAU;gBAChC,KAAK,EAAE,YAAY;gBACnB,WAAW,EAAE,wCAAwC;aACtD;YACD,QAAQ,EAAE;gBACR,GAAG,kBAAkB,CAAC,QAAQ;gBAC9B,KAAK,EAAE,UAAU;gBACjB,WAAW,EAAE,2CAA2C;aACzD;SACF;QACD,MAAM,EAAE;YACN,6EAA6E;YAC7E,kBAAkB,EAAE,OAAO;YAC3B,YAAY,EAAE,QAAQ;SACvB;QACD,IAAI,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACpC,CAAC;AACJ,CAAC;AAID,MAAM,UAAU,qBAAqB,CACnC,IAAwB,EACxB,UAAU,GAAG,SAAS;IAEtB,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,wBAAwB,CAAC,UAAU,CAAC,CAAC;IACtE,OAAO,sBAAsB,CAAC,UAAU,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAyB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAIxB;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,MAAM,QAAQ,GAAG,2BAA2B,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;IAClE,MAAM,WAAW,GAAG,wBAAwB,EAAE,CAAC;IAC/C,OAAO;QACL,UAAU;QACV,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,WAAW;QACjD,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,IAAI,WAAW;QAC7D,WAAW;QACX,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE;QACnF,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACtD,CAAC;AACJ,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,2BAA2B,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;IAChE,OAAO;QACL,UAAU;QACV,WAAW;QACX,iBAAiB,EAAE,WAAW;QAC9B,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE;QAClF,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE;KACtD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAiC,EACjC,UAAU,GAAG,SAAS;IAEtB,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,wBAAwB,CAAC,UAAU,CAAC,CAAC;IACtE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE5E,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,MAAM,EAAE,OAAO,KAAK,WAAW;QAAE,OAAO,wBAAwB,CAAC,UAAU,CAAC,CAAC;IACjF,IAAI,MAAM,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC;QACnC,kFAAkF;QAClF,OAAO,sBAAsB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAyB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /** Re-export base types plus Memorix profile options. */
2
- export type { ContentTypeMeta, JsonObject, MemorixBaseRecord, MemorixConcept, MemorixConceptIdentifier, MemorixLifecycleEvent, MemorixSystemBlock, OpenBucketDecl, OpenBucketKind, RecordInspection, RootCategory, ValidateBaseOptions, ValidateBaseResult, ValidationIssue, ValidationSeverity, } from "@x12i/memorix-base-format";
2
+ export type { ContentTypeMeta, JsonObject, MemorixBaseRecord, MemorixConcept, MemorixConceptIdentifier, MemorixExtIdentifier, MemorixLifecycleEvent, MemorixRecordState, MemorixSystemBlock, OpenBucketDecl, OpenBucketKind, RecordInspection, RootCategory, ValidateBaseOptions, ValidateBaseResult, ValidationIssue, ValidationSeverity, } from "@x12i/memorix-base-format";
3
+ export { MEMORIX_RECORD_STATES } from "@x12i/memorix-base-format";
3
4
  import type { MemorixBaseRecord } from "@x12i/memorix-base-format";
4
5
  /** Alias for MemorixBaseRecord (compatibility with 1.x). */
5
6
  export type MemorixRecord = MemorixBaseRecord;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,YAAY,EACV,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE9C,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,YAAY,EACV,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE9C,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/types.js CHANGED
@@ -1,2 +1,2 @@
1
- export {};
1
+ export { MEMORIX_RECORD_STATES } from "@x12i/memorix-base-format";
2
2
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAExB,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG;IACzD,gDAAgD;IAChD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAeF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,sBAA2B,GACnC,kBAAkB,CA0EpB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAAE,EAClB,OAAO,GAAE,sBAA2B,GACnC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAGhD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAExB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG;IACzD,gDAAgD;IAChD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAeF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,sBAA2B,GACnC,kBAAkB,CA0EpB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAAE,EAClB,OAAO,GAAE,sBAA2B,GACnC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAGhD"}
package/dist/validate.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { validateMemorixBaseRecord, } from "@x12i/memorix-base-format";
2
- import { isAssociatedPropertyName, isLegacyAssociatedPropertyName, } from "./associated.js";
2
+ import { isAssociatedPropertyName, isLegacyAssociatedPropertyName, KNOWN_OPEN_BUCKETS, } from "./associated.js";
3
3
  import { resolveMemorixProfile } from "./profiles.js";
4
4
  function issue(path, code, message, severity = "error") {
5
5
  return { path, code, message, severity };
@@ -52,7 +52,7 @@ export function validateMemorixRecord(input, options = {}) {
52
52
  }
53
53
  }
54
54
  if (!isSnapshot) {
55
- for (const bucket of ["analytics", "enrichment", "insights"]) {
55
+ for (const bucket of Object.keys(KNOWN_OPEN_BUCKETS)) {
56
56
  if (input[bucket] !== undefined) {
57
57
  issues.push(issue(bucket, "SCOPE-2", `${bucket} SHOULD be omitted on non-snapshot content types unless opted in`));
58
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
@@ -49,4 +49,6 @@ These names are **Memorix declarations**, not base-reserved keys. Base classifie
49
49
 
50
50
  **TOOL-3.** `validateMemorixRecord` = `validateMemorixBaseRecord` + profile/ASSOC/SCOPE.
51
51
 
52
+ **TOOL-4.** `migrateMemorixRecord` / CLI `migrate` transforms legacy/transitional envelopes to the present format and SHOULD validate the result.
53
+
52
54
  Built-in profiles: `snapshots`, `minimal` (`--profile=`).
@@ -1,14 +1,15 @@
1
1
  # Memorix Record Format
2
2
 
3
- > **Package split (2.0):** Core envelope → [`@x12i/memorix-base-format`](https://www.npmjs.com/package/@x12i/memorix-base-format).
3
+ > **Package split:** Core envelope → [`@x12i/memorix-base-format`](https://www.npmjs.com/package/@x12i/memorix-base-format).
4
4
  > Product open buckets / associations → this package (`@x12i/memorix-format`).
5
- > Requirements: [memorix-format-requirements.md](./memorix-format-requirements.md).
5
+ > Requirements: [memorix-format-requirements.md](./memorix-format-requirements.md).
6
+ > Migrate legacy records: `npx memorix-format migrate ./records/`.
6
7
 
7
8
  ## Purpose
8
9
 
9
10
  A Memorix record is a structured memory object: a stable envelope around domain payload, with clear separation between business data, derived analytics, external enrichment, AI insights, and cross-entity references.
10
11
 
11
- The clean format removes the legacy 2.0 `identity` block, root-level `lifecycle`, `sourceFacts`, and redundant `concept.name`. Every field belongs in exactly one place.
12
+ **Present envelope:** `recordId`, `concept` (`title` + `_extIdentifier`), `data`, optional open buckets (`analytics`, `enrichment`, `insights`, `associated*`, …), and `_…` machine roots (`_system.state`, `_system.lifecycle`, …). Open-bucket **names** are not closed — base does not reserve product names.
12
13
 
13
14
  ---
14
15
 
@@ -17,39 +18,34 @@ The clean format removes the legacy 2.0 `identity` block, root-level `lifecycle`
17
18
  ```ts
18
19
  type MemorixRecord = {
19
20
  _id?: string; // MongoDB document id (storage only)
20
- recordId: string; // stable logical record id
21
- concept: MemorixConcept;
22
- data: JsonObject; // required — see data bucket rules
21
+ recordId: string; // join plumbing across content types (same subject)
22
+ concept: {
23
+ _extIdentifier: { kind: string; key: string; [kindValue: string]: string };
24
+ title: string;
25
+ // other human/LLM-readable fields allowed
26
+ };
27
+ data: JsonObject; // required — native facts
23
28
 
24
29
  analytics?: JsonObject;
25
30
  enrichment?: JsonObject;
26
31
  insights?: JsonObject;
27
- associatedData?: JsonObject[];
28
- associatedDiscovery?: JsonObject[];
29
- associatedAnalysis?: JsonObject[];
30
- associatedSiblings?: JsonObject[];
31
- associatedChildren?: JsonObject[];
32
- // associated<CustomName>?: JsonObject[];
33
-
34
- _system?: MemorixSystemBlock;
32
+ // associated…?: JsonObject[];
33
+
34
+ _system?: {
35
+ state?: "active" | "archived" | "superseded";
36
+ lifecycle?: Array<{ process: string; processedAt: string }>;
37
+ // …
38
+ };
35
39
  };
36
40
  ```
37
41
 
38
- Associated properties use the reserved `associated` prefix. **Legacy** names (`associatedData`, `associatedDiscovery`, …) remain on existing data. **v2** names follow `associated<ObjectType><ContentType>` — see [memorix-pipeline/docs/association-format.md](../memorix-pipeline/docs/association-format.md).
42
+ Associated properties use the reserved `associated` prefix. **Legacy** short names (`associatedData`, …) may still appear. Prefer `associated<ObjectType><ContentType>` — see [association-format.md](./association-format.md).
39
43
 
40
- The root holds only `_id`, `recordId`, `concept`, the data buckets, associated properties, and `_system`. No other top-level keys.
44
+ Human/LLM readers SHOULD omit root `_…` and `concept._extIdentifier` by default; keep `recordId` for joins.
41
45
 
42
- ### Removed from 2.0
43
-
44
- | Legacy field | Fate |
45
- |---|---|
46
- | `identity` (`target`, `targetId`, `objectType`, `contentType`, `version`) | Dropped; `recordId` is root-level |
47
- | Root `lifecycle` (`createdAt`, `modifiedAt`, `capturedAt`, `status`) | Replaced by `_system.lifecycle` event array |
48
- | `sourceFacts` | Promoted into `data` or `associatedData` |
49
- | `concept.name` | Dropped; use `concept.identifier` + `concept.title` |
50
- | Root `_graphRuns` / `_jobTypeRuns` | Moved to `_system` |
46
+ ### Migrate tooling (not format law)
51
47
 
52
- `objectType` is implied by collection name. `contentType` and `version` were constant across all records and are not carried forward.
48
+ Use `memorix-format migrate` to convert older envelopes (`identity`, root `lifecycle`, `concept.identifier`, root `_graphRuns`, …) into the present shape. Do not encode past roots in envelope meta.
53
49
 
54
50
  ---
55
51
 
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "recordId": "69d216ed358778e93215787e",
3
3
  "concept": {
4
- "identifier": {
4
+ "_extIdentifier": {
5
5
  "kind": "pluginId",
6
6
  "pluginId": "142594",
7
- "identifierKey": "pluginId:142594"
7
+ "key": "pluginId:142594"
8
8
  },
9
9
  "title": "Oracle WebLogic Server RCE (CVE-2020-14882)"
10
10
  },
@@ -22,6 +22,7 @@
22
22
  "exploitability": { "level": "HIGH", "confidence": 0.92 }
23
23
  },
24
24
  "_system": {
25
+ "state": "active",
25
26
  "lifecycle": [
26
27
  { "process": "enriched", "processedAt": "2026-04-05T08:01:15.511Z" }
27
28
  ]
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schemaNote": "Associated* naming conventions + legacy short names. No objectType bindings.",
3
+ "version": "2.1.0",
4
+ "prefix": "associated",
5
+ "defaultTopMaxItems": 5,
6
+ "legacyNames": [
7
+ "associatedData",
8
+ "associatedDiscovery",
9
+ "associatedAnalysis",
10
+ "associatedSiblings",
11
+ "associatedChildren",
12
+ "associatedAssets",
13
+ "associatedSubnets"
14
+ ],
15
+ "namingForms": [
16
+ {
17
+ "form": "content",
18
+ "pattern": "associated[Top?]<ObjectType><ContentType>",
19
+ "kind": "linked-payloads",
20
+ "shape": "array-of-objects"
21
+ },
22
+ {
23
+ "form": "enrichment",
24
+ "pattern": "associated[Top?]<ObjectType>Enrichment",
25
+ "kind": "linked-payloads",
26
+ "shape": "array-of-objects"
27
+ },
28
+ {
29
+ "form": "snapshotsRootProperty",
30
+ "pattern": "associated[Top?]<ObjectType>Snapshots<RootProperty>",
31
+ "kind": "linked-payloads",
32
+ "shape": "array-of-objects"
33
+ },
34
+ {
35
+ "form": "concepts",
36
+ "pattern": "associated[Top?]<ObjectType>Concepts",
37
+ "kind": "linked-payloads",
38
+ "shape": "array-of-objects"
39
+ },
40
+ {
41
+ "form": "recordIds",
42
+ "pattern": "associated[Top?]<ObjectType>RecordIds",
43
+ "kind": "linked-payloads",
44
+ "shape": "array-of-objects"
45
+ },
46
+ {
47
+ "form": "customDomain",
48
+ "pattern": "associated<CustomName>",
49
+ "kind": "linked-payloads",
50
+ "shape": "array-of-objects",
51
+ "examples": ["associatedTopology", "associatedCompliance"]
52
+ }
53
+ ],
54
+ "rules": {
55
+ "ASSOC-2": "when present MUST be an array",
56
+ "ASSOC-3": "MUST be omitted when empty — never []",
57
+ "ASSOC-6": "resolution MUST be snapshot-first (match *-snapshots, then content by recordId)"
58
+ }
59
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schemaNote": "Content-type profiles (policies). objectType is filled by the caller — never hardcoded here.",
3
+ "version": "2.1.0",
4
+ "profiles": {
5
+ "snapshots": {
6
+ "contentType": "snapshots",
7
+ "collectionPostfix": "snapshots",
8
+ "openBucketsRef": "open-buckets.json",
9
+ "policy": {
10
+ "unknownOpenBuckets": "allow",
11
+ "emptyBuckets": "reject"
12
+ },
13
+ "read": {
14
+ "missingOptionalIsNa": true
15
+ }
16
+ },
17
+ "minimal": {
18
+ "policy": {
19
+ "unknownOpenBuckets": "warn",
20
+ "emptyBuckets": "reject"
21
+ },
22
+ "read": {
23
+ "missingOptionalIsNa": true
24
+ }
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "$schemaNote": "Content-type vocabulary used by Memorix. Not object types. Aligned with managed Catalox entity descriptors + product vocabulary.",
3
+ "version": "2.1.0",
4
+ "canonicalContentType": "snapshots",
5
+ "contentTypes": {
6
+ "snapshots": {
7
+ "profile": "snapshots",
8
+ "description": "Full readable object view — may carry known open buckets and associated*"
9
+ },
10
+ "discovery": {
11
+ "profile": "minimal",
12
+ "description": "Discovery / Q&A style content"
13
+ },
14
+ "analysis": {
15
+ "profile": "minimal",
16
+ "description": "Analysis content"
17
+ },
18
+ "decisions": {
19
+ "profile": "minimal",
20
+ "description": "Decision content",
21
+ "collectionPostfixVariants": ["decision", "decisions"]
22
+ },
23
+ "scoped": {
24
+ "profile": "minimal",
25
+ "description": "Scoped slice"
26
+ },
27
+ "legacy": {
28
+ "profile": "minimal",
29
+ "description": "Quarantined / legacy slice"
30
+ },
31
+ "narratives": {
32
+ "profile": "minimal",
33
+ "description": "Narrative records"
34
+ },
35
+ "narrative-steps": {
36
+ "profile": "minimal",
37
+ "description": "Narrative step records"
38
+ },
39
+ "workflow": {
40
+ "profile": "workflow",
41
+ "description": "Product workflow overlay (memorix-workflow/1) — not the snapshot envelope"
42
+ },
43
+ "extrated": {
44
+ "profile": "minimal",
45
+ "description": "Extracted document content (managed key spelling as in Catalox descriptors)"
46
+ },
47
+ "chunks": {
48
+ "profile": "minimal",
49
+ "description": "Document chunks"
50
+ },
51
+ "ai-processing": {
52
+ "profile": "minimal",
53
+ "description": "Product vocabulary — optional CT"
54
+ },
55
+ "context": {
56
+ "profile": "minimal",
57
+ "description": "Product vocabulary — optional CT"
58
+ },
59
+ "suggested-plans": {
60
+ "profile": "minimal",
61
+ "description": "Product vocabulary — optional CT"
62
+ },
63
+ "suggested-actions": {
64
+ "profile": "minimal",
65
+ "description": "Product vocabulary — optional CT"
66
+ }
67
+ }
68
+ }