@tearleads/client-sdk 0.1.15 → 0.1.17

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 (244) hide show
  1. package/client/Tearleads.d.ts +2 -0
  2. package/client/Tearleads.js +1 -0
  3. package/client/Tearleads.js.map +1 -1
  4. package/client/index.d.ts +1 -1
  5. package/client/index.js.map +1 -1
  6. package/client/organizations/currentPrincipalMutations.js +96 -0
  7. package/client/organizations/currentPrincipalMutations.js.map +1 -0
  8. package/client/organizations/index.d.ts +4 -42
  9. package/client/organizations/index.js +17 -3
  10. package/client/organizations/index.js.map +1 -1
  11. package/client/organizations/organizationGroupHistory.js +44 -0
  12. package/client/organizations/organizationGroupHistory.js.map +1 -0
  13. package/client/organizations/organizationGroupNameHydration.js +14 -1
  14. package/client/organizations/organizationGroupNameHydration.js.map +1 -1
  15. package/client/organizations/organizationGroupPresentation.d.ts +1 -0
  16. package/client/organizations/organizationGroupPresentation.js +16 -2
  17. package/client/organizations/organizationGroupPresentation.js.map +1 -1
  18. package/client/organizations/organizationReadModels.d.ts +1 -1
  19. package/client/organizations/organizationReadModels.js +11 -1
  20. package/client/organizations/organizationReadModels.js.map +1 -1
  21. package/client/organizations/organizationsTypes.d.ts +50 -0
  22. package/client/organizations/organizationsTypes.js +2 -0
  23. package/client/organizations/organizationsTypes.js.map +1 -0
  24. package/client/organizations/principalContainerMutations.js +2 -0
  25. package/client/organizations/principalContainerMutations.js.map +1 -1
  26. package/client/organizations/principalMutationRecovery.d.ts +16 -0
  27. package/client/organizations/principalMutationRecovery.js +23 -0
  28. package/client/organizations/principalMutationRecovery.js.map +1 -0
  29. package/client/organizations/principalMutationScope.js +7 -2
  30. package/client/organizations/principalMutationScope.js.map +1 -1
  31. package/client/organizations/principalMutations.d.ts +4 -308
  32. package/client/organizations/principalMutations.js +165 -87
  33. package/client/organizations/principalMutations.js.map +1 -1
  34. package/client/principalMutationApi.d.ts +24 -0
  35. package/client/principalMutationApi.js +108 -0
  36. package/client/principalMutationApi.js.map +1 -0
  37. package/client/principalMutationDeadline.js +23 -0
  38. package/client/principalMutationDeadline.js.map +1 -0
  39. package/client/workflowRuntime.d.ts +3 -1
  40. package/client/workflowRuntime.js +44 -5
  41. package/client/workflowRuntime.js.map +1 -1
  42. package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +27 -0
  43. package/data/persistence/principalCurrentAcknowledgementPersistence.js +116 -0
  44. package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -0
  45. package/data/persistence/principalGrantRetirementPersistence.d.ts +3 -3
  46. package/data/persistence/principalGrantRetirementPersistence.js +4 -1
  47. package/data/persistence/principalGrantRetirementPersistence.js.map +1 -1
  48. package/data/persistence/principalKeyEnvelopeCandidates.js +12 -1
  49. package/data/persistence/principalKeyEnvelopeCandidates.js.map +1 -1
  50. package/data/persistence/principalMutationJournalPersistence.d.ts +19 -0
  51. package/data/persistence/principalMutationJournalPersistence.js +53 -0
  52. package/data/persistence/principalMutationJournalPersistence.js.map +1 -0
  53. package/data/persistence/verifiedPrincipalPolicyBundle.js +7 -51
  54. package/data/persistence/verifiedPrincipalPolicyBundle.js.map +1 -1
  55. package/data/persistence/verifiedPrincipalPolicyCurrent.js +56 -0
  56. package/data/persistence/verifiedPrincipalPolicyCurrent.js.map +1 -0
  57. package/data/principals/currentPolicyReferenceResolver.js +2 -0
  58. package/data/principals/currentPolicyReferenceResolver.js.map +1 -0
  59. package/data/principals/principalHistoryScopeProtection.js +23 -0
  60. package/data/principals/principalHistoryScopeProtection.js.map +1 -0
  61. package/data/principals/principalMutationJournal.d.ts +26 -0
  62. package/data/principals/principalMutationJournal.js +90 -0
  63. package/data/principals/principalMutationJournal.js.map +1 -0
  64. package/data/principals/principalMutationJournalRecord.d.ts +8 -0
  65. package/data/principals/principalMutationJournalRecord.js +25 -0
  66. package/data/principals/principalMutationJournalRecord.js.map +1 -0
  67. package/data/principals/principalPolicyAdminSigners.js.map +1 -1
  68. package/data/sqlite/principalHistoryStageSchema.js +3 -0
  69. package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
  70. package/data/sqlite/principalMutationJournalSchema.d.ts +85 -0
  71. package/data/sqlite/principalMutationJournalSchema.js +13 -0
  72. package/data/sqlite/principalMutationJournalSchema.js.map +1 -0
  73. package/data/sqlite/schema.d.ts +83 -0
  74. package/data/sqlite/schema.js +3 -0
  75. package/data/sqlite/schema.js.map +1 -1
  76. package/index.d.ts +3 -3
  77. package/index.js +1 -1
  78. package/index.js.map +1 -1
  79. package/internal/crypto/index.d.ts +1 -1
  80. package/internal/crypto/index.js +1 -1
  81. package/internal/crypto/index.js.map +1 -1
  82. package/internal/crypto/keying/index.d.ts +3 -0
  83. package/internal/crypto/keying/index.js +3 -0
  84. package/internal/crypto/keying/index.js.map +1 -1
  85. package/internal/crypto/keying/principalPolicyCurrent.d.ts +1 -1
  86. package/internal/crypto/keying/principalPolicyCurrent.js +3 -3
  87. package/internal/crypto/keying/principalPolicyCurrent.js.map +1 -1
  88. package/internal/crypto/keying/principalPolicyCurrentEvidence.js +16 -0
  89. package/internal/crypto/keying/principalPolicyCurrentEvidence.js.map +1 -0
  90. package/internal/crypto/keying/principalPolicyCurrentMutation.d.ts +10 -0
  91. package/internal/crypto/keying/principalPolicyCurrentMutation.js +51 -0
  92. package/internal/crypto/keying/principalPolicyCurrentMutation.js.map +1 -0
  93. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.d.ts +8 -0
  94. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js +46 -0
  95. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js.map +1 -0
  96. package/internal/crypto/keying/principalPolicyCurrentSuccessor.d.ts +10 -0
  97. package/internal/crypto/keying/principalPolicyCurrentSuccessor.js +60 -0
  98. package/internal/crypto/keying/principalPolicyCurrentSuccessor.js.map +1 -0
  99. package/internal/crypto/keying/principalPolicyHistory.js +4 -1
  100. package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
  101. package/internal/crypto/keying/principalPolicyHistoryReferences.js +1 -1
  102. package/internal/crypto/keying/principalPolicyHistoryReferences.js.map +1 -1
  103. package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +5 -2
  104. package/internal/crypto/keying/principalPolicyHistoryTypes.js +6 -3
  105. package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
  106. package/package.json +1 -1
  107. package/workflows/containers/child/carriedDescendantRekeys.js +9 -1
  108. package/workflows/containers/child/carriedDescendantRekeys.js.map +1 -1
  109. package/workflows/containers/child/replacementPrincipalPolicyReferences.js +19 -0
  110. package/workflows/containers/child/replacementPrincipalPolicyReferences.js.map +1 -0
  111. package/workflows/containers/child/share.js +4 -0
  112. package/workflows/containers/child/share.js.map +1 -1
  113. package/workflows/containers/child/sharePrincipalPolicy.d.ts +1 -0
  114. package/workflows/containers/child/sharePrincipalPolicy.js.map +1 -1
  115. package/workflows/organizations/acknowledgedDirectoryBindings.js +18 -0
  116. package/workflows/organizations/acknowledgedDirectoryBindings.js.map +1 -0
  117. package/workflows/organizations/commitCurrentGroupPolicyMutation.js +72 -0
  118. package/workflows/organizations/commitCurrentGroupPolicyMutation.js.map +1 -0
  119. package/workflows/organizations/createCurrentOrganizationGroup.js +85 -0
  120. package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -0
  121. package/workflows/organizations/currentGroupMetadataAuthority.js +53 -0
  122. package/workflows/organizations/currentGroupMetadataAuthority.js.map +1 -0
  123. package/workflows/organizations/currentGroupMutationReferences.js +35 -0
  124. package/workflows/organizations/currentGroupMutationReferences.js.map +1 -0
  125. package/workflows/organizations/currentGroupPolicyMutationContext.js +79 -0
  126. package/workflows/organizations/currentGroupPolicyMutationContext.js.map +1 -0
  127. package/workflows/organizations/currentOrganizationAuthority.js +88 -0
  128. package/workflows/organizations/currentOrganizationAuthority.js.map +1 -0
  129. package/workflows/organizations/currentOrganizationGroupNames.js +72 -0
  130. package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -0
  131. package/workflows/organizations/currentOrganizationMutationAuthority.js +16 -0
  132. package/workflows/organizations/currentOrganizationMutationAuthority.js.map +1 -0
  133. package/workflows/organizations/currentOrganizationMutationRetention.js +53 -0
  134. package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -0
  135. package/workflows/organizations/currentPolicyMutationAcknowledgement.js +65 -0
  136. package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +1 -0
  137. package/workflows/organizations/currentPrincipalMutationLease.js +38 -0
  138. package/workflows/organizations/currentPrincipalMutationLease.js.map +1 -0
  139. package/workflows/organizations/deleteCurrentOrganizationGroup.js +35 -0
  140. package/workflows/organizations/deleteCurrentOrganizationGroup.js.map +1 -0
  141. package/workflows/organizations/deleteOrganizationGroup.d.ts +1 -0
  142. package/workflows/organizations/deleteOrganizationGroup.js +11 -0
  143. package/workflows/organizations/deleteOrganizationGroup.js.map +1 -1
  144. package/workflows/organizations/groupCreation.d.ts +1 -0
  145. package/workflows/organizations/groupCreation.js +9 -0
  146. package/workflows/organizations/groupCreation.js.map +1 -1
  147. package/workflows/organizations/groupMembershipName.d.ts +1 -1
  148. package/workflows/organizations/groupMembershipName.js.map +1 -1
  149. package/workflows/organizations/groupMetadataAccess.d.ts +2 -2
  150. package/workflows/organizations/groupMetadataAccess.js +1 -1
  151. package/workflows/organizations/groupMetadataAccess.js.map +1 -1
  152. package/workflows/organizations/groupMetadataBinding.js.map +1 -1
  153. package/workflows/organizations/groupMetadataContainerAuthority.js +2 -47
  154. package/workflows/organizations/groupMetadataContainerAuthority.js.map +1 -1
  155. package/workflows/organizations/groupMetadataRootBinding.js +51 -0
  156. package/workflows/organizations/groupMetadataRootBinding.js.map +1 -0
  157. package/workflows/organizations/groupMetadataRuntime.js +26 -10
  158. package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
  159. package/workflows/organizations/groupMutationAuthorization.js.map +1 -1
  160. package/workflows/organizations/groupNameUniqueness.js +1 -1
  161. package/workflows/organizations/groupNameUniqueness.js.map +1 -1
  162. package/workflows/organizations/groupPolicyHistoryPage.js +31 -0
  163. package/workflows/organizations/groupPolicyHistoryPage.js.map +1 -0
  164. package/workflows/organizations/groupPolicyMutationAcknowledgement.js +10 -75
  165. package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
  166. package/workflows/organizations/groupPolicyMutationContext.d.ts +23 -13
  167. package/workflows/organizations/groupPolicyMutationContext.js +2 -1
  168. package/workflows/organizations/groupPolicyMutationContext.js.map +1 -1
  169. package/workflows/organizations/groupPolicyMutationEvidence.d.ts +26 -0
  170. package/workflows/organizations/groupPolicyMutationEvidence.js +64 -0
  171. package/workflows/organizations/groupPolicyMutationEvidence.js.map +1 -0
  172. package/workflows/organizations/groupPolicyMutationHead.js.map +1 -1
  173. package/workflows/organizations/groupPolicyRequests.js +69 -63
  174. package/workflows/organizations/groupPolicyRequests.js.map +1 -1
  175. package/workflows/organizations/index.d.ts +6 -0
  176. package/workflows/organizations/index.js +5 -0
  177. package/workflows/organizations/index.js.map +1 -1
  178. package/workflows/organizations/initialPrincipalCurrentPublication.js +83 -0
  179. package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -0
  180. package/workflows/organizations/organizationGroupDirectory.js +6 -0
  181. package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
  182. package/workflows/organizations/organizationGroupNames.js +7 -0
  183. package/workflows/organizations/organizationGroupNames.js.map +1 -1
  184. package/workflows/organizations/policyHistoryTypes.d.ts +2 -0
  185. package/workflows/organizations/policyHistoryTypes.js.map +1 -1
  186. package/workflows/organizations/principalContainerRematerialization.js +12 -2
  187. package/workflows/organizations/principalContainerRematerialization.js.map +1 -1
  188. package/workflows/organizations/principalContainerRematerializationPlanning.js +1 -0
  189. package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
  190. package/workflows/organizations/principalContainerRematerializationTargets.js.map +1 -1
  191. package/workflows/organizations/principalCurrentPublicationSeal.js +51 -0
  192. package/workflows/organizations/principalCurrentPublicationSeal.js.map +1 -0
  193. package/workflows/organizations/principalMutationJournalLane.js +26 -0
  194. package/workflows/organizations/principalMutationJournalLane.js.map +1 -0
  195. package/workflows/organizations/principalMutationJournalManagement.d.ts +26 -0
  196. package/workflows/organizations/principalMutationJournalManagement.js +104 -0
  197. package/workflows/organizations/principalMutationJournalManagement.js.map +1 -0
  198. package/workflows/organizations/principalMutationJournalSession.d.ts +26 -0
  199. package/workflows/organizations/principalMutationJournalSession.js +85 -0
  200. package/workflows/organizations/principalMutationJournalSession.js.map +1 -0
  201. package/workflows/organizations/principalMutationReceipt.js +21 -0
  202. package/workflows/organizations/principalMutationReceipt.js.map +1 -0
  203. package/workflows/organizations/principalPolicyReceiptArtifacts.js +74 -0
  204. package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +1 -0
  205. package/workflows/organizations/principalPolicyRequest.d.ts +5 -4
  206. package/workflows/organizations/principalPolicyRequest.js.map +1 -1
  207. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +23 -0
  208. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +159 -0
  209. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -0
  210. package/workflows/organizations/runtimeCurrentGroupMutation.js +85 -0
  211. package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -0
  212. package/workflows/organizations/runtimeCurrentOrganizationMutation.js +48 -0
  213. package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -0
  214. package/workflows/principals/loadRecoveredPrincipalHistoryPage.d.ts +11 -0
  215. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js +120 -0
  216. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +1 -0
  217. package/workflows/principals/principalCurrentRecoveryBatch.js +14 -0
  218. package/workflows/principals/principalCurrentRecoveryBatch.js.map +1 -0
  219. package/workflows/principals/principalHistoryRecoveryReferences.js +8 -0
  220. package/workflows/principals/principalHistoryRecoveryReferences.js.map +1 -1
  221. package/workflows/principals/principalRecoveryDirectory.d.ts +1 -1
  222. package/workflows/principals/principalRecoveryDirectory.js +32 -12
  223. package/workflows/principals/principalRecoveryDirectory.js.map +1 -1
  224. package/workflows/principals/principalRecoveryDiscoveryPage.js +36 -0
  225. package/workflows/principals/principalRecoveryDiscoveryPage.js.map +1 -0
  226. package/workflows/principals/principalRecoveryLocalPreference.js +29 -0
  227. package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -0
  228. package/workflows/principals/principalRecoveryMemo.d.ts +16 -0
  229. package/workflows/principals/principalRecoveryMemo.js +88 -16
  230. package/workflows/principals/principalRecoveryMemo.js.map +1 -1
  231. package/workflows/principals/recoverCurrentOrganizationPolicy.js +33 -0
  232. package/workflows/principals/recoverCurrentOrganizationPolicy.js.map +1 -0
  233. package/workflows/principals/recoverPrincipalHistoryPage.js +30 -0
  234. package/workflows/principals/recoverPrincipalHistoryPage.js.map +1 -0
  235. package/workflows/principals/recoverPrincipalPolicyHistory.d.ts +2 -0
  236. package/workflows/principals/recoverPrincipalPolicyHistory.js +14 -2
  237. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  238. package/workflows/principals/recoverScopedPrincipalPolicyHistory.d.ts +8 -1
  239. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +30 -20
  240. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
  241. package/workflows/principals/runtimePolicyRecovery.js +36 -9
  242. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  243. package/workflows/principals/runtimePolicyWarmer.js +2 -2
  244. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
