@serve.zone/interfaces 27.2.0 → 27.3.0

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.
@@ -37,6 +37,12 @@ export const cloudlyLegacyDeploymentSettlementDomains = Object.freeze({
37
37
  'serve.zone/cloudly-legacy-deployment-settlement/scratch-receipt-hmac-v1\0',
38
38
  productionReceiptHmac:
39
39
  'serve.zone/cloudly-legacy-deployment-settlement/production-receipt-hmac-v1\0',
40
+ productionExecutionAuthorizationHmac:
41
+ 'serve.zone/cloudly-legacy-deployment-settlement/production-execution-authorization-hmac-v1\0',
42
+ productionReceiptV2Hmac:
43
+ 'serve.zone/cloudly-legacy-deployment-settlement/production-receipt-hmac-v2\0',
44
+ resolutionHmac:
45
+ 'serve.zone/cloudly-legacy-deployment-settlement/resolution-recovery-attestation-hmac-v1\0',
40
46
  } as const);
41
47
 
42
48
  export type TCloudlyLegacyDeploymentSettlementCodecErrorCode =
@@ -84,8 +90,7 @@ export interface ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1 {
84
90
  authorityMetadataSha256: string;
85
91
  }
86
92
 
87
- export interface ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1
88
- {
93
+ interface ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 {
89
94
  schemaVersion: 1;
90
95
  operationId: string;
91
96
  authorityId: string;
@@ -115,6 +120,47 @@ export interface ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1
115
120
  digestProofSha256: string;
116
121
  }
117
122
 
123
+ export interface ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1
124
+ extends ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 {
125
+ executionProtocol?: 'fenced-attempt-v1';
126
+ sourceAuthority?: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
127
+ sourceAuthenticatedPlanSha256?: string;
128
+ sourceRequestBundleSha256?: string;
129
+ scratchReceiptSha256?: string;
130
+ }
131
+
132
+ export interface ICloudlyLegacyDeploymentSettlementLegacyAuthorityMetadataV1
133
+ extends ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 {
134
+ executionProtocol?: never;
135
+ sourceAuthority?: never;
136
+ sourceAuthenticatedPlanSha256?: never;
137
+ sourceRequestBundleSha256?: never;
138
+ scratchReceiptSha256?: never;
139
+ }
140
+
141
+ export interface ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1
142
+ extends ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 {
143
+ executionProtocol: 'fenced-attempt-v1';
144
+ sourceAuthority?: never;
145
+ sourceAuthenticatedPlanSha256?: never;
146
+ sourceRequestBundleSha256?: never;
147
+ scratchReceiptSha256?: never;
148
+ }
149
+
150
+ export interface ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1
151
+ extends ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 {
152
+ executionProtocol: 'fenced-attempt-v1';
153
+ sourceAuthority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
154
+ sourceAuthenticatedPlanSha256: string;
155
+ sourceRequestBundleSha256: string;
156
+ scratchReceiptSha256: string;
157
+ }
158
+
159
+ export type TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1 =
160
+ | ICloudlyLegacyDeploymentSettlementLegacyAuthorityMetadataV1
161
+ | ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1
162
+ | ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1;
163
+
118
164
  /** Private plaintext HMAC key. Never persist, log, or place in summaries or receipts. */
119
165
  export interface ICloudlyLegacyDeploymentSettlementHmacKeyPlaintextV1 {
120
166
  format: 'raw-32-byte-base64url';
@@ -123,9 +169,9 @@ export interface ICloudlyLegacyDeploymentSettlementHmacKeyPlaintextV1 {
123
169
 
124
170
  /**
125
171
  * Exact private-file handoff parsed by pinned maintenance containers.
126
- * Interfaces only parses and encodes it; consumers own secure generation,
127
- * storage, use, and destruction of the plaintext key.
128
- * This package never generates, stores, logs, or performs HMAC with the key.
172
+ * Consumers own secure generation, storage, use, and destruction of the key.
173
+ * Interfaces never generates, persists, or logs it; the private stdio verifier
174
+ * transiently decodes it for HMAC verification and wipes the decoded bytes.
129
175
  */
130
176
  export interface ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1 {
131
177
  schemaVersion: 1;
@@ -444,6 +490,38 @@ const authorityMetadataKeys = [
444
490
  'restoredDataSha256',
445
491
  'digestProofSha256',
446
492
  ] as const;
493
+ const authorityMetadataOptionalKeys = [
494
+ 'executionProtocol',
495
+ 'sourceAuthority',
496
+ 'sourceAuthenticatedPlanSha256',
497
+ 'sourceRequestBundleSha256',
498
+ 'scratchReceiptSha256',
499
+ ] as const;
500
+ const authorityMetadataCrossAuthorityKeys = [
501
+ 'schemaVersion',
502
+ 'operationId',
503
+ 'keyVersion',
504
+ 'settlementId',
505
+ 'maintenanceImageDigest',
506
+ 'sourceImageDigest',
507
+ 'targetImageDigest',
508
+ 'targetVersion',
509
+ 'targetManifestSha256',
510
+ 'targetConfigSha256',
511
+ 'backupId',
512
+ 'backupSnapshotIdSha256',
513
+ 'backupProofSha256',
514
+ 'runId',
515
+ 'rehearsalId',
516
+ 'scratchServiceId',
517
+ 'allocationId',
518
+ 'allocationGeneration',
519
+ 'allocationBindingSha256',
520
+ 'allocationReceiptSha256',
521
+ 'sourceDataSha256',
522
+ 'restoredDataSha256',
523
+ 'digestProofSha256',
524
+ ] as const;
447
525
  const classificationKeys = [
448
526
  'image-recorded-not-current',
449
527
  'image-recorded-current-failed',
@@ -707,9 +785,10 @@ export const normalizeCloudlyLegacyDeploymentSettlementAuthorityReference = (
707
785
  const normalizeAuthorityMetadataInternal = (
708
786
  valueArg: unknown,
709
787
  pathArg: string,
710
- ): ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1 => {
788
+ ): TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1 => {
711
789
  const value = readRecord(valueArg, pathArg);
712
- assertExactKeys(value, authorityMetadataKeys, pathArg);
790
+ const optionalKeys = authorityMetadataOptionalKeys.filter((keyArg) => Object.hasOwn(value, keyArg));
791
+ assertExactKeys(value, [...authorityMetadataKeys, ...optionalKeys], pathArg);
713
792
  if (value.schemaVersion !== 1 || value.keyVersion !== 1) {
714
793
  fail('INVALID_VALUE', `${pathArg}.schemaVersion`);
715
794
  }
@@ -731,11 +810,37 @@ const normalizeAuthorityMetadataInternal = (
731
810
  if (sourceDataSha256 !== restoredDataSha256) {
732
811
  fail('CROSS_FIELD_MISMATCH', `${pathArg}.restoredDataSha256`);
733
812
  }
734
- return {
813
+ const predecessorKeys = authorityMetadataOptionalKeys.filter((keyArg) => (
814
+ keyArg !== 'executionProtocol'
815
+ ));
816
+ const hasExecutionProtocol = Object.hasOwn(value, 'executionProtocol');
817
+ const predecessorKeyCount = predecessorKeys.filter((keyArg) => Object.hasOwn(value, keyArg)).length;
818
+ if (hasExecutionProtocol && value.executionProtocol !== 'fenced-attempt-v1') {
819
+ fail('INVALID_VALUE', `${pathArg}.executionProtocol`);
820
+ }
821
+ if (predecessorKeyCount !== 0 && predecessorKeyCount !== predecessorKeys.length) {
822
+ fail('INVALID_SCHEMA', `${pathArg}.sourceAuthority`);
823
+ }
824
+ if (predecessorKeyCount > 0 && !hasExecutionProtocol) {
825
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.executionProtocol`);
826
+ }
827
+ const operationId = readIdentifier(value.operationId, `${pathArg}.operationId`);
828
+ const authorityId = readIdentifier(value.authorityId, `${pathArg}.authorityId`);
829
+ const keyId = readIdentifier(value.keyId, `${pathArg}.keyId`);
830
+ const sourceAuthority = predecessorKeyCount === 0
831
+ ? undefined
832
+ : normalizeAuthorityReferenceInternal(value.sourceAuthority, `${pathArg}.sourceAuthority`);
833
+ if (sourceAuthority
834
+ && (sourceAuthority.operationId !== operationId
835
+ || sourceAuthority.authorityId === authorityId
836
+ || sourceAuthority.keyId === keyId)) {
837
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.sourceAuthority`);
838
+ }
839
+ const common: ICloudlyLegacyDeploymentSettlementAuthorityMetadataBaseV1 = {
735
840
  schemaVersion: 1,
736
- operationId: readIdentifier(value.operationId, `${pathArg}.operationId`),
737
- authorityId: readIdentifier(value.authorityId, `${pathArg}.authorityId`),
738
- keyId: readIdentifier(value.keyId, `${pathArg}.keyId`),
841
+ operationId,
842
+ authorityId,
843
+ keyId,
739
844
  keyVersion: 1,
740
845
  settlementId: readIdentifier(value.settlementId, `${pathArg}.settlementId`),
741
846
  issuedAt,
@@ -779,11 +884,37 @@ const normalizeAuthorityMetadataInternal = (
779
884
  restoredDataSha256,
780
885
  digestProofSha256: readSha256(value.digestProofSha256, `${pathArg}.digestProofSha256`),
781
886
  };
887
+ if (!hasExecutionProtocol) {
888
+ return common as ICloudlyLegacyDeploymentSettlementLegacyAuthorityMetadataV1;
889
+ }
890
+ if (!sourceAuthority) {
891
+ return {
892
+ ...common,
893
+ executionProtocol: 'fenced-attempt-v1',
894
+ } as ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1;
895
+ }
896
+ return {
897
+ ...common,
898
+ executionProtocol: 'fenced-attempt-v1',
899
+ sourceAuthority,
900
+ sourceAuthenticatedPlanSha256: readSha256(
901
+ value.sourceAuthenticatedPlanSha256,
902
+ `${pathArg}.sourceAuthenticatedPlanSha256`,
903
+ ),
904
+ sourceRequestBundleSha256: readSha256(
905
+ value.sourceRequestBundleSha256,
906
+ `${pathArg}.sourceRequestBundleSha256`,
907
+ ),
908
+ scratchReceiptSha256: readSha256(
909
+ value.scratchReceiptSha256,
910
+ `${pathArg}.scratchReceiptSha256`,
911
+ ),
912
+ } as ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1;
782
913
  };
783
914
 
784
915
  export const normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata = (
785
916
  valueArg: unknown,
786
- ): Readonly<ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1> => finalize(
917
+ ): Readonly<TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1> => finalize(
787
918
  normalizeAuthorityMetadataInternal(valueArg, 'authorityMetadata'),
788
919
  cloudlyLegacyDeploymentSettlementLimits.maximumAuthorityBytes,
789
920
  'authorityMetadata',
@@ -834,6 +965,81 @@ export const normalizeCloudlyLegacyDeploymentSettlementAuthorityReferenceForMeta
834
965
  return reference;
835
966
  };
836
967
 
968
+ const normalizeFencedSourceAuthorityMetadata = (
969
+ metadataArg: unknown,
970
+ pathArg: string,
971
+ ): Readonly<ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1> => {
972
+ const metadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(metadataArg);
973
+ if (metadata.executionProtocol !== 'fenced-attempt-v1'
974
+ || Object.hasOwn(metadata, 'sourceAuthority')) {
975
+ fail('CROSS_FIELD_MISMATCH', pathArg);
976
+ }
977
+ return metadata as Readonly<
978
+ ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1
979
+ >;
980
+ };
981
+
982
+ const normalizeProductionAuthorityMetadataPair = (
983
+ productionMetadataArg: unknown,
984
+ sourceMetadataArg: unknown,
985
+ ): {
986
+ productionMetadata: Readonly<
987
+ ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1
988
+ >;
989
+ sourceMetadata: Readonly<ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1>;
990
+ } => {
991
+ const productionMetadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(
992
+ productionMetadataArg,
993
+ );
994
+ const sourceMetadata = normalizeFencedSourceAuthorityMetadata(
995
+ sourceMetadataArg,
996
+ 'sourceAuthorityMetadata',
997
+ );
998
+ if (productionMetadata.executionProtocol !== 'fenced-attempt-v1'
999
+ || !Object.hasOwn(productionMetadata, 'sourceAuthority')) {
1000
+ fail('CROSS_FIELD_MISMATCH', 'productionAuthorityMetadata');
1001
+ }
1002
+ const fencedSourceMetadata = sourceMetadata;
1003
+ const fencedProductionMetadata = productionMetadata as Readonly<
1004
+ ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1
1005
+ >;
1006
+ const sourceAuthority = createCloudlyLegacyDeploymentSettlementAuthorityReference(
1007
+ fencedSourceMetadata,
1008
+ );
1009
+ const productionAuthority = createCloudlyLegacyDeploymentSettlementAuthorityReference(
1010
+ fencedProductionMetadata,
1011
+ );
1012
+ const sourceContext = Object.fromEntries(authorityMetadataCrossAuthorityKeys.map((keyArg) => [
1013
+ keyArg,
1014
+ fencedSourceMetadata[keyArg],
1015
+ ]));
1016
+ const productionContext = Object.fromEntries(authorityMetadataCrossAuthorityKeys.map((keyArg) => [
1017
+ keyArg,
1018
+ fencedProductionMetadata[keyArg],
1019
+ ]));
1020
+ if (canonicalize(fencedProductionMetadata.sourceAuthority, 'productionMetadata.sourceAuthority')
1021
+ !== canonicalize(sourceAuthority, 'sourceMetadata.authority')
1022
+ || canonicalize(productionAuthority, 'productionMetadata.authority')
1023
+ === canonicalize(sourceAuthority, 'sourceMetadata.authority')
1024
+ || fencedProductionMetadata.authorityId === fencedSourceMetadata.authorityId
1025
+ || fencedProductionMetadata.keyId === fencedSourceMetadata.keyId
1026
+ || canonicalize(productionContext, 'productionMetadata.context')
1027
+ !== canonicalize(sourceContext, 'sourceMetadata.context')) {
1028
+ fail('CROSS_FIELD_MISMATCH', 'productionAuthorityMetadata.sourceAuthority');
1029
+ }
1030
+ return {
1031
+ productionMetadata: fencedProductionMetadata,
1032
+ sourceMetadata: fencedSourceMetadata,
1033
+ };
1034
+ };
1035
+
1036
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionAuthorityMetadataForSourceAuthority = (
1037
+ productionMetadataArg: unknown,
1038
+ sourceMetadataArg: unknown,
1039
+ ): Readonly<ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1> => (
1040
+ normalizeProductionAuthorityMetadataPair(productionMetadataArg, sourceMetadataArg).productionMetadata
1041
+ );
1042
+
837
1043
  export const normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext = (
838
1044
  valueArg: unknown,
839
1045
  ): Readonly<ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1> => {
@@ -875,8 +1081,12 @@ export const normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext
875
1081
  fail('INVALID_VALUE', 'authorityHandoffPlaintext.hmacKeyPlaintext');
876
1082
  }
877
1083
  const keyBytes = Buffer.from(keyValue, 'base64url');
878
- if (keyBytes.byteLength !== 32 || keyBytes.toString('base64url') !== keyValue) {
879
- fail('INVALID_VALUE', 'authorityHandoffPlaintext.hmacKeyPlaintext.value');
1084
+ try {
1085
+ if (keyBytes.byteLength !== 32 || keyBytes.toString('base64url') !== keyValue) {
1086
+ fail('INVALID_VALUE', 'authorityHandoffPlaintext.hmacKeyPlaintext.value');
1087
+ }
1088
+ } finally {
1089
+ keyBytes.fill(0);
880
1090
  }
881
1091
  return finalize({
882
1092
  schemaVersion: 1,
@@ -894,6 +1104,61 @@ export const encodeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext =
894
1104
  'authorityHandoffPlaintext',
895
1105
  );
896
1106
 
1107
+ /**
1108
+ * Private in-process stdio handoff verification only. Do not persist or log the
1109
+ * handoff or returned verifier; discard both as soon as the stdio exchange ends.
1110
+ */
1111
+ export const createCloudlyLegacyDeploymentSettlementStdioHandoffHmacVerifier = (
1112
+ handoffArg: unknown,
1113
+ ): TCloudlyLegacyDeploymentSettlementHmacVerifier => {
1114
+ const handoff = normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
1115
+ handoffArg,
1116
+ );
1117
+ const authorityCanonical = canonicalize(
1118
+ handoff.authorityReference,
1119
+ 'stdioHandoffHmacVerifier.authority',
1120
+ );
1121
+ const keyValue = handoff.hmacKeyPlaintext.value;
1122
+ return (inputArg): boolean => {
1123
+ let keyBytes: Buffer | undefined;
1124
+ let suppliedMacBytes: Buffer | undefined;
1125
+ let expectedMacBytes: Buffer | undefined;
1126
+ try {
1127
+ if (!(inputArg.hmacInput instanceof Uint8Array)
1128
+ || canonicalize(inputArg.authority, 'stdioHandoffHmacVerifier.input.authority')
1129
+ !== authorityCanonical
1130
+ || !macPattern.test(inputArg.mac)) {
1131
+ return false;
1132
+ }
1133
+ const domainBytes = Buffer.from(inputArg.domain, 'utf8');
1134
+ const hmacInputBytes = Buffer.from(inputArg.hmacInput);
1135
+ if (hmacInputBytes.byteLength < domainBytes.byteLength
1136
+ || !hmacInputBytes.subarray(0, domainBytes.byteLength).equals(domainBytes)) {
1137
+ return false;
1138
+ }
1139
+ keyBytes = Buffer.from(keyValue, 'base64url');
1140
+ suppliedMacBytes = Buffer.from(inputArg.mac, 'base64url');
1141
+ if (keyBytes.byteLength !== 32
1142
+ || keyBytes.toString('base64url') !== keyValue
1143
+ || suppliedMacBytes.byteLength !== 32
1144
+ || suppliedMacBytes.toString('base64url') !== inputArg.mac) {
1145
+ return false;
1146
+ }
1147
+ expectedMacBytes = plugins.crypto
1148
+ .createHmac('sha256', keyBytes)
1149
+ .update(hmacInputBytes)
1150
+ .digest();
1151
+ return plugins.crypto.timingSafeEqual(expectedMacBytes, suppliedMacBytes);
1152
+ } catch {
1153
+ return false;
1154
+ } finally {
1155
+ keyBytes?.fill(0);
1156
+ suppliedMacBytes?.fill(0);
1157
+ expectedMacBytes?.fill(0);
1158
+ }
1159
+ };
1160
+ };
1161
+
897
1162
  const normalizeClassificationCounts = (
898
1163
  valueArg: unknown,
899
1164
  pathArg: string,
@@ -2321,7 +2586,7 @@ const requireConsumerVerifiedHmac = async (
2321
2586
 
2322
2587
  const assertAuthorityTimestamp = (
2323
2588
  timestampArg: number,
2324
- metadataArg: ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2589
+ metadataArg: TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2325
2590
  pathArg: string,
2326
2591
  ): void => {
2327
2592
  if (timestampArg < metadataArg.issuedAt || timestampArg >= metadataArg.expiresAt) {
@@ -2331,7 +2596,7 @@ const assertAuthorityTimestamp = (
2331
2596
 
2332
2597
  const assertAuthorityReferenceMatchesMetadata = (
2333
2598
  referenceArg: unknown,
2334
- metadataArg: ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2599
+ metadataArg: TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2335
2600
  pathArg: string,
2336
2601
  ): void => {
2337
2602
  try {
@@ -2346,7 +2611,7 @@ const assertAuthorityReferenceMatchesMetadata = (
2346
2611
 
2347
2612
  const assertRehearsalBindingMatchesAuthorityMetadata = (
2348
2613
  bindingArg: ICloudlyLegacyDeploymentSettlementRehearsalBindingV1,
2349
- metadataArg: ICloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2614
+ metadataArg: TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
2350
2615
  pathArg: string,
2351
2616
  ): void => {
2352
2617
  const expected = {
@@ -2882,4 +3147,3473 @@ export const normalizeCloudlyLegacyDeploymentSettlementProductionReceiptStructur
2882
3147
  return receipt;
2883
3148
  };
2884
3149
 
3150
+ export interface ICloudlyLegacyDeploymentSettlementRequestBundleV1 {
3151
+ schemaVersion: 1;
3152
+ kind: 'cloudly-legacy-deployment-settlement-request-bundle';
3153
+ authenticatedRehearsalBinding:
3154
+ IAuthenticatedCloudlyLegacyDeploymentSettlementRehearsalBindingV1;
3155
+ authenticatedRequest: IAuthenticatedCloudlyLegacyDeploymentSettlementProductionRequestV1;
3156
+ }
3157
+
3158
+ export type TCloudlyLegacyDeploymentSettlementExecutionPurpose =
3159
+ | 'scratch-rehearsal'
3160
+ | 'production';
3161
+
3162
+ export interface ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1 {
3163
+ schemaVersion: 1;
3164
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-identity';
3165
+ attemptId: string;
3166
+ purpose: TCloudlyLegacyDeploymentSettlementExecutionPurpose;
3167
+ operationId: string;
3168
+ settlementId: string;
3169
+ executionAuthority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3170
+ sourceAuthority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3171
+ authenticatedPlanSha256: string;
3172
+ requestBundleSha256: string;
3173
+ scratchReceiptSha256: string | null;
3174
+ }
3175
+
3176
+ export type TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1 =
3177
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1 & {
3178
+ purpose: 'scratch-rehearsal';
3179
+ scratchReceiptSha256: null;
3180
+ };
3181
+ export type TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1 =
3182
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1 & {
3183
+ purpose: 'production';
3184
+ scratchReceiptSha256: string;
3185
+ };
3186
+ export type TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1 =
3187
+ | TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1
3188
+ | TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
3189
+
3190
+ export interface ICloudlyLegacyDeploymentSettlementExecutionAttemptPreparedV1 {
3191
+ schemaVersion: 1;
3192
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation';
3193
+ identity: TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
3194
+ state: 'prepared';
3195
+ preparedAt: number;
3196
+ }
3197
+
3198
+ export interface ICloudlyLegacyDeploymentSettlementExecutionAttemptCommittedV1 {
3199
+ schemaVersion: 1;
3200
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation';
3201
+ identity: TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
3202
+ state: 'committed';
3203
+ preparedAt: number;
3204
+ resolvedAt: number;
3205
+ receiptSchemaVersion: 1 | 2;
3206
+ receiptSha256: string;
3207
+ }
3208
+
3209
+ export interface ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1 {
3210
+ schemaVersion: 1;
3211
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation';
3212
+ identity: TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
3213
+ state: 'aborted';
3214
+ preparedAt: number;
3215
+ resolvedAt: number;
3216
+ }
3217
+
3218
+ export type TCloudlyLegacyDeploymentSettlementExecutionAttemptObservationV1 =
3219
+ | ICloudlyLegacyDeploymentSettlementExecutionAttemptPreparedV1
3220
+ | ICloudlyLegacyDeploymentSettlementExecutionAttemptCommittedV1
3221
+ | ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1;
3222
+
3223
+ const requestBundleKeys = [
3224
+ 'schemaVersion',
3225
+ 'kind',
3226
+ 'authenticatedRehearsalBinding',
3227
+ 'authenticatedRequest',
3228
+ ] as const;
3229
+
3230
+ export const normalizeCloudlyLegacyDeploymentSettlementRequestBundle = (
3231
+ valueArg: unknown,
3232
+ ): Readonly<ICloudlyLegacyDeploymentSettlementRequestBundleV1> => {
3233
+ const value = readRecord(valueArg, 'requestBundle');
3234
+ assertExactKeys(value, requestBundleKeys, 'requestBundle');
3235
+ if (value.schemaVersion !== 1
3236
+ || value.kind !== 'cloudly-legacy-deployment-settlement-request-bundle') {
3237
+ fail('INVALID_VALUE', 'requestBundle.kind');
3238
+ }
3239
+ const authenticatedRehearsalBinding =
3240
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedRehearsalBindingStructure(
3241
+ value.authenticatedRehearsalBinding,
3242
+ );
3243
+ const authenticatedRequest =
3244
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedProductionRequestStructure(
3245
+ value.authenticatedRequest,
3246
+ );
3247
+ if (canonicalize(authenticatedRehearsalBinding.authority, 'requestBundle.binding.authority')
3248
+ !== canonicalize(authenticatedRequest.authority, 'requestBundle.request.authority')
3249
+ || canonicalize(
3250
+ authenticatedRehearsalBinding.payload,
3251
+ 'requestBundle.binding.payload',
3252
+ ) !== canonicalize(
3253
+ authenticatedRequest.payload.rehearsalBinding,
3254
+ 'requestBundle.request.rehearsalBinding',
3255
+ )
3256
+ || authenticatedRehearsalBinding.payloadSha256
3257
+ !== authenticatedRequest.payload.rehearsalBindingSha256) {
3258
+ fail('CROSS_FIELD_MISMATCH', 'requestBundle.authenticatedRehearsalBinding');
3259
+ }
3260
+ return finalize({
3261
+ schemaVersion: 1,
3262
+ kind: 'cloudly-legacy-deployment-settlement-request-bundle',
3263
+ authenticatedRehearsalBinding,
3264
+ authenticatedRequest,
3265
+ }, cloudlyLegacyDeploymentSettlementLimits.maximumAuthenticatedArtifactBytes * 2, 'requestBundle');
3266
+ };
3267
+
3268
+ export const encodeCloudlyLegacyDeploymentSettlementRequestBundle = (
3269
+ valueArg: unknown,
3270
+ ): Uint8Array => encodeNormalized(
3271
+ normalizeCloudlyLegacyDeploymentSettlementRequestBundle(valueArg),
3272
+ 'requestBundle',
3273
+ );
3274
+
3275
+ export const digestCloudlyLegacyDeploymentSettlementRequestBundle = (
3276
+ valueArg: unknown,
3277
+ ): string => digestBytes(encodeCloudlyLegacyDeploymentSettlementRequestBundle(valueArg));
3278
+
3279
+ const executionAttemptIdentityKeys = [
3280
+ 'schemaVersion',
3281
+ 'kind',
3282
+ 'attemptId',
3283
+ 'purpose',
3284
+ 'operationId',
3285
+ 'settlementId',
3286
+ 'executionAuthority',
3287
+ 'sourceAuthority',
3288
+ 'authenticatedPlanSha256',
3289
+ 'requestBundleSha256',
3290
+ 'scratchReceiptSha256',
3291
+ ] as const;
3292
+
3293
+ const executionAttemptIdentitySeed = (
3294
+ valueArg: Omit<ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1, 'attemptId'>,
3295
+ ): unknown => ({
3296
+ schemaVersion: valueArg.schemaVersion,
3297
+ kind: valueArg.kind,
3298
+ purpose: valueArg.purpose,
3299
+ operationId: valueArg.operationId,
3300
+ settlementId: valueArg.settlementId,
3301
+ executionAuthority: valueArg.executionAuthority,
3302
+ sourceAuthority: valueArg.sourceAuthority,
3303
+ authenticatedPlanSha256: valueArg.authenticatedPlanSha256,
3304
+ requestBundleSha256: valueArg.requestBundleSha256,
3305
+ scratchReceiptSha256: valueArg.scratchReceiptSha256,
3306
+ });
3307
+
3308
+ const createExecutionAttemptId = (
3309
+ valueArg: Omit<ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1, 'attemptId'>,
3310
+ ): string => `settlement-attempt-${digestBytes(encodeNormalized(
3311
+ executionAttemptIdentitySeed(valueArg),
3312
+ 'executionAttemptIdentity.seed',
3313
+ )).slice(0, 40)}`;
3314
+
3315
+ const normalizeExecutionAttemptIdentityInternal = (
3316
+ valueArg: unknown,
3317
+ pathArg: string,
3318
+ ): TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1 => {
3319
+ const value = readRecord(valueArg, pathArg);
3320
+ assertExactKeys(value, executionAttemptIdentityKeys, pathArg);
3321
+ if (value.schemaVersion !== 1
3322
+ || value.kind !== 'cloudly-legacy-deployment-settlement-execution-attempt-identity') {
3323
+ fail('INVALID_VALUE', `${pathArg}.kind`);
3324
+ }
3325
+ const purpose = readLiteral(
3326
+ value.purpose,
3327
+ ['scratch-rehearsal', 'production'],
3328
+ `${pathArg}.purpose`,
3329
+ );
3330
+ const operationId = readIdentifier(value.operationId, `${pathArg}.operationId`);
3331
+ const executionAuthority = normalizeAuthorityReferenceInternal(
3332
+ value.executionAuthority,
3333
+ `${pathArg}.executionAuthority`,
3334
+ );
3335
+ const sourceAuthority = normalizeAuthorityReferenceInternal(
3336
+ value.sourceAuthority,
3337
+ `${pathArg}.sourceAuthority`,
3338
+ );
3339
+ const usesSameAuthority = canonicalize(executionAuthority, `${pathArg}.executionAuthority`)
3340
+ === canonicalize(sourceAuthority, `${pathArg}.sourceAuthority`);
3341
+ if (executionAuthority.operationId !== operationId
3342
+ || sourceAuthority.operationId !== operationId
3343
+ || (purpose === 'scratch-rehearsal') !== usesSameAuthority) {
3344
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.executionAuthority`);
3345
+ }
3346
+ const scratchReceiptSha256 = value.scratchReceiptSha256 === null
3347
+ ? null
3348
+ : readSha256(value.scratchReceiptSha256, `${pathArg}.scratchReceiptSha256`);
3349
+ if ((purpose === 'production') !== (scratchReceiptSha256 !== null)) {
3350
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.scratchReceiptSha256`);
3351
+ }
3352
+ const identityWithoutId = {
3353
+ schemaVersion: 1 as const,
3354
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-identity' as const,
3355
+ purpose,
3356
+ operationId,
3357
+ settlementId: readIdentifier(value.settlementId, `${pathArg}.settlementId`),
3358
+ executionAuthority,
3359
+ sourceAuthority,
3360
+ authenticatedPlanSha256: readSha256(
3361
+ value.authenticatedPlanSha256,
3362
+ `${pathArg}.authenticatedPlanSha256`,
3363
+ ),
3364
+ requestBundleSha256: readSha256(
3365
+ value.requestBundleSha256,
3366
+ `${pathArg}.requestBundleSha256`,
3367
+ ),
3368
+ scratchReceiptSha256,
3369
+ };
3370
+ const attemptId = readIdentifier(value.attemptId, `${pathArg}.attemptId`);
3371
+ if (attemptId !== createExecutionAttemptId(identityWithoutId)) {
3372
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.attemptId`);
3373
+ }
3374
+ return { ...identityWithoutId, attemptId } as
3375
+ TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
3376
+ };
3377
+
3378
+ export function createCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(
3379
+ valueArg: Omit<
3380
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1,
3381
+ 'schemaVersion' | 'kind' | 'attemptId'
3382
+ >,
3383
+ ): Readonly<TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1>;
3384
+ export function createCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(
3385
+ valueArg: Omit<
3386
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
3387
+ 'schemaVersion' | 'kind' | 'attemptId'
3388
+ >,
3389
+ ): Readonly<TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1>;
3390
+ export function createCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(
3391
+ valueArg: Omit<
3392
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1,
3393
+ 'schemaVersion' | 'kind' | 'attemptId'
3394
+ >,
3395
+ ): Readonly<TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1>;
3396
+ export function createCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(
3397
+ valueArg: Omit<
3398
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1,
3399
+ 'schemaVersion' | 'kind' | 'attemptId'
3400
+ >,
3401
+ ): Readonly<TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1> {
3402
+ const seed = {
3403
+ schemaVersion: 1 as const,
3404
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-identity' as const,
3405
+ purpose: valueArg.purpose,
3406
+ operationId: valueArg.operationId,
3407
+ settlementId: valueArg.settlementId,
3408
+ executionAuthority: valueArg.executionAuthority,
3409
+ sourceAuthority: valueArg.sourceAuthority,
3410
+ authenticatedPlanSha256: valueArg.authenticatedPlanSha256,
3411
+ requestBundleSha256: valueArg.requestBundleSha256,
3412
+ scratchReceiptSha256: valueArg.scratchReceiptSha256,
3413
+ };
3414
+ return normalizeCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity({
3415
+ ...seed,
3416
+ attemptId: createExecutionAttemptId(seed),
3417
+ });
3418
+ }
3419
+
3420
+ export const normalizeCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity = (
3421
+ valueArg: unknown,
3422
+ ): Readonly<TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1> => finalize(
3423
+ normalizeExecutionAttemptIdentityInternal(valueArg, 'executionAttemptIdentity'),
3424
+ cloudlyLegacyDeploymentSettlementLimits.maximumAuthorityBytes,
3425
+ 'executionAttemptIdentity',
3426
+ );
3427
+
3428
+ export const encodeCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity = (
3429
+ valueArg: unknown,
3430
+ ): Uint8Array => encodeNormalized(
3431
+ normalizeCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(valueArg),
3432
+ 'executionAttemptIdentity',
3433
+ );
3434
+
3435
+ export const digestCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity = (
3436
+ valueArg: unknown,
3437
+ ): string => digestBytes(
3438
+ encodeCloudlyLegacyDeploymentSettlementExecutionAttemptIdentity(valueArg),
3439
+ );
3440
+
3441
+ const normalizeExecutionAttemptObservationInternal = (
3442
+ valueArg: unknown,
3443
+ pathArg: string,
3444
+ ): TCloudlyLegacyDeploymentSettlementExecutionAttemptObservationV1 => {
3445
+ const value = readRecord(valueArg, pathArg);
3446
+ const state = readLiteral(value.state, ['prepared', 'committed', 'aborted'], `${pathArg}.state`);
3447
+ assertExactKeys(value, [
3448
+ 'schemaVersion',
3449
+ 'kind',
3450
+ 'identity',
3451
+ 'state',
3452
+ 'preparedAt',
3453
+ ...(state === 'committed' ? ['resolvedAt', 'receiptSchemaVersion', 'receiptSha256'] : []),
3454
+ ...(state === 'aborted' ? ['resolvedAt'] : []),
3455
+ ], pathArg);
3456
+ if (value.schemaVersion !== 1
3457
+ || value.kind !== 'cloudly-legacy-deployment-settlement-execution-attempt-observation') {
3458
+ fail('INVALID_VALUE', `${pathArg}.kind`);
3459
+ }
3460
+ const identity = normalizeExecutionAttemptIdentityInternal(value.identity, `${pathArg}.identity`);
3461
+ const preparedAt = readInteger(value.preparedAt, `${pathArg}.preparedAt`, 1);
3462
+ if (state === 'prepared') {
3463
+ return {
3464
+ schemaVersion: 1,
3465
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation',
3466
+ identity,
3467
+ state,
3468
+ preparedAt,
3469
+ };
3470
+ }
3471
+ const resolvedAt = readInteger(value.resolvedAt, `${pathArg}.resolvedAt`, preparedAt);
3472
+ if (state === 'aborted') {
3473
+ return {
3474
+ schemaVersion: 1,
3475
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation',
3476
+ identity,
3477
+ state,
3478
+ preparedAt,
3479
+ resolvedAt,
3480
+ };
3481
+ }
3482
+ if (value.receiptSchemaVersion !== 1 && value.receiptSchemaVersion !== 2) {
3483
+ fail('INVALID_VALUE', `${pathArg}.receiptSchemaVersion`);
3484
+ }
3485
+ const receiptSchemaVersion = value.receiptSchemaVersion as 1 | 2;
3486
+ return {
3487
+ schemaVersion: 1,
3488
+ kind: 'cloudly-legacy-deployment-settlement-execution-attempt-observation',
3489
+ identity,
3490
+ state,
3491
+ preparedAt,
3492
+ resolvedAt,
3493
+ receiptSchemaVersion,
3494
+ receiptSha256: readSha256(value.receiptSha256, `${pathArg}.receiptSha256`),
3495
+ };
3496
+ };
3497
+
3498
+ export const normalizeCloudlyLegacyDeploymentSettlementExecutionAttemptObservation = (
3499
+ valueArg: unknown,
3500
+ ): Readonly<TCloudlyLegacyDeploymentSettlementExecutionAttemptObservationV1> => finalize(
3501
+ normalizeExecutionAttemptObservationInternal(valueArg, 'executionAttemptObservation'),
3502
+ cloudlyLegacyDeploymentSettlementLimits.maximumAuthorityBytes,
3503
+ 'executionAttemptObservation',
3504
+ );
3505
+
3506
+ export const encodeCloudlyLegacyDeploymentSettlementExecutionAttemptObservation = (
3507
+ valueArg: unknown,
3508
+ ): Uint8Array => encodeNormalized(
3509
+ normalizeCloudlyLegacyDeploymentSettlementExecutionAttemptObservation(valueArg),
3510
+ 'executionAttemptObservation',
3511
+ );
3512
+
3513
+ export const digestCloudlyLegacyDeploymentSettlementExecutionAttemptObservation = (
3514
+ valueArg: unknown,
3515
+ ): string => digestBytes(
3516
+ encodeCloudlyLegacyDeploymentSettlementExecutionAttemptObservation(valueArg),
3517
+ );
3518
+
3519
+ export interface ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationPayloadV1 {
3520
+ schemaVersion: 1;
3521
+ kind: 'cloudly-legacy-deployment-settlement-production-execution-authorization';
3522
+ authority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3523
+ sourceAuthority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3524
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
3525
+ authenticatedPlanSha256: string;
3526
+ requestBundleSha256: string;
3527
+ scratchReceiptSha256: string;
3528
+ maintenanceImageDigest: `sha256:${string}`;
3529
+ operationId: string;
3530
+ settlementId: string;
3531
+ runId: string;
3532
+ rehearsalId: string;
3533
+ scratchServiceId: string;
3534
+ allocationId: string;
3535
+ allocationGeneration: number;
3536
+ allocationBindingSha256: string;
3537
+ allocationReceiptSha256: string;
3538
+ sourceImageDigest: `sha256:${string}`;
3539
+ targetImageDigest: `sha256:${string}`;
3540
+ requestedAt: number;
3541
+ approvedAt: number;
3542
+ }
3543
+
3544
+ export interface ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1
3545
+ extends ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationPayloadV1 {
3546
+ payloadSha256: string;
3547
+ mac: string;
3548
+ }
3549
+
3550
+ export type TCloudlyLegacyDeploymentSettlementUnsignedProductionExecutionAuthorizationV1 =
3551
+ Omit<ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1, 'mac'>;
3552
+
3553
+ export interface ICloudlyLegacyDeploymentSettlementProductionReceiptPayloadV2 {
3554
+ schemaVersion: 2;
3555
+ kind: 'cloudly-legacy-deployment-settlement-production-receipt';
3556
+ authority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3557
+ sourceAuthority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
3558
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
3559
+ productionAuthorization:
3560
+ ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1;
3561
+ productionAuthorizationSha256: string;
3562
+ requestSha256: string;
3563
+ requestBundleSha256: string;
3564
+ scratchReceipt: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
3565
+ scratchReceiptSha256: string;
3566
+ stableOutcome: ICloudlyLegacyDeploymentSettlementStableOutcomeV1;
3567
+ stableOutcomeSha256: string;
3568
+ transactionCommitted: true;
3569
+ disposition: 'applied' | 'exact-replay' | 'no-op';
3570
+ completedAt: number;
3571
+ }
3572
+
3573
+ export interface ICloudlyLegacyDeploymentSettlementProductionReceiptV2
3574
+ extends ICloudlyLegacyDeploymentSettlementProductionReceiptPayloadV2 {
3575
+ payloadSha256: string;
3576
+ mac: string;
3577
+ }
3578
+
3579
+ export type TCloudlyLegacyDeploymentSettlementUnsignedProductionReceiptV2 =
3580
+ Omit<ICloudlyLegacyDeploymentSettlementProductionReceiptV2, 'mac'>;
3581
+ export type TCloudlyLegacyDeploymentSettlementProductionReceipt =
3582
+ | ICloudlyLegacyDeploymentSettlementProductionReceiptV1
3583
+ | ICloudlyLegacyDeploymentSettlementProductionReceiptV2;
3584
+
3585
+ const productionExecutionAuthorizationPayloadKeys = [
3586
+ 'schemaVersion',
3587
+ 'kind',
3588
+ 'authority',
3589
+ 'sourceAuthority',
3590
+ 'executionAttempt',
3591
+ 'authenticatedPlanSha256',
3592
+ 'requestBundleSha256',
3593
+ 'scratchReceiptSha256',
3594
+ 'maintenanceImageDigest',
3595
+ 'operationId',
3596
+ 'settlementId',
3597
+ 'runId',
3598
+ 'rehearsalId',
3599
+ 'scratchServiceId',
3600
+ 'allocationId',
3601
+ 'allocationGeneration',
3602
+ 'allocationBindingSha256',
3603
+ 'allocationReceiptSha256',
3604
+ 'sourceImageDigest',
3605
+ 'targetImageDigest',
3606
+ 'requestedAt',
3607
+ 'approvedAt',
3608
+ ] as const;
3609
+ const unsignedProductionExecutionAuthorizationKeys = [
3610
+ ...productionExecutionAuthorizationPayloadKeys,
3611
+ 'payloadSha256',
3612
+ ] as const;
3613
+ const productionExecutionAuthorizationKeys = [
3614
+ ...unsignedProductionExecutionAuthorizationKeys,
3615
+ 'mac',
3616
+ ] as const;
3617
+
3618
+ const productionExecutionAuthorizationPayload = (
3619
+ valueArg: ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationPayloadV1,
3620
+ ): unknown => Object.fromEntries(productionExecutionAuthorizationPayloadKeys.map((keyArg) => [
3621
+ keyArg,
3622
+ valueArg[keyArg],
3623
+ ]));
3624
+
3625
+ const normalizeProductionExecutionAuthorizationPayloadInternal = (
3626
+ valueArg: unknown,
3627
+ pathArg: string,
3628
+ ): ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationPayloadV1 => {
3629
+ const value = readRecord(valueArg, pathArg);
3630
+ assertExactKeys(value, productionExecutionAuthorizationPayloadKeys, pathArg);
3631
+ if (value.schemaVersion !== 1
3632
+ || value.kind
3633
+ !== 'cloudly-legacy-deployment-settlement-production-execution-authorization') {
3634
+ fail('INVALID_VALUE', `${pathArg}.kind`);
3635
+ }
3636
+ const authority = normalizeAuthorityReferenceInternal(value.authority, `${pathArg}.authority`);
3637
+ const sourceAuthority = normalizeAuthorityReferenceInternal(
3638
+ value.sourceAuthority,
3639
+ `${pathArg}.sourceAuthority`,
3640
+ );
3641
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
3642
+ value.executionAttempt,
3643
+ `${pathArg}.executionAttempt`,
3644
+ );
3645
+ const operationId = readIdentifier(value.operationId, `${pathArg}.operationId`);
3646
+ const settlementId = readIdentifier(value.settlementId, `${pathArg}.settlementId`);
3647
+ const authenticatedPlanSha256 = readSha256(
3648
+ value.authenticatedPlanSha256,
3649
+ `${pathArg}.authenticatedPlanSha256`,
3650
+ );
3651
+ const requestBundleSha256 = readSha256(
3652
+ value.requestBundleSha256,
3653
+ `${pathArg}.requestBundleSha256`,
3654
+ );
3655
+ const scratchReceiptSha256 = readSha256(
3656
+ value.scratchReceiptSha256,
3657
+ `${pathArg}.scratchReceiptSha256`,
3658
+ );
3659
+ if (executionAttempt.purpose !== 'production'
3660
+ || executionAttempt.operationId !== operationId
3661
+ || executionAttempt.settlementId !== settlementId
3662
+ || authority.authorityId === sourceAuthority.authorityId
3663
+ || authority.keyId === sourceAuthority.keyId
3664
+ || canonicalize(authority, `${pathArg}.authority`)
3665
+ === canonicalize(sourceAuthority, `${pathArg}.sourceAuthority`)
3666
+ || canonicalize(executionAttempt.executionAuthority, `${pathArg}.attempt.executionAuthority`)
3667
+ !== canonicalize(authority, `${pathArg}.authority`)
3668
+ || canonicalize(executionAttempt.sourceAuthority, `${pathArg}.attempt.sourceAuthority`)
3669
+ !== canonicalize(sourceAuthority, `${pathArg}.sourceAuthority`)
3670
+ || executionAttempt.authenticatedPlanSha256 !== authenticatedPlanSha256
3671
+ || executionAttempt.requestBundleSha256 !== requestBundleSha256
3672
+ || executionAttempt.scratchReceiptSha256 !== scratchReceiptSha256) {
3673
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.executionAttempt`);
3674
+ }
3675
+ const requestedAt = readInteger(value.requestedAt, `${pathArg}.requestedAt`, 1);
3676
+ const approvedAt = readInteger(value.approvedAt, `${pathArg}.approvedAt`, requestedAt);
3677
+ return {
3678
+ schemaVersion: 1,
3679
+ kind: 'cloudly-legacy-deployment-settlement-production-execution-authorization',
3680
+ authority,
3681
+ sourceAuthority,
3682
+ executionAttempt: executionAttempt as
3683
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
3684
+ authenticatedPlanSha256,
3685
+ requestBundleSha256,
3686
+ scratchReceiptSha256,
3687
+ maintenanceImageDigest: readOciDigest(
3688
+ value.maintenanceImageDigest,
3689
+ `${pathArg}.maintenanceImageDigest`,
3690
+ ),
3691
+ operationId,
3692
+ settlementId,
3693
+ runId: readIdentifier(value.runId, `${pathArg}.runId`),
3694
+ rehearsalId: readIdentifier(value.rehearsalId, `${pathArg}.rehearsalId`),
3695
+ scratchServiceId: readIdentifier(value.scratchServiceId, `${pathArg}.scratchServiceId`),
3696
+ allocationId: readIdentifier(value.allocationId, `${pathArg}.allocationId`),
3697
+ allocationGeneration: readInteger(
3698
+ value.allocationGeneration,
3699
+ `${pathArg}.allocationGeneration`,
3700
+ 1,
3701
+ ),
3702
+ allocationBindingSha256: readSha256(
3703
+ value.allocationBindingSha256,
3704
+ `${pathArg}.allocationBindingSha256`,
3705
+ ),
3706
+ allocationReceiptSha256: readSha256(
3707
+ value.allocationReceiptSha256,
3708
+ `${pathArg}.allocationReceiptSha256`,
3709
+ ),
3710
+ sourceImageDigest: readOciDigest(value.sourceImageDigest, `${pathArg}.sourceImageDigest`),
3711
+ targetImageDigest: readOciDigest(value.targetImageDigest, `${pathArg}.targetImageDigest`),
3712
+ requestedAt,
3713
+ approvedAt,
3714
+ };
3715
+ };
3716
+
3717
+ const normalizeUnsignedProductionExecutionAuthorizationInternal = (
3718
+ valueArg: unknown,
3719
+ pathArg: string,
3720
+ ): TCloudlyLegacyDeploymentSettlementUnsignedProductionExecutionAuthorizationV1 => {
3721
+ const value = readRecord(valueArg, pathArg);
3722
+ assertExactKeys(value, unsignedProductionExecutionAuthorizationKeys, pathArg);
3723
+ const payloadInput = Object.fromEntries(productionExecutionAuthorizationPayloadKeys.map(
3724
+ (keyArg) => [keyArg, value[keyArg]],
3725
+ ));
3726
+ const payload = normalizeProductionExecutionAuthorizationPayloadInternal(
3727
+ payloadInput,
3728
+ `${pathArg}.payload`,
3729
+ );
3730
+ const payloadSha256 = readSha256(value.payloadSha256, `${pathArg}.payloadSha256`);
3731
+ if (payloadSha256 !== digestBytes(encodeNormalized(
3732
+ productionExecutionAuthorizationPayload(payload),
3733
+ `${pathArg}.payload`,
3734
+ ))) {
3735
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.payloadSha256`);
3736
+ }
3737
+ return { ...payload, payloadSha256 };
3738
+ };
3739
+
3740
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization = (
3741
+ valueArg: unknown,
3742
+ ): Readonly<ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1> => {
3743
+ const value = readRecord(valueArg, 'productionExecutionAuthorization');
3744
+ assertExactKeys(value, productionExecutionAuthorizationKeys, 'productionExecutionAuthorization');
3745
+ const unsignedInput = Object.fromEntries(unsignedProductionExecutionAuthorizationKeys.map(
3746
+ (keyArg) => [keyArg, value[keyArg]],
3747
+ ));
3748
+ return finalize({
3749
+ ...normalizeUnsignedProductionExecutionAuthorizationInternal(
3750
+ unsignedInput,
3751
+ 'productionExecutionAuthorization.unsigned',
3752
+ ),
3753
+ mac: readMac(value.mac, 'productionExecutionAuthorization.mac'),
3754
+ }, cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes, 'productionExecutionAuthorization');
3755
+ };
3756
+
3757
+ export const digestCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationPayload = (
3758
+ valueArg: unknown,
3759
+ ): string => digestBytes(encodeNormalized(
3760
+ productionExecutionAuthorizationPayload(
3761
+ normalizeProductionExecutionAuthorizationPayloadInternal(
3762
+ valueArg,
3763
+ 'productionExecutionAuthorizationPayload',
3764
+ ),
3765
+ ),
3766
+ 'productionExecutionAuthorizationPayload',
3767
+ ));
3768
+
3769
+ export const encodeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization = (
3770
+ valueArg: unknown,
3771
+ ): Uint8Array => encodeNormalized(
3772
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(valueArg),
3773
+ 'productionExecutionAuthorization',
3774
+ );
3775
+
3776
+ export const digestCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization = (
3777
+ valueArg: unknown,
3778
+ ): string => digestBytes(
3779
+ encodeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(valueArg),
3780
+ );
3781
+
3782
+ export const encodeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationHmacInput = (
3783
+ valueArg: unknown,
3784
+ ): Uint8Array => frame(
3785
+ cloudlyLegacyDeploymentSettlementDomains.productionExecutionAuthorizationHmac,
3786
+ encodeNormalized(
3787
+ finalize(
3788
+ normalizeUnsignedProductionExecutionAuthorizationInternal(
3789
+ valueArg,
3790
+ 'unsignedProductionExecutionAuthorization',
3791
+ ),
3792
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes,
3793
+ 'unsignedProductionExecutionAuthorization',
3794
+ ),
3795
+ 'productionExecutionAuthorization.authenticated',
3796
+ ),
3797
+ );
3798
+
3799
+ export const normalizeCloudlyLegacyDeploymentSettlementRequestBundleForAuthority = async (
3800
+ bundleArg: unknown,
3801
+ authenticatedPlanArg: unknown,
3802
+ metadataArg: unknown,
3803
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
3804
+ ): Promise<Readonly<ICloudlyLegacyDeploymentSettlementRequestBundleV1>> => {
3805
+ const metadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(metadataArg);
3806
+ const plan = await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementPlanForAuthority(
3807
+ authenticatedPlanArg,
3808
+ metadata,
3809
+ verifierArg,
3810
+ );
3811
+ const bundle = normalizeCloudlyLegacyDeploymentSettlementRequestBundle(bundleArg);
3812
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementRehearsalBindingForAuthority(
3813
+ bundle.authenticatedRehearsalBinding,
3814
+ metadata,
3815
+ verifierArg,
3816
+ );
3817
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementProductionRequestForAuthority(
3818
+ bundle.authenticatedRequest,
3819
+ metadata,
3820
+ verifierArg,
3821
+ );
3822
+ if (canonicalize(plan.payload, 'requestBundle.plan')
3823
+ !== canonicalize(bundle.authenticatedRequest.payload.plan, 'requestBundle.request.plan')
3824
+ || plan.payloadSha256 !== bundle.authenticatedRequest.payload.planSha256) {
3825
+ fail('CROSS_FIELD_MISMATCH', 'requestBundle.authenticatedRequest.plan');
3826
+ }
3827
+ return bundle;
3828
+ };
3829
+
3830
+ const assertProductionAuthorizationMetadata = (
3831
+ authorizationArg: ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1,
3832
+ productionMetadataArg:
3833
+ ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1,
3834
+ sourceMetadataArg: ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1,
3835
+ ): void => {
3836
+ assertAuthorityReferenceMatchesMetadata(
3837
+ authorizationArg.authority,
3838
+ productionMetadataArg,
3839
+ 'productionExecutionAuthorization.authority',
3840
+ );
3841
+ assertAuthorityReferenceMatchesMetadata(
3842
+ authorizationArg.sourceAuthority,
3843
+ sourceMetadataArg,
3844
+ 'productionExecutionAuthorization.sourceAuthority',
3845
+ );
3846
+ if (canonicalize(productionMetadataArg.sourceAuthority, 'productionMetadata.sourceAuthority')
3847
+ !== canonicalize(authorizationArg.sourceAuthority, 'authorization.sourceAuthority')
3848
+ || productionMetadataArg.sourceAuthenticatedPlanSha256
3849
+ !== authorizationArg.authenticatedPlanSha256
3850
+ || productionMetadataArg.sourceRequestBundleSha256 !== authorizationArg.requestBundleSha256
3851
+ || productionMetadataArg.scratchReceiptSha256 !== authorizationArg.scratchReceiptSha256
3852
+ || authorizationArg.operationId !== productionMetadataArg.operationId
3853
+ || authorizationArg.operationId !== sourceMetadataArg.operationId
3854
+ || authorizationArg.settlementId !== productionMetadataArg.settlementId
3855
+ || authorizationArg.settlementId !== sourceMetadataArg.settlementId
3856
+ || authorizationArg.runId !== productionMetadataArg.runId
3857
+ || authorizationArg.runId !== sourceMetadataArg.runId
3858
+ || authorizationArg.rehearsalId !== productionMetadataArg.rehearsalId
3859
+ || authorizationArg.rehearsalId !== sourceMetadataArg.rehearsalId
3860
+ || authorizationArg.scratchServiceId !== productionMetadataArg.scratchServiceId
3861
+ || authorizationArg.scratchServiceId !== sourceMetadataArg.scratchServiceId
3862
+ || authorizationArg.allocationId !== productionMetadataArg.allocationId
3863
+ || authorizationArg.allocationId !== sourceMetadataArg.allocationId
3864
+ || authorizationArg.allocationGeneration !== productionMetadataArg.allocationGeneration
3865
+ || authorizationArg.allocationGeneration !== sourceMetadataArg.allocationGeneration
3866
+ || authorizationArg.allocationBindingSha256 !== productionMetadataArg.allocationBindingSha256
3867
+ || authorizationArg.allocationBindingSha256 !== sourceMetadataArg.allocationBindingSha256
3868
+ || authorizationArg.allocationReceiptSha256 !== productionMetadataArg.allocationReceiptSha256
3869
+ || authorizationArg.allocationReceiptSha256 !== sourceMetadataArg.allocationReceiptSha256
3870
+ || authorizationArg.maintenanceImageDigest !== productionMetadataArg.maintenanceImageDigest
3871
+ || authorizationArg.sourceImageDigest !== productionMetadataArg.sourceImageDigest
3872
+ || authorizationArg.sourceImageDigest !== sourceMetadataArg.sourceImageDigest
3873
+ || authorizationArg.targetImageDigest !== productionMetadataArg.targetImageDigest
3874
+ || authorizationArg.targetImageDigest !== sourceMetadataArg.targetImageDigest) {
3875
+ fail('CROSS_FIELD_MISMATCH', 'productionExecutionAuthorization.authorityMetadata');
3876
+ }
3877
+ assertAuthorityTimestamp(
3878
+ authorizationArg.requestedAt,
3879
+ productionMetadataArg,
3880
+ 'productionExecutionAuthorization.requestedAt',
3881
+ );
3882
+ assertAuthorityTimestamp(
3883
+ authorizationArg.approvedAt,
3884
+ productionMetadataArg,
3885
+ 'productionExecutionAuthorization.approvedAt',
3886
+ );
3887
+ };
3888
+
3889
+ const assertProductionAuthorizationArtifacts = (
3890
+ authorizationArg: ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1,
3891
+ productionMetadataArg:
3892
+ ICloudlyLegacyDeploymentSettlementFencedProductionAuthorityMetadataV1,
3893
+ sourceMetadataArg: ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1,
3894
+ authenticatedPlanArg: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1,
3895
+ requestBundleArg: ICloudlyLegacyDeploymentSettlementRequestBundleV1,
3896
+ scratchReceiptArg: ICloudlyLegacyDeploymentSettlementScratchReceiptV1,
3897
+ ): void => {
3898
+ if (authorizationArg.authenticatedPlanSha256
3899
+ !== digestAuthenticatedCloudlyLegacyDeploymentSettlementPlan(authenticatedPlanArg)
3900
+ || authorizationArg.requestBundleSha256
3901
+ !== digestCloudlyLegacyDeploymentSettlementRequestBundle(requestBundleArg)
3902
+ || authorizationArg.scratchReceiptSha256
3903
+ !== digestCloudlyLegacyDeploymentSettlementScratchReceipt(scratchReceiptArg)
3904
+ || productionMetadataArg.issuedAt < scratchReceiptArg.completedAt
3905
+ || authorizationArg.requestedAt < scratchReceiptArg.completedAt
3906
+ || authorizationArg.requestedAt < productionMetadataArg.issuedAt
3907
+ || authorizationArg.approvedAt < authorizationArg.requestedAt) {
3908
+ fail('CROSS_FIELD_MISMATCH', 'productionExecutionAuthorization.sourceProof');
3909
+ }
3910
+ assertProductionAuthorizationMetadata(
3911
+ authorizationArg,
3912
+ productionMetadataArg,
3913
+ sourceMetadataArg,
3914
+ );
3915
+ };
3916
+
3917
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationForAuthorities = async (
3918
+ authorizationArg: unknown,
3919
+ productionMetadataArg: unknown,
3920
+ sourceMetadataArg: unknown,
3921
+ authenticatedPlanArg: unknown,
3922
+ requestBundleArg: unknown,
3923
+ scratchReceiptArg: unknown,
3924
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
3925
+ ): Promise<Readonly<ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1>> => {
3926
+ const {
3927
+ productionMetadata,
3928
+ sourceMetadata,
3929
+ } = normalizeProductionAuthorityMetadataPair(
3930
+ productionMetadataArg,
3931
+ sourceMetadataArg,
3932
+ );
3933
+ const plan = await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementPlanForAuthority(
3934
+ authenticatedPlanArg,
3935
+ sourceMetadata,
3936
+ verifierArg,
3937
+ );
3938
+ const requestBundle = await normalizeCloudlyLegacyDeploymentSettlementRequestBundleForAuthority(
3939
+ requestBundleArg,
3940
+ plan,
3941
+ sourceMetadata,
3942
+ verifierArg,
3943
+ );
3944
+ const scratchReceipt = await normalizeCloudlyLegacyDeploymentSettlementScratchReceiptForAuthority(
3945
+ scratchReceiptArg,
3946
+ sourceMetadata,
3947
+ requestBundle.authenticatedRequest,
3948
+ verifierArg,
3949
+ );
3950
+ const authorization =
3951
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(authorizationArg);
3952
+ assertProductionAuthorizationArtifacts(
3953
+ authorization,
3954
+ productionMetadata,
3955
+ sourceMetadata,
3956
+ plan,
3957
+ requestBundle,
3958
+ scratchReceipt,
3959
+ );
3960
+ await requireConsumerVerifiedHmac(
3961
+ authorization.authority,
3962
+ cloudlyLegacyDeploymentSettlementDomains.productionExecutionAuthorizationHmac,
3963
+ encodeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationHmacInput(
3964
+ withoutArtifactMac(authorization),
3965
+ ),
3966
+ authorization.mac,
3967
+ verifierArg,
3968
+ 'productionExecutionAuthorization.mac',
3969
+ );
3970
+ return authorization;
3971
+ };
3972
+
3973
+ const productionReceiptV2PayloadKeys = [
3974
+ 'schemaVersion',
3975
+ 'kind',
3976
+ 'authority',
3977
+ 'sourceAuthority',
3978
+ 'executionAttempt',
3979
+ 'productionAuthorization',
3980
+ 'productionAuthorizationSha256',
3981
+ 'requestSha256',
3982
+ 'requestBundleSha256',
3983
+ 'scratchReceipt',
3984
+ 'scratchReceiptSha256',
3985
+ 'stableOutcome',
3986
+ 'stableOutcomeSha256',
3987
+ 'transactionCommitted',
3988
+ 'disposition',
3989
+ 'completedAt',
3990
+ ] as const;
3991
+ const unsignedProductionReceiptV2Keys = [...productionReceiptV2PayloadKeys, 'payloadSha256'] as const;
3992
+ const productionReceiptV2Keys = [...unsignedProductionReceiptV2Keys, 'mac'] as const;
3993
+
3994
+ const productionReceiptV2Payload = (
3995
+ valueArg: ICloudlyLegacyDeploymentSettlementProductionReceiptPayloadV2,
3996
+ ): unknown => Object.fromEntries(productionReceiptV2PayloadKeys.map((keyArg) => [
3997
+ keyArg,
3998
+ valueArg[keyArg],
3999
+ ]));
4000
+
4001
+ const normalizeProductionReceiptV2PayloadInternal = (
4002
+ valueArg: unknown,
4003
+ pathArg: string,
4004
+ ): ICloudlyLegacyDeploymentSettlementProductionReceiptPayloadV2 => {
4005
+ const value = readRecord(valueArg, pathArg);
4006
+ assertExactKeys(value, productionReceiptV2PayloadKeys, pathArg);
4007
+ if (value.schemaVersion !== 2
4008
+ || value.kind !== 'cloudly-legacy-deployment-settlement-production-receipt'
4009
+ || value.transactionCommitted !== true) {
4010
+ fail('INVALID_VALUE', `${pathArg}.kind`);
4011
+ }
4012
+ const authority = normalizeAuthorityReferenceInternal(value.authority, `${pathArg}.authority`);
4013
+ const sourceAuthority = normalizeAuthorityReferenceInternal(
4014
+ value.sourceAuthority,
4015
+ `${pathArg}.sourceAuthority`,
4016
+ );
4017
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
4018
+ value.executionAttempt,
4019
+ `${pathArg}.executionAttempt`,
4020
+ );
4021
+ const productionAuthorization =
4022
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(
4023
+ value.productionAuthorization,
4024
+ );
4025
+ const productionAuthorizationSha256 = readSha256(
4026
+ value.productionAuthorizationSha256,
4027
+ `${pathArg}.productionAuthorizationSha256`,
4028
+ );
4029
+ const requestBundleSha256 = readSha256(
4030
+ value.requestBundleSha256,
4031
+ `${pathArg}.requestBundleSha256`,
4032
+ );
4033
+ const scratchReceipt = normalizeScratchReceiptInternal(
4034
+ value.scratchReceipt,
4035
+ `${pathArg}.scratchReceipt`,
4036
+ );
4037
+ const scratchReceiptSha256 = readSha256(
4038
+ value.scratchReceiptSha256,
4039
+ `${pathArg}.scratchReceiptSha256`,
4040
+ );
4041
+ const stableOutcome = normalizeStableOutcomeInternal(
4042
+ value.stableOutcome,
4043
+ `${pathArg}.stableOutcome`,
4044
+ );
4045
+ const stableOutcomeSha256 = readSha256(
4046
+ value.stableOutcomeSha256,
4047
+ `${pathArg}.stableOutcomeSha256`,
4048
+ );
4049
+ const requestSha256 = readSha256(value.requestSha256, `${pathArg}.requestSha256`);
4050
+ const disposition = readLiteral(
4051
+ value.disposition,
4052
+ ['applied', 'exact-replay', 'no-op'],
4053
+ `${pathArg}.disposition`,
4054
+ );
4055
+ const dispositionMatchesScratch = disposition === scratchReceipt.disposition
4056
+ || (scratchReceipt.disposition === 'applied' && disposition === 'exact-replay');
4057
+ if (canonicalize(authority, `${pathArg}.authority`)
4058
+ !== canonicalize(productionAuthorization.authority, `${pathArg}.authorization.authority`)
4059
+ || canonicalize(sourceAuthority, `${pathArg}.sourceAuthority`)
4060
+ !== canonicalize(productionAuthorization.sourceAuthority, `${pathArg}.authorization.sourceAuthority`)
4061
+ || canonicalize(executionAttempt, `${pathArg}.executionAttempt`)
4062
+ !== canonicalize(productionAuthorization.executionAttempt, `${pathArg}.authorization.attempt`)
4063
+ || productionAuthorizationSha256
4064
+ !== digestCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(
4065
+ productionAuthorization,
4066
+ )
4067
+ || requestBundleSha256 !== productionAuthorization.requestBundleSha256
4068
+ || scratchReceiptSha256 !== productionAuthorization.scratchReceiptSha256
4069
+ || scratchReceiptSha256
4070
+ !== digestCloudlyLegacyDeploymentSettlementScratchReceipt(scratchReceipt)
4071
+ || canonicalize(sourceAuthority, `${pathArg}.sourceAuthority`)
4072
+ !== canonicalize(scratchReceipt.authority, `${pathArg}.scratchReceipt.authority`)
4073
+ || requestSha256 !== scratchReceipt.requestSha256
4074
+ || !dispositionMatchesScratch
4075
+ || canonicalize(stableOutcome, `${pathArg}.stableOutcome`)
4076
+ !== canonicalize(scratchReceipt.stableOutcome, `${pathArg}.scratchReceipt.stableOutcome`)
4077
+ || stableOutcomeSha256 !== scratchReceipt.stableOutcomeSha256
4078
+ || stableOutcomeSha256
4079
+ !== digestCloudlyLegacyDeploymentSettlementStableOutcome(stableOutcome)) {
4080
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.productionAuthorization`);
4081
+ }
4082
+ return {
4083
+ schemaVersion: 2,
4084
+ kind: 'cloudly-legacy-deployment-settlement-production-receipt',
4085
+ authority,
4086
+ sourceAuthority,
4087
+ executionAttempt: executionAttempt as
4088
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
4089
+ productionAuthorization,
4090
+ productionAuthorizationSha256,
4091
+ requestSha256,
4092
+ requestBundleSha256,
4093
+ scratchReceipt,
4094
+ scratchReceiptSha256,
4095
+ stableOutcome,
4096
+ stableOutcomeSha256,
4097
+ transactionCommitted: true,
4098
+ disposition,
4099
+ completedAt: readInteger(
4100
+ value.completedAt,
4101
+ `${pathArg}.completedAt`,
4102
+ productionAuthorization.approvedAt,
4103
+ ),
4104
+ };
4105
+ };
4106
+
4107
+ const normalizeUnsignedProductionReceiptV2Internal = (
4108
+ valueArg: unknown,
4109
+ pathArg: string,
4110
+ ): TCloudlyLegacyDeploymentSettlementUnsignedProductionReceiptV2 => {
4111
+ const value = readRecord(valueArg, pathArg);
4112
+ assertExactKeys(value, unsignedProductionReceiptV2Keys, pathArg);
4113
+ const payloadInput = Object.fromEntries(productionReceiptV2PayloadKeys.map(
4114
+ (keyArg) => [keyArg, value[keyArg]],
4115
+ ));
4116
+ const payload = normalizeProductionReceiptV2PayloadInternal(payloadInput, `${pathArg}.payload`);
4117
+ const payloadSha256 = readSha256(value.payloadSha256, `${pathArg}.payloadSha256`);
4118
+ if (payloadSha256 !== digestBytes(encodeNormalized(
4119
+ productionReceiptV2Payload(payload),
4120
+ `${pathArg}.payload`,
4121
+ ))) {
4122
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.payloadSha256`);
4123
+ }
4124
+ return { ...payload, payloadSha256 };
4125
+ };
4126
+
4127
+ export const digestCloudlyLegacyDeploymentSettlementProductionReceiptPayloadV2 = (
4128
+ valueArg: unknown,
4129
+ ): string => digestBytes(encodeNormalized(
4130
+ productionReceiptV2Payload(
4131
+ normalizeProductionReceiptV2PayloadInternal(valueArg, 'productionReceiptPayloadV2'),
4132
+ ),
4133
+ 'productionReceiptPayloadV2',
4134
+ ));
4135
+
4136
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2 = (
4137
+ valueArg: unknown,
4138
+ ): Readonly<ICloudlyLegacyDeploymentSettlementProductionReceiptV2> => {
4139
+ const value = readRecord(valueArg, 'productionReceiptV2');
4140
+ assertExactKeys(value, productionReceiptV2Keys, 'productionReceiptV2');
4141
+ const unsignedInput = Object.fromEntries(unsignedProductionReceiptV2Keys.map(
4142
+ (keyArg) => [keyArg, value[keyArg]],
4143
+ ));
4144
+ return finalize({
4145
+ ...normalizeUnsignedProductionReceiptV2Internal(unsignedInput, 'productionReceiptV2.unsigned'),
4146
+ mac: readMac(value.mac, 'productionReceiptV2.mac'),
4147
+ }, cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 3, 'productionReceiptV2');
4148
+ };
4149
+
4150
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionReceiptAnyVersion = (
4151
+ valueArg: unknown,
4152
+ ): Readonly<TCloudlyLegacyDeploymentSettlementProductionReceipt> => {
4153
+ const value = readRecord(valueArg, 'productionReceipt');
4154
+ return value.schemaVersion === 2
4155
+ ? normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2(value)
4156
+ : normalizeCloudlyLegacyDeploymentSettlementProductionReceipt(value);
4157
+ };
4158
+
4159
+ export const encodeCloudlyLegacyDeploymentSettlementProductionReceiptV2 = (
4160
+ valueArg: unknown,
4161
+ ): Uint8Array => encodeNormalized(
4162
+ normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2(valueArg),
4163
+ 'productionReceiptV2',
4164
+ );
4165
+
4166
+ export const digestCloudlyLegacyDeploymentSettlementProductionReceiptV2 = (
4167
+ valueArg: unknown,
4168
+ ): string => digestBytes(encodeCloudlyLegacyDeploymentSettlementProductionReceiptV2(valueArg));
4169
+
4170
+ export const encodeCloudlyLegacyDeploymentSettlementProductionReceiptV2HmacInput = (
4171
+ valueArg: unknown,
4172
+ ): Uint8Array => frame(
4173
+ cloudlyLegacyDeploymentSettlementDomains.productionReceiptV2Hmac,
4174
+ encodeNormalized(
4175
+ finalize(
4176
+ normalizeUnsignedProductionReceiptV2Internal(valueArg, 'unsignedProductionReceiptV2'),
4177
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 3,
4178
+ 'unsignedProductionReceiptV2',
4179
+ ),
4180
+ 'productionReceiptV2.authenticated',
4181
+ ),
4182
+ );
4183
+
4184
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2ForAuthorities = async (
4185
+ receiptArg: unknown,
4186
+ productionMetadataArg: unknown,
4187
+ sourceMetadataArg: unknown,
4188
+ authenticatedPlanArg: unknown,
4189
+ requestBundleArg: unknown,
4190
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
4191
+ ): Promise<Readonly<ICloudlyLegacyDeploymentSettlementProductionReceiptV2>> => {
4192
+ const {
4193
+ productionMetadata,
4194
+ sourceMetadata,
4195
+ } = normalizeProductionAuthorityMetadataPair(
4196
+ productionMetadataArg,
4197
+ sourceMetadataArg,
4198
+ );
4199
+ const receipt = normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2(receiptArg);
4200
+ const requestBundle = normalizeCloudlyLegacyDeploymentSettlementRequestBundle(requestBundleArg);
4201
+ await normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationForAuthorities(
4202
+ receipt.productionAuthorization,
4203
+ productionMetadata,
4204
+ sourceMetadata,
4205
+ authenticatedPlanArg,
4206
+ requestBundle,
4207
+ receipt.scratchReceipt,
4208
+ verifierArg,
4209
+ );
4210
+ await normalizeCloudlyLegacyDeploymentSettlementScratchReceiptForAuthority(
4211
+ receipt.scratchReceipt,
4212
+ sourceMetadata,
4213
+ requestBundle.authenticatedRequest,
4214
+ verifierArg,
4215
+ );
4216
+ assertAuthorityReferenceMatchesMetadata(
4217
+ receipt.authority,
4218
+ productionMetadata,
4219
+ 'productionReceiptV2.authority',
4220
+ );
4221
+ assertAuthorityTimestamp(receipt.completedAt, productionMetadata, 'productionReceiptV2.completedAt');
4222
+ await requireConsumerVerifiedHmac(
4223
+ receipt.authority,
4224
+ cloudlyLegacyDeploymentSettlementDomains.productionReceiptV2Hmac,
4225
+ encodeCloudlyLegacyDeploymentSettlementProductionReceiptV2HmacInput(
4226
+ withoutArtifactMac(receipt),
4227
+ ),
4228
+ receipt.mac,
4229
+ verifierArg,
4230
+ 'productionReceiptV2.mac',
4231
+ );
4232
+ return receipt;
4233
+ };
4234
+
4235
+ export type TCloudlyLegacyDeploymentSettlementAuthorityStatus = 'active' | 'expired';
4236
+ export type TCloudlyLegacyDeploymentSettlementResolutionMode =
4237
+ | 'committed-schema1'
4238
+ | 'committed-schema2'
4239
+ | 'aborted-prepared'
4240
+ | 'observed-aborted'
4241
+ | 'absent-tombstone'
4242
+ | 'legacy-no-op';
4243
+
4244
+ export type TCloudlyLegacyDeploymentSettlementCommittedReceipt =
4245
+ | ICloudlyLegacyDeploymentSettlementScratchReceiptV1
4246
+ | ICloudlyLegacyDeploymentSettlementProductionReceiptV2;
4247
+ type TCloudlyLegacyDeploymentSettlementCommittedObservationV1<
4248
+ TAttempt extends TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1,
4249
+ TReceiptSchemaVersion extends 1 | 2,
4250
+ > = Omit<
4251
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptCommittedV1,
4252
+ 'identity' | 'receiptSchemaVersion'
4253
+ > & {
4254
+ identity: TAttempt;
4255
+ receiptSchemaVersion: TReceiptSchemaVersion;
4256
+ };
4257
+
4258
+ interface ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4259
+ schemaVersion: 1;
4260
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle';
4261
+ executionAttempt: TCloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
4262
+ observedAt: number;
4263
+ sourceAuthorityStatus: TCloudlyLegacyDeploymentSettlementAuthorityStatus;
4264
+ executionAuthorityStatus: TCloudlyLegacyDeploymentSettlementAuthorityStatus;
4265
+ }
4266
+
4267
+ export interface ICloudlyLegacyDeploymentSettlementCommittedScratchSchema1ResolutionBundleV1
4268
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4269
+ outcome: 'committed';
4270
+ mode: 'committed-schema1';
4271
+ executionAttempt: TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
4272
+ attemptObservation: TCloudlyLegacyDeploymentSettlementCommittedObservationV1<
4273
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1,
4274
+ 1
4275
+ >;
4276
+ originalReceipt: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
4277
+ originalReceiptSha256: string;
4278
+ }
4279
+
4280
+ export interface ICloudlyLegacyDeploymentSettlementCommittedSchema2ResolutionBundleV1
4281
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4282
+ outcome: 'committed';
4283
+ mode: 'committed-schema2';
4284
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
4285
+ attemptObservation: TCloudlyLegacyDeploymentSettlementCommittedObservationV1<
4286
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
4287
+ 2
4288
+ >;
4289
+ originalReceipt: ICloudlyLegacyDeploymentSettlementProductionReceiptV2;
4290
+ originalReceiptSha256: string;
4291
+ }
4292
+
4293
+ export type TCloudlyLegacyDeploymentSettlementCommittedResolutionBundleV1 =
4294
+ | ICloudlyLegacyDeploymentSettlementCommittedScratchSchema1ResolutionBundleV1
4295
+ | ICloudlyLegacyDeploymentSettlementCommittedSchema2ResolutionBundleV1;
4296
+
4297
+ export interface ICloudlyLegacyDeploymentSettlementAbortedPreparedResolutionBundleV1
4298
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4299
+ outcome: 'unapplied';
4300
+ mode: 'aborted-prepared';
4301
+ attemptObservation: ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1;
4302
+ }
4303
+
4304
+ export interface ICloudlyLegacyDeploymentSettlementObservedAbortedResolutionBundleV1
4305
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4306
+ outcome: 'unapplied';
4307
+ mode: 'observed-aborted';
4308
+ attemptObservation: ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1;
4309
+ }
4310
+
4311
+ export type TCloudlyLegacyDeploymentSettlementAbortedResolutionBundleV1 =
4312
+ | ICloudlyLegacyDeploymentSettlementAbortedPreparedResolutionBundleV1
4313
+ | ICloudlyLegacyDeploymentSettlementObservedAbortedResolutionBundleV1;
4314
+
4315
+ export interface ICloudlyLegacyDeploymentSettlementAbsentTombstoneResolutionBundleV1
4316
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4317
+ outcome: 'unapplied';
4318
+ mode: 'absent-tombstone';
4319
+ attemptObservation: ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1;
4320
+ }
4321
+
4322
+ export interface ICloudlyLegacyDeploymentSettlementLegacyNoOpResolutionBundleV1
4323
+ extends ICloudlyLegacyDeploymentSettlementResolutionBundleBaseV1 {
4324
+ outcome: 'unapplied';
4325
+ mode: 'legacy-no-op';
4326
+ executionAttempt: TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
4327
+ attemptObservation: null;
4328
+ }
4329
+
4330
+ export type TCloudlyLegacyDeploymentSettlementResolutionBundleV1 =
4331
+ | ICloudlyLegacyDeploymentSettlementCommittedScratchSchema1ResolutionBundleV1
4332
+ | ICloudlyLegacyDeploymentSettlementCommittedSchema2ResolutionBundleV1
4333
+ | ICloudlyLegacyDeploymentSettlementAbortedPreparedResolutionBundleV1
4334
+ | ICloudlyLegacyDeploymentSettlementObservedAbortedResolutionBundleV1
4335
+ | ICloudlyLegacyDeploymentSettlementAbsentTombstoneResolutionBundleV1
4336
+ | ICloudlyLegacyDeploymentSettlementLegacyNoOpResolutionBundleV1;
4337
+
4338
+ const normalizeCommittedResolutionReceipt = (
4339
+ valueArg: unknown,
4340
+ pathArg: string,
4341
+ ): Readonly<TCloudlyLegacyDeploymentSettlementCommittedReceipt> => {
4342
+ const value = readRecord(valueArg, pathArg);
4343
+ if (value.kind === 'cloudly-legacy-deployment-settlement-scratch-receipt') {
4344
+ return normalizeCloudlyLegacyDeploymentSettlementScratchReceipt(value);
4345
+ }
4346
+ if (value.kind !== 'cloudly-legacy-deployment-settlement-production-receipt') {
4347
+ fail('INVALID_VALUE', `${pathArg}.kind`);
4348
+ }
4349
+ if (value.schemaVersion !== 2) {
4350
+ fail('INVALID_VALUE', `${pathArg}.schemaVersion`);
4351
+ }
4352
+ return normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2(value);
4353
+ };
4354
+
4355
+ /** Structural only; this function does not authenticate receipt MACs. */
4356
+ export const normalizeCloudlyLegacyDeploymentSettlementResolutionBundle = (
4357
+ valueArg: unknown,
4358
+ ): Readonly<TCloudlyLegacyDeploymentSettlementResolutionBundleV1> => {
4359
+ const value = readRecord(valueArg, 'resolutionBundle');
4360
+ const outcome = readLiteral(value.outcome, ['committed', 'unapplied'], 'resolutionBundle.outcome');
4361
+ const mode = readLiteral(value.mode, [
4362
+ 'committed-schema1',
4363
+ 'committed-schema2',
4364
+ 'aborted-prepared',
4365
+ 'observed-aborted',
4366
+ 'absent-tombstone',
4367
+ 'legacy-no-op',
4368
+ ], 'resolutionBundle.mode');
4369
+ const committed = outcome === 'committed';
4370
+ assertExactKeys(value, [
4371
+ 'schemaVersion',
4372
+ 'kind',
4373
+ 'executionAttempt',
4374
+ 'observedAt',
4375
+ 'sourceAuthorityStatus',
4376
+ 'executionAuthorityStatus',
4377
+ 'outcome',
4378
+ 'mode',
4379
+ 'attemptObservation',
4380
+ ...(committed ? ['originalReceipt', 'originalReceiptSha256'] : []),
4381
+ ], 'resolutionBundle');
4382
+ if (value.schemaVersion !== 1
4383
+ || value.kind !== 'cloudly-legacy-deployment-settlement-resolution-bundle') {
4384
+ fail('INVALID_VALUE', 'resolutionBundle.kind');
4385
+ }
4386
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
4387
+ value.executionAttempt,
4388
+ 'resolutionBundle.executionAttempt',
4389
+ );
4390
+ const observedAt = readInteger(value.observedAt, 'resolutionBundle.observedAt', 1);
4391
+ const sourceAuthorityStatus = readLiteral(
4392
+ value.sourceAuthorityStatus,
4393
+ ['active', 'expired'],
4394
+ 'resolutionBundle.sourceAuthorityStatus',
4395
+ );
4396
+ const executionAuthorityStatus = readLiteral(
4397
+ value.executionAuthorityStatus,
4398
+ ['active', 'expired'],
4399
+ 'resolutionBundle.executionAuthorityStatus',
4400
+ );
4401
+ if (canonicalize(executionAttempt.sourceAuthority, 'resolutionBundle.sourceAuthority')
4402
+ === canonicalize(executionAttempt.executionAuthority, 'resolutionBundle.executionAuthority')
4403
+ && sourceAuthorityStatus !== executionAuthorityStatus) {
4404
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.executionAuthorityStatus');
4405
+ }
4406
+ if (committed) {
4407
+ if (mode !== 'committed-schema1' && mode !== 'committed-schema2') {
4408
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.mode');
4409
+ }
4410
+ const attemptObservation = normalizeExecutionAttemptObservationInternal(
4411
+ value.attemptObservation,
4412
+ 'resolutionBundle.attemptObservation',
4413
+ );
4414
+ if (attemptObservation.state !== 'committed') {
4415
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4416
+ }
4417
+ const committedObservation = attemptObservation as
4418
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptCommittedV1;
4419
+ if (canonicalize(committedObservation.identity, 'resolutionBundle.observation.identity')
4420
+ !== canonicalize(executionAttempt, 'resolutionBundle.executionAttempt')) {
4421
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4422
+ }
4423
+ const originalReceipt = normalizeCommittedResolutionReceipt(
4424
+ value.originalReceipt,
4425
+ 'resolutionBundle.originalReceipt',
4426
+ );
4427
+ const receiptSchemaVersion = originalReceipt.schemaVersion;
4428
+ const originalReceiptSha256 = readSha256(
4429
+ value.originalReceiptSha256,
4430
+ 'resolutionBundle.originalReceiptSha256',
4431
+ );
4432
+ const expectedReceiptSha256 = originalReceipt.kind
4433
+ === 'cloudly-legacy-deployment-settlement-scratch-receipt'
4434
+ ? digestCloudlyLegacyDeploymentSettlementScratchReceipt(originalReceipt)
4435
+ : originalReceipt.schemaVersion === 2
4436
+ ? digestCloudlyLegacyDeploymentSettlementProductionReceiptV2(originalReceipt)
4437
+ : digestCloudlyLegacyDeploymentSettlementProductionReceipt(originalReceipt);
4438
+ const receiptExecutionAuthority = originalReceipt.authority;
4439
+ const receiptSourceAuthority = originalReceipt.schemaVersion === 2
4440
+ ? originalReceipt.sourceAuthority
4441
+ : originalReceipt.authority;
4442
+ if ((mode === 'committed-schema1') !== (receiptSchemaVersion === 1)
4443
+ || committedObservation.receiptSchemaVersion !== receiptSchemaVersion
4444
+ || committedObservation.receiptSha256 !== originalReceiptSha256
4445
+ || originalReceiptSha256 !== expectedReceiptSha256
4446
+ || committedObservation.resolvedAt !== originalReceipt.completedAt
4447
+ || observedAt < committedObservation.resolvedAt
4448
+ || canonicalize(receiptExecutionAuthority, 'resolutionBundle.receipt.executionAuthority')
4449
+ !== canonicalize(executionAttempt.executionAuthority, 'resolutionBundle.executionAuthority')
4450
+ || canonicalize(receiptSourceAuthority, 'resolutionBundle.receipt.sourceAuthority')
4451
+ !== canonicalize(executionAttempt.sourceAuthority, 'resolutionBundle.sourceAuthority')
4452
+ || (originalReceipt.schemaVersion === 2
4453
+ && canonicalize(originalReceipt.executionAttempt, 'resolutionBundle.receipt.executionAttempt')
4454
+ !== canonicalize(executionAttempt, 'resolutionBundle.executionAttempt'))
4455
+ || (executionAttempt.purpose === 'scratch-rehearsal')
4456
+ !== (originalReceipt.kind
4457
+ === 'cloudly-legacy-deployment-settlement-scratch-receipt')) {
4458
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.originalReceipt');
4459
+ }
4460
+ let result: TCloudlyLegacyDeploymentSettlementCommittedResolutionBundleV1;
4461
+ if (mode === 'committed-schema1'
4462
+ && originalReceipt.kind === 'cloudly-legacy-deployment-settlement-scratch-receipt') {
4463
+ const scratchAttempt = executionAttempt as
4464
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
4465
+ result = {
4466
+ schemaVersion: 1,
4467
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle',
4468
+ executionAttempt: scratchAttempt,
4469
+ observedAt,
4470
+ sourceAuthorityStatus,
4471
+ executionAuthorityStatus,
4472
+ outcome,
4473
+ mode,
4474
+ attemptObservation: {
4475
+ ...committedObservation,
4476
+ identity: scratchAttempt,
4477
+ receiptSchemaVersion: 1,
4478
+ },
4479
+ originalReceipt,
4480
+ originalReceiptSha256,
4481
+ };
4482
+ } else {
4483
+ const productionAttempt = executionAttempt as
4484
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
4485
+ result = {
4486
+ schemaVersion: 1,
4487
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle',
4488
+ executionAttempt: productionAttempt,
4489
+ observedAt,
4490
+ sourceAuthorityStatus,
4491
+ executionAuthorityStatus,
4492
+ outcome,
4493
+ mode: 'committed-schema2',
4494
+ attemptObservation: {
4495
+ ...committedObservation,
4496
+ identity: productionAttempt,
4497
+ receiptSchemaVersion: 2,
4498
+ },
4499
+ originalReceipt: originalReceipt as
4500
+ ICloudlyLegacyDeploymentSettlementProductionReceiptV2,
4501
+ originalReceiptSha256,
4502
+ };
4503
+ }
4504
+ return finalize(
4505
+ result,
4506
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 4,
4507
+ 'resolutionBundle',
4508
+ );
4509
+ }
4510
+ if (mode === 'committed-schema1' || mode === 'committed-schema2') {
4511
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.mode');
4512
+ }
4513
+ if (mode === 'aborted-prepared'
4514
+ || mode === 'observed-aborted'
4515
+ || mode === 'absent-tombstone') {
4516
+ const attemptObservation = normalizeExecutionAttemptObservationInternal(
4517
+ value.attemptObservation,
4518
+ 'resolutionBundle.attemptObservation',
4519
+ );
4520
+ if (attemptObservation.state !== 'aborted') {
4521
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4522
+ }
4523
+ const abortedObservation = attemptObservation as
4524
+ ICloudlyLegacyDeploymentSettlementExecutionAttemptAbortedV1;
4525
+ if (canonicalize(abortedObservation.identity, 'resolutionBundle.observation.identity')
4526
+ !== canonicalize(executionAttempt, 'resolutionBundle.executionAttempt')
4527
+ || observedAt < abortedObservation.resolvedAt) {
4528
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4529
+ }
4530
+ if (mode === 'absent-tombstone') {
4531
+ const result: ICloudlyLegacyDeploymentSettlementAbsentTombstoneResolutionBundleV1 = {
4532
+ schemaVersion: 1,
4533
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle',
4534
+ executionAttempt,
4535
+ observedAt,
4536
+ sourceAuthorityStatus,
4537
+ executionAuthorityStatus,
4538
+ outcome,
4539
+ mode,
4540
+ attemptObservation: abortedObservation,
4541
+ };
4542
+ return finalize(
4543
+ result,
4544
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes,
4545
+ 'resolutionBundle',
4546
+ );
4547
+ }
4548
+ const result = mode === 'aborted-prepared'
4549
+ ? {
4550
+ schemaVersion: 1 as const,
4551
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle' as const,
4552
+ executionAttempt,
4553
+ observedAt,
4554
+ sourceAuthorityStatus,
4555
+ executionAuthorityStatus,
4556
+ outcome,
4557
+ mode,
4558
+ attemptObservation: abortedObservation,
4559
+ } satisfies ICloudlyLegacyDeploymentSettlementAbortedPreparedResolutionBundleV1
4560
+ : {
4561
+ schemaVersion: 1 as const,
4562
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle' as const,
4563
+ executionAttempt,
4564
+ observedAt,
4565
+ sourceAuthorityStatus,
4566
+ executionAuthorityStatus,
4567
+ outcome,
4568
+ mode,
4569
+ attemptObservation: abortedObservation,
4570
+ } satisfies ICloudlyLegacyDeploymentSettlementObservedAbortedResolutionBundleV1;
4571
+ return finalize(
4572
+ result,
4573
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes,
4574
+ 'resolutionBundle',
4575
+ );
4576
+ }
4577
+ if (value.attemptObservation !== null) {
4578
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4579
+ }
4580
+ if (executionAttempt.purpose !== 'scratch-rehearsal') {
4581
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.executionAttempt');
4582
+ }
4583
+ const scratchExecutionAttempt = executionAttempt as
4584
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
4585
+ const result: ICloudlyLegacyDeploymentSettlementLegacyNoOpResolutionBundleV1 = {
4586
+ schemaVersion: 1,
4587
+ kind: 'cloudly-legacy-deployment-settlement-resolution-bundle',
4588
+ executionAttempt: scratchExecutionAttempt,
4589
+ observedAt,
4590
+ sourceAuthorityStatus,
4591
+ executionAuthorityStatus,
4592
+ outcome,
4593
+ mode: 'legacy-no-op',
4594
+ attemptObservation: null,
4595
+ };
4596
+ return finalize(
4597
+ result,
4598
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes,
4599
+ 'resolutionBundle',
4600
+ );
4601
+ };
4602
+
4603
+ export const encodeCloudlyLegacyDeploymentSettlementResolutionBundle = (
4604
+ valueArg: unknown,
4605
+ ): Uint8Array => encodeNormalized(
4606
+ normalizeCloudlyLegacyDeploymentSettlementResolutionBundle(valueArg),
4607
+ 'resolutionBundle',
4608
+ );
4609
+
4610
+ export const digestCloudlyLegacyDeploymentSettlementResolutionBundle = (
4611
+ valueArg: unknown,
4612
+ ): string => digestBytes(encodeCloudlyLegacyDeploymentSettlementResolutionBundle(valueArg));
4613
+
4614
+ /** Recovery attestation only; this is neither a receipt nor an execution authorization. */
4615
+ export interface IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1 {
4616
+ schemaVersion: 1;
4617
+ kind: 'authenticated-cloudly-legacy-deployment-settlement-resolution';
4618
+ authority: ICloudlyLegacyDeploymentSettlementAuthorityReferenceV1;
4619
+ payload: TCloudlyLegacyDeploymentSettlementResolutionBundleV1;
4620
+ payloadSha256: string;
4621
+ mac: string;
4622
+ }
4623
+
4624
+ export type TUnsignedAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1 = Omit<
4625
+ IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1,
4626
+ 'mac'
4627
+ >;
4628
+
4629
+ const unsignedAuthenticatedResolutionKeys = [
4630
+ 'schemaVersion',
4631
+ 'kind',
4632
+ 'authority',
4633
+ 'payload',
4634
+ 'payloadSha256',
4635
+ ] as const;
4636
+ const authenticatedResolutionKeys = [...unsignedAuthenticatedResolutionKeys, 'mac'] as const;
4637
+
4638
+ const normalizeUnsignedAuthenticatedResolutionInternal = (
4639
+ valueArg: unknown,
4640
+ pathArg: string,
4641
+ ): TUnsignedAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1 => {
4642
+ const value = readRecord(valueArg, pathArg);
4643
+ assertExactKeys(value, unsignedAuthenticatedResolutionKeys, pathArg);
4644
+ if (value.schemaVersion !== 1
4645
+ || value.kind !== 'authenticated-cloudly-legacy-deployment-settlement-resolution') {
4646
+ fail('INVALID_VALUE', `${pathArg}.kind`);
4647
+ }
4648
+ const authority = normalizeAuthorityReferenceInternal(value.authority, `${pathArg}.authority`);
4649
+ const payload = normalizeCloudlyLegacyDeploymentSettlementResolutionBundle(value.payload);
4650
+ const payloadSha256 = readSha256(value.payloadSha256, `${pathArg}.payloadSha256`);
4651
+ if (canonicalize(authority, `${pathArg}.authority`)
4652
+ !== canonicalize(payload.executionAttempt.executionAuthority, `${pathArg}.payload.authority`)
4653
+ || payloadSha256 !== digestCloudlyLegacyDeploymentSettlementResolutionBundle(payload)) {
4654
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.payload`);
4655
+ }
4656
+ return {
4657
+ schemaVersion: 1,
4658
+ kind: 'authenticated-cloudly-legacy-deployment-settlement-resolution',
4659
+ authority,
4660
+ payload,
4661
+ payloadSha256,
4662
+ };
4663
+ };
4664
+
4665
+ /** Structural only; this function does not authenticate the recovery-attestation MAC. */
4666
+ export const normalizeCloudlyLegacyDeploymentSettlementAuthenticatedResolutionStructure = (
4667
+ valueArg: unknown,
4668
+ ): Readonly<IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1> => {
4669
+ const value = readRecord(valueArg, 'authenticatedResolution');
4670
+ assertExactKeys(value, authenticatedResolutionKeys, 'authenticatedResolution');
4671
+ return finalize({
4672
+ ...normalizeUnsignedAuthenticatedResolutionInternal(
4673
+ Object.fromEntries(unsignedAuthenticatedResolutionKeys.map((keyArg) => [
4674
+ keyArg,
4675
+ value[keyArg],
4676
+ ])),
4677
+ 'authenticatedResolution.unsigned',
4678
+ ),
4679
+ mac: readMac(value.mac, 'authenticatedResolution.mac'),
4680
+ }, cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 5, 'authenticatedResolution');
4681
+ };
4682
+
4683
+ export const encodeAuthenticatedCloudlyLegacyDeploymentSettlementResolution = (
4684
+ valueArg: unknown,
4685
+ ): Uint8Array => encodeNormalized(
4686
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedResolutionStructure(valueArg),
4687
+ 'authenticatedResolution',
4688
+ );
4689
+
4690
+ export const digestAuthenticatedCloudlyLegacyDeploymentSettlementResolution = (
4691
+ valueArg: unknown,
4692
+ ): string => digestBytes(encodeAuthenticatedCloudlyLegacyDeploymentSettlementResolution(valueArg));
4693
+
4694
+ export const encodeCloudlyLegacyDeploymentSettlementResolutionHmacInput = (
4695
+ valueArg: unknown,
4696
+ ): Uint8Array => frame(
4697
+ cloudlyLegacyDeploymentSettlementDomains.resolutionHmac,
4698
+ encodeNormalized(
4699
+ finalize(
4700
+ normalizeUnsignedAuthenticatedResolutionInternal(
4701
+ valueArg,
4702
+ 'unsignedAuthenticatedResolution',
4703
+ ),
4704
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 5,
4705
+ 'unsignedAuthenticatedResolution',
4706
+ ),
4707
+ 'authenticatedResolution.authenticated',
4708
+ ),
4709
+ );
4710
+
4711
+ const normalizeExecutionAttemptAuthorityMetadata = (
4712
+ attemptArg: ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1,
4713
+ sourceMetadataArg: unknown,
4714
+ executionMetadataArg: unknown,
4715
+ ): {
4716
+ sourceMetadata: Readonly<ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1>;
4717
+ executionMetadata: Readonly<TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1>;
4718
+ splitProductionAuthority: boolean;
4719
+ } => {
4720
+ const sourceMetadata = normalizeFencedSourceAuthorityMetadata(
4721
+ sourceMetadataArg,
4722
+ 'executionAttempt.sourceAuthorityMetadata',
4723
+ );
4724
+ const executionMetadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(
4725
+ executionMetadataArg,
4726
+ );
4727
+ assertAuthorityReferenceMatchesMetadata(
4728
+ attemptArg.sourceAuthority,
4729
+ sourceMetadata,
4730
+ 'executionAttempt.sourceAuthority',
4731
+ );
4732
+ assertAuthorityReferenceMatchesMetadata(
4733
+ attemptArg.executionAuthority,
4734
+ executionMetadata,
4735
+ 'executionAttempt.executionAuthority',
4736
+ );
4737
+ const splitProductionAuthority = canonicalize(
4738
+ attemptArg.sourceAuthority,
4739
+ 'executionAttempt.sourceAuthority',
4740
+ ) !== canonicalize(attemptArg.executionAuthority, 'executionAttempt.executionAuthority');
4741
+ if (attemptArg.purpose === 'scratch-rehearsal') {
4742
+ if (splitProductionAuthority) {
4743
+ fail('CROSS_FIELD_MISMATCH', 'executionAttempt.executionAuthority');
4744
+ }
4745
+ normalizeFencedSourceAuthorityMetadata(
4746
+ executionMetadata,
4747
+ 'executionAttempt.executionAuthorityMetadata',
4748
+ );
4749
+ } else {
4750
+ if (!splitProductionAuthority) {
4751
+ fail('CROSS_FIELD_MISMATCH', 'executionAttempt.executionAuthority');
4752
+ }
4753
+ const productionMetadata = normalizeProductionAuthorityMetadataPair(
4754
+ executionMetadata,
4755
+ sourceMetadata,
4756
+ ).productionMetadata;
4757
+ if (productionMetadata.sourceAuthenticatedPlanSha256
4758
+ !== attemptArg.authenticatedPlanSha256
4759
+ || productionMetadata.sourceRequestBundleSha256 !== attemptArg.requestBundleSha256
4760
+ || productionMetadata.scratchReceiptSha256 !== attemptArg.scratchReceiptSha256) {
4761
+ fail('CROSS_FIELD_MISMATCH', 'executionAttempt.productionAuthorityMetadata');
4762
+ }
4763
+ }
4764
+ return { sourceMetadata, executionMetadata, splitProductionAuthority };
4765
+ };
4766
+
4767
+ const authorityStatusAt = (
4768
+ observedAtArg: number,
4769
+ metadataArg: TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1,
4770
+ pathArg: string,
4771
+ ): TCloudlyLegacyDeploymentSettlementAuthorityStatus => {
4772
+ if (observedAtArg < metadataArg.issuedAt) {
4773
+ fail('CROSS_FIELD_MISMATCH', pathArg);
4774
+ }
4775
+ return observedAtArg < metadataArg.expiresAt ? 'active' : 'expired';
4776
+ };
4777
+
4778
+ const normalizeExecutionAttemptProofArtifacts = async (argsArg: {
4779
+ executionAttempt: ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
4780
+ sourceMetadata: unknown;
4781
+ executionMetadata: unknown;
4782
+ authenticatedPlan: unknown;
4783
+ requestBundle: unknown;
4784
+ scratchReceipt: unknown | null;
4785
+ productionAuthorization: unknown | null;
4786
+ requireProductionAuthorization: boolean;
4787
+ verifier: TCloudlyLegacyDeploymentSettlementHmacVerifier;
4788
+ }): Promise<{
4789
+ sourceMetadata: Readonly<ICloudlyLegacyDeploymentSettlementFencedSourceAuthorityMetadataV1>;
4790
+ executionMetadata: Readonly<TCloudlyLegacyDeploymentSettlementAuthorityMetadataV1>;
4791
+ authenticatedPlan: Readonly<IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1>;
4792
+ requestBundle: Readonly<ICloudlyLegacyDeploymentSettlementRequestBundleV1>;
4793
+ scratchReceipt: Readonly<ICloudlyLegacyDeploymentSettlementScratchReceiptV1> | null;
4794
+ productionAuthorization:
4795
+ Readonly<ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1> | null;
4796
+ splitProductionAuthority: boolean;
4797
+ }> => {
4798
+ const metadata = normalizeExecutionAttemptAuthorityMetadata(
4799
+ argsArg.executionAttempt,
4800
+ argsArg.sourceMetadata,
4801
+ argsArg.executionMetadata,
4802
+ );
4803
+ const authenticatedPlan =
4804
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementPlanForAuthority(
4805
+ argsArg.authenticatedPlan,
4806
+ metadata.sourceMetadata,
4807
+ argsArg.verifier,
4808
+ );
4809
+ const requestBundle = await normalizeCloudlyLegacyDeploymentSettlementRequestBundleForAuthority(
4810
+ argsArg.requestBundle,
4811
+ authenticatedPlan,
4812
+ metadata.sourceMetadata,
4813
+ argsArg.verifier,
4814
+ );
4815
+ let scratchReceipt: Readonly<ICloudlyLegacyDeploymentSettlementScratchReceiptV1> | null = null;
4816
+ let productionAuthorization:
4817
+ Readonly<ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1> | null = null;
4818
+ if (argsArg.executionAttempt.purpose === 'production') {
4819
+ if (argsArg.scratchReceipt === null) {
4820
+ fail('INVALID_SCHEMA', 'executionAttempt.scratchReceipt');
4821
+ }
4822
+ scratchReceipt = await normalizeCloudlyLegacyDeploymentSettlementScratchReceiptForAuthority(
4823
+ argsArg.scratchReceipt,
4824
+ metadata.sourceMetadata,
4825
+ requestBundle.authenticatedRequest,
4826
+ argsArg.verifier,
4827
+ );
4828
+ if (metadata.splitProductionAuthority) {
4829
+ if (argsArg.productionAuthorization === null) {
4830
+ if (argsArg.requireProductionAuthorization) {
4831
+ fail('INVALID_SCHEMA', 'executionAttempt.productionAuthorization');
4832
+ }
4833
+ } else {
4834
+ productionAuthorization =
4835
+ await normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationForAuthorities(
4836
+ argsArg.productionAuthorization,
4837
+ metadata.executionMetadata,
4838
+ metadata.sourceMetadata,
4839
+ authenticatedPlan,
4840
+ requestBundle,
4841
+ scratchReceipt,
4842
+ argsArg.verifier,
4843
+ );
4844
+ }
4845
+ } else if (argsArg.productionAuthorization !== null) {
4846
+ fail('INVALID_SCHEMA', 'executionAttempt.productionAuthorization');
4847
+ }
4848
+ } else if (argsArg.scratchReceipt !== null || argsArg.productionAuthorization !== null) {
4849
+ fail('INVALID_SCHEMA', 'executionAttempt.sourceProof');
4850
+ }
4851
+ const expectedScratchReceiptSha256 = scratchReceipt
4852
+ ? digestCloudlyLegacyDeploymentSettlementScratchReceipt(scratchReceipt)
4853
+ : null;
4854
+ if (argsArg.executionAttempt.authenticatedPlanSha256
4855
+ !== digestAuthenticatedCloudlyLegacyDeploymentSettlementPlan(authenticatedPlan)
4856
+ || argsArg.executionAttempt.requestBundleSha256
4857
+ !== digestCloudlyLegacyDeploymentSettlementRequestBundle(requestBundle)
4858
+ || argsArg.executionAttempt.scratchReceiptSha256 !== expectedScratchReceiptSha256) {
4859
+ fail('CROSS_FIELD_MISMATCH', 'executionAttempt.sourceProof');
4860
+ }
4861
+ return {
4862
+ ...metadata,
4863
+ authenticatedPlan,
4864
+ requestBundle,
4865
+ scratchReceipt,
4866
+ productionAuthorization,
4867
+ };
4868
+ };
4869
+
4870
+ const normalizeAuthenticatedApplyResultForExecutionAuthority = async (
4871
+ resultArg: unknown,
4872
+ executionMetadataArg: unknown,
4873
+ requestArg: unknown,
4874
+ productionAuthorizationArg:
4875
+ ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1,
4876
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
4877
+ ): Promise<Readonly<IAuthenticatedCloudlyLegacyDeploymentSettlementApplyResultV1>> => {
4878
+ const executionMetadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(
4879
+ executionMetadataArg,
4880
+ );
4881
+ const request = normalizeCloudlyLegacyDeploymentSettlementAuthenticatedProductionRequestStructure(
4882
+ requestArg,
4883
+ );
4884
+ const result = normalizeCloudlyLegacyDeploymentSettlementAuthenticatedApplyResultStructure(resultArg);
4885
+ assertAuthorityReferenceMatchesMetadata(result.authority, executionMetadata, 'applyResult.authority');
4886
+ assertSummaryMatchesProductionRequest(result.payload, request.payload, 'applyResult.payload');
4887
+ const resultAt = result.payload.status === 'completed'
4888
+ ? result.payload.completedAt
4889
+ : result.payload.rejectedAt;
4890
+ const resultAtPath = result.payload.status === 'completed'
4891
+ ? 'applyResult.payload.completedAt'
4892
+ : 'applyResult.payload.rejectedAt';
4893
+ if (canonicalize(result.authority, 'applyResult.authority')
4894
+ !== canonicalize(productionAuthorizationArg.authority, 'productionAuthorization.authority')
4895
+ || resultAt < request.payload.requestedAt
4896
+ || resultAt < productionAuthorizationArg.approvedAt) {
4897
+ fail('CROSS_FIELD_MISMATCH', resultAtPath);
4898
+ }
4899
+ assertAuthorityTimestamp(resultAt, executionMetadata, resultAtPath);
4900
+ await requireConsumerVerifiedHmac(
4901
+ result.authority,
4902
+ cloudlyLegacyDeploymentSettlementDomains.applyResultHmac,
4903
+ encodeCloudlyLegacyDeploymentSettlementApplyResultHmacInput(withoutArtifactMac(result)),
4904
+ result.mac,
4905
+ verifierArg,
4906
+ 'applyResult.mac',
4907
+ );
4908
+ return result;
4909
+ };
4910
+
4911
+ const normalizeAuthenticatedCheckResultForExecutionAuthority = async (
4912
+ resultArg: unknown,
4913
+ executionMetadataArg: unknown,
4914
+ requestArg: unknown,
4915
+ productionAuthorizationArg:
4916
+ ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1,
4917
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
4918
+ ): Promise<Readonly<IAuthenticatedCloudlyLegacyDeploymentSettlementCheckResultV1>> => {
4919
+ const executionMetadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(
4920
+ executionMetadataArg,
4921
+ );
4922
+ const request = normalizeCloudlyLegacyDeploymentSettlementAuthenticatedProductionRequestStructure(
4923
+ requestArg,
4924
+ );
4925
+ const result = normalizeCloudlyLegacyDeploymentSettlementAuthenticatedCheckResultStructure(resultArg);
4926
+ assertAuthorityReferenceMatchesMetadata(result.authority, executionMetadata, 'checkResult.authority');
4927
+ assertSummaryMatchesProductionRequest(result.payload, request.payload, 'checkResult.payload');
4928
+ if (canonicalize(result.authority, 'checkResult.authority')
4929
+ !== canonicalize(productionAuthorizationArg.authority, 'productionAuthorization.authority')
4930
+ || result.payload.checkedAt < request.payload.requestedAt
4931
+ || result.payload.checkedAt < productionAuthorizationArg.approvedAt) {
4932
+ fail('CROSS_FIELD_MISMATCH', 'checkResult.payload.checkedAt');
4933
+ }
4934
+ assertAuthorityTimestamp(result.payload.checkedAt, executionMetadata, 'checkResult.checkedAt');
4935
+ await requireConsumerVerifiedHmac(
4936
+ result.authority,
4937
+ cloudlyLegacyDeploymentSettlementDomains.checkResultHmac,
4938
+ encodeCloudlyLegacyDeploymentSettlementCheckResultHmacInput(withoutArtifactMac(result)),
4939
+ result.mac,
4940
+ verifierArg,
4941
+ 'checkResult.mac',
4942
+ );
4943
+ return result;
4944
+ };
4945
+
4946
+ /** Artifact/status binding only; trust the authenticated recovery attestation instead. */
4947
+ export const normalizeCloudlyLegacyDeploymentSettlementResolutionBundleForAuthorities = async (
4948
+ bundleArg: unknown,
4949
+ sourceMetadataArg: unknown,
4950
+ executionMetadataArg: unknown,
4951
+ authenticatedPlanArg: unknown,
4952
+ requestBundleArg: unknown,
4953
+ scratchReceiptArg: unknown | null,
4954
+ productionAuthorizationArg: unknown | null,
4955
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
4956
+ ): Promise<Readonly<TCloudlyLegacyDeploymentSettlementResolutionBundleV1>> => {
4957
+ const bundle = normalizeCloudlyLegacyDeploymentSettlementResolutionBundle(bundleArg);
4958
+ const artifacts = await normalizeExecutionAttemptProofArtifacts({
4959
+ executionAttempt: bundle.executionAttempt,
4960
+ sourceMetadata: sourceMetadataArg,
4961
+ executionMetadata: executionMetadataArg,
4962
+ authenticatedPlan: authenticatedPlanArg,
4963
+ requestBundle: requestBundleArg,
4964
+ scratchReceipt: scratchReceiptArg,
4965
+ productionAuthorization: productionAuthorizationArg,
4966
+ requireProductionAuthorization: true,
4967
+ verifier: verifierArg,
4968
+ });
4969
+ if (bundle.sourceAuthorityStatus !== authorityStatusAt(
4970
+ bundle.observedAt,
4971
+ artifacts.sourceMetadata,
4972
+ 'resolutionBundle.sourceAuthorityStatus',
4973
+ )) {
4974
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.sourceAuthorityStatus');
4975
+ }
4976
+ if (bundle.executionAuthorityStatus !== authorityStatusAt(
4977
+ bundle.observedAt,
4978
+ artifacts.executionMetadata,
4979
+ 'resolutionBundle.executionAuthorityStatus',
4980
+ )) {
4981
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.executionAuthorityStatus');
4982
+ }
4983
+ if (bundle.executionAttempt.purpose === 'production') {
4984
+ const productionAuthorization = artifacts.productionAuthorization
4985
+ ?? fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.productionAuthorization');
4986
+ const attemptObservation = bundle.attemptObservation
4987
+ ?? fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation');
4988
+ if (attemptObservation.preparedAt < productionAuthorization.approvedAt
4989
+ || attemptObservation.resolvedAt < productionAuthorization.approvedAt
4990
+ || bundle.observedAt < productionAuthorization.approvedAt) {
4991
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.attemptObservation.preparedAt');
4992
+ }
4993
+ }
4994
+ if (bundle.outcome === 'committed') {
4995
+ const receipt = bundle.originalReceipt;
4996
+ if (receipt.kind === 'cloudly-legacy-deployment-settlement-scratch-receipt') {
4997
+ await normalizeCloudlyLegacyDeploymentSettlementScratchReceiptForAuthority(
4998
+ receipt,
4999
+ artifacts.sourceMetadata,
5000
+ artifacts.requestBundle.authenticatedRequest,
5001
+ verifierArg,
5002
+ );
5003
+ } else if (receipt.schemaVersion === 2) {
5004
+ if (!artifacts.splitProductionAuthority || !artifacts.productionAuthorization) {
5005
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.originalReceipt.authority');
5006
+ }
5007
+ await normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2ForAuthorities(
5008
+ receipt,
5009
+ artifacts.executionMetadata,
5010
+ artifacts.sourceMetadata,
5011
+ artifacts.authenticatedPlan,
5012
+ artifacts.requestBundle,
5013
+ verifierArg,
5014
+ );
5015
+ if (canonicalize(
5016
+ receipt.productionAuthorization,
5017
+ 'resolutionBundle.originalReceipt.productionAuthorization',
5018
+ ) !== canonicalize(
5019
+ artifacts.productionAuthorization,
5020
+ 'resolutionBundle.productionAuthorization',
5021
+ )) {
5022
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.originalReceipt.productionAuthorization');
5023
+ }
5024
+ } else {
5025
+ if (artifacts.splitProductionAuthority) {
5026
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.originalReceipt.authority');
5027
+ }
5028
+ await normalizeCloudlyLegacyDeploymentSettlementProductionReceiptForAuthority(
5029
+ receipt,
5030
+ artifacts.sourceMetadata,
5031
+ artifacts.requestBundle.authenticatedRequest,
5032
+ verifierArg,
5033
+ );
5034
+ }
5035
+ if (receipt.kind === 'cloudly-legacy-deployment-settlement-production-receipt'
5036
+ && artifacts.scratchReceipt
5037
+ && digestCloudlyLegacyDeploymentSettlementScratchReceipt(receipt.scratchReceipt)
5038
+ !== digestCloudlyLegacyDeploymentSettlementScratchReceipt(artifacts.scratchReceipt)) {
5039
+ fail('CROSS_FIELD_MISMATCH', 'resolutionBundle.originalReceipt.scratchReceipt');
5040
+ }
5041
+ }
5042
+ return bundle;
5043
+ };
5044
+
5045
+ export const normalizeAuthenticatedCloudlyLegacyDeploymentSettlementResolutionForAuthorities = async (
5046
+ attestationArg: unknown,
5047
+ sourceMetadataArg: unknown,
5048
+ executionMetadataArg: unknown,
5049
+ authenticatedPlanArg: unknown,
5050
+ requestBundleArg: unknown,
5051
+ scratchReceiptArg: unknown | null,
5052
+ productionAuthorizationArg: unknown | null,
5053
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
5054
+ ): Promise<Readonly<IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1>> => {
5055
+ const attestation =
5056
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedResolutionStructure(attestationArg);
5057
+ const executionMetadata = normalizeCloudlyLegacyDeploymentSettlementAuthorityMetadata(
5058
+ executionMetadataArg,
5059
+ );
5060
+ assertAuthorityReferenceMatchesMetadata(
5061
+ attestation.authority,
5062
+ executionMetadata,
5063
+ 'authenticatedResolution.authority',
5064
+ );
5065
+ await requireConsumerVerifiedHmac(
5066
+ attestation.authority,
5067
+ cloudlyLegacyDeploymentSettlementDomains.resolutionHmac,
5068
+ encodeCloudlyLegacyDeploymentSettlementResolutionHmacInput(
5069
+ withoutArtifactMac(attestation),
5070
+ ),
5071
+ attestation.mac,
5072
+ verifierArg,
5073
+ 'authenticatedResolution.mac',
5074
+ );
5075
+ const payload = await normalizeCloudlyLegacyDeploymentSettlementResolutionBundleForAuthorities(
5076
+ attestation.payload,
5077
+ sourceMetadataArg,
5078
+ executionMetadata,
5079
+ authenticatedPlanArg,
5080
+ requestBundleArg,
5081
+ scratchReceiptArg,
5082
+ productionAuthorizationArg,
5083
+ verifierArg,
5084
+ );
5085
+ if (canonicalize(attestation.payload, 'authenticatedResolution.payload')
5086
+ !== canonicalize(payload, 'authenticatedResolution.verifiedPayload')) {
5087
+ fail('CROSS_FIELD_MISMATCH', 'authenticatedResolution.payload');
5088
+ }
5089
+ return attestation;
5090
+ };
5091
+
5092
+ export type TCloudlyLegacyDeploymentSettlementCompletedApplyResultV1 = Extract<
5093
+ TCloudlyLegacyDeploymentSettlementApplyResultV1,
5094
+ { status: 'completed' }
5095
+ >;
5096
+ export type TCloudlyLegacyDeploymentSettlementRejectedApplyResultV1 = Extract<
5097
+ TCloudlyLegacyDeploymentSettlementApplyResultV1,
5098
+ { status: 'rejected' }
5099
+ >;
5100
+ export type TAuthenticatedCloudlyLegacyDeploymentSettlementCompletedApplyResultV1 = Omit<
5101
+ IAuthenticatedCloudlyLegacyDeploymentSettlementApplyResultV1,
5102
+ 'payload'
5103
+ > & {
5104
+ payload: TCloudlyLegacyDeploymentSettlementCompletedApplyResultV1;
5105
+ };
5106
+ export type TAuthenticatedCloudlyLegacyDeploymentSettlementRejectedApplyResultV1 = Omit<
5107
+ IAuthenticatedCloudlyLegacyDeploymentSettlementApplyResultV1,
5108
+ 'payload'
5109
+ > & {
5110
+ payload: TCloudlyLegacyDeploymentSettlementRejectedApplyResultV1;
5111
+ };
5112
+
5113
+ interface ICloudlyLegacyDeploymentSettlementScratchExecutionBundleBaseV1 {
5114
+ schemaVersion: 1;
5115
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle';
5116
+ purpose: 'scratch-rehearsal';
5117
+ executionAttempt: TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
5118
+ }
5119
+
5120
+ export interface ICloudlyLegacyDeploymentSettlementCompletedScratchExecutionBundleV1
5121
+ extends ICloudlyLegacyDeploymentSettlementScratchExecutionBundleBaseV1 {
5122
+ authenticatedResult:
5123
+ TAuthenticatedCloudlyLegacyDeploymentSettlementCompletedApplyResultV1;
5124
+ receipt: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
5125
+ }
5126
+
5127
+ export interface ICloudlyLegacyDeploymentSettlementRejectedScratchExecutionBundleV1
5128
+ extends ICloudlyLegacyDeploymentSettlementScratchExecutionBundleBaseV1 {
5129
+ authenticatedResult:
5130
+ TAuthenticatedCloudlyLegacyDeploymentSettlementRejectedApplyResultV1;
5131
+ receipt?: never;
5132
+ }
5133
+
5134
+ export type TCloudlyLegacyDeploymentSettlementScratchExecutionBundleV1 =
5135
+ | ICloudlyLegacyDeploymentSettlementCompletedScratchExecutionBundleV1
5136
+ | ICloudlyLegacyDeploymentSettlementRejectedScratchExecutionBundleV1;
5137
+
5138
+ interface ICloudlyLegacyDeploymentSettlementProductionExecutionBundleBaseV2 {
5139
+ schemaVersion: 2;
5140
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle';
5141
+ purpose: 'production';
5142
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
5143
+ }
5144
+
5145
+ export interface ICloudlyLegacyDeploymentSettlementCompletedProductionExecutionBundleV2
5146
+ extends ICloudlyLegacyDeploymentSettlementProductionExecutionBundleBaseV2 {
5147
+ authenticatedResult:
5148
+ TAuthenticatedCloudlyLegacyDeploymentSettlementCompletedApplyResultV1;
5149
+ receipt: ICloudlyLegacyDeploymentSettlementProductionReceiptV2;
5150
+ }
5151
+
5152
+ export interface ICloudlyLegacyDeploymentSettlementRejectedProductionExecutionBundleV2
5153
+ extends ICloudlyLegacyDeploymentSettlementProductionExecutionBundleBaseV2 {
5154
+ authenticatedResult:
5155
+ TAuthenticatedCloudlyLegacyDeploymentSettlementRejectedApplyResultV1;
5156
+ receipt?: never;
5157
+ }
5158
+
5159
+ export type TCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2 =
5160
+ | ICloudlyLegacyDeploymentSettlementCompletedProductionExecutionBundleV2
5161
+ | ICloudlyLegacyDeploymentSettlementRejectedProductionExecutionBundleV2;
5162
+
5163
+ const normalizeSettlementExecutionBundleCommon = (
5164
+ valueArg: unknown,
5165
+ pathArg: string,
5166
+ purposeArg: TCloudlyLegacyDeploymentSettlementExecutionPurpose,
5167
+ ): {
5168
+ value: Record<string, unknown>;
5169
+ executionAttempt: ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
5170
+ authenticatedResult: IAuthenticatedCloudlyLegacyDeploymentSettlementApplyResultV1;
5171
+ hasReceipt: boolean;
5172
+ } => {
5173
+ const value = readRecord(valueArg, pathArg);
5174
+ const hasReceipt = Object.hasOwn(value, 'receipt');
5175
+ assertExactKeys(value, [
5176
+ 'schemaVersion',
5177
+ 'kind',
5178
+ 'purpose',
5179
+ 'executionAttempt',
5180
+ 'authenticatedResult',
5181
+ ...(hasReceipt ? ['receipt'] : []),
5182
+ ], pathArg);
5183
+ if (value.kind !== 'cloudly-legacy-deployment-settlement-execution-bundle'
5184
+ || value.purpose !== purposeArg) {
5185
+ fail('INVALID_VALUE', `${pathArg}.kind`);
5186
+ }
5187
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
5188
+ value.executionAttempt,
5189
+ `${pathArg}.executionAttempt`,
5190
+ );
5191
+ const authenticatedResult =
5192
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedApplyResultStructure(
5193
+ value.authenticatedResult,
5194
+ );
5195
+ if (executionAttempt.purpose !== purposeArg
5196
+ || canonicalize(authenticatedResult.authority, `${pathArg}.result.authority`)
5197
+ !== canonicalize(executionAttempt.executionAuthority, `${pathArg}.attempt.authority`)
5198
+ || (authenticatedResult.payload.status === 'completed') !== hasReceipt) {
5199
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.authenticatedResult`);
5200
+ }
5201
+ return { value, executionAttempt, authenticatedResult, hasReceipt };
5202
+ };
5203
+
5204
+ /** Structural only; this function does not authenticate result or receipt MACs. */
5205
+ export const normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundle = (
5206
+ valueArg: unknown,
5207
+ ): Readonly<TCloudlyLegacyDeploymentSettlementScratchExecutionBundleV1> => {
5208
+ const normalized = normalizeSettlementExecutionBundleCommon(
5209
+ valueArg,
5210
+ 'scratchExecutionBundle',
5211
+ 'scratch-rehearsal',
5212
+ );
5213
+ if (normalized.value.schemaVersion !== 1) {
5214
+ fail('INVALID_VALUE', 'scratchExecutionBundle.schemaVersion');
5215
+ }
5216
+ const receipt = normalized.hasReceipt
5217
+ ? normalizeCloudlyLegacyDeploymentSettlementScratchReceipt(normalized.value.receipt)
5218
+ : undefined;
5219
+ if (receipt
5220
+ && (canonicalize(receipt.authority, 'scratchExecutionBundle.receipt.authority')
5221
+ !== canonicalize(
5222
+ normalized.executionAttempt.executionAuthority,
5223
+ 'scratchExecutionBundle.attempt.authority',
5224
+ )
5225
+ || normalized.authenticatedResult.payload.status !== 'completed'
5226
+ || normalized.authenticatedResult.payload.requestSha256 !== receipt.requestSha256
5227
+ || (normalized.authenticatedResult.payload.disposition !== receipt.disposition
5228
+ && !(receipt.disposition === 'applied'
5229
+ && normalized.authenticatedResult.payload.disposition === 'exact-replay')))) {
5230
+ fail('CROSS_FIELD_MISMATCH', 'scratchExecutionBundle.receipt');
5231
+ }
5232
+ const executionAttempt = normalized.executionAttempt as
5233
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
5234
+ const result: TCloudlyLegacyDeploymentSettlementScratchExecutionBundleV1 = receipt
5235
+ ? {
5236
+ schemaVersion: 1,
5237
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle',
5238
+ purpose: 'scratch-rehearsal',
5239
+ executionAttempt,
5240
+ authenticatedResult: normalized.authenticatedResult as
5241
+ TAuthenticatedCloudlyLegacyDeploymentSettlementCompletedApplyResultV1,
5242
+ receipt,
5243
+ }
5244
+ : {
5245
+ schemaVersion: 1,
5246
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle',
5247
+ purpose: 'scratch-rehearsal',
5248
+ executionAttempt,
5249
+ authenticatedResult: normalized.authenticatedResult as
5250
+ TAuthenticatedCloudlyLegacyDeploymentSettlementRejectedApplyResultV1,
5251
+ };
5252
+ return finalize(
5253
+ result,
5254
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 2,
5255
+ 'scratchExecutionBundle',
5256
+ );
5257
+ };
5258
+
5259
+ /** Structural only; this function does not authenticate result or receipt MACs. */
5260
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2 = (
5261
+ valueArg: unknown,
5262
+ ): Readonly<TCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2> => {
5263
+ const normalized = normalizeSettlementExecutionBundleCommon(
5264
+ valueArg,
5265
+ 'productionExecutionBundleV2',
5266
+ 'production',
5267
+ );
5268
+ if (normalized.value.schemaVersion !== 2) {
5269
+ fail('INVALID_VALUE', 'productionExecutionBundleV2.schemaVersion');
5270
+ }
5271
+ const receipt = normalized.hasReceipt
5272
+ ? normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2(normalized.value.receipt)
5273
+ : undefined;
5274
+ if (receipt
5275
+ && (canonicalize(receipt.executionAttempt, 'productionExecutionBundleV2.receipt.attempt')
5276
+ !== canonicalize(
5277
+ normalized.executionAttempt,
5278
+ 'productionExecutionBundleV2.executionAttempt',
5279
+ )
5280
+ || normalized.authenticatedResult.payload.status !== 'completed'
5281
+ || normalized.authenticatedResult.payload.requestSha256 !== receipt.requestSha256
5282
+ || (normalized.authenticatedResult.payload.disposition !== receipt.disposition
5283
+ && !(receipt.disposition === 'applied'
5284
+ && normalized.authenticatedResult.payload.disposition === 'exact-replay')))) {
5285
+ fail('CROSS_FIELD_MISMATCH', 'productionExecutionBundleV2.receipt');
5286
+ }
5287
+ const executionAttempt = normalized.executionAttempt as
5288
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
5289
+ const result: TCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2 = receipt
5290
+ ? {
5291
+ schemaVersion: 2,
5292
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle',
5293
+ purpose: 'production',
5294
+ executionAttempt,
5295
+ authenticatedResult: normalized.authenticatedResult as
5296
+ TAuthenticatedCloudlyLegacyDeploymentSettlementCompletedApplyResultV1,
5297
+ receipt,
5298
+ }
5299
+ : {
5300
+ schemaVersion: 2,
5301
+ kind: 'cloudly-legacy-deployment-settlement-execution-bundle',
5302
+ purpose: 'production',
5303
+ executionAttempt,
5304
+ authenticatedResult: normalized.authenticatedResult as
5305
+ TAuthenticatedCloudlyLegacyDeploymentSettlementRejectedApplyResultV1,
5306
+ };
5307
+ return finalize(
5308
+ result,
5309
+ cloudlyLegacyDeploymentSettlementLimits.maximumReceiptBytes * 4,
5310
+ 'productionExecutionBundleV2',
5311
+ );
5312
+ };
5313
+
5314
+ export const encodeCloudlyLegacyDeploymentSettlementScratchExecutionBundle = (
5315
+ valueArg: unknown,
5316
+ ): Uint8Array => encodeNormalized(
5317
+ normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundle(valueArg),
5318
+ 'scratchExecutionBundle',
5319
+ );
5320
+
5321
+ export const encodeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2 = (
5322
+ valueArg: unknown,
5323
+ ): Uint8Array => encodeNormalized(
5324
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2(valueArg),
5325
+ 'productionExecutionBundleV2',
5326
+ );
5327
+
5328
+ export const normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundleForAuthority = async (
5329
+ bundleArg: unknown,
5330
+ sourceMetadataArg: unknown,
5331
+ authenticatedPlanArg: unknown,
5332
+ requestBundleArg: unknown,
5333
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
5334
+ ): Promise<Readonly<TCloudlyLegacyDeploymentSettlementScratchExecutionBundleV1>> => {
5335
+ const bundle = normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundle(bundleArg);
5336
+ const artifacts = await normalizeExecutionAttemptProofArtifacts({
5337
+ executionAttempt: bundle.executionAttempt,
5338
+ sourceMetadata: sourceMetadataArg,
5339
+ executionMetadata: sourceMetadataArg,
5340
+ authenticatedPlan: authenticatedPlanArg,
5341
+ requestBundle: requestBundleArg,
5342
+ scratchReceipt: null,
5343
+ productionAuthorization: null,
5344
+ requireProductionAuthorization: false,
5345
+ verifier: verifierArg,
5346
+ });
5347
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementApplyResultForAuthority(
5348
+ bundle.authenticatedResult,
5349
+ artifacts.sourceMetadata,
5350
+ artifacts.requestBundle.authenticatedRequest,
5351
+ verifierArg,
5352
+ );
5353
+ if (bundle.receipt) {
5354
+ await normalizeCloudlyLegacyDeploymentSettlementScratchReceiptForAuthority(
5355
+ bundle.receipt,
5356
+ artifacts.sourceMetadata,
5357
+ artifacts.requestBundle.authenticatedRequest,
5358
+ verifierArg,
5359
+ );
5360
+ }
5361
+ return bundle;
5362
+ };
5363
+
5364
+ export const normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2ForAuthorities = async (
5365
+ bundleArg: unknown,
5366
+ productionAuthorizationArg: unknown,
5367
+ productionMetadataArg: unknown,
5368
+ sourceMetadataArg: unknown,
5369
+ authenticatedPlanArg: unknown,
5370
+ requestBundleArg: unknown,
5371
+ scratchReceiptArg: unknown,
5372
+ verifierArg: TCloudlyLegacyDeploymentSettlementHmacVerifier,
5373
+ ): Promise<Readonly<TCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2>> => {
5374
+ const bundle = normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2(bundleArg);
5375
+ const artifacts = await normalizeExecutionAttemptProofArtifacts({
5376
+ executionAttempt: bundle.executionAttempt,
5377
+ sourceMetadata: sourceMetadataArg,
5378
+ executionMetadata: productionMetadataArg,
5379
+ authenticatedPlan: authenticatedPlanArg,
5380
+ requestBundle: requestBundleArg,
5381
+ scratchReceipt: scratchReceiptArg,
5382
+ productionAuthorization: productionAuthorizationArg,
5383
+ requireProductionAuthorization: true,
5384
+ verifier: verifierArg,
5385
+ });
5386
+ const productionAuthorization = artifacts.productionAuthorization
5387
+ ?? fail('CROSS_FIELD_MISMATCH', 'productionExecutionBundleV2.executionAuthority');
5388
+ if (!artifacts.splitProductionAuthority) {
5389
+ fail('CROSS_FIELD_MISMATCH', 'productionExecutionBundleV2.executionAuthority');
5390
+ }
5391
+ await normalizeAuthenticatedApplyResultForExecutionAuthority(
5392
+ bundle.authenticatedResult,
5393
+ artifacts.executionMetadata,
5394
+ artifacts.requestBundle.authenticatedRequest,
5395
+ productionAuthorization,
5396
+ verifierArg,
5397
+ );
5398
+ if (bundle.receipt) {
5399
+ await normalizeCloudlyLegacyDeploymentSettlementProductionReceiptV2ForAuthorities(
5400
+ bundle.receipt,
5401
+ artifacts.executionMetadata,
5402
+ artifacts.sourceMetadata,
5403
+ artifacts.authenticatedPlan,
5404
+ artifacts.requestBundle,
5405
+ verifierArg,
5406
+ );
5407
+ if (canonicalize(
5408
+ bundle.receipt.productionAuthorization,
5409
+ 'productionExecutionBundleV2.receipt.productionAuthorization',
5410
+ ) !== canonicalize(
5411
+ artifacts.productionAuthorization,
5412
+ 'productionExecutionBundleV2.productionAuthorization',
5413
+ )) {
5414
+ fail('CROSS_FIELD_MISMATCH', 'productionExecutionBundleV2.productionAuthorization');
5415
+ }
5416
+ }
5417
+ return bundle;
5418
+ };
5419
+
5420
+ export const cloudlyLegacyDeploymentSettlementStdioLimits = Object.freeze({
5421
+ maximumMongoDescriptorBytes: 16 * 1024,
5422
+ maximumPrivateArtifactAggregateBytes: 4 * 1024 * 1024,
5423
+ maximumRequestFrameBytes: 5 * 1024 * 1024,
5424
+ maximumResponseFrameBytes: 4 * 1024 * 1024,
5425
+ });
5426
+
5427
+ export const cloudlyLegacyDeploymentSettlementStdioCommands = Object.freeze([
5428
+ 'settlement-plan',
5429
+ 'settlement-request',
5430
+ 'settlement-scratch-check',
5431
+ 'settlement-scratch-apply',
5432
+ 'settlement-scratch-resolve',
5433
+ 'settlement-production-authorize',
5434
+ 'settlement-production-check',
5435
+ 'settlement-production-apply',
5436
+ 'settlement-production-resolve',
5437
+ ] as const);
5438
+
5439
+ export type TCloudlyLegacyDeploymentSettlementStdioCommand =
5440
+ typeof cloudlyLegacyDeploymentSettlementStdioCommands[number];
5441
+
5442
+ export interface ICloudlyLegacyDeploymentSettlementMongoDescriptorV1 {
5443
+ mongoDbUrl: string;
5444
+ mongoDbName: string;
5445
+ mongoDbUser: string;
5446
+ mongoDbPass: string;
5447
+ }
5448
+
5449
+ interface ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5450
+ schemaVersion: 1;
5451
+ kind: 'cloudly-legacy-deployment-settlement-stdio-request';
5452
+ requestId: string;
5453
+ command: TCloudlyLegacyDeploymentSettlementStdioCommand;
5454
+ }
5455
+
5456
+ export interface ICloudlyLegacyDeploymentSettlementPlanStdioRequestV1
5457
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5458
+ command: 'settlement-plan';
5459
+ payload: {
5460
+ mongoDescriptor: ICloudlyLegacyDeploymentSettlementMongoDescriptorV1;
5461
+ authorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5462
+ effectiveAt: number;
5463
+ };
5464
+ }
5465
+
5466
+ export interface ICloudlyLegacyDeploymentSettlementRequestStdioRequestV1
5467
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5468
+ command: 'settlement-request';
5469
+ payload: {
5470
+ authorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5471
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5472
+ requestedAt: number;
5473
+ };
5474
+ }
5475
+
5476
+ interface ICloudlyLegacyDeploymentSettlementScratchStdioPayloadV1 {
5477
+ mongoDescriptor: ICloudlyLegacyDeploymentSettlementMongoDescriptorV1;
5478
+ authorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5479
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5480
+ requestBundle: ICloudlyLegacyDeploymentSettlementRequestBundleV1;
5481
+ executionAttempt: TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1;
5482
+ }
5483
+
5484
+ export interface ICloudlyLegacyDeploymentSettlementScratchCheckStdioRequestV1
5485
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5486
+ command: 'settlement-scratch-check';
5487
+ payload: ICloudlyLegacyDeploymentSettlementScratchStdioPayloadV1;
5488
+ }
5489
+
5490
+ export interface ICloudlyLegacyDeploymentSettlementScratchApplyStdioRequestV1
5491
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5492
+ command: 'settlement-scratch-apply';
5493
+ payload: ICloudlyLegacyDeploymentSettlementScratchStdioPayloadV1;
5494
+ }
5495
+
5496
+ export interface ICloudlyLegacyDeploymentSettlementScratchResolveStdioRequestV1
5497
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5498
+ command: 'settlement-scratch-resolve';
5499
+ payload: ICloudlyLegacyDeploymentSettlementScratchStdioPayloadV1 & {
5500
+ observedAt: number;
5501
+ };
5502
+ }
5503
+
5504
+ export interface ICloudlyLegacyDeploymentSettlementProductionAuthorizeStdioRequestV1
5505
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5506
+ command: 'settlement-production-authorize';
5507
+ payload: {
5508
+ sourceAuthorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5509
+ productionAuthorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5510
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5511
+ requestBundle: ICloudlyLegacyDeploymentSettlementRequestBundleV1;
5512
+ scratchReceipt: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
5513
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
5514
+ requestedAt: number;
5515
+ approvedAt: number;
5516
+ };
5517
+ }
5518
+
5519
+ interface ICloudlyLegacyDeploymentSettlementProductionStdioPayloadV1 {
5520
+ mongoDescriptor: ICloudlyLegacyDeploymentSettlementMongoDescriptorV1;
5521
+ sourceAuthorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5522
+ productionAuthorityHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5523
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5524
+ requestBundle: ICloudlyLegacyDeploymentSettlementRequestBundleV1;
5525
+ scratchReceipt: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
5526
+ productionAuthorization:
5527
+ ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1;
5528
+ executionAttempt: TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1;
5529
+ }
5530
+
5531
+ export interface ICloudlyLegacyDeploymentSettlementProductionCheckStdioRequestV1
5532
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5533
+ command: 'settlement-production-check';
5534
+ payload: ICloudlyLegacyDeploymentSettlementProductionStdioPayloadV1;
5535
+ }
5536
+
5537
+ export interface ICloudlyLegacyDeploymentSettlementProductionApplyStdioRequestV1
5538
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5539
+ command: 'settlement-production-apply';
5540
+ payload: ICloudlyLegacyDeploymentSettlementProductionStdioPayloadV1;
5541
+ }
5542
+
5543
+ export interface ICloudlyLegacyDeploymentSettlementProductionResolveStdioRequestV1
5544
+ extends ICloudlyLegacyDeploymentSettlementStdioRequestBaseV1 {
5545
+ command: 'settlement-production-resolve';
5546
+ payload: ICloudlyLegacyDeploymentSettlementProductionStdioPayloadV1 & {
5547
+ observedAt: number;
5548
+ };
5549
+ }
5550
+
5551
+ export type TCloudlyLegacyDeploymentSettlementStdioRequestV1 =
5552
+ | ICloudlyLegacyDeploymentSettlementPlanStdioRequestV1
5553
+ | ICloudlyLegacyDeploymentSettlementRequestStdioRequestV1
5554
+ | ICloudlyLegacyDeploymentSettlementScratchCheckStdioRequestV1
5555
+ | ICloudlyLegacyDeploymentSettlementScratchApplyStdioRequestV1
5556
+ | ICloudlyLegacyDeploymentSettlementScratchResolveStdioRequestV1
5557
+ | ICloudlyLegacyDeploymentSettlementProductionAuthorizeStdioRequestV1
5558
+ | ICloudlyLegacyDeploymentSettlementProductionCheckStdioRequestV1
5559
+ | ICloudlyLegacyDeploymentSettlementProductionApplyStdioRequestV1
5560
+ | ICloudlyLegacyDeploymentSettlementProductionResolveStdioRequestV1;
5561
+
5562
+ export const cloudlyLegacyDeploymentSettlementStdioErrorMetadata = Object.freeze({
5563
+ INVALID_FRAME: Object.freeze({ retryable: false }),
5564
+ INVALID_REQUEST: Object.freeze({ retryable: false }),
5565
+ AUTHORITY_INVALID: Object.freeze({ retryable: false }),
5566
+ AUTHORITY_EXPIRED: Object.freeze({ retryable: true }),
5567
+ REQUEST_MISMATCH: Object.freeze({ retryable: false }),
5568
+ PLAN_MISMATCH: Object.freeze({ retryable: false }),
5569
+ SOURCE_STATE_MISMATCH: Object.freeze({ retryable: false }),
5570
+ FINAL_STATE_MISMATCH: Object.freeze({ retryable: true }),
5571
+ TRANSACTIONS_UNSUPPORTED: Object.freeze({ retryable: false }),
5572
+ OPERATION_DRIFT: Object.freeze({ retryable: false }),
5573
+ CLAIM_DRIFT: Object.freeze({ retryable: false }),
5574
+ CLASSIFICATION_MISMATCH: Object.freeze({ retryable: false }),
5575
+ ATTEMPT_CONFLICT: Object.freeze({ retryable: false }),
5576
+ ATTEMPT_NOT_FOUND: Object.freeze({ retryable: false }),
5577
+ INTERNAL_ERROR: Object.freeze({ retryable: true }),
5578
+ } as const);
5579
+
5580
+ export type TCloudlyLegacyDeploymentSettlementStdioErrorCode =
5581
+ keyof typeof cloudlyLegacyDeploymentSettlementStdioErrorMetadata;
5582
+
5583
+ export type TCloudlyLegacyDeploymentSettlementStdioSafeErrorV1 = {
5584
+ [TCode in TCloudlyLegacyDeploymentSettlementStdioErrorCode]: {
5585
+ code: TCode;
5586
+ retryable: typeof cloudlyLegacyDeploymentSettlementStdioErrorMetadata[TCode]['retryable'];
5587
+ };
5588
+ }[TCloudlyLegacyDeploymentSettlementStdioErrorCode];
5589
+
5590
+ interface ICloudlyLegacyDeploymentSettlementStdioResponseBaseV1<
5591
+ TCommand extends TCloudlyLegacyDeploymentSettlementStdioCommand,
5592
+ > {
5593
+ schemaVersion: 1;
5594
+ kind: 'cloudly-legacy-deployment-settlement-stdio-response';
5595
+ requestId: string;
5596
+ command: TCommand;
5597
+ }
5598
+
5599
+ export interface ICloudlyLegacyDeploymentSettlementStdioSuccessPayloadByCommandV1 {
5600
+ 'settlement-plan': {
5601
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5602
+ };
5603
+ 'settlement-request': {
5604
+ requestBundle: ICloudlyLegacyDeploymentSettlementRequestBundleV1;
5605
+ };
5606
+ 'settlement-scratch-check': {
5607
+ authenticatedResult: IAuthenticatedCloudlyLegacyDeploymentSettlementCheckResultV1;
5608
+ };
5609
+ 'settlement-scratch-apply': {
5610
+ executionBundle: TCloudlyLegacyDeploymentSettlementScratchExecutionBundleV1;
5611
+ };
5612
+ 'settlement-scratch-resolve': {
5613
+ authenticatedResolution: IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1;
5614
+ };
5615
+ 'settlement-production-authorize': {
5616
+ productionAuthorization:
5617
+ ICloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationV1;
5618
+ };
5619
+ 'settlement-production-check': {
5620
+ authenticatedResult: IAuthenticatedCloudlyLegacyDeploymentSettlementCheckResultV1;
5621
+ };
5622
+ 'settlement-production-apply': {
5623
+ executionBundle: TCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2;
5624
+ };
5625
+ 'settlement-production-resolve': {
5626
+ authenticatedResolution: IAuthenticatedCloudlyLegacyDeploymentSettlementResolutionV1;
5627
+ };
5628
+ }
5629
+
5630
+ export type TCloudlyLegacyDeploymentSettlementStdioSuccessPayloadV1 =
5631
+ ICloudlyLegacyDeploymentSettlementStdioSuccessPayloadByCommandV1[
5632
+ TCloudlyLegacyDeploymentSettlementStdioCommand
5633
+ ];
5634
+
5635
+ export type TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1 = {
5636
+ [TCommand in TCloudlyLegacyDeploymentSettlementStdioCommand]:
5637
+ ICloudlyLegacyDeploymentSettlementStdioResponseBaseV1<TCommand> & {
5638
+ ok: true;
5639
+ payload: ICloudlyLegacyDeploymentSettlementStdioSuccessPayloadByCommandV1[TCommand];
5640
+ };
5641
+ }[TCloudlyLegacyDeploymentSettlementStdioCommand];
5642
+
5643
+ export type TCloudlyLegacyDeploymentSettlementStdioErrorResponseV1 = {
5644
+ [TCommand in TCloudlyLegacyDeploymentSettlementStdioCommand]:
5645
+ ICloudlyLegacyDeploymentSettlementStdioResponseBaseV1<TCommand> & {
5646
+ ok: false;
5647
+ error: TCloudlyLegacyDeploymentSettlementStdioSafeErrorV1;
5648
+ };
5649
+ }[TCloudlyLegacyDeploymentSettlementStdioCommand];
5650
+
5651
+ export type TCloudlyLegacyDeploymentSettlementStdioResponseV1 =
5652
+ | TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1
5653
+ | TCloudlyLegacyDeploymentSettlementStdioErrorResponseV1;
5654
+
5655
+ const stdioRequestKeys = ['schemaVersion', 'kind', 'requestId', 'command', 'payload'] as const;
5656
+ const stdioResponseSuccessKeys = [
5657
+ 'schemaVersion',
5658
+ 'kind',
5659
+ 'requestId',
5660
+ 'command',
5661
+ 'ok',
5662
+ 'payload',
5663
+ ] as const;
5664
+ const stdioResponseErrorKeys = [
5665
+ 'schemaVersion',
5666
+ 'kind',
5667
+ 'requestId',
5668
+ 'command',
5669
+ 'ok',
5670
+ 'error',
5671
+ ] as const;
5672
+
5673
+ const normalizeSettlementMongoDescriptor = (
5674
+ valueArg: unknown,
5675
+ pathArg: string,
5676
+ ): ICloudlyLegacyDeploymentSettlementMongoDescriptorV1 => {
5677
+ const value = readRecord(valueArg, pathArg);
5678
+ assertExactKeys(value, ['mongoDbUrl', 'mongoDbName', 'mongoDbUser', 'mongoDbPass'], pathArg);
5679
+ for (const key of ['mongoDbUrl', 'mongoDbName', 'mongoDbUser', 'mongoDbPass'] as const) {
5680
+ if (typeof value[key] !== 'string'
5681
+ || value[key].length === 0
5682
+ || Buffer.byteLength(value[key], 'utf8')
5683
+ > cloudlyLegacyDeploymentSettlementStdioLimits.maximumMongoDescriptorBytes
5684
+ || /[\u0000-\u0020\u007f]/u.test(value[key])) {
5685
+ fail('INVALID_VALUE', `${pathArg}.${key}`);
5686
+ }
5687
+ }
5688
+ const descriptor = value as unknown as ICloudlyLegacyDeploymentSettlementMongoDescriptorV1;
5689
+ let url: URL;
5690
+ let mongoDbName: string;
5691
+ let mongoDbUser: string;
5692
+ let mongoDbPass: string;
5693
+ try {
5694
+ url = new URL(descriptor.mongoDbUrl);
5695
+ mongoDbName = decodeURIComponent(url.pathname.slice(1));
5696
+ mongoDbUser = decodeURIComponent(url.username);
5697
+ mongoDbPass = decodeURIComponent(url.password);
5698
+ } catch {
5699
+ return fail('INVALID_VALUE', `${pathArg}.mongoDbUrl`);
5700
+ }
5701
+ const queryKeys = [...new Set(url.searchParams.keys())].sort();
5702
+ if (url.protocol !== 'mongodb:'
5703
+ || !url.hostname
5704
+ || !url.port
5705
+ || url.hash !== ''
5706
+ || mongoDbName !== descriptor.mongoDbName
5707
+ || mongoDbUser !== descriptor.mongoDbUser
5708
+ || mongoDbPass !== descriptor.mongoDbPass
5709
+ || JSON.stringify(queryKeys) !== JSON.stringify(['authSource', 'directConnection'])
5710
+ || url.searchParams.getAll('authSource').length !== 1
5711
+ || url.searchParams.get('authSource') !== descriptor.mongoDbName
5712
+ || url.searchParams.getAll('directConnection').length !== 1
5713
+ || url.searchParams.get('directConnection') !== 'true') {
5714
+ fail('CROSS_FIELD_MISMATCH', pathArg);
5715
+ }
5716
+ const output = {
5717
+ mongoDbUrl: descriptor.mongoDbUrl,
5718
+ mongoDbName: descriptor.mongoDbName,
5719
+ mongoDbUser: descriptor.mongoDbUser,
5720
+ mongoDbPass: descriptor.mongoDbPass,
5721
+ };
5722
+ if (Buffer.byteLength(canonicalize(output, pathArg), 'utf8')
5723
+ > cloudlyLegacyDeploymentSettlementStdioLimits.maximumMongoDescriptorBytes) {
5724
+ fail('LIMIT_EXCEEDED', pathArg);
5725
+ }
5726
+ return output;
5727
+ };
5728
+
5729
+ export const normalizeCloudlyLegacyDeploymentSettlementMongoDescriptor = (
5730
+ valueArg: unknown,
5731
+ ): Readonly<ICloudlyLegacyDeploymentSettlementMongoDescriptorV1> => finalize(
5732
+ normalizeSettlementMongoDescriptor(valueArg, 'mongoDescriptor'),
5733
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumMongoDescriptorBytes,
5734
+ 'mongoDescriptor',
5735
+ );
5736
+
5737
+ const assertStdioArtifactAggregate = (valueArg: unknown, pathArg: string): void => {
5738
+ if (Buffer.byteLength(canonicalize(valueArg, pathArg), 'utf8')
5739
+ > cloudlyLegacyDeploymentSettlementStdioLimits.maximumPrivateArtifactAggregateBytes) {
5740
+ fail('LIMIT_EXCEEDED', pathArg);
5741
+ }
5742
+ };
5743
+
5744
+ const assertDistinctStdioHandoffKeyMaterial = (
5745
+ sourceHandoffArg: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1,
5746
+ executionHandoffArg: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1,
5747
+ pathArg: string,
5748
+ ): void => {
5749
+ const sourceKey = Buffer.from(sourceHandoffArg.hmacKeyPlaintext.value, 'base64url');
5750
+ const executionKey = Buffer.from(executionHandoffArg.hmacKeyPlaintext.value, 'base64url');
5751
+ let equal = false;
5752
+ try {
5753
+ equal = plugins.crypto.timingSafeEqual(sourceKey, executionKey);
5754
+ } finally {
5755
+ sourceKey.fill(0);
5756
+ executionKey.fill(0);
5757
+ }
5758
+ if (equal) {
5759
+ fail('CROSS_FIELD_MISMATCH', pathArg);
5760
+ }
5761
+ };
5762
+
5763
+ const assertExecutionAttemptMatchesStdioArtifacts = (argsArg: {
5764
+ attempt: ICloudlyLegacyDeploymentSettlementExecutionAttemptIdentityV1;
5765
+ purpose: TCloudlyLegacyDeploymentSettlementExecutionPurpose;
5766
+ sourceHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5767
+ executionHandoff: ICloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintextV1;
5768
+ authenticatedPlan: IAuthenticatedCloudlyLegacyDeploymentSettlementPlanV1;
5769
+ requestBundle: ICloudlyLegacyDeploymentSettlementRequestBundleV1;
5770
+ scratchReceipt?: ICloudlyLegacyDeploymentSettlementScratchReceiptV1;
5771
+ path: string;
5772
+ }): void => {
5773
+ const sourceReference = argsArg.sourceHandoff.authorityReference;
5774
+ const executionReference = argsArg.executionHandoff.authorityReference;
5775
+ const sourceMetadata = normalizeFencedSourceAuthorityMetadata(
5776
+ argsArg.sourceHandoff.authorityMetadata,
5777
+ `${argsArg.path}.sourceAuthorityMetadata`,
5778
+ );
5779
+ if (argsArg.purpose === 'production') {
5780
+ assertDistinctStdioHandoffKeyMaterial(
5781
+ argsArg.sourceHandoff,
5782
+ argsArg.executionHandoff,
5783
+ `${argsArg.path}.authorityKeySeparation`,
5784
+ );
5785
+ normalizeProductionAuthorityMetadataPair(
5786
+ argsArg.executionHandoff.authorityMetadata,
5787
+ sourceMetadata,
5788
+ );
5789
+ } else {
5790
+ normalizeFencedSourceAuthorityMetadata(
5791
+ argsArg.executionHandoff.authorityMetadata,
5792
+ `${argsArg.path}.executionAuthorityMetadata`,
5793
+ );
5794
+ }
5795
+ normalizeCloudlyLegacyDeploymentSettlementPlanForAuthority(
5796
+ argsArg.authenticatedPlan.payload,
5797
+ sourceMetadata,
5798
+ );
5799
+ normalizeCloudlyLegacyDeploymentSettlementProductionRequestForAuthority(
5800
+ argsArg.requestBundle.authenticatedRequest.payload,
5801
+ sourceMetadata,
5802
+ );
5803
+ if (argsArg.scratchReceipt) {
5804
+ normalizeCloudlyLegacyDeploymentSettlementScratchReceiptStructureForRequest(
5805
+ argsArg.scratchReceipt,
5806
+ argsArg.requestBundle.authenticatedRequest,
5807
+ );
5808
+ }
5809
+ if (canonicalize(argsArg.authenticatedPlan.authority, `${argsArg.path}.plan.authority`)
5810
+ !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5811
+ || canonicalize(
5812
+ argsArg.requestBundle.authenticatedRequest.authority,
5813
+ `${argsArg.path}.request.authority`,
5814
+ ) !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5815
+ || canonicalize(
5816
+ argsArg.requestBundle.authenticatedRehearsalBinding.authority,
5817
+ `${argsArg.path}.binding.authority`,
5818
+ ) !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5819
+ || canonicalize(argsArg.authenticatedPlan.payload, `${argsArg.path}.plan.payload`)
5820
+ !== canonicalize(
5821
+ argsArg.requestBundle.authenticatedRequest.payload.plan,
5822
+ `${argsArg.path}.request.plan`,
5823
+ )
5824
+ || argsArg.authenticatedPlan.payloadSha256
5825
+ !== argsArg.requestBundle.authenticatedRequest.payload.planSha256
5826
+ || (argsArg.scratchReceipt !== undefined
5827
+ && (canonicalize(argsArg.scratchReceipt.authority, `${argsArg.path}.scratch.authority`)
5828
+ !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5829
+ || argsArg.scratchReceipt.requestSha256
5830
+ !== argsArg.requestBundle.authenticatedRequest.payloadSha256))) {
5831
+ fail('CROSS_FIELD_MISMATCH', `${argsArg.path}.sourceArtifacts`);
5832
+ }
5833
+ const scratchReceiptSha256 = argsArg.scratchReceipt
5834
+ ? digestCloudlyLegacyDeploymentSettlementScratchReceipt(argsArg.scratchReceipt)
5835
+ : null;
5836
+ if (argsArg.attempt.purpose !== argsArg.purpose
5837
+ || argsArg.attempt.operationId !== argsArg.executionHandoff.authorityMetadata.operationId
5838
+ || argsArg.attempt.settlementId !== argsArg.executionHandoff.authorityMetadata.settlementId
5839
+ || canonicalize(argsArg.attempt.sourceAuthority, `${argsArg.path}.attempt.sourceAuthority`)
5840
+ !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5841
+ || canonicalize(argsArg.attempt.executionAuthority, `${argsArg.path}.attempt.executionAuthority`)
5842
+ !== canonicalize(executionReference, `${argsArg.path}.executionAuthority`)
5843
+ || argsArg.attempt.authenticatedPlanSha256
5844
+ !== digestAuthenticatedCloudlyLegacyDeploymentSettlementPlan(argsArg.authenticatedPlan)
5845
+ || argsArg.attempt.requestBundleSha256
5846
+ !== digestCloudlyLegacyDeploymentSettlementRequestBundle(argsArg.requestBundle)
5847
+ || argsArg.attempt.scratchReceiptSha256 !== scratchReceiptSha256) {
5848
+ fail('CROSS_FIELD_MISMATCH', `${argsArg.path}.executionAttempt`);
5849
+ }
5850
+ if (argsArg.purpose === 'production') {
5851
+ const productionMetadata = argsArg.executionHandoff.authorityMetadata;
5852
+ if (!productionMetadata.sourceAuthority
5853
+ || canonicalize(productionMetadata.sourceAuthority, `${argsArg.path}.metadata.sourceAuthority`)
5854
+ !== canonicalize(sourceReference, `${argsArg.path}.sourceAuthority`)
5855
+ || productionMetadata.sourceAuthenticatedPlanSha256
5856
+ !== argsArg.attempt.authenticatedPlanSha256
5857
+ || productionMetadata.sourceRequestBundleSha256 !== argsArg.attempt.requestBundleSha256
5858
+ || productionMetadata.scratchReceiptSha256 !== scratchReceiptSha256) {
5859
+ fail('CROSS_FIELD_MISMATCH', `${argsArg.path}.productionAuthorityHandoff`);
5860
+ }
5861
+ }
5862
+ };
5863
+
5864
+ const normalizeScratchStdioPayload = (
5865
+ valueArg: unknown,
5866
+ pathArg: string,
5867
+ resolveArg: boolean,
5868
+ ): ICloudlyLegacyDeploymentSettlementScratchStdioPayloadV1 & { observedAt?: number } => {
5869
+ const value = readRecord(valueArg, pathArg);
5870
+ assertExactKeys(value, [
5871
+ 'mongoDescriptor',
5872
+ 'authorityHandoff',
5873
+ 'authenticatedPlan',
5874
+ 'requestBundle',
5875
+ 'executionAttempt',
5876
+ ...(resolveArg ? ['observedAt'] : []),
5877
+ ], pathArg);
5878
+ const authorityHandoff = normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
5879
+ value.authorityHandoff,
5880
+ );
5881
+ const authenticatedPlan =
5882
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedPlanStructure(value.authenticatedPlan);
5883
+ const requestBundle = normalizeCloudlyLegacyDeploymentSettlementRequestBundle(value.requestBundle);
5884
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
5885
+ value.executionAttempt,
5886
+ `${pathArg}.executionAttempt`,
5887
+ );
5888
+ assertExecutionAttemptMatchesStdioArtifacts({
5889
+ attempt: executionAttempt,
5890
+ purpose: 'scratch-rehearsal',
5891
+ sourceHandoff: authorityHandoff,
5892
+ executionHandoff: authorityHandoff,
5893
+ authenticatedPlan,
5894
+ requestBundle,
5895
+ path: pathArg,
5896
+ });
5897
+ const output = {
5898
+ mongoDescriptor: normalizeSettlementMongoDescriptor(
5899
+ value.mongoDescriptor,
5900
+ `${pathArg}.mongoDescriptor`,
5901
+ ),
5902
+ authorityHandoff,
5903
+ authenticatedPlan,
5904
+ requestBundle,
5905
+ executionAttempt: executionAttempt as
5906
+ TCloudlyLegacyDeploymentSettlementScratchExecutionAttemptIdentityV1,
5907
+ ...(resolveArg
5908
+ ? { observedAt: readInteger(value.observedAt, `${pathArg}.observedAt`, 1) }
5909
+ : {}),
5910
+ };
5911
+ assertStdioArtifactAggregate(output, pathArg);
5912
+ return output;
5913
+ };
5914
+
5915
+ const normalizeProductionStdioPayload = (
5916
+ valueArg: unknown,
5917
+ pathArg: string,
5918
+ resolveArg: boolean,
5919
+ ): ICloudlyLegacyDeploymentSettlementProductionStdioPayloadV1 & { observedAt?: number } => {
5920
+ const value = readRecord(valueArg, pathArg);
5921
+ assertExactKeys(value, [
5922
+ 'mongoDescriptor',
5923
+ 'sourceAuthorityHandoff',
5924
+ 'productionAuthorityHandoff',
5925
+ 'authenticatedPlan',
5926
+ 'requestBundle',
5927
+ 'scratchReceipt',
5928
+ 'productionAuthorization',
5929
+ 'executionAttempt',
5930
+ ...(resolveArg ? ['observedAt'] : []),
5931
+ ], pathArg);
5932
+ const sourceAuthorityHandoff =
5933
+ normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
5934
+ value.sourceAuthorityHandoff,
5935
+ );
5936
+ const productionAuthorityHandoff =
5937
+ normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
5938
+ value.productionAuthorityHandoff,
5939
+ );
5940
+ const authenticatedPlan =
5941
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedPlanStructure(value.authenticatedPlan);
5942
+ const requestBundle = normalizeCloudlyLegacyDeploymentSettlementRequestBundle(value.requestBundle);
5943
+ const scratchReceipt = normalizeCloudlyLegacyDeploymentSettlementScratchReceipt(
5944
+ value.scratchReceipt,
5945
+ );
5946
+ const productionAuthorization =
5947
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(
5948
+ value.productionAuthorization,
5949
+ );
5950
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
5951
+ value.executionAttempt,
5952
+ `${pathArg}.executionAttempt`,
5953
+ );
5954
+ assertExecutionAttemptMatchesStdioArtifacts({
5955
+ attempt: executionAttempt,
5956
+ purpose: 'production',
5957
+ sourceHandoff: sourceAuthorityHandoff,
5958
+ executionHandoff: productionAuthorityHandoff,
5959
+ authenticatedPlan,
5960
+ requestBundle,
5961
+ scratchReceipt,
5962
+ path: pathArg,
5963
+ });
5964
+ if (canonicalize(productionAuthorization.executionAttempt, `${pathArg}.authorization.attempt`)
5965
+ !== canonicalize(executionAttempt, `${pathArg}.executionAttempt`)) {
5966
+ fail('CROSS_FIELD_MISMATCH', `${pathArg}.productionAuthorization`);
5967
+ }
5968
+ const metadata = normalizeProductionAuthorityMetadataPair(
5969
+ productionAuthorityHandoff.authorityMetadata,
5970
+ sourceAuthorityHandoff.authorityMetadata,
5971
+ );
5972
+ assertProductionAuthorizationArtifacts(
5973
+ productionAuthorization,
5974
+ metadata.productionMetadata,
5975
+ metadata.sourceMetadata,
5976
+ authenticatedPlan,
5977
+ requestBundle,
5978
+ scratchReceipt,
5979
+ );
5980
+ const output = {
5981
+ mongoDescriptor: normalizeSettlementMongoDescriptor(
5982
+ value.mongoDescriptor,
5983
+ `${pathArg}.mongoDescriptor`,
5984
+ ),
5985
+ sourceAuthorityHandoff,
5986
+ productionAuthorityHandoff,
5987
+ authenticatedPlan,
5988
+ requestBundle,
5989
+ scratchReceipt,
5990
+ productionAuthorization,
5991
+ executionAttempt: executionAttempt as
5992
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
5993
+ ...(resolveArg
5994
+ ? { observedAt: readInteger(value.observedAt, `${pathArg}.observedAt`, 1) }
5995
+ : {}),
5996
+ };
5997
+ assertStdioArtifactAggregate(output, pathArg);
5998
+ return output;
5999
+ };
6000
+
6001
+ /** Structural only; use the authority-aware variant before trusting artifacts. */
6002
+ export const normalizeCloudlyLegacyDeploymentSettlementStdioRequest = (
6003
+ valueArg: unknown,
6004
+ ): Readonly<TCloudlyLegacyDeploymentSettlementStdioRequestV1> => {
6005
+ const value = readRecord(valueArg, 'stdioRequest');
6006
+ assertExactKeys(value, stdioRequestKeys, 'stdioRequest');
6007
+ assertStdioArtifactAggregate(value.payload, 'stdioRequest.payload');
6008
+ if (value.schemaVersion !== 1
6009
+ || value.kind !== 'cloudly-legacy-deployment-settlement-stdio-request') {
6010
+ fail('INVALID_VALUE', 'stdioRequest.kind');
6011
+ }
6012
+ const requestId = readIdentifier(value.requestId, 'stdioRequest.requestId');
6013
+ const command = readLiteral(
6014
+ value.command,
6015
+ cloudlyLegacyDeploymentSettlementStdioCommands,
6016
+ 'stdioRequest.command',
6017
+ );
6018
+ const payloadPath = 'stdioRequest.payload';
6019
+ let payload: TCloudlyLegacyDeploymentSettlementStdioRequestV1['payload'];
6020
+ if (command === 'settlement-plan') {
6021
+ const input = readRecord(value.payload, payloadPath);
6022
+ assertExactKeys(input, ['mongoDescriptor', 'authorityHandoff', 'effectiveAt'], payloadPath);
6023
+ const authorityHandoff = normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
6024
+ input.authorityHandoff,
6025
+ );
6026
+ const sourceMetadata = normalizeFencedSourceAuthorityMetadata(
6027
+ authorityHandoff.authorityMetadata,
6028
+ `${payloadPath}.authorityHandoff.authorityMetadata`,
6029
+ );
6030
+ const effectiveAt = readInteger(input.effectiveAt, `${payloadPath}.effectiveAt`, 1);
6031
+ assertAuthorityTimestamp(effectiveAt, sourceMetadata, `${payloadPath}.effectiveAt`);
6032
+ payload = {
6033
+ mongoDescriptor: normalizeSettlementMongoDescriptor(
6034
+ input.mongoDescriptor,
6035
+ `${payloadPath}.mongoDescriptor`,
6036
+ ),
6037
+ authorityHandoff,
6038
+ effectiveAt,
6039
+ };
6040
+ } else if (command === 'settlement-request') {
6041
+ const input = readRecord(value.payload, payloadPath);
6042
+ assertExactKeys(input, ['authorityHandoff', 'authenticatedPlan', 'requestedAt'], payloadPath);
6043
+ const authorityHandoff = normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
6044
+ input.authorityHandoff,
6045
+ );
6046
+ const sourceMetadata = normalizeFencedSourceAuthorityMetadata(
6047
+ authorityHandoff.authorityMetadata,
6048
+ `${payloadPath}.authorityHandoff.authorityMetadata`,
6049
+ );
6050
+ const authenticatedPlan =
6051
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedPlanStructure(
6052
+ input.authenticatedPlan,
6053
+ );
6054
+ assertAuthorityReferenceMatchesMetadata(
6055
+ authenticatedPlan.authority,
6056
+ sourceMetadata,
6057
+ `${payloadPath}.authenticatedPlan.authority`,
6058
+ );
6059
+ normalizeCloudlyLegacyDeploymentSettlementPlanForAuthority(
6060
+ authenticatedPlan.payload,
6061
+ sourceMetadata,
6062
+ );
6063
+ const requestedAt = readInteger(input.requestedAt, `${payloadPath}.requestedAt`, 1);
6064
+ assertAuthorityTimestamp(requestedAt, sourceMetadata, `${payloadPath}.requestedAt`);
6065
+ if (requestedAt < authenticatedPlan.payload.effectiveAt) {
6066
+ fail('CROSS_FIELD_MISMATCH', `${payloadPath}.requestedAt`);
6067
+ }
6068
+ payload = {
6069
+ authorityHandoff,
6070
+ authenticatedPlan,
6071
+ requestedAt,
6072
+ };
6073
+ } else if (command === 'settlement-scratch-check'
6074
+ || command === 'settlement-scratch-apply') {
6075
+ payload = normalizeScratchStdioPayload(value.payload, payloadPath, false);
6076
+ } else if (command === 'settlement-scratch-resolve') {
6077
+ payload = normalizeScratchStdioPayload(value.payload, payloadPath, true) as
6078
+ ICloudlyLegacyDeploymentSettlementScratchResolveStdioRequestV1['payload'];
6079
+ } else if (command === 'settlement-production-authorize') {
6080
+ const input = readRecord(value.payload, payloadPath);
6081
+ assertExactKeys(input, [
6082
+ 'sourceAuthorityHandoff',
6083
+ 'productionAuthorityHandoff',
6084
+ 'authenticatedPlan',
6085
+ 'requestBundle',
6086
+ 'scratchReceipt',
6087
+ 'executionAttempt',
6088
+ 'requestedAt',
6089
+ 'approvedAt',
6090
+ ], payloadPath);
6091
+ const sourceAuthorityHandoff =
6092
+ normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
6093
+ input.sourceAuthorityHandoff,
6094
+ );
6095
+ const productionAuthorityHandoff =
6096
+ normalizeCloudlyLegacyDeploymentSettlementAuthorityHandoffPlaintext(
6097
+ input.productionAuthorityHandoff,
6098
+ );
6099
+ const authenticatedPlan =
6100
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedPlanStructure(
6101
+ input.authenticatedPlan,
6102
+ );
6103
+ const requestBundle = normalizeCloudlyLegacyDeploymentSettlementRequestBundle(
6104
+ input.requestBundle,
6105
+ );
6106
+ const scratchReceipt = normalizeCloudlyLegacyDeploymentSettlementScratchReceipt(
6107
+ input.scratchReceipt,
6108
+ );
6109
+ const executionAttempt = normalizeExecutionAttemptIdentityInternal(
6110
+ input.executionAttempt,
6111
+ `${payloadPath}.executionAttempt`,
6112
+ );
6113
+ assertExecutionAttemptMatchesStdioArtifacts({
6114
+ attempt: executionAttempt,
6115
+ purpose: 'production',
6116
+ sourceHandoff: sourceAuthorityHandoff,
6117
+ executionHandoff: productionAuthorityHandoff,
6118
+ authenticatedPlan,
6119
+ requestBundle,
6120
+ scratchReceipt,
6121
+ path: payloadPath,
6122
+ });
6123
+ const requestedAt = readInteger(input.requestedAt, `${payloadPath}.requestedAt`, 1);
6124
+ const metadata = normalizeProductionAuthorityMetadataPair(
6125
+ productionAuthorityHandoff.authorityMetadata,
6126
+ sourceAuthorityHandoff.authorityMetadata,
6127
+ );
6128
+ const approvedAt = readInteger(input.approvedAt, `${payloadPath}.approvedAt`, requestedAt);
6129
+ assertAuthorityTimestamp(requestedAt, metadata.productionMetadata, `${payloadPath}.requestedAt`);
6130
+ assertAuthorityTimestamp(approvedAt, metadata.productionMetadata, `${payloadPath}.approvedAt`);
6131
+ if (metadata.productionMetadata.issuedAt < scratchReceipt.completedAt
6132
+ || requestedAt < scratchReceipt.completedAt) {
6133
+ fail('CROSS_FIELD_MISMATCH', `${payloadPath}.requestedAt`);
6134
+ }
6135
+ payload = {
6136
+ sourceAuthorityHandoff,
6137
+ productionAuthorityHandoff,
6138
+ authenticatedPlan,
6139
+ requestBundle,
6140
+ scratchReceipt,
6141
+ executionAttempt: executionAttempt as
6142
+ TCloudlyLegacyDeploymentSettlementProductionExecutionAttemptIdentityV1,
6143
+ requestedAt,
6144
+ approvedAt,
6145
+ };
6146
+ } else if (command === 'settlement-production-resolve') {
6147
+ payload = normalizeProductionStdioPayload(value.payload, payloadPath, true) as
6148
+ ICloudlyLegacyDeploymentSettlementProductionResolveStdioRequestV1['payload'];
6149
+ } else {
6150
+ payload = normalizeProductionStdioPayload(value.payload, payloadPath, false);
6151
+ }
6152
+ assertStdioArtifactAggregate(payload, payloadPath);
6153
+ return finalize({
6154
+ schemaVersion: 1,
6155
+ kind: 'cloudly-legacy-deployment-settlement-stdio-request',
6156
+ requestId,
6157
+ command,
6158
+ payload,
6159
+ } as TCloudlyLegacyDeploymentSettlementStdioRequestV1,
6160
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumRequestFrameBytes - 1,
6161
+ 'stdioRequest');
6162
+ };
6163
+
6164
+ const createCloudlyLegacyDeploymentSettlementStdioRequestHmacVerifier = (
6165
+ requestArg: TCloudlyLegacyDeploymentSettlementStdioRequestV1,
6166
+ ): TCloudlyLegacyDeploymentSettlementHmacVerifier => {
6167
+ if (requestArg.command === 'settlement-plan'
6168
+ || requestArg.command === 'settlement-request'
6169
+ || requestArg.command === 'settlement-scratch-check'
6170
+ || requestArg.command === 'settlement-scratch-apply'
6171
+ || requestArg.command === 'settlement-scratch-resolve') {
6172
+ return createCloudlyLegacyDeploymentSettlementStdioHandoffHmacVerifier(
6173
+ requestArg.payload.authorityHandoff,
6174
+ );
6175
+ }
6176
+ const sourceVerifier = createCloudlyLegacyDeploymentSettlementStdioHandoffHmacVerifier(
6177
+ requestArg.payload.sourceAuthorityHandoff,
6178
+ );
6179
+ const executionVerifier = createCloudlyLegacyDeploymentSettlementStdioHandoffHmacVerifier(
6180
+ requestArg.payload.productionAuthorityHandoff,
6181
+ );
6182
+ return async (inputArg): Promise<boolean> => (
6183
+ await sourceVerifier(inputArg) || await executionVerifier(inputArg)
6184
+ );
6185
+ };
6186
+
6187
+ export const normalizeCloudlyLegacyDeploymentSettlementStdioRequestForAuthorities = async (
6188
+ valueArg: unknown,
6189
+ ): Promise<Readonly<TCloudlyLegacyDeploymentSettlementStdioRequestV1>> => {
6190
+ const request = normalizeCloudlyLegacyDeploymentSettlementStdioRequest(valueArg);
6191
+ const verifier = createCloudlyLegacyDeploymentSettlementStdioRequestHmacVerifier(request);
6192
+ if (request.command === 'settlement-plan') {
6193
+ return request;
6194
+ }
6195
+ if (request.command === 'settlement-request') {
6196
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementPlanForAuthority(
6197
+ request.payload.authenticatedPlan,
6198
+ request.payload.authorityHandoff.authorityMetadata,
6199
+ verifier,
6200
+ );
6201
+ return request;
6202
+ }
6203
+ if (request.command === 'settlement-scratch-check'
6204
+ || request.command === 'settlement-scratch-apply'
6205
+ || request.command === 'settlement-scratch-resolve') {
6206
+ await normalizeExecutionAttemptProofArtifacts({
6207
+ executionAttempt: request.payload.executionAttempt,
6208
+ sourceMetadata: request.payload.authorityHandoff.authorityMetadata,
6209
+ executionMetadata: request.payload.authorityHandoff.authorityMetadata,
6210
+ authenticatedPlan: request.payload.authenticatedPlan,
6211
+ requestBundle: request.payload.requestBundle,
6212
+ scratchReceipt: null,
6213
+ productionAuthorization: null,
6214
+ requireProductionAuthorization: false,
6215
+ verifier,
6216
+ });
6217
+ return request;
6218
+ }
6219
+ await normalizeExecutionAttemptProofArtifacts({
6220
+ executionAttempt: request.payload.executionAttempt,
6221
+ sourceMetadata: request.payload.sourceAuthorityHandoff.authorityMetadata,
6222
+ executionMetadata: request.payload.productionAuthorityHandoff.authorityMetadata,
6223
+ authenticatedPlan: request.payload.authenticatedPlan,
6224
+ requestBundle: request.payload.requestBundle,
6225
+ scratchReceipt: request.payload.scratchReceipt,
6226
+ productionAuthorization: request.command === 'settlement-production-authorize'
6227
+ ? null
6228
+ : request.payload.productionAuthorization,
6229
+ requireProductionAuthorization: request.command !== 'settlement-production-authorize',
6230
+ verifier,
6231
+ });
6232
+ return request;
6233
+ };
6234
+
6235
+ const normalizeStdioSuccessPayload = (
6236
+ commandArg: TCloudlyLegacyDeploymentSettlementStdioCommand,
6237
+ valueArg: unknown,
6238
+ ): TCloudlyLegacyDeploymentSettlementStdioSuccessPayloadV1 => {
6239
+ const path = 'stdioResponse.payload';
6240
+ const value = readRecord(valueArg, path);
6241
+ if (commandArg === 'settlement-plan') {
6242
+ assertExactKeys(value, ['authenticatedPlan'], path);
6243
+ return {
6244
+ authenticatedPlan: normalizeCloudlyLegacyDeploymentSettlementAuthenticatedPlanStructure(
6245
+ value.authenticatedPlan,
6246
+ ),
6247
+ };
6248
+ }
6249
+ if (commandArg === 'settlement-request') {
6250
+ assertExactKeys(value, ['requestBundle'], path);
6251
+ return { requestBundle: normalizeCloudlyLegacyDeploymentSettlementRequestBundle(
6252
+ value.requestBundle,
6253
+ ) };
6254
+ }
6255
+ if (commandArg === 'settlement-scratch-check'
6256
+ || commandArg === 'settlement-production-check') {
6257
+ assertExactKeys(value, ['authenticatedResult'], path);
6258
+ return {
6259
+ authenticatedResult:
6260
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedCheckResultStructure(
6261
+ value.authenticatedResult,
6262
+ ),
6263
+ };
6264
+ }
6265
+ if (commandArg === 'settlement-scratch-apply') {
6266
+ assertExactKeys(value, ['executionBundle'], path);
6267
+ return {
6268
+ executionBundle: normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundle(
6269
+ value.executionBundle,
6270
+ ),
6271
+ };
6272
+ }
6273
+ if (commandArg === 'settlement-production-apply') {
6274
+ assertExactKeys(value, ['executionBundle'], path);
6275
+ return {
6276
+ executionBundle: normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2(
6277
+ value.executionBundle,
6278
+ ),
6279
+ };
6280
+ }
6281
+ if (commandArg === 'settlement-production-authorize') {
6282
+ assertExactKeys(value, ['productionAuthorization'], path);
6283
+ return {
6284
+ productionAuthorization:
6285
+ normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorization(
6286
+ value.productionAuthorization,
6287
+ ),
6288
+ };
6289
+ }
6290
+ assertExactKeys(value, ['authenticatedResolution'], path);
6291
+ return {
6292
+ authenticatedResolution:
6293
+ normalizeCloudlyLegacyDeploymentSettlementAuthenticatedResolutionStructure(
6294
+ value.authenticatedResolution,
6295
+ ),
6296
+ };
6297
+ };
6298
+
6299
+ const createCloudlyLegacyDeploymentSettlementStdioSafeError = (
6300
+ codeArg: TCloudlyLegacyDeploymentSettlementStdioErrorCode,
6301
+ ): TCloudlyLegacyDeploymentSettlementStdioSafeErrorV1 => ({
6302
+ code: codeArg,
6303
+ retryable: cloudlyLegacyDeploymentSettlementStdioErrorMetadata[codeArg].retryable,
6304
+ } as TCloudlyLegacyDeploymentSettlementStdioSafeErrorV1);
6305
+
6306
+ /** Structural only; use the request-authority-aware variant before trusting artifacts. */
6307
+ export const normalizeCloudlyLegacyDeploymentSettlementStdioResponse = (
6308
+ valueArg: unknown,
6309
+ ): Readonly<TCloudlyLegacyDeploymentSettlementStdioResponseV1> => {
6310
+ const value = readRecord(valueArg, 'stdioResponse');
6311
+ if (typeof value.ok !== 'boolean') fail('INVALID_VALUE', 'stdioResponse.ok');
6312
+ assertExactKeys(
6313
+ value,
6314
+ value.ok ? stdioResponseSuccessKeys : stdioResponseErrorKeys,
6315
+ 'stdioResponse',
6316
+ );
6317
+ if (value.schemaVersion !== 1
6318
+ || value.kind !== 'cloudly-legacy-deployment-settlement-stdio-response') {
6319
+ fail('INVALID_VALUE', 'stdioResponse.kind');
6320
+ }
6321
+ if (value.ok) {
6322
+ assertStdioArtifactAggregate(value.payload, 'stdioResponse.payload');
6323
+ }
6324
+ const requestId = readIdentifier(value.requestId, 'stdioResponse.requestId');
6325
+ const command = readLiteral(
6326
+ value.command,
6327
+ cloudlyLegacyDeploymentSettlementStdioCommands,
6328
+ 'stdioResponse.command',
6329
+ );
6330
+ if (value.ok) {
6331
+ const payload = normalizeStdioSuccessPayload(command, value.payload);
6332
+ assertStdioArtifactAggregate(payload, 'stdioResponse.payload');
6333
+ return finalize({
6334
+ schemaVersion: 1,
6335
+ kind: 'cloudly-legacy-deployment-settlement-stdio-response',
6336
+ requestId,
6337
+ command,
6338
+ ok: true,
6339
+ payload,
6340
+ } as TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6341
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumResponseFrameBytes - 1,
6342
+ 'stdioResponse');
6343
+ }
6344
+ const error = readRecord(value.error, 'stdioResponse.error');
6345
+ assertExactKeys(error, ['code', 'retryable'], 'stdioResponse.error');
6346
+ if (typeof error.code !== 'string'
6347
+ || !Object.hasOwn(cloudlyLegacyDeploymentSettlementStdioErrorMetadata, error.code)) {
6348
+ fail('INVALID_VALUE', 'stdioResponse.error.code');
6349
+ }
6350
+ const code = error.code as TCloudlyLegacyDeploymentSettlementStdioErrorCode;
6351
+ if (error.retryable !== cloudlyLegacyDeploymentSettlementStdioErrorMetadata[code].retryable) {
6352
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.error.retryable');
6353
+ }
6354
+ return finalize({
6355
+ schemaVersion: 1,
6356
+ kind: 'cloudly-legacy-deployment-settlement-stdio-response',
6357
+ requestId,
6358
+ command,
6359
+ ok: false,
6360
+ error: createCloudlyLegacyDeploymentSettlementStdioSafeError(code),
6361
+ } as TCloudlyLegacyDeploymentSettlementStdioErrorResponseV1,
6362
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumResponseFrameBytes - 1,
6363
+ 'stdioResponse');
6364
+ };
6365
+
6366
+ export const normalizeCloudlyLegacyDeploymentSettlementStdioResponseForRequestAuthorities = async (
6367
+ responseArg: unknown,
6368
+ requestArg: unknown,
6369
+ ): Promise<Readonly<TCloudlyLegacyDeploymentSettlementStdioResponseV1>> => {
6370
+ const request = await normalizeCloudlyLegacyDeploymentSettlementStdioRequestForAuthorities(
6371
+ requestArg,
6372
+ );
6373
+ const verifier = createCloudlyLegacyDeploymentSettlementStdioRequestHmacVerifier(request);
6374
+ const response = normalizeCloudlyLegacyDeploymentSettlementStdioResponse(responseArg);
6375
+ if (response.requestId !== request.requestId || response.command !== request.command) {
6376
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.request');
6377
+ }
6378
+ if (!response.ok) {
6379
+ return response;
6380
+ }
6381
+ if (request.command === 'settlement-plan') {
6382
+ const success = response as Extract<
6383
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6384
+ { command: 'settlement-plan' }
6385
+ >;
6386
+ const plan = await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementPlanForAuthority(
6387
+ success.payload.authenticatedPlan,
6388
+ request.payload.authorityHandoff.authorityMetadata,
6389
+ verifier,
6390
+ );
6391
+ if (plan.payload.effectiveAt !== request.payload.effectiveAt) {
6392
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.payload.authenticatedPlan.effectiveAt');
6393
+ }
6394
+ return response;
6395
+ }
6396
+ if (request.command === 'settlement-request') {
6397
+ const success = response as Extract<
6398
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6399
+ { command: 'settlement-request' }
6400
+ >;
6401
+ const requestBundle =
6402
+ await normalizeCloudlyLegacyDeploymentSettlementRequestBundleForAuthority(
6403
+ success.payload.requestBundle,
6404
+ request.payload.authenticatedPlan,
6405
+ request.payload.authorityHandoff.authorityMetadata,
6406
+ verifier,
6407
+ );
6408
+ if (requestBundle.authenticatedRequest.payload.requestedAt
6409
+ !== request.payload.requestedAt) {
6410
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.payload.requestBundle.requestedAt');
6411
+ }
6412
+ return response;
6413
+ }
6414
+ if (request.command === 'settlement-scratch-check') {
6415
+ const success = response as Extract<
6416
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6417
+ { command: 'settlement-scratch-check' }
6418
+ >;
6419
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementCheckResultForAuthority(
6420
+ success.payload.authenticatedResult,
6421
+ request.payload.authorityHandoff.authorityMetadata,
6422
+ request.payload.requestBundle.authenticatedRequest,
6423
+ verifier,
6424
+ );
6425
+ return response;
6426
+ }
6427
+ if (request.command === 'settlement-scratch-apply') {
6428
+ const success = response as Extract<
6429
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6430
+ { command: 'settlement-scratch-apply' }
6431
+ >;
6432
+ await normalizeCloudlyLegacyDeploymentSettlementScratchExecutionBundleForAuthority(
6433
+ success.payload.executionBundle,
6434
+ request.payload.authorityHandoff.authorityMetadata,
6435
+ request.payload.authenticatedPlan,
6436
+ request.payload.requestBundle,
6437
+ verifier,
6438
+ );
6439
+ return response;
6440
+ }
6441
+ if (request.command === 'settlement-scratch-resolve') {
6442
+ const success = response as Extract<
6443
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6444
+ { command: 'settlement-scratch-resolve' }
6445
+ >;
6446
+ const resolution =
6447
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementResolutionForAuthorities(
6448
+ success.payload.authenticatedResolution,
6449
+ request.payload.authorityHandoff.authorityMetadata,
6450
+ request.payload.authorityHandoff.authorityMetadata,
6451
+ request.payload.authenticatedPlan,
6452
+ request.payload.requestBundle,
6453
+ null,
6454
+ null,
6455
+ verifier,
6456
+ );
6457
+ if (resolution.payload.observedAt !== request.payload.observedAt) {
6458
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.payload.authenticatedResolution.observedAt');
6459
+ }
6460
+ return response;
6461
+ }
6462
+ if (request.command === 'settlement-production-authorize') {
6463
+ const success = response as Extract<
6464
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6465
+ { command: 'settlement-production-authorize' }
6466
+ >;
6467
+ const authorization =
6468
+ await normalizeCloudlyLegacyDeploymentSettlementProductionExecutionAuthorizationForAuthorities(
6469
+ success.payload.productionAuthorization,
6470
+ request.payload.productionAuthorityHandoff.authorityMetadata,
6471
+ request.payload.sourceAuthorityHandoff.authorityMetadata,
6472
+ request.payload.authenticatedPlan,
6473
+ request.payload.requestBundle,
6474
+ request.payload.scratchReceipt,
6475
+ verifier,
6476
+ );
6477
+ if (authorization.requestedAt !== request.payload.requestedAt
6478
+ || authorization.approvedAt !== request.payload.approvedAt) {
6479
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.payload.productionAuthorization.timestamp');
6480
+ }
6481
+ return response;
6482
+ }
6483
+ if (request.command === 'settlement-production-check') {
6484
+ const success = response as Extract<
6485
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6486
+ { command: 'settlement-production-check' }
6487
+ >;
6488
+ await normalizeAuthenticatedCheckResultForExecutionAuthority(
6489
+ success.payload.authenticatedResult,
6490
+ request.payload.productionAuthorityHandoff.authorityMetadata,
6491
+ request.payload.requestBundle.authenticatedRequest,
6492
+ request.payload.productionAuthorization,
6493
+ verifier,
6494
+ );
6495
+ return response;
6496
+ }
6497
+ if (request.command === 'settlement-production-apply') {
6498
+ const success = response as Extract<
6499
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6500
+ { command: 'settlement-production-apply' }
6501
+ >;
6502
+ await normalizeCloudlyLegacyDeploymentSettlementProductionExecutionBundleV2ForAuthorities(
6503
+ success.payload.executionBundle,
6504
+ request.payload.productionAuthorization,
6505
+ request.payload.productionAuthorityHandoff.authorityMetadata,
6506
+ request.payload.sourceAuthorityHandoff.authorityMetadata,
6507
+ request.payload.authenticatedPlan,
6508
+ request.payload.requestBundle,
6509
+ request.payload.scratchReceipt,
6510
+ verifier,
6511
+ );
6512
+ return response;
6513
+ }
6514
+ const success = response as Extract<
6515
+ TCloudlyLegacyDeploymentSettlementStdioSuccessResponseV1,
6516
+ { command: 'settlement-production-resolve' }
6517
+ >;
6518
+ const resolution =
6519
+ await normalizeAuthenticatedCloudlyLegacyDeploymentSettlementResolutionForAuthorities(
6520
+ success.payload.authenticatedResolution,
6521
+ request.payload.sourceAuthorityHandoff.authorityMetadata,
6522
+ request.payload.productionAuthorityHandoff.authorityMetadata,
6523
+ request.payload.authenticatedPlan,
6524
+ request.payload.requestBundle,
6525
+ request.payload.scratchReceipt,
6526
+ request.payload.productionAuthorization,
6527
+ verifier,
6528
+ );
6529
+ if (resolution.payload.observedAt !== request.payload.observedAt) {
6530
+ fail('CROSS_FIELD_MISMATCH', 'stdioResponse.payload.authenticatedResolution.observedAt');
6531
+ }
6532
+ return response;
6533
+ };
6534
+
6535
+ const encodeStdioFrame = (
6536
+ valueArg: unknown,
6537
+ maximumBytesArg: number,
6538
+ pathArg: string,
6539
+ ): Uint8Array => {
6540
+ const payload = encodeNormalized(valueArg, pathArg);
6541
+ if (payload.byteLength + 1 > maximumBytesArg) fail('LIMIT_EXCEEDED', pathArg);
6542
+ const output = new Uint8Array(payload.byteLength + 1);
6543
+ output.set(payload);
6544
+ output[payload.byteLength] = 0x0a;
6545
+ return output;
6546
+ };
6547
+
6548
+ export const encodeCloudlyLegacyDeploymentSettlementStdioRequestFrame = (
6549
+ valueArg: unknown,
6550
+ ): Uint8Array => encodeStdioFrame(
6551
+ normalizeCloudlyLegacyDeploymentSettlementStdioRequest(valueArg),
6552
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumRequestFrameBytes,
6553
+ 'stdioRequest',
6554
+ );
6555
+
6556
+ export const encodeCloudlyLegacyDeploymentSettlementStdioResponseFrame = (
6557
+ valueArg: unknown,
6558
+ ): Uint8Array => encodeStdioFrame(
6559
+ normalizeCloudlyLegacyDeploymentSettlementStdioResponse(valueArg),
6560
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumResponseFrameBytes,
6561
+ 'stdioResponse',
6562
+ );
6563
+
6564
+ const decodeStdioFrame = <T>(
6565
+ frameArg: Uint8Array,
6566
+ maximumBytesArg: number,
6567
+ pathArg: string,
6568
+ normalizeArg: (valueArg: unknown) => Readonly<T>,
6569
+ encodeArg: (valueArg: unknown) => Uint8Array,
6570
+ ): Readonly<T> => {
6571
+ if (!(frameArg instanceof Uint8Array)
6572
+ || frameArg.byteLength < 3
6573
+ || frameArg.byteLength > maximumBytesArg
6574
+ || frameArg.at(-1) !== 0x0a
6575
+ || frameArg.subarray(0, -1).some((byteArg) => byteArg === 0x0a || byteArg === 0x0d)) {
6576
+ fail('INVALID_DATA', pathArg);
6577
+ }
6578
+ const payloadBytes = new Uint8Array(frameArg.subarray(0, -1));
6579
+ let text: string;
6580
+ try {
6581
+ text = new TextDecoder('utf-8', { fatal: true }).decode(payloadBytes);
6582
+ } catch {
6583
+ return fail('INVALID_DATA', pathArg);
6584
+ }
6585
+ let value: unknown;
6586
+ try {
6587
+ value = JSON.parse(text) as unknown;
6588
+ } catch {
6589
+ return fail('INVALID_DATA', pathArg);
6590
+ }
6591
+ const normalized = normalizeArg(value);
6592
+ const canonicalFrame = encodeArg(normalized);
6593
+ if (!Buffer.from(canonicalFrame).equals(Buffer.from(frameArg))) {
6594
+ fail('INVALID_DATA', pathArg);
6595
+ }
6596
+ return normalized;
6597
+ };
6598
+
6599
+ export const decodeCloudlyLegacyDeploymentSettlementStdioRequestFrame = (
6600
+ frameArg: Uint8Array,
6601
+ ): Readonly<TCloudlyLegacyDeploymentSettlementStdioRequestV1> => decodeStdioFrame(
6602
+ frameArg,
6603
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumRequestFrameBytes,
6604
+ 'stdioRequestFrame',
6605
+ normalizeCloudlyLegacyDeploymentSettlementStdioRequest,
6606
+ encodeCloudlyLegacyDeploymentSettlementStdioRequestFrame,
6607
+ );
6608
+
6609
+ export const decodeCloudlyLegacyDeploymentSettlementStdioResponseFrame = (
6610
+ frameArg: Uint8Array,
6611
+ ): Readonly<TCloudlyLegacyDeploymentSettlementStdioResponseV1> => decodeStdioFrame(
6612
+ frameArg,
6613
+ cloudlyLegacyDeploymentSettlementStdioLimits.maximumResponseFrameBytes,
6614
+ 'stdioResponseFrame',
6615
+ normalizeCloudlyLegacyDeploymentSettlementStdioResponse,
6616
+ encodeCloudlyLegacyDeploymentSettlementStdioResponseFrame,
6617
+ );
6618
+
2885
6619
  export { cloudlyLegacyDeploymentSettlementGoldenVectors } from './runtime.cloudlylegacydeploymentsettlement.golden.js';