@tearleads/client-sdk 0.1.63 → 0.1.64

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 (616) hide show
  1. package/data/documents/blob/shared/projection.js +1 -1
  2. package/data/documents/blob/shared/projection.js.map +1 -1
  3. package/data/documents/shared/projectionContentKeys.js +1 -1
  4. package/data/documents/shared/projectionContentKeys.js.map +1 -1
  5. package/data/documents/shared/syncResponseAuthorization.js +1 -1
  6. package/data/documents/shared/syncResponseAuthorization.js.map +1 -1
  7. package/data/keyingProjectionVerification/{accessManifestCheckpointEnforcement.js → checkpoints/accessManifestCheckpointEnforcement.js} +2 -2
  8. package/data/keyingProjectionVerification/checkpoints/accessManifestCheckpointEnforcement.js.map +1 -0
  9. package/data/keyingProjectionVerification/{bundleVerification.js → checkpoints/bundleVerification.js} +5 -5
  10. package/data/keyingProjectionVerification/checkpoints/bundleVerification.js.map +1 -0
  11. package/data/keyingProjectionVerification/{checkpointContext.d.ts → checkpoints/checkpointContext.d.ts} +6 -6
  12. package/data/keyingProjectionVerification/{checkpointContext.js → checkpoints/checkpointContext.js} +6 -6
  13. package/data/keyingProjectionVerification/checkpoints/checkpointContext.js.map +1 -0
  14. package/data/keyingProjectionVerification/{manifestCheckpointVerification.js → checkpoints/manifestCheckpointVerification.js} +2 -2
  15. package/data/keyingProjectionVerification/checkpoints/manifestCheckpointVerification.js.map +1 -0
  16. package/data/keyingProjectionVerification/{containerAncestorCitations.js → container/containerAncestorCitations.js} +4 -4
  17. package/data/keyingProjectionVerification/container/containerAncestorCitations.js.map +1 -0
  18. package/data/keyingProjectionVerification/{containerCreateManifest.js → container/containerCreateManifest.js} +1 -1
  19. package/data/keyingProjectionVerification/{containerDestinationVerification.js → container/containerDestinationVerification.js} +4 -4
  20. package/data/keyingProjectionVerification/container/containerDestinationVerification.js.map +1 -0
  21. package/data/keyingProjectionVerification/{containerManifestVerification.js → container/containerManifestVerification.js} +7 -7
  22. package/data/keyingProjectionVerification/container/containerManifestVerification.js.map +1 -0
  23. package/data/keyingProjectionVerification/{containerPathVerification.js → container/containerPathVerification.js} +2 -2
  24. package/data/keyingProjectionVerification/container/containerPathVerification.js.map +1 -0
  25. package/data/keyingProjectionVerification/{containerProjectionVerification.d.ts → container/containerProjectionVerification.d.ts} +7 -7
  26. package/data/keyingProjectionVerification/{containerProjectionVerification.js → container/containerProjectionVerification.js} +9 -9
  27. package/data/keyingProjectionVerification/container/containerProjectionVerification.js.map +1 -0
  28. package/data/keyingProjectionVerification/{documentDependencyPaths.d.ts → document/documentDependencyPaths.d.ts} +1 -1
  29. package/data/keyingProjectionVerification/{documentDependencyPaths.js → document/documentDependencyPaths.js} +3 -3
  30. package/data/keyingProjectionVerification/document/documentDependencyPaths.js.map +1 -0
  31. package/data/keyingProjectionVerification/{documentManifestPolicies.js → document/documentManifestPolicies.js} +2 -2
  32. package/data/keyingProjectionVerification/document/documentManifestPolicies.js.map +1 -0
  33. package/data/keyingProjectionVerification/{documentManifestPredecessor.js → document/documentManifestPredecessor.js} +1 -1
  34. package/data/keyingProjectionVerification/{documentManifestVerification.js → document/documentManifestVerification.js} +5 -5
  35. package/data/keyingProjectionVerification/document/documentManifestVerification.js.map +1 -0
  36. package/data/keyingProjectionVerification/{documentProjectionVerification.d.ts → document/documentProjectionVerification.d.ts} +4 -4
  37. package/data/keyingProjectionVerification/{documentProjectionVerification.js → document/documentProjectionVerification.js} +9 -9
  38. package/data/keyingProjectionVerification/document/documentProjectionVerification.js.map +1 -0
  39. package/data/keyingProjectionVerification/{documentPurgeCheckpointCurrency.js → documentPurge/documentPurgeCheckpointCurrency.js} +12 -12
  40. package/data/keyingProjectionVerification/documentPurge/documentPurgeCheckpointCurrency.js.map +1 -0
  41. package/data/keyingProjectionVerification/{documentPurgeCheckpointEnforcement.js → documentPurge/documentPurgeCheckpointEnforcement.js} +2 -2
  42. package/data/keyingProjectionVerification/documentPurge/documentPurgeCheckpointEnforcement.js.map +1 -0
  43. package/data/keyingProjectionVerification/{documentPurgeDocumentChainVerification.js → documentPurge/documentPurgeDocumentChainVerification.js} +8 -8
  44. package/data/keyingProjectionVerification/documentPurge/documentPurgeDocumentChainVerification.js.map +1 -0
  45. package/data/keyingProjectionVerification/{documentPurgePolicyCheckpoints.js → documentPurge/documentPurgePolicyCheckpoints.js} +2 -2
  46. package/data/keyingProjectionVerification/documentPurge/documentPurgePolicyCheckpoints.js.map +1 -0
  47. package/data/keyingProjectionVerification/{documentPurgePolicyCurrency.js → documentPurge/documentPurgePolicyCurrency.js} +4 -4
  48. package/data/keyingProjectionVerification/documentPurge/documentPurgePolicyCurrency.js.map +1 -0
  49. package/data/keyingProjectionVerification/{documentPurgePrincipalEvidence.js → documentPurge/documentPurgePrincipalEvidence.js} +3 -3
  50. package/data/keyingProjectionVerification/documentPurge/documentPurgePrincipalEvidence.js.map +1 -0
  51. package/data/keyingProjectionVerification/{documentPurgeProofVerification.d.ts → documentPurge/documentPurgeProofVerification.d.ts} +5 -5
  52. package/data/keyingProjectionVerification/{documentPurgeProofVerification.js → documentPurge/documentPurgeProofVerification.js} +10 -10
  53. package/data/keyingProjectionVerification/documentPurge/documentPurgeProofVerification.js.map +1 -0
  54. package/data/keyingProjectionVerification/index.d.ts +4 -4
  55. package/data/keyingProjectionVerification/index.js +4 -4
  56. package/data/keyingProjectionVerification/index.js.map +1 -1
  57. package/data/keyingProjectionVerification/{mergeProjectionPolicyEvidence.js → principalPolicy/mergeProjectionPolicyEvidence.js} +2 -2
  58. package/data/keyingProjectionVerification/principalPolicy/mergeProjectionPolicyEvidence.js.map +1 -0
  59. package/data/keyingProjectionVerification/{organizationFounderBinding.js → principalPolicy/organizationFounderBinding.js} +3 -3
  60. package/data/keyingProjectionVerification/principalPolicy/organizationFounderBinding.js.map +1 -0
  61. package/data/keyingProjectionVerification/{principalPolicyCache.js → principalPolicy/principalPolicyCache.js} +6 -6
  62. package/data/keyingProjectionVerification/principalPolicy/principalPolicyCache.js.map +1 -0
  63. package/data/keyingProjectionVerification/{principalPolicyVerification.js → principalPolicy/principalPolicyVerification.js} +12 -12
  64. package/data/keyingProjectionVerification/principalPolicy/principalPolicyVerification.js.map +1 -0
  65. package/data/keyingProjectionVerification/{projectionAuthorizationEvidence.js → principalPolicy/projectionAuthorizationEvidence.js} +3 -3
  66. package/data/keyingProjectionVerification/principalPolicy/projectionAuthorizationEvidence.js.map +1 -0
  67. package/data/keyingProjectionVerification/{projectionPolicyEvidence.js → principalPolicy/projectionPolicyEvidence.js} +3 -3
  68. package/data/keyingProjectionVerification/principalPolicy/projectionPolicyEvidence.js.map +1 -0
  69. package/data/keyingProjectionVerification/{resolvedPrincipalPolicy.js → principalPolicy/resolvedPrincipalPolicy.js} +6 -6
  70. package/data/keyingProjectionVerification/principalPolicy/resolvedPrincipalPolicy.js.map +1 -0
  71. package/package.json +1 -1
  72. package/stores/container-contents/accessRestorationSweep.js +1 -1
  73. package/stores/container-contents/accessRestorationSweep.js.map +1 -1
  74. package/stores/container-contents/containerContentsStore.d.ts +1 -1
  75. package/stores/container-contents/containerContentsStore.js +12 -12
  76. package/stores/container-contents/containerContentsStore.js.map +1 -1
  77. package/stores/container-contents/containerState/containerStateMap.js.map +1 -0
  78. package/stores/container-contents/{containerStatePersistence.js → containerState/containerStatePersistence.js} +2 -2
  79. package/stores/container-contents/containerState/containerStatePersistence.js.map +1 -0
  80. package/stores/container-contents/{missingContainerState.js → containerState/missingContainerState.js} +1 -1
  81. package/stores/container-contents/containerState/missingContainerState.js.map +1 -0
  82. package/stores/container-contents/containerState/missingSyncedContainerState.js.map +1 -0
  83. package/stores/container-contents/{reconcilableContainer.d.ts → containerState/reconcilableContainer.d.ts} +1 -1
  84. package/stores/container-contents/containerState/reconcilableContainer.js.map +1 -0
  85. package/stores/container-contents/{documentRecovery.js → documentWork/documentRecovery.js} +6 -6
  86. package/stores/container-contents/documentWork/documentRecovery.js.map +1 -0
  87. package/stores/container-contents/{documentRotation.js → documentWork/documentRotation.js} +2 -2
  88. package/stores/container-contents/documentWork/documentRotation.js.map +1 -0
  89. package/stores/container-contents/{documentWork.js → documentWork/index.js} +1 -1
  90. package/stores/container-contents/documentWork/index.js.map +1 -0
  91. package/stores/container-contents/{backgroundHydration.js → hydration/backgroundHydration.js} +3 -3
  92. package/stores/container-contents/hydration/backgroundHydration.js.map +1 -0
  93. package/stores/container-contents/{remoteHydrationRequest.js → hydration/remoteHydrationRequest.js} +3 -3
  94. package/stores/container-contents/hydration/remoteHydrationRequest.js.map +1 -0
  95. package/stores/container-contents/{startupHydration.js → hydration/startupHydration.js} +3 -3
  96. package/stores/container-contents/hydration/startupHydration.js.map +1 -0
  97. package/stores/container-contents/index.d.ts +3 -3
  98. package/stores/container-contents/index.js +2 -2
  99. package/stores/container-contents/index.js.map +1 -1
  100. package/stores/container-contents/localRefresh.js +2 -2
  101. package/stores/container-contents/localRefresh.js.map +1 -1
  102. package/stores/container-contents/{containerPurgeCore.js → operations/containerPurgeCore.js} +4 -4
  103. package/stores/container-contents/operations/containerPurgeCore.js.map +1 -0
  104. package/stores/container-contents/operations/emptyTrashOperation.js.map +1 -0
  105. package/stores/container-contents/{groupRewrapOperation.js → operations/groupRewrapOperation.js} +2 -2
  106. package/stores/container-contents/operations/groupRewrapOperation.js.map +1 -0
  107. package/stores/container-contents/{operations.js → operations/index.js} +18 -18
  108. package/stores/container-contents/operations/index.js.map +1 -0
  109. package/stores/container-contents/operations/purgeContainerOperation.js.map +1 -0
  110. package/stores/container-contents/{reportShareFailure.js → operations/reportShareFailure.js} +4 -4
  111. package/stores/container-contents/operations/reportShareFailure.js.map +1 -0
  112. package/stores/container-contents/{setContainerIconOperation.js → operations/setContainerIconOperation.js} +6 -6
  113. package/stores/container-contents/operations/setContainerIconOperation.js.map +1 -0
  114. package/stores/container-contents/{shareOperations.js → operations/shareOperations.js} +6 -6
  115. package/stores/container-contents/operations/shareOperations.js.map +1 -0
  116. package/stores/container-contents/remoteEvents/remoteBackedContainerState.js.map +1 -0
  117. package/stores/container-contents/{remoteContainerIngestion.js → remoteEvents/remoteContainerIngestion.js} +4 -4
  118. package/stores/container-contents/remoteEvents/remoteContainerIngestion.js.map +1 -0
  119. package/stores/container-contents/{remoteEventProjectionInvalidation.js → remoteEvents/remoteEventProjectionInvalidation.js} +1 -1
  120. package/stores/container-contents/remoteEvents/remoteEventProjectionInvalidation.js.map +1 -0
  121. package/stores/container-contents/{remoteEventSync.js → remoteEvents/remoteEventSync.js} +4 -4
  122. package/stores/container-contents/remoteEvents/remoteEventSync.js.map +1 -0
  123. package/stores/container-contents/{remoteWriteGuards.js → remoteWrites/remoteWriteGuards.js} +2 -2
  124. package/stores/container-contents/remoteWrites/remoteWriteGuards.js.map +1 -0
  125. package/stores/container-contents/{remoteWriteQueue.js → remoteWrites/remoteWriteQueue.js} +1 -1
  126. package/stores/container-contents/remoteWrites/remoteWriteQueue.js.map +1 -0
  127. package/stores/container-contents/remoteWrites/writeGeneration.js.map +1 -0
  128. package/stores/container-contents/state.d.ts +1 -1
  129. package/stores/container-contents/state.js +2 -2
  130. package/stores/container-contents/state.js.map +1 -1
  131. package/stores/container-contents/{syncAgent.d.ts → syncAgent/index.d.ts} +2 -2
  132. package/stores/container-contents/{syncAgent.js → syncAgent/index.js} +14 -14
  133. package/stores/container-contents/syncAgent/index.js.map +1 -0
  134. package/stores/container-contents/{metadataSyncSignal.js → syncAgent/metadataSyncSignal.js} +1 -1
  135. package/stores/container-contents/{metadataSyncSignal.js.map → syncAgent/metadataSyncSignal.js.map} +1 -1
  136. package/stores/container-contents/{syncAgentTypes.d.ts → syncAgent/syncAgentTypes.d.ts} +5 -5
  137. package/stores/container-contents/syncAgent/syncAgentTypes.js.map +1 -0
  138. package/stores/container-contents/{syncLaneIteration.js → syncAgent/syncLaneIteration.js} +11 -11
  139. package/stores/container-contents/syncAgent/syncLaneIteration.js.map +1 -0
  140. package/stores/container-contents/{existingSystemContainer.js → systemContainers/existingSystemContainer.js} +4 -4
  141. package/stores/container-contents/systemContainers/existingSystemContainer.js.map +1 -0
  142. package/stores/container-contents/{organizationMetadataSystemContainer.js → systemContainers/organizationMetadataSystemContainer.js} +2 -2
  143. package/stores/container-contents/systemContainers/organizationMetadataSystemContainer.js.map +1 -0
  144. package/stores/container-contents/{systemContainerHydration.js → systemContainers/systemContainerHydration.js} +3 -3
  145. package/stores/container-contents/systemContainers/systemContainerHydration.js.map +1 -0
  146. package/stores/container-contents/{systemContainerIcon.js → systemContainers/systemContainerIcon.js} +5 -5
  147. package/stores/container-contents/systemContainers/systemContainerIcon.js.map +1 -0
  148. package/stores/container-contents/systemContainers/systemContainerLookup.js.map +1 -0
  149. package/stores/container-contents/{systemContainerPostCreate.js → systemContainers/systemContainerPostCreate.js} +2 -2
  150. package/stores/container-contents/systemContainers/systemContainerPostCreate.js.map +1 -0
  151. package/stores/container-contents/{systemContainerPromotion.js → systemContainers/systemContainerPromotion.js} +1 -1
  152. package/stores/container-contents/systemContainers/systemContainerPromotion.js.map +1 -0
  153. package/stores/container-contents/types.d.ts +2 -2
  154. package/stores/container-contents/types.js.map +1 -1
  155. package/stores/documents/documentStore/{attachmentSourceUpload.js → attachmentUpload/attachmentSourceUpload.js} +4 -4
  156. package/stores/documents/documentStore/attachmentUpload/attachmentSourceUpload.js.map +1 -0
  157. package/stores/documents/documentStore/{attachmentStaging.js → attachmentUpload/attachmentStaging.js} +5 -5
  158. package/stores/documents/documentStore/attachmentUpload/attachmentStaging.js.map +1 -0
  159. package/stores/documents/documentStore/{attachmentUploadAttempt.js → attachmentUpload/attachmentUploadAttempt.js} +2 -2
  160. package/stores/documents/documentStore/attachmentUpload/attachmentUploadAttempt.js.map +1 -0
  161. package/stores/documents/documentStore/{attachmentUploadLane.js → attachmentUpload/attachmentUploadLane.js} +1 -1
  162. package/stores/documents/documentStore/attachmentUpload/attachmentUploadLane.js.map +1 -0
  163. package/stores/documents/documentStore/{attachmentUploadResume.js → attachmentUpload/attachmentUploadResume.js} +4 -4
  164. package/stores/documents/documentStore/attachmentUpload/attachmentUploadResume.js.map +1 -0
  165. package/stores/documents/documentStore/{attachmentDetachState.js → attachments/attachmentDetachState.js} +1 -1
  166. package/stores/documents/documentStore/attachments/attachmentDetachState.js.map +1 -0
  167. package/stores/documents/documentStore/{attachmentHydration.js → attachments/attachmentHydration.js} +5 -5
  168. package/stores/documents/documentStore/attachments/attachmentHydration.js.map +1 -0
  169. package/stores/documents/documentStore/{attachmentHydrationCommit.js → attachments/attachmentHydrationCommit.js} +3 -3
  170. package/stores/documents/documentStore/attachments/attachmentHydrationCommit.js.map +1 -0
  171. package/stores/documents/documentStore/{attachmentIntents.js → attachments/attachmentIntents.js} +2 -2
  172. package/stores/documents/documentStore/attachments/attachmentIntents.js.map +1 -0
  173. package/stores/documents/documentStore/{attachmentMutationPersistence.js → attachments/attachmentMutationPersistence.js} +4 -4
  174. package/stores/documents/documentStore/attachments/attachmentMutationPersistence.js.map +1 -0
  175. package/stores/documents/documentStore/attachments/attachmentPersistFollowup.js.map +1 -0
  176. package/stores/documents/documentStore/{attachmentPersistence.js → attachments/attachmentPersistence.js} +4 -4
  177. package/stores/documents/documentStore/attachments/attachmentPersistence.js.map +1 -0
  178. package/stores/documents/documentStore/{attachmentRemoval.js → attachments/attachmentRemoval.js} +11 -11
  179. package/stores/documents/documentStore/attachments/attachmentRemoval.js.map +1 -0
  180. package/stores/documents/documentStore/attachments/attachmentSnapshot.js.map +1 -0
  181. package/stores/documents/documentStore/{attachmentWriteGeneration.js → attachments/attachmentWriteGeneration.js} +2 -2
  182. package/stores/documents/documentStore/attachments/attachmentWriteGeneration.js.map +1 -0
  183. package/stores/documents/documentStore/{attachments.js → attachments/index.js} +11 -11
  184. package/stores/documents/documentStore/attachments/index.js.map +1 -0
  185. package/stores/documents/documentStore/{documentHistoryCompaction.js → history/documentHistoryCompaction.js} +4 -4
  186. package/stores/documents/documentStore/history/documentHistoryCompaction.js.map +1 -0
  187. package/stores/documents/documentStore/{durableDocumentReload.js → history/durableDocumentReload.js} +6 -6
  188. package/stores/documents/documentStore/history/durableDocumentReload.js.map +1 -0
  189. package/stores/documents/documentStore/{historyRebuild.js → history/historyRebuild.js} +6 -6
  190. package/stores/documents/documentStore/history/historyRebuild.js.map +1 -0
  191. package/stores/documents/{documentStore.d.ts → documentStore/index.d.ts} +5 -5
  192. package/stores/documents/{documentStore.js → documentStore/index.js} +18 -18
  193. package/stores/documents/documentStore/index.js.map +1 -0
  194. package/stores/documents/documentStore/{deferredInitialUpdate.js → initialization/deferredInitialUpdate.js} +9 -9
  195. package/stores/documents/documentStore/initialization/deferredInitialUpdate.js.map +1 -0
  196. package/stores/documents/documentStore/{initialization.js → initialization/index.js} +14 -14
  197. package/stores/documents/documentStore/initialization/index.js.map +1 -0
  198. package/stores/documents/documentStore/{initializationAttachments.js → initialization/initializationAttachments.js} +1 -1
  199. package/stores/documents/documentStore/initialization/initializationAttachments.js.map +1 -0
  200. package/stores/documents/documentStore/{initializationHistory.js → initialization/initializationHistory.js} +3 -3
  201. package/stores/documents/documentStore/initialization/initializationHistory.js.map +1 -0
  202. package/stores/documents/documentStore/{initializationRecovery.js → initialization/initializationRecovery.js} +7 -7
  203. package/stores/documents/documentStore/initialization/initializationRecovery.js.map +1 -0
  204. package/stores/documents/documentStore/mutationIdentityRevalidation.js.map +1 -1
  205. package/stores/documents/documentStore/mutations.js +2 -2
  206. package/stores/documents/documentStore/mutations.js.map +1 -1
  207. package/stores/documents/documentStore/pendingUpdateRefusal.js +1 -1
  208. package/stores/documents/documentStore/pendingUpdateRefusal.js.map +1 -1
  209. package/stores/documents/documentStore/persistence.js +3 -3
  210. package/stores/documents/documentStore/persistence.js.map +1 -1
  211. package/stores/documents/documentStore/{rotation.js → rotation/index.js} +14 -14
  212. package/stores/documents/documentStore/rotation/index.js.map +1 -0
  213. package/stores/documents/documentStore/{rotationProvenance.js → rotation/rotationProvenance.js} +2 -2
  214. package/stores/documents/documentStore/rotation/rotationProvenance.js.map +1 -0
  215. package/stores/documents/documentStore/{rotationSettlement.js → rotation/rotationSettlement.js} +9 -9
  216. package/stores/documents/documentStore/rotation/rotationSettlement.js.map +1 -0
  217. package/stores/documents/documentStore/rows.js +2 -2
  218. package/stores/documents/documentStore/rows.js.map +1 -1
  219. package/stores/documents/documentStore/state.js +1 -1
  220. package/stores/documents/documentStore/state.js.map +1 -1
  221. package/stores/documents/documentStore/{sync.js → sync/index.js} +7 -7
  222. package/stores/documents/documentStore/sync/index.js.map +1 -0
  223. package/stores/documents/documentStore/{pullContinuationInvalidation.js → sync/pullContinuationInvalidation.js} +3 -3
  224. package/stores/documents/documentStore/sync/pullContinuationInvalidation.js.map +1 -0
  225. package/stores/documents/documentStore/{remoteRevalidationTelemetry.js → sync/remoteRevalidationTelemetry.js} +1 -1
  226. package/stores/documents/documentStore/sync/remoteRevalidationTelemetry.js.map +1 -0
  227. package/stores/documents/documentStore/sync/remoteWork.js.map +1 -0
  228. package/stores/documents/documentStore/sync/syncAcceptedUpdateIds.js.map +1 -0
  229. package/stores/documents/documentStore/{syncAttachmentSettlement.js → sync/syncAttachmentSettlement.js} +3 -3
  230. package/stores/documents/documentStore/sync/syncAttachmentSettlement.js.map +1 -0
  231. package/stores/documents/documentStore/{syncAttachments.js → sync/syncAttachments.js} +7 -7
  232. package/stores/documents/documentStore/sync/syncAttachments.js.map +1 -0
  233. package/stores/documents/documentStore/{syncDetachedAttachments.js → sync/syncDetachedAttachments.js} +7 -7
  234. package/stores/documents/documentStore/sync/syncDetachedAttachments.js.map +1 -0
  235. package/stores/documents/documentStore/{syncFinalize.js → sync/syncFinalize.js} +9 -9
  236. package/stores/documents/documentStore/sync/syncFinalize.js.map +1 -0
  237. package/stores/documents/documentStore/sync/syncGeneration.js.map +1 -0
  238. package/stores/documents/documentStore/{syncOutgoingCoverage.js → sync/syncOutgoingCoverage.js} +4 -4
  239. package/stores/documents/documentStore/sync/syncOutgoingCoverage.js.map +1 -0
  240. package/stores/documents/documentStore/{syncRemoteSignals.js → sync/syncRemoteSignals.js} +4 -4
  241. package/stores/documents/documentStore/sync/syncRemoteSignals.js.map +1 -0
  242. package/stores/documents/documentStore/{syncRequest.js → sync/syncRequest.js} +8 -8
  243. package/stores/documents/documentStore/sync/syncRequest.js.map +1 -0
  244. package/stores/documents/documentStore/{syncShared.js → sync/syncShared.js} +8 -8
  245. package/stores/documents/documentStore/sync/syncShared.js.map +1 -0
  246. package/stores/documents/documentStore/{syncUpdateImport.js → sync/syncUpdateImport.js} +3 -3
  247. package/stores/documents/documentStore/sync/syncUpdateImport.js.map +1 -0
  248. package/stores/documents/documentStore/{versionCoverage.js → sync/versionCoverage.js} +1 -1
  249. package/stores/documents/index.d.ts +1 -1
  250. package/stores/documents/index.js +1 -1
  251. package/stores/local-projection/localProjectionStore.d.ts +1 -1
  252. package/stores/local-projection/localProjectionStore.js +1 -1
  253. package/stores/local-projection/localProjectionStore.js.map +1 -1
  254. package/stores/local-projection/registry.d.ts +1 -1
  255. package/stores/local-projection/types.d.ts +1 -1
  256. package/workflows/blobs/hydration/decrypt.js +1 -1
  257. package/workflows/blobs/hydration/decrypt.js.map +1 -1
  258. package/workflows/container-contents/container-state/{createAdoption.js → create/createAdoption.js} +6 -6
  259. package/workflows/container-contents/container-state/create/createAdoption.js.map +1 -0
  260. package/workflows/container-contents/container-state/{createChild.js → create/createChild.js} +7 -7
  261. package/workflows/container-contents/container-state/create/createChild.js.map +1 -0
  262. package/workflows/container-contents/container-state/{createIntentDepth.js → create/createIntentDepth.js} +2 -2
  263. package/workflows/container-contents/container-state/create/createIntentDepth.js.map +1 -0
  264. package/workflows/container-contents/container-state/create/createIntentSettlement.js.map +1 -0
  265. package/workflows/container-contents/container-state/{createIntentSync.js → create/createIntentSync.js} +7 -7
  266. package/workflows/container-contents/container-state/create/createIntentSync.js.map +1 -0
  267. package/workflows/container-contents/container-state/{createTerminalFailure.js → create/createTerminalFailure.js} +2 -2
  268. package/workflows/container-contents/container-state/create/createTerminalFailure.js.map +1 -0
  269. package/workflows/container-contents/container-state/{createWithMetadata.js → create/createWithMetadata.js} +9 -9
  270. package/workflows/container-contents/container-state/create/createWithMetadata.js.map +1 -0
  271. package/workflows/container-contents/container-state/{createWithMetadataPlan.js → create/createWithMetadataPlan.js} +4 -4
  272. package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -0
  273. package/workflows/container-contents/container-state/{localPurgeScope.js → purge/localPurgeScope.js} +1 -1
  274. package/workflows/container-contents/container-state/purge/localPurgeScope.js.map +1 -0
  275. package/workflows/container-contents/container-state/{purgeTree.js → purge/purgeTree.js} +5 -5
  276. package/workflows/container-contents/container-state/purge/purgeTree.js.map +1 -0
  277. package/workflows/container-contents/container-state/purge/purgeTreeCollection.js.map +1 -0
  278. package/workflows/container-contents/container-state/{purgeTreeContainerDeletion.js → purge/purgeTreeContainerDeletion.js} +1 -1
  279. package/workflows/container-contents/container-state/purge/purgeTreeContainerDeletion.js.map +1 -0
  280. package/workflows/container-contents/container-state/{purgeTreeScope.js → purge/purgeTreeScope.js} +8 -8
  281. package/workflows/container-contents/container-state/purge/purgeTreeScope.js.map +1 -0
  282. package/workflows/container-contents/container-state/{readLocalPurgeScope.js → purge/readLocalPurgeScope.js} +3 -3
  283. package/workflows/container-contents/container-state/purge/readLocalPurgeScope.js.map +1 -0
  284. package/workflows/container-contents/container-state/remote.js +2 -2
  285. package/workflows/container-contents/container-state/remote.js.map +1 -1
  286. package/workflows/container-contents/container-state/{groupGrantVerification.js → share/groupGrantVerification.js} +8 -8
  287. package/workflows/container-contents/container-state/share/groupGrantVerification.js.map +1 -0
  288. package/workflows/container-contents/container-state/{groupShareEpoch.js → share/groupShareEpoch.js} +2 -2
  289. package/workflows/container-contents/container-state/share/groupShareEpoch.js.map +1 -0
  290. package/workflows/container-contents/container-state/{share.js → share/index.js} +8 -8
  291. package/workflows/container-contents/container-state/share/index.js.map +1 -0
  292. package/workflows/container-contents/container-state/{sharePersistence.js → share/sharePersistence.js} +3 -3
  293. package/workflows/container-contents/container-state/share/sharePersistence.js.map +1 -0
  294. package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js +1 -1
  295. package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js.map +1 -1
  296. package/workflows/container-contents/documentDiscovery/index.js +1 -1
  297. package/workflows/container-contents/documentDiscovery/index.js.map +1 -1
  298. package/workflows/container-contents/metadata/metadataSyncErrors.js +1 -1
  299. package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -1
  300. package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js.map +1 -0
  301. package/workflows/container-contents/remoteHydration/destination/destinationRoleCache.js.map +1 -0
  302. package/workflows/container-contents/remoteHydration/{destinationRootReload.js → destination/destinationRootReload.js} +1 -1
  303. package/workflows/container-contents/remoteHydration/destination/destinationRootReload.js.map +1 -0
  304. package/workflows/container-contents/remoteHydration/{replacementBinding.js → destination/replacementBinding.js} +5 -5
  305. package/workflows/container-contents/remoteHydration/destination/replacementBinding.js.map +1 -0
  306. package/workflows/container-contents/remoteHydration/{verifiedDestination.js → destination/verifiedDestination.js} +9 -9
  307. package/workflows/container-contents/remoteHydration/destination/verifiedDestination.js.map +1 -0
  308. package/workflows/container-contents/remoteHydration/index.js +4 -4
  309. package/workflows/container-contents/remoteHydration/index.js.map +1 -1
  310. package/workflows/container-contents/remoteHydration/lanes/childIndex.js.map +1 -0
  311. package/workflows/container-contents/remoteHydration/{laneFetchMarkers.js → lanes/laneFetchMarkers.js} +1 -1
  312. package/workflows/container-contents/remoteHydration/lanes/laneFetchMarkers.js.map +1 -0
  313. package/workflows/container-contents/remoteHydration/{parentLaneFetch.js → lanes/parentLaneFetch.js} +2 -2
  314. package/workflows/container-contents/remoteHydration/lanes/parentLaneFetch.js.map +1 -0
  315. package/workflows/container-contents/remoteHydration/lanes/parentLaneQueue.js.map +1 -0
  316. package/workflows/container-contents/remoteHydration/principalPolicyCache.js +1 -1
  317. package/workflows/container-contents/remoteHydration/principalPolicyCache.js.map +1 -1
  318. package/workflows/container-contents/remoteHydration/reconciliation.js +2 -2
  319. package/workflows/container-contents/remoteHydration/reconciliation.js.map +1 -1
  320. package/workflows/container-contents/remoteHydration/remoteContainers/containerStateFingerprint.js.map +1 -0
  321. package/workflows/container-contents/remoteHydration/{insertRemoteContainer.js → remoteContainers/insertRemoteContainer.js} +6 -6
  322. package/workflows/container-contents/remoteHydration/remoteContainers/insertRemoteContainer.js.map +1 -0
  323. package/workflows/container-contents/remoteHydration/{remoteContainerPageHydration.js → remoteContainers/remoteContainerPageHydration.js} +7 -7
  324. package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -0
  325. package/workflows/container-contents/remoteHydration/{remoteContainerState.js → remoteContainers/remoteContainerState.js} +9 -9
  326. package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerState.js.map +1 -0
  327. package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerTimestamps.js.map +1 -0
  328. package/workflows/container-contents/remoteHydration/tombstoneApplication.js +2 -2
  329. package/workflows/container-contents/remoteHydration/tombstoneApplication.js.map +1 -1
  330. package/workflows/containers/child/{createProjection.d.ts → create/createProjection.d.ts} +2 -2
  331. package/workflows/containers/child/{createProjection.js → create/createProjection.js} +2 -2
  332. package/workflows/containers/child/create/createProjection.js.map +1 -0
  333. package/workflows/containers/child/{createSubmission.d.ts → create/createSubmission.d.ts} +7 -7
  334. package/workflows/containers/child/{createSubmission.js → create/createSubmission.js} +2 -2
  335. package/workflows/containers/child/create/createSubmission.js.map +1 -0
  336. package/workflows/containers/child/{create.d.ts → create/index.d.ts} +5 -5
  337. package/workflows/containers/child/{create.js → create/index.js} +15 -15
  338. package/workflows/containers/child/create/index.js.map +1 -0
  339. package/workflows/containers/child/{move.d.ts → move/index.d.ts} +5 -5
  340. package/workflows/containers/child/{move.js → move/index.js} +12 -12
  341. package/workflows/containers/child/move/index.js.map +1 -0
  342. package/workflows/containers/child/{moveArtifacts.js → move/moveArtifacts.js} +3 -3
  343. package/workflows/containers/child/move/moveArtifacts.js.map +1 -0
  344. package/workflows/containers/child/{moveRotation.js → move/moveRotation.js} +3 -3
  345. package/workflows/containers/child/move/moveRotation.js.map +1 -0
  346. package/workflows/containers/child/{moveWraps.js → move/moveWraps.js} +5 -5
  347. package/workflows/containers/child/move/moveWraps.js.map +1 -0
  348. package/workflows/containers/child/mutationSubmit.js +1 -1
  349. package/workflows/containers/child/mutationSubmit.js.map +1 -1
  350. package/workflows/containers/child/{carriedDescendantRekeys.js → rekey/carriedDescendantRekeys.js} +4 -4
  351. package/workflows/containers/child/rekey/carriedDescendantRekeys.js.map +1 -0
  352. package/workflows/containers/child/{rekey.d.ts → rekey/index.d.ts} +6 -6
  353. package/workflows/containers/child/{rekey.js → rekey/index.js} +13 -13
  354. package/workflows/containers/child/rekey/index.js.map +1 -0
  355. package/workflows/containers/child/{keyringOverrideLineage.d.ts → rekey/keyringOverrideLineage.d.ts} +1 -1
  356. package/workflows/containers/child/{keyringOverrideLineage.js → rekey/keyringOverrideLineage.js} +1 -1
  357. package/workflows/containers/child/{rekeyProjection.d.ts → rekey/rekeyProjection.d.ts} +2 -2
  358. package/workflows/containers/child/{rekeyProjection.js → rekey/rekeyProjection.js} +3 -3
  359. package/workflows/containers/child/rekey/rekeyProjection.js.map +1 -0
  360. package/workflows/containers/child/{rekeyRemote.d.ts → rekey/rekeyRemote.d.ts} +6 -6
  361. package/workflows/containers/child/{rekeyRemote.js → rekey/rekeyRemote.js} +2 -2
  362. package/workflows/containers/child/rekey/rekeyRemote.js.map +1 -0
  363. package/workflows/containers/child/revoke.js +5 -5
  364. package/workflows/containers/child/revoke.js.map +1 -1
  365. package/workflows/containers/child/{replacementPrincipalPolicyReferences.js → rotation/replacementPrincipalPolicyReferences.js} +2 -2
  366. package/workflows/containers/child/rotation/replacementPrincipalPolicyReferences.js.map +1 -0
  367. package/workflows/containers/child/{rotationContext.js → rotation/rotationContext.js} +5 -5
  368. package/workflows/containers/child/rotation/rotationContext.js.map +1 -0
  369. package/workflows/containers/child/{rotationPrincipalPolicies.js → rotation/rotationPrincipalPolicies.js} +2 -2
  370. package/workflows/containers/child/rotation/rotationPrincipalPolicies.js.map +1 -0
  371. package/workflows/containers/child/{rotationWraps.js → rotation/rotationWraps.js} +1 -1
  372. package/workflows/containers/child/rotation/rotationWraps.js.map +1 -0
  373. package/workflows/containers/child/{currentShareGrantMutation.js → share/currentShareGrantMutation.js} +6 -6
  374. package/workflows/containers/child/share/currentShareGrantMutation.js.map +1 -0
  375. package/workflows/containers/child/{currentSharePrincipalPolicy.js → share/currentSharePrincipalPolicy.js} +10 -10
  376. package/workflows/containers/child/share/currentSharePrincipalPolicy.js.map +1 -0
  377. package/workflows/containers/child/{share.d.ts → share/index.d.ts} +8 -8
  378. package/workflows/containers/child/{share.js → share/index.js} +10 -10
  379. package/workflows/containers/child/share/index.js.map +1 -0
  380. package/workflows/containers/child/{runtimeCurrentGroupShare.js → share/runtimeCurrentGroupShare.js} +6 -6
  381. package/workflows/containers/child/share/runtimeCurrentGroupShare.js.map +1 -0
  382. package/workflows/containers/child/{shareAncestorRepair.js → share/shareAncestorRepair.js} +4 -4
  383. package/workflows/containers/child/share/shareAncestorRepair.js.map +1 -0
  384. package/workflows/containers/child/{shareMaterialization.d.ts → share/shareMaterialization.d.ts} +5 -5
  385. package/workflows/containers/child/{shareMaterialization.js → share/shareMaterialization.js} +7 -7
  386. package/workflows/containers/child/share/shareMaterialization.js.map +1 -0
  387. package/workflows/containers/child/{sharePlanCore.d.ts → share/sharePlanCore.d.ts} +7 -7
  388. package/workflows/containers/child/{sharePlanCore.js → share/sharePlanCore.js} +6 -6
  389. package/workflows/containers/child/share/sharePlanCore.js.map +1 -0
  390. package/workflows/containers/child/{sharePrincipalPolicy.d.ts → share/sharePrincipalPolicy.d.ts} +9 -9
  391. package/workflows/containers/child/{sharePrincipalPolicy.js → share/sharePrincipalPolicy.js} +13 -13
  392. package/workflows/containers/child/share/sharePrincipalPolicy.js.map +1 -0
  393. package/workflows/containers/child/share/shareProjection.js.map +1 -0
  394. package/workflows/containers/index.d.ts +10 -10
  395. package/workflows/containers/index.js +10 -10
  396. package/workflows/containers/index.js.map +1 -1
  397. package/workflows/documents/linkSet/linkSetAuthority.js +1 -1
  398. package/workflows/documents/linkSet/linkSetAuthority.js.map +1 -1
  399. package/workflows/documents/linkSet/linkSetBlobRewraps.js +1 -1
  400. package/workflows/documents/linkSet/linkSetBlobRewraps.js.map +1 -1
  401. package/workflows/documents/linkSet/linkSetProjectionSeed.js +1 -1
  402. package/workflows/documents/linkSet/linkSetProjectionSeed.js.map +1 -1
  403. package/workflows/documents/purge/index.js +1 -1
  404. package/workflows/documents/purge/index.js.map +1 -1
  405. package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js +2 -2
  406. package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js.map +1 -1
  407. package/workflows/organizations/rematerialization/precedingPrincipalRematerialization.js +1 -1
  408. package/workflows/organizations/rematerialization/precedingPrincipalRematerialization.js.map +1 -1
  409. package/workflows/organizations/rematerialization/principalContainerRematerialization.js +5 -5
  410. package/workflows/organizations/rematerialization/principalContainerRematerialization.js.map +1 -1
  411. package/workflows/organizations/rematerialization/principalContainerRematerializationPlanning.js +1 -1
  412. package/workflows/organizations/rematerialization/principalContainerRematerializationPlanning.js.map +1 -1
  413. package/workflows/organizations/rematerialization/principalContainerRematerializationTargets.js +1 -1
  414. package/workflows/organizations/rematerialization/principalContainerRematerializationTargets.js.map +1 -1
  415. package/workflows/principals/policyCache/index.js +1 -1
  416. package/workflows/principals/policyCache/index.js.map +1 -1
  417. package/workflows/principals/policyRepair.js +1 -1
  418. package/workflows/principals/policyRepair.js.map +1 -1
  419. package/workflows/registration/organizationProvisioningArtifacts.d.ts +1 -1
  420. package/workflows/registration/provisioningBootstrapBuilders.js +1 -1
  421. package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +0 -1
  422. package/data/keyingProjectionVerification/bundleVerification.js.map +0 -1
  423. package/data/keyingProjectionVerification/checkpointContext.js.map +0 -1
  424. package/data/keyingProjectionVerification/containerAncestorCitations.js.map +0 -1
  425. package/data/keyingProjectionVerification/containerDestinationVerification.js.map +0 -1
  426. package/data/keyingProjectionVerification/containerManifestVerification.js.map +0 -1
  427. package/data/keyingProjectionVerification/containerPathVerification.js.map +0 -1
  428. package/data/keyingProjectionVerification/containerProjectionVerification.js.map +0 -1
  429. package/data/keyingProjectionVerification/documentDependencyPaths.js.map +0 -1
  430. package/data/keyingProjectionVerification/documentManifestPolicies.js.map +0 -1
  431. package/data/keyingProjectionVerification/documentManifestVerification.js.map +0 -1
  432. package/data/keyingProjectionVerification/documentProjectionVerification.js.map +0 -1
  433. package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js.map +0 -1
  434. package/data/keyingProjectionVerification/documentPurgeCheckpointEnforcement.js.map +0 -1
  435. package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +0 -1
  436. package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js.map +0 -1
  437. package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js.map +0 -1
  438. package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js.map +0 -1
  439. package/data/keyingProjectionVerification/documentPurgeProofVerification.js.map +0 -1
  440. package/data/keyingProjectionVerification/manifestCheckpointVerification.js.map +0 -1
  441. package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js.map +0 -1
  442. package/data/keyingProjectionVerification/organizationFounderBinding.js.map +0 -1
  443. package/data/keyingProjectionVerification/principalPolicyCache.js.map +0 -1
  444. package/data/keyingProjectionVerification/principalPolicyVerification.js.map +0 -1
  445. package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +0 -1
  446. package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +0 -1
  447. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +0 -1
  448. package/stores/container-contents/backgroundHydration.js.map +0 -1
  449. package/stores/container-contents/containerPurgeCore.js.map +0 -1
  450. package/stores/container-contents/containerStateMap.js.map +0 -1
  451. package/stores/container-contents/containerStatePersistence.js.map +0 -1
  452. package/stores/container-contents/documentRecovery.js.map +0 -1
  453. package/stores/container-contents/documentRotation.js.map +0 -1
  454. package/stores/container-contents/documentWork.js.map +0 -1
  455. package/stores/container-contents/emptyTrashOperation.js.map +0 -1
  456. package/stores/container-contents/existingSystemContainer.js.map +0 -1
  457. package/stores/container-contents/groupRewrapOperation.js.map +0 -1
  458. package/stores/container-contents/missingContainerState.js.map +0 -1
  459. package/stores/container-contents/missingSyncedContainerState.js.map +0 -1
  460. package/stores/container-contents/operations.js.map +0 -1
  461. package/stores/container-contents/organizationMetadataSystemContainer.js.map +0 -1
  462. package/stores/container-contents/purgeContainerOperation.js.map +0 -1
  463. package/stores/container-contents/reconcilableContainer.js.map +0 -1
  464. package/stores/container-contents/remoteBackedContainerState.js.map +0 -1
  465. package/stores/container-contents/remoteContainerIngestion.js.map +0 -1
  466. package/stores/container-contents/remoteEventProjectionInvalidation.js.map +0 -1
  467. package/stores/container-contents/remoteEventSync.js.map +0 -1
  468. package/stores/container-contents/remoteHydrationRequest.js.map +0 -1
  469. package/stores/container-contents/remoteWriteGuards.js.map +0 -1
  470. package/stores/container-contents/remoteWriteQueue.js.map +0 -1
  471. package/stores/container-contents/reportShareFailure.js.map +0 -1
  472. package/stores/container-contents/setContainerIconOperation.js.map +0 -1
  473. package/stores/container-contents/shareOperations.js.map +0 -1
  474. package/stores/container-contents/startupHydration.js.map +0 -1
  475. package/stores/container-contents/syncAgent.js.map +0 -1
  476. package/stores/container-contents/syncAgentTypes.js.map +0 -1
  477. package/stores/container-contents/syncLaneIteration.js.map +0 -1
  478. package/stores/container-contents/systemContainerHydration.js.map +0 -1
  479. package/stores/container-contents/systemContainerIcon.js.map +0 -1
  480. package/stores/container-contents/systemContainerLookup.js.map +0 -1
  481. package/stores/container-contents/systemContainerPostCreate.js.map +0 -1
  482. package/stores/container-contents/systemContainerPromotion.js.map +0 -1
  483. package/stores/container-contents/writeGeneration.js.map +0 -1
  484. package/stores/documents/documentStore/attachmentDetachState.js.map +0 -1
  485. package/stores/documents/documentStore/attachmentHydration.js.map +0 -1
  486. package/stores/documents/documentStore/attachmentHydrationCommit.js.map +0 -1
  487. package/stores/documents/documentStore/attachmentIntents.js.map +0 -1
  488. package/stores/documents/documentStore/attachmentMutationPersistence.js.map +0 -1
  489. package/stores/documents/documentStore/attachmentPersistFollowup.js.map +0 -1
  490. package/stores/documents/documentStore/attachmentPersistence.js.map +0 -1
  491. package/stores/documents/documentStore/attachmentRemoval.js.map +0 -1
  492. package/stores/documents/documentStore/attachmentSnapshot.js.map +0 -1
  493. package/stores/documents/documentStore/attachmentSourceUpload.js.map +0 -1
  494. package/stores/documents/documentStore/attachmentStaging.js.map +0 -1
  495. package/stores/documents/documentStore/attachmentUploadAttempt.js.map +0 -1
  496. package/stores/documents/documentStore/attachmentUploadLane.js.map +0 -1
  497. package/stores/documents/documentStore/attachmentUploadResume.js.map +0 -1
  498. package/stores/documents/documentStore/attachmentWriteGeneration.js.map +0 -1
  499. package/stores/documents/documentStore/attachments.js.map +0 -1
  500. package/stores/documents/documentStore/deferredInitialUpdate.js.map +0 -1
  501. package/stores/documents/documentStore/documentHistoryCompaction.js.map +0 -1
  502. package/stores/documents/documentStore/durableDocumentReload.js.map +0 -1
  503. package/stores/documents/documentStore/historyRebuild.js.map +0 -1
  504. package/stores/documents/documentStore/initialization.js.map +0 -1
  505. package/stores/documents/documentStore/initializationAttachments.js.map +0 -1
  506. package/stores/documents/documentStore/initializationHistory.js.map +0 -1
  507. package/stores/documents/documentStore/initializationRecovery.js.map +0 -1
  508. package/stores/documents/documentStore/pullContinuationInvalidation.js.map +0 -1
  509. package/stores/documents/documentStore/remoteRevalidationTelemetry.js.map +0 -1
  510. package/stores/documents/documentStore/remoteWork.js.map +0 -1
  511. package/stores/documents/documentStore/rotation.js.map +0 -1
  512. package/stores/documents/documentStore/rotationProvenance.js.map +0 -1
  513. package/stores/documents/documentStore/rotationSettlement.js.map +0 -1
  514. package/stores/documents/documentStore/sync.js.map +0 -1
  515. package/stores/documents/documentStore/syncAcceptedUpdateIds.js.map +0 -1
  516. package/stores/documents/documentStore/syncAttachmentSettlement.js.map +0 -1
  517. package/stores/documents/documentStore/syncAttachments.js.map +0 -1
  518. package/stores/documents/documentStore/syncDetachedAttachments.js.map +0 -1
  519. package/stores/documents/documentStore/syncFinalize.js.map +0 -1
  520. package/stores/documents/documentStore/syncGeneration.js.map +0 -1
  521. package/stores/documents/documentStore/syncOutgoingCoverage.js.map +0 -1
  522. package/stores/documents/documentStore/syncRemoteSignals.js.map +0 -1
  523. package/stores/documents/documentStore/syncRequest.js.map +0 -1
  524. package/stores/documents/documentStore/syncShared.js.map +0 -1
  525. package/stores/documents/documentStore/syncUpdateImport.js.map +0 -1
  526. package/stores/documents/documentStore.js.map +0 -1
  527. package/workflows/container-contents/container-state/createAdoption.js.map +0 -1
  528. package/workflows/container-contents/container-state/createChild.js.map +0 -1
  529. package/workflows/container-contents/container-state/createIntentDepth.js.map +0 -1
  530. package/workflows/container-contents/container-state/createIntentSettlement.js.map +0 -1
  531. package/workflows/container-contents/container-state/createIntentSync.js.map +0 -1
  532. package/workflows/container-contents/container-state/createTerminalFailure.js.map +0 -1
  533. package/workflows/container-contents/container-state/createWithMetadata.js.map +0 -1
  534. package/workflows/container-contents/container-state/createWithMetadataPlan.js.map +0 -1
  535. package/workflows/container-contents/container-state/groupGrantVerification.js.map +0 -1
  536. package/workflows/container-contents/container-state/groupShareEpoch.js.map +0 -1
  537. package/workflows/container-contents/container-state/localPurgeScope.js.map +0 -1
  538. package/workflows/container-contents/container-state/purgeTree.js.map +0 -1
  539. package/workflows/container-contents/container-state/purgeTreeCollection.js.map +0 -1
  540. package/workflows/container-contents/container-state/purgeTreeContainerDeletion.js.map +0 -1
  541. package/workflows/container-contents/container-state/purgeTreeScope.js.map +0 -1
  542. package/workflows/container-contents/container-state/readLocalPurgeScope.js.map +0 -1
  543. package/workflows/container-contents/container-state/share.js.map +0 -1
  544. package/workflows/container-contents/container-state/sharePersistence.js.map +0 -1
  545. package/workflows/container-contents/remoteHydration/childIndex.js.map +0 -1
  546. package/workflows/container-contents/remoteHydration/containerStateFingerprint.js.map +0 -1
  547. package/workflows/container-contents/remoteHydration/destinationPrefetch.js.map +0 -1
  548. package/workflows/container-contents/remoteHydration/destinationRoleCache.js.map +0 -1
  549. package/workflows/container-contents/remoteHydration/destinationRootReload.js.map +0 -1
  550. package/workflows/container-contents/remoteHydration/insertRemoteContainer.js.map +0 -1
  551. package/workflows/container-contents/remoteHydration/laneFetchMarkers.js.map +0 -1
  552. package/workflows/container-contents/remoteHydration/parentLaneFetch.js.map +0 -1
  553. package/workflows/container-contents/remoteHydration/parentLaneQueue.js.map +0 -1
  554. package/workflows/container-contents/remoteHydration/remoteContainerPageHydration.js.map +0 -1
  555. package/workflows/container-contents/remoteHydration/remoteContainerState.js.map +0 -1
  556. package/workflows/container-contents/remoteHydration/remoteContainerTimestamps.js.map +0 -1
  557. package/workflows/container-contents/remoteHydration/replacementBinding.js.map +0 -1
  558. package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +0 -1
  559. package/workflows/containers/child/carriedDescendantRekeys.js.map +0 -1
  560. package/workflows/containers/child/create.js.map +0 -1
  561. package/workflows/containers/child/createProjection.js.map +0 -1
  562. package/workflows/containers/child/createSubmission.js.map +0 -1
  563. package/workflows/containers/child/currentShareGrantMutation.js.map +0 -1
  564. package/workflows/containers/child/currentSharePrincipalPolicy.js.map +0 -1
  565. package/workflows/containers/child/move.js.map +0 -1
  566. package/workflows/containers/child/moveArtifacts.js.map +0 -1
  567. package/workflows/containers/child/moveRotation.js.map +0 -1
  568. package/workflows/containers/child/moveWraps.js.map +0 -1
  569. package/workflows/containers/child/rekey.js.map +0 -1
  570. package/workflows/containers/child/rekeyProjection.js.map +0 -1
  571. package/workflows/containers/child/rekeyRemote.js.map +0 -1
  572. package/workflows/containers/child/replacementPrincipalPolicyReferences.js.map +0 -1
  573. package/workflows/containers/child/rotationContext.js.map +0 -1
  574. package/workflows/containers/child/rotationPrincipalPolicies.js.map +0 -1
  575. package/workflows/containers/child/rotationWraps.js.map +0 -1
  576. package/workflows/containers/child/runtimeCurrentGroupShare.js.map +0 -1
  577. package/workflows/containers/child/share.js.map +0 -1
  578. package/workflows/containers/child/shareAncestorRepair.js.map +0 -1
  579. package/workflows/containers/child/shareMaterialization.js.map +0 -1
  580. package/workflows/containers/child/sharePlanCore.js.map +0 -1
  581. package/workflows/containers/child/sharePrincipalPolicy.js.map +0 -1
  582. package/workflows/containers/child/shareProjection.js.map +0 -1
  583. /package/data/keyingProjectionVerification/{containerCreateManifest.js.map → container/containerCreateManifest.js.map} +0 -0
  584. /package/data/keyingProjectionVerification/{documentContainerProjections.js → document/documentContainerProjections.js} +0 -0
  585. /package/data/keyingProjectionVerification/{documentContainerProjections.js.map → document/documentContainerProjections.js.map} +0 -0
  586. /package/data/keyingProjectionVerification/{documentManifestPredecessor.js.map → document/documentManifestPredecessor.js.map} +0 -0
  587. /package/stores/container-contents/{containerStateMap.js → containerState/containerStateMap.js} +0 -0
  588. /package/stores/container-contents/{missingSyncedContainerState.js → containerState/missingSyncedContainerState.js} +0 -0
  589. /package/stores/container-contents/{reconcilableContainer.js → containerState/reconcilableContainer.js} +0 -0
  590. /package/stores/container-contents/{remoteHydrationRefresh.js → hydration/remoteHydrationRefresh.js} +0 -0
  591. /package/stores/container-contents/{remoteHydrationRefresh.js.map → hydration/remoteHydrationRefresh.js.map} +0 -0
  592. /package/stores/container-contents/{emptyTrashOperation.js → operations/emptyTrashOperation.js} +0 -0
  593. /package/stores/container-contents/{purgeContainerOperation.js → operations/purgeContainerOperation.js} +0 -0
  594. /package/stores/container-contents/{remoteBackedContainerState.js → remoteEvents/remoteBackedContainerState.js} +0 -0
  595. /package/stores/container-contents/{writeGeneration.js → remoteWrites/writeGeneration.js} +0 -0
  596. /package/stores/container-contents/{syncAgentTypes.js → syncAgent/syncAgentTypes.js} +0 -0
  597. /package/stores/container-contents/{systemContainerLookup.js → systemContainers/systemContainerLookup.js} +0 -0
  598. /package/stores/documents/documentStore/{attachmentPersistFollowup.js → attachments/attachmentPersistFollowup.js} +0 -0
  599. /package/stores/documents/documentStore/{attachmentSnapshot.js → attachments/attachmentSnapshot.js} +0 -0
  600. /package/stores/documents/documentStore/{remoteWork.js → sync/remoteWork.js} +0 -0
  601. /package/stores/documents/documentStore/{syncAcceptedUpdateIds.js → sync/syncAcceptedUpdateIds.js} +0 -0
  602. /package/stores/documents/documentStore/{syncGeneration.js → sync/syncGeneration.js} +0 -0
  603. /package/stores/documents/documentStore/{versionCoverage.js.map → sync/versionCoverage.js.map} +0 -0
  604. /package/workflows/container-contents/container-state/{createIntentSettlement.js → create/createIntentSettlement.js} +0 -0
  605. /package/workflows/container-contents/container-state/{purgeProgress.d.ts → purge/purgeProgress.d.ts} +0 -0
  606. /package/workflows/container-contents/container-state/{purgeProgress.js → purge/purgeProgress.js} +0 -0
  607. /package/workflows/container-contents/container-state/{purgeProgress.js.map → purge/purgeProgress.js.map} +0 -0
  608. /package/workflows/container-contents/container-state/{purgeTreeCollection.js → purge/purgeTreeCollection.js} +0 -0
  609. /package/workflows/container-contents/remoteHydration/{destinationPrefetch.js → destination/destinationPrefetch.js} +0 -0
  610. /package/workflows/container-contents/remoteHydration/{destinationRoleCache.js → destination/destinationRoleCache.js} +0 -0
  611. /package/workflows/container-contents/remoteHydration/{childIndex.js → lanes/childIndex.js} +0 -0
  612. /package/workflows/container-contents/remoteHydration/{parentLaneQueue.js → lanes/parentLaneQueue.js} +0 -0
  613. /package/workflows/container-contents/remoteHydration/{containerStateFingerprint.js → remoteContainers/containerStateFingerprint.js} +0 -0
  614. /package/workflows/container-contents/remoteHydration/{remoteContainerTimestamps.js → remoteContainers/remoteContainerTimestamps.js} +0 -0
  615. /package/workflows/containers/child/{keyringOverrideLineage.js.map → rekey/keyringOverrideLineage.js.map} +0 -0
  616. /package/workflows/containers/child/{shareProjection.js → share/shareProjection.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"linkSetProjectionSeed.js","sourceRoot":"","sources":["linkSetProjectionSeed.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;AAErG,OAAO,EAAE,6BAA6B,EAAE,MAAM,0EAA0E,CAAC;AAUzH,SAAS,qBAAqB,CAC5B,OAAoD;IAEpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4C,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,mBAAmB,CAC1B,KAA+D;IAE/D,MAAM,UAAU,GAAG,IAAI,GAAG,EAA8C,CAAC;IACzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,kCAAkC,CACzC,UAAuC;IAEvC,OAAO,UAAU,CAAC,aAAa,CAAC,OAAO,CACrC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,wBAAwB,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,gCAAgC,CACvC,UAA4C;IAE5C,OAAO,mBAAmB,CAAC;QACzB,GAAG,UAAU,CAAC,8BAA8B;QAC5C,GAAG,UAAU,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kCAAkC,CAAC,KAG3C;IACC,MAAM,mBAAmB,GAAG,gCAAgC,CAC1D,KAAK,CAAC,eAAe,CACtB,CAAC;IACF,MAAM,oCAAoC,GACxC,KAAK,CAAC,eAAe,CAAC,yBAAyB,CAAC;IAElD,OAAO,qBAAqB,CAAC;QAC3B,GAAG,KAAK,CAAC,eAAe,CAAC,gCAAgC;QACzD,GAAG,mBAAmB,CAAC,IAAI,EAAE;QAC7B,GAAG,oCAAoC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;YAC9D,GAAG,UAAU,CAAC,IAAI;YAClB,GAAG,kCAAkC,CAAC,UAAU,CAAC;SAClD,CAAC;QACF,GAAG,KAAK,CAAC,yBAAyB,CAAC,IAAI;QACvC,GAAG,kCAAkC,CAAC,KAAK,CAAC,yBAAyB,CAAC;KACvE,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,mCAAmC,CAAC,KAM5C;IACC,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,aAAa,GAAG,KAAK,CAAC,eAAe,CAAC,yBAAyB,CAAC,MAAM,CAC1E,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,iBAAiB,CACvD,CAAC;IACF,MAAM,yBAAyB,GAC7B,KAAK,CAAC,SAAS,KAAK,MAAM;QACxB,CAAC,CAAC,CAAC,GAAG,aAAa,EAAE,KAAK,CAAC,yBAAyB,CAAC;QACrD,CAAC,CAAC,aAAa,CAAC;IACpB,MAAM,8BAA8B,GAAG,mBAAmB,CAAC;QACzD,GAAG,gCAAgC,CAAC,KAAK,CAAC,eAAe,CAAC;QAC1D,KAAK,CAAC,yBAAyB,CAAC,IAAI;KACrC,CAAC,CAAC;IACH,OAAO;QACL,cAAc,EAAE,6BAA6B,CAAC;YAC5C,KAAK,CAAC,eAAe,CAAC,cAAc;YACpC,KAAK,CAAC,yBAAyB,CAAC,cAAc;SAC/C,CAAC;QACF,yBAAyB;QACzB,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,gBAAgB;QACjD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;QAC7B,gCAAgC,EAAE,kCAAkC,CAAC;YACnE,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;SAC3D,CAAC;QACF,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB;QACrD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc;QAC/C,8BAA8B;QAC9B,uBAAuB,EAAE;YACvB,KAAK,CAAC,eAAe,CAAC,gBAAgB;YACtC,GAAG,KAAK,CAAC,eAAe,CAAC,uBAAuB;SACjD;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,KASjD;IACC,MAAM,UAAU,GAAG,mCAAmC,CAAC;QACrD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;KAC3D,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,wCAAwC,CAAC,UAAU,EAAE;YACzD,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,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,SAAS,CAAC,6BAA6B,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["import type {\n AccessManifestBundleWireResponse,\n ContainerKeyingPathResponse,\n ContainerWriterProjectionResponse,\n DocumentLinkSetMutationResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../data/documents/shared/projection\";\nimport type { DocumentLinkSetMutationOperation } from \"../../../data/documents/shared/types\";\nimport { mergeProjectionPolicyEvidence } from \"../../../data/keyingProjectionVerification/mergeProjectionPolicyEvidence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\n\ninterface DocumentLinkSetProjectionSeedApi {\n primeDocumentWriterProjection(\n documentId: string,\n projection: DocumentWriterProjectionResponse,\n ): void;\n}\n\nfunction uniqueManifestBundles(\n bundles: readonly AccessManifestBundleWireResponse[],\n): AccessManifestBundleWireResponse[] {\n const byHash = new Map<string, AccessManifestBundleWireResponse>();\n for (const bundle of bundles) {\n if (!byHash.has(bundle.manifestHash)) {\n byHash.set(bundle.manifestHash, bundle);\n }\n }\n\n return [...byHash.values()];\n}\n\nfunction uniqueManifestPaths(\n paths: readonly (readonly AccessManifestBundleWireResponse[])[],\n): AccessManifestBundleWireResponse[][] {\n const byLeafHash = new Map<string, AccessManifestBundleWireResponse[]>();\n for (const path of paths) {\n const leafHash = path.at(-1)?.manifestHash;\n if (!leafHash || byLeafHash.has(leafHash)) {\n continue;\n }\n\n byLeafHash.set(leafHash, [...path]);\n }\n\n return [...byLeafHash.values()];\n}\n\nfunction containerProjectionManifestHistory(\n projection: ContainerKeyingPathResponse,\n): AccessManifestBundleWireResponse[] {\n return projection.containerKeks.flatMap(\n (kek) => kek.containerManifestHistory,\n );\n}\n\nfunction documentProjectionContainerPaths(\n projection: DocumentWriterProjectionResponse,\n): AccessManifestBundleWireResponse[][] {\n return uniqueManifestPaths([\n ...projection.documentManifestContainerPaths,\n ...projection.authorizingContainerPaths.map((path) => path.path),\n ]);\n}\n\nfunction documentProjectionContainerHistory(input: {\n priorProjection: DocumentWriterProjectionResponse;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): AccessManifestBundleWireResponse[] {\n const priorContainerPaths = documentProjectionContainerPaths(\n input.priorProjection,\n );\n const priorAuthorizingContainerProjections =\n input.priorProjection.authorizingContainerPaths;\n\n return uniqueManifestBundles([\n ...input.priorProjection.documentContainerManifestHistory,\n ...priorContainerPaths.flat(),\n ...priorAuthorizingContainerProjections.flatMap((projection) => [\n ...projection.path,\n ...containerProjectionManifestHistory(projection),\n ]),\n ...input.targetContainerProjection.path,\n ...containerProjectionManifestHistory(input.targetContainerProjection),\n ]);\n}\n\n/**\n * Reconstruct the post-mutation writer projection from a link/unlink response.\n * The response carries the fresh manifest, content-key bundle, and KEK targets;\n * the authorizing container paths change by exactly one entry — link appends\n * the target container's projection, unlink drops it (keyed by containerId).\n * Link does not rotate the content key (only unlink does), but either way the\n * bundle/targets the next write needs come straight from the response. The\n * caller verifies this projection for internal consistency before seeding it,\n * so a wrong reconstruction is discarded rather than cached.\n */\nfunction linkSetWriterProjectionFromResponse(input: {\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): DocumentWriterProjectionResponse {\n // The target container's authorizing path is replaced wholesale: link adds\n // the fresh target projection back, unlink leaves it dropped.\n const retainedPaths = input.priorProjection.authorizingContainerPaths.filter(\n (path) => path.containerId !== input.targetContainerId,\n );\n const authorizingContainerPaths =\n input.operation === \"link\"\n ? [...retainedPaths, input.targetContainerProjection]\n : retainedPaths;\n const documentManifestContainerPaths = uniqueManifestPaths([\n ...documentProjectionContainerPaths(input.priorProjection),\n input.targetContainerProjection.path,\n ]);\n return {\n policyEvidence: mergeProjectionPolicyEvidence([\n input.priorProjection.policyEvidence,\n input.targetContainerProjection.policyEvidence,\n ]),\n authorizingContainerPaths,\n contentKeyBundle: input.response.contentKeyBundle,\n documentId: input.response.id,\n documentContainerManifestHistory: documentProjectionContainerHistory({\n priorProjection: input.priorProjection,\n targetContainerProjection: input.targetContainerProjection,\n }),\n documentKekTargets: input.response.documentKekTargets,\n documentManifest: input.response.accessManifest,\n documentManifestContainerPaths,\n documentManifestHistory: [\n input.priorProjection.documentManifest,\n ...input.priorProjection.documentManifestHistory,\n ],\n };\n}\n\n/**\n * Reconstruct and seed the post-mutation writer projection so the first read\n * after a link/unlink resolves locally instead of a cold GET. Gates the seed on\n * the projection's internal consistency (manifest hash ↔ content-key bundle ↔\n * KEK targets ↔ linked containers); on any mismatch the seed is skipped and the\n * next read falls back to a fetch — the seed is an optimization, never a\n * correctness dependency. The expensive per-path signature re-verification is\n * deliberately not run here: the server already verified the mutation, and the\n * next read re-verifies the projection before any write.\n */\nexport async function seedLinkSetWriterProjection(input: {\n apiClient: DocumentLinkSetProjectionSeedApi;\n execSql?: ExecSql | undefined;\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = linkSetWriterProjectionFromResponse({\n operation: input.operation,\n priorProjection: input.priorProjection,\n response: input.response,\n targetContainerId: input.targetContainerId,\n targetContainerProjection: input.targetContainerProjection,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.apiClient.primeDocumentWriterProjection(input.response.id, projection);\n}\n"]}
1
+ {"version":3,"file":"linkSetProjectionSeed.js","sourceRoot":"","sources":["linkSetProjectionSeed.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccessManifestBundleWireResponse,\n ContainerKeyingPathResponse,\n ContainerWriterProjectionResponse,\n DocumentLinkSetMutationResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../../data/documents/shared/projection\";\nimport type { DocumentLinkSetMutationOperation } from \"../../../data/documents/shared/types\";\nimport { mergeProjectionPolicyEvidence } from \"../../../data/keyingProjectionVerification/principalPolicy/mergeProjectionPolicyEvidence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\n\ninterface DocumentLinkSetProjectionSeedApi {\n primeDocumentWriterProjection(\n documentId: string,\n projection: DocumentWriterProjectionResponse,\n ): void;\n}\n\nfunction uniqueManifestBundles(\n bundles: readonly AccessManifestBundleWireResponse[],\n): AccessManifestBundleWireResponse[] {\n const byHash = new Map<string, AccessManifestBundleWireResponse>();\n for (const bundle of bundles) {\n if (!byHash.has(bundle.manifestHash)) {\n byHash.set(bundle.manifestHash, bundle);\n }\n }\n\n return [...byHash.values()];\n}\n\nfunction uniqueManifestPaths(\n paths: readonly (readonly AccessManifestBundleWireResponse[])[],\n): AccessManifestBundleWireResponse[][] {\n const byLeafHash = new Map<string, AccessManifestBundleWireResponse[]>();\n for (const path of paths) {\n const leafHash = path.at(-1)?.manifestHash;\n if (!leafHash || byLeafHash.has(leafHash)) {\n continue;\n }\n\n byLeafHash.set(leafHash, [...path]);\n }\n\n return [...byLeafHash.values()];\n}\n\nfunction containerProjectionManifestHistory(\n projection: ContainerKeyingPathResponse,\n): AccessManifestBundleWireResponse[] {\n return projection.containerKeks.flatMap(\n (kek) => kek.containerManifestHistory,\n );\n}\n\nfunction documentProjectionContainerPaths(\n projection: DocumentWriterProjectionResponse,\n): AccessManifestBundleWireResponse[][] {\n return uniqueManifestPaths([\n ...projection.documentManifestContainerPaths,\n ...projection.authorizingContainerPaths.map((path) => path.path),\n ]);\n}\n\nfunction documentProjectionContainerHistory(input: {\n priorProjection: DocumentWriterProjectionResponse;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): AccessManifestBundleWireResponse[] {\n const priorContainerPaths = documentProjectionContainerPaths(\n input.priorProjection,\n );\n const priorAuthorizingContainerProjections =\n input.priorProjection.authorizingContainerPaths;\n\n return uniqueManifestBundles([\n ...input.priorProjection.documentContainerManifestHistory,\n ...priorContainerPaths.flat(),\n ...priorAuthorizingContainerProjections.flatMap((projection) => [\n ...projection.path,\n ...containerProjectionManifestHistory(projection),\n ]),\n ...input.targetContainerProjection.path,\n ...containerProjectionManifestHistory(input.targetContainerProjection),\n ]);\n}\n\n/**\n * Reconstruct the post-mutation writer projection from a link/unlink response.\n * The response carries the fresh manifest, content-key bundle, and KEK targets;\n * the authorizing container paths change by exactly one entry — link appends\n * the target container's projection, unlink drops it (keyed by containerId).\n * Link does not rotate the content key (only unlink does), but either way the\n * bundle/targets the next write needs come straight from the response. The\n * caller verifies this projection for internal consistency before seeding it,\n * so a wrong reconstruction is discarded rather than cached.\n */\nfunction linkSetWriterProjectionFromResponse(input: {\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n}): DocumentWriterProjectionResponse {\n // The target container's authorizing path is replaced wholesale: link adds\n // the fresh target projection back, unlink leaves it dropped.\n const retainedPaths = input.priorProjection.authorizingContainerPaths.filter(\n (path) => path.containerId !== input.targetContainerId,\n );\n const authorizingContainerPaths =\n input.operation === \"link\"\n ? [...retainedPaths, input.targetContainerProjection]\n : retainedPaths;\n const documentManifestContainerPaths = uniqueManifestPaths([\n ...documentProjectionContainerPaths(input.priorProjection),\n input.targetContainerProjection.path,\n ]);\n return {\n policyEvidence: mergeProjectionPolicyEvidence([\n input.priorProjection.policyEvidence,\n input.targetContainerProjection.policyEvidence,\n ]),\n authorizingContainerPaths,\n contentKeyBundle: input.response.contentKeyBundle,\n documentId: input.response.id,\n documentContainerManifestHistory: documentProjectionContainerHistory({\n priorProjection: input.priorProjection,\n targetContainerProjection: input.targetContainerProjection,\n }),\n documentKekTargets: input.response.documentKekTargets,\n documentManifest: input.response.accessManifest,\n documentManifestContainerPaths,\n documentManifestHistory: [\n input.priorProjection.documentManifest,\n ...input.priorProjection.documentManifestHistory,\n ],\n };\n}\n\n/**\n * Reconstruct and seed the post-mutation writer projection so the first read\n * after a link/unlink resolves locally instead of a cold GET. Gates the seed on\n * the projection's internal consistency (manifest hash ↔ content-key bundle ↔\n * KEK targets ↔ linked containers); on any mismatch the seed is skipped and the\n * next read falls back to a fetch — the seed is an optimization, never a\n * correctness dependency. The expensive per-path signature re-verification is\n * deliberately not run here: the server already verified the mutation, and the\n * next read re-verifies the projection before any write.\n */\nexport async function seedLinkSetWriterProjection(input: {\n apiClient: DocumentLinkSetProjectionSeedApi;\n execSql?: ExecSql | undefined;\n operation: DocumentLinkSetMutationOperation;\n priorProjection: DocumentWriterProjectionResponse;\n response: DocumentLinkSetMutationResponse;\n targetContainerId: string;\n targetContainerProjection: ContainerWriterProjectionResponse;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n const projection = linkSetWriterProjectionFromResponse({\n operation: input.operation,\n priorProjection: input.priorProjection,\n response: input.response,\n targetContainerId: input.targetContainerId,\n targetContainerProjection: input.targetContainerProjection,\n });\n try {\n await assertDocumentWriterProjectionConsistent(projection, {\n execSql: input.execSql,\n trustedLocalProjection: true,\n });\n } catch {\n return;\n }\n if (input.stillCurrent?.() === false) return;\n input.apiClient.primeDocumentWriterProjection(input.response.id, projection);\n}\n"]}
@@ -5,7 +5,7 @@ import { assertDocumentManifestBundleConsistent, readManifestContainerId, } from
5
5
  import { readCanonicalJson, readCanonicalRecord, } from "../../../data/keying/canonicalJson.js";
6
6
  import { verifyDocumentPurgeProof, verifyDocumentPurgeProofBaseline, verifyDocumentWriterProjection, } from "../../../data/keyingProjectionVerification/index.js";
7
7
  import { ProjectionDependencyUnavailableError } from "../../../data/keyingProjectionVerification/dependencyUnavailable.js";
8
- import { documentContainerProjections } from "../../../data/keyingProjectionVerification/documentContainerProjections.js";
8
+ import { documentContainerProjections } from "../../../data/keyingProjectionVerification/document/documentContainerProjections.js";
9
9
  import { assertSubtreePurgePath, } from "./subtreePurgeScope.js";
10
10
  const REMOTE_DOCUMENT_ALREADY_PURGED = Symbol("remoteDocumentAlreadyPurged");
11
11
  async function loadAuthenticatedDocumentPurgeProof(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventBodyHash,\n type DocumentPurgeAccessEventBody,\n KeyingVerificationError,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { DocumentPurgeRequest } from \"@tearleads/validators/request\";\nimport {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentPurgeProofResponse,\n type DocumentPurgeResponse,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n containerPathRefs,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../../data/documents/shared/projection\";\nimport {\n assertDocumentManifestBundleConsistent,\n readManifestContainerId,\n} from \"../../../data/documents/shared/readers\";\nimport type {\n DocumentCreateAuthor,\n DocumentSyncApi,\n} from \"../../../data/documents/shared/types\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../../data/keying/canonicalJson\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../../data/keyingProjectionVerification\";\nimport {\n verifyDocumentPurgeProof,\n verifyDocumentPurgeProofBaseline,\n verifyDocumentWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { documentContainerProjections } from \"../../../data/keyingProjectionVerification/documentContainerProjections\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n assertSubtreePurgePath,\n type SubtreePurgeRoot,\n} from \"./subtreePurgeScope\";\n\ninterface DocumentPurgeApi {\n getDocumentPurgeProof(\n documentId: string,\n options?: {\n readonly documentCheckpointManifestHash?: string;\n },\n requestOptions?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeProofResponse | null>;\n getDocumentWriterProjectionResult: NonNullable<\n DocumentSyncApi[\"getDocumentWriterProjectionResult\"]\n >;\n purgeDocument(\n documentId: string,\n request: DocumentPurgeRequest,\n options?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeResponse | null>;\n}\n\nconst REMOTE_DOCUMENT_ALREADY_PURGED = Symbol(\"remoteDocumentAlreadyPurged\");\n\nasync function loadAuthenticatedDocumentPurgeProof(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeProofResponse | null> {\n if (!input.apiClient.getDocumentPurgeProof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing a purge-proof endpoint\",\n );\n }\n const initialProof = await input.apiClient.getDocumentPurgeProof(\n input.documentId,\n undefined,\n {\n expectedPaymentRequiredOrganizationId: input.expectedOrganizationId,\n },\n );\n if (!initialProof) {\n // ApiClient returns null for transport, HTTP and response-shape failures.\n // Even after a deletion hint, absence cannot prove signed-data tampering.\n // Keep local data and defer deletion until an actual proof verifies.\n return null;\n }\n await verifyDocumentPurgeProofBaseline({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof: initialProof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The current API returns complete history to recorded readers. Otherwise\n // its terminal snapshot needs an exact local pin; a floor refetch cannot\n // grant missing observation authority.\n return initialProof;\n}\n\nasync function resolveDocumentPurgeWriterProjection(input: {\n readonly apiClient: DocumentPurgeApi;\n readonly documentId: string;\n}): Promise<\n | DocumentWriterProjectionResponse\n | typeof REMOTE_DOCUMENT_ALREADY_PURGED\n | null\n> {\n const result = await input.apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n if (result.status === 404 && result.code === DOCUMENT_NOT_FOUND_ERROR_CODE) {\n return REMOTE_DOCUMENT_ALREADY_PURGED;\n }\n result.report();\n return null;\n}\n\nexport async function buildDocumentPurgeRequest(input: {\n readonly author: DocumentCreateAuthor;\n readonly expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n readonly eventId?: string | undefined;\n readonly signedAt?: string | undefined;\n readonly writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentPurgeRequest> {\n const identity = await assertDocumentManifestBundleConsistent({\n bundle: input.writerProjection.documentManifest,\n label: \"Document purge predecessor\",\n });\n if (identity.documentId !== input.writerProjection.documentId) {\n throw new Error(\"Document purge projection identity mismatch\");\n }\n if (identity.organizationId !== input.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document purge author organization mismatch\",\n );\n }\n const linkedContainerIds = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n if (linkedContainerIds.length !== 1) {\n throw new Error(\"Document purge requires exactly one linked container\");\n }\n const [containerId] = linkedContainerIds;\n const authorizingProjection = documentContainerProjections(\n input.writerProjection,\n ).find((projection) => {\n const leaf = projection.path.at(-1);\n return leaf && readManifestContainerId(leaf) === containerId;\n });\n const containerManifestHash =\n authorizingProjection?.path.at(-1)?.manifestHash;\n if (!authorizingProjection || !containerId || !containerManifestHash) {\n throw new Error(\"Document purge authorization path is unavailable\");\n }\n assertSubtreePurgePath(authorizingProjection.path, input.expectedSubtreeRoot);\n const authorizingContainerManifestHashes = authorizingProjection.path.map(\n (bundle) => bundle.manifestHash,\n );\n const body: DocumentPurgeAccessEventBody = {\n authorizingContainerManifestHashes,\n containerId,\n containerManifestHash,\n documentManifestHash: input.writerProjection.documentManifest.manifestHash,\n eventType: \"document.purge\",\n };\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId ?? crypto.randomUUID(),\n eventType: \"document.purge\",\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.author.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes: authorizingContainerManifestHashes,\n bodyHash: await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document purge body\"),\n ),\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt ?? new Date().toISOString(),\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n\n return {\n authorizingContainerPathRefs: containerPathRefs(authorizingProjection.path),\n body: readCanonicalRecord(body, \"Document purge body\"),\n event: readCanonicalRecord(event, \"Document purge event\"),\n };\n}\n\nexport function createVerifiedRemoteDocumentDeletionHandler(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly onVerifiedDeletion: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n readonly documentId: string;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): (deleted: { readonly documentId: string }) => Promise<void> {\n return async ({ documentId }) => {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedDeletion({\n commitPurgeProof: verified.commitCheckpoints,\n documentId,\n });\n };\n}\n\nexport async function purgeRemoteDocument(input: {\n readonly beforeSubmit?: (() => Promise<boolean>) | undefined;\n readonly apiClient: DocumentPurgeApi;\n readonly author: DocumentCreateAuthor;\n readonly documentId: string;\n readonly expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n readonly execSql: ExecSql;\n readonly onVerifiedPurge: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeResponse | null> {\n const writerProjection = await resolveDocumentPurgeWriterProjection({\n apiClient: input.apiClient,\n documentId: input.documentId,\n });\n if (!writerProjection) {\n return null;\n }\n if (writerProjection === REMOTE_DOCUMENT_ALREADY_PURGED) {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId: input.documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.author.organizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Purged remote document is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return { ...proof, reclaimedBlobStorageKeys: [] };\n }\n await verifyDocumentWriterProjection({\n execSql: input.execSql,\n projection: writerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const request = await buildDocumentPurgeRequest({\n author: input.author,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n writerProjection,\n });\n if (input.beforeSubmit && !(await input.beforeSubmit())) return null;\n if (input.stillCurrent?.() === false) return null;\n const response = await input.apiClient.purgeDocument(\n input.documentId,\n request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n );\n if (!response) {\n return null;\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof: response,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return response;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAE1B,uBAAuB,EACvB,eAAe,GAEhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,6BAA6B,GAI9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,0CAA0C,GAC3C,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,sCAAsC,EACtC,uBAAuB,GACxB,MAAM,wCAAwC,CAAC;AAKhD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EACL,wBAAwB,EACxB,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,oCAAoC,EAAE,MAAM,kEAAkE,CAAC;AACxH,OAAO,EAAE,4BAA4B,EAAE,MAAM,kFAAkF,CAAC;AAEhI,OAAO,EACL,sBAAsB,GAEvB,MAAM,qBAAqB,CAAC;AAwB7B,MAAM,8BAA8B,GAAG,MAAM,CAAC,6BAA6B,CAAC,CAAC;AAE7E,KAAK,UAAU,mCAAmC,CAAC,KAUlD;IACC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAC;QAC3C,MAAM,IAAI,oCAAoC,CAC5C,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,qBAAqB,CAC9D,KAAK,CAAC,UAAU,EAChB,SAAS,EACT;QACE,qCAAqC,EAAE,KAAK,CAAC,sBAAsB;KACpE,CACF,CAAC;IACF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,gCAAgC,CAAC;QACrC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,kBAAkB,EAAE,KAAK,CAAC,UAAU;QACpC,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,KAAK,EAAE,YAAY;QACnB,cAAc,EAAE,KAAK,CAAC,wBAAwB;QAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;KACvE,CAAC,CAAC;IACH,0EAA0E;IAC1E,yEAAyE;IACzE,uCAAuC;IACvC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,oCAAoC,CAAC,KAGnD;IAKC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,iCAAiC,CACpE,KAAK,CAAC,UAAU,EAChB,EAAE,YAAY,EAAE,KAAK,EAAE,CACxB,CAAC;IACF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,KAAK,6BAA6B,EAAE,CAAC;QAC3E,OAAO,8BAA8B,CAAC;IACxC,CAAC;IACD,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,KAM/C;IACC,MAAM,QAAQ,GAAG,MAAM,sCAAsC,CAAC;QAC5D,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,gBAAgB;QAC/C,KAAK,EAAE,4BAA4B;KACpC,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,UAAU,KAAK,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,QAAQ,CAAC,cAAc,KAAK,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC5D,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,6CAA6C,CAC9C,CAAC;IACJ,CAAC;IACD,MAAM,kBAAkB,GAAG,0CAA0C,CACnE,KAAK,CAAC,gBAAgB,CACvB,CAAC;IACF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,CAAC,WAAW,CAAC,GAAG,kBAAkB,CAAC;IACzC,MAAM,qBAAqB,GAAG,4BAA4B,CACxD,KAAK,CAAC,gBAAgB,CACvB,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;QACpB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,IAAI,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,MAAM,qBAAqB,GACzB,qBAAqB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;IACnD,IAAI,CAAC,qBAAqB,IAAI,CAAC,WAAW,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC9E,MAAM,kCAAkC,GAAG,qBAAqB,CAAC,IAAI,CAAC,GAAG,CACvE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAChC,CAAC;IACF,MAAM,IAAI,GAAiC;QACzC,kCAAkC;QAClC,WAAW;QACX,qBAAqB;QACrB,oBAAoB,EAAE,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,YAAY;QAC1E,SAAS,EAAE,gBAAgB;KAC5B,CAAC;IACF,MAAM,aAAa,GAAwB;QACzC,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE;QAC7C,SAAS,EAAE,gBAAgB;QAC3B,UAAU,EAAE,UAAU;QACtB,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC,UAAU;QAC3C,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;QAC3C,oBAAoB,EAAE,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,YAAY;QAC1E,wBAAwB,EAAE,kCAAkC;QAC5D,QAAQ,EAAE,MAAM,0BAA0B,CACxC,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAC/C;QACD,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;QACvC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;QAC3C,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,oBAAoB;QACvD,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrD,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,eAAe,CACjC,aAAa,EACb,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAC9B,CAAC;IAEF,OAAO;QACL,4BAA4B,EAAE,iBAAiB,CAAC,qBAAqB,CAAC,IAAI,CAAC;QAC3E,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,CAAC;QACtD,KAAK,EAAE,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2CAA2C,CAAC,KAa3D;IACC,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,MAAM,mCAAmC,CAAC;YACtD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU;YACV,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;YACpD,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;YACxD,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;SACvE,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,oCAAoC,CAC5C,4DAA4D,CAC7D,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC;YAC9C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,kBAAkB,EAAE,UAAU;YAC9B,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;YACpD,KAAK;YACL,cAAc,EAAE,KAAK,CAAC,wBAAwB;YAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;SACvE,CAAC,CAAC;QACH,MAAM,KAAK,CAAC,kBAAkB,CAAC;YAC7B,gBAAgB,EAAE,QAAQ,CAAC,iBAAiB;YAC5C,UAAU;SACX,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAezC;IACC,MAAM,gBAAgB,GAAG,MAAM,oCAAoC,CAAC;QAClE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,gBAAgB,KAAK,8BAA8B,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,mCAAmC,CAAC;YACtD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;YACnD,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;YACxD,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;SACvE,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,oCAAoC,CAC5C,0DAA0D,CAC3D,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC;YAC9C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,kBAAkB,EAAE,KAAK,CAAC,UAAU;YACpC,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;YACnD,KAAK;YACL,cAAc,EAAE,KAAK,CAAC,wBAAwB;YAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;SACvE,CAAC,CAAC;QACH,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,gBAAgB,EAAE,QAAQ,CAAC,iBAAiB;SAC7C,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,KAAK,EAAE,wBAAwB,EAAE,EAAE,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,8BAA8B,CAAC;QACnC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,gBAAgB;QAC5B,cAAc,EAAE,KAAK,CAAC,wBAAwB;QAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;KACvE,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC;QAC9C,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,gBAAgB;KACjB,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,CAClD,KAAK,CAAC,UAAU,EAChB,OAAO,EACP;QACE,qCAAqC,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;KACnE,CACF,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC;QAC9C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,kBAAkB,EAAE,KAAK,CAAC,UAAU;QACpC,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;QACnD,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,KAAK,CAAC,wBAAwB;QAC9C,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;KACvE,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,eAAe,CAAC;QAC1B,gBAAgB,EAAE,QAAQ,CAAC,iBAAiB;KAC7C,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n computeAccessEventBodyHash,\n type DocumentPurgeAccessEventBody,\n KeyingVerificationError,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { DocumentPurgeRequest } from \"@tearleads/validators/request\";\nimport {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentPurgeProofResponse,\n type DocumentPurgeResponse,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n containerPathRefs,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../../data/documents/shared/projection\";\nimport {\n assertDocumentManifestBundleConsistent,\n readManifestContainerId,\n} from \"../../../data/documents/shared/readers\";\nimport type {\n DocumentCreateAuthor,\n DocumentSyncApi,\n} from \"../../../data/documents/shared/types\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../../data/keying/canonicalJson\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../../data/keyingProjectionVerification\";\nimport {\n verifyDocumentPurgeProof,\n verifyDocumentPurgeProofBaseline,\n verifyDocumentWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { documentContainerProjections } from \"../../../data/keyingProjectionVerification/document/documentContainerProjections\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n assertSubtreePurgePath,\n type SubtreePurgeRoot,\n} from \"./subtreePurgeScope\";\n\ninterface DocumentPurgeApi {\n getDocumentPurgeProof(\n documentId: string,\n options?: {\n readonly documentCheckpointManifestHash?: string;\n },\n requestOptions?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeProofResponse | null>;\n getDocumentWriterProjectionResult: NonNullable<\n DocumentSyncApi[\"getDocumentWriterProjectionResult\"]\n >;\n purgeDocument(\n documentId: string,\n request: DocumentPurgeRequest,\n options?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeResponse | null>;\n}\n\nconst REMOTE_DOCUMENT_ALREADY_PURGED = Symbol(\"remoteDocumentAlreadyPurged\");\n\nasync function loadAuthenticatedDocumentPurgeProof(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeProofResponse | null> {\n if (!input.apiClient.getDocumentPurgeProof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing a purge-proof endpoint\",\n );\n }\n const initialProof = await input.apiClient.getDocumentPurgeProof(\n input.documentId,\n undefined,\n {\n expectedPaymentRequiredOrganizationId: input.expectedOrganizationId,\n },\n );\n if (!initialProof) {\n // ApiClient returns null for transport, HTTP and response-shape failures.\n // Even after a deletion hint, absence cannot prove signed-data tampering.\n // Keep local data and defer deletion until an actual proof verifies.\n return null;\n }\n await verifyDocumentPurgeProofBaseline({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof: initialProof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The current API returns complete history to recorded readers. Otherwise\n // its terminal snapshot needs an exact local pin; a floor refetch cannot\n // grant missing observation authority.\n return initialProof;\n}\n\nasync function resolveDocumentPurgeWriterProjection(input: {\n readonly apiClient: DocumentPurgeApi;\n readonly documentId: string;\n}): Promise<\n | DocumentWriterProjectionResponse\n | typeof REMOTE_DOCUMENT_ALREADY_PURGED\n | null\n> {\n const result = await input.apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n if (result.status === 404 && result.code === DOCUMENT_NOT_FOUND_ERROR_CODE) {\n return REMOTE_DOCUMENT_ALREADY_PURGED;\n }\n result.report();\n return null;\n}\n\nexport async function buildDocumentPurgeRequest(input: {\n readonly author: DocumentCreateAuthor;\n readonly expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n readonly eventId?: string | undefined;\n readonly signedAt?: string | undefined;\n readonly writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentPurgeRequest> {\n const identity = await assertDocumentManifestBundleConsistent({\n bundle: input.writerProjection.documentManifest,\n label: \"Document purge predecessor\",\n });\n if (identity.documentId !== input.writerProjection.documentId) {\n throw new Error(\"Document purge projection identity mismatch\");\n }\n if (identity.organizationId !== input.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document purge author organization mismatch\",\n );\n }\n const linkedContainerIds = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n if (linkedContainerIds.length !== 1) {\n throw new Error(\"Document purge requires exactly one linked container\");\n }\n const [containerId] = linkedContainerIds;\n const authorizingProjection = documentContainerProjections(\n input.writerProjection,\n ).find((projection) => {\n const leaf = projection.path.at(-1);\n return leaf && readManifestContainerId(leaf) === containerId;\n });\n const containerManifestHash =\n authorizingProjection?.path.at(-1)?.manifestHash;\n if (!authorizingProjection || !containerId || !containerManifestHash) {\n throw new Error(\"Document purge authorization path is unavailable\");\n }\n assertSubtreePurgePath(authorizingProjection.path, input.expectedSubtreeRoot);\n const authorizingContainerManifestHashes = authorizingProjection.path.map(\n (bundle) => bundle.manifestHash,\n );\n const body: DocumentPurgeAccessEventBody = {\n authorizingContainerManifestHashes,\n containerId,\n containerManifestHash,\n documentManifestHash: input.writerProjection.documentManifest.manifestHash,\n eventType: \"document.purge\",\n };\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId ?? crypto.randomUUID(),\n eventType: \"document.purge\",\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.author.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes: authorizingContainerManifestHashes,\n bodyHash: await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document purge body\"),\n ),\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt ?? new Date().toISOString(),\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n\n return {\n authorizingContainerPathRefs: containerPathRefs(authorizingProjection.path),\n body: readCanonicalRecord(body, \"Document purge body\"),\n event: readCanonicalRecord(event, \"Document purge event\"),\n };\n}\n\nexport function createVerifiedRemoteDocumentDeletionHandler(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly onVerifiedDeletion: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n readonly documentId: string;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): (deleted: { readonly documentId: string }) => Promise<void> {\n return async ({ documentId }) => {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedDeletion({\n commitPurgeProof: verified.commitCheckpoints,\n documentId,\n });\n };\n}\n\nexport async function purgeRemoteDocument(input: {\n readonly beforeSubmit?: (() => Promise<boolean>) | undefined;\n readonly apiClient: DocumentPurgeApi;\n readonly author: DocumentCreateAuthor;\n readonly documentId: string;\n readonly expectedSubtreeRoot?: SubtreePurgeRoot | undefined;\n readonly execSql: ExecSql;\n readonly onVerifiedPurge: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeResponse | null> {\n const writerProjection = await resolveDocumentPurgeWriterProjection({\n apiClient: input.apiClient,\n documentId: input.documentId,\n });\n if (!writerProjection) {\n return null;\n }\n if (writerProjection === REMOTE_DOCUMENT_ALREADY_PURGED) {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId: input.documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.author.organizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Purged remote document is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return { ...proof, reclaimedBlobStorageKeys: [] };\n }\n await verifyDocumentWriterProjection({\n execSql: input.execSql,\n projection: writerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const request = await buildDocumentPurgeRequest({\n author: input.author,\n expectedSubtreeRoot: input.expectedSubtreeRoot,\n writerProjection,\n });\n if (input.beforeSubmit && !(await input.beforeSubmit())) return null;\n if (input.stillCurrent?.() === false) return null;\n const response = await input.apiClient.purgeDocument(\n input.documentId,\n request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n );\n if (!response) {\n return null;\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof: response,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return response;\n}\n"]}