@@ -0,0 +1,116 @@
1
+ import { KeyingVerificationError, verifyPrincipalPolicyCheckpoint, } from "../../internal/crypto/index.js";
2
+ import { eq } from "drizzle-orm";
3
+ import { assertProjectionVerificationCurrent } from "../keyingProjectionVerification/types.js";
4
+ import { principalHistoryPrefixes } from "../sqlite/principalHistoryEvidenceSchema.js";
5
+ import { principalHistoryStages } from "../sqlite/principalHistoryStageSchema.js";
6
+ import { keyingCheckpointTables, principalPolicyTables, } from "../sqlite/schema.js";
7
+ import { getClientSQLitePersistenceRuntime, } from "../sqlite/sqlitePersistenceRuntime.js";
8
+ import { ensureSqlTables } from "../sqlite/sqlSchema.js";
9
+ import { loadStoredPrincipalPolicyCheckpoint, principalPolicyKey, upsertPrincipalPolicyCheckpointInTransaction, } from "./keyingCheckpointPersistence.js";
10
+ import { storePrincipalGrantRetirements } from "./principalGrantRetirementPersistence.js";
11
+ import { writePrincipalHistoryEvidencePage, } from "./principalHistoryEvidencePersistence.js";
12
+ function assertPublicationScope(entries, organizationId) {
13
+ const seen = new Set();
14
+ for (const entry of entries) {
15
+ const key = principalPolicyKey(entry.policy);
16
+ if (seen.has(key))
17
+ throw new KeyingVerificationError("duplicate_entry", "Acknowledged current batch repeats a principal");
18
+ seen.add(key);
19
+ if (entry.prefix.organizationId !== organizationId ||
20
+ entry.stage.organizationId !== organizationId ||
21
+ (entry.predecessorStage
22
+ ? entry.predecessorStage.organizationId !== organizationId ||
23
+ !entry.predecessorStage.complete ||
24
+ entry.predecessorStage.afterVersion !== entry.policy.version - 2
25
+ : entry.policy.principalType !== "group" ||
26
+ entry.policy.version !== 1 ||
27
+ entry.policy.state.prevStateHash !== null ||
28
+ entry.previousPrefixProgress !== null) ||
29
+ entry.evidence.organizationId !== organizationId ||
30
+ entry.prefix.scopeId !== entry.evidence.scopeId ||
31
+ entry.prefix.version !== entry.policy.version ||
32
+ entry.stage.afterVersion !== entry.policy.version - 1 ||
33
+ !entry.stage.complete ||
34
+ entry.stage.currentJson !== entry.prefix.currentJson)
35
+ throw new KeyingVerificationError("object_mismatch", "Acknowledged current publication is outside its scope");
36
+ }
37
+ }
38
+ async function validatePublication(tx, entry) {
39
+ const checkpoint = await loadStoredPrincipalPolicyCheckpoint(tx, entry.policy);
40
+ verifyPrincipalPolicyCheckpoint({
41
+ chain: entry.policy.retainedHistory,
42
+ currentState: entry.policy.state,
43
+ localCheckpoint: checkpoint,
44
+ });
45
+ if ((!checkpoint && entry.policy.version !== 1) ||
46
+ (checkpoint && entry.policy.version > checkpoint.version + 1))
47
+ throw new KeyingVerificationError("stale_predecessor", "Acknowledged current policy must directly extend its durable checkpoint");
48
+ const [prefix] = await tx
49
+ .select()
50
+ .from(principalHistoryPrefixes)
51
+ .where(eq(principalHistoryPrefixes.scopeId, entry.prefix.scopeId))
52
+ .limit(1);
53
+ if ((prefix?.progress ?? null) !== entry.previousPrefixProgress)
54
+ throw new KeyingVerificationError("stale_predecessor", "Authenticated principal prefix changed before acknowledgement");
55
+ }
56
+ /** Store current artifacts and resumable progress in the same transaction as their pins. */
57
+ export async function persistAcknowledgedPrincipalCurrents(input) {
58
+ const entries = structuredClone(input.entries);
59
+ const retirements = structuredClone(input.retirements ?? []);
60
+ const organizationId = input.organizationId;
61
+ const stillCurrent = input.stillCurrent;
62
+ assertPublicationScope(entries, organizationId);
63
+ assertProjectionVerificationCurrent(stillCurrent);
64
+ await ensureSqlTables(input.execSql, [
65
+ ...principalPolicyTables,
66
+ ...keyingCheckpointTables,
67
+ ]);
68
+ const runtime = getClientSQLitePersistenceRuntime(input.execSql);
69
+ const stored = await runtime.guardedTransaction(async (tx) => {
70
+ for (const entry of entries)
71
+ await validatePublication(tx, entry);
72
+ for (const retirement of retirements) {
73
+ const policy = entries.find((entry) => entry.policy.principalId === retirement.principalId &&
74
+ entry.policy.principalType === retirement.principalType)?.policy;
75
+ if (!policy)
76
+ throw new KeyingVerificationError("object_mismatch", "Retirement must accompany its acknowledged principal");
77
+ await storePrincipalGrantRetirements(tx, { ...retirement, policy, organizationId }, entries.map((entry) => entry.policy), organizationId);
78
+ }
79
+ for (const entry of entries) {
80
+ await writePrincipalHistoryEvidencePage(tx, entry.evidence);
81
+ // A prefix-only predecessor must keep its encrypted key envelopes
82
+ // before its reusable slot is replaced by the acknowledged successor.
83
+ if (entry.predecessorStage)
84
+ await tx
85
+ .insert(principalHistoryStages)
86
+ .values(entry.predecessorStage)
87
+ .onConflictDoUpdate({
88
+ target: principalHistoryStages.id,
89
+ set: entry.predecessorStage,
90
+ setWhere: eq(principalHistoryStages.complete, false),
91
+ })
92
+ .run();
93
+ // A fully authenticated publication supersedes an in-flight stage for
94
+ // this exact head. Its other writer fails its progress CAS and resumes.
95
+ await tx
96
+ .insert(principalHistoryStages)
97
+ .values(entry.stage)
98
+ .onConflictDoUpdate({
99
+ target: principalHistoryStages.id,
100
+ set: entry.stage,
101
+ })
102
+ .run();
103
+ await tx
104
+ .insert(principalHistoryPrefixes)
105
+ .values(entry.prefix)
106
+ .onConflictDoUpdate({
107
+ target: principalHistoryPrefixes.scopeId,
108
+ set: entry.prefix,
109
+ })
110
+ .run();
111
+ await upsertPrincipalPolicyCheckpointInTransaction(tx, entry.policy.checkpoint, new Date().toISOString(), organizationId);
112
+ }
113
+ }, stillCurrent, { behavior: "immediate" });
114
+ assertProjectionVerificationCurrent(() => stored.committed);
115
+ }
116
+ //# sourceMappingURL=principalCurrentAcknowledgementPersistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalCurrentAcknowledgementPersistence.js","sourceRoot":"","sources":["principalCurrentAcknowledgementPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,+BAA+B,GAChC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,iCAAiC,GAClC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAgB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EACL,mCAAmC,EACnC,kBAAkB,EAClB,4CAA4C,GAC7C,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,uCAAuC,CAAC;AACvF,OAAO,EAEL,iCAAiC,GAClC,MAAM,uCAAuC,CAAC;AAoB/C,SAAS,sBAAsB,CAC7B,OAA2D,EAC3D,cAAsB;IAEtB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACf,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,gDAAgD,CACjD,CAAC;QACJ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IACE,KAAK,CAAC,MAAM,CAAC,cAAc,KAAK,cAAc;YAC9C,KAAK,CAAC,KAAK,CAAC,cAAc,KAAK,cAAc;YAC7C,CAAC,KAAK,CAAC,gBAAgB;gBACrB,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,cAAc,KAAK,cAAc;oBACxD,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ;oBAChC,KAAK,CAAC,gBAAgB,CAAC,YAAY,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC;gBAClE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,KAAK,OAAO;oBACtC,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC;oBAC1B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI;oBACzC,KAAK,CAAC,sBAAsB,KAAK,IAAI,CAAC;YAC1C,KAAK,CAAC,QAAQ,CAAC,cAAc,KAAK,cAAc;YAChD,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,QAAQ,CAAC,OAAO;YAC/C,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO;YAC7C,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC;YACrD,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ;YACrB,KAAK,CAAC,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW;YAEpD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,uDAAuD,CACxD,CAAC;IACN,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,EAAgC,EAChC,KAA8C;IAE9C,MAAM,UAAU,GAAG,MAAM,mCAAmC,CAC1D,EAAE,EACF,KAAK,CAAC,MAAM,CACb,CAAC;IACF,+BAA+B,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe;QACnC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK;QAChC,eAAe,EAAE,UAAU;KAC5B,CAAC,CAAC;IACH,IACE,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC;QAC3C,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;QAE7D,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,EACnB,yEAAyE,CAC1E,CAAC;IACJ,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;SACtB,MAAM,EAAE;SACR,IAAI,CAAC,wBAAwB,CAAC;SAC9B,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SACjE,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,sBAAsB;QAC7D,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,EACnB,+DAA+D,CAChE,CAAC;AACN,CAAC;AAED,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAQ1D;IACC,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC5C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,sBAAsB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAChD,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE;QACnC,GAAG,qBAAqB;QACxB,GAAG,sBAAsB;KAC1B,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAC7C,KAAK,EAAE,EAAE,EAAE,EAAE;QACX,KAAK,MAAM,KAAK,IAAI,OAAO;YAAE,MAAM,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAClE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,MAAM,CAAC,WAAW,KAAK,UAAU,CAAC,WAAW;gBACnD,KAAK,CAAC,MAAM,CAAC,aAAa,KAAK,UAAU,CAAC,aAAa,CAC1D,EAAE,MAAM,CAAC;YACV,IAAI,CAAC,MAAM;gBACT,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,sDAAsD,CACvD,CAAC;YACJ,MAAM,8BAA8B,CAClC,EAAE,EACF,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,EACzC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EACpC,cAAc,CACf,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,iCAAiC,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5D,kEAAkE;YAClE,sEAAsE;YACtE,IAAI,KAAK,CAAC,gBAAgB;gBACxB,MAAM,EAAE;qBACL,MAAM,CAAC,sBAAsB,CAAC;qBAC9B,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC;qBAC9B,kBAAkB,CAAC;oBAClB,MAAM,EAAE,sBAAsB,CAAC,EAAE;oBACjC,GAAG,EAAE,KAAK,CAAC,gBAAgB;oBAC3B,QAAQ,EAAE,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC;iBACrD,CAAC;qBACD,GAAG,EAAE,CAAC;YACX,sEAAsE;YACtE,wEAAwE;YACxE,MAAM,EAAE;iBACL,MAAM,CAAC,sBAAsB,CAAC;iBAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;iBACnB,kBAAkB,CAAC;gBAClB,MAAM,EAAE,sBAAsB,CAAC,EAAE;gBACjC,GAAG,EAAE,KAAK,CAAC,KAAK;aACjB,CAAC;iBACD,GAAG,EAAE,CAAC;YACT,MAAM,EAAE;iBACL,MAAM,CAAC,wBAAwB,CAAC;iBAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;iBACpB,kBAAkB,CAAC;gBAClB,MAAM,EAAE,wBAAwB,CAAC,OAAO;gBACxC,GAAG,EAAE,KAAK,CAAC,MAAM;aAClB,CAAC;iBACD,GAAG,EAAE,CAAC;YACT,MAAM,4CAA4C,CAChD,EAAE,EACF,KAAK,CAAC,MAAM,CAAC,UAAU,EACvB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EACxB,cAAc,CACf,CAAC;QACJ,CAAC;IACH,CAAC,EACD,YAAY,EACZ,EAAE,QAAQ,EAAE,WAAW,EAAE,CAC1B,CAAC;IACF,mCAAmC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n type VerifiedPrincipalPolicyCurrent,\n verifyPrincipalPolicyCheckpoint,\n} from \"@tearleads/crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { assertProjectionVerificationCurrent } from \"../keyingProjectionVerification/types\";\nimport { principalHistoryPrefixes } from \"../sqlite/principalHistoryEvidenceSchema\";\nimport { principalHistoryStages } from \"../sqlite/principalHistoryStageSchema\";\nimport {\n keyingCheckpointTables,\n principalPolicyTables,\n} from \"../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\nimport {\n loadStoredPrincipalPolicyCheckpoint,\n principalPolicyKey,\n upsertPrincipalPolicyCheckpointInTransaction,\n} from \"./keyingCheckpointPersistence\";\nimport { storePrincipalGrantRetirements } from \"./principalGrantRetirementPersistence\";\nimport {\n type PrincipalHistoryEvidencePage,\n writePrincipalHistoryEvidencePage,\n} from \"./principalHistoryEvidencePersistence\";\nimport type { PrincipalHistoryPrefix } from \"./principalHistoryPrefixPersistence\";\nimport type { PrincipalHistoryStage } from \"./principalHistoryStagePersistence\";\n\n/** Owned output of authenticated prefix extension and exact receipt verification. */\nexport interface AcknowledgedPrincipalCurrentPublication {\n readonly policy: VerifiedPrincipalPolicyCurrent;\n readonly prefix: PrincipalHistoryPrefix;\n readonly previousPrefixProgress: string | null;\n readonly stage: PrincipalHistoryStage;\n readonly predecessorStage: PrincipalHistoryStage | null;\n readonly evidence: PrincipalHistoryEvidencePage;\n}\n\nexport interface AcknowledgedPrincipalCurrentRetirement {\n readonly principalId: string;\n readonly principalType: VerifiedPrincipalPolicyCurrent[\"principalType\"];\n readonly containerIds: readonly string[];\n}\n\nfunction assertPublicationScope(\n entries: readonly AcknowledgedPrincipalCurrentPublication[],\n organizationId: string,\n) {\n const seen = new Set<string>();\n for (const entry of entries) {\n const key = principalPolicyKey(entry.policy);\n if (seen.has(key))\n throw new KeyingVerificationError(\n \"duplicate_entry\",\n \"Acknowledged current batch repeats a principal\",\n );\n seen.add(key);\n if (\n entry.prefix.organizationId !== organizationId ||\n entry.stage.organizationId !== organizationId ||\n (entry.predecessorStage\n ? entry.predecessorStage.organizationId !== organizationId ||\n !entry.predecessorStage.complete ||\n entry.predecessorStage.afterVersion !== entry.policy.version - 2\n : entry.policy.principalType !== \"group\" ||\n entry.policy.version !== 1 ||\n entry.policy.state.prevStateHash !== null ||\n entry.previousPrefixProgress !== null) ||\n entry.evidence.organizationId !== organizationId ||\n entry.prefix.scopeId !== entry.evidence.scopeId ||\n entry.prefix.version !== entry.policy.version ||\n entry.stage.afterVersion !== entry.policy.version - 1 ||\n !entry.stage.complete ||\n entry.stage.currentJson !== entry.prefix.currentJson\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Acknowledged current publication is outside its scope\",\n );\n }\n}\n\nasync function validatePublication(\n tx: ClientSQLiteTransactionScope,\n entry: AcknowledgedPrincipalCurrentPublication,\n) {\n const checkpoint = await loadStoredPrincipalPolicyCheckpoint(\n tx,\n entry.policy,\n );\n verifyPrincipalPolicyCheckpoint({\n chain: entry.policy.retainedHistory,\n currentState: entry.policy.state,\n localCheckpoint: checkpoint,\n });\n if (\n (!checkpoint && entry.policy.version !== 1) ||\n (checkpoint && entry.policy.version > checkpoint.version + 1)\n )\n throw new KeyingVerificationError(\n \"stale_predecessor\",\n \"Acknowledged current policy must directly extend its durable checkpoint\",\n );\n const [prefix] = await tx\n .select()\n .from(principalHistoryPrefixes)\n .where(eq(principalHistoryPrefixes.scopeId, entry.prefix.scopeId))\n .limit(1);\n if ((prefix?.progress ?? null) !== entry.previousPrefixProgress)\n throw new KeyingVerificationError(\n \"stale_predecessor\",\n \"Authenticated principal prefix changed before acknowledgement\",\n );\n}\n\n/** Store current artifacts and resumable progress in the same transaction as their pins. */\nexport async function persistAcknowledgedPrincipalCurrents(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly entries: readonly AcknowledgedPrincipalCurrentPublication[];\n readonly retirements?:\n | readonly AcknowledgedPrincipalCurrentRetirement[]\n | undefined;\n readonly stillCurrent: () => boolean;\n}): Promise<void> {\n const entries = structuredClone(input.entries);\n const retirements = structuredClone(input.retirements ?? []);\n const organizationId = input.organizationId;\n const stillCurrent = input.stillCurrent;\n assertPublicationScope(entries, organizationId);\n assertProjectionVerificationCurrent(stillCurrent);\n await ensureSqlTables(input.execSql, [\n ...principalPolicyTables,\n ...keyingCheckpointTables,\n ]);\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const stored = await runtime.guardedTransaction(\n async (tx) => {\n for (const entry of entries) await validatePublication(tx, entry);\n for (const retirement of retirements) {\n const policy = entries.find(\n (entry) =>\n entry.policy.principalId === retirement.principalId &&\n entry.policy.principalType === retirement.principalType,\n )?.policy;\n if (!policy)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retirement must accompany its acknowledged principal\",\n );\n await storePrincipalGrantRetirements(\n tx,\n { ...retirement, policy, organizationId },\n entries.map((entry) => entry.policy),\n organizationId,\n );\n }\n for (const entry of entries) {\n await writePrincipalHistoryEvidencePage(tx, entry.evidence);\n // A prefix-only predecessor must keep its encrypted key envelopes\n // before its reusable slot is replaced by the acknowledged successor.\n if (entry.predecessorStage)\n await tx\n .insert(principalHistoryStages)\n .values(entry.predecessorStage)\n .onConflictDoUpdate({\n target: principalHistoryStages.id,\n set: entry.predecessorStage,\n setWhere: eq(principalHistoryStages.complete, false),\n })\n .run();\n // A fully authenticated publication supersedes an in-flight stage for\n // this exact head. Its other writer fails its progress CAS and resumes.\n await tx\n .insert(principalHistoryStages)\n .values(entry.stage)\n .onConflictDoUpdate({\n target: principalHistoryStages.id,\n set: entry.stage,\n })\n .run();\n await tx\n .insert(principalHistoryPrefixes)\n .values(entry.prefix)\n .onConflictDoUpdate({\n target: principalHistoryPrefixes.scopeId,\n set: entry.prefix,\n })\n .run();\n await upsertPrincipalPolicyCheckpointInTransaction(\n tx,\n entry.policy.checkpoint,\n new Date().toISOString(),\n organizationId,\n );\n }\n },\n stillCurrent,\n { behavior: \"immediate\" },\n );\n assertProjectionVerificationCurrent(() => stored.committed);\n}\n"]}
@@ -1,9 +1,9 @@
1
- import { type AccessManifestCheckpoint, type VerifiedPrincipalPolicy } from "../../internal/crypto/index.js";
1
+ import { type AccessManifestCheckpoint, type VerifiedPrincipalPolicy, type VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
2
2
  import type { ClientSQLiteTransactionScope } from "../sqlite/sqlitePersistenceRuntime.js";
3
3
  export interface AcknowledgedPrincipalGrantRetirements {
4
4
  readonly containerIds: readonly string[];
5
5
  readonly organizationId: string;
6
- readonly policy: VerifiedPrincipalPolicy;
6
+ readonly policy: VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent;
7
7
  }
8
- export declare function storePrincipalGrantRetirements(tx: ClientSQLiteTransactionScope, retirement: AcknowledgedPrincipalGrantRetirements, policies: readonly VerifiedPrincipalPolicy[], organizationId: string | undefined): Promise<void>;
8
+ export declare function storePrincipalGrantRetirements(tx: ClientSQLiteTransactionScope, retirement: AcknowledgedPrincipalGrantRetirements, policies: readonly (VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent)[], organizationId: string | undefined): Promise<void>;
9
9
  export declare function assertContainerNotRetired(tx: ClientSQLiteTransactionScope, checkpoint: AccessManifestCheckpoint): Promise<void>;
@@ -7,7 +7,10 @@ export async function storePrincipalGrantRetirements(tx, retirement, policies, o
7
7
  policy.stateHash === retirement.policy.stateHash)) {
8
8
  throw new KeyingVerificationError("object_mismatch", "Retirement must accompany its acknowledged policy");
9
9
  }
