@mannyc1/ts-release 0.2.2 → 0.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.
Files changed (107) hide show
  1. package/ARCHITECTURE.md +60 -0
  2. package/CHANGELOG.md +82 -0
  3. package/README.md +129 -6
  4. package/SPEC.md +51 -0
  5. package/apps/release-ts/README.md +7 -0
  6. package/apps/ts-release-agents/package.json +1 -1
  7. package/apps/ts-release-agents/src/check.ts +7 -2
  8. package/apps/ts-release-agents/test/contract.test.ts +2 -2
  9. package/dist/bin/ts-release.js +154 -47
  10. package/dist/drivers/archive.d.ts +2 -1
  11. package/dist/drivers/archive.d.ts.map +1 -1
  12. package/dist/drivers/archive.js +12 -8
  13. package/dist/drivers/archive.js.map +1 -1
  14. package/dist/drivers/process.d.ts.map +1 -1
  15. package/dist/drivers/process.js +4 -4
  16. package/dist/drivers/process.js.map +1 -1
  17. package/dist/drivers/python-wheel.d.ts +21 -0
  18. package/dist/drivers/python-wheel.d.ts.map +1 -0
  19. package/dist/drivers/python-wheel.js +109 -0
  20. package/dist/drivers/python-wheel.js.map +1 -0
  21. package/dist/drivers/workspace.d.ts +3 -0
  22. package/dist/drivers/workspace.d.ts.map +1 -1
  23. package/dist/drivers/workspace.js +5 -1
  24. package/dist/drivers/workspace.js.map +1 -1
  25. package/dist/operation-journal/authority.d.ts +3 -0
  26. package/dist/operation-journal/authority.d.ts.map +1 -0
  27. package/dist/operation-journal/authority.js +147 -0
  28. package/dist/operation-journal/authority.js.map +1 -0
  29. package/dist/operation-journal/aws/deadline.d.ts +12 -0
  30. package/dist/operation-journal/aws/deadline.d.ts.map +1 -0
  31. package/dist/operation-journal/aws/deadline.js +38 -0
  32. package/dist/operation-journal/aws/deadline.js.map +1 -0
  33. package/dist/operation-journal/aws/oidc.d.ts +27 -0
  34. package/dist/operation-journal/aws/oidc.d.ts.map +1 -0
  35. package/dist/operation-journal/aws/oidc.js +361 -0
  36. package/dist/operation-journal/aws/oidc.js.map +1 -0
  37. package/dist/operation-journal/aws/policy.d.ts +42 -0
  38. package/dist/operation-journal/aws/policy.d.ts.map +1 -0
  39. package/dist/operation-journal/aws/policy.js +404 -0
  40. package/dist/operation-journal/aws/policy.js.map +1 -0
  41. package/dist/operation-journal/aws/s3-boundary.d.ts +17 -0
  42. package/dist/operation-journal/aws/s3-boundary.d.ts.map +1 -0
  43. package/dist/operation-journal/aws/s3-boundary.js +417 -0
  44. package/dist/operation-journal/aws/s3-boundary.js.map +1 -0
  45. package/dist/operation-journal/aws.d.ts +11 -0
  46. package/dist/operation-journal/aws.d.ts.map +1 -0
  47. package/dist/operation-journal/aws.js +50 -0
  48. package/dist/operation-journal/aws.js.map +1 -0
  49. package/dist/operation-journal/canonical.d.ts +52 -0
  50. package/dist/operation-journal/canonical.d.ts.map +1 -0
  51. package/dist/operation-journal/canonical.js +282 -0
  52. package/dist/operation-journal/canonical.js.map +1 -0
  53. package/dist/operation-journal/model.d.ts +251 -0
  54. package/dist/operation-journal/model.d.ts.map +1 -0
  55. package/dist/operation-journal/model.js +56 -0
  56. package/dist/operation-journal/model.js.map +1 -0
  57. package/dist/operation-journal/reducer.d.ts +28 -0
  58. package/dist/operation-journal/reducer.d.ts.map +1 -0
  59. package/dist/operation-journal/reducer.js +73 -0
  60. package/dist/operation-journal/reducer.js.map +1 -0
  61. package/dist/operation-journal/s3.d.ts +7 -0
  62. package/dist/operation-journal/s3.d.ts.map +1 -0
  63. package/dist/operation-journal/s3.js +667 -0
  64. package/dist/operation-journal/s3.js.map +1 -0
  65. package/dist/operation-journal.d.ts +14 -0
  66. package/dist/operation-journal.d.ts.map +1 -0
  67. package/dist/operation-journal.js +12 -0
  68. package/dist/operation-journal.js.map +1 -0
  69. package/dist/platform/credentials.d.ts.map +1 -1
  70. package/dist/platform/credentials.js +65 -3
  71. package/dist/platform/credentials.js.map +1 -1
  72. package/dist/publication/github.d.ts.map +1 -1
  73. package/dist/publication/github.js +66 -15
  74. package/dist/publication/github.js.map +1 -1
  75. package/dist/release/capabilities.d.ts.map +1 -1
  76. package/dist/release/capabilities.js +2 -2
  77. package/dist/release/capabilities.js.map +1 -1
  78. package/dist/release/prepare.d.ts.map +1 -1
  79. package/dist/release/prepare.js +4 -5
  80. package/dist/release/prepare.js.map +1 -1
  81. package/dist/release/prepared-store.d.ts.map +1 -1
  82. package/dist/release/prepared-store.js +11 -9
  83. package/dist/release/prepared-store.js.map +1 -1
  84. package/package.json +19 -4
  85. package/src/drivers/archive.ts +17 -8
  86. package/src/drivers/process.ts +3 -4
  87. package/src/drivers/python-wheel.ts +145 -0
  88. package/src/drivers/workspace.ts +7 -1
  89. package/src/operation-journal/authority.ts +162 -0
  90. package/src/operation-journal/aws/deadline.ts +41 -0
  91. package/src/operation-journal/aws/oidc.ts +439 -0
  92. package/src/operation-journal/aws/policy.ts +491 -0
  93. package/src/operation-journal/aws/s3-boundary.ts +562 -0
  94. package/src/operation-journal/aws.ts +60 -0
  95. package/src/operation-journal/canonical.ts +373 -0
  96. package/src/operation-journal/model.ts +301 -0
  97. package/src/operation-journal/reducer.ts +112 -0
  98. package/src/operation-journal/s3.ts +884 -0
  99. package/src/operation-journal.ts +51 -0
  100. package/src/platform/credentials.ts +71 -3
  101. package/src/publication/github.ts +83 -15
  102. package/src/release/capabilities.ts +3 -2
  103. package/src/release/prepare.ts +3 -5
  104. package/src/release/prepared-store.ts +8 -7
  105. package/templates/README.md +2 -2
  106. package/templates/github-actions/release.yml +24 -7
  107. package/templates/github-actions/reviewed-release.yml +49 -14