@@ -3,9 +3,9 @@ import { MAX_INLINE_CONTAINER_REKEYS } from "../../../internal/validators/util/i
3
3
  import { ContainerAuthorAccessError } from "../../../data/containers/shared/authorAccess.js";
4
4
  import { ContainerKekRepairInaccessibleError } from "../../../data/documents/shared/containerKekCurrency.js";
5
5
  import { ContainerKekTargetUnreachableError } from "../../../data/documents/shared/containerKekPath.js";
6
- import { documentContainerProjections } from "../../../data/keyingProjectionVerification/documentContainerProjections.js";
6
+ import { documentContainerProjections } from "../../../data/keyingProjectionVerification/document/documentContainerProjections.js";
7
7
  import { assertProjectionVerificationCurrent } from "../../../data/keyingProjectionVerification/types.js";
8
- import { buildMaterializedContainerRekeyPlan } from "../../containers/child/rekey.js";
8
+ import { buildMaterializedContainerRekeyPlan } from "../../containers/child/rekey/index.js";
9
9
  import { DocumentAncestorRepairAbandonedError } from "../syncFailures/syncRepairAbandon.js";
10
10
  import { hasOtherLinkedWriteAccess } from "../syncFailures/syncRepairAccess.js";
11
11
  import { applyContainerRekeyPlan } from "./syncContainerRekeyProjection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"syncAutomaticContainerRekeys.js","sourceRoot":"","sources":["syncAutomaticContainerRekeys.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { MAX_INLINE_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { ContainerAuthorAccessError } from \"../../../data/containers/shared/authorAccess\";\nimport type { MaterializedContainerRekeyPlan } from \"../../../data/containers/shared/types\";\nimport { ContainerKekRepairInaccessibleError } from \"../../../data/documents/shared/containerKekCurrency\";\nimport { ContainerKekTargetUnreachableError } from \"../../../data/documents/shared/containerKekPath\";\nimport { documentContainerProjections } from \"../../../data/keyingProjectionVerification/documentContainerProjections\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { buildMaterializedContainerRekeyPlan } from \"../../containers/child/rekey\";\nimport type { SyncRemoteDocumentInput } from \"../sync/readOnlySync\";\nimport { DocumentAncestorRepairAbandonedError } from \"../syncFailures/syncRepairAbandon\";\nimport { hasOtherLinkedWriteAccess } from \"../syncFailures/syncRepairAccess\";\nimport { applyContainerRekeyPlan } from \"./syncContainerRekeyProjection\";\n\ninterface StaleContainer {\n /** The stale container is the one the document itself is linked into. */\n readonly isPathTarget: boolean;\n readonly projection: ContainerWriterProjectionResponse;\n}\n\nfunction firstStaleContainer(\n projection: DocumentWriterProjectionResponse,\n): StaleContainer | null {\n for (const path of documentContainerProjections(projection)) {\n for (let index = 1; index < path.containerKeks.length; index += 1) {\n const parent = path.containerKeks[index - 1];\n const child = path.containerKeks[index];\n if (!parent || !child)\n throw new Error(\"Container KEK path is incomplete\");\n if (child.parentContainerKeyEpochId === parent.containerKeyEpochId) {\n continue;\n }\n return {\n isPathTarget: index === path.containerKeks.length - 1,\n projection: {\n ...path,\n containerId: child.containerId,\n containerKeks: path.containerKeks.slice(0, index + 1),\n path: path.path.slice(0, index + 1),\n },\n };\n }\n }\n return null;\n}\n\n/**\n * The stale container is not this writer's to re-key: no wrap on the verified\n * path opens it, or the signed path grants the signer no write access there.\n * Both are judged against the path sliced at the stale container, so a grant\n * held only further down never counts — exactly the API's `container.rekey`\n * rule. Anything else (keyring damage, a forged path) stays an error.\n *\n * A target's write refusal is handled separately: another linked target may\n * still authorize the document write. Key unwrap failures on a target stay\n * errors, because this path's readable grant should open its own key.\n */\nfunction isRepairInaccessible(error: unknown, stale: StaleContainer): boolean {\n if (stale.isPathTarget) return false;\n return (\n error instanceof ContainerAuthorAccessError ||\n (error instanceof ContainerKekTargetUnreachableError &&\n error.containerId === stale.projection.containerId)\n );\n}\n\n/** Prepare parent-first repairs; the sync transaction commits them with the write. */\nexport async function buildAutomaticContainerRekeys(\n sync: SyncRemoteDocumentInput,\n initialProjection: DocumentWriterProjectionResponse,\n): Promise<{ plans: MaterializedContainerRekeyPlan[]; hasMore: boolean }> {\n const plans: MaterializedContainerRekeyPlan[] = [];\n const plannedIds = new Set<string>();\n let projection = initialProjection;\n for (;;) {\n const stale = firstStaleContainer(projection);\n if (!stale) return { plans, hasMore: false };\n const previousProjection = stale.projection;\n if (plans.length >= MAX_INLINE_CONTAINER_REKEYS) {\n return { plans, hasMore: true };\n }\n // Use the shared cancellation sentinel: syncRemoteDocument converts only\n // that to a graceful null, so a plain Error would report a routine\n // generation flip mid-repair as a real sync failure.\n assertProjectionVerificationCurrent(sync.stillCurrent);\n if (plannedIds.has(previousProjection.containerId)) {\n // Abandon like every other routine repair failure: two linked paths\n // disagreeing about a container is a concurrent-rotation race, not a\n // defect, and a raw Error would crash the sync lane instead.\n throw new DocumentAncestorRepairAbandonedError(\"peer-rotation\");\n }\n // Assert rather than adopt: resolveRotationContext compares the verified\n // manifest's organization against the author's, so substituting the path's\n // own organization here would make that the only cross-org check and leave\n // it comparing a server-supplied value with itself.\n if (previousProjection.organizationId !== sync.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document ancestor repair crosses the author's organization\",\n );\n }\n const planned = await buildMaterializedContainerRekeyPlan({\n author: sync.author,\n persistVerificationCheckpoints: false,\n previousProjection,\n signedAt: sync.signedAt,\n targetSecretKey: sync.targetSecretKey,\n resolveProjectionUserKey: sync.resolveProjectionUserKey,\n stillCurrent: sync.stillCurrent,\n warmReferencedPrincipalPolicies: sync.warmReferencedPrincipalPolicies,\n execSql: sync.execSql,\n }).catch(async (error: unknown) => {\n if (error instanceof ContainerAuthorAccessError && stale.isPathTarget) {\n if (\n await hasOtherLinkedWriteAccess(\n sync,\n initialProjection,\n previousProjection.containerId,\n )\n ) {\n throw new ContainerKekRepairInaccessibleError(\n previousProjection.containerId,\n );\n }\n await sync.onTerminalSubmitFailure?.({\n code: error.code,\n message: error.message,\n ok: false,\n report: () => undefined,\n status: error.status,\n });\n throw new DocumentAncestorRepairAbandonedError(\"refused\");\n }\n // Repairs run parent-first and access inherits downward, so only the\n // first stale container can be out of reach. Retry-classified like any\n // stale path: one refetch sees a repair a capable member already made.\n throw isRepairInaccessible(error, stale)\n ? new ContainerKekRepairInaccessibleError(\n previousProjection.containerId,\n )\n : error;\n });\n plannedIds.add(previousProjection.containerId);\n plans.push(planned);\n projection = await applyContainerRekeyPlan(projection, planned);\n }\n}\n"]}
