@tearleads/client-sdk 0.1.54 → 0.1.56

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 (64) hide show
  1. package/data/containers/shared/types.d.ts +1 -2
  2. package/data/containers/shared/types.js.map +1 -1
  3. package/package.json +1 -1
  4. package/workflows/container-contents/container-state/types.js.map +1 -1
  5. package/workflows/container-contents/remoteHydration/types.d.ts +5 -4
  6. package/workflows/container-contents/remoteHydration/types.js.map +1 -1
  7. package/workflows/containers/child/runtimeCurrentGroupShare.js +5 -8
  8. package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -1
  9. package/workflows/containers/child/sharePrincipalPolicy.d.ts +3 -3
  10. package/workflows/containers/child/sharePrincipalPolicy.js +1 -1
  11. package/workflows/containers/child/sharePrincipalPolicy.js.map +1 -1
  12. package/workflows/organizations/currentOrganizationMutationRetention.js +1 -1
  13. package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -1
  14. package/workflows/organizations/currentPrincipalMutationLease.js +5 -4
  15. package/workflows/organizations/currentPrincipalMutationLease.js.map +1 -1
  16. package/workflows/organizations/deleteOrganizationGroup.js +1 -1
  17. package/workflows/organizations/deleteOrganizationGroup.js.map +1 -1
  18. package/workflows/organizations/groupCreation.js +1 -1
  19. package/workflows/organizations/groupCreation.js.map +1 -1
  20. package/workflows/organizations/groupNameUniqueness.js.map +1 -1
  21. package/workflows/organizations/groupPolicyMutationContext.js +1 -1
  22. package/workflows/organizations/groupPolicyMutationContext.js.map +1 -1
  23. package/workflows/organizations/organizationGroupNamePolicies.js +19 -5
  24. package/workflows/organizations/organizationGroupNamePolicies.js.map +1 -1
  25. package/workflows/organizations/principalPolicyApi.d.ts +3 -3
  26. package/workflows/organizations/principalPolicyApi.js.map +1 -1
  27. package/workflows/organizations/runtimeCurrentGroupMutation.js +4 -4
  28. package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -1
  29. package/workflows/organizations/runtimeCurrentOrganizationMutation.js +2 -2
  30. package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -1
  31. package/workflows/principals/currentPrincipalPolicyReader.d.ts +12 -0
  32. package/workflows/principals/currentPrincipalPolicyReader.js +2 -0
  33. package/workflows/principals/currentPrincipalPolicyReader.js.map +1 -0
  34. package/workflows/principals/externalAdminPolicy.d.ts +2 -1
  35. package/workflows/principals/externalAdminPolicy.js +3 -3
  36. package/workflows/principals/externalAdminPolicy.js.map +1 -1
  37. package/workflows/principals/policyCache.d.ts +3 -2
  38. package/workflows/principals/policyCache.js +9 -9
  39. package/workflows/principals/policyCache.js.map +1 -1
  40. package/workflows/principals/principalHistoryRecoveryTypes.d.ts +3 -2
  41. package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
  42. package/workflows/principals/principalPolicyHistoryReader.d.ts +20 -0
  43. package/workflows/principals/principalPolicyHistoryReader.js +13 -0
  44. package/workflows/principals/principalPolicyHistoryReader.js.map +1 -0
  45. package/workflows/principals/principalPolicyOrganizationScope.js +1 -1
  46. package/workflows/principals/principalPolicyOrganizationScope.js.map +1 -1
  47. package/workflows/principals/principalRecoveryDirectory.js +6 -6
  48. package/workflows/principals/principalRecoveryDirectory.js.map +1 -1
  49. package/workflows/principals/principalRecoveryDiscoveryPage.js +4 -4
  50. package/workflows/principals/principalRecoveryDiscoveryPage.js.map +1 -1
  51. package/workflows/principals/publicPrincipalHistoryTypes.d.ts +2 -2
  52. package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -1
  53. package/workflows/principals/recoverPrincipalPolicyHistory.js +1 -1
  54. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  55. package/workflows/principals/recoverPublicPrincipalHistory.js +1 -1
  56. package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -1
  57. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +1 -1
  58. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
  59. package/workflows/principals/runtimePolicyRecovery.js +4 -3
  60. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  61. package/workflows/principals/runtimeProjectionPolicyRecovery.js +4 -3
  62. package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -1
  63. package/workflows/registration/provisionedPrincipalHistory.js +1 -1
  64. package/workflows/registration/provisionedPrincipalHistory.js.map +1 -1
@@ -29,7 +29,7 @@ function dedupePrincipalPolicyBundles(bundles) {
29
29
  }
30
30
  return Array.from(bundlesByPrincipal.values());
31
31
  }
