@origintrail-official/dkg-agent 10.0.21 → 10.0.23
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/approved-private-replica-proof-runs.d.ts +40 -0
- package/dist/approved-private-replica-proof-runs.d.ts.map +1 -0
- package/dist/approved-private-replica-proof-runs.js +49 -0
- package/dist/approved-private-replica-proof-runs.js.map +1 -0
- package/dist/approved-private-replica.d.ts +18 -1
- package/dist/approved-private-replica.d.ts.map +1 -1
- package/dist/approved-private-replica.js +9 -3
- package/dist/approved-private-replica.js.map +1 -1
- package/dist/context-graph-chain-discovery-binding.d.ts +2 -0
- package/dist/context-graph-chain-discovery-binding.d.ts.map +1 -1
- package/dist/context-graph-chain-discovery-binding.js +7 -0
- package/dist/context-graph-chain-discovery-binding.js.map +1 -1
- package/dist/context-graph-dormant-identity.d.ts +8 -0
- package/dist/context-graph-dormant-identity.d.ts.map +1 -0
- package/dist/context-graph-dormant-identity.js +48 -0
- package/dist/context-graph-dormant-identity.js.map +1 -0
- package/dist/context-graph-meta-projection.d.ts +19 -55
- package/dist/context-graph-meta-projection.d.ts.map +1 -1
- package/dist/context-graph-meta-projection.js +94 -46
- package/dist/context-graph-meta-projection.js.map +1 -1
- package/dist/context-graph-name-binding-target.d.ts +21 -0
- package/dist/context-graph-name-binding-target.d.ts.map +1 -0
- package/dist/context-graph-name-binding-target.js +68 -0
- package/dist/context-graph-name-binding-target.js.map +1 -0
- package/dist/context-graph-persisted-name-aliases.d.ts +47 -0
- package/dist/context-graph-persisted-name-aliases.d.ts.map +1 -0
- package/dist/context-graph-persisted-name-aliases.js +173 -0
- package/dist/context-graph-persisted-name-aliases.js.map +1 -0
- package/dist/context-graph-read-authority.d.ts +26 -11
- package/dist/context-graph-read-authority.d.ts.map +1 -1
- package/dist/context-graph-read-authority.js +26 -2
- package/dist/context-graph-read-authority.js.map +1 -1
- package/dist/context-graph-subscription-authority-recovery.d.ts +4 -0
- package/dist/context-graph-subscription-authority-recovery.d.ts.map +1 -1
- package/dist/context-graph-subscription-authority-recovery.js +8 -2
- package/dist/context-graph-subscription-authority-recovery.js.map +1 -1
- package/dist/context-graph-subscription-policy.d.ts +34 -1
- package/dist/context-graph-subscription-policy.d.ts.map +1 -1
- package/dist/context-graph-subscription-policy.js +143 -1
- package/dist/context-graph-subscription-policy.js.map +1 -1
- package/dist/curator-meta-refresh.d.ts.map +1 -1
- package/dist/curator-meta-refresh.js +31 -9
- package/dist/curator-meta-refresh.js.map +1 -1
- package/dist/dkg-agent-base.d.ts.map +1 -1
- package/dist/dkg-agent-base.js +0 -1
- package/dist/dkg-agent-base.js.map +1 -1
- package/dist/dkg-agent-cg-name-resolution.d.ts +6 -24
- package/dist/dkg-agent-cg-name-resolution.d.ts.map +1 -1
- package/dist/dkg-agent-cg-name-resolution.js +42 -58
- package/dist/dkg-agent-cg-name-resolution.js.map +1 -1
- package/dist/dkg-agent-cg-on-chain-id.d.ts +3 -3
- package/dist/dkg-agent-cg-on-chain-id.d.ts.map +1 -1
- package/dist/dkg-agent-cg-on-chain-id.js +7 -23
- package/dist/dkg-agent-cg-on-chain-id.js.map +1 -1
- package/dist/dkg-agent-cg-registry.d.ts +7 -3
- package/dist/dkg-agent-cg-registry.d.ts.map +1 -1
- package/dist/dkg-agent-cg-registry.js +30 -16
- package/dist/dkg-agent-cg-registry.js.map +1 -1
- package/dist/dkg-agent-cg-resolve.d.ts +10 -6
- package/dist/dkg-agent-cg-resolve.d.ts.map +1 -1
- package/dist/dkg-agent-cg-resolve.js +16 -19
- package/dist/dkg-agent-cg-resolve.js.map +1 -1
- package/dist/dkg-agent-context-graph.d.ts.map +1 -1
- package/dist/dkg-agent-context-graph.js +0 -4
- package/dist/dkg-agent-context-graph.js.map +1 -1
- package/dist/dkg-agent-crypto.d.ts.map +1 -1
- package/dist/dkg-agent-crypto.js +53 -57
- package/dist/dkg-agent-crypto.js.map +1 -1
- package/dist/dkg-agent-lifecycle.d.ts +5 -0
- package/dist/dkg-agent-lifecycle.d.ts.map +1 -1
- package/dist/dkg-agent-lifecycle.js +156 -133
- package/dist/dkg-agent-lifecycle.js.map +1 -1
- package/dist/dkg-agent-publish.d.ts.map +1 -1
- package/dist/dkg-agent-publish.js +2 -3
- package/dist/dkg-agent-publish.js.map +1 -1
- package/dist/dkg-agent-query.d.ts.map +1 -1
- package/dist/dkg-agent-query.js +12 -9
- package/dist/dkg-agent-query.js.map +1 -1
- package/dist/dkg-agent-registered-private-empty-vm.d.ts +8 -0
- package/dist/dkg-agent-registered-private-empty-vm.d.ts.map +1 -1
- package/dist/dkg-agent-registered-private-empty-vm.js +15 -0
- package/dist/dkg-agent-registered-private-empty-vm.js.map +1 -1
- package/dist/dkg-agent-rfc64-catalog-auto-publish.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-catalog-auto-publish.js +4 -0
- package/dist/dkg-agent-rfc64-catalog-auto-publish.js.map +1 -1
- package/dist/dkg-agent-rfc64-catalog-upsert.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-catalog-upsert.js +7 -0
- package/dist/dkg-agent-rfc64-catalog-upsert.js.map +1 -1
- package/dist/dkg-agent-rfc64-catalog.d.ts +4 -0
- package/dist/dkg-agent-rfc64-catalog.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-catalog.js +12 -2
- package/dist/dkg-agent-rfc64-catalog.js.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.d.ts +2 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.js +23 -15
- package/dist/dkg-agent-rfc64-swm-catalog-projection-supervisor.js.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection.d.ts.map +1 -1
- package/dist/dkg-agent-rfc64-swm-catalog-projection.js +3 -0
- package/dist/dkg-agent-rfc64-swm-catalog-projection.js.map +1 -1
- package/dist/dkg-agent-swm-host.d.ts +13 -22
- package/dist/dkg-agent-swm-host.d.ts.map +1 -1
- package/dist/dkg-agent-swm-host.js +179 -81
- package/dist/dkg-agent-swm-host.js.map +1 -1
- package/dist/dkg-agent-swm-substrate.d.ts +2 -0
- package/dist/dkg-agent-swm-substrate.d.ts.map +1 -1
- package/dist/dkg-agent-swm-substrate.js +5 -9
- package/dist/dkg-agent-swm-substrate.js.map +1 -1
- package/dist/dkg-agent-types.d.ts +3 -2
- package/dist/dkg-agent-types.d.ts.map +1 -1
- package/dist/dkg-agent.d.ts +4 -10
- package/dist/dkg-agent.d.ts.map +1 -1
- package/dist/dkg-agent.js +43 -58
- package/dist/dkg-agent.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts +6 -1
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.d.ts.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js +5 -5
- package/dist/internal/context-graph-authority/context-graph-agent-gate-authority.js.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-authority.d.ts +14 -1
- package/dist/internal/context-graph-authority/context-graph-authority.d.ts.map +1 -1
- package/dist/internal/context-graph-authority/context-graph-authority.js +19 -0
- package/dist/internal/context-graph-authority/context-graph-authority.js.map +1 -1
- package/dist/internal/context-graph-cache-invalidating-store.d.ts +10 -2
- package/dist/internal/context-graph-cache-invalidating-store.d.ts.map +1 -1
- package/dist/internal/context-graph-cache-invalidating-store.js +67 -67
- package/dist/internal/context-graph-cache-invalidating-store.js.map +1 -1
- package/dist/internal/context-graph-meta-record-copy.d.ts +1 -1
- package/dist/internal/context-graph-meta-record-copy.d.ts.map +1 -1
- package/dist/internal/context-graph-meta-record.d.ts +40 -0
- package/dist/internal/context-graph-meta-record.d.ts.map +1 -0
- package/dist/internal/context-graph-meta-record.js +3 -0
- package/dist/internal/context-graph-meta-record.js.map +1 -0
- package/dist/internal/peer-gate-revision.d.ts +28 -0
- package/dist/internal/peer-gate-revision.d.ts.map +1 -0
- package/dist/internal/peer-gate-revision.js +46 -0
- package/dist/internal/peer-gate-revision.js.map +1 -0
- package/dist/internal/projection-mutation-observer.d.ts +5 -0
- package/dist/internal/projection-mutation-observer.d.ts.map +1 -0
- package/dist/internal/projection-mutation-observer.js +24 -0
- package/dist/internal/projection-mutation-observer.js.map +1 -0
- package/dist/internal/promote/assertion-promote-precommit.d.ts +8 -6
- package/dist/internal/promote/assertion-promote-precommit.d.ts.map +1 -1
- package/dist/internal/promote/assertion-promote-precommit.js +8 -6
- package/dist/internal/promote/assertion-promote-precommit.js.map +1 -1
- package/dist/internal/recipient-key-route-fence.d.ts +57 -0
- package/dist/internal/recipient-key-route-fence.d.ts.map +1 -0
- package/dist/internal/recipient-key-route-fence.js +169 -0
- package/dist/internal/recipient-key-route-fence.js.map +1 -0
- package/dist/internal/store-mutation.d.ts +28 -0
- package/dist/internal/store-mutation.d.ts.map +1 -0
- package/dist/internal/store-mutation.js +3 -0
- package/dist/internal/store-mutation.js.map +1 -0
- package/dist/main-thread-time-slice.d.ts +19 -0
- package/dist/main-thread-time-slice.d.ts.map +1 -0
- package/dist/main-thread-time-slice.js +32 -0
- package/dist/main-thread-time-slice.js.map +1 -0
- package/dist/p2p/storage-ack-registrar.d.ts.map +1 -1
- package/dist/p2p/storage-ack-registrar.js +3 -5
- package/dist/p2p/storage-ack-registrar.js.map +1 -1
- package/dist/registered-context-graph-authority.d.ts +17 -0
- package/dist/registered-context-graph-authority.d.ts.map +1 -1
- package/dist/registered-private-empty-vm-attempt-v1.d.ts.map +1 -1
- package/dist/registered-private-empty-vm-attempt-v1.js +8 -4
- package/dist/registered-private-empty-vm-attempt-v1.js.map +1 -1
- package/dist/rfc64/catalog-repair-retry-v1.d.ts +9 -3
- package/dist/rfc64/catalog-repair-retry-v1.d.ts.map +1 -1
- package/dist/rfc64/catalog-repair-retry-v1.js +22 -6
- package/dist/rfc64/catalog-repair-retry-v1.js.map +1 -1
- package/dist/rfc64/control-envelope-signer-v1.d.ts +8 -0
- package/dist/rfc64/control-envelope-signer-v1.d.ts.map +1 -1
- package/dist/rfc64/control-envelope-signer-v1.js +20 -0
- package/dist/rfc64/control-envelope-signer-v1.js.map +1 -1
- package/dist/rfc64/legacy-swm-boundary-fence-v1.d.ts +109 -0
- package/dist/rfc64/legacy-swm-boundary-fence-v1.d.ts.map +1 -0
- package/dist/rfc64/legacy-swm-boundary-fence-v1.js +236 -0
- package/dist/rfc64/legacy-swm-boundary-fence-v1.js.map +1 -0
- package/dist/rfc64/legacy-swm-boundary-v1.d.ts +28 -1
- package/dist/rfc64/legacy-swm-boundary-v1.d.ts.map +1 -1
- package/dist/rfc64/legacy-swm-boundary-v1.js +74 -145
- package/dist/rfc64/legacy-swm-boundary-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-successor-producer-v1.d.ts +2 -0
- package/dist/rfc64/public-catalog-successor-producer-v1.d.ts.map +1 -1
- package/dist/rfc64/public-catalog-successor-producer-v1.js +77 -33
- package/dist/rfc64/public-catalog-successor-producer-v1.js.map +1 -1
- package/dist/rfc64/public-catalog-successor-row-binding-v1.d.ts +16 -0
- package/dist/rfc64/public-catalog-successor-row-binding-v1.d.ts.map +1 -0
- package/dist/rfc64/public-catalog-successor-row-binding-v1.js +28 -0
- package/dist/rfc64/public-catalog-successor-row-binding-v1.js.map +1 -0
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.d.ts +6 -0
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.d.ts.map +1 -1
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.js +9 -3
- package/dist/rfc64/swm-inventory-catalog-reconciler-v1.js.map +1 -1
- package/dist/rfc64/swm-inventory-settlement-outlook-v1.d.ts +8 -0
- package/dist/rfc64/swm-inventory-settlement-outlook-v1.d.ts.map +1 -0
- package/dist/rfc64/swm-inventory-settlement-outlook-v1.js +32 -0
- package/dist/rfc64/swm-inventory-settlement-outlook-v1.js.map +1 -0
- package/dist/sync/requester/swm-recovery-apply.d.ts +1 -1
- package/dist/sync/requester/swm-recovery-apply.d.ts.map +1 -1
- package/dist/sync/requester/swm-recovery-apply.js +0 -1
- package/dist/sync/requester/swm-recovery-apply.js.map +1 -1
- package/dist/sync/requester/swm-target-executor.d.ts +2 -2
- package/dist/sync/requester/swm-target-executor.d.ts.map +1 -1
- package/dist/sync/requester/swm-target-executor.js +1 -2
- package/dist/sync/requester/swm-target-executor.js.map +1 -1
- package/package.json +11 -8
|
@@ -188,11 +188,12 @@ import { chainAuthorityReadBudgetsOf } from './chain-authority-read-budgets.js';
|
|
|
188
188
|
import { peekFinalizedAuthorityColdResolution } from './finalized-authority-cold-resolution.js';
|
|
189
189
|
import { AGENTS_PHONEBOOK_PRIME_MAX_DIALS, peekOnDemandAgentsPhonebook, } from './sync/on-demand-agents-phonebook.js';
|
|
190
190
|
import { raceWithBootTimeout, isTransientBootChainError } from './dkg-agent-boot.js';
|
|
191
|
-
import { normalizeContextGraphSubscriptionTransition, projectContextGraphSubscriptionPersistence, } from './context-graph-subscription-policy.js';
|
|
191
|
+
import { mayAdoptContextGraphWireSubscription, normalizeContextGraphSubscriptionTransition, projectContextGraphSubscriptionPersistence, projectContextGraphSubscriptionPersistenceWithSavedHosting, readPreservedContextGraphCoreHosting, isContextGraphSubscriptionPersistenceTargetCurrent, projectContextGraphJoinSubscriptionRecord, contextGraphSubscriptionClearTargets, retainsInactiveContextGraphBinding, } from './context-graph-subscription-policy.js';
|
|
192
192
|
import { partitionSupersededContextGraphNamePlaceholders } from './dkg-agent-cg-name-resolution.js';
|
|
193
193
|
import { authoritativeSyncPeerId, resolveBoundedCuratorSyncPeer, resolveCuratorSyncPeer, } from './dkg-agent-cg-resolve.js';
|
|
194
194
|
import { runCuratorMetaRefreshFromPeer } from './curator-meta-refresh.js';
|
|
195
195
|
import { isCanonicalAuthoritativeContextGraphId } from './context-graph-binding-state.js';
|
|
196
|
+
import { projectDormantContextGraphIdentities } from './context-graph-dormant-identity.js';
|
|
196
197
|
import { normalizeAgentDid, inferAdapterPublisherAddress, } from './dkg-agent-helpers.js';
|
|
197
198
|
import { DKGAgentBase } from './dkg-agent-base.js';
|
|
198
199
|
import { VmReconcileShutdownTimeoutError } from './vm-reconcile-service.js';
|
|
@@ -208,7 +209,7 @@ import { isRfc64PrivateRecoveryOwnerV1, resolveRfc64PrivateRecoveryContextGraphI
|
|
|
208
209
|
import { CONTEXT_GRAPH_AUTHORITY_RPC_SITES as CG_AUTH_RPC_SITES, withRpcUsageSite, } from '@origintrail-official/dkg-chain';
|
|
209
210
|
import { rfc64ExecutionPlanAllowsLegacySyncV1, resolveRfc64RuntimeCatalogBootstrapConfigV1, } from './rfc64/public-catalog-activation-config-v1.js';
|
|
210
211
|
import { reconcileRfc64CatalogAuthorityPlanV1 } from './rfc64/catalog-rollout-authority-reconciliation-v1.js';
|
|
211
|
-
import { initializeRfc64LegacySwmBoundaryV1,
|
|
212
|
+
import { describeRfc64LegacySwmFenceEventV1, initializeRfc64LegacySwmBoundaryV1, rfc64LateLegacySwmCompanionResolverV1, retireRfc64LegacySwmAfterFinalizedVmV1, } from './rfc64/legacy-swm-boundary-v1.js';
|
|
212
213
|
import { projectPersistedJoinApprovals, } from './join-approval-restart-projection.js';
|
|
213
214
|
import { verifiedCuratorDialAddress } from './curator-dial-address.js';
|
|
214
215
|
const DEFAULT_HOST_MODE_RECONCILE_JITTER_RATIO = 0.15;
|
|
@@ -1045,7 +1046,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1045
1046
|
try {
|
|
1046
1047
|
if (this.config.dataDir !== undefined
|
|
1047
1048
|
&& this.rfc64PersistenceV1 !== undefined) {
|
|
1048
|
-
await initializeRfc64LegacySwmBoundaryV1(this, this.rfc64PersistenceV1.rootPath, this.store);
|
|
1049
|
+
await initializeRfc64LegacySwmBoundaryV1(this, this.rfc64PersistenceV1.rootPath, this.store, { onFenceEvent: (event) => this.log.warn(ctx, describeRfc64LegacySwmFenceEventV1(event)) });
|
|
1049
1050
|
await reconcileRfc64CatalogAuthorityPlanV1(this.rfc64PersistenceV1, this.store, this.config.rfc64CatalogExecutionPlan);
|
|
1050
1051
|
}
|
|
1051
1052
|
await this.prepareFinalizationRecoveryStore();
|
|
@@ -1348,6 +1349,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1348
1349
|
await this.loadSwmSenderKeyState();
|
|
1349
1350
|
await this.initializeSwmHostModeStore();
|
|
1350
1351
|
await this.rehydrateContextGraphsFromDurableState();
|
|
1352
|
+
await this.restoreSwmHostModeSubscriptions();
|
|
1351
1353
|
this.networkAdmissionCoordinator.registerIdentityProtocol(this.router);
|
|
1352
1354
|
// Register protocol handlers. PROTOCOL_ACCESS migrated onto the
|
|
1353
1355
|
// Universal Messenger substrate in rc.9 PR-8 — handler is
|
|
@@ -1628,7 +1630,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
1628
1630
|
recordStorageAckDecline: (code) => this.recordStorageAckDecline(code),
|
|
1629
1631
|
gossipWireIdFor: (id) => this.gossipWireIdFor(id),
|
|
1630
1632
|
getSwmSubscriptionSource: (...ids) => this.getSwmSubscriptionSource(...ids),
|
|
1631
|
-
prepareDurableRootAtomicCompanion: (
|
|
1633
|
+
prepareDurableRootAtomicCompanion: rfc64LateLegacySwmCompanionResolverV1(this),
|
|
1632
1634
|
chain: this.chain,
|
|
1633
1635
|
config: this.config,
|
|
1634
1636
|
log: this.log,
|
|
@@ -2132,6 +2134,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2132
2134
|
// once the allowlist is locally visible — clean self-heal,
|
|
2133
2135
|
// no spurious denial. Other gossip topics (publish/app/
|
|
2134
2136
|
// update/finalization) wire up immediately as before.
|
|
2137
|
+
const wirePredecessor = this.resolveWireOnlyContextGraphSubscription(contextGraphId);
|
|
2135
2138
|
this.subscribeToContextGraph(contextGraphId, {
|
|
2136
2139
|
deferSharedMemoryGossipSubscribe: true,
|
|
2137
2140
|
syncMode: 'always-on',
|
|
@@ -2158,6 +2161,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
2158
2161
|
// as a public CG locally, which is the exact corruption these
|
|
2159
2162
|
// guards exist to prevent. Lex review on PR #517 round 2 + Codex.
|
|
2160
2163
|
this.setContextGraphSubscription(contextGraphId, approvedSubscription, { persist: false });
|
|
2164
|
+
if (wirePredecessor && !this.subscribedContextGraphs.has(wirePredecessor.localId)) {
|
|
2165
|
+
void this.persistContextGraphSubscription(contextGraphId, { retiredNamePredecessor: { ...wirePredecessor.subscription, id: wirePredecessor.localId } });
|
|
2166
|
+
}
|
|
2161
2167
|
this.joinRequestAcceptedBy.delete(this.joinRequestTrackingKey(contextGraphId, approvedAddr, requestGeneration));
|
|
2162
2168
|
// Sync immediately by targeting the curator peer we just received
|
|
2163
2169
|
// this notification from, instead of relying on the periodic
|
|
@@ -4328,7 +4334,6 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
4328
4334
|
});
|
|
4329
4335
|
if (outcome === 'applied') {
|
|
4330
4336
|
this.invalidateListContextGraphsCache();
|
|
4331
|
-
this.contextGraphMetaProjection.markDirtyFromQuads(authentication.asset.metadataQuads);
|
|
4332
4337
|
try {
|
|
4333
4338
|
let retiredTwin;
|
|
4334
4339
|
const retirement = await reconcileFinalizedSwmTwin({
|
|
@@ -6346,17 +6351,13 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6346
6351
|
async refreshMetaSyncedFlags(contextGraphIds) {
|
|
6347
6352
|
for (const contextGraphId of contextGraphIds) {
|
|
6348
6353
|
const sub = this.subscribedContextGraphs.get(contextGraphId);
|
|
6349
|
-
if (!sub)
|
|
6354
|
+
if (!sub || (!sub.subscribed && sub.coreHosted !== true))
|
|
6350
6355
|
continue;
|
|
6351
6356
|
if (await this.hasConfirmedMetaState(contextGraphId)) {
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
//
|
|
6355
|
-
//
|
|
6356
|
-
// definition has passed `hasConfirmedMetaState`, bind and persist it as
|
|
6357
|
-
// part of the same readiness transition. This also makes a completed
|
|
6358
|
-
// catch-up restart-safe instead of leaving `on_chain_id = NULL` in the
|
|
6359
|
-
// durable subscription row.
|
|
6357
|
+
if (this.subscribedContextGraphs.get(contextGraphId) !== sub)
|
|
6358
|
+
continue;
|
|
6359
|
+
// Confirmed private metadata can fill an unbound late member's numeric id.
|
|
6360
|
+
// Persist this readiness binding so completed catch-up survives restart.
|
|
6360
6361
|
const contextGraphUri = contextGraphDataGraphUri(contextGraphId);
|
|
6361
6362
|
const metaGraph = contextGraphMetaGraphUri(contextGraphId);
|
|
6362
6363
|
const onChainIdPredicate = `${DKG_ONTOLOGY.DKG_CONTEXT_GRAPH}OnChainId`;
|
|
@@ -6372,6 +6373,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6372
6373
|
}
|
|
6373
6374
|
}
|
|
6374
6375
|
`, { source: 'agent.durableSync.registrationBinding' });
|
|
6376
|
+
if (this.subscribedContextGraphs.get(contextGraphId) !== sub)
|
|
6377
|
+
continue;
|
|
6375
6378
|
let confirmedOnChainId;
|
|
6376
6379
|
let confirmedOnChainHash;
|
|
6377
6380
|
let invalidOnChainId = false;
|
|
@@ -6398,6 +6401,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6398
6401
|
confirmedOnChainHash = undefined;
|
|
6399
6402
|
}
|
|
6400
6403
|
let current = this.subscribedContextGraphs.get(contextGraphId) ?? sub;
|
|
6404
|
+
if (confirmedOnChainId && isCanonicalAuthoritativeContextGraphId(current.onChainId) && current.onChainId !== confirmedOnChainId) {
|
|
6405
|
+
this.log.warn(createOperationContext('sync'), `Ignored conflicting confirmed-meta binding for ${contextGraphId}: retained ${current.onChainId}, observed ${confirmedOnChainId}`);
|
|
6406
|
+
continue;
|
|
6407
|
+
}
|
|
6401
6408
|
let registrationChanged = false;
|
|
6402
6409
|
let nextOnChainHash = current.onChainHash;
|
|
6403
6410
|
if (confirmedOnChainId && current.onChainId !== confirmedOnChainId) {
|
|
@@ -6416,6 +6423,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6416
6423
|
});
|
|
6417
6424
|
current = this.subscribedContextGraphs.get(contextGraphId) ?? current;
|
|
6418
6425
|
}
|
|
6426
|
+
const metadataWasPending = current.metaSynced !== true || current.pendingMeta === true;
|
|
6419
6427
|
if (current.metaSynced !== true) {
|
|
6420
6428
|
this.setContextGraphSubscription(contextGraphId, { ...current, metaSynced: true });
|
|
6421
6429
|
}
|
|
@@ -6425,12 +6433,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6425
6433
|
// (set by the join-approved handler) no longer applies — the
|
|
6426
6434
|
// CG will now surface via the normal `_meta` branch in
|
|
6427
6435
|
// `listContextGraphs`.
|
|
6428
|
-
this.setContextGraphSubscription(contextGraphId, {
|
|
6429
|
-
...current,
|
|
6430
|
-
metaSynced: true,
|
|
6431
|
-
pendingMeta: false,
|
|
6432
|
-
});
|
|
6436
|
+
this.setContextGraphSubscription(contextGraphId, { ...current, metaSynced: true, pendingMeta: false });
|
|
6433
6437
|
}
|
|
6438
|
+
if (metadataWasPending)
|
|
6439
|
+
this.announceJoinMetadataConfirmedV1(contextGraphId);
|
|
6434
6440
|
// Private responsibility depends on the live ACL projection, not only
|
|
6435
6441
|
// on subscription fields. A curator refresh can add/remove the local
|
|
6436
6442
|
// agent while `metaSynced`, `subscribed`, and the chain binding all stay
|
|
@@ -6454,7 +6460,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6454
6460
|
const explicitNextWireId = next.onChainHash === undefined
|
|
6455
6461
|
? undefined
|
|
6456
6462
|
: this.contextGraphWireId(next.onChainHash);
|
|
6457
|
-
const adoptsWireOnlySubscription = wireOnlySubscription !== null
|
|
6463
|
+
const adoptsWireOnlySubscription = options?.deferWireAdoption !== true && wireOnlySubscription !== null
|
|
6464
|
+
&& mayAdoptContextGraphWireSubscription(next, wireOnlySubscription.subscription)
|
|
6458
6465
|
&& (explicitNextWireId === undefined || explicitNextWireId === localWireId)
|
|
6459
6466
|
&& (next.onChainId === undefined
|
|
6460
6467
|
|| wireOnlySubscription.subscription.onChainId === undefined
|
|
@@ -6471,28 +6478,16 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6471
6478
|
// was first recorded under.
|
|
6472
6479
|
...(adoptsWireOnlySubscription
|
|
6473
6480
|
&& wireOnlySubscription.subscription.coreHosted === true
|
|
6474
|
-
&& next.coreHosted === undefined
|
|
6475
6481
|
? { coreHosted: true }
|
|
6476
6482
|
: {}),
|
|
6477
6483
|
});
|
|
6478
6484
|
if (adoptsWireOnlySubscription) {
|
|
6479
|
-
//
|
|
6480
|
-
//
|
|
6481
|
-
// local path supplies the matching cleartext id, that hash-only row is
|
|
6482
|
-
// an identity placeholder rather than a second graph. Retire it before
|
|
6483
|
-
// publishing the canonical row so its RFC-64 responsibility, binding
|
|
6484
|
-
// fence, and receiver lifecycle cannot remain active under the wire id.
|
|
6485
|
-
// Host-mode bookkeeping is already wire-keyed and therefore survives
|
|
6486
|
-
// this local-identity promotion without rewiring its ciphertext topic.
|
|
6485
|
+
// Retire the authenticated placeholder before publishing its canonical
|
|
6486
|
+
// row so no RFC-64 responsibility, binding or receiver stays wire-keyed.
|
|
6487
6487
|
this.deleteContextGraphSubscription(wireOnlySubscription.localId);
|
|
6488
6488
|
if (this.wireIdToLocalCgId.get(localWireId) === wireOnlySubscription.localId) {
|
|
6489
6489
|
this.wireIdToLocalCgId.delete(localWireId);
|
|
6490
6490
|
}
|
|
6491
|
-
// A placeholder can be durable (a `dkg subscribe <hash> --save` row, or
|
|
6492
|
-
// a Core's hosted row). Delete that record too, whatever this caller's
|
|
6493
|
-
// persist flag: otherwise the next rehydration resurrects the hash row
|
|
6494
|
-
// and re-points the reverse index away from the cleartext id.
|
|
6495
|
-
this.retirePersistedContextGraphNamePlaceholder(wireOnlySubscription.localId, wireOnlySubscription.subscription);
|
|
6496
6491
|
this.log.info(createOperationContext('system'), `Promoted wire-only Context Graph ${localWireId.slice(0, 18)}… to local identity "${contextGraphId}"`);
|
|
6497
6492
|
}
|
|
6498
6493
|
const previousWireId = previous?.onChainHash
|
|
@@ -6506,13 +6501,21 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6506
6501
|
...normalizedNext,
|
|
6507
6502
|
...(normalizedNext.onChainHash === nextOnChainHash ? {} : { onChainHash: nextOnChainHash }),
|
|
6508
6503
|
};
|
|
6504
|
+
const retainsInactiveBinding = retainsInactiveContextGraphBinding(previous, canonicalNext);
|
|
6509
6505
|
const bindingFacts = this.contextGraphBindingState.applySubscriptionTransition(contextGraphId, previous, canonicalNext, nextWireId);
|
|
6510
6506
|
if (previousWireId !== nextWireId
|
|
6511
6507
|
&& this.wireIdToLocalCgId.get(previousWireId) === contextGraphId) {
|
|
6512
6508
|
this.wireIdToLocalCgId.delete(previousWireId);
|
|
6513
6509
|
}
|
|
6514
6510
|
this.subscribedContextGraphs.set(contextGraphId, canonicalNext);
|
|
6515
|
-
this.wireIdToLocalCgId.
|
|
6511
|
+
const wireOwnerId = this.wireIdToLocalCgId.get(nextWireId);
|
|
6512
|
+
const wireOwner = wireOwnerId === undefined ? undefined : this.subscribedContextGraphs.get(wireOwnerId);
|
|
6513
|
+
const preserveWireOwner = options?.deferWireAdoption === true || ((options?.preserveAdmittedWireBinding === true || retainsInactiveBinding)
|
|
6514
|
+
&& wireOwnerId !== contextGraphId
|
|
6515
|
+
&& (wireOwner?.subscribed === true || wireOwner?.coreHosted === true)
|
|
6516
|
+
&& (retainsInactiveBinding || wireOwner.onChainId !== canonicalNext.onChainId));
|
|
6517
|
+
if (!preserveWireOwner)
|
|
6518
|
+
this.wireIdToLocalCgId.set(nextWireId, contextGraphId);
|
|
6516
6519
|
if ((canonicalNext.subscribed === true || canonicalNext.coreHosted === true)
|
|
6517
6520
|
&& previous?.subscribed !== true
|
|
6518
6521
|
&& previous?.coreHosted !== true) {
|
|
@@ -6573,20 +6576,20 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6573
6576
|
else if (!bindingFacts.admitted) {
|
|
6574
6577
|
this.clearVmReconcileStateForContextGraph(contextGraphId);
|
|
6575
6578
|
}
|
|
6576
|
-
// On-demand member subscriptions deliberately keep their live state and
|
|
6577
|
-
// readiness process-local. A Core's independent hosting obligation is
|
|
6578
|
-
// still durable, though: persistContextGraphSubscription writes a
|
|
6579
|
-
// host-only snapshot without converting the member intent to always-on.
|
|
6580
6579
|
const persistence = projectContextGraphSubscriptionPersistence({
|
|
6581
6580
|
contextGraphId,
|
|
6582
6581
|
subscription: canonicalNext,
|
|
6583
6582
|
syncScoped: (this.config.syncContextGraphs ?? []).includes(contextGraphId),
|
|
6583
|
+
preserveInactiveIntent: options?.persist !== true && retainsInactiveBinding
|
|
6584
|
+
&& previous?.subscribed !== true && previous?.coreHosted !== true,
|
|
6584
6585
|
});
|
|
6585
6586
|
if (options?.persist !== false && persistence.action !== 'skip') {
|
|
6586
6587
|
if (this.config.contextGraphSubscriptionStore) {
|
|
6587
6588
|
const revision = this.nextContextGraphSubscriptionPersistRevision(contextGraphId);
|
|
6588
6589
|
this.persistContextGraphSubscription(contextGraphId, {
|
|
6589
6590
|
revision,
|
|
6591
|
+
preserveDormantHosting: previous?.coreHosted !== true || canonicalNext.coreHosted === true,
|
|
6592
|
+
retiredNamePredecessor: adoptsWireOnlySubscription ? { ...wireOnlySubscription.subscription, id: wireOnlySubscription.localId } : undefined,
|
|
6590
6593
|
updateRehydrationStatus: options?.updateRehydrationStatus !== false,
|
|
6591
6594
|
});
|
|
6592
6595
|
}
|
|
@@ -6713,21 +6716,31 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6713
6716
|
const hostedActivatedIds = status.hostedActivatedIds ?? [];
|
|
6714
6717
|
const wasAccounted = this.contextGraphSubscriptionRehydrationAccountedIds.has(contextGraphId);
|
|
6715
6718
|
const isPersisted = next?.subscribed === true || next?.coreHosted === true;
|
|
6719
|
+
const live = this.subscribedContextGraphs.get(contextGraphId);
|
|
6720
|
+
const isActive = live?.subscribed === true || live?.coreHosted === true;
|
|
6716
6721
|
let persistedTotal = status.persistedTotal;
|
|
6717
6722
|
let activated = status.activated;
|
|
6718
6723
|
const dormancyById = this.contextGraphSubscriptionDormancyById;
|
|
6719
|
-
|
|
6724
|
+
if (!isPersisted || isActive)
|
|
6725
|
+
dormancyById.delete(contextGraphId);
|
|
6726
|
+
else
|
|
6727
|
+
dormancyById.set(contextGraphId, dormancyById.get(contextGraphId)
|
|
6728
|
+
?? (status.rehydrationEnabled ? 'authorityUnavailable' : 'rehydrationDisabled'));
|
|
6720
6729
|
let nextHostedActivatedIds = hostedActivatedIds.filter((id) => id !== contextGraphId);
|
|
6721
|
-
if (
|
|
6730
|
+
if (live?.coreHosted === true) {
|
|
6722
6731
|
nextHostedActivatedIds = sortIds([...nextHostedActivatedIds, contextGraphId]);
|
|
6723
6732
|
}
|
|
6724
6733
|
if (isPersisted) {
|
|
6725
|
-
if (wasDormant) {
|
|
6734
|
+
if (wasDormant && isActive) {
|
|
6726
6735
|
activated += 1;
|
|
6727
6736
|
}
|
|
6728
6737
|
else if (!wasAccounted) {
|
|
6729
6738
|
persistedTotal += 1;
|
|
6730
|
-
|
|
6739
|
+
if (isActive)
|
|
6740
|
+
activated += 1;
|
|
6741
|
+
}
|
|
6742
|
+
else if (!wasDormant && !isActive) {
|
|
6743
|
+
activated = Math.max(0, activated - 1);
|
|
6731
6744
|
}
|
|
6732
6745
|
this.contextGraphSubscriptionRehydrationAccountedIds.add(contextGraphId);
|
|
6733
6746
|
}
|
|
@@ -6933,6 +6946,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6933
6946
|
return this.persistContextGraphSubscription(contextGraphId, {
|
|
6934
6947
|
revision: this.nextContextGraphSubscriptionPersistRevision(contextGraphId),
|
|
6935
6948
|
updateRehydrationStatus: false,
|
|
6949
|
+
preserveInactiveIntent: true,
|
|
6936
6950
|
});
|
|
6937
6951
|
}
|
|
6938
6952
|
persistContextGraphSubscription(contextGraphId, options) {
|
|
@@ -6943,44 +6957,45 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
6943
6957
|
return Promise.resolve();
|
|
6944
6958
|
}
|
|
6945
6959
|
const sub = this.subscribedContextGraphs.get(contextGraphId);
|
|
6946
|
-
const
|
|
6947
|
-
|
|
6948
|
-
|
|
6960
|
+
const generation = this.contextGraphBindingState.capture(contextGraphId);
|
|
6961
|
+
const revision = options?.revision ?? this.contextGraphSubscriptionPersistRevisions.get(contextGraphId);
|
|
6962
|
+
const input = {
|
|
6963
|
+
contextGraphId, subscription: sub && { ...sub },
|
|
6949
6964
|
syncScoped: (this.config.syncContextGraphs ?? []).includes(contextGraphId),
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
// instead of going through setContextGraphSubscription. Preserve the
|
|
6954
|
-
// process-local lifetime at this lowest shared write boundary too.
|
|
6965
|
+
preserveInactiveIntent: options?.preserveInactiveIntent,
|
|
6966
|
+
};
|
|
6967
|
+
if (projectContextGraphSubscriptionPersistence(input).action === 'skip') {
|
|
6955
6968
|
this.clearContextGraphSubscriptionPersistRevisionStateIfIdle(contextGraphId);
|
|
6956
6969
|
return Promise.resolve();
|
|
6957
6970
|
}
|
|
6958
|
-
// Persist member subscriptions AND (Phase D) public CGs this Core hosts —
|
|
6959
|
-
// the host-only record MUST survive restart so a Core that was offline
|
|
6960
|
-
// during a publish remembers it hosts the CG and fills its gap. Drop the
|
|
6961
|
-
// row only when the node neither subscribes to nor hosts the CG.
|
|
6962
6971
|
this.beginContextGraphSubscriptionPersistRevision(contextGraphId, options?.revision);
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6972
|
+
let written = false;
|
|
6973
|
+
let persisted;
|
|
6974
|
+
return this.enqueueContextGraphSubscriptionPersistWrite(contextGraphId, async () => {
|
|
6975
|
+
const persistence = input.subscription?.coreHosted === true
|
|
6976
|
+
? projectContextGraphSubscriptionPersistence(input)
|
|
6977
|
+
: await projectContextGraphSubscriptionPersistenceWithSavedHosting(input, store, options?.preserveDormantHosting);
|
|
6978
|
+
const current = this.subscribedContextGraphs.get(contextGraphId);
|
|
6979
|
+
const retired = persistence.action === 'delete' && current === undefined;
|
|
6980
|
+
if (persistence.action === 'skip' || (!retired && (!this.contextGraphBindingState.isGenerationCurrent(contextGraphId, generation)
|
|
6981
|
+
|| !isContextGraphSubscriptionPersistenceTargetCurrent(sub, input, current, {
|
|
6982
|
+
revision,
|
|
6983
|
+
pendingRevisions: this.contextGraphSubscriptionPersistPendingRevisions.get(contextGraphId),
|
|
6984
|
+
syncScoped: (this.config.syncContextGraphs ?? []).includes(contextGraphId),
|
|
6985
|
+
}))))
|
|
6986
|
+
return;
|
|
6987
|
+
if (persistence.action === 'delete')
|
|
6988
|
+
await store.delete(contextGraphId);
|
|
6989
|
+
else {
|
|
6990
|
+
persisted = persistence.record;
|
|
6991
|
+
await store.save(persisted);
|
|
6992
|
+
}
|
|
6993
|
+
await this.retirePersistedContextGraphNamePredecessors(input, sub, generation, revision, persistence, options?.retiredNamePredecessor);
|
|
6994
|
+
written = true;
|
|
6995
|
+
}).then(() => {
|
|
6996
|
+
if (written && options?.updateRehydrationStatus === true
|
|
6997
|
+
&& this.claimContextGraphSubscriptionPersistRevision(contextGraphId, options.revision)) {
|
|
6998
|
+
this.updateContextGraphSubscriptionRehydrationStatusAfterPersist(contextGraphId, persisted);
|
|
6984
6999
|
}
|
|
6985
7000
|
}).catch((err) => {
|
|
6986
7001
|
this.log.warn(createOperationContext('system'), `Failed to persist context-graph subscription for "${contextGraphId}": ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -7042,6 +7057,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7042
7057
|
// Queue behind any fire-and-forget writes scheduled by subscribe/mark so
|
|
7043
7058
|
// this final authoritative snapshot is the last write before the ACK.
|
|
7044
7059
|
await this.enqueueContextGraphSubscriptionPersistWrite(input.contextGraphId, async () => {
|
|
7060
|
+
const hostedRecord = await readPreservedContextGraphCoreHosting(store, record);
|
|
7045
7061
|
const current = this.subscribedContextGraphs.get(input.contextGraphId);
|
|
7046
7062
|
if (!(input.isCurrent?.() ?? true)
|
|
7047
7063
|
|| current !== expectedLiveSub
|
|
@@ -7049,7 +7065,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7049
7065
|
|| !this.contextGraphBindingState.isGenerationCurrent(input.contextGraphId, expectedBindingGeneration)) {
|
|
7050
7066
|
throw asSyncFetchAbortError(new Error(`Context graph "${input.contextGraphId}" changed before its strict subscription snapshot (${input.operation}) was persisted`));
|
|
7051
7067
|
}
|
|
7052
|
-
await store.save(
|
|
7068
|
+
await store.save(hostedRecord);
|
|
7053
7069
|
});
|
|
7054
7070
|
}
|
|
7055
7071
|
/**
|
|
@@ -7116,22 +7132,19 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7116
7132
|
? await subscriptionStore.load(contextGraphId)
|
|
7117
7133
|
: (await subscriptionStore.loadAll()).find((row) => row.id === contextGraphId) ?? null;
|
|
7118
7134
|
}
|
|
7119
|
-
const subscriptionRecord =
|
|
7120
|
-
id: contextGraphId,
|
|
7121
|
-
name: subscription.name,
|
|
7122
|
-
subscribed: subscription.subscribed,
|
|
7123
|
-
synced: subscription.synced,
|
|
7124
|
-
sharedMemorySynced: subscription.sharedMemorySynced,
|
|
7125
|
-
metaSynced: subscription.metaSynced,
|
|
7126
|
-
onChainId: subscription.onChainId,
|
|
7127
|
-
onChainHash: subscription.onChainHash,
|
|
7128
|
-
lastReconciledOrdinal: subscription.lastReconciledOrdinal,
|
|
7129
|
-
coreHosted: subscription.coreHosted,
|
|
7130
|
-
syncScoped: true,
|
|
7131
|
-
};
|
|
7135
|
+
const subscriptionRecord = projectContextGraphJoinSubscriptionRecord(contextGraphId, subscription);
|
|
7132
7136
|
let membershipAttempted = false;
|
|
7133
7137
|
let subscriptionAttempted = false;
|
|
7134
7138
|
try {
|
|
7139
|
+
const expectedLiveSub = this.subscribedContextGraphs.get(contextGraphId);
|
|
7140
|
+
const generation = this.contextGraphBindingState.capture(contextGraphId);
|
|
7141
|
+
const hostedRecord = subscriptionStore
|
|
7142
|
+
? await readPreservedContextGraphCoreHosting(subscriptionStore, subscriptionRecord, previousSubscription)
|
|
7143
|
+
: subscriptionRecord;
|
|
7144
|
+
if (subscriptionStore && (this.subscribedContextGraphs.get(contextGraphId) !== expectedLiveSub
|
|
7145
|
+
|| !this.contextGraphBindingState.isGenerationCurrent(contextGraphId, generation))) {
|
|
7146
|
+
throw asSyncFetchAbortError(new Error(`Context graph "${contextGraphId}" changed before join persistence`));
|
|
7147
|
+
}
|
|
7135
7148
|
if (membershipStore) {
|
|
7136
7149
|
membershipAttempted = true;
|
|
7137
7150
|
await membershipStore.upsert({
|
|
@@ -7142,7 +7155,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7142
7155
|
}
|
|
7143
7156
|
if (subscriptionStore) {
|
|
7144
7157
|
subscriptionAttempted = true;
|
|
7145
|
-
await subscriptionStore.save(
|
|
7158
|
+
await subscriptionStore.save(hostedRecord);
|
|
7146
7159
|
}
|
|
7147
7160
|
}
|
|
7148
7161
|
catch (error) {
|
|
@@ -7310,20 +7323,27 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7310
7323
|
lastReconciledOrdinal: record.lastReconciledOrdinal,
|
|
7311
7324
|
coreHosted: record.coreHosted,
|
|
7312
7325
|
}, {
|
|
7313
|
-
persist: false,
|
|
7326
|
+
persist: false, deferWireAdoption: true,
|
|
7314
7327
|
updateRehydrationStatus: input.updateRehydrationStatus,
|
|
7315
7328
|
}),
|
|
7316
7329
|
current: (contextGraphId) => this.subscribedContextGraphs.get(contextGraphId),
|
|
7317
7330
|
remove: (contextGraphId) => this.deleteContextGraphSubscription(contextGraphId),
|
|
7331
|
+
restoreInactive: (id, previous) => void this.setContextGraphSubscription(id, previous, { persist: false, preserveAdmittedWireBinding: true }),
|
|
7318
7332
|
rollbackNetworkEffects: (contextGraphId) => this.unsubscribeFromContextGraph(contextGraphId, { persist: false, updateRehydrationStatus: false }),
|
|
7319
7333
|
trackSync: (contextGraphId) => this.trackSyncContextGraph(contextGraphId),
|
|
7320
7334
|
subscribe: (contextGraphId) => this.subscribeToContextGraph(contextGraphId, {
|
|
7321
7335
|
trackSyncScope: false,
|
|
7322
|
-
persist: false,
|
|
7336
|
+
persist: false, deferWireAdoption: true,
|
|
7323
7337
|
syncMode: 'always-on',
|
|
7324
7338
|
}),
|
|
7325
|
-
persistMembership: (
|
|
7326
|
-
|
|
7339
|
+
persistMembership: (id) => this.persistLocalNodeMembership(id, 'rehydrated-subscription'),
|
|
7340
|
+
commit: (id) => {
|
|
7341
|
+
const wire = this.resolveWireOnlyContextGraphSubscription(id);
|
|
7342
|
+
this.retireLiveContextGraphNamePlaceholderFor(id);
|
|
7343
|
+
const committed = this.setContextGraphSubscription(id, this.subscribedContextGraphs.get(id), { persist: false, preserveAdmittedWireBinding: true });
|
|
7344
|
+
if (wire && !this.subscribedContextGraphs.has(wire.localId))
|
|
7345
|
+
void this.persistContextGraphSubscription(id, { retiredNamePredecessor: { ...wire.subscription, id: wire.localId } });
|
|
7346
|
+
return committed;
|
|
7327
7347
|
},
|
|
7328
7348
|
}, options);
|
|
7329
7349
|
}
|
|
@@ -7473,7 +7493,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7473
7493
|
this.updateContextGraphSubscriptionRehydrationStatusAfterClear([], [contextGraphId]);
|
|
7474
7494
|
continue;
|
|
7475
7495
|
}
|
|
7476
|
-
|
|
7496
|
+
const currentSubscription = this.subscribedContextGraphs.get(contextGraphId);
|
|
7497
|
+
if (currentSubscription?.subscribed || currentSubscription?.coreHosted) {
|
|
7477
7498
|
this.contextGraphSubscriptionRehydrationPendingIds.delete(contextGraphId);
|
|
7478
7499
|
this.contextGraphSubscriptionDormancyById.delete(contextGraphId);
|
|
7479
7500
|
continue;
|
|
@@ -7527,7 +7548,8 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7527
7548
|
|| this.contextGraphSubscriptionDormancyById.get(contextGraphId) !== 'activationCap') {
|
|
7528
7549
|
continue;
|
|
7529
7550
|
}
|
|
7530
|
-
|
|
7551
|
+
const freshSubscription = this.subscribedContextGraphs.get(contextGraphId);
|
|
7552
|
+
if (freshSubscription?.subscribed || freshSubscription?.coreHosted) {
|
|
7531
7553
|
this.contextGraphSubscriptionRehydrationPendingIds.delete(contextGraphId);
|
|
7532
7554
|
this.contextGraphSubscriptionDormancyById.delete(contextGraphId);
|
|
7533
7555
|
continue;
|
|
@@ -7675,9 +7697,10 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7675
7697
|
this.recordPersistedContextGraphIdAliases(persistedRows);
|
|
7676
7698
|
this.rewriteContextGraphSyncScopeAliases();
|
|
7677
7699
|
let rows = persistedRows.filter((r) => !systemContextGraphs.has(r.id));
|
|
7700
|
+
const namePlaceholders = partitionSupersededContextGraphNamePlaceholders(rows);
|
|
7701
|
+
rows = namePlaceholders.active;
|
|
7678
7702
|
// The operator kill-switch below promises not to touch durable state.
|
|
7679
7703
|
if (this.config.contextGraphSubscriptionRehydrationEnabled) {
|
|
7680
|
-
const namePlaceholders = partitionSupersededContextGraphNamePlaceholders(rows);
|
|
7681
7704
|
for (const superseded of namePlaceholders.superseded) {
|
|
7682
7705
|
try {
|
|
7683
7706
|
await store.delete(superseded.id);
|
|
@@ -7687,7 +7710,6 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7687
7710
|
this.log.warn(ctx, `Failed to drop superseded name-hash subscription row ${superseded.id.slice(0, 18)}…: ${error instanceof Error ? error.message : String(error)}`);
|
|
7688
7711
|
}
|
|
7689
7712
|
}
|
|
7690
|
-
rows = namePlaceholders.active;
|
|
7691
7713
|
}
|
|
7692
7714
|
// Validate the cap before either branch below so diagnostics retain the
|
|
7693
7715
|
// operator's configured cap even when the independent rehydration gate
|
|
@@ -7703,12 +7725,19 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7703
7725
|
`(must be a non-negative integer); using default ${DEFAULT_MAX_REHYDRATED_SUBSCRIPTIONS}.`);
|
|
7704
7726
|
}
|
|
7705
7727
|
}
|
|
7706
|
-
//
|
|
7707
|
-
//
|
|
7708
|
-
//
|
|
7709
|
-
//
|
|
7710
|
-
//
|
|
7711
|
-
|
|
7728
|
+
// Restore exact saved identity before discovery, independently of every
|
|
7729
|
+
// activation gate (disabled, capped or authority-denied). Inactive rows
|
|
7730
|
+
// cannot admit gossip, sync or RFC-64 authority; installation owns no
|
|
7731
|
+
// subscription, membership or RDF writes. Unbound/invalid rows stay
|
|
7732
|
+
// absent, and the fresh authority gates below still own activation.
|
|
7733
|
+
for (const [id, identity] of projectDormantContextGraphIdentities(rows)) {
|
|
7734
|
+
const current = this.subscribedContextGraphs.get(id);
|
|
7735
|
+
if (current?.subscribed || current?.coreHosted)
|
|
7736
|
+
continue;
|
|
7737
|
+
this.setContextGraphSubscription(id, identity, {
|
|
7738
|
+
persist: false, preserveAdmittedWireBinding: true,
|
|
7739
|
+
});
|
|
7740
|
+
}
|
|
7712
7741
|
if (!this.config.contextGraphSubscriptionRehydrationEnabled) {
|
|
7713
7742
|
const dormancyById = this.contextGraphSubscriptionDormancyById;
|
|
7714
7743
|
dormancyById.clear();
|
|
@@ -7722,7 +7751,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7722
7751
|
this.contextGraphSubscriptionRehydrationStatus = {
|
|
7723
7752
|
rehydrationEnabled: false,
|
|
7724
7753
|
persistedTotal: rows.length,
|
|
7725
|
-
systemExcluded: persistedRows.length - rows.length,
|
|
7754
|
+
systemExcluded: persistedRows.length - rows.length - namePlaceholders.superseded.length,
|
|
7726
7755
|
hostedActivated: 0,
|
|
7727
7756
|
hostedActivatedIds: [],
|
|
7728
7757
|
activated: 0,
|
|
@@ -7762,10 +7791,9 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7762
7791
|
// the cap stay PERSISTED but dormant and are promoted when an earlier
|
|
7763
7792
|
// rehydrated subscription reaches a safe synced state. Prioritise
|
|
7764
7793
|
// core-hosted, then subscribed, so the first set is most relevant.
|
|
7765
|
-
//
|
|
7766
|
-
//
|
|
7767
|
-
//
|
|
7768
|
-
// DELETE endpoint.
|
|
7794
|
+
// Canonically bound dormant rows retain inactive identity only; no data
|
|
7795
|
+
// lane is active. Every dormant row remains eligible for rolling
|
|
7796
|
+
// activation or explicit pruning through the existing DELETE endpoint.
|
|
7769
7797
|
// coreHosted graphs MUST always be restored — their chain-driven
|
|
7770
7798
|
// reconcile / host-mode path depends on it — so EXEMPT them from the cap.
|
|
7771
7799
|
// The cap (a #997 anti-wedge measure) applies only to the non-hosted
|
|
@@ -7976,7 +8004,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
7976
8004
|
this.contextGraphSubscriptionRehydrationStatus = {
|
|
7977
8005
|
rehydrationEnabled: true,
|
|
7978
8006
|
persistedTotal: rows.length,
|
|
7979
|
-
systemExcluded: persistedRows.length - rows.length,
|
|
8007
|
+
systemExcluded: persistedRows.length - rows.length - namePlaceholders.superseded.length,
|
|
7980
8008
|
hostedActivated: activatedRows.filter((r) => r.coreHosted).length,
|
|
7981
8009
|
hostedActivatedIds: activatedRows.filter((r) => r.coreHosted).map((r) => r.id),
|
|
7982
8010
|
activated: activatedRows.length,
|
|
@@ -8040,29 +8068,13 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
8040
8068
|
// USER context-graph subscriptions, live and persisted alike. (The store's
|
|
8041
8069
|
// system-unaware bulk delete is deliberately NOT used here.)
|
|
8042
8070
|
const systemContextGraphs = new Set(Object.values(SYSTEM_CONTEXT_GRAPHS));
|
|
8043
|
-
//
|
|
8044
|
-
// the
|
|
8045
|
-
//
|
|
8046
|
-
|
|
8047
|
-
// rehydration cap already exempts — clearing/counting them here would report a
|
|
8048
|
-
// removal that didn't happen. The clear targets only the stale non-hosted
|
|
8049
|
-
// backlog, the actual #997 wedge.
|
|
8050
|
-
const isClearable = (id, coreHosted) => !systemContextGraphs.has(id) && coreHosted !== true;
|
|
8051
|
-
const activeUserIds = [...this.subscribedContextGraphs.entries()]
|
|
8052
|
-
.filter(([id, s]) => isClearable(id, s?.coreHosted))
|
|
8053
|
-
.map(([id]) => id);
|
|
8054
|
-
// The full persisted clearable backlog (active + dormant rows left behind by
|
|
8055
|
-
// the rehydration cap). Counted up front: `unsubscribeFromContextGraph`
|
|
8056
|
-
// deletes each active row as a side effect, so a post-teardown count would
|
|
8057
|
-
// miss them. Starts empty so a node with NO store reports 0 persisted rows
|
|
8058
|
-
// removed (the active teardown is logged separately) rather than a phantom
|
|
8059
|
-
// count of the in-memory subs.
|
|
8060
|
-
let persistedUserIds = [];
|
|
8071
|
+
// Snapshot saved hosting before teardown: dormant Core intent is not
|
|
8072
|
+
// reflected by the inactive runtime projection. Pending writes are checked
|
|
8073
|
+
// again inside their serial lane before a selective durable deletion.
|
|
8074
|
+
let persistedRows = [];
|
|
8061
8075
|
if (store) {
|
|
8062
8076
|
try {
|
|
8063
|
-
|
|
8064
|
-
.filter((r) => isClearable(r.id, r.coreHosted))
|
|
8065
|
-
.map((r) => r.id);
|
|
8077
|
+
persistedRows = await store.loadAll();
|
|
8066
8078
|
}
|
|
8067
8079
|
catch (err) {
|
|
8068
8080
|
// Can't enumerate the persisted backlog → the dormant (capped-out) rows
|
|
@@ -8075,6 +8087,7 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
8075
8087
|
`Resolve the store error and retry.`);
|
|
8076
8088
|
}
|
|
8077
8089
|
}
|
|
8090
|
+
const { activeUserIds, persistedUserIds } = contextGraphSubscriptionClearTargets(this.subscribedContextGraphs, persistedRows, systemContextGraphs);
|
|
8078
8091
|
const activeUserIdsWithPendingStoreWrite = store
|
|
8079
8092
|
? activeUserIds.filter((id) => this.contextGraphSubscriptionPersistence.hasLane(id))
|
|
8080
8093
|
: [];
|
|
@@ -8116,7 +8129,17 @@ export class LifecycleSyncMethods extends DKGAgentBase {
|
|
|
8116
8129
|
cleared = 0;
|
|
8117
8130
|
for (const id of storeDeleteIds) {
|
|
8118
8131
|
try {
|
|
8119
|
-
|
|
8132
|
+
let deleted = false;
|
|
8133
|
+
await this.enqueueContextGraphSubscriptionPersistWrite(id, async () => {
|
|
8134
|
+
const hosted = store.load ? (await store.load(id))?.coreHosted === true
|
|
8135
|
+
: (await store.loadAll()).some(row => row.id === id && row.coreHosted === true);
|
|
8136
|
+
if (hosted || this.subscribedContextGraphs.get(id)?.coreHosted === true)
|
|
8137
|
+
return;
|
|
8138
|
+
await store.delete(id);
|
|
8139
|
+
deleted = true;
|
|
8140
|
+
});
|
|
8141
|
+
if (!deleted)
|
|
8142
|
+
continue;
|
|
8120
8143
|
cleared++;
|
|
8121
8144
|
clearedIds.push(id);
|
|
8122
8145
|
}
|