@tearleads/client-sdk 0.1.66 → 0.1.67

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.
Files changed (23) hide show
  1. package/package.json +1 -1
  2. package/stores/container-contents/syncAgent/acceptedMoveRetry.js +40 -0
  3. package/stores/container-contents/syncAgent/acceptedMoveRetry.js.map +1 -0
  4. package/stores/container-contents/syncAgent/syncLaneIteration.js +9 -2
  5. package/stores/container-contents/syncAgent/syncLaneIteration.js.map +1 -1
  6. package/workflows/container-contents/container-state/move/acceptedMoveSettlement.js +59 -0
  7. package/workflows/container-contents/container-state/move/acceptedMoveSettlement.js.map +1 -0
  8. package/workflows/container-contents/container-state/{moveIntentSync.js → move/moveIntentSync.js} +71 -71
  9. package/workflows/container-contents/container-state/move/moveIntentSync.js.map +1 -0
  10. package/workflows/container-contents/container-state/remote.js +22 -19
  11. package/workflows/container-contents/container-state/remote.js.map +1 -1
  12. package/workflows/container-contents/container-state/types.js.map +1 -1
  13. package/workflows/containers/child/move/index.d.ts +24 -3
  14. package/workflows/containers/child/move/index.js +62 -71
  15. package/workflows/containers/child/move/index.js.map +1 -1
  16. package/workflows/containers/child/move/moveRequest.js +47 -0
  17. package/workflows/containers/child/move/moveRequest.js.map +1 -0
  18. package/workflows/containers/child/mutationSubmit.js +2 -3
  19. package/workflows/containers/child/mutationSubmit.js.map +1 -1
  20. package/workflows/containers/index.d.ts +1 -1
  21. package/workflows/containers/index.js +1 -1
  22. package/workflows/containers/index.js.map +1 -1
  23. package/workflows/container-contents/container-state/moveIntentSync.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./rekey/carriedDescendantRekeys\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /** Called when the server accepted but a stale caller dropped the result. */\n onStaleAcceptance?: (() => void) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) {\n input.onStaleAcceptance?.();\n return null;\n }\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