1
+ {"version":3,"file":"syncAutomaticContainerRekeys.js","sourceRoot":"","sources":["syncAutomaticContainerRekeys.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { MAX_INLINE_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { ContainerAuthorAccessError } from \"../../../data/containers/shared/authorAccess\";\nimport type { MaterializedContainerRekeyPlan } from \"../../../data/containers/shared/types\";\nimport { ContainerKekRepairInaccessibleError } from \"../../../data/documents/shared/containerKekCurrency\";\nimport { ContainerKekTargetUnreachableError } from \"../../../data/documents/shared/containerKekPath\";\nimport { documentContainerProjections } from \"../../../data/keyingProjectionVerification/document/documentContainerProjections\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { buildMaterializedContainerRekeyPlan } from \"../../containers/child/rekey\";\nimport type { SyncRemoteDocumentInput } from \"../sync/readOnlySync\";\nimport { DocumentAncestorRepairAbandonedError } from \"../syncFailures/syncRepairAbandon\";\nimport { hasOtherLinkedWriteAccess } from \"../syncFailures/syncRepairAccess\";\nimport { applyContainerRekeyPlan } from \"./syncContainerRekeyProjection\";\n\ninterface StaleContainer {\n /** The stale container is the one the document itself is linked into. */\n readonly isPathTarget: boolean;\n readonly projection: ContainerWriterProjectionResponse;\n}\n\nfunction firstStaleContainer(\n projection: DocumentWriterProjectionResponse,\n): StaleContainer | null {\n for (const path of documentContainerProjections(projection)) {\n for (let index = 1; index < path.containerKeks.length; index += 1) {\n const parent = path.containerKeks[index - 1];\n const child = path.containerKeks[index];\n if (!parent || !child)\n throw new Error(\"Container KEK path is incomplete\");\n if (child.parentContainerKeyEpochId === parent.containerKeyEpochId) {\n continue;\n }\n return {\n isPathTarget: index === path.containerKeks.length - 1,\n projection: {\n ...path,\n containerId: child.containerId,\n containerKeks: path.containerKeks.slice(0, index + 1),\n path: path.path.slice(0, index + 1),\n },\n };\n }\n }\n return null;\n}\n\n/**\n * The stale container is not this writer's to re-key: no wrap on the verified\n * path opens it, or the signed path grants the signer no write access there.\n * Both are judged against the path sliced at the stale container, so a grant\n * held only further down never counts — exactly the API's `container.rekey`\n * rule. Anything else (keyring damage, a forged path) stays an error.\n *\n * A target's write refusal is handled separately: another linked target may\n * still authorize the document write. Key unwrap failures on a target stay\n * errors, because this path's readable grant should open its own key.\n */\nfunction isRepairInaccessible(error: unknown, stale: StaleContainer): boolean {\n if (stale.isPathTarget) return false;\n return (\n error instanceof ContainerAuthorAccessError ||\n (error instanceof ContainerKekTargetUnreachableError &&\n error.containerId === stale.projection.containerId)\n );\n}\n\n/** Prepare parent-first repairs; the sync transaction commits them with the write. */\nexport async function buildAutomaticContainerRekeys(\n sync: SyncRemoteDocumentInput,\n initialProjection: DocumentWriterProjectionResponse,\n): Promise<{ plans: MaterializedContainerRekeyPlan[]; hasMore: boolean }> {\n const plans: MaterializedContainerRekeyPlan[] = [];\n const plannedIds = new Set<string>();\n let projection = initialProjection;\n for (;;) {\n const stale = firstStaleContainer(projection);\n if (!stale) return { plans, hasMore: false };\n const previousProjection = stale.projection;\n if (plans.length >= MAX_INLINE_CONTAINER_REKEYS) {\n return { plans, hasMore: true };\n }\n // Use the shared cancellation sentinel: syncRemoteDocument converts only\n // that to a graceful null, so a plain Error would report a routine\n // generation flip mid-repair as a real sync failure.\n assertProjectionVerificationCurrent(sync.stillCurrent);\n if (plannedIds.has(previousProjection.containerId)) {\n // Abandon like every other routine repair failure: two linked paths\n // disagreeing about a container is a concurrent-rotation race, not a\n // defect, and a raw Error would crash the sync lane instead.\n throw new DocumentAncestorRepairAbandonedError(\"peer-rotation\");\n }\n // Assert rather than adopt: resolveRotationContext compares the verified\n // manifest's organization against the author's, so substituting the path's\n // own organization here would make that the only cross-org check and leave\n // it comparing a server-supplied value with itself.\n if (previousProjection.organizationId !== sync.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document ancestor repair crosses the author's organization\",\n );\n }\n const planned = await buildMaterializedContainerRekeyPlan({\n author: sync.author,\n persistVerificationCheckpoints: false,\n previousProjection,\n signedAt: sync.signedAt,\n targetSecretKey: sync.targetSecretKey,\n resolveProjectionUserKey: sync.resolveProjectionUserKey,\n stillCurrent: sync.stillCurrent,\n warmReferencedPrincipalPolicies: sync.warmReferencedPrincipalPolicies,\n execSql: sync.execSql,\n }).catch(async (error: unknown) => {\n if (error instanceof ContainerAuthorAccessError && stale.isPathTarget) {\n if (\n await hasOtherLinkedWriteAccess(\n sync,\n initialProjection,\n previousProjection.containerId,\n )\n ) {\n throw new ContainerKekRepairInaccessibleError(\n previousProjection.containerId,\n );\n }\n await sync.onTerminalSubmitFailure?.({\n code: error.code,\n message: error.message,\n ok: false,\n report: () => undefined,\n status: error.status,\n });\n throw new DocumentAncestorRepairAbandonedError(\"refused\");\n }\n // Repairs run parent-first and access inherits downward, so only the\n // first stale container can be out of reach. Retry-classified like any\n // stale path: one refetch sees a repair a capable member already made.\n throw isRepairInaccessible(error, stale)\n ? new ContainerKekRepairInaccessibleError(\n previousProjection.containerId,\n )\n : error;\n });\n plannedIds.add(previousProjection.containerId);\n plans.push(planned);\n projection = await applyContainerRekeyPlan(projection, planned);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { rebaseOnDeepestAncestor } from "../../containers/child/carriedDescendantRekeys.js";
1
+ import { rebaseOnDeepestAncestor } from "../../containers/child/rekey/carriedDescendantRekeys.js";
2
2
  import { withAuthoredPrincipalPolicies } from "./authoredPrincipalPolicyWarmer.js";
3
3
  /** Plan the next group against container heads authored earlier in the same transaction. */
4
4
  export function withPrecedingRematerialization(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"precedingPrincipalRematerialization.js","sourceRoot":"","sources":["precedingPrincipalRematerialization.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AACzF,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAGhF,4FAA4F;AAC5F,MAAM,UAAU,8BAA8B,CAC5C,KAA+C;IAE/C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,MAAyC,EAAE,EAAE;QAC3D,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,QAAQ,CACxC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,CAC9D,CAAC;QACF,MAAM,UAAU,GAAG,GAAG,IAAI,MAAM,CAAC;QACjC,OAAO,CACL,uBAAuB,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU;YACtE,UAAU,CACX,CAAC;IACJ,CAAC,CAAC;IACF,OAAO;QACL,GAAG,KAAK;QACR,+BAA+B,EAAE,6BAA6B,CAC5D,KAAK,CAAC,+BAA+B,EACrC,SAAS,CAAC,QAAQ,IAAI,EAAE,CACzB;QACD,SAAS,EAAE;YACT,GAAG,KAAK,CAAC,SAAS;YAClB,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACtE,4BAA4B,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;gBAClD,MAAM,UAAU,GACd,MAAM,KAAK,CAAC,SAAS,CAAC,4BAA4B,CAAC,WAAW,CAAC,CAAC;gBAClE,OAAO,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChD,CAAC;YACD,kCAAkC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;gBACjE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kCAAkC,CACrE,WAAW,EACX,OAAO,CACR,CAAC;gBACF,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACvE,CAAC;SACF;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { rebaseOnDeepestAncestor } from \"../../containers/child/carriedDescendantRekeys\";\nimport { withAuthoredPrincipalPolicies } from \"./authoredPrincipalPolicyWarmer\";\nimport type { PrincipalContainerRematerializationInput } from \"./principalContainerRematerializationPlanning\";\n\n/** Plan the next group against container heads authored earlier in the same transaction. */\nexport function withPrecedingRematerialization(\n input: PrincipalContainerRematerializationInput,\n): PrincipalContainerRematerializationInput {\n const preceding = input.preceding;\n if (!preceding) return input;\n const rebase = (served: ContainerWriterProjectionResponse) => {\n const own = preceding.projections.findLast(\n (projection) => projection.containerId === served.containerId,\n );\n const projection = own ?? served;\n return (\n rebaseOnDeepestAncestor(projection, preceding.projections)?.projection ??\n projection\n );\n };\n return {\n ...input,\n warmReferencedPrincipalPolicies: withAuthoredPrincipalPolicies(\n input.warmReferencedPrincipalPolicies,\n preceding.authored ?? [],\n ),\n apiClient: {\n ...input.apiClient,\n reciteContainer: input.apiClient.reciteContainer.bind(input.apiClient),\n getContainerWriterProjection: async (containerId) => {\n const projection =\n await input.apiClient.getContainerWriterProjection(containerId);\n return projection ? rebase(projection) : null;\n },\n getContainerWriterProjectionResult: async (containerId, options) => {\n const result = await input.apiClient.getContainerWriterProjectionResult(\n containerId,\n options,\n );\n return result.ok ? { ...result, data: rebase(result.data) } : result;\n },\n },\n };\n}\n"]}
1
+ {"version":3,"file":"precedingPrincipalRematerialization.js","sourceRoot":"","sources":["precedingPrincipalRematerialization.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sDAAsD,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAGhF,4FAA4F;AAC5F,MAAM,UAAU,8BAA8B,CAC5C,KAA+C;IAE/C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,MAAyC,EAAE,EAAE;QAC3D,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,QAAQ,CACxC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,CAC9D,CAAC;QACF,MAAM,UAAU,GAAG,GAAG,IAAI,MAAM,CAAC;QACjC,OAAO,CACL,uBAAuB,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU;YACtE,UAAU,CACX,CAAC;IACJ,CAAC,CAAC;IACF,OAAO;QACL,GAAG,KAAK;QACR,+BAA+B,EAAE,6BAA6B,CAC5D,KAAK,CAAC,+BAA+B,EACrC,SAAS,CAAC,QAAQ,IAAI,EAAE,CACzB;QACD,SAAS,EAAE;YACT,GAAG,KAAK,CAAC,SAAS;YAClB,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;YACtE,4BAA4B,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;gBAClD,MAAM,UAAU,GACd,MAAM,KAAK,CAAC,SAAS,CAAC,4BAA4B,CAAC,WAAW,CAAC,CAAC;gBAClE,OAAO,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChD,CAAC;YACD,kCAAkC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;gBACjE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kCAAkC,CACrE,WAAW,EACX,OAAO,CACR,CAAC;gBACF,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACvE,CAAC;SACF;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { rebaseOnDeepestAncestor } from \"../../containers/child/rekey/carriedDescendantRekeys\";\nimport { withAuthoredPrincipalPolicies } from \"./authoredPrincipalPolicyWarmer\";\nimport type { PrincipalContainerRematerializationInput } from \"./principalContainerRematerializationPlanning\";\n\n/** Plan the next group against container heads authored earlier in the same transaction. */\nexport function withPrecedingRematerialization(\n input: PrincipalContainerRematerializationInput,\n): PrincipalContainerRematerializationInput {\n const preceding = input.preceding;\n if (!preceding) return input;\n const rebase = (served: ContainerWriterProjectionResponse) => {\n const own = preceding.projections.findLast(\n (projection) => projection.containerId === served.containerId,\n );\n const projection = own ?? served;\n return (\n rebaseOnDeepestAncestor(projection, preceding.projections)?.projection ??\n projection\n );\n };\n return {\n ...input,\n warmReferencedPrincipalPolicies: withAuthoredPrincipalPolicies(\n input.warmReferencedPrincipalPolicies,\n preceding.authored ?? [],\n ),\n apiClient: {\n ...input.apiClient,\n reciteContainer: input.apiClient.reciteContainer.bind(input.apiClient),\n getContainerWriterProjection: async (containerId) => {\n const projection =\n await input.apiClient.getContainerWriterProjection(containerId);\n return projection ? rebase(projection) : null;\n },\n getContainerWriterProjectionResult: async (containerId, options) => {\n const result = await input.apiClient.getContainerWriterProjectionResult(\n containerId,\n options,\n );\n return result.ok ? { ...result, data: rebase(result.data) } : result;\n },\n },\n };\n}\n"]}
@@ -4,13 +4,13 @@ import { acknowledgeContainerMutationBatch } from "../../../data/containers/shar
4
4
  import { getTargetContainerContext, readContainerState, } from "../../../data/containers/shared/projection.js";
5
5
  import { verifyContainerWriterProjection, } from "../../../data/keyingProjectionVerification/index.js";
6
6
  import { createProjectionUserKeyResolver } from "../../../data/keyingProjectionVerification/userKeyResolver.js";
7
- import { rebaseOnDeepestAncestor } from "../../containers/child/carriedDescendantRekeys.js";
8
7
  import { scheduleHeldDescendantRecitations } from "../../containers/child/recite.js";
9
- import { buildMaterializedContainerRekeyPlan } from "../../containers/child/rekey.js";
10
- import { containerWriterProjectionFromRotationPlan, containerWriterProjectionFromSharePlan, isSpeculativeContainerWriterProjection, } from "../../containers/child/rekeyProjection.js";
11
- import { selectReplacementPrincipalPolicyReferences } from "../../containers/child/replacementPrincipalPolicyReferences.js";
8
+ import { buildMaterializedContainerRekeyPlan } from "../../containers/child/rekey/index.js";
9
+ import { rebaseOnDeepestAncestor } from "../../containers/child/rekey/carriedDescendantRekeys.js";
10
+ import { containerWriterProjectionFromRotationPlan, containerWriterProjectionFromSharePlan, isSpeculativeContainerWriterProjection, } from "../../containers/child/rekey/rekeyProjection.js";
12
11
  import { buildMaterializedContainerRevokePlan } from "../../containers/child/revoke.js";
13
- import { buildMaterializedContainerSharePlan } from "../../containers/child/shareMaterialization.js";
12
+ import { selectReplacementPrincipalPolicyReferences } from "../../containers/child/rotation/replacementPrincipalPolicyReferences.js";
13
+ import { buildMaterializedContainerSharePlan } from "../../containers/child/share/shareMaterialization.js";
14
14
  import { withPrecedingRematerialization } from "./precedingPrincipalRematerialization.js";
15
15
  import { addPlan, carryLevel, staleLevelsAbove, } from "./principalContainerRematerializationPlanning.js";
16
16
  import { loadRematerializationTargets, loadServedProjection, seededPrincipalPolicyCache, } from "./principalContainerRematerializationTargets.js";
@@ -1 +1 @@
1
- {"version":3,"file":"principalContainerRematerialization.js","sourceRoot":"","sources":["principalContainerRematerialization.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerDirectGrant,\n PrincipalContainerGrant,\n} from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport type { AuthoredContainerMutationHead } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { acknowledgeContainerMutationBatch } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport {\n getTargetContainerContext,\n readContainerState,\n} from \"../../../data/containers/shared/projection\";\nimport {\n type PrincipalPolicyCache,\n verifyContainerWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport { rebaseOnDeepestAncestor } from \"../../containers/child/carriedDescendantRekeys\";\nimport { scheduleHeldDescendantRecitations } from \"../../containers/child/recite\";\nimport { buildMaterializedContainerRekeyPlan } from \"../../containers/child/rekey\";\nimport {\n containerWriterProjectionFromRotationPlan,\n containerWriterProjectionFromSharePlan,\n isSpeculativeContainerWriterProjection,\n} from \"../../containers/child/rekeyProjection\";\nimport { selectReplacementPrincipalPolicyReferences } from \"../../containers/child/replacementPrincipalPolicyReferences\";\nimport { buildMaterializedContainerRevokePlan } from \"../../containers/child/revoke\";\nimport { buildMaterializedContainerSharePlan } from \"../../containers/child/shareMaterialization\";\nimport { withPrecedingRematerialization } from \"./precedingPrincipalRematerialization\";\nimport {\n addPlan,\n type BatchPlanning,\n carryLevel,\n type PrincipalContainerRematerializationInput,\n type PrincipalRematerializationPredecessor,\n staleLevelsAbove,\n} from \"./principalContainerRematerializationPlanning\";\nimport {\n loadRematerializationTargets,\n loadServedProjection,\n type MaterializedPrincipalContainerMutationPlan,\n type PlannedRematerialization,\n type RematerializationTarget,\n seededPrincipalPolicyCache,\n} from \"./principalContainerRematerializationTargets\";\n\nfunction matchingGroupGrant(input: {\n readonly directGrants: readonly ContainerDirectGrant[];\n readonly groupId: string;\n}): ContainerDirectGrant | null {\n return (\n input.directGrants.find(\n (grant) =>\n grant.subjectType === \"group\" && grant.subjectId === input.groupId,\n ) ?? null\n );\n}\n\nfunction referencedGroupKeyEpoch(input: {\n readonly groupId: string;\n readonly referencedPrincipalHeads: ReturnType<\n typeof readContainerState\n >[\"referencedPrincipalHeads\"];\n}): number | null {\n return (\n input.referencedPrincipalHeads.find(\n (head) =>\n head.principalType === \"group\" && head.principalId === input.groupId,\n )?.keyEpoch ?? null\n );\n}\n\nasync function loadGrantedContainerContext(\n input: PrincipalContainerRematerializationInput,\n grantRow: PrincipalContainerGrant,\n projection: ContainerWriterProjectionResponse,\n principalPolicyCache: PrincipalPolicyCache,\n) {\n // A projection re-rooted on a rotation this batch has yet to commit must\n // not pin anything: its heads are speculative until acknowledged, and a\n // pin past the group's served head would refuse the other served paths.\n await verifyContainerWriterProjection({\n execSql: input.execSql,\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n principalPolicyCache,\n projection,\n resolveUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const state = readContainerState(\n getTargetContainerContext(projection).manifest,\n );\n const grant = matchingGroupGrant({\n directGrants: state.directGrants,\n groupId: input.groupId,\n });\n if (grant && grant.accessLevel !== grantRow.accessLevel) {\n const nextGrant = input.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n if (!nextGrant || nextGrant.accessLevel !== grantRow.accessLevel) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the expected group grant`,\n );\n }\n }\n const referencedKeyEpoch = referencedGroupKeyEpoch({\n groupId: input.groupId,\n referencedPrincipalHeads: state.referencedPrincipalHeads,\n });\n if (grant && referencedKeyEpoch === null) {\n throw new Error(\n `Container ${grantRow.containerId} is missing its group reference`,\n );\n }\n return { grant, projection, referencedKeyEpoch };\n}\n\nexport async function buildPrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<ContainerMutationRequest[]> {\n return (\n await buildPrincipalContainerRematerializationPlans(input)\n ).entries.map((entry) => entry.planned.plan.request);\n}\n\nexport interface PreparedPrincipalContainerRematerializationBatch {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly retiredContainerIds: readonly string[];\n readonly acknowledge: (\n responses: readonly ContainerMutationResponse[],\n stillCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n /**\n * Re-sign the batch with the descendant rekeys the server named for its\n * rotations woven in, parent-first, each against the path the batch will\n * leave behind. A named container the batch already rotates is re-planned\n * under what is carried above it, so no container rotates twice. Returns the\n * whole request list, which replaces `requests`; `acknowledge` then expects\n * the responses in that order.\n */\n readonly carry: (\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>;\n readonly plans: readonly MaterializedPrincipalContainerMutationPlan[];\n readonly requests: readonly ContainerMutationRequest[];\n}\n\nfunction authoredMutationHead(\n planned: MaterializedPrincipalContainerMutationPlan,\n): AuthoredContainerMutationHead {\n return planned.plan;\n}\n\nasync function buildPrincipalContainerRematerializationPlan(input: {\n readonly grantRow: PrincipalContainerGrant;\n /** Keys the batch minted above this container; see `BatchPlanning`. */\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n /** Holds the policy this batch commits, which rebased paths already cite. */\n readonly principalPolicyCache: PrincipalPolicyCache;\n /** The served projection, re-rooted on any rotation planned above it. */\n readonly projection: ContainerWriterProjectionResponse;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n}): Promise<MaterializedPrincipalContainerMutationPlan> {\n const { grantRow } = input;\n const rematerialization = {\n ...input.rematerialization,\n nextPolicy: await selectReplacementPrincipalPolicyReferences({\n policy: input.rematerialization.nextPolicy,\n projection: input.projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveAuthoredPolicyReferences:\n input.rematerialization.resolveAuthoredPolicyReferences,\n }),\n };\n const { grant, projection, referencedKeyEpoch } =\n await loadGrantedContainerContext(\n rematerialization,\n grantRow,\n input.projection,\n input.principalPolicyCache,\n );\n const nextGrant = rematerialization.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n const author = {\n ...rematerialization.author,\n organizationId: projection.organizationId,\n };\n const sharedInput = {\n author,\n execSql: rematerialization.execSql,\n knownContainerKeks: input.knownContainerKeks,\n // Planning against a path this batch has yet to commit pins nothing; the\n // acknowledgement advances every head at once. The rekey planner applies\n // this rule itself; revoke and grant planning take it from here.\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n previousProjection: projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n };\n if (grantRow.containerId === rematerialization.revokedContainerId) {\n if (!grant) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the revoked group grant`,\n );\n }\n return buildMaterializedContainerRevokePlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n revokedSubject: {\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (!grant || grant.accessLevel !== nextGrant?.accessLevel) {\n if (!nextGrant) {\n throw new Error(\n `Container ${grantRow.containerId} is absent from the next group grant set`,\n );\n }\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: nextGrant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (referencedKeyEpoch === rematerialization.nextPolicy.keyEpoch) {\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: grant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n return buildMaterializedContainerRekeyPlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n });\n}\n\n/**\n * Plan one target against the paths already planned above it. A grant's\n * rematerialization extends the served head; a rotation's, and every carried\n * rekey, extends the epoch the batch mints above it.\n */\nasync function planRematerializationTarget(\n batch: BatchPlanning,\n target: RematerializationTarget,\n): Promise<void> {\n const { rematerialization } = batch;\n let rebased = rebaseOnDeepestAncestor(target.projection, batch.rotatedAbove);\n const stale = rebased\n ? staleLevelsAbove(\n rebased.projection,\n rebased.ancestor.containerKeks.at(-1)?.containerId ?? \"\",\n )\n : [];\n for (const containerId of stale) {\n await carryLevel(\n batch,\n await loadServedProjection(rematerialization.apiClient, containerId),\n );\n }\n if (!target.grantRow) {\n await carryLevel(batch, target.projection);\n return;\n }\n // Each level carried above re-roots the target one step deeper.\n if (stale.length > 0) {\n rebased = rebaseOnDeepestAncestor(target.projection, batch.rotatedAbove);\n }\n const previousProjection = rebased?.projection ?? target.projection;\n const planned = await buildPrincipalContainerRematerializationPlan({\n grantRow: target.grantRow,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n projection: previousProjection,\n rematerialization,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n });\n const nextProjection =\n \"keyring\" in planned.plan\n ? await containerWriterProjectionFromRotationPlan({\n plan: planned.plan,\n previousProjection,\n })\n : await containerWriterProjectionFromSharePlan({\n plan: planned.plan,\n previousProjection,\n });\n addPlan(batch, {\n carried: false,\n planned,\n rotated: \"keyring\" in planned.plan ? nextProjection : null,\n nextProjection,\n });\n}\n\n/**\n * Sign the batch parent-first. `carriedContainerIds` are the descendant rekeys\n * a refused attempt was told to carry; woven in by depth, each sits under the\n * rotation it rides, and a named container the batch rematerializes anyway is\n * re-planned there rather than rotated twice.\n */\nasync function buildPrincipalContainerRematerializationPlans(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[] = [],\n): Promise<{\n entries: PlannedRematerialization[];\n retiredContainerIds: readonly string[];\n preceding: PrincipalRematerializationPredecessor;\n}> {\n input = withPrecedingRematerialization(input);\n if (\n input.revokedContainerId &&\n !input.grants.some(\n (grant) => grant.containerId === input.revokedContainerId,\n )\n ) {\n throw new Error(\"Revoked container is not granted to the group\");\n }\n const { targets, retiredContainerIds } = await loadRematerializationTargets({\n apiClient: input.apiClient,\n carriedContainerIds,\n grants: input.grants,\n });\n const batch: BatchPlanning = {\n knownContainerKeks: new Map(input.preceding?.knownContainerKeks),\n plans: [],\n // A rotation planned above cites the group at the head this batch commits,\n // which no store holds yet; the cache is what lets a rebased path verify.\n principalPolicyCache: new Map([\n ...(input.preceding?.policies ?? []).flatMap((policy) => [\n ...seededPrincipalPolicyCache(policy),\n ]),\n ...seededPrincipalPolicyCache(input.nextPolicy),\n ]),\n rematerialization: input,\n resolveProjectionUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n rotatedAbove: [],\n };\n for (const target of targets) {\n await planRematerializationTarget(batch, target);\n }\n return {\n entries: batch.plans,\n retiredContainerIds,\n preceding: {\n policies: [...(input.preceding?.policies ?? []), input.nextPolicy],\n projections: [\n ...(input.preceding?.projections ?? []),\n ...batch.plans.flatMap((entry) =>\n entry.nextProjection ? [entry.nextProjection] : [],\n ),\n ],\n knownContainerKeks: batch.knownContainerKeks,\n },\n };\n}\n\n/**\n * The server names a level it found pinned to a retired epoch. A batch answers\n * with a rotation of it: a carried rekey, or its own rematerialization when\n * that is a rekey or revoke. A rematerialized grant rotates nothing, so a\n * batch that both grants a container and must re-key it cannot be signed;\n * no policy change the SDK builds combines the two.\n */\nfunction assertNamedContainersRotated(\n plans: readonly PlannedRematerialization[],\n requiredContainerIds: readonly string[],\n): void {\n const rotatedIds = new Set(\n plans.flatMap((entry) =>\n entry.rotated ? [entry.planned.plan.containerId] : [],\n ),\n );\n const unrotated = requiredContainerIds\n .slice(0, MAX_ROTATION_CONTAINER_REKEYS)\n .find((containerId) => !rotatedIds.has(containerId));\n if (unrotated !== undefined) {\n throw new Error(\n `Container ${unrotated} needs a rekey this policy change only grants`,\n );\n }\n}\n\nexport async function preparePrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<PreparedPrincipalContainerRematerializationBatch> {\n let { entries, retiredContainerIds, preceding } =\n await buildPrincipalContainerRematerializationPlans(input);\n const requests = () => entries.map((entry) => entry.planned.plan.request);\n return {\n get preceding() {\n return preceding;\n },\n get retiredContainerIds() {\n return retiredContainerIds;\n },\n get plans() {\n return entries.map((entry) => entry.planned);\n },\n get requests() {\n return requests();\n },\n carry: async (requiredContainerIds) => {\n // The refused attempt rolled back whole, so every served head still\n // stands; the batch is signed again from them with the named levels in.\n const replanned = await buildPrincipalContainerRematerializationPlans(\n input,\n requiredContainerIds,\n );\n assertNamedContainersRotated(replanned.entries, requiredContainerIds);\n entries = replanned.entries;\n retiredContainerIds = replanned.retiredContainerIds;\n preceding = replanned.preceding;\n return requests();\n },\n acknowledge: async (responses, stillCurrent) => {\n const isCurrent = () =>\n input.stillCurrent?.() !== false && stillCurrent?.() !== false;\n const heads = entries.map((entry) => authoredMutationHead(entry.planned));\n const acknowledged = await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: heads,\n responses,\n stillCurrent: isCurrent,\n });\n if (!acknowledged || !isCurrent()) return;\n const plansByOrganization = new Map<\n string,\n AuthoredContainerMutationHead[]\n >();\n for (const head of heads) {\n const organizationId = head.state.organizationId;\n const group = plansByOrganization.get(organizationId) ?? [];\n group.push(head);\n plansByOrganization.set(organizationId, group);\n }\n for (const [organizationId, organizationPlans] of plansByOrganization) {\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql,\n heads: [],\n policies: [input.nextPolicy],\n });\n } catch {\n // Cache failure must not invalidate the durably acknowledged batch.\n continue;\n }\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: { ...input.author, organizationId },\n execSql: input.execSql,\n plans: organizationPlans,\n stillCurrent: input.recitationStillCurrent ?? isCurrent,\n reportSecurityIncident: input.reportSecurityIncident,\n });\n }\n },\n };\n}\n"]}
1
+ {"version":3,"file":"principalContainerRematerialization.js","sourceRoot":"","sources":["principalContainerRematerialization.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerDirectGrant,\n PrincipalContainerGrant,\n} from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport type { AuthoredContainerMutationHead } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { acknowledgeContainerMutationBatch } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport {\n getTargetContainerContext,\n readContainerState,\n} from \"../../../data/containers/shared/projection\";\nimport {\n type PrincipalPolicyCache,\n verifyContainerWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport { scheduleHeldDescendantRecitations } from \"../../containers/child/recite\";\nimport { buildMaterializedContainerRekeyPlan } from \"../../containers/child/rekey\";\nimport { rebaseOnDeepestAncestor } from \"../../containers/child/rekey/carriedDescendantRekeys\";\nimport {\n containerWriterProjectionFromRotationPlan,\n containerWriterProjectionFromSharePlan,\n isSpeculativeContainerWriterProjection,\n} from \"../../containers/child/rekey/rekeyProjection\";\nimport { buildMaterializedContainerRevokePlan } from \"../../containers/child/revoke\";\nimport { selectReplacementPrincipalPolicyReferences } from \"../../containers/child/rotation/replacementPrincipalPolicyReferences\";\nimport { buildMaterializedContainerSharePlan } from \"../../containers/child/share/shareMaterialization\";\nimport { withPrecedingRematerialization } from \"./precedingPrincipalRematerialization\";\nimport {\n addPlan,\n type BatchPlanning,\n carryLevel,\n type PrincipalContainerRematerializationInput,\n type PrincipalRematerializationPredecessor,\n staleLevelsAbove,\n} from \"./principalContainerRematerializationPlanning\";\nimport {\n loadRematerializationTargets,\n loadServedProjection,\n type MaterializedPrincipalContainerMutationPlan,\n type PlannedRematerialization,\n type RematerializationTarget,\n seededPrincipalPolicyCache,\n} from \"./principalContainerRematerializationTargets\";\n\nfunction matchingGroupGrant(input: {\n readonly directGrants: readonly ContainerDirectGrant[];\n readonly groupId: string;\n}): ContainerDirectGrant | null {\n return (\n input.directGrants.find(\n (grant) =>\n grant.subjectType === \"group\" && grant.subjectId === input.groupId,\n ) ?? null\n );\n}\n\nfunction referencedGroupKeyEpoch(input: {\n readonly groupId: string;\n readonly referencedPrincipalHeads: ReturnType<\n typeof readContainerState\n >[\"referencedPrincipalHeads\"];\n}): number | null {\n return (\n input.referencedPrincipalHeads.find(\n (head) =>\n head.principalType === \"group\" && head.principalId === input.groupId,\n )?.keyEpoch ?? null\n );\n}\n\nasync function loadGrantedContainerContext(\n input: PrincipalContainerRematerializationInput,\n grantRow: PrincipalContainerGrant,\n projection: ContainerWriterProjectionResponse,\n principalPolicyCache: PrincipalPolicyCache,\n) {\n // A projection re-rooted on a rotation this batch has yet to commit must\n // not pin anything: its heads are speculative until acknowledged, and a\n // pin past the group's served head would refuse the other served paths.\n await verifyContainerWriterProjection({\n execSql: input.execSql,\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n principalPolicyCache,\n projection,\n resolveUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const state = readContainerState(\n getTargetContainerContext(projection).manifest,\n );\n const grant = matchingGroupGrant({\n directGrants: state.directGrants,\n groupId: input.groupId,\n });\n if (grant && grant.accessLevel !== grantRow.accessLevel) {\n const nextGrant = input.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n if (!nextGrant || nextGrant.accessLevel !== grantRow.accessLevel) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the expected group grant`,\n );\n }\n }\n const referencedKeyEpoch = referencedGroupKeyEpoch({\n groupId: input.groupId,\n referencedPrincipalHeads: state.referencedPrincipalHeads,\n });\n if (grant && referencedKeyEpoch === null) {\n throw new Error(\n `Container ${grantRow.containerId} is missing its group reference`,\n );\n }\n return { grant, projection, referencedKeyEpoch };\n}\n\nexport async function buildPrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<ContainerMutationRequest[]> {\n return (\n await buildPrincipalContainerRematerializationPlans(input)\n ).entries.map((entry) => entry.planned.plan.request);\n}\n\nexport interface PreparedPrincipalContainerRematerializationBatch {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly retiredContainerIds: readonly string[];\n readonly acknowledge: (\n responses: readonly ContainerMutationResponse[],\n stillCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n /**\n * Re-sign the batch with the descendant rekeys the server named for its\n * rotations woven in, parent-first, each against the path the batch will\n * leave behind. A named container the batch already rotates is re-planned\n * under what is carried above it, so no container rotates twice. Returns the\n * whole request list, which replaces `requests`; `acknowledge` then expects\n * the responses in that order.\n */\n readonly carry: (\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>;\n readonly plans: readonly MaterializedPrincipalContainerMutationPlan[];\n readonly requests: readonly ContainerMutationRequest[];\n}\n\nfunction authoredMutationHead(\n planned: MaterializedPrincipalContainerMutationPlan,\n): AuthoredContainerMutationHead {\n return planned.plan;\n}\n\nasync function buildPrincipalContainerRematerializationPlan(input: {\n readonly grantRow: PrincipalContainerGrant;\n /** Keys the batch minted above this container; see `BatchPlanning`. */\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n /** Holds the policy this batch commits, which rebased paths already cite. */\n readonly principalPolicyCache: PrincipalPolicyCache;\n /** The served projection, re-rooted on any rotation planned above it. */\n readonly projection: ContainerWriterProjectionResponse;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n}): Promise<MaterializedPrincipalContainerMutationPlan> {\n const { grantRow } = input;\n const rematerialization = {\n ...input.rematerialization,\n nextPolicy: await selectReplacementPrincipalPolicyReferences({\n policy: input.rematerialization.nextPolicy,\n projection: input.projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveAuthoredPolicyReferences:\n input.rematerialization.resolveAuthoredPolicyReferences,\n }),\n };\n const { grant, projection, referencedKeyEpoch } =\n await loadGrantedContainerContext(\n rematerialization,\n grantRow,\n input.projection,\n input.principalPolicyCache,\n );\n const nextGrant = rematerialization.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n const author = {\n ...rematerialization.author,\n organizationId: projection.organizationId,\n };\n const sharedInput = {\n author,\n execSql: rematerialization.execSql,\n knownContainerKeks: input.knownContainerKeks,\n // Planning against a path this batch has yet to commit pins nothing; the\n // acknowledgement advances every head at once. The rekey planner applies\n // this rule itself; revoke and grant planning take it from here.\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n previousProjection: projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n };\n if (grantRow.containerId === rematerialization.revokedContainerId) {\n if (!grant) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the revoked group grant`,\n );\n }\n return buildMaterializedContainerRevokePlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n revokedSubject: {\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (!grant || grant.accessLevel !== nextGrant?.accessLevel) {\n if (!nextGrant) {\n throw new Error(\n `Container ${grantRow.containerId} is absent from the next group grant set`,\n );\n }\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: nextGrant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (referencedKeyEpoch === rematerialization.nextPolicy.keyEpoch) {\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: grant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n return buildMaterializedContainerRekeyPlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n });\n}\n\n/**\n * Plan one target against the paths already planned above it. A grant's\n * rematerialization extends the served head; a rotation's, and every carried\n * rekey, extends the epoch the batch mints above it.\n */\nasync function planRematerializationTarget(\n batch: BatchPlanning,\n target: RematerializationTarget,\n): Promise<void> {\n const { rematerialization } = batch;\n let rebased = rebaseOnDeepestAncestor(target.projection, batch.rotatedAbove);\n const stale = rebased\n ? staleLevelsAbove(\n rebased.projection,\n rebased.ancestor.containerKeks.at(-1)?.containerId ?? \"\",\n )\n : [];\n for (const containerId of stale) {\n await carryLevel(\n batch,\n await loadServedProjection(rematerialization.apiClient, containerId),\n );\n }\n if (!target.grantRow) {\n await carryLevel(batch, target.projection);\n return;\n }\n // Each level carried above re-roots the target one step deeper.\n if (stale.length > 0) {\n rebased = rebaseOnDeepestAncestor(target.projection, batch.rotatedAbove);\n }\n const previousProjection = rebased?.projection ?? target.projection;\n const planned = await buildPrincipalContainerRematerializationPlan({\n grantRow: target.grantRow,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n projection: previousProjection,\n rematerialization,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n });\n const nextProjection =\n \"keyring\" in planned.plan\n ? await containerWriterProjectionFromRotationPlan({\n plan: planned.plan,\n previousProjection,\n })\n : await containerWriterProjectionFromSharePlan({\n plan: planned.plan,\n previousProjection,\n });\n addPlan(batch, {\n carried: false,\n planned,\n rotated: \"keyring\" in planned.plan ? nextProjection : null,\n nextProjection,\n });\n}\n\n/**\n * Sign the batch parent-first. `carriedContainerIds` are the descendant rekeys\n * a refused attempt was told to carry; woven in by depth, each sits under the\n * rotation it rides, and a named container the batch rematerializes anyway is\n * re-planned there rather than rotated twice.\n */\nasync function buildPrincipalContainerRematerializationPlans(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[] = [],\n): Promise<{\n entries: PlannedRematerialization[];\n retiredContainerIds: readonly string[];\n preceding: PrincipalRematerializationPredecessor;\n}> {\n input = withPrecedingRematerialization(input);\n if (\n input.revokedContainerId &&\n !input.grants.some(\n (grant) => grant.containerId === input.revokedContainerId,\n )\n ) {\n throw new Error(\"Revoked container is not granted to the group\");\n }\n const { targets, retiredContainerIds } = await loadRematerializationTargets({\n apiClient: input.apiClient,\n carriedContainerIds,\n grants: input.grants,\n });\n const batch: BatchPlanning = {\n knownContainerKeks: new Map(input.preceding?.knownContainerKeks),\n plans: [],\n // A rotation planned above cites the group at the head this batch commits,\n // which no store holds yet; the cache is what lets a rebased path verify.\n principalPolicyCache: new Map([\n ...(input.preceding?.policies ?? []).flatMap((policy) => [\n ...seededPrincipalPolicyCache(policy),\n ]),\n ...seededPrincipalPolicyCache(input.nextPolicy),\n ]),\n rematerialization: input,\n resolveProjectionUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n rotatedAbove: [],\n };\n for (const target of targets) {\n await planRematerializationTarget(batch, target);\n }\n return {\n entries: batch.plans,\n retiredContainerIds,\n preceding: {\n policies: [...(input.preceding?.policies ?? []), input.nextPolicy],\n projections: [\n ...(input.preceding?.projections ?? []),\n ...batch.plans.flatMap((entry) =>\n entry.nextProjection ? [entry.nextProjection] : [],\n ),\n ],\n knownContainerKeks: batch.knownContainerKeks,\n },\n };\n}\n\n/**\n * The server names a level it found pinned to a retired epoch. A batch answers\n * with a rotation of it: a carried rekey, or its own rematerialization when\n * that is a rekey or revoke. A rematerialized grant rotates nothing, so a\n * batch that both grants a container and must re-key it cannot be signed;\n * no policy change the SDK builds combines the two.\n */\nfunction assertNamedContainersRotated(\n plans: readonly PlannedRematerialization[],\n requiredContainerIds: readonly string[],\n): void {\n const rotatedIds = new Set(\n plans.flatMap((entry) =>\n entry.rotated ? [entry.planned.plan.containerId] : [],\n ),\n );\n const unrotated = requiredContainerIds\n .slice(0, MAX_ROTATION_CONTAINER_REKEYS)\n .find((containerId) => !rotatedIds.has(containerId));\n if (unrotated !== undefined) {\n throw new Error(\n `Container ${unrotated} needs a rekey this policy change only grants`,\n );\n }\n}\n\nexport async function preparePrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<PreparedPrincipalContainerRematerializationBatch> {\n let { entries, retiredContainerIds, preceding } =\n await buildPrincipalContainerRematerializationPlans(input);\n const requests = () => entries.map((entry) => entry.planned.plan.request);\n return {\n get preceding() {\n return preceding;\n },\n get retiredContainerIds() {\n return retiredContainerIds;\n },\n get plans() {\n return entries.map((entry) => entry.planned);\n },\n get requests() {\n return requests();\n },\n carry: async (requiredContainerIds) => {\n // The refused attempt rolled back whole, so every served head still\n // stands; the batch is signed again from them with the named levels in.\n const replanned = await buildPrincipalContainerRematerializationPlans(\n input,\n requiredContainerIds,\n );\n assertNamedContainersRotated(replanned.entries, requiredContainerIds);\n entries = replanned.entries;\n retiredContainerIds = replanned.retiredContainerIds;\n preceding = replanned.preceding;\n return requests();\n },\n acknowledge: async (responses, stillCurrent) => {\n const isCurrent = () =>\n input.stillCurrent?.() !== false && stillCurrent?.() !== false;\n const heads = entries.map((entry) => authoredMutationHead(entry.planned));\n const acknowledged = await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: heads,\n responses,\n stillCurrent: isCurrent,\n });\n if (!acknowledged || !isCurrent()) return;\n const plansByOrganization = new Map<\n string,\n AuthoredContainerMutationHead[]\n >();\n for (const head of heads) {\n const organizationId = head.state.organizationId;\n const group = plansByOrganization.get(organizationId) ?? [];\n group.push(head);\n plansByOrganization.set(organizationId, group);\n }\n for (const [organizationId, organizationPlans] of plansByOrganization) {\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql,\n heads: [],\n policies: [input.nextPolicy],\n });\n } catch {\n // Cache failure must not invalidate the durably acknowledged batch.\n continue;\n }\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: { ...input.author, organizationId },\n execSql: input.execSql,\n plans: organizationPlans,\n stillCurrent: input.recitationStillCurrent ?? isCurrent,\n reportSecurityIncident: input.reportSecurityIncident,\n });\n }\n },\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { MAX_ROTATION_CONTAINER_REKEYS } from "../../../internal/validators/util/index.js";
2
- import { planCarriedDescendantRekey, } from "../../containers/child/carriedDescendantRekeys.js";
2
+ import { planCarriedDescendantRekey, } from "../../containers/child/rekey/carriedDescendantRekeys.js";
3
3
  /** How many rekeys the batch carries beyond its rematerializations. */
4
4
  function carriedCount(batch) {
5
5
  return batch.plans.filter((entry) => entry.carried).length;
@@ -1 +1 @@
1
- {"version":3,"file":"principalContainerRematerializationPlanning.js","sourceRoot":"","sources":["principalContainerRematerializationPlanning.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type { ContainerMutationAuthor } from \"../../../data/containers/shared/types\";\nimport type {\n PrincipalPolicyCache,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../../data/keyingProjectionVerification\";\nimport type { ResolvedPrincipalPolicyEvidence } from \"../../../data/keyingProjectionVerification/types\";\nimport type { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport type { CurrentPolicyReferenceResolver } from \"../../../data/principals/currentPolicyReferenceResolver\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport {\n planCarriedDescendantRekey,\n type SpeculativePath,\n} from \"../../containers/child/carriedDescendantRekeys\";\nimport type { PlannedRematerialization } from \"./principalContainerRematerializationTargets\";\n\nexport interface RematerializationApi\n extends ContainerReciteApi,\n Pick<ApiClient, \"getContainerWriterProjectionResult\"> {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport interface PrincipalRematerializationPredecessor {\n readonly authored?: readonly ResolvedPrincipalPolicyEvidence[] | undefined;\n readonly policies: readonly PrincipalPolicyCurrentEvidence[];\n readonly projections: readonly ContainerWriterProjectionResponse[];\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n}\n\nexport interface PrincipalContainerRematerializationInput {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly apiClient: RematerializationApi;\n readonly author: ContainerMutationAuthor;\n readonly execSql: ExecSql;\n readonly grants: readonly PrincipalContainerGrant[];\n readonly groupId: string;\n readonly nextPolicy: PrincipalPolicyCurrentEvidence;\n readonly resolveAuthoredPolicyReferences?:\n | CurrentPolicyReferenceResolver\n | undefined;\n readonly revokedContainerId?: string | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly targetSecretKey: Uint8Array;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\n/** What the batch has signed so far, in the order it will be submitted. */\nexport interface BatchPlanning {\n /**\n * Keys the batch minted, by epoch id. A rotation wraps its successor to the\n * group at the head this batch commits, which no store can open yet; a\n * level planned beneath it opens that epoch with the key minted here, and\n * its keyring then opens the retired epoch the level below is pinned to.\n */\n readonly knownContainerKeks: Map<string, Uint8Array>;\n readonly plans: PlannedRematerialization[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n readonly rotatedAbove: SpeculativePath[];\n}\n\n/** How many rekeys the batch carries beyond its rematerializations. */\nfunction carriedCount(batch: BatchPlanning): number {\n return batch.plans.filter((entry) => entry.carried).length;\n}\n\n/**\n * Sign a rekey of `served` under the batch's rotations above it, and add it.\n * The server accepts at most `MAX_ROTATION_CONTAINER_REKEYS` carried entries;\n * past that a rematerialization below them could not be signed on a current\n * path, so the batch is refused here, before signing what the server would\n * refuse anyway, and the policy change has to wait for a lazy repair of the\n * tree. Groups granted that far apart on one chain are not a shape the SDK\n * creates.\n */\nexport async function carryLevel(\n batch: BatchPlanning,\n served: ContainerWriterProjectionResponse,\n): Promise<void> {\n const { rematerialization } = batch;\n if (carriedCount(batch) >= MAX_ROTATION_CONTAINER_REKEYS) {\n throw new Error(\n `Policy change would carry more than ${MAX_ROTATION_CONTAINER_REKEYS} descendant rekeys`,\n );\n }\n const planned = await planCarriedDescendantRekey({\n apiClient: rematerialization.apiClient,\n author: rematerialization.author,\n execSql: rematerialization.execSql,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n // Its path cites the policy this batch commits, so like every\n // rematerialized rotation it must cite the successor.\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n resolveAuthoredPolicyReferences:\n rematerialization.resolveAuthoredPolicyReferences,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n rotated: batch.rotatedAbove,\n served,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n });\n addPlan(batch, {\n carried: true,\n planned,\n rotated: planned.writerProjection,\n nextProjection: planned.writerProjection,\n });\n}\n\nexport function addPlan(\n batch: BatchPlanning,\n entry: PlannedRematerialization,\n): void {\n batch.plans.push(entry);\n if (!entry.rotated) return;\n batch.rotatedAbove.push(entry.rotated);\n const minted = entry.rotated.containerKeks.at(-1)?.containerKeyEpochId;\n if (minted) batch.knownContainerKeks.set(minted, entry.planned.containerKey);\n}\n\n/**\n * Levels of a re-rooted path pinned to an epoch the batch retires above them:\n * those strictly between the rotated ancestor the path was re-rooted on and\n * the target, parent-first, from the first stale one down. A rotation planned\n * above a target strands every level between the two, and each must be\n * re-keyed under the one above before the target can be signed. The batch\n * carries them without waiting to be told: they are proper ancestors of a\n * granted container, so the server would name them, and a refusal per level\n * is a round trip each. Anything stale above the rotated ancestor is not this\n * batch's doing and is left alone. `carryLevel` holds the count to the cap.\n */\nexport function staleLevelsAbove(\n projection: ContainerWriterProjectionResponse,\n rotatedAncestorId: string,\n): string[] {\n const keks = projection.containerKeks;\n const ancestor = keks.findIndex(\n (kek) => kek.containerId === rotatedAncestorId,\n );\n if (ancestor < 0) return [];\n const between = keks.slice(ancestor, -1);\n const firstStale = between.findIndex(\n (kek, index) =>\n index > 0 &&\n kek.parentContainerKeyEpochId !== between[index - 1]?.containerKeyEpochId,\n );\n return firstStale < 0\n ? []\n : between.slice(firstStale).map((kek) => kek.containerId);\n}\n"]}
1
+ {"version":3,"file":"principalContainerRematerializationPlanning.js","sourceRoot":"","sources":["principalContainerRematerializationPlanning.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type { ContainerMutationAuthor } from \"../../../data/containers/shared/types\";\nimport type {\n PrincipalPolicyCache,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../../data/keyingProjectionVerification\";\nimport type { ResolvedPrincipalPolicyEvidence } from \"../../../data/keyingProjectionVerification/types\";\nimport type { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport type { CurrentPolicyReferenceResolver } from \"../../../data/principals/currentPolicyReferenceResolver\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport {\n planCarriedDescendantRekey,\n type SpeculativePath,\n} from \"../../containers/child/rekey/carriedDescendantRekeys\";\nimport type { PlannedRematerialization } from \"./principalContainerRematerializationTargets\";\n\nexport interface RematerializationApi\n extends ContainerReciteApi,\n Pick<ApiClient, \"getContainerWriterProjectionResult\"> {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport interface PrincipalRematerializationPredecessor {\n readonly authored?: readonly ResolvedPrincipalPolicyEvidence[] | undefined;\n readonly policies: readonly PrincipalPolicyCurrentEvidence[];\n readonly projections: readonly ContainerWriterProjectionResponse[];\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n}\n\nexport interface PrincipalContainerRematerializationInput {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly apiClient: RematerializationApi;\n readonly author: ContainerMutationAuthor;\n readonly execSql: ExecSql;\n readonly grants: readonly PrincipalContainerGrant[];\n readonly groupId: string;\n readonly nextPolicy: PrincipalPolicyCurrentEvidence;\n readonly resolveAuthoredPolicyReferences?:\n | CurrentPolicyReferenceResolver\n | undefined;\n readonly revokedContainerId?: string | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly targetSecretKey: Uint8Array;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\n/** What the batch has signed so far, in the order it will be submitted. */\nexport interface BatchPlanning {\n /**\n * Keys the batch minted, by epoch id. A rotation wraps its successor to the\n * group at the head this batch commits, which no store can open yet; a\n * level planned beneath it opens that epoch with the key minted here, and\n * its keyring then opens the retired epoch the level below is pinned to.\n */\n readonly knownContainerKeks: Map<string, Uint8Array>;\n readonly plans: PlannedRematerialization[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n readonly rotatedAbove: SpeculativePath[];\n}\n\n/** How many rekeys the batch carries beyond its rematerializations. */\nfunction carriedCount(batch: BatchPlanning): number {\n return batch.plans.filter((entry) => entry.carried).length;\n}\n\n/**\n * Sign a rekey of `served` under the batch's rotations above it, and add it.\n * The server accepts at most `MAX_ROTATION_CONTAINER_REKEYS` carried entries;\n * past that a rematerialization below them could not be signed on a current\n * path, so the batch is refused here, before signing what the server would\n * refuse anyway, and the policy change has to wait for a lazy repair of the\n * tree. Groups granted that far apart on one chain are not a shape the SDK\n * creates.\n */\nexport async function carryLevel(\n batch: BatchPlanning,\n served: ContainerWriterProjectionResponse,\n): Promise<void> {\n const { rematerialization } = batch;\n if (carriedCount(batch) >= MAX_ROTATION_CONTAINER_REKEYS) {\n throw new Error(\n `Policy change would carry more than ${MAX_ROTATION_CONTAINER_REKEYS} descendant rekeys`,\n );\n }\n const planned = await planCarriedDescendantRekey({\n apiClient: rematerialization.apiClient,\n author: rematerialization.author,\n execSql: rematerialization.execSql,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n // Its path cites the policy this batch commits, so like every\n // rematerialized rotation it must cite the successor.\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n resolveAuthoredPolicyReferences:\n rematerialization.resolveAuthoredPolicyReferences,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n rotated: batch.rotatedAbove,\n served,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n });\n addPlan(batch, {\n carried: true,\n planned,\n rotated: planned.writerProjection,\n nextProjection: planned.writerProjection,\n });\n}\n\nexport function addPlan(\n batch: BatchPlanning,\n entry: PlannedRematerialization,\n): void {\n batch.plans.push(entry);\n if (!entry.rotated) return;\n batch.rotatedAbove.push(entry.rotated);\n const minted = entry.rotated.containerKeks.at(-1)?.containerKeyEpochId;\n if (minted) batch.knownContainerKeks.set(minted, entry.planned.containerKey);\n}\n\n/**\n * Levels of a re-rooted path pinned to an epoch the batch retires above them:\n * those strictly between the rotated ancestor the path was re-rooted on and\n * the target, parent-first, from the first stale one down. A rotation planned\n * above a target strands every level between the two, and each must be\n * re-keyed under the one above before the target can be signed. The batch\n * carries them without waiting to be told: they are proper ancestors of a\n * granted container, so the server would name them, and a refusal per level\n * is a round trip each. Anything stale above the rotated ancestor is not this\n * batch's doing and is left alone. `carryLevel` holds the count to the cap.\n */\nexport function staleLevelsAbove(\n projection: ContainerWriterProjectionResponse,\n rotatedAncestorId: string,\n): string[] {\n const keks = projection.containerKeks;\n const ancestor = keks.findIndex(\n (kek) => kek.containerId === rotatedAncestorId,\n );\n if (ancestor < 0) return [];\n const between = keks.slice(ancestor, -1);\n const firstStale = between.findIndex(\n (kek, index) =>\n index > 0 &&\n kek.parentContainerKeyEpochId !== between[index - 1]?.containerKeyEpochId,\n );\n return firstStale < 0\n ? []\n : between.slice(firstStale).map((kek) => kek.containerId);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { MAX_ROTATION_CONTAINER_REKEYS } from "../../../internal/validators/util/index.js";
2
2
  import { isContainerNotFoundFailure } from "../../../data/containers/shared/mutationFailures.js";
3
- import { referencedPrincipalPolicyKey } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
3
+ import { referencedPrincipalPolicyKey } from "../../../data/keyingProjectionVerification/principalPolicy/principalPolicyCache.js";
4
4
  /**
5
5
  * Order a batch parent-first, by served depth. A group granted on a container
6
6
  * and on one of its descendants rotates both, and the lower rotation must be
@@ -1 +1 @@
1
- {"version":3,"file":"principalContainerRematerializationTargets.js","sourceRoot":"","sources":["principalContainerRematerializationTargets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type {\n MaterializedContainerRekeyPlan,\n MaterializedContainerRevokePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCache } from \"../../../data/keyingProjectionVerification\";\nimport { referencedPrincipalPolicyKey } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SpeculativePath } from \"../../containers/child/carriedDescendantRekeys\";\n\nexport type MaterializedPrincipalContainerMutationPlan =\n | MaterializedContainerRekeyPlan\n | MaterializedContainerRevokePlan\n | MaterializedContainerSharePlan;\n\n/** Authored paths for chaining plans; only rotated is null for a grant. */\nexport interface PlannedRematerialization {\n /** The authored successor for either a grant or a rotation. */\n readonly nextProjection?: ContainerWriterProjectionResponse | undefined;\n /** A descendant rekey carried for a rotation above, not a rematerialization. */\n readonly carried: boolean;\n readonly planned: MaterializedPrincipalContainerMutationPlan;\n readonly rotated: SpeculativePath | null;\n}\n\n/**\n * One container a batch signs for: a group grant it rematerializes, or a\n * descendant rekey it carries for a rotation above (`grantRow` null).\n */\nexport interface RematerializationTarget {\n readonly grantRow: PrincipalContainerGrant | null;\n readonly projection: ContainerWriterProjectionResponse;\n}\n\n/**\n * Order a batch parent-first, by served depth. A group granted on a container\n * and on one of its descendants rotates both, and the lower rotation must be\n * signed against the epoch the upper one mints in this same batch, or it\n * extends a head the batch itself retires. A carried rekey sits below the\n * rotation it rides for the same reason. Ties keep id order for stability.\n */\nexport function orderRematerializationsParentFirst<\n T extends {\n readonly projection: {\n readonly containerId: string;\n readonly path: readonly unknown[];\n };\n },\n>(batch: readonly T[]): T[] {\n return [...batch].sort(\n (left, right) =>\n left.projection.path.length - right.projection.path.length ||\n left.projection.containerId.localeCompare(right.projection.containerId),\n );\n}\n\ninterface ProjectionApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\n/** The served projection of a container the batch will sign for. */\nexport async function loadServedProjection(\n apiClient: ProjectionApi,\n containerId: string,\n): Promise<ContainerWriterProjectionResponse> {\n const projection = await apiClient.getContainerWriterProjection(containerId);\n if (!projection) {\n throw new Error(\n `Container ${containerId} could not be prepared for principal rotation`,\n );\n }\n if (projection.containerId !== containerId) {\n throw new Error(\"Served projection describes another container\");\n }\n return projection;\n}\n\n/**\n * Fetch what the batch signs for, parent-first. A named descendant the batch\n * already rematerializes is not fetched twice: its own rotation is re-planned\n * under whatever the batch carries above it. Names are a hint from the server,\n * never an authority; each is verified where it is planned.\n */\nexport async function loadRematerializationTargets(input: {\n readonly apiClient: Pick<ApiClient, \"getContainerWriterProjectionResult\">;\n readonly carriedContainerIds: readonly string[];\n readonly grants: readonly PrincipalContainerGrant[];\n}): Promise<{\n targets: RematerializationTarget[];\n retiredContainerIds: string[];\n}> {\n const grantByContainerId = new Map(\n input.grants.map((grant) => [grant.containerId, grant] as const),\n );\n const carried = [...new Set(input.carriedContainerIds)]\n .filter((containerId) => !grantByContainerId.has(containerId))\n .slice(0, MAX_ROTATION_CONTAINER_REKEYS);\n const targets: RematerializationTarget[] = [];\n const retiredContainerIds: string[] = [];\n for (const containerId of [...grantByContainerId.keys(), ...carried].sort(\n (left, right) => left.localeCompare(right),\n )) {\n const grantRow = grantByContainerId.get(containerId) ?? null;\n const result = await input.apiClient.getContainerWriterProjectionResult(\n containerId,\n { reportErrors: false },\n );\n if (!result.ok) {\n // This is only a planning hint. Keep the signed grant intact; the API\n // independently requires every live grant under the organization lock.\n if (\n grantRow &&\n result.kind === \"http\" &&\n isContainerNotFoundFailure(result)\n ) {\n retiredContainerIds.push(containerId);\n continue;\n }\n result.report();\n throw new Error(\n `Container ${containerId} could not be prepared for principal rotation: ${result.message}`,\n );\n }\n if (result.data.containerId !== containerId)\n throw new Error(\"Served projection describes another container\");\n targets.push({ grantRow, projection: result.data });\n }\n return {\n targets: orderRematerializationsParentFirst(targets),\n retiredContainerIds,\n };\n}\n\n/** An in-memory cache holding only the policy this batch is about to commit. */\nexport function seededPrincipalPolicyCache(\n nextPolicy: PrincipalPolicyCurrentEvidence,\n): PrincipalPolicyCache {\n return new Map([\n [\n referencedPrincipalPolicyKey({\n keyEpoch: nextPolicy.keyEpoch,\n keyFingerprint: nextPolicy.state.keyFingerprint,\n principalId: nextPolicy.principalId,\n principalType: nextPolicy.principalType,\n stateHash: nextPolicy.stateHash,\n version: nextPolicy.version,\n }),\n nextPolicy,\n ],\n ]);\n}\n"]}
1
+ {"version":3,"file":"principalContainerRematerializationTargets.js","sourceRoot":"","sources":["principalContainerRematerializationTargets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport { isContainerNotFoundFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type {\n MaterializedContainerRekeyPlan,\n MaterializedContainerRevokePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCache } from \"../../../data/keyingProjectionVerification\";\nimport { referencedPrincipalPolicyKey } from \"../../../data/keyingProjectionVerification/principalPolicy/principalPolicyCache\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SpeculativePath } from \"../../containers/child/rekey/carriedDescendantRekeys\";\n\nexport type MaterializedPrincipalContainerMutationPlan =\n | MaterializedContainerRekeyPlan\n | MaterializedContainerRevokePlan\n | MaterializedContainerSharePlan;\n\n/** Authored paths for chaining plans; only rotated is null for a grant. */\nexport interface PlannedRematerialization {\n /** The authored successor for either a grant or a rotation. */\n readonly nextProjection?: ContainerWriterProjectionResponse | undefined;\n /** A descendant rekey carried for a rotation above, not a rematerialization. */\n readonly carried: boolean;\n readonly planned: MaterializedPrincipalContainerMutationPlan;\n readonly rotated: SpeculativePath | null;\n}\n\n/**\n * One container a batch signs for: a group grant it rematerializes, or a\n * descendant rekey it carries for a rotation above (`grantRow` null).\n */\nexport interface RematerializationTarget {\n readonly grantRow: PrincipalContainerGrant | null;\n readonly projection: ContainerWriterProjectionResponse;\n}\n\n/**\n * Order a batch parent-first, by served depth. A group granted on a container\n * and on one of its descendants rotates both, and the lower rotation must be\n * signed against the epoch the upper one mints in this same batch, or it\n * extends a head the batch itself retires. A carried rekey sits below the\n * rotation it rides for the same reason. Ties keep id order for stability.\n */\nexport function orderRematerializationsParentFirst<\n T extends {\n readonly projection: {\n readonly containerId: string;\n readonly path: readonly unknown[];\n };\n },\n>(batch: readonly T[]): T[] {\n return [...batch].sort(\n (left, right) =>\n left.projection.path.length - right.projection.path.length ||\n left.projection.containerId.localeCompare(right.projection.containerId),\n );\n}\n\ninterface ProjectionApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\n/** The served projection of a container the batch will sign for. */\nexport async function loadServedProjection(\n apiClient: ProjectionApi,\n containerId: string,\n): Promise<ContainerWriterProjectionResponse> {\n const projection = await apiClient.getContainerWriterProjection(containerId);\n if (!projection) {\n throw new Error(\n `Container ${containerId} could not be prepared for principal rotation`,\n );\n }\n if (projection.containerId !== containerId) {\n throw new Error(\"Served projection describes another container\");\n }\n return projection;\n}\n\n/**\n * Fetch what the batch signs for, parent-first. A named descendant the batch\n * already rematerializes is not fetched twice: its own rotation is re-planned\n * under whatever the batch carries above it. Names are a hint from the server,\n * never an authority; each is verified where it is planned.\n */\nexport async function loadRematerializationTargets(input: {\n readonly apiClient: Pick<ApiClient, \"getContainerWriterProjectionResult\">;\n readonly carriedContainerIds: readonly string[];\n readonly grants: readonly PrincipalContainerGrant[];\n}): Promise<{\n targets: RematerializationTarget[];\n retiredContainerIds: string[];\n}> {\n const grantByContainerId = new Map(\n input.grants.map((grant) => [grant.containerId, grant] as const),\n );\n const carried = [...new Set(input.carriedContainerIds)]\n .filter((containerId) => !grantByContainerId.has(containerId))\n .slice(0, MAX_ROTATION_CONTAINER_REKEYS);\n const targets: RematerializationTarget[] = [];\n const retiredContainerIds: string[] = [];\n for (const containerId of [...grantByContainerId.keys(), ...carried].sort(\n (left, right) => left.localeCompare(right),\n )) {\n const grantRow = grantByContainerId.get(containerId) ?? null;\n const result = await input.apiClient.getContainerWriterProjectionResult(\n containerId,\n { reportErrors: false },\n );\n if (!result.ok) {\n // This is only a planning hint. Keep the signed grant intact; the API\n // independently requires every live grant under the organization lock.\n if (\n grantRow &&\n result.kind === \"http\" &&\n isContainerNotFoundFailure(result)\n ) {\n retiredContainerIds.push(containerId);\n continue;\n }\n result.report();\n throw new Error(\n `Container ${containerId} could not be prepared for principal rotation: ${result.message}`,\n );\n }\n if (result.data.containerId !== containerId)\n throw new Error(\"Served projection describes another container\");\n targets.push({ grantRow, projection: result.data });\n }\n return {\n targets: orderRematerializationsParentFirst(targets),\n retiredContainerIds,\n };\n}\n\n/** An in-memory cache holding only the policy this batch is about to commit. */\nexport function seededPrincipalPolicyCache(\n nextPolicy: PrincipalPolicyCurrentEvidence,\n): PrincipalPolicyCache {\n return new Map([\n [\n referencedPrincipalPolicyKey({\n keyEpoch: nextPolicy.keyEpoch,\n keyFingerprint: nextPolicy.state.keyFingerprint,\n principalId: nextPolicy.principalId,\n principalType: nextPolicy.principalType,\n stateHash: nextPolicy.stateHash,\n version: nextPolicy.version,\n }),\n nextPolicy,\n ],\n ]);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { isProjectionVerificationCancelledError } from "../../../data/keyingProjectionVerification/index.js";
2
2
  import { reportAndRethrowKeyingVerificationError, rethrowKeyingVerificationError, } from "../../../data/keyingProjectionVerification/error.js";
3
- import { dedupeReferencedPrincipalStates } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
3
+ import { dedupeReferencedPrincipalStates } from "../../../data/keyingProjectionVerification/principalPolicy/principalPolicyCache.js";
4
4
  import { loadPrincipalPolicyCheckpoint } from "../../../data/persistence/keyingCheckpointPersistence.js";
5
5
  import { ensurePrincipalPolicyTables } from "../../../data/persistence/principalPolicyPersistence.js";
6
6
  import { loadPrincipalPolicyBundleForReference } from "../../../data/persistence/principalPolicyReferencePersistence.js";