@x12i/memorix-format 3.0.2 → 3.0.4

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 (43) hide show
  1. package/CHANGELOG.md +65 -61
  2. package/README.md +78 -78
  3. package/dist/base/concept.d.ts +4 -0
  4. package/dist/base/concept.d.ts.map +1 -1
  5. package/dist/base/concept.js +5 -1
  6. package/dist/base/concept.js.map +1 -1
  7. package/dist/cli.js +36 -36
  8. package/dist/v2/identity.d.ts +19 -0
  9. package/dist/v2/identity.d.ts.map +1 -0
  10. package/dist/v2/identity.js +39 -0
  11. package/dist/v2/identity.js.map +1 -0
  12. package/dist/v2/index.d.ts +1 -0
  13. package/dist/v2/index.d.ts.map +1 -1
  14. package/dist/v2/index.js +1 -0
  15. package/dist/v2/index.js.map +1 -1
  16. package/docs/association-format.md +47 -47
  17. package/docs/memorix-format-requirements.md +54 -54
  18. package/docs/memorix-format.md +68 -68
  19. package/docs/memorix-record-v2.md +102 -101
  20. package/docs/memorix-workflow-format.md +126 -126
  21. package/docs/migrate-present-to-v2.md +49 -49
  22. package/examples/invalid-record.json +11 -11
  23. package/examples/v2/activity-events-snapshots.json +31 -31
  24. package/examples/v2/{employees-discovery.json → people-discovery.json} +26 -26
  25. package/examples/v2/{employees-snapshots.json → people-snapshots-employee.json} +27 -27
  26. package/examples/v2/{procedures-knowledge.json → playbooks-knowledge.json} +27 -27
  27. package/examples/v2/work-items-analysis.json +26 -26
  28. package/examples/v2/work-items-context.json +32 -32
  29. package/examples/v2/work-items-decisions.json +26 -26
  30. package/examples/v2/work-items-raw.json +37 -37
  31. package/examples/v2/work-items-relationships-candidate.json +38 -38
  32. package/examples/v2/work-items-snapshots-lifecycle.json +31 -31
  33. package/examples/v2/work-items-snapshots-lightweight-refs.json +34 -34
  34. package/examples/v2/work-items-snapshots.json +28 -28
  35. package/examples/v2/work-items-workflow.json +28 -28
  36. package/examples/valid-snapshot.json +30 -30
  37. package/meta/associated-conventions.json +59 -59
  38. package/meta/content-type-profiles.json +27 -27
  39. package/meta/content-types.json +80 -68
  40. package/meta/envelope.json +104 -104
  41. package/meta/inventory/managed-descriptors.json +78 -78
  42. package/meta/open-buckets.json +24 -24
  43. package/package.json +77 -77