1
+ {"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./rekey/carriedDescendantRekeys\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /**\n * Called once the server has accepted the mutation, before this device\n * acknowledges it, so a caller can tell an accepted mutation it failed to\n * settle from one that never committed.\n */\n onAccepted?: (() => void) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n input.onAccepted?.();\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
@@ -7,7 +7,7 @@ export type { AggregatedContainerKekLog, KeyringRebuildResult, } from "../../dat
7
7
  export { fetchContainerKekLog, HistoricalWrapUnavailableError, type HistoricalWrapUnavailableReason, rebuildKeyringEntriesFromLog, recoverKeyringEntryFromWraps, } from "../../data/documents/shared/containerKek/keyringRebuild.js";
8
8
  export { isProjectionVerificationCancelledError } from "../../data/keyingProjectionVerification/types.js";
9
9
  export { buildContainerCreatePlan, buildMaterializedContainerCreatePlan, childContainerWriterProjectionFromCreatePlan, createRemoteContainer, } from "./child/create/index.js";
10
- export { moveRemoteContainer } from "./child/move/index.js";
10
+ export { type AppliedContainerMove, moveRemoteContainer, replayRemoteContainerMove, } from "./child/move/index.js";
11
11
  export { buildMaterializedContainerRekeyPlan } from "./child/rekey/index.js";
12
12
  export { ContainerKeyringOverrideStaleError } from "./child/rekey/keyringOverrideLineage.js";
13
13
  export { containerWriterProjectionFromRekeyPlan } from "./child/rekey/rekeyProjection.js";
@@ -10,7 +10,7 @@ export { fetchContainerKekLog, HistoricalWrapUnavailableError, rebuildKeyringEnt
10
10
  // underneath the caller; hosts filter that outcome from their own reporting.
11
11
  export { isProjectionVerificationCancelledError } from "../../data/keyingProjectionVerification/types.js";
12
12
  export { buildContainerCreatePlan, buildMaterializedContainerCreatePlan, childContainerWriterProjectionFromCreatePlan, createRemoteContainer, } from "./child/create/index.js";
13
- export { moveRemoteContainer } from "./child/move/index.js";
13
+ export { moveRemoteContainer, replayRemoteContainerMove, } from "./child/move/index.js";
14
14
  export { buildMaterializedContainerRekeyPlan } from "./child/rekey/index.js";
15
15
  // A rebuilt keyring override that a concurrent rotation outdated: rebuild it.
16
16
  export { ContainerKeyringOverrideStaleError } from "./child/rekey/keyringOverrideLineage.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iEAAiE;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,4DAA4D;AAC5D,8EAA8E;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,kDAAkD,CAAC;AAM7F,OAAO,EACL,mCAAmC,EACnC,+BAA+B,GAChC,MAAM,+DAA+D,CAAC;AAKvE,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAE9B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,yDAAyD,CAAC;AACjE,2EAA2E;AAC3E,6EAA6E;AAC7E,OAAO,EAAE,sCAAsC,EAAE,MAAM,+CAA+C,CAAC;AACvG,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,4CAA4C,EAC5C,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC;AACpE,8EAA8E;AAC9E,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,sCAAsC,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,oCAAoC,EACpC,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,qCAAqC,GAEtC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,uCAAuC,EACvC,qDAAqD,GACtD,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,4BAA4B,EAC5B,2CAA2C,GAC5C,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC","sourcesContent":["// Refusals the SDK raises before it encrypts or sends a container-scoped\n// write; hosts classify them with classifyContainerWriteRefusal.\nexport { ContainerAuthorAccessError } from \"../../data/containers/shared/authorAccess\";\n// A create or move past the readable path length; `code` is\n// `container_path_too_deep`. Queued moves are abandoned, queued creates wait.\nexport { ContainerPathTooDeepError } from \"../../data/containers/shared/containerPathLimits\";\nexport type { ContainerReciteApi } from \"../../data/containers/shared/reciteApi\";\nexport type {\n ContainerMutationAuthor,\n MaterializedContainerRekeyPlan,\n} from \"../../data/containers/shared/types\";\nexport {\n ContainerKekRepairInaccessibleError,\n ContainerKekRepairRequiredError,\n} from \"../../data/documents/shared/containerKek/containerKekCurrency\";\nexport type {\n AggregatedContainerKekLog,\n KeyringRebuildResult,\n} from \"../../data/documents/shared/containerKek/keyringRebuild\";\nexport {\n fetchContainerKekLog,\n HistoricalWrapUnavailableError,\n type HistoricalWrapUnavailableReason,\n rebuildKeyringEntriesFromLog,\n recoverKeyringEntryFromWraps,\n} from \"../../data/documents/shared/containerKek/keyringRebuild\";\n// A share's projection verification can be cancelled by a newer generation\n// underneath the caller; hosts filter that outcome from their own reporting.\nexport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification/types\";\nexport {\n buildContainerCreatePlan,\n buildMaterializedContainerCreatePlan,\n childContainerWriterProjectionFromCreatePlan,\n createRemoteContainer,\n} from \"./child/create\";\nexport { moveRemoteContainer } from \"./child/move\";\nexport { buildMaterializedContainerRekeyPlan } from \"./child/rekey\";\n// A rebuilt keyring override that a concurrent rotation outdated: rebuild it.\nexport { ContainerKeyringOverrideStaleError } from \"./child/rekey/keyringOverrideLineage\";\nexport { containerWriterProjectionFromRekeyPlan } from \"./child/rekey/rekeyProjection\";\nexport { rekeyRemoteContainer } from \"./child/rekey/rekeyRemote\";\nexport {\n buildMaterializedContainerRevokePlan,\n revokeRemoteContainer,\n} from \"./child/revoke\";\nexport {\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"./child/share\";\nexport { buildMaterializedContainerSharePlan } from \"./child/share/shareMaterialization\";\nexport { referencedPrincipalHeadFromPolicy } from \"./child/share/sharePlanCore\";\nexport {\n advanceVerifiedSharePolicies,\n GroupShareNameMismatchError,\n loadVerifiedGroupSharePrincipalPolicy,\n type VerifiedSharePrincipalPolicy,\n} from \"./child/share/sharePrincipalPolicy\";\nexport {\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n} from \"./mutationResponse\";\nexport {\n buildRootContainerCreatePlan,\n rootContainerWriterProjectionFromCreatePlan,\n} from \"./root/create\";\nexport {\n type ContainerWriteRefusal,\n classifyContainerWriteRefusal,\n} from \"./writeRefusal\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iEAAiE;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,4DAA4D;AAC5D,8EAA8E;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,kDAAkD,CAAC;AAM7F,OAAO,EACL,mCAAmC,EACnC,+BAA+B,GAChC,MAAM,+DAA+D,CAAC;AAKvE,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAE9B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,yDAAyD,CAAC;AACjE,2EAA2E;AAC3E,6EAA6E;AAC7E,OAAO,EAAE,sCAAsC,EAAE,MAAM,+CAA+C,CAAC;AACvG,OAAO,EACL,wBAAwB,EACxB,oCAAoC,EACpC,4CAA4C,EAC5C,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,mCAAmC,EAAE,MAAM,eAAe,CAAC;AACpE,8EAA8E;AAC9E,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,sCAAsC,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,oCAAoC,EACpC,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mCAAmC,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,qCAAqC,GAEtC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,uCAAuC,EACvC,qDAAqD,GACtD,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,4BAA4B,EAC5B,2CAA2C,GAC5C,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC","sourcesContent":["// Refusals the SDK raises before it encrypts or sends a container-scoped\n// write; hosts classify them with classifyContainerWriteRefusal.\nexport { ContainerAuthorAccessError } from \"../../data/containers/shared/authorAccess\";\n// A create or move past the readable path length; `code` is\n// `container_path_too_deep`. Queued moves are abandoned, queued creates wait.\nexport { ContainerPathTooDeepError } from \"../../data/containers/shared/containerPathLimits\";\nexport type { ContainerReciteApi } from \"../../data/containers/shared/reciteApi\";\nexport type {\n ContainerMutationAuthor,\n MaterializedContainerRekeyPlan,\n} from \"../../data/containers/shared/types\";\nexport {\n ContainerKekRepairInaccessibleError,\n ContainerKekRepairRequiredError,\n} from \"../../data/documents/shared/containerKek/containerKekCurrency\";\nexport type {\n AggregatedContainerKekLog,\n KeyringRebuildResult,\n} from \"../../data/documents/shared/containerKek/keyringRebuild\";\nexport {\n fetchContainerKekLog,\n HistoricalWrapUnavailableError,\n type HistoricalWrapUnavailableReason,\n rebuildKeyringEntriesFromLog,\n recoverKeyringEntryFromWraps,\n} from \"../../data/documents/shared/containerKek/keyringRebuild\";\n// A share's projection verification can be cancelled by a newer generation\n// underneath the caller; hosts filter that outcome from their own reporting.\nexport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification/types\";\nexport {\n buildContainerCreatePlan,\n buildMaterializedContainerCreatePlan,\n childContainerWriterProjectionFromCreatePlan,\n createRemoteContainer,\n} from \"./child/create\";\nexport {\n type AppliedContainerMove,\n moveRemoteContainer,\n replayRemoteContainerMove,\n} from \"./child/move\";\nexport { buildMaterializedContainerRekeyPlan } from \"./child/rekey\";\n// A rebuilt keyring override that a concurrent rotation outdated: rebuild it.\nexport { ContainerKeyringOverrideStaleError } from \"./child/rekey/keyringOverrideLineage\";\nexport { containerWriterProjectionFromRekeyPlan } from \"./child/rekey/rekeyProjection\";\nexport { rekeyRemoteContainer } from \"./child/rekey/rekeyRemote\";\nexport {\n buildMaterializedContainerRevokePlan,\n revokeRemoteContainer,\n} from \"./child/revoke\";\nexport {\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"./child/share\";\nexport { buildMaterializedContainerSharePlan } from \"./child/share/shareMaterialization\";\nexport { referencedPrincipalHeadFromPolicy } from \"./child/share/sharePlanCore\";\nexport {\n advanceVerifiedSharePolicies,\n GroupShareNameMismatchError,\n loadVerifiedGroupSharePrincipalPolicy,\n type VerifiedSharePrincipalPolicy,\n} from \"./child/share/sharePrincipalPolicy\";\nexport {\n readContainerMutationMetadataDocumentId,\n referencedPrincipalHeadsFromContainerMutationResponse,\n} from \"./mutationResponse\";\nexport {\n buildRootContainerCreatePlan,\n rootContainerWriterProjectionFromCreatePlan,\n} from \"./root/create\";\nexport {\n type ContainerWriteRefusal,\n classifyContainerWriteRefusal,\n} from \"./writeRefusal\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"moveIntentSync.js","sourceRoot":"","sources":["moveIntentSync.ts"],"names":[],"mappings":"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","sourcesContent":["import { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { reportAndRethrowKeyingVerificationError } from \"../../../data/keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../../data/shared/errorMessage\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport {\n createDetachedContainerMetadataState,\n installDetachedContainerMetadataState,\n} from \"../metadata/metadataStateIsolation\";\nimport type { ContainerState, RemoteContainer } from \"../remoteHydration\";\nimport { hasRemoteContainerMetadataState } from \"../remoteHydration/reconciliation\";\nimport { moveRemoteContainer } from \"./remote\";\nimport type {\n ContainerMoveIntentSyncHost,\n ContainerMoveIntentSyncInput,\n ContainerMoveIntentSyncState,\n} from \"./types\";\n\ntype MoveIntentSyncResult = \"abandoned\" | \"blocked\" | \"failed\" | \"moved\";\n\nfunction currentMoveResult<\n Result extends Exclude<MoveIntentSyncResult, \"abandoned\">,\n>(isCurrent: () => boolean, result: Result): \"abandoned\" | Result {\n return isCurrent() ? result : \"abandoned\";\n}\n\n/**\n * The server accepted a move this pass did not settle, so the intent stays\n * queued: a later pass re-posts it and a purge of its subtree waits. Fixed\n * messages only; the error's call site names the path.\n */\nfunction reportUnsettledAcceptedMove(\n state: ContainerMoveIntentSyncState,\n message: string,\n error: Error,\n): void {\n try {\n const report = state.runtime.util.logError;\n if (report) void Promise.resolve(report(message, error)).catch(() => {});\n } catch {\n // A host logger must not change the replay result.\n }\n}\n\nfunction reportStaleAcceptedMove(\n state: ContainerMoveIntentSyncState,\n error: Error,\n): void {\n reportUnsettledAcceptedMove(\n state,\n \"Container contents: a stale sync pass dropped an accepted container move\",\n error,\n );\n}\n\nfunction reportFailedAcceptedMove(\n state: ContainerMoveIntentSyncState,\n error: unknown,\n): void {\n if (!(error instanceof Error)) return;\n reportUnsettledAcceptedMove(\n state,\n \"Container contents: an accepted container move failed to settle\",\n error,\n );\n}\n\n/** persistAcceptedMoveIntent already asked to reconcile a stale result. */\nfunction unpersistedMoveResult(\n syncInput: ContainerMoveIntentSyncInput,\n): MoveIntentSyncResult {\n if (!syncInput.isCurrent()) {\n reportStaleAcceptedMove(\n syncInput.state,\n new Error(\"Stale pass dropped a persisting container move\"),\n );\n return \"abandoned\";\n }\n reportUnsettledAcceptedMove(\n syncInput.state,\n \"Container contents: an accepted container move did not persist\",\n new Error(\"Accepted container move did not persist\"),\n );\n return \"failed\";\n}\n\nasync function recordPendingMoveIntentError(input: {\n blocked?: boolean | undefined;\n containerId: string;\n expectedIntentId: string;\n expectedUpdatedAt: string;\n isCurrent: () => boolean;\n message: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n if (!input.isCurrent()) {\n return false;\n }\n const execSql = input.state.runtime.infra.execSql;\n await input.state.persistence.recordMoveIntentError(execSql, {\n blocked: input.blocked,\n containerId: input.containerId,\n expectedIntentId: input.expectedIntentId,\n expectedUpdatedAt: input.expectedUpdatedAt,\n message: input.message,\n stillCurrent: input.isCurrent,\n });\n return input.isCurrent();\n}\n\nasync function resolveMoveIntentLocalUpdatedAt(input: {\n containerId: string;\n isCurrent: () => boolean;\n remoteUpdatedAt: string;\n state: ContainerMoveIntentSyncState;\n}): Promise<string | null> {\n if (!input.isCurrent()) {\n return null;\n }\n const previousLocalUpdatedAt =\n input.state.containersById.get(input.containerId)?.container\n .localUpdatedAt ?? null;\n if (\n !previousLocalUpdatedAt ||\n previousLocalUpdatedAt.localeCompare(input.remoteUpdatedAt) <= 0\n ) {\n return input.remoteUpdatedAt;\n }\n\n const execSql = input.state.runtime.infra.execSql;\n const containersWithPendingMetadataUpdates =\n await input.state.persistence.listContainerIdsWithPendingUpdates(execSql, [\n input.containerId,\n ]);\n if (!input.isCurrent()) {\n return null;\n }\n\n return containersWithPendingMetadataUpdates.includes(input.containerId)\n ? previousLocalUpdatedAt\n : input.remoteUpdatedAt;\n}\n\nexport async function persistAcceptedMoveIntent(input: {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n intent: ContainerMoveIntentSyncInput[\"intent\"];\n moved: RemoteContainer;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<boolean> {\n const { host, intent, moved, state } = input;\n const abandon = () => {\n input.requestRemoteReconciliation(moved.parentId);\n return false;\n };\n if (!input.isCurrent()) return abandon();\n const containerState = state.containersById.get(intent.containerId);\n if (!containerState) {\n return false;\n }\n\n await createRuntimePrincipalPolicyWarmer(state.runtime)({\n organizationId: moved.organizationId,\n references: moved.metadataReferencedPrincipals,\n stillCurrent: input.isCurrent,\n });\n if (!input.isCurrent()) {\n return abandon();\n }\n const localUpdatedAt = await resolveMoveIntentLocalUpdatedAt({\n containerId: intent.containerId,\n isCurrent: input.isCurrent,\n remoteUpdatedAt: moved.updatedAt,\n state,\n });\n if (!input.isCurrent() || localUpdatedAt === null) {\n return abandon();\n }\n const persistenceCandidate =\n await createDetachedContainerMetadataState(containerState);\n if (!input.isCurrent()) {\n return abandon();\n }\n persistenceCandidate.container = {\n ...persistenceCandidate.container,\n createdAt: moved.createdAt,\n serverCreatedAt: moved.createdAt,\n serverUpdatedAt: moved.updatedAt,\n updatedAt: moved.updatedAt,\n };\n const persistenceResult = await host.persistContainerState(\n persistenceCandidate,\n {\n accessEpoch: moved.metadataAccessEpoch,\n accessStateHash: moved.metadataAccessStateHash,\n documentId: moved.metadataDocumentId,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n systemSlot: moved.systemSlot ?? null,\n },\n false,\n {\n localUpdatedAt,\n serverTimestamps: {\n createdAt: moved.createdAt,\n updatedAt: moved.updatedAt,\n },\n },\n {\n expectedStateWhenMissing: containerState,\n isCurrent: input.isCurrent,\n moveIntentSettlement: {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n },\n },\n );\n if (!input.isCurrent() || persistenceResult.status !== \"persisted\") {\n return abandon();\n }\n if (persistenceResult.moveIntentSettled !== true) {\n throw new Error(\n \"Container move persistence must settle the intent atomically\",\n );\n }\n if (!input.isCurrent()) return abandon();\n const { record: nextRecord } = persistenceResult;\n installDetachedContainerMetadataState(containerState, persistenceCandidate, {\n candidateRecord: nextRecord,\n preserveConcurrentMetadataEdit: true,\n });\n containerState.container = {\n ...containerState.container,\n metadataDocumentId: moved.metadataDocumentId,\n organizationId: moved.organizationId,\n parentId: moved.parentId,\n };\n return true;\n}\n\n/**\n * A move refused for path length never succeeds; the queue-time check saw only\n * the descendants this device holds. Drop the queued move and restore the\n * previous parent together: the server row never changed, so no listing would\n * ever put the folder back.\n */\nasync function abandonTooDeepMove(\n syncInput: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { host, intent, state } = syncInput;\n const previousParentId = intent.previousParentContainerId;\n if (previousParentId === null) {\n throw new Error(\"A queued container move must name its previous parent\");\n }\n const abandoned = await state.persistence.abandonMoveIntentRevision(\n state.runtime.infra.execSql,\n {\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n previousParentContainerId: previousParentId,\n stillCurrent: syncInput.isCurrent,\n },\n );\n if (!syncInput.isCurrent()) return \"abandoned\";\n // A newer local move superseded this revision; it replays on its own.\n if (!abandoned) return \"failed\";\n const containerState = state.containersById.get(intent.containerId);\n if (containerState) {\n containerState.container = {\n ...containerState.container,\n parentId: previousParentId,\n };\n }\n host.updateSnapshot();\n state.runtime.util.log(\n `Container contents: abandoned queued move of ${intent.containerId}; its path would exceed the maximum depth`,\n );\n return \"failed\";\n}\n\nasync function movePendingRemoteContainer(input: {\n parentState: ContainerState;\n syncInput: ContainerMoveIntentSyncInput;\n}): Promise<MoveIntentSyncResult> {\n const { parentState, syncInput } = input;\n const { host, intent, state } = syncInput;\n let remoteMoveApplied = false;\n let remoteParentId: string | null = intent.parentContainerId;\n const abandonAppliedMove = () => {\n if (remoteMoveApplied) {\n reportStaleAcceptedMove(\n state,\n new Error(\"Stale pass dropped an accepted container move\"),\n );\n syncInput.requestRemoteReconciliation(remoteParentId);\n }\n return \"abandoned\" as const;\n };\n try {\n const moved = await moveRemoteContainer({\n containerId: intent.containerId,\n onStaleAcceptance: () => {\n remoteMoveApplied = true;\n },\n parentContainerId: intent.parentContainerId,\n resolveProjectionUserKey: state.resolveProjectionUserKey,\n runtime: state.runtime,\n stillCurrent: syncInput.isCurrent,\n });\n if (!moved) {\n if (!syncInput.isCurrent()) {\n if (!remoteMoveApplied)\n syncInput.requestRemoteReconciliation(intent.parentContainerId);\n return abandonAppliedMove();\n }\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: \"Remote container move was rejected or unavailable\",\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n remoteMoveApplied = true;\n remoteParentId = moved.parentId;\n if (!syncInput.isCurrent()) return abandonAppliedMove();\n\n const persisted = await persistAcceptedMoveIntent({\n host,\n isCurrent: syncInput.isCurrent,\n intent,\n moved,\n requestRemoteReconciliation: syncInput.requestRemoteReconciliation,\n state,\n });\n if (!persisted) return unpersistedMoveResult(syncInput);\n state.runtime.util.log(\n `Container contents: synced queued container move ${intent.containerId}`,\n );\n return \"moved\";\n } catch (error: unknown) {\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (error instanceof ContainerPathTooDeepError)\n return abandonTooDeepMove(syncInput);\n await reportAndRethrowKeyingVerificationError(\n error,\n state.runtime.util.reportSecurityIncident,\n {\n objectId: intent.containerId,\n objectKind: \"container\",\n operation: \"container.move.replay\",\n organizationId: parentState.container.organizationId,\n },\n );\n if (!syncInput.isCurrent()) {\n return abandonAppliedMove();\n }\n if (remoteMoveApplied) reportFailedAcceptedMove(state, error);\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: syncInput.isCurrent,\n message: `Failed to sync container move: ${errorMessage(error)}`,\n state,\n });\n return currentMoveResult(syncInput.isCurrent, \"failed\");\n }\n}\n\nasync function trySyncPendingContainerMoveIntent(\n input: ContainerMoveIntentSyncInput,\n): Promise<MoveIntentSyncResult> {\n const { intent, state } = input;\n if (!input.isCurrent()) {\n return \"abandoned\";\n }\n const containerState = state.containersById.get(intent.containerId);\n const parentState = state.containersById.get(intent.parentContainerId);\n\n if (!containerState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move intent references a missing local container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (!parentState) {\n await recordPendingMoveIntentError({\n blocked: true,\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message:\n \"Container move intent references a missing destination parent container\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"failed\");\n }\n if (input.isRemoteSyncBlocked(containerState.container.organizationId)) {\n return \"blocked\";\n }\n if (\n !hasRemoteContainerMetadataState(containerState) ||\n input.isCreatePending(intent.containerId)\n ) {\n // Source not synced yet is TRANSIENT, exactly like the destination case\n // below: the source's own create intent syncs first (createIntentSync runs\n // before moveIntentSync in a pass), but if that create fails on this pass\n // the source still lacks remote metadata here. Keep the intent 'pending'\n // (not 'blocked') so the queue reports a retryable failure rather than a\n // missing-dependency block; either way listUnsyncedMoveIntents replays it\n // once the create lands.\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move source is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n if (\n !hasRemoteContainerMetadataState(parentState) ||\n input.isCreatePending(intent.parentContainerId)\n ) {\n await recordPendingMoveIntentError({\n containerId: intent.containerId,\n expectedIntentId: intent.id,\n expectedUpdatedAt: intent.updatedAt,\n isCurrent: input.isCurrent,\n message: \"Container move destination parent is not synced yet\",\n state,\n });\n return currentMoveResult(input.isCurrent, \"blocked\");\n }\n\n return movePendingRemoteContainer({ parentState, syncInput: input });\n}\n\nexport async function syncPendingContainerMoveIntents(input: {\n host: ContainerMoveIntentSyncHost;\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}): Promise<number> {\n if (!input.isCurrent()) {\n return 0;\n }\n const { host } = input;\n const state = { ...input.state };\n const execSql = state.runtime.infra.execSql;\n const pendingIntents =\n await state.persistence.listUnsyncedMoveIntents(execSql);\n if (!input.isCurrent()) {\n return 0;\n }\n let movedCount = 0;\n\n for (const intent of pendingIntents) {\n if (!input.isCurrent()) {\n return movedCount;\n }\n const result = await trySyncPendingContainerMoveIntent({\n host,\n isCurrent: input.isCurrent,\n isCreatePending: input.isCreatePending,\n isRemoteSyncBlocked: input.isRemoteSyncBlocked,\n intent,\n requestRemoteReconciliation: input.requestRemoteReconciliation,\n state,\n });\n if (result === \"abandoned\") {\n return movedCount;\n }\n\n if (result === \"moved\") {\n movedCount += 1;\n }\n }\n\n return movedCount;\n}\n"]}