@tearleads/client-sdk 0.1.11 → 0.1.14

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 (144) hide show
  1. package/README.md +50 -9
  2. package/client/Tearleads.d.ts +4 -0
  3. package/client/Tearleads.js +5 -0
  4. package/client/Tearleads.js.map +1 -1
  5. package/client/index.d.ts +1 -0
  6. package/client/index.js.map +1 -1
  7. package/client/principalHistoryProtection.d.ts +19 -0
  8. package/client/principalHistoryProtection.js +76 -0
  9. package/client/principalHistoryProtection.js.map +1 -0
  10. package/client/workflowRuntime.d.ts +5 -0
  11. package/client/workflowRuntime.js +34 -5
  12. package/client/workflowRuntime.js.map +1 -1
  13. package/data/containers/shared/authorAccess.d.ts +2 -2
  14. package/data/containers/shared/authorAccess.js.map +1 -1
  15. package/data/containers/shared/heldContainerHeads.js.map +1 -1
  16. package/data/containers/shared/principalPolicies.js.map +1 -1
  17. package/data/containers/shared/types.d.ts +3 -2
  18. package/data/containers/shared/types.js.map +1 -1
  19. package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +1 -1
  20. package/data/keyingProjectionVerification/checkpointContext.d.ts +4 -3
  21. package/data/keyingProjectionVerification/checkpointContext.js.map +1 -1
  22. package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
  23. package/data/keyingProjectionVerification/containerPathVerification.js.map +1 -1
  24. package/data/keyingProjectionVerification/containerProjectionVerification.d.ts +4 -3
  25. package/data/keyingProjectionVerification/containerProjectionVerification.js.map +1 -1
  26. package/data/keyingProjectionVerification/documentManifestPolicies.js.map +1 -1
  27. package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
  28. package/data/keyingProjectionVerification/documentProjectionVerification.d.ts +3 -2
  29. package/data/keyingProjectionVerification/documentProjectionVerification.js.map +1 -1
  30. package/data/keyingProjectionVerification/organizationFounderBinding.js +9 -4
  31. package/data/keyingProjectionVerification/organizationFounderBinding.js.map +1 -1
  32. package/data/keyingProjectionVerification/principalPolicyCache.js +3 -4
  33. package/data/keyingProjectionVerification/principalPolicyCache.js.map +1 -1
  34. package/data/keyingProjectionVerification/principalPolicyVerification.js +12 -2
  35. package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
  36. package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +1 -1
  37. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js +70 -0
  38. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +1 -0
  39. package/data/keyingProjectionVerification/types.d.ts +17 -2
  40. package/data/keyingProjectionVerification/types.js +12 -0
  41. package/data/keyingProjectionVerification/types.js.map +1 -1
  42. package/data/persistence/organizationFounderPersistence.js +3 -2
  43. package/data/persistence/organizationFounderPersistence.js.map +1 -1
  44. package/data/persistence/principalHistoryEvidencePersistence.js +91 -0
  45. package/data/persistence/principalHistoryEvidencePersistence.js.map +1 -0
  46. package/data/persistence/principalHistoryPrefixPersistence.js +52 -0
  47. package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -0
  48. package/data/persistence/principalHistoryStagePersistence.js +9 -2
  49. package/data/persistence/principalHistoryStagePersistence.js.map +1 -1
  50. package/data/persistence/principalKeyEnvelopeCandidates.js +67 -0
  51. package/data/persistence/principalKeyEnvelopeCandidates.js.map +1 -0
  52. package/data/principals/principalHistoryPrefixProtection.js +29 -0
  53. package/data/principals/principalHistoryPrefixProtection.js.map +1 -0
  54. package/data/principals/principalHistoryProtection.d.ts +10 -0
  55. package/data/principals/principalHistoryProtection.js +14 -0
  56. package/data/principals/principalHistoryProtection.js.map +1 -0
  57. package/data/principals/principalHistoryStageProtection.js.map +1 -1
  58. package/data/principals/principalPolicyCrypto.js +11 -21
  59. package/data/principals/principalPolicyCrypto.js.map +1 -1
  60. package/data/principals/principalPolicyEvidence.d.ts +4 -0
  61. package/data/principals/principalPolicyEvidence.js +12 -0
  62. package/data/principals/principalPolicyEvidence.js.map +1 -0
  63. package/data/sqlite/principalHistoryEvidenceSchema.js +46 -0
  64. package/data/sqlite/principalHistoryEvidenceSchema.js.map +1 -0
  65. package/data/sqlite/principalKeyFingerprintJson.js +9 -0
  66. package/data/sqlite/principalKeyFingerprintJson.js.map +1 -0
  67. package/data/sqlite/principalPolicySchema.js +4 -0
  68. package/data/sqlite/principalPolicySchema.js.map +1 -1
  69. package/data/sqlite/schema.d.ts +304 -0
  70. package/data/sqlite/schema.js +5 -0
  71. package/data/sqlite/schema.js.map +1 -1
  72. package/data/sqlite/sqlTableSchema.js +1 -1
  73. package/data/sqlite/sqlTableSchema.js.map +1 -1
  74. package/index.d.ts +3 -3
  75. package/index.js +1 -1
  76. package/index.js.map +1 -1
  77. package/internal/api-client/principalPolicyPages.d.ts +2 -0
  78. package/internal/api-client/principalPolicyPages.js +11 -2
  79. package/internal/api-client/principalPolicyPages.js.map +1 -1
  80. package/internal/crypto/index.d.ts +1 -1
  81. package/internal/crypto/index.js +1 -1
  82. package/internal/crypto/index.js.map +1 -1
  83. package/internal/crypto/keying/index.d.ts +1 -1
  84. package/internal/crypto/keying/index.js +1 -1
  85. package/internal/crypto/keying/index.js.map +1 -1
  86. package/internal/crypto/keying/principalPolicyHistoryIndex.d.ts +6 -2
  87. package/internal/crypto/keying/principalPolicyHistoryIndex.js +11 -5
  88. package/internal/crypto/keying/principalPolicyHistoryIndex.js.map +1 -1
  89. package/internal/crypto/keying/principalPolicyHistoryReferences.d.ts +2 -0
  90. package/internal/crypto/keying/principalPolicyHistoryReferences.js +19 -2
  91. package/internal/crypto/keying/principalPolicyHistoryReferences.js.map +1 -1
  92. package/package.json +4 -1
  93. package/sqlite/sqlite3-licenses.md +38 -0
  94. package/sqlite/sqlite3.wasm +0 -0
  95. package/sqlite/worker.js +4 -0
  96. package/workflows/containers/child/create.js.map +1 -1
  97. package/workflows/containers/child/move.js.map +1 -1
  98. package/workflows/containers/child/moveWraps.js.map +1 -1
  99. package/workflows/containers/child/mutationRequestCore.js.map +1 -1
  100. package/workflows/containers/child/recitePlan.js.map +1 -1
  101. package/workflows/containers/child/rekey.d.ts +3 -2
  102. package/workflows/containers/child/rekey.js.map +1 -1
  103. package/workflows/containers/child/revoke.d.ts +2 -2
  104. package/workflows/containers/child/revoke.js.map +1 -1
  105. package/workflows/containers/child/rotationPrincipalPolicies.js.map +1 -1
  106. package/workflows/containers/child/rotationWraps.js.map +1 -1
  107. package/workflows/containers/child/sharePlanCore.d.ts +11 -10
  108. package/workflows/containers/child/sharePlanCore.js.map +1 -1
  109. package/workflows/documents/linkSetAuthority.js.map +1 -1
  110. package/workflows/principals/index.d.ts +1 -0
  111. package/workflows/principals/index.js +1 -0
  112. package/workflows/principals/index.js.map +1 -1
  113. package/workflows/principals/principalHistoryRecoveryPrefix.js +65 -0
  114. package/workflows/principals/principalHistoryRecoveryPrefix.js.map +1 -0
  115. package/workflows/principals/principalHistoryRecoveryReferences.js +60 -0
  116. package/workflows/principals/principalHistoryRecoveryReferences.js.map +1 -0
  117. package/workflows/principals/principalHistoryRecoveryStage.js +38 -2
  118. package/workflows/principals/principalHistoryRecoveryStage.js.map +1 -1
  119. package/workflows/principals/principalHistoryRecoveryTypes.d.ts +9 -1
  120. package/workflows/principals/principalHistoryRecoveryTypes.js +7 -0
  121. package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
  122. package/workflows/principals/principalHistoryRecoveryVerification.js +24 -0
  123. package/workflows/principals/principalHistoryRecoveryVerification.js.map +1 -0
  124. package/workflows/principals/principalRecoveryDirectory.d.ts +10 -0
  125. package/workflows/principals/principalRecoveryDirectory.js +107 -0
  126. package/workflows/principals/principalRecoveryDirectory.js.map +1 -0
  127. package/workflows/principals/principalRecoveryMemo.js +46 -0
  128. package/workflows/principals/principalRecoveryMemo.js.map +1 -0
  129. package/workflows/principals/principalRecoveryOutage.js +40 -0
  130. package/workflows/principals/principalRecoveryOutage.js.map +1 -0
  131. package/workflows/principals/principalRecoveryQueue.js +22 -0
  132. package/workflows/principals/principalRecoveryQueue.js.map +1 -0
  133. package/workflows/principals/recoverPrincipalPolicyHistory.d.ts +1 -0
  134. package/workflows/principals/recoverPrincipalPolicyHistory.js +108 -36
  135. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  136. package/workflows/principals/recoverScopedPrincipalPolicyHistory.d.ts +13 -0
  137. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +150 -0
  138. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -0
  139. package/workflows/principals/runtimePolicyRecovery.js +65 -0
  140. package/workflows/principals/runtimePolicyRecovery.js.map +1 -0
  141. package/workflows/principals/runtimePolicyWarmer.js +5 -1
  142. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
  143. package/workflows/sync/remoteResetPrincipalScope.js +10 -0
  144. package/workflows/sync/remoteResetPrincipalScope.js.map +1 -1