@@ -1,54 +1,54 @@
1
- # Memorix Format — Requirements (product layer)
2
-
3
- **Package:** `@x12i/memorix-format`
4
- **Depends on:** `@x12i/memorix-base-format` (fixed skeleton — do not re-state ENV/ID/DATA/SYS here).
5
-
6
- This document covers **Memorix product** open-bucket conventions. Base envelope MUST be satisfied first (`TOOL-3`: layer checks on base).
7
-
8
- ---
9
-
10
- ## Known open buckets (when present)
11
-
12
- **BUCKET-5.**
13
-
14
- | Bucket | MUST contain | MUST NOT contain |
15
- |---|---|---|
16
- | `analytics` | Numeric rollups | The underlying list of records |
17
- | `enrichment` | External / prior-system values as received | Interpreted judgments |
18
- | `insights` | Judgments, scores, recommendations | Anything a reader would mistake for a stored native fact |
19
-
20
- These names are **Memorix declarations**, not base-reserved keys. Base classifies them as open buckets.
21
-
22
- ---
23
-
24
- ## Associated properties
25
-
26
- **ASSOC-1.** Keys matching Memorix association patterns (`associated…`, legacy short names, `associatedTop…`, `associated…Enrichment`, custom `associated` prefix).
27
-
28
- **ASSOC-2.** When present, MUST be an array.
29
-
30
- **ASSOC-3.** MUST be omitted when empty — never `[]`.
31
-
32
- **ASSOC-5.** Items MUST be plain objects (linked payloads), not full envelopes.
33
-
34
- **ASSOC-6.** Resolution MUST be snapshot-first (see association-format.md). Enforced by associator tooling, documented here.
35
-
36
- ---
37
-
38
- ## Snapshot vs minimal (SCOPE)
39
-
40
- **SCOPE-1.** Full open-bucket set SHOULD appear primarily on snapshots.
41
-
42
- **SCOPE-2.** Non-snapshot content types MUST include `recordId` + `data`; SHOULD omit `analytics` / `insights` / most `associated*` unless opted in via ContentTypeMeta.
43
-
44
- **SCOPE-3.** Readers MUST treat missing optional buckets as N/A, not error.
45
-
46
- ---
47
-
48
- ## Validator
49
-
50
- **TOOL-3.** `validateMemorixRecord` = `validateMemorixBaseRecord` + profile/ASSOC/SCOPE.
51
-
52
- **TOOL-4.** `migrateMemorixRecord` / CLI `migrate` transforms legacy/transitional envelopes to the present format and SHOULD validate the result.
53
-
54
- Built-in profiles: `snapshots`, `minimal` (`--profile=`).
1
+ # Memorix Format — Requirements (product layer)
2
+
3
+ **Package:** `@x12i/memorix-format`
4
+ **Depends on:** `@x12i/memorix-base-format` (fixed skeleton — do not re-state ENV/ID/DATA/SYS here).
5
+
6
+ This document covers **Memorix product** open-bucket conventions. Base envelope MUST be satisfied first (`TOOL-3`: layer checks on base).
7
+
8
+ ---
9
+
10
+ ## Known open buckets (when present)
11
+
12
+ **BUCKET-5.**
13
+
14
+ | Bucket | MUST contain | MUST NOT contain |
15
+ |---|---|---|
16
+ | `analytics` | Numeric rollups | The underlying list of records |
17
+ | `enrichment` | External / prior-system values as received | Interpreted judgments |
18
+ | `insights` | Judgments, scores, recommendations | Anything a reader would mistake for a stored native fact |
19
+
20
+ These names are **Memorix declarations**, not base-reserved keys. Base classifies them as open buckets.
21
+
22
+ ---
23
+
24
+ ## Associated properties
25
+
26
+ **ASSOC-1.** Keys matching Memorix association patterns (`associated…`, legacy short names, `associatedTop…`, `associated…Enrichment`, custom `associated` prefix).
27
+
28
+ **ASSOC-2.** When present, MUST be an array.
29
+
30
+ **ASSOC-3.** MUST be omitted when empty — never `[]`.
31
+
32
+ **ASSOC-5.** Items MUST be plain objects (linked payloads), not full envelopes.
33
+
34
+ **ASSOC-6.** Resolution MUST be snapshot-first (see association-format.md). Enforced by associator tooling, documented here.
35
+
36
+ ---
37
+
38
+ ## Snapshot vs minimal (SCOPE)
39
+
40
+ **SCOPE-1.** Full open-bucket set SHOULD appear primarily on snapshots.
41
+
42
+ **SCOPE-2.** Non-snapshot content types MUST include `recordId` + `data`; SHOULD omit `analytics` / `insights` / most `associated*` unless opted in via ContentTypeMeta.
43
+
44
+ **SCOPE-3.** Readers MUST treat missing optional buckets as N/A, not error.
45
+
46
+ ---
47
+
48
+ ## Validator
49
+
50
+ **TOOL-3.** `validateMemorixRecord` = `validateMemorixBaseRecord` + profile/ASSOC/SCOPE.
51
+
52
+ **TOOL-4.** `migrateMemorixRecord` / CLI `migrate` transforms legacy/transitional envelopes to the present format and SHOULD validate the result.
53
+
54
+ Built-in profiles: `snapshots`, `minimal` (`--profile=`).
@@ -1,68 +1,68 @@
1
- # Memorix Record Format
2
-
3
- > **Canonical SoT for new work:** [memorix-record/2](./memorix-record-v2.md) (`validateMemorixRecordV2`).
4
- > **Present envelope (migration source):** documented below — still enforced by default in writer/pipeline until `MEMORIX_RECORD_FORMAT=v2`.
5
- > Core present envelope helpers: [`@x12i/memorix-base-format`](https://www.npmjs.com/package/@x12i/memorix-base-format) (temporary; folding into this package).
6
- > Requirements: [memorix-format-requirements.md](./memorix-format-requirements.md).
7
-
8
- ## Purpose
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.
11
-
12
- **Prefer `memorix-record/2` for all new platform paths.** Present envelope remains for reading/migrating existing data.
13
-
14
- ---
15
-
16
- ## Present envelope (migration source)
17
-
18
- ```ts
19
- type MemorixRecordPresent = {
20
- _id?: string;
21
- recordId: string;
22
- concept: {
23
- _extIdentifier: { kind: string; key: string; [kindValue: string]: string };
24
- title: string;
25
- };
26
- data: JsonObject;
27
- analytics?: JsonObject;
28
- enrichment?: JsonObject;
29
- insights?: JsonObject;
30
- // associated…?: JsonObject[]; // copied payloads — removed in V2
31
- _system?: {
32
- state?: "active" | "archived" | "superseded";
33
- lifecycle?: Array<{ process: string; processedAt: string }>;
34
- };
35
- };
36
- ```
37
-
38
- Migrate legacy → present: `npx memorix-format migrate`.
39
- Migrate present → V2: `npx memorix-format migrate-to-v2 --object-type=… --content-type=… --data-category=…`.
40
-
41
- Associated properties use the reserved `associated` prefix on **present** records only. See [association-format.md](./association-format.md). V2 rejects copied association roots.
42
-
43
- Human/LLM readers SHOULD omit root `_…` and `concept._extIdentifier` by default; keep `recordId` for joins.
44
-
45
- ---
46
-
47
- ## Data And Associated Buckets (present)
48
-
49
- Every piece of business data lives in **exactly one** of these buckets (plus the envelope fields above):
50
-
51
- | Bucket | Contents |
52
- |---|---|
53
- | **`data`** | Native facts about the subject itself |
54
- | **`analytics`** | Numeric rollups computed from other records |
55
- | **`enrichment`** | External / prior-system values as received |
56
- | **`insights`** | AI / judgment outputs |
57
- | **`associated*`** | Copied related payloads (present only; removed in V2) |
58
-
59
- On **memorix-record/2**, snapshot buckets are optional and **omitted when empty**. Root `associated*` may hold **lightweight refs** only (Option A — still format-valid). **Authoritative relationship storage (Gate G4)** is centralized per-category collections (Candidate C); see `@x12i/memorix-relationship-store` (archived: `.tmp/housekeeping-2026-07-23/docs/re-factoring-and-ops-agent/RELATIONSHIP-STORAGE-DECISION.md`).
60
-
61
- ---
62
-
63
- ## Further reading
64
-
65
- - [memorix-record-v2.md](./memorix-record-v2.md) — Gate G2 contract
66
- - [association-format.md](./association-format.md) — present association naming
67
- - [memorix-workflow-format.md](./memorix-workflow-format.md) — workflow as sibling content
68
- - Golden V2 examples: `examples/v2/`
1
+ # Memorix Record Format
2
+
3
+ > **Canonical SoT for new work:** [memorix-record/2](./memorix-record-v2.md) (`validateMemorixRecordV2`).
4
+ > **Present envelope (migration source):** documented below — still enforced by default in writer/pipeline until `MEMORIX_RECORD_FORMAT=v2`.
5
+ > Core present envelope helpers: [`@x12i/memorix-base-format`](https://www.npmjs.com/package/@x12i/memorix-base-format) (temporary; folding into this package).
6
+ > Requirements: [memorix-format-requirements.md](./memorix-format-requirements.md).
7
+
8
+ ## Purpose
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.
11
+
12
+ **Prefer `memorix-record/2` for all new platform paths.** Present envelope remains for reading/migrating existing data.
13
+
14
+ ---
15
+
16
+ ## Present envelope (migration source)
17
+
18
+ ```ts
19
+ type MemorixRecordPresent = {
20
+ _id?: string;
21
+ recordId: string;
22
+ concept: {
23
+ _extIdentifier: { kind: string; key: string; [kindValue: string]: string };
24
+ title: string;
25
+ };
26
+ data: JsonObject;
27
+ analytics?: JsonObject;
28
+ enrichment?: JsonObject;
29
+ insights?: JsonObject;
30
+ // associated…?: JsonObject[]; // copied payloads — removed in V2
31
+ _system?: {
32
+ state?: "active" | "archived" | "superseded";
33
+ lifecycle?: Array<{ process: string; processedAt: string }>;
34
+ };
35
+ };
36
+ ```
37
+
38
+ Migrate legacy → present: `npx memorix-format migrate`.
39
+ Migrate present → V2: `npx memorix-format migrate-to-v2 --object-type=… --content-type=… --data-category=…`.
40
+
41
+ Associated properties use the reserved `associated` prefix on **present** records only. See [association-format.md](./association-format.md). V2 rejects copied association roots.
42
+
43
+ Human/LLM readers SHOULD omit root `_…` and `concept._extIdentifier` by default; keep `recordId` for joins.
44
+
45
+ ---
46
+
47
+ ## Data And Associated Buckets (present)
48
+
49
+ Every piece of business data lives in **exactly one** of these buckets (plus the envelope fields above):
50
+
51
+ | Bucket | Contents |
52
+ |---|---|
53
+ | **`data`** | Native facts about the subject itself |
54
+ | **`analytics`** | Numeric rollups computed from other records |
55
+ | **`enrichment`** | External / prior-system values as received |
56
+ | **`insights`** | AI / judgment outputs |
57
+ | **`associated*`** | Copied related payloads (present only; removed in V2) |
58
+
59
+ On **memorix-record/2**, snapshot buckets are optional and **omitted when empty**. Root `associated*` may hold **lightweight refs** only (Option A — still format-valid). **Authoritative relationship storage (Gate G4)** is centralized per-category collections (Candidate C); see `@x12i/memorix-relationship-store` (archived: `.tmp/housekeeping-2026-07-23/docs/re-factoring-and-opx-agent/RELATIONSHIP-STORAGE-DECISION.md`).
60
+
61
+ ---
62
+
63
+ ## Further reading
64
+
65
+ - [memorix-record-v2.md](./memorix-record-v2.md) — Gate G2 contract
66
+ - [association-format.md](./association-format.md) — present association naming
67
+ - [memorix-workflow-format.md](./memorix-workflow-format.md) — workflow as sibling content
68
+ - Golden V2 examples: `examples/v2/`
@@ -1,101 +1,102 @@
1
- # memorix-record/2
2
-
3
- **Status:** Gate G2 contract — preferred source of truth for new platform work.
4
- **Package:** `@x12i/memorix-format` (`validateMemorixRecordV2`, `migratePresentToV2`, CLI `validate-v2` / `migrate-to-v2`).
5
-
6
- Present-tense envelope docs remain in [memorix-format.md](./memorix-format.md) for migration only.
7
- Migration semantics: [migrate-present-to-v2.md](./migrate-present-to-v2.md).
8
-
9
- ## Envelope
10
-
11
- ```ts
12
- type MemorixRecordV2 = {
13
- format: "memorix-record/2";
14
- recordId: string;
15
- revision: number; // starts at 1; increments every successful mutation
16
- objectType: string;
17
- contentType: string;
18
- dataCategory: "entity" | "event" | "knowledge";
19
- concept: {
20
- title: string;
21
- identifiers: {
22
- primary: { kind: string; value: string; issuer?: string; normalizedValue?: string };
23
- alternates?: Array<...>; // omit when empty
24
- };
25
- };
26
- data: Record<string, unknown>;
27
- analytics?: Record<string, unknown>; // snapshots (and knowledge) only; omit when unused
28
- enrichment?: Record<string, unknown>;
29
- insights?: Record<string, unknown>;
30
- // Option A — lightweight relationship refs remain FORMAT-VALID (G2).
31
- // Gate G4 selected authoritative storage = central per-category collections (Candidate C).
32
- // associatedPeople?: Array<{
33
- // relationshipDefinitionId: string; // required
34
- // recordId: string; // required
35
- // relationshipId?: string; // optional — deterministically derivable
36
- // }>;
37
- _system: {
38
- state: "active" | "archived" | "superseded";
39
- createdAt: string;
40
- modifiedAt: string;
41
- observedAt?: string;
42
- lifecycle?: Array<{ process: string; processedAt: string }>; // omit when empty
43
- provenance?: Record<string, unknown>;
44
- };
45
- };
46
- ```
47
-
48
- ## Locked decisions (Gate G2)
49
-
50
- 1. **Empty optional snapshot buckets are omitted** — never emit `{}`.
51
- 2. **Workflow is a sibling content record** (`contentType: "workflow"`), not a separate document system.
52
- 3. **Composition** = same `recordId` across content types; not a relationship.
53
- 4. **`_graphRuns` / `_jobTypeRuns` stay off the subject** — operational run ledger owns run history.
54
- 5. **V2 rejects copied related-record payloads.** Root `associated*` may hold **lightweight relationship refs** only: required `relationshipDefinitionId` + `recordId`; optional `relationshipId` (derivable). Without `relationshipDefinitionId` the item is not a relationship. **Option A** (direct-record lightweight `associated*` roots) remains **format-valid** for validation and migration compatibility.
55
- 6. **Authoritative physical relationship storage is Gate G4 Candidate C** — org-prefixed per-category `relationships` collections (`entity` / `event` / `knowledge`). Option A lightweight roots and sibling `relationships` content are **not** the selected authoritative storage model; see `@x12i/memorix-relationship-store` / `@x12i/memorix-relationships` (decision note archived under `.tmp/housekeeping-2026-07-23/docs/re-factoring-and-ops-agent/RELATIONSHIP-STORAGE-DECISION.md`).
56
- 7. **Present format remains the writer/pipeline default** until cutover (`MEMORIX_RECORD_FORMAT=v2`). All **new** refactor packages and the `ops` harness use V2 exclusively. The env switch is transitional (`DEL-FORMAT-PRESENT-SOT`).
57
-
58
- ## Revision vs lifecycle
59
-
60
- | Rule | Behavior |
61
- |---|---|
62
- | Revision | Increments on every successful mutation |
63
- | Lifecycle | Appended only for meaningful process/state events |
64
- | Independence | Revision may change with no lifecycle entry |
65
- | Concurrency | Stale `expectedRevision` is rejected (`checkExpectedRevision`) |
66
-
67
- Helpers: `applySuccessfulMutation`, `nextRevision`, `checkExpectedRevision`.
68
-
69
- ## Discriminators
70
-
71
- - Pure structural V2 validation does not invent discriminator values.
72
- - Content-type **profiles** (from metadata) may declare `path`, `required`, `defaultValue`, `allowedValues`.
73
- - Missing + profile default → warning `V2-DISCRIMINATOR-DEFAULT` (writers apply default).
74
- - Missing + required + no default → error `V2-DISCRIMINATOR`.
75
-
76
- ## Examples
77
-
78
- See [`examples/v2/`](../examples/v2/) — includes lifecycle, lightweight refs, analysis/decision/discovery, workflow sibling, relationships-candidate sibling.
79
-
80
- ## Migrate
81
-
82
- ```bash
83
- npx memorix-format migrate-to-v2 ./present.json \
84
- --object-type=work-items \
85
- --content-type=snapshots \
86
- --data-category=entity \
87
- --issuer=ops-source
88
- ```
89
-
90
- Output includes `v2`, `extractedRelationships`, and `warnings`.
91
-
92
- ## Writer cutover flag
93
-
94
- ```bash
95
- MEMORIX_RECORD_FORMAT=v2 # writer uses validateMemorixRecordV2
96
- # default: present (legacy paths only)
97
- ```
98
-
99
- ## Folding `@x12i/memorix-base-format`
100
-
101
- Present base validation still depends on `@x12i/memorix-base-format`. That package becomes a temporary re-export after consumers move to `@x12i/memorix-format` / V2, then is deleted (Phase 0 deletion ledger).
1
+ # memorix-record/2
2
+
3
+ **Status:** Gate G2 contract — preferred source of truth for new platform work.
4
+ **Package:** `@x12i/memorix-format` (`validateMemorixRecordV2`, `migratePresentToV2`, CLI `validate-v2` / `migrate-to-v2`).
5
+
6
+ Present-tense envelope docs remain in [memorix-format.md](./memorix-format.md) for migration only.
7
+ Migration semantics: [migrate-present-to-v2.md](./migrate-present-to-v2.md).
8
+
9
+ ## Envelope
10
+
11
+ ```ts
12
+ type MemorixRecordV2 = {
13
+ format: "memorix-record/2";
14
+ recordId: string;
15
+ revision: number; // starts at 1; increments every successful mutation
16
+ objectType: string;
17
+ contentType: string;
18
+ dataCategory: "entity" | "event" | "knowledge";
19
+ concept: {
20
+ title: string;
21
+ identifiers: {
22
+ primary: { kind: string; value: string; issuer?: string; normalizedValue?: string };
23
+ alternates?: Array<...>; // omit when empty
24
+ };
25
+ };
26
+ data: Record<string, unknown>;
27
+ analytics?: Record<string, unknown>; // snapshots (and knowledge) only; omit when unused
28
+ enrichment?: Record<string, unknown>;
29
+ insights?: Record<string, unknown>;
30
+ // Option A — lightweight relationship refs remain FORMAT-VALID (G2).
31
+ // Gate G4 selected authoritative storage = central per-category collections (Candidate C).
32
+ // associatedPeople?: Array<{
33
+ // relationshipDefinitionId: string; // required
34
+ // recordId: string; // required
35
+ // relationshipId?: string; // optional — deterministically derivable
36
+ // }>;
37
+ _system: {
38
+ state: "active" | "archived" | "superseded";
39
+ createdAt: string;
40
+ modifiedAt: string;
41
+ observedAt?: string;
42
+ lifecycle?: Array<{ process: string; processedAt: string }>; // omit when empty
43
+ provenance?: Record<string, unknown>;
44
+ };
45
+ };
46
+ ```
47
+
48
+ ## Locked decisions (Gate G2)
49
+
50
+ 1. **Empty optional snapshot buckets are omitted** — never emit `{}`.
51
+ 2. **Workflow is a sibling content record** (`contentType: "workflow"`), not a separate document system.
52
+ 3. **Composition** = same `recordId` across content types; not a relationship.
53
+ 4. **`_graphRuns` / `_jobTypeRuns` stay off the subject** — operational run ledger owns run history.
54
+ 5. **V2 rejects copied related-record payloads.** Root `associated*` may hold **lightweight relationship refs** only: required `relationshipDefinitionId` + `recordId`; optional `relationshipId` (derivable). Without `relationshipDefinitionId` the item is not a relationship. **Option A** (direct-record lightweight `associated*` roots) remains **format-valid** for validation and migration compatibility.
55
+ 6. **Authoritative physical relationship storage is Gate G4 Candidate C** — org-prefixed per-category `relationships` collections (`entity` / `event` / `knowledge`). Option A lightweight roots and sibling `relationships` content are **not** the selected authoritative storage model; see `@x12i/memorix-relationship-store` / `@x12i/memorix-relationships` (decision note archived under `.tmp/housekeeping-2026-07-23/docs/re-factoring-and-opx-agent/RELATIONSHIP-STORAGE-DECISION.md`).
56
+ 7. **Writers persist `memorix-record/2` exclusively.** The historical `MEMORIX_RECORD_FORMAT=v2` switch is obsolete and must not be documented as optional. Present-format docs remain for migration tooling only.
57
+
58
+ ## Revision vs lifecycle
59
+
60
+ | Rule | Behavior |
61
+ |---|---|
62
+ | Revision | Increments on every successful mutation |
63
+ | Lifecycle | Appended only for meaningful process/state events |
64
+ | Independence | Revision may change with no lifecycle entry |
65
+ | Concurrency | Stale `expectedRevision` is rejected (`checkExpectedRevision`) |
66
+
67
+ Helpers: `applySuccessfulMutation`, `nextRevision`, `checkExpectedRevision`.
68
+
69
+ ## Discriminators
70
+
71
+ - Pure structural V2 validation does not invent discriminator values.
72
+ - Content-type **profiles** (from metadata) may declare `path`, `required`, `defaultValue`, `allowedValues`.
73
+ - Missing + profile default → warning `V2-DISCRIMINATOR-DEFAULT` (writers apply default).
74
+ - Missing + required + no default → error `V2-DISCRIMINATOR`.
75
+
76
+ ## Examples
77
+
78
+ See [`examples/v2/`](../examples/v2/) — includes lifecycle, lightweight refs, analysis/decision/discovery, workflow sibling, relationships-candidate sibling.
79
+
80
+ ## Migrate
81
+
82
+ ```bash
83
+ npx memorix-format migrate-to-v2 ./present.json \
84
+ --object-type=work-items \
85
+ --content-type=snapshots \
86
+ --data-category=entity \
87
+ --issuer=opx-source
88
+ ```
89
+
90
+ Output includes `v2`, `extractedRelationships`, and `warnings`.
91
+
92
+ ## Writer cutover flag
93
+
94
+ Obsolete. Production writers always validate and persist `memorix-record/2`. Do not set `MEMORIX_RECORD_FORMAT`.
95
+
96
+ ## Subject identity
97
+
98
+ See [the subject-model contract](../../docs/subject-model-contract.md). `recordId` is never Mongo `_id`. Source identifiers are adopted as `{issuer}/{kind}/{value}`.
99
+
100
+ ## Folding `@x12i/memorix-base-format`
101
+
102
+ Present base validation still depends on `@x12i/memorix-base-format`. That package becomes a temporary re-export after consumers move to `@x12i/memorix-format` / V2, then is deleted (Phase 0 deletion ledger).