@remnic/core 9.3.757 → 9.3.758

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 (165) hide show
  1. package/dist/access-admin-ops-surface.d.ts +1 -1
  2. package/dist/access-admin-ops-surface.js +20 -20
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-boundary.d.ts +1 -1
  5. package/dist/access-boundary.js +21 -21
  6. package/dist/access-cli.js +68 -68
  7. package/dist/access-http.d.ts +1 -1
  8. package/dist/access-http.js +28 -28
  9. package/dist/access-identity-continuity-surface.d.ts +166 -0
  10. package/dist/access-identity-continuity-surface.js +128 -0
  11. package/dist/access-lcm-surface.d.ts +1 -1
  12. package/dist/access-lcm-surface.js +20 -20
  13. package/dist/access-mcp.d.ts +1 -1
  14. package/dist/access-mcp.js +27 -27
  15. package/dist/access-observe-write-surface.d.ts +1 -1
  16. package/dist/access-observe-write-surface.js +20 -20
  17. package/dist/access-operations-batch.js +24 -24
  18. package/dist/access-operations.d.ts +5 -5
  19. package/dist/access-operations.js +26 -26
  20. package/dist/access-recall-surface.d.ts +1 -1
  21. package/dist/access-recall-surface.js +20 -20
  22. package/dist/access-schema.d.ts +68 -68
  23. package/dist/access-schema.js +5 -5
  24. package/dist/{access-service-CJwcDoQp.d.ts → access-service-Z-8CnmrW.d.ts} +3 -2
  25. package/dist/access-service.d.ts +1 -1
  26. package/dist/access-service.js +20 -20
  27. package/dist/access-surface-catalog.d.ts +1 -1
  28. package/dist/briefing.js +3 -3
  29. package/dist/{capsule-crypto-RAARDY3M.js → capsule-crypto-CZJSLEFG.js} +2 -2
  30. package/dist/causal-behavior.js +2 -2
  31. package/dist/causal-chain.js +2 -2
  32. package/dist/causal-consolidation.js +8 -8
  33. package/dist/causal-retrieval.js +2 -2
  34. package/dist/causal-trajectory-graph.js +2 -2
  35. package/dist/causal-trajectory.js +1 -1
  36. package/dist/{chunk-EEIROWEG.js → chunk-2BFLDH5F.js} +2 -2
  37. package/dist/{chunk-UPSAT4PY.js → chunk-2MR3MFQB.js} +2 -2
  38. package/dist/{chunk-IZP62CEF.js → chunk-3QLPBCFG.js} +4 -4
  39. package/dist/{chunk-LNQUAJNC.js → chunk-437S3G37.js} +1 -1
  40. package/dist/{chunk-4L2KHKLY.js → chunk-6C6BBBCI.js} +271 -197
  41. package/dist/chunk-6C6BBBCI.js.map +1 -0
  42. package/dist/{chunk-6FYRCQ7K.js → chunk-7I2QTC2K.js} +2 -2
  43. package/dist/{chunk-RQXVVENY.js → chunk-7ME6VBF7.js} +69 -69
  44. package/dist/{chunk-AGNBY3VG.js → chunk-APJQ6UEA.js} +4 -4
  45. package/dist/{chunk-GI7PRVMV.js → chunk-CJDGB3EG.js} +2 -2
  46. package/dist/{chunk-IR6ATBUI.js → chunk-CQCCVJZO.js} +2 -2
  47. package/dist/{chunk-5PHPNUZN.js → chunk-DUQHQ3TL.js} +286 -230
  48. package/dist/chunk-DUQHQ3TL.js.map +1 -0
  49. package/dist/{chunk-XROP4ZHB.js → chunk-EHQ5HO5T.js} +4 -4
  50. package/dist/{chunk-AINK3KDE.js → chunk-EOTTKLPJ.js} +2 -2
  51. package/dist/{chunk-KTULX4YO.js → chunk-FLVL4L3L.js} +4 -4
  52. package/dist/{chunk-6A76LSX6.js → chunk-HO3VUUGI.js} +2 -2
  53. package/dist/{chunk-2NTWULEQ.js → chunk-ILB2MFTS.js} +2 -2
  54. package/dist/{chunk-FBS6V6LJ.js → chunk-IWI2ICTF.js} +4 -4
  55. package/dist/{chunk-FFPH47IX.js → chunk-K2DJQOE3.js} +2 -2
  56. package/dist/{chunk-6DMTYBNY.js → chunk-LQDA67TT.js} +2 -2
  57. package/dist/{chunk-7HJ3XBMD.js → chunk-LX4ZWRGD.js} +2 -2
  58. package/dist/{chunk-CYWCKFCL.js → chunk-M5QKGHCR.js} +5 -5
  59. package/dist/{chunk-QVQG7W2H.js → chunk-ODC4HOUZ.js} +2 -2
  60. package/dist/{chunk-ZG2WP425.js → chunk-ORAK3LNZ.js} +2 -2
  61. package/dist/{chunk-LVMVYLNB.js → chunk-PJ5AG6D4.js} +2 -2
  62. package/dist/{chunk-GIJDW2YO.js → chunk-QEAOKI4U.js} +3 -3
  63. package/dist/{chunk-MQQO56LN.js → chunk-QJUZAUAD.js} +30 -30
  64. package/dist/{chunk-SUN6XVNI.js → chunk-QKOTOUVR.js} +3 -3
  65. package/dist/{chunk-XKUYMM34.js → chunk-RF6BZHOD.js} +2 -2
  66. package/dist/{chunk-I65IQD7Y.js → chunk-RQNV75HR.js} +2 -2
  67. package/dist/{chunk-ZE7GJ76H.js → chunk-SQNED75R.js} +1 -1
  68. package/dist/{chunk-PHWBKQHK.js → chunk-TMXTQCJ7.js} +8 -8
  69. package/dist/{chunk-PMBWVQ7D.js → chunk-TQT3USCG.js} +2 -2
  70. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  71. package/dist/{chunk-T3UW6NRQ.js → chunk-TVWF3GNF.js} +7 -7
  72. package/dist/{chunk-IF6BTZCB.js → chunk-XQT5GSWU.js} +2 -2
  73. package/dist/{chunk-PXHY2E3S.js → chunk-YQYG24C6.js} +4 -4
  74. package/dist/{chunk-L5DU7THE.js → chunk-ZFYML7C3.js} +2 -2
  75. package/dist/{chunk-ZL3Y3ZTQ.js → chunk-ZLOD23PD.js} +5 -5
  76. package/dist/{chunk-CTGK5VK3.js → chunk-ZQNCHPTZ.js} +2 -2
  77. package/dist/{cli-cZyANcmY.d.ts → cli-C5pCwszN.d.ts} +1 -1
  78. package/dist/cli.d.ts +2 -2
  79. package/dist/cli.js +46 -46
  80. package/dist/compounding/engine.js +3 -3
  81. package/dist/connectors/codex-materialize-runner.js +3 -3
  82. package/dist/connectors/index.js +3 -3
  83. package/dist/contradiction/index.js +4 -4
  84. package/dist/entity-retrieval.js +3 -3
  85. package/dist/{first-start-migration-RYY7PPGF.js → first-start-migration-DY6YCRC2.js} +4 -4
  86. package/dist/{graph-edge-decay-U2GKDAVM.js → graph-edge-decay-RXUCJIN4.js} +4 -4
  87. package/dist/graph-edge-decay-RXUCJIN4.js.map +1 -0
  88. package/dist/graph-snapshot.js +3 -3
  89. package/dist/graph.js +2 -2
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +85 -85
  92. package/dist/lcm/index.js +3 -3
  93. package/dist/maintenance/memory-governance.js +3 -3
  94. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  95. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  96. package/dist/mcp-memory-inspector-app.d.ts +1 -1
  97. package/dist/namespaces/migrate.js +7 -7
  98. package/dist/namespaces/search.js +3 -3
  99. package/dist/namespaces/storage.js +3 -3
  100. package/dist/operator-toolkit.js +12 -12
  101. package/dist/orchestration/maintenance.js +5 -5
  102. package/dist/orchestrator.js +70 -70
  103. package/dist/schemas.d.ts +90 -90
  104. package/dist/search/factory.js +2 -2
  105. package/dist/search/index.js +4 -4
  106. package/dist/semantic-consolidation.js +4 -4
  107. package/dist/semantic-rule-promotion.js +3 -3
  108. package/dist/semantic-rule-verifier.js +3 -3
  109. package/dist/shared-context/manager.d.ts +8 -8
  110. package/dist/storage.d.ts +3 -4
  111. package/dist/storage.js +2 -2
  112. package/dist/transfer/backup.js +3 -3
  113. package/dist/transfer/capsule-export.js +4 -4
  114. package/dist/transfer/capsule-import.js +3 -3
  115. package/dist/transfer/import-sqlite.js +2 -2
  116. package/dist/transfer/types.d.ts +66 -66
  117. package/dist/verified-recall.js +3 -3
  118. package/package.json +2 -2
  119. package/src/access-identity-continuity-surface.test.ts +374 -0
  120. package/src/access-identity-continuity-surface.ts +322 -0
  121. package/src/access-service.ts +23 -171
  122. package/src/storage/identity-continuity-store.ts +223 -0
  123. package/src/storage.ts +25 -142
  124. package/dist/chunk-4L2KHKLY.js.map +0 -1
  125. package/dist/chunk-5PHPNUZN.js.map +0 -1
  126. /package/dist/{capsule-crypto-RAARDY3M.js.map → access-identity-continuity-surface.js.map} +0 -0
  127. /package/dist/{graph-edge-decay-U2GKDAVM.js.map → capsule-crypto-CZJSLEFG.js.map} +0 -0
  128. /package/dist/{chunk-EEIROWEG.js.map → chunk-2BFLDH5F.js.map} +0 -0
  129. /package/dist/{chunk-UPSAT4PY.js.map → chunk-2MR3MFQB.js.map} +0 -0
  130. /package/dist/{chunk-IZP62CEF.js.map → chunk-3QLPBCFG.js.map} +0 -0
  131. /package/dist/{chunk-LNQUAJNC.js.map → chunk-437S3G37.js.map} +0 -0
  132. /package/dist/{chunk-6FYRCQ7K.js.map → chunk-7I2QTC2K.js.map} +0 -0
  133. /package/dist/{chunk-RQXVVENY.js.map → chunk-7ME6VBF7.js.map} +0 -0
  134. /package/dist/{chunk-AGNBY3VG.js.map → chunk-APJQ6UEA.js.map} +0 -0
  135. /package/dist/{chunk-GI7PRVMV.js.map → chunk-CJDGB3EG.js.map} +0 -0
  136. /package/dist/{chunk-IR6ATBUI.js.map → chunk-CQCCVJZO.js.map} +0 -0
  137. /package/dist/{chunk-XROP4ZHB.js.map → chunk-EHQ5HO5T.js.map} +0 -0
  138. /package/dist/{chunk-AINK3KDE.js.map → chunk-EOTTKLPJ.js.map} +0 -0
  139. /package/dist/{chunk-KTULX4YO.js.map → chunk-FLVL4L3L.js.map} +0 -0
  140. /package/dist/{chunk-6A76LSX6.js.map → chunk-HO3VUUGI.js.map} +0 -0
  141. /package/dist/{chunk-2NTWULEQ.js.map → chunk-ILB2MFTS.js.map} +0 -0
  142. /package/dist/{chunk-FBS6V6LJ.js.map → chunk-IWI2ICTF.js.map} +0 -0
  143. /package/dist/{chunk-FFPH47IX.js.map → chunk-K2DJQOE3.js.map} +0 -0
  144. /package/dist/{chunk-6DMTYBNY.js.map → chunk-LQDA67TT.js.map} +0 -0
  145. /package/dist/{chunk-7HJ3XBMD.js.map → chunk-LX4ZWRGD.js.map} +0 -0
  146. /package/dist/{chunk-CYWCKFCL.js.map → chunk-M5QKGHCR.js.map} +0 -0
  147. /package/dist/{chunk-QVQG7W2H.js.map → chunk-ODC4HOUZ.js.map} +0 -0
  148. /package/dist/{chunk-ZG2WP425.js.map → chunk-ORAK3LNZ.js.map} +0 -0
  149. /package/dist/{chunk-LVMVYLNB.js.map → chunk-PJ5AG6D4.js.map} +0 -0
  150. /package/dist/{chunk-GIJDW2YO.js.map → chunk-QEAOKI4U.js.map} +0 -0
  151. /package/dist/{chunk-MQQO56LN.js.map → chunk-QJUZAUAD.js.map} +0 -0
  152. /package/dist/{chunk-SUN6XVNI.js.map → chunk-QKOTOUVR.js.map} +0 -0
  153. /package/dist/{chunk-XKUYMM34.js.map → chunk-RF6BZHOD.js.map} +0 -0
  154. /package/dist/{chunk-I65IQD7Y.js.map → chunk-RQNV75HR.js.map} +0 -0
  155. /package/dist/{chunk-ZE7GJ76H.js.map → chunk-SQNED75R.js.map} +0 -0
  156. /package/dist/{chunk-PHWBKQHK.js.map → chunk-TMXTQCJ7.js.map} +0 -0
  157. /package/dist/{chunk-PMBWVQ7D.js.map → chunk-TQT3USCG.js.map} +0 -0
  158. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  159. /package/dist/{chunk-T3UW6NRQ.js.map → chunk-TVWF3GNF.js.map} +0 -0
  160. /package/dist/{chunk-IF6BTZCB.js.map → chunk-XQT5GSWU.js.map} +0 -0
  161. /package/dist/{chunk-PXHY2E3S.js.map → chunk-YQYG24C6.js.map} +0 -0
  162. /package/dist/{chunk-L5DU7THE.js.map → chunk-ZFYML7C3.js.map} +0 -0
  163. /package/dist/{chunk-ZL3Y3ZTQ.js.map → chunk-ZLOD23PD.js.map} +0 -0
  164. /package/dist/{chunk-CTGK5VK3.js.map → chunk-ZQNCHPTZ.js.map} +0 -0
  165. /package/dist/{first-start-migration-RYY7PPGF.js.map → first-start-migration-DY6YCRC2.js.map} +0 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Access identity-continuity surface.
