@ship.zone/ci-spec 2.0.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 (116) hide show
  1. package/.smartconfig.json +46 -0
  2. package/changelog.md +190 -0
  3. package/conformance/archive-cases.json +446 -0
  4. package/conformance/ci-actions/compile-invalid/build-arg-secret-collision.yml +31 -0
  5. package/conformance/ci-actions/compile-invalid/candidate-without-needs.yml +36 -0
  6. package/conformance/ci-actions/compile-invalid/needs-wider-triggers.yml +42 -0
  7. package/conformance/ci-actions/compile-invalid/npm-read-registry-not-allowlisted.yml +34 -0
  8. package/conformance/ci-actions/compile-invalid/publish-job-excludes-tag.yml +57 -0
  9. package/conformance/ci-actions/compile-invalid/shared-memory-above-memory.yml +28 -0
  10. package/conformance/ci-actions/compile-invalid/trigger-kind-without-job.yml +30 -0
  11. package/conformance/ci-actions/invalid/alias-affix-invalid.yml +33 -0
  12. package/conformance/ci-actions/invalid/alias.yml +32 -0
  13. package/conformance/ci-actions/invalid/bridge-network.yml +27 -0
  14. package/conformance/ci-actions/invalid/build-darwin-platform.yml +24 -0
  15. package/conformance/ci-actions/invalid/build-with-steps.yml +27 -0
  16. package/conformance/ci-actions/invalid/concurrency-empty-group.yml +28 -0
  17. package/conformance/ci-actions/invalid/concurrency-without-cancel-in-progress.yml +27 -0
  18. package/conformance/ci-actions/invalid/container-job-build-profile.yml +25 -0
  19. package/conformance/ci-actions/invalid/custom-tag.txt +23 -0
  20. package/conformance/ci-actions/invalid/duplicate-key.txt +24 -0
  21. package/conformance/ci-actions/invalid/egress-bare-wildcard.yml +29 -0
  22. package/conformance/ci-actions/invalid/egress-empty-allowlist.yml +28 -0
  23. package/conformance/ci-actions/invalid/egress-ip-literal.yml +29 -0
  24. package/conformance/ci-actions/invalid/egress-single-label-wildcard.yml +29 -0
  25. package/conformance/ci-actions/invalid/job-publish-permission.yml +28 -0
  26. package/conformance/ci-actions/invalid/job-trigger-undeclared-kind.yml +27 -0
  27. package/conformance/ci-actions/invalid/literal-alias-affix.yml +33 -0
  28. package/conformance/ci-actions/invalid/missing-spec.yml +24 -0
  29. package/conformance/ci-actions/invalid/multiple-documents.yml +25 -0
  30. package/conformance/ci-actions/invalid/npm-read-invalid-scope.yml +33 -0
  31. package/conformance/ci-actions/invalid/oci-darwin-platform.yml +25 -0
  32. package/conformance/ci-actions/invalid/permission-without-publication.yml +31 -0
  33. package/conformance/ci-actions/invalid/publish-order-duplicate.yml +50 -0
  34. package/conformance/ci-actions/invalid/publish-order-missing-kind.yml +48 -0
  35. package/conformance/ci-actions/invalid/publish-order-undeclared-kind.yml +45 -0
  36. package/conformance/ci-actions/invalid/publish-without-permission.yml +31 -0
  37. package/conformance/ci-actions/invalid/publish-without-tag-trigger.yml +31 -0
  38. package/conformance/ci-actions/invalid/release-notes-without-assets.yml +46 -0
  39. package/conformance/ci-actions/invalid/reserved-label-prefix.yml +25 -0
  40. package/conformance/ci-actions/invalid/reserved-label.yml +25 -0
  41. package/conformance/ci-actions/invalid/retention-above-maximum.yml +83 -0
  42. package/conformance/ci-actions/invalid/retention-below-minimum.yml +83 -0
  43. package/conformance/ci-actions/invalid/schema-version-field.yml +26 -0
  44. package/conformance/ci-actions/invalid/shared-memory-below-minimum.yml +28 -0
  45. package/conformance/ci-actions/invalid/shell-string.yml +21 -0
  46. package/conformance/ci-actions/invalid/spec-number.yml +25 -0
  47. package/conformance/ci-actions/invalid/spec-prerelease.yml +25 -0
  48. package/conformance/ci-actions/invalid/spec-range.yml +25 -0
  49. package/conformance/ci-actions/invalid/timeout-above-maximum.yml +26 -0
  50. package/conformance/ci-actions/invalid/timeout-below-minimum.yml +26 -0
  51. package/conformance/ci-actions/invalid/unknown-alias-kind.yml +31 -0
  52. package/conformance/ci-actions/invalid/unknown-key.yml +24 -0
  53. package/conformance/ci-actions/invalid/vm-darwin-candidate.yml +38 -0
  54. package/conformance/ci-actions/invalid/vm-darwin-shared-memory.yml +28 -0
  55. package/conformance/ci-actions/invalid/vm-oci-execution.yml +25 -0
  56. package/conformance/ci-actions/invalid/vm-unsupported-platform.yml +25 -0
  57. package/conformance/ci-actions/invalid/vm-without-platform.yml +24 -0
  58. package/conformance/ci-actions/valid/concurrency.yml +83 -0
  59. package/conformance/ci-actions/valid/egress.yml +40 -0
  60. package/conformance/ci-actions/valid/image-build.yml +80 -0
  61. package/conformance/ci-actions/valid/matrix.yml +45 -0
  62. package/conformance/ci-actions/valid/minimal.yml +25 -0
  63. package/conformance/ci-actions/valid/npm-read.yml +60 -0
  64. package/conformance/ci-actions/valid/release-assets.yml +114 -0
  65. package/conformance/ci-actions/valid/release-signing.yml +71 -0
  66. package/conformance/ci-actions/valid/release.yml +109 -0
  67. package/conformance/ci-actions/valid/resources.yml +79 -0
  68. package/conformance/ci-actions/valid/vm.yml +77 -0
  69. package/conformance/compile-cases.json +5885 -0
  70. package/conformance/compile-cases.schema.json +766 -0
  71. package/conformance/digest-cases.json +144 -0
  72. package/conformance/runner-cases.json +1238 -0
  73. package/conformance/runner-jobs/invalid/bridge-network.json +70 -0
  74. package/conformance/runner-jobs/invalid/build-darwin-platform.json +100 -0
  75. package/conformance/runner-jobs/invalid/build-with-steps.json +111 -0
  76. package/conformance/runner-jobs/invalid/build-without-microvm.json +100 -0
  77. package/conformance/runner-jobs/invalid/egress-empty-allowlist.json +71 -0
  78. package/conformance/runner-jobs/invalid/mutable-image.json +70 -0
  79. package/conformance/runner-jobs/invalid/npm-read-reserved-environment.json +82 -0
  80. package/conformance/runner-jobs/invalid/oci-darwin-platform.json +71 -0
  81. package/conformance/runner-jobs/invalid/push-permission-container.json +70 -0
  82. package/conformance/runner-jobs/invalid/shared-memory-below-minimum.json +71 -0
  83. package/conformance/runner-jobs/invalid/timeout-missing.json +69 -0
  84. package/conformance/runner-jobs/invalid/vm-without-microvm.json +82 -0
  85. package/conformance/runner-jobs/valid/candidate-test.json +72 -0
  86. package/conformance/runner-jobs/valid/egress.json +80 -0
  87. package/conformance/runner-jobs/valid/image-build.json +100 -0
  88. package/conformance/runner-jobs/valid/minimal.json +70 -0
  89. package/conformance/runner-jobs/valid/npm-read.json +81 -0
  90. package/conformance/runner-jobs/valid/resources.json +71 -0
  91. package/conformance/runner-jobs/valid/timeout-retention-defaults.json +91 -0
  92. package/conformance/runner-jobs/valid/vm-darwin.json +70 -0
  93. package/conformance/runner-jobs/valid/vm.json +82 -0
  94. package/conformance/runner-messages.json +2035 -0
  95. package/conformance/version-cases.json +125 -0
  96. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  97. package/dist_ts/00_commitinfo_data.js +9 -0
  98. package/dist_ts/constants.d.ts +199 -0
  99. package/dist_ts/constants.js +106 -0
  100. package/dist_ts/index.d.ts +1 -0
  101. package/dist_ts/index.js +2 -0
  102. package/dist_ts/plugins.d.ts +1 -0
  103. package/dist_ts/plugins.js +3 -0
  104. package/examples/ci_actions.yml +64 -0
  105. package/license.md +21 -0
  106. package/package.json +72 -0
  107. package/readme.md +146 -0
  108. package/schemas/ci_actions.schema.json +1664 -0
  109. package/schemas/runner-job.schema.json +1172 -0
  110. package/spec/ci-actions.md +433 -0
  111. package/spec/runner-protocol.md +378 -0
  112. package/spec/runner.openapi.json +2182 -0
  113. package/ts/00_commitinfo_data.ts +8 -0
  114. package/ts/constants.ts +112 -0
  115. package/ts/index.ts +1 -0
  116. package/ts/plugins.ts +1 -0