@@ -0,0 +1,417 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { GetRoleCommand, GetRolePolicyCommand, ListAttachedRolePoliciesCommand, ListRolePoliciesCommand } from "@aws-sdk/client-iam";
3
+ import { GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketPolicyStatusCommand, GetBucketVersioningCommand, GetObjectAttributesCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetObjectRetentionCommand, GetPublicAccessBlockCommand, ListObjectVersionsCommand, PutObjectCommand } from "@aws-sdk/client-s3";
4
+ import { GetCallerIdentityCommand } from "@aws-sdk/client-sts";
5
+ import * as Effect from "effect/Effect";
6
+ import { isCanonicalS3VersionId, objectChecksum } from "../canonical.js";
7
+ import { S3JournalBoundaryError, operationJournalByteLimits } from "../model.js";
8
+ import { operationJournalNetworkDeadlineMilliseconds, withOperationJournalNetworkDeadline } from "./deadline.js";
9
+ import { assertAwsJournalPolicyDigests, validateAwsJournalPolicies } from "./policy.js";
10
+ const error = (operation, commitment, reason) => S3JournalBoundaryError.make({ operation, commitment, reason });
11
+ const fail = (operation, reason) => {
12
+ throw error(operation, "not-applicable", reason);
13
+ };
14
+ const boundaryError = (cause, operation, reason) => cause instanceof S3JournalBoundaryError
15
+ ? cause
16
+ : error(operation, "not-applicable", reason);
17
+ const statusCode = (cause) => {
18
+ if (typeof cause !== "object" || cause === null || !("$metadata" in cause))
19
+ return undefined;
20
+ const metadata = cause.$metadata;
21
+ return typeof metadata?.httpStatusCode === "number" ? metadata.httpStatusCode : undefined;
22
+ };
23
+ const errorName = (cause) => {
24
+ if (typeof cause !== "object" || cause === null || !("name" in cause) ||
25
+ typeof cause.name !== "string")
26
+ return "UnknownError";
27
+ const name = cause.name;
28
+ return /^[A-Za-z0-9_.-]{1,128}$/u.test(name) ? name : "UnknownError";
29
+ };
30
+ const putFailure = (cause, operation) => {
31
+ if (cause instanceof S3JournalBoundaryError)
32
+ return cause;
33
+ const status = statusCode(cause);
34
+ return error(operation, status !== undefined && status >= 300 && status < 500 ? "not-committed" : "unknown", `AWS S3 conditional write did not return one admitted response (${errorName(cause)}).`);
35
+ };
36
+ const roleName = (roleArn) => roleArn.slice(roleArn.lastIndexOf("/") + 1);
37
+ const journalNamespacePattern = /^operation-journal\/v1\/[a-f0-9]{40}\/[a-f0-9]{64}\/$/u;
38
+ const journalEventKeyPattern = /^operation-journal\/v1\/[a-f0-9]{40}\/[a-f0-9]{64}\/events\/[0-9]{8}\/[a-f0-9-]{36}\.bin$/u;
39
+ const journalHeadKeyPattern = /^operation-journal\/v1\/[a-f0-9]{40}\/[a-f0-9]{64}\/head\.bin$/u;
40
+ const requireSealedInput = (input, authority, operation) => {
41
+ if (input.bucketName !== authority.bucketName ||
42
+ input.expectedBucketOwner !== authority.expectedBucketOwner ||
43
+ input.region !== authority.region) {
44
+ fail(operation, "AWS journal request coordinates escaped the sealed activation contract.");
45
+ }
46
+ };
47
+ const requireString = (value, operation, label) => {
48
+ if (value === undefined || value.length === 0)
49
+ fail(operation, `${label} is absent.`);
50
+ return value;
51
+ };
52
+ const checksumToBase64 = (checksum, operation) => {
53
+ if (!/^sha256:[a-f0-9]{64}$/u.test(checksum))
54
+ fail(operation, "Journal checksum is not canonical SHA-256.");
55
+ return Buffer.from(checksum.slice("sha256:".length), "hex").toString("base64");
56
+ };
57
+ const checksumFromBase64 = (checksum, operation) => {
58
+ if (checksum === undefined || !/^(?:[A-Za-z0-9+/]{4}){10}[A-Za-z0-9+/]{3}=$/u.test(checksum)) {
59
+ fail(operation, "AWS S3 response lacks one canonical SHA-256 checksum.");
60
+ }
61
+ const canonicalChecksum = checksum;
62
+ const bytes = Buffer.from(canonicalChecksum, "base64");
63
+ if (bytes.length !== 32 || bytes.toString("base64") !== canonicalChecksum) {
64
+ fail(operation, "AWS S3 response SHA-256 checksum is malformed.");
65
+ }
66
+ return `sha256:${bytes.toString("hex")}`;
67
+ };
68
+ export const readBoundedObjectBody = async (body, contentLength, deadlineMilliseconds = operationJournalNetworkDeadlineMilliseconds) => {
69
+ if (!Number.isSafeInteger(contentLength) || contentLength < 1 ||
70
+ contentLength > operationJournalByteLimits.object) {
71
+ fail("get-object-version", "AWS S3 exact object Content-Length exceeds the admitted byte bound.");
72
+ }
73
+ if (typeof body !== "object" || body === null ||
74
+ typeof body[Symbol.asyncIterator] !== "function") {
75
+ fail("get-object-version", "AWS S3 exact object body is not one bounded byte stream.");
76
+ }
77
+ const stream = body;
78
+ const iterator = stream[Symbol.asyncIterator]();
79
+ return withOperationJournalNetworkDeadline(async (signal) => {
80
+ const stop = () => {
81
+ try {
82
+ const destroy = body.destroy;
83
+ if (typeof destroy === "function")
84
+ destroy.call(body, signal.reason);
85
+ }
86
+ catch {
87
+ // The deadline result is authoritative; cleanup failures are not a fallback result.
88
+ }
89
+ try {
90
+ const completion = iterator.return?.();
91
+ if (completion !== undefined)
92
+ void Promise.resolve(completion).catch(() => undefined);
93
+ }
94
+ catch {
95
+ // The deadline result is authoritative; cleanup failures are not a fallback result.
96
+ }
97
+ };
98
+ signal.addEventListener("abort", stop, { once: true });
99
+ const bytes = new Uint8Array(contentLength);
100
+ let offset = 0;
101
+ try {
102
+ while (true) {
103
+ const result = await iterator.next();
104
+ if (result.done === true)
105
+ break;
106
+ const byteChunk = result.value instanceof Uint8Array
107
+ ? result.value
108
+ : fail("get-object-version", "AWS S3 exact object stream emitted a non-byte chunk.");
109
+ if (offset + byteChunk.length > bytes.length) {
110
+ fail("get-object-version", "AWS S3 exact object stream exceeded its admitted Content-Length.");
111
+ }
112
+ bytes.set(byteChunk, offset);
113
+ offset += byteChunk.length;
114
+ }
115
+ if (offset !== bytes.length) {
116
+ fail("get-object-version", "AWS S3 exact object stream length disagrees with Content-Length.");
117
+ }
118
+ return bytes;
119
+ }
120
+ finally {
121
+ signal.removeEventListener("abort", stop);
122
+ }
123
+ }, deadlineMilliseconds);
124
+ };
125
+ const makePolicyCoordinates = (options) => ({
126
+ accountId: options.authority.accountId,
127
+ bucketArn: options.authority.bucketArn,
128
+ roleArn: options.authority.roleArn,
129
+ rolePolicyName: options.rolePolicyName,
130
+ oidcTrust: options.authority.oidcTrust
131
+ });
132
+ const observeAuthority = (options, session, clients, deadlineMilliseconds) => Effect.tryPromise({
133
+ try: async () => {
134
+ const authority = options.authority;
135
+ if (!/^[A-Za-z0-9+=,.@_-]{1,128}$/u.test(options.rolePolicyName)) {
136
+ fail("observe-authority", "Journal inline role policy name is not canonical.");
137
+ }
138
+ const name = roleName(authority.roleArn);
139
+ const [roleResponse, inlineResponse, attachedResponse, versioningResponse, lockResponse, ownershipResponse, publicAccessResponse, bucketPolicyResponse, bucketPolicyStatusResponse, callerIdentityResponse] = await Promise.all([
140
+ withOperationJournalNetworkDeadline((signal) => clients.iam.send(new GetRoleCommand({ RoleName: name }), { abortSignal: signal }), deadlineMilliseconds),
141
+ withOperationJournalNetworkDeadline((signal) => clients.iam.send(new ListRolePoliciesCommand({ RoleName: name, MaxItems: 2 }), { abortSignal: signal }), deadlineMilliseconds),
142
+ withOperationJournalNetworkDeadline((signal) => clients.iam.send(new ListAttachedRolePoliciesCommand({ RoleName: name, MaxItems: 1 }), { abortSignal: signal }), deadlineMilliseconds),
143
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetBucketVersioningCommand({
144
+ Bucket: authority.bucketName,
145
+ ExpectedBucketOwner: authority.expectedBucketOwner
146
+ }), { abortSignal: signal }), deadlineMilliseconds),
147
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetObjectLockConfigurationCommand({
148
+ Bucket: authority.bucketName,
149
+ ExpectedBucketOwner: authority.expectedBucketOwner
150
+ }), { abortSignal: signal }), deadlineMilliseconds),
151
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetBucketOwnershipControlsCommand({
152
+ Bucket: authority.bucketName,
153
+ ExpectedBucketOwner: authority.expectedBucketOwner
154
+ }), { abortSignal: signal }), deadlineMilliseconds),
155
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetPublicAccessBlockCommand({
156
+ Bucket: authority.bucketName,
157
+ ExpectedBucketOwner: authority.expectedBucketOwner
158
+ }), { abortSignal: signal }), deadlineMilliseconds),
159
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetBucketPolicyCommand({
160
+ Bucket: authority.bucketName,
161
+ ExpectedBucketOwner: authority.expectedBucketOwner
162
+ }), { abortSignal: signal }), deadlineMilliseconds),
163
+ withOperationJournalNetworkDeadline((signal) => clients.s3.send(new GetBucketPolicyStatusCommand({
164
+ Bucket: authority.bucketName,
165
+ ExpectedBucketOwner: authority.expectedBucketOwner
166
+ }), { abortSignal: signal }), deadlineMilliseconds),
167
+ withOperationJournalNetworkDeadline((signal) => clients.sts.send(new GetCallerIdentityCommand({}), { abortSignal: signal }), deadlineMilliseconds)
168
+ ]);
169
+ const role = roleResponse.Role;
170
+ if (role?.Arn !== authority.roleArn || role.RoleName !== name ||
171
+ role.AssumeRolePolicyDocument === undefined || role.PermissionsBoundary !== undefined ||
172
+ role.MaxSessionDuration === undefined || role.MaxSessionDuration < 900) {
173
+ fail("observe-authority", "AWS journal role identity or session governance drifted.");
174
+ }
175
+ if (inlineResponse.IsTruncated === true || inlineResponse.PolicyNames?.length !== 1 ||
176
+ inlineResponse.PolicyNames[0] !== options.rolePolicyName ||
177
+ attachedResponse.IsTruncated === true || (attachedResponse.AttachedPolicies?.length ?? 0) !== 0) {
178
+ fail("observe-authority", "AWS journal role does not contain exactly one inline policy and zero managed policies.");
179
+ }
180
+ const rolePolicyResponse = await withOperationJournalNetworkDeadline((signal) => clients.iam.send(new GetRolePolicyCommand({
181
+ RoleName: name,
182
+ PolicyName: options.rolePolicyName
183
+ }), { abortSignal: signal }), deadlineMilliseconds);
184
+ if (rolePolicyResponse.RoleName !== name || rolePolicyResponse.PolicyName !== options.rolePolicyName ||
185
+ rolePolicyResponse.PolicyDocument === undefined) {
186
+ fail("observe-authority", "AWS journal inline role policy response is incomplete.");
187
+ }
188
+ if (versioningResponse.Status !== "Enabled") {
189
+ fail("observe-authority", "AWS journal bucket versioning is not enabled.");
190
+ }
191
+ const retention = lockResponse.ObjectLockConfiguration?.Rule?.DefaultRetention;
192
+ if (lockResponse.ObjectLockConfiguration?.ObjectLockEnabled !== "Enabled" ||
193
+ retention?.Mode !== "COMPLIANCE" || retention.Years !== 10 || retention.Days !== undefined) {
194
+ fail("observe-authority", "AWS journal bucket Object Lock is not ten-year COMPLIANCE retention.");
195
+ }
196
+ const ownershipRules = ownershipResponse.OwnershipControls?.Rules;
197
+ if (ownershipRules?.length !== 1 || ownershipRules[0]?.ObjectOwnership !== "BucketOwnerEnforced") {
198
+ fail("observe-authority", "AWS journal bucket ownership is not BucketOwnerEnforced.");
199
+ }
200
+ const publicBlock = publicAccessResponse.PublicAccessBlockConfiguration;
201
+ if (publicBlock?.BlockPublicAcls !== true || publicBlock.IgnorePublicAcls !== true ||
202
+ publicBlock.BlockPublicPolicy !== true || publicBlock.RestrictPublicBuckets !== true ||
203
+ bucketPolicyStatusResponse.PolicyStatus?.IsPublic !== false) {
204
+ fail("observe-authority", "AWS journal bucket public access is not completely blocked.");
205
+ }
206
+ if (callerIdentityResponse.Account !== authority.accountId ||
207
+ callerIdentityResponse.Arn !== session.callerArn ||
208
+ callerIdentityResponse.UserId === undefined || callerIdentityResponse.UserId.length === 0) {
209
+ fail("observe-authority", "AWS STS caller identity drifted from the exact journal role session.");
210
+ }
211
+ const policyDigests = validateAwsJournalPolicies({
212
+ coordinates: makePolicyCoordinates(options),
213
+ trustPolicyDocument: role.AssumeRolePolicyDocument,
214
+ rolePolicyDocument: rolePolicyResponse.PolicyDocument,
215
+ bucketPolicyDocument: requireString(bucketPolicyResponse.Policy, "observe-authority", "AWS journal bucket policy")
216
+ });
217
+ assertAwsJournalPolicyDigests(authority, policyDigests);
218
+ const oidcTrust = {
219
+ audience: session.oidc.audience,
220
+ subject: session.oidc.subject,
221
+ repository: session.oidc.repository,
222
+ repositoryId: session.oidc.repositoryId,
223
+ repositoryOwnerId: session.oidc.repositoryOwnerId,
224
+ workflow: session.oidc.workflow,
225
+ ref: session.oidc.ref,
226
+ environment: session.oidc.environment,
227
+ jobWorkflowRef: session.oidc.jobWorkflowRef
228
+ };
229
+ return {
230
+ accountId: authority.accountId,
231
+ bucketName: authority.bucketName,
232
+ bucketArn: authority.bucketArn,
233
+ region: authority.region,
234
+ roleArn: authority.roleArn,
235
+ prefix: "operation-journal/v1",
236
+ expectedBucketOwner: authority.expectedBucketOwner,
237
+ versioning: "Enabled",
238
+ objectLock: "Enabled",
239
+ retentionMode: "COMPLIANCE",
240
+ retentionYears: 10,
241
+ bucketOwnerEnforced: true,
242
+ publicAccessBlocked: true,
243
+ deleteDenied: true,
244
+ multipartDenied: true,
245
+ conditionalWritesEnforced: true,
246
+ ...policyDigests,
247
+ oidc: session.oidc,
248
+ oidcTrust
249
+ };
250
+ },
251
+ catch: (cause) => boundaryError(cause, "observe-authority", "AWS journal authority observation failed.")
252
+ });
253
+ const listNamespace = (options, client, input, deadlineMilliseconds) => Effect.tryPromise({
254
+ try: async () => {
255
+ requireSealedInput(input, options.authority, "list-namespace");
256
+ if (!journalNamespacePattern.test(input.prefix) || input.maximum !== 512) {
257
+ fail("list-namespace", "AWS journal namespace read escaped its exact bound.");
258
+ }
259
+ const response = await withOperationJournalNetworkDeadline((signal) => client.send(new ListObjectVersionsCommand({
260
+ Bucket: input.bucketName,
261
+ Prefix: input.prefix,
262
+ MaxKeys: input.maximum,
263
+ ExpectedBucketOwner: input.expectedBucketOwner
264
+ }), { abortSignal: signal }), deadlineMilliseconds);
265
+ if (response.Name !== input.bucketName || response.Prefix !== input.prefix ||
266
+ response.MaxKeys !== input.maximum || typeof response.IsTruncated !== "boolean") {
267
+ fail("list-namespace", "AWS S3 version listing identity or bound drifted from the exact request.");
268
+ }
269
+ if ((response.Versions?.length ?? 0) + (response.DeleteMarkers?.length ?? 0) > input.maximum) {
270
+ fail("list-namespace", "AWS S3 version listing exceeded its exact response bound.");
271
+ }
272
+ const versions = (response.Versions ?? []).map((version, index) => {
273
+ const key = requireString(version.Key, "list-namespace", `AWS S3 version ${index} key`);
274
+ const versionId = requireString(version.VersionId, "list-namespace", `AWS S3 version ${index} VersionId`);
275
+ const etag = requireString(version.ETag, "list-namespace", `AWS S3 version ${index} ETag`);
276
+ if ((!journalEventKeyPattern.test(key) && !journalHeadKeyPattern.test(key)) ||
277
+ !isCanonicalS3VersionId(versionId) || !/^"[!#-~]{1,1024}"$/u.test(etag)) {
278
+ fail("list-namespace", `AWS S3 version ${index} identity is not canonical.`);
279
+ }
280
+ return { key, versionId, etag, isLatest: version.IsLatest === true };
281
+ });
282
+ const deleteMarkers = (response.DeleteMarkers ?? []).map((marker, index) => {
283
+ const key = requireString(marker.Key, "list-namespace", `AWS S3 delete marker ${index} key`);
284
+ const versionId = requireString(marker.VersionId, "list-namespace", `AWS S3 delete marker ${index} VersionId`);
285
+ if ((!journalEventKeyPattern.test(key) && !journalHeadKeyPattern.test(key)) ||
286
+ !isCanonicalS3VersionId(versionId)) {
287
+ fail("list-namespace", `AWS S3 delete marker ${index} identity is not canonical.`);
288
+ }
289
+ return { key, versionId };
290
+ });
291
+ if (versions.some((version) => !version.key.startsWith(input.prefix)) ||
292
+ deleteMarkers.some((marker) => !marker.key.startsWith(input.prefix))) {
293
+ fail("list-namespace", "AWS S3 returned an object outside the exact journal prefix.");
294
+ }
295
+ return { versions, deleteMarkers, truncated: response.IsTruncated === true };
296
+ },
297
+ catch: (cause) => boundaryError(cause, "list-namespace", `AWS S3 journal namespace read failed (${errorName(cause)}).`)
298
+ });
299
+ const getObjectVersion = (options, client, input, deadlineMilliseconds) => Effect.tryPromise({
300
+ try: async () => {
301
+ requireSealedInput(input, options.authority, "get-object-version");
302
+ if ((!journalEventKeyPattern.test(input.key) && !journalHeadKeyPattern.test(input.key)) ||
303
+ !isCanonicalS3VersionId(input.versionId)) {
304
+ fail("get-object-version", "AWS journal exact-version read escaped its sealed namespace.");
305
+ }
306
+ const response = await withOperationJournalNetworkDeadline((signal) => client.send(new GetObjectCommand({
307
+ Bucket: input.bucketName,
308
+ Key: input.key,
309
+ VersionId: input.versionId,
310
+ ExpectedBucketOwner: input.expectedBucketOwner,
311
+ ChecksumMode: "ENABLED"
312
+ }), { abortSignal: signal }), deadlineMilliseconds);
313
+ if (response.Body === undefined || response.ContentLength === undefined || response.LastModified === undefined ||
314
+ response.ObjectLockMode !== "COMPLIANCE" || response.ObjectLockRetainUntilDate === undefined ||
315
+ (response.ChecksumType !== undefined && response.ChecksumType !== "FULL_OBJECT")) {
316
+ fail("get-object-version", "AWS S3 exact object response lacks bytes, time, checksum, or COMPLIANCE retention.");
317
+ }
318
+ const retainUntil = response.ObjectLockRetainUntilDate;
319
+ const body = response.Body;
320
+ const lastModified = response.LastModified;
321
+ const retention = await withOperationJournalNetworkDeadline((signal) => client.send(new GetObjectRetentionCommand({
322
+ Bucket: input.bucketName,
323
+ Key: input.key,
324
+ VersionId: input.versionId,
325
+ ExpectedBucketOwner: input.expectedBucketOwner
326
+ }), { abortSignal: signal }), deadlineMilliseconds);
327
+ if (retention.Retention?.Mode !== "COMPLIANCE" || retention.Retention.RetainUntilDate === undefined ||
328
+ retention.Retention.RetainUntilDate.getTime() !== retainUntil.getTime()) {
329
+ fail("get-object-version", "AWS S3 exact object retention disagrees with its independent retention read.");
330
+ }
331
+ const bytes = await readBoundedObjectBody(body, response.ContentLength, deadlineMilliseconds);
332
+ const attributes = await withOperationJournalNetworkDeadline((signal) => client.send(new GetObjectAttributesCommand({
333
+ Bucket: input.bucketName,
334
+ Key: input.key,
335
+ VersionId: input.versionId,
336
+ ExpectedBucketOwner: input.expectedBucketOwner,
337
+ ObjectAttributes: ["Checksum", "ETag", "ObjectSize"]
338
+ }), { abortSignal: signal }), deadlineMilliseconds);
339
+ const responseVersionId = requireString(response.VersionId, "get-object-version", "AWS S3 exact object VersionId");
340
+ const checksumSha256 = checksumFromBase64(response.ChecksumSHA256, "get-object-version");
341
+ if (responseVersionId !== input.versionId || attributes.DeleteMarker === true || attributes.VersionId !== input.versionId ||
342
+ attributes.ETag !== response.ETag || attributes.ObjectSize !== bytes.length ||
343
+ attributes.Checksum?.ChecksumType !== "FULL_OBJECT" ||
344
+ checksumFromBase64(attributes.Checksum.ChecksumSHA256, "get-object-version") !== checksumSha256) {
345
+ fail("get-object-version", "AWS S3 exact object attributes disagree with its retained bytes and version.");
346
+ }
347
+ return {
348
+ key: input.key,
349
+ versionId: responseVersionId,
350
+ etag: requireString(response.ETag, "get-object-version", "AWS S3 exact object ETag"),
351
+ checksumSha256,
352
+ bytes,
353
+ lastModified: lastModified.toISOString(),
354
+ retentionMode: "COMPLIANCE",
355
+ retainUntil: retainUntil.toISOString()
356
+ };
357
+ },
358
+ catch: (cause) => boundaryError(cause, "get-object-version", `AWS S3 exact journal object read failed (${errorName(cause)}).`)
359
+ });
360
+ const putObject = (options, client, input, operation, deadlineMilliseconds) => Effect.tryPromise({
361
+ try: async () => {
362
+ requireSealedInput(input, options.authority, operation);
363
+ if (operation === "put-event" ? !journalEventKeyPattern.test(input.key) : !journalHeadKeyPattern.test(input.key)) {
364
+ fail(operation, "AWS S3 conditional write key is outside its exact journal object class.");
365
+ }
366
+ if (!(input.bytes instanceof Uint8Array) || input.bytes.length < 1 ||
367
+ input.bytes.length > operationJournalByteLimits.object) {
368
+ fail(operation, "AWS S3 conditional write bytes exceed the admitted object bound.");
369
+ }
370
+ if (objectChecksum(input.bytes) !== input.checksumSha256) {
371
+ fail(operation, "AWS S3 conditional write checksum does not match its exact bytes.");
372
+ }
373
+ if (input.condition._tag === "IfMatch" && !/^"[!#-~]{1,1024}"$/u.test(input.condition.etag)) {
374
+ fail(operation, "AWS S3 If-Match ETag is not canonical.");
375
+ }
376
+ const checksum = checksumToBase64(input.checksumSha256, operation);
377
+ let response;
378
+ try {
379
+ response = await withOperationJournalNetworkDeadline((signal) => client.send(new PutObjectCommand({
380
+ Bucket: input.bucketName,
381
+ Key: input.key,
382
+ Body: new Uint8Array(input.bytes),
383
+ ContentLength: input.bytes.length,
384
+ ContentType: "application/octet-stream",
385
+ ChecksumAlgorithm: "SHA256",
386
+ ChecksumSHA256: checksum,
387
+ ExpectedBucketOwner: input.expectedBucketOwner,
388
+ ...(input.condition._tag === "IfNoneMatch"
389
+ ? { IfNoneMatch: "*" }
390
+ : { IfMatch: input.condition.etag })
391
+ }), { abortSignal: signal }), deadlineMilliseconds);
392
+ }
393
+ catch (cause) {
394
+ const status = statusCode(cause);
395
+ if (status === 409 || status === 412)
396
+ return { _tag: "PreconditionFailed" };
397
+ throw cause;
398
+ }
399
+ const versionId = requireString(response.VersionId, operation, "AWS S3 committed object VersionId");
400
+ const etag = requireString(response.ETag, operation, "AWS S3 committed object ETag");
401
+ const responseChecksum = checksumFromBase64(response.ChecksumSHA256, operation);
402
+ if (responseChecksum !== input.checksumSha256 ||
403
+ (response.ChecksumType !== undefined && response.ChecksumType !== "FULL_OBJECT")) {
404
+ fail(operation, "AWS S3 committed object checksum disagrees with the exact request bytes.");
405
+ }
406
+ return { _tag: "Committed", versionId, etag, checksumSha256: responseChecksum };
407
+ },
408
+ catch: (cause) => putFailure(cause, operation)
409
+ });
410
+ export const makeAwsS3JournalBoundaryFromClients = (options, session, clients, deadlineMilliseconds = operationJournalNetworkDeadlineMilliseconds) => ({
411
+ observeAuthority: () => observeAuthority(options, session, clients, deadlineMilliseconds),
412
+ listNamespace: (input) => listNamespace(options, clients.s3, input, deadlineMilliseconds),
413
+ getObjectVersion: (input) => getObjectVersion(options, clients.s3, input, deadlineMilliseconds),
414
+ putEvent: (input) => putObject(options, clients.s3, input, "put-event", deadlineMilliseconds),
415
+ putHead: (input) => putObject(options, clients.s3, input, "put-head", deadlineMilliseconds)
416
+ });
417
+ //# sourceMappingURL=s3-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-boundary.js","sourceRoot":"","sources":["../../../src/operation-journal/aws/s3-boundary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { S3JournalBoundaryError, type S3JournalBoundaryShape } from "./model.js";
3
+ import { type AwsS3JournalBoundaryOptions } from "./aws/s3-boundary.js";
4
+ /**
5
+ * Acquire one fresh GitHub OIDC/STS session and seal an AWS S3 boundary around
6
+ * the exact activation contract. The constructor never consults the AWS
7
+ * credential chain and exposes no endpoint, profile, or credential override.
8
+ */
9
+ export declare const makeAwsS3JournalBoundary: (options: AwsS3JournalBoundaryOptions) => Effect.Effect<S3JournalBoundaryShape, S3JournalBoundaryError>;
10
+ export type { AwsS3JournalBoundaryOptions } from "./aws/s3-boundary.js";
11
+ //# sourceMappingURL=aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../../src/operation-journal/aws.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,YAAY,CAAA;AAGnB,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,sBAAsB,CAAA;AAE7B;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,2BAA2B,KACnC,MAAM,CAAC,MAAM,CAAC,sBAAsB,EAAE,sBAAsB,CAmC7D,CAAA;AAEF,YAAY,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,50 @@
1
+ import { IAMClient } from "@aws-sdk/client-iam";
2
+ import { S3Client } from "@aws-sdk/client-s3";
3
+ import { STSClient } from "@aws-sdk/client-sts";
4
+ import * as Effect from "effect/Effect";
5
+ import { S3JournalBoundaryError } from "./model.js";
6
+ import { validateS3JournalAuthority } from "./authority.js";
7
+ import { acquireAwsJournalSession } from "./aws/oidc.js";
8
+ import { makeAwsS3JournalBoundaryFromClients } from "./aws/s3-boundary.js";
9
+ /**
10
+ * Acquire one fresh GitHub OIDC/STS session and seal an AWS S3 boundary around
11
+ * the exact activation contract. The constructor never consults the AWS
12
+ * credential chain and exposes no endpoint, profile, or credential override.
13
+ */
14
+ export const makeAwsS3JournalBoundary = (options) => Effect.gen(function* () {
15
+ yield* Effect.try({
16
+ try: () => {
17
+ validateS3JournalAuthority(options.authority);
18
+ if (!/^[A-Za-z0-9+=,.@_-]{1,128}$/u.test(options.rolePolicyName)) {
19
+ throw new Error("invalid role policy name");
20
+ }
21
+ },
22
+ catch: () => S3JournalBoundaryError.make({
23
+ operation: "observe-authority",
24
+ commitment: "not-applicable",
25
+ reason: "AWS journal activation contract is malformed."
26
+ })
27
+ });
28
+ const session = yield* acquireAwsJournalSession(options.authority);
29
+ const credentials = session.credentials;
30
+ const iam = new IAMClient({
31
+ region: options.authority.region,
32
+ credentials,
33
+ maxAttempts: 1
34
+ });
35
+ const s3 = new S3Client({
36
+ region: options.authority.region,
37
+ credentials,
38
+ maxAttempts: 1,
39
+ followRegionRedirects: false,
40
+ forcePathStyle: false,
41
+ useArnRegion: false
42
+ });
43
+ const sts = new STSClient({
44
+ region: options.authority.region,
45
+ credentials,
46
+ maxAttempts: 1
47
+ });
48
+ return makeAwsS3JournalBoundaryFromClients(options, session, { iam, s3, sts });
49
+ });
50
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../../src/operation-journal/aws.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EACL,sBAAsB,EAEvB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EACL,mCAAmC,EAEpC,MAAM,sBAAsB,CAAA;AAE7B;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,OAAoC,EAC2B,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACtF,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;QAChB,GAAG,EAAE,GAAG,EAAE;YACR,0BAA0B,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC7C,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBACjE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,IAAI,CAAC;YACvC,SAAS,EAAE,mBAAmB;YAC9B,UAAU,EAAE,gBAAgB;YAC5B,MAAM,EAAE,+CAA+C;SACxD,CAAC;KACH,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAClE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;IACvC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC;QACxB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM;QAChC,WAAW;QACX,WAAW,EAAE,CAAC;KACf,CAAC,CAAA;IACF,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC;QACtB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM;QAChC,WAAW;QACX,WAAW,EAAE,CAAC;QACd,qBAAqB,EAAE,KAAK;QAC5B,cAAc,EAAE,KAAK;QACrB,YAAY,EAAE,KAAK;KACpB,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC;QACxB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM;QAChC,WAAW;QACX,WAAW,EAAE,CAAC;KACf,CAAC,CAAA;IACF,OAAO,mCAAmC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;AAChF,CAAC,CAAC,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { type JournalOperation, type JournalRecord, type JournalRecordTag, type JournalWorkflowCoordinate } from "./model.js";
2
+ export declare const isCanonicalS3VersionId: (value: string) => boolean;
3
+ export interface CanonicalJournalRecord {
4
+ readonly tag: JournalRecordTag;
5
+ readonly codecId: string;
6
+ readonly payloadBase64: string;
7
+ readonly payloadDigest: string;
8
+ }
9
+ export interface CanonicalJournalPredecessor {
10
+ readonly eventDigest: string;
11
+ readonly headVersionId: string;
12
+ readonly headEtag: string;
13
+ }
14
+ export interface CanonicalJournalEvent extends JournalOperation {
15
+ readonly schemaVersion: "ts-release-operation-journal-event/v1";
16
+ readonly sequence: number;
17
+ readonly transactionId: string;
18
+ readonly previous: CanonicalJournalPredecessor | null;
19
+ readonly workflow: JournalWorkflowCoordinate;
20
+ readonly record: CanonicalJournalRecord;
21
+ }
22
+ export interface CanonicalJournalHead extends JournalOperation {
23
+ readonly schemaVersion: "ts-release-operation-journal-head/v1";
24
+ readonly sequence: number;
25
+ readonly transactionId: string;
26
+ readonly eventKey: string;
27
+ readonly eventVersionId: string;
28
+ readonly eventChecksumSha256: string;
29
+ readonly eventDigest: string;
30
+ readonly previousHeadVersionId: string | null;
31
+ readonly previousHeadEtag: string | null;
32
+ }
33
+ export declare const validateJournalOperation: (operation: JournalOperation) => JournalOperation;
34
+ export declare const validateJournalWorkflow: (workflow: JournalWorkflowCoordinate) => JournalWorkflowCoordinate;
35
+ export declare const validateTransactionId: (transactionId: string) => string;
36
+ export declare const deriveOperationKey: (canonicalOperationIdentity: Uint8Array) => string;
37
+ export declare const journalNamespace: (operation: JournalOperation, prefix?: string) => string;
38
+ export declare const journalHeadKey: (operation: JournalOperation) => string;
39
+ export declare const journalEventKey: (operation: JournalOperation, sequence: number, transactionId: string) => string;
40
+ export declare const makeCanonicalJournalRecord: (input: {
41
+ readonly tag: JournalRecordTag;
42
+ readonly codecId: string;
43
+ readonly payload: Uint8Array;
44
+ }) => CanonicalJournalRecord;
45
+ export declare const encodeJournalEvent: (event: CanonicalJournalEvent) => Uint8Array;
46
+ export declare const encodeJournalHead: (head: CanonicalJournalHead) => Uint8Array;
47
+ export declare const decodeJournalEvent: (bytes: Uint8Array) => CanonicalJournalEvent;
48
+ export declare const decodeJournalHead: (bytes: Uint8Array) => CanonicalJournalHead;
49
+ export declare const eventDigest: (bytes: Uint8Array) => string;
50
+ export declare const objectChecksum: (bytes: Uint8Array) => string;
51
+ export declare const journalRecordFromEvent: (event: CanonicalJournalEvent) => JournalRecord;
52
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/operation-journal/canonical.ts"],"names":[],"mappings":"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"}