32
- async function cacheReferencedPrincipalPolicy(execSql, getCurrentPrincipalPolicy, reference, resolveTrustedUserIdentity, log, loadExternalAdminPolicy, organizationId, stillCurrent, loadDirectory, fresh) {
32
+ async function cacheReferencedPrincipalPolicy(execSql, reader, reference, resolveTrustedUserIdentity, log, loadExternalAdminPolicy, organizationId, stillCurrent, loadDirectory, fresh) {
33
33
  const localCheckpoint = await loadPrincipalPolicyCheckpoint(execSql, reference.principalType, reference.principalId);
34
34
  // Only null is a recoverable local miss. Integrity failures remain typed and
35
35
  // must escape rather than being hidden by a canonical network retry.
@@ -37,7 +37,7 @@ async function cacheReferencedPrincipalPolicy(execSql, getCurrentPrincipalPolicy
37
37
  ? null
38
38
  : await loadPrincipalPolicyBundleForReference(execSql, reference, localCheckpoint);
39
39
  let bundle = cachedBundle ??
40
- (await getCurrentPrincipalPolicy(reference.principalType, reference.principalId));
40
+ (await reader.getCurrentPrincipalPolicy(reference.principalType, reference.principalId));
41
41
  if (!bundle) {
42
42
  log?.(`Principal policy cache: failed to fetch ${getReferencedPrincipalKey(reference)}`);
43
43
  return [];
@@ -64,7 +64,7 @@ async function cacheReferencedPrincipalPolicy(execSql, getCurrentPrincipalPolicy
64
64
  loadDirectory,
65
65
  organizationId,
66
66
  reloadBundle: cachedBundle
67
- ? () => getCurrentPrincipalPolicy("group", reference.principalId)
67
+ ? () => reader.getCurrentPrincipalPolicy("group", reference.principalId)
68
68
  : null,
69
69
  });
70
70
  if (!scoped) {
@@ -151,8 +151,8 @@ async function runPrincipalPolicyCache(input) {
151
151
  let externalAdminPolicy = null;
152
152
  const loadExternalAdminPolicy = () => {
153
153
  externalAdminPolicy ??= loadOrganizationExternalAdminPolicy({
154
+ currentPolicyReader: input.currentPolicyReader,
154
155
  execSql: input.execSql,
155
- getCurrentPrincipalPolicy: input.getCurrentPrincipalPolicy,
156
156
  organizationId: input.organizationId,
157
157
  resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,
158
158
  stillCurrent: input.stillCurrent,
@@ -197,12 +197,12 @@ async function runPrincipalPolicyCache(input) {
197
197
  return [];
198
198
  }
199
199
  }
200
- async function loadReferencedPrincipalPolicies({ execSql, getCurrentPrincipalPolicy, log, organizationId, reportSecurityIncident, references, resolveTrustedUserIdentity, stillCurrent, }) {
200
+ async function loadReferencedPrincipalPolicies({ currentPolicyReader, execSql, log, organizationId, reportSecurityIncident, references, resolveTrustedUserIdentity, stillCurrent, }) {
201
201
  return runPrincipalPolicyCache({
202
- cacheItem: (reference, loadExternalAdminPolicy, loadDirectory, fresh) => cacheReferencedPrincipalPolicy(execSql, getCurrentPrincipalPolicy, reference, resolveTrustedUserIdentity, log, loadExternalAdminPolicy, organizationId, stillCurrent, loadDirectory, fresh),
202
+ cacheItem: (reference, loadExternalAdminPolicy, loadDirectory, fresh) => cacheReferencedPrincipalPolicy(execSql, currentPolicyReader, reference, resolveTrustedUserIdentity, log, loadExternalAdminPolicy, organizationId, stillCurrent, loadDirectory, fresh),
203
+ currentPolicyReader,
203
204
  dedupe: dedupeReferencedPrincipalStates,
204
205
  execSql,
205
- getCurrentPrincipalPolicy,
206
206
  itemKey: getReferencedPrincipalKey,
207
207
  items: references,
208
208
  log,
@@ -215,7 +215,7 @@ async function loadReferencedPrincipalPolicies({ execSql, getCurrentPrincipalPol
215
215
  export async function cacheReferencedPrincipalPolicies(input) {
216
216
  await loadReferencedPrincipalPolicies(input);
217
217
  }
218
- export async function cachePrincipalPolicyBundles({ bundles, execSql, getCurrentPrincipalPolicy, log, organizationId, reportSecurityIncident, resolveTrustedUserIdentity, stillCurrent, }) {
218
+ export async function cachePrincipalPolicyBundles({ bundles, currentPolicyReader, execSql, log, organizationId, reportSecurityIncident, resolveTrustedUserIdentity, stillCurrent, }) {
219
219
  await runPrincipalPolicyCache({
220
220
  cacheItem: (bundle, loadExternalAdminPolicy, loadDirectory) => cachePrincipalPolicyBundle({
221
221
  bundle,
@@ -227,9 +227,9 @@ export async function cachePrincipalPolicyBundles({ bundles, execSql, getCurrent
227
227
  resolveTrustedUserIdentity,
228
228
  stillCurrent,
229
229
  }),
230
+ currentPolicyReader,
230
231
  dedupe: dedupePrincipalPolicyBundles,
231
232
  execSql,
232
- getCurrentPrincipalPolicy,
233
233
  itemKey: getBundlePrincipalKey,
234
234
  items: bundles,
235
235
  log,
@@ -1 +1 @@
1
- {"version":3,"file":"policyCache.js","sourceRoot":"","sources":["policyCache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VerifiedPrincipalPolicy } from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { errorMessage } from \"../../data/errorMessage\";\nimport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification\";\nimport {\n reportAndRethrowKeyingVerificationError,\n rethrowKeyingVerificationError,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { dedupeReferencedPrincipalStates } from \"../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../data/persistence/keyingCheckpointPersistence\";\nimport { ensurePrincipalPolicyTables } from \"../../data/persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../../data/persistence/principalPolicyReferencePersistence\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"./externalAdminPolicy\";\nimport {\n persistPrincipalPolicyCacheEntries,\n retryPrincipalPolicyCacheAdvance,\n} from \"./principalPolicyCacheAdvance\";\nimport { scopeReferencedPolicyForCache } from \"./principalPolicyCacheScope\";\nimport { validatePrincipalPolicyBundleForCache } from \"./principalPolicyCacheValidation\";\nimport {\n createPolicyDirectoryLoader,\n directoryBindsGroupReference,\n type PolicyDirectoryLoader,\n type VerifiedPolicyDirectory,\n} from \"./principalPolicyOrganizationScope\";\n\nexport interface CacheReferencedPrincipalPoliciesOptions {\n execSql: ExecSql;\n getCurrentPrincipalPolicy: (\n principalType: \"group\" | \"organization\",\n principalId: string,\n ) => Promise<PrincipalPolicyBundleResponse | null>;\n log?: (message: string) => void;\n organizationId: string;\n reportSecurityIncident: SecurityIncidentReporter;\n references: ReadonlyArray<ReferencedPrincipalStateResponse> | undefined;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface CachePrincipalPolicyBundlesOptions\n extends Omit<CacheReferencedPrincipalPoliciesOptions, \"references\"> {\n bundles: ReadonlyArray<PrincipalPolicyBundleResponse> | undefined;\n}\n\nfunction getReferencedPrincipalKey(\n reference: ReferencedPrincipalStateResponse,\n): string {\n return `${reference.principalType}:${reference.principalId}`;\n}\n\nfunction getBundlePrincipalKey(bundle: PrincipalPolicyBundleResponse): string {\n return `${bundle.currentState.principalType}:${bundle.currentState.principalId}`;\n}\n\nfunction dedupePrincipalPolicyBundles(\n bundles: ReadonlyArray<PrincipalPolicyBundleResponse>,\n): PrincipalPolicyBundleResponse[] {\n const bundlesByPrincipal = new Map<string, PrincipalPolicyBundleResponse>();\n\n for (const bundle of bundles) {\n const key = getBundlePrincipalKey(bundle);\n const previous = bundlesByPrincipal.get(key);\n if (\n !previous ||\n bundle.currentState.version > previous.currentState.version\n ) {\n bundlesByPrincipal.set(key, bundle);\n }\n }\n\n return Array.from(bundlesByPrincipal.values());\n}\n\nasync function cacheReferencedPrincipalPolicy(\n execSql: ExecSql,\n getCurrentPrincipalPolicy: CacheReferencedPrincipalPoliciesOptions[\"getCurrentPrincipalPolicy\"],\n reference: ReferencedPrincipalStateResponse,\n resolveTrustedUserIdentity: TrustedUserIdentityResolver,\n log: ((message: string) => void) | undefined,\n loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>,\n organizationId: string,\n stillCurrent: (() => boolean) | undefined,\n loadDirectory: PolicyDirectoryLoader,\n fresh: boolean,\n): Promise<VerifiedPrincipalPolicy[]> {\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n reference.principalType,\n reference.principalId,\n );\n // Only null is a recoverable local miss. Integrity failures remain typed and\n // must escape rather than being hidden by a canonical network retry.\n const cachedBundle = fresh\n ? null\n : await loadPrincipalPolicyBundleForReference(\n execSql,\n reference,\n localCheckpoint,\n );\n let bundle =\n cachedBundle ??\n (await getCurrentPrincipalPolicy(\n reference.principalType,\n reference.principalId,\n ));\n if (!bundle) {\n log?.(\n `Principal policy cache: failed to fetch ${getReferencedPrincipalKey(reference)}`,\n );\n return [];\n }\n\n let validation = await validatePrincipalPolicyBundleForCache({\n bundle,\n loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity,\n });\n if (!validation.ok) {\n throw validation.error;\n }\n\n const scoped = await scopeReferencedPolicyForCache({\n bundle,\n validation,\n validationInput: {\n loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity,\n },\n loadDirectory,\n organizationId,\n reloadBundle: cachedBundle\n ? () => getCurrentPrincipalPolicy(\"group\", reference.principalId)\n : null,\n });\n if (!scoped) {\n log?.(\n `Principal policy cache: signed organization directory does not cover ${getReferencedPrincipalKey(reference)}`,\n );\n return [];\n }\n bundle = scoped.bundle;\n validation = scoped.validation;\n const directory = scoped.directory;\n const externalEntries = validation.externalAdminPolicy\n ? externalAdminPolicyPersistenceEntries(\n validation.externalAdminPolicy,\n ).filter(\n (entry) => !directory || entry.policy.principalType !== \"organization\",\n )\n : [];\n const directoryEntries = directory\n ? [{ bundle: directory.bundle, policy: directory.policy }]\n : [];\n await persistPrincipalPolicyCacheEntries({\n entries: [\n ...externalEntries,\n ...directoryEntries,\n { bundle, policy: validation.policy },\n ],\n execSql,\n organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent,\n });\n return [...externalEntries.map(({ policy }) => policy), validation.policy];\n}\n\nasync function cachePrincipalPolicyBundle(input: {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly execSql: ExecSql;\n readonly loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>;\n readonly log: ((message: string) => void) | undefined;\n readonly loadDirectory: PolicyDirectoryLoader;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedPrincipalPolicy[]> {\n const reference = principalPolicyReferenceFromBundle(input.bundle);\n // The API supplied this bundle after rejecting a write, but local storage is\n // only updated after normal signature, signer, and checkpoint verification.\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n reference.principalType,\n reference.principalId,\n );\n const validation = await validatePrincipalPolicyBundleForCache({\n bundle: input.bundle,\n loadExternalAdminPolicy: input.loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (!validation.ok) {\n throw validation.error;\n }\n\n let directory: VerifiedPolicyDirectory | null = null;\n if (reference.principalType === \"group\") {\n directory = await input.loadDirectory(false);\n if (!directoryBindsGroupReference(directory, validation.policy, reference))\n directory = await input.loadDirectory(true);\n if (\n !directoryBindsGroupReference(directory, validation.policy, reference)\n ) {\n input.log?.(\n \"Principal policy cache: signed organization directory does not cover supplied group\",\n );\n return [];\n }\n } else if (reference.principalId !== input.organizationId) {\n return [];\n }\n const externalEntries = validation.externalAdminPolicy\n ? externalAdminPolicyPersistenceEntries(\n validation.externalAdminPolicy,\n ).filter(\n (entry) => !directory || entry.policy.principalType !== \"organization\",\n )\n : [];\n const directoryEntries = directory\n ? [{ bundle: directory.bundle, policy: directory.policy }]\n : [];\n await persistPrincipalPolicyCacheEntries({\n entries: [\n ...externalEntries,\n ...directoryEntries,\n { bundle: input.bundle, policy: validation.policy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent: input.stillCurrent,\n });\n return [...externalEntries.map(({ policy }) => policy), validation.policy];\n}\n\nasync function runPrincipalPolicyCache<Item, Result>(input: {\n readonly cacheItem: (\n item: Item,\n loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>,\n loadDirectory: PolicyDirectoryLoader,\n fresh: boolean,\n ) => Promise<readonly Result[]>;\n readonly dedupe: (items: ReadonlyArray<Item>) => Item[];\n readonly execSql: ExecSql;\n readonly getCurrentPrincipalPolicy: CacheReferencedPrincipalPoliciesOptions[\"getCurrentPrincipalPolicy\"];\n readonly itemKey: (item: Item) => string;\n readonly items: ReadonlyArray<Item> | undefined;\n readonly log: ((message: string) => void) | undefined;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<Result[]> {\n if (!input.items || input.items.length === 0) {\n return [];\n }\n\n try {\n await ensurePrincipalPolicyTables(input.execSql);\n const uniqueItems = input.dedupe(input.items);\n const loadDirectory = createPolicyDirectoryLoader(input);\n let externalAdminPolicy: Promise<VerifiedExternalAdminPolicy | null> | null =\n null;\n const loadExternalAdminPolicy = () => {\n externalAdminPolicy ??= loadOrganizationExternalAdminPolicy({\n execSql: input.execSql,\n getCurrentPrincipalPolicy: input.getCurrentPrincipalPolicy,\n organizationId: input.organizationId,\n\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n return externalAdminPolicy;\n };\n\n const results = await Promise.all(\n uniqueItems.map(async (item) => {\n try {\n return await retryPrincipalPolicyCacheAdvance((fresh) => {\n const reloadDirectory = createPolicyDirectoryLoader(input);\n let reloadedAuthority: Promise<VerifiedExternalAdminPolicy | null> | null =\n null;\n return input.cacheItem(\n item,\n fresh\n ? () =>\n (reloadedAuthority ??=\n loadOrganizationExternalAdminPolicy(input))\n : loadExternalAdminPolicy,\n fresh ? () => reloadDirectory(true) : loadDirectory,\n fresh,\n );\n });\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return [];\n await reportAndRethrowKeyingVerificationError(\n error,\n input.reportSecurityIncident,\n {\n objectId: input.itemKey(item),\n objectKind: \"principal\",\n operation: \"principal.policy.cache\",\n organizationId: input.organizationId,\n },\n );\n const message = errorMessage(error);\n input.log?.(\n `Principal policy cache: failed to store ${input.itemKey(item)}: ${message}`,\n );\n return [];\n }\n }),\n );\n return results.flat();\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return [];\n // Per-item verification failures were reported above before reaching this\n // initialization/aggregation boundary.\n rethrowKeyingVerificationError(error);\n const message = errorMessage(error);\n input.log?.(\n `Principal policy cache: failed to initialize cache: ${message}`,\n );\n return [];\n }\n}\n\nasync function loadReferencedPrincipalPolicies({\n execSql,\n getCurrentPrincipalPolicy,\n log,\n organizationId,\n reportSecurityIncident,\n references,\n resolveTrustedUserIdentity,\n stillCurrent,\n}: CacheReferencedPrincipalPoliciesOptions): Promise<\n VerifiedPrincipalPolicy[]\n> {\n return runPrincipalPolicyCache({\n cacheItem: (reference, loadExternalAdminPolicy, loadDirectory, fresh) =>\n cacheReferencedPrincipalPolicy(\n execSql,\n getCurrentPrincipalPolicy,\n reference,\n resolveTrustedUserIdentity,\n log,\n loadExternalAdminPolicy,\n organizationId,\n stillCurrent,\n loadDirectory,\n fresh,\n ),\n dedupe: dedupeReferencedPrincipalStates,\n execSql,\n getCurrentPrincipalPolicy,\n itemKey: getReferencedPrincipalKey,\n items: references,\n log,\n organizationId,\n\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n });\n}\n\nexport async function cacheReferencedPrincipalPolicies(\n input: CacheReferencedPrincipalPoliciesOptions,\n): Promise<void> {\n await loadReferencedPrincipalPolicies(input);\n}\n\nexport async function cachePrincipalPolicyBundles({\n bundles,\n execSql,\n getCurrentPrincipalPolicy,\n log,\n organizationId,\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n}: CachePrincipalPolicyBundlesOptions): Promise<void> {\n await runPrincipalPolicyCache({\n cacheItem: (bundle, loadExternalAdminPolicy, loadDirectory) =>\n cachePrincipalPolicyBundle({\n bundle,\n execSql,\n loadExternalAdminPolicy,\n loadDirectory,\n log,\n organizationId,\n resolveTrustedUserIdentity,\n stillCurrent,\n }),\n dedupe: dedupePrincipalPolicyBundles,\n execSql,\n getCurrentPrincipalPolicy,\n itemKey: getBundlePrincipalKey,\n items: bundles,\n log,\n organizationId,\n\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n });\n}\n"]}
1
+ {"version":3,"file":"policyCache.js","sourceRoot":"","sources":["policyCache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VerifiedPrincipalPolicy } from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { errorMessage } from \"../../data/errorMessage\";\nimport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification\";\nimport {\n reportAndRethrowKeyingVerificationError,\n rethrowKeyingVerificationError,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { dedupeReferencedPrincipalStates } from \"../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../data/persistence/keyingCheckpointPersistence\";\nimport { ensurePrincipalPolicyTables } from \"../../data/persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../../data/persistence/principalPolicyReferencePersistence\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport type { CurrentPrincipalPolicyReader } from \"./currentPrincipalPolicyReader\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"./externalAdminPolicy\";\nimport {\n persistPrincipalPolicyCacheEntries,\n retryPrincipalPolicyCacheAdvance,\n} from \"./principalPolicyCacheAdvance\";\nimport { scopeReferencedPolicyForCache } from \"./principalPolicyCacheScope\";\nimport { validatePrincipalPolicyBundleForCache } from \"./principalPolicyCacheValidation\";\nimport {\n createPolicyDirectoryLoader,\n directoryBindsGroupReference,\n type PolicyDirectoryLoader,\n type VerifiedPolicyDirectory,\n} from \"./principalPolicyOrganizationScope\";\n\nexport interface CacheReferencedPrincipalPoliciesOptions {\n currentPolicyReader: CurrentPrincipalPolicyReader;\n execSql: ExecSql;\n log?: (message: string) => void;\n organizationId: string;\n reportSecurityIncident: SecurityIncidentReporter;\n references: ReadonlyArray<ReferencedPrincipalStateResponse> | undefined;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface CachePrincipalPolicyBundlesOptions\n extends Omit<CacheReferencedPrincipalPoliciesOptions, \"references\"> {\n bundles: ReadonlyArray<PrincipalPolicyBundleResponse> | undefined;\n}\n\nfunction getReferencedPrincipalKey(\n reference: ReferencedPrincipalStateResponse,\n): string {\n return `${reference.principalType}:${reference.principalId}`;\n}\n\nfunction getBundlePrincipalKey(bundle: PrincipalPolicyBundleResponse): string {\n return `${bundle.currentState.principalType}:${bundle.currentState.principalId}`;\n}\n\nfunction dedupePrincipalPolicyBundles(\n bundles: ReadonlyArray<PrincipalPolicyBundleResponse>,\n): PrincipalPolicyBundleResponse[] {\n const bundlesByPrincipal = new Map<string, PrincipalPolicyBundleResponse>();\n\n for (const bundle of bundles) {\n const key = getBundlePrincipalKey(bundle);\n const previous = bundlesByPrincipal.get(key);\n if (\n !previous ||\n bundle.currentState.version > previous.currentState.version\n ) {\n bundlesByPrincipal.set(key, bundle);\n }\n }\n\n return Array.from(bundlesByPrincipal.values());\n}\n\nasync function cacheReferencedPrincipalPolicy(\n execSql: ExecSql,\n reader: CurrentPrincipalPolicyReader,\n reference: ReferencedPrincipalStateResponse,\n resolveTrustedUserIdentity: TrustedUserIdentityResolver,\n log: ((message: string) => void) | undefined,\n loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>,\n organizationId: string,\n stillCurrent: (() => boolean) | undefined,\n loadDirectory: PolicyDirectoryLoader,\n fresh: boolean,\n): Promise<VerifiedPrincipalPolicy[]> {\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n reference.principalType,\n reference.principalId,\n );\n // Only null is a recoverable local miss. Integrity failures remain typed and\n // must escape rather than being hidden by a canonical network retry.\n const cachedBundle = fresh\n ? null\n : await loadPrincipalPolicyBundleForReference(\n execSql,\n reference,\n localCheckpoint,\n );\n let bundle =\n cachedBundle ??\n (await reader.getCurrentPrincipalPolicy(\n reference.principalType,\n reference.principalId,\n ));\n if (!bundle) {\n log?.(\n `Principal policy cache: failed to fetch ${getReferencedPrincipalKey(reference)}`,\n );\n return [];\n }\n\n let validation = await validatePrincipalPolicyBundleForCache({\n bundle,\n loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity,\n });\n if (!validation.ok) {\n throw validation.error;\n }\n\n const scoped = await scopeReferencedPolicyForCache({\n bundle,\n validation,\n validationInput: {\n loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity,\n },\n loadDirectory,\n organizationId,\n reloadBundle: cachedBundle\n ? () => reader.getCurrentPrincipalPolicy(\"group\", reference.principalId)\n : null,\n });\n if (!scoped) {\n log?.(\n `Principal policy cache: signed organization directory does not cover ${getReferencedPrincipalKey(reference)}`,\n );\n return [];\n }\n bundle = scoped.bundle;\n validation = scoped.validation;\n const directory = scoped.directory;\n const externalEntries = validation.externalAdminPolicy\n ? externalAdminPolicyPersistenceEntries(\n validation.externalAdminPolicy,\n ).filter(\n (entry) => !directory || entry.policy.principalType !== \"organization\",\n )\n : [];\n const directoryEntries = directory\n ? [{ bundle: directory.bundle, policy: directory.policy }]\n : [];\n await persistPrincipalPolicyCacheEntries({\n entries: [\n ...externalEntries,\n ...directoryEntries,\n { bundle, policy: validation.policy },\n ],\n execSql,\n organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent,\n });\n return [...externalEntries.map(({ policy }) => policy), validation.policy];\n}\n\nasync function cachePrincipalPolicyBundle(input: {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly execSql: ExecSql;\n readonly loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>;\n readonly log: ((message: string) => void) | undefined;\n readonly loadDirectory: PolicyDirectoryLoader;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedPrincipalPolicy[]> {\n const reference = principalPolicyReferenceFromBundle(input.bundle);\n // The API supplied this bundle after rejecting a write, but local storage is\n // only updated after normal signature, signer, and checkpoint verification.\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n reference.principalType,\n reference.principalId,\n );\n const validation = await validatePrincipalPolicyBundleForCache({\n bundle: input.bundle,\n loadExternalAdminPolicy: input.loadExternalAdminPolicy,\n localCheckpoint,\n reference,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (!validation.ok) {\n throw validation.error;\n }\n\n let directory: VerifiedPolicyDirectory | null = null;\n if (reference.principalType === \"group\") {\n directory = await input.loadDirectory(false);\n if (!directoryBindsGroupReference(directory, validation.policy, reference))\n directory = await input.loadDirectory(true);\n if (\n !directoryBindsGroupReference(directory, validation.policy, reference)\n ) {\n input.log?.(\n \"Principal policy cache: signed organization directory does not cover supplied group\",\n );\n return [];\n }\n } else if (reference.principalId !== input.organizationId) {\n return [];\n }\n const externalEntries = validation.externalAdminPolicy\n ? externalAdminPolicyPersistenceEntries(\n validation.externalAdminPolicy,\n ).filter(\n (entry) => !directory || entry.policy.principalType !== \"organization\",\n )\n : [];\n const directoryEntries = directory\n ? [{ bundle: directory.bundle, policy: directory.policy }]\n : [];\n await persistPrincipalPolicyCacheEntries({\n entries: [\n ...externalEntries,\n ...directoryEntries,\n { bundle: input.bundle, policy: validation.policy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent: input.stillCurrent,\n });\n return [...externalEntries.map(({ policy }) => policy), validation.policy];\n}\n\nasync function runPrincipalPolicyCache<Item, Result>(input: {\n readonly cacheItem: (\n item: Item,\n loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>,\n loadDirectory: PolicyDirectoryLoader,\n fresh: boolean,\n ) => Promise<readonly Result[]>;\n readonly currentPolicyReader: CurrentPrincipalPolicyReader;\n readonly dedupe: (items: ReadonlyArray<Item>) => Item[];\n readonly execSql: ExecSql;\n readonly itemKey: (item: Item) => string;\n readonly items: ReadonlyArray<Item> | undefined;\n readonly log: ((message: string) => void) | undefined;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<Result[]> {\n if (!input.items || input.items.length === 0) {\n return [];\n }\n\n try {\n await ensurePrincipalPolicyTables(input.execSql);\n const uniqueItems = input.dedupe(input.items);\n const loadDirectory = createPolicyDirectoryLoader(input);\n let externalAdminPolicy: Promise<VerifiedExternalAdminPolicy | null> | null =\n null;\n const loadExternalAdminPolicy = () => {\n externalAdminPolicy ??= loadOrganizationExternalAdminPolicy({\n currentPolicyReader: input.currentPolicyReader,\n execSql: input.execSql,\n organizationId: input.organizationId,\n\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n return externalAdminPolicy;\n };\n\n const results = await Promise.all(\n uniqueItems.map(async (item) => {\n try {\n return await retryPrincipalPolicyCacheAdvance((fresh) => {\n const reloadDirectory = createPolicyDirectoryLoader(input);\n let reloadedAuthority: Promise<VerifiedExternalAdminPolicy | null> | null =\n null;\n return input.cacheItem(\n item,\n fresh\n ? () =>\n (reloadedAuthority ??=\n loadOrganizationExternalAdminPolicy(input))\n : loadExternalAdminPolicy,\n fresh ? () => reloadDirectory(true) : loadDirectory,\n fresh,\n );\n });\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return [];\n await reportAndRethrowKeyingVerificationError(\n error,\n input.reportSecurityIncident,\n {\n objectId: input.itemKey(item),\n objectKind: \"principal\",\n operation: \"principal.policy.cache\",\n organizationId: input.organizationId,\n },\n );\n const message = errorMessage(error);\n input.log?.(\n `Principal policy cache: failed to store ${input.itemKey(item)}: ${message}`,\n );\n return [];\n }\n }),\n );\n return results.flat();\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return [];\n // Per-item verification failures were reported above before reaching this\n // initialization/aggregation boundary.\n rethrowKeyingVerificationError(error);\n const message = errorMessage(error);\n input.log?.(\n `Principal policy cache: failed to initialize cache: ${message}`,\n );\n return [];\n }\n}\n\nasync function loadReferencedPrincipalPolicies({\n currentPolicyReader,\n execSql,\n log,\n organizationId,\n reportSecurityIncident,\n references,\n resolveTrustedUserIdentity,\n stillCurrent,\n}: CacheReferencedPrincipalPoliciesOptions): Promise<\n VerifiedPrincipalPolicy[]\n> {\n return runPrincipalPolicyCache({\n cacheItem: (reference, loadExternalAdminPolicy, loadDirectory, fresh) =>\n cacheReferencedPrincipalPolicy(\n execSql,\n currentPolicyReader,\n reference,\n resolveTrustedUserIdentity,\n log,\n loadExternalAdminPolicy,\n organizationId,\n stillCurrent,\n loadDirectory,\n fresh,\n ),\n currentPolicyReader,\n dedupe: dedupeReferencedPrincipalStates,\n execSql,\n itemKey: getReferencedPrincipalKey,\n items: references,\n log,\n organizationId,\n\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n });\n}\n\nexport async function cacheReferencedPrincipalPolicies(\n input: CacheReferencedPrincipalPoliciesOptions,\n): Promise<void> {\n await loadReferencedPrincipalPolicies(input);\n}\n\nexport async function cachePrincipalPolicyBundles({\n bundles,\n currentPolicyReader,\n execSql,\n log,\n organizationId,\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n}: CachePrincipalPolicyBundlesOptions): Promise<void> {\n await runPrincipalPolicyCache({\n cacheItem: (bundle, loadExternalAdminPolicy, loadDirectory) =>\n cachePrincipalPolicyBundle({\n bundle,\n execSql,\n loadExternalAdminPolicy,\n loadDirectory,\n log,\n organizationId,\n resolveTrustedUserIdentity,\n stillCurrent,\n }),\n currentPolicyReader,\n dedupe: dedupePrincipalPolicyBundles,\n execSql,\n itemKey: getBundlePrincipalKey,\n items: bundles,\n log,\n organizationId,\n\n reportSecurityIncident,\n resolveTrustedUserIdentity,\n stillCurrent,\n });\n}\n"]}
@@ -1,13 +1,14 @@
1
- import type { ApiClient, PrincipalPolicyPageCurrent, RequestFailure } from "../../internal/api-client/index.js";
1
+ import type { PrincipalPolicyPageCurrent, RequestFailure } from "../../internal/api-client/index.js";
2
2
  import { KeyingVerificationError, type PrincipalPolicyExternalAuthority, type PrincipalPolicyHistoryProgressOptions, 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
+ import type { PrincipalPolicyPageReader } from "./principalPolicyHistoryReader.js";
5
6
  /** A locally observed race, distinct from a rejected signed predecessor. */
6
7
  export declare class PrincipalHistoryRecoveryRaceError extends KeyingVerificationError {
7
8
  constructor(message: string);
8
9
  }
9
10
  export interface RecoverPrincipalPolicyHistoryOptions {
10
- readonly apiClient: Pick<ApiClient, "getPrincipalPolicyPages">;
11
+ readonly historyReader: PrincipalPolicyPageReader;
11
12
  readonly execSql: ExecSql;
12
13
  readonly organizationId: string;
13
14
  readonly expectedHead: ReferencedPrincipalHead;
@@ -1 +1 @@
1
- {"version":3,"file":"principalHistoryRecoveryTypes.js","sourceRoot":"","sources":["principalHistoryRecoveryTypes.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,uBAAuB,GAKxB,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 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 /** Authenticate these exact authority references, including cached-prefix citations. */\n readonly loadExternalAuthority?:\n | ((\n references: readonly ReferencedPrincipalHead[],\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":"AAIA,OAAO,EACL,uBAAuB,GAKxB,MAAM,mBAAmB,CAAC;AAK3B,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 PrincipalPolicyPageCurrent,\n RequestFailure,\n} from \"@tearleads/api-client\";\nimport {\n KeyingVerificationError,\n type PrincipalPolicyExternalAuthority,\n type PrincipalPolicyHistoryProgressOptions,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport type { PrincipalPolicyPageReader } from \"./principalPolicyHistoryReader\";\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 historyReader: PrincipalPolicyPageReader;\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 /** Authenticate these exact authority references, including cached-prefix citations. */\n readonly loadExternalAuthority?:\n | ((\n references: readonly ReferencedPrincipalHead[],\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,20 @@
1
+ import type { ApiClient } from "../../internal/api-client/index.js";
2
+ /**
3
+ * Where recovery reads signed principal policy history. The API client is the
4
+ * production reader; registration reads a just-provisioned principal from its
5
+ * local bundles, and directory discovery replays a page it already fetched.
6
+ * Every page is untrusted input to the same verifier, whichever reader
7
+ * supplied it.
8
+ */
9
+ export interface PrincipalPolicyHistoryReader {
10
+ readonly getPrincipalPolicyPages: ApiClient["getPrincipalPolicyPages"];
11
+ readonly getProjectionPolicyHistoryPages: ApiClient["getProjectionPolicyHistoryPages"];
12
+ }
13
+ /** Reads one principal's own policy history. */
14
+ export type PrincipalPolicyPageReader = Pick<PrincipalPolicyHistoryReader, "getPrincipalPolicyPages">;
15
+ /** Reads an organization's public projection policy history. */
16
+ export type ProjectionPolicyHistoryReader = Pick<PrincipalPolicyHistoryReader, "getProjectionPolicyHistoryPages">;
17
+ /** The API client as a page reader, or undefined when this client has none. */
18
+ export declare function apiPrincipalPolicyPageReader(apiClient: Partial<PrincipalPolicyPageReader>): PrincipalPolicyPageReader | undefined;
19
+ /** The API client as a projection reader, or undefined when it has none. */
20
+ export declare function apiProjectionPolicyHistoryReader(apiClient: Partial<ProjectionPolicyHistoryReader>): ProjectionPolicyHistoryReader | undefined;
@@ -0,0 +1,13 @@
1
+ /** The API client as a page reader, or undefined when this client has none. */
2
+ export function apiPrincipalPolicyPageReader(apiClient) {
3
+ const getPrincipalPolicyPages = apiClient.getPrincipalPolicyPages?.bind(apiClient);
4
+ return getPrincipalPolicyPages ? { getPrincipalPolicyPages } : undefined;
5
+ }
6
+ /** The API client as a projection reader, or undefined when it has none. */
7
+ export function apiProjectionPolicyHistoryReader(apiClient) {
8
+ const getProjectionPolicyHistoryPages = apiClient.getProjectionPolicyHistoryPages?.bind(apiClient);
9
+ return getProjectionPolicyHistoryPages
10
+ ? { getProjectionPolicyHistoryPages }
11
+ : undefined;
12
+ }
13
+ //# sourceMappingURL=principalPolicyHistoryReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principalPolicyHistoryReader.js","sourceRoot":"","sources":["principalPolicyHistoryReader.ts"],"names":[],"mappings":"AA0BA,+EAA+E;AAC/E,MAAM,UAAU,4BAA4B,CAC1C,SAA6C;IAE7C,MAAM,uBAAuB,GAC3B,SAAS,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACrD,OAAO,uBAAuB,CAAC,CAAC,CAAC,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,gCAAgC,CAC9C,SAAiD;IAEjD,MAAM,+BAA+B,GACnC,SAAS,CAAC,+BAA+B,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7D,OAAO,+BAA+B;QACpC,CAAC,CAAC,EAAE,+BAA+B,EAAE;QACrC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\n\n/**\n * Where recovery reads signed principal policy history. The API client is the\n * production reader; registration reads a just-provisioned principal from its\n * local bundles, and directory discovery replays a page it already fetched.\n * Every page is untrusted input to the same verifier, whichever reader\n * supplied it.\n */\nexport interface PrincipalPolicyHistoryReader {\n readonly getPrincipalPolicyPages: ApiClient[\"getPrincipalPolicyPages\"];\n readonly getProjectionPolicyHistoryPages: ApiClient[\"getProjectionPolicyHistoryPages\"];\n}\n\n/** Reads one principal's own policy history. */\nexport type PrincipalPolicyPageReader = Pick<\n PrincipalPolicyHistoryReader,\n \"getPrincipalPolicyPages\"\n>;\n\n/** Reads an organization's public projection policy history. */\nexport type ProjectionPolicyHistoryReader = Pick<\n PrincipalPolicyHistoryReader,\n \"getProjectionPolicyHistoryPages\"\n>;\n\n/** The API client as a page reader, or undefined when this client has none. */\nexport function apiPrincipalPolicyPageReader(\n apiClient: Partial<PrincipalPolicyPageReader>,\n): PrincipalPolicyPageReader | undefined {\n const getPrincipalPolicyPages =\n apiClient.getPrincipalPolicyPages?.bind(apiClient);\n return getPrincipalPolicyPages ? { getPrincipalPolicyPages } : undefined;\n}\n\n/** The API client as a projection reader, or undefined when it has none. */\nexport function apiProjectionPolicyHistoryReader(\n apiClient: Partial<ProjectionPolicyHistoryReader>,\n): ProjectionPolicyHistoryReader | undefined {\n const getProjectionPolicyHistoryPages =\n apiClient.getProjectionPolicyHistoryPages?.bind(apiClient);\n return getProjectionPolicyHistoryPages\n ? { getProjectionPolicyHistoryPages }\n : undefined;\n}\n"]}
@@ -24,7 +24,7 @@ export function createPolicyDirectoryLoader(input) {
24
24
  if (bundle &&
25
25
  !principalPolicyHeadMeetsCheckpoint(bundle.currentState, checkpoint))
26
26
  bundle = null;
27
- bundle ??= await input.getCurrentPrincipalPolicy("organization", input.organizationId);
27
+ bundle ??= await input.currentPolicyReader.getCurrentPrincipalPolicy("organization", input.organizationId);
28
28
  if (!bundle)
29
29
  return null;
30
30
  const signers = await collectPrincipalPolicySignerPublicKeys({
@@ -1 +1 @@
1
- {"version":3,"file":"principalPolicyOrganizationScope.js","sourceRoot":"","sources":["principalPolicyOrganizationScope.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../data/persistence/keyingCheckpointPersistence\";\nimport { principalPolicyHeadMeetsCheckpoint } from \"../../data/persistence/principalPolicyCheckpointSelection\";\nimport { loadPrincipalPolicyBundle } from \"../../data/persistence/principalPolicyPersistence\";\nimport {\n type OrganizationAuthorityDescriptor,\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { verifyOrganizationAdminPolicy } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"./policyVerification\";\n\nexport interface VerifiedPolicyDirectory {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n readonly descriptor: OrganizationAuthorityDescriptor;\n}\n\nexport type PolicyDirectoryLoader = (\n remote: boolean,\n) => Promise<VerifiedPolicyDirectory | null>;\n\nexport function directoryBindsGroupReference(\n directory: VerifiedPolicyDirectory | null,\n policy: VerifiedPrincipalPolicy,\n reference: ReferencedPrincipalHead,\n): boolean {\n const head = directory?.descriptor.groupHeads.find(\n (head) => head.principalId === reference.principalId,\n );\n // A newer directory head authenticates its verified predecessors too.\n // Requiring equality with a historical manifest citation bricks old reads.\n return (\n !!head &&\n head.version >= reference.version &&\n head.version === policy.version &&\n [policy.state, ...(policy.history ?? []).map((entry) => entry.state)].some(\n (state) => principalHeadMatchesReference(state, head),\n )\n );\n}\n\nexport function createPolicyDirectoryLoader(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly getCurrentPrincipalPolicy: (\n kind: \"group\" | \"organization\",\n id: string,\n ) => Promise<PrincipalPolicyBundleResponse | null>;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}): PolicyDirectoryLoader {\n const memo = new Map<boolean, Promise<VerifiedPolicyDirectory | null>>();\n const load = async (\n remote: boolean,\n ): Promise<VerifiedPolicyDirectory | null> => {\n const checkpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"organization\",\n input.organizationId,\n );\n let bundle = remote\n ? null\n : await loadPrincipalPolicyBundle(\n input.execSql,\n \"organization\",\n input.organizationId,\n );\n if (\n bundle &&\n !principalPolicyHeadMeetsCheckpoint(bundle.currentState, checkpoint)\n )\n bundle = null;\n bundle ??= await input.getCurrentPrincipalPolicy(\n \"organization\",\n input.organizationId,\n );\n if (!bundle) return null;\n const signers = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signers) {\n if (signers.error === \"fingerprint-mismatch\")\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"organization directory signer fingerprint does not match\",\n );\n return null;\n }\n const verified = await verifyOrganizationAdminPolicy({\n bundle,\n localCheckpoint: checkpoint,\n organizationId: input.organizationId,\n signerPublicKeys: signers.signerPublicKeys,\n });\n if (!verified.ok) throw verified.error;\n let descriptor: OrganizationAuthorityDescriptor;\n try {\n descriptor = parseOrganizationAuthorityDescriptor(\n bundle.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 { bundle, policy: verified.value, descriptor };\n };\n return (remote) => {\n let pending = memo.get(remote);\n if (!pending) {\n pending = load(remote);\n memo.set(remote, pending);\n }\n return pending;\n };\n}\n"]}
1
+ {"version":3,"file":"principalPolicyOrganizationScope.js","sourceRoot":"","sources":["principalPolicyOrganizationScope.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../data/persistence/keyingCheckpointPersistence\";\nimport { principalPolicyHeadMeetsCheckpoint } from \"../../data/persistence/principalPolicyCheckpointSelection\";\nimport { loadPrincipalPolicyBundle } from \"../../data/persistence/principalPolicyPersistence\";\nimport {\n type OrganizationAuthorityDescriptor,\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { verifyOrganizationAdminPolicy } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport type { CurrentPrincipalPolicyReader } from \"./currentPrincipalPolicyReader\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"./policyVerification\";\n\nexport interface VerifiedPolicyDirectory {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n readonly descriptor: OrganizationAuthorityDescriptor;\n}\n\nexport type PolicyDirectoryLoader = (\n remote: boolean,\n) => Promise<VerifiedPolicyDirectory | null>;\n\nexport function directoryBindsGroupReference(\n directory: VerifiedPolicyDirectory | null,\n policy: VerifiedPrincipalPolicy,\n reference: ReferencedPrincipalHead,\n): boolean {\n const head = directory?.descriptor.groupHeads.find(\n (head) => head.principalId === reference.principalId,\n );\n // A newer directory head authenticates its verified predecessors too.\n // Requiring equality with a historical manifest citation bricks old reads.\n return (\n !!head &&\n head.version >= reference.version &&\n head.version === policy.version &&\n [policy.state, ...(policy.history ?? []).map((entry) => entry.state)].some(\n (state) => principalHeadMatchesReference(state, head),\n )\n );\n}\n\nexport function createPolicyDirectoryLoader(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly currentPolicyReader: CurrentPrincipalPolicyReader;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}): PolicyDirectoryLoader {\n const memo = new Map<boolean, Promise<VerifiedPolicyDirectory | null>>();\n const load = async (\n remote: boolean,\n ): Promise<VerifiedPolicyDirectory | null> => {\n const checkpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"organization\",\n input.organizationId,\n );\n let bundle = remote\n ? null\n : await loadPrincipalPolicyBundle(\n input.execSql,\n \"organization\",\n input.organizationId,\n );\n if (\n bundle &&\n !principalPolicyHeadMeetsCheckpoint(bundle.currentState, checkpoint)\n )\n bundle = null;\n bundle ??= await input.currentPolicyReader.getCurrentPrincipalPolicy(\n \"organization\",\n input.organizationId,\n );\n if (!bundle) return null;\n const signers = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signers) {\n if (signers.error === \"fingerprint-mismatch\")\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"organization directory signer fingerprint does not match\",\n );\n return null;\n }\n const verified = await verifyOrganizationAdminPolicy({\n bundle,\n localCheckpoint: checkpoint,\n organizationId: input.organizationId,\n signerPublicKeys: signers.signerPublicKeys,\n });\n if (!verified.ok) throw verified.error;\n let descriptor: OrganizationAuthorityDescriptor;\n try {\n descriptor = parseOrganizationAuthorityDescriptor(\n bundle.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 { bundle, policy: verified.value, descriptor };\n };\n return (remote) => {\n let pending = memo.get(remote);\n if (!pending) {\n pending = load(remote);\n memo.set(remote, pending);\n }\n return pending;\n };\n}\n"]}
@@ -54,10 +54,10 @@ async function discoverDirectoryHead(input) {
54
54
  return {
55
55
  head: prefix.head,
56
56
  genesis: genesis.reference,
57
- apiClient: input.apiClient,
57
+ historyReader: input.historyReader,
58
58
  };
59
59
  }
60
- for await (const result of input.apiClient.getPrincipalPolicyPages("organization", input.organizationId, { signal: input.signal })) {
60
+ for await (const result of input.historyReader.getPrincipalPolicyPages("organization", input.organizationId, { signal: input.signal })) {
61
61
  if (!result.ok)
62
62
  throw new PrincipalPolicyHistoryReadError(result);
63
63
  assertProjectionVerificationCurrent(() => !input.signal?.aborted && input.stillCurrent());
@@ -68,7 +68,7 @@ async function discoverDirectoryHead(input) {
68
68
  first.principalId !== input.organizationId)
69
69
  throw new KeyingVerificationError("missing_dependency", "Organization directory discovery requires genesis");
70
70
  return {
71
- apiClient: reusePrincipalDiscoveryPage(input.apiClient, result),
71
+ historyReader: reusePrincipalDiscoveryPage(input.historyReader, result),
72
72
  genesis: {
73
73
  principalType: first.principalType,
74
74
  principalId: first.principalId,
@@ -94,11 +94,11 @@ export async function recoverPolicyDirectory(input, references, selected) {
94
94
  ...input,
95
95
  protection: directoryHistoryProtection(input.protection),
96
96
  };
97
- const { head: expectedHead, genesis, apiClient, } = selected
97
+ const { head: expectedHead, genesis, historyReader, } = selected
98
98
  ? {
99
99
  head: exactHead(selected.policy.state),
100
100
  genesis: selected.policy.retainedHistory[0]?.state,
101
- apiClient: input.apiClient,
101
+ historyReader: input.historyReader,
102
102
  }
103
103
  : await discoverDirectoryHead(scoped);
104
104
  if (genesis?.version !== 1)
@@ -107,7 +107,7 @@ export async function recoverPolicyDirectory(input, references, selected) {
107
107
  throw new PrincipalRecoveryDirectoryAdvanced();
108
108
  const recovered = await recoverPrincipalPolicyHistory({
109
109
  ...scoped,
110
- apiClient,
110
+ historyReader,
111
111
  expectedHead,
112
112
  retainedReferences: references.some((reference) => reference.version === 1)
113
113
  ? references
@@ -1 +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 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 { directoryHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { loadVerifiedPrincipalHistoryPrefix } from \"./principalHistoryRecoveryPrefix\";\nimport {\n PrincipalPolicyHistoryReadError,\n type RecoveredPrincipalPolicyHistory,\n type RecoverPrincipalPolicyHistoryOptions,\n} from \"./principalHistoryRecoveryTypes\";\nimport { reusePrincipalDiscoveryPage } from \"./principalRecoveryDiscoveryPage\";\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\nfunction exactHead(state: ReferencedPrincipalHead): ReferencedPrincipalHead {\n return {\n principalType: state.principalType,\n principalId: state.principalId,\n version: state.version,\n stateHash: state.stateHash,\n keyEpoch: state.keyEpoch,\n keyFingerprint: state.keyFingerprint,\n };\n}\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 apiClient: PrincipalRecoveryContext[\"apiClient\"];\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 {\n head: prefix.head,\n genesis: genesis.reference,\n apiClient: input.apiClient,\n };\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 apiClient: reusePrincipalDiscoveryPage(input.apiClient, result),\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 selected?: RecoveredPolicyDirectory,\n): Promise<RecoveredPolicyDirectory> {\n const scoped = {\n ...input,\n protection: directoryHistoryProtection(input.protection),\n };\n const {\n head: expectedHead,\n genesis,\n apiClient,\n } = selected\n ? {\n head: exactHead(selected.policy.state),\n genesis: selected.policy.retainedHistory[0]?.state,\n apiClient: input.apiClient,\n }\n : await discoverDirectoryHead(scoped);\n if (genesis?.version !== 1)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization directory recovery requires verified genesis\",\n );\n if (references.some((reference) => reference.version > expectedHead.version))\n throw new PrincipalRecoveryDirectoryAdvanced();\n const recovered = await recoverPrincipalPolicyHistory({\n ...scoped,\n apiClient,\n expectedHead,\n retainedReferences: references.some((reference) => reference.version === 1)\n ? references\n : [exactHead(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"]}
1
+ {"version":3,"file":"principalRecoveryDirectory.js","sourceRoot":"","sources":["principalRecoveryDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\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 { directoryHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { loadVerifiedPrincipalHistoryPrefix } from \"./principalHistoryRecoveryPrefix\";\nimport {\n PrincipalPolicyHistoryReadError,\n type RecoveredPrincipalPolicyHistory,\n type RecoverPrincipalPolicyHistoryOptions,\n} from \"./principalHistoryRecoveryTypes\";\nimport { reusePrincipalDiscoveryPage } from \"./principalRecoveryDiscoveryPage\";\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\nfunction exactHead(state: ReferencedPrincipalHead): ReferencedPrincipalHead {\n return {\n principalType: state.principalType,\n principalId: state.principalId,\n version: state.version,\n stateHash: state.stateHash,\n keyEpoch: state.keyEpoch,\n keyFingerprint: state.keyFingerprint,\n };\n}\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 historyReader: PrincipalRecoveryContext[\"historyReader\"];\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 {\n head: prefix.head,\n genesis: genesis.reference,\n historyReader: input.historyReader,\n };\n }\n for await (const result of input.historyReader.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 historyReader: reusePrincipalDiscoveryPage(input.historyReader, result),\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 selected?: RecoveredPolicyDirectory,\n): Promise<RecoveredPolicyDirectory> {\n const scoped = {\n ...input,\n protection: directoryHistoryProtection(input.protection),\n };\n const {\n head: expectedHead,\n genesis,\n historyReader,\n } = selected\n ? {\n head: exactHead(selected.policy.state),\n genesis: selected.policy.retainedHistory[0]?.state,\n historyReader: input.historyReader,\n }\n : await discoverDirectoryHead(scoped);\n if (genesis?.version !== 1)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization directory recovery requires verified genesis\",\n );\n if (references.some((reference) => reference.version > expectedHead.version))\n throw new PrincipalRecoveryDirectoryAdvanced();\n const recovered = await recoverPrincipalPolicyHistory({\n ...scoped,\n historyReader,\n expectedHead,\n retainedReferences: references.some((reference) => reference.version === 1)\n ? references\n : [exactHead(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"]}
@@ -1,5 +1,5 @@
1
1
  /** Reuse the discovery bytes as untrusted input to the ordinary verifier. */
2
- export function reusePrincipalDiscoveryPage(apiClient, discovery) {
2
+ export function reusePrincipalDiscoveryPage(reader, discovery) {
3
3
  const first = structuredClone(discovery);
4
4
  const page = first.data;
5
5
  const current = {
@@ -16,7 +16,7 @@ export function reusePrincipalDiscoveryPage(apiClient, discovery) {
16
16
  options.stateHash !== current.currentState.stateHash ||
17
17
  principalType !== current.currentState.principalType ||
18
18
  principalId !== current.currentState.principalId) {
19
- yield* apiClient.getPrincipalPolicyPages(principalType, principalId, options);
19
+ yield* reader.getPrincipalPolicyPages(principalType, principalId, options);
20
20
  return;
21
21
  }
22
22
  yield structuredClone(first);
@@ -24,8 +24,8 @@ export function reusePrincipalDiscoveryPage(apiClient, discovery) {
24
24
  if (next === null)
25
25
  return;
26
26
  // Resume binds every later page to these exact artifacts, including bytes
27
- // outside the signed head. The API client's cursor/shape checks still run.
28
- yield* apiClient.getPrincipalPolicyPages(principalType, principalId, {
27
+ // outside the signed head. The wrapped reader's cursor/shape checks still run.
28
+ yield* reader.getPrincipalPolicyPages(principalType, principalId, {
29
29
  ...options,
30
30
  afterVersion: undefined,
31
31
  resume: { current, afterVersion: next },
@@ -1 +1 @@
1
- {"version":3,"file":"principalRecoveryDiscoveryPage.js","sourceRoot":"","sources":["principalRecoveryDiscoveryPage.ts"],"names":[],"mappings":"AAGA,6EAA6E;AAC7E,MAAM,UAAU,2BAA2B,CACzC,SAAqD,EACrD,SAAsD;IAEtD,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG;QACd,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;KACpD,CAAC;IACF,OAAO;QACL,KAAK,CAAC,CAAC,uBAAuB,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,GAAG,EAAE;YACrE,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;gBAC5B,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,KAAK,CAAC;gBACjC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,YAAY,CAAC,SAAS;gBACpD,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,aAAa;gBACpD,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,WAAW,EAChD,CAAC;gBACD,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CACtC,aAAa,EACb,WAAW,EACX,OAAO,CACR,CAAC;gBACF,OAAO;YACT,CAAC;YACD,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC;YAC/C,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO;YAC1B,0EAA0E;YAC1E,2EAA2E;YAC3E,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,aAAa,EAAE,WAAW,EAAE;gBACnE,GAAG,OAAO;gBACV,YAAY,EAAE,SAAS;gBACvB,MAAM,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE;aACxC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ApiClient, RequestSuccess } from \"@tearleads/api-client\";\nimport type { PrincipalPolicyPageResponse } from \"@tearleads/validators/response\";\n\n/** Reuse the discovery bytes as untrusted input to the ordinary verifier. */\nexport function reusePrincipalDiscoveryPage(\n apiClient: Pick<ApiClient, \"getPrincipalPolicyPages\">,\n discovery: RequestSuccess<PrincipalPolicyPageResponse>,\n): Pick<ApiClient, \"getPrincipalPolicyPages\"> {\n const first = structuredClone(discovery);\n const page = first.data;\n const current = {\n currentState: page.currentState,\n currentPayload: page.currentPayload,\n currentProjection: page.currentProjection,\n currentGrants: page.currentGrants,\n currentMemberEnvelopes: page.currentMemberEnvelopes,\n };\n return {\n async *getPrincipalPolicyPages(principalType, principalId, options = {}) {\n if (\n options.resume !== undefined ||\n (options.afterVersion ?? 0) !== 0 ||\n options.stateHash !== current.currentState.stateHash ||\n principalType !== current.currentState.principalType ||\n principalId !== current.currentState.principalId\n ) {\n yield* apiClient.getPrincipalPolicyPages(\n principalType,\n principalId,\n options,\n );\n return;\n }\n yield structuredClone(first);\n const next = page.historyPage.nextAfterVersion;\n if (next === null) return;\n // Resume binds every later page to these exact artifacts, including bytes\n // outside the signed head. The API client's cursor/shape checks still run.\n yield* apiClient.getPrincipalPolicyPages(principalType, principalId, {\n ...options,\n afterVersion: undefined,\n resume: { current, afterVersion: next },\n });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"principalRecoveryDiscoveryPage.js","sourceRoot":"","sources":["principalRecoveryDiscoveryPage.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,MAAM,UAAU,2BAA2B,CACzC,MAAiC,EACjC,SAAsD;IAEtD,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG;QACd,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;KACpD,CAAC;IACF,OAAO;QACL,KAAK,CAAC,CAAC,uBAAuB,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,GAAG,EAAE;YACrE,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;gBAC5B,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,KAAK,CAAC;gBACjC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,YAAY,CAAC,SAAS;gBACpD,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,aAAa;gBACpD,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,WAAW,EAChD,CAAC;gBACD,KAAK,CAAC,CAAC,MAAM,CAAC,uBAAuB,CACnC,aAAa,EACb,WAAW,EACX,OAAO,CACR,CAAC;gBACF,OAAO;YACT,CAAC;YACD,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC;YAC/C,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO;YAC1B,0EAA0E;YAC1E,+EAA+E;YAC/E,KAAK,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,WAAW,EAAE;gBAChE,GAAG,OAAO;gBACV,YAAY,EAAE,SAAS;gBACvB,MAAM,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE;aACxC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { RequestSuccess } from \"@tearleads/api-client\";\nimport type { PrincipalPolicyPageResponse } from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyPageReader } from \"./principalPolicyHistoryReader\";\n\n/** Reuse the discovery bytes as untrusted input to the ordinary verifier. */\nexport function reusePrincipalDiscoveryPage(\n reader: PrincipalPolicyPageReader,\n discovery: RequestSuccess<PrincipalPolicyPageResponse>,\n): PrincipalPolicyPageReader {\n const first = structuredClone(discovery);\n const page = first.data;\n const current = {\n currentState: page.currentState,\n currentPayload: page.currentPayload,\n currentProjection: page.currentProjection,\n currentGrants: page.currentGrants,\n currentMemberEnvelopes: page.currentMemberEnvelopes,\n };\n return {\n async *getPrincipalPolicyPages(principalType, principalId, options = {}) {\n if (\n options.resume !== undefined ||\n (options.afterVersion ?? 0) !== 0 ||\n options.stateHash !== current.currentState.stateHash ||\n principalType !== current.currentState.principalType ||\n principalId !== current.currentState.principalId\n ) {\n yield* reader.getPrincipalPolicyPages(\n principalType,\n principalId,\n options,\n );\n return;\n }\n yield structuredClone(first);\n const next = page.historyPage.nextAfterVersion;\n if (next === null) return;\n // Resume binds every later page to these exact artifacts, including bytes\n // outside the signed head. The wrapped reader's cursor/shape checks still run.\n yield* reader.getPrincipalPolicyPages(principalType, principalId, {\n ...options,\n afterVersion: undefined,\n resume: { current, afterVersion: next },\n });\n },\n };\n}\n"]}
@@ -1,12 +1,12 @@
1
- import type { ApiClient } from "../../internal/api-client/index.js";
2
1
  import type { PrincipalPolicyExternalAuthority, PrincipalPolicyHistoryProgressOptions, PrincipalPolicyHistoryVerifier, ReferencedPrincipalHead, VerifiedPrincipalPolicyHistory } from "../../internal/crypto/index.js";
3
2
  import type { PrincipalPolicyHistorySourceResponse } from "../../internal/validators/response/index.js";
4
3
  import type { PrincipalHistoryPrefix } from "../../data/persistence/principalHistoryPrefixPersistence.js";
5
4
  import type { PrincipalHistoryStage } from "../../data/persistence/principalHistoryStagePersistence.js";
6
5
  import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
7
6
  import type { TrustedUserIdentityResolver } from "../../data/trustedUserIdentity/index.js";
7
+ import type { ProjectionPolicyHistoryReader } from "./principalPolicyHistoryReader.js";
8
8
  export interface PublicPrincipalHistoryOptions {
9
- readonly apiClient: Pick<ApiClient, "getProjectionPolicyHistoryPages">;
9
+ readonly historyReader: ProjectionPolicyHistoryReader;
10
10
  /** Terminal proof verification defers durable currency until all artifacts authenticate. */
11
11
  readonly historicalProof?: boolean | undefined;
12
12
  readonly source: PrincipalPolicyHistorySourceResponse;
@@ -1 +1 @@
1
- {"version":3,"file":"publicPrincipalHistoryTypes.js","sourceRoot":"","sources":["publicPrincipalHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type {\n PrincipalPolicyExternalAuthority,\n PrincipalPolicyHistoryProgressOptions,\n PrincipalPolicyHistoryVerifier,\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyHistory,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyHistorySourceResponse } from \"@tearleads/validators/response\";\nimport type { PrincipalHistoryPrefix } from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport type { PrincipalHistoryStage } from \"../../data/persistence/principalHistoryStagePersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\n\nexport interface PublicPrincipalHistoryOptions {\n readonly apiClient: Pick<ApiClient, \"getProjectionPolicyHistoryPages\">;\n /** Terminal proof verification defers durable currency until all artifacts authenticate. */\n readonly historicalProof?: boolean | undefined;\n readonly source: PrincipalPolicyHistorySourceResponse;\n readonly organizationId: string;\n readonly execSql: ExecSql;\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent: () => boolean;\n readonly signal?: AbortSignal | undefined;\n readonly offline?: boolean | undefined;\n /** Retry disposable evidence loss once from signatures, without reusing hints. */\n readonly replay?: boolean | undefined;\n readonly strictAdmins?: boolean | undefined;\n /** Already verified organization binding; included in the protected cache scope. */\n readonly authorityGroupId?: string | undefined;\n readonly loadExternalAuthority?:\n | ((\n references: readonly ReferencedPrincipalHead[],\n cachedPrefix?: boolean,\n ) => Promise<PrincipalPolicyExternalAuthority | undefined>)\n | undefined;\n}\n\nexport interface PublicPrincipalHistoryProgress {\n readonly id: string;\n readonly scopeId: string;\n readonly verifier: PrincipalPolicyHistoryVerifier;\n readonly completedHead: ReferencedPrincipalHead | null;\n readonly afterVersion: number;\n readonly saved: PrincipalHistoryStage | null;\n readonly cachedPrefix: PrincipalHistoryPrefix | null;\n readonly authorityReference: ReferencedPrincipalHead | null;\n}\n\n/** Public authorization only; caller must check directory binding and local pins. */\nexport interface RecoveredPublicPrincipalHistory {\n readonly scopeId: string;\n readonly history: VerifiedPrincipalPolicyHistory;\n}\n"]}
1
+ {"version":3,"file":"publicPrincipalHistoryTypes.js","sourceRoot":"","sources":["publicPrincipalHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n PrincipalPolicyExternalAuthority,\n PrincipalPolicyHistoryProgressOptions,\n PrincipalPolicyHistoryVerifier,\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyHistory,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyHistorySourceResponse } from \"@tearleads/validators/response\";\nimport type { PrincipalHistoryPrefix } from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport type { PrincipalHistoryStage } from \"../../data/persistence/principalHistoryStagePersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport type { ProjectionPolicyHistoryReader } from \"./principalPolicyHistoryReader\";\n\nexport interface PublicPrincipalHistoryOptions {\n readonly historyReader: ProjectionPolicyHistoryReader;\n /** Terminal proof verification defers durable currency until all artifacts authenticate. */\n readonly historicalProof?: boolean | undefined;\n readonly source: PrincipalPolicyHistorySourceResponse;\n readonly organizationId: string;\n readonly execSql: ExecSql;\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent: () => boolean;\n readonly signal?: AbortSignal | undefined;\n readonly offline?: boolean | undefined;\n /** Retry disposable evidence loss once from signatures, without reusing hints. */\n readonly replay?: boolean | undefined;\n readonly strictAdmins?: boolean | undefined;\n /** Already verified organization binding; included in the protected cache scope. */\n readonly authorityGroupId?: string | undefined;\n readonly loadExternalAuthority?:\n | ((\n references: readonly ReferencedPrincipalHead[],\n cachedPrefix?: boolean,\n ) => Promise<PrincipalPolicyExternalAuthority | undefined>)\n | undefined;\n}\n\nexport interface PublicPrincipalHistoryProgress {\n readonly id: string;\n readonly scopeId: string;\n readonly verifier: PrincipalPolicyHistoryVerifier;\n readonly completedHead: ReferencedPrincipalHead | null;\n readonly afterVersion: number;\n readonly saved: PrincipalHistoryStage | null;\n readonly cachedPrefix: PrincipalHistoryPrefix | null;\n readonly authorityReference: ReferencedPrincipalHead | null;\n}\n\n/** Public authorization only; caller must check directory binding and local pins. */\nexport interface RecoveredPublicPrincipalHistory {\n readonly scopeId: string;\n readonly history: VerifiedPrincipalPolicyHistory;\n}\n"]}
@@ -186,7 +186,7 @@ async function readRecoveryPages(input, stage) {
186
186
  if (completedStageMatchesHead(stage, input.expectedHead))
187
187
  return true;
188
188
  let receivedFinalPage = false;
189
- for await (const result of input.apiClient.getPrincipalPolicyPages(input.expectedHead.principalType, input.expectedHead.principalId, {
189
+ for await (const result of input.historyReader.getPrincipalPolicyPages(input.expectedHead.principalType, input.expectedHead.principalId, {
190
190
  signal: input.signal,
191
191
  stateHash: input.expectedHead.stateHash,
192
192
  ...(stage.saved && stage.current