@tearleads/client-sdk 0.1.56 → 0.1.58

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 (59) hide show
  1. package/data/persistence/organizations/organizationAccessRevocationPersistence.js +2 -2
  2. package/data/persistence/organizations/organizationAccessRevocationPersistence.js.map +1 -1
  3. package/data/persistence/organizations/organizationReadModelPersistence.js +2 -2
  4. package/data/persistence/organizations/organizationReadModelPersistence.js.map +1 -1
  5. package/data/principals/principalPolicyCoordinator.js +40 -0
  6. package/data/principals/principalPolicyCoordinator.js.map +1 -0
  7. package/index.d.ts +4 -4
  8. package/index.js +2 -2
  9. package/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/workflows/organizations/currentOrganizationMutationRetention.js +1 -1
  12. package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -1
  13. package/workflows/organizations/index.d.ts +0 -1
  14. package/workflows/organizations/index.js +0 -1
  15. package/workflows/organizations/index.js.map +1 -1
  16. package/workflows/organizations/principalMutationJournalManagement.js +3 -3
  17. package/workflows/organizations/principalMutationJournalManagement.js.map +1 -1
  18. package/workflows/organizations/principalMutationJournalSession.js +3 -3
  19. package/workflows/organizations/principalMutationJournalSession.js.map +1 -1
  20. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +4 -24
  21. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +13 -133
  22. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
  23. package/workflows/organizations/runtimeCurrentGroupMutation.js +1 -1
  24. package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -1
  25. package/workflows/principals/acknowledgedPrincipalCurrents.d.ts +33 -0
  26. package/workflows/principals/acknowledgedPrincipalCurrents.js +140 -0
  27. package/workflows/principals/acknowledgedPrincipalCurrents.js.map +1 -0
  28. package/workflows/{organizations → principals}/acknowledgedPrincipalPredecessor.d.ts +1 -1
  29. package/workflows/{organizations → principals}/acknowledgedPrincipalPredecessor.js +1 -1
  30. package/workflows/principals/acknowledgedPrincipalPredecessor.js.map +1 -0
  31. package/workflows/principals/index.d.ts +1 -0
  32. package/workflows/principals/index.js +1 -0
  33. package/workflows/principals/index.js.map +1 -1
  34. package/workflows/{organizations → principals}/initialPrincipalCurrentPublication.js +5 -7
  35. package/workflows/principals/initialPrincipalCurrentPublication.js.map +1 -0
  36. package/workflows/principals/principalAcknowledgementChecks.d.ts +30 -0
  37. package/workflows/principals/principalAcknowledgementChecks.js +2 -0
  38. package/workflows/principals/principalAcknowledgementChecks.js.map +1 -0
  39. package/workflows/{organizations → principals}/principalCurrentPublicationSeal.js.map +1 -1
  40. package/workflows/principals/principalRecoveryMemoValidity.js +2 -2
  41. package/workflows/principals/principalRecoveryMemoValidity.js.map +1 -1
  42. package/workflows/{organizations → principals}/reconcileAcknowledgedPrincipalCurrent.js +2 -2
  43. package/workflows/principals/reconcileAcknowledgedPrincipalCurrent.js.map +1 -0
  44. package/workflows/principals/runtimePolicyRecovery.js +2 -2
  45. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  46. package/workflows/principals/runtimeProjectionPolicyRecovery.js +2 -2
  47. package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -1
  48. package/workflows/registration/provisionedPrincipalHistory.js +2 -2
  49. package/workflows/registration/provisionedPrincipalHistory.js.map +1 -1
  50. package/data/principals/principalRecoveryEpoch.js +0 -18
  51. package/data/principals/principalRecoveryEpoch.js.map +0 -1
  52. package/workflows/organizations/acknowledgedPrincipalPredecessor.js.map +0 -1
  53. package/workflows/organizations/initialPrincipalCurrentPublication.js.map +0 -1
  54. package/workflows/organizations/principalMutationJournalLane.js +0 -26
  55. package/workflows/organizations/principalMutationJournalLane.js.map +0 -1
  56. package/workflows/organizations/reconcileAcknowledgedPrincipalCurrent.js.map +0 -1
  57. package/workflows/principals/principalRecoveryQueue.js +0 -22
  58. package/workflows/principals/principalRecoveryQueue.js.map +0 -1
  59. /package/workflows/{organizations → principals}/principalCurrentPublicationSeal.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"principalMutationJournalManagement.js","sourceRoot":"","sources":["principalMutationJournalManagement.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n principalMutationJournalScopeId,\n} from \"../../data/principals/principalMutationJournal\";\nimport {\n principalMutationJournalRecordId,\n UnreadablePrincipalMutationError,\n} from \"../../data/principals/principalMutationJournalRecord\";\nimport { runPrincipalMutationJournalOperation } from \"./principalMutationJournalLane\";\nimport type { PrincipalMutationJournalContext } from \"./principalMutationJournalSession\";\n\nexport interface PrincipalMutationRecoveryApi {\n readonly readPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<AuthoredPrincipalMutation | null>;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n readonly abandonPendingPrincipalMutation: (\n organizationId: string,\n mutation: AuthoredPrincipalMutation,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n readonly discardUnreadablePrincipalMutation: (\n organizationId: string,\n recordId: string,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n}\n\ntype JournalIdentity = Pick<\n PrincipalMutationJournalContext,\n \"execSql\" | \"scope\" | \"signingKeyPair\" | \"stillCurrent\"\n>;\n\nasync function loadAuthenticatedMutation(input: JournalIdentity) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n let mutation: AuthoredPrincipalMutation;\n try {\n mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!(error instanceof KeyingVerificationError)) throw error;\n const recordId = await principalMutationJournalRecordId(row);\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new UnreadablePrincipalMutationError(\n recordId,\n error.code === \"invalid_shape\" ? \"format\" : \"authentication\",\n );\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { row, mutation };\n}\n\n/** Discard only the inspected unreadable bytes; never parse them for submission. */\nexport async function discardUnreadableJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly recordId: string;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Discarding unreadable work requires acknowledging its unknown outcome\",\n );\n const expected = input.recordId;\n return runPrincipalMutationJournalOperation(\n input.execSql,\n input.scope,\n async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return false;\n if ((await principalMutationJournalRecordId(row)) !== expected)\n throw new Error(\n \"The unreadable principal mutation changed after inspection\",\n );\n let unreadable = false;\n try {\n await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n if (!(error instanceof KeyingVerificationError)) throw error;\n unreadable = true;\n }\n if (!unreadable)\n throw new Error(\n \"Readable principal mutations require ordinary abandonment\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The unreadable principal mutation changed during discard\",\n );\n return true;\n },\n );\n}\n\n/** Inspect authenticated authored work without retrying it or changing checkpoints. */\nexport async function readJournaledPrincipalMutation(\n input: JournalIdentity,\n): Promise<AuthoredPrincipalMutation | null> {\n // Inspection may observe an owned dispatch; all mutations still use the lane.\n return (await loadAuthenticatedMutation(input))?.mutation ?? null;\n}\n\n/**\n * An explicit host/user choice to stop retries, not a claim that the write failed.\n * The exact inspected request must still own the lane; ordinary recovery never\n * calls this. Future authoring must still verify the latest policy state.\n */\nexport async function abandonJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly mutation: AuthoredPrincipalMutation;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Abandoning authored work requires acknowledging its unknown outcome\",\n );\n const expected = canonicalKeyingJsonString(\n JSON.parse(JSON.stringify(input.mutation)),\n \"inspected authored mutation\",\n );\n return runPrincipalMutationJournalOperation(\n input.execSql,\n input.scope,\n async () => {\n const saved = await loadAuthenticatedMutation(input);\n if (!saved) return false;\n if (\n canonicalKeyingJsonString(saved.mutation, \"saved authored mutation\") !==\n expected\n )\n throw new Error(\n \"The pending principal mutation changed after inspection\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row: saved.row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The pending principal mutation changed during abandonment\",\n );\n return true;\n },\n );\n}\n"]}