3
+ *
4
+ * Owns continuity audits, incident and improvement-loop operations, identity
5
+ * anchor access, and legacy identity-reflection reads. EngramAccessService
6
+ * remains the public facade and supplies live namespace/orchestrator bindings.
7
+ */
8
+
9
+ import {
10
+ resolveConsolidationCapabilities,
11
+ resolveIdentityContinuityCapabilities,
12
+ resolveRecallAuxiliaryCapabilities,
13
+ } from "./capabilities.js";
14
+ import type { Orchestrator } from "./orchestrator.js";
15
+ import { EngramAccessInputError } from "./access-service.js";
16
+
17
+ export interface AccessIdentityContinuitySurfaceDeps {
18
+ readonly orchestrator: Orchestrator;
19
+ resolveReadableNamespace(namespace: string | undefined, principal?: string): string;
20
+ writableNamespaceFor(
21
+ namespace: string | undefined,
22
+ sessionKey: string | undefined,
23
+ authenticatedPrincipal?: string
24
+ ): string;
25
+ }
26
+
27
+ export class AccessIdentityContinuitySurface {
28
+ constructor(private readonly deps: AccessIdentityContinuitySurfaceDeps) {}
29
+
30
+ async continuityAuditGenerate(request: {
31
+ period?: "weekly" | "monthly";
32
+ key?: string;
33
+ }): Promise<{ enabled: boolean; reason?: string; period?: string; key?: string; reportPath?: string }> {
34
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
35
+ return {
36
+ enabled: false,
37
+ reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`.",
38
+ };
39
+ }
40
+ if (!resolveConsolidationCapabilities(this.deps.orchestrator.config).continuityAudit) {
41
+ return {
42
+ enabled: false,
43
+ reason: "Continuity audits are disabled. Enable `continuityAuditEnabled: true`.",
44
+ };
45
+ }
46
+ if (!this.deps.orchestrator.compounding) {
47
+ return {
48
+ enabled: false,
49
+ reason: "Compounding engine is disabled. Enable `compoundingEnabled: true`.",
50
+ };
51
+ }
52
+ const period = request.period === "monthly" ? "monthly" : "weekly";
53
+ const key = request.key?.trim() || undefined;
54
+ const audit = await this.deps.orchestrator.compounding.synthesizeContinuityAudit({ period, key });
55
+ return { enabled: true, period: audit.period, key: audit.key, reportPath: audit.reportPath };
56
+ }
57
+
58
+ async continuityIncidentOpen(request: {
59
+ symptom: string;
60
+ namespace?: string;
61
+ principal?: string;
62
+ triggerWindow?: string;
63
+ suspectedCause?: string;
64
+ }): Promise<unknown> {
65
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
66
+ return {
67
+ enabled: false,
68
+ reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`.",
69
+ };
70
+ }
71
+ if (!resolveRecallAuxiliaryCapabilities(this.deps.orchestrator.config).continuityIncidentLogging) {
72
+ return {
73
+ enabled: false,
74
+ reason: "Continuity incident logging is disabled. Enable `continuityIncidentLoggingEnabled: true`.",
75
+ };
76
+ }
77
+ const symptom = request.symptom?.trim();
78
+ if (!symptom) throw new EngramAccessInputError("symptom is required");
79
+ const resolvedNs = this.deps.writableNamespaceFor(request.namespace, undefined, request.principal);
80
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
81
+ const created = await storage.appendContinuityIncident({
82
+ symptom,
83
+ triggerWindow: request.triggerWindow?.trim() || undefined,
84
+ suspectedCause: request.suspectedCause?.trim() || undefined,
85
+ });
86
+ return { created: true, incident: created };
87
+ }
88
+
89
+ async continuityIncidentClose(request: {
90
+ id: string;
91
+ namespace?: string;
92
+ principal?: string;
93
+ fixApplied: string;
94
+ verificationResult: string;
95
+ preventiveRule?: string;
96
+ }): Promise<unknown> {
97
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
98
+ return { enabled: false, reason: "Identity continuity is disabled." };
99
+ }
100
+ if (!resolveRecallAuxiliaryCapabilities(this.deps.orchestrator.config).continuityIncidentLogging) {
101
+ return { enabled: false, reason: "Continuity incident logging is disabled." };
102
+ }
103
+ const id = request.id?.trim();
104
+ if (!id) throw new EngramAccessInputError("id is required");
105
+ const fixApplied = request.fixApplied?.trim();
106
+ if (!fixApplied) throw new EngramAccessInputError("fixApplied is required");
107
+ const verificationResult = request.verificationResult?.trim();
108
+ if (!verificationResult) throw new EngramAccessInputError("verificationResult is required");
109
+ const resolvedNs = this.deps.writableNamespaceFor(request.namespace, undefined, request.principal);
110
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
111
+ const closed = await storage.closeContinuityIncident(id, {
112
+ fixApplied,
113
+ verificationResult,
114
+ preventiveRule: request.preventiveRule?.trim() || undefined,
115
+ });
116
+ if (!closed) return { closed: false, reason: `Incident not found: ${id}` };
117
+ return { closed: true, incident: closed };
118
+ }
119
+
120
+ async continuityIncidentList(request: {
121
+ state?: "open" | "closed" | "all";
122
+ namespace?: string;
123
+ principal?: string;
124
+ limit?: number;
125
+ }): Promise<unknown> {
126
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
127
+ return { enabled: false, reason: "Identity continuity is disabled." };
128
+ }
129
+ const state = request.state === "closed" || request.state === "all" ? request.state : "open";
130
+ const limit = Math.max(1, Math.min(200, Math.floor(request.limit ?? 25)));
131
+ const resolvedNs = this.deps.resolveReadableNamespace(request.namespace, request.principal);
132
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
133
+ const incidents = await storage.readContinuityIncidents(limit, state);
134
+ return { state, incidents, count: incidents.length };
135
+ }
136
+
137
+ async continuityLoopAddOrUpdate(request: {
138
+ id: string;
139
+ cadence: "daily" | "weekly" | "monthly" | "quarterly";
140
+ purpose: string;
141
+ status: "active" | "paused" | "retired";
142
+ killCondition: string;
143
+ namespace?: string;
144
+ principal?: string;
145
+ lastReviewed?: string;
146
+ notes?: string;
147
+ }): Promise<unknown> {
148
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
149
+ return { enabled: false, reason: "Identity continuity is disabled." };
150
+ }
151
+ const resolvedNs = this.deps.writableNamespaceFor(request.namespace, undefined, request.principal);
152
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
153
+ const loop = await storage.upsertIdentityImprovementLoop({
154
+ id: request.id?.trim() || "",
155
+ cadence: request.cadence,
156
+ purpose: request.purpose?.trim() || "",
157
+ status: request.status,
158
+ killCondition: request.killCondition?.trim() || "",
159
+ lastReviewed: request.lastReviewed?.trim() || undefined,
160
+ notes: request.notes?.trim() || undefined,
161
+ });
162
+ return { saved: true, loop };
163
+ }
164
+
165
+ async continuityLoopReview(request: {
166
+ id: string;
167
+ namespace?: string;
168
+ principal?: string;
169
+ status?: "active" | "paused" | "retired";
170
+ notes?: string;
171
+ reviewedAt?: string;
172
+ }): Promise<unknown> {
173
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
174
+ return { enabled: false, reason: "Identity continuity is disabled." };
175
+ }
176
+ const id = request.id?.trim();
177
+ if (!id) throw new EngramAccessInputError("id is required");
178
+ const resolvedNs = this.deps.writableNamespaceFor(request.namespace, undefined, request.principal);
179
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
180
+ const reviewed = await storage.reviewIdentityImprovementLoop(id, {
181
+ status: request.status,
182
+ notes: request.notes?.trim() || undefined,
183
+ reviewedAt: request.reviewedAt?.trim() || undefined,
184
+ });
185
+ if (!reviewed) return { reviewed: false, reason: `Continuity loop not found: ${id}` };
186
+ return { reviewed: true, loop: reviewed };
187
+ }
188
+
189
+ async identityAnchorGet(request: {
190
+ namespace?: string;
191
+ principal?: string;
192
+ }): Promise<unknown> {
193
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
194
+ return { enabled: false, reason: "Identity continuity is disabled." };
195
+ }
196
+ const resolvedNs = this.deps.resolveReadableNamespace(request.namespace, request.principal);
197
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
198
+ const anchor = await storage.readIdentityAnchor();
199
+ if (!anchor) {
200
+ return {
201
+ found: false,
202
+ message: "No identity anchor found yet. Use identity_anchor_update to create one.",
203
+ };
204
+ }
205
+ return { found: true, anchor };
206
+ }
207
+
208
+ async identityAnchorUpdate(request: {
209
+ namespace?: string;
210
+ principal?: string;
211
+ identityTraits?: string;
212
+ communicationPreferences?: string;
213
+ operatingPrinciples?: string;
214
+ continuityNotes?: string;
215
+ }): Promise<unknown> {
216
+ if (!resolveIdentityContinuityCapabilities(this.deps.orchestrator.config).identityContinuity) {
217
+ return { enabled: false, reason: "Identity continuity is disabled." };
218
+ }
219
+
220
+ const updates: Record<string, string | undefined> = {
221
+ "Identity Traits": request.identityTraits?.trim() || undefined,
222
+ "Communication Preferences": request.communicationPreferences?.trim() || undefined,
223
+ "Operating Principles": request.operatingPrinciples?.trim() || undefined,
224
+ "Continuity Notes": request.continuityNotes?.trim() || undefined,
225
+ };
226
+ const hasUpdate = Object.values(updates).some((value) => typeof value === "string" && value.length > 0);
227
+ if (!hasUpdate) {
228
+ throw new EngramAccessInputError("At least one section field is required.");
229
+ }
230
+
231
+ const resolvedNs = this.deps.writableNamespaceFor(request.namespace, undefined, request.principal);
232
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
233
+ const existing = await storage.readIdentityAnchor();
234
+ const merged = this.mergeIdentityAnchorSections(existing, updates);
235
+ await storage.writeIdentityAnchor(merged);
236
+
237
+ const updatedSections = Object.entries(updates)
238
+ .filter(([, value]) => typeof value === "string" && value.length > 0)
239
+ .map(([name]) => name);
240
+ return { updated: true, sections: updatedSections, anchor: merged };
241
+ }
242
+
243
+ async memoryIdentity(request: {
244
+ namespace?: string;
245
+ principal?: string;
246
+ }): Promise<unknown> {
247
+ const resolvedNs = this.deps.resolveReadableNamespace(request.namespace, request.principal);
248
+ const storage = await this.deps.orchestrator.getStorage(resolvedNs);
249
+ const identity = await storage.readIdentityReflections();
250
+ if (!identity) return { found: false, message: "No identity reflections found." };
251
+ return { found: true, identity };
252
+ }
253
+
254
+ /** Conservative identity anchor section merge (matches tools.ts mergeIdentityAnchor logic). */
255
+ private mergeIdentityAnchorSections(existingRaw: string | null, updates: Record<string, string | undefined>): string {
256
+ const title = "# Identity Continuity Anchor";
257
+ const sectionOrder = ["Identity Traits", "Communication Preferences", "Operating Principles", "Continuity Notes"];
258
+
259
+ const lines = (existingRaw ?? "").replace(/\r/g, "").split("\n");
260
+ const headerLines: string[] = [];
261
+ const sectionContent = new Map<string, string[]>();
262
+ const order: string[] = [];
263
+ let current: string | null = null;
264
+ for (const line of lines) {
265
+ const match = line.match(/^##\s+(.+?)\s*$/);
266
+ if (match) {
267
+ current = match[1].trim();
268
+ if (!sectionContent.has(current)) {
269
+ sectionContent.set(current, []);
270
+ order.push(current);
271
+ }
272
+ continue;
273
+ }
274
+ if (!current) {
275
+ headerLines.push(line);
276
+ } else {
277
+ sectionContent.get(current)?.push(line);
278
+ }
279
+ }
280
+ const sections = new Map<string, string>();
281
+ for (const [name, contentLines] of sectionContent) {
282
+ sections.set(name, contentLines.join("\n").trim());
283
+ }
284
+
285
+ const header = headerLines.join("\n").trim() || title;
286
+ for (const sectionName of sectionOrder) {
287
+ const previous = sections.get(sectionName)?.trim();
288
+ const next = updates[sectionName]?.trim();
289
+ const existing = previous === "- (empty)" ? "" : previous;
290
+ if (!next) {
291
+ if (!sections.has(sectionName)) sections.set(sectionName, "");
292
+ continue;
293
+ }
294
+ if (!existing) {
295
+ sections.set(sectionName, next);
296
+ continue;
297
+ }
298
+ if (existing.includes(next)) continue;
299
+ if (next.includes(existing)) {
300
+ sections.set(sectionName, next);
301
+ continue;
302
+ }
303
+ sections.set(sectionName, `${existing}\n\n${next}`);
304
+ }
305
+
306
+ const finalOrder = [
307
+ ...sectionOrder.filter((section) => sections.has(section)),
308
+ ...order.filter((section) => !sectionOrder.includes(section) && sections.has(section)),
309
+ ];
310
+ const output: string[] = [header, ""];
311
+ for (const name of finalOrder) {
312
+ output.push(`## ${name}`, "");
313
+ const body = sections.get(name)?.trim();
314
+ if (body) output.push(body, "");
315
+ else output.push("");
316
+ }
317
+ return `${output
318
+ .join("\n")
319
+ .replace(/\n{3,}/g, "\n\n")
320
+ .trimEnd()}\n`;
321
+ }
322
+ }
@@ -8,8 +8,7 @@ import { AccessIdempotencyStore, hashAccessIdempotencyPayload } from "./access-i
8
8
  import { resolveNamespaceCapabilities,
9
9
  resolveMemoryLifecycleCapabilities,
10
10
  resolveQmdCapabilities,
11
- resolveIdentityContinuityCapabilities,
12
- resolveSecurityCapabilities, resolveObjectiveStateCapabilities, resolveCompressionCapabilities, resolveConsolidationCapabilities, resolveRecallAuxiliaryCapabilities } from "./capabilities.js";
11
+ resolveSecurityCapabilities, resolveObjectiveStateCapabilities, resolveCompressionCapabilities, resolveRecallAuxiliaryCapabilities } from "./capabilities.js";
13
12
  import { AccessAuditAdapter, type AccessAuditConfig, type AccessAuditResult } from "./access-audit.js";
