instar 1.3.526 → 1.3.527
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.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +47 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +13 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/CoherenceJournal.d.ts +1 -1
- package/dist/core/CoherenceJournal.d.ts.map +1 -1
- package/dist/core/CoherenceJournal.js +12 -2
- package/dist/core/CoherenceJournal.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +21 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PreferencesReplicatedStore.d.ts +212 -0
- package/dist/core/PreferencesReplicatedStore.d.ts.map +1 -0
- package/dist/core/PreferencesReplicatedStore.js +330 -0
- package/dist/core/PreferencesReplicatedStore.js.map +1 -0
- package/dist/core/PreferencesSync.d.ts +8 -0
- package/dist/core/PreferencesSync.d.ts.map +1 -1
- package/dist/core/PreferencesSync.js +8 -0
- package/dist/core/PreferencesSync.js.map +1 -1
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +5 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +1 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +4 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +7 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +19 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/scaffold/templates.ts +1 -0
- package/upgrades/1.3.527.md +31 -0
- package/upgrades/side-effects/ws21-preferences-replicated-store.md +91 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PreferencesReplicatedStore — the FIRST concrete consumer of the HLC
|
|
3
|
+
* replicated-store foundation (WS2.1, multi-machine-replicated-store-foundation
|
|
4
|
+
* §4 + §7.2 + §13). It layers the `pref-record` replicated kind onto the generic
|
|
5
|
+
* substrate (ReplicatedRecordEnvelope / UnionReader / ConflictStore /
|
|
6
|
+
* RollbackUnmerge / ReplicationBudget / StoreSnapshot) so a user preference
|
|
7
|
+
* learned on machine A is honored on machine B — ONE memory, not one-per-machine.
|
|
8
|
+
*
|
|
9
|
+
* THIS IS PURE LOGIC. No fs, no Date directly, no network. It defines:
|
|
10
|
+
* A. The `pref-record` store schema (the StoreFieldSchema the registry validates
|
|
11
|
+
* on top of the envelope) + the store's IMPACT TIER (high) + per-kind bounds.
|
|
12
|
+
* B. The emit-envelope builder: PreferenceEntry → the `data` object a journal
|
|
13
|
+
* `pref-record` entry carries (recordKey=dedupeKey, hlc, op, origin, observed).
|
|
14
|
+
* C. The union-aware read: a `Map<recordKey, UnionResult>` (from
|
|
15
|
+
* ReplicatedStoreReader.readAll('preferences')) → a `PreferenceEntry[]` for
|
|
16
|
+
* the session-start block. THE LOAD-BEARING ADVISORY RECONCILIATION (the §15.1
|
|
17
|
+
* decision): on an OPEN conflict for a dedupeKey, BOTH variants are injected as
|
|
18
|
+
* hints — they ARE advisory, both are usable guidance — rather than blocking on
|
|
19
|
+
* operator resolution. Operator resolution (POST /state/resolve-conflict) is
|
|
20
|
+
* OPTIONAL cleanup that collapses the flag; it is NEVER a gate on the hint
|
|
21
|
+
* being injected. A flag is observability + optional cleanup, not a blocked
|
|
22
|
+
* preference. This is what kills the §15.1 over-flag-fatigue concern.
|
|
23
|
+
*
|
|
24
|
+
* SUPERSESSION (CMT-1416): this foundation path SUPERSEDES the earlier advisory
|
|
25
|
+
* `PreferencesSync.ts` (the seamlessness-spec WS2.1, behind
|
|
26
|
+
* multiMachine.seamlessness.ws21PreferencesPool). BOTH ship dark/default-off, so
|
|
27
|
+
* there is ZERO runtime duplication today. PreferencesSync is retained dark until
|
|
28
|
+
* this path is validated, then removed (tracked CMT-1416 — a separate cleanup PR).
|
|
29
|
+
* They are MUTUALLY EXCLUSIVE in practice: the consumer reads ONE path at a time
|
|
30
|
+
* (the foundation reader is consulted only when `multiMachine.stateSync.preferences`
|
|
31
|
+
* is enabled; the legacy merge only when `seamlessness.ws21PreferencesPool` is). An
|
|
32
|
+
* operator who enables BOTH gets the foundation path's precedence (it is the
|
|
33
|
+
* principled substrate); the legacy path is the fallback for an agent that has not
|
|
34
|
+
* yet flipped to the foundation flag.
|
|
35
|
+
*
|
|
36
|
+
* SAFETY POSTURE (§14): MECHANISM, dark by default. Nothing here blocks a
|
|
37
|
+
* user-initiated action. `violationPattern` (the operator's self-violation
|
|
38
|
+
* detection regex/keywords) is a LOCAL-ONLY signal that reveals the operator's
|
|
39
|
+
* security posture, so it is NEVER part of the replicated store schema and is
|
|
40
|
+
* stripped from every emitted envelope (mirrors PreferencesSync finding #1).
|
|
41
|
+
*/
|
|
42
|
+
import type { PreferenceEntry } from './PreferencesManager.js';
|
|
43
|
+
import type { StoreFieldSchema, ReplicatedEnvelope, ReplicatedOp } from './ReplicatedRecordEnvelope.js';
|
|
44
|
+
import type { ImpactTier, OriginRecord, UnionResult } from './UnionReader.js';
|
|
45
|
+
import type { ReplicatedKindBounds } from './ReplicationBudget.js';
|
|
46
|
+
import type { HlcTimestamp } from './HybridLogicalClock.js';
|
|
47
|
+
/** The stateSync config sub-key + advert suffix for this store (e.g.
|
|
48
|
+
* `multiMachine.stateSync.preferences.enabled`). Equal to the advert flag key
|
|
49
|
+
* `stateSyncReceive['preferences']`. */
|
|
50
|
+
export declare const PREF_STORE_KEY = "preferences";
|
|
51
|
+
/** The JournalKind string this store rides — the DUAL-REGISTRY's dynamic half.
|
|
52
|
+
* MUST also be present in CoherenceJournal.JOURNAL_KINDS (the static half), or the
|
|
53
|
+
* store advertises receive=true yet serves/applies/pulls nothing (§4 callout). */
|
|
54
|
+
export declare const PREF_RECORD_KIND = "pref-record";
|
|
55
|
+
/**
|
|
56
|
+
* Preferences are HIGH-impact (spec §614 / master-spec decision 2): a concurrent
|
|
57
|
+
* divergent edit to the SAME dedupeKey from different origins goes through
|
|
58
|
+
* APPEND-BOTH-AND-FLAG — both versions preserved, ONE deduped conflict, never a
|
|
59
|
+
* silent overwrite. (The CONSUMER read path still injects BOTH variants as advisory
|
|
60
|
+
* hints — see mergeUnionToPreferences — so the flag never suppresses guidance.)
|
|
61
|
+
*/
|
|
62
|
+
export declare const PREF_IMPACT_TIER: ImpactTier;
|
|
63
|
+
/**
|
|
64
|
+
* Per-kind replication bounds (§8). Preferences are FEW — a tight window with a
|
|
65
|
+
* coalescing rate cap (the burst of edits to one dedupeKey collapses to the latest
|
|
66
|
+
* state per interval). Mirrors the PreferencesSync precedent's per-store cap
|
|
67
|
+
* (DEFAULT_MAX_REPLICATED_PREFERENCES=500). The retention here matches the
|
|
68
|
+
* journal-level `pref-record` fallback in CoherenceJournal.DEFAULT_RETENTION; the
|
|
69
|
+
* aggregate journal budget (64 MiB default) trivially covers a 2 MiB pref stream.
|
|
70
|
+
*/
|
|
71
|
+
export declare const PREF_RECORD_BOUNDS: ReplicatedKindBounds;
|
|
72
|
+
/**
|
|
73
|
+
* The store-specific field names the `pref-record` schema OWNS (the unknown-field
|
|
74
|
+
* counter's allowlist). NOTE: `violationPattern` is DELIBERATELY ABSENT — it is a
|
|
75
|
+
* LOCAL-ONLY signal (the operator's self-violation regex/keywords) that must never
|
|
76
|
+
* replicate (PreferencesSync finding #1). `dedupeKey` is ABSENT too — it is the
|
|
77
|
+
* recordKey (a reserved envelope field), never a store field. `lastMutatedSeq`,
|
|
78
|
+
* `storeIncarnation` etc. are local replication bookkeeping, never replicated here.
|
|
79
|
+
*/
|
|
80
|
+
export declare const PREF_STORE_KNOWN_FIELDS: ReadonlyArray<string>;
|
|
81
|
+
/** Caps mirroring the PreferencesManager discipline — a value over the cap REJECTS
|
|
82
|
+
* the whole record (never truncate-and-accept). */
|
|
83
|
+
export declare const MAX_LEARNING_LENGTH: number;
|
|
84
|
+
export declare const MAX_PROVENANCE_LENGTH = 64;
|
|
85
|
+
/**
|
|
86
|
+
* The `pref-record` store schema (§4). Strict typed validation on top of the
|
|
87
|
+
* envelope: reject free text beyond the known fields, jail any path-shaped string,
|
|
88
|
+
* narrow each field. Returns the validated store-specific object, or null to reject
|
|
89
|
+
* the WHOLE record. PURE (no I/O, no mutation of `raw`).
|
|
90
|
+
*/
|
|
91
|
+
export declare const prefRecordStoreSchema: StoreFieldSchema;
|
|
92
|
+
/** The `data` object a `pref-record` journal entry carries: the validated store
|
|
93
|
+
* fields PLUS the envelope fields. Deterministic shape; `observed` omitted when
|
|
94
|
+
* absent. */
|
|
95
|
+
export type PrefRecordData = Record<string, unknown>;
|
|
96
|
+
/** The credential scrubber seam (injected so this module stays pure — the real
|
|
97
|
+
* wiring passes `redactForLiveTail`). Returns the scrubbed text + whether anything
|
|
98
|
+
* was redacted. */
|
|
99
|
+
export type LearningScrubber = (input: string) => {
|
|
100
|
+
text: string;
|
|
101
|
+
redactedCount: number;
|
|
102
|
+
};
|
|
103
|
+
/** Input to buildPrefRecordData: the entry to emit, the freshly-ticked hlc, the op,
|
|
104
|
+
* this machine's origin id, and the observed-witness (the hlc already merged for
|
|
105
|
+
* THIS dedupeKey before writing, or absent). */
|
|
106
|
+
export interface BuildPrefRecordInput {
|
|
107
|
+
entry: Pick<PreferenceEntry, 'learning' | 'confidence' | 'dedupeCount' | 'provenance' | 'recordedAt' | 'dedupeKey'>;
|
|
108
|
+
hlc: HlcTimestamp;
|
|
109
|
+
op: ReplicatedOp;
|
|
110
|
+
origin: string;
|
|
111
|
+
/** The HLC already merged for THIS dedupeKey before writing, or absent (§7.2). */
|
|
112
|
+
observed?: HlcTimestamp;
|
|
113
|
+
/** Credential scrubber applied to `learning` at emit time (PreferencesSync finding
|
|
114
|
+
* #5: usefulness never depends on the scan — a flagged learning still replicates,
|
|
115
|
+
* redacted). Omitted ⇒ no scrub (the in-process default is to pass the real
|
|
116
|
+
* scrubber). */
|
|
117
|
+
scrub?: LearningScrubber;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build the `pref-record` envelope `data` for emission (§4). recordKey = the
|
|
121
|
+
* preference `dedupeKey` (the natural primary key — the same dedupeKey on two
|
|
122
|
+
* machines is the SAME learned lesson). `violationPattern` is NEVER included (local-
|
|
123
|
+
* only). `learning` is credential-scrubbed when a scrubber is supplied. The returned
|
|
124
|
+
* object is the journal entry's `data`; the envelope fields are authoritative.
|
|
125
|
+
*
|
|
126
|
+
* NOTE: this does NOT validate — it produces a well-formed `data` the journal emit
|
|
127
|
+
* path serializes; the RECEIVE door (validateReplicatedEnvelope + the store schema)
|
|
128
|
+
* re-validates on apply. Emission is GATED upstream by
|
|
129
|
+
* `multiMachine.stateSync.preferences.enabled` (the caller checks
|
|
130
|
+
* isStoreEmissionEnabled before calling this) — when off, this is never reached.
|
|
131
|
+
*/
|
|
132
|
+
export declare function buildPrefRecordData(input: BuildPrefRecordInput): PrefRecordData;
|
|
133
|
+
/**
|
|
134
|
+
* Reconstruct a PreferenceEntry from an OriginRecord's store `data` (the envelope
|
|
135
|
+
* fields stripped). Defensive: a field that does not narrow falls back to the same
|
|
136
|
+
* safe default PreferencesManager.read() uses. `dedupeKey` is the recordKey.
|
|
137
|
+
*/
|
|
138
|
+
export declare function prefEntryFromOriginRecord(rec: OriginRecord): PreferenceEntry;
|
|
139
|
+
/**
|
|
140
|
+
* Build an OriginRecord for the OWN preference store (the single-origin
|
|
141
|
+
* materialization the union reader merges). recordKey = dedupeKey; the envelope
|
|
142
|
+
* carries a SYNTHETIC own-origin stamp. NOTE: this is the OWN record at rest — it
|
|
143
|
+
* is NOT the wire/journal hlc (that is minted by clock.tick() at the EMIT path);
|
|
144
|
+
* here we only need a stable own-origin record for the union to merge against peer
|
|
145
|
+
* replicas. `lastMutatedSeq` is folded into a deterministic logical counter so the
|
|
146
|
+
* own record has a well-formed, monotone HLC position relative to its own edits.
|
|
147
|
+
* `violationPattern` is NEVER carried into the replicated namespace (local-only).
|
|
148
|
+
*/
|
|
149
|
+
export declare function prefEntryToOriginRecord(entry: PreferenceEntry, origin: string): OriginRecord;
|
|
150
|
+
/**
|
|
151
|
+
* THE LOAD-BEARING ADVISORY RECONCILIATION (§15.1 decision, recorded verbatim).
|
|
152
|
+
*
|
|
153
|
+
* Collapse a `Map<recordKey, UnionResult>` (from
|
|
154
|
+
* ReplicatedStoreReader.readAll('preferences')) into the PreferenceEntry[] the
|
|
155
|
+
* session-start block consumes. The §15.1 contract:
|
|
156
|
+
* - A resolved single value ⇒ inject that one entry.
|
|
157
|
+
* - An OPEN HIGH-impact conflict ⇒ inject BOTH (all) concurrent variants as
|
|
158
|
+
* separate hints. They ARE advisory — both are usable guidance — so the open
|
|
159
|
+
* conflict NEVER suppresses a usable hint. Operator resolution (POST
|
|
160
|
+
* /state/resolve-conflict) is OPTIONAL cleanup that collapses the flag; it is
|
|
161
|
+
* NEVER a gate on the hint being injected.
|
|
162
|
+
* - A LOW-impact divergence ⇒ the HLC-winner is `value`; inject it (the overwrite
|
|
163
|
+
* was flagged for observability, but the value is usable).
|
|
164
|
+
* - A null `value` with no conflict (every origin deleted, or no record) ⇒ nothing
|
|
165
|
+
* to inject for that key.
|
|
166
|
+
*
|
|
167
|
+
* This is the proof obligation the §12 wiring test exercises: an OPEN conflict for a
|
|
168
|
+
* dedupeKey STILL yields both variants in the output (it can never suppress a usable
|
|
169
|
+
* hint waiting on operator resolution). The conflict's `versions` carry every
|
|
170
|
+
* concurrent origin's record; we map EACH to a PreferenceEntry hint.
|
|
171
|
+
*
|
|
172
|
+
* Determinism: variants from a conflict are emitted in the union reader's stable
|
|
173
|
+
* (HLC-sorted) version order, so the injected block is stable across reads.
|
|
174
|
+
*/
|
|
175
|
+
export declare function mergeUnionToPreferences(union: Map<string, UnionResult>): PreferenceEntry[];
|
|
176
|
+
/**
|
|
177
|
+
* Build the session-start preferences block from a union read (the foundation
|
|
178
|
+
* path's equivalent of PreferencesManager.sessionContext()). Reuses the SAME
|
|
179
|
+
* deterministic, byte-bounded, priority-ordered renderer
|
|
180
|
+
* (`formatPreferencesForSessionStart`) so the injected block shape is identical to
|
|
181
|
+
* the single-machine path — only the SOURCE differs (the no-clobber union vs the
|
|
182
|
+
* local store). An open conflict yields BOTH variants in the block (§15.1).
|
|
183
|
+
*/
|
|
184
|
+
export declare function buildUnionSessionContext(union: Map<string, UnionResult>, maxBytes?: number): {
|
|
185
|
+
present: boolean;
|
|
186
|
+
block: string;
|
|
187
|
+
count: number;
|
|
188
|
+
scope: 'mesh';
|
|
189
|
+
};
|
|
190
|
+
/** The ReplicatedKindRegistry registration for the `pref-record` store. server.ts
|
|
191
|
+
* registers this onto the shared registry; the dual-registry coupling test asserts
|
|
192
|
+
* `kind` is also present in JOURNAL_KINDS. */
|
|
193
|
+
export declare const PREF_KIND_REGISTRATION: {
|
|
194
|
+
readonly kind: "pref-record";
|
|
195
|
+
readonly store: "preferences";
|
|
196
|
+
readonly schema: StoreFieldSchema;
|
|
197
|
+
};
|
|
198
|
+
/** Convenience re-export for the rollback-unmerge `kindsForStore('preferences')`
|
|
199
|
+
* wiring + any caller that needs the store's contributing journal kinds. */
|
|
200
|
+
export declare function prefContributingKinds(): string[];
|
|
201
|
+
/**
|
|
202
|
+
* The store's impact tier resolver, for ReplicatedStoreReader.tierOf. Returns the
|
|
203
|
+
* preferences tier (high) for the `preferences` store. An UNKNOWN store also
|
|
204
|
+
* resolves to `high` — the CONSERVATIVE direction (append-both-and-flag never
|
|
205
|
+
* silently clobbers), so a future store wired before its own tierOf lands can never
|
|
206
|
+
* accidentally get the silent-overwrite path. The reader composes per-store; this is
|
|
207
|
+
* the default a server wires for the preferences store specifically.
|
|
208
|
+
*/
|
|
209
|
+
export declare function prefTierOf(_store: string): ImpactTier;
|
|
210
|
+
/** Re-export the envelope type for callers building/applying pref-record envelopes. */
|
|
211
|
+
export type { ReplicatedEnvelope };
|
|
212
|
+
//# sourceMappingURL=PreferencesReplicatedStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreferencesReplicatedStore.d.ts","sourceRoot":"","sources":["../../src/core/PreferencesReplicatedStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EACV,gBAAgB,EAEhB,kBAAkB,EAClB,YAAY,EACb,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAM5D;;yCAEyC;AACzC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C;;mFAEmF;AACnF,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,UAAmB,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,oBAKhC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,EAAE,aAAa,CAAC,MAAM,CAMxD,CAAC;AAEH;oDACoD;AACpD,eAAO,MAAM,mBAAmB,QAAW,CAAC;AAC5C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBA4CnC,CAAC;AAMF;;cAEc;AACd,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD;;oBAEoB;AACpB,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F;;iDAEiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC;IACpH,GAAG,EAAE,YAAY,CAAC;IAClB,EAAE,EAAE,YAAY,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;qBAGiB;IACjB,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,cAAc,CAqB/E;AAWD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,YAAY,GAAG,eAAe,CAe5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAqB5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,eAAe,EAAE,CAsB1F;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAC/B,QAAQ,SAAO,GACd;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOnE;AAMD;;+CAE+C;AAC/C,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAEX;6EAC6E;AAC7E,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAErD;AAED,uFAAuF;AACvF,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PreferencesReplicatedStore — the FIRST concrete consumer of the HLC
|
|
3
|
+
* replicated-store foundation (WS2.1, multi-machine-replicated-store-foundation
|
|
4
|
+
* §4 + §7.2 + §13). It layers the `pref-record` replicated kind onto the generic
|
|
5
|
+
* substrate (ReplicatedRecordEnvelope / UnionReader / ConflictStore /
|
|
6
|
+
* RollbackUnmerge / ReplicationBudget / StoreSnapshot) so a user preference
|
|
7
|
+
* learned on machine A is honored on machine B — ONE memory, not one-per-machine.
|
|
8
|
+
*
|
|
9
|
+
* THIS IS PURE LOGIC. No fs, no Date directly, no network. It defines:
|
|
10
|
+
* A. The `pref-record` store schema (the StoreFieldSchema the registry validates
|
|
11
|
+
* on top of the envelope) + the store's IMPACT TIER (high) + per-kind bounds.
|
|
12
|
+
* B. The emit-envelope builder: PreferenceEntry → the `data` object a journal
|
|
13
|
+
* `pref-record` entry carries (recordKey=dedupeKey, hlc, op, origin, observed).
|
|
14
|
+
* C. The union-aware read: a `Map<recordKey, UnionResult>` (from
|
|
15
|
+
* ReplicatedStoreReader.readAll('preferences')) → a `PreferenceEntry[]` for
|
|
16
|
+
* the session-start block. THE LOAD-BEARING ADVISORY RECONCILIATION (the §15.1
|
|
17
|
+
* decision): on an OPEN conflict for a dedupeKey, BOTH variants are injected as
|
|
18
|
+
* hints — they ARE advisory, both are usable guidance — rather than blocking on
|
|
19
|
+
* operator resolution. Operator resolution (POST /state/resolve-conflict) is
|
|
20
|
+
* OPTIONAL cleanup that collapses the flag; it is NEVER a gate on the hint
|
|
21
|
+
* being injected. A flag is observability + optional cleanup, not a blocked
|
|
22
|
+
* preference. This is what kills the §15.1 over-flag-fatigue concern.
|
|
23
|
+
*
|
|
24
|
+
* SUPERSESSION (CMT-1416): this foundation path SUPERSEDES the earlier advisory
|
|
25
|
+
* `PreferencesSync.ts` (the seamlessness-spec WS2.1, behind
|
|
26
|
+
* multiMachine.seamlessness.ws21PreferencesPool). BOTH ship dark/default-off, so
|
|
27
|
+
* there is ZERO runtime duplication today. PreferencesSync is retained dark until
|
|
28
|
+
* this path is validated, then removed (tracked CMT-1416 — a separate cleanup PR).
|
|
29
|
+
* They are MUTUALLY EXCLUSIVE in practice: the consumer reads ONE path at a time
|
|
30
|
+
* (the foundation reader is consulted only when `multiMachine.stateSync.preferences`
|
|
31
|
+
* is enabled; the legacy merge only when `seamlessness.ws21PreferencesPool` is). An
|
|
32
|
+
* operator who enables BOTH gets the foundation path's precedence (it is the
|
|
33
|
+
* principled substrate); the legacy path is the fallback for an agent that has not
|
|
34
|
+
* yet flipped to the foundation flag.
|
|
35
|
+
*
|
|
36
|
+
* SAFETY POSTURE (§14): MECHANISM, dark by default. Nothing here blocks a
|
|
37
|
+
* user-initiated action. `violationPattern` (the operator's self-violation
|
|
38
|
+
* detection regex/keywords) is a LOCAL-ONLY signal that reveals the operator's
|
|
39
|
+
* security posture, so it is NEVER part of the replicated store schema and is
|
|
40
|
+
* stripped from every emitted envelope (mirrors PreferencesSync finding #1).
|
|
41
|
+
*/
|
|
42
|
+
import { formatPreferencesForSessionStart } from './PreferencesManager.js';
|
|
43
|
+
import { jailStoreStringField } from './ReplicatedRecordEnvelope.js';
|
|
44
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
45
|
+
// A. Identity, tier, schema, bounds
|
|
46
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
47
|
+
/** The stateSync config sub-key + advert suffix for this store (e.g.
|
|
48
|
+
* `multiMachine.stateSync.preferences.enabled`). Equal to the advert flag key
|
|
49
|
+
* `stateSyncReceive['preferences']`. */
|
|
50
|
+
export const PREF_STORE_KEY = 'preferences';
|
|
51
|
+
/** The JournalKind string this store rides — the DUAL-REGISTRY's dynamic half.
|
|
52
|
+
* MUST also be present in CoherenceJournal.JOURNAL_KINDS (the static half), or the
|
|
53
|
+
* store advertises receive=true yet serves/applies/pulls nothing (§4 callout). */
|
|
54
|
+
export const PREF_RECORD_KIND = 'pref-record';
|
|
55
|
+
/**
|
|
56
|
+
* Preferences are HIGH-impact (spec §614 / master-spec decision 2): a concurrent
|
|
57
|
+
* divergent edit to the SAME dedupeKey from different origins goes through
|
|
58
|
+
* APPEND-BOTH-AND-FLAG — both versions preserved, ONE deduped conflict, never a
|
|
59
|
+
* silent overwrite. (The CONSUMER read path still injects BOTH variants as advisory
|
|
60
|
+
* hints — see mergeUnionToPreferences — so the flag never suppresses guidance.)
|
|
61
|
+
*/
|
|
62
|
+
export const PREF_IMPACT_TIER = 'high';
|
|
63
|
+
/**
|
|
64
|
+
* Per-kind replication bounds (§8). Preferences are FEW — a tight window with a
|
|
65
|
+
* coalescing rate cap (the burst of edits to one dedupeKey collapses to the latest
|
|
66
|
+
* state per interval). Mirrors the PreferencesSync precedent's per-store cap
|
|
67
|
+
* (DEFAULT_MAX_REPLICATED_PREFERENCES=500). The retention here matches the
|
|
68
|
+
* journal-level `pref-record` fallback in CoherenceJournal.DEFAULT_RETENTION; the
|
|
69
|
+
* aggregate journal budget (64 MiB default) trivially covers a 2 MiB pref stream.
|
|
70
|
+
*/
|
|
71
|
+
export const PREF_RECORD_BOUNDS = {
|
|
72
|
+
retention: { maxFileBytes: 2 * 1024 * 1024, rotateKeep: 4 },
|
|
73
|
+
// A few preferences, occasional edits — a tight cap with coalescing. Capacity is
|
|
74
|
+
// the burst; refill is the sustained rate. Well under the aggregate budget.
|
|
75
|
+
rateCap: { capacity: 50, refillPerSec: 10 },
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The store-specific field names the `pref-record` schema OWNS (the unknown-field
|
|
79
|
+
* counter's allowlist). NOTE: `violationPattern` is DELIBERATELY ABSENT — it is a
|
|
80
|
+
* LOCAL-ONLY signal (the operator's self-violation regex/keywords) that must never
|
|
81
|
+
* replicate (PreferencesSync finding #1). `dedupeKey` is ABSENT too — it is the
|
|
82
|
+
* recordKey (a reserved envelope field), never a store field. `lastMutatedSeq`,
|
|
83
|
+
* `storeIncarnation` etc. are local replication bookkeeping, never replicated here.
|
|
84
|
+
*/
|
|
85
|
+
export const PREF_STORE_KNOWN_FIELDS = Object.freeze([
|
|
86
|
+
'learning',
|
|
87
|
+
'confidence',
|
|
88
|
+
'dedupeCount',
|
|
89
|
+
'provenance',
|
|
90
|
+
'recordedAt',
|
|
91
|
+
]);
|
|
92
|
+
/** Caps mirroring the PreferencesManager discipline — a value over the cap REJECTS
|
|
93
|
+
* the whole record (never truncate-and-accept). */
|
|
94
|
+
export const MAX_LEARNING_LENGTH = 8 * 1024;
|
|
95
|
+
export const MAX_PROVENANCE_LENGTH = 64;
|
|
96
|
+
/**
|
|
97
|
+
* The `pref-record` store schema (§4). Strict typed validation on top of the
|
|
98
|
+
* envelope: reject free text beyond the known fields, jail any path-shaped string,
|
|
99
|
+
* narrow each field. Returns the validated store-specific object, or null to reject
|
|
100
|
+
* the WHOLE record. PURE (no I/O, no mutation of `raw`).
|
|
101
|
+
*/
|
|
102
|
+
export const prefRecordStoreSchema = {
|
|
103
|
+
knownFields: PREF_STORE_KNOWN_FIELDS,
|
|
104
|
+
// `learning` is free-text user content — credential-scrubbed at SERVE time
|
|
105
|
+
// (buildPrefEnvelope), not here. It is NOT path-sensitive in the path-jail sense
|
|
106
|
+
// (a learning may legitimately mention a slash), so it is not auto-jailed; we
|
|
107
|
+
// length-cap it instead. No store field holds an artifact path, so
|
|
108
|
+
// pathSensitiveFields is empty — but we still jail `provenance` imperatively below
|
|
109
|
+
// as defense-in-depth (a provenance value can never be path-shaped).
|
|
110
|
+
validate(raw, ctx) {
|
|
111
|
+
// learning — required non-empty string, length-capped.
|
|
112
|
+
const learning = raw.learning;
|
|
113
|
+
if (typeof learning !== 'string' || learning.length === 0 || learning.length > MAX_LEARNING_LENGTH) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
// confidence — a finite number in [0,1] (clamped, not rejected, to match the
|
|
117
|
+
// PreferencesManager clamp discipline; an absent/garbage value → 0.5).
|
|
118
|
+
let confidence = 0.5;
|
|
119
|
+
if (typeof raw.confidence === 'number' && Number.isFinite(raw.confidence)) {
|
|
120
|
+
confidence = raw.confidence < 0 ? 0 : raw.confidence > 1 ? 1 : raw.confidence;
|
|
121
|
+
}
|
|
122
|
+
// dedupeCount — a positive integer (≥1).
|
|
123
|
+
let dedupeCount = 1;
|
|
124
|
+
if (typeof raw.dedupeCount === 'number' && Number.isFinite(raw.dedupeCount)) {
|
|
125
|
+
dedupeCount = Math.max(1, Math.floor(raw.dedupeCount));
|
|
126
|
+
}
|
|
127
|
+
// provenance — a short enum-like slug; jail (path-shaped → reject whole record).
|
|
128
|
+
// Slice 1a only ever writes 'correction-loop'; any other (incl. an unknown
|
|
129
|
+
// future) slug is COERCED to it (forward-compat — never reject for a future
|
|
130
|
+
// provenance), so the field is effectively a constant today but the jail still
|
|
131
|
+
// guards against a path-shaped value smuggled into the slot.
|
|
132
|
+
const provenance = 'correction-loop';
|
|
133
|
+
if (raw.provenance !== undefined) {
|
|
134
|
+
const jailed = jailStoreStringField(raw.provenance, ctx);
|
|
135
|
+
if (jailed === null)
|
|
136
|
+
return null; // path-shaped provenance → reject whole record
|
|
137
|
+
}
|
|
138
|
+
// recordedAt — an ISO string; a missing/garbage one is coerced to epoch-0 (the
|
|
139
|
+
// PreferencesManager read() discipline) rather than rejecting the record.
|
|
140
|
+
const recordedAt = typeof raw.recordedAt === 'string' && raw.recordedAt.length > 0 && raw.recordedAt.length <= 64
|
|
141
|
+
? raw.recordedAt
|
|
142
|
+
: new Date(0).toISOString();
|
|
143
|
+
return { learning: learning.trim(), confidence, dedupeCount, provenance, recordedAt };
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Build the `pref-record` envelope `data` for emission (§4). recordKey = the
|
|
148
|
+
* preference `dedupeKey` (the natural primary key — the same dedupeKey on two
|
|
149
|
+
* machines is the SAME learned lesson). `violationPattern` is NEVER included (local-
|
|
150
|
+
* only). `learning` is credential-scrubbed when a scrubber is supplied. The returned
|
|
151
|
+
* object is the journal entry's `data`; the envelope fields are authoritative.
|
|
152
|
+
*
|
|
153
|
+
* NOTE: this does NOT validate — it produces a well-formed `data` the journal emit
|
|
154
|
+
* path serializes; the RECEIVE door (validateReplicatedEnvelope + the store schema)
|
|
155
|
+
* re-validates on apply. Emission is GATED upstream by
|
|
156
|
+
* `multiMachine.stateSync.preferences.enabled` (the caller checks
|
|
157
|
+
* isStoreEmissionEnabled before calling this) — when off, this is never reached.
|
|
158
|
+
*/
|
|
159
|
+
export function buildPrefRecordData(input) {
|
|
160
|
+
const { entry, hlc, op, origin, observed, scrub } = input;
|
|
161
|
+
const scrubbed = scrub ? scrub(entry.learning) : { text: entry.learning, redactedCount: 0 };
|
|
162
|
+
const learning = scrubbed.redactedCount > 0 ? scrubbed.text : entry.learning;
|
|
163
|
+
const data = {
|
|
164
|
+
// store-specific fields FIRST (the envelope fields are appended authoritatively
|
|
165
|
+
// by the journal's validateReplicatedEnvelope on the receive side; on emit we
|
|
166
|
+
// include them so the on-disk shape is complete).
|
|
167
|
+
learning,
|
|
168
|
+
confidence: clamp01(entry.confidence),
|
|
169
|
+
dedupeCount: Math.max(1, Math.floor(entry.dedupeCount || 1)),
|
|
170
|
+
provenance: entry.provenance ?? 'correction-loop',
|
|
171
|
+
recordedAt: entry.recordedAt,
|
|
172
|
+
// envelope fields (recordKey = dedupeKey).
|
|
173
|
+
recordKey: entry.dedupeKey,
|
|
174
|
+
hlc,
|
|
175
|
+
op,
|
|
176
|
+
origin,
|
|
177
|
+
...(observed !== undefined ? { observed } : {}),
|
|
178
|
+
};
|
|
179
|
+
return data;
|
|
180
|
+
}
|
|
181
|
+
function clamp01(v) {
|
|
182
|
+
if (typeof v !== 'number' || Number.isNaN(v))
|
|
183
|
+
return 0.5;
|
|
184
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
185
|
+
}
|
|
186
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
187
|
+
// C. Union-aware read — the LOAD-BEARING advisory reconciliation (§15.1)
|
|
188
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* Reconstruct a PreferenceEntry from an OriginRecord's store `data` (the envelope
|
|
191
|
+
* fields stripped). Defensive: a field that does not narrow falls back to the same
|
|
192
|
+
* safe default PreferencesManager.read() uses. `dedupeKey` is the recordKey.
|
|
193
|
+
*/
|
|
194
|
+
export function prefEntryFromOriginRecord(rec) {
|
|
195
|
+
const d = rec.data;
|
|
196
|
+
const learning = typeof d.learning === 'string' ? d.learning : '';
|
|
197
|
+
const confidence = typeof d.confidence === 'number' && Number.isFinite(d.confidence) ? clamp01(d.confidence) : 0.5;
|
|
198
|
+
const dedupeCount = typeof d.dedupeCount === 'number' && Number.isFinite(d.dedupeCount) ? Math.max(1, Math.floor(d.dedupeCount)) : 1;
|
|
199
|
+
const recordedAt = typeof d.recordedAt === 'string' && d.recordedAt.length > 0 ? d.recordedAt : new Date(0).toISOString();
|
|
200
|
+
return {
|
|
201
|
+
learning,
|
|
202
|
+
provenance: 'correction-loop',
|
|
203
|
+
dedupeKey: rec.envelope.recordKey,
|
|
204
|
+
recordedAt,
|
|
205
|
+
confidence,
|
|
206
|
+
dedupeCount,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Build an OriginRecord for the OWN preference store (the single-origin
|
|
211
|
+
* materialization the union reader merges). recordKey = dedupeKey; the envelope
|
|
212
|
+
* carries a SYNTHETIC own-origin stamp. NOTE: this is the OWN record at rest — it
|
|
213
|
+
* is NOT the wire/journal hlc (that is minted by clock.tick() at the EMIT path);
|
|
214
|
+
* here we only need a stable own-origin record for the union to merge against peer
|
|
215
|
+
* replicas. `lastMutatedSeq` is folded into a deterministic logical counter so the
|
|
216
|
+
* own record has a well-formed, monotone HLC position relative to its own edits.
|
|
217
|
+
* `violationPattern` is NEVER carried into the replicated namespace (local-only).
|
|
218
|
+
*/
|
|
219
|
+
export function prefEntryToOriginRecord(entry, origin) {
|
|
220
|
+
const physical = Date.parse(entry.recordedAt);
|
|
221
|
+
const hlc = {
|
|
222
|
+
physical: Number.isFinite(physical) ? physical : 0,
|
|
223
|
+
logical: Math.max(0, Math.floor(entry.lastMutatedSeq ?? 0)),
|
|
224
|
+
node: origin,
|
|
225
|
+
};
|
|
226
|
+
const data = {
|
|
227
|
+
learning: entry.learning,
|
|
228
|
+
confidence: clamp01(entry.confidence),
|
|
229
|
+
dedupeCount: Math.max(1, Math.floor(entry.dedupeCount || 1)),
|
|
230
|
+
provenance: entry.provenance ?? 'correction-loop',
|
|
231
|
+
recordedAt: entry.recordedAt,
|
|
232
|
+
};
|
|
233
|
+
const envelope = {
|
|
234
|
+
recordKey: entry.dedupeKey,
|
|
235
|
+
hlc,
|
|
236
|
+
op: 'put',
|
|
237
|
+
origin,
|
|
238
|
+
};
|
|
239
|
+
return { origin, envelope, data };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* THE LOAD-BEARING ADVISORY RECONCILIATION (§15.1 decision, recorded verbatim).
|
|
243
|
+
*
|
|
244
|
+
* Collapse a `Map<recordKey, UnionResult>` (from
|
|
245
|
+
* ReplicatedStoreReader.readAll('preferences')) into the PreferenceEntry[] the
|
|
246
|
+
* session-start block consumes. The §15.1 contract:
|
|
247
|
+
* - A resolved single value ⇒ inject that one entry.
|
|
248
|
+
* - An OPEN HIGH-impact conflict ⇒ inject BOTH (all) concurrent variants as
|
|
249
|
+
* separate hints. They ARE advisory — both are usable guidance — so the open
|
|
250
|
+
* conflict NEVER suppresses a usable hint. Operator resolution (POST
|
|
251
|
+
* /state/resolve-conflict) is OPTIONAL cleanup that collapses the flag; it is
|
|
252
|
+
* NEVER a gate on the hint being injected.
|
|
253
|
+
* - A LOW-impact divergence ⇒ the HLC-winner is `value`; inject it (the overwrite
|
|
254
|
+
* was flagged for observability, but the value is usable).
|
|
255
|
+
* - A null `value` with no conflict (every origin deleted, or no record) ⇒ nothing
|
|
256
|
+
* to inject for that key.
|
|
257
|
+
*
|
|
258
|
+
* This is the proof obligation the §12 wiring test exercises: an OPEN conflict for a
|
|
259
|
+
* dedupeKey STILL yields both variants in the output (it can never suppress a usable
|
|
260
|
+
* hint waiting on operator resolution). The conflict's `versions` carry every
|
|
261
|
+
* concurrent origin's record; we map EACH to a PreferenceEntry hint.
|
|
262
|
+
*
|
|
263
|
+
* Determinism: variants from a conflict are emitted in the union reader's stable
|
|
264
|
+
* (HLC-sorted) version order, so the injected block is stable across reads.
|
|
265
|
+
*/
|
|
266
|
+
export function mergeUnionToPreferences(union) {
|
|
267
|
+
const out = [];
|
|
268
|
+
for (const result of union.values()) {
|
|
269
|
+
if (result.conflict) {
|
|
270
|
+
// OPEN HIGH-impact conflict: inject BOTH (all) concurrent variants as hints —
|
|
271
|
+
// NEVER suppress a usable hint waiting on operator resolution (§15.1). A `put`
|
|
272
|
+
// tombstone variant (op==='delete') contributes no usable guidance, so it is
|
|
273
|
+
// skipped, but every surviving `put` variant is injected.
|
|
274
|
+
for (const v of result.conflict.versions) {
|
|
275
|
+
if (v.envelope.op === 'delete')
|
|
276
|
+
continue;
|
|
277
|
+
out.push(prefEntryFromOriginRecord(v));
|
|
278
|
+
}
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
// Resolved value (single origin, clean sequential chain, or LOW-impact HLC-win).
|
|
282
|
+
// `value` is null when the resolved winner is a delete tombstone (or no record) —
|
|
283
|
+
// nothing usable to inject for that key.
|
|
284
|
+
if (result.value && result.value.envelope.op !== 'delete') {
|
|
285
|
+
out.push(prefEntryFromOriginRecord(result.value));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return out;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Build the session-start preferences block from a union read (the foundation
|
|
292
|
+
* path's equivalent of PreferencesManager.sessionContext()). Reuses the SAME
|
|
293
|
+
* deterministic, byte-bounded, priority-ordered renderer
|
|
294
|
+
* (`formatPreferencesForSessionStart`) so the injected block shape is identical to
|
|
295
|
+
* the single-machine path — only the SOURCE differs (the no-clobber union vs the
|
|
296
|
+
* local store). An open conflict yields BOTH variants in the block (§15.1).
|
|
297
|
+
*/
|
|
298
|
+
export function buildUnionSessionContext(union, maxBytes = 4000) {
|
|
299
|
+
const preferences = mergeUnionToPreferences(union);
|
|
300
|
+
const block = formatPreferencesForSessionStart({ schemaVersion: 1, preferences }, maxBytes);
|
|
301
|
+
return { present: block.length > 0, block, count: preferences.length, scope: 'mesh' };
|
|
302
|
+
}
|
|
303
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
304
|
+
// Registration descriptor (consumed by server.ts to register the dual registry)
|
|
305
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
306
|
+
/** The ReplicatedKindRegistry registration for the `pref-record` store. server.ts
|
|
307
|
+
* registers this onto the shared registry; the dual-registry coupling test asserts
|
|
308
|
+
* `kind` is also present in JOURNAL_KINDS. */
|
|
309
|
+
export const PREF_KIND_REGISTRATION = {
|
|
310
|
+
kind: PREF_RECORD_KIND,
|
|
311
|
+
store: PREF_STORE_KEY,
|
|
312
|
+
schema: prefRecordStoreSchema,
|
|
313
|
+
};
|
|
314
|
+
/** Convenience re-export for the rollback-unmerge `kindsForStore('preferences')`
|
|
315
|
+
* wiring + any caller that needs the store's contributing journal kinds. */
|
|
316
|
+
export function prefContributingKinds() {
|
|
317
|
+
return [PREF_RECORD_KIND];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* The store's impact tier resolver, for ReplicatedStoreReader.tierOf. Returns the
|
|
321
|
+
* preferences tier (high) for the `preferences` store. An UNKNOWN store also
|
|
322
|
+
* resolves to `high` — the CONSERVATIVE direction (append-both-and-flag never
|
|
323
|
+
* silently clobbers), so a future store wired before its own tierOf lands can never
|
|
324
|
+
* accidentally get the silent-overwrite path. The reader composes per-store; this is
|
|
325
|
+
* the default a server wires for the preferences store specifically.
|
|
326
|
+
*/
|
|
327
|
+
export function prefTierOf(_store) {
|
|
328
|
+
return PREF_IMPACT_TIER;
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=PreferencesReplicatedStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreferencesReplicatedStore.js","sourceRoot":"","sources":["../../src/core/PreferencesReplicatedStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* DEPRECATED / SUPERSEDED (CMT-1416): this seamlessness-spec WS2.1 advisory
|
|
3
|
+
* replicator is superseded by the HLC-foundation `pref-record` replicated store
|
|
4
|
+
* (`multiMachine.stateSync.preferences`, src/core/PreferencesReplicatedStore.ts).
|
|
5
|
+
* Retained dark (behind `multiMachine.seamlessness.ws21PreferencesPool`) until the
|
|
6
|
+
* foundation path is validated, then removed — a separate reviewable cleanup PR.
|
|
7
|
+
* BOTH ship dark/default-off ⇒ zero runtime duplication; they are mutually
|
|
8
|
+
* exclusive in practice (the foundation path takes precedence when its flag is on).
|
|
9
|
+
*
|
|
2
10
|
* PreferencesSync — WS2.1 of multi-machine seamlessness: the serve / receive /
|
|
3
11
|
* merge engine behind the `preferences-sync` mesh verb. Replicates the
|
|
4
12
|
* correction-learning preference store (PreferencesManager,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreferencesSync.d.ts","sourceRoot":"","sources":["../../src/core/PreferencesSync.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"PreferencesSync.d.ts","sourceRoot":"","sources":["../../src/core/PreferencesSync.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* DEPRECATED / SUPERSEDED (CMT-1416): this seamlessness-spec WS2.1 advisory
|
|
3
|
+
* replicator is superseded by the HLC-foundation `pref-record` replicated store
|
|
4
|
+
* (`multiMachine.stateSync.preferences`, src/core/PreferencesReplicatedStore.ts).
|
|
5
|
+
* Retained dark (behind `multiMachine.seamlessness.ws21PreferencesPool`) until the
|
|
6
|
+
* foundation path is validated, then removed — a separate reviewable cleanup PR.
|
|
7
|
+
* BOTH ship dark/default-off ⇒ zero runtime duplication; they are mutually
|
|
8
|
+
* exclusive in practice (the foundation path takes precedence when its flag is on).
|
|
9
|
+
*
|
|
2
10
|
* PreferencesSync — WS2.1 of multi-machine seamlessness: the serve / receive /
|
|
3
11
|
* merge engine behind the `preferences-sync` mesh verb. Replicates the
|
|
4
12
|
* correction-learning preference store (PreferencesManager,
|