1
+ {"version":3,"file":"principalMutationJournalManagement.js","sourceRoot":"","sources":["principalMutationJournalManagement.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n principalMutationJournalScopeId,\n} from \"../../data/principals/principalMutationJournal\";\nimport {\n principalMutationJournalRecordId,\n UnreadablePrincipalMutationError,\n} from \"../../data/principals/principalMutationJournalRecord\";\nimport { getOrCreatePrincipalPolicyCoordinator } from \"../../data/principals/principalPolicyCoordinator\";\nimport type { PrincipalMutationJournalContext } from \"./principalMutationJournalSession\";\n\nexport interface PrincipalMutationRecoveryApi {\n readonly readPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<AuthoredPrincipalMutation | null>;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n readonly abandonPendingPrincipalMutation: (\n organizationId: string,\n mutation: AuthoredPrincipalMutation,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n readonly discardUnreadablePrincipalMutation: (\n organizationId: string,\n recordId: string,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n}\n\ntype JournalIdentity = Pick<\n PrincipalMutationJournalContext,\n \"execSql\" | \"scope\" | \"signingKeyPair\" | \"stillCurrent\"\n>;\n\nasync function loadAuthenticatedMutation(input: JournalIdentity) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n let mutation: AuthoredPrincipalMutation;\n try {\n mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!(error instanceof KeyingVerificationError)) throw error;\n const recordId = await principalMutationJournalRecordId(row);\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new UnreadablePrincipalMutationError(\n recordId,\n error.code === \"invalid_shape\" ? \"format\" : \"authentication\",\n );\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { row, mutation };\n}\n\n/** Discard only the inspected unreadable bytes; never parse them for submission. */\nexport async function discardUnreadableJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly recordId: string;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Discarding unreadable work requires acknowledging its unknown outcome\",\n );\n const expected = input.recordId;\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return false;\n if ((await principalMutationJournalRecordId(row)) !== expected)\n throw new Error(\n \"The unreadable principal mutation changed after inspection\",\n );\n let unreadable = false;\n try {\n await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n if (!(error instanceof KeyingVerificationError)) throw error;\n unreadable = true;\n }\n if (!unreadable)\n throw new Error(\n \"Readable principal mutations require ordinary abandonment\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The unreadable principal mutation changed during discard\",\n );\n return true;\n });\n}\n\n/** Inspect authenticated authored work without retrying it or changing checkpoints. */\nexport async function readJournaledPrincipalMutation(\n input: JournalIdentity,\n): Promise<AuthoredPrincipalMutation | null> {\n // Inspection may observe an owned dispatch; all mutations still use the lane.\n return (await loadAuthenticatedMutation(input))?.mutation ?? null;\n}\n\n/**\n * An explicit host/user choice to stop retries, not a claim that the write failed.\n * The exact inspected request must still own the lane; ordinary recovery never\n * calls this. Future authoring must still verify the latest policy state.\n */\nexport async function abandonJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly mutation: AuthoredPrincipalMutation;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Abandoning authored work requires acknowledging its unknown outcome\",\n );\n const expected = canonicalKeyingJsonString(\n JSON.parse(JSON.stringify(input.mutation)),\n \"inspected authored mutation\",\n );\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n const saved = await loadAuthenticatedMutation(input);\n if (!saved) return false;\n if (\n canonicalKeyingJsonString(saved.mutation, \"saved authored mutation\") !==\n expected\n )\n throw new Error(\n \"The pending principal mutation changed after inspection\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row: saved.row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The pending principal mutation changed during abandonment\",\n );\n return true;\n });\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
2
2
  import { claimPrincipalMutationJournal, clearPrincipalMutationJournal, loadPrincipalMutationJournal, } from "../../data/persistence/principalMutationJournalPersistence.js";
3
3
  import { openPrincipalMutation, principalMutationJournalScopeId, sealPrincipalMutation, } from "../../data/principals/principalMutationJournal.js";
4
- import { runPrincipalMutationJournalOperation } from "./principalMutationJournalLane.js";
4
+ import { getOrCreatePrincipalPolicyCoordinator } from "../../data/principals/principalPolicyCoordinator.js";
5
5
  import { assertAuthoredPrincipalOperationReceipt, } from "./principalOperationReceipt.js";
6
6
  export class PrincipalMutationOutcomeUnknownError extends Error {
7
7
  constructor(options) {
@@ -57,7 +57,7 @@ async function submitSavedMutation(input, row, recovering) {
57
57
  }
58
58
  /** No HTTP begins until the exact authored request is durably claimed. */
59
59
  export async function submitJournaledPrincipalMutation(input) {
60
- return runPrincipalMutationJournalOperation(input.execSql, input.scope, async () => {
60
+ return getOrCreatePrincipalPolicyCoordinator(input.execSql).runJournalOperation(input.scope, async () => {
61
61
  assertProjectionVerificationCurrent(input.stillCurrent);
62
62
  const row = await sealPrincipalMutation(input);
63
63
  await claimPrincipalMutationJournal({
@@ -70,7 +70,7 @@ export async function submitJournaledPrincipalMutation(input) {
70
70
  }
71
71
  /** Retry only authenticated saved bytes, never an application mutation callback. */
72
72
  export async function recoverJournaledPrincipalMutation(input) {
73
- return runPrincipalMutationJournalOperation(input.execSql, input.scope, async () => {
73
+ return getOrCreatePrincipalPolicyCoordinator(input.execSql).runJournalOperation(input.scope, async () => {
74
74
  assertProjectionVerificationCurrent(input.stillCurrent);
75
75
  const row = await loadPrincipalMutationJournal(input.execSql, await principalMutationJournalScopeId(input.scope));
76
76
  assertProjectionVerificationCurrent(input.stillCurrent);
@@ -1 +1 @@
1
- {"version":3,"file":"principalMutationJournalSession.js","sourceRoot":"","sources":["principalMutationJournalSession.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,GAE7B,MAAM,4DAA4D,CAAC;AACpE,OAAO,EAEL,qBAAqB,EAErB,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,gDAAgD,CAAC;AAExD,OAAO,EAAE,oCAAoC,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EACL,uCAAuC,GAExC,MAAM,6BAA6B,CAAC;AAcrC,MAAM,OAAO,oCAAqC,SAAQ,KAAK;IAC7D,YAAY,OAAsB;QAChC,KAAK,CACH,wHAAwH,EACxH,OAAO,CACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sCAAsC,CAAC;IACrD,CAAC;CACF;AAED,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,8EAA8E;IAC9E,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CACL,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QACtD,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG;YACpB,MAAM,CAAC,IAAI,KAAK,2CAA2C,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,KAAsC,EACtC,GAAgC,EAChC,UAAmB;IAEnB,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC;QAC3C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG;QACH,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,gBAAgB;KACxD,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,6EAA6E;IAC7E,qEAAqE;IACrE,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,IAAI,oCAAoC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,MAAM,uCAAuC,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,4EAA4E;QAC5E,2EAA2E;QAC3E,MAAM,IAAI,oCAAoC,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,6BAA6B,CAAC;QAClC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG;QACH,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,KAEC;IAED,OAAO,oCAAoC,CACzC,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,EACX,KAAK,IAAI,EAAE;QACT,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,6BAA6B,CAAC;YAClC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG;YACH,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC,CACF,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,KAAsC;IAKtC,OAAO,oCAAoC,CACzC,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,EACX,KAAK,IAAI,EAAE;QACT,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,4BAA4B,CAC5C,KAAK,CAAC,OAAO,EACb,MAAM,+BAA+B,CAAC,KAAK,CAAC,KAAK,CAAC,CACnD,CAAC;QACF,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,oCAAoC,EAAE,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { RequestResult } from \"@tearleads/api-client\";\nimport type { SigningKeyPair } from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n claimPrincipalMutationJournal,\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n type PrincipalMutationJournalRow,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n type PrincipalMutationJournalScope,\n principalMutationJournalScopeId,\n sealPrincipalMutation,\n} from \"../../data/principals/principalMutationJournal\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { runPrincipalMutationJournalOperation } from \"./principalMutationJournalLane\";\nimport {\n assertAuthoredPrincipalOperationReceipt,\n type PrincipalMutationResponse,\n} from \"./principalOperationReceipt\";\n\ntype MutationResult = RequestResult<PrincipalMutationResponse>;\n\nexport interface PrincipalMutationJournalContext {\n readonly execSql: ExecSql;\n readonly scope: PrincipalMutationJournalScope;\n readonly signingKeyPair: SigningKeyPair;\n readonly stillCurrent: () => boolean;\n readonly submit: (\n mutation: AuthoredPrincipalMutation,\n ) => Promise<MutationResult>;\n}\n\nexport class PrincipalMutationOutcomeUnknownError extends Error {\n constructor(options?: ErrorOptions) {\n super(\n \"A saved policy request may have committed; resolve its outcome or explicitly abandon its retry before another mutation\",\n options,\n );\n this.name = \"PrincipalMutationOutcomeUnknownError\";\n }\n}\n\nfunction knownInitialRefusal(result: MutationResult): boolean {\n if (result.ok) return false;\n // ApiClient separates pre-dispatch cancellation from an uncertain sent write.\n if (result.kind === \"cancelled\") return true;\n if (result.kind !== \"http\") return false;\n return (\n [400, 401, 402, 403, 409].includes(result.status ?? 0) ||\n (result.status === 503 &&\n result.code === \"principal_history_preparation_unavailable\")\n );\n}\n\nasync function submitSavedMutation(\n input: PrincipalMutationJournalContext,\n row: PrincipalMutationJournalRow,\n recovering: boolean,\n): Promise<{ mutation: AuthoredPrincipalMutation; result: MutationResult }> {\n const mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n // Keep the authenticated copy for acknowledgement checks even if a transport\n // mutates its argument while preparing or retrying the HTTP request.\n let result: MutationResult;\n try {\n result = await input.submit(structuredClone(mutation));\n } catch (cause) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new PrincipalMutationOutcomeUnknownError({ cause });\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (result.ok) {\n await assertAuthoredPrincipalOperationReceipt(mutation, result.data);\n } else if (recovering || !knownInitialRefusal(result)) {\n // A refusal today (including loss of admin access) cannot establish whether\n // an earlier disconnected attempt committed. Preserve the original intent.\n throw new PrincipalMutationOutcomeUnknownError();\n }\n await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { mutation, result };\n}\n\n/** No HTTP begins until the exact authored request is durably claimed. */\nexport async function submitJournaledPrincipalMutation(\n input: PrincipalMutationJournalContext & {\n readonly mutation: AuthoredPrincipalMutation;\n },\n): Promise<MutationResult> {\n return runPrincipalMutationJournalOperation(\n input.execSql,\n input.scope,\n async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await sealPrincipalMutation(input);\n await claimPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n return (await submitSavedMutation(input, row, false)).result;\n },\n );\n}\n\n/** Retry only authenticated saved bytes, never an application mutation callback. */\nexport async function recoverJournaledPrincipalMutation(\n input: PrincipalMutationJournalContext,\n): Promise<{\n readonly mutation: AuthoredPrincipalMutation;\n readonly response: PrincipalMutationResponse;\n} | null> {\n return runPrincipalMutationJournalOperation(\n input.execSql,\n input.scope,\n async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n const { mutation, result } = await submitSavedMutation(input, row, true);\n if (!result.ok) throw new PrincipalMutationOutcomeUnknownError();\n return { mutation, response: result.data };\n },\n );\n}\n"]}
1
+ {"version":3,"file":"principalMutationJournalSession.js","sourceRoot":"","sources":["principalMutationJournalSession.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,GAE7B,MAAM,4DAA4D,CAAC;AACpE,OAAO,EAEL,qBAAqB,EAErB,+BAA+B,EAC/B,qBAAqB,GACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,qCAAqC,EAAE,MAAM,kDAAkD,CAAC;AAEzG,OAAO,EACL,uCAAuC,GAExC,MAAM,6BAA6B,CAAC;AAcrC,MAAM,OAAO,oCAAqC,SAAQ,KAAK;IAC7D,YAAY,OAAsB;QAChC,KAAK,CACH,wHAAwH,EACxH,OAAO,CACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sCAAsC,CAAC;IACrD,CAAC;CACF;AAED,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC5B,8EAA8E;IAC9E,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CACL,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QACtD,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG;YACpB,MAAM,CAAC,IAAI,KAAK,2CAA2C,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,KAAsC,EACtC,GAAgC,EAChC,UAAmB;IAEnB,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC;QAC3C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG;QACH,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,gBAAgB;KACxD,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,6EAA6E;IAC7E,qEAAqE;IACrE,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,IAAI,oCAAoC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,MAAM,uCAAuC,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;SAAM,IAAI,UAAU,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,4EAA4E;QAC5E,2EAA2E;QAC3E,MAAM,IAAI,oCAAoC,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,6BAA6B,CAAC;QAClC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG;QACH,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,KAEC;IAED,OAAO,qCAAqC,CAC1C,KAAK,CAAC,OAAO,CACd,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QAC5C,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,6BAA6B,CAAC;YAClC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG;YACH,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,KAAsC;IAKtC,OAAO,qCAAqC,CAC1C,KAAK,CAAC,OAAO,CACd,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;QAC5C,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,4BAA4B,CAC5C,KAAK,CAAC,OAAO,EACb,MAAM,+BAA+B,CAAC,KAAK,CAAC,KAAK,CAAC,CACnD,CAAC;QACF,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,oCAAoC,EAAE,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { RequestResult } from \"@tearleads/api-client\";\nimport type { SigningKeyPair } from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n claimPrincipalMutationJournal,\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n type PrincipalMutationJournalRow,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n type PrincipalMutationJournalScope,\n principalMutationJournalScopeId,\n sealPrincipalMutation,\n} from \"../../data/principals/principalMutationJournal\";\nimport { getOrCreatePrincipalPolicyCoordinator } from \"../../data/principals/principalPolicyCoordinator\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n assertAuthoredPrincipalOperationReceipt,\n type PrincipalMutationResponse,\n} from \"./principalOperationReceipt\";\n\ntype MutationResult = RequestResult<PrincipalMutationResponse>;\n\nexport interface PrincipalMutationJournalContext {\n readonly execSql: ExecSql;\n readonly scope: PrincipalMutationJournalScope;\n readonly signingKeyPair: SigningKeyPair;\n readonly stillCurrent: () => boolean;\n readonly submit: (\n mutation: AuthoredPrincipalMutation,\n ) => Promise<MutationResult>;\n}\n\nexport class PrincipalMutationOutcomeUnknownError extends Error {\n constructor(options?: ErrorOptions) {\n super(\n \"A saved policy request may have committed; resolve its outcome or explicitly abandon its retry before another mutation\",\n options,\n );\n this.name = \"PrincipalMutationOutcomeUnknownError\";\n }\n}\n\nfunction knownInitialRefusal(result: MutationResult): boolean {\n if (result.ok) return false;\n // ApiClient separates pre-dispatch cancellation from an uncertain sent write.\n if (result.kind === \"cancelled\") return true;\n if (result.kind !== \"http\") return false;\n return (\n [400, 401, 402, 403, 409].includes(result.status ?? 0) ||\n (result.status === 503 &&\n result.code === \"principal_history_preparation_unavailable\")\n );\n}\n\nasync function submitSavedMutation(\n input: PrincipalMutationJournalContext,\n row: PrincipalMutationJournalRow,\n recovering: boolean,\n): Promise<{ mutation: AuthoredPrincipalMutation; result: MutationResult }> {\n const mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n // Keep the authenticated copy for acknowledgement checks even if a transport\n // mutates its argument while preparing or retrying the HTTP request.\n let result: MutationResult;\n try {\n result = await input.submit(structuredClone(mutation));\n } catch (cause) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new PrincipalMutationOutcomeUnknownError({ cause });\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (result.ok) {\n await assertAuthoredPrincipalOperationReceipt(mutation, result.data);\n } else if (recovering || !knownInitialRefusal(result)) {\n // A refusal today (including loss of admin access) cannot establish whether\n // an earlier disconnected attempt committed. Preserve the original intent.\n throw new PrincipalMutationOutcomeUnknownError();\n }\n await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { mutation, result };\n}\n\n/** No HTTP begins until the exact authored request is durably claimed. */\nexport async function submitJournaledPrincipalMutation(\n input: PrincipalMutationJournalContext & {\n readonly mutation: AuthoredPrincipalMutation;\n },\n): Promise<MutationResult> {\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await sealPrincipalMutation(input);\n await claimPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n return (await submitSavedMutation(input, row, false)).result;\n });\n}\n\n/** Retry only authenticated saved bytes, never an application mutation callback. */\nexport async function recoverJournaledPrincipalMutation(\n input: PrincipalMutationJournalContext,\n): Promise<{\n readonly mutation: AuthoredPrincipalMutation;\n readonly response: PrincipalMutationResponse;\n} | null> {\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n const { mutation, result } = await submitSavedMutation(input, row, true);\n if (!result.ok) throw new PrincipalMutationOutcomeUnknownError();\n return { mutation, response: result.data };\n });\n}\n"]}
@@ -1,26 +1,6 @@
1
- import { type VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
2
- import type { PutPrincipalPolicyRequest } from "../../internal/validators/request/index.js";
3
- import type { PrincipalPolicyMutationResponse } from "../../internal/validators/response/index.js";
4
- import { type AcknowledgedPrincipalCurrentRetirement } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
5
- import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
6
- import type { RecoverPrincipalPolicyHistoryOptions } from "../principals/principalHistoryRecoveryTypes.js";
7
- import { type AcknowledgedPrincipalPredecessor } from "./acknowledgedPrincipalPredecessor.js";
1
+ import type { VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
2
+ import { type AcknowledgedPrincipalCurrentBatch } from "../principals/acknowledgedPrincipalCurrents.js";
8
3
  export type { AcknowledgedPrincipalCurrentRetirement } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
9
- export interface AcknowledgedPrincipalCurrentInput {
10
- /** Capture before submitting the mutation; null only for a new group. */
11
- readonly predecessor: AcknowledgedPrincipalPredecessor | null;
12
- /** Only a newly authored group at version one; never skips a predecessor. */
13
- readonly initialGroup?: boolean | undefined;
14
- /** The same scoped protection and verification mode used to recover the predecessor. */
15
- readonly recovery: Omit<RecoverPrincipalPolicyHistoryOptions, "execSql" | "organizationId" | "stillCurrent">;
16
- readonly request: PutPrincipalPolicyRequest;
17
- readonly response: PrincipalPolicyMutationResponse;
18
- }
4
+ export type { AcknowledgedPrincipalCurrentInput } from "../principals/acknowledgedPrincipalCurrents.js";
19
5
  /** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */
20
- export declare function retainAcknowledgedPrincipalCurrents(input: {
21
- readonly execSql: ExecSql;
22
- readonly organizationId: string;
23
- readonly entries: readonly AcknowledgedPrincipalCurrentInput[];
24
- readonly retirements?: readonly AcknowledgedPrincipalCurrentRetirement[] | undefined;
25
- readonly stillCurrent: () => boolean;
26
- }): Promise<VerifiedPrincipalPolicyCurrent[]>;
6
+ export declare function retainAcknowledgedPrincipalCurrents(input: AcknowledgedPrincipalCurrentBatch): Promise<VerifiedPrincipalPolicyCurrent[]>;
@@ -1,140 +1,20 @@
1
- import { KeyingVerificationError, } from "../../internal/crypto/index.js";
2
- import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
- import { PrincipalAcknowledgementChangedError, persistAcknowledgedPrincipalCurrents, } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
4
- import { preparePrincipalHistoryEvidencePage } from "../../data/persistence/principalHistoryEvidencePersistence.js";
5
- import { ownPrincipalHistoryProtection } from "../../data/principals/principalHistoryProtection.js";
6
- import { collectPrincipalPolicySignerPublicKeys } from "../principals/policyVerification.js";
7
- import { assertPrincipalHistoryVerificationMode, principalHistoryVerificationContext, } from "../principals/principalHistoryRecoveryVerification.js";
1
+ import { recordAcknowledgedPrincipalCurrents, } from "../principals/acknowledgedPrincipalCurrents.js";
8
2
  import { assertAcknowledgedDirectoryBindings } from "./acknowledgedDirectoryBindings.js";
9
- import { restoreAcknowledgedPrincipalPredecessor, } from "./acknowledgedPrincipalPredecessor.js";
10
3
  import { acknowledgeGroupPolicyState } from "./groupPolicyMutationAcknowledgement.js";
11
4
  import { groupPolicyMutationHead } from "./groupPolicyMutationHead.js";
12
- import { prepareInitialGroupCurrentPublication } from "./initialPrincipalCurrentPublication.js";
13
- import { sealPrincipalCurrentPublication, sealPrincipalCurrentStage, } from "./principalCurrentPublicationSeal.js";
14
5
  import { assertPrincipalPolicyReceiptArtifacts } from "./principalPolicyReceiptArtifacts.js";
15
- import { reconcileAcknowledgedPrincipalCurrent } from "./reconcileAcknowledgedPrincipalCurrent.js";
16
- async function preparePublication(options, request, response, predecessor) {
17
- options = {
18
- ...options,
19
- protection: {
20
- ...options.protection,
21
- context: principalHistoryVerificationContext(options),
22
- },
23
- };
24
- const current = () => !options.signal?.aborted && options.stillCurrent();
25
- assertProjectionVerificationCurrent(current);
26
- const { scopeId, saved, artifacts, verifier, previous, predecessorIndexRootHash, } = await restoreAcknowledgedPrincipalPredecessor(options, predecessor);
27
- const expectedHead = await groupPolicyMutationHead(request);
28
- assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });
29
- const keys = await collectPrincipalPolicySignerPublicKeys({
30
- bundle: { currentState: response.currentState, previousStates: [] },
31
- resolveTrustedUserIdentity: options.resolveTrustedUserIdentity,
32
- });
33
- assertProjectionVerificationCurrent(current);
34
- if ("error" in keys)
35
- throw new KeyingVerificationError(keys.error === "not-found" ? "missing_dependency" : "signer_mismatch", "Acknowledged principal signer could not be authenticated");
36
- const externalAuthority = await options.loadExternalAuthority?.(request.state.externalAuthority ? [request.state.externalAuthority] : []);
37
- assertProjectionVerificationCurrent(current);
38
- const policy = await acknowledgeGroupPolicyState({
39
- verifiedCurrentPolicy: previous,
40
- expectedHead,
41
- request,
42
- response: response.currentState,
43
- signerPublicKeys: keys.signerPublicKeys,
44
- externalAuthority,
45
- stillCurrent: current,
46
- });
47
- const entry = {
48
- state: response.currentState,
49
- projection: response.currentProjection,
50
- grants: response.currentGrants,
51
- };
52
- assertPrincipalHistoryVerificationMode(options, [entry]);
53
- const predecessorStage = await sealPrincipalCurrentStage(options, previous.state, verifier, artifacts);
54
- const appended = await verifier.append({
55
- entries: [entry],
56
- signerPublicKeys: keys.signerPublicKeys,
57
- ...(externalAuthority ? { externalAuthority } : {}),
58
- });
59
- if (!appended.ok)
60
- throw appended.error;
61
- const sealed = await sealPrincipalCurrentPublication(options, scopeId, expectedHead, verifier, response);
62
- assertProjectionVerificationCurrent(current);
63
- return {
64
- policy,
65
- previousPrefixProgress: saved.progress,
66
- predecessorStage,
67
- predecessorIndexRootHash,
68
- ...sealed,
69
- evidence: await preparePrincipalHistoryEvidencePage({
70
- indexRootHash: appended.value.indexRootHash,
71
- scopeId,
72
- organizationId: options.organizationId,
73
- entries: [entry],
74
- nodes: appended.value.indexNodes,
75
- }),
76
- };
77
- }
6
+ /** How organization and group mutations check an acknowledgement they authored. */
7
+ const principalAcknowledgementChecks = {
8
+ authoredHead: groupPolicyMutationHead,
9
+ assertReceipt: assertPrincipalPolicyReceiptArtifacts,
10
+ acknowledgeSuccessor: (input) => acknowledgeGroupPolicyState(input),
11
+ assertDirectoryBindings: assertAcknowledgedDirectoryBindings,
12
+ };
78
13
  /** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */
79
- export async function retainAcknowledgedPrincipalCurrents(input) {
80
- const execSql = input.execSql;
81
- const organizationId = input.organizationId;
82
- const stillCurrent = input.stillCurrent;
83
- const retirements = structuredClone(input.retirements ?? []);
84
- const entries = [];
85
- try {
86
- assertProjectionVerificationCurrent(stillCurrent);
87
- for (const entry of input.entries)
88
- entries.push({
89
- initialGroup: entry.initialGroup === true,
90
- predecessor: structuredClone(entry.predecessor),
91
- request: structuredClone(entry.request),
92
- response: structuredClone(entry.response),
93
- options: {
94
- ...entry.recovery,
95
- expectedHead: structuredClone(entry.recovery.expectedHead),
96
- protection: ownPrincipalHistoryProtection(entry.recovery.protection),
97
- execSql,
98
- organizationId,
99
- stillCurrent,
100
- },
101
- });
102
- const publications = [];
103
- for (const entry of entries)
104
- publications.push(await (entry.initialGroup
105
- ? prepareInitialGroupCurrentPublication
106
- : preparePublication)(entry.options, entry.request, entry.response, entry.predecessor));
107
- assertAcknowledgedDirectoryBindings(organizationId, entries.map(({ response }) => response));
108
- for (let attempt = 0;; attempt += 1) {
109
- const reconciled = [];
110
- for (const [index, publication] of publications.entries()) {
111
- const entry = entries[index];
112
- if (!entry)
113
- throw new Error("Missing acknowledgement entry");
114
- reconciled.push(await reconcileAcknowledgedPrincipalCurrent(entry.options, publication));
115
- }
116
- try {
117
- await persistAcknowledgedPrincipalCurrents({
118
- execSql,
119
- organizationId,
120
- entries: reconciled,
121
- retirements,
122
- stillCurrent: () => stillCurrent() &&
123
- entries.every((entry) => !entry.options.signal?.aborted),
124
- });
125
- break;
126
- }
127
- catch (error) {
128
- if (!(error instanceof PrincipalAcknowledgementChangedError) ||
129
- attempt >= 7)
130
- throw error;
131
- }
132
- }
133
- return publications.map(({ policy }) => policy);
134
- }
135
- finally {
136
- for (const entry of entries)
137
- entry.options.protection.localKey.fill(0);
138
- }
14
+ export function retainAcknowledgedPrincipalCurrents(input) {
15
+ return recordAcknowledgedPrincipalCurrents({
16
+ ...input,
17
+ checks: principalAcknowledgementChecks,
18
+ });
139
19
  }
140
20
  //# sourceMappingURL=retainAcknowledgedPrincipalCurrents.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retainAcknowledgedPrincipalCurrents.js","sourceRoot":"","sources":["retainAcknowledgedPrincipalCurrents.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n type AcknowledgedPrincipalCurrentPublication,\n type AcknowledgedPrincipalCurrentRetirement,\n PrincipalAcknowledgementChangedError,\n persistAcknowledgedPrincipalCurrents,\n} from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { ownPrincipalHistoryProtection } from \"../../data/principals/principalHistoryProtection\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport { assertAcknowledgedDirectoryBindings } from \"./acknowledgedDirectoryBindings\";\nimport {\n type AcknowledgedPrincipalPredecessor,\n restoreAcknowledgedPrincipalPredecessor,\n} from \"./acknowledgedPrincipalPredecessor\";\nimport { acknowledgeGroupPolicyState } from \"./groupPolicyMutationAcknowledgement\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { prepareInitialGroupCurrentPublication } from \"./initialPrincipalCurrentPublication\";\nimport {\n sealPrincipalCurrentPublication,\n sealPrincipalCurrentStage,\n} from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\nimport { reconcileAcknowledgedPrincipalCurrent } from \"./reconcileAcknowledgedPrincipalCurrent\";\n\nexport type { AcknowledgedPrincipalCurrentRetirement } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\n\nexport interface AcknowledgedPrincipalCurrentInput {\n /** Capture before submitting the mutation; null only for a new group. */\n readonly predecessor: AcknowledgedPrincipalPredecessor | null;\n /** Only a newly authored group at version one; never skips a predecessor. */\n readonly initialGroup?: boolean | undefined;\n /** The same scoped protection and verification mode used to recover the predecessor. */\n readonly recovery: Omit<\n RecoverPrincipalPolicyHistoryOptions,\n \"execSql\" | \"organizationId\" | \"stillCurrent\"\n >;\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n}\n\nasync function preparePublication(\n options: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n predecessor: AcknowledgedPrincipalPredecessor | null,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n options = {\n ...options,\n protection: {\n ...options.protection,\n context: principalHistoryVerificationContext(options),\n },\n };\n const current = () => !options.signal?.aborted && options.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const {\n scopeId,\n saved,\n artifacts,\n verifier,\n previous,\n predecessorIndexRootHash,\n } = await restoreAcknowledgedPrincipalPredecessor(options, predecessor);\n const expectedHead = await groupPolicyMutationHead(request);\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: options.resolveTrustedUserIdentity,\n });\n assertProjectionVerificationCurrent(current);\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n keys.error === \"not-found\" ? \"missing_dependency\" : \"signer_mismatch\",\n \"Acknowledged principal signer could not be authenticated\",\n );\n const externalAuthority = await options.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const policy = await acknowledgeGroupPolicyState({\n verifiedCurrentPolicy: previous,\n expectedHead,\n request,\n response: response.currentState,\n signerPublicKeys: keys.signerPublicKeys,\n externalAuthority,\n stillCurrent: current,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(options, [entry]);\n const predecessorStage = await sealPrincipalCurrentStage(\n options,\n previous.state,\n verifier,\n artifacts,\n );\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n policy,\n previousPrefixProgress: saved.progress,\n predecessorStage,\n predecessorIndexRootHash,\n ...sealed,\n evidence: await preparePrincipalHistoryEvidencePage({\n indexRootHash: appended.value.indexRootHash,\n scopeId,\n organizationId: options.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n\n/** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */\nexport async function retainAcknowledgedPrincipalCurrents(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly entries: readonly AcknowledgedPrincipalCurrentInput[];\n readonly retirements?:\n | readonly AcknowledgedPrincipalCurrentRetirement[]\n | undefined;\n readonly stillCurrent: () => boolean;\n}): Promise<VerifiedPrincipalPolicyCurrent[]> {\n const execSql = input.execSql;\n const organizationId = input.organizationId;\n const stillCurrent = input.stillCurrent;\n const retirements = structuredClone(input.retirements ?? []);\n const entries: {\n initialGroup: boolean;\n request: PutPrincipalPolicyRequest;\n response: PrincipalPolicyMutationResponse;\n options: RecoverPrincipalPolicyHistoryOptions;\n predecessor: AcknowledgedPrincipalPredecessor | null;\n }[] = [];\n try {\n assertProjectionVerificationCurrent(stillCurrent);\n for (const entry of input.entries)\n entries.push({\n initialGroup: entry.initialGroup === true,\n predecessor: structuredClone(entry.predecessor),\n request: structuredClone(entry.request),\n response: structuredClone(entry.response),\n options: {\n ...entry.recovery,\n expectedHead: structuredClone(entry.recovery.expectedHead),\n protection: ownPrincipalHistoryProtection(entry.recovery.protection),\n execSql,\n organizationId,\n stillCurrent,\n },\n });\n const publications: AcknowledgedPrincipalCurrentPublication[] = [];\n for (const entry of entries)\n publications.push(\n await (entry.initialGroup\n ? prepareInitialGroupCurrentPublication\n : preparePublication)(\n entry.options,\n entry.request,\n entry.response,\n entry.predecessor,\n ),\n );\n assertAcknowledgedDirectoryBindings(\n organizationId,\n entries.map(({ response }) => response),\n );\n for (let attempt = 0; ; attempt += 1) {\n const reconciled = [];\n for (const [index, publication] of publications.entries()) {\n const entry = entries[index];\n if (!entry) throw new Error(\"Missing acknowledgement entry\");\n reconciled.push(\n await reconcileAcknowledgedPrincipalCurrent(\n entry.options,\n publication,\n ),\n );\n }\n try {\n await persistAcknowledgedPrincipalCurrents({\n execSql,\n organizationId,\n entries: reconciled,\n retirements,\n stillCurrent: () =>\n stillCurrent() &&\n entries.every((entry) => !entry.options.signal?.aborted),\n });\n break;\n } catch (error) {\n if (\n !(error instanceof PrincipalAcknowledgementChangedError) ||\n attempt >= 7\n )\n throw error;\n }\n }\n return publications.map(({ policy }) => policy);\n } finally {\n for (const entry of entries) entry.options.protection.localKey.fill(0);\n }\n}\n"]}
1
+ {"version":3,"file":"retainAcknowledgedPrincipalCurrents.js","sourceRoot":"","sources":["retainAcknowledgedPrincipalCurrents.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,mCAAmC,GACpC,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAAE,mCAAmC,EAAE,MAAM,iCAAiC,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,qCAAqC,EAAE,MAAM,mCAAmC,CAAC;AAK1F,mFAAmF;AACnF,MAAM,8BAA8B,GAAmC;IACrE,YAAY,EAAE,uBAAuB;IACrC,aAAa,EAAE,qCAAqC;IACpD,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,CAAC,KAAK,CAAC;IACnE,uBAAuB,EAAE,mCAAmC;CAC7D,CAAC;AAEF,wGAAwG;AACxG,MAAM,UAAU,mCAAmC,CACjD,KAAwC;IAExC,OAAO,mCAAmC,CAAC;QACzC,GAAG,KAAK;QACR,MAAM,EAAE,8BAA8B;KACvC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { VerifiedPrincipalPolicyCurrent } from \"@tearleads/crypto\";\nimport {\n type AcknowledgedPrincipalCurrentBatch,\n recordAcknowledgedPrincipalCurrents,\n} from \"../principals/acknowledgedPrincipalCurrents\";\nimport type { PrincipalAcknowledgementChecks } from \"../principals/principalAcknowledgementChecks\";\nimport { assertAcknowledgedDirectoryBindings } from \"./acknowledgedDirectoryBindings\";\nimport { acknowledgeGroupPolicyState } from \"./groupPolicyMutationAcknowledgement\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\nexport type { AcknowledgedPrincipalCurrentRetirement } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nexport type { AcknowledgedPrincipalCurrentInput } from \"../principals/acknowledgedPrincipalCurrents\";\n\n/** How organization and group mutations check an acknowledgement they authored. */\nconst principalAcknowledgementChecks: PrincipalAcknowledgementChecks = {\n authoredHead: groupPolicyMutationHead,\n assertReceipt: assertPrincipalPolicyReceiptArtifacts,\n acknowledgeSuccessor: (input) => acknowledgeGroupPolicyState(input),\n assertDirectoryBindings: assertAcknowledgedDirectoryBindings,\n};\n\n/** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */\nexport function retainAcknowledgedPrincipalCurrents(\n input: AcknowledgedPrincipalCurrentBatch,\n): Promise<VerifiedPrincipalPolicyCurrent[]> {\n return recordAcknowledgedPrincipalCurrents({\n ...input,\n checks: principalAcknowledgementChecks,\n });\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
2
2
  import { scopedGroupHistoryProtection } from "../../data/principals/principalHistoryScopeProtection.js";
3
3
  import { principalPolicyReferenceFromBundle } from "../../data/principals/principalPolicyAdminSigners.js";
4
- import { captureAcknowledgedPrincipalPredecessor } from "./acknowledgedPrincipalPredecessor.js";
4
+ import { captureAcknowledgedPrincipalPredecessor } from "../principals/acknowledgedPrincipalPredecessor.js";
5
5
  import { resolveCurrentGroupMutationReferences } from "./currentGroupMutationReferences.js";
6
6
  import { loadCurrentGroupPolicyMutationContext } from "./currentGroupPolicyMutationContext.js";
7
7
  import { createCurrentPrincipalMutationLease } from "./currentPrincipalMutationLease.js";
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeCurrentGroupMutation.js","sourceRoot":"","sources":["runtimeCurrentGroupMutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyHistoryProgressOptions } from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { CommitOrganizationGroupPolicyResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { CurrentPolicyReferenceResolver } from \"../../data/principals/currentPolicyReferenceResolver\";\nimport { scopedGroupHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { PrincipalPolicyPageReader } from \"../principals/principalPolicyHistoryReader\";\nimport type { PrincipalPolicyRecoveryRuntime } from \"../principals/runtimePolicyRecovery\";\nimport { captureAcknowledgedPrincipalPredecessor } from \"./acknowledgedPrincipalPredecessor\";\nimport { resolveCurrentGroupMutationReferences } from \"./currentGroupMutationReferences\";\nimport { loadCurrentGroupPolicyMutationContext } from \"./currentGroupPolicyMutationContext\";\nimport { createCurrentPrincipalMutationLease } from \"./currentPrincipalMutationLease\";\nimport type { PrincipalMutationRecoveryApi } from \"./principalMutationJournalManagement\";\nimport {\n type AcknowledgedPrincipalCurrentInput,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\n\ntype MutationRuntime = PrincipalPolicyRecoveryRuntime & {\n readonly apiClient: PrincipalPolicyRecoveryRuntime[\"apiClient\"] &\n Pick<PrincipalMutationRecoveryApi, \"recoverPendingPrincipalMutation\">;\n};\n\ntype CurrentMutationContext = Awaited<\n ReturnType<typeof loadCurrentGroupPolicyMutationContext>\n>;\n\nexport type RuntimeCurrentGroupMutationContext = CurrentMutationContext & {\n readonly resolveAuthoredPolicyReferences: CurrentPolicyReferenceResolver;\n readonly loadGroup: (\n groupId: string,\n ) => Promise<RuntimeCurrentGroupMutationContext>;\n readonly groupRetention: Pick<\n AcknowledgedPrincipalCurrentInput,\n \"recovery\" | \"predecessor\"\n >;\n readonly retainAcknowledged: (\n receipt: CurrentMutationReceipt,\n ) => Promise<void>;\n};\n\ninterface CurrentMutationReceipt {\n readonly additionalGroups?:\n | readonly (AcknowledgedPrincipalCurrentInput & {\n readonly retiredContainerIds?: readonly string[] | undefined;\n })[]\n | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly response: CommitOrganizationGroupPolicyResponse;\n readonly retiredContainerIds?: readonly string[] | undefined;\n}\n\ninterface MutationInput {\n readonly groupId: string;\n readonly organizationId: string;\n readonly signerUserId: string;\n readonly stillCurrent: () => boolean;\n}\n\n/** Keep private prefix custody inside the entire mutation and its acknowledgement. */\nexport function createRuntimeCurrentGroupMutation(runtime: MutationRuntime) {\n const lease = createCurrentPrincipalMutationLease(runtime);\n if (!lease) return undefined;\n return async <T>(\n input: MutationInput,\n work: (context: RuntimeCurrentGroupMutationContext) => Promise<T>,\n ): Promise<T> => {\n input = { ...input };\n return lease(\n input.stillCurrent,\n async ({\n protection,\n stillCurrent,\n resolveCurrentPolicy,\n historyReader,\n directoryRecovery,\n }) => {\n const loadGroup = async (\n groupId: string,\n ): Promise<RuntimeCurrentGroupMutationContext> => {\n const context = await loadCurrentGroupPolicyMutationContext({\n ...input,\n groupId,\n execSql: runtime.infra.execSql,\n resolveCurrentPolicy,\n recoverPendingPrincipalMutation: (organizationId) =>\n runtime.apiClient.recoverPendingPrincipalMutation(organizationId),\n stillCurrent,\n });\n const retention = await createCurrentMutationRetention(\n runtime,\n { ...input, groupId },\n context,\n protection,\n historyReader,\n directoryRecovery(context.organizationCurrent.current),\n );\n return {\n ...context,\n ...retention,\n loadGroup,\n resolveAuthoredPolicyReferences: (current, references) =>\n resolveCurrentGroupMutationReferences({\n current,\n predecessor: context.verifiedCurrentPolicy,\n references,\n readPredecessorReference: context.readPredecessorReference,\n stillCurrent: context.stillCurrent,\n }),\n };\n };\n const context = await loadGroup(input.groupId);\n const result = await work(context);\n assertProjectionVerificationCurrent(context.stillCurrent);\n return result;\n },\n );\n };\n}\n\nasync function createCurrentMutationRetention(\n runtime: MutationRuntime,\n input: MutationInput,\n context: CurrentMutationContext,\n protection: PrincipalPolicyHistoryProgressOptions,\n historyReader: PrincipalPolicyPageReader,\n directoryRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"],\n) {\n const common = {\n historyReader,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n };\n const groupRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"] = {\n ...common,\n expectedHead: principalPolicyReferenceFromBundle(context.currentPolicy),\n protection: context.isOrganizationAdminsGroup\n ? protection\n : scopedGroupHistoryProtection(\n protection,\n input.organizationId,\n context.adminGroupId,\n ),\n historyVerification: context.isOrganizationAdminsGroup\n ? \"direct-admins\"\n : \"standard\",\n ...(context.isOrganizationAdminsGroup\n ? {}\n : { loadExternalAuthority: async () => context.externalAuthority }),\n };\n const capture = (recovery: AcknowledgedPrincipalCurrentInput[\"recovery\"]) =>\n captureAcknowledgedPrincipalPredecessor({\n ...recovery,\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n stillCurrent: context.stillCurrent,\n });\n const groupPredecessor = await capture(groupRecovery);\n const directoryPredecessor = await capture(directoryRecovery);\n const retainAcknowledged = async (\n receipt: CurrentMutationReceipt,\n ): Promise<void> => {\n assertProjectionVerificationCurrent(context.stillCurrent);\n await retainAcknowledgedPrincipalCurrents({\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n entries: [\n ...(receipt.additionalGroups ?? []),\n {\n recovery: groupRecovery,\n predecessor: groupPredecessor,\n request: receipt.request,\n response: receipt.response.groupPolicy,\n },\n {\n recovery: directoryRecovery,\n predecessor: directoryPredecessor,\n request: receipt.organizationRequest,\n response: receipt.response.organizationPolicy,\n },\n ],\n retirements: [\n ...(receipt.additionalGroups ?? []).map((entry) => ({\n principalId: entry.request.state.principalId,\n principalType: \"group\" as const,\n containerIds: entry.retiredContainerIds ?? [],\n })),\n {\n principalId: input.groupId,\n principalType: \"group\",\n containerIds: receipt.retiredContainerIds ?? [],\n },\n ],\n stillCurrent: context.stillCurrent,\n });\n };\n return {\n groupRetention: { recovery: groupRecovery, predecessor: groupPredecessor },\n retainAcknowledged,\n };\n}\n"]}
1
+ {"version":3,"file":"runtimeCurrentGroupMutation.js","sourceRoot":"","sources":["runtimeCurrentGroupMutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyHistoryProgressOptions } from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { CommitOrganizationGroupPolicyResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { CurrentPolicyReferenceResolver } from \"../../data/principals/currentPolicyReferenceResolver\";\nimport { scopedGroupHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport { captureAcknowledgedPrincipalPredecessor } from \"../principals/acknowledgedPrincipalPredecessor\";\nimport type { PrincipalPolicyPageReader } from \"../principals/principalPolicyHistoryReader\";\nimport type { PrincipalPolicyRecoveryRuntime } from \"../principals/runtimePolicyRecovery\";\nimport { resolveCurrentGroupMutationReferences } from \"./currentGroupMutationReferences\";\nimport { loadCurrentGroupPolicyMutationContext } from \"./currentGroupPolicyMutationContext\";\nimport { createCurrentPrincipalMutationLease } from \"./currentPrincipalMutationLease\";\nimport type { PrincipalMutationRecoveryApi } from \"./principalMutationJournalManagement\";\nimport {\n type AcknowledgedPrincipalCurrentInput,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\n\ntype MutationRuntime = PrincipalPolicyRecoveryRuntime & {\n readonly apiClient: PrincipalPolicyRecoveryRuntime[\"apiClient\"] &\n Pick<PrincipalMutationRecoveryApi, \"recoverPendingPrincipalMutation\">;\n};\n\ntype CurrentMutationContext = Awaited<\n ReturnType<typeof loadCurrentGroupPolicyMutationContext>\n>;\n\nexport type RuntimeCurrentGroupMutationContext = CurrentMutationContext & {\n readonly resolveAuthoredPolicyReferences: CurrentPolicyReferenceResolver;\n readonly loadGroup: (\n groupId: string,\n ) => Promise<RuntimeCurrentGroupMutationContext>;\n readonly groupRetention: Pick<\n AcknowledgedPrincipalCurrentInput,\n \"recovery\" | \"predecessor\"\n >;\n readonly retainAcknowledged: (\n receipt: CurrentMutationReceipt,\n ) => Promise<void>;\n};\n\ninterface CurrentMutationReceipt {\n readonly additionalGroups?:\n | readonly (AcknowledgedPrincipalCurrentInput & {\n readonly retiredContainerIds?: readonly string[] | undefined;\n })[]\n | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly response: CommitOrganizationGroupPolicyResponse;\n readonly retiredContainerIds?: readonly string[] | undefined;\n}\n\ninterface MutationInput {\n readonly groupId: string;\n readonly organizationId: string;\n readonly signerUserId: string;\n readonly stillCurrent: () => boolean;\n}\n\n/** Keep private prefix custody inside the entire mutation and its acknowledgement. */\nexport function createRuntimeCurrentGroupMutation(runtime: MutationRuntime) {\n const lease = createCurrentPrincipalMutationLease(runtime);\n if (!lease) return undefined;\n return async <T>(\n input: MutationInput,\n work: (context: RuntimeCurrentGroupMutationContext) => Promise<T>,\n ): Promise<T> => {\n input = { ...input };\n return lease(\n input.stillCurrent,\n async ({\n protection,\n stillCurrent,\n resolveCurrentPolicy,\n historyReader,\n directoryRecovery,\n }) => {\n const loadGroup = async (\n groupId: string,\n ): Promise<RuntimeCurrentGroupMutationContext> => {\n const context = await loadCurrentGroupPolicyMutationContext({\n ...input,\n groupId,\n execSql: runtime.infra.execSql,\n resolveCurrentPolicy,\n recoverPendingPrincipalMutation: (organizationId) =>\n runtime.apiClient.recoverPendingPrincipalMutation(organizationId),\n stillCurrent,\n });\n const retention = await createCurrentMutationRetention(\n runtime,\n { ...input, groupId },\n context,\n protection,\n historyReader,\n directoryRecovery(context.organizationCurrent.current),\n );\n return {\n ...context,\n ...retention,\n loadGroup,\n resolveAuthoredPolicyReferences: (current, references) =>\n resolveCurrentGroupMutationReferences({\n current,\n predecessor: context.verifiedCurrentPolicy,\n references,\n readPredecessorReference: context.readPredecessorReference,\n stillCurrent: context.stillCurrent,\n }),\n };\n };\n const context = await loadGroup(input.groupId);\n const result = await work(context);\n assertProjectionVerificationCurrent(context.stillCurrent);\n return result;\n },\n );\n };\n}\n\nasync function createCurrentMutationRetention(\n runtime: MutationRuntime,\n input: MutationInput,\n context: CurrentMutationContext,\n protection: PrincipalPolicyHistoryProgressOptions,\n historyReader: PrincipalPolicyPageReader,\n directoryRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"],\n) {\n const common = {\n historyReader,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n };\n const groupRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"] = {\n ...common,\n expectedHead: principalPolicyReferenceFromBundle(context.currentPolicy),\n protection: context.isOrganizationAdminsGroup\n ? protection\n : scopedGroupHistoryProtection(\n protection,\n input.organizationId,\n context.adminGroupId,\n ),\n historyVerification: context.isOrganizationAdminsGroup\n ? \"direct-admins\"\n : \"standard\",\n ...(context.isOrganizationAdminsGroup\n ? {}\n : { loadExternalAuthority: async () => context.externalAuthority }),\n };\n const capture = (recovery: AcknowledgedPrincipalCurrentInput[\"recovery\"]) =>\n captureAcknowledgedPrincipalPredecessor({\n ...recovery,\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n stillCurrent: context.stillCurrent,\n });\n const groupPredecessor = await capture(groupRecovery);\n const directoryPredecessor = await capture(directoryRecovery);\n const retainAcknowledged = async (\n receipt: CurrentMutationReceipt,\n ): Promise<void> => {\n assertProjectionVerificationCurrent(context.stillCurrent);\n await retainAcknowledgedPrincipalCurrents({\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n entries: [\n ...(receipt.additionalGroups ?? []),\n {\n recovery: groupRecovery,\n predecessor: groupPredecessor,\n request: receipt.request,\n response: receipt.response.groupPolicy,\n },\n {\n recovery: directoryRecovery,\n predecessor: directoryPredecessor,\n request: receipt.organizationRequest,\n response: receipt.response.organizationPolicy,\n },\n ],\n retirements: [\n ...(receipt.additionalGroups ?? []).map((entry) => ({\n principalId: entry.request.state.principalId,\n principalType: \"group\" as const,\n containerIds: entry.retiredContainerIds ?? [],\n })),\n {\n principalId: input.groupId,\n principalType: \"group\",\n containerIds: receipt.retiredContainerIds ?? [],\n },\n ],\n stillCurrent: context.stillCurrent,\n });\n };\n return {\n groupRetention: { recovery: groupRecovery, predecessor: groupPredecessor },\n retainAcknowledged,\n };\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import { type VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
2
+ import type { PutPrincipalPolicyRequest } from "../../internal/validators/request/index.js";
3
+ import type { PrincipalPolicyMutationResponse } from "../../internal/validators/response/index.js";
4
+ import { type AcknowledgedPrincipalCurrentRetirement } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
5
+ import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
6
+ import { type AcknowledgedPrincipalPredecessor } from "./acknowledgedPrincipalPredecessor.js";
7
+ import type { PrincipalAcknowledgementChecks } from "./principalAcknowledgementChecks.js";
8
+ import type { RecoverPrincipalPolicyHistoryOptions } from "./principalHistoryRecoveryTypes.js";
9
+ export interface AcknowledgedPrincipalCurrentInput {
10
+ /** Capture before submitting the mutation; null only for a new group. */
11
+ readonly predecessor: AcknowledgedPrincipalPredecessor | null;
12
+ /** Only a newly authored group at version one; never skips a predecessor. */
13
+ readonly initialGroup?: boolean | undefined;
14
+ /** The same scoped protection and verification mode used to recover the predecessor. */
15
+ readonly recovery: Omit<RecoverPrincipalPolicyHistoryOptions, "execSql" | "organizationId" | "stillCurrent">;
16
+ readonly request: PutPrincipalPolicyRequest;
17
+ readonly response: PrincipalPolicyMutationResponse;
18
+ }
19
+ /** The acknowledged currents of one mutation, recorded together. */
20
+ export interface AcknowledgedPrincipalCurrentBatch {
21
+ readonly execSql: ExecSql;
22
+ readonly organizationId: string;
23
+ readonly entries: readonly AcknowledgedPrincipalCurrentInput[];
24
+ readonly retirements?: readonly AcknowledgedPrincipalCurrentRetirement[] | undefined;
25
+ readonly stillCurrent: () => boolean;
26
+ }
27
+ /**
28
+ * Extend authenticated local progress and retain exact acknowledged artifacts
29
+ * atomically with pins, once `checks` accept each acknowledgement.
30
+ */
31
+ export declare function recordAcknowledgedPrincipalCurrents(input: AcknowledgedPrincipalCurrentBatch & {
32
+ readonly checks: PrincipalAcknowledgementChecks;
33
+ }): Promise<VerifiedPrincipalPolicyCurrent[]>;
@@ -0,0 +1,140 @@
1
+ import { KeyingVerificationError, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { PrincipalAcknowledgementChangedError, persistAcknowledgedPrincipalCurrents, } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
4
+ import { preparePrincipalHistoryEvidencePage } from "../../data/persistence/principalHistoryEvidencePersistence.js";
5
+ import { ownPrincipalHistoryProtection } from "../../data/principals/principalHistoryProtection.js";
6
+ import { restoreAcknowledgedPrincipalPredecessor, } from "./acknowledgedPrincipalPredecessor.js";
7
+ import { prepareInitialGroupCurrentPublication } from "./initialPrincipalCurrentPublication.js";
8
+ import { collectPrincipalPolicySignerPublicKeys } from "./policyVerification.js";
9
+ import { sealPrincipalCurrentPublication, sealPrincipalCurrentStage, } from "./principalCurrentPublicationSeal.js";
10
+ import { assertPrincipalHistoryVerificationMode, principalHistoryVerificationContext, } from "./principalHistoryRecoveryVerification.js";
11
+ import { reconcileAcknowledgedPrincipalCurrent } from "./reconcileAcknowledgedPrincipalCurrent.js";
12
+ async function preparePublication(options, request, response, predecessor, checks) {
13
+ options = {
14
+ ...options,
15
+ protection: {
16
+ ...options.protection,
17
+ context: principalHistoryVerificationContext(options),
18
+ },
19
+ };
20
+ const current = () => !options.signal?.aborted && options.stillCurrent();
21
+ assertProjectionVerificationCurrent(current);
22
+ const { scopeId, saved, artifacts, verifier, previous, predecessorIndexRootHash, } = await restoreAcknowledgedPrincipalPredecessor(options, predecessor);
23
+ const expectedHead = await checks.authoredHead(request);
24
+ checks.assertReceipt({ expectedHead, request, response });
25
+ const keys = await collectPrincipalPolicySignerPublicKeys({
26
+ bundle: { currentState: response.currentState, previousStates: [] },
27
+ resolveTrustedUserIdentity: options.resolveTrustedUserIdentity,
28
+ });
29
+ assertProjectionVerificationCurrent(current);
30
+ if ("error" in keys)
31
+ throw new KeyingVerificationError(keys.error === "not-found" ? "missing_dependency" : "signer_mismatch", "Acknowledged principal signer could not be authenticated");
32
+ const externalAuthority = await options.loadExternalAuthority?.(request.state.externalAuthority ? [request.state.externalAuthority] : []);
33
+ assertProjectionVerificationCurrent(current);
34
+ const policy = await checks.acknowledgeSuccessor({
35
+ verifiedCurrentPolicy: previous,
36
+ expectedHead,
37
+ request,
38
+ response: response.currentState,
39
+ signerPublicKeys: keys.signerPublicKeys,
40
+ externalAuthority,
41
+ stillCurrent: current,
42
+ });
43
+ const entry = {
44
+ state: response.currentState,
45
+ projection: response.currentProjection,
46
+ grants: response.currentGrants,
47
+ };
48
+ assertPrincipalHistoryVerificationMode(options, [entry]);
49
+ const predecessorStage = await sealPrincipalCurrentStage(options, previous.state, verifier, artifacts);
50
+ const appended = await verifier.append({
51
+ entries: [entry],
52
+ signerPublicKeys: keys.signerPublicKeys,
53
+ ...(externalAuthority ? { externalAuthority } : {}),
54
+ });
55
+ if (!appended.ok)
56
+ throw appended.error;
57
+ const sealed = await sealPrincipalCurrentPublication(options, scopeId, expectedHead, verifier, response);
58
+ assertProjectionVerificationCurrent(current);
59
+ return {
60
+ policy,
61
+ previousPrefixProgress: saved.progress,
62
+ predecessorStage,
63
+ predecessorIndexRootHash,
64
+ ...sealed,
65
+ evidence: await preparePrincipalHistoryEvidencePage({
66
+ indexRootHash: appended.value.indexRootHash,
67
+ scopeId,
68
+ organizationId: options.organizationId,
69
+ entries: [entry],
70
+ nodes: appended.value.indexNodes,
71
+ }),
72
+ };
73
+ }
74
+ /**
75
+ * Extend authenticated local progress and retain exact acknowledged artifacts
76
+ * atomically with pins, once `checks` accept each acknowledgement.
77
+ */
78
+ export async function recordAcknowledgedPrincipalCurrents(input) {
79
+ const checks = input.checks;
80
+ const execSql = input.execSql;
81
+ const organizationId = input.organizationId;
82
+ const stillCurrent = input.stillCurrent;
83
+ const retirements = structuredClone(input.retirements ?? []);
84
+ const entries = [];
85
+ try {
86
+ assertProjectionVerificationCurrent(stillCurrent);
87
+ for (const entry of input.entries)
88
+ entries.push({
89
+ initialGroup: entry.initialGroup === true,
90
+ predecessor: structuredClone(entry.predecessor),
91
+ request: structuredClone(entry.request),
92
+ response: structuredClone(entry.response),
93
+ options: {
94
+ ...entry.recovery,
95
+ expectedHead: structuredClone(entry.recovery.expectedHead),
96
+ protection: ownPrincipalHistoryProtection(entry.recovery.protection),
97
+ execSql,
98
+ organizationId,
99
+ stillCurrent,
100
+ },
101
+ });
102
+ const publications = [];
103
+ for (const entry of entries)
104
+ publications.push(await (entry.initialGroup
105
+ ? prepareInitialGroupCurrentPublication
106
+ : preparePublication)(entry.options, entry.request, entry.response, entry.predecessor, checks));
107
+ checks.assertDirectoryBindings(organizationId, entries.map(({ response }) => response));
108
+ for (let attempt = 0;; attempt += 1) {
109
+ const reconciled = [];
110
+ for (const [index, publication] of publications.entries()) {
111
+ const entry = entries[index];
112
+ if (!entry)
113
+ throw new Error("Missing acknowledgement entry");
114
+ reconciled.push(await reconcileAcknowledgedPrincipalCurrent(entry.options, publication));
115
+ }
116
+ try {
117
+ await persistAcknowledgedPrincipalCurrents({
118
+ execSql,
119
+ organizationId,
120
+ entries: reconciled,
121
+ retirements,
122
+ stillCurrent: () => stillCurrent() &&
123
+ entries.every((entry) => !entry.options.signal?.aborted),
124
+ });
125
+ break;
126
+ }
127
+ catch (error) {
128
+ if (!(error instanceof PrincipalAcknowledgementChangedError) ||
129
+ attempt >= 7)
130
+ throw error;
131
+ }
132
+ }
133
+ return publications.map(({ policy }) => policy);
134
+ }
135
+ finally {
136
+ for (const entry of entries)
137
+ entry.options.protection.localKey.fill(0);
138
+ }
139
+ }
140
+ //# sourceMappingURL=acknowledgedPrincipalCurrents.js.map