14
13
  import type { AnomalyDetectorResult } from "./recall-audit-anomaly.js";
15
14
  import { resolveGitContext } from "./coding/git-context.js";
@@ -255,6 +254,7 @@ import { AccessObserveWriteSurface } from "./access-observe-write-surface.js";
255
254
  import { AccessLcmSurface } from "./access-lcm-surface.js";
256
255
  import { AccessAdminOpsSurface } from "./access-admin-ops-surface.js";
257
256
  import { AccessRecallSurface } from "./access-recall-surface.js";
257
+ import { AccessIdentityContinuitySurface } from "./access-identity-continuity-surface.js";
258
258
  import { selfDeps } from "./orchestration/self-deps.js";
259
259
 
260
260
  export class EngramAccessInputError extends Error {}
@@ -1358,6 +1358,18 @@ export class EngramAccessService {
1358
1358
  return this._accessRecallSurface;
1359
1359
  }
1360
1360
 
1361
+ /** AccessIdentityContinuitySurface (access-service decomposition). Lazy; selfDeps live wiring. */
1362
+ private _accessIdentityContinuitySurface: AccessIdentityContinuitySurface | undefined;
1363
+
1364
+ private get accessIdentityContinuitySurface(): AccessIdentityContinuitySurface {
1365
+ if (!this._accessIdentityContinuitySurface) {
1366
+ this._accessIdentityContinuitySurface = new AccessIdentityContinuitySurface(
1367
+ selfDeps<ConstructorParameters<typeof AccessIdentityContinuitySurface>[0]>(this),
1368
+ );
1369
+ }
1370
+ return this._accessIdentityContinuitySurface;
1371
+ }
1372
+
1361
1373
  constructor(private readonly orchestrator: Orchestrator) {
1362
1374
  this.idempotency = new AccessIdempotencyStore(orchestrator.config.memoryDir);
1363
1375
  const accessCaps = resolveAccessSetupCapabilities(orchestrator.config); // #1566 Cluster B
@@ -4423,19 +4435,7 @@ export class EngramAccessService {
4423
4435
  period?: "weekly" | "monthly";
4424
4436
  key?: string;
4425
4437
  }): Promise<{ enabled: boolean; reason?: string; period?: string; key?: string; reportPath?: string }> {
4426
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4427
- return { enabled: false, reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`." };
4428
- }
4429
- if (!resolveConsolidationCapabilities(this.orchestrator.config).continuityAudit) {
4430
- return { enabled: false, reason: "Continuity audits are disabled. Enable `continuityAuditEnabled: true`." };
4431
- }
4432
- if (!this.orchestrator.compounding) {
4433
- return { enabled: false, reason: "Compounding engine is disabled. Enable `compoundingEnabled: true`." };
4434
- }
4435
- const period = request.period === "monthly" ? "monthly" : "weekly";
4436
- const key = request.key?.trim() || undefined;
4437
- const audit = await this.orchestrator.compounding.synthesizeContinuityAudit({ period, key });
4438
- return { enabled: true, period: audit.period, key: audit.key, reportPath: audit.reportPath };
4438
+ return this.accessIdentityContinuitySurface.continuityAuditGenerate(request);
4439
4439
  }
4440
4440
 
4441
4441
  async continuityIncidentOpen(request: {
@@ -4445,22 +4445,7 @@ export class EngramAccessService {
4445
4445
  triggerWindow?: string;
4446
4446
  suspectedCause?: string;
4447
4447
  }): Promise<unknown> {
4448
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4449
- return { enabled: false, reason: "Identity continuity is disabled. Enable `identityContinuityEnabled: true`." };
4450
- }
4451
- if (!resolveRecallAuxiliaryCapabilities(this.orchestrator.config).continuityIncidentLogging) {
4452
- return { enabled: false, reason: "Continuity incident logging is disabled. Enable `continuityIncidentLoggingEnabled: true`." };
4453
- }
4454
- const symptom = request.symptom?.trim();
4455
- if (!symptom) throw new EngramAccessInputError("symptom is required");
4456
- const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
4457
- const storage = await this.orchestrator.getStorage(resolvedNs);
4458
- const created = await storage.appendContinuityIncident({
4459
- symptom,
4460
- triggerWindow: request.triggerWindow?.trim() || undefined,
4461
- suspectedCause: request.suspectedCause?.trim() || undefined,
4462
- });
4463
- return { created: true, incident: created };
4448
+ return this.accessIdentityContinuitySurface.continuityIncidentOpen(request);
4464
4449
  }
4465
4450
 
4466
4451
  async continuityIncidentClose(request: {
@@ -4471,27 +4456,7 @@ export class EngramAccessService {
4471
4456
  verificationResult: string;
4472
4457
  preventiveRule?: string;
4473
4458
  }): Promise<unknown> {
4474
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4475
- return { enabled: false, reason: "Identity continuity is disabled." };
4476
- }
4477
- if (!resolveRecallAuxiliaryCapabilities(this.orchestrator.config).continuityIncidentLogging) {
4478
- return { enabled: false, reason: "Continuity incident logging is disabled." };
4479
- }
4480
- const id = request.id?.trim();
4481
- if (!id) throw new EngramAccessInputError("id is required");
4482
- const fixApplied = request.fixApplied?.trim();
4483
- if (!fixApplied) throw new EngramAccessInputError("fixApplied is required");
4484
- const verificationResult = request.verificationResult?.trim();
4485
- if (!verificationResult) throw new EngramAccessInputError("verificationResult is required");
4486
- const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
4487
- const storage = await this.orchestrator.getStorage(resolvedNs);
4488
- const closed = await storage.closeContinuityIncident(id, {
4489
- fixApplied,
4490
- verificationResult,
4491
- preventiveRule: request.preventiveRule?.trim() || undefined,
4492
- });
4493
- if (!closed) return { closed: false, reason: `Incident not found: ${id}` };
4494
- return { closed: true, incident: closed };
4459
+ return this.accessIdentityContinuitySurface.continuityIncidentClose(request);
4495
4460
  }
4496
4461
 
4497
4462
  async continuityIncidentList(request: {
@@ -4500,15 +4465,7 @@ export class EngramAccessService {
4500
4465
  principal?: string;
4501
4466
  limit?: number;
4502
4467
  }): Promise<unknown> {
4503
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4504
- return { enabled: false, reason: "Identity continuity is disabled." };
4505
- }
4506
- const state = request.state === "closed" || request.state === "all" ? request.state : "open";
4507
- const limit = Math.max(1, Math.min(200, Math.floor(request.limit ?? 25)));
4508
- const resolvedNs = this.resolveReadableNamespace(request.namespace, request.principal);
4509
- const storage = await this.orchestrator.getStorage(resolvedNs);
4510
- const incidents = await storage.readContinuityIncidents(limit, state);
4511
- return { state, incidents, count: incidents.length };
4468
+ return this.accessIdentityContinuitySurface.continuityIncidentList(request);
4512
4469
  }
4513
4470
 
4514
4471
  async continuityLoopAddOrUpdate(request: {
@@ -4522,21 +4479,7 @@ export class EngramAccessService {
4522
4479
  lastReviewed?: string;
4523
4480
  notes?: string;
4524
4481
  }): Promise<unknown> {
4525
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4526
- return { enabled: false, reason: "Identity continuity is disabled." };
4527
- }
4528
- const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
4529
- const storage = await this.orchestrator.getStorage(resolvedNs);
4530
- const loop = await storage.upsertIdentityImprovementLoop({
4531
- id: request.id?.trim() || "",
4532
- cadence: request.cadence,
4533
- purpose: request.purpose?.trim() || "",
4534
- status: request.status,
4535
- killCondition: request.killCondition?.trim() || "",
4536
- lastReviewed: request.lastReviewed?.trim() || undefined,
4537
- notes: request.notes?.trim() || undefined,
4538
- });
4539
- return { saved: true, loop };
4482
+ return this.accessIdentityContinuitySurface.continuityLoopAddOrUpdate(request);
4540
4483
  }
4541
4484
 
4542
4485
  async continuityLoopReview(request: {
@@ -4547,34 +4490,14 @@ export class EngramAccessService {
4547
4490
  notes?: string;
4548
4491
  reviewedAt?: string;
4549
4492
  }): Promise<unknown> {
4550
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4551
- return { enabled: false, reason: "Identity continuity is disabled." };
4552
- }
4553
- const id = request.id?.trim();
4554
- if (!id) throw new EngramAccessInputError("id is required");
4555
- const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
4556
- const storage = await this.orchestrator.getStorage(resolvedNs);
4557
- const reviewed = await storage.reviewIdentityImprovementLoop(id, {
4558
- status: request.status,
4559
- notes: request.notes?.trim() || undefined,
4560
- reviewedAt: request.reviewedAt?.trim() || undefined,
4561
- });
4562
- if (!reviewed) return { reviewed: false, reason: `Continuity loop not found: ${id}` };
4563
- return { reviewed: true, loop: reviewed };
4493
+ return this.accessIdentityContinuitySurface.continuityLoopReview(request);
4564
4494
  }
4565
4495
 
4566
4496
  async identityAnchorGet(request: {
4567
4497
  namespace?: string;
4568
4498
  principal?: string;
4569
4499
  }): Promise<unknown> {
4570
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4571
- return { enabled: false, reason: "Identity continuity is disabled." };
4572
- }
4573
- const resolvedNs = this.resolveReadableNamespace(request.namespace, request.principal);
4574
- const storage = await this.orchestrator.getStorage(resolvedNs);
4575
- const anchor = await storage.readIdentityAnchor();
4576
- if (!anchor) return { found: false, message: "No identity anchor found yet. Use identity_anchor_update to create one." };
4577
- return { found: true, anchor };
4500
+ return this.accessIdentityContinuitySurface.identityAnchorGet(request);
4578
4501
  }
4579
4502
 
4580
4503
  /**
@@ -4593,42 +4516,14 @@ export class EngramAccessService {
4593
4516
  operatingPrinciples?: string;
4594
4517
  continuityNotes?: string;
4595
4518
  }): Promise<unknown> {
4596
- if (!resolveIdentityContinuityCapabilities(this.orchestrator.config).identityContinuity) {
4597
- return { enabled: false, reason: "Identity continuity is disabled." };
4598
- }
4599
-
4600
- const updates: Record<string, string | undefined> = {
4601
- "Identity Traits": request.identityTraits?.trim() || undefined,
4602
- "Communication Preferences": request.communicationPreferences?.trim() || undefined,
4603
- "Operating Principles": request.operatingPrinciples?.trim() || undefined,
4604
- "Continuity Notes": request.continuityNotes?.trim() || undefined,
4605
- };
4606
- const hasUpdate = Object.values(updates).some((v) => typeof v === "string" && v.length > 0);
4607
- if (!hasUpdate) throw new EngramAccessInputError("At least one section field is required.");
4608
-
4609
- const resolvedNs = this.writableNamespaceFor(request.namespace, undefined, request.principal);
4610
- const storage = await this.orchestrator.getStorage(resolvedNs);
4611
- const existing = await storage.readIdentityAnchor();
4612
-
4613
- // Merge sections conservatively (append, don't overwrite)
4614
- const merged = this.mergeIdentityAnchorSections(existing, updates);
4615
- await storage.writeIdentityAnchor(merged);
4616
-
4617
- const updatedSections = Object.entries(updates)
4618
- .filter(([, v]) => typeof v === "string" && v.length > 0)
4619
- .map(([name]) => name);
4620
- return { updated: true, sections: updatedSections, anchor: merged };
4519
+ return this.accessIdentityContinuitySurface.identityAnchorUpdate(request);
4621
4520
  }
4622
4521
 
4623
4522
  async memoryIdentity(request: {
4624
4523
  namespace?: string;
4625
4524
  principal?: string;
4626
4525
  }): Promise<unknown> {
4627
- const resolvedNs = this.resolveReadableNamespace(request.namespace, request.principal);
4628
- const storage = await this.orchestrator.getStorage(resolvedNs);
4629
- const identity = await storage.readIdentityReflections();
4630
- if (!identity) return { found: false, message: "No identity reflections found." };
4631
- return { found: true, identity };
4526
+ return this.accessIdentityContinuitySurface.memoryIdentity(request);
4632
4527
  }
4633
4528
 
4634
4529
  // ── Work Layer ──────────────────────────────────────────────────────────
@@ -4838,49 +4733,6 @@ export class EngramAccessService {
4838
4733
  });
4839
4734
  }
4840
4735
 
4841
- /** Conservative identity anchor section merge (matches tools.ts mergeIdentityAnchor logic). */
4842
- private mergeIdentityAnchorSections(
4843
- existingRaw: string | null,
4844
- updates: Record<string, string | undefined>,
4845
- ): string {
4846
- const TITLE = "# Identity Continuity Anchor";
4847
- const SECTION_ORDER = ["Identity Traits", "Communication Preferences", "Operating Principles", "Continuity Notes"];
4848
-
4849
- const lines = (existingRaw ?? "").replace(/\r/g, "").split("\n");
4850
- const headerLines: string[] = [];
4851
- const sectionContent = new Map<string, string[]>();
4852
- const order: string[] = [];
4853
- let current: string | null = null;
4854
- for (const line of lines) {
4855
- const m = line.match(/^##\s+(.+?)\s*$/);
4856
- if (m) { current = m[1].trim(); if (!sectionContent.has(current)) { sectionContent.set(current, []); order.push(current); } continue; }
4857
- if (!current) { headerLines.push(line); } else { sectionContent.get(current)?.push(line); }
4858
- }
4859
- const sections = new Map<string, string>();
4860
- for (const [name, cLines] of sectionContent) sections.set(name, cLines.join("\n").trim());
4861
-
4862
- const header = headerLines.join("\n").trim() || TITLE;
4863
- for (const sectionName of SECTION_ORDER) {
4864
- const prev = sections.get(sectionName)?.trim();
4865
- const next = updates[sectionName]?.trim();
4866
- const existing = prev === "- (empty)" ? "" : prev;
4867
- if (!next) { if (!sections.has(sectionName)) sections.set(sectionName, ""); continue; }
4868
- if (!existing) { sections.set(sectionName, next); continue; }
4869
- if (existing.includes(next)) continue;
4870
- if (next.includes(existing)) { sections.set(sectionName, next); continue; }
4871
- sections.set(sectionName, `${existing}\n\n${next}`);
4872
- }
4873
-
4874
- const finalOrder = [...SECTION_ORDER.filter((s) => sections.has(s)), ...order.filter((s) => !SECTION_ORDER.includes(s) && sections.has(s))];
4875
- const out: string[] = [header, ""];
4876
- for (const name of finalOrder) {
4877
- out.push(`## ${name}`, "");
4878
- const body = sections.get(name)?.trim();
4879
- if (body) out.push(body, "");
4880
- else out.push("");
4881
- }
4882
- return out.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd() + "\n";
4883
- }
4884
4736
 
4885
4737
  // ── Memory search & debug ─────────────────────────────────────────────
4886
4738