@tearleads/client-sdk 0.1.57 → 0.1.59
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/Tearleads.d.ts +2 -2
- package/Tearleads.js +1 -1
- package/Tearleads.js.map +1 -1
- package/client/blobs.d.ts +1 -1
- package/client/blobs.js.map +1 -1
- package/client/deviceFirst.js.map +1 -1
- package/client/identity.js +1 -1
- package/client/identity.js.map +1 -1
- package/client/index.d.ts +1 -1
- package/client/index.js +1 -1
- package/client/index.js.map +1 -1
- package/client/organizations/organizationAccessRestoration.js.map +1 -1
- package/client/organizations/organizationDataUsage.js.map +1 -1
- package/client/organizations/organizationGroupNameHydration.js.map +1 -1
- package/client/organizations/organizationMetadataProfileSync.js +1 -1
- package/client/organizations/organizationMetadataProfileSync.js.map +1 -1
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/organizationWorkflowRuntime.js.map +1 -1
- package/client/rootContainerAdoption.js.map +1 -1
- package/client/securityIncidents.d.ts +1 -1
- package/client/securityIncidents.js.map +1 -1
- package/client/session/sessionLoginRefusal.js.map +1 -1
- package/client/session/sessionRootAuthority.js.map +1 -1
- package/client/session/sessionTypes.d.ts +1 -1
- package/client/session/sessionTypes.js.map +1 -1
- package/client/userIdentities.d.ts +1 -1
- package/client/userIdentities.js.map +1 -1
- package/client/workflowRuntime.d.ts +2 -2
- package/client/workflowRuntime.js.map +1 -1
- package/data/blobs/createBlobStore.d.ts +1 -1
- package/data/blobs/createBlobStore.js.map +1 -1
- package/data/blobs/encryptedBlobByteSource.js +1 -1
- package/data/blobs/encryptedBlobByteSource.js.map +1 -1
- package/data/blobs/encryptedBlobEnvelope.d.ts +1 -1
- package/data/blobs/encryptedBlobEnvelope.js +2 -2
- package/data/blobs/encryptedBlobEnvelope.js.map +1 -1
- package/data/blobs/encryptedBlobStore.d.ts +1 -1
- package/data/blobs/encryptedBlobStore.js +1 -1
- package/data/blobs/encryptedBlobStore.js.map +1 -1
- package/data/blobs/memoryBlobStore.d.ts +1 -1
- package/data/blobs/memoryBlobStore.js +1 -1
- package/data/blobs/memoryBlobStore.js.map +1 -1
- package/data/blobs/opfsBlobStore.d.ts +1 -1
- package/data/blobs/opfsBlobStore.js +1 -1
- package/data/blobs/opfsBlobStore.js.map +1 -1
- package/data/containers/containerMetadataDocument.js +1 -1
- package/data/containers/containerMetadataDocument.js.map +1 -1
- package/data/containers/shared/events.js +1 -1
- package/data/containers/shared/events.js.map +1 -1
- package/data/containers/shared/heldContainerHeads.js +1 -1
- package/data/containers/shared/heldContainerHeads.js.map +1 -1
- package/data/containers/shared/mutationAcknowledgement.js +1 -1
- package/data/containers/shared/mutationAcknowledgement.js.map +1 -1
- package/data/containers/shared/principalPolicies.js +1 -1
- package/data/containers/shared/principalPolicies.js.map +1 -1
- package/data/containers/shared/readers.js +2 -2
- package/data/containers/shared/readers.js.map +1 -1
- package/data/documents/attachmentContentIdentity.js +1 -1
- package/data/documents/attachmentContentIdentity.js.map +1 -1
- package/data/documents/blob/shared/blobEnvelopeStream.js.map +1 -1
- package/data/documents/blob/shared/blobSourceSnapshot.d.ts +1 -1
- package/data/documents/blob/shared/blobSourceSnapshot.js.map +1 -1
- package/data/documents/blob/shared/chunkedBlobCrypto.js.map +1 -1
- package/data/documents/blob/shared/encryptedUploadParts.js.map +1 -1
- package/data/documents/blob/shared/events.js +1 -1
- package/data/documents/blob/shared/events.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +2 -2
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/documents/shared/containerKekPathHistory.js +1 -1
- package/data/documents/shared/containerKekPathHistory.js.map +1 -1
- package/data/documents/shared/containerKekPathVerification.d.ts +1 -1
- package/data/documents/shared/containerKekPathVerification.js +1 -1
- package/data/documents/shared/events.js +1 -1
- package/data/documents/shared/events.js.map +1 -1
- package/data/documents/shared/manifestBundleReaders.js +2 -2
- package/data/documents/shared/manifestBundleReaders.js.map +1 -1
- package/data/documents/shared/projection.d.ts +1 -1
- package/data/documents/shared/projection.js +2 -2
- package/data/documents/shared/projection.js.map +1 -1
- package/data/documents/shared/projectionContentKeys.d.ts +1 -1
- package/data/documents/shared/readers.js +3 -3
- package/data/documents/shared/readers.js.map +1 -1
- package/data/documents/shared/stableDocumentId.js +1 -1
- package/data/documents/shared/stableDocumentId.js.map +1 -1
- package/data/documents/shared/types.d.ts +1 -1
- package/data/documents/shared/types.js +1 -1
- package/data/{keyingCanonicalJson.js → keying/canonicalJson.js} +3 -3
- package/data/keying/canonicalJson.js.map +1 -0
- package/data/keyingProjectionVerification/bundleVerification.js +1 -1
- package/data/keyingProjectionVerification/bundleVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerAncestorCitations.js +1 -1
- package/data/keyingProjectionVerification/containerAncestorCitations.js.map +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js +1 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +1 -1
- package/data/keyingProjectionVerification/error.js +1 -1
- package/data/keyingProjectionVerification/error.js.map +1 -1
- package/data/keyingProjectionVerification/index.d.ts +9 -0
- package/data/{keyingProjectionVerification.js → keyingProjectionVerification/index.js} +8 -8
- package/data/keyingProjectionVerification/index.js.map +1 -0
- package/data/keyingProjectionVerification/principalPolicyCache.js +1 -1
- package/data/keyingProjectionVerification/principalPolicyCache.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js +1 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
- package/data/keyingProjectionVerification/readers.d.ts +1 -1
- package/data/keyingProjectionVerification/readers.js +3 -3
- package/data/keyingProjectionVerification/readers.js.map +1 -1
- package/data/keyingProjectionVerification/userKeyResolver.d.ts +1 -1
- package/data/keyingProjectionVerification/userKeyResolver.js.map +1 -1
- package/data/persistence/containers/containerPersistence.js +1 -1
- package/data/persistence/containers/containerPersistence.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryCandidate.js +1 -1
- package/data/persistence/documents/documentDiscoveryCandidate.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +1 -1
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js.map +1 -1
- package/data/persistence/documents/internal/documentRows.js +1 -1
- package/data/persistence/documents/internal/documentRows.js.map +1 -1
- package/data/persistence/principalPolicyBundleIntegrity.js +1 -1
- package/data/persistence/principalPolicyBundleIntegrity.js.map +1 -1
- package/data/persistence/principalPolicyReferenceCheckpoint.js +1 -1
- package/data/persistence/principalPolicyReferenceCheckpoint.js.map +1 -1
- package/data/persistence/principalPolicyReferenceIndexPersistence.js +1 -1
- package/data/persistence/principalPolicyReferenceIndexPersistence.js.map +1 -1
- package/data/persistence/principalPolicyReferencePersistence.js +1 -1
- package/data/persistence/principalPolicyReferencePersistence.js.map +1 -1
- package/data/persistence/securityIncidentPersistence.js.map +1 -1
- package/data/persistence/verifiedPrincipalPolicyBundle.js +1 -1
- package/data/persistence/verifiedPrincipalPolicyBundle.js.map +1 -1
- package/data/persistence/verifiedPrincipalPolicyCurrent.js +1 -1
- package/data/persistence/verifiedPrincipalPolicyCurrent.js.map +1 -1
- package/data/principals/principalMutationJournal.js +1 -1
- package/data/principals/principalMutationJournal.js.map +1 -1
- package/data/{securityIncidents.d.ts → shared/securityIncidents.d.ts} +1 -1
- package/data/sqlite/documentRecordPersistence.js +1 -1
- package/data/sqlite/documentRecordPersistence.js.map +1 -1
- package/data/sync/crdtPeerSeed.d.ts +18 -0
- package/data/sync/originatedDocuments.d.ts +1 -1
- package/data/sync/originatedDocuments.js.map +1 -1
- package/data/sync/syncCoordinator.d.ts +1 -1
- package/data/sync/syncCoordinator.js.map +1 -1
- package/index.d.ts +4 -4
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/stores/container-contents/backgroundHydration.js +1 -1
- package/stores/container-contents/backgroundHydration.js.map +1 -1
- package/stores/container-contents/containerContentsStore.d.ts +1 -1
- package/stores/container-contents/containerContentsStore.js.map +1 -1
- package/stores/container-contents/localRefresh.js +1 -1
- package/stores/container-contents/localRefresh.js.map +1 -1
- package/stores/container-contents/remoteContainerIngestion.js +1 -1
- package/stores/container-contents/remoteContainerIngestion.js.map +1 -1
- package/stores/container-contents/remoteWriteQueue.js +1 -1
- package/stores/container-contents/remoteWriteQueue.js.map +1 -1
- package/stores/container-contents/systemContainerHydration.js +1 -1
- package/stores/container-contents/systemContainerHydration.js.map +1 -1
- package/stores/container-contents/utils.js +1 -1
- package/stores/container-contents/utils.js.map +1 -1
- package/stores/documents/documentStore/attachmentIntents.js +1 -1
- package/stores/documents/documentStore/attachmentIntents.js.map +1 -1
- package/stores/documents/documentStore/attachmentSourceUpload.js.map +1 -1
- package/stores/documents/documentStore/attachmentStaging.js +1 -1
- package/stores/documents/documentStore/attachmentStaging.js.map +1 -1
- package/stores/documents/documentStore/attachmentUploadLane.js.map +1 -1
- package/stores/documents/documentStore/persistence.js +2 -2
- package/stores/documents/documentStore/persistence.js.map +1 -1
- package/stores/documents/documentStore/state.js +1 -1
- package/stores/documents/documentStore/state.js.map +1 -1
- package/stores/documents/documentStore/storedDocument.js +1 -1
- package/stores/documents/documentStore/storedDocument.js.map +1 -1
- package/stores/documents/documentStore/syncAttachments.js.map +1 -1
- package/stores/documents/documentStore.d.ts +1 -1
- package/stores/documents/documentStore.js.map +1 -1
- package/stores/documents/registry.d.ts +1 -1
- package/stores/documents/registry.js.map +1 -1
- package/stores/documents/types.d.ts +1 -1
- package/stores/documents/types.js.map +1 -1
- package/stores/local-projection/registry.d.ts +1 -1
- package/stores/local-projection/registry.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +1 -1
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/sync/reconciliation/triggers.d.ts +1 -1
- package/sync/reconciliation/triggers.js.map +1 -1
- package/workflows/blobs/attachmentBindingVerification.js +2 -2
- package/workflows/blobs/attachmentBindingVerification.js.map +1 -1
- package/workflows/blobs/blobChunkDecryption.js.map +1 -1
- package/workflows/blobs/decrypt.d.ts +1 -1
- package/workflows/blobs/decrypt.js +2 -2
- package/workflows/blobs/decrypt.js.map +1 -1
- package/workflows/blobs/detach.js +2 -2
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +3 -3
- package/workflows/blobs/hydrate.js +1 -1
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/hydrationResults.js.map +1 -1
- package/workflows/blobs/index.d.ts +2 -2
- package/workflows/blobs/index.js +1 -1
- package/workflows/blobs/index.js.map +1 -1
- package/workflows/blobs/multipartFirstParts.js.map +1 -1
- package/workflows/blobs/retainedAttachmentVerification.js +1 -1
- package/workflows/blobs/upload.js +3 -3
- package/workflows/blobs/upload.js.map +1 -1
- package/workflows/container-contents/container-state/createAdoption.js +1 -1
- package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/createChild.js +1 -1
- package/workflows/container-contents/container-state/createChild.js.map +1 -1
- package/workflows/container-contents/container-state/createIntentSync.js +1 -1
- package/workflows/container-contents/container-state/createIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/groupGrantVerification.js +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/purgeTreeScope.js +1 -1
- package/workflows/container-contents/container-state/purgeTreeScope.js.map +1 -1
- package/workflows/container-contents/container-state/share.js +1 -1
- package/workflows/container-contents/documentDiscoveryInputs.js +1 -1
- package/workflows/container-contents/documentDiscoveryInputs.js.map +1 -1
- package/workflows/container-contents/documentInfo.d.ts +1 -1
- package/workflows/container-contents/documentInfo.js.map +1 -1
- package/workflows/container-contents/documentLinks.d.ts +1 -1
- package/workflows/container-contents/documentLinks.js +1 -1
- package/workflows/container-contents/documentLinks.js.map +1 -1
- package/workflows/container-contents/documentMoveIntentSync.js +1 -1
- package/workflows/container-contents/documentMoveIntentSync.js.map +1 -1
- package/workflows/container-contents/documentPurge.d.ts +1 -1
- package/workflows/container-contents/documentPurge.js +1 -1
- package/workflows/container-contents/documentPurge.js.map +1 -1
- package/workflows/container-contents/documentQueries/rows.js +1 -1
- package/workflows/container-contents/documentQueries/rows.js.map +1 -1
- package/workflows/container-contents/metadata.d.ts +1 -1
- package/workflows/container-contents/metadataMutationPreparation.js +1 -1
- package/workflows/container-contents/metadataMutationPreparation.js.map +1 -1
- package/workflows/container-contents/metadataRemoteSync.d.ts +1 -1
- package/workflows/container-contents/metadataSyncErrors.js.map +1 -1
- package/workflows/container-contents/projectionKeys.d.ts +1 -1
- package/workflows/container-contents/syncLane.d.ts +1 -1
- package/workflows/container-contents/syncLane.js.map +1 -1
- package/workflows/containers/child/carriedDescendantRekeys.js +1 -1
- package/workflows/containers/child/create.d.ts +1 -1
- package/workflows/containers/child/create.js +2 -2
- package/workflows/containers/child/create.js.map +1 -1
- package/workflows/containers/child/createProjection.js +1 -1
- package/workflows/containers/child/createProjection.js.map +1 -1
- package/workflows/containers/child/createSubmission.d.ts +2 -2
- package/workflows/containers/child/createSubmission.js.map +1 -1
- package/workflows/containers/child/move.d.ts +2 -2
- package/workflows/containers/child/move.js +2 -2
- package/workflows/containers/child/move.js.map +1 -1
- package/workflows/containers/child/moveWraps.js +1 -1
- package/workflows/containers/child/mutationRequestCore.js +1 -1
- package/workflows/containers/child/mutationRequestCore.js.map +1 -1
- package/workflows/containers/child/mutationSubmit.js.map +1 -1
- package/workflows/containers/child/recite.js.map +1 -1
- package/workflows/containers/child/recitePlan.js +1 -1
- package/workflows/containers/child/recitePlan.js.map +1 -1
- package/workflows/containers/child/rekey.d.ts +1 -1
- package/workflows/containers/child/rekey.js +2 -2
- package/workflows/containers/child/rekey.js.map +1 -1
- package/workflows/containers/child/rekeyProjection.js +1 -1
- package/workflows/containers/child/rekeyProjection.js.map +1 -1
- package/workflows/containers/child/rekeyRemote.d.ts +2 -2
- package/workflows/containers/child/rekeyRemote.js.map +1 -1
- package/workflows/containers/child/revoke.d.ts +2 -2
- package/workflows/containers/child/revoke.js +2 -2
- package/workflows/containers/child/revoke.js.map +1 -1
- package/workflows/containers/child/rotationPrincipalPolicies.js +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
- package/workflows/containers/child/share.d.ts +2 -2
- package/workflows/containers/child/share.js +1 -1
- package/workflows/containers/child/share.js.map +1 -1
- package/workflows/containers/child/shareAncestorRepair.js.map +1 -1
- package/workflows/containers/child/shareMaterialization.d.ts +1 -1
- package/workflows/containers/child/sharePlanCore.d.ts +1 -1
- package/workflows/containers/child/sharePlanCore.js +1 -1
- package/workflows/containers/root/create.js +1 -1
- package/workflows/containers/root/create.js.map +1 -1
- package/workflows/containers/root/initialGroupPolicy.js +1 -1
- package/workflows/containers/root/initialGroupPolicy.js.map +1 -1
- package/workflows/documents/create.d.ts +1 -1
- package/workflows/documents/create.js +1 -1
- package/workflows/documents/documentMutationPreparation.js +1 -1
- package/workflows/documents/documentMutationPreparation.js.map +1 -1
- package/workflows/documents/historyContent.js +1 -1
- package/workflows/documents/historyContent.js.map +1 -1
- package/workflows/documents/linkSet.js +1 -1
- package/workflows/documents/linkSet.js.map +1 -1
- package/workflows/documents/linkSetAuthority.js +1 -1
- package/workflows/documents/linkSetBlobRewraps.js +2 -2
- package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/linkSetRemote.d.ts +1 -1
- package/workflows/documents/linkSetRemote.js +1 -1
- package/workflows/documents/orphanBlobReclaims.js +1 -1
- package/workflows/documents/orphanBlobReclaims.js.map +1 -1
- package/workflows/documents/projectionKeys.d.ts +1 -1
- package/workflows/documents/purge.d.ts +1 -1
- package/workflows/documents/purge.js +2 -2
- package/workflows/documents/purge.js.map +1 -1
- package/workflows/documents/readOnlySync.d.ts +1 -1
- package/workflows/documents/readOnlySync.js +1 -1
- package/workflows/documents/readOnlySync.js.map +1 -1
- package/workflows/documents/sync.js +1 -1
- package/workflows/documents/syncContainerRekeyPreparation.js +1 -1
- package/workflows/documents/syncLane.d.ts +1 -1
- package/workflows/documents/syncLane.js.map +1 -1
- package/workflows/documents/syncPlanIdentity.js +1 -1
- package/workflows/documents/syncPlanIdentity.js.map +1 -1
- package/workflows/documents/syncRepairAccess.js +1 -1
- package/workflows/documents/syncSubmittedResult.js +1 -1
- package/workflows/organizations/authoredPrincipalPolicyWarmer.js +1 -1
- package/workflows/organizations/authoredPrincipalPolicyWarmer.js.map +1 -1
- package/workflows/organizations/containerGrantRevocation.d.ts +2 -2
- package/workflows/organizations/containerGrantRevocation.js.map +1 -1
- package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -1
- package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -1
- package/workflows/organizations/currentOrganizationMutationRetention.js +1 -1
- package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -1
- package/workflows/organizations/currentPolicyMutationAcknowledgement.js +1 -1
- package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +1 -1
- package/workflows/organizations/groupCreation.d.ts +1 -1
- package/workflows/organizations/groupCreation.js.map +1 -1
- package/workflows/organizations/groupMetadataAccess.d.ts +1 -1
- package/workflows/organizations/groupMetadataContainerAuthority.js.map +1 -1
- package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
- package/workflows/organizations/groupNameUniqueness.js.map +1 -1
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js +1 -1
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
- package/workflows/organizations/groupPolicyRequests.js.map +1 -1
- package/workflows/organizations/index.d.ts +0 -1
- package/workflows/organizations/index.js +0 -1
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/loadPolicyHistoryDetails.js.map +1 -1
- package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
- package/workflows/organizations/organizationProfile.js +1 -1
- package/workflows/organizations/organizationProfile.js.map +1 -1
- package/workflows/organizations/policyHistoryCache.js.map +1 -1
- package/workflows/organizations/principalContainerRematerialization.js +1 -1
- package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
- package/workflows/organizations/principalMutationJournalManagement.js +1 -1
- package/workflows/organizations/principalMutationJournalManagement.js.map +1 -1
- package/workflows/organizations/principalMutationReceipt.js +1 -1
- package/workflows/organizations/principalMutationReceipt.js.map +1 -1
- package/workflows/organizations/principalPolicy.d.ts +1 -1
- package/workflows/organizations/principalPolicy.js.map +1 -1
- package/workflows/organizations/principalPolicyReceiptArtifacts.js +1 -1
- package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +1 -1
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +4 -24
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +13 -133
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
- package/workflows/organizations/rosterProfileContainer.js +1 -1
- package/workflows/organizations/rosterProfileContainer.js.map +1 -1
- package/workflows/organizations/runtimeCurrentGroupMutation.js +1 -1
- package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -1
- package/workflows/principals/acknowledgedPrincipalCurrents.d.ts +33 -0
- package/workflows/principals/acknowledgedPrincipalCurrents.js +140 -0
- package/workflows/principals/acknowledgedPrincipalCurrents.js.map +1 -0
- package/workflows/{organizations → principals}/acknowledgedPrincipalPredecessor.d.ts +1 -1
- package/workflows/{organizations → principals}/acknowledgedPrincipalPredecessor.js +1 -1
- package/workflows/principals/acknowledgedPrincipalPredecessor.js.map +1 -0
- package/workflows/principals/index.d.ts +1 -0
- package/workflows/principals/index.js +1 -0
- package/workflows/principals/index.js.map +1 -1
- package/workflows/{organizations → principals}/initialPrincipalCurrentPublication.js +5 -7
- package/workflows/principals/initialPrincipalCurrentPublication.js.map +1 -0
- package/workflows/principals/policyCache.d.ts +1 -1
- package/workflows/principals/policyCache.js +2 -2
- package/workflows/principals/policyCache.js.map +1 -1
- package/workflows/principals/principalAcknowledgementChecks.d.ts +30 -0
- package/workflows/principals/principalAcknowledgementChecks.js +2 -0
- package/workflows/principals/principalAcknowledgementChecks.js.map +1 -0
- package/workflows/{organizations → principals}/principalCurrentPublicationSeal.js.map +1 -1
- package/workflows/{organizations → principals}/reconcileAcknowledgedPrincipalCurrent.js +2 -2
- package/workflows/principals/reconcileAcknowledgedPrincipalCurrent.js.map +1 -0
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +1 -1
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
- package/workflows/runtimeInput.d.ts +3 -3
- package/workflows/runtimeInput.js.map +1 -1
- package/workflows/sync/index.d.ts +2 -1
- package/workflows/sync/index.js +2 -1
- package/workflows/sync/index.js.map +1 -1
- package/data/keyingCanonicalJson.js.map +0 -1
- package/data/keyingProjectionVerification.d.ts +0 -9
- package/data/keyingProjectionVerification.js.map +0 -1
- package/workflows/organizations/acknowledgedPrincipalPredecessor.js.map +0 -1
- package/workflows/organizations/initialPrincipalCurrentPublication.js.map +0 -1
- package/workflows/organizations/reconcileAcknowledgedPrincipalCurrent.js.map +0 -1
- /package/data/{blobContracts.d.ts → blobs/blobContracts.d.ts} +0 -0
- /package/data/{blobContracts.js → blobs/blobContracts.js} +0 -0
- /package/data/{blobContracts.js.map → blobs/blobContracts.js.map} +0 -0
- /package/data/{accessLevel.js → keying/accessLevel.js} +0 -0
- /package/data/{accessLevel.js.map → keying/accessLevel.js.map} +0 -0
- /package/data/{stableUuid.js → keying/stableUuid.js} +0 -0
- /package/data/{stableUuid.js.map → keying/stableUuid.js.map} +0 -0
- /package/data/{principalPolicyStates.js → principals/principalPolicyStates.js} +0 -0
- /package/data/{principalPolicyStates.js.map → principals/principalPolicyStates.js.map} +0 -0
- /package/data/{domainScope.d.ts → shared/domainScope.d.ts} +0 -0
- /package/data/{domainScope.js → shared/domainScope.js} +0 -0
- /package/data/{domainScope.js.map → shared/domainScope.js.map} +0 -0
- /package/data/{errorMessage.js → shared/errorMessage.js} +0 -0
- /package/data/{errorMessage.js.map → shared/errorMessage.js.map} +0 -0
- /package/data/{recordReaders.d.ts → shared/recordReaders.d.ts} +0 -0
- /package/data/{recordReaders.js → shared/recordReaders.js} +0 -0
- /package/data/{recordReaders.js.map → shared/recordReaders.js.map} +0 -0
- /package/data/{securityIncidents.js → shared/securityIncidents.js} +0 -0
- /package/data/{securityIncidents.js.map → shared/securityIncidents.js.map} +0 -0
- /package/data/{crdtPeerSeed.js → sync/crdtPeerSeed.js} +0 -0
- /package/data/{crdtPeerSeed.js.map → sync/crdtPeerSeed.js.map} +0 -0
- /package/workflows/{organizations → principals}/principalCurrentPublicationSeal.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAdoption.js","sourceRoot":"","sources":["createAdoption.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type KeyingVerificationCode,\n KeyingVerificationError,\n} from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { errorMessage } from \"../../../data/errorMessage\";\nimport { verifiedContainerCreateManifest } from \"../../../data/keyingProjectionVerification/containerCreateManifest\";\nimport { verifyContainerDestinationProjection } from \"../../../data/keyingProjectionVerification/containerDestinationVerification\";\nimport {\n isKeyingVerificationError,\n reportKeyingVerificationErrorInCauseChain,\n} from \"../../../data/keyingProjectionVerification/error\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { settleContainerCreateIntent } from \"./createIntentSettlement\";\nimport type {\n AdoptedContainerPlacement,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n} from \"./types\";\n\nconst LABEL = \"Container create conflict\";\n\n/** The recorded error that parks an intent whose listed create is foreign. */\nexport const CONTAINER_CREATE_ADOPTION_REFUSED =\n \"Container create adoption was refused\";\n\n/**\n * The listed create's signed identity is not this device's pending create: its\n * signed create names another signer, another organization, or a root. An honest server never lists that under the\n * id this device minted, and no later read can change those signed facts, so\n * the intent parks instead of re-verifying.\n */\nclass ForeignContainerCreateError extends KeyingVerificationError {}\n\nfunction foreignCreate(\n code: KeyingVerificationCode,\n message: string,\n): ForeignContainerCreateError {\n return new ForeignContainerCreateError(code, `${LABEL} ${message}`);\n}\n\nasync function verifyAdoptableProjection(input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n readonly projection: ContainerWriterProjectionResponse;\n readonly sessionUserId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const { projection } = input;\n if (\n projection.containerId !== input.containerId ||\n projection.organizationId !== input.expectedOrganizationId\n ) {\n // The envelope is unsigned: a corrupt read is retried, not parked.\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${LABEL} projection has the wrong identity`,\n );\n }\n const { path, verifiedByHash } = await verifyContainerDestinationProjection({\n execSql: input.state.runtime.infra.execSql,\n projection,\n resolveUserKey: input.state.resolveProjectionUserKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.state.runtime,\n ),\n });\n const head = path.at(-1);\n // One read naming another container says nothing signed about this id.\n if (!head || head.state.containerId !== input.containerId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${LABEL} projection names another container`,\n );\n }\n const create = verifiedContainerCreateManifest({\n head,\n label: LABEL,\n verifiedByHash,\n });\n if (create.event.event.signerUserId !== input.sessionUserId) {\n throw foreignCreate(\"signer_mismatch\", \"was signed by another user\");\n }\n if (create.state.organizationId !== input.expectedOrganizationId) {\n throw foreignCreate(\"object_mismatch\", \"belongs to another organization\");\n }\n const createdParentId = create.state.parentContainerId;\n const currentParentId = head.state.parentContainerId;\n if (createdParentId === null || currentParentId === null) {\n throw foreignCreate(\"object_mismatch\", \"is an organization root\");\n }\n return { createdParentId, currentParentId };\n}\n\n/**\n * A pending create whose container the listing already carries is adopted\n * only when the container's signed epoch-1 `container.create` is this user's,\n * in the intended organization (#2365 finding 26). Listing metadata is\n * unsigned: a create by another writer that collides on the pending id, or one\n * a dishonest server invents, must not become this device's container.\n * Documents apply the same rule (`workflows/documents/createAdoption.ts`).\n *\n * Returns where the create committed and where the verified head sits now.\n * The user may have moved the pending container since, which rewrites its\n * intent's parent; that is a move still owed, not a mismatch.\n */\nasync function assertContainerCreateAdoptable(input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const { runtime } = input.state;\n const sessionUserId = runtime.auth.userId;\n // Without a session user there is no signer to compare: not tampering.\n if (!sessionUserId) {\n throw new Error(`${LABEL} needs a signed-in session user`);\n }\n const projection = await runtime.apiClient.getContainerWriterProjection(\n input.containerId,\n );\n if (!projection) {\n throw new Error(`${LABEL} is unavailable to verify`);\n }\n try {\n return await verifyAdoptableProjection({\n ...input,\n projection,\n sessionUserId,\n });\n } catch (error) {\n // Never re-serve a cached projection that failed verification.\n if (isKeyingVerificationError(error)) {\n runtime.apiClient.evictContainerWriterProjection(input.containerId);\n }\n throw error;\n }\n}\n\nfunction verifyListedContainerCreate(input: {\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly parentState: ContainerState;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const adoption = {\n containerId: input.intent.containerId,\n expectedOrganizationId: input.parentState.container.organizationId,\n };\n return input.state.verifyCreateAdoption\n ? input.state.verifyCreateAdoption(adoption)\n : assertContainerCreateAdoptable({ ...adoption, state: input.state });\n}\n\n/** Settles a verified adoption against the row hydration installed. */\nasync function markContainerCreateIntentAdopted(input: {\n containerState: ContainerState;\n placement: AdoptedContainerPlacement;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<boolean> {\n const { containerState, placement, syncInput } = input;\n const remoteMetadataDocumentId = containerState.record.documentId;\n const remoteMetadataAccessStateHash = containerState.record.accessStateHash;\n\n if (!remoteMetadataDocumentId || !remoteMetadataAccessStateHash) {\n return false;\n }\n return settleContainerCreateIntent({\n createdParentContainerId: placement.createdParentId,\n desiredParentContainerId: syncInput.intent.parentContainerId,\n intent: syncInput.intent,\n isCurrent: syncInput.isCurrent,\n remoteContainerId: containerState.container.id,\n remoteMetadataAccessStateHash,\n remoteMetadataDocumentId,\n state: syncInput.state,\n supersededMovePreviousParentId: placement.currentParentId,\n });\n}\n\n/**\n * Records a failed adoption and leaves the lane's other intents to proceed. A\n * foreign create parks the intent: its signed facts never change, so later\n * passes neither re-read it nor report it again. Any other failure retries.\n */\nasync function recordAdoptionFailure(input: {\n readonly error: unknown;\n readonly organizationId: string;\n readonly syncInput: ContainerCreateIntentSyncInput;\n}): Promise<\"abandoned\" | \"failed\"> {\n const { intent, isCurrent, state } = input.syncInput;\n if (!isCurrent()) return \"abandoned\";\n await reportKeyingVerificationErrorInCauseChain(\n input.error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n if (!isCurrent()) return \"abandoned\";\n const action =\n input.error instanceof ForeignContainerCreateError\n ? CONTAINER_CREATE_ADOPTION_REFUSED\n : \"Container create adoption verification failed\";\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: `${action}: ${errorMessage(input.error)}`,\n stillCurrent: isCurrent,\n },\n );\n return isCurrent() ? \"failed\" : \"abandoned\";\n}\n\n/**\n * Adopts a pending create the listing already carries, once its signed create\n * proves it is this device's. A parked refusal stays blocked without a read.\n */\nexport async function syncListedContainerCreate(input: {\n readonly containerState: ContainerState;\n readonly parentState: ContainerState;\n readonly syncInput: ContainerCreateIntentSyncInput;\n}): Promise<\"abandoned\" | \"blocked\" | \"created\" | \"failed\"> {\n const { containerState, parentState, syncInput } = input;\n const { intent, isCurrent, state } = syncInput;\n if (intent.lastError?.startsWith(CONTAINER_CREATE_ADOPTION_REFUSED)) {\n return \"blocked\";\n }\n let placement: AdoptedContainerPlacement;\n try {\n placement = await verifyListedContainerCreate({\n intent,\n parentState,\n state,\n });\n } catch (error) {\n return recordAdoptionFailure({\n error,\n organizationId: parentState.container.organizationId,\n syncInput,\n });\n }\n const marked = await markContainerCreateIntentAdopted({\n containerState,\n placement,\n syncInput,\n });\n if (!marked) return isCurrent() ? \"blocked\" : \"abandoned\";\n // The folder now sits elsewhere; list it there rather than waiting for the\n // next poll to correct the local parent.\n if (placement.currentParentId !== intent.parentContainerId) {\n syncInput.requestRemoteReconciliation(placement.currentParentId);\n }\n return \"created\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createAdoption.js","sourceRoot":"","sources":["createAdoption.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type KeyingVerificationCode,\n KeyingVerificationError,\n} from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { verifiedContainerCreateManifest } from \"../../../data/keyingProjectionVerification/containerCreateManifest\";\nimport { verifyContainerDestinationProjection } from \"../../../data/keyingProjectionVerification/containerDestinationVerification\";\nimport {\n isKeyingVerificationError,\n reportKeyingVerificationErrorInCauseChain,\n} from \"../../../data/keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { settleContainerCreateIntent } from \"./createIntentSettlement\";\nimport type {\n AdoptedContainerPlacement,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n} from \"./types\";\n\nconst LABEL = \"Container create conflict\";\n\n/** The recorded error that parks an intent whose listed create is foreign. */\nexport const CONTAINER_CREATE_ADOPTION_REFUSED =\n \"Container create adoption was refused\";\n\n/**\n * The listed create's signed identity is not this device's pending create: its\n * signed create names another signer, another organization, or a root. An honest server never lists that under the\n * id this device minted, and no later read can change those signed facts, so\n * the intent parks instead of re-verifying.\n */\nclass ForeignContainerCreateError extends KeyingVerificationError {}\n\nfunction foreignCreate(\n code: KeyingVerificationCode,\n message: string,\n): ForeignContainerCreateError {\n return new ForeignContainerCreateError(code, `${LABEL} ${message}`);\n}\n\nasync function verifyAdoptableProjection(input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n readonly projection: ContainerWriterProjectionResponse;\n readonly sessionUserId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const { projection } = input;\n if (\n projection.containerId !== input.containerId ||\n projection.organizationId !== input.expectedOrganizationId\n ) {\n // The envelope is unsigned: a corrupt read is retried, not parked.\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${LABEL} projection has the wrong identity`,\n );\n }\n const { path, verifiedByHash } = await verifyContainerDestinationProjection({\n execSql: input.state.runtime.infra.execSql,\n projection,\n resolveUserKey: input.state.resolveProjectionUserKey,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.state.runtime,\n ),\n });\n const head = path.at(-1);\n // One read naming another container says nothing signed about this id.\n if (!head || head.state.containerId !== input.containerId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${LABEL} projection names another container`,\n );\n }\n const create = verifiedContainerCreateManifest({\n head,\n label: LABEL,\n verifiedByHash,\n });\n if (create.event.event.signerUserId !== input.sessionUserId) {\n throw foreignCreate(\"signer_mismatch\", \"was signed by another user\");\n }\n if (create.state.organizationId !== input.expectedOrganizationId) {\n throw foreignCreate(\"object_mismatch\", \"belongs to another organization\");\n }\n const createdParentId = create.state.parentContainerId;\n const currentParentId = head.state.parentContainerId;\n if (createdParentId === null || currentParentId === null) {\n throw foreignCreate(\"object_mismatch\", \"is an organization root\");\n }\n return { createdParentId, currentParentId };\n}\n\n/**\n * A pending create whose container the listing already carries is adopted\n * only when the container's signed epoch-1 `container.create` is this user's,\n * in the intended organization (#2365 finding 26). Listing metadata is\n * unsigned: a create by another writer that collides on the pending id, or one\n * a dishonest server invents, must not become this device's container.\n * Documents apply the same rule (`workflows/documents/createAdoption.ts`).\n *\n * Returns where the create committed and where the verified head sits now.\n * The user may have moved the pending container since, which rewrites its\n * intent's parent; that is a move still owed, not a mismatch.\n */\nasync function assertContainerCreateAdoptable(input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const { runtime } = input.state;\n const sessionUserId = runtime.auth.userId;\n // Without a session user there is no signer to compare: not tampering.\n if (!sessionUserId) {\n throw new Error(`${LABEL} needs a signed-in session user`);\n }\n const projection = await runtime.apiClient.getContainerWriterProjection(\n input.containerId,\n );\n if (!projection) {\n throw new Error(`${LABEL} is unavailable to verify`);\n }\n try {\n return await verifyAdoptableProjection({\n ...input,\n projection,\n sessionUserId,\n });\n } catch (error) {\n // Never re-serve a cached projection that failed verification.\n if (isKeyingVerificationError(error)) {\n runtime.apiClient.evictContainerWriterProjection(input.containerId);\n }\n throw error;\n }\n}\n\nfunction verifyListedContainerCreate(input: {\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly parentState: ContainerState;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<AdoptedContainerPlacement> {\n const adoption = {\n containerId: input.intent.containerId,\n expectedOrganizationId: input.parentState.container.organizationId,\n };\n return input.state.verifyCreateAdoption\n ? input.state.verifyCreateAdoption(adoption)\n : assertContainerCreateAdoptable({ ...adoption, state: input.state });\n}\n\n/** Settles a verified adoption against the row hydration installed. */\nasync function markContainerCreateIntentAdopted(input: {\n containerState: ContainerState;\n placement: AdoptedContainerPlacement;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<boolean> {\n const { containerState, placement, syncInput } = input;\n const remoteMetadataDocumentId = containerState.record.documentId;\n const remoteMetadataAccessStateHash = containerState.record.accessStateHash;\n\n if (!remoteMetadataDocumentId || !remoteMetadataAccessStateHash) {\n return false;\n }\n return settleContainerCreateIntent({\n createdParentContainerId: placement.createdParentId,\n desiredParentContainerId: syncInput.intent.parentContainerId,\n intent: syncInput.intent,\n isCurrent: syncInput.isCurrent,\n remoteContainerId: containerState.container.id,\n remoteMetadataAccessStateHash,\n remoteMetadataDocumentId,\n state: syncInput.state,\n supersededMovePreviousParentId: placement.currentParentId,\n });\n}\n\n/**\n * Records a failed adoption and leaves the lane's other intents to proceed. A\n * foreign create parks the intent: its signed facts never change, so later\n * passes neither re-read it nor report it again. Any other failure retries.\n */\nasync function recordAdoptionFailure(input: {\n readonly error: unknown;\n readonly organizationId: string;\n readonly syncInput: ContainerCreateIntentSyncInput;\n}): Promise<\"abandoned\" | \"failed\"> {\n const { intent, isCurrent, state } = input.syncInput;\n if (!isCurrent()) return \"abandoned\";\n await reportKeyingVerificationErrorInCauseChain(\n input.error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n if (!isCurrent()) return \"abandoned\";\n const action =\n input.error instanceof ForeignContainerCreateError\n ? CONTAINER_CREATE_ADOPTION_REFUSED\n : \"Container create adoption verification failed\";\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: `${action}: ${errorMessage(input.error)}`,\n stillCurrent: isCurrent,\n },\n );\n return isCurrent() ? \"failed\" : \"abandoned\";\n}\n\n/**\n * Adopts a pending create the listing already carries, once its signed create\n * proves it is this device's. A parked refusal stays blocked without a read.\n */\nexport async function syncListedContainerCreate(input: {\n readonly containerState: ContainerState;\n readonly parentState: ContainerState;\n readonly syncInput: ContainerCreateIntentSyncInput;\n}): Promise<\"abandoned\" | \"blocked\" | \"created\" | \"failed\"> {\n const { containerState, parentState, syncInput } = input;\n const { intent, isCurrent, state } = syncInput;\n if (intent.lastError?.startsWith(CONTAINER_CREATE_ADOPTION_REFUSED)) {\n return \"blocked\";\n }\n let placement: AdoptedContainerPlacement;\n try {\n placement = await verifyListedContainerCreate({\n intent,\n parentState,\n state,\n });\n } catch (error) {\n return recordAdoptionFailure({\n error,\n organizationId: parentState.container.organizationId,\n syncInput,\n });\n }\n const marked = await markContainerCreateIntentAdopted({\n containerState,\n placement,\n syncInput,\n });\n if (!marked) return isCurrent() ? \"blocked\" : \"abandoned\";\n // The folder now sits elsewhere; list it there rather than waiting for the\n // next poll to correct the local parent.\n if (placement.currentParentId !== intent.parentContainerId) {\n syncInput.requestRemoteReconciliation(placement.currentParentId);\n }\n return \"created\";\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bytesToBase64 } from "../../../internal/encoding/index.js";
|
|
2
2
|
import { createInitializedContainerMetadataDocument } from "../../../data/containers/containerMetadataDocument.js";
|
|
3
3
|
import { createPendingUpdateFields } from "../../../data/documents/documentSync.js";
|
|
4
|
-
import { deriveStableUuidV4Shaped } from "../../../data/stableUuid.js";
|
|
4
|
+
import { deriveStableUuidV4Shaped } from "../../../data/keying/stableUuid.js";
|
|
5
5
|
import { defaultContainerContentsPersistence } from "../containerPersistence.js";
|
|
6
6
|
import { CONTAINER_ALREADY_COMMITTED } from "./createWithMetadata.js";
|
|
7
7
|
import { loadContainerWriterProjectionForState } from "./projectionCache.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createChild.js","sourceRoot":"","sources":["createChild.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport { createInitializedContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport { createPendingUpdateFields } from \"../../../data/documents/documentSync\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { deriveStableUuidV4Shaped } from \"../../../data/stableUuid\";\nimport type {\n ContainerContentsPersistence,\n ContainerDocumentRecord as DocumentRecord,\n} from \"../containerPersistence\";\nimport { defaultContainerContentsPersistence } from \"../containerPersistence\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\nimport { loadContainerWriterProjectionForState } from \"./projectionCache\";\nimport { createRemoteContainer } from \"./remote\";\nimport type {\n ContainerMetadataDocumentState,\n ContainerWorkflowRuntime,\n CreatedChildContainerState,\n} from \"./types\";\n\nconst SYSTEM_CONTAINER_ID_NAMESPACE_BYTES = new Uint8Array([\n 0xc5, 0x5e, 0x8f, 0x2e, 0x3d, 0x82, 0x4b, 0x4d, 0x8d, 0xbd, 0x0d, 0xd2, 0xd3,\n 0x60, 0xb3, 0x6d,\n]);\n\n/**\n * Derives a stable, UUID-shaped container id for a built-in system slot.\n *\n * The namespace digest makes each slot idempotent across stale store snapshots.\n * The UUID version and variant bits are normalized to a v4 shape because remote\n * container APIs currently validate container ids with the same v4 UUID contract\n * they use for random user-created containers.\n */\nfunction deriveSystemContainerId(input: {\n parentContainerId: string;\n systemSlot: ContainerSystemSlot;\n}): Promise<string> {\n return deriveStableUuidV4Shaped(\n SYSTEM_CONTAINER_ID_NAMESPACE_BYTES,\n `${input.parentContainerId}\\u0000${input.systemSlot}`,\n );\n}\n\nasync function createChildContainerId(\n parentContainerId: string,\n systemSlot: ContainerSystemSlot | null | undefined,\n): Promise<string> {\n return systemSlot\n ? deriveSystemContainerId({ parentContainerId, systemSlot })\n : crypto.randomUUID();\n}\n\nasync function buildRemoteContainerContentsChildContainerState(input: {\n childId: string;\n icon: string | null;\n systemSlot?: ContainerSystemSlot | null | undefined;\n doc: ContainerMetadataDocumentState;\n initialRecord: DocumentRecord;\n parentState: ContainerState;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n trimmedName: string;\n}): Promise<ContainerState | null> {\n const {\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n resolveProjectionUserKey,\n runtime,\n stillCurrent,\n trimmedName,\n } = input;\n const parentProjection = await loadContainerWriterProjectionForState({\n containerState: parentState,\n runtime,\n });\n if (!parentProjection) {\n return null;\n }\n\n const created = await createRemoteContainer({\n systemSlot,\n containerId: childId,\n parentContainerId: parentState.container.id,\n parentProjection,\n resolveProjectionUserKey,\n runtime,\n stillCurrent,\n });\n\n if (!created || created === CONTAINER_ALREADY_COMMITTED) {\n // A benign manifest-exists conflict means the container is already committed\n // remotely (a lost create response). This eager path cannot rebuild its\n // committed metadata state, so leave the create intent to reconcile it via\n // hydration rather than fabricating a local record from a missing response.\n return null;\n }\n\n return {\n container: {\n id: created.containerId,\n // The creator owns a newly-created container until the server reconciles.\n effectiveAccessLevel: \"admin\",\n organizationId: created.organizationId,\n parentId: created.parentId,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n name: trimmedName,\n icon,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n },\n doc,\n record: {\n ...initialRecord,\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n ...created.persistedMetadataState,\n },\n };\n}\n\nfunction buildLocalContainerContentsChildContainerState(input: {\n childId: string;\n icon: string | null;\n systemSlot?: ContainerSystemSlot | null | undefined;\n doc: ContainerMetadataDocumentState;\n initialRecord: DocumentRecord;\n parentState: ContainerState;\n trimmedName: string;\n}): ContainerState {\n const {\n systemSlot,\n childId,\n doc,\n icon,\n initialRecord,\n parentState,\n trimmedName,\n } = input;\n\n return {\n container: {\n id: childId,\n effectiveAccessLevel: \"admin\",\n organizationId: parentState.container.organizationId,\n parentId: parentState.container.id,\n metadataDocumentId: null,\n systemSlot: systemSlot ?? null,\n name: trimmedName,\n icon,\n },\n doc,\n record: initialRecord,\n };\n}\n\nfunction createInitialChildContainerDocumentRecord(input: {\n childId: string;\n initialUpdate: Uint8Array;\n}): DocumentRecord {\n return {\n accessEpoch: 1,\n accessStateHash: null,\n contentKeyBundle: null,\n documentId: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n id: input.childId,\n lastCommitLsn: null,\n metadataUpdates: bytesToBase64(input.initialUpdate),\n snapshotEndVersion: \"\",\n };\n}\n\nfunction resolveAtomicChildContainerSave(\n persistence: ContainerContentsPersistence,\n): NonNullable<\n ContainerContentsPersistence[\"saveContainerWithPendingUpdate\"]\n> | null {\n const saveContainerWithPendingUpdate =\n persistence.saveContainerWithPendingUpdate;\n if (!saveContainerWithPendingUpdate) return null;\n const inheritedSqlAtomicSave =\n saveContainerWithPendingUpdate ===\n defaultContainerContentsPersistence.saveContainerWithPendingUpdate &&\n (persistence.saveContainer !==\n defaultContainerContentsPersistence.saveContainer ||\n persistence.enqueuePendingUpdate !==\n defaultContainerContentsPersistence.enqueuePendingUpdate);\n return inheritedSqlAtomicSave ? null : saveContainerWithPendingUpdate;\n}\n\nasync function persistCreatedChildContainer(input: {\n containerState: ContainerState;\n initialUpdate: Uint8Array;\n persistence: ContainerContentsPersistence;\n queueRemoteSync: boolean;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<boolean | null> {\n const { containerState, persistence, queueRemoteSync, runtime } = input;\n const createIntent =\n queueRemoteSync &&\n !containerState.record.documentId &&\n containerState.container.parentId\n ? { parentContainerId: containerState.container.parentId }\n : undefined;\n const shouldRequestSync =\n queueRemoteSync &&\n (!containerState.record.documentId ||\n Boolean(containerState.record.contentKeyBundle));\n const saveOptions =\n createIntent || input.stillCurrent\n ? {\n ...(createIntent ? { createIntent } : {}),\n stillCurrent: input.stillCurrent,\n }\n : undefined;\n const pendingUpdate = shouldRequestSync\n ? createPendingUpdateFields(input.initialUpdate)\n : null;\n if (pendingUpdate) {\n const saveContainerWithPendingUpdate =\n resolveAtomicChildContainerSave(persistence);\n if (!saveContainerWithPendingUpdate) return null;\n containerState.container = await saveContainerWithPendingUpdate(\n runtime.infra.execSql,\n containerState.container,\n containerState.record,\n { ...saveOptions, pendingUpdate },\n );\n } else {\n containerState.container = await persistence.saveContainer(\n runtime.infra.execSql,\n containerState.container,\n containerState.record,\n saveOptions,\n );\n }\n return input.stillCurrent?.() === false ? null : shouldRequestSync;\n}\n\nexport async function createChildContainerState(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n createRemote: boolean;\n icon?: string | null | undefined;\n name: string;\n parentState: ContainerState;\n persistence: ContainerContentsPersistence;\n queueRemoteSync?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedChildContainerState | null> {\n const {\n createRemote,\n systemSlot,\n name,\n parentState,\n persistence,\n queueRemoteSync = true,\n resolveProjectionUserKey,\n runtime,\n } = input;\n const trimmedName = name.trim();\n if (!trimmedName) {\n return null;\n }\n\n const icon = input.icon?.trim() || null;\n const childId = await createChildContainerId(\n parentState.container.id,\n systemSlot,\n );\n const { doc, initialUpdate } =\n await createInitializedContainerMetadataDocument(childId, {\n icon,\n name: trimmedName,\n });\n const initialRecord = createInitialChildContainerDocumentRecord({\n childId,\n initialUpdate,\n });\n if (input.stillCurrent?.() === false) return null;\n // An initial metadata update and its container identity are one durable unit.\n // Refuse before any remote create when an adapter cannot provide\n // that atomic operation; a SQLite transaction cannot roll back adapter-owned\n // side effects.\n if (queueRemoteSync && !resolveAtomicChildContainerSave(persistence)) {\n return null;\n }\n\n const remoteChildState = createRemote\n ? await buildRemoteContainerContentsChildContainerState({\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n resolveProjectionUserKey,\n runtime,\n stillCurrent: input.stillCurrent,\n trimmedName,\n })\n : null;\n const containerState =\n remoteChildState ??\n buildLocalContainerContentsChildContainerState({\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n trimmedName,\n });\n const shouldRequestSync = await persistCreatedChildContainer({\n containerState,\n initialUpdate,\n persistence,\n queueRemoteSync,\n runtime,\n stillCurrent: input.stillCurrent,\n });\n if (shouldRequestSync === null) return null;\n\n return {\n containerState,\n initialUpdate,\n shouldRequestSync,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createChild.js","sourceRoot":"","sources":["createChild.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport { createInitializedContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport { createPendingUpdateFields } from \"../../../data/documents/documentSync\";\nimport { deriveStableUuidV4Shaped } from \"../../../data/keying/stableUuid\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport type {\n ContainerContentsPersistence,\n ContainerDocumentRecord as DocumentRecord,\n} from \"../containerPersistence\";\nimport { defaultContainerContentsPersistence } from \"../containerPersistence\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\nimport { loadContainerWriterProjectionForState } from \"./projectionCache\";\nimport { createRemoteContainer } from \"./remote\";\nimport type {\n ContainerMetadataDocumentState,\n ContainerWorkflowRuntime,\n CreatedChildContainerState,\n} from \"./types\";\n\nconst SYSTEM_CONTAINER_ID_NAMESPACE_BYTES = new Uint8Array([\n 0xc5, 0x5e, 0x8f, 0x2e, 0x3d, 0x82, 0x4b, 0x4d, 0x8d, 0xbd, 0x0d, 0xd2, 0xd3,\n 0x60, 0xb3, 0x6d,\n]);\n\n/**\n * Derives a stable, UUID-shaped container id for a built-in system slot.\n *\n * The namespace digest makes each slot idempotent across stale store snapshots.\n * The UUID version and variant bits are normalized to a v4 shape because remote\n * container APIs currently validate container ids with the same v4 UUID contract\n * they use for random user-created containers.\n */\nfunction deriveSystemContainerId(input: {\n parentContainerId: string;\n systemSlot: ContainerSystemSlot;\n}): Promise<string> {\n return deriveStableUuidV4Shaped(\n SYSTEM_CONTAINER_ID_NAMESPACE_BYTES,\n `${input.parentContainerId}\\u0000${input.systemSlot}`,\n );\n}\n\nasync function createChildContainerId(\n parentContainerId: string,\n systemSlot: ContainerSystemSlot | null | undefined,\n): Promise<string> {\n return systemSlot\n ? deriveSystemContainerId({ parentContainerId, systemSlot })\n : crypto.randomUUID();\n}\n\nasync function buildRemoteContainerContentsChildContainerState(input: {\n childId: string;\n icon: string | null;\n systemSlot?: ContainerSystemSlot | null | undefined;\n doc: ContainerMetadataDocumentState;\n initialRecord: DocumentRecord;\n parentState: ContainerState;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n trimmedName: string;\n}): Promise<ContainerState | null> {\n const {\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n resolveProjectionUserKey,\n runtime,\n stillCurrent,\n trimmedName,\n } = input;\n const parentProjection = await loadContainerWriterProjectionForState({\n containerState: parentState,\n runtime,\n });\n if (!parentProjection) {\n return null;\n }\n\n const created = await createRemoteContainer({\n systemSlot,\n containerId: childId,\n parentContainerId: parentState.container.id,\n parentProjection,\n resolveProjectionUserKey,\n runtime,\n stillCurrent,\n });\n\n if (!created || created === CONTAINER_ALREADY_COMMITTED) {\n // A benign manifest-exists conflict means the container is already committed\n // remotely (a lost create response). This eager path cannot rebuild its\n // committed metadata state, so leave the create intent to reconcile it via\n // hydration rather than fabricating a local record from a missing response.\n return null;\n }\n\n return {\n container: {\n id: created.containerId,\n // The creator owns a newly-created container until the server reconciles.\n effectiveAccessLevel: \"admin\",\n organizationId: created.organizationId,\n parentId: created.parentId,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n name: trimmedName,\n icon,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n },\n doc,\n record: {\n ...initialRecord,\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n ...created.persistedMetadataState,\n },\n };\n}\n\nfunction buildLocalContainerContentsChildContainerState(input: {\n childId: string;\n icon: string | null;\n systemSlot?: ContainerSystemSlot | null | undefined;\n doc: ContainerMetadataDocumentState;\n initialRecord: DocumentRecord;\n parentState: ContainerState;\n trimmedName: string;\n}): ContainerState {\n const {\n systemSlot,\n childId,\n doc,\n icon,\n initialRecord,\n parentState,\n trimmedName,\n } = input;\n\n return {\n container: {\n id: childId,\n effectiveAccessLevel: \"admin\",\n organizationId: parentState.container.organizationId,\n parentId: parentState.container.id,\n metadataDocumentId: null,\n systemSlot: systemSlot ?? null,\n name: trimmedName,\n icon,\n },\n doc,\n record: initialRecord,\n };\n}\n\nfunction createInitialChildContainerDocumentRecord(input: {\n childId: string;\n initialUpdate: Uint8Array;\n}): DocumentRecord {\n return {\n accessEpoch: 1,\n accessStateHash: null,\n contentKeyBundle: null,\n documentId: null,\n documentKekTargets: null,\n documentManifestBundle: null,\n id: input.childId,\n lastCommitLsn: null,\n metadataUpdates: bytesToBase64(input.initialUpdate),\n snapshotEndVersion: \"\",\n };\n}\n\nfunction resolveAtomicChildContainerSave(\n persistence: ContainerContentsPersistence,\n): NonNullable<\n ContainerContentsPersistence[\"saveContainerWithPendingUpdate\"]\n> | null {\n const saveContainerWithPendingUpdate =\n persistence.saveContainerWithPendingUpdate;\n if (!saveContainerWithPendingUpdate) return null;\n const inheritedSqlAtomicSave =\n saveContainerWithPendingUpdate ===\n defaultContainerContentsPersistence.saveContainerWithPendingUpdate &&\n (persistence.saveContainer !==\n defaultContainerContentsPersistence.saveContainer ||\n persistence.enqueuePendingUpdate !==\n defaultContainerContentsPersistence.enqueuePendingUpdate);\n return inheritedSqlAtomicSave ? null : saveContainerWithPendingUpdate;\n}\n\nasync function persistCreatedChildContainer(input: {\n containerState: ContainerState;\n initialUpdate: Uint8Array;\n persistence: ContainerContentsPersistence;\n queueRemoteSync: boolean;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<boolean | null> {\n const { containerState, persistence, queueRemoteSync, runtime } = input;\n const createIntent =\n queueRemoteSync &&\n !containerState.record.documentId &&\n containerState.container.parentId\n ? { parentContainerId: containerState.container.parentId }\n : undefined;\n const shouldRequestSync =\n queueRemoteSync &&\n (!containerState.record.documentId ||\n Boolean(containerState.record.contentKeyBundle));\n const saveOptions =\n createIntent || input.stillCurrent\n ? {\n ...(createIntent ? { createIntent } : {}),\n stillCurrent: input.stillCurrent,\n }\n : undefined;\n const pendingUpdate = shouldRequestSync\n ? createPendingUpdateFields(input.initialUpdate)\n : null;\n if (pendingUpdate) {\n const saveContainerWithPendingUpdate =\n resolveAtomicChildContainerSave(persistence);\n if (!saveContainerWithPendingUpdate) return null;\n containerState.container = await saveContainerWithPendingUpdate(\n runtime.infra.execSql,\n containerState.container,\n containerState.record,\n { ...saveOptions, pendingUpdate },\n );\n } else {\n containerState.container = await persistence.saveContainer(\n runtime.infra.execSql,\n containerState.container,\n containerState.record,\n saveOptions,\n );\n }\n return input.stillCurrent?.() === false ? null : shouldRequestSync;\n}\n\nexport async function createChildContainerState(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n createRemote: boolean;\n icon?: string | null | undefined;\n name: string;\n parentState: ContainerState;\n persistence: ContainerContentsPersistence;\n queueRemoteSync?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedChildContainerState | null> {\n const {\n createRemote,\n systemSlot,\n name,\n parentState,\n persistence,\n queueRemoteSync = true,\n resolveProjectionUserKey,\n runtime,\n } = input;\n const trimmedName = name.trim();\n if (!trimmedName) {\n return null;\n }\n\n const icon = input.icon?.trim() || null;\n const childId = await createChildContainerId(\n parentState.container.id,\n systemSlot,\n );\n const { doc, initialUpdate } =\n await createInitializedContainerMetadataDocument(childId, {\n icon,\n name: trimmedName,\n });\n const initialRecord = createInitialChildContainerDocumentRecord({\n childId,\n initialUpdate,\n });\n if (input.stillCurrent?.() === false) return null;\n // An initial metadata update and its container identity are one durable unit.\n // Refuse before any remote create when an adapter cannot provide\n // that atomic operation; a SQLite transaction cannot roll back adapter-owned\n // side effects.\n if (queueRemoteSync && !resolveAtomicChildContainerSave(persistence)) {\n return null;\n }\n\n const remoteChildState = createRemote\n ? await buildRemoteContainerContentsChildContainerState({\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n resolveProjectionUserKey,\n runtime,\n stillCurrent: input.stillCurrent,\n trimmedName,\n })\n : null;\n const containerState =\n remoteChildState ??\n buildLocalContainerContentsChildContainerState({\n childId,\n icon,\n systemSlot,\n doc,\n initialRecord,\n parentState,\n trimmedName,\n });\n const shouldRequestSync = await persistCreatedChildContainer({\n containerState,\n initialUpdate,\n persistence,\n queueRemoteSync,\n runtime,\n stillCurrent: input.stillCurrent,\n });\n if (shouldRequestSync === null) return null;\n\n return {\n containerState,\n initialUpdate,\n shouldRequestSync,\n };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ContainerPathTooDeepError } from "../../../data/containers/shared/containerPathLimits.js";
|
|
2
|
-
import { errorMessage } from "../../../data/errorMessage.js";
|
|
3
2
|
import { reportAndRethrowKeyingVerificationError } from "../../../data/keyingProjectionVerification/error.js";
|
|
4
3
|
import { ContainerCreateIntentSupersededError } from "../../../data/persistence/container-contents/containerIntentPersistence.js";
|
|
4
|
+
import { errorMessage } from "../../../data/shared/errorMessage.js";
|
|
5
5
|
import { createDetachedContainerMetadataState, installDetachedContainerMetadataState, } from "../metadataStateIsolation.js";
|
|
6
6
|
import { hasRemoteContainerMetadataState } from "../remoteHydration/reconciliation.js";
|
|
7
7
|
import { syncListedContainerCreate } from "./createAdoption.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createIntentSync.js","sourceRoot":"","sources":["createIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { errorMessage } from \"../../../data/errorMessage\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { ContainerCreateIntentSupersededError } from \"../../../data/persistence/container-contents/containerIntentPersistence\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadataStateIsolation\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { syncListedContainerCreate } from \"./createAdoption\";\nimport {\n deferTooDeepCreate,\n recordRefusedTooDeepCreate,\n} from \"./createIntentDepth\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\nimport { createRemoteContainer, deleteRemoteContainer } from \"./remote\";\nimport type {\n ContainerCreateIntentSyncHost,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n CreatedRemoteContainerState,\n} from \"./types\";\n\nclass IncompleteContainerCreateSettlementError extends Error {}\n\ntype CreateIntentSyncResult = \"abandoned\" | \"blocked\" | \"created\" | \"failed\";\n\nfunction currentCreateResult<\n Result extends Exclude<CreateIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function reportContainerCreateIntegrityFailure(input: {\n readonly containerId: string;\n readonly error: unknown;\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n await reportAndRethrowKeyingVerificationError(\n input.error,\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: input.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n}\n\nasync function recordContainerCreateFailure(input: {\n readonly error: unknown;\n readonly isCurrent: () => boolean;\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<\"abandoned\" | \"failed\"> {\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await reportContainerCreateIntegrityFailure({\n containerId: input.intent.containerId,\n error: input.error,\n organizationId: input.organizationId,\n state: input.state,\n });\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await input.state.persistence.recordCreateIntentRevisionError(\n input.state.runtime.infra.execSql,\n {\n containerId: input.intent.containerId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n message: `${input.error instanceof IncompleteContainerCreateSettlementError ? \"Container create persistence failed\" : \"Remote container create failed\"}: ${errorMessage(input.error)}`,\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n}\n\nasync function persistCreatedRemoteContainerStateFromIntent(input: {\n containerState: ContainerState;\n created: CreatedRemoteContainerState;\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerCreateIntentSyncInput[\"intent\"];\n state: ContainerCreateIntentSyncState;\n}): Promise<\n | \"abandoned\"\n | \"identity-superseded\"\n | \"intent-superseded\"\n | \"missing\"\n | \"persisted\"\n> {\n const { containerState, created, host, intent, state } = input;\n if (!input.isCurrent()) return \"abandoned\";\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) return \"abandoned\";\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n };\n\n let persistenceResult: Awaited<\n ReturnType<ContainerCreateIntentSyncHost[\"persistContainerState\"]>\n >;\n try {\n persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n lastCommitLsn: null,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: created.parentId,\n ...created.persistedMetadataState,\n },\n false,\n {\n serverTimestamps: {\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n },\n },\n {\n createIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n remoteContainerId: created.containerId,\n remoteMetadataAccessStateHash: created.accessManifestHash,\n remoteMetadataDocumentId: created.metadataDocumentId,\n supersededMovePreviousParentId: created.parentId,\n },\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n preserveDurableStructureWhenPending: true,\n },\n );\n } catch (error) {\n if (error instanceof ContainerCreateIntentSupersededError) {\n return \"intent-superseded\";\n }\n throw error;\n }\n if (!input.isCurrent() || persistenceResult.status === \"stale-generation\") {\n return \"abandoned\";\n }\n if (persistenceResult.status !== \"persisted\") return persistenceResult.status;\n if (persistenceResult.createIntentSettled !== true) {\n throw new IncompleteContainerCreateSettlementError(\n \"Container create persistence must settle the intent atomically\",\n );\n }\n const { record: nextRecord } = persistenceResult;\n if (!input.isCurrent()) return \"abandoned\";\n const currentContainerState = state.containersById.get(intent.containerId);\n if (!currentContainerState) return \"missing\";\n if (currentContainerState !== containerState) return \"identity-superseded\";\n\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: persistenceCandidate.container.parentId,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n };\n return \"persisted\";\n}\n\nasync function discardOrphanedRemoteContainer(input: {\n created: CreatedRemoteContainerState;\n isCurrent: () => boolean;\n state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n if (!input.isCurrent()) {\n return;\n }\n const discardFailure = await deleteRemoteContainer({\n containerId: input.created.containerId,\n organizationId: input.created.organizationId,\n runtime: input.state.runtime,\n }).then(\n (deleted) => (deleted ? null : \"the server rejected the delete\"),\n (error: unknown) => errorMessage(error),\n );\n if (input.isCurrent() && discardFailure !== null) {\n input.state.runtime.util.log(\n `Container contents: failed to discard orphaned remote container ${input.created.containerId} after local delete: ${discardFailure}`,\n );\n }\n}\n\nasync function settleRemoteContainerCreate(input: {\n containerState: ContainerState;\n created: Awaited<ReturnType<typeof createRemoteContainer>>;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, created, syncInput } = input;\n const { host, intent, state } = syncInput;\n if (created === CONTAINER_ALREADY_COMMITTED) {\n // A lost create response leaves the intent pending until hydration installs\n // the committed remote metadata state.\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; container already committed remotely, awaiting hydration.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (!created) {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Remote container create was rejected or unavailable\",\n stillCurrent: syncInput.isCurrent,\n },\n );\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (!state.containersById.has(intent.containerId)) {\n // A same-generation local delete wins; discard the remote orphan instead\n // of resurrecting the deleted local container.\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n\n const persistenceStatus = await persistCreatedRemoteContainerStateFromIntent({\n containerState,\n created,\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n state,\n });\n if (persistenceStatus === \"abandoned\") {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n if (persistenceStatus === \"missing\") {\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (persistenceStatus === \"identity-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; another writer persisted its remote identity.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (persistenceStatus === \"intent-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; a newer local intent superseded this pass.`,\n );\n return \"blocked\";\n }\n state.runtime.util.log(\n `Container contents: synced local container create ${containerState.container.id}`,\n );\n return \"created\";\n}\n\nasync function createPendingRemoteContainer(input: {\n containerState: ContainerState;\n parentState: ContainerState;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, parentState, syncInput } = input;\n const { intent, state } = syncInput;\n let created: Awaited<ReturnType<typeof createRemoteContainer>>;\n try {\n created = await createRemoteContainer({\n systemSlot: containerState.container.systemSlot,\n containerId: containerState.container.id,\n parentContainerId: parentState.container.id,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n } catch (error) {\n if (error instanceof ContainerPathTooDeepError)\n return recordRefusedTooDeepCreate(syncInput);\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n try {\n return await settleRemoteContainerCreate({\n containerState,\n created,\n syncInput,\n });\n } catch (error) {\n if (!(error instanceof IncompleteContainerCreateSettlementError))\n throw error;\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n}\n\nasync function trySyncPendingContainerContentsContainerCreateIntent(\n input: ContainerCreateIntentSyncInput,\n): Promise<CreateIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState || !parentState) {\n const execSql = state.runtime.infra.execSql;\n await state.persistence.recordCreateIntentRevisionError(execSql, {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create intent references a missing local container\",\n stillCurrent: input.isCurrent,\n });\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (typeof state.persistence.markCreateIntentRevisionSynced !== \"function\") {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create replay requires revision-CAS persistence\",\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (input.isRemoteSyncBlocked(parentState.container.organizationId)) {\n return \"blocked\";\n }\n\n if (hasRemoteContainerMetadataState(containerState)) {\n return syncListedContainerCreate({\n containerState,\n parentState,\n syncInput: input,\n });\n }\n\n // A parent whose own create has not settled may carry a listed identity\n // adoption has not verified, or has refused; nothing is created under it.\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(parentState.container.id)\n ) {\n return \"blocked\";\n }\n\n if (await deferTooDeepCreate(input)) {\n return currentCreateResult(input.isCurrent, \"blocked\");\n }\n\n return createPendingRemoteContainer({\n containerState,\n parentState,\n syncInput: input,\n });\n}\n\nexport async function syncPendingContainerCreateIntents(input: {\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listPendingCreateIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n const remainingContainerIds = new Set(\n pendingIntents.map((intent) => intent.containerId),\n );\n // Only a create that settles in this pass leaves the pending set; a failed\n // or parked one stays pending even though this pass stops retrying it.\n const unsettledContainerIds = new Set(remainingContainerIds);\n let createdCount = 0;\n let progressed = true;\n\n while (progressed && input.isCurrent()) {\n progressed = false;\n\n for (const intent of pendingIntents) {\n if (!remainingContainerIds.has(intent.containerId)) {\n continue;\n }\n\n const result = await trySyncPendingContainerContentsContainerCreateIntent(\n {\n host,\n isCreatePending: (containerId) =>\n unsettledContainerIds.has(containerId),\n isCurrent: input.isCurrent,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n },\n );\n if (result === \"abandoned\") {\n return createdCount;\n }\n\n if (result === \"blocked\") {\n continue;\n }\n\n remainingContainerIds.delete(intent.containerId);\n progressed = result === \"created\" || progressed;\n if (result === \"created\") {\n createdCount += 1;\n unsettledContainerIds.delete(intent.containerId);\n }\n }\n }\n\n return createdCount;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createIntentSync.js","sourceRoot":"","sources":["createIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { ContainerCreateIntentSupersededError } from \"../../../data/persistence/container-contents/containerIntentPersistence\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadataStateIsolation\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { syncListedContainerCreate } from \"./createAdoption\";\nimport {\n deferTooDeepCreate,\n recordRefusedTooDeepCreate,\n} from \"./createIntentDepth\";\nimport { CONTAINER_ALREADY_COMMITTED } from \"./createWithMetadata\";\nimport { createRemoteContainer, deleteRemoteContainer } from \"./remote\";\nimport type {\n ContainerCreateIntentSyncHost,\n ContainerCreateIntentSyncInput,\n ContainerCreateIntentSyncState,\n CreatedRemoteContainerState,\n} from \"./types\";\n\nclass IncompleteContainerCreateSettlementError extends Error {}\n\ntype CreateIntentSyncResult = \"abandoned\" | \"blocked\" | \"created\" | \"failed\";\n\nfunction currentCreateResult<\n Result extends Exclude<CreateIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function reportContainerCreateIntegrityFailure(input: {\n readonly containerId: string;\n readonly error: unknown;\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n await reportAndRethrowKeyingVerificationError(\n input.error,\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: input.containerId,\n objectKind: \"container\",\n operation: \"container.create.replay\",\n organizationId: input.organizationId,\n },\n );\n}\n\nasync function recordContainerCreateFailure(input: {\n readonly error: unknown;\n readonly isCurrent: () => boolean;\n readonly intent: ContainerCreateIntentSyncInput[\"intent\"];\n readonly organizationId: string;\n readonly state: ContainerCreateIntentSyncState;\n}): Promise<\"abandoned\" | \"failed\"> {\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await reportContainerCreateIntegrityFailure({\n containerId: input.intent.containerId,\n error: input.error,\n organizationId: input.organizationId,\n state: input.state,\n });\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n await input.state.persistence.recordCreateIntentRevisionError(\n input.state.runtime.infra.execSql,\n {\n containerId: input.intent.containerId,\n expectedIntentId: input.intent.id,\n expectedUpdatedAt: input.intent.updatedAt,\n message: `${input.error instanceof IncompleteContainerCreateSettlementError ? \"Container create persistence failed\" : \"Remote container create failed\"}: ${errorMessage(input.error)}`,\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n}\n\nasync function persistCreatedRemoteContainerStateFromIntent(input: {\n containerState: ContainerState;\n created: CreatedRemoteContainerState;\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerCreateIntentSyncInput[\"intent\"];\n state: ContainerCreateIntentSyncState;\n}): Promise<\n | \"abandoned\"\n | \"identity-superseded\"\n | \"intent-superseded\"\n | \"missing\"\n | \"persisted\"\n> {\n const { containerState, created, host, intent, state } = input;\n if (!input.isCurrent()) return \"abandoned\";\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) return \"abandoned\";\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: created.createdAt,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n updatedAt: created.updatedAt,\n };\n\n let persistenceResult: Awaited<\n ReturnType<ContainerCreateIntentSyncHost[\"persistContainerState\"]>\n >;\n try {\n persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: 1,\n accessStateHash: created.accessManifestHash,\n lastCommitLsn: null,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: created.parentId,\n ...created.persistedMetadataState,\n },\n false,\n {\n serverTimestamps: {\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n },\n },\n {\n createIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n remoteContainerId: created.containerId,\n remoteMetadataAccessStateHash: created.accessManifestHash,\n remoteMetadataDocumentId: created.metadataDocumentId,\n supersededMovePreviousParentId: created.parentId,\n },\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n preserveDurableStructureWhenPending: true,\n },\n );\n } catch (error) {\n if (error instanceof ContainerCreateIntentSupersededError) {\n return \"intent-superseded\";\n }\n throw error;\n }\n if (!input.isCurrent() || persistenceResult.status === \"stale-generation\") {\n return \"abandoned\";\n }\n if (persistenceResult.status !== \"persisted\") return persistenceResult.status;\n if (persistenceResult.createIntentSettled !== true) {\n throw new IncompleteContainerCreateSettlementError(\n \"Container create persistence must settle the intent atomically\",\n );\n }\n const { record: nextRecord } = persistenceResult;\n if (!input.isCurrent()) return \"abandoned\";\n const currentContainerState = state.containersById.get(intent.containerId);\n if (!currentContainerState) return \"missing\";\n if (currentContainerState !== containerState) return \"identity-superseded\";\n\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: created.metadataDocumentId,\n systemSlot: created.systemSlot,\n organizationId: created.organizationId,\n parentId: persistenceCandidate.container.parentId,\n serverCreatedAt: created.createdAt,\n serverUpdatedAt: created.updatedAt,\n createdAt: created.createdAt,\n updatedAt: created.updatedAt,\n };\n return \"persisted\";\n}\n\nasync function discardOrphanedRemoteContainer(input: {\n created: CreatedRemoteContainerState;\n isCurrent: () => boolean;\n state: ContainerCreateIntentSyncState;\n}): Promise<void> {\n if (!input.isCurrent()) {\n return;\n }\n const discardFailure = await deleteRemoteContainer({\n containerId: input.created.containerId,\n organizationId: input.created.organizationId,\n runtime: input.state.runtime,\n }).then(\n (deleted) => (deleted ? null : \"the server rejected the delete\"),\n (error: unknown) => errorMessage(error),\n );\n if (input.isCurrent() && discardFailure !== null) {\n input.state.runtime.util.log(\n `Container contents: failed to discard orphaned remote container ${input.created.containerId} after local delete: ${discardFailure}`,\n );\n }\n}\n\nasync function settleRemoteContainerCreate(input: {\n containerState: ContainerState;\n created: Awaited<ReturnType<typeof createRemoteContainer>>;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, created, syncInput } = input;\n const { host, intent, state } = syncInput;\n if (created === CONTAINER_ALREADY_COMMITTED) {\n // A lost create response leaves the intent pending until hydration installs\n // the committed remote metadata state.\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; container already committed remotely, awaiting hydration.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (!created) {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Remote container create was rejected or unavailable\",\n stillCurrent: syncInput.isCurrent,\n },\n );\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (!state.containersById.has(intent.containerId)) {\n // A same-generation local delete wins; discard the remote orphan instead\n // of resurrecting the deleted local container.\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n\n const persistenceStatus = await persistCreatedRemoteContainerStateFromIntent({\n containerState,\n created,\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n state,\n });\n if (persistenceStatus === \"abandoned\") {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n if (persistenceStatus === \"missing\") {\n await discardOrphanedRemoteContainer({\n created,\n isCurrent: syncInput.isCurrent,\n state,\n });\n return currentCreateResult(syncInput.isCurrent, \"failed\");\n }\n if (persistenceStatus === \"identity-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; another writer persisted its remote identity.`,\n );\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"blocked\";\n }\n if (persistenceStatus === \"intent-superseded\") {\n state.runtime.util.log(\n `Container contents: deferred create intent for ${intent.containerId}; a newer local intent superseded this pass.`,\n );\n return \"blocked\";\n }\n state.runtime.util.log(\n `Container contents: synced local container create ${containerState.container.id}`,\n );\n return \"created\";\n}\n\nasync function createPendingRemoteContainer(input: {\n containerState: ContainerState;\n parentState: ContainerState;\n syncInput: ContainerCreateIntentSyncInput;\n}): Promise<CreateIntentSyncResult> {\n const { containerState, parentState, syncInput } = input;\n const { intent, state } = syncInput;\n let created: Awaited<ReturnType<typeof createRemoteContainer>>;\n try {\n created = await createRemoteContainer({\n systemSlot: containerState.container.systemSlot,\n containerId: containerState.container.id,\n parentContainerId: parentState.container.id,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n } catch (error) {\n if (error instanceof ContainerPathTooDeepError)\n return recordRefusedTooDeepCreate(syncInput);\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n try {\n return await settleRemoteContainerCreate({\n containerState,\n created,\n syncInput,\n });\n } catch (error) {\n if (!(error instanceof IncompleteContainerCreateSettlementError))\n throw error;\n return recordContainerCreateFailure({\n error,\n isCurrent: syncInput.isCurrent,\n intent,\n organizationId: parentState.container.organizationId,\n state,\n });\n }\n}\n\nasync function trySyncPendingContainerContentsContainerCreateIntent(\n input: ContainerCreateIntentSyncInput,\n): Promise<CreateIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState || !parentState) {\n const execSql = state.runtime.infra.execSql;\n await state.persistence.recordCreateIntentRevisionError(execSql, {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create intent references a missing local container\",\n stillCurrent: input.isCurrent,\n });\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (typeof state.persistence.markCreateIntentRevisionSynced !== \"function\") {\n await state.persistence.recordCreateIntentRevisionError(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n message: \"Container create replay requires revision-CAS persistence\",\n stillCurrent: input.isCurrent,\n },\n );\n return currentCreateResult(input.isCurrent, \"failed\");\n }\n\n if (input.isRemoteSyncBlocked(parentState.container.organizationId)) {\n return \"blocked\";\n }\n\n if (hasRemoteContainerMetadataState(containerState)) {\n return syncListedContainerCreate({\n containerState,\n parentState,\n syncInput: input,\n });\n }\n\n // A parent whose own create has not settled may carry a listed identity\n // adoption has not verified, or has refused; nothing is created under it.\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(parentState.container.id)\n ) {\n return \"blocked\";\n }\n\n if (await deferTooDeepCreate(input)) {\n return currentCreateResult(input.isCurrent, \"blocked\");\n }\n\n return createPendingRemoteContainer({\n containerState,\n parentState,\n syncInput: input,\n });\n}\n\nexport async function syncPendingContainerCreateIntents(input: {\n host: ContainerCreateIntentSyncHost;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listPendingCreateIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n const remainingContainerIds = new Set(\n pendingIntents.map((intent) => intent.containerId),\n );\n // Only a create that settles in this pass leaves the pending set; a failed\n // or parked one stays pending even though this pass stops retrying it.\n const unsettledContainerIds = new Set(remainingContainerIds);\n let createdCount = 0;\n let progressed = true;\n\n while (progressed && input.isCurrent()) {\n progressed = false;\n\n for (const intent of pendingIntents) {\n if (!remainingContainerIds.has(intent.containerId)) {\n continue;\n }\n\n const result = await trySyncPendingContainerContentsContainerCreateIntent(\n {\n host,\n isCreatePending: (containerId) =>\n unsettledContainerIds.has(containerId),\n isCurrent: input.isCurrent,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n },\n );\n if (result === \"abandoned\") {\n return createdCount;\n }\n\n if (result === \"blocked\") {\n continue;\n }\n\n remainingContainerIds.delete(intent.containerId);\n progressed = result === \"created\" || progressed;\n if (result === \"created\") {\n createdCount += 1;\n unsettledContainerIds.delete(intent.containerId);\n }\n }\n }\n\n return createdCount;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getTargetContainerContext, readContainerState, } from "../../../data/containers/shared/projection.js";
|
|
2
|
-
import { nullOnProjectionVerificationCancellation, verifyContainerWriterProjection, } from "../../../data/keyingProjectionVerification.js";
|
|
2
|
+
import { nullOnProjectionVerificationCancellation, verifyContainerWriterProjection, } from "../../../data/keyingProjectionVerification/index.js";
|
|
3
3
|
import { ProjectionDependencyUnavailableError } from "../../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
4
4
|
import { principalPolicyCacheForVerifiedPolicies } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
|
|
5
5
|
import { referencedPrincipalHeadFromPolicy } from "../../containers/index.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ContainerPathTooDeepError } from "../../../data/containers/shared/containerPathLimits.js";
|
|
2
|
-
import { errorMessage } from "../../../data/errorMessage.js";
|
|
3
2
|
import { reportAndRethrowKeyingVerificationError } from "../../../data/keyingProjectionVerification/error.js";
|
|
3
|
+
import { errorMessage } from "../../../data/shared/errorMessage.js";
|
|
4
4
|
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
5
5
|
import { createDetachedContainerMetadataState, installDetachedContainerMetadataState, } from "../metadataStateIsolation.js";
|
|
6
6
|
import { hasRemoteContainerMetadataState } from "../remoteHydration/reconciliation.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moveIntentSync.js","sourceRoot":"","sources":["moveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { errorMessage } from \"../../../data/errorMessage\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadataStateIsolation\";\nimport type { ContainerState, RemoteContainer } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { moveRemoteContainer } from \"./remote\";\nimport type {\n ContainerMoveIntentSyncHost,\n ContainerMoveIntentSyncInput,\n ContainerMoveIntentSyncState,\n} from \"./types\";\n\ntype MoveIntentSyncResult = \"abandoned\" | \"blocked\" | \"failed\" | \"moved\";\n\nfunction currentMoveResult<\n Result extends Exclude<MoveIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function recordPendingMoveIntentError(input: {\n blocked?: boolean | undefined;\n containerId: string;\n expectedIntentId: string;\n expectedUpdatedAt: string;\n isCurrent: () => boolean;\n message: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n if (!input.isCurrent()) {\n return false;\n }\n const execSql = input.state.runtime.infra.execSql;\n await input.state.persistence.recordMoveIntentError(execSql, {\n blocked: input.blocked,\n containerId: input.containerId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n });\n return input.isCurrent();\n}\n\nasync function resolveMoveIntentLocalUpdatedAt(input: {\n containerId: string;\n isCurrent: () => boolean;\n remoteUpdatedAt: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<string | null> {\n if (!input.isCurrent()) {\n return null;\n }\n const previousLocalUpdatedAt =\n input.state.containersById.get(input.containerId)?.container\n .localUpdatedAt ?? null;\n if (\n !previousLocalUpdatedAt ||\n previousLocalUpdatedAt.localeCompare(input.remoteUpdatedAt) <= 0\n ) {\n return input.remoteUpdatedAt;\n }\n\n const execSql = input.state.runtime.infra.execSql;\n const containersWithPendingMetadataUpdates =\n await input.state.persistence.listContainerIdsWithPendingUpdates(execSql, [\n input.containerId,\n ]);\n if (!input.isCurrent()) {\n return null;\n }\n\n return containersWithPendingMetadataUpdates.includes(input.containerId)\n ? previousLocalUpdatedAt\n : input.remoteUpdatedAt;\n}\n\nexport async function persistAcceptedMoveIntent(input: {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerMoveIntentSyncInput[\"intent\"];\n moved: RemoteContainer;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const abandon = () => {\n input.requestRemoteReconciliation(moved.parentId);\n return false;\n };\n if (!input.isCurrent()) return abandon();\n const containerState = state.containersById.get(intent.containerId);\n if (!containerState) {\n return false;\n }\n\n await createRuntimePrincipalPolicyWarmer(state.runtime)({\n organizationId: moved.organizationId,\n references: moved.metadataReferencedPrincipals,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n return abandon();\n }\n const localUpdatedAt = await resolveMoveIntentLocalUpdatedAt({\n containerId: intent.containerId,\n isCurrent: input.isCurrent,\n remoteUpdatedAt: moved.updatedAt,\n state,\n });\n if (!input.isCurrent() || localUpdatedAt === null) {\n return abandon();\n }\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) {\n return abandon();\n }\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: moved.createdAt,\n serverCreatedAt: moved.createdAt,\n serverUpdatedAt: moved.updatedAt,\n updatedAt: moved.updatedAt,\n };\n const persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: moved.metadataAccessEpoch,\n accessStateHash: moved.metadataAccessStateHash,\n documentId: moved.metadataDocumentId,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n systemSlot: moved.systemSlot ?? null,\n },\n false,\n {\n localUpdatedAt,\n serverTimestamps: {\n createdAt: moved.createdAt,\n updatedAt: moved.updatedAt,\n },\n },\n {\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n moveIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n },\n },\n );\n if (!input.isCurrent() || persistenceResult.status !== \"persisted\") {\n return abandon();\n }\n if (persistenceResult.moveIntentSettled !== true) {\n throw new Error(\n \"Container move persistence must settle the intent atomically\",\n );\n }\n if (!input.isCurrent()) return abandon();\n const { record: nextRecord } = persistenceResult;\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n };\n return true;\n}\n\n/**\n * A move refused for path length never succeeds; the queue-time check saw only\n * the descendants this device holds. Drop the queued move and restore the\n * previous parent together: the server row never changed, so no listing would\n * ever put the folder back.\n */\nasync function abandonTooDeepMove(\n syncInput: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { host, intent, state } = syncInput;\n const previousParentId = intent.previousParentContainerId;\n if (previousParentId === null) {\n throw new Error(\"A queued container move must name its previous parent\");\n }\n const abandoned = await state.persistence.abandonMoveIntentRevision(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n previousParentContainerId: previousParentId,\n stillCurrent: syncInput.isCurrent,\n },\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n // A newer local move superseded this revision; it replays on its own.\n if (!abandoned) return \"failed\";\n const containerState = state.containersById.get(intent.containerId);\n if (containerState) {\n containerState.container = {\n ...containerState.container,\n parentId: previousParentId,\n };\n }\n host.updateSnapshot();\n state.runtime.util.log(\n `Container contents: abandoned queued move of ${intent.containerId}; its path would exceed the maximum depth`,\n );\n return \"failed\";\n}\n\nasync function movePendingRemoteContainer(input: {\n parentState: ContainerState;\n syncInput: ContainerMoveIntentSyncInput;\n}): Promise<MoveIntentSyncResult> {\n const { parentState, syncInput } = input;\n const { host, intent, state } = syncInput;\n let remoteMoveApplied = false;\n let remoteParentId: string | null = intent.parentContainerId;\n const abandonAppliedMove = () => {\n if (remoteMoveApplied) {\n syncInput.requestRemoteReconciliation(remoteParentId);\n }\n return \"abandoned\" as const;\n };\n try {\n const moved = await moveRemoteContainer({\n containerId: intent.containerId,\n parentContainerId: intent.parentContainerId,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n if (!moved) {\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: \"Remote container move was rejected or unavailable\",\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n remoteMoveApplied = true;\n remoteParentId = moved.parentId;\n if (!syncInput.isCurrent()) return abandonAppliedMove();\n\n const persisted = await persistAcceptedMoveIntent({\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n moved,\n requestRemoteReconciliation: syncInput.requestRemoteReconciliation,\n state,\n });\n if (!persisted) {\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n state.runtime.util.log(\n `Container contents: synced queued container move ${intent.containerId}`,\n );\n return \"moved\";\n } catch (error: unknown) {\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (error instanceof ContainerPathTooDeepError)\n return abandonTooDeepMove(syncInput);\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.move.replay\",\n organizationId: parentState.container.organizationId,\n },\n );\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: `Failed to sync container move: ${errorMessage(error)}`,\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n}\n\nasync function trySyncPendingContainerMoveIntent(\n input: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move intent references a missing local container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (!parentState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Container move intent references a missing destination parent container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (input.isRemoteSyncBlocked(containerState.container.organizationId)) {\n return \"blocked\";\n }\n if (\n !hasRemoteContainerMetadataState(containerState) ||\n input.isCreatePending(intent.containerId)\n ) {\n // Source not synced yet is TRANSIENT, exactly like the destination case\n // below: the source's own create intent syncs first (createIntentSync runs\n // before moveIntentSync in a pass), but if that create fails on this pass\n // the source still lacks remote metadata here. Keep the intent 'pending'\n // (not 'blocked') so the queue reports a retryable failure rather than a\n // missing-dependency block; either way listUnsyncedMoveIntents replays it\n // once the create lands.\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move source is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(intent.parentContainerId)\n ) {\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move destination parent is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n\n return movePendingRemoteContainer({ parentState, syncInput: input });\n}\n\nexport async function syncPendingContainerMoveIntents(input: {\n host: ContainerMoveIntentSyncHost;\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listUnsyncedMoveIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) {\n return movedCount;\n }\n const result = await trySyncPendingContainerMoveIntent({\n host,\n isCurrent: input.isCurrent,\n isCreatePending: input.isCreatePending,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n });\n if (result === \"abandoned\") {\n return movedCount;\n }\n\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"moveIntentSync.js","sourceRoot":"","sources":["moveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadataStateIsolation\";\nimport type { ContainerState, RemoteContainer } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { moveRemoteContainer } from \"./remote\";\nimport type {\n ContainerMoveIntentSyncHost,\n ContainerMoveIntentSyncInput,\n ContainerMoveIntentSyncState,\n} from \"./types\";\n\ntype MoveIntentSyncResult = \"abandoned\" | \"blocked\" | \"failed\" | \"moved\";\n\nfunction currentMoveResult<\n Result extends Exclude<MoveIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\nasync function recordPendingMoveIntentError(input: {\n blocked?: boolean | undefined;\n containerId: string;\n expectedIntentId: string;\n expectedUpdatedAt: string;\n isCurrent: () => boolean;\n message: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n if (!input.isCurrent()) {\n return false;\n }\n const execSql = input.state.runtime.infra.execSql;\n await input.state.persistence.recordMoveIntentError(execSql, {\n blocked: input.blocked,\n containerId: input.containerId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n });\n return input.isCurrent();\n}\n\nasync function resolveMoveIntentLocalUpdatedAt(input: {\n containerId: string;\n isCurrent: () => boolean;\n remoteUpdatedAt: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<string | null> {\n if (!input.isCurrent()) {\n return null;\n }\n const previousLocalUpdatedAt =\n input.state.containersById.get(input.containerId)?.container\n .localUpdatedAt ?? null;\n if (\n !previousLocalUpdatedAt ||\n previousLocalUpdatedAt.localeCompare(input.remoteUpdatedAt) <= 0\n ) {\n return input.remoteUpdatedAt;\n }\n\n const execSql = input.state.runtime.infra.execSql;\n const containersWithPendingMetadataUpdates =\n await input.state.persistence.listContainerIdsWithPendingUpdates(execSql, [\n input.containerId,\n ]);\n if (!input.isCurrent()) {\n return null;\n }\n\n return containersWithPendingMetadataUpdates.includes(input.containerId)\n ? previousLocalUpdatedAt\n : input.remoteUpdatedAt;\n}\n\nexport async function persistAcceptedMoveIntent(input: {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerMoveIntentSyncInput[\"intent\"];\n moved: RemoteContainer;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const abandon = () => {\n input.requestRemoteReconciliation(moved.parentId);\n return false;\n };\n if (!input.isCurrent()) return abandon();\n const containerState = state.containersById.get(intent.containerId);\n if (!containerState) {\n return false;\n }\n\n await createRuntimePrincipalPolicyWarmer(state.runtime)({\n organizationId: moved.organizationId,\n references: moved.metadataReferencedPrincipals,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n return abandon();\n }\n const localUpdatedAt = await resolveMoveIntentLocalUpdatedAt({\n containerId: intent.containerId,\n isCurrent: input.isCurrent,\n remoteUpdatedAt: moved.updatedAt,\n state,\n });\n if (!input.isCurrent() || localUpdatedAt === null) {\n return abandon();\n }\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) {\n return abandon();\n }\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: moved.createdAt,\n serverCreatedAt: moved.createdAt,\n serverUpdatedAt: moved.updatedAt,\n updatedAt: moved.updatedAt,\n };\n const persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: moved.metadataAccessEpoch,\n accessStateHash: moved.metadataAccessStateHash,\n documentId: moved.metadataDocumentId,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n systemSlot: moved.systemSlot ?? null,\n },\n false,\n {\n localUpdatedAt,\n serverTimestamps: {\n createdAt: moved.createdAt,\n updatedAt: moved.updatedAt,\n },\n },\n {\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n moveIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n },\n },\n );\n if (!input.isCurrent() || persistenceResult.status !== \"persisted\") {\n return abandon();\n }\n if (persistenceResult.moveIntentSettled !== true) {\n throw new Error(\n \"Container move persistence must settle the intent atomically\",\n );\n }\n if (!input.isCurrent()) return abandon();\n const { record: nextRecord } = persistenceResult;\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n };\n return true;\n}\n\n/**\n * A move refused for path length never succeeds; the queue-time check saw only\n * the descendants this device holds. Drop the queued move and restore the\n * previous parent together: the server row never changed, so no listing would\n * ever put the folder back.\n */\nasync function abandonTooDeepMove(\n syncInput: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { host, intent, state } = syncInput;\n const previousParentId = intent.previousParentContainerId;\n if (previousParentId === null) {\n throw new Error(\"A queued container move must name its previous parent\");\n }\n const abandoned = await state.persistence.abandonMoveIntentRevision(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n previousParentContainerId: previousParentId,\n stillCurrent: syncInput.isCurrent,\n },\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n // A newer local move superseded this revision; it replays on its own.\n if (!abandoned) return \"failed\";\n const containerState = state.containersById.get(intent.containerId);\n if (containerState) {\n containerState.container = {\n ...containerState.container,\n parentId: previousParentId,\n };\n }\n host.updateSnapshot();\n state.runtime.util.log(\n `Container contents: abandoned queued move of ${intent.containerId}; its path would exceed the maximum depth`,\n );\n return \"failed\";\n}\n\nasync function movePendingRemoteContainer(input: {\n parentState: ContainerState;\n syncInput: ContainerMoveIntentSyncInput;\n}): Promise<MoveIntentSyncResult> {\n const { parentState, syncInput } = input;\n const { host, intent, state } = syncInput;\n let remoteMoveApplied = false;\n let remoteParentId: string | null = intent.parentContainerId;\n const abandonAppliedMove = () => {\n if (remoteMoveApplied) {\n syncInput.requestRemoteReconciliation(remoteParentId);\n }\n return \"abandoned\" as const;\n };\n try {\n const moved = await moveRemoteContainer({\n containerId: intent.containerId,\n parentContainerId: intent.parentContainerId,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n if (!moved) {\n if (!syncInput.isCurrent()) {\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return \"abandoned\";\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: \"Remote container move was rejected or unavailable\",\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n remoteMoveApplied = true;\n remoteParentId = moved.parentId;\n if (!syncInput.isCurrent()) return abandonAppliedMove();\n\n const persisted = await persistAcceptedMoveIntent({\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n moved,\n requestRemoteReconciliation: syncInput.requestRemoteReconciliation,\n state,\n });\n if (!persisted) {\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n state.runtime.util.log(\n `Container contents: synced queued container move ${intent.containerId}`,\n );\n return \"moved\";\n } catch (error: unknown) {\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (error instanceof ContainerPathTooDeepError)\n return abandonTooDeepMove(syncInput);\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.move.replay\",\n organizationId: parentState.container.organizationId,\n },\n );\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: `Failed to sync container move: ${errorMessage(error)}`,\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n}\n\nasync function trySyncPendingContainerMoveIntent(\n input: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move intent references a missing local container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (!parentState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Container move intent references a missing destination parent container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (input.isRemoteSyncBlocked(containerState.container.organizationId)) {\n return \"blocked\";\n }\n if (\n !hasRemoteContainerMetadataState(containerState) ||\n input.isCreatePending(intent.containerId)\n ) {\n // Source not synced yet is TRANSIENT, exactly like the destination case\n // below: the source's own create intent syncs first (createIntentSync runs\n // before moveIntentSync in a pass), but if that create fails on this pass\n // the source still lacks remote metadata here. Keep the intent 'pending'\n // (not 'blocked') so the queue reports a retryable failure rather than a\n // missing-dependency block; either way listUnsyncedMoveIntents replays it\n // once the create lands.\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move source is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(intent.parentContainerId)\n ) {\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move destination parent is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n\n return movePendingRemoteContainer({ parentState, syncInput: input });\n}\n\nexport async function syncPendingContainerMoveIntents(input: {\n host: ContainerMoveIntentSyncHost;\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listUnsyncedMoveIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) {\n return movedCount;\n }\n const result = await trySyncPendingContainerMoveIntent({\n host,\n isCurrent: input.isCurrent,\n isCreatePending: input.isCreatePending,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n });\n if (result === \"abandoned\") {\n return movedCount;\n }\n\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { KeyingVerificationError } from "../../../internal/crypto/index.js";
|
|
2
|
-
import { errorMessage } from "../../../data/errorMessage.js";
|
|
3
2
|
import { verifyContainerWriterProjection } from "../../../data/keyingProjectionVerification/containerProjectionVerification.js";
|
|
4
3
|
import { runWithSecurityIncidentReporting } from "../../../data/keyingProjectionVerification/error.js";
|
|
5
4
|
import { rethrowProjectionVerificationCancelled } from "../../../data/keyingProjectionVerification/types.js";
|
|
6
5
|
import { hasUnsettledDocumentPlacement } from "../../../data/persistence/container-contents/documentPurgePlacement.js";
|
|
7
6
|
import { sqlDocumentsPersistence } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
7
|
+
import { errorMessage } from "../../../data/shared/errorMessage.js";
|
|
8
8
|
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
9
9
|
import { assertLocalPurgeScope } from "./localPurgeScope.js";
|
|
10
10
|
import { snapshotContainerStates } from "./purgeTreeCollection.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purgeTreeScope.js","sourceRoot":"","sources":["purgeTreeScope.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type { DocumentSummary } from \"../../../data/documents/documentSummary\";\nimport { errorMessage } from \"../../../data/errorMessage\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { verifyContainerWriterProjection } from \"../../../data/keyingProjectionVerification/containerProjectionVerification\";\nimport { runWithSecurityIncidentReporting } from \"../../../data/keyingProjectionVerification/error\";\nimport { rethrowProjectionVerificationCancelled } from \"../../../data/keyingProjectionVerification/types\";\nimport { hasUnsettledDocumentPlacement } from \"../../../data/persistence/container-contents/documentPurgePlacement\";\nimport { sqlDocumentsPersistence } from \"../../../data/persistence/documents/documentsPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { ContainerContentsPersistence } from \"../containerPersistence\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\nimport { assertLocalPurgeScope } from \"./localPurgeScope\";\nimport { snapshotContainerStates } from \"./purgeTreeCollection\";\nimport { readLocalPurgeScope } from \"./readLocalPurgeScope\";\n\ninterface SubtreePurgeScopeInput {\n containersById: ReadonlyMap<string, ContainerState>;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rootContainerId: string;\n runtime: ContainerContentsWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nasync function verifiedRemoteScope(\n input: SubtreePurgeScopeInput,\n current: Pick<ContainerState, \"container\" | \"record\">,\n verifiedAncestorsById: Map<string, readonly string[]>,\n): Promise<boolean> {\n const { runtime, rootContainerId } = input;\n const targetId = current.container.id;\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: targetId,\n objectKind: \"container\",\n operation: \"container.purge.scope\",\n },\n async () => {\n runtime.apiClient.evictContainerWriterProjection(targetId);\n const projection =\n await runtime.apiClient.getContainerWriterProjection(targetId);\n if (!projection || input.stillCurrent?.() === false) return false;\n if (\n projection.containerId !== targetId ||\n projection.organizationId !== current.container.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Subtree purge container identity mismatch\",\n );\n }\n const path = await verifyContainerWriterProjection({\n execSql: runtime.infra.execSql,\n projection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n const rootIndex = path.findIndex(\n (head) => head.state.containerId === rootContainerId,\n );\n const latest = await input.persistence.loadContainerMetadataState(\n runtime.infra.execSql,\n targetId,\n );\n const pendingMoves = await readPendingMoves(input);\n const allowed =\n rootIndex >= 0 &&\n path[rootIndex]?.state.parentContainerId ===\n input.containersById.get(rootContainerId)?.container.parentId &&\n latest?.container.parentId === current.container.parentId &&\n latest.record?.documentId === current.record.documentId &&\n !path\n .slice(rootIndex)\n .some((head) => pendingMoves.has(head.state.containerId)) &&\n input.stillCurrent?.() !== false;\n if (allowed)\n verifiedAncestorsById.set(\n targetId,\n path.slice(rootIndex).map((head) => head.state.containerId),\n );\n return allowed;\n },\n );\n}\n\n/**\n * A local-only unit cites no signed request, so a remote ordinary root must\n * prove that it still sits under the parent it was selected from. A system\n * root's signed topology is fixed by its destination role.\n */\nasync function rootPlacementIsCurrent(\n input: SubtreePurgeScopeInput,\n verifiedAncestorsById: Map<string, readonly string[]>,\n): Promise<boolean> {\n const root = input.containersById.get(input.rootContainerId);\n if (!root?.record.documentId || (root.container.systemSlot ?? null) !== null)\n return true;\n return verifiedRemoteScope(input, root, verifiedAncestorsById);\n}\n\nasync function allowsContainer(\n input: SubtreePurgeScopeInput,\n containerId: string,\n verifiedAncestorsById: Map<string, readonly string[]>,\n localOnlyUnit: boolean,\n): Promise<boolean> {\n const { runtime, persistence, rootContainerId } = input;\n if (input.stillCurrent?.() === false) return false;\n const execSql = runtime.infra.execSql;\n const pendingMoves = await readPendingMoves(input);\n if (pendingMoves.has(rootContainerId)) return false;\n const seen = new Set<string>([rootContainerId]);\n let currentId: string | null = containerId;\n let verifiedRemoteAncestry = false;\n while (currentId !== rootContainerId) {\n if (!currentId || seen.has(currentId) || pendingMoves.has(currentId))\n return false;\n seen.add(currentId);\n const expected = input.containersById.get(currentId);\n const current = await persistence.loadContainerMetadataState(\n execSql,\n currentId,\n );\n if (\n !expected ||\n !current?.record ||\n current.container.parentId !== expected.container.parentId ||\n current.container.organizationId !== expected.container.organizationId ||\n current.record.documentId !== expected.record.documentId\n )\n return false;\n if (current.record.documentId) {\n if (\n !(await verifiedRemoteScope(\n input,\n {\n container: current.container,\n record: current.record,\n },\n verifiedAncestorsById,\n ))\n )\n return false;\n verifiedRemoteAncestry = true;\n break;\n }\n currentId = current.container.parentId;\n }\n if (\n localOnlyUnit &&\n !verifiedRemoteAncestry &&\n !(await rootPlacementIsCurrent(input, verifiedAncestorsById))\n )\n return false;\n return readLocalPurgeScope({\n ...input,\n containerId,\n execSql,\n verifiedAncestorsById,\n });\n}\n\nasync function readPendingMoves(input: SubtreePurgeScopeInput) {\n return new Set(\n (\n await input.persistence.listUnsyncedMoveIntents(\n input.runtime.infra.execSql,\n )\n ).map((intent) => intent.containerId),\n );\n}\n\nasync function documentPlacementIsCurrent(\n input: SubtreePurgeScopeInput,\n document: DocumentSummary,\n): Promise<boolean> {\n const execSql = input.runtime.infra.execSql;\n if (await hasUnsettledDocumentPlacement(execSql, document.id)) return false;\n const current = await sqlDocumentsPersistence.loadDocument(\n execSql,\n document.id,\n );\n return (\n current !== null &&\n current.documentId === document.documentId &&\n current.containerId === document.containerId &&\n input.stillCurrent?.() !== false\n );\n}\n\n/** Listing edges only select candidates; each destructive unit proves its scope. */\nexport function createSubtreePurgeScope(request: SubtreePurgeScopeInput) {\n const input = {\n ...request,\n containersById: snapshotContainerStates(request.containersById),\n };\n const verifiedAncestorsById = new Map<string, readonly string[]>();\n return {\n allowsLocalScopeInTransaction: (execSql: ExecSql, containerId: string) =>\n checkAvailableScope(input, async () => {\n await assertLocalPurgeScope({\n ...input,\n execSql,\n containerId,\n verifiedAncestorsById,\n });\n return true;\n }),\n assertLocalScopeInTransaction: (\n execSql: ExecSql,\n containerId: string | null | undefined,\n localId: string,\n ) =>\n assertLocalPurgeScope({\n ...input,\n execSql,\n containerId,\n localId,\n verifiedAncestorsById,\n }),\n allowsContainer: (containerId: string) =>\n checkAvailableScope(input, () =>\n allowsContainer(\n input,\n containerId,\n verifiedAncestorsById,\n !input.containersById.get(containerId)?.record.documentId,\n ),\n ),\n allowsDocument: (document: DocumentSummary) =>\n checkAvailableScope(input, async () => {\n if (\n !document.containerId ||\n !(await documentPlacementIsCurrent(input, document))\n )\n return false;\n if (\n !(await allowsContainer(\n input,\n document.containerId,\n verifiedAncestorsById,\n !document.documentId,\n ))\n )\n return false;\n // Freeze local placement checks together after all remote verification.\n return readLocalPurgeScope(\n {\n ...input,\n containerId: document.containerId,\n execSql: input.runtime.infra.execSql,\n localId: document.id,\n verifiedAncestorsById,\n },\n document,\n );\n }),\n };\n}\n\nasync function checkAvailableScope(\n input: SubtreePurgeScopeInput,\n check: () => Promise<boolean>,\n): Promise<boolean> {\n try {\n return await check();\n } catch (error) {\n rethrowProjectionVerificationCancelled(error);\n if (error instanceof KeyingVerificationError) throw error;\n input.runtime.util.log(\n `Container contents: purge scope unavailable: ${errorMessage(error)}`,\n );\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"purgeTreeScope.js","sourceRoot":"","sources":["purgeTreeScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,+BAA+B,EAAE,MAAM,4EAA4E,CAAC;AAC7H,OAAO,EAAE,gCAAgC,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,sCAAsC,EAAE,MAAM,kDAAkD,CAAC;AAC1G,OAAO,EAAE,6BAA6B,EAAE,MAAM,qEAAqE,CAAC;AACpH,OAAO,EAAE,uBAAuB,EAAE,MAAM,0DAA0D,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAI1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAW5D,KAAK,UAAU,mBAAmB,CAChC,KAA6B,EAC7B,OAAqD,EACrD,qBAAqD;IAErD,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACtC,OAAO,gCAAgC,CACrC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACnC;QACE,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,WAAW;QACvB,SAAS,EAAE,uBAAuB;KACnC,EACD,KAAK,IAAI,EAAE;QACT,OAAO,CAAC,SAAS,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,UAAU,GACd,MAAM,OAAO,CAAC,SAAS,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAClE,IACE,UAAU,CAAC,WAAW,KAAK,QAAQ;YACnC,UAAU,CAAC,cAAc,KAAK,OAAO,CAAC,SAAS,CAAC,cAAc,EAC9D,CAAC;YACD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,2CAA2C,CAC5C,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,+BAA+B,CAAC;YACjD,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;YAC9B,UAAU;YACV,cAAc,EAAE,KAAK,CAAC,wBAAwB;YAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAC7B,kCAAkC,CAAC,OAAO,CAAC;SAC9C,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAC9B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,eAAe,CACrD,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,0BAA0B,CAC/D,OAAO,CAAC,KAAK,CAAC,OAAO,EACrB,QAAQ,CACT,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,OAAO,GACX,SAAS,IAAI,CAAC;YACd,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,iBAAiB;gBACtC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC,QAAQ;YAC/D,MAAM,EAAE,SAAS,CAAC,QAAQ,KAAK,OAAO,CAAC,SAAS,CAAC,QAAQ;YACzD,MAAM,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,UAAU;YACvD,CAAC,IAAI;iBACF,KAAK,CAAC,SAAS,CAAC;iBAChB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3D,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CAAC;QACnC,IAAI,OAAO;YACT,qBAAqB,CAAC,GAAG,CACvB,QAAQ,EACR,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAC5D,CAAC;QACJ,OAAO,OAAO,CAAC;IACjB,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,sBAAsB,CACnC,KAA6B,EAC7B,qBAAqD;IAErD,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI;QAC1E,OAAO,IAAI,CAAC;IACd,OAAO,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,KAA6B,EAC7B,WAAmB,EACnB,qBAAqD,EACrD,aAAsB;IAEtB,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IACxD,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnD,IAAI,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC,eAAe,CAAC,CAAC,CAAC;IAChD,IAAI,SAAS,GAAkB,WAAW,CAAC;IAC3C,IAAI,sBAAsB,GAAG,KAAK,CAAC;IACnC,OAAO,SAAS,KAAK,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;YAClE,OAAO,KAAK,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,0BAA0B,CAC1D,OAAO,EACP,SAAS,CACV,CAAC;QACF,IACE,CAAC,QAAQ;YACT,CAAC,OAAO,EAAE,MAAM;YAChB,OAAO,CAAC,SAAS,CAAC,QAAQ,KAAK,QAAQ,CAAC,SAAS,CAAC,QAAQ;YAC1D,OAAO,CAAC,SAAS,CAAC,cAAc,KAAK,QAAQ,CAAC,SAAS,CAAC,cAAc;YACtE,OAAO,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,MAAM,CAAC,UAAU;YAExD,OAAO,KAAK,CAAC;QACf,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC9B,IACE,CAAC,CAAC,MAAM,mBAAmB,CACzB,KAAK,EACL;gBACE,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,EACD,qBAAqB,CACtB,CAAC;gBAEF,OAAO,KAAK,CAAC;YACf,sBAAsB,GAAG,IAAI,CAAC;YAC9B,MAAM;QACR,CAAC;QACD,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC;IACzC,CAAC;IACD,IACE,aAAa;QACb,CAAC,sBAAsB;QACvB,CAAC,CAAC,MAAM,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAE7D,OAAO,KAAK,CAAC;IACf,OAAO,mBAAmB,CAAC;QACzB,GAAG,KAAK;QACR,WAAW;QACX,OAAO;QACP,qBAAqB;KACtB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,KAA6B;IAC3D,OAAO,IAAI,GAAG,CACZ,CACE,MAAM,KAAK,CAAC,WAAW,CAAC,uBAAuB,CAC7C,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAC5B,CACF,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CACtC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,KAA6B,EAC7B,QAAyB;IAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5C,IAAI,MAAM,6BAA6B,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,YAAY,CACxD,OAAO,EACP,QAAQ,CAAC,EAAE,CACZ,CAAC;IACF,OAAO,CACL,OAAO,KAAK,IAAI;QAChB,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;QAC1C,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW;QAC5C,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CACjC,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,uBAAuB,CAAC,OAA+B;IACrE,MAAM,KAAK,GAAG;QACZ,GAAG,OAAO;QACV,cAAc,EAAE,uBAAuB,CAAC,OAAO,CAAC,cAAc,CAAC;KAChE,CAAC;IACF,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA6B,CAAC;IACnE,OAAO;QACL,6BAA6B,EAAE,CAAC,OAAgB,EAAE,WAAmB,EAAE,EAAE,CACvE,mBAAmB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YACpC,MAAM,qBAAqB,CAAC;gBAC1B,GAAG,KAAK;gBACR,OAAO;gBACP,WAAW;gBACX,qBAAqB;aACtB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACJ,6BAA6B,EAAE,CAC7B,OAAgB,EAChB,WAAsC,EACtC,OAAe,EACf,EAAE,CACF,qBAAqB,CAAC;YACpB,GAAG,KAAK;YACR,OAAO;YACP,WAAW;YACX,OAAO;YACP,qBAAqB;SACtB,CAAC;QACJ,eAAe,EAAE,CAAC,WAAmB,EAAE,EAAE,CACvC,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,CAC9B,eAAe,CACb,KAAK,EACL,WAAW,EACX,qBAAqB,EACrB,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAC1D,CACF;QACH,cAAc,EAAE,CAAC,QAAyB,EAAE,EAAE,CAC5C,mBAAmB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YACpC,IACE,CAAC,QAAQ,CAAC,WAAW;gBACrB,CAAC,CAAC,MAAM,0BAA0B,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAEpD,OAAO,KAAK,CAAC;YACf,IACE,CAAC,CAAC,MAAM,eAAe,CACrB,KAAK,EACL,QAAQ,CAAC,WAAW,EACpB,qBAAqB,EACrB,CAAC,QAAQ,CAAC,UAAU,CACrB,CAAC;gBAEF,OAAO,KAAK,CAAC;YACf,wEAAwE;YACxE,OAAO,mBAAmB,CACxB;gBACE,GAAG,KAAK;gBACR,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;gBACpC,OAAO,EAAE,QAAQ,CAAC,EAAE;gBACpB,qBAAqB;aACtB,EACD,QAAQ,CACT,CAAC;QACJ,CAAC,CAAC;KACL,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,KAA6B,EAC7B,KAA6B;IAE7B,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,sCAAsC,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,KAAK,YAAY,uBAAuB;YAAE,MAAM,KAAK,CAAC;QAC1D,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CACpB,gDAAgD,YAAY,CAAC,KAAK,CAAC,EAAE,CACtE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type { DocumentSummary } from \"../../../data/documents/documentSummary\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { verifyContainerWriterProjection } from \"../../../data/keyingProjectionVerification/containerProjectionVerification\";\nimport { runWithSecurityIncidentReporting } from \"../../../data/keyingProjectionVerification/error\";\nimport { rethrowProjectionVerificationCancelled } from \"../../../data/keyingProjectionVerification/types\";\nimport { hasUnsettledDocumentPlacement } from \"../../../data/persistence/container-contents/documentPurgePlacement\";\nimport { sqlDocumentsPersistence } from \"../../../data/persistence/documents/documentsPersistence\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { ContainerContentsPersistence } from \"../containerPersistence\";\nimport type { ContainerState } from \"../remoteHydration\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\nimport { assertLocalPurgeScope } from \"./localPurgeScope\";\nimport { snapshotContainerStates } from \"./purgeTreeCollection\";\nimport { readLocalPurgeScope } from \"./readLocalPurgeScope\";\n\ninterface SubtreePurgeScopeInput {\n containersById: ReadonlyMap<string, ContainerState>;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n rootContainerId: string;\n runtime: ContainerContentsWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nasync function verifiedRemoteScope(\n input: SubtreePurgeScopeInput,\n current: Pick<ContainerState, \"container\" | \"record\">,\n verifiedAncestorsById: Map<string, readonly string[]>,\n): Promise<boolean> {\n const { runtime, rootContainerId } = input;\n const targetId = current.container.id;\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: targetId,\n objectKind: \"container\",\n operation: \"container.purge.scope\",\n },\n async () => {\n runtime.apiClient.evictContainerWriterProjection(targetId);\n const projection =\n await runtime.apiClient.getContainerWriterProjection(targetId);\n if (!projection || input.stillCurrent?.() === false) return false;\n if (\n projection.containerId !== targetId ||\n projection.organizationId !== current.container.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Subtree purge container identity mismatch\",\n );\n }\n const path = await verifyContainerWriterProjection({\n execSql: runtime.infra.execSql,\n projection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n });\n const rootIndex = path.findIndex(\n (head) => head.state.containerId === rootContainerId,\n );\n const latest = await input.persistence.loadContainerMetadataState(\n runtime.infra.execSql,\n targetId,\n );\n const pendingMoves = await readPendingMoves(input);\n const allowed =\n rootIndex >= 0 &&\n path[rootIndex]?.state.parentContainerId ===\n input.containersById.get(rootContainerId)?.container.parentId &&\n latest?.container.parentId === current.container.parentId &&\n latest.record?.documentId === current.record.documentId &&\n !path\n .slice(rootIndex)\n .some((head) => pendingMoves.has(head.state.containerId)) &&\n input.stillCurrent?.() !== false;\n if (allowed)\n verifiedAncestorsById.set(\n targetId,\n path.slice(rootIndex).map((head) => head.state.containerId),\n );\n return allowed;\n },\n );\n}\n\n/**\n * A local-only unit cites no signed request, so a remote ordinary root must\n * prove that it still sits under the parent it was selected from. A system\n * root's signed topology is fixed by its destination role.\n */\nasync function rootPlacementIsCurrent(\n input: SubtreePurgeScopeInput,\n verifiedAncestorsById: Map<string, readonly string[]>,\n): Promise<boolean> {\n const root = input.containersById.get(input.rootContainerId);\n if (!root?.record.documentId || (root.container.systemSlot ?? null) !== null)\n return true;\n return verifiedRemoteScope(input, root, verifiedAncestorsById);\n}\n\nasync function allowsContainer(\n input: SubtreePurgeScopeInput,\n containerId: string,\n verifiedAncestorsById: Map<string, readonly string[]>,\n localOnlyUnit: boolean,\n): Promise<boolean> {\n const { runtime, persistence, rootContainerId } = input;\n if (input.stillCurrent?.() === false) return false;\n const execSql = runtime.infra.execSql;\n const pendingMoves = await readPendingMoves(input);\n if (pendingMoves.has(rootContainerId)) return false;\n const seen = new Set<string>([rootContainerId]);\n let currentId: string | null = containerId;\n let verifiedRemoteAncestry = false;\n while (currentId !== rootContainerId) {\n if (!currentId || seen.has(currentId) || pendingMoves.has(currentId))\n return false;\n seen.add(currentId);\n const expected = input.containersById.get(currentId);\n const current = await persistence.loadContainerMetadataState(\n execSql,\n currentId,\n );\n if (\n !expected ||\n !current?.record ||\n current.container.parentId !== expected.container.parentId ||\n current.container.organizationId !== expected.container.organizationId ||\n current.record.documentId !== expected.record.documentId\n )\n return false;\n if (current.record.documentId) {\n if (\n !(await verifiedRemoteScope(\n input,\n {\n container: current.container,\n record: current.record,\n },\n verifiedAncestorsById,\n ))\n )\n return false;\n verifiedRemoteAncestry = true;\n break;\n }\n currentId = current.container.parentId;\n }\n if (\n localOnlyUnit &&\n !verifiedRemoteAncestry &&\n !(await rootPlacementIsCurrent(input, verifiedAncestorsById))\n )\n return false;\n return readLocalPurgeScope({\n ...input,\n containerId,\n execSql,\n verifiedAncestorsById,\n });\n}\n\nasync function readPendingMoves(input: SubtreePurgeScopeInput) {\n return new Set(\n (\n await input.persistence.listUnsyncedMoveIntents(\n input.runtime.infra.execSql,\n )\n ).map((intent) => intent.containerId),\n );\n}\n\nasync function documentPlacementIsCurrent(\n input: SubtreePurgeScopeInput,\n document: DocumentSummary,\n): Promise<boolean> {\n const execSql = input.runtime.infra.execSql;\n if (await hasUnsettledDocumentPlacement(execSql, document.id)) return false;\n const current = await sqlDocumentsPersistence.loadDocument(\n execSql,\n document.id,\n );\n return (\n current !== null &&\n current.documentId === document.documentId &&\n current.containerId === document.containerId &&\n input.stillCurrent?.() !== false\n );\n}\n\n/** Listing edges only select candidates; each destructive unit proves its scope. */\nexport function createSubtreePurgeScope(request: SubtreePurgeScopeInput) {\n const input = {\n ...request,\n containersById: snapshotContainerStates(request.containersById),\n };\n const verifiedAncestorsById = new Map<string, readonly string[]>();\n return {\n allowsLocalScopeInTransaction: (execSql: ExecSql, containerId: string) =>\n checkAvailableScope(input, async () => {\n await assertLocalPurgeScope({\n ...input,\n execSql,\n containerId,\n verifiedAncestorsById,\n });\n return true;\n }),\n assertLocalScopeInTransaction: (\n execSql: ExecSql,\n containerId: string | null | undefined,\n localId: string,\n ) =>\n assertLocalPurgeScope({\n ...input,\n execSql,\n containerId,\n localId,\n verifiedAncestorsById,\n }),\n allowsContainer: (containerId: string) =>\n checkAvailableScope(input, () =>\n allowsContainer(\n input,\n containerId,\n verifiedAncestorsById,\n !input.containersById.get(containerId)?.record.documentId,\n ),\n ),\n allowsDocument: (document: DocumentSummary) =>\n checkAvailableScope(input, async () => {\n if (\n !document.containerId ||\n !(await documentPlacementIsCurrent(input, document))\n )\n return false;\n if (\n !(await allowsContainer(\n input,\n document.containerId,\n verifiedAncestorsById,\n !document.documentId,\n ))\n )\n return false;\n // Freeze local placement checks together after all remote verification.\n return readLocalPurgeScope(\n {\n ...input,\n containerId: document.containerId,\n execSql: input.runtime.infra.execSql,\n localId: document.id,\n verifiedAncestorsById,\n },\n document,\n );\n }),\n };\n}\n\nasync function checkAvailableScope(\n input: SubtreePurgeScopeInput,\n check: () => Promise<boolean>,\n): Promise<boolean> {\n try {\n return await check();\n } catch (error) {\n rethrowProjectionVerificationCancelled(error);\n if (error instanceof KeyingVerificationError) throw error;\n input.runtime.util.log(\n `Container contents: purge scope unavailable: ${errorMessage(error)}`,\n );\n return false;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getTargetContainerContext, readContainerState, } from "../../../data/containers/shared/projection.js";
|
|
2
2
|
import { unwrapContainerKekPath } from "../../../data/documents/shared/projection.js";
|
|
3
|
-
import { nullOnProjectionVerificationCancellation, verifyContainerWriterProjection, } from "../../../data/keyingProjectionVerification.js";
|
|
3
|
+
import { nullOnProjectionVerificationCancellation, verifyContainerWriterProjection, } from "../../../data/keyingProjectionVerification/index.js";
|
|
4
4
|
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
5
5
|
import { projectionGeneration } from "../projectionGeneration.js";
|
|
6
6
|
import { resolveCurrentGroupKeyEpoch } from "./groupShareEpoch.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { maxEffectiveAccessLevel, normalizeEffectiveAccessLevel, } from "../../data/accessLevel.js";
|
|
2
1
|
import { uniqueSortedStrings } from "../../data/documents/shared/readers.js";
|
|
2
|
+
import { maxEffectiveAccessLevel, normalizeEffectiveAccessLevel, } from "../../data/keying/accessLevel.js";
|
|
3
3
|
function mergeDiscoveredDocumentInputs(current, next) {
|
|
4
4
|
// A lane page carries a complete link set for its epoch. Combining an old
|
|
5
5
|
// root page with a newer trash page must not manufacture a newer root link.
|