@@ -1,7 +1,14 @@
1
1
  import { createPrincipalPolicyHistoryVerifier, restorePrincipalPolicyHistoryVerifier, } from "../../internal/crypto/index.js";
2
2
  import { discardPrincipalHistoryStage, loadPrincipalHistoryStage, } from "../../data/persistence/principalHistoryStagePersistence.js";
3
+ import { principalHistoryEvidenceScopeId } from "../../data/principals/principalHistoryPrefixProtection.js";
3
4
  import { parsePrincipalHistoryStageCurrent, principalHistoryStageId, principalHistoryStageProtection, } from "../../data/principals/principalHistoryStageProtection.js";
4
- export async function restorePrincipalHistoryRecoveryStage(input, historyInput) {
5
+ import { restoreReusablePrincipalHistoryPrefix } from "./principalHistoryRecoveryPrefix.js";
6
+ export async function restorePrincipalHistoryRecoveryStage(input, historyInput, useReusablePrefix = true) {
7
+ const scopeId = await principalHistoryEvidenceScopeId({
8
+ organizationId: input.organizationId,
9
+ head: input.expectedHead,
10
+ protection: input.protection,
11
+ });
5
12
  const id = await principalHistoryStageId(input.organizationId, input.expectedHead, input.protection.context, input.retainedReferences ?? []);
6
13
  const saved = await loadPrincipalHistoryStage(input.execSql, id);
7
14
  if (saved) {
@@ -9,17 +16,46 @@ export async function restorePrincipalHistoryRecoveryStage(input, historyInput)
9
16
  if (current && saved.organizationId === input.organizationId) {
10
17
  const restored = await restorePrincipalPolicyHistoryVerifier(historyInput, saved.progress, await principalHistoryStageProtection(input.protection, input.expectedHead, saved));
11
18
  if (restored.ok)
12
- return { id, verifier: restored.value, current, saved };
19
+ return {
20
+ id,
21
+ scopeId,
22
+ verifier: restored.value,
23
+ current,
24
+ saved,
25
+ complete: saved.complete,
26
+ initialAfterVersion: saved.afterVersion,
27
+ fromCache: true,
28
+ };
13
29
  }
14
30
  // Saved bytes are a disposable hint. Only a locally authenticated restore
15
31
  // can skip signed history; missing keys or changed inputs replay genesis.
16
32
  await discardPrincipalHistoryStage(input.execSql, saved, () => !input.signal?.aborted && input.stillCurrent());
17
33
  }
34
+ const prefix = useReusablePrefix
35
+ ? await restoreReusablePrincipalHistoryPrefix(input, historyInput, scopeId)
36
+ : null;
37
+ if (prefix) {
38
+ const complete = prefix.version === input.expectedHead.version;
39
+ return {
40
+ id,
41
+ scopeId,
42
+ verifier: prefix.verifier,
43
+ current: complete ? prefix.current : null,
44
+ saved: null,
45
+ complete,
46
+ initialAfterVersion: prefix.version - (complete ? 1 : 0),
47
+ fromCache: true,
48
+ };
49
+ }
18
50
  return {
19
51
  id,
52
+ scopeId,
20
53
  verifier: createPrincipalPolicyHistoryVerifier(historyInput),
21
54
  current: null,
22
55
  saved: null,
56
+ complete: false,
57
+ initialAfterVersion: 0,
58
+ fromCache: false,
23
59
  };
24
60
  }
25
61
  //# sourceMappingURL=principalHistoryRecoveryStage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"principalHistoryRecoveryStage.js","sourceRoot":"","sources":["principalHistoryRecoveryStage.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oCAAoC,EAGpC,qCAAqC,GACtC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAE1B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,uDAAuD,CAAC;AAU/D,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,KAA2C,EAC3C,YAAyC;IAEzC,MAAM,EAAE,GAAG,MAAM,uBAAuB,CACtC,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,UAAU,CAAC,OAAO,EACxB,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAC/B,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,yBAAyB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACjE,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,CAAC;QACzD,IAAI,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,MAAM,qCAAqC,CAC1D,YAAY,EACZ,KAAK,CAAC,QAAQ,EACd,MAAM,+BAA+B,CACnC,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CACN,CACF,CAAC;YACF,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC3E,CAAC;QACD,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,4BAA4B,CAChC,KAAK,CAAC,OAAO,EACb,KAAK,EACL,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,CACrD,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE;QACF,QAAQ,EAAE,oCAAoC,CAAC,YAAY,CAAC;QAC5D,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,IAAI;KACZ,CAAC;AACJ,CAAC","sourcesContent":["import type { PrincipalPolicyPageCurrent } from \"@tearleads/api-client\";\nimport {\n createPrincipalPolicyHistoryVerifier,\n type PrincipalPolicyHistoryInput,\n type PrincipalPolicyHistoryVerifier,\n restorePrincipalPolicyHistoryVerifier,\n} from \"@tearleads/crypto\";\nimport {\n discardPrincipalHistoryStage,\n loadPrincipalHistoryStage,\n type PrincipalHistoryStage,\n} from \"../../data/persistence/principalHistoryStagePersistence\";\nimport {\n parsePrincipalHistoryStageCurrent,\n principalHistoryStageId,\n principalHistoryStageProtection,\n} from \"../../data/principals/principalHistoryStageProtection\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"./principalHistoryRecoveryTypes\";\n\nexport interface PrincipalHistoryRecoveryStage {\n readonly id: string;\n readonly verifier: PrincipalPolicyHistoryVerifier;\n current: PrincipalPolicyPageCurrent | null;\n saved: PrincipalHistoryStage | null;\n}\n\nexport async function restorePrincipalHistoryRecoveryStage(\n input: RecoverPrincipalPolicyHistoryOptions,\n historyInput: PrincipalPolicyHistoryInput,\n): Promise<PrincipalHistoryRecoveryStage> {\n const id = await principalHistoryStageId(\n input.organizationId,\n input.expectedHead,\n input.protection.context,\n input.retainedReferences ?? [],\n );\n const saved = await loadPrincipalHistoryStage(input.execSql, id);\n if (saved) {\n const current = parsePrincipalHistoryStageCurrent(saved);\n if (current && saved.organizationId === input.organizationId) {\n const restored = await restorePrincipalPolicyHistoryVerifier(\n historyInput,\n saved.progress,\n await principalHistoryStageProtection(\n input.protection,\n input.expectedHead,\n saved,\n ),\n );\n if (restored.ok) return { id, verifier: restored.value, current, saved };\n }\n // Saved bytes are a disposable hint. Only a locally authenticated restore\n // can skip signed history; missing keys or changed inputs replay genesis.\n await discardPrincipalHistoryStage(\n input.execSql,\n saved,\n () => !input.signal?.aborted && input.stillCurrent(),\n );\n }\n return {\n id,\n verifier: createPrincipalPolicyHistoryVerifier(historyInput),\n current: null,\n saved: null,\n };\n}\n"]}
1
+ {"version":3,"file":"principalHistoryRecoveryStage.js","sourceRoot":"","sources":["principalHistoryRecoveryStage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyPageCurrent } from \"@tearleads/api-client\";\nimport {\n createPrincipalPolicyHistoryVerifier,\n type PrincipalPolicyHistoryInput,\n type PrincipalPolicyHistoryVerifier,\n restorePrincipalPolicyHistoryVerifier,\n} from \"@tearleads/crypto\";\nimport {\n discardPrincipalHistoryStage,\n loadPrincipalHistoryStage,\n type PrincipalHistoryStage,\n} from \"../../data/persistence/principalHistoryStagePersistence\";\nimport { principalHistoryEvidenceScopeId } from \"../../data/principals/principalHistoryPrefixProtection\";\nimport {\n parsePrincipalHistoryStageCurrent,\n principalHistoryStageId,\n principalHistoryStageProtection,\n} from \"../../data/principals/principalHistoryStageProtection\";\nimport { restoreReusablePrincipalHistoryPrefix } from \"./principalHistoryRecoveryPrefix\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"./principalHistoryRecoveryTypes\";\n\nexport interface PrincipalHistoryRecoveryStage {\n readonly id: string;\n readonly scopeId: string;\n readonly verifier: PrincipalPolicyHistoryVerifier;\n readonly initialAfterVersion: number;\n readonly fromCache: boolean;\n complete: boolean;\n current: PrincipalPolicyPageCurrent | null;\n saved: PrincipalHistoryStage | null;\n}\n\nexport async function restorePrincipalHistoryRecoveryStage(\n input: RecoverPrincipalPolicyHistoryOptions,\n historyInput: PrincipalPolicyHistoryInput,\n useReusablePrefix = true,\n): Promise<PrincipalHistoryRecoveryStage> {\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: input.organizationId,\n head: input.expectedHead,\n protection: input.protection,\n });\n const id = await principalHistoryStageId(\n input.organizationId,\n input.expectedHead,\n input.protection.context,\n input.retainedReferences ?? [],\n );\n const saved = await loadPrincipalHistoryStage(input.execSql, id);\n if (saved) {\n const current = parsePrincipalHistoryStageCurrent(saved);\n if (current && saved.organizationId === input.organizationId) {\n const restored = await restorePrincipalPolicyHistoryVerifier(\n historyInput,\n saved.progress,\n await principalHistoryStageProtection(\n input.protection,\n input.expectedHead,\n saved,\n ),\n );\n if (restored.ok)\n return {\n id,\n scopeId,\n verifier: restored.value,\n current,\n saved,\n complete: saved.complete,\n initialAfterVersion: saved.afterVersion,\n fromCache: true,\n };\n }\n // Saved bytes are a disposable hint. Only a locally authenticated restore\n // can skip signed history; missing keys or changed inputs replay genesis.\n await discardPrincipalHistoryStage(\n input.execSql,\n saved,\n () => !input.signal?.aborted && input.stillCurrent(),\n );\n }\n const prefix = useReusablePrefix\n ? await restoreReusablePrincipalHistoryPrefix(input, historyInput, scopeId)\n : null;\n if (prefix) {\n const complete = prefix.version === input.expectedHead.version;\n return {\n id,\n scopeId,\n verifier: prefix.verifier,\n current: complete ? prefix.current : null,\n saved: null,\n complete,\n initialAfterVersion: prefix.version - (complete ? 1 : 0),\n fromCache: true,\n };\n }\n return {\n id,\n scopeId,\n verifier: createPrincipalPolicyHistoryVerifier(historyInput),\n current: null,\n saved: null,\n complete: false,\n initialAfterVersion: 0,\n fromCache: false,\n };\n}\n"]}
@@ -1,15 +1,23 @@
1
1
  import type { ApiClient, PrincipalPolicyPageCurrent, RequestFailure } from "../../internal/api-client/index.js";
2
- import type { PrincipalPolicyExternalAuthority, PrincipalPolicyHistoryProgressOptions, PrincipalPolicyStateChainEntry, ReferencedPrincipalHead, VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
2
+ import { KeyingVerificationError, type PrincipalPolicyExternalAuthority, type PrincipalPolicyHistoryProgressOptions, type PrincipalPolicyStateChainEntry, type ReferencedPrincipalHead, type VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
3
3
  import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
4
4
  import type { TrustedUserIdentityResolver } from "../../data/trustedUserIdentity/index.js";
5
+ /** A locally observed race, distinct from a rejected signed predecessor. */
6
+ export declare class PrincipalHistoryRecoveryRaceError extends KeyingVerificationError {
7
+ constructor(message: string);
8
+ }
5
9
  export interface RecoverPrincipalPolicyHistoryOptions {
6
10
  readonly apiClient: Pick<ApiClient, "getPrincipalPolicyPages">;
7
11
  readonly execSql: ExecSql;
8
12
  readonly organizationId: string;
9
13
  readonly expectedHead: ReferencedPrincipalHead;
14
+ /** Only use locally authenticated completed evidence; never perform HTTP. */
15
+ readonly offline?: boolean | undefined;
10
16
  /** Device-controlled key and stable identity/trust-policy context, never supplied by the API. */
11
17
  readonly protection: PrincipalPolicyHistoryProgressOptions;
12
18
  readonly retainedReferences?: readonly ReferencedPrincipalHead[] | undefined;
19
+ /** Strict Admins mode checks every historical projection in a separate cache scope. */
20
+ readonly historyVerification?: "standard" | "direct-admins" | undefined;
13
21
  readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;
14
22
  /** Return only authority already authenticated by this client. */
15
23
  readonly loadExternalAuthority?: ((entries: readonly PrincipalPolicyStateChainEntry[]) => Promise<PrincipalPolicyExternalAuthority | undefined>) | undefined;
@@ -1,3 +1,10 @@
1
+ import { KeyingVerificationError, } from "../../internal/crypto/index.js";
2
+ /** A locally observed race, distinct from a rejected signed predecessor. */
3
+ export class PrincipalHistoryRecoveryRaceError extends KeyingVerificationError {
4
+ constructor(message) {
5
+ super("stale_predecessor", message);
6
+ }
7
+ }
1
8
  export class PrincipalPolicyHistoryReadError extends Error {
2
9
  failure;
3
10
  constructor(failure) {
@@ -1 +1 @@
1
- {"version":3,"file":"principalHistoryRecoveryTypes.js","sourceRoot":"","sources":["principalHistoryRecoveryTypes.ts"],"names":[],"mappings":"AAuCA,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACnC;IAArB,YAAqB,OAAuB;QAC1C,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QADJ,YAAO,GAAP,OAAO,CAAgB;QAE1C,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF","sourcesContent":["import type {\n ApiClient,\n PrincipalPolicyPageCurrent,\n RequestFailure,\n} from \"@tearleads/api-client\";\nimport type {\n PrincipalPolicyExternalAuthority,\n PrincipalPolicyHistoryProgressOptions,\n PrincipalPolicyStateChainEntry,\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\n\nexport interface RecoverPrincipalPolicyHistoryOptions {\n readonly apiClient: Pick<ApiClient, \"getPrincipalPolicyPages\">;\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly expectedHead: ReferencedPrincipalHead;\n /** Device-controlled key and stable identity/trust-policy context, never supplied by the API. */\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly retainedReferences?: readonly ReferencedPrincipalHead[] | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n /** Return only authority already authenticated by this client. */\n readonly loadExternalAuthority?:\n | ((\n entries: readonly PrincipalPolicyStateChainEntry[],\n ) => Promise<PrincipalPolicyExternalAuthority | undefined>)\n | undefined;\n readonly stillCurrent: () => boolean;\n readonly signal?: AbortSignal | undefined;\n}\n\nexport interface RecoveredPrincipalPolicyHistory {\n readonly current: PrincipalPolicyPageCurrent;\n readonly policy: VerifiedPrincipalPolicyCurrent;\n}\n\nexport class PrincipalPolicyHistoryReadError extends Error {\n constructor(readonly failure: RequestFailure) {\n super(failure.message);\n this.name = \"PrincipalPolicyHistoryReadError\";\n }\n}\n"]}
1
+ {"version":3,"file":"principalHistoryRecoveryTypes.js","sourceRoot":"","sources":["principalHistoryRecoveryTypes.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,uBAAuB,GAMxB,MAAM,mBAAmB,CAAC;AAI3B,4EAA4E;AAC5E,MAAM,OAAO,iCAAkC,SAAQ,uBAAuB;IAC5E,YAAY,OAAe;QACzB,KAAK,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;CACF;AA8BD,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACnC;IAArB,YAAqB,OAAuB;QAC1C,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QADJ,YAAO,GAAP,OAAO,CAAgB;QAE1C,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF","sourcesContent":["import type {\n ApiClient,\n PrincipalPolicyPageCurrent,\n RequestFailure,\n} from \"@tearleads/api-client\";\nimport {\n KeyingVerificationError,\n type PrincipalPolicyExternalAuthority,\n type PrincipalPolicyHistoryProgressOptions,\n type PrincipalPolicyStateChainEntry,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\n\n/** A locally observed race, distinct from a rejected signed predecessor. */\nexport class PrincipalHistoryRecoveryRaceError extends KeyingVerificationError {\n constructor(message: string) {\n super(\"stale_predecessor\", message);\n }\n}\n\nexport interface RecoverPrincipalPolicyHistoryOptions {\n readonly apiClient: Pick<ApiClient, \"getPrincipalPolicyPages\">;\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly expectedHead: ReferencedPrincipalHead;\n /** Only use locally authenticated completed evidence; never perform HTTP. */\n readonly offline?: boolean | undefined;\n /** Device-controlled key and stable identity/trust-policy context, never supplied by the API. */\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly retainedReferences?: readonly ReferencedPrincipalHead[] | undefined;\n /** Strict Admins mode checks every historical projection in a separate cache scope. */\n readonly historyVerification?: \"standard\" | \"direct-admins\" | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n /** Return only authority already authenticated by this client. */\n readonly loadExternalAuthority?:\n | ((\n entries: readonly PrincipalPolicyStateChainEntry[],\n ) => Promise<PrincipalPolicyExternalAuthority | undefined>)\n | undefined;\n readonly stillCurrent: () => boolean;\n readonly signal?: AbortSignal | undefined;\n}\n\nexport interface RecoveredPrincipalPolicyHistory {\n readonly current: PrincipalPolicyPageCurrent;\n readonly policy: VerifiedPrincipalPolicyCurrent;\n}\n\nexport class PrincipalPolicyHistoryReadError extends Error {\n constructor(readonly failure: RequestFailure) {\n super(failure.message);\n this.name = \"PrincipalPolicyHistoryReadError\";\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { KeyingVerificationError, serializeKeyingCanonicalJson, } from "../../internal/crypto/index.js";
2
+ export function principalHistoryVerificationContext(input) {
3
+ const mode = input.historyVerification ?? "standard";
4
+ if (mode !== "standard" && mode !== "direct-admins")
5
+ throw new KeyingVerificationError("invalid_shape", "Unknown principal history verification mode");
6
+ if (mode === "standard")
7
+ return input.protection.context;
8
+ if (input.expectedHead.principalType !== "group" ||
9
+ input.loadExternalAuthority)
10
+ throw new KeyingVerificationError("invalid_shape", "Strict Admins history requires a group without external authority fallback");
11
+ // Retire this local attestation domain whenever strict validation changes.
12
+ return serializeKeyingCanonicalJson([
13
+ "tearleads.sdk.principal-history.direct-admins.v1",
14
+ input.protection.context,
15
+ ]);
16
+ }
17
+ export function assertPrincipalHistoryVerificationMode(input, entries) {
18
+ if (input.historyVerification !== "direct-admins")
19
+ return;
20
+ if (entries.some((entry) => entry.projection.length === 0 ||
21
+ entry.projection.some((member) => member.role !== "admin")))
22
+ throw new KeyingVerificationError("invalid_shape", "Reserved Admins history must contain only direct admin users");
23
+ }
24
+ //# sourceMappingURL=principalHistoryRecoveryVerification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalHistoryRecoveryVerification.js","sourceRoot":"","sources":["principalHistoryRecoveryVerification.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAG3B,MAAM,UAAU,mCAAmC,CACjD,KAA2C;IAE3C,MAAM,IAAI,GAAG,KAAK,CAAC,mBAAmB,IAAI,UAAU,CAAC;IACrD,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,eAAe;QACjD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,6CAA6C,CAC9C,CAAC;IACJ,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;IACzD,IACE,KAAK,CAAC,YAAY,CAAC,aAAa,KAAK,OAAO;QAC5C,KAAK,CAAC,qBAAqB;QAE3B,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,4EAA4E,CAC7E,CAAC;IACJ,2EAA2E;IAC3E,OAAO,4BAA4B,CAAC;QAClC,kDAAkD;QAClD,KAAK,CAAC,UAAU,CAAC,OAAO;KACzB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sCAAsC,CACpD,KAA2C,EAC3C,OAAkD;IAElD,IAAI,KAAK,CAAC,mBAAmB,KAAK,eAAe;QAAE,OAAO;IAC1D,IACE,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAC7B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAC7D;QAED,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,8DAA8D,CAC/D,CAAC;AACN,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n type PrincipalPolicyStateChainEntry,\n serializeKeyingCanonicalJson,\n} from \"@tearleads/crypto\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"./principalHistoryRecoveryTypes\";\n\nexport function principalHistoryVerificationContext(\n input: RecoverPrincipalPolicyHistoryOptions,\n): string {\n const mode = input.historyVerification ?? \"standard\";\n if (mode !== \"standard\" && mode !== \"direct-admins\")\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Unknown principal history verification mode\",\n );\n if (mode === \"standard\") return input.protection.context;\n if (\n input.expectedHead.principalType !== \"group\" ||\n input.loadExternalAuthority\n )\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Strict Admins history requires a group without external authority fallback\",\n );\n // Retire this local attestation domain whenever strict validation changes.\n return serializeKeyingCanonicalJson([\n \"tearleads.sdk.principal-history.direct-admins.v1\",\n input.protection.context,\n ]);\n}\n\nexport function assertPrincipalHistoryVerificationMode(\n input: RecoverPrincipalPolicyHistoryOptions,\n entries: readonly PrincipalPolicyStateChainEntry[],\n): void {\n if (input.historyVerification !== \"direct-admins\") return;\n if (\n entries.some(\n (entry) =>\n entry.projection.length === 0 ||\n entry.projection.some((member) => member.role !== \"admin\"),\n )\n )\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Reserved Admins history must contain only direct admin users\",\n );\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { type ReferencedPrincipalHead } from "../../internal/crypto/index.js";
2
+ import { type OrganizationAuthorityDescriptor } from "../../data/principals/organizationAuthorityDescriptor.js";
3
+ import { type RecoveredPrincipalPolicyHistory, type RecoverPrincipalPolicyHistoryOptions } from "./principalHistoryRecoveryTypes.js";
4
+ export type PrincipalRecoveryContext = Omit<RecoverPrincipalPolicyHistoryOptions, "expectedHead" | "retainedReferences" | "historyVerification" | "loadExternalAuthority">;
5
+ export interface RecoveredPolicyDirectory extends RecoveredPrincipalPolicyHistory {
6
+ readonly descriptor: OrganizationAuthorityDescriptor;
7
+ }
8
+ export declare class PrincipalRecoveryDirectoryAdvanced extends Error {
9
+ }
10
+ export declare function recoverPolicyDirectory(input: PrincipalRecoveryContext, references: readonly ReferencedPrincipalHead[]): Promise<RecoveredPolicyDirectory>;
@@ -0,0 +1,107 @@
1
+ import { KeyingVerificationError, serializeKeyingCanonicalJson, verifyPrincipalPolicyHistoryReferences, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { loadPrincipalHistoryReference } from "../../data/persistence/principalHistoryEvidencePersistence.js";
4
+ import { parseOrganizationAuthorityDescriptor, } from "../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { principalHistoryEvidenceScopeId } from "../../data/principals/principalHistoryPrefixProtection.js";
6
+ import { loadVerifiedPrincipalHistoryPrefix } from "./principalHistoryRecoveryPrefix.js";
7
+ import { PrincipalPolicyHistoryReadError, } from "./principalHistoryRecoveryTypes.js";
8
+ import { recoverPrincipalPolicyHistory } from "./recoverPrincipalPolicyHistory.js";
9
+ export class PrincipalRecoveryDirectoryAdvanced extends Error {
10
+ }
11
+ /** An unverified discovery read chooses a pin; recovery must authenticate it. */
12
+ async function discoverDirectoryHead(input) {
13
+ assertProjectionVerificationCurrent(() => !input.signal?.aborted && input.stillCurrent());
14
+ if (input.offline) {
15
+ const principal = {
16
+ principalType: "organization",
17
+ principalId: input.organizationId,
18
+ };
19
+ const scopeId = await principalHistoryEvidenceScopeId({
20
+ organizationId: input.organizationId,
21
+ head: principal,
22
+ protection: input.protection,
23
+ });
24
+ const prefix = await loadVerifiedPrincipalHistoryPrefix(input, principal, scopeId);
25
+ if (!prefix)
26
+ throw new KeyingVerificationError("missing_dependency", "Organization directory is unavailable offline");
27
+ const history = prefix.verifier.finish(prefix.head);
28
+ if (!history.ok)
29
+ throw history.error;
30
+ const genesis = await loadPrincipalHistoryReference({
31
+ execSql: input.execSql,
32
+ scopeId,
33
+ history: history.value,
34
+ version: 1,
35
+ });
36
+ const selected = await verifyPrincipalPolicyHistoryReferences({
37
+ history: history.value,
38
+ references: [genesis],
39
+ });
40
+ if (!selected.ok)
41
+ throw selected.error;
42
+ return { head: prefix.head, genesis: genesis.reference };
43
+ }
44
+ for await (const result of input.apiClient.getPrincipalPolicyPages("organization", input.organizationId, { signal: input.signal })) {
45
+ if (!result.ok)
46
+ throw new PrincipalPolicyHistoryReadError(result);
47
+ assertProjectionVerificationCurrent(() => !input.signal?.aborted && input.stillCurrent());
48
+ const state = result.data.currentState;
49
+ const first = result.data.previousStates[0]?.state ?? state;
50
+ if (first.version !== 1 ||
51
+ first.principalType !== "organization" ||
52
+ first.principalId !== input.organizationId)
53
+ throw new KeyingVerificationError("missing_dependency", "Organization directory discovery requires genesis");
54
+ return {
55
+ genesis: {
56
+ principalType: first.principalType,
57
+ principalId: first.principalId,
58
+ version: first.version,
59
+ stateHash: first.stateHash,
60
+ keyEpoch: first.keyEpoch,
61
+ keyFingerprint: first.keyFingerprint,
62
+ },
63
+ head: {
64
+ principalType: "organization",
65
+ principalId: input.organizationId,
66
+ version: state.version,
67
+ stateHash: state.stateHash,
68
+ keyEpoch: state.keyEpoch,
69
+ keyFingerprint: state.keyFingerprint,
70
+ },
71
+ };
72
+ }
73
+ throw new KeyingVerificationError("missing_dependency", "Organization directory head is unavailable");
74
+ }
75
+ export async function recoverPolicyDirectory(input, references) {
76
+ const scoped = {
77
+ ...input,
78
+ protection: {
79
+ localKey: input.protection.localKey,
80
+ context: serializeKeyingCanonicalJson([
81
+ "tearleads.sdk.principal-history.directory.v1",
82
+ input.protection.context,
83
+ ]),
84
+ },
85
+ };
86
+ const { head: expectedHead, genesis } = await discoverDirectoryHead(scoped);
87
+ if (references.some((reference) => reference.version > expectedHead.version))
88
+ throw new PrincipalRecoveryDirectoryAdvanced();
89
+ const recovered = await recoverPrincipalPolicyHistory({
90
+ ...scoped,
91
+ expectedHead,
92
+ retainedReferences: references.some((reference) => reference.version === 1)
93
+ ? references
94
+ : [genesis, ...references],
95
+ });
96
+ let descriptor;
97
+ try {
98
+ descriptor = parseOrganizationAuthorityDescriptor(recovered.current.currentPayload.ciphertext);
99
+ }
100
+ catch {
101
+ throw new KeyingVerificationError("invalid_shape", "Organization directory payload is invalid");
102
+ }
103
+ if (descriptor.organizationId !== input.organizationId)
104
+ throw new KeyingVerificationError("object_mismatch", "Organization directory scope does not match");
105
+ return { ...recovered, descriptor };
106
+ }
107
+ //# sourceMappingURL=principalRecoveryDirectory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalRecoveryDirectory.js","sourceRoot":"","sources":["principalRecoveryDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n serializeKeyingCanonicalJson,\n verifyPrincipalPolicyHistoryReferences,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadPrincipalHistoryReference } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport {\n type OrganizationAuthorityDescriptor,\n parseOrganizationAuthorityDescriptor,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { principalHistoryEvidenceScopeId } from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { loadVerifiedPrincipalHistoryPrefix } from \"./principalHistoryRecoveryPrefix\";\nimport {\n PrincipalPolicyHistoryReadError,\n type RecoveredPrincipalPolicyHistory,\n type RecoverPrincipalPolicyHistoryOptions,\n} from \"./principalHistoryRecoveryTypes\";\nimport { recoverPrincipalPolicyHistory } from \"./recoverPrincipalPolicyHistory\";\n\nexport type PrincipalRecoveryContext = Omit<\n RecoverPrincipalPolicyHistoryOptions,\n | \"expectedHead\"\n | \"retainedReferences\"\n | \"historyVerification\"\n | \"loadExternalAuthority\"\n>;\n\nexport interface RecoveredPolicyDirectory\n extends RecoveredPrincipalPolicyHistory {\n readonly descriptor: OrganizationAuthorityDescriptor;\n}\n\nexport class PrincipalRecoveryDirectoryAdvanced extends Error {}\n\n/** An unverified discovery read chooses a pin; recovery must authenticate it. */\nasync function discoverDirectoryHead(input: PrincipalRecoveryContext): Promise<{\n head: ReferencedPrincipalHead;\n genesis: ReferencedPrincipalHead;\n}> {\n assertProjectionVerificationCurrent(\n () => !input.signal?.aborted && input.stillCurrent(),\n );\n if (input.offline) {\n const principal = {\n principalType: \"organization\" as const,\n principalId: input.organizationId,\n };\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: input.organizationId,\n head: principal,\n protection: input.protection,\n });\n const prefix = await loadVerifiedPrincipalHistoryPrefix(\n input,\n principal,\n scopeId,\n );\n if (!prefix)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization directory is unavailable offline\",\n );\n const history = prefix.verifier.finish(prefix.head);\n if (!history.ok) throw history.error;\n const genesis = await loadPrincipalHistoryReference({\n execSql: input.execSql,\n scopeId,\n history: history.value,\n version: 1,\n });\n const selected = await verifyPrincipalPolicyHistoryReferences({\n history: history.value,\n references: [genesis],\n });\n if (!selected.ok) throw selected.error;\n return { head: prefix.head, genesis: genesis.reference };\n }\n for await (const result of input.apiClient.getPrincipalPolicyPages(\n \"organization\",\n input.organizationId,\n { signal: input.signal },\n )) {\n if (!result.ok) throw new PrincipalPolicyHistoryReadError(result);\n assertProjectionVerificationCurrent(\n () => !input.signal?.aborted && input.stillCurrent(),\n );\n const state = result.data.currentState;\n const first = result.data.previousStates[0]?.state ?? state;\n if (\n first.version !== 1 ||\n first.principalType !== \"organization\" ||\n first.principalId !== input.organizationId\n )\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization directory discovery requires genesis\",\n );\n return {\n genesis: {\n principalType: first.principalType,\n principalId: first.principalId,\n version: first.version,\n stateHash: first.stateHash,\n keyEpoch: first.keyEpoch,\n keyFingerprint: first.keyFingerprint,\n },\n head: {\n principalType: \"organization\",\n principalId: input.organizationId,\n version: state.version,\n stateHash: state.stateHash,\n keyEpoch: state.keyEpoch,\n keyFingerprint: state.keyFingerprint,\n },\n };\n }\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization directory head is unavailable\",\n );\n}\n\nexport async function recoverPolicyDirectory(\n input: PrincipalRecoveryContext,\n references: readonly ReferencedPrincipalHead[],\n): Promise<RecoveredPolicyDirectory> {\n const scoped = {\n ...input,\n protection: {\n localKey: input.protection.localKey,\n context: serializeKeyingCanonicalJson([\n \"tearleads.sdk.principal-history.directory.v1\",\n input.protection.context,\n ]),\n },\n };\n const { head: expectedHead, genesis } = await discoverDirectoryHead(scoped);\n if (references.some((reference) => reference.version > expectedHead.version))\n throw new PrincipalRecoveryDirectoryAdvanced();\n const recovered = await recoverPrincipalPolicyHistory({\n ...scoped,\n expectedHead,\n retainedReferences: references.some((reference) => reference.version === 1)\n ? references\n : [genesis, ...references],\n });\n let descriptor: OrganizationAuthorityDescriptor;\n try {\n descriptor = parseOrganizationAuthorityDescriptor(\n recovered.current.currentPayload.ciphertext,\n );\n } catch {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Organization directory payload is invalid\",\n );\n }\n if (descriptor.organizationId !== input.organizationId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Organization directory scope does not match\",\n );\n return { ...recovered, descriptor };\n}\n"]}
@@ -0,0 +1,46 @@
1
+ import { serializeKeyingCanonicalJson, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { recoverPolicyDirectory, } from "./principalRecoveryDirectory.js";
4
+ import { recoverPrincipalPolicyHistory } from "./recoverPrincipalPolicyHistory.js";
5
+ /** Only share authenticated results within one projection collection lifetime. */
6
+ async function memoPrincipalRecovery(memo, key, stillCurrent, work) {
7
+ assertProjectionVerificationCurrent(stillCurrent);
8
+ let pending = memo?.get(key);
9
+ if (!pending) {
10
+ pending = work().then((value) => ({ value, stillCurrent }));
11
+ memo?.set(key, pending);
12
+ }
13
+ const result = await pending.catch((error) => {
14
+ if (memo?.get(key) === pending)
15
+ memo.delete(key);
16
+ throw error;
17
+ });
18
+ assertProjectionVerificationCurrent(result.stillCurrent);
19
+ assertProjectionVerificationCurrent(stillCurrent);
20
+ return result.value;
21
+ }
22
+ export function createPrincipalRecoveryReader(input, memo) {
23
+ const scope = [
24
+ input.organizationId,
25
+ input.protection.context,
26
+ input.offline === true,
27
+ ];
28
+ const current = () => !input.signal?.aborted && input.stillCurrent();
29
+ return {
30
+ directory: (references) => memoPrincipalRecovery(memo?.directories, serializeKeyingCanonicalJson([
31
+ ...scope,
32
+ references.map((reference) => ({ ...reference })),
33
+ ]), current, () => recoverPolicyDirectory(input, references)),
34
+ admins: (expectedHead, retainedReferences = []) => memoPrincipalRecovery(memo?.admins, serializeKeyingCanonicalJson([
35
+ ...scope,
36
+ { ...expectedHead },
37
+ retainedReferences.map((reference) => ({ ...reference })),
38
+ ]), current, () => recoverPrincipalPolicyHistory({
39
+ ...input,
40
+ expectedHead,
41
+ retainedReferences,
42
+ historyVerification: "direct-admins",
43
+ })),
44
+ };
45
+ }
46
+ //# sourceMappingURL=principalRecoveryMemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalRecoveryMemo.js","sourceRoot":"","sources":["principalRecoveryMemo.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AAEpG,OAAO,EAGL,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAShF,kFAAkF;AAClF,KAAK,UAAU,qBAAqB,CAClC,IAAyB,EACzB,GAAW,EACX,YAA2B,EAC3B,IAAsB;IAEtB,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,OAAO,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;QAC5D,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACpD,IAAI,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;IACH,mCAAmC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACzD,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,KAA+B,EAC/B,IAA4B;IAE5B,MAAM,KAAK,GAAG;QACZ,KAAK,CAAC,cAAc;QACpB,KAAK,CAAC,UAAU,CAAC,OAAO;QACxB,KAAK,CAAC,OAAO,KAAK,IAAI;KACvB,CAAC;IACF,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;IACrE,OAAO;QACL,SAAS,EAAE,CAAC,UAA8C,EAAE,EAAE,CAC5D,qBAAqB,CACnB,IAAI,EAAE,WAAW,EACjB,4BAA4B,CAAC;YAC3B,GAAG,KAAK;YACR,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;SAClD,CAAC,EACF,OAAO,EACP,GAAG,EAAE,CAAC,sBAAsB,CAAC,KAAK,EAAE,UAAU,CAAC,CAChD;QACH,MAAM,EAAE,CACN,YAAqC,EACrC,qBAAyD,EAAE,EAC3D,EAAE,CACF,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,4BAA4B,CAAC;YAC3B,GAAG,KAAK;YACR,EAAE,GAAG,YAAY,EAAE;YACnB,kBAAkB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;SAC1D,CAAC,EACF,OAAO,EACP,GAAG,EAAE,CACH,6BAA6B,CAAC;YAC5B,GAAG,KAAK;YACR,YAAY;YACZ,kBAAkB;YAClB,mBAAmB,EAAE,eAAe;SACrC,CAAC,CACL;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import {\n type ReferencedPrincipalHead,\n serializeKeyingCanonicalJson,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { RecoveredPrincipalPolicyHistory } from \"./principalHistoryRecoveryTypes\";\nimport {\n type PrincipalRecoveryContext,\n type RecoveredPolicyDirectory,\n recoverPolicyDirectory,\n} from \"./principalRecoveryDirectory\";\nimport { recoverPrincipalPolicyHistory } from \"./recoverPrincipalPolicyHistory\";\n\ntype Memo<T> = Map<string, Promise<{ value: T; stillCurrent: () => boolean }>>;\n\nexport interface PrincipalRecoveryMemo {\n readonly directories: Memo<RecoveredPolicyDirectory>;\n readonly admins: Memo<RecoveredPrincipalPolicyHistory>;\n}\n\n/** Only share authenticated results within one projection collection lifetime. */\nasync function memoPrincipalRecovery<T>(\n memo: Memo<T> | undefined,\n key: string,\n stillCurrent: () => boolean,\n work: () => Promise<T>,\n): Promise<T> {\n assertProjectionVerificationCurrent(stillCurrent);\n let pending = memo?.get(key);\n if (!pending) {\n pending = work().then((value) => ({ value, stillCurrent }));\n memo?.set(key, pending);\n }\n const result = await pending.catch((error: unknown) => {\n if (memo?.get(key) === pending) memo.delete(key);\n throw error;\n });\n assertProjectionVerificationCurrent(result.stillCurrent);\n assertProjectionVerificationCurrent(stillCurrent);\n return result.value;\n}\n\nexport function createPrincipalRecoveryReader(\n input: PrincipalRecoveryContext,\n memo?: PrincipalRecoveryMemo,\n) {\n const scope = [\n input.organizationId,\n input.protection.context,\n input.offline === true,\n ];\n const current = () => !input.signal?.aborted && input.stillCurrent();\n return {\n directory: (references: readonly ReferencedPrincipalHead[]) =>\n memoPrincipalRecovery(\n memo?.directories,\n serializeKeyingCanonicalJson([\n ...scope,\n references.map((reference) => ({ ...reference })),\n ]),\n current,\n () => recoverPolicyDirectory(input, references),\n ),\n admins: (\n expectedHead: ReferencedPrincipalHead,\n retainedReferences: readonly ReferencedPrincipalHead[] = [],\n ) =>\n memoPrincipalRecovery(\n memo?.admins,\n serializeKeyingCanonicalJson([\n ...scope,\n { ...expectedHead },\n retainedReferences.map((reference) => ({ ...reference })),\n ]),\n current,\n () =>\n recoverPrincipalPolicyHistory({\n ...input,\n expectedHead,\n retainedReferences,\n historyVerification: \"direct-admins\",\n }),\n ),\n };\n}\n"]}
@@ -0,0 +1,40 @@
1
+ import { KeyingVerificationError } from "../../internal/crypto/index.js";
2
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
4
+ import { PrincipalPolicyHistoryReadError } from "./principalHistoryRecoveryTypes.js";
5
+ import { recoverScopedPrincipalPolicyHistory } from "./recoverScopedPrincipalPolicyHistory.js";
6
+ /** Refusals and invalid evidence must never silently select a cached policy. */
7
+ function isPrincipalRecoveryOutage(error) {
8
+ if (!(error instanceof PrincipalPolicyHistoryReadError))
9
+ return false;
10
+ const { failure } = error;
11
+ return (failure.kind === "network" ||
12
+ (failure.kind === "http" &&
13
+ failure.status !== null &&
14
+ failure.status >= 500) ||
15
+ (failure.kind === "cancelled" &&
16
+ failure.code === "principal_history_request_timed_out"));
17
+ }
18
+ export async function recoverWithPrincipalOutageFallback(recover, options) {
19
+ try {
20
+ return await recover(options);
21
+ }
22
+ catch (error) {
23
+ assertProjectionVerificationCurrent(options.stillCurrent);
24
+ if (options.offline || !isPrincipalRecoveryOutage(error))
25
+ throw error;
26
+ try {
27
+ return await recoverScopedPrincipalPolicyHistory({
28
+ ...options,
29
+ offline: true,
30
+ });
31
+ }
32
+ catch (localError) {
33
+ if (localError instanceof KeyingVerificationError &&
34
+ localError.code === "missing_dependency")
35
+ throw new ProjectionDependencyUnavailableError(localError.message);
36
+ throw localError;
37
+ }
38
+ }
39
+ }
40
+ //# sourceMappingURL=principalRecoveryOutage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalRecoveryOutage.js","sourceRoot":"","sources":["principalRecoveryOutage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAE5F,gFAAgF;AAChF,SAAS,yBAAyB,CAAC,KAAc;IAC/C,IAAI,CAAC,CAAC,KAAK,YAAY,+BAA+B,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC1B,OAAO,CACL,OAAO,CAAC,IAAI,KAAK,SAAS;QAC1B,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;YACtB,OAAO,CAAC,MAAM,KAAK,IAAI;YACvB,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;QACxB,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW;YAC3B,OAAO,CAAC,IAAI,KAAK,qCAAqC,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,OAAmD,EACnD,OAAkE;IAElE,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mCAAmC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC;QACtE,IAAI,CAAC;YACH,OAAO,MAAM,mCAAmC,CAAC;gBAC/C,GAAG,OAAO;gBACV,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,UAAU,EAAE,CAAC;YACpB,IACE,UAAU,YAAY,uBAAuB;gBAC7C,UAAU,CAAC,IAAI,KAAK,oBAAoB;gBAExC,MAAM,IAAI,oCAAoC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACrE,MAAM,UAAU,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { PrincipalPolicyHistoryReadError } from \"./principalHistoryRecoveryTypes\";\nimport { recoverScopedPrincipalPolicyHistory } from \"./recoverScopedPrincipalPolicyHistory\";\n\n/** Refusals and invalid evidence must never silently select a cached policy. */\nfunction isPrincipalRecoveryOutage(error: unknown): boolean {\n if (!(error instanceof PrincipalPolicyHistoryReadError)) return false;\n const { failure } = error;\n return (\n failure.kind === \"network\" ||\n (failure.kind === \"http\" &&\n failure.status !== null &&\n failure.status >= 500) ||\n (failure.kind === \"cancelled\" &&\n failure.code === \"principal_history_request_timed_out\")\n );\n}\n\nexport async function recoverWithPrincipalOutageFallback(\n recover: typeof recoverScopedPrincipalPolicyHistory,\n options: Parameters<typeof recoverScopedPrincipalPolicyHistory>[0],\n) {\n try {\n return await recover(options);\n } catch (error) {\n assertProjectionVerificationCurrent(options.stillCurrent);\n if (options.offline || !isPrincipalRecoveryOutage(error)) throw error;\n try {\n return await recoverScopedPrincipalPolicyHistory({\n ...options,\n offline: true,\n });\n } catch (localError) {\n if (\n localError instanceof KeyingVerificationError &&\n localError.code === \"missing_dependency\"\n )\n throw new ProjectionDependencyUnavailableError(localError.message);\n throw localError;\n }\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ // Directory and Admins stages are shared by every reference in an organization.
2
+ // Coordinate runtime callers across warmer instances; different databases and
3
+ // organizations keep independent queues. Completed queues retain no work.
4
+ // Queued work must not re-enter this queue for the same organization.
5
+ const queues = new WeakMap();
6
+ export function queuePrincipalRecovery(execSql, organizationId, work) {
7
+ let scoped = queues.get(execSql);
8
+ if (!scoped) {
9
+ scoped = new Map();
10
+ queues.set(execSql, scoped);
11
+ }
12
+ const operation = (scoped.get(organizationId) ?? Promise.resolve()).then(work);
13
+ const settled = operation.then(() => undefined, () => undefined);
14
+ scoped.set(organizationId, settled);
15
+ const owned = scoped;
16
+ void settled.then(() => {
17
+ if (owned.get(organizationId) === settled)
18
+ owned.delete(organizationId);
19
+ });
20
+ return operation;
21
+ }
22
+ //# sourceMappingURL=principalRecoveryQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalRecoveryQueue.js","sourceRoot":"","sources":["principalRecoveryQueue.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,8EAA8E;AAC9E,0EAA0E;AAC1E,sEAAsE;AACtE,MAAM,MAAM,GAAG,IAAI,OAAO,EAAuC,CAAC;AAElE,MAAM,UAAU,sBAAsB,CACpC,OAAgB,EAChB,cAAsB,EACtB,IAAsB;IAEtB,IAAI,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CACtE,IAAI,CACL,CAAC;IACF,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAC5B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACF,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC;IACrB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,OAAO;YAAE,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\n// Directory and Admins stages are shared by every reference in an organization.\n// Coordinate runtime callers across warmer instances; different databases and\n// organizations keep independent queues. Completed queues retain no work.\n// Queued work must not re-enter this queue for the same organization.\nconst queues = new WeakMap<ExecSql, Map<string, Promise<void>>>();\n\nexport function queuePrincipalRecovery<T>(\n execSql: ExecSql,\n organizationId: string,\n work: () => Promise<T>,\n): Promise<T> {\n let scoped = queues.get(execSql);\n if (!scoped) {\n scoped = new Map();\n queues.set(execSql, scoped);\n }\n const operation = (scoped.get(organizationId) ?? Promise.resolve()).then(\n work,\n );\n const settled = operation.then(\n () => undefined,\n () => undefined,\n );\n scoped.set(organizationId, settled);\n const owned = scoped;\n void settled.then(() => {\n if (owned.get(organizationId) === settled) owned.delete(organizationId);\n });\n return operation;\n}\n"]}
@@ -2,5 +2,6 @@ import { type RecoveredPrincipalPolicyHistory, type RecoverPrincipalPolicyHistor
2
2
  /**
3
3
  * Recover one exact head with bounded retained history and durable checked progress.
4
4
  * The result is a sparse current-policy capability; this does not advance app checkpoints.
5
+ * Retain organization version 1 when the result will establish founder binding.
5
6
  */
6
7
  export declare function recoverPrincipalPolicyHistory(options: RecoverPrincipalPolicyHistoryOptions): Promise<RecoveredPrincipalPolicyHistory>;