@@ -0,0 +1,2182 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "ship.zone CI Runner Protocol",
5
+ "version": "2.0.0",
6
+ "description": "Language-neutral, outbound runner protocol of @ship.zone/ci-spec. info.version is the specification version this description is written against. This draft is incompatible with the legacy internal runner protocol it replaces.",
7
+ "license": {
8
+ "name": "MIT",
9
+ "identifier": "MIT"
10
+ }
11
+ },
12
+ "tags": [
13
+ {
14
+ "name": "Discovery"
15
+ },
16
+ {
17
+ "name": "Runner lifecycle"
18
+ },
19
+ {
20
+ "name": "Job lifecycle"
21
+ },
22
+ {
23
+ "name": "Transfers"
24
+ }
25
+ ],
26
+ "paths": {
27
+ "/api/runner": {
28
+ "get": {
29
+ "tags": ["Discovery"],
30
+ "operationId": "getRunnerProtocol",
31
+ "security": [],
32
+ "responses": {
33
+ "200": {
34
+ "description": "Runner protocol discovery",
35
+ "content": {
36
+ "application/json": {
37
+ "schema": {
38
+ "$ref": "#/components/schemas/DiscoveryResponse"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ },
46
+ "/api/runner/runners/register": {
47
+ "post": {
48
+ "tags": ["Runner lifecycle"],
49
+ "operationId": "registerRunner",
50
+ "security": [
51
+ {
52
+ "bootstrapBearer": []
53
+ }
54
+ ],
55
+ "requestBody": {
56
+ "required": true,
57
+ "content": {
58
+ "application/json": {
59
+ "schema": {
60
+ "$ref": "#/components/schemas/RegisterRunnerRequest"
61
+ }
62
+ }
63
+ }
64
+ },
65
+ "responses": {
66
+ "200": {
67
+ "description": "Registered runner or exact replayed registration response",
68
+ "content": {
69
+ "application/json": {
70
+ "schema": {
71
+ "$ref": "#/components/schemas/RegisterRunnerResponse"
72
+ }
73
+ }
74
+ }
75
+ },
76
+ "401": {
77
+ "$ref": "#/components/responses/Unauthorized"
78
+ },
79
+ "409": {
80
+ "$ref": "#/components/responses/Conflict"
81
+ },
82
+ "413": {
83
+ "$ref": "#/components/responses/PayloadTooLarge"
84
+ }
85
+ }
86
+ }
87
+ },
88
+ "/api/runner/runners/{runnerId}/sessions": {
89
+ "post": {
90
+ "tags": ["Runner lifecycle"],
91
+ "operationId": "startRunnerSession",
92
+ "security": [
93
+ {
94
+ "runnerBearer": []
95
+ }
96
+ ],
97
+ "parameters": [
98
+ {
99
+ "$ref": "#/components/parameters/RunnerId"
100
+ }
101
+ ],
102
+ "requestBody": {
103
+ "required": true,
104
+ "content": {
105
+ "application/json": {
106
+ "schema": {
107
+ "$ref": "#/components/schemas/StartSessionRequest"
108
+ }
109
+ }
110
+ }
111
+ },
112
+ "responses": {
113
+ "200": {
114
+ "description": "Started runner session",
115
+ "content": {
116
+ "application/json": {
117
+ "schema": {
118
+ "$ref": "#/components/schemas/StartSessionResponse"
119
+ }
120
+ }
121
+ }
122
+ },
123
+ "401": {
124
+ "$ref": "#/components/responses/Unauthorized"
125
+ },
126
+ "409": {
127
+ "$ref": "#/components/responses/Conflict"
128
+ },
129
+ "413": {
130
+ "$ref": "#/components/responses/PayloadTooLarge"
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "/api/runner/runners/{runnerId}/heartbeat": {
136
+ "post": {
137
+ "tags": ["Runner lifecycle"],
138
+ "operationId": "heartbeatRunner",
139
+ "security": [
140
+ {
141
+ "runnerBearer": []
142
+ }
143
+ ],
144
+ "parameters": [
145
+ {
146
+ "$ref": "#/components/parameters/RunnerId"
147
+ }
148
+ ],
149
+ "requestBody": {
150
+ "required": true,
151
+ "content": {
152
+ "application/json": {
153
+ "schema": {
154
+ "$ref": "#/components/schemas/RunnerHeartbeatRequest"
155
+ }
156
+ }
157
+ }
158
+ },
159
+ "responses": {
160
+ "200": {
161
+ "description": "Runner heartbeat accepted",
162
+ "content": {
163
+ "application/json": {
164
+ "schema": {
165
+ "$ref": "#/components/schemas/RunnerHeartbeatResponse"
166
+ }
167
+ }
168
+ }
169
+ },
170
+ "401": {
171
+ "$ref": "#/components/responses/Unauthorized"
172
+ },
173
+ "409": {
174
+ "$ref": "#/components/responses/Conflict"
175
+ },
176
+ "413": {
177
+ "$ref": "#/components/responses/PayloadTooLarge"
178
+ }
179
+ }
180
+ }
181
+ },
182
+ "/api/runner/jobs/claim": {
183
+ "post": {
184
+ "tags": ["Job lifecycle"],
185
+ "operationId": "claimJob",
186
+ "security": [
187
+ {
188
+ "runnerBearer": []
189
+ }
190
+ ],
191
+ "requestBody": {
192
+ "required": true,
193
+ "content": {
194
+ "application/json": {
195
+ "schema": {
196
+ "$ref": "#/components/schemas/ClaimJobRequest"
197
+ }
198
+ }
199
+ }
200
+ },
201
+ "responses": {
202
+ "200": {
203
+ "description": "Matching lease or no available job",
204
+ "content": {
205
+ "application/json": {
206
+ "schema": {
207
+ "$ref": "#/components/schemas/ClaimJobResponse"
208
+ }
209
+ }
210
+ }
211
+ },
212
+ "401": {
213
+ "$ref": "#/components/responses/Unauthorized"
214
+ },
215
+ "409": {
216
+ "$ref": "#/components/responses/Conflict"
217
+ },
218
+ "413": {
219
+ "$ref": "#/components/responses/PayloadTooLarge"
220
+ }
221
+ }
222
+ }
223
+ },
224
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/accept": {
225
+ "post": {
226
+ "tags": ["Job lifecycle"],
227
+ "operationId": "acceptJob",
228
+ "security": [
229
+ {
230
+ "runnerBearer": []
231
+ }
232
+ ],
233
+ "parameters": [
234
+ {
235
+ "$ref": "#/components/parameters/JobId"
236
+ },
237
+ {
238
+ "$ref": "#/components/parameters/AttemptId"
239
+ }
240
+ ],
241
+ "requestBody": {
242
+ "required": true,
243
+ "content": {
244
+ "application/json": {
245
+ "schema": {
246
+ "$ref": "#/components/schemas/AcceptJobRequest"
247
+ }
248
+ }
249
+ }
250
+ },
251
+ "responses": {
252
+ "204": {
253
+ "description": "Lease accepted or exact acceptance replayed"
254
+ },
255
+ "401": {
256
+ "$ref": "#/components/responses/Unauthorized"
257
+ },
258
+ "409": {
259
+ "$ref": "#/components/responses/Conflict"
260
+ },
261
+ "413": {
262
+ "$ref": "#/components/responses/PayloadTooLarge"
263
+ }
264
+ }
265
+ }
266
+ },
267
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/heartbeat": {
268
+ "post": {
269
+ "tags": ["Job lifecycle"],
270
+ "operationId": "heartbeatJob",
271
+ "security": [
272
+ {
273
+ "runnerBearer": []
274
+ }
275
+ ],
276
+ "parameters": [
277
+ {
278
+ "$ref": "#/components/parameters/JobId"
279
+ },
280
+ {
281
+ "$ref": "#/components/parameters/AttemptId"
282
+ }
283
+ ],
284
+ "requestBody": {
285
+ "required": true,
286
+ "content": {
287
+ "application/json": {
288
+ "schema": {
289
+ "$ref": "#/components/schemas/JobHeartbeatRequest"
290
+ }
291
+ }
292
+ }
293
+ },
294
+ "responses": {
295
+ "200": {
296
+ "description": "Lease renewed and optional cancellation directive delivered",
297
+ "content": {
298
+ "application/json": {
299
+ "schema": {
300
+ "$ref": "#/components/schemas/JobHeartbeatResponse"
301
+ }
302
+ }
303
+ }
304
+ },
305
+ "401": {
306
+ "$ref": "#/components/responses/Unauthorized"
307
+ },
308
+ "409": {
309
+ "$ref": "#/components/responses/Conflict"
310
+ },
311
+ "413": {
312
+ "$ref": "#/components/responses/PayloadTooLarge"
313
+ }
314
+ }
315
+ }
316
+ },
317
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/logs": {
318
+ "post": {
319
+ "tags": ["Job lifecycle"],
320
+ "operationId": "appendJobLog",
321
+ "security": [
322
+ {
323
+ "runnerBearer": []
324
+ }
325
+ ],
326
+ "parameters": [
327
+ {
328
+ "$ref": "#/components/parameters/JobId"
329
+ },
330
+ {
331
+ "$ref": "#/components/parameters/AttemptId"
332
+ }
333
+ ],
334
+ "requestBody": {
335
+ "required": true,
336
+ "content": {
337
+ "application/json": {
338
+ "schema": {
339
+ "$ref": "#/components/schemas/LogChunk"
340
+ }
341
+ }
342
+ }
343
+ },
344
+ "responses": {
345
+ "200": {
346
+ "description": "Log sequence acknowledgement",
347
+ "content": {
348
+ "application/json": {
349
+ "schema": {
350
+ "$ref": "#/components/schemas/LogAcknowledgement"
351
+ }
352
+ }
353
+ }
354
+ },
355
+ "401": {
356
+ "$ref": "#/components/responses/Unauthorized"
357
+ },
358
+ "409": {
359
+ "$ref": "#/components/responses/Conflict"
360
+ },
361
+ "413": {
362
+ "$ref": "#/components/responses/PayloadTooLarge"
363
+ }
364
+ }
365
+ }
366
+ },
367
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/complete": {
368
+ "post": {
369
+ "tags": ["Job lifecycle"],
370
+ "operationId": "completeJob",
371
+ "security": [
372
+ {
373
+ "runnerBearer": []
374
+ }
375
+ ],
376
+ "parameters": [
377
+ {
378
+ "$ref": "#/components/parameters/JobId"
379
+ },
380
+ {
381
+ "$ref": "#/components/parameters/AttemptId"
382
+ }
383
+ ],
384
+ "requestBody": {
385
+ "required": true,
386
+ "content": {
387
+ "application/json": {
388
+ "schema": {
389
+ "$ref": "#/components/schemas/CompleteJobRequest"
390
+ }
391
+ }
392
+ }
393
+ },
394
+ "responses": {
395
+ "200": {
396
+ "description": "Terminal result accepted or exactly replayed",
397
+ "content": {
398
+ "application/json": {
399
+ "schema": {
400
+ "$ref": "#/components/schemas/CompleteJobResponse"
401
+ }
402
+ }
403
+ }
404
+ },
405
+ "401": {
406
+ "$ref": "#/components/responses/Unauthorized"
407
+ },
408
+ "409": {
409
+ "$ref": "#/components/responses/Conflict"
410
+ },
411
+ "413": {
412
+ "$ref": "#/components/responses/PayloadTooLarge"
413
+ }
414
+ }
415
+ }
416
+ },
417
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/abandon": {
418
+ "post": {
419
+ "tags": ["Job lifecycle"],
420
+ "operationId": "abandonJob",
421
+ "security": [
422
+ {
423
+ "runnerBearer": []
424
+ }
425
+ ],
426
+ "parameters": [
427
+ {
428
+ "$ref": "#/components/parameters/JobId"
429
+ },
430
+ {
431
+ "$ref": "#/components/parameters/AttemptId"
432
+ }
433
+ ],
434
+ "requestBody": {
435
+ "required": true,
436
+ "content": {
437
+ "application/json": {
438
+ "schema": {
439
+ "$ref": "#/components/schemas/AbandonJobRequest"
440
+ }
441
+ }
442
+ }
443
+ },
444
+ "responses": {
445
+ "204": {
446
+ "description": "Attempt abandoned"
447
+ },
448
+ "401": {
449
+ "$ref": "#/components/responses/Unauthorized"
450
+ },
451
+ "409": {
452
+ "$ref": "#/components/responses/Conflict"
453
+ },
454
+ "413": {
455
+ "$ref": "#/components/responses/PayloadTooLarge"
456
+ }
457
+ }
458
+ }
459
+ },
460
+ "/api/runner/jobs/recover": {
461
+ "post": {
462
+ "tags": ["Job lifecycle"],
463
+ "operationId": "recoverJobAttempt",
464
+ "security": [
465
+ {
466
+ "runnerBearer": []
467
+ }
468
+ ],
469
+ "requestBody": {
470
+ "required": true,
471
+ "content": {
472
+ "application/json": {
473
+ "schema": {
474
+ "$ref": "#/components/schemas/RecoverAttemptRequest"
475
+ }
476
+ }
477
+ }
478
+ },
479
+ "responses": {
480
+ "204": {
481
+ "description": "Interrupted attempt reconciled"
482
+ },
483
+ "401": {
484
+ "$ref": "#/components/responses/Unauthorized"
485
+ },
486
+ "409": {
487
+ "$ref": "#/components/responses/Conflict"
488
+ },
489
+ "413": {
490
+ "$ref": "#/components/responses/PayloadTooLarge"
491
+ }
492
+ }
493
+ }
494
+ },
495
+ "/api/runner/sources/{sha256}": {
496
+ "get": {
497
+ "tags": ["Transfers"],
498
+ "operationId": "downloadJobSource",
499
+ "security": [
500
+ {
501
+ "runnerBearer": []
502
+ }
503
+ ],
504
+ "parameters": [
505
+ {
506
+ "$ref": "#/components/parameters/Sha256"
507
+ },
508
+ {
509
+ "$ref": "#/components/parameters/RunnerIdHeader"
510
+ },
511
+ {
512
+ "$ref": "#/components/parameters/SessionIdHeader"
513
+ },
514
+ {
515
+ "$ref": "#/components/parameters/JobIdHeader"
516
+ },
517
+ {
518
+ "$ref": "#/components/parameters/AttemptIdHeader"
519
+ },
520
+ {
521
+ "$ref": "#/components/parameters/LeaseIdHeader"
522
+ },
523
+ {
524
+ "$ref": "#/components/parameters/FencingTokenHeader"
525
+ }
526
+ ],
527
+ "responses": {
528
+ "200": {
529
+ "description": "Exact immutable source archive",
530
+ "headers": {
531
+ "X-Content-SHA256": {
532
+ "$ref": "#/components/headers/Sha256"
533
+ },
534
+ "Content-Length": {
535
+ "$ref": "#/components/headers/SourceArchiveBytes"
536
+ },
537
+ "X-Extracted-Bytes": {
538
+ "$ref": "#/components/headers/SourceExtractedBytes"
539
+ },
540
+ "X-Archive-Entries": {
541
+ "$ref": "#/components/headers/SourceArchiveEntries"
542
+ }
543
+ },
544
+ "content": {
545
+ "application/gzip": {
546
+ "schema": {
547
+ "type": "string",
548
+ "contentEncoding": "binary"
549
+ }
550
+ }
551
+ }
552
+ },
553
+ "401": {
554
+ "$ref": "#/components/responses/Unauthorized"
555
+ },
556
+ "409": {
557
+ "$ref": "#/components/responses/Conflict"
558
+ }
559
+ }
560
+ }
561
+ },
562
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/artifacts/{artifactName}": {
563
+ "put": {
564
+ "tags": ["Transfers"],
565
+ "operationId": "uploadJobArtifact",
566
+ "security": [
567
+ {
568
+ "runnerBearer": []
569
+ }
570
+ ],
571
+ "parameters": [
572
+ {
573
+ "$ref": "#/components/parameters/JobId"
574
+ },
575
+ {
576
+ "$ref": "#/components/parameters/AttemptId"
577
+ },
578
+ {
579
+ "$ref": "#/components/parameters/ArtifactName"
580
+ },
581
+ {
582
+ "$ref": "#/components/parameters/RunnerIdHeader"
583
+ },
584
+ {
585
+ "$ref": "#/components/parameters/SessionIdHeader"
586
+ },
587
+ {
588
+ "$ref": "#/components/parameters/LeaseIdHeader"
589
+ },
590
+ {
591
+ "$ref": "#/components/parameters/FencingTokenHeader"
592
+ },
593
+ {
594
+ "$ref": "#/components/parameters/ContentSha256Header"
595
+ },
596
+ {
597
+ "$ref": "#/components/parameters/TransferRequestIdHeader"
598
+ },
599
+ {
600
+ "$ref": "#/components/parameters/ContentLengthHeader"
601
+ },
602
+ {
603
+ "$ref": "#/components/parameters/ExtractedBytesHeader"
604
+ },
605
+ {
606
+ "$ref": "#/components/parameters/ArchiveEntriesHeader"
607
+ }
608
+ ],
609
+ "requestBody": {
610
+ "required": true,
611
+ "content": {
612
+ "application/gzip": {
613
+ "schema": {
614
+ "type": "string",
615
+ "contentEncoding": "binary"
616
+ }
617
+ }
618
+ }
619
+ },
620
+ "responses": {
621
+ "200": {
622
+ "description": "Artifact verified and published",
623
+ "content": {
624
+ "application/json": {
625
+ "schema": {
626
+ "$ref": "#/components/schemas/TransferRecord"
627
+ }
628
+ }
629
+ }
630
+ },
631
+ "401": {
632
+ "$ref": "#/components/responses/Unauthorized"
633
+ },
634
+ "409": {
635
+ "$ref": "#/components/responses/Conflict"
636
+ },
637
+ "413": {
638
+ "$ref": "#/components/responses/PayloadTooLarge"
639
+ }
640
+ }
641
+ }
642
+ },
643
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/caches/{cacheName}": {
644
+ "get": {
645
+ "tags": ["Transfers"],
646
+ "operationId": "downloadJobCache",
647
+ "security": [
648
+ {
649
+ "runnerBearer": []
650
+ }
651
+ ],
652
+ "parameters": [
653
+ {
654
+ "$ref": "#/components/parameters/JobId"
655
+ },
656
+ {
657
+ "$ref": "#/components/parameters/AttemptId"
658
+ },
659
+ {
660
+ "$ref": "#/components/parameters/CacheName"
661
+ },
662
+ {
663
+ "$ref": "#/components/parameters/RunnerIdHeader"
664
+ },
665
+ {
666
+ "$ref": "#/components/parameters/SessionIdHeader"
667
+ },
668
+ {
669
+ "$ref": "#/components/parameters/LeaseIdHeader"
670
+ },
671
+ {
672
+ "$ref": "#/components/parameters/FencingTokenHeader"
673
+ }
674
+ ],
675
+ "responses": {
676
+ "200": {
677
+ "description": "Exact trust-scoped cache archive",
678
+ "headers": {
679
+ "X-Content-SHA256": {
680
+ "$ref": "#/components/headers/Sha256"
681
+ },
682
+ "Content-Length": {
683
+ "$ref": "#/components/headers/ArchiveBytes"
684
+ },
685
+ "X-Extracted-Bytes": {
686
+ "$ref": "#/components/headers/ExtractedBytes"
687
+ },
688
+ "X-Archive-Entries": {
689
+ "$ref": "#/components/headers/ArchiveEntries"
690
+ }
691
+ },
692
+ "content": {
693
+ "application/gzip": {
694
+ "schema": {
695
+ "type": "string",
696
+ "contentEncoding": "binary"
697
+ }
698
+ }
699
+ }
700
+ },
701
+ "204": {
702
+ "description": "No matching cache exists"
703
+ },
704
+ "401": {
705
+ "$ref": "#/components/responses/Unauthorized"
706
+ },
707
+ "409": {
708
+ "$ref": "#/components/responses/Conflict"
709
+ }
710
+ }
711
+ },
712
+ "put": {
713
+ "tags": ["Transfers"],
714
+ "operationId": "uploadJobCache",
715
+ "security": [
716
+ {
717
+ "runnerBearer": []
718
+ }
719
+ ],
720
+ "parameters": [
721
+ {
722
+ "$ref": "#/components/parameters/JobId"
723
+ },
724
+ {
725
+ "$ref": "#/components/parameters/AttemptId"
726
+ },
727
+ {
728
+ "$ref": "#/components/parameters/CacheName"
729
+ },
730
+ {
731
+ "$ref": "#/components/parameters/RunnerIdHeader"
732
+ },
733
+ {
734
+ "$ref": "#/components/parameters/SessionIdHeader"
735
+ },
736
+ {
737
+ "$ref": "#/components/parameters/LeaseIdHeader"
738
+ },
739
+ {
740
+ "$ref": "#/components/parameters/FencingTokenHeader"
741
+ },
742
+ {
743
+ "$ref": "#/components/parameters/ContentSha256Header"
744
+ },
745
+ {
746
+ "$ref": "#/components/parameters/TransferRequestIdHeader"
747
+ },
748
+ {
749
+ "$ref": "#/components/parameters/ContentLengthHeader"
750
+ },
751
+ {
752
+ "$ref": "#/components/parameters/ExtractedBytesHeader"
753
+ },
754
+ {
755
+ "$ref": "#/components/parameters/ArchiveEntriesHeader"
756
+ }
757
+ ],
758
+ "requestBody": {
759
+ "required": true,
760
+ "content": {
761
+ "application/gzip": {
762
+ "schema": {
763
+ "type": "string",
764
+ "contentEncoding": "binary"
765
+ }
766
+ }
767
+ }
768
+ },
769
+ "responses": {
770
+ "200": {
771
+ "description": "Cache verified and generation published",
772
+ "content": {
773
+ "application/json": {
774
+ "schema": {
775
+ "$ref": "#/components/schemas/TransferRecord"
776
+ }
777
+ }
778
+ }
779
+ },
780
+ "401": {
781
+ "$ref": "#/components/responses/Unauthorized"
782
+ },
783
+ "409": {
784
+ "$ref": "#/components/responses/Conflict"
785
+ },
786
+ "413": {
787
+ "$ref": "#/components/responses/PayloadTooLarge"
788
+ }
789
+ }
790
+ }
791
+ },
792
+ "/api/runner/jobs/{jobId}/attempts/{attemptId}/image": {
793
+ "put": {
794
+ "tags": ["Transfers"],
795
+ "operationId": "recordJobImage",
796
+ "security": [
797
+ {
798
+ "runnerBearer": []
799
+ }
800
+ ],
801
+ "parameters": [
802
+ {
803
+ "$ref": "#/components/parameters/JobId"
804
+ },
805
+ {
806
+ "$ref": "#/components/parameters/AttemptId"
807
+ }
808
+ ],
809
+ "requestBody": {
810
+ "required": true,
811
+ "content": {
812
+ "application/json": {
813
+ "schema": {
814
+ "$ref": "#/components/schemas/RecordImageRequest"
815
+ }
816
+ }
817
+ }
818
+ },
819
+ "responses": {
820
+ "200": {
821
+ "description": "Pushed image manifest verified and recorded, or exact record replayed",
822
+ "content": {
823
+ "application/json": {
824
+ "schema": {
825
+ "$ref": "#/components/schemas/ImageRecord"
826
+ }
827
+ }
828
+ }
829
+ },
830
+ "401": {
831
+ "$ref": "#/components/responses/Unauthorized"
832
+ },
833
+ "409": {
834
+ "$ref": "#/components/responses/Conflict"
835
+ },
836
+ "413": {
837
+ "$ref": "#/components/responses/PayloadTooLarge"
838
+ }
839
+ }
840
+ }
841
+ }
842
+ },
843
+ "components": {
844
+ "securitySchemes": {
845
+ "bootstrapBearer": {
846
+ "type": "http",
847
+ "scheme": "bearer",
848
+ "bearerFormat": "opaque one-time registration credential"
849
+ },
850
+ "runnerBearer": {
851
+ "type": "http",
852
+ "scheme": "bearer",
853
+ "bearerFormat": "opaque short-lived runner credential"
854
+ }
855
+ },
856
+ "parameters": {
857
+ "RunnerId": {
858
+ "name": "runnerId",
859
+ "in": "path",
860
+ "required": true,
861
+ "schema": {
862
+ "$ref": "#/components/schemas/Identifier"
863
+ }
864
+ },
865
+ "JobId": {
866
+ "name": "jobId",
867
+ "in": "path",
868
+ "required": true,
869
+ "schema": {
870
+ "$ref": "#/components/schemas/Identifier"
871
+ }
872
+ },
873
+ "AttemptId": {
874
+ "name": "attemptId",
875
+ "in": "path",
876
+ "required": true,
877
+ "schema": {
878
+ "$ref": "#/components/schemas/Identifier"
879
+ }
880
+ },
881
+ "ArtifactName": {
882
+ "name": "artifactName",
883
+ "in": "path",
884
+ "required": true,
885
+ "schema": {
886
+ "$ref": "#/components/schemas/Identifier"
887
+ }
888
+ },
889
+ "CacheName": {
890
+ "name": "cacheName",
891
+ "in": "path",
892
+ "required": true,
893
+ "schema": {
894
+ "$ref": "#/components/schemas/Identifier"
895
+ }
896
+ },
897
+ "Sha256": {
898
+ "name": "sha256",
899
+ "in": "path",
900
+ "required": true,
901
+ "schema": {
902
+ "$ref": "#/components/schemas/Sha256"
903
+ }
904
+ },
905
+ "RunnerIdHeader": {
906
+ "name": "X-Runner-ID",
907
+ "in": "header",
908
+ "required": true,
909
+ "schema": {
910
+ "$ref": "#/components/schemas/Identifier"
911
+ }
912
+ },
913
+ "SessionIdHeader": {
914
+ "name": "X-Session-ID",
915
+ "in": "header",
916
+ "required": true,
917
+ "schema": {
918
+ "$ref": "#/components/schemas/Identifier"
919
+ }
920
+ },
921
+ "JobIdHeader": {
922
+ "name": "X-Job-ID",
923
+ "in": "header",
924
+ "required": true,
925
+ "schema": {
926
+ "$ref": "#/components/schemas/Identifier"
927
+ }
928
+ },
929
+ "AttemptIdHeader": {
930
+ "name": "X-Attempt-ID",
931
+ "in": "header",
932
+ "required": true,
933
+ "schema": {
934
+ "$ref": "#/components/schemas/Identifier"
935
+ }
936
+ },
937
+ "LeaseIdHeader": {
938
+ "name": "X-Lease-ID",
939
+ "in": "header",
940
+ "required": true,
941
+ "schema": {
942
+ "$ref": "#/components/schemas/Identifier"
943
+ }
944
+ },
945
+ "FencingTokenHeader": {
946
+ "name": "X-Fencing-Token",
947
+ "in": "header",
948
+ "required": true,
949
+ "schema": {
950
+ "type": "string",
951
+ "minLength": 16,
952
+ "maxLength": 512
953
+ }
954
+ },
955
+ "ContentSha256Header": {
956
+ "name": "X-Content-SHA256",
957
+ "in": "header",
958
+ "required": true,
959
+ "schema": {
960
+ "$ref": "#/components/schemas/Sha256"
961
+ }
962
+ },
963
+ "TransferRequestIdHeader": {
964
+ "name": "X-Transfer-Request-ID",
965
+ "in": "header",
966
+ "required": true,
967
+ "schema": {
968
+ "$ref": "#/components/schemas/Identifier"
969
+ }
970
+ },
971
+ "ContentLengthHeader": {
972
+ "name": "Content-Length",
973
+ "in": "header",
974
+ "required": true,
975
+ "schema": {
976
+ "type": "integer",
977
+ "minimum": 0,
978
+ "maximum": 17179869184
979
+ }
980
+ },
981
+ "ExtractedBytesHeader": {
982
+ "name": "X-Extracted-Bytes",
983
+ "in": "header",
984
+ "required": true,
985
+ "schema": {
986
+ "type": "integer",
987
+ "minimum": 0,
988
+ "maximum": 137438953472
989
+ }
990
+ },
991
+ "ArchiveEntriesHeader": {
992
+ "name": "X-Archive-Entries",
993
+ "in": "header",
994
+ "required": true,
995
+ "schema": {
996
+ "type": "integer",
997
+ "minimum": 0,
998
+ "maximum": 1000000
999
+ }
1000
+ }
1001
+ },
1002
+ "headers": {
1003
+ "Sha256": {
1004
+ "description": "Lowercase SHA-256 of the response body",
1005
+ "schema": {
1006
+ "$ref": "#/components/schemas/Sha256"
1007
+ }
1008
+ },
1009
+ "ArchiveBytes": {
1010
+ "description": "Recomputed compressed response body bytes",
1011
+ "schema": {
1012
+ "type": "integer",
1013
+ "minimum": 0,
1014
+ "maximum": 17179869184
1015
+ }
1016
+ },
1017
+ "SourceArchiveBytes": {
1018
+ "description": "Recomputed compressed source response body bytes",
1019
+ "schema": {
1020
+ "type": "integer",
1021
+ "minimum": 0,
1022
+ "maximum": 8589934592
1023
+ }
1024
+ },
1025
+ "ExtractedBytes": {
1026
+ "description": "Recomputed regular-file bytes after safe extraction",
1027
+ "schema": {
1028
+ "type": "integer",
1029
+ "minimum": 0,
1030
+ "maximum": 137438953472
1031
+ }
1032
+ },
1033
+ "SourceExtractedBytes": {
1034
+ "description": "Recomputed regular-file bytes after safe source extraction",
1035
+ "schema": {
1036
+ "type": "integer",
1037
+ "minimum": 0,
1038
+ "maximum": 68719476736
1039
+ }
1040
+ },
1041
+ "ArchiveEntries": {
1042
+ "description": "Recomputed archive entry count",
1043
+ "schema": {
1044
+ "type": "integer",
1045
+ "minimum": 0,
1046
+ "maximum": 1000000
1047
+ }
1048
+ },
1049
+ "SourceArchiveEntries": {
1050
+ "description": "Recomputed source archive entry count",
1051
+ "schema": {
1052
+ "type": "integer",
1053
+ "minimum": 0,
1054
+ "maximum": 1000000
1055
+ }
1056
+ }
1057
+ },
1058
+ "responses": {
1059
+ "Unauthorized": {
1060
+ "description": "Credential missing, expired, revoked, or not authorized for the endpoint",
1061
+ "content": {
1062
+ "application/json": {
1063
+ "schema": {
1064
+ "$ref": "#/components/schemas/ErrorResponse"
1065
+ }
1066
+ }
1067
+ }
1068
+ },
1069
+ "Conflict": {
1070
+ "description": "Idempotency, lifecycle, sequence, session, lease, attempt, fencing, or specification-version conflict",
1071
+ "content": {
1072
+ "application/json": {
1073
+ "schema": {
1074
+ "$ref": "#/components/schemas/ErrorResponse"
1075
+ }
1076
+ }
1077
+ }
1078
+ },
1079
+ "PayloadTooLarge": {
1080
+ "description": "Body exceeds the declared job or protocol limit",
1081
+ "content": {
1082
+ "application/json": {
1083
+ "schema": {
1084
+ "$ref": "#/components/schemas/ErrorResponse"
1085
+ }
1086
+ }
1087
+ }
1088
+ }
1089
+ },
1090
+ "schemas": {
1091
+ "Identifier": {
1092
+ "type": "string",
1093
+ "minLength": 1,
1094
+ "maxLength": 64,
1095
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
1096
+ },
1097
+ "Sha256": {
1098
+ "type": "string",
1099
+ "pattern": "^[a-f0-9]{64}$"
1100
+ },
1101
+ "Timestamp": {
1102
+ "type": "string",
1103
+ "format": "date-time"
1104
+ },
1105
+ "OciDigest": {
1106
+ "type": "string",
1107
+ "pattern": "^sha256:[a-f0-9]{64}$"
1108
+ },
1109
+ "RegistryHost": {
1110
+ "type": "string",
1111
+ "minLength": 1,
1112
+ "maxLength": 253,
1113
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*(?::[0-9]{1,5})?$"
1114
+ },
1115
+ "OciRepository": {
1116
+ "type": "string",
1117
+ "minLength": 1,
1118
+ "maxLength": 255,
1119
+ "pattern": "^[a-z0-9]+(?:(?:\\.|_|__|-+)[a-z0-9]+)*(?:/[a-z0-9]+(?:(?:\\.|_|__|-+)[a-z0-9]+)*)*$"
1120
+ },
1121
+ "DiscoveryResponse": {
1122
+ "type": "object",
1123
+ "additionalProperties": false,
1124
+ "required": ["spec", "basePath", "status", "serverTime", "limits"],
1125
+ "properties": {
1126
+ "spec": {
1127
+ "$ref": "../schemas/runner-job.schema.json#/$defs/specVersion"
1128
+ },
1129
+ "basePath": {
1130
+ "const": "/api/runner"
1131
+ },
1132
+ "status": {
1133
+ "const": "draft"
1134
+ },
1135
+ "serverTime": {
1136
+ "$ref": "#/components/schemas/Timestamp"
1137
+ },
1138
+ "limits": {
1139
+ "$ref": "#/components/schemas/ProtocolLimits"
1140
+ }
1141
+ }
1142
+ },
1143
+ "ProtocolLimits": {
1144
+ "type": "object",
1145
+ "additionalProperties": false,
1146
+ "required": ["maximumJsonBytes", "maximumLogChunkBytes", "maximumTotalLogBytes", "minimumLeaseSeconds", "maximumLeaseSeconds"],
1147
+ "properties": {
1148
+ "maximumJsonBytes": {
1149
+ "type": "integer",
1150
+ "minimum": 1,
1151
+ "maximum": 2097152
1152
+ },
1153
+ "maximumLogChunkBytes": {
1154
+ "type": "integer",
1155
+ "minimum": 1,
1156
+ "maximum": 65536
1157
+ },
1158
+ "maximumTotalLogBytes": {
1159
+ "type": "integer",
1160
+ "minimum": 0,
1161
+ "maximum": 1073741824
1162
+ },
1163
+ "minimumLeaseSeconds": {
1164
+ "type": "integer",
1165
+ "minimum": 30,
1166
+ "maximum": 600
1167
+ },
1168
+ "maximumLeaseSeconds": {
1169
+ "type": "integer",
1170
+ "minimum": 30,
1171
+ "maximum": 600
1172
+ }
1173
+ }
1174
+ },
1175
+ "RunnerCredential": {
1176
+ "type": "object",
1177
+ "additionalProperties": false,
1178
+ "required": ["credentialId", "runnerId", "token", "expiresAt"],
1179
+ "properties": {
1180
+ "credentialId": {
1181
+ "$ref": "#/components/schemas/Identifier"
1182
+ },
1183
+ "runnerId": {
1184
+ "$ref": "#/components/schemas/Identifier"
1185
+ },
1186
+ "token": {
1187
+ "type": "string",
1188
+ "minLength": 32,
1189
+ "maxLength": 8192,
1190
+ "writeOnly": true
1191
+ },
1192
+ "expiresAt": {
1193
+ "$ref": "#/components/schemas/Timestamp"
1194
+ },
1195
+ "previousCredentialValidUntil": {
1196
+ "$ref": "#/components/schemas/Timestamp"
1197
+ }
1198
+ }
1199
+ },
1200
+ "TransferLimits": {
1201
+ "type": "object",
1202
+ "additionalProperties": false,
1203
+ "required": [
1204
+ "maximumSourceArchiveBytes",
1205
+ "maximumSourceExtractedBytes",
1206
+ "maximumSourceEntries",
1207
+ "maximumArtifactArchiveBytes",
1208
+ "maximumArtifactExtractedBytes",
1209
+ "maximumArtifactEntries",
1210
+ "maximumArtifacts",
1211
+ "maximumCacheArchiveBytes",
1212
+ "maximumCacheExtractedBytes",
1213
+ "maximumCacheEntries",
1214
+ "maximumCaches",
1215
+ "maximumLogChunkBytes",
1216
+ "maximumTotalLogBytes",
1217
+ "maximumWorkspaceBytes",
1218
+ "maximumWorkspaceEntries"
1219
+ ],
1220
+ "properties": {
1221
+ "maximumSourceArchiveBytes": {
1222
+ "type": "integer",
1223
+ "minimum": 0,
1224
+ "maximum": 8589934592
1225
+ },
1226
+ "maximumSourceExtractedBytes": {
1227
+ "type": "integer",
1228
+ "minimum": 0,
1229
+ "maximum": 68719476736
1230
+ },
1231
+ "maximumSourceEntries": {
1232
+ "type": "integer",
1233
+ "minimum": 0,
1234
+ "maximum": 1000000
1235
+ },
1236
+ "maximumArtifactArchiveBytes": {
1237
+ "type": "integer",
1238
+ "minimum": 0,
1239
+ "maximum": 17179869184
1240
+ },
1241
+ "maximumArtifactExtractedBytes": {
1242
+ "type": "integer",
1243
+ "minimum": 0,
1244
+ "maximum": 137438953472
1245
+ },
1246
+ "maximumArtifactEntries": {
1247
+ "type": "integer",
1248
+ "minimum": 0,
1249
+ "maximum": 1000000
1250
+ },
1251
+ "maximumArtifacts": {
1252
+ "type": "integer",
1253
+ "minimum": 0,
1254
+ "maximum": 64
1255
+ },
1256
+ "maximumCacheArchiveBytes": {
1257
+ "type": "integer",
1258
+ "minimum": 0,
1259
+ "maximum": 17179869184
1260
+ },
1261
+ "maximumCacheExtractedBytes": {
1262
+ "type": "integer",
1263
+ "minimum": 0,
1264
+ "maximum": 137438953472
1265
+ },
1266
+ "maximumCacheEntries": {
1267
+ "type": "integer",
1268
+ "minimum": 0,
1269
+ "maximum": 1000000
1270
+ },
1271
+ "maximumCaches": {
1272
+ "type": "integer",
1273
+ "minimum": 0,
1274
+ "maximum": 32
1275
+ },
1276
+ "maximumLogChunkBytes": {
1277
+ "type": "integer",
1278
+ "minimum": 1,
1279
+ "maximum": 65536
1280
+ },
1281
+ "maximumTotalLogBytes": {
1282
+ "type": "integer",
1283
+ "minimum": 0,
1284
+ "maximum": 1073741824
1285
+ },
1286
+ "maximumWorkspaceBytes": {
1287
+ "type": "integer",
1288
+ "minimum": 16777216,
1289
+ "maximum": 1099511627776
1290
+ },
1291
+ "maximumWorkspaceEntries": {
1292
+ "type": "integer",
1293
+ "minimum": 1,
1294
+ "maximum": 2000000
1295
+ }
1296
+ }
1297
+ },
1298
+ "ResourceLimits": {
1299
+ "type": "object",
1300
+ "additionalProperties": false,
1301
+ "description": "Largest per-attempt resource ceilings the runner can enforce. A runner that advertises them is leased only jobs whose declared resources fit.",
1302
+ "required": ["maximumMemoryBytes", "maximumCpus", "maximumPids", "maximumSharedMemoryBytes"],
1303
+ "properties": {
1304
+ "maximumMemoryBytes": {
1305
+ "type": "integer",
1306
+ "minimum": 16777216,
1307
+ "maximum": 1099511627776
1308
+ },
1309
+ "maximumCpus": {
1310
+ "type": "number",
1311
+ "exclusiveMinimum": 0,
1312
+ "maximum": 1024
1313
+ },
1314
+ "maximumPids": {
1315
+ "type": "integer",
1316
+ "minimum": 1,
1317
+ "maximum": 1048576
1318
+ },
1319
+ "maximumSharedMemoryBytes": {
1320
+ "type": "integer",
1321
+ "minimum": 1048576,
1322
+ "maximum": 1099511627776
1323
+ }
1324
+ }
1325
+ },
1326
+ "LeaseFeature": {
1327
+ "description": "Lease content a runner uses: image pull grants, candidate bindings, or npm read grants.",
1328
+ "enum": ["image-pull-grants", "candidate-bindings", "npm-read-grants"]
1329
+ },
1330
+ "RunnerCapabilities": {
1331
+ "type": "object",
1332
+ "additionalProperties": false,
1333
+ "required": ["executionProfiles", "isolation", "platforms", "labels", "features", "networks", "sourceFormats", "limits"],
1334
+ "properties": {
1335
+ "executionProfiles": {
1336
+ "type": "array",
1337
+ "minItems": 1,
1338
+ "maxItems": 16,
1339
+ "uniqueItems": true,
1340
+ "items": {
1341
+ "$ref": "../schemas/runner-job.schema.json#/$defs/executionProfile"
1342
+ }
1343
+ },
1344
+ "isolation": {
1345
+ "type": "array",
1346
+ "minItems": 1,
1347
+ "maxItems": 2,
1348
+ "uniqueItems": true,
1349
+ "items": {
1350
+ "$ref": "../schemas/runner-job.schema.json#/$defs/isolation"
1351
+ }
1352
+ },
1353
+ "platforms": {
1354
+ "type": "array",
1355
+ "minItems": 1,
1356
+ "maxItems": 16,
1357
+ "uniqueItems": true,
1358
+ "items": {
1359
+ "$ref": "../schemas/runner-job.schema.json#/$defs/platform"
1360
+ }
1361
+ },
1362
+ "labels": {
1363
+ "type": "array",
1364
+ "maxItems": 32,
1365
+ "uniqueItems": true,
1366
+ "items": {
1367
+ "$ref": "#/components/schemas/Identifier"
1368
+ }
1369
+ },
1370
+ "features": {
1371
+ "type": "array",
1372
+ "maxItems": 16,
1373
+ "uniqueItems": true,
1374
+ "items": {
1375
+ "$ref": "../schemas/runner-job.schema.json#/$defs/feature"
1376
+ }
1377
+ },
1378
+ "networks": {
1379
+ "type": "array",
1380
+ "minItems": 1,
1381
+ "maxItems": 2,
1382
+ "uniqueItems": true,
1383
+ "items": {
1384
+ "$ref": "../schemas/runner-job.schema.json#/$defs/networkMode"
1385
+ }
1386
+ },
1387
+ "sourceFormats": {
1388
+ "type": "array",
1389
+ "minItems": 1,
1390
+ "maxItems": 1,
1391
+ "items": {
1392
+ "const": "tar.gz"
1393
+ }
1394
+ },
1395
+ "limits": {
1396
+ "$ref": "#/components/schemas/TransferLimits"
1397
+ },
1398
+ "resources": {
1399
+ "$ref": "#/components/schemas/ResourceLimits"
1400
+ },
1401
+ "leaseFeatures": {
1402
+ "type": "array",
1403
+ "description": "Lease contents the runner uses. When present, a lease uses only listed lease features.",
1404
+ "maxItems": 3,
1405
+ "uniqueItems": true,
1406
+ "items": {
1407
+ "$ref": "#/components/schemas/LeaseFeature"
1408
+ }
1409
+ },
1410
+ "maximumTimeoutMs": {
1411
+ "type": "integer",
1412
+ "description": "Largest job timeoutMs the runner executes. When present, a job is leased only when its timeoutMs is at most this value.",
1413
+ "minimum": 1000,
1414
+ "maximum": 86400000
1415
+ }
1416
+ },
1417
+ "allOf": [
1418
+ {
1419
+ "if": {
1420
+ "type": "object",
1421
+ "properties": {
1422
+ "executionProfiles": {
1423
+ "type": "array",
1424
+ "contains": {
1425
+ "$ref": "../schemas/runner-job.schema.json#/$defs/imageBuildProfile"
1426
+ }
1427
+ }
1428
+ },
1429
+ "required": ["executionProfiles"]
1430
+ },
1431
+ "then": {
1432
+ "type": "object",
1433
+ "properties": {
1434
+ "executionProfiles": {
1435
+ "type": "array",
1436
+ "maxItems": 1
1437
+ },
1438
+ "isolation": {
1439
+ "type": "array",
1440
+ "contains": {
1441
+ "const": "microvm"
1442
+ }
1443
+ }
1444
+ }
1445
+ }
1446
+ },
1447
+ {
1448
+ "if": {
1449
+ "type": "object",
1450
+ "properties": {
1451
+ "executionProfiles": {
1452
+ "type": "array",
1453
+ "contains": {
1454
+ "$ref": "../schemas/runner-job.schema.json#/$defs/vmProfile"
1455
+ }
1456
+ }
1457
+ },
1458
+ "required": ["executionProfiles"]
1459
+ },
1460
+ "then": {
1461
+ "type": "object",
1462
+ "properties": {
1463
+ "isolation": {
1464
+ "type": "array",
1465
+ "contains": {
1466
+ "const": "microvm"
1467
+ }
1468
+ }
1469
+ }
1470
+ }
1471
+ },
1472
+ {
1473
+ "if": {
1474
+ "type": "object",
1475
+ "properties": {
1476
+ "leaseFeatures": {
1477
+ "type": "array",
1478
+ "contains": {
1479
+ "const": "candidate-bindings"
1480
+ }
1481
+ }
1482
+ },
1483
+ "required": ["leaseFeatures"]
1484
+ },
1485
+ "then": {
1486
+ "type": "object",
1487
+ "properties": {
1488
+ "leaseFeatures": {
1489
+ "type": "array",
1490
+ "contains": {
1491
+ "const": "image-pull-grants"
1492
+ }
1493
+ }
1494
+ }
1495
+ }
1496
+ }
1497
+ ]
1498
+ },
1499
+ "RegisterRunnerRequest": {
1500
+ "type": "object",
1501
+ "additionalProperties": false,
1502
+ "required": ["registrationRequestId", "spec", "runnerVersion", "name", "capabilities"],
1503
+ "properties": {
1504
+ "registrationRequestId": {
1505
+ "$ref": "#/components/schemas/Identifier"
1506
+ },
1507
+ "spec": {
1508
+ "$ref": "../schemas/runner-job.schema.json#/$defs/specVersion"
1509
+ },
1510
+ "runnerVersion": {
1511
+ "type": "string",
1512
+ "minLength": 1,
1513
+ "maxLength": 64
1514
+ },
1515
+ "name": {
1516
+ "type": "string",
1517
+ "minLength": 1,
1518
+ "maxLength": 128
1519
+ },
1520
+ "capabilities": {
1521
+ "$ref": "#/components/schemas/RunnerCapabilities"
1522
+ }
1523
+ }
1524
+ },
1525
+ "RegisterRunnerResponse": {
1526
+ "type": "object",
1527
+ "additionalProperties": false,
1528
+ "required": ["spec", "serverTime", "registrationReplayUntil", "credential"],
1529
+ "properties": {
1530
+ "spec": {
1531
+ "$ref": "../schemas/runner-job.schema.json#/$defs/specVersion"
1532
+ },
1533
+ "serverTime": {
1534
+ "$ref": "#/components/schemas/Timestamp"
1535
+ },
1536
+ "registrationReplayUntil": {
1537
+ "$ref": "#/components/schemas/Timestamp"
1538
+ },
1539
+ "credential": {
1540
+ "$ref": "#/components/schemas/RunnerCredential"
1541
+ }
1542
+ }
1543
+ },
1544
+ "StartSessionRequest": {
1545
+ "type": "object",
1546
+ "additionalProperties": false,
1547
+ "required": ["sessionRequestId", "runnerId", "spec", "runnerVersion", "capabilities"],
1548
+ "properties": {
1549
+ "sessionRequestId": {
1550
+ "$ref": "#/components/schemas/Identifier"
1551
+ },
1552
+ "runnerId": {
1553
+ "$ref": "#/components/schemas/Identifier"
1554
+ },
1555
+ "spec": {
1556
+ "$ref": "../schemas/runner-job.schema.json#/$defs/specVersion"
1557
+ },
1558
+ "runnerVersion": {
1559
+ "type": "string",
1560
+ "minLength": 1,
1561
+ "maxLength": 64
1562
+ },
1563
+ "capabilities": {
1564
+ "$ref": "#/components/schemas/RunnerCapabilities"
1565
+ }
1566
+ }
1567
+ },
1568
+ "StartSessionResponse": {
1569
+ "type": "object",
1570
+ "additionalProperties": false,
1571
+ "required": ["sessionId", "spec", "serverTime"],
1572
+ "properties": {
1573
+ "sessionId": {
1574
+ "$ref": "#/components/schemas/Identifier"
1575
+ },
1576
+ "spec": {
1577
+ "$ref": "../schemas/runner-job.schema.json#/$defs/specVersion"
1578
+ },
1579
+ "serverTime": {
1580
+ "$ref": "#/components/schemas/Timestamp"
1581
+ },
1582
+ "credential": {
1583
+ "$ref": "#/components/schemas/RunnerCredential"
1584
+ }
1585
+ }
1586
+ },
1587
+ "RunnerHeartbeatRequest": {
1588
+ "type": "object",
1589
+ "additionalProperties": false,
1590
+ "required": ["runnerId", "sessionId"],
1591
+ "properties": {
1592
+ "runnerId": {
1593
+ "$ref": "#/components/schemas/Identifier"
1594
+ },
1595
+ "sessionId": {
1596
+ "$ref": "#/components/schemas/Identifier"
1597
+ }
1598
+ }
1599
+ },
1600
+ "RunnerHeartbeatResponse": {
1601
+ "type": "object",
1602
+ "additionalProperties": false,
1603
+ "required": ["serverTime", "drainRequested"],
1604
+ "properties": {
1605
+ "serverTime": {
1606
+ "$ref": "#/components/schemas/Timestamp"
1607
+ },
1608
+ "drainRequested": {
1609
+ "type": "boolean"
1610
+ },
1611
+ "credential": {
1612
+ "$ref": "#/components/schemas/RunnerCredential"
1613
+ }
1614
+ }
1615
+ },
1616
+ "ClaimJobRequest": {
1617
+ "type": "object",
1618
+ "additionalProperties": false,
1619
+ "required": ["claimRequestId", "runnerId", "sessionId", "capabilities"],
1620
+ "properties": {
1621
+ "claimRequestId": {
1622
+ "$ref": "#/components/schemas/Identifier"
1623
+ },
1624
+ "runnerId": {
1625
+ "$ref": "#/components/schemas/Identifier"
1626
+ },
1627
+ "sessionId": {
1628
+ "$ref": "#/components/schemas/Identifier"
1629
+ },
1630
+ "capabilities": {
1631
+ "$ref": "#/components/schemas/RunnerCapabilities"
1632
+ }
1633
+ }
1634
+ },
1635
+ "ClaimJobResponse": {
1636
+ "type": "object",
1637
+ "additionalProperties": false,
1638
+ "required": ["serverTime", "lease"],
1639
+ "properties": {
1640
+ "serverTime": {
1641
+ "$ref": "#/components/schemas/Timestamp"
1642
+ },
1643
+ "retryAfterMs": {
1644
+ "type": "integer",
1645
+ "minimum": 0,
1646
+ "maximum": 30000
1647
+ },
1648
+ "lease": {
1649
+ "oneOf": [
1650
+ {
1651
+ "type": "null"
1652
+ },
1653
+ {
1654
+ "$ref": "#/components/schemas/JobLease"
1655
+ }
1656
+ ]
1657
+ }
1658
+ }
1659
+ },
1660
+ "JobLease": {
1661
+ "type": "object",
1662
+ "additionalProperties": false,
1663
+ "required": ["jobId", "attemptId", "leaseId", "fencingToken", "leaseExpiresAt", "job", "grants", "bindings"],
1664
+ "properties": {
1665
+ "jobId": {
1666
+ "$ref": "#/components/schemas/Identifier"
1667
+ },
1668
+ "attemptId": {
1669
+ "$ref": "#/components/schemas/Identifier"
1670
+ },
1671
+ "leaseId": {
1672
+ "$ref": "#/components/schemas/Identifier"
1673
+ },
1674
+ "fencingToken": {
1675
+ "type": "string",
1676
+ "minLength": 16,
1677
+ "maxLength": 512
1678
+ },
1679
+ "leaseExpiresAt": {
1680
+ "$ref": "#/components/schemas/Timestamp"
1681
+ },
1682
+ "job": {
1683
+ "$ref": "../schemas/runner-job.schema.json"
1684
+ },
1685
+ "grants": {
1686
+ "type": "array",
1687
+ "maxItems": 64,
1688
+ "items": {
1689
+ "$ref": "#/components/schemas/ImageGrant"
1690
+ }
1691
+ },
1692
+ "bindings": {
1693
+ "type": "array",
1694
+ "maxItems": 64,
1695
+ "items": {
1696
+ "$ref": "#/components/schemas/ImageBinding"
1697
+ }
1698
+ },
1699
+ "npmGrants": {
1700
+ "type": "array",
1701
+ "minItems": 1,
1702
+ "maxItems": 8,
1703
+ "items": {
1704
+ "$ref": "#/components/schemas/NpmGrant"
1705
+ }
1706
+ }
1707
+ },
1708
+ "allOf": [
1709
+ {
1710
+ "if": {
1711
+ "type": "object",
1712
+ "properties": {
1713
+ "job": {
1714
+ "type": "object",
1715
+ "properties": {
1716
+ "npmRead": {}
1717
+ },
1718
+ "required": ["npmRead"]
1719
+ }
1720
+ },
1721
+ "required": ["job"]
1722
+ },
1723
+ "then": {
1724
+ "type": "object",
1725
+ "properties": {
1726
+ "npmGrants": {}
1727
+ },
1728
+ "required": ["npmGrants"]
1729
+ },
1730
+ "else": {
1731
+ "type": "object",
1732
+ "properties": {
1733
+ "npmGrants": false
1734
+ }
1735
+ }
1736
+ }
1737
+ ]
1738
+ },
1739
+ "NpmGrant": {
1740
+ "type": "object",
1741
+ "additionalProperties": false,
1742
+ "description": "Attempt-scoped read-only npm registry token for one npmRead entry of the leased job. Outside the compiled plan digest.",
1743
+ "required": ["grantId", "registry", "scopes", "secret", "expiresAt"],
1744
+ "properties": {
1745
+ "grantId": {
1746
+ "$ref": "#/components/schemas/Identifier"
1747
+ },
1748
+ "registry": {
1749
+ "$ref": "../schemas/runner-job.schema.json#/$defs/npmRegistry"
1750
+ },
1751
+ "scopes": {
1752
+ "type": "array",
1753
+ "minItems": 1,
1754
+ "maxItems": 16,
1755
+ "uniqueItems": true,
1756
+ "items": {
1757
+ "$ref": "../schemas/runner-job.schema.json#/$defs/npmScope"
1758
+ }
1759
+ },
1760
+ "secret": {
1761
+ "type": "string",
1762
+ "minLength": 32,
1763
+ "maxLength": 8192,
1764
+ "writeOnly": true
1765
+ },
1766
+ "expiresAt": {
1767
+ "$ref": "#/components/schemas/Timestamp"
1768
+ }
1769
+ }
1770
+ },
1771
+ "ImageGrant": {
1772
+ "type": "object",
1773
+ "additionalProperties": false,
1774
+ "required": ["grantId", "access", "registry", "repository", "username", "secret", "expiresAt"],
1775
+ "properties": {
1776
+ "grantId": {
1777
+ "$ref": "#/components/schemas/Identifier"
1778
+ },
1779
+ "access": {
1780
+ "enum": ["pull", "push"]
1781
+ },
1782
+ "registry": {
1783
+ "$ref": "#/components/schemas/RegistryHost"
1784
+ },
1785
+ "repository": {
1786
+ "$ref": "#/components/schemas/OciRepository"
1787
+ },
1788
+ "username": {
1789
+ "$ref": "#/components/schemas/Identifier"
1790
+ },
1791
+ "secret": {
1792
+ "type": "string",
1793
+ "minLength": 32,
1794
+ "maxLength": 8192,
1795
+ "writeOnly": true
1796
+ },
1797
+ "expiresAt": {
1798
+ "$ref": "#/components/schemas/Timestamp"
1799
+ }
1800
+ }
1801
+ },
1802
+ "ImageBinding": {
1803
+ "type": "object",
1804
+ "additionalProperties": false,
1805
+ "required": ["candidate", "image"],
1806
+ "properties": {
1807
+ "candidate": {
1808
+ "$ref": "#/components/schemas/Identifier"
1809
+ },
1810
+ "image": {
1811
+ "$ref": "../schemas/runner-job.schema.json#/$defs/pinnedImage"
1812
+ }
1813
+ }
1814
+ },
1815
+ "JobIdentity": {
1816
+ "type": "object",
1817
+ "additionalProperties": false,
1818
+ "required": ["runnerId", "sessionId", "jobId", "attemptId", "leaseId", "fencingToken"],
1819
+ "properties": {
1820
+ "runnerId": {
1821
+ "$ref": "#/components/schemas/Identifier"
1822
+ },
1823
+ "sessionId": {
1824
+ "$ref": "#/components/schemas/Identifier"
1825
+ },
1826
+ "jobId": {
1827
+ "$ref": "#/components/schemas/Identifier"
1828
+ },
1829
+ "attemptId": {
1830
+ "$ref": "#/components/schemas/Identifier"
1831
+ },
1832
+ "leaseId": {
1833
+ "$ref": "#/components/schemas/Identifier"
1834
+ },
1835
+ "fencingToken": {
1836
+ "type": "string",
1837
+ "minLength": 16,
1838
+ "maxLength": 512
1839
+ }
1840
+ }
1841
+ },
1842
+ "AcceptJobRequest": {
1843
+ "type": "object",
1844
+ "additionalProperties": false,
1845
+ "required": ["acceptRequestId", "identity"],
1846
+ "properties": {
1847
+ "acceptRequestId": {
1848
+ "$ref": "#/components/schemas/Identifier"
1849
+ },
1850
+ "identity": {
1851
+ "$ref": "#/components/schemas/JobIdentity"
1852
+ }
1853
+ }
1854
+ },
1855
+ "JobHeartbeatRequest": {
1856
+ "type": "object",
1857
+ "additionalProperties": false,
1858
+ "required": ["identity"],
1859
+ "properties": {
1860
+ "identity": {
1861
+ "$ref": "#/components/schemas/JobIdentity"
1862
+ },
1863
+ "observedCancellationRequestId": {
1864
+ "$ref": "#/components/schemas/Identifier"
1865
+ }
1866
+ }
1867
+ },
1868
+ "CancellationDirective": {
1869
+ "type": "object",
1870
+ "additionalProperties": false,
1871
+ "required": ["requestId", "requestedAt", "reason", "terminateBy"],
1872
+ "properties": {
1873
+ "requestId": {
1874
+ "$ref": "#/components/schemas/Identifier"
1875
+ },
1876
+ "requestedAt": {
1877
+ "$ref": "#/components/schemas/Timestamp"
1878
+ },
1879
+ "reason": {
1880
+ "enum": ["user_requested", "superseded", "policy", "coordinator_shutdown"]
1881
+ },
1882
+ "terminateBy": {
1883
+ "$ref": "#/components/schemas/Timestamp"
1884
+ }
1885
+ }
1886
+ },
1887
+ "JobHeartbeatResponse": {
1888
+ "type": "object",
1889
+ "additionalProperties": false,
1890
+ "required": ["serverTime", "leaseExpiresAt"],
1891
+ "properties": {
1892
+ "serverTime": {
1893
+ "$ref": "#/components/schemas/Timestamp"
1894
+ },
1895
+ "leaseExpiresAt": {
1896
+ "$ref": "#/components/schemas/Timestamp"
1897
+ },
1898
+ "cancellation": {
1899
+ "$ref": "#/components/schemas/CancellationDirective"
1900
+ }
1901
+ }
1902
+ },
1903
+ "LogChunk": {
1904
+ "type": "object",
1905
+ "additionalProperties": false,
1906
+ "required": ["identity", "sequence", "stream", "data", "timestamp"],
1907
+ "properties": {
1908
+ "identity": {
1909
+ "$ref": "#/components/schemas/JobIdentity"
1910
+ },
1911
+ "sequence": {
1912
+ "type": "integer",
1913
+ "minimum": 0,
1914
+ "maximum": 9007199254740991
1915
+ },
1916
+ "stream": {
1917
+ "enum": ["stdout", "stderr", "runner"]
1918
+ },
1919
+ "data": {
1920
+ "type": "string",
1921
+ "maxLength": 65536
1922
+ },
1923
+ "timestamp": {
1924
+ "$ref": "#/components/schemas/Timestamp"
1925
+ }
1926
+ }
1927
+ },
1928
+ "LogAcknowledgement": {
1929
+ "type": "object",
1930
+ "additionalProperties": false,
1931
+ "required": ["serverTime", "nextSequence"],
1932
+ "properties": {
1933
+ "serverTime": {
1934
+ "$ref": "#/components/schemas/Timestamp"
1935
+ },
1936
+ "nextSequence": {
1937
+ "type": "integer",
1938
+ "minimum": 0,
1939
+ "maximum": 9007199254740991
1940
+ }
1941
+ }
1942
+ },
1943
+ "CompleteJobRequest": {
1944
+ "type": "object",
1945
+ "additionalProperties": false,
1946
+ "required": ["completionRequestId", "identity", "status", "exitCode", "startedAt", "completedAt"],
1947
+ "properties": {
1948
+ "completionRequestId": {
1949
+ "$ref": "#/components/schemas/Identifier"
1950
+ },
1951
+ "identity": {
1952
+ "$ref": "#/components/schemas/JobIdentity"
1953
+ },
1954
+ "status": {
1955
+ "enum": ["succeeded", "failed", "canceled", "timed_out", "system_error"]
1956
+ },
1957
+ "exitCode": {
1958
+ "anyOf": [
1959
+ {
1960
+ "type": "integer",
1961
+ "minimum": 0,
1962
+ "maximum": 255
1963
+ },
1964
+ {
1965
+ "type": "null"
1966
+ }
1967
+ ]
1968
+ },
1969
+ "startedAt": {
1970
+ "$ref": "#/components/schemas/Timestamp"
1971
+ },
1972
+ "completedAt": {
1973
+ "$ref": "#/components/schemas/Timestamp"
1974
+ },
1975
+ "cancellationRequestId": {
1976
+ "$ref": "#/components/schemas/Identifier"
1977
+ },
1978
+ "error": {
1979
+ "type": "string",
1980
+ "maxLength": 1024
1981
+ }
1982
+ },
1983
+ "allOf": [
1984
+ {
1985
+ "if": {
1986
+ "properties": {
1987
+ "status": {
1988
+ "const": "canceled"
1989
+ }
1990
+ },
1991
+ "required": ["status"]
1992
+ },
1993
+ "then": {
1994
+ "properties": {
1995
+ "cancellationRequestId": {}
1996
+ },
1997
+ "required": ["cancellationRequestId"]
1998
+ },
1999
+ "else": {
2000
+ "not": {
2001
+ "required": ["cancellationRequestId"]
2002
+ }
2003
+ }
2004
+ }
2005
+ ]
2006
+ },
2007
+ "CompleteJobResponse": {
2008
+ "type": "object",
2009
+ "additionalProperties": false,
2010
+ "required": ["serverTime", "accepted"],
2011
+ "properties": {
2012
+ "serverTime": {
2013
+ "$ref": "#/components/schemas/Timestamp"
2014
+ },
2015
+ "accepted": {
2016
+ "const": true
2017
+ }
2018
+ }
2019
+ },
2020
+ "AbandonJobRequest": {
2021
+ "type": "object",
2022
+ "additionalProperties": false,
2023
+ "required": ["abandonRequestId", "identity", "reason"],
2024
+ "properties": {
2025
+ "abandonRequestId": {
2026
+ "$ref": "#/components/schemas/Identifier"
2027
+ },
2028
+ "identity": {
2029
+ "$ref": "#/components/schemas/JobIdentity"
2030
+ },
2031
+ "reason": {
2032
+ "enum": ["runner_shutdown", "runner_error"]
2033
+ }
2034
+ }
2035
+ },
2036
+ "RecoverAttemptRequest": {
2037
+ "type": "object",
2038
+ "additionalProperties": false,
2039
+ "required": ["recoveryRequestId", "runnerId", "currentSessionId", "previousSessionId", "jobId", "attemptId", "reason"],
2040
+ "properties": {
2041
+ "recoveryRequestId": {
2042
+ "$ref": "#/components/schemas/Identifier"
2043
+ },
2044
+ "runnerId": {
2045
+ "$ref": "#/components/schemas/Identifier"
2046
+ },
2047
+ "currentSessionId": {
2048
+ "$ref": "#/components/schemas/Identifier"
2049
+ },
2050
+ "previousSessionId": {
2051
+ "$ref": "#/components/schemas/Identifier"
2052
+ },
2053
+ "jobId": {
2054
+ "$ref": "#/components/schemas/Identifier"
2055
+ },
2056
+ "attemptId": {
2057
+ "$ref": "#/components/schemas/Identifier"
2058
+ },
2059
+ "reason": {
2060
+ "const": "runner_restarted"
2061
+ }
2062
+ }
2063
+ },
2064
+ "TransferRecord": {
2065
+ "type": "object",
2066
+ "additionalProperties": false,
2067
+ "required": ["name", "format", "sha256", "sizeBytes", "extractedSizeBytes", "entryCount", "createdAt"],
2068
+ "properties": {
2069
+ "name": {
2070
+ "$ref": "#/components/schemas/Identifier"
2071
+ },
2072
+ "format": {
2073
+ "const": "tar.gz"
2074
+ },
2075
+ "sha256": {
2076
+ "$ref": "#/components/schemas/Sha256"
2077
+ },
2078
+ "sizeBytes": {
2079
+ "type": "integer",
2080
+ "minimum": 0,
2081
+ "maximum": 17179869184
2082
+ },
2083
+ "extractedSizeBytes": {
2084
+ "type": "integer",
2085
+ "minimum": 0,
2086
+ "maximum": 137438953472
2087
+ },
2088
+ "entryCount": {
2089
+ "type": "integer",
2090
+ "minimum": 0,
2091
+ "maximum": 1000000
2092
+ },
2093
+ "createdAt": {
2094
+ "$ref": "#/components/schemas/Timestamp"
2095
+ }
2096
+ }
2097
+ },
2098
+ "RecordImageRequest": {
2099
+ "type": "object",
2100
+ "additionalProperties": false,
2101
+ "required": ["recordRequestId", "identity", "manifestDigest", "mediaType", "sizeBytes", "platform"],
2102
+ "properties": {
2103
+ "recordRequestId": {
2104
+ "$ref": "#/components/schemas/Identifier"
2105
+ },
2106
+ "identity": {
2107
+ "$ref": "#/components/schemas/JobIdentity"
2108
+ },
2109
+ "manifestDigest": {
2110
+ "$ref": "#/components/schemas/OciDigest"
2111
+ },
2112
+ "mediaType": {
2113
+ "const": "application/vnd.oci.image.manifest.v1+json"
2114
+ },
2115
+ "sizeBytes": {
2116
+ "type": "integer",
2117
+ "minimum": 1,
2118
+ "maximum": 4194304
2119
+ },
2120
+ "platform": {
2121
+ "$ref": "../schemas/runner-job.schema.json#/$defs/platform"
2122
+ }
2123
+ }
2124
+ },
2125
+ "ImageRecord": {
2126
+ "type": "object",
2127
+ "additionalProperties": false,
2128
+ "required": ["registry", "repository", "manifestDigest", "mediaType", "sizeBytes", "platform", "createdAt"],
2129
+ "properties": {
2130
+ "registry": {
2131
+ "$ref": "#/components/schemas/RegistryHost"
2132
+ },
2133
+ "repository": {
2134
+ "$ref": "#/components/schemas/OciRepository"
2135
+ },
2136
+ "manifestDigest": {
2137
+ "$ref": "#/components/schemas/OciDigest"
2138
+ },
2139
+ "mediaType": {
2140
+ "const": "application/vnd.oci.image.manifest.v1+json"
2141
+ },
2142
+ "sizeBytes": {
2143
+ "type": "integer",
2144
+ "minimum": 1,
2145
+ "maximum": 4194304
2146
+ },
2147
+ "platform": {
2148
+ "$ref": "../schemas/runner-job.schema.json#/$defs/platform"
2149
+ },
2150
+ "createdAt": {
2151
+ "$ref": "#/components/schemas/Timestamp"
2152
+ }
2153
+ }
2154
+ },
2155
+ "ErrorResponse": {
2156
+ "type": "object",
2157
+ "additionalProperties": false,
2158
+ "required": ["error"],
2159
+ "properties": {
2160
+ "error": {
2161
+ "type": "object",
2162
+ "additionalProperties": false,
2163
+ "required": ["code", "message"],
2164
+ "properties": {
2165
+ "code": {
2166
+ "type": "string",
2167
+ "minLength": 1,
2168
+ "maxLength": 64,
2169
+ "pattern": "^[a-z][a-z0-9_]{0,63}$"
2170
+ },
2171
+ "message": {
2172
+ "type": "string",
2173
+ "minLength": 1,
2174
+ "maxLength": 512
2175
+ }
2176
+ }
2177
+ }
2178
+ }
2179
+ }
2180
+ }
2181
+ }
2182
+ }