@tearleads/client-sdk 0.1.14 → 0.1.15
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/client/containerContents.js +2 -1
- package/client/containerContents.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +4 -0
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js +2 -0
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +1 -1
- package/data/keyingProjectionVerification/checkpointContext.d.ts +2 -1
- package/data/keyingProjectionVerification/checkpointContext.js +22 -0
- package/data/keyingProjectionVerification/checkpointContext.js.map +1 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js +11 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerPathVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerProjectionVerification.d.ts +3 -2
- package/data/keyingProjectionVerification/containerProjectionVerification.js +10 -11
- package/data/keyingProjectionVerification/containerProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestPolicies.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentProjectionVerification.d.ts +2 -3
- package/data/keyingProjectionVerification/documentProjectionVerification.js +4 -0
- package/data/keyingProjectionVerification/documentProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js +14 -12
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/organizationFounderBinding.js.map +1 -1
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js +33 -6
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/projectionLifetimes.js +13 -0
- package/data/keyingProjectionVerification/projectionLifetimes.js.map +1 -0
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js +19 -66
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/types.d.ts +13 -2
- package/data/keyingProjectionVerification/types.js +15 -0
- package/data/keyingProjectionVerification/types.js.map +1 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js +4 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js.map +1 -1
- package/data/persistence/organizationFounderPersistence.js +2 -2
- package/data/persistence/organizationFounderPersistence.js.map +1 -1
- package/data/persistence/principalAuthorizationCheckpoints.js +29 -0
- package/data/persistence/principalAuthorizationCheckpoints.js.map +1 -0
- package/data/persistence/principalHistoryEvidencePersistence.d.ts +30 -0
- package/data/persistence/principalHistoryPrefixPersistence.d.ts +24 -0
- package/data/persistence/principalHistoryPrefixPersistence.js +6 -2
- package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
- package/data/persistence/principalHistoryStagePersistence.d.ts +21 -0
- package/data/principals/principalHistoryRuntime.js +12 -0
- package/data/principals/principalHistoryRuntime.js.map +1 -0
- package/data/principals/principalHistoryStageProtection.js +2 -12
- package/data/principals/principalHistoryStageProtection.js.map +1 -1
- package/data/principals/principalPolicyEvidence.d.ts +2 -2
- package/data/principals/principalPolicyEvidence.js.map +1 -1
- package/data/sqlite/principalHistoryEvidenceSchema.d.ts +308 -0
- package/data/sqlite/principalHistoryStageSchema.d.ts +119 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiCache.d.ts +54 -0
- package/internal/api-client/ApiClient.d.ts +255 -309
- package/internal/api-client/ApiClient.js +15 -6
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/index.d.ts +1 -0
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/principalHistoryDeadline.js +20 -0
- package/internal/api-client/principalHistoryDeadline.js.map +1 -0
- package/internal/api-client/principalHistoryRequest.js +59 -22
- package/internal/api-client/principalHistoryRequest.js.map +1 -1
- package/internal/api-client/principalHistoryRequestContext.js +18 -5
- package/internal/api-client/principalHistoryRequestContext.js.map +1 -1
- package/internal/api-client/principalPolicyRequests.d.ts +799 -0
- package/internal/api-client/principalPolicyRequests.js +9 -4
- package/internal/api-client/principalPolicyRequests.js.map +1 -1
- package/internal/api-client/projectionPolicyHistoryPages.d.ts +9 -0
- package/internal/api-client/projectionPolicyHistoryPages.js +88 -0
- package/internal/api-client/projectionPolicyHistoryPages.js.map +1 -0
- package/internal/api-client/writerProjectionRequests.js +26 -0
- package/internal/api-client/writerProjectionRequests.js.map +1 -0
- package/internal/crypto/keying/principalPolicyHistory.js +4 -0
- package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
- package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +2 -0
- package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
- package/internal/crypto/projectionHistorySlots.js +0 -4
- package/internal/crypto/projectionHistorySlots.js.map +1 -1
- package/internal/validators/operation/index.d.ts +1 -0
- package/internal/validators/operation/index.js +1 -0
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/principals.d.ts +38 -16
- package/internal/validators/operation/principals.js +11 -5
- package/internal/validators/operation/principals.js.map +1 -1
- package/internal/validators/operation/projectionPolicyHistory.d.ts +512 -0
- package/internal/validators/operation/projectionPolicyHistory.js +37 -0
- package/internal/validators/operation/projectionPolicyHistory.js.map +1 -0
- package/internal/validators/operation/registry.d.ts +2 -0
- package/internal/validators/operation/registry.js +2 -0
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/operation/writerProjections.d.ts +178 -1224
- package/internal/validators/operation/writerProjections.js +9 -2
- package/internal/validators/operation/writerProjections.js.map +1 -1
- package/internal/validators/response/container.d.ts +84 -612
- package/internal/validators/response/documentMutation.d.ts +84 -612
- package/internal/validators/response/index.d.ts +1 -0
- package/internal/validators/response/index.js +1 -0
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationBilling.d.ts +1 -0
- package/internal/validators/response/organizationBilling.js +1 -1
- package/internal/validators/response/organizationBilling.js.map +1 -1
- package/internal/validators/response/principalHistoryPreparation.js +28 -1
- package/internal/validators/response/principalHistoryPreparation.js.map +1 -1
- package/internal/validators/response/principalPolicySnapshotPage.d.ts +388 -0
- package/internal/validators/response/principalPolicySnapshotPage.js +24 -0
- package/internal/validators/response/principalPolicySnapshotPage.js.map +1 -0
- package/internal/validators/response/projectionPolicyEvidence.d.ts +85 -613
- package/internal/validators/response/projectionPolicyEvidence.js +10 -5
- package/internal/validators/response/projectionPolicyEvidence.js.map +1 -1
- package/package.json +1 -1
- package/stores/documents/documentStore/attachmentHydration.js +3 -0
- package/stores/documents/documentStore/attachmentHydration.js.map +1 -1
- package/stores/documents/documentStore/syncDetachedAttachments.js +3 -0
- package/stores/documents/documentStore/syncDetachedAttachments.js.map +1 -1
- package/workflows/blobs/decrypt.d.ts +1 -1
- package/workflows/blobs/decrypt.js +3 -1
- package/workflows/blobs/decrypt.js.map +1 -1
- package/workflows/blobs/detach.js +6 -1
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +3 -1
- package/workflows/blobs/hydrate.js +2 -0
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/retainedAttachmentVerification.js +2 -0
- package/workflows/blobs/retainedAttachmentVerification.js.map +1 -1
- package/workflows/container-contents/container-state/createAdoption.js +2 -0
- package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadata.js +7 -39
- package/workflows/container-contents/container-state/createWithMetadata.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadataPlan.js +68 -0
- package/workflows/container-contents/container-state/createWithMetadataPlan.js.map +1 -0
- package/workflows/container-contents/remoteContainerState.js +3 -1
- package/workflows/container-contents/remoteContainerState.js.map +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js +3 -0
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
- package/workflows/container-contents/runtime.d.ts +3 -0
- package/workflows/container-contents/runtime.js +7 -6
- package/workflows/container-contents/runtime.js.map +1 -1
- package/workflows/documents/create.d.ts +2 -15
- package/workflows/documents/create.js +9 -64
- package/workflows/documents/create.js.map +1 -1
- package/workflows/documents/createProjection.d.ts +14 -0
- package/workflows/documents/createProjection.js +26 -0
- package/workflows/documents/createProjection.js.map +1 -0
- package/workflows/documents/createResponse.js +49 -0
- package/workflows/documents/createResponse.js.map +1 -0
- package/workflows/documents/linkSetBlobRewraps.js +2 -0
- package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/runtime.d.ts +3 -0
- package/workflows/documents/runtime.js +3 -2
- package/workflows/documents/runtime.js.map +1 -1
- package/workflows/documents/syncFailureClassification.js +3 -1
- package/workflows/documents/syncFailureClassification.js.map +1 -1
- package/workflows/principals/index.d.ts +2 -0
- package/workflows/principals/index.js +1 -0
- package/workflows/principals/index.js.map +1 -1
- package/workflows/principals/policyVerification.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryAuthority.js +20 -0
- package/workflows/principals/principalHistoryRecoveryAuthority.js.map +1 -0
- package/workflows/principals/principalHistoryRecoveryStage.js +1 -1
- package/workflows/principals/principalHistoryRecoveryStage.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryTypes.d.ts +3 -3
- package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js +6 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js.map +1 -1
- package/workflows/principals/principalRecoveryOutage.js +1 -1
- package/workflows/principals/principalRecoveryOutage.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryAuthority.js +60 -0
- package/workflows/principals/publicPrincipalHistoryAuthority.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryPage.js +87 -0
- package/workflows/principals/publicPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js +178 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryTypes.d.ts +39 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js +2 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -0
- package/workflows/principals/publicProjectionDirectory.js +40 -0
- package/workflows/principals/publicProjectionDirectory.js.map +1 -0
- package/workflows/principals/publicProjectionPrincipal.js +53 -0
- package/workflows/principals/publicProjectionPrincipal.js.map +1 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.js +4 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverProjectionPolicyHistory.d.ts +9 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js +98 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js.map +1 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js +176 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -0
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +2 -5
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +2 -1
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +2 -0
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
- package/workflows/principals/runtimeProjectionPolicyRecovery.js +56 -0
- package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -0
- package/workflows/principals/selectPublicPrincipalHistory.js +90 -0
- package/workflows/principals/selectPublicPrincipalHistory.js.map +1 -0
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +21 -153
|
@@ -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 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 });\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 { 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"]}
|
|
@@ -3,12 +3,12 @@ import { locallyAcknowledgedContainerMutationHead } from "../../../data/containe
|
|
|
3
3
|
import { isStaleParentContainerPathFailure } from "../../../data/containers/shared/mutationFailures.js";
|
|
4
4
|
import { assertDocumentWriterProjectionConsistent } from "../../../data/documents/shared/projection.js";
|
|
5
5
|
import { advanceLocallyAcknowledgedAccessManifestHeadsAtomically, locallyAuthoredAccessManifestHead, } from "../../../data/persistence/locallyAcknowledgedCheckpointPersistence.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { readContainerMutationMetadataDocumentId, } from "../../containers/index.js";
|
|
7
|
+
import { documentWriterProjectionFromCreateResponse, persistedDocumentCreateStateFromResponse, resolveDocumentCreateAuthor, } from "../../documents/index.js";
|
|
8
8
|
import { cachePrincipalPolicyBundles } from "../../principals/policyCache.js";
|
|
9
9
|
import { PrincipalPolicyRepairBudget } from "../../principals/policyRepairBudget.js";
|
|
10
|
-
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
11
10
|
import { settleTerminalCreateFailure } from "./createTerminalFailure.js";
|
|
11
|
+
import { buildContainerWithMetadataPlans, } from "./createWithMetadataPlan.js";
|
|
12
12
|
/**
|
|
13
13
|
* Sentinel for a lost-response retry whose manifest already exists remotely.
|
|
14
14
|
* Callers avoid a duplicate; the next parent hydration settles local state.
|
|
@@ -187,42 +187,10 @@ async function settleContainerWithMetadataCreate(input) {
|
|
|
187
187
|
}
|
|
188
188
|
async function createRemoteContainerWithMetadataDocumentAttempt(input) {
|
|
189
189
|
const execSql = input.runtime.infra.execSql;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
containerId: input.containerId,
|
|
195
|
-
containerKey: input.containerKey,
|
|
196
|
-
execSql,
|
|
197
|
-
eventId: input.containerEventId,
|
|
198
|
-
metadataDocumentId: input.containerId,
|
|
199
|
-
systemSlot: input.systemSlot,
|
|
200
|
-
parentProjection: input.parentProjection,
|
|
201
|
-
parentSecretKey: input.parentSecretKey,
|
|
202
|
-
resolveProjectionUserKey: input.resolveProjectionUserKey,
|
|
203
|
-
signedAt: input.containerSignedAt,
|
|
204
|
-
stillCurrent: input.stillCurrent,
|
|
205
|
-
warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(input.runtime),
|
|
206
|
-
});
|
|
207
|
-
const childProjection = childContainerWriterProjectionFromCreatePlan({
|
|
208
|
-
materializedPlan: containerPlan,
|
|
209
|
-
parentProjection: input.parentProjection,
|
|
210
|
-
});
|
|
211
|
-
const metadataDocumentPlan = await buildMaterializedDocumentCreatePlan({
|
|
212
|
-
author: input.author,
|
|
213
|
-
containerProjection: childProjection,
|
|
214
|
-
contentKey: input.metadataContentKey,
|
|
215
|
-
documentId: containerPlan.plan.metadataDocumentId,
|
|
216
|
-
eventId: input.metadataEventId,
|
|
217
|
-
execSql,
|
|
218
|
-
knownContainerKeks: new Map([
|
|
219
|
-
[containerPlan.plan.containerKeyEpochId, containerPlan.containerKey],
|
|
220
|
-
]),
|
|
221
|
-
signedAt: input.metadataSignedAt,
|
|
222
|
-
stillCurrent: input.stillCurrent,
|
|
223
|
-
targetSecretKey: input.parentSecretKey,
|
|
224
|
-
trustedLocalProjection: true,
|
|
225
|
-
});
|
|
190
|
+
const plans = await buildContainerWithMetadataPlans(input);
|
|
191
|
+
if (!plans)
|
|
192
|
+
return null;
|
|
193
|
+
const { containerPlan, childProjection, metadataDocumentPlan } = plans;
|
|
226
194
|
const submitted = await submitContainerWithMetadataDocument({
|
|
227
195
|
organizationId: containerPlan.plan.state.organizationId,
|
|
228
196
|
request: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWithMetadata.js","sourceRoot":"","sources":["createWithMetadata.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AAMnD,OAAO,EAAE,wCAAwC,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,iCAAiC,EAAE,MAAM,kDAAkD,CAAC;AAErG,OAAO,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;AAErG,OAAO,EACL,uDAAuD,EACvD,iCAAiC,GAClC,MAAM,oEAAoE,CAAC;AAE5E,OAAO,EACL,oCAAoC,EACpC,4CAA4C,EAC5C,uCAAuC,GACxC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mCAAmC,EACnC,0CAA0C,EAC1C,wCAAwC,EACxC,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAMtE;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,2BAA2B,CAAC,CAAC;AAG/E,KAAK,UAAU,mCAAmC,CAAC,KAKlD;IAQC,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,yCAAyC,CACtE,KAAK,CAAC,OAAO,EACb;QACE,qCAAqC,EAAE,KAAK,CAAC,cAAc;QAC3D,YAAY,EAAE,KAAK;KACpB,CACF,CAAC;IACF,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,gCAAgC,CAAC,KAK/C;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC;IACrD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;IAC1C,MAAM,yBAAyB,GAC7B,SAAS,CAAC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,2BAA2B,CAAC;QAChC,OAAO;QACP,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACpC,yBAAyB;QACzB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG;QAC3B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,sBAAsB,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB;QACjE,0BAA0B,EAAE,KAAK,CAAC,OAAO,CAAC,0BAA0B;QACpE,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CAAC;AAC1C,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,oCAAoC,CAAC,KAMnD;IACC,MAAM,UAAU,GAAG,0CAA0C,CAAC;QAC5D,mBAAmB,EAAE,KAAK,CAAC,eAAe;QAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,gBAAgB;KAC1C,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,wCAAwC,CAAC,UAAU,EAAE;YACzD,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,sBAAsB,EAAE,IAAI;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO;IAC7C,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,6BAA6B,CACnD,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAClC,UAAU,CACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gCAAgC,CAAC,KAU/C;IACC,MAAM,cAAc,GAAG,wCAAwC,CAC7D,KAAK,CAAC,oBAAoB,EAC1B,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAChC,CAAC;IACF,MAAM,aAAa,GAAG,MAAM,wCAAwC,CAAC;QACnE,IAAI,EAAE,KAAK,CAAC,aAAa;QACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS;KACnC,CAAC,CAAC;IACH,MAAM,uDAAuD,CAAC;QAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE;YACL,aAAa;YACb,iCAAiC,CAAC,KAAK,CAAC,oBAAoB,CAAC;SAC9D;QACD,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,kCAAkC,CAAC,KAI3C;IACC,MAAM,mBAAmB,GACvB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC;IACrD,MAAM,qBAAqB,GAAG,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;IAC9E,+EAA+E;IAC/E,+CAA+C;IAC/C,IACE,CAAC,mBAAmB;QACpB,CAAC,qBAAqB;QACtB,KAAK,CAAC,eAAe,CAAC,WAAW;YAC/B,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW;QACtC,qBAAqB,KAAK,mBAAmB,EAC7C,CAAC;QACD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,8BAA8B,CACpD,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EACpC,KAAK,CAAC,eAAe,CACtB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,KAAmC;IAEnC,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,iCAAiC,CAAC,KAYhD;IAIC,IACE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW;QACpC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,EACpC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAClE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,kBAAkB,GAAG,uCAAuC,CAAC;QACjE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS;KACnC,CAAC,CAAC;IACH,IACE,kBAAkB,KAAK,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,kBAAkB;QAClE,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;YAChC,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAC5C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,sBAAsB,GAAG,MAAM,gCAAgC,CAAC;QACpE,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI;QACvC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,CAAC,IAAI;QACrD,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,oCAAoC,CAAC;QACzC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,kCAAkC,CAAC;QACjC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC;IACH,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY;YACtE,UAAU,EAAE,sBAAsB,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;YAClE,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW;YACjD,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS;YAC7C,kBAAkB;YAClB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc;YACvD,QAAQ;YACR,sBAAsB;YACtB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS;SAC9C;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gDAAgD,CAAC,KAe/D;IAQC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5C,8EAA8E;IAC9E,4EAA4E;IAC5E,MAAM,aAAa,GAAG,MAAM,oCAAoC,CAAC;QAC/D,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO;QACP,OAAO,EAAE,KAAK,CAAC,gBAAgB;QAC/B,kBAAkB,EAAE,KAAK,CAAC,WAAW;QACrC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;QACxD,QAAQ,EAAE,KAAK,CAAC,iBAAiB;QACjC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,+BAA+B,EAAE,kCAAkC,CACjE,KAAK,CAAC,OAAO,CACd;KACF,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,4CAA4C,CAAC;QACnE,gBAAgB,EAAE,aAAa;QAC/B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KACzC,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,MAAM,mCAAmC,CAAC;QACrE,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,mBAAmB,EAAE,eAAe;QACpC,UAAU,EAAE,KAAK,CAAC,kBAAkB;QACpC,UAAU,EAAE,aAAa,CAAC,IAAI,CAAC,kBAAkB;QACjD,OAAO,EAAE,KAAK,CAAC,eAAe;QAC9B,OAAO;QACP,kBAAkB,EAAE,IAAI,GAAG,CAAC;YAC1B,CAAC,aAAa,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,YAAY,CAAC;SACrE,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,gBAAgB;QAChC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,sBAAsB,EAAE,IAAI;KAC7B,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,mCAAmC,CAAC;QAC1D,cAAc,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc;QACvD,OAAO,EAAE;YACP,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO;YACrC,gBAAgB,EAAE,oBAAoB,CAAC,IAAI,CAAC,OAAO;SACpD;QACD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,iCAAiC,CAAC;QACvC,eAAe;QACf,aAAa;QACb,OAAO;QACP,oBAAoB;QACpB,QAAQ,EAAE,SAAS,CAAC,QAAQ;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sCAAsC,CACnD,KAIC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACpC,IAAI,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC9C,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,IAAI,2BAA2B,EAAE,CAAC;IACxD,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,MAAM,gDAAgD,CAAC;YACvE,GAAG,KAAK;YACR,gBAAgB;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,SAAS,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC,KAAK,CAAC;QACzB,CAAC;QACD,IACE,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC;YACpD,CAAC,MAAM,gCAAgC,CAAC;gBACtC,OAAO,EAAE,SAAS;gBAClB,cAAc,EAAE,gBAAgB,CAAC,cAAc;gBAC/C,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,YAAY,EAAE,KAAK,CAAC,YAAY;aACjC,CAAC,CAAC,EACH,CAAC;YACD,SAAS;QACX,CAAC;QACD,IACE,CAAC,oBAAoB;YACrB,iCAAiC,CAAC,SAAS,CAAC;YAC5C,SAAS,CAAC,8BAA8B;YACxC,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,EAChC,CAAC;YACD,oBAAoB,GAAG,IAAI,CAAC;YAC5B,SAAS,CAAC,8BAA8B,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAClE,MAAM,mBAAmB,GAAG,MAAM,SAAS,CAAC,4BAA4B,CACtE,KAAK,CAAC,iBAAiB,CACxB,CAAC;YACF,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;gBAAE,OAAO,IAAI,CAAC;YAClD,gBAAgB,GAAG,mBAAmB,CAAC;YACvC,SAAS;QACX,CAAC;QACD,OAAO,2BAA2B,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;YAC/D,WAAW;YACX,CAAC,CAAC,2BAA2B;YAC7B,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yCAAyC,CAAC,KAQ/D;IACC,MAAM,MAAM,GAAG,2BAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACpC,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,SAAS,CAAC;IAC7E,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CACpB,yFAAyF,CAC1F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GACpB,KAAK,CAAC,gBAAgB;QACtB,CAAC,MAAM,SAAS,CAAC,4BAA4B,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,iBAAiB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,kBAAkB,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5C,MAAM,gBAAgB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClD,OAAO,sCAAsC,CAAC;QAC5C,MAAM;QACN,gBAAgB;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,YAAY;QACZ,iBAAiB;QACjB,kBAAkB;QAClB,eAAe;QACf,gBAAgB;QAChB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,gBAAgB;QAChB,eAAe;QACf,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;QACxD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ContainerAccessManifestState } from \"@tearleads/crypto\";\nimport {\n type ContainerSystemSlot,\n isContainerSystemSlot,\n} from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerCreateWithMetadataDocumentRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { locallyAcknowledgedContainerMutationHead } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isStaleParentContainerPathFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerMutationSubmitFailure } from \"../../../data/containers/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../data/documents/shared/projection\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n locallyAuthoredAccessManifestHead,\n} from \"../../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n buildMaterializedContainerCreatePlan,\n childContainerWriterProjectionFromCreatePlan,\n readContainerMutationMetadataDocumentId,\n} from \"../../containers\";\nimport {\n buildMaterializedDocumentCreatePlan,\n documentWriterProjectionFromCreateResponse,\n persistedDocumentCreateStateFromResponse,\n resolveDocumentCreateAuthor,\n} from \"../../documents\";\nimport { cachePrincipalPolicyBundles } from \"../../principals/policyCache\";\nimport { PrincipalPolicyRepairBudget } from \"../../principals/policyRepairBudget\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport { settleTerminalCreateFailure } from \"./createTerminalFailure\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Sentinel for a lost-response retry whose manifest already exists remotely.\n * Callers avoid a duplicate; the next parent hydration settles local state.\n */\nexport const CONTAINER_ALREADY_COMMITTED = Symbol(\"containerAlreadyCommitted\");\nexport type ContainerAlreadyCommitted = typeof CONTAINER_ALREADY_COMMITTED;\n\nasync function submitContainerWithMetadataDocument(input: {\n readonly organizationId: string;\n readonly request: ContainerCreateWithMetadataDocumentRequest;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | {\n readonly ok: true;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const result = await apiClient.createContainerWithMetadataDocumentResult(\n input.request,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n },\n );\n return result.ok ? { ok: true, response: result.data } : result;\n}\n\nasync function cacheStalePrincipalPolicyBundles(input: {\n readonly failure: ContainerMutationSubmitFailure;\n readonly organizationId: string;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<boolean> {\n const bundles = input.failure.stalePrincipalPolicies;\n const apiClient = input.runtime.apiClient;\n const getCurrentPrincipalPolicy =\n apiClient.getCurrentPrincipalPolicy.bind(apiClient);\n if (input.stillCurrent?.() === false) return false;\n if (!bundles || bundles.length === 0) {\n return false;\n }\n\n // A stale-policy failure is actionable only after the supplied bundles have\n // been verified and cached; the next attempt will rebuild from that cache.\n await cachePrincipalPolicyBundles({\n bundles,\n execSql: input.runtime.infra.execSql,\n getCurrentPrincipalPolicy,\n log: input.runtime.util.log,\n organizationId: input.organizationId,\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n return input.stillCurrent?.() !== false;\n}\n\n/**\n * Seed the metadata document's writer projection from the create response so the\n * first read after the container is created (its own metadata sync, contents\n * hydration) resolves locally instead of a cold `GET writer-projection`. The\n * authorizing path is the child container projection the create was authored\n * against — locally built rather than server-fetched, so unlike the plain\n * document-create path this is gated on the projection's internal consistency;\n * on any mismatch the seed is skipped and the next read falls back to a fetch.\n */\nasync function seedMetadataDocumentWriterProjection(input: {\n readonly runtime: ContainerWorkflowRuntime;\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = documentWriterProjectionFromCreateResponse({\n containerProjection: input.childProjection,\n response: input.response.metadataDocument,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n stillCurrent: input.stillCurrent,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.runtime.apiClient.primeDocumentWriterProjection(\n input.response.metadataDocument.id,\n projection,\n );\n}\n\nasync function acknowledgeContainerWithMetadata(input: {\n containerPlan: Parameters<\n typeof locallyAcknowledgedContainerMutationHead\n >[0][\"plan\"];\n execSql: ExecSql;\n metadataDocumentPlan: Parameters<\n typeof persistedDocumentCreateStateFromResponse\n >[0];\n response: ContainerCreateWithMetadataDocumentResponse;\n stillCurrent?: (() => boolean) | undefined;\n}) {\n const persistedState = persistedDocumentCreateStateFromResponse(\n input.metadataDocumentPlan,\n input.response.metadataDocument,\n );\n const containerHead = await locallyAcknowledgedContainerMutationHead({\n plan: input.containerPlan,\n response: input.response.container,\n });\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: input.execSql,\n heads: [\n containerHead,\n locallyAuthoredAccessManifestHead(input.metadataDocumentPlan),\n ],\n stillCurrent: input.stillCurrent,\n });\n return persistedState;\n}\n\n/**\n * Prime the new container's writer projection from the create plan the client\n * just authored, so the first write under it (a child folder, a document)\n * resolves locally instead of a cold `GET writer-projection`. Only primed when\n * the locally-built projection matches what the server created — the create\n * response echoes the container id and manifest head — so a mismatch skips the\n * seed and the next write falls back to a fetch (same fail-closed contract as\n * the metadata-document seed). Priming is safe for writes: the server still\n * validates every mutation, so a projection that later goes stale (rekey/share/\n * move evict it) just yields a rejected write that retries with a fresh fetch.\n */\nfunction seedChildContainerWriterProjection(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n}): void {\n const createdManifestHash =\n input.response.container.manifestHead.manifestHash;\n const projectedManifestHash = input.childProjection.path.at(-1)?.manifestHash;\n // Both hashes must be present and equal, or two undefined hashes would compare\n // equal and prime an empty/invalid projection.\n if (\n !createdManifestHash ||\n !projectedManifestHash ||\n input.childProjection.containerId !==\n input.response.container.containerId ||\n projectedManifestHash !== createdManifestHash\n ) {\n return;\n }\n\n input.runtime.apiClient.primeContainerWriterProjection(\n input.response.container.containerId,\n input.childProjection,\n );\n}\n\n/**\n * The persisted slot is the one this client signed into the manifest state.\n * The acknowledgement already refused a response that echoed anything else,\n * so the server's column never chooses which local record becomes Trash.\n */\nfunction signedCreateSystemSlot(\n state: ContainerAccessManifestState,\n): ContainerSystemSlot | null {\n if (state.systemSlot === null) return null;\n if (!isContainerSystemSlot(state.systemSlot)) {\n throw new Error(\"Container create plan signed an invalid system slot\");\n }\n return state.systemSlot;\n}\n\nasync function settleContainerWithMetadataCreate(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly containerPlan: Awaited<\n ReturnType<typeof buildMaterializedContainerCreatePlan>\n >;\n readonly execSql: ExecSql;\n readonly metadataDocumentPlan: Awaited<\n ReturnType<typeof buildMaterializedDocumentCreatePlan>\n >;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<{\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n} | null> {\n if (\n input.response.container.containerId !==\n input.containerPlan.plan.containerId\n ) {\n throw new Error(\"Container metadata create response container mismatch\");\n }\n // The acknowledgement echoed the signed parent, which a child always names.\n const parentId = input.containerPlan.plan.state.parentContainerId;\n if (parentId === null) {\n throw new Error(\"A container create must commit under a parent\");\n }\n const metadataDocumentId = readContainerMutationMetadataDocumentId({\n response: input.response.container,\n });\n if (\n metadataDocumentId !== input.containerPlan.plan.metadataDocumentId ||\n input.response.metadataDocument.id !==\n input.metadataDocumentPlan.plan.documentId\n ) {\n throw new Error(\"Container metadata create response document mismatch\");\n }\n const persistedMetadataState = await acknowledgeContainerWithMetadata({\n containerPlan: input.containerPlan.plan,\n execSql: input.execSql,\n metadataDocumentPlan: input.metadataDocumentPlan.plan,\n response: input.response,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n await seedMetadataDocumentWriterProjection({\n childProjection: input.childProjection,\n execSql: input.execSql,\n response: input.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n seedChildContainerWriterProjection({\n childProjection: input.childProjection,\n response: input.response,\n runtime: input.runtime,\n });\n return {\n ok: true,\n state: {\n accessManifestHash: input.response.container.manifestHead.manifestHash,\n systemSlot: signedCreateSystemSlot(input.containerPlan.plan.state),\n containerId: input.response.container.containerId,\n createdAt: input.response.container.createdAt,\n metadataDocumentId,\n organizationId: input.response.container.organizationId,\n parentId,\n persistedMetadataState,\n updatedAt: input.response.container.updatedAt,\n },\n };\n}\n\nasync function createRemoteContainerWithMetadataDocumentAttempt(input: {\n readonly author: NonNullable<ReturnType<typeof resolveDocumentCreateAuthor>>;\n readonly containerEventId: string;\n readonly containerId: string;\n readonly containerKey: Uint8Array;\n readonly containerSignedAt: string;\n readonly metadataContentKey: Uint8Array;\n readonly metadataEventId: string;\n readonly metadataSignedAt: string;\n readonly parentProjection: ContainerWriterProjectionResponse;\n readonly parentSecretKey: Uint8Array;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly runtime: ContainerWorkflowRuntime;\n readonly systemSlot?: ContainerSystemSlot | null | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | {\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n const execSql = input.runtime.infra.execSql;\n // Rebuild parent- and policy-dependent hashes, signatures, and wraps on every\n // attempt while retaining the logical mutation identities and key material.\n const containerPlan = await buildMaterializedContainerCreatePlan({\n author: input.author,\n containerId: input.containerId,\n containerKey: input.containerKey,\n execSql,\n eventId: input.containerEventId,\n metadataDocumentId: input.containerId,\n systemSlot: input.systemSlot,\n parentProjection: input.parentProjection,\n parentSecretKey: input.parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.containerSignedAt,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n const childProjection = childContainerWriterProjectionFromCreatePlan({\n materializedPlan: containerPlan,\n parentProjection: input.parentProjection,\n });\n const metadataDocumentPlan = await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection: childProjection,\n contentKey: input.metadataContentKey,\n documentId: containerPlan.plan.metadataDocumentId,\n eventId: input.metadataEventId,\n execSql,\n knownContainerKeks: new Map([\n [containerPlan.plan.containerKeyEpochId, containerPlan.containerKey],\n ]),\n signedAt: input.metadataSignedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.parentSecretKey,\n trustedLocalProjection: true,\n });\n const submitted = await submitContainerWithMetadataDocument({\n organizationId: containerPlan.plan.state.organizationId,\n request: {\n systemSlot: input.systemSlot ?? null,\n container: containerPlan.plan.request,\n metadataDocument: metadataDocumentPlan.plan.request,\n },\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!submitted?.ok) {\n return submitted;\n }\n return settleContainerWithMetadataCreate({\n childProjection,\n containerPlan,\n execSql,\n metadataDocumentPlan,\n response: submitted.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n}\n\nasync function createContainerWithMetadataWithRepairs(\n input: Parameters<\n typeof createRemoteContainerWithMetadataDocumentAttempt\n >[0] & {\n readonly parentContainerId: string;\n },\n): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const { apiClient } = input.runtime;\n let parentProjection = input.parentProjection;\n let didRepairStaleParent = false;\n const policyRepairs = new PrincipalPolicyRepairBudget();\n for (;;) {\n const submitted = await createRemoteContainerWithMetadataDocumentAttempt({\n ...input,\n parentProjection,\n });\n if (!submitted) {\n return null;\n }\n if (submitted.ok) {\n return submitted.state;\n }\n if (\n policyRepairs.take(submitted.stalePrincipalPolicies) &&\n (await cacheStalePrincipalPolicyBundles({\n failure: submitted,\n organizationId: parentProjection.organizationId,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n }))\n ) {\n continue;\n }\n if (\n !didRepairStaleParent &&\n isStaleParentContainerPathFailure(submitted) &&\n apiClient.evictContainerWriterProjection &&\n input.stillCurrent?.() !== false\n ) {\n didRepairStaleParent = true;\n apiClient.evictContainerWriterProjection(input.parentContainerId);\n const refreshedProjection = await apiClient.getContainerWriterProjection(\n input.parentContainerId,\n );\n if (!refreshedProjection) {\n return null;\n }\n if (input.stillCurrent?.() === false) return null;\n parentProjection = refreshedProjection;\n continue;\n }\n return settleTerminalCreateFailure(submitted, input.stillCurrent) ===\n \"committed\"\n ? CONTAINER_ALREADY_COMMITTED\n : null;\n }\n}\n\nexport async function createRemoteContainerWithMetadataDocument(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const author = resolveDocumentCreateAuthor(input.runtime);\n const { apiClient } = input.runtime;\n const parentSecretKey = input.runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !parentSecretKey) {\n input.runtime.util.log(\n \"Container contents: skipped container create because the writer context is unavailable.\",\n );\n return null;\n }\n\n const parentProjection =\n input.parentProjection ??\n (await apiClient.getContainerWriterProjection(input.parentContainerId));\n if (!parentProjection) {\n return null;\n }\n\n const containerEventId = crypto.randomUUID();\n const containerKey = crypto.getRandomValues(new Uint8Array(32));\n const containerSignedAt = new Date().toISOString();\n const metadataContentKey = crypto.getRandomValues(new Uint8Array(32));\n const metadataEventId = crypto.randomUUID();\n const metadataSignedAt = new Date().toISOString();\n return createContainerWithMetadataWithRepairs({\n author,\n containerEventId,\n containerId: input.containerId,\n containerKey,\n containerSignedAt,\n metadataContentKey,\n metadataEventId,\n metadataSignedAt,\n parentContainerId: input.parentContainerId,\n parentProjection,\n parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n systemSlot: input.systemSlot,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createWithMetadata.js","sourceRoot":"","sources":["createWithMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerAccessManifestState } from \"@tearleads/crypto\";\nimport {\n type ContainerSystemSlot,\n isContainerSystemSlot,\n} from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerCreateWithMetadataDocumentRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { locallyAcknowledgedContainerMutationHead } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isStaleParentContainerPathFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerMutationSubmitFailure } from \"../../../data/containers/shared/types\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../data/documents/shared/projection\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport {\n advanceLocallyAcknowledgedAccessManifestHeadsAtomically,\n locallyAuthoredAccessManifestHead,\n} from \"../../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n type buildMaterializedContainerCreatePlan,\n readContainerMutationMetadataDocumentId,\n} from \"../../containers\";\nimport {\n type buildMaterializedDocumentCreatePlan,\n documentWriterProjectionFromCreateResponse,\n persistedDocumentCreateStateFromResponse,\n resolveDocumentCreateAuthor,\n} from \"../../documents\";\nimport { cachePrincipalPolicyBundles } from \"../../principals/policyCache\";\nimport { PrincipalPolicyRepairBudget } from \"../../principals/policyRepairBudget\";\nimport { settleTerminalCreateFailure } from \"./createTerminalFailure\";\nimport {\n buildContainerWithMetadataPlans,\n type ContainerWithMetadataPlanInput,\n} from \"./createWithMetadataPlan\";\nimport type {\n ContainerWorkflowRuntime,\n CreatedRemoteContainerState,\n} from \"./types\";\n\n/**\n * Sentinel for a lost-response retry whose manifest already exists remotely.\n * Callers avoid a duplicate; the next parent hydration settles local state.\n */\nexport const CONTAINER_ALREADY_COMMITTED = Symbol(\"containerAlreadyCommitted\");\nexport type ContainerAlreadyCommitted = typeof CONTAINER_ALREADY_COMMITTED;\n\nasync function submitContainerWithMetadataDocument(input: {\n readonly organizationId: string;\n readonly request: ContainerCreateWithMetadataDocumentRequest;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<\n | {\n readonly ok: true;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const result = await apiClient.createContainerWithMetadataDocumentResult(\n input.request,\n {\n expectedPaymentRequiredOrganizationId: input.organizationId,\n reportErrors: false,\n },\n );\n return result.ok ? { ok: true, response: result.data } : result;\n}\n\nasync function cacheStalePrincipalPolicyBundles(input: {\n readonly failure: ContainerMutationSubmitFailure;\n readonly organizationId: string;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<boolean> {\n const bundles = input.failure.stalePrincipalPolicies;\n const apiClient = input.runtime.apiClient;\n const getCurrentPrincipalPolicy =\n apiClient.getCurrentPrincipalPolicy.bind(apiClient);\n if (input.stillCurrent?.() === false) return false;\n if (!bundles || bundles.length === 0) {\n return false;\n }\n\n // A stale-policy failure is actionable only after the supplied bundles have\n // been verified and cached; the next attempt will rebuild from that cache.\n await cachePrincipalPolicyBundles({\n bundles,\n execSql: input.runtime.infra.execSql,\n getCurrentPrincipalPolicy,\n log: input.runtime.util.log,\n organizationId: input.organizationId,\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n return input.stillCurrent?.() !== false;\n}\n\n/**\n * Seed the metadata document's writer projection from the create response so the\n * first read after the container is created (its own metadata sync, contents\n * hydration) resolves locally instead of a cold `GET writer-projection`. The\n * authorizing path is the child container projection the create was authored\n * against — locally built rather than server-fetched, so unlike the plain\n * document-create path this is gated on the projection's internal consistency;\n * on any mismatch the seed is skipped and the next read falls back to a fetch.\n */\nasync function seedMetadataDocumentWriterProjection(input: {\n readonly runtime: ContainerWorkflowRuntime;\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = documentWriterProjectionFromCreateResponse({\n containerProjection: input.childProjection,\n response: input.response.metadataDocument,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n stillCurrent: input.stillCurrent,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.runtime.apiClient.primeDocumentWriterProjection(\n input.response.metadataDocument.id,\n projection,\n );\n}\n\nasync function acknowledgeContainerWithMetadata(input: {\n containerPlan: Parameters<\n typeof locallyAcknowledgedContainerMutationHead\n >[0][\"plan\"];\n execSql: ExecSql;\n metadataDocumentPlan: Parameters<\n typeof persistedDocumentCreateStateFromResponse\n >[0];\n response: ContainerCreateWithMetadataDocumentResponse;\n stillCurrent?: (() => boolean) | undefined;\n}) {\n const persistedState = persistedDocumentCreateStateFromResponse(\n input.metadataDocumentPlan,\n input.response.metadataDocument,\n );\n const containerHead = await locallyAcknowledgedContainerMutationHead({\n plan: input.containerPlan,\n response: input.response.container,\n });\n await advanceLocallyAcknowledgedAccessManifestHeadsAtomically({\n execSql: input.execSql,\n heads: [\n containerHead,\n locallyAuthoredAccessManifestHead(input.metadataDocumentPlan),\n ],\n stillCurrent: input.stillCurrent,\n });\n return persistedState;\n}\n\n/**\n * Prime the new container's writer projection from the create plan the client\n * just authored, so the first write under it (a child folder, a document)\n * resolves locally instead of a cold `GET writer-projection`. Only primed when\n * the locally-built projection matches what the server created — the create\n * response echoes the container id and manifest head — so a mismatch skips the\n * seed and the next write falls back to a fetch (same fail-closed contract as\n * the metadata-document seed). Priming is safe for writes: the server still\n * validates every mutation, so a projection that later goes stale (rekey/share/\n * move evict it) just yields a rejected write that retries with a fresh fetch.\n */\nfunction seedChildContainerWriterProjection(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n}): void {\n const createdManifestHash =\n input.response.container.manifestHead.manifestHash;\n const projectedManifestHash = input.childProjection.path.at(-1)?.manifestHash;\n // Both hashes must be present and equal, or two undefined hashes would compare\n // equal and prime an empty/invalid projection.\n if (\n !createdManifestHash ||\n !projectedManifestHash ||\n input.childProjection.containerId !==\n input.response.container.containerId ||\n projectedManifestHash !== createdManifestHash\n ) {\n return;\n }\n\n input.runtime.apiClient.primeContainerWriterProjection(\n input.response.container.containerId,\n input.childProjection,\n );\n}\n\n/**\n * The persisted slot is the one this client signed into the manifest state.\n * The acknowledgement already refused a response that echoed anything else,\n * so the server's column never chooses which local record becomes Trash.\n */\nfunction signedCreateSystemSlot(\n state: ContainerAccessManifestState,\n): ContainerSystemSlot | null {\n if (state.systemSlot === null) return null;\n if (!isContainerSystemSlot(state.systemSlot)) {\n throw new Error(\"Container create plan signed an invalid system slot\");\n }\n return state.systemSlot;\n}\n\nasync function settleContainerWithMetadataCreate(input: {\n readonly childProjection: ContainerWriterProjectionResponse;\n readonly containerPlan: Awaited<\n ReturnType<typeof buildMaterializedContainerCreatePlan>\n >;\n readonly execSql: ExecSql;\n readonly metadataDocumentPlan: Awaited<\n ReturnType<typeof buildMaterializedDocumentCreatePlan>\n >;\n readonly response: ContainerCreateWithMetadataDocumentResponse;\n readonly runtime: ContainerWorkflowRuntime;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<{\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n} | null> {\n if (\n input.response.container.containerId !==\n input.containerPlan.plan.containerId\n ) {\n throw new Error(\"Container metadata create response container mismatch\");\n }\n // The acknowledgement echoed the signed parent, which a child always names.\n const parentId = input.containerPlan.plan.state.parentContainerId;\n if (parentId === null) {\n throw new Error(\"A container create must commit under a parent\");\n }\n const metadataDocumentId = readContainerMutationMetadataDocumentId({\n response: input.response.container,\n });\n if (\n metadataDocumentId !== input.containerPlan.plan.metadataDocumentId ||\n input.response.metadataDocument.id !==\n input.metadataDocumentPlan.plan.documentId\n ) {\n throw new Error(\"Container metadata create response document mismatch\");\n }\n const persistedMetadataState = await acknowledgeContainerWithMetadata({\n containerPlan: input.containerPlan.plan,\n execSql: input.execSql,\n metadataDocumentPlan: input.metadataDocumentPlan.plan,\n response: input.response,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n await seedMetadataDocumentWriterProjection({\n childProjection: input.childProjection,\n execSql: input.execSql,\n response: input.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n seedChildContainerWriterProjection({\n childProjection: input.childProjection,\n response: input.response,\n runtime: input.runtime,\n });\n return {\n ok: true,\n state: {\n accessManifestHash: input.response.container.manifestHead.manifestHash,\n systemSlot: signedCreateSystemSlot(input.containerPlan.plan.state),\n containerId: input.response.container.containerId,\n createdAt: input.response.container.createdAt,\n metadataDocumentId,\n organizationId: input.response.container.organizationId,\n parentId,\n persistedMetadataState,\n updatedAt: input.response.container.updatedAt,\n },\n };\n}\n\nasync function createRemoteContainerWithMetadataDocumentAttempt(\n input: ContainerWithMetadataPlanInput,\n): Promise<\n | {\n readonly ok: true;\n readonly state: CreatedRemoteContainerState;\n }\n | ContainerMutationSubmitFailure\n | null\n> {\n const execSql = input.runtime.infra.execSql;\n const plans = await buildContainerWithMetadataPlans(input);\n if (!plans) return null;\n const { containerPlan, childProjection, metadataDocumentPlan } = plans;\n const submitted = await submitContainerWithMetadataDocument({\n organizationId: containerPlan.plan.state.organizationId,\n request: {\n systemSlot: input.systemSlot ?? null,\n container: containerPlan.plan.request,\n metadataDocument: metadataDocumentPlan.plan.request,\n },\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!submitted?.ok) {\n return submitted;\n }\n return settleContainerWithMetadataCreate({\n childProjection,\n containerPlan,\n execSql,\n metadataDocumentPlan,\n response: submitted.response,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n}\n\nasync function createContainerWithMetadataWithRepairs(\n input: Parameters<\n typeof createRemoteContainerWithMetadataDocumentAttempt\n >[0] & {\n readonly parentContainerId: string;\n },\n): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const { apiClient } = input.runtime;\n let parentProjection = input.parentProjection;\n let didRepairStaleParent = false;\n const policyRepairs = new PrincipalPolicyRepairBudget();\n for (;;) {\n const submitted = await createRemoteContainerWithMetadataDocumentAttempt({\n ...input,\n parentProjection,\n });\n if (!submitted) {\n return null;\n }\n if (submitted.ok) {\n return submitted.state;\n }\n if (\n policyRepairs.take(submitted.stalePrincipalPolicies) &&\n (await cacheStalePrincipalPolicyBundles({\n failure: submitted,\n organizationId: parentProjection.organizationId,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n }))\n ) {\n continue;\n }\n if (\n !didRepairStaleParent &&\n isStaleParentContainerPathFailure(submitted) &&\n apiClient.evictContainerWriterProjection &&\n input.stillCurrent?.() !== false\n ) {\n didRepairStaleParent = true;\n apiClient.evictContainerWriterProjection(input.parentContainerId);\n const refreshedProjection = await apiClient.getContainerWriterProjection(\n input.parentContainerId,\n );\n if (!refreshedProjection) {\n return null;\n }\n if (input.stillCurrent?.() === false) return null;\n parentProjection = refreshedProjection;\n continue;\n }\n return settleTerminalCreateFailure(submitted, input.stillCurrent) ===\n \"committed\"\n ? CONTAINER_ALREADY_COMMITTED\n : null;\n }\n}\n\nexport async function createRemoteContainerWithMetadataDocument(input: {\n systemSlot?: ContainerSystemSlot | null | undefined;\n containerId: string;\n parentContainerId: string;\n parentProjection?: ContainerWriterProjectionResponse | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<CreatedRemoteContainerState | ContainerAlreadyCommitted | null> {\n const author = resolveDocumentCreateAuthor(input.runtime);\n const { apiClient } = input.runtime;\n const parentSecretKey = input.runtime.crypto.encapsulationKeyPair?.secretKey;\n if (!author || !parentSecretKey) {\n input.runtime.util.log(\n \"Container contents: skipped container create because the writer context is unavailable.\",\n );\n return null;\n }\n\n const parentProjection =\n input.parentProjection ??\n (await apiClient.getContainerWriterProjection(input.parentContainerId));\n if (!parentProjection) {\n return null;\n }\n\n const containerEventId = crypto.randomUUID();\n const containerKey = crypto.getRandomValues(new Uint8Array(32));\n const containerSignedAt = new Date().toISOString();\n const metadataContentKey = crypto.getRandomValues(new Uint8Array(32));\n const metadataEventId = crypto.randomUUID();\n const metadataSignedAt = new Date().toISOString();\n return createContainerWithMetadataWithRepairs({\n author,\n containerEventId,\n containerId: input.containerId,\n containerKey,\n containerSignedAt,\n metadataContentKey,\n metadataEventId,\n metadataSignedAt,\n parentContainerId: input.parentContainerId,\n parentProjection,\n parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n systemSlot: input.systemSlot,\n });\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ProjectionDependencyUnavailableError } from "../../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
2
|
+
import { buildMaterializedContainerCreatePlan, childContainerWriterProjectionFromCreatePlan, } from "../../containers/index.js";
|
|
3
|
+
import { buildMaterializedDocumentCreatePlan, } from "../../documents/index.js";
|
|
4
|
+
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
5
|
+
async function buildPlans(input) {
|
|
6
|
+
const execSql = input.runtime.infra.execSql;
|
|
7
|
+
// Rebuild parent- and policy-dependent hashes, signatures, and wraps on every
|
|
8
|
+
// attempt while retaining the logical mutation identities and key material.
|
|
9
|
+
const containerPlan = await buildMaterializedContainerCreatePlan({
|
|
10
|
+
author: input.author,
|
|
11
|
+
containerId: input.containerId,
|
|
12
|
+
containerKey: input.containerKey,
|
|
13
|
+
execSql,
|
|
14
|
+
eventId: input.containerEventId,
|
|
15
|
+
metadataDocumentId: input.containerId,
|
|
16
|
+
systemSlot: input.systemSlot,
|
|
17
|
+
parentProjection: input.parentProjection,
|
|
18
|
+
parentSecretKey: input.parentSecretKey,
|
|
19
|
+
resolveProjectionUserKey: input.resolveProjectionUserKey,
|
|
20
|
+
signedAt: input.containerSignedAt,
|
|
21
|
+
stillCurrent: input.stillCurrent,
|
|
22
|
+
warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(input.runtime),
|
|
23
|
+
});
|
|
24
|
+
const childProjection = childContainerWriterProjectionFromCreatePlan({
|
|
25
|
+
materializedPlan: containerPlan,
|
|
26
|
+
parentProjection: input.parentProjection,
|
|
27
|
+
});
|
|
28
|
+
const metadataDocumentPlan = await buildMaterializedDocumentCreatePlan({
|
|
29
|
+
author: input.author,
|
|
30
|
+
containerProjection: childProjection,
|
|
31
|
+
contentKey: input.metadataContentKey,
|
|
32
|
+
documentId: containerPlan.plan.metadataDocumentId,
|
|
33
|
+
eventId: input.metadataEventId,
|
|
34
|
+
execSql,
|
|
35
|
+
knownContainerKeks: new Map([
|
|
36
|
+
[containerPlan.plan.containerKeyEpochId, containerPlan.containerKey],
|
|
37
|
+
]),
|
|
38
|
+
signedAt: input.metadataSignedAt,
|
|
39
|
+
stillCurrent: input.stillCurrent,
|
|
40
|
+
targetSecretKey: input.parentSecretKey,
|
|
41
|
+
trustedLocalProjection: true,
|
|
42
|
+
});
|
|
43
|
+
return { containerPlan, childProjection, metadataDocumentPlan };
|
|
44
|
+
}
|
|
45
|
+
/** Refresh stale history evidence once, strictly before submitting the write. */
|
|
46
|
+
export async function buildContainerWithMetadataPlans(input) {
|
|
47
|
+
try {
|
|
48
|
+
return await buildPlans(input);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (!(error instanceof ProjectionDependencyUnavailableError))
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
if (input.stillCurrent?.() === false)
|
|
55
|
+
return null;
|
|
56
|
+
const { apiClient } = input.runtime;
|
|
57
|
+
const parentId = input.parentProjection.containerId;
|
|
58
|
+
apiClient.evictContainerWriterProjection(parentId);
|
|
59
|
+
const parentProjection = await apiClient.getContainerWriterProjection(parentId);
|
|
60
|
+
if (!parentProjection || input.stillCurrent?.() === false)
|
|
61
|
+
return null;
|
|
62
|
+
if (parentProjection.containerId !== parentId ||
|
|
63
|
+
parentProjection.organizationId !== input.parentProjection.organizationId) {
|
|
64
|
+
throw new Error("Refreshed parent projection belongs to another container or organization");
|
|
65
|
+
}
|
|
66
|
+
return buildPlans({ ...input, parentProjection });
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=createWithMetadataPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createWithMetadataPlan.js","sourceRoot":"","sources":["createWithMetadataPlan.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n buildMaterializedContainerCreatePlan,\n childContainerWriterProjectionFromCreatePlan,\n} from \"../../containers\";\nimport {\n buildMaterializedDocumentCreatePlan,\n type resolveDocumentCreateAuthor,\n} from \"../../documents\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { ContainerWorkflowRuntime } from \"./types\";\n\nexport interface ContainerWithMetadataPlanInput {\n readonly author: NonNullable<ReturnType<typeof resolveDocumentCreateAuthor>>;\n readonly containerEventId: string;\n readonly containerId: string;\n readonly containerKey: Uint8Array;\n readonly containerSignedAt: string;\n readonly metadataContentKey: Uint8Array;\n readonly metadataEventId: string;\n readonly metadataSignedAt: string;\n readonly parentProjection: ContainerWriterProjectionResponse;\n readonly parentSecretKey: Uint8Array;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly runtime: ContainerWorkflowRuntime;\n readonly systemSlot?: ContainerSystemSlot | null | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nasync function buildPlans(input: ContainerWithMetadataPlanInput) {\n const execSql = input.runtime.infra.execSql;\n // Rebuild parent- and policy-dependent hashes, signatures, and wraps on every\n // attempt while retaining the logical mutation identities and key material.\n const containerPlan = await buildMaterializedContainerCreatePlan({\n author: input.author,\n containerId: input.containerId,\n containerKey: input.containerKey,\n execSql,\n eventId: input.containerEventId,\n metadataDocumentId: input.containerId,\n systemSlot: input.systemSlot,\n parentProjection: input.parentProjection,\n parentSecretKey: input.parentSecretKey,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.containerSignedAt,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n });\n const childProjection = childContainerWriterProjectionFromCreatePlan({\n materializedPlan: containerPlan,\n parentProjection: input.parentProjection,\n });\n const metadataDocumentPlan = await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection: childProjection,\n contentKey: input.metadataContentKey,\n documentId: containerPlan.plan.metadataDocumentId,\n eventId: input.metadataEventId,\n execSql,\n knownContainerKeks: new Map([\n [containerPlan.plan.containerKeyEpochId, containerPlan.containerKey],\n ]),\n signedAt: input.metadataSignedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.parentSecretKey,\n trustedLocalProjection: true,\n });\n return { containerPlan, childProjection, metadataDocumentPlan };\n}\n\n/** Refresh stale history evidence once, strictly before submitting the write. */\nexport async function buildContainerWithMetadataPlans(\n input: ContainerWithMetadataPlanInput,\n) {\n try {\n return await buildPlans(input);\n } catch (error) {\n if (!(error instanceof ProjectionDependencyUnavailableError)) throw error;\n }\n if (input.stillCurrent?.() === false) return null;\n const { apiClient } = input.runtime;\n const parentId = input.parentProjection.containerId;\n apiClient.evictContainerWriterProjection(parentId);\n const parentProjection =\n await apiClient.getContainerWriterProjection(parentId);\n if (!parentProjection || input.stillCurrent?.() === false) return null;\n if (\n parentProjection.containerId !== parentId ||\n parentProjection.organizationId !== input.parentProjection.organizationId\n ) {\n throw new Error(\n \"Refreshed parent projection belongs to another container or organization\",\n );\n }\n return buildPlans({ ...input, parentProjection });\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { heldContainerBinding, listingRepeatsHeldOrdinaryBinding, } from "../../data/containers/containerBinding.js";
|
|
2
2
|
import { isKeyingVerificationError, runWithSecurityIncidentReporting, } from "../../data/keyingProjectionVerification/error.js";
|
|
3
|
+
import { isProjectionVerificationCancelledError } from "../../data/keyingProjectionVerification/types.js";
|
|
3
4
|
import { installContainerMetadataRecord } from "./metadataPersistence.js";
|
|
4
5
|
import { projectionGeneration } from "./projectionGeneration.js";
|
|
5
6
|
import { moveIndexedContainerChild, removeIndexedContainerChild, } from "./remoteHydration/childIndex.js";
|
|
@@ -229,7 +230,8 @@ export async function upsertIsolatedRemoteContainerState(input) {
|
|
|
229
230
|
return await upsertRemoteContainerState(input);
|
|
230
231
|
}
|
|
231
232
|
catch (error) {
|
|
232
|
-
if (!isKeyingVerificationError(error)
|
|
233
|
+
if (!isKeyingVerificationError(error) &&
|
|
234
|
+
!isProjectionVerificationCancelledError(error))
|
|
233
235
|
throw error;
|
|
234
236
|
return null;
|
|
235
237
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteContainerState.js","sourceRoot":"","sources":["remoteContainerState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessManifestCheckpoint } from \"@tearleads/crypto\";\nimport {\n heldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../data/containers/containerBinding\";\nimport {\n isKeyingVerificationError,\n runWithSecurityIncidentReporting,\n} from \"../../data/keyingProjectionVerification/error\";\nimport type { ContainerHydrationTombstone } from \"./containerPersistence\";\nimport { installContainerMetadataRecord } from \"./metadataPersistence\";\nimport { projectionGeneration } from \"./projectionGeneration\";\nimport {\n moveIndexedContainerChild,\n removeIndexedContainerChild,\n} from \"./remoteHydration/childIndex\";\nimport type { PrefetchedDestinationProjection } from \"./remoteHydration/destinationPrefetch\";\nimport { rebindReHomedContainer } from \"./remoteHydration/heldContainerRebind\";\nimport { insertRemoteContainerState } from \"./remoteHydration/insertRemoteContainer\";\nimport {\n reconcileLocalOnlyRootContainers,\n reconcileLocalOnlySystemContainers,\n} from \"./remoteHydration/reconciliation\";\nimport {\n applyRemoteContainerTimestamps,\n remoteContainerHydrationSaveOptions,\n resolveRemoteContainerHydrationLocalUpdatedAt,\n} from \"./remoteHydration/remoteContainerTimestamps\";\nimport type {\n ContainerChildIndex,\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"./remoteHydration/types\";\nimport { verifyRemoteContainerDestination } from \"./remoteHydration/verifiedDestination\";\n\n// Container ids (restricted to the inbound page) that carry an unsynced local\n// create or move intent. Such a container's parent and local-edit timestamp are\n// owned by its structural-intent lane until that lane reconciles, so inbound\n// hydration must not revert parentId to the server value nor collapse\n// localUpdatedAt — doing so silently undoes a queued move and falsely reads\n// \"synced\". Move intents are read via listUnsyncedMoveIntents so a blocked\n// move — one whose destination parent has not synced yet, the common boot-time\n// case — is protected too. Pending *metadata*\n// updates are handled separately (listRemoteContainerIdsWithPendingMetadataUpdates);\n// these live in dedicated create/move intent tables that that query does not cover.\nexport async function listRemoteContainerIdsWithPendingStructuralIntents(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n if (input.remoteContainers.length === 0) {\n return new Set();\n }\n const remoteContainerIds = new Set(\n input.remoteContainers.map((remoteContainer) => remoteContainer.id),\n );\n\n const execSql = input.state.runtime.infra.execSql;\n const [pendingCreateIntents, unsyncedMoveIntents] = await Promise.all([\n input.state.persistence.listPendingCreateIntents(execSql),\n input.state.persistence.listUnsyncedMoveIntents(execSql),\n ]);\n const containerIdsWithPendingStructuralIntents = new Set<string>();\n for (const intent of pendingCreateIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n for (const intent of unsyncedMoveIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n return containerIdsWithPendingStructuralIntents;\n}\n\nexport async function listRemoteContainerIdsWithPendingMetadataUpdates(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n const containerIds = input.remoteContainers.flatMap((remoteContainer) => {\n const previousLocalUpdatedAt = input.state.containersById.get(\n remoteContainer.id,\n )?.container.localUpdatedAt;\n\n return previousLocalUpdatedAt &&\n previousLocalUpdatedAt.localeCompare(remoteContainer.updatedAt) > 0\n ? [remoteContainer.id]\n : [];\n });\n if (containerIds.length === 0) {\n return new Set();\n }\n\n const execSql = input.state.runtime.infra.execSql;\n return new Set(\n await input.state.persistence.listContainerIdsWithPendingUpdates(\n execSql,\n containerIds,\n ),\n );\n}\n\nfunction removeMissingHydratedContainer(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n existingState: ContainerState;\n host: RemoteContainerHydrationHost;\n previousParentId: string | null;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): void {\n const { existingState, remoteContainer, state } = input;\n if (state.containersById.get(remoteContainer.id) !== existingState) {\n return;\n }\n\n state.containersById.delete(remoteContainer.id);\n if (input.childIdsByParentId) {\n removeIndexedContainerChild(\n input.childIdsByParentId,\n remoteContainer.id,\n input.previousParentId,\n );\n input.childIdsByParentId.delete(remoteContainer.id);\n }\n input.host.updateSnapshot();\n}\n\nfunction createUpdatedRemoteContainerState(\n existingState: ContainerState,\n remoteContainer: RemoteContainer,\n): ContainerState {\n return {\n ...existingState,\n container: applyRemoteContainerTimestamps(\n existingState.container,\n remoteContainer,\n ),\n containerWriterProjection: null,\n metadataReferencedPrincipals: remoteContainer.metadataReferencedPrincipals,\n };\n}\n\nfunction installUpdatedRemoteContainerState(\n existingState: ContainerState,\n nextState: ContainerState,\n host: RemoteContainerHydrationHost,\n): void {\n const wasLocalOnly = existingState.container.serverCreatedAt == null;\n existingState.container = nextState.container;\n existingState.containerWriterProjection = nextState.containerWriterProjection;\n existingState.metadataReferencedPrincipals =\n nextState.metadataReferencedPrincipals;\n // The snapshot copied the live generation when it was taken; a hint that\n // landed during the persist leaves the live metadata projection dropped.\n if (projectionGeneration(existingState) === projectionGeneration(nextState))\n existingState.metadataWriterProjection = nextState.metadataWriterProjection;\n installContainerMetadataRecord(existingState, nextState.record);\n // A document pass may have deferred while this root was awaiting proof.\n // The first durable remote acknowledgement makes its pending creates runnable.\n if (wasLocalOnly && existingState.container.serverCreatedAt != null)\n host.requestDocumentPriming?.();\n}\n\nasync function updateExistingRemoteContainerState(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n existingState: ContainerState;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): Promise<ContainerState | null> {\n const { childIdsByParentId, existingState, host, remoteContainer, state } =\n input;\n const previousParentId = existingState.container.parentId;\n const previousLocalUpdatedAt = existingState.container.localUpdatedAt;\n // A queued, not-yet-synced local move/create owns this container's parent\n // until its intent lane reconciles. Omit the remote parent when the page scan\n // saw one; persistence also rechecks the intent transactionally so a move\n // created after that scan wins. Both paths preserve the durable local clock.\n const hasPendingStructuralIntent =\n input.containerIdsWithPendingStructuralIntents.has(remoteContainer.id);\n const nextParentId = hasPendingStructuralIntent\n ? undefined\n : remoteContainer.parentId;\n const localUpdatedAt = resolveRemoteContainerHydrationLocalUpdatedAt({\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n hasPendingStructuralIntent,\n previousLocalUpdatedAt,\n remoteContainer,\n });\n const nextState = createUpdatedRemoteContainerState(\n existingState,\n remoteContainer,\n );\n const persistenceResult = await host.persistContainerState(\n nextState,\n {\n accessEpoch: remoteContainer.metadataAccessEpoch,\n accessStateHash: remoteContainer.metadataAccessStateHash,\n documentId: remoteContainer.metadataDocumentId,\n effectiveAccessLevel: remoteContainer.effectiveAccessLevel,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n systemSlot: remoteContainer.systemSlot ?? null,\n organizationId: remoteContainer.organizationId,\n ...(nextParentId !== undefined ? { parentId: nextParentId } : {}),\n },\n false,\n remoteContainerHydrationSaveOptions({\n localUpdatedAt,\n remoteContainer,\n }),\n {\n preserveDurableStructureWhenPending: true,\n },\n );\n if (persistenceResult.status === \"missing\") {\n // Hydration persists a detached candidate so an in-flight response cannot\n // mutate mapped state before its guards settle. Retire the exact state this\n // hydration read because store-level reference cleanup cannot see the clone.\n removeMissingHydratedContainer({\n childIdsByParentId,\n existingState,\n host,\n previousParentId,\n remoteContainer,\n state,\n });\n return null;\n }\n if (persistenceResult.status !== \"persisted\") return null;\n const { record: nextRecord } = persistenceResult;\n installContainerMetadataRecord(nextState, nextRecord);\n if (input.isCurrent?.() === false) {\n return existingState;\n }\n nextState.container = {\n ...nextState.container,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n organizationId: remoteContainer.organizationId,\n parentId: nextState.container.parentId,\n };\n\n installUpdatedRemoteContainerState(existingState, nextState, host);\n moveIndexedContainerChild(\n childIdsByParentId,\n remoteContainer.id,\n previousParentId,\n existingState.container.parentId,\n );\n await reconcileLocalOnlyRootContainers({\n childIdsByParentId,\n isCurrent: input.isCurrent,\n remoteRootState: existingState,\n requestDocumentPriming: host.requestDocumentPriming,\n state,\n });\n return existingState;\n}\n\ninterface UpsertRemoteContainerStateInput {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n expectedHydrationTombstone?: ContainerHydrationTombstone | null | undefined;\n isCurrent?: (() => boolean) | undefined;\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}\n\nexport async function upsertRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n let expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n const heldState = input.state.containersById.get(input.remoteContainer.id);\n const heldBinding = heldState\n ? heldContainerBinding(heldState)\n : await input.state.persistence.loadHeldContainerBinding(\n input.state.runtime.infra.execSql,\n input.remoteContainer.id,\n );\n const listed = input.remoteContainer;\n // A folder re-homed away from the listed organization never returns there,\n // whatever binding (possibly none, after a reset) the device holds now.\n const supersededListing =\n !listingRepeatsHeldOrdinaryBinding(heldBinding, listed) &&\n (await input.state.persistence.isSupersededContainerBinding(\n input.state.runtime.infra.execSql,\n { containerId: listed.id, organizationId: listed.organizationId },\n ));\n if (input.isCurrent?.() === false) return null;\n const verified = await verifyRemoteContainerDestination({\n ...input,\n heldBinding,\n supersededListing,\n refresh: !!input.expectedHydrationTombstone,\n onVerifiedCheckpoint: (checkpoint) => {\n expectedPlacementCheckpoint = checkpoint;\n },\n });\n if (!verified || input.isCurrent?.() === false) return null;\n input = { ...input, remoteContainer: verified };\n const existingState = input.state.containersById.get(\n input.remoteContainer.id,\n );\n const remoteState = await runWithSecurityIncidentReporting(\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: verified.id,\n objectKind: \"container\",\n operation: \"container.binding.persist\",\n organizationId: verified.organizationId,\n },\n async () =>\n (await rebindReHomedContainer({\n existingState,\n heldBinding,\n isCurrent: input.isCurrent,\n state: input.state,\n verified,\n }))\n ? persistVerifiedRemoteContainer({\n ...input,\n existingState,\n expectedPlacementCheckpoint,\n })\n : null,\n );\n if (!remoteState) {\n return null;\n }\n await reconcileLocalOnlySystemContainers({\n childIdsByParentId: input.childIdsByParentId,\n isCurrent: input.isCurrent,\n requestDocumentPriming: input.host.requestDocumentPriming,\n remoteSystemState: remoteState,\n state: input.state,\n });\n return remoteState;\n}\n\n/**\n * Upsert one listed folder, isolating a rejected proof or binding. The refusal\n * was already reported; returning no state leaves the item unapplied without\n * blocking independent folders.\n */\nexport async function upsertIsolatedRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n try {\n return await upsertRemoteContainerState(input);\n } catch (error) {\n if (!isKeyingVerificationError(error)) throw error;\n return null;\n }\n}\n\nfunction persistVerifiedRemoteContainer(\n input: UpsertRemoteContainerStateInput & {\n existingState: ContainerState | undefined;\n expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n },\n): Promise<ContainerState | null> {\n const { existingState, expectedPlacementCheckpoint } = input;\n return existingState\n ? updateExistingRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents:\n input.containerIdsWithPendingStructuralIntents,\n existingState,\n host: input.host,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n })\n : insertRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n host: input.host,\n expectedHydrationTombstone: input.expectedHydrationTombstone ?? null,\n expectedPlacementCheckpoint,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteContainerState.js","sourceRoot":"","sources":["remoteContainerState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessManifestCheckpoint } from \"@tearleads/crypto\";\nimport {\n heldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../data/containers/containerBinding\";\nimport {\n isKeyingVerificationError,\n runWithSecurityIncidentReporting,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification/types\";\nimport type { ContainerHydrationTombstone } from \"./containerPersistence\";\nimport { installContainerMetadataRecord } from \"./metadataPersistence\";\nimport { projectionGeneration } from \"./projectionGeneration\";\nimport {\n moveIndexedContainerChild,\n removeIndexedContainerChild,\n} from \"./remoteHydration/childIndex\";\nimport type { PrefetchedDestinationProjection } from \"./remoteHydration/destinationPrefetch\";\nimport { rebindReHomedContainer } from \"./remoteHydration/heldContainerRebind\";\nimport { insertRemoteContainerState } from \"./remoteHydration/insertRemoteContainer\";\nimport {\n reconcileLocalOnlyRootContainers,\n reconcileLocalOnlySystemContainers,\n} from \"./remoteHydration/reconciliation\";\nimport {\n applyRemoteContainerTimestamps,\n remoteContainerHydrationSaveOptions,\n resolveRemoteContainerHydrationLocalUpdatedAt,\n} from \"./remoteHydration/remoteContainerTimestamps\";\nimport type {\n ContainerChildIndex,\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"./remoteHydration/types\";\nimport { verifyRemoteContainerDestination } from \"./remoteHydration/verifiedDestination\";\n\n// Container ids (restricted to the inbound page) that carry an unsynced local\n// create or move intent. Such a container's parent and local-edit timestamp are\n// owned by its structural-intent lane until that lane reconciles, so inbound\n// hydration must not revert parentId to the server value nor collapse\n// localUpdatedAt — doing so silently undoes a queued move and falsely reads\n// \"synced\". Move intents are read via listUnsyncedMoveIntents so a blocked\n// move — one whose destination parent has not synced yet, the common boot-time\n// case — is protected too. Pending *metadata*\n// updates are handled separately (listRemoteContainerIdsWithPendingMetadataUpdates);\n// these live in dedicated create/move intent tables that that query does not cover.\nexport async function listRemoteContainerIdsWithPendingStructuralIntents(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n if (input.remoteContainers.length === 0) {\n return new Set();\n }\n const remoteContainerIds = new Set(\n input.remoteContainers.map((remoteContainer) => remoteContainer.id),\n );\n\n const execSql = input.state.runtime.infra.execSql;\n const [pendingCreateIntents, unsyncedMoveIntents] = await Promise.all([\n input.state.persistence.listPendingCreateIntents(execSql),\n input.state.persistence.listUnsyncedMoveIntents(execSql),\n ]);\n const containerIdsWithPendingStructuralIntents = new Set<string>();\n for (const intent of pendingCreateIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n for (const intent of unsyncedMoveIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n return containerIdsWithPendingStructuralIntents;\n}\n\nexport async function listRemoteContainerIdsWithPendingMetadataUpdates(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n const containerIds = input.remoteContainers.flatMap((remoteContainer) => {\n const previousLocalUpdatedAt = input.state.containersById.get(\n remoteContainer.id,\n )?.container.localUpdatedAt;\n\n return previousLocalUpdatedAt &&\n previousLocalUpdatedAt.localeCompare(remoteContainer.updatedAt) > 0\n ? [remoteContainer.id]\n : [];\n });\n if (containerIds.length === 0) {\n return new Set();\n }\n\n const execSql = input.state.runtime.infra.execSql;\n return new Set(\n await input.state.persistence.listContainerIdsWithPendingUpdates(\n execSql,\n containerIds,\n ),\n );\n}\n\nfunction removeMissingHydratedContainer(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n existingState: ContainerState;\n host: RemoteContainerHydrationHost;\n previousParentId: string | null;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): void {\n const { existingState, remoteContainer, state } = input;\n if (state.containersById.get(remoteContainer.id) !== existingState) {\n return;\n }\n\n state.containersById.delete(remoteContainer.id);\n if (input.childIdsByParentId) {\n removeIndexedContainerChild(\n input.childIdsByParentId,\n remoteContainer.id,\n input.previousParentId,\n );\n input.childIdsByParentId.delete(remoteContainer.id);\n }\n input.host.updateSnapshot();\n}\n\nfunction createUpdatedRemoteContainerState(\n existingState: ContainerState,\n remoteContainer: RemoteContainer,\n): ContainerState {\n return {\n ...existingState,\n container: applyRemoteContainerTimestamps(\n existingState.container,\n remoteContainer,\n ),\n containerWriterProjection: null,\n metadataReferencedPrincipals: remoteContainer.metadataReferencedPrincipals,\n };\n}\n\nfunction installUpdatedRemoteContainerState(\n existingState: ContainerState,\n nextState: ContainerState,\n host: RemoteContainerHydrationHost,\n): void {\n const wasLocalOnly = existingState.container.serverCreatedAt == null;\n existingState.container = nextState.container;\n existingState.containerWriterProjection = nextState.containerWriterProjection;\n existingState.metadataReferencedPrincipals =\n nextState.metadataReferencedPrincipals;\n // The snapshot copied the live generation when it was taken; a hint that\n // landed during the persist leaves the live metadata projection dropped.\n if (projectionGeneration(existingState) === projectionGeneration(nextState))\n existingState.metadataWriterProjection = nextState.metadataWriterProjection;\n installContainerMetadataRecord(existingState, nextState.record);\n // A document pass may have deferred while this root was awaiting proof.\n // The first durable remote acknowledgement makes its pending creates runnable.\n if (wasLocalOnly && existingState.container.serverCreatedAt != null)\n host.requestDocumentPriming?.();\n}\n\nasync function updateExistingRemoteContainerState(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n existingState: ContainerState;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): Promise<ContainerState | null> {\n const { childIdsByParentId, existingState, host, remoteContainer, state } =\n input;\n const previousParentId = existingState.container.parentId;\n const previousLocalUpdatedAt = existingState.container.localUpdatedAt;\n // A queued, not-yet-synced local move/create owns this container's parent\n // until its intent lane reconciles. Omit the remote parent when the page scan\n // saw one; persistence also rechecks the intent transactionally so a move\n // created after that scan wins. Both paths preserve the durable local clock.\n const hasPendingStructuralIntent =\n input.containerIdsWithPendingStructuralIntents.has(remoteContainer.id);\n const nextParentId = hasPendingStructuralIntent\n ? undefined\n : remoteContainer.parentId;\n const localUpdatedAt = resolveRemoteContainerHydrationLocalUpdatedAt({\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n hasPendingStructuralIntent,\n previousLocalUpdatedAt,\n remoteContainer,\n });\n const nextState = createUpdatedRemoteContainerState(\n existingState,\n remoteContainer,\n );\n const persistenceResult = await host.persistContainerState(\n nextState,\n {\n accessEpoch: remoteContainer.metadataAccessEpoch,\n accessStateHash: remoteContainer.metadataAccessStateHash,\n documentId: remoteContainer.metadataDocumentId,\n effectiveAccessLevel: remoteContainer.effectiveAccessLevel,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n systemSlot: remoteContainer.systemSlot ?? null,\n organizationId: remoteContainer.organizationId,\n ...(nextParentId !== undefined ? { parentId: nextParentId } : {}),\n },\n false,\n remoteContainerHydrationSaveOptions({\n localUpdatedAt,\n remoteContainer,\n }),\n {\n preserveDurableStructureWhenPending: true,\n },\n );\n if (persistenceResult.status === \"missing\") {\n // Hydration persists a detached candidate so an in-flight response cannot\n // mutate mapped state before its guards settle. Retire the exact state this\n // hydration read because store-level reference cleanup cannot see the clone.\n removeMissingHydratedContainer({\n childIdsByParentId,\n existingState,\n host,\n previousParentId,\n remoteContainer,\n state,\n });\n return null;\n }\n if (persistenceResult.status !== \"persisted\") return null;\n const { record: nextRecord } = persistenceResult;\n installContainerMetadataRecord(nextState, nextRecord);\n if (input.isCurrent?.() === false) {\n return existingState;\n }\n nextState.container = {\n ...nextState.container,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n organizationId: remoteContainer.organizationId,\n parentId: nextState.container.parentId,\n };\n\n installUpdatedRemoteContainerState(existingState, nextState, host);\n moveIndexedContainerChild(\n childIdsByParentId,\n remoteContainer.id,\n previousParentId,\n existingState.container.parentId,\n );\n await reconcileLocalOnlyRootContainers({\n childIdsByParentId,\n isCurrent: input.isCurrent,\n remoteRootState: existingState,\n requestDocumentPriming: host.requestDocumentPriming,\n state,\n });\n return existingState;\n}\n\ninterface UpsertRemoteContainerStateInput {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n expectedHydrationTombstone?: ContainerHydrationTombstone | null | undefined;\n isCurrent?: (() => boolean) | undefined;\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}\n\nexport async function upsertRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n let expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n const heldState = input.state.containersById.get(input.remoteContainer.id);\n const heldBinding = heldState\n ? heldContainerBinding(heldState)\n : await input.state.persistence.loadHeldContainerBinding(\n input.state.runtime.infra.execSql,\n input.remoteContainer.id,\n );\n const listed = input.remoteContainer;\n // A folder re-homed away from the listed organization never returns there,\n // whatever binding (possibly none, after a reset) the device holds now.\n const supersededListing =\n !listingRepeatsHeldOrdinaryBinding(heldBinding, listed) &&\n (await input.state.persistence.isSupersededContainerBinding(\n input.state.runtime.infra.execSql,\n { containerId: listed.id, organizationId: listed.organizationId },\n ));\n if (input.isCurrent?.() === false) return null;\n const verified = await verifyRemoteContainerDestination({\n ...input,\n heldBinding,\n supersededListing,\n refresh: !!input.expectedHydrationTombstone,\n onVerifiedCheckpoint: (checkpoint) => {\n expectedPlacementCheckpoint = checkpoint;\n },\n });\n if (!verified || input.isCurrent?.() === false) return null;\n input = { ...input, remoteContainer: verified };\n const existingState = input.state.containersById.get(\n input.remoteContainer.id,\n );\n const remoteState = await runWithSecurityIncidentReporting(\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: verified.id,\n objectKind: \"container\",\n operation: \"container.binding.persist\",\n organizationId: verified.organizationId,\n },\n async () =>\n (await rebindReHomedContainer({\n existingState,\n heldBinding,\n isCurrent: input.isCurrent,\n state: input.state,\n verified,\n }))\n ? persistVerifiedRemoteContainer({\n ...input,\n existingState,\n expectedPlacementCheckpoint,\n })\n : null,\n );\n if (!remoteState) {\n return null;\n }\n await reconcileLocalOnlySystemContainers({\n childIdsByParentId: input.childIdsByParentId,\n isCurrent: input.isCurrent,\n requestDocumentPriming: input.host.requestDocumentPriming,\n remoteSystemState: remoteState,\n state: input.state,\n });\n return remoteState;\n}\n\n/**\n * Upsert one listed folder, isolating a rejected proof or binding. The refusal\n * was already reported; returning no state leaves the item unapplied without\n * blocking independent folders.\n */\nexport async function upsertIsolatedRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n try {\n return await upsertRemoteContainerState(input);\n } catch (error) {\n if (\n !isKeyingVerificationError(error) &&\n !isProjectionVerificationCancelledError(error)\n )\n throw error;\n return null;\n }\n}\n\nfunction persistVerifiedRemoteContainer(\n input: UpsertRemoteContainerStateInput & {\n existingState: ContainerState | undefined;\n expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n },\n): Promise<ContainerState | null> {\n const { existingState, expectedPlacementCheckpoint } = input;\n return existingState\n ? updateExistingRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents:\n input.containerIdsWithPendingStructuralIntents,\n existingState,\n host: input.host,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n })\n : insertRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n host: input.host,\n expectedHydrationTombstone: input.expectedHydrationTombstone ?? null,\n expectedPlacementCheckpoint,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n });\n}\n"]}
|
|
@@ -6,6 +6,7 @@ import { verifyContainerDestinationProjection } from "../../../data/keyingProjec
|
|
|
6
6
|
import { verifyContainerWriterProjection } from "../../../data/keyingProjectionVerification/containerProjectionVerification.js";
|
|
7
7
|
import { isKeyingVerificationError, reportKeyingVerificationErrorInCauseChain, runWithSecurityIncidentReporting, } from "../../../data/keyingProjectionVerification/error.js";
|
|
8
8
|
import { createGroupMetadataContainerVerifier } from "../../organizations/groupMetadataContainerAuthority.js";
|
|
9
|
+
import { createRuntimePrincipalPolicyWarmer } from "../../principals/runtimePolicyWarmer.js";
|
|
9
10
|
import { cachedDestinationRole, rememberDestinationRole, } from "./destinationRoleCache.js";
|
|
10
11
|
import { resolveWithMetadataRootReload } from "./destinationRootReload.js";
|
|
11
12
|
import { assertPermittedDestinationBinding } from "./replacementBinding.js";
|
|
@@ -97,6 +98,8 @@ async function verifyDestinationRole(input) {
|
|
|
97
98
|
execSql: runtime.infra.execSql,
|
|
98
99
|
projection,
|
|
99
100
|
resolveUserKey: runtime.resolveTrustedUserIdentity,
|
|
101
|
+
stillCurrent: isCurrent,
|
|
102
|
+
warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(runtime),
|
|
100
103
|
};
|
|
101
104
|
const { path, verifiedByHash } = await verifyContainerDestinationProjection(verificationInput);
|
|
102
105
|
if (isCurrent?.() === false)
|