instar 1.3.548 → 1.3.550

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 (46) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +122 -5
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +29 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/CoherenceJournal.d.ts +1 -1
  8. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  9. package/dist/core/CoherenceJournal.js +23 -2
  10. package/dist/core/CoherenceJournal.js.map +1 -1
  11. package/dist/core/CredentialRebalancerSnapshot.d.ts +17 -0
  12. package/dist/core/CredentialRebalancerSnapshot.d.ts.map +1 -1
  13. package/dist/core/CredentialRebalancerSnapshot.js +24 -0
  14. package/dist/core/CredentialRebalancerSnapshot.js.map +1 -1
  15. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  16. package/dist/core/PostUpdateMigrator.js +27 -1
  17. package/dist/core/PostUpdateMigrator.js.map +1 -1
  18. package/dist/core/TopicOperatorReplicatedStore.d.ts +250 -0
  19. package/dist/core/TopicOperatorReplicatedStore.d.ts.map +1 -0
  20. package/dist/core/TopicOperatorReplicatedStore.js +413 -0
  21. package/dist/core/TopicOperatorReplicatedStore.js.map +1 -0
  22. package/dist/core/UserRegistryReplicatedStore.d.ts +287 -0
  23. package/dist/core/UserRegistryReplicatedStore.d.ts.map +1 -0
  24. package/dist/core/UserRegistryReplicatedStore.js +527 -0
  25. package/dist/core/UserRegistryReplicatedStore.js.map +1 -0
  26. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  27. package/dist/core/devGatedFeatures.js +10 -0
  28. package/dist/core/devGatedFeatures.js.map +1 -1
  29. package/dist/scaffold/templates.d.ts.map +1 -1
  30. package/dist/scaffold/templates.js +3 -1
  31. package/dist/scaffold/templates.js.map +1 -1
  32. package/dist/users/TopicOperatorStore.d.ts +24 -0
  33. package/dist/users/TopicOperatorStore.d.ts.map +1 -1
  34. package/dist/users/TopicOperatorStore.js +28 -0
  35. package/dist/users/TopicOperatorStore.js.map +1 -1
  36. package/dist/users/UserManager.d.ts +27 -0
  37. package/dist/users/UserManager.d.ts.map +1 -1
  38. package/dist/users/UserManager.js +44 -0
  39. package/dist/users/UserManager.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/data/builtin-manifest.json +19 -19
  42. package/src/scaffold/templates.ts +3 -1
  43. package/upgrades/1.3.549.md +36 -0
  44. package/upgrades/1.3.550.md +23 -0
  45. package/upgrades/side-effects/multi-machine-replicated-store-ws26-user-topicop.md +123 -0
  46. package/upgrades/side-effects/ws52-busyness.md +38 -0