10
- const previous = retirement.policy.history?.find((entry) => entry.state.stateHash === retirement.policy.state.prevStateHash);
10
+ const history = "retainedHistory" in retirement.policy
11
+ ? retirement.policy.retainedHistory
12
+ : retirement.policy.history;
13
+ const previous = history?.find((entry) => entry.state.stateHash === retirement.policy.state.prevStateHash);
11
14
  const granted = new Set([...retirement.policy.grants, ...(previous?.grants ?? [])].map((grant) => grant.containerId));
12
15
  if (retirement.organizationId !== organizationId ||
13
16
  retirement.containerIds.some((id) => !granted.has(id))) {
@@ -1 +1 @@
1
- {"version":3,"file":"principalGrantRetirementPersistence.js","sourceRoot":"","sources":["principalGrantRetirementPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AASrF,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,EAAgC,EAChC,UAAiD,EACjD,QAA4C,EAC5C,cAAkC;IAElC,IACE,CAAC,QAAQ,CAAC,IAAI,CACZ,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,WAAW,KAAK,UAAU,CAAC,MAAM,CAAC,WAAW;QACpD,MAAM,CAAC,aAAa,KAAK,UAAU,CAAC,MAAM,CAAC,aAAa;QACxD,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,MAAM,CAAC,SAAS,CACnD,EACD,CAAC;QACD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,mDAAmD,CACpD,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAC9C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAC3E,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAC5D,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAC7B,CACF,CAAC;IACF,IACE,UAAU,CAAC,cAAc,KAAK,cAAc;QAC5C,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EACtD,CAAC;QACD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,uEAAuE,CACxE,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,WAAW,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3D,MAAM,EAAE;aACL,MAAM,CAAC,yBAAyB,CAAC;aACjC,MAAM,CAAC;YACN,cAAc,EAAE,UAAU,CAAC,cAAc;YACzC,WAAW;YACX,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW;YAC1C,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,SAAS;SAC7C,CAAC;aACD,mBAAmB,EAAE;aACrB,GAAG,EAAE,CAAC;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,EAAgC,EAChC,UAAoC;IAEpC,IAAI,UAAU,CAAC,UAAU,KAAK,WAAW;QAAE,OAAO;IAClD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE;SACvB,MAAM,CAAC,EAAE,WAAW,EAAE,yBAAyB,CAAC,WAAW,EAAE,CAAC;SAC9D,IAAI,CAAC,yBAAyB,CAAC;SAC/B,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,yBAAyB,CAAC,cAAc,EAAE,UAAU,CAAC,cAAc,CAAC,EACvE,EAAE,CAAC,yBAAyB,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,CAC/D,CACF;SACA,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,OAAO;QACT,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,aAAa,UAAU,CAAC,QAAQ,wCAAwC,CACzE,CAAC;AACN,CAAC","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport { principalGrantRetirements } from \"../sqlite/principalGrantRetirementSchema\";\nimport type { ClientSQLiteTransactionScope } from \"../sqlite/sqlitePersistenceRuntime\";\n\nexport interface AcknowledgedPrincipalGrantRetirements {\n readonly containerIds: readonly string[];\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicy;\n}\n\nexport async function storePrincipalGrantRetirements(\n tx: ClientSQLiteTransactionScope,\n retirement: AcknowledgedPrincipalGrantRetirements,\n policies: readonly VerifiedPrincipalPolicy[],\n organizationId: string | undefined,\n): Promise<void> {\n if (\n !policies.some(\n (policy) =>\n policy.principalId === retirement.policy.principalId &&\n policy.principalType === retirement.policy.principalType &&\n policy.stateHash === retirement.policy.stateHash,\n )\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retirement must accompany its acknowledged policy\",\n );\n }\n const previous = retirement.policy.history?.find(\n (entry) => entry.state.stateHash === retirement.policy.state.prevStateHash,\n );\n const granted = new Set(\n [...retirement.policy.grants, ...(previous?.grants ?? [])].map(\n (grant) => grant.containerId,\n ),\n );\n if (\n retirement.organizationId !== organizationId ||\n retirement.containerIds.some((id) => !granted.has(id))\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retirement must match the acknowledged organization and signed grants\",\n );\n }\n for (const containerId of new Set(retirement.containerIds)) {\n await tx\n .insert(principalGrantRetirements)\n .values({\n organizationId: retirement.organizationId,\n containerId,\n principalId: retirement.policy.principalId,\n policyStateHash: retirement.policy.stateHash,\n })\n .onConflictDoNothing()\n .run();\n }\n}\n\nexport async function assertContainerNotRetired(\n tx: ClientSQLiteTransactionScope,\n checkpoint: AccessManifestCheckpoint,\n): Promise<void> {\n if (checkpoint.objectKind !== \"container\") return;\n const [retired] = await tx\n .select({ containerId: principalGrantRetirements.containerId })\n .from(principalGrantRetirements)\n .where(\n and(\n eq(principalGrantRetirements.organizationId, checkpoint.organizationId),\n eq(principalGrantRetirements.containerId, checkpoint.objectId),\n ),\n )\n .limit(1);\n if (retired)\n throw new KeyingVerificationError(\n \"equivocation\",\n `Container ${checkpoint.objectId} was retired during principal rotation`,\n );\n}\n"]}
1
+ {"version":3,"file":"principalGrantRetirementPersistence.js","sourceRoot":"","sources":["principalGrantRetirementPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport { principalGrantRetirements } from \"../sqlite/principalGrantRetirementSchema\";\nimport type { ClientSQLiteTransactionScope } from \"../sqlite/sqlitePersistenceRuntime\";\n\nexport interface AcknowledgedPrincipalGrantRetirements {\n readonly containerIds: readonly string[];\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent;\n}\n\nexport async function storePrincipalGrantRetirements(\n tx: ClientSQLiteTransactionScope,\n retirement: AcknowledgedPrincipalGrantRetirements,\n policies: readonly (\n | VerifiedPrincipalPolicy\n | VerifiedPrincipalPolicyCurrent\n )[],\n organizationId: string | undefined,\n): Promise<void> {\n if (\n !policies.some(\n (policy) =>\n policy.principalId === retirement.policy.principalId &&\n policy.principalType === retirement.policy.principalType &&\n policy.stateHash === retirement.policy.stateHash,\n )\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retirement must accompany its acknowledged policy\",\n );\n }\n const history =\n \"retainedHistory\" in retirement.policy\n ? retirement.policy.retainedHistory\n : retirement.policy.history;\n const previous = history?.find(\n (entry) => entry.state.stateHash === retirement.policy.state.prevStateHash,\n );\n const granted = new Set(\n [...retirement.policy.grants, ...(previous?.grants ?? [])].map(\n (grant) => grant.containerId,\n ),\n );\n if (\n retirement.organizationId !== organizationId ||\n retirement.containerIds.some((id) => !granted.has(id))\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Retirement must match the acknowledged organization and signed grants\",\n );\n }\n for (const containerId of new Set(retirement.containerIds)) {\n await tx\n .insert(principalGrantRetirements)\n .values({\n organizationId: retirement.organizationId,\n containerId,\n principalId: retirement.policy.principalId,\n policyStateHash: retirement.policy.stateHash,\n })\n .onConflictDoNothing()\n .run();\n }\n}\n\nexport async function assertContainerNotRetired(\n tx: ClientSQLiteTransactionScope,\n checkpoint: AccessManifestCheckpoint,\n): Promise<void> {\n if (checkpoint.objectKind !== \"container\") return;\n const [retired] = await tx\n .select({ containerId: principalGrantRetirements.containerId })\n .from(principalGrantRetirements)\n .where(\n and(\n eq(principalGrantRetirements.organizationId, checkpoint.organizationId),\n eq(principalGrantRetirements.containerId, checkpoint.objectId),\n ),\n )\n .limit(1);\n if (retired)\n throw new KeyingVerificationError(\n \"equivocation\",\n `Container ${checkpoint.objectId} was retired during principal rotation`,\n );\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { isCurrentPrincipalMemberEnvelopesResponse, } from "../../internal/validators/response/index.js";
2
- import { desc, eq, sql } from "drizzle-orm";
2
+ import { and, desc, eq, sql } from "drizzle-orm";
3
3
  import { principalHistoryEvidenceTables, principalHistoryPrefixes, } from "../sqlite/principalHistoryEvidenceSchema.js";
4
+ import { principalHistoryStages } from "../sqlite/principalHistoryStageSchema.js";
4
5
  import { principalCurrentFingerprintJson, principalStateFingerprintJson, } from "../sqlite/principalKeyFingerprintJson.js";
5
6
  import { principalPolicies, principalPolicyBundleHistory, } from "../sqlite/principalPolicySchema.js";
6
7
  import { principalPolicyTables } from "../sqlite/schema.js";
@@ -41,6 +42,16 @@ export async function loadPrincipalKeyEnvelopeCandidates(execSql, fingerprints)
41
42
  .limit(1);
42
43
  if (prefix)
43
44
  encoded.push(prefix.envelopes);
45
+ const [stage] = await db
46
+ .select({
47
+ envelopes: sql `json_extract(${principalHistoryStages.currentJson}, '$.currentMemberEnvelopes')`,
48
+ })
49
+ .from(principalHistoryStages)
50
+ .where(and(eq(principalCurrentFingerprintJson(principalHistoryStages.currentJson), fingerprint), eq(principalHistoryStages.complete, true)))
51
+ .orderBy(desc(principalHistoryStages.afterVersion))
52
+ .limit(1);
53
+ if (stage)
54
+ encoded.push(stage.envelopes);
44
55
  for (const json of encoded) {
45
56
  let envelopes;
46
57
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"principalKeyEnvelopeCandidates.js","sourceRoot":"","sources":["principalKeyEnvelopeCandidates.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,yCAAyC,GAC1C,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,8BAA8B,EAC9B,wBAAwB,GACzB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,GAC9B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAgB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAYpE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,OAAgB,EAChB,YAA+B;IAE/B,MAAM,eAAe,CAAC,OAAO,EAAE;QAC7B,GAAG,qBAAqB;QACxB,GAAG,8BAA8B;KAClC,CAAC,CAAC;IACH,MAAM,EAAE,EAAE,EAAE,GAAG,iCAAiC,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAoC,EAAE,CAAC;IACvD,KAAK,MAAM,WAAW,IAAI,IAAI,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,CAAC,iBAAiB,EAAE,4BAA4B,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE;iBACnB,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,0BAA0B,EAAE,CAAC;iBACvD,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CACJ,EAAE,CACA,6BAA6B,CAAC,KAAK,CAAC,gBAAgB,CAAC,EACrD,WAAW,CACZ,CACF;iBACA,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;iBAC9B,KAAK,CAAC,CAAC,CAAC,CAAC;YACZ,IAAI,GAAG;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;aACtB,MAAM,CAAC;YACN,SAAS,EAAE,GAAG,CAAQ,gBAAgB,wBAAwB,CAAC,WAAW,+BAA+B;SAC1G,CAAC;aACD,IAAI,CAAC,wBAAwB,CAAC;aAC9B,KAAK,CACJ,EAAE,CACA,+BAA+B,CAAC,wBAAwB,CAAC,WAAW,CAAC,EACrE,WAAW,CACZ,CACF;aACA,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;aAC/C,KAAK,CAAC,CAAC,CAAC,CAAC;QACZ,IAAI,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,SAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC,yCAAyC,CAAC,SAAS,CAAC;gBAAE,SAAS;YACpE,UAAU,CAAC,IAAI,CAAC;gBACd,YAAY,EAAE;oBACZ,aAAa,EAAE,SAAS,CAAC,aAAa;oBACtC,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,cAAc,EAAE,WAAW;iBAC5B;gBACD,sBAAsB,EAAE,SAAS;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import {\n type CurrentPrincipalMemberEnvelopesResponse,\n isCurrentPrincipalMemberEnvelopesResponse,\n} from \"@tearleads/validators/response\";\nimport { desc, eq, sql } from \"drizzle-orm\";\nimport {\n principalHistoryEvidenceTables,\n principalHistoryPrefixes,\n} from \"../sqlite/principalHistoryEvidenceSchema\";\nimport {\n principalCurrentFingerprintJson,\n principalStateFingerprintJson,\n} from \"../sqlite/principalKeyFingerprintJson\";\nimport {\n principalPolicies,\n principalPolicyBundleHistory,\n} from \"../sqlite/principalPolicySchema\";\nimport { principalPolicyTables } from \"../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\n\nexport interface PrincipalKeyEnvelopeCandidate {\n readonly currentState: {\n readonly principalType: \"group\" | \"organization\";\n readonly principalId: string;\n readonly stateHash: string;\n readonly keyFingerprint: string;\n };\n readonly currentMemberEnvelopes: CurrentPrincipalMemberEnvelopesResponse;\n}\n\n/**\n * Untrusted encrypted key candidates, never authorization evidence. The actual\n * private key must open the requested recipient wrap; the projection verifier\n * separately checks the signed KEK material identity and all policy authority.\n * Read only envelopes for the requested fingerprints, never signed histories.\n */\nexport async function loadPrincipalKeyEnvelopeCandidates(\n execSql: ExecSql,\n fingerprints: readonly string[],\n): Promise<PrincipalKeyEnvelopeCandidate[]> {\n await ensureSqlTables(execSql, [\n ...principalPolicyTables,\n ...principalHistoryEvidenceTables,\n ]);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const candidates: PrincipalKeyEnvelopeCandidate[] = [];\n for (const fingerprint of new Set(fingerprints)) {\n const encoded: string[] = [];\n for (const table of [principalPolicies, principalPolicyBundleHistory]) {\n const [row] = await db\n .select({ envelopes: table.currentMemberEnvelopesJson })\n .from(table)\n .where(\n eq(\n principalStateFingerprintJson(table.currentStateJson),\n fingerprint,\n ),\n )\n .orderBy(desc(table.updatedAt))\n .limit(1);\n if (row) encoded.push(row.envelopes);\n }\n const [prefix] = await db\n .select({\n envelopes: sql<string>`json_extract(${principalHistoryPrefixes.currentJson}, '$.currentMemberEnvelopes')`,\n })\n .from(principalHistoryPrefixes)\n .where(\n eq(\n principalCurrentFingerprintJson(principalHistoryPrefixes.currentJson),\n fingerprint,\n ),\n )\n .orderBy(desc(principalHistoryPrefixes.version))\n .limit(1);\n if (prefix) encoded.push(prefix.envelopes);\n for (const json of encoded) {\n let envelopes: unknown;\n try {\n envelopes = JSON.parse(json);\n } catch {\n continue;\n }\n if (!isCurrentPrincipalMemberEnvelopesResponse(envelopes)) continue;\n candidates.push({\n currentState: {\n principalType: envelopes.principalType,\n principalId: envelopes.principalId,\n stateHash: envelopes.stateHash,\n keyFingerprint: fingerprint,\n },\n currentMemberEnvelopes: envelopes,\n });\n }\n }\n return candidates;\n}\n"]}
1
+ {"version":3,"file":"principalKeyEnvelopeCandidates.js","sourceRoot":"","sources":["principalKeyEnvelopeCandidates.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type CurrentPrincipalMemberEnvelopesResponse,\n isCurrentPrincipalMemberEnvelopesResponse,\n} from \"@tearleads/validators/response\";\nimport { and, desc, eq, sql } from \"drizzle-orm\";\nimport {\n principalHistoryEvidenceTables,\n principalHistoryPrefixes,\n} from \"../sqlite/principalHistoryEvidenceSchema\";\nimport { principalHistoryStages } from \"../sqlite/principalHistoryStageSchema\";\nimport {\n principalCurrentFingerprintJson,\n principalStateFingerprintJson,\n} from \"../sqlite/principalKeyFingerprintJson\";\nimport {\n principalPolicies,\n principalPolicyBundleHistory,\n} from \"../sqlite/principalPolicySchema\";\nimport { principalPolicyTables } from \"../sqlite/schema\";\nimport { getClientSQLitePersistenceRuntime } from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\n\nexport interface PrincipalKeyEnvelopeCandidate {\n readonly currentState: {\n readonly principalType: \"group\" | \"organization\";\n readonly principalId: string;\n readonly stateHash: string;\n readonly keyFingerprint: string;\n };\n readonly currentMemberEnvelopes: CurrentPrincipalMemberEnvelopesResponse;\n}\n\n/**\n * Untrusted encrypted key candidates, never authorization evidence. The actual\n * private key must open the requested recipient wrap; the projection verifier\n * separately checks the signed KEK material identity and all policy authority.\n * Read only envelopes for the requested fingerprints, never signed histories.\n */\nexport async function loadPrincipalKeyEnvelopeCandidates(\n execSql: ExecSql,\n fingerprints: readonly string[],\n): Promise<PrincipalKeyEnvelopeCandidate[]> {\n await ensureSqlTables(execSql, [\n ...principalPolicyTables,\n ...principalHistoryEvidenceTables,\n ]);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const candidates: PrincipalKeyEnvelopeCandidate[] = [];\n for (const fingerprint of new Set(fingerprints)) {\n const encoded: string[] = [];\n for (const table of [principalPolicies, principalPolicyBundleHistory]) {\n const [row] = await db\n .select({ envelopes: table.currentMemberEnvelopesJson })\n .from(table)\n .where(\n eq(\n principalStateFingerprintJson(table.currentStateJson),\n fingerprint,\n ),\n )\n .orderBy(desc(table.updatedAt))\n .limit(1);\n if (row) encoded.push(row.envelopes);\n }\n const [prefix] = await db\n .select({\n envelopes: sql<string>`json_extract(${principalHistoryPrefixes.currentJson}, '$.currentMemberEnvelopes')`,\n })\n .from(principalHistoryPrefixes)\n .where(\n eq(\n principalCurrentFingerprintJson(principalHistoryPrefixes.currentJson),\n fingerprint,\n ),\n )\n .orderBy(desc(principalHistoryPrefixes.version))\n .limit(1);\n if (prefix) encoded.push(prefix.envelopes);\n const [stage] = await db\n .select({\n envelopes: sql<string>`json_extract(${principalHistoryStages.currentJson}, '$.currentMemberEnvelopes')`,\n })\n .from(principalHistoryStages)\n .where(\n and(\n eq(\n principalCurrentFingerprintJson(principalHistoryStages.currentJson),\n fingerprint,\n ),\n eq(principalHistoryStages.complete, true),\n ),\n )\n .orderBy(desc(principalHistoryStages.afterVersion))\n .limit(1);\n if (stage) encoded.push(stage.envelopes);\n for (const json of encoded) {\n let envelopes: unknown;\n try {\n envelopes = JSON.parse(json);\n } catch {\n continue;\n }\n if (!isCurrentPrincipalMemberEnvelopesResponse(envelopes)) continue;\n candidates.push({\n currentState: {\n principalType: envelopes.principalType,\n principalId: envelopes.principalId,\n stateHash: envelopes.stateHash,\n keyFingerprint: fingerprint,\n },\n currentMemberEnvelopes: envelopes,\n });\n }\n }\n return candidates;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { principalMutationJournal } from "../sqlite/principalMutationJournalSchema.js";
2
+ import { type ExecSql } from "../sqlite/sqlSchema.js";
3
+ export type PrincipalMutationJournalRow = typeof principalMutationJournal.$inferSelect;
4
+ export declare class PendingPrincipalMutationError extends Error {
5
+ constructor();
6
+ }
7
+ export declare function loadPrincipalMutationJournal(execSql: ExecSql, scopeId: string): Promise<PrincipalMutationJournalRow | null>;
8
+ /** Claim the organization lane before dispatch; never overwrite unresolved work. */
9
+ export declare function claimPrincipalMutationJournal(input: {
10
+ readonly execSql: ExecSql;
11
+ readonly row: PrincipalMutationJournalRow;
12
+ readonly stillCurrent: () => boolean;
13
+ }): Promise<void>;
14
+ /** A late acknowledgement cannot retire another operation's journal entry. */
15
+ export declare function clearPrincipalMutationJournal(input: {
16
+ readonly execSql: ExecSql;
17
+ readonly row: PrincipalMutationJournalRow;
18
+ readonly stillCurrent: () => boolean;
19
+ }): Promise<boolean>;
@@ -0,0 +1,53 @@
1
+ import { and, eq } from "drizzle-orm";
2
+ import { assertProjectionVerificationCurrent } from "../keyingProjectionVerification/types.js";
3
+ import { principalMutationJournal, principalMutationJournalTables, } from "../sqlite/principalMutationJournalSchema.js";
4
+ import { getClientSQLitePersistenceRuntime } from "../sqlite/sqlitePersistenceRuntime.js";
5
+ import { ensureSqlTables } from "../sqlite/sqlSchema.js";
6
+ export class PendingPrincipalMutationError extends Error {
7
+ constructor() {
8
+ super("Resolve the pending principal mutation or explicitly abandon its retry before submitting another");
9
+ this.name = "PendingPrincipalMutationError";
10
+ }
11
+ }
12
+ export async function loadPrincipalMutationJournal(execSql, scopeId) {
13
+ await ensureSqlTables(execSql, principalMutationJournalTables);
14
+ const { db } = getClientSQLitePersistenceRuntime(execSql);
15
+ const [row] = await db
16
+ .select()
17
+ .from(principalMutationJournal)
18
+ .where(eq(principalMutationJournal.scopeId, scopeId))
19
+ .limit(1);
20
+ return row ?? null;
21
+ }
22
+ /** Claim the organization lane before dispatch; never overwrite unresolved work. */
23
+ export async function claimPrincipalMutationJournal(input) {
24
+ const row = { ...input.row };
25
+ await ensureSqlTables(input.execSql, principalMutationJournalTables);
26
+ const runtime = getClientSQLitePersistenceRuntime(input.execSql);
27
+ const result = await runtime.guardedTransaction(async (tx) => {
28
+ const [existing] = await tx
29
+ .select({ scopeId: principalMutationJournal.scopeId })
30
+ .from(principalMutationJournal)
31
+ .where(eq(principalMutationJournal.scopeId, row.scopeId))
32
+ .limit(1);
33
+ if (existing)
34
+ throw new PendingPrincipalMutationError();
35
+ await tx.insert(principalMutationJournal).values(row).run();
36
+ }, input.stillCurrent, { behavior: "immediate" });
37
+ assertProjectionVerificationCurrent(() => result.committed);
38
+ }
39
+ /** A late acknowledgement cannot retire another operation's journal entry. */
40
+ export async function clearPrincipalMutationJournal(input) {
41
+ const row = { ...input.row };
42
+ const runtime = getClientSQLitePersistenceRuntime(input.execSql);
43
+ const result = await runtime.guardedTransaction(async (tx) => {
44
+ const deleted = await tx
45
+ .delete(principalMutationJournal)
46
+ .where(and(eq(principalMutationJournal.scopeId, row.scopeId), eq(principalMutationJournal.organizationId, row.organizationId), eq(principalMutationJournal.serializedRequest, row.serializedRequest), eq(principalMutationJournal.signature, row.signature)))
47
+ .returning({ scopeId: principalMutationJournal.scopeId });
48
+ return deleted.length > 0;
49
+ }, input.stillCurrent, { behavior: "immediate" });
50
+ assertProjectionVerificationCurrent(() => result.committed);
51
+ return result.result === true;
52
+ }
53
+ //# sourceMappingURL=principalMutationJournalPersistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalMutationJournalPersistence.js","sourceRoot":"","sources":["principalMutationJournalPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { and, eq } from \"drizzle-orm\";\nimport { assertProjectionVerificationCurrent } from \"../keyingProjectionVerification/types\";\nimport {\n principalMutationJournal,\n principalMutationJournalTables,\n} from \"../sqlite/principalMutationJournalSchema\";\nimport { getClientSQLitePersistenceRuntime } from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\n\nexport type PrincipalMutationJournalRow =\n typeof principalMutationJournal.$inferSelect;\n\nexport class PendingPrincipalMutationError extends Error {\n constructor() {\n super(\n \"Resolve the pending principal mutation or explicitly abandon its retry before submitting another\",\n );\n this.name = \"PendingPrincipalMutationError\";\n }\n}\n\nexport async function loadPrincipalMutationJournal(\n execSql: ExecSql,\n scopeId: string,\n): Promise<PrincipalMutationJournalRow | null> {\n await ensureSqlTables(execSql, principalMutationJournalTables);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const [row] = await db\n .select()\n .from(principalMutationJournal)\n .where(eq(principalMutationJournal.scopeId, scopeId))\n .limit(1);\n return row ?? null;\n}\n\n/** Claim the organization lane before dispatch; never overwrite unresolved work. */\nexport async function claimPrincipalMutationJournal(input: {\n readonly execSql: ExecSql;\n readonly row: PrincipalMutationJournalRow;\n readonly stillCurrent: () => boolean;\n}): Promise<void> {\n const row = { ...input.row };\n await ensureSqlTables(input.execSql, principalMutationJournalTables);\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const result = await runtime.guardedTransaction(\n async (tx) => {\n const [existing] = await tx\n .select({ scopeId: principalMutationJournal.scopeId })\n .from(principalMutationJournal)\n .where(eq(principalMutationJournal.scopeId, row.scopeId))\n .limit(1);\n if (existing) throw new PendingPrincipalMutationError();\n await tx.insert(principalMutationJournal).values(row).run();\n },\n input.stillCurrent,\n { behavior: \"immediate\" },\n );\n assertProjectionVerificationCurrent(() => result.committed);\n}\n\n/** A late acknowledgement cannot retire another operation's journal entry. */\nexport async function clearPrincipalMutationJournal(input: {\n readonly execSql: ExecSql;\n readonly row: PrincipalMutationJournalRow;\n readonly stillCurrent: () => boolean;\n}): Promise<boolean> {\n const row = { ...input.row };\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const result = await runtime.guardedTransaction(\n async (tx) => {\n const deleted = await tx\n .delete(principalMutationJournal)\n .where(\n and(\n eq(principalMutationJournal.scopeId, row.scopeId),\n eq(principalMutationJournal.organizationId, row.organizationId),\n eq(\n principalMutationJournal.serializedRequest,\n row.serializedRequest,\n ),\n eq(principalMutationJournal.signature, row.signature),\n ),\n )\n .returning({ scopeId: principalMutationJournal.scopeId });\n return deleted.length > 0;\n },\n input.stillCurrent,\n { behavior: \"immediate\" },\n );\n assertProjectionVerificationCurrent(() => result.committed);\n return result.result === true;\n}\n"]}
@@ -1,55 +1,8 @@
1
- import { computePrincipalMemberEnvelopesRoot, computePrincipalStatePayloadCiphertextHash, KeyingVerificationError, normalizePrincipalContainerGrants, normalizePrincipalProjectionMembers, PrincipalMemberEnvelopeValidationError, } from "../../internal/crypto/index.js";
1
+ import { KeyingVerificationError, normalizePrincipalContainerGrants, normalizePrincipalProjectionMembers, } from "../../internal/crypto/index.js";
2
2
  import { canonicalKeyingJsonString } from "../keyingCanonicalJson.js";
3
- function bundleMismatch(message) {
4
- throw new KeyingVerificationError("equivocation", message);
5
- }
6
- async function memberEnvelopesRoot(bundle) {
7
- try {
8
- return await computePrincipalMemberEnvelopesRoot(bundle.currentMemberEnvelopes.envelopes);
9
- }
10
- catch (error) {
11
- if (error instanceof PrincipalMemberEnvelopeValidationError) {
12
- throw new KeyingVerificationError("invalid_shape", error.message);
13
- }
14
- throw error;
15
- }
16
- }
17
- async function assertBundlePayloadMatches(input) {
18
- const { bundle, policy } = input;
19
- const payloadHash = await computePrincipalStatePayloadCiphertextHash(bundle.currentPayload.ciphertext);
20
- const envelopesRoot = await memberEnvelopesRoot(bundle);
21
- if (bundle.currentPayload.principalType !== policy.principalType ||
22
- bundle.currentPayload.principalId !== policy.principalId ||
23
- bundle.currentPayload.stateHash !== policy.stateHash ||
24
- bundle.currentPayload.ciphertextHash !== payloadHash ||
25
- policy.state.payloadCiphertextHash !== payloadHash ||
26
- bundle.currentMemberEnvelopes.principalType !== policy.principalType ||
27
- bundle.currentMemberEnvelopes.principalId !== policy.principalId ||
28
- bundle.currentMemberEnvelopes.stateHash !== policy.stateHash ||
29
- bundle.currentMemberEnvelopes.epoch !== policy.keyEpoch ||
30
- envelopesRoot !== policy.state.memberEnvelopesRoot) {
31
- bundleMismatch("Verified principal policy bundle payload mismatch");
32
- }
33
- }
3
+ import { assertCurrentMatchesVerifiedPolicy } from "./verifiedPrincipalPolicyCurrent.js";
34
4
  export async function assertBundleMatchesVerifiedPolicy(input) {
35
5
  const { bundle, policy } = input;
36
- if (bundle.currentState.principalType !== policy.principalType ||
37
- bundle.currentState.principalId !== policy.principalId ||
38
- bundle.currentState.version !== policy.version ||
39
- bundle.currentState.keyEpoch !== policy.keyEpoch ||
40
- bundle.currentState.stateHash !== policy.stateHash ||
41
- policy.checkpoint.version !== policy.version ||
42
- policy.checkpoint.stateHash !== policy.stateHash) {
43
- bundleMismatch("Verified principal policy bundle head mismatch");
44
- }
45
- if (canonicalKeyingJsonString(bundle.currentState, "principal policy bundle state") !==
46
- canonicalKeyingJsonString(policy.state, "verified principal policy state") ||
47
- canonicalKeyingJsonString(normalizePrincipalProjectionMembers(bundle.currentProjection), "principal policy bundle projection") !==
48
- canonicalKeyingJsonString(normalizePrincipalProjectionMembers(policy.projection), "verified principal policy projection") ||
49
- canonicalKeyingJsonString(normalizePrincipalContainerGrants(bundle.currentGrants), "principal policy bundle grants") !==
50
- canonicalKeyingJsonString(normalizePrincipalContainerGrants(policy.grants), "verified principal policy grants")) {
51
- bundleMismatch("Verified principal policy bundle content mismatch");
52
- }
53
6
  const history = policy.history ?? [];
54
7
  const expectedChain = [
55
8
  ...bundle.previousStates,
@@ -70,8 +23,11 @@ export async function assertBundleMatchesVerifiedPolicy(input) {
70
23
  }));
71
24
  if (canonicalKeyingJsonString(expectedChain, "principal policy bundle history") !==
72
25
  canonicalKeyingJsonString(verifiedHistory, "verified principal policy history")) {
73
- bundleMismatch("Verified principal policy bundle history mismatch");
26
+ throw new KeyingVerificationError("equivocation", "Verified principal policy bundle history mismatch");
74
27
  }
75
- await assertBundlePayloadMatches(input);
28
+ await assertCurrentMatchesVerifiedPolicy({
29
+ current: input.bundle,
30
+ policy: input.policy,
31
+ });
76
32
  }
77
33
  //# sourceMappingURL=verifiedPrincipalPolicyBundle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verifiedPrincipalPolicyBundle.js","sourceRoot":"","sources":["verifiedPrincipalPolicyBundle.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computePrincipalMemberEnvelopesRoot,\n computePrincipalStatePayloadCiphertextHash,\n KeyingVerificationError,\n normalizePrincipalContainerGrants,\n normalizePrincipalProjectionMembers,\n PrincipalMemberEnvelopeValidationError,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../keyingCanonicalJson\";\n\nfunction bundleMismatch(message: string): never {\n throw new KeyingVerificationError(\"equivocation\", message);\n}\n\nasync function memberEnvelopesRoot(\n bundle: PrincipalPolicyBundleResponse,\n): Promise<string> {\n try {\n return await computePrincipalMemberEnvelopesRoot(\n bundle.currentMemberEnvelopes.envelopes,\n );\n } catch (error) {\n if (error instanceof PrincipalMemberEnvelopeValidationError) {\n throw new KeyingVerificationError(\"invalid_shape\", error.message);\n }\n throw error;\n }\n}\n\nasync function assertBundlePayloadMatches(input: {\n bundle: PrincipalPolicyBundleResponse;\n policy: VerifiedPrincipalPolicy;\n}): Promise<void> {\n const { bundle, policy } = input;\n const payloadHash = await computePrincipalStatePayloadCiphertextHash(\n bundle.currentPayload.ciphertext,\n );\n const envelopesRoot = await memberEnvelopesRoot(bundle);\n if (\n bundle.currentPayload.principalType !== policy.principalType ||\n bundle.currentPayload.principalId !== policy.principalId ||\n bundle.currentPayload.stateHash !== policy.stateHash ||\n bundle.currentPayload.ciphertextHash !== payloadHash ||\n policy.state.payloadCiphertextHash !== payloadHash ||\n bundle.currentMemberEnvelopes.principalType !== policy.principalType ||\n bundle.currentMemberEnvelopes.principalId !== policy.principalId ||\n bundle.currentMemberEnvelopes.stateHash !== policy.stateHash ||\n bundle.currentMemberEnvelopes.epoch !== policy.keyEpoch ||\n envelopesRoot !== policy.state.memberEnvelopesRoot\n ) {\n bundleMismatch(\"Verified principal policy bundle payload mismatch\");\n }\n}\n\nexport async function assertBundleMatchesVerifiedPolicy(input: {\n bundle: PrincipalPolicyBundleResponse;\n policy: VerifiedPrincipalPolicy;\n}): Promise<void> {\n const { bundle, policy } = input;\n if (\n bundle.currentState.principalType !== policy.principalType ||\n bundle.currentState.principalId !== policy.principalId ||\n bundle.currentState.version !== policy.version ||\n bundle.currentState.keyEpoch !== policy.keyEpoch ||\n bundle.currentState.stateHash !== policy.stateHash ||\n policy.checkpoint.version !== policy.version ||\n policy.checkpoint.stateHash !== policy.stateHash\n ) {\n bundleMismatch(\"Verified principal policy bundle head mismatch\");\n }\n if (\n canonicalKeyingJsonString(\n bundle.currentState,\n \"principal policy bundle state\",\n ) !==\n canonicalKeyingJsonString(\n policy.state,\n \"verified principal policy state\",\n ) ||\n canonicalKeyingJsonString(\n normalizePrincipalProjectionMembers(bundle.currentProjection),\n \"principal policy bundle projection\",\n ) !==\n canonicalKeyingJsonString(\n normalizePrincipalProjectionMembers(policy.projection),\n \"verified principal policy projection\",\n ) ||\n canonicalKeyingJsonString(\n normalizePrincipalContainerGrants(bundle.currentGrants),\n \"principal policy bundle grants\",\n ) !==\n canonicalKeyingJsonString(\n normalizePrincipalContainerGrants(policy.grants),\n \"verified principal policy grants\",\n )\n ) {\n bundleMismatch(\"Verified principal policy bundle content mismatch\");\n }\n\n const history = policy.history ?? [];\n const expectedChain = [\n ...bundle.previousStates,\n {\n state: bundle.currentState,\n projection: bundle.currentProjection,\n grants: bundle.currentGrants,\n },\n ].map((entry) => ({\n ...entry,\n projection: normalizePrincipalProjectionMembers(entry.projection),\n grants: normalizePrincipalContainerGrants(entry.grants),\n }));\n const verifiedHistory = history.map((entry) => ({\n ...entry,\n projection: normalizePrincipalProjectionMembers(entry.projection),\n grants: normalizePrincipalContainerGrants(entry.grants),\n }));\n if (\n canonicalKeyingJsonString(\n expectedChain,\n \"principal policy bundle history\",\n ) !==\n canonicalKeyingJsonString(\n verifiedHistory,\n \"verified principal policy history\",\n )\n ) {\n bundleMismatch(\"Verified principal policy bundle history mismatch\");\n }\n await assertBundlePayloadMatches(input);\n}\n"]}
1
+ {"version":3,"file":"verifiedPrincipalPolicyBundle.js","sourceRoot":"","sources":["verifiedPrincipalPolicyBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,iCAAiC,EACjC,mCAAmC,GAEpC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,KAGvD;IACC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACrC,MAAM,aAAa,GAAG;QACpB,GAAG,MAAM,CAAC,cAAc;QACxB;YACE,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,UAAU,EAAE,MAAM,CAAC,iBAAiB;YACpC,MAAM,EAAE,MAAM,CAAC,aAAa;SAC7B;KACF,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChB,GAAG,KAAK;QACR,UAAU,EAAE,mCAAmC,CAAC,KAAK,CAAC,UAAU,CAAC;QACjE,MAAM,EAAE,iCAAiC,CAAC,KAAK,CAAC,MAAM,CAAC;KACxD,CAAC,CAAC,CAAC;IACJ,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9C,GAAG,KAAK;QACR,UAAU,EAAE,mCAAmC,CAAC,KAAK,CAAC,UAAU,CAAC;QACjE,MAAM,EAAE,iCAAiC,CAAC,KAAK,CAAC,MAAM,CAAC;KACxD,CAAC,CAAC,CAAC;IACJ,IACE,yBAAyB,CACvB,aAAa,EACb,iCAAiC,CAClC;QACD,yBAAyB,CACvB,eAAe,EACf,mCAAmC,CACpC,EACD,CAAC;QACD,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,mDAAmD,CACpD,CAAC;IACJ,CAAC;IACD,MAAM,kCAAkC,CAAC;QACvC,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n normalizePrincipalContainerGrants,\n normalizePrincipalProjectionMembers,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../keyingCanonicalJson\";\nimport { assertCurrentMatchesVerifiedPolicy } from \"./verifiedPrincipalPolicyCurrent\";\n\nexport async function assertBundleMatchesVerifiedPolicy(input: {\n bundle: PrincipalPolicyBundleResponse;\n policy: VerifiedPrincipalPolicy;\n}): Promise<void> {\n const { bundle, policy } = input;\n const history = policy.history ?? [];\n const expectedChain = [\n ...bundle.previousStates,\n {\n state: bundle.currentState,\n projection: bundle.currentProjection,\n grants: bundle.currentGrants,\n },\n ].map((entry) => ({\n ...entry,\n projection: normalizePrincipalProjectionMembers(entry.projection),\n grants: normalizePrincipalContainerGrants(entry.grants),\n }));\n const verifiedHistory = history.map((entry) => ({\n ...entry,\n projection: normalizePrincipalProjectionMembers(entry.projection),\n grants: normalizePrincipalContainerGrants(entry.grants),\n }));\n if (\n canonicalKeyingJsonString(\n expectedChain,\n \"principal policy bundle history\",\n ) !==\n canonicalKeyingJsonString(\n verifiedHistory,\n \"verified principal policy history\",\n )\n ) {\n throw new KeyingVerificationError(\n \"equivocation\",\n \"Verified principal policy bundle history mismatch\",\n );\n }\n await assertCurrentMatchesVerifiedPolicy({\n current: input.bundle,\n policy: input.policy,\n });\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import { computePrincipalMemberEnvelopesRoot, computePrincipalStatePayloadCiphertextHash, KeyingVerificationError, normalizePrincipalContainerGrants, normalizePrincipalProjectionMembers, PrincipalMemberEnvelopeValidationError, } from "../../internal/crypto/index.js";
2
+ import { canonicalKeyingJsonString } from "../keyingCanonicalJson.js";
3
+ function currentMismatch(message) {
4
+ throw new KeyingVerificationError("equivocation", message);
5
+ }
6
+ async function memberEnvelopesRoot(current) {
7
+ try {
8
+ return await computePrincipalMemberEnvelopesRoot(current.currentMemberEnvelopes.envelopes);
9
+ }
10
+ catch (error) {
11
+ if (error instanceof PrincipalMemberEnvelopeValidationError) {
12
+ throw new KeyingVerificationError("invalid_shape", error.message);
13
+ }
14
+ throw error;
15
+ }
16
+ }
17
+ async function assertCurrentPayloadMatches(input) {
18
+ const { current, policy } = input;
19
+ const payloadHash = await computePrincipalStatePayloadCiphertextHash(current.currentPayload.ciphertext);
20
+ const envelopesRoot = await memberEnvelopesRoot(current);
21
+ if (current.currentPayload.principalType !== policy.principalType ||
22
+ current.currentPayload.principalId !== policy.principalId ||
23
+ current.currentPayload.stateHash !== policy.stateHash ||
24
+ current.currentPayload.ciphertextHash !== payloadHash ||
25
+ policy.state.payloadCiphertextHash !== payloadHash ||
26
+ current.currentMemberEnvelopes.principalType !== policy.principalType ||
27
+ current.currentMemberEnvelopes.principalId !== policy.principalId ||
28
+ current.currentMemberEnvelopes.stateHash !== policy.stateHash ||
29
+ current.currentMemberEnvelopes.epoch !== policy.keyEpoch ||
30
+ envelopesRoot !== policy.state.memberEnvelopesRoot) {
31
+ currentMismatch("Verified principal policy current payload mismatch");
32
+ }
33
+ }
34
+ /** Bind current wire artifacts to already verified policy evidence; never authenticate history. */
35
+ export async function assertCurrentMatchesVerifiedPolicy(input) {
36
+ const { current, policy } = input;
37
+ if (current.currentState.principalType !== policy.principalType ||
38
+ current.currentState.principalId !== policy.principalId ||
39
+ current.currentState.version !== policy.version ||
40
+ current.currentState.keyEpoch !== policy.keyEpoch ||
41
+ current.currentState.stateHash !== policy.stateHash ||
42
+ policy.checkpoint.version !== policy.version ||
43
+ policy.checkpoint.stateHash !== policy.stateHash) {
44
+ currentMismatch("Verified principal policy current head mismatch");
45
+ }
46
+ if (canonicalKeyingJsonString(current.currentState, "principal policy current state") !==
47
+ canonicalKeyingJsonString(policy.state, "verified principal policy state") ||
48
+ canonicalKeyingJsonString(normalizePrincipalProjectionMembers(current.currentProjection), "principal policy current projection") !==
49
+ canonicalKeyingJsonString(normalizePrincipalProjectionMembers(policy.projection), "verified principal policy projection") ||
50
+ canonicalKeyingJsonString(normalizePrincipalContainerGrants(current.currentGrants), "principal policy current grants") !==
51
+ canonicalKeyingJsonString(normalizePrincipalContainerGrants(policy.grants), "verified principal policy grants")) {
52
+ currentMismatch("Verified principal policy current content mismatch");
53
+ }
54
+ await assertCurrentPayloadMatches(input);
55
+ }
56
+ //# sourceMappingURL=verifiedPrincipalPolicyCurrent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifiedPrincipalPolicyCurrent.js","sourceRoot":"","sources":["verifiedPrincipalPolicyCurrent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyPageCurrent } from \"@tearleads/api-client\";\nimport {\n computePrincipalMemberEnvelopesRoot,\n computePrincipalStatePayloadCiphertextHash,\n KeyingVerificationError,\n normalizePrincipalContainerGrants,\n normalizePrincipalProjectionMembers,\n PrincipalMemberEnvelopeValidationError,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { canonicalKeyingJsonString } from \"../keyingCanonicalJson\";\n\ntype VerifiedCurrentPolicy =\n | VerifiedPrincipalPolicy\n | VerifiedPrincipalPolicyCurrent;\n\nfunction currentMismatch(message: string): never {\n throw new KeyingVerificationError(\"equivocation\", message);\n}\n\nasync function memberEnvelopesRoot(\n current: PrincipalPolicyPageCurrent,\n): Promise<string> {\n try {\n return await computePrincipalMemberEnvelopesRoot(\n current.currentMemberEnvelopes.envelopes,\n );\n } catch (error) {\n if (error instanceof PrincipalMemberEnvelopeValidationError) {\n throw new KeyingVerificationError(\"invalid_shape\", error.message);\n }\n throw error;\n }\n}\n\nasync function assertCurrentPayloadMatches(input: {\n current: PrincipalPolicyPageCurrent;\n policy: VerifiedCurrentPolicy;\n}): Promise<void> {\n const { current, policy } = input;\n const payloadHash = await computePrincipalStatePayloadCiphertextHash(\n current.currentPayload.ciphertext,\n );\n const envelopesRoot = await memberEnvelopesRoot(current);\n if (\n current.currentPayload.principalType !== policy.principalType ||\n current.currentPayload.principalId !== policy.principalId ||\n current.currentPayload.stateHash !== policy.stateHash ||\n current.currentPayload.ciphertextHash !== payloadHash ||\n policy.state.payloadCiphertextHash !== payloadHash ||\n current.currentMemberEnvelopes.principalType !== policy.principalType ||\n current.currentMemberEnvelopes.principalId !== policy.principalId ||\n current.currentMemberEnvelopes.stateHash !== policy.stateHash ||\n current.currentMemberEnvelopes.epoch !== policy.keyEpoch ||\n envelopesRoot !== policy.state.memberEnvelopesRoot\n ) {\n currentMismatch(\"Verified principal policy current payload mismatch\");\n }\n}\n\n/** Bind current wire artifacts to already verified policy evidence; never authenticate history. */\nexport async function assertCurrentMatchesVerifiedPolicy(input: {\n current: PrincipalPolicyPageCurrent;\n policy: VerifiedCurrentPolicy;\n}): Promise<void> {\n const { current, policy } = input;\n if (\n current.currentState.principalType !== policy.principalType ||\n current.currentState.principalId !== policy.principalId ||\n current.currentState.version !== policy.version ||\n current.currentState.keyEpoch !== policy.keyEpoch ||\n current.currentState.stateHash !== policy.stateHash ||\n policy.checkpoint.version !== policy.version ||\n policy.checkpoint.stateHash !== policy.stateHash\n ) {\n currentMismatch(\"Verified principal policy current head mismatch\");\n }\n if (\n canonicalKeyingJsonString(\n current.currentState,\n \"principal policy current state\",\n ) !==\n canonicalKeyingJsonString(\n policy.state,\n \"verified principal policy state\",\n ) ||\n canonicalKeyingJsonString(\n normalizePrincipalProjectionMembers(current.currentProjection),\n \"principal policy current projection\",\n ) !==\n canonicalKeyingJsonString(\n normalizePrincipalProjectionMembers(policy.projection),\n \"verified principal policy projection\",\n ) ||\n canonicalKeyingJsonString(\n normalizePrincipalContainerGrants(current.currentGrants),\n \"principal policy current grants\",\n ) !==\n canonicalKeyingJsonString(\n normalizePrincipalContainerGrants(policy.grants),\n \"verified principal policy grants\",\n )\n ) {\n currentMismatch(\"Verified principal policy current content mismatch\");\n }\n\n await assertCurrentPayloadMatches(input);\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=currentPolicyReferenceResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentPolicyReferenceResolver.js","sourceRoot":"","sources":["currentPolicyReferenceResolver.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\n\n/** Privately authenticated historical citations selected for one authored head. */\nexport type CurrentPolicyReferenceResolver = (\n current: VerifiedPrincipalPolicyCurrent,\n references: readonly ReferencedPrincipalHead[],\n) => Promise<VerifiedPrincipalPolicyCurrent>;\n"]}
@@ -0,0 +1,23 @@
1
+ import { serializeKeyingCanonicalJson, } from "../../internal/crypto/index.js";
2
+ /** Stable authenticated scopes shared by paged recovery and acknowledged extension. */
3
+ export function directoryHistoryProtection(protection) {
4
+ return {
5
+ localKey: protection.localKey,
6
+ context: serializeKeyingCanonicalJson([
7
+ "tearleads.sdk.principal-history.directory.v1",
8
+ protection.context,
9
+ ]),
10
+ };
11
+ }
12
+ export function scopedGroupHistoryProtection(protection, organizationId, adminGroupId) {
13
+ return {
14
+ localKey: protection.localKey,
15
+ context: serializeKeyingCanonicalJson([
16
+ "tearleads.sdk.principal-history.scoped-group.v1",
17
+ protection.context,
18
+ organizationId,
19
+ adminGroupId,
20
+ ]),
21
+ };
22
+ }
23
+ //# sourceMappingURL=principalHistoryScopeProtection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalHistoryScopeProtection.js","sourceRoot":"","sources":["principalHistoryScopeProtection.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAE3B,uFAAuF;AACvF,MAAM,UAAU,0BAA0B,CACxC,UAAiD;IAEjD,OAAO;QACL,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,OAAO,EAAE,4BAA4B,CAAC;YACpC,8CAA8C;YAC9C,UAAU,CAAC,OAAO;SACnB,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,UAAiD,EACjD,cAAsB,EACtB,YAAoB;IAEpB,OAAO;QACL,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,OAAO,EAAE,4BAA4B,CAAC;YACpC,iDAAiD;YACjD,UAAU,CAAC,OAAO;YAClB,cAAc;YACd,YAAY;SACb,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["import {\n type PrincipalPolicyHistoryProgressOptions,\n serializeKeyingCanonicalJson,\n} from \"@tearleads/crypto\";\n\n/** Stable authenticated scopes shared by paged recovery and acknowledged extension. */\nexport function directoryHistoryProtection(\n protection: PrincipalPolicyHistoryProgressOptions,\n) {\n return {\n localKey: protection.localKey,\n context: serializeKeyingCanonicalJson([\n \"tearleads.sdk.principal-history.directory.v1\",\n protection.context,\n ]),\n };\n}\n\nexport function scopedGroupHistoryProtection(\n protection: PrincipalPolicyHistoryProgressOptions,\n organizationId: string,\n adminGroupId: string,\n) {\n return {\n localKey: protection.localKey,\n context: serializeKeyingCanonicalJson([\n \"tearleads.sdk.principal-history.scoped-group.v1\",\n protection.context,\n organizationId,\n adminGroupId,\n ]),\n };\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import { type SigningKeyPair } from "../../internal/crypto/index.js";
2
+ import { type CommitOrganizationGroupPolicyRequest } from "../../internal/validators/request/index.js";
3
+ import type { PrincipalMutationJournalRow } from "../persistence/principalMutationJournalPersistence.js";
4
+ export interface PrincipalMutationJournalScope {
5
+ readonly identityTrustDomain: string;
6
+ readonly organizationId: string;
7
+ readonly userId: string;
8
+ readonly signingFingerprint: string;
9
+ }
10
+ export interface AuthoredPrincipalMutation {
11
+ readonly groupId: string;
12
+ readonly request: CommitOrganizationGroupPolicyRequest;
13
+ }
14
+ export declare function principalMutationJournalScopeId(scope: PrincipalMutationJournalScope): Promise<string>;
15
+ /** Sign the complete wire body, including artifacts outside policy signatures. */
16
+ export declare function sealPrincipalMutation(input: {
17
+ readonly scope: PrincipalMutationJournalScope;
18
+ readonly mutation: AuthoredPrincipalMutation;
19
+ readonly signingKeyPair: SigningKeyPair;
20
+ }): Promise<PrincipalMutationJournalRow>;
21
+ /** Authentication precedes parsing or submission; corrupt authored work is retained. */
22
+ export declare function openPrincipalMutation(input: {
23
+ readonly scope: PrincipalMutationJournalScope;
24
+ readonly row: PrincipalMutationJournalRow;
25
+ readonly signingPublicKey: Uint8Array;
26
+ }): Promise<AuthoredPrincipalMutation>;