instar 1.3.569 → 1.3.571
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 +127 -53
- package/dist/commands/server.js.map +1 -1
- package/dist/core/CoherenceJournal.d.ts +46 -0
- package/dist/core/CoherenceJournal.d.ts.map +1 -1
- package/dist/core/CoherenceJournal.js +94 -2
- package/dist/core/CoherenceJournal.js.map +1 -1
- package/dist/core/JournalSyncApplier.d.ts +22 -0
- package/dist/core/JournalSyncApplier.d.ts.map +1 -1
- package/dist/core/JournalSyncApplier.js +39 -2
- package/dist/core/JournalSyncApplier.js.map +1 -1
- package/dist/core/MachinePoolRegistry.d.ts.map +1 -1
- package/dist/core/MachinePoolRegistry.js +26 -4
- package/dist/core/MachinePoolRegistry.js.map +1 -1
- package/dist/core/PeerPresencePuller.d.ts +39 -0
- package/dist/core/PeerPresencePuller.d.ts.map +1 -1
- package/dist/core/PeerPresencePuller.js +46 -1
- package/dist/core/PeerPresencePuller.js.map +1 -1
- package/dist/core/ReplicatedPeerStreamReader.d.ts +97 -0
- package/dist/core/ReplicatedPeerStreamReader.d.ts.map +1 -0
- package/dist/core/ReplicatedPeerStreamReader.js +274 -0
- package/dist/core/ReplicatedPeerStreamReader.js.map +1 -0
- package/dist/core/ReplicatedRecordEmitter.d.ts +102 -0
- package/dist/core/ReplicatedRecordEmitter.d.ts.map +1 -0
- package/dist/core/ReplicatedRecordEmitter.js +122 -0
- package/dist/core/ReplicatedRecordEmitter.js.map +1 -0
- package/dist/core/ws2SendWiring.d.ts +52 -0
- package/dist/core/ws2SendWiring.d.ts.map +1 -0
- package/dist/core/ws2SendWiring.js +71 -0
- package/dist/core/ws2SendWiring.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.570.md +69 -0
- package/upgrades/1.3.571.md +64 -0
- package/upgrades/side-effects/statesync-peer-advert-propagation-fix.md +125 -0
- package/upgrades/side-effects/ws2-send-side-emission.md +40 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAg4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAg4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4mctE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -3423,6 +3423,69 @@ export async function startServer(options) {
|
|
|
3423
3423
|
// answer to "who is my verified operator?" (only the local authenticated setOperator binds it).
|
|
3424
3424
|
const { TOPIC_OPERATOR_KIND_REGISTRATION } = await import('../core/TopicOperatorReplicatedStore.js');
|
|
3425
3425
|
replicatedKindRegistry.register(TOPIC_OPERATOR_KIND_REGISTRATION);
|
|
3426
|
+
// ── WS2 SEND-SIDE wiring (docs/specs/WS2-SEND-SIDE-EMISSION-SPEC.md). The
|
|
3427
|
+
// substrate above ships the registry + receive/serve machinery + advert; THIS
|
|
3428
|
+
// wires the SEND half that was deferred ("the journal-backed emitter is attached
|
|
3429
|
+
// in a later rollout stage"). Three pieces, all KIND-AGNOSTIC: (1) inject the
|
|
3430
|
+
// now-populated registry into the journal writer + the applier so a registered
|
|
3431
|
+
// `*-record` kind validates/accepts on BOTH ends (without it a peer's record
|
|
3432
|
+
// suspect-flags the stream — the receive-only gap); (2) the peer-stream reader
|
|
3433
|
+
// that materializes own + peer journal streams into the union's per-origin
|
|
3434
|
+
// records (makes a received record READABLE) + the snapshot loadOwnEntries
|
|
3435
|
+
// source + the emitter's `observed`-witness source; (3) the author-side HLC
|
|
3436
|
+
// clock. All require the coherence journal (the emit sink + the streams to read);
|
|
3437
|
+
// when it is dark these stay undefined and every consumer degrades to its
|
|
3438
|
+
// existing single-machine no-op. The generic record emitter is constructed below
|
|
3439
|
+
// (it also needs the resolved stateSync flags).
|
|
3440
|
+
let replicatedPeerStreamReader;
|
|
3441
|
+
let replicatedRecordEmitter;
|
|
3442
|
+
let replicatedHlcClock;
|
|
3443
|
+
if (coherenceJournal && cjOwnMachineId) {
|
|
3444
|
+
try {
|
|
3445
|
+
coherenceJournal.setReplicatedKindRegistry(replicatedKindRegistry);
|
|
3446
|
+
journalSyncApplier?.setReplicatedKindRegistry(replicatedKindRegistry);
|
|
3447
|
+
const { ReplicatedPeerStreamReader } = await import('../core/ReplicatedPeerStreamReader.js');
|
|
3448
|
+
replicatedPeerStreamReader = new ReplicatedPeerStreamReader({
|
|
3449
|
+
stateDir: config.stateDir,
|
|
3450
|
+
registry: replicatedKindRegistry,
|
|
3451
|
+
selfMachineId: cjOwnMachineId,
|
|
3452
|
+
});
|
|
3453
|
+
// Author-side HLC clock — persisted under the journal dir (atomic temp+rename)
|
|
3454
|
+
// so the merge total order survives restarts (§3.5). node = this machine's id.
|
|
3455
|
+
const { HybridLogicalClock } = await import('../core/HybridLogicalClock.js');
|
|
3456
|
+
const hlcSafeId = cjOwnMachineId.replace(/[^A-Za-z0-9_.-]/g, '_');
|
|
3457
|
+
const hlcPath = path.join(config.stateDir, 'state', 'coherence-journal', `hlc-${hlcSafeId}.json`);
|
|
3458
|
+
replicatedHlcClock = new HybridLogicalClock({
|
|
3459
|
+
node: cjOwnMachineId,
|
|
3460
|
+
now: () => Date.now(),
|
|
3461
|
+
persist: {
|
|
3462
|
+
load: () => {
|
|
3463
|
+
try {
|
|
3464
|
+
const o = JSON.parse(fs.readFileSync(hlcPath, 'utf-8'));
|
|
3465
|
+
return o && typeof o.physical === 'number' ? o : null;
|
|
3466
|
+
}
|
|
3467
|
+
catch { /* @silent-fallback-ok: absent/corrupt hlc file = fresh clock (first boot) — the clock starts at 0, never throws. */
|
|
3468
|
+
return null;
|
|
3469
|
+
}
|
|
3470
|
+
},
|
|
3471
|
+
save: (t) => {
|
|
3472
|
+
try {
|
|
3473
|
+
fs.mkdirSync(path.dirname(hlcPath), { recursive: true });
|
|
3474
|
+
const tmp = `${hlcPath}.tmp-${process.pid}`;
|
|
3475
|
+
fs.writeFileSync(tmp, JSON.stringify(t));
|
|
3476
|
+
fs.renameSync(tmp, hlcPath);
|
|
3477
|
+
}
|
|
3478
|
+
catch { /* @silent-fallback-ok: a failed hlc persist degrades to in-memory-only (the clock still advances this run); replication merge order is best-effort durable, never a boot blocker. */ }
|
|
3479
|
+
},
|
|
3480
|
+
},
|
|
3481
|
+
});
|
|
3482
|
+
}
|
|
3483
|
+
catch (e) { /* @silent-fallback-ok: the SEND-side wiring must never endanger boot — a failure leaves replication dark (undefined seams), exactly the pre-WS2-send behavior. */
|
|
3484
|
+
replicatedPeerStreamReader = undefined;
|
|
3485
|
+
replicatedHlcClock = undefined;
|
|
3486
|
+
console.log(pc.dim(` [ws2-send] emitter wiring skipped: ${e instanceof Error ? e.message : String(e)}`));
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3426
3489
|
// Snapshot-then-tail engine (Component 4 / build-order step 3,
|
|
3427
3490
|
// multi-machine-replicated-store-foundation §6). The cache (FIXED ceiling,
|
|
3428
3491
|
// §8.2 — NOT pool-scaled), the per-peer rebuild breaker (§6.3), and the engine
|
|
@@ -3443,10 +3506,12 @@ export async function startServer(options) {
|
|
|
3443
3506
|
cache: snapshotCache,
|
|
3444
3507
|
breaker: snapshotRebuildBreaker,
|
|
3445
3508
|
seams: {
|
|
3446
|
-
//
|
|
3447
|
-
//
|
|
3448
|
-
//
|
|
3449
|
-
|
|
3509
|
+
// WS2 send-side: read the OWN journal streams for the store's registered
|
|
3510
|
+
// kind(s) so a snapshot serve returns real entries (replaces the no-op stub).
|
|
3511
|
+
// Single-origin is enforced inside the reader (it serves only this machine's
|
|
3512
|
+
// own stream). When the journal is dark the reader is undefined ⇒ `{}` (the
|
|
3513
|
+
// correct no-store no-op; serveSnapshot then answers 'no-entries').
|
|
3514
|
+
loadOwnEntries: (store, origin) => replicatedPeerStreamReader ? replicatedPeerStreamReader.loadOwnEntries(store, origin) : {},
|
|
3450
3515
|
now: () => Date.now(),
|
|
3451
3516
|
},
|
|
3452
3517
|
maxSnapshotBytes: stateSync.maxCacheBytes,
|
|
@@ -3461,6 +3526,26 @@ export async function startServer(options) {
|
|
|
3461
3526
|
// `enabled === true` semantics but now see a live flag on a dev agent. An explicit
|
|
3462
3527
|
// operator `enabled` in config still wins (force-dark false / fleet-flip true).
|
|
3463
3528
|
const _stateSyncStoresResolved = resolveStateSyncStores(config);
|
|
3529
|
+
// WS2 send-side: the generic journal-backed record emitter (the concrete emitter
|
|
3530
|
+
// the per-store managers' emit hooks call). Needs the journal sink, the HLC clock,
|
|
3531
|
+
// the registry (store → kind), this machine's origin id, the resolved stateSync
|
|
3532
|
+
// flags (the dark gate — read via a getter so a live flip is honored), and the
|
|
3533
|
+
// peer-stream reader as the `observed`-witness source. Constructed only when the
|
|
3534
|
+
// journal + clock + reader exist (all gated on the coherence journal being live);
|
|
3535
|
+
// otherwise it stays undefined and every per-store emit adapter is simply never
|
|
3536
|
+
// attached (the managers' hooks stay no-ops, the pre-WS2-send behavior).
|
|
3537
|
+
if (coherenceJournal && replicatedHlcClock && replicatedPeerStreamReader) {
|
|
3538
|
+
const { ReplicatedRecordEmitter } = await import('../core/ReplicatedRecordEmitter.js');
|
|
3539
|
+
replicatedRecordEmitter = new ReplicatedRecordEmitter({
|
|
3540
|
+
journal: coherenceJournal,
|
|
3541
|
+
clock: replicatedHlcClock,
|
|
3542
|
+
registry: replicatedKindRegistry,
|
|
3543
|
+
origin: cjOwnMachineId,
|
|
3544
|
+
stores: () => _stateSyncStoresResolved,
|
|
3545
|
+
loadWitness: (store, recordKey) => replicatedPeerStreamReader.loadWitness(store, recordKey),
|
|
3546
|
+
log: (event, detail) => console.log(pc.dim(` [ws2-send] ${event} ${JSON.stringify(detail)}`)),
|
|
3547
|
+
});
|
|
3548
|
+
}
|
|
3464
3549
|
const selfStateSyncReceive = () => {
|
|
3465
3550
|
const out = {};
|
|
3466
3551
|
const stores = _stateSyncStoresResolved;
|
|
@@ -7843,37 +7928,40 @@ export async function startServer(options) {
|
|
|
7843
7928
|
// and-flag never silently clobbers two divergent lessons; the READ layer is advisory,
|
|
7844
7929
|
// injecting both variants as hints rather than blocking — fork #2). Consulted by a
|
|
7845
7930
|
// learnings peer-read surface ONLY when stateSync.learnings.enabled is true.
|
|
7846
|
-
const { learningTierOf,
|
|
7931
|
+
const { learningTierOf, deriveLearningRecordKey, buildLearningRecordData, buildLearningTombstoneData, LEARNING_STORE_KEY, } = await import('../core/LearningsReplicatedStore.js');
|
|
7847
7932
|
const learningsUnionReader = new ReplicatedStoreReader({
|
|
7848
7933
|
registry: replicatedKindRegistry,
|
|
7849
7934
|
stores: _stateSyncStoresResolved, // gate-resolved (dev-live / fleet-dark) per operator directive 2026-06-13
|
|
7850
7935
|
tierOf: learningTierOf,
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
listRecordKeys: (store) => {
|
|
7863
|
-
if (store !== LEARNING_STORE_KEY)
|
|
7864
|
-
return [];
|
|
7865
|
-
const keys = [];
|
|
7866
|
-
for (const l of evolution.listLearnings()) {
|
|
7867
|
-
const k = deriveLearningRecordKey(l.title, l.category, l.source);
|
|
7868
|
-
if (k !== null)
|
|
7869
|
-
keys.push(k);
|
|
7870
|
-
}
|
|
7871
|
-
return keys;
|
|
7872
|
-
},
|
|
7936
|
+
// WS2 send-side: the union now reads OWN + PEER journal streams (each record's
|
|
7937
|
+
// authoritative emit-time HLC) via the peer-stream reader — so a learning
|
|
7938
|
+
// replicated FROM a peer is READABLE here, not just the local one. Dark / no
|
|
7939
|
+
// journal ⇒ reader undefined ⇒ [] (isLive already gates a disabled store to a
|
|
7940
|
+
// strict no-op, so this never changes single-machine behavior).
|
|
7941
|
+
loadOriginRecords: (store, recordKey) => store === LEARNING_STORE_KEY && replicatedPeerStreamReader
|
|
7942
|
+
? replicatedPeerStreamReader.loadOriginRecords(store, recordKey)
|
|
7943
|
+
: [],
|
|
7944
|
+
listRecordKeys: (store) => store === LEARNING_STORE_KEY && replicatedPeerStreamReader
|
|
7945
|
+
? replicatedPeerStreamReader.listRecordKeys(store)
|
|
7946
|
+
: [],
|
|
7873
7947
|
droppedOrigins: droppedOriginRegistry,
|
|
7874
7948
|
conflictStore,
|
|
7875
7949
|
});
|
|
7876
|
-
void learningsUnionReader; // consumed by the learnings peer-read surface
|
|
7950
|
+
void learningsUnionReader; // consumed by the learnings peer-read surface (the E2E reads through it) + future session-context injection
|
|
7951
|
+
// WS2 SEND-SIDE: attach the journal-backed emitter to the EvolutionManager's
|
|
7952
|
+
// learning hooks. The call sites already fire emitPut/emitDelete on every
|
|
7953
|
+
// saveLearnings (prune→emitDelete, survivor→emitPut); the adapter maps the
|
|
7954
|
+
// manager's emit signature to the store's build*RecordData. The emitter owns the
|
|
7955
|
+
// dark gate, HLC tick, `observed` witness, and journal append. Attached only when
|
|
7956
|
+
// the emitter exists (journal live); when dark the hooks stay no-ops (byte-
|
|
7957
|
+
// identical single-machine behavior — the local LRN-NNN id never crosses the wire).
|
|
7958
|
+
if (replicatedRecordEmitter) {
|
|
7959
|
+
const emitter = replicatedRecordEmitter;
|
|
7960
|
+
evolution.setLearningReplicationEmitter({
|
|
7961
|
+
emitPut: (rec) => emitter.emit(LEARNING_STORE_KEY, deriveLearningRecordKey(rec.title, rec.category, rec.source), (hlc, origin, observed) => buildLearningRecordData({ record: rec, hlc, origin, observed })),
|
|
7962
|
+
emitDelete: (title, category, source, deletedAt) => emitter.emit(LEARNING_STORE_KEY, deriveLearningRecordKey(title, category, source), (hlc, origin, observed) => buildLearningTombstoneData({ title, category, source, hlc, origin, deletedAt, observed })),
|
|
7963
|
+
});
|
|
7964
|
+
}
|
|
7877
7965
|
// WS2.4 — the bypass-proof union reader for the `knowledge` store + the emit seam on
|
|
7878
7966
|
// the KnowledgeManager. The KnowledgeManager reads the local catalog.json (cheap, no
|
|
7879
7967
|
// background work); we construct one here scoped to the replication wiring. The union
|
|
@@ -15405,31 +15493,17 @@ export async function startServer(options) {
|
|
|
15405
15493
|
fetchPeerCapacity: async (machineId, url) => {
|
|
15406
15494
|
const res = await meshClient.send({ machineId, url }, { type: 'session-status' }, 0);
|
|
15407
15495
|
if (res.ok && res.result && typeof res.result === 'object') {
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
//
|
|
15411
|
-
//
|
|
15412
|
-
//
|
|
15413
|
-
//
|
|
15414
|
-
//
|
|
15415
|
-
//
|
|
15416
|
-
//
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
return {
|
|
15420
|
-
selfReportedLastSeen: cap.selfReportedLastSeen,
|
|
15421
|
-
loadAvg: cap.loadAvg,
|
|
15422
|
-
journalAdvert,
|
|
15423
|
-
...(cap.commitmentsAdvert ? { commitmentsAdvert: cap.commitmentsAdvert } : {}),
|
|
15424
|
-
// §WS2.1 sibling pass-through (the #930/A2 narrowing lesson): the
|
|
15425
|
-
// peer's preferences advert is served but would be dropped here
|
|
15426
|
-
// without this, so drivePreferencesSync would never fire.
|
|
15427
|
-
...(cap.preferencesAdvert ? { preferencesAdvert: cap.preferencesAdvert } : {}),
|
|
15428
|
-
...(cap.quotaState ? { quotaState: cap.quotaState } : {}),
|
|
15429
|
-
// Guard posture rides the same pass-through (the A2 narrowing
|
|
15430
|
-
// lesson): dropping it here would blind the pool to peers' posture.
|
|
15431
|
-
...(cap.guardPosture ? { guardPosture: cap.guardPosture } : {}),
|
|
15432
|
-
};
|
|
15496
|
+
// The journal advert is the one slice that needs closure context
|
|
15497
|
+
// (the machine-id-keyed unwrap), so it is computed HERE; the rest
|
|
15498
|
+
// of the narrowing — commitmentsAdvert (#930), quotaState (A2/#804),
|
|
15499
|
+
// preferencesAdvert (WS2.1), guardPosture, and seamlessnessFlags
|
|
15500
|
+
// (THIS fix, the 4th instance of the narrowing-return-forgets-a-field
|
|
15501
|
+
// class) — is the SINGLE shared `narrowSessionStatusToPeerCapacity`
|
|
15502
|
+
// pass-through that the peer-presence round-trip test also runs, so
|
|
15503
|
+
// the test proves the REAL mapping and a forgotten field can't recur
|
|
15504
|
+
// silently (the wiring-integrity ratchet asserts over this helper).
|
|
15505
|
+
const journalAdvert = _unwrapPeerJournalAdvert(machineId, res.result.journalAdvert);
|
|
15506
|
+
return presenceMod.narrowSessionStatusToPeerCapacity(res.result, journalAdvert);
|
|
15433
15507
|
}
|
|
15434
15508
|
return null;
|
|
15435
15509
|
},
|