@@ -0,0 +1,527 @@
1
+ /**
2
+ * UserRegistryReplicatedStore — the SIXTH concrete consumer of the HLC replicated-store
3
+ * foundation (WS2.6a) and the SECOND PII kind (after WS2.3 relationships). It layers the
4
+ * `user-record` replicated kind onto the generic substrate (ReplicatedRecordEnvelope /
5
+ * UnionReader / ConflictStore / RollbackUnmerge / ReplicationBudget / StoreSnapshot) so that
6
+ * a user the agent knows on machine A is known on machine B — ONE user registry, not
7
+ * one-per-machine.
8
+ *
9
+ * It is the literal analog of `RelationshipsReplicatedStore.ts` (the WS2.3 PII reference
10
+ * consumer): a UserProfile is a registered principal (the multi-user identity the
11
+ * UserManager resolves an inbound message to), so it carries directly-identifying PII and
12
+ * REUSES the WS2.3 PII machinery (type-clamp, disclosure-min projection, channel-set
13
+ * recordKey, tombstones, flag-coherence) rather than reinventing or downgrading it. THIS IS
14
+ * PURE LOGIC. No fs, no Date directly, no network. It defines:
15
+ *
16
+ * A. The `user-record` store schema — a STRICT typed validator that TYPE-CLAMPS every
17
+ * known field (`createdAt` ISO-8601-or-absent, `telegramUserId` a finite number,
18
+ * `channels[]`/`permissions[]`/free text length-bounded + jailed). The schema is a
19
+ * DISCRIMINATED UNION on `op` — an `op:'put'` VALUE schema AND an `op:'delete'`
20
+ * TOMBSTONE schema coexist under the one kind, so a tombstone is never marked invalid
21
+ * by the value schema.
22
+ *
23
+ * B. The disclosure-minimized PROJECTION — `buildUserRecordData` emits ONLY the enumerated
24
+ * resolution + merge-relevant fields, NEVER the raw on-disk blob and NEVER the local
25
+ * `userId` `id`. `recordKey` is the cross-machine IDENTITY SURFACE, derived
26
+ * deterministically from the SORTED channel-set ("type:identifier" pairs) — the SAME
27
+ * identity model as relationships (a user IS their channel identifiers, mirroring
28
+ * UserManager.channelIndex) — never the per-machine `userId` (VM-A and VM-B mint
29
+ * different ids for the same human; a UUID-keyed record could never collide them).
30
+ *
31
+ * C. The TOMBSTONE builder — `buildUserTombstoneData` emits an `op:'delete'` record
32
+ * `{ recordKey, op, hlc, origin, deletedAt }` so a removeUser propagates as a positive
33
+ * signal across an offline-then-rejoining peer instead of a record absence. CRITICAL:
34
+ * the UserManager.removeUser() path MUST emit a tombstone, else a peer re-replicates the
35
+ * locally-removed user forever (resurrection).
36
+ *
37
+ * D. The union-aware read — `mergeUnionToUsers` collapses a `Map<recordKey, UnionResult>`
38
+ * into the merged user view. Users are HIGH-impact at the REPLICATION layer (a concurrent
39
+ * divergent edit to the SAME channel-set identity goes through APPEND-BOTH-AND-FLAG —
40
+ * both versions surface, never a silent clobber; auto-merging two divergent profiles
41
+ * could fuse two distinct humans). The CONSUMER READ path is ADVISORY: a replicated user
42
+ * record is a HINT about what my OTHER machines know — NEVER my authoritative answer to
43
+ * "who is this inbound sender?" (identity RESOLUTION of an inbound principal is
44
+ * LOCAL-ONLY, mirroring REQ-M14 — the local channelIndex is always authoritative). The
45
+ * read NEVER writes a foreign record into the local store.
46
+ *
47
+ * E. Foreign-record render safety — `renderForeignUserContext` wraps a replicated record in
48
+ * an explicit `<replicated-untrusted-data origin="…">` envelope and sanitizes EVERY
49
+ * rendered field. There is no "trusted because machine-set" render slot for a foreign
50
+ * record.
51
+ *
52
+ * DECIDED FORKS (build prompt, recorded verbatim in the PR ELI16):
53
+ * 1. recordKey = sha256 of the SORTED channel-set ("type:identifier" pairs), NEVER the
54
+ * local `userId` (cross-machine identity surface — see deriveUserRecordKey).
55
+ * 2. Impact tier = HIGH at the REPLICATION layer (append-both-and-flag), ADVISORY at the
56
+ * READ layer (a replicated user is a hint, never the authoritative inbound-resolution).
57
+ * 3. disclosure-min: strip the local `userId` — a peer's local id is meaningless + a mild
58
+ * correlation leak; the channel-set IS the cross-machine identity.
59
+ *
60
+ * SAFETY POSTURE: MECHANISM, dark by default. Nothing here blocks a user-initiated action.
61
+ * The local `userId` is NEVER part of the replicated schema and is stripped from every emitted
62
+ * projection (disclosure minimization).
63
+ */
64
+ import { createHash } from 'node:crypto';
65
+ import { jailStoreStringField } from './ReplicatedRecordEnvelope.js';
66
+ // ───────────────────────────────────────────────────────────────────────────
67
+ // A. Identity, tier, schema, bounds, caps
68
+ // ───────────────────────────────────────────────────────────────────────────
69
+ /** The stateSync config sub-key + advert suffix for this store (e.g.
70
+ * `multiMachine.stateSync.userRegistry.enabled`). Equal to the advert flag key
71
+ * `stateSyncReceive['userRegistry']`. */
72
+ export const USER_STORE_KEY = 'userRegistry';
73
+ /** The JournalKind string this store rides — the DUAL-REGISTRY's dynamic half.
74
+ * MUST also be present in CoherenceJournal.JOURNAL_KINDS (the static half), or the
75
+ * store advertises receive=true yet serves/applies/pulls nothing. */
76
+ export const USER_RECORD_KIND = 'user-record';
77
+ /**
78
+ * Users are HIGH-impact at the REPLICATION layer (fork #2): a concurrent divergent VALUE
79
+ * edit to the SAME channel-set identity surface from different origins goes through
80
+ * APPEND-BOTH-AND-FLAG — both versions preserved, ONE deduped conflict, never a silent
81
+ * overwrite (auto-merging two divergent profiles could fuse two distinct humans). The READ
82
+ * path (mergeUnionToUsers) is ADVISORY — a replicated user record is a HINT about what my
83
+ * OTHER machines know, NEVER my authoritative answer to "who is this inbound sender?".
84
+ */
85
+ export const USER_IMPACT_TIER = 'high';
86
+ // ── Local-record caps mirrored on RECEIVE (length-clamp discipline). A value over a cap
87
+ // REJECTS the whole record (never truncate-and-accept), EXCEPT free text which is
88
+ // length-clamped on receive (a flood is bounded, not record-rejected). ───────────────
89
+ /** Mirrors a reasonable per-user channel count (UserManager has no hard cap; this bounds a
90
+ * hostile peer's flood). */
91
+ export const MAX_CHANNELS = 50;
92
+ /** Per-free-text-string clamp for name / each channel identifier / each permission / each
93
+ * free-text profile field. */
94
+ export const MAX_FREETEXT_LENGTH = 2_000;
95
+ /** A channel `type` / permission is a short slug. */
96
+ export const MAX_SLUG_LENGTH = 128;
97
+ /** Permissions cap. */
98
+ export const MAX_PERMISSIONS = 50;
99
+ /**
100
+ * Per-kind replication bounds. The user registry is FEW + bounded (a handful of registered
101
+ * principals), so the per-store retention mirrors the pref-record / learning-record siblings
102
+ * (a small window with a few archives). NEVER `rotateKeep: 0` (rotate-but-never-delete would
103
+ * be a compliance defect for any PII kind, REQ-D1). The rate cap COALESCES (latest state per
104
+ * recordKey per interval) so a churny upsert loop does not flood the stream.
105
+ */
106
+ export const USER_RECORD_BOUNDS = {
107
+ retention: { maxFileBytes: 4 * 1024 * 1024, rotateKeep: 4 },
108
+ // Few records, coalesced: capacity is the burst, refill the sustained rate.
109
+ rateCap: { capacity: 30, refillPerSec: 5 },
110
+ };
111
+ /**
112
+ * Per-entry size cap RAISED to 64KB for this PII kind. The default
113
+ * APPLIER_MAX_ENTRY_BYTES = 8KB could be smaller than a fat profile (many channels + a long
114
+ * bio), so under it the highest-PII records would never replicate AND would wedge the stream.
115
+ * 64KB is provably above the disclosure-minimized projection's maximum (50 channels ×
116
+ * (128 + 2000) ≈ 106KB worst-case shows why we additionally enforce a HARD post-projection
117
+ * ceiling): a record that STILL exceeds 64KB after projection is REJECTED with a named error
118
+ * (never silent-truncate, never suspect-wedge). See assertProjectionUnderCap.
119
+ */
120
+ export const USER_MAX_ENTRY_BYTES = 64 * 1024;
121
+ /**
122
+ * The store-specific field names the `user-record` VALUE schema OWNS (the unknown-field
123
+ * counter's allowlist). The local `userId` `id` is DELIBERATELY ABSENT — it is per-machine
124
+ * and never replicated (fork #1/#3: the recordKey keys on the channel-set identity surface,
125
+ * not the id). `recordKey`/`hlc`/`op`/`origin`/`observed` are reserved envelope fields, never
126
+ * store fields.
127
+ */
128
+ export const USER_STORE_KNOWN_FIELDS = Object.freeze([
129
+ 'name',
130
+ 'channels',
131
+ 'permissions',
132
+ 'telegramUserId',
133
+ 'slackUserId',
134
+ 'createdAt',
135
+ 'relationshipContext',
136
+ ]);
137
+ /** The tombstone's store-owned fields beyond the reserved envelope set. `deletedAt`
138
+ * is the only store field a delete carries. */
139
+ export const USER_TOMBSTONE_KNOWN_FIELDS = Object.freeze([
140
+ 'deletedAt',
141
+ ]);
142
+ /** The full set of known store fields across BOTH op-branches (the schema's knownFields the
143
+ * registry uses for unknown-field counting — a field legal in EITHER branch is "known", and
144
+ * the branch validate() enforces which is legal for THIS op). */
145
+ const ALL_KNOWN_FIELDS = Object.freeze([
146
+ ...USER_STORE_KNOWN_FIELDS,
147
+ ...USER_TOMBSTONE_KNOWN_FIELDS,
148
+ ]);
149
+ // ── ISO-8601 type-clamp: createdAt is the load-bearing date field. On a foreign record it
150
+ // MUST validate as a real date or be dropped, so markup cannot survive the clamp. ───────
151
+ /** Is `v` a valid ISO-8601 date string (and ONLY a date — no smuggled markup)? A string
152
+ * Date.parse rejects, or that contains an injection char (`<`, `>`, `"`), is not a clean ISO
153
+ * date. */
154
+ export function isIso8601(v) {
155
+ if (typeof v !== 'string' || v.length === 0 || v.length > 64)
156
+ return false;
157
+ const ms = Date.parse(v);
158
+ if (!Number.isFinite(ms))
159
+ return false;
160
+ if (v.includes('<') || v.includes('>') || v.includes('"'))
161
+ return false;
162
+ return true;
163
+ }
164
+ function clampFreeText(v, max = MAX_FREETEXT_LENGTH) {
165
+ if (typeof v !== 'string')
166
+ return null;
167
+ return v.length > max ? v.slice(0, max) : v;
168
+ }
169
+ /** Validate one channel `{ type, identifier }` on RECEIVE: both strings, type a short
170
+ * non-path slug, identifier length-clamped + jailed (no path-shape). Returns the clamped
171
+ * channel or null to reject the whole record. */
172
+ function validateChannel(raw, ctx) {
173
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
174
+ return null;
175
+ const c = raw;
176
+ if (typeof c.type !== 'string' || c.type.length === 0 || c.type.length > MAX_SLUG_LENGTH)
177
+ return null;
178
+ if (typeof c.identifier !== 'string' || c.identifier.length === 0)
179
+ return null;
180
+ // The channel identifier feeds the recordKey identity surface — a path-shaped type is
181
+ // rejected (defense in depth; a platform slug is never path-shaped).
182
+ if (jailStoreStringField(c.type, ctx) === null)
183
+ return null;
184
+ const ident = c.identifier.length > MAX_FREETEXT_LENGTH ? c.identifier.slice(0, MAX_FREETEXT_LENGTH) : c.identifier;
185
+ return { type: c.type, identifier: ident };
186
+ }
187
+ /**
188
+ * The `user-record` store schema — a DISCRIMINATED UNION on `op`. Strict typed validation on
189
+ * top of the envelope: reject free text beyond the known fields, TYPE-CLAMP every known field
190
+ * (createdAt ISO-8601, telegramUserId finite number, channels/permissions/free text
191
+ * length-clamped + jailed) so markup cannot smuggle through a render slot that bypasses
192
+ * sanitize(). Returns the validated store-specific object (known fields only), or null to
193
+ * reject the WHOLE record. PURE (no I/O, no mutation of `raw`).
194
+ *
195
+ * The envelope validator has ALREADY validated `op` ∈ {put,delete} before calling this. We
196
+ * branch on it so a tombstone `{recordKey, op:'delete', hlc, origin, deletedAt}` passes (only
197
+ * `deletedAt` is a legal store field for a delete) WITHOUT being marked invalid by the rich
198
+ * VALUE schema.
199
+ */
200
+ export const userRecordStoreSchema = {
201
+ knownFields: ALL_KNOWN_FIELDS,
202
+ validate(raw, ctx) {
203
+ const op = raw.op;
204
+ // ── DELETE (tombstone) branch. Only `deletedAt` is a legal store field; any VALUE field
205
+ // present is counted as a dropped field but does not reject — the tombstone's
206
+ // recordKey + hlc + op (envelope, already validated) carry the suppression. ─────────
207
+ if (op === 'delete') {
208
+ const deletedAt = isIso8601(raw.deletedAt) ? raw.deletedAt : undefined;
209
+ for (const k of Object.keys(raw)) {
210
+ if (k === 'op' || k === 'deletedAt')
211
+ continue;
212
+ if (USER_STORE_KNOWN_FIELDS.includes(k))
213
+ ctx.countDroppedField();
214
+ }
215
+ return deletedAt !== undefined ? { deletedAt } : {};
216
+ }
217
+ // ── VALUE (put) branch. ──────────────────────────────────────────────────
218
+ // name — required non-empty free text, clamped.
219
+ const name = clampFreeText(raw.name);
220
+ if (name === null || name.length === 0)
221
+ return null;
222
+ // channels — an array, each clamped + jailed, ≤ MAX_CHANNELS. A bad channel rejects the
223
+ // whole record (the identity surface must be trustworthy).
224
+ if (!Array.isArray(raw.channels))
225
+ return null;
226
+ if (raw.channels.length > MAX_CHANNELS)
227
+ return null;
228
+ const channels = [];
229
+ for (const c of raw.channels) {
230
+ const vc = validateChannel(c, ctx);
231
+ if (vc === null)
232
+ return null;
233
+ channels.push(vc);
234
+ }
235
+ // permissions — array of clamped slugs, ≤ MAX_PERMISSIONS.
236
+ const permissions = Array.isArray(raw.permissions)
237
+ ? raw.permissions
238
+ .filter((p) => typeof p === 'string')
239
+ .slice(0, MAX_PERMISSIONS)
240
+ .map((p) => (p.length > MAX_SLUG_LENGTH ? p.slice(0, MAX_SLUG_LENGTH) : p))
241
+ : [];
242
+ const out = {
243
+ name,
244
+ channels,
245
+ permissions,
246
+ };
247
+ // telegramUserId — FINITE NUMBER if present (markup cannot survive a number slot).
248
+ if (raw.telegramUserId !== undefined) {
249
+ if (typeof raw.telegramUserId === 'number' && Number.isFinite(raw.telegramUserId)) {
250
+ out.telegramUserId = raw.telegramUserId;
251
+ }
252
+ }
253
+ // slackUserId — a short slug, clamped + jailed.
254
+ if (raw.slackUserId !== undefined) {
255
+ const slackId = clampFreeText(raw.slackUserId, MAX_SLUG_LENGTH);
256
+ if (slackId !== null && slackId.length > 0 && jailStoreStringField(slackId, ctx) !== null)
257
+ out.slackUserId = slackId;
258
+ }
259
+ // createdAt — ISO-8601-or-absent (markup dropped).
260
+ if (isIso8601(raw.createdAt))
261
+ out.createdAt = raw.createdAt;
262
+ // relationshipContext — optional clamped free text.
263
+ const relationshipContext = raw.relationshipContext !== undefined ? clampFreeText(raw.relationshipContext) : null;
264
+ if (relationshipContext !== null && relationshipContext.length > 0)
265
+ out.relationshipContext = relationshipContext;
266
+ return out;
267
+ },
268
+ };
269
+ // ───────────────────────────────────────────────────────────────────────────
270
+ // recordKey — the cross-machine IDENTITY SURFACE (fork #1)
271
+ // ───────────────────────────────────────────────────────────────────────────
272
+ /**
273
+ * Normalize one channel into its stable uid form `type:identifier` (lowercased type, trimmed
274
+ * identifier). This is the SAME `${type}:${identifier}` key UserManager.channelIndex uses to
275
+ * resolve a user across platforms.
276
+ */
277
+ export function channelUid(channel) {
278
+ const type = channel.type.trim().toLowerCase();
279
+ const identifier = channel.identifier.trim();
280
+ return `${type}:${identifier}`;
281
+ }
282
+ /**
283
+ * Derive the cross-machine-stable recordKey for a user (fork #1). A user is "the same" across
284
+ * machines by their CHANNEL SET (mirroring UserManager.channelIndex), NOT by the per-machine
285
+ * `userId` — VM-A and VM-B mint different ids for the same human, so an id-keyed record could
286
+ * never collide them (exactly the relationship-UUID trap WS2.3 solved with the channel-set
287
+ * key).
288
+ *
289
+ * The key is a deterministic, collision-resistant hash of the SORTED, de-duplicated
290
+ * channel-uids: `sha256(sorted(channelUids).join('\n'))`, hex-truncated to 32 chars (the same
291
+ * shape UnionReader.conflictId uses). Sorting makes it order-independent (the two machines
292
+ * converge to the SAME key for the same channel set); the hash makes it a bounded,
293
+ * non-path-shaped string (the envelope's recordKey jail accepts it). A user with NO channels
294
+ * (a degenerate local-only record) is NOT replicable — it has no cross-machine identity
295
+ * surface — and is reported as null so the caller skips emission (it can never collide a
296
+ * stranger by an empty key).
297
+ *
298
+ * COLLISION SAFETY: two DIFFERENT users share a key ONLY if they share the EXACT same full
299
+ * channel set — which IS the UserManager's own definition of "the same user" (the channelIndex
300
+ * maps one user per channel-uid and refuses a cross-user collision). SPLIT-IDENTITY SAFETY: the
301
+ * same user derives the SAME key on both machines IFF both hold the same channel set; when the
302
+ * sets differ (one machine learned an extra channel) the keys differ — correct (they are not
303
+ * yet provably the same user on the machine missing the channel).
304
+ */
305
+ export function deriveUserRecordKey(channels) {
306
+ const uids = Array.from(new Set(channels.map(channelUid))).filter((u) => u.length > 1).sort();
307
+ if (uids.length === 0)
308
+ return null;
309
+ const h = createHash('sha256');
310
+ h.update(uids.join('\n'));
311
+ return h.digest('hex').slice(0, 32);
312
+ }
313
+ /** The named error a record-over-cap surfaces: not silent-truncate, not suspect-wedge. */
314
+ export class UserRecordTooLargeError extends Error {
315
+ recordKey;
316
+ bytes;
317
+ constructor(recordKey, bytes) {
318
+ super(`user-record ${recordKey} is ${bytes} bytes after projection — over the ${USER_MAX_ENTRY_BYTES}-byte per-entry cap; not replicated`);
319
+ this.recordKey = recordKey;
320
+ this.bytes = bytes;
321
+ this.name = 'UserRecordTooLargeError';
322
+ }
323
+ }
324
+ function clampFreeTextEmit(v, max = MAX_FREETEXT_LENGTH) {
325
+ return typeof v === 'string' && v.length > max ? v.slice(0, max) : (v ?? '');
326
+ }
327
+ /**
328
+ * Build the disclosure-minimized `user-record` envelope `data` for an `op:'put'` (fork #3).
329
+ * Emits ONLY the enumerated resolution + merge-relevant fields — NEVER the raw on-disk blob,
330
+ * NEVER the local `userId` id. recordKey = the derived channel-set identity surface (fork #1).
331
+ *
332
+ * Returns null when the record has NO channels (no cross-machine identity surface ⇒ not
333
+ * replicable — the caller skips emission). Throws UserRecordTooLargeError when the projection
334
+ * STILL exceeds the 64KB per-entry cap (a NAMED, surfaced rejection — never silent-truncate).
335
+ */
336
+ export function buildUserRecordData(input) {
337
+ const { record, hlc, origin, observed } = input;
338
+ const recordKey = deriveUserRecordKey(record.channels);
339
+ if (recordKey === null)
340
+ return null;
341
+ const data = {
342
+ name: clampFreeTextEmit(record.name),
343
+ channels: record.channels.slice(0, MAX_CHANNELS).map((c) => ({ type: c.type, identifier: c.identifier })),
344
+ permissions: Array.isArray(record.permissions) ? record.permissions.slice(0, MAX_PERMISSIONS).map((p) => clampFreeTextEmit(p, MAX_SLUG_LENGTH)) : [],
345
+ // envelope fields (recordKey = identity surface).
346
+ recordKey,
347
+ hlc,
348
+ op: 'put',
349
+ origin,
350
+ ...(observed !== undefined ? { observed } : {}),
351
+ };
352
+ // Optional fields — only when present (the local userId is NEVER among them).
353
+ if (typeof record.telegramUserId === 'number' && Number.isFinite(record.telegramUserId))
354
+ data.telegramUserId = record.telegramUserId;
355
+ if (typeof record.slackUserId === 'string' && record.slackUserId.length > 0)
356
+ data.slackUserId = clampFreeTextEmit(record.slackUserId, MAX_SLUG_LENGTH);
357
+ if (typeof record.createdAt === 'string' && record.createdAt.length > 0)
358
+ data.createdAt = record.createdAt;
359
+ if (typeof record.relationshipContext === 'string' && record.relationshipContext.length > 0)
360
+ data.relationshipContext = clampFreeTextEmit(record.relationshipContext);
361
+ assertProjectionUnderCap(recordKey, data);
362
+ return data;
363
+ }
364
+ /** Throw UserRecordTooLargeError if the projected data serializes over the per-entry cap. The
365
+ * cap is set so a legal disclosure-minimized record can never reach it; this is the
366
+ * belt-and-suspenders named rejection. */
367
+ export function assertProjectionUnderCap(recordKey, data) {
368
+ const bytes = Buffer.byteLength(JSON.stringify(data), 'utf-8');
369
+ if (bytes > USER_MAX_ENTRY_BYTES) {
370
+ throw new UserRecordTooLargeError(recordKey, bytes);
371
+ }
372
+ }
373
+ /**
374
+ * Build an `op:'delete'` TOMBSTONE `data` for a user removal. recordKey = the SAME channel-set
375
+ * identity surface the value records key on, so the tombstone reaches the same human's record
376
+ * on every machine even though the local ids differ. Returns null when the user has no channels
377
+ * (no identity surface to tombstone).
378
+ *
379
+ * CRITICAL: the UserManager.removeUser() path MUST call this, else a peer re-replicates the
380
+ * locally-removed user forever (resurrection). The delete-resurrection guard lives in the merge
381
+ * (a later `delete` hlc wins over an earlier `put`).
382
+ */
383
+ export function buildUserTombstoneData(input) {
384
+ const recordKey = deriveUserRecordKey(input.channels);
385
+ if (recordKey === null)
386
+ return null;
387
+ return {
388
+ deletedAt: input.deletedAt,
389
+ recordKey,
390
+ hlc: input.hlc,
391
+ op: 'delete',
392
+ origin: input.origin,
393
+ ...(input.observed !== undefined ? { observed: input.observed } : {}),
394
+ };
395
+ }
396
+ /** Reconstruct a MergedUserView from an OriginRecord (the envelope stripped). */
397
+ function viewFromOriginRecord(rec, conflicted) {
398
+ return { recordKey: rec.envelope.recordKey, origin: rec.origin, data: rec.data, conflicted };
399
+ }
400
+ /**
401
+ * Collapse a `Map<recordKey, UnionResult>` into the merged user view.
402
+ * HIGH-impact-at-replication / ADVISORY-at-read contract (fork #2):
403
+ * - A resolved single value ⇒ that one view entry.
404
+ * - An OPEN concurrent conflict ⇒ BOTH (all) `put` variants as separate entries (append-both
405
+ * — both surface as ADVISORY hints; the read NEVER suppresses a usable view AND NEVER
406
+ * BLOCKS waiting on operator resolution — a replicated user is a hint, not authority). A
407
+ * `delete` variant contributes nothing to display.
408
+ * - A delete-resolved key (every origin's latest is a tombstone) ⇒ nothing (the
409
+ * delete-resurrection guard: a later delete wins over an earlier put).
410
+ * The read is READ-ONLY: a replicated record NEVER clobbers a divergent local record — the
411
+ * local store files are never written here.
412
+ */
413
+ export function mergeUnionToUsers(union) {
414
+ const out = [];
415
+ for (const result of union.values()) {
416
+ if (result.conflict) {
417
+ for (const v of result.conflict.versions) {
418
+ if (v.envelope.op === 'delete')
419
+ continue;
420
+ out.push(viewFromOriginRecord(v, true));
421
+ }
422
+ continue;
423
+ }
424
+ if (result.value && result.value.envelope.op !== 'delete') {
425
+ out.push(viewFromOriginRecord(result.value, false));
426
+ }
427
+ }
428
+ return out;
429
+ }
430
+ // ───────────────────────────────────────────────────────────────────────────
431
+ // E. Foreign-record render safety — quoted untrusted data
432
+ // ───────────────────────────────────────────────────────────────────────────
433
+ /** Sanitize a string for inclusion in a context block (escape the envelope-break + markup
434
+ * vectors). */
435
+ function sanitize(s) {
436
+ return String(s).replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
437
+ }
438
+ /**
439
+ * Render a FOREIGN (replicated) user record into a session-context block, wrapped in an
440
+ * explicit `<replicated-untrusted-data origin="…">` envelope so the session model treats it as
441
+ * a PEER'S claim to re-ground against, never a directive AND never the authoritative
442
+ * inbound-resolution answer. EVERY rendered field is escaped — there is no "trusted because
443
+ * machine-set" slot. A null `data.name` (a malformed view) yields null.
444
+ */
445
+ export function renderForeignUserContext(view) {
446
+ const d = view.data;
447
+ if (typeof d.name !== 'string' || d.name.length === 0)
448
+ return null;
449
+ const safeOrigin = sanitize(view.origin);
450
+ const lines = [
451
+ `<replicated-untrusted-data origin="${safeOrigin}">`,
452
+ `User: ${sanitize(d.name)}`,
453
+ ];
454
+ if (Array.isArray(d.channels)) {
455
+ const platforms = [...new Set(d.channels.map((c) => c.type))];
456
+ if (platforms.length > 0)
457
+ lines.push(`Platforms: ${platforms.map(sanitize).join(', ')}`);
458
+ }
459
+ if (Array.isArray(d.permissions) && d.permissions.length > 0)
460
+ lines.push(`Permissions: ${d.permissions.map(sanitize).join(', ')}`);
461
+ if (typeof d.relationshipContext === 'string' && d.relationshipContext.length > 0)
462
+ lines.push(`Relationship: ${sanitize(d.relationshipContext)}`);
463
+ if (typeof d.createdAt === 'string')
464
+ lines.push(`Known since: ${sanitize(d.createdAt)}`);
465
+ lines.push('</replicated-untrusted-data>');
466
+ return lines.join('\n');
467
+ }
468
+ // ───────────────────────────────────────────────────────────────────────────
469
+ // Own-origin materialization for the union reader (mirrors WS2.3)
470
+ // ───────────────────────────────────────────────────────────────────────────
471
+ /**
472
+ * Build an OriginRecord for the OWN user registry (the single-origin materialization the union
473
+ * reader merges against peer replicas). recordKey = derived channel-set identity surface; the
474
+ * envelope carries a SYNTHETIC own-origin HLC stamp derived deterministically from the
475
+ * record's createdAt (physical) so the own record has a well-formed, stable position relative
476
+ * to peer records. Returns null for a channel-less record (no identity surface). The local
477
+ * `userId` is NEVER carried into the replicated namespace (fork #1/#3).
478
+ */
479
+ export function userToOriginRecord(record, origin) {
480
+ const recordKey = deriveUserRecordKey(record.channels);
481
+ if (recordKey === null)
482
+ return null;
483
+ const physical = Date.parse(record.createdAt ?? '');
484
+ const hlc = {
485
+ physical: Number.isFinite(physical) ? physical : 0,
486
+ logical: 0,
487
+ node: origin,
488
+ };
489
+ const data = {
490
+ name: record.name,
491
+ channels: record.channels.map((c) => ({ type: c.type, identifier: c.identifier })),
492
+ permissions: Array.isArray(record.permissions) ? record.permissions : [],
493
+ };
494
+ if (typeof record.telegramUserId === 'number' && Number.isFinite(record.telegramUserId))
495
+ data.telegramUserId = record.telegramUserId;
496
+ if (typeof record.slackUserId === 'string' && record.slackUserId.length > 0)
497
+ data.slackUserId = record.slackUserId;
498
+ if (typeof record.createdAt === 'string' && record.createdAt.length > 0)
499
+ data.createdAt = record.createdAt;
500
+ if (typeof record.relationshipContext === 'string' && record.relationshipContext.length > 0)
501
+ data.relationshipContext = record.relationshipContext;
502
+ const envelope = { recordKey, hlc, op: 'put', origin };
503
+ return { origin, envelope, data };
504
+ }
505
+ // ───────────────────────────────────────────────────────────────────────────
506
+ // Registration descriptor (consumed by server.ts to register the dual registry)
507
+ // ───────────────────────────────────────────────────────────────────────────
508
+ /** The ReplicatedKindRegistry registration for the `user-record` store. server.ts registers
509
+ * this onto the shared registry; the dual-registry coupling test asserts `kind` is also
510
+ * present in JOURNAL_KINDS. */
511
+ export const USER_KIND_REGISTRATION = {
512
+ kind: USER_RECORD_KIND,
513
+ store: USER_STORE_KEY,
514
+ schema: userRecordStoreSchema,
515
+ };
516
+ /** Convenience: the store's contributing journal kinds (for rollback-unmerge's
517
+ * kindsForStore('userRegistry') wiring). */
518
+ export function userContributingKinds() {
519
+ return [USER_RECORD_KIND];
520
+ }
521
+ /** The store's impact tier resolver, for ReplicatedStoreReader.tierOf. Returns HIGH for the
522
+ * `userRegistry` store (and HIGH for any unknown store — the conservative
523
+ * append-both-and-flag direction, never a silent clobber). */
524
+ export function userTierOf(_store) {
525
+ return USER_IMPACT_TIER;
526
+ }
527
+ //# sourceMappingURL=UserRegistryReplicatedStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserRegistryReplicatedStore.js","sourceRoot":"","sources":["../../src/core/UserRegistryReplicatedStore.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"devGatedFeatures.d.ts","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA2J/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,sBAAsB,GACtB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,EAwInD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAO5E"}
1
+ {"version":3,"file":"devGatedFeatures.d.ts","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA2J/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,sBAAsB,GACtB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,EAkJnD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAO5E"}
@@ -261,6 +261,16 @@ export const DARK_GATE_EXCLUSIONS = [
261
261
  category: 'optional-integration',
262
262
  reason: 'WS2.5 cross-machine evolution-action-queue replication — the FOURTH memory-family kind on the HLC foundation; graduated rollout dark→dryRun→live per multi-machine-replicated-store-foundation, opt-in per deployment (no action crosses a machine boundary while dark; the local ACT-NNN id is never replicated; the load-bearing field is status so a peer sees an action was already completed elsewhere; mirrors the knowledge sibling)',
263
263
  },
264
+ {
265
+ configPath: 'multiMachine.stateSync.userRegistry.enabled',
266
+ category: 'optional-integration',
267
+ reason: 'WS2.6 cross-machine user-registry replication — the SECOND PII kind on the HLC foundation; graduated rollout dark→dryRun→live per multi-machine-replicated-store-foundation, opt-in per deployment (no user PII crosses a machine boundary while dark; the local userId is never replicated, the recordKey is the channel-set identity surface; mirrors the relationships sibling)',
268
+ },
269
+ {
270
+ configPath: 'multiMachine.stateSync.topicOperator.enabled',
271
+ category: 'optional-integration',
272
+ reason: 'WS2.6 cross-machine topic-operator replication — the THIRD PII kind on the HLC foundation; graduated rollout dark to dryRun to live per multi-machine-replicated-store-foundation, opt-in per deployment (no operator binding crosses a machine boundary while dark; recordKey is sha256 of topicId plus the verified uid, never a content-name; THE LOAD-BEARING INVARIANT: a replicated topic-operator record is NEVER the authoritative principal — only the local authenticated setOperator binds it; mirrors the userRegistry sibling)',
273
+ },
264
274
  // ── action-bearing — when merely enabled, automatically produces an outbound
265
275
  // side-effect that reaches an external system or the operator (a send, a PR
266
276
  // merge, a remote mutation). De-dup/rate-limiting reduces severity but an
@@ -1 +1 @@
1
- {"version":3,"file":"devGatedFeatures.js","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"devGatedFeatures.js","sourceRoot":"","sources":["../../src/core/devGatedFeatures.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,CA29CR;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,GAC3B,MAAM,CA2TR"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,CA69CR;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,GAC3B,MAAM,CA2TR"}