instar 1.3.602 → 1.3.604
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 +108 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +36 -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/CredentialLocationLedger.d.ts +70 -0
- package/dist/core/CredentialLocationLedger.d.ts.map +1 -1
- package/dist/core/CredentialLocationLedger.js +126 -0
- package/dist/core/CredentialLocationLedger.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +25 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ThreadlinePairingReplicatedStore.d.ts +285 -0
- package/dist/core/ThreadlinePairingReplicatedStore.d.ts.map +1 -0
- package/dist/core/ThreadlinePairingReplicatedStore.js +462 -0
- package/dist/core/ThreadlinePairingReplicatedStore.js.map +1 -0
- 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/core/types.d.ts +22 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +6 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +323 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/AgentTrustManager.d.ts +201 -1
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
- package/dist/threadline/AgentTrustManager.js +395 -2
- package/dist/threadline/AgentTrustManager.js.map +1 -1
- package/dist/threadline/CredentialShareGate.d.ts +66 -0
- package/dist/threadline/CredentialShareGate.d.ts.map +1 -0
- package/dist/threadline/CredentialShareGate.js +82 -0
- package/dist/threadline/CredentialShareGate.js.map +1 -0
- package/dist/threadline/InboundMessageGate.d.ts +46 -1
- package/dist/threadline/InboundMessageGate.d.ts.map +1 -1
- package/dist/threadline/InboundMessageGate.js +105 -0
- package/dist/threadline/InboundMessageGate.js.map +1 -1
- package/dist/threadline/PairVerifyReceipt.d.ts +69 -0
- package/dist/threadline/PairVerifyReceipt.d.ts.map +1 -0
- package/dist/threadline/PairVerifyReceipt.js +151 -0
- package/dist/threadline/PairVerifyReceipt.js.map +1 -0
- package/dist/threadline/PairingPendingStore.d.ts +55 -0
- package/dist/threadline/PairingPendingStore.d.ts.map +1 -0
- package/dist/threadline/PairingPendingStore.js +110 -0
- package/dist/threadline/PairingPendingStore.js.map +1 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts +11 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +5 -0
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/ThreadlineCrypto.d.ts +28 -0
- package/dist/threadline/ThreadlineCrypto.d.ts.map +1 -1
- package/dist/threadline/ThreadlineCrypto.js +100 -0
- package/dist/threadline/ThreadlineCrypto.js.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.d.ts +8 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.js +5 -0
- package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts +3 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +107 -1
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/client/ThreadlineClient.d.ts +10 -0
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
- package/dist/threadline/client/ThreadlineClient.js +13 -0
- package/dist/threadline/client/ThreadlineClient.js.map +1 -1
- package/package.json +2 -1
- package/scripts/check-e2e-pairing.cjs +4 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/data/state-coherence-registry.json +26 -0
- package/src/scaffold/templates.ts +6 -0
- package/src/threadline/data/sas-wordlist-en.json +1 -0
- package/upgrades/1.3.603.md +39 -0
- package/upgrades/1.3.604.md +57 -0
- package/upgrades/side-effects/credential-identity-audit.md +183 -0
- package/upgrades/side-effects/secure-a2a-verified-pairing.md +116 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,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;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,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,CAo4dtE;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
|
@@ -3426,6 +3426,20 @@ export async function startServer(options) {
|
|
|
3426
3426
|
// answer to "who is my verified operator?" (only the local authenticated setOperator binds it).
|
|
3427
3427
|
const { TOPIC_OPERATOR_KIND_REGISTRATION } = await import('../core/TopicOperatorReplicatedStore.js');
|
|
3428
3428
|
replicatedKindRegistry.register(TOPIC_OPERATOR_KIND_REGISTRATION);
|
|
3429
|
+
// Secure A2A Verified Pairing §3.8 (FD11) — register the EIGHTH concrete replicated kind,
|
|
3430
|
+
// `threadline-pairing-record`, onto the registry. Unlike the WS2 memory/PII stores it
|
|
3431
|
+
// replicates ONLY the verified-IDENTITY RESULT of a pairing { peerFp, peerIdentityPub,
|
|
3432
|
+
// state:'mutual-verified', verifiedAt, verifiedOnMachine } — NEVER the SAS, shared secret, or
|
|
3433
|
+
// relay token (those stay machine-local BY DESIGN). Dual-registry's dynamic half (the static
|
|
3434
|
+
// half is CoherenceJournal.JOURNAL_KINDS, which now lists 'threadline-pairing-record').
|
|
3435
|
+
// Registration is INERT — emission/serve/pull stay gated behind
|
|
3436
|
+
// `multiMachine.stateSync.threadlinePairing.enabled` (default false ⇒ strict no-op). Machine B
|
|
3437
|
+
// honors a replicated record ONLY by pinning peerIdentityPub (a mismatching handshake key is
|
|
3438
|
+
// refused inheritance + downgraded to pending-verification); inherited = identity-verified, NOT
|
|
3439
|
+
// channel-ready (the outbound CredentialShareGate enforces the encrypted-path half). A revoke /
|
|
3440
|
+
// verification-failed propagates as a tombstone (ThreadlinePairingReplicatedStore).
|
|
3441
|
+
const { THREADLINE_PAIRING_KIND_REGISTRATION } = await import('../core/ThreadlinePairingReplicatedStore.js');
|
|
3442
|
+
replicatedKindRegistry.register(THREADLINE_PAIRING_KIND_REGISTRATION);
|
|
3429
3443
|
// ── WS2 SEND-SIDE wiring (docs/specs/WS2-SEND-SIDE-EMISSION-SPEC.md). The
|
|
3430
3444
|
// substrate above ships the registry + receive/serve machinery + advert; THIS
|
|
3431
3445
|
// wires the SEND half that was deferred ("the journal-backed emitter is attached
|
|
@@ -9232,7 +9246,7 @@ export async function startServer(options) {
|
|
|
9232
9246
|
// off (always, while dark) every gate read returns the enrollment-home fallback, so every
|
|
9233
9247
|
// consumer is byte-for-byte today's behavior. A never-seeded ledger is the same fallback (back-
|
|
9234
9248
|
// compat); only UNKNOWN mode (corrupt on-disk) raises a HIGH attention item, never throws.
|
|
9235
|
-
const { CredentialLocationLedger, shouldBootSeedCredentialLedger } = await import('../core/CredentialLocationLedger.js');
|
|
9249
|
+
const { CredentialLocationLedger, shouldBootSeedCredentialLedger, shouldRunIdentityAudit } = await import('../core/CredentialLocationLedger.js');
|
|
9236
9250
|
const { CredentialIdentityOracle } = await import('../core/CredentialIdentityOracle.js');
|
|
9237
9251
|
const { CredentialLocationGate } = await import('../core/CredentialLocationGate.js');
|
|
9238
9252
|
const credentialGateEmitAttention = telegram
|
|
@@ -9432,14 +9446,22 @@ export async function startServer(options) {
|
|
|
9432
9446
|
// never blocked on them; failures are loud at the slot level (quarantine + attention) INSIDE
|
|
9433
9447
|
// seedFromOracle. Seeding writes ONLY the local slot→account map — it moves ZERO credentials
|
|
9434
9448
|
// (the executor's dryRun gate + the one-home invariant still guard every real swap). <!-- tracked: 20905 -->
|
|
9449
|
+
// `credSeedInFlight` closes the fresh-agent seed↔audit interleave: a never-seeded boot fires
|
|
9450
|
+
// seedFromOracle() fire-and-forget at t=0, and the boot identity audit fires at t≈90s. If the
|
|
9451
|
+
// oracle hangs past 90s the two passes could otherwise touch the in-memory assignments view at
|
|
9452
|
+
// their respective awaits. isSeeded() does NOT protect this (seedFromOracle bumps version at
|
|
9453
|
+
// 'begin', so isSeeded() flips true mid-seed), so the audit gate also checks this flag.
|
|
9454
|
+
let credSeedInFlight = false;
|
|
9435
9455
|
if (shouldBootSeedCredentialLedger(resolveDevAgentGate(config.subscriptionPool?.credentialRepointing?.enabled, config), credentialLocationLedger.isSeeded())) {
|
|
9456
|
+
credSeedInFlight = true;
|
|
9436
9457
|
void credentialLocationLedger
|
|
9437
9458
|
.seedFromOracle()
|
|
9438
9459
|
.then((outcomes) => {
|
|
9439
9460
|
const assigned = outcomes.filter((o) => o.result === 'assigned').length;
|
|
9440
9461
|
console.log(pc.green(` Credential location ledger seeded: ${assigned}/${outcomes.length} slot(s) mapped`));
|
|
9441
9462
|
})
|
|
9442
|
-
.catch((e) => console.warn(`[CredentialLedger] boot seed failed: ${e instanceof Error ? e.message : String(e)}`))
|
|
9463
|
+
.catch((e) => console.warn(`[CredentialLedger] boot seed failed: ${e instanceof Error ? e.message : String(e)}`))
|
|
9464
|
+
.finally(() => { credSeedInFlight = false; });
|
|
9443
9465
|
}
|
|
9444
9466
|
// B3b — the periodic balancer pass. tick() is a strict no-op while the feature resolves dark
|
|
9445
9467
|
// (so the timer can always run; the gate lives INSIDE tick()), and on a dev agent it runs the
|
|
@@ -9457,6 +9479,54 @@ export async function startServer(options) {
|
|
|
9457
9479
|
.finally(() => { credRebalancerTickInFlight = false; });
|
|
9458
9480
|
}, credRebalancerPassMs);
|
|
9459
9481
|
credRebalancerTimer.unref?.();
|
|
9482
|
+
// B3c — the periodic NON-DESTRUCTIVE identity audit. THE FIX for the inert-optimizer bug:
|
|
9483
|
+
// the rebalancer's every objective (wall-rescue AND the use-it-or-lose-it drain) only acts on
|
|
9484
|
+
// a DESTINATION slot whose identity was verified within `auditCadenceMs` (default 6h). Nothing
|
|
9485
|
+
// re-stamped verification after the boot seed (markVerified had zero callers), so every slot
|
|
9486
|
+
// decayed to "not recently verified" and the rebalancer went permanently inert — it decided
|
|
9487
|
+
// nothing because it had no eligible targets. auditIdentities() re-probes each slot and refreshes
|
|
9488
|
+
// its verification (and lets a since-resolvable slot EXIT quarantine), keeping the optimizer's
|
|
9489
|
+
// target set live. It moves ZERO credentials (ledger verification state only); never triggers a
|
|
9490
|
+
// swap; HOLDS a healthy slot on a transient oracle blip (never re-creates the stall). Same
|
|
9491
|
+
// dev-gate as the rebalancer (strict no-op / no probe on the dark fleet); reentrancy-guarded;
|
|
9492
|
+
// unref'd. Audit cadence = half of auditCadenceMs, capped at 30min, floored at 1min, so a
|
|
9493
|
+
// healthy slot is always re-confirmed well inside the verified-recent window. <!-- tracked: 20905 -->
|
|
9494
|
+
const credAuditCadenceMs = credResolveBalancerConfig({
|
|
9495
|
+
...(config.subscriptionPool?.credentialRepointing?.balancer ?? {}),
|
|
9496
|
+
slotCount: credentialLocationLedger.getAssignments().length,
|
|
9497
|
+
}).auditCadenceMs;
|
|
9498
|
+
const credAuditIntervalMs = Math.max(60_000, Math.min(Math.floor(credAuditCadenceMs / 2), 30 * 60_000));
|
|
9499
|
+
let credAuditInFlight = false;
|
|
9500
|
+
const runCredentialIdentityAudit = async (trigger) => {
|
|
9501
|
+
// Pure, unit-tested gate (shouldRunIdentityAudit): enabled (no-op/no-probe on the dark fleet)
|
|
9502
|
+
// AND seeded AND not UNKNOWN-mode AND not already in flight (reentrancy guard).
|
|
9503
|
+
// `credSeedInFlight` is the runtime seed↔audit interleave guard (a boot seed can be mid-probe
|
|
9504
|
+
// when the boot audit fires); the pure predicate covers the persistent-state gates.
|
|
9505
|
+
if (credSeedInFlight ||
|
|
9506
|
+
!shouldRunIdentityAudit(resolveDevAgentGate(config.subscriptionPool?.credentialRepointing?.enabled, config), credentialLocationLedger.isSeeded(), credentialLocationLedger.isUnknownMode(), credAuditInFlight)) {
|
|
9507
|
+
return;
|
|
9508
|
+
}
|
|
9509
|
+
credAuditInFlight = true;
|
|
9510
|
+
try {
|
|
9511
|
+
const r = await credentialLocationLedger.auditIdentities();
|
|
9512
|
+
if (r.refreshed || r.recovered || r.quarantined) {
|
|
9513
|
+
console.log(pc.dim(` Credential identity audit (${trigger}): ${r.refreshed} refreshed, ${r.recovered} recovered, ${r.quarantined} quarantined, ${r.unresolved} unresolved`));
|
|
9514
|
+
}
|
|
9515
|
+
}
|
|
9516
|
+
catch (e) {
|
|
9517
|
+
console.warn(`[CredentialIdentityAudit] ${trigger} error: ${e instanceof Error ? e.message : String(e)}`);
|
|
9518
|
+
}
|
|
9519
|
+
finally {
|
|
9520
|
+
credAuditInFlight = false;
|
|
9521
|
+
}
|
|
9522
|
+
};
|
|
9523
|
+
// Boot one-shot (delayed so it never races the boot seed) — refreshes stale verification
|
|
9524
|
+
// immediately on restart so a long-running agent's rebalancer has fresh targets without
|
|
9525
|
+
// waiting a full cadence.
|
|
9526
|
+
const credAuditBootTimer = setTimeout(() => void runCredentialIdentityAudit('boot'), 90_000);
|
|
9527
|
+
credAuditBootTimer.unref?.();
|
|
9528
|
+
const credAuditTimer = setInterval(() => void runCredentialIdentityAudit('periodic'), credAuditIntervalMs);
|
|
9529
|
+
credAuditTimer.unref?.();
|
|
9460
9530
|
// QuotaPoller — per-account live quota reader (P1.2 of the Subscription &
|
|
9461
9531
|
// Auth Standard). Reads each account's 5h/weekly utilization + reset dates
|
|
9462
9532
|
// via the OAuth usage endpoint (transient per-account token, never persisted)
|
|
@@ -11746,6 +11816,17 @@ export async function startServer(options) {
|
|
|
11746
11816
|
relayUrl: config.threadline?.relayUrl,
|
|
11747
11817
|
visibility: config.threadline?.visibility,
|
|
11748
11818
|
capabilities: config.threadline?.capabilities,
|
|
11819
|
+
// Secure A2A Verified Pairing (spec §3.10). Live reader so credentialShareEnforced
|
|
11820
|
+
// takes effect without a restart. `enabled` rides the developmentAgent gate when
|
|
11821
|
+
// omitted (dev-live, dark-fleet); when off the inbound gate is a pass-through.
|
|
11822
|
+
getVerifiedPairingConfig: () => {
|
|
11823
|
+
const vp = config.threadline?.verifiedPairing;
|
|
11824
|
+
return {
|
|
11825
|
+
enabled: resolveDevAgentGate(vp?.enabled, config),
|
|
11826
|
+
dryRun: vp?.dryRun ?? true,
|
|
11827
|
+
credentialShareEnforced: vp?.credentialShareEnforced ?? false,
|
|
11828
|
+
};
|
|
11829
|
+
},
|
|
11749
11830
|
});
|
|
11750
11831
|
threadlineHandshake = threadline.handshakeManager;
|
|
11751
11832
|
threadlineShutdown = threadline.shutdown;
|
|
@@ -11763,6 +11844,31 @@ export async function startServer(options) {
|
|
|
11763
11844
|
console.error(`Unified trust system init failed (non-fatal): ${err instanceof Error ? err.message : err}`);
|
|
11764
11845
|
}
|
|
11765
11846
|
}
|
|
11847
|
+
// Secure A2A Verified Pairing §3.8 (FD11) — SEND-SIDE: attach the journal-backed
|
|
11848
|
+
// emitter to the trust manager's pairing-replication hooks so a local markMutualVerified
|
|
11849
|
+
// ALSO replicates the verified-IDENTITY RESULT to the agent's OWN machines, and a
|
|
11850
|
+
// verification-failed propagates a tombstone. The emitter is handed ONLY the 5-field
|
|
11851
|
+
// result (it has NO access to the SAS store), so the SAS / shared secret / relay token
|
|
11852
|
+
// can never cross. Gated on the EXPLICIT `multiMachine.stateSync.threadlinePairing.enabled`
|
|
11853
|
+
// (default false ⇒ NOT attached ⇒ strict no-op, single-machine behavior). Attached only
|
|
11854
|
+
// when the journal-backed emitter exists (journal live) AND the store is enabled.
|
|
11855
|
+
if (threadline.trustManager && replicatedRecordEmitter && cjOwnMachineId) {
|
|
11856
|
+
const pairingStoreEnabled = config.multiMachine?.stateSync
|
|
11857
|
+
?.threadlinePairing?.enabled === true;
|
|
11858
|
+
if (pairingStoreEnabled) {
|
|
11859
|
+
const emitter = replicatedRecordEmitter;
|
|
11860
|
+
const { THREADLINE_PAIRING_STORE_KEY, deriveThreadlinePairingRecordKey, buildThreadlinePairingRecordData, buildThreadlinePairingTombstoneData, } = await import('../core/ThreadlinePairingReplicatedStore.js');
|
|
11861
|
+
threadline.trustManager.setPairingReplicationEmitter({
|
|
11862
|
+
emitVerified: (result) => emitter.emit(THREADLINE_PAIRING_STORE_KEY, deriveThreadlinePairingRecordKey(result.peerFp), (hlc, origin, observed) => buildThreadlinePairingRecordData({
|
|
11863
|
+
result: { ...result, state: 'mutual-verified' },
|
|
11864
|
+
hlc,
|
|
11865
|
+
origin,
|
|
11866
|
+
observed,
|
|
11867
|
+
})),
|
|
11868
|
+
emitRevoke: (peerFp, deletedAt) => emitter.emit(THREADLINE_PAIRING_STORE_KEY, deriveThreadlinePairingRecordKey(peerFp), (hlc, origin, observed) => buildThreadlinePairingTombstoneData({ peerFp, hlc, origin, deletedAt, observed })),
|
|
11869
|
+
}, cjOwnMachineId);
|
|
11870
|
+
}
|
|
11871
|
+
}
|
|
11766
11872
|
if (threadlineRelayClient) {
|
|
11767
11873
|
// Wire relay message delivery through ThreadlineRouter (Phase 1).
|
|
11768
11874
|
// Replaces the ad-hoc handler with proper thread persistence, auto-ack,
|