@supernovae-st/nika 0.71.0 → 0.120.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.
package/openapi.json ADDED
@@ -0,0 +1,1797 @@
1
+ {
2
+ "components": {
3
+ "parameters": {
4
+ "IdempotencyKey": {
5
+ "in": "header",
6
+ "name": "Idempotency-Key",
7
+ "required": true,
8
+ "schema": {
9
+ "maxLength": 255,
10
+ "minLength": 1,
11
+ "type": "string"
12
+ }
13
+ },
14
+ "IfMatch": {
15
+ "in": "header",
16
+ "name": "If-Match",
17
+ "required": false,
18
+ "schema": {
19
+ "maxLength": 96,
20
+ "type": "string"
21
+ }
22
+ },
23
+ "IfNoneMatch": {
24
+ "in": "header",
25
+ "name": "If-None-Match",
26
+ "required": false,
27
+ "schema": {
28
+ "const": "*",
29
+ "type": "string"
30
+ }
31
+ },
32
+ "LastEventId": {
33
+ "in": "header",
34
+ "name": "Last-Event-ID",
35
+ "required": false,
36
+ "schema": {
37
+ "pattern": "^(0|[1-9][0-9]*)$",
38
+ "type": "string"
39
+ }
40
+ }
41
+ },
42
+ "schemas": {
43
+ "CheckByName": {
44
+ "additionalProperties": false,
45
+ "description": "Source-only Check by served name. Required launch inputs may remain unsupplied; caller inputs are accepted only on POST /v1/jobs and are refused here. Check does not execute an access plan.",
46
+ "properties": {
47
+ "access": {
48
+ "description": "Access pin, same vocabulary as `--access` (class or harness id). A pin never silently substitutes a metered seat.",
49
+ "maxLength": 64,
50
+ "minLength": 1,
51
+ "type": "string"
52
+ },
53
+ "workflow": {
54
+ "maxLength": 4096,
55
+ "minLength": 1,
56
+ "type": "string"
57
+ }
58
+ },
59
+ "required": [
60
+ "workflow"
61
+ ],
62
+ "type": "object"
63
+ },
64
+ "Error": {
65
+ "additionalProperties": false,
66
+ "properties": {
67
+ "error": {
68
+ "additionalProperties": false,
69
+ "properties": {
70
+ "code": {
71
+ "type": "string"
72
+ },
73
+ "message": {
74
+ "type": "string"
75
+ }
76
+ },
77
+ "required": [
78
+ "code",
79
+ "message"
80
+ ],
81
+ "type": "object"
82
+ }
83
+ },
84
+ "required": [
85
+ "error"
86
+ ],
87
+ "type": "object"
88
+ },
89
+ "ExecutionSnapshot": {
90
+ "additionalProperties": false,
91
+ "description": "Immutable byte-owned execution world — the body `nika check <file> --json --sdk-snapshot` prints (the engine is the one producer; a client never hashes). Unit bytes are canonical lowercase hexadecimal. `digest` and every unit `digest` are OPTIONAL caller-supplied integrity digests (canonical lowercase SHA-256 · a content assertion, never a signature): absent, the resident computes them and the receipt carries the result; present, they must match the bytes or the request is refused as `snapshot_tampered`. The decoded unit aggregate is limited to 16 MiB and the complete encoded request to 33 MiB. This object is the request body itself, not a path-bearing wrapper.",
92
+ "properties": {
93
+ "digest": {
94
+ "description": "Optional caller-supplied integrity digest of the world (never a signature)",
95
+ "pattern": "^[0-9a-f]{64}$",
96
+ "type": "string"
97
+ },
98
+ "format_version": {
99
+ "const": 1,
100
+ "type": "integer"
101
+ },
102
+ "root": {
103
+ "maxLength": 4096,
104
+ "minLength": 1,
105
+ "type": "string"
106
+ },
107
+ "units": {
108
+ "items": {
109
+ "additionalProperties": false,
110
+ "properties": {
111
+ "bytes_hex": {
112
+ "pattern": "^(?:[0-9a-f]{2})*$",
113
+ "type": "string"
114
+ },
115
+ "digest": {
116
+ "description": "Optional caller-supplied integrity digest of the unit (never a signature)",
117
+ "pattern": "^[0-9a-f]{64}$",
118
+ "type": "string"
119
+ },
120
+ "kind": {
121
+ "description": "0 root (the admitted workflow) · 1 child (a transitively invoked workflow) · 2 skill (an Agent Skill document) · 3 import (an opaque import the caller supplied)",
122
+ "maximum": 3,
123
+ "minimum": 0,
124
+ "type": "integer"
125
+ },
126
+ "path": {
127
+ "maxLength": 4096,
128
+ "minLength": 1,
129
+ "type": "string"
130
+ }
131
+ },
132
+ "required": [
133
+ "path",
134
+ "kind",
135
+ "bytes_hex"
136
+ ],
137
+ "type": "object"
138
+ },
139
+ "maxItems": 256,
140
+ "type": "array"
141
+ }
142
+ },
143
+ "required": [
144
+ "format_version",
145
+ "root",
146
+ "units"
147
+ ],
148
+ "type": "object"
149
+ },
150
+ "Health": {
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "api_version": {
154
+ "minLength": 1,
155
+ "type": "string"
156
+ },
157
+ "buildSha": {
158
+ "minLength": 1,
159
+ "type": "string"
160
+ },
161
+ "build_sha": {
162
+ "minLength": 1,
163
+ "type": "string"
164
+ },
165
+ "checkReportVersion": {
166
+ "minimum": 1,
167
+ "type": "integer"
168
+ },
169
+ "engineVersion": {
170
+ "minLength": 1,
171
+ "type": "string"
172
+ },
173
+ "engine_version": {
174
+ "minLength": 1,
175
+ "type": "string"
176
+ },
177
+ "eventFormatVersion": {
178
+ "minimum": 1,
179
+ "type": "integer"
180
+ },
181
+ "machineProtocolVersion": {
182
+ "minimum": 1,
183
+ "type": "integer"
184
+ },
185
+ "service": {
186
+ "const": "nika-serve",
187
+ "type": "string"
188
+ },
189
+ "snapshotFormatVersion": {
190
+ "minimum": 1,
191
+ "type": "integer"
192
+ },
193
+ "specSha": {
194
+ "minLength": 1,
195
+ "type": "string"
196
+ },
197
+ "spec_sha": {
198
+ "minLength": 1,
199
+ "type": "string"
200
+ },
201
+ "status": {
202
+ "const": "ok",
203
+ "type": "string"
204
+ },
205
+ "storeFormatVersion": {
206
+ "additionalProperties": false,
207
+ "description": "Durable store formats this resident reads and writes; independent of the HTTP and event protocol versions.",
208
+ "properties": {
209
+ "jobs": {
210
+ "examples": [
211
+ 3
212
+ ],
213
+ "minimum": 1,
214
+ "type": "integer"
215
+ },
216
+ "schedules": {
217
+ "examples": [
218
+ 1
219
+ ],
220
+ "minimum": 1,
221
+ "type": "integer"
222
+ }
223
+ },
224
+ "required": [
225
+ "jobs",
226
+ "schedules"
227
+ ],
228
+ "type": "object"
229
+ },
230
+ "supportedCapabilities": {
231
+ "items": {
232
+ "type": "string"
233
+ },
234
+ "type": "array",
235
+ "uniqueItems": true
236
+ },
237
+ "traceFormatVersion": {
238
+ "minimum": 1,
239
+ "type": "integer"
240
+ }
241
+ },
242
+ "required": [
243
+ "status",
244
+ "service",
245
+ "engine_version",
246
+ "build_sha",
247
+ "spec_sha",
248
+ "api_version",
249
+ "engineVersion",
250
+ "buildSha",
251
+ "specSha",
252
+ "machineProtocolVersion",
253
+ "snapshotFormatVersion",
254
+ "checkReportVersion",
255
+ "eventFormatVersion",
256
+ "traceFormatVersion",
257
+ "storeFormatVersion",
258
+ "supportedCapabilities"
259
+ ],
260
+ "type": "object"
261
+ },
262
+ "Job": {
263
+ "additionalProperties": false,
264
+ "properties": {
265
+ "error": {
266
+ "additionalProperties": false,
267
+ "properties": {
268
+ "code": {
269
+ "type": "string"
270
+ },
271
+ "message": {
272
+ "type": "string"
273
+ }
274
+ },
275
+ "required": [
276
+ "code",
277
+ "message"
278
+ ],
279
+ "type": "object"
280
+ },
281
+ "evidence": {
282
+ "$ref": "#/components/schemas/JournalEvidence"
283
+ },
284
+ "execution_id": {
285
+ "type": "string"
286
+ },
287
+ "id": {
288
+ "format": "uuid",
289
+ "type": "string"
290
+ },
291
+ "outputs": {
292
+ "additionalProperties": true,
293
+ "description": "Declared workflow outputs; present only after settlement when supplied by the execution adapter",
294
+ "type": "object"
295
+ },
296
+ "receipt": {
297
+ "$ref": "#/components/schemas/JobReceipt"
298
+ },
299
+ "settlement": {
300
+ "$ref": "#/components/schemas/RunSettlement"
301
+ },
302
+ "status": {
303
+ "$ref": "#/components/schemas/JobStatus"
304
+ },
305
+ "trace_id": {
306
+ "type": "string"
307
+ }
308
+ },
309
+ "required": [
310
+ "id",
311
+ "status"
312
+ ],
313
+ "type": "object"
314
+ },
315
+ "JobByName": {
316
+ "additionalProperties": false,
317
+ "description": "The by-name form (ADR-131): a workflow the served registry lists (GET /v1/workflows · project-root-relative, `.nika`). The resident captures its world exactly as a schedule does — the one owner of the snapshot and its digest domain. Idempotency binds to these request bytes. Optional `access` is the same pin as CLI `--access` (a pin is a pin). Absent: the resident's unpinned plan. Snapshot bodies reject both access and inputs overlays, including null or empty maps. Optional inputs are literal JSON values checked against declared keys, types and required values before a job exists; strings are never CLI @env instructions or expressions.",
318
+ "properties": {
319
+ "access": {
320
+ "description": "Access pin, same vocabulary as `--access` (class or harness id). A pin never silently substitutes a metered seat.",
321
+ "maxLength": 64,
322
+ "minLength": 1,
323
+ "type": "string"
324
+ },
325
+ "inputs": {
326
+ "additionalProperties": true,
327
+ "description": "Literal JSON overrides for declared workflow inputs. Unknown keys, wrong types and missing required values refuse with 422; defaults remain authored. A present null is refused. Inputs bind exact request identity and survive durable queue recovery; workflow bytes are unchanged.",
328
+ "type": "object"
329
+ },
330
+ "workflow": {
331
+ "maxLength": 4096,
332
+ "minLength": 1,
333
+ "type": "string"
334
+ }
335
+ },
336
+ "required": [
337
+ "workflow"
338
+ ],
339
+ "type": "object"
340
+ },
341
+ "JobEvent": {
342
+ "additionalProperties": false,
343
+ "properties": {
344
+ "at": {
345
+ "description": "When the resident admitted the event (RFC 3339 · UTC). Outside the event's hash chain; absent on an event written before the journal was dated.",
346
+ "format": "date-time",
347
+ "type": "string"
348
+ },
349
+ "code": {
350
+ "type": "string"
351
+ },
352
+ "evidence": {
353
+ "$ref": "#/components/schemas/JournalEvidence"
354
+ },
355
+ "kind": {
356
+ "anyOf": [
357
+ {
358
+ "enum": [
359
+ "execution.queued",
360
+ "execution.started",
361
+ "execution.prepared",
362
+ "execution.requeued",
363
+ "execution.settled",
364
+ "execution.cancelled",
365
+ "execution.interrupted",
366
+ "execution.refused",
367
+ "execution.aborted_before_claim",
368
+ "approval_decided"
369
+ ],
370
+ "type": "string"
371
+ },
372
+ {
373
+ "type": "null"
374
+ }
375
+ ],
376
+ "description": "The resident's event vocabulary: execution.<word> (queued · started · prepared · requeued · settled · cancelled · interrupted · refused · aborted_before_claim), plus the approval_decided frame the journal admits. Null on a payload that carries no kind."
377
+ },
378
+ "message": {
379
+ "type": "string"
380
+ },
381
+ "outputs": {
382
+ "additionalProperties": true,
383
+ "type": "object"
384
+ },
385
+ "receipt": {
386
+ "$ref": "#/components/schemas/JobReceipt"
387
+ },
388
+ "sequence": {
389
+ "minimum": 1,
390
+ "type": "integer"
391
+ },
392
+ "settlement": {
393
+ "$ref": "#/components/schemas/RunSettlement"
394
+ },
395
+ "status": {
396
+ "anyOf": [
397
+ {
398
+ "$ref": "#/components/schemas/JobStatus"
399
+ },
400
+ {
401
+ "type": "null"
402
+ }
403
+ ]
404
+ }
405
+ },
406
+ "required": [
407
+ "sequence",
408
+ "kind",
409
+ "status"
410
+ ],
411
+ "type": "object"
412
+ },
413
+ "JobOrigin": {
414
+ "oneOf": [
415
+ {
416
+ "additionalProperties": false,
417
+ "properties": {
418
+ "kind": {
419
+ "const": "manual",
420
+ "type": "string"
421
+ }
422
+ },
423
+ "required": [
424
+ "kind"
425
+ ],
426
+ "type": "object"
427
+ },
428
+ {
429
+ "additionalProperties": false,
430
+ "properties": {
431
+ "arm_generation": {
432
+ "pattern": "^[0-9a-f]{64}$",
433
+ "type": "string"
434
+ },
435
+ "decision": {
436
+ "enum": [
437
+ "scheduled",
438
+ "catch_up"
439
+ ],
440
+ "type": "string"
441
+ },
442
+ "fired_at": {
443
+ "format": "date-time",
444
+ "type": "string"
445
+ },
446
+ "kind": {
447
+ "const": "schedule",
448
+ "type": "string"
449
+ },
450
+ "schedule_id": {
451
+ "description": "Origin-local identifier, bounded to 255 UTF-8 bytes by the server",
452
+ "maxLength": 255,
453
+ "minLength": 1,
454
+ "type": "string"
455
+ },
456
+ "schedule_origin": {
457
+ "enum": [
458
+ "project",
459
+ "api"
460
+ ],
461
+ "type": "string"
462
+ },
463
+ "schedule_revision": {
464
+ "pattern": "^sha256:[0-9a-f]{64}$",
465
+ "type": "string"
466
+ },
467
+ "scheduled_for": {
468
+ "format": "date-time",
469
+ "type": "string"
470
+ },
471
+ "slot_id": {
472
+ "pattern": "^[0-9a-f]{64}$",
473
+ "type": "string"
474
+ }
475
+ },
476
+ "required": [
477
+ "kind",
478
+ "schedule_origin",
479
+ "schedule_id",
480
+ "schedule_revision",
481
+ "slot_id",
482
+ "decision",
483
+ "scheduled_for",
484
+ "fired_at",
485
+ "arm_generation"
486
+ ],
487
+ "type": "object"
488
+ }
489
+ ]
490
+ },
491
+ "JobReceipt": {
492
+ "additionalProperties": false,
493
+ "description": "Terminal binding to the exact immutable admitted execution",
494
+ "properties": {
495
+ "chain_head": {
496
+ "minLength": 1,
497
+ "type": "string"
498
+ },
499
+ "execution_id": {
500
+ "minLength": 1,
501
+ "type": "string"
502
+ },
503
+ "job_id": {
504
+ "format": "uuid",
505
+ "type": "string"
506
+ },
507
+ "origin": {
508
+ "$ref": "#/components/schemas/JobOrigin"
509
+ },
510
+ "snapshot_digest": {
511
+ "pattern": "^[0-9a-f]{64}$",
512
+ "type": "string"
513
+ },
514
+ "trace_id": {
515
+ "minLength": 1,
516
+ "type": "string"
517
+ }
518
+ },
519
+ "required": [
520
+ "job_id",
521
+ "execution_id",
522
+ "trace_id",
523
+ "snapshot_digest"
524
+ ],
525
+ "type": "object"
526
+ },
527
+ "JobStatus": {
528
+ "description": "queued and running: the resident owns the execution. interrupted: execution ownership was lost and effect settlement is unknown — an EVIDENCE state (the journal is INCOMPLETE), never a run state (ADR-129). paused, succeeded, failed and cancelled: the run's own settlement, the words its terminal frame carries (ADR-128).",
529
+ "enum": [
530
+ "queued",
531
+ "running",
532
+ "interrupted",
533
+ "paused",
534
+ "succeeded",
535
+ "failed",
536
+ "cancelled"
537
+ ],
538
+ "type": "string"
539
+ },
540
+ "JobStatusOnly": {
541
+ "additionalProperties": false,
542
+ "description": "Status only. Redacted diagnosis lives on GET /v1/jobs/{id} and SSE, never here.",
543
+ "properties": {
544
+ "status": {
545
+ "$ref": "#/components/schemas/JobStatus"
546
+ }
547
+ },
548
+ "required": [
549
+ "status"
550
+ ],
551
+ "type": "object"
552
+ },
553
+ "JournalEvidence": {
554
+ "additionalProperties": false,
555
+ "description": "Reported journal delivery loss, independent of execution status. The reason classifies the mirror's first error without exposing OS text or paths. Absence is not a claim that a journal exists.",
556
+ "properties": {
557
+ "reason": {
558
+ "enum": [
559
+ "write_failed",
560
+ "record_refused"
561
+ ],
562
+ "type": "string"
563
+ },
564
+ "status": {
565
+ "const": "mirror_lost",
566
+ "type": "string"
567
+ }
568
+ },
569
+ "required": [
570
+ "status",
571
+ "reason"
572
+ ],
573
+ "type": "object"
574
+ },
575
+ "RunSettlement": {
576
+ "additionalProperties": false,
577
+ "description": "The run's settlement (ADR-128), built once by the runtime and projected whole: the state word every door speaks, why, the elapsed time on the kernel clock, the task tally, the spend with its qualifier, the failure named. Unknown cost is never zero: `total_cost_usd` is absent when nothing was metered. Present on the terminal event and durable job response of a job whose runtime settled; absent when the resident lost the execution (interrupted) or refused it before any task. Reattachment and idempotent admission replay project the same hash-bound terminal event, never a new settlement.",
578
+ "properties": {
579
+ "cause": {
580
+ "enum": [
581
+ "normal",
582
+ "human_gate",
583
+ "task_failed",
584
+ "output_contract",
585
+ "budget",
586
+ "operator",
587
+ "refused"
588
+ ],
589
+ "type": "string"
590
+ },
591
+ "elapsed_ms": {
592
+ "minimum": 0,
593
+ "type": "integer"
594
+ },
595
+ "error": {
596
+ "additionalProperties": false,
597
+ "properties": {
598
+ "code": {
599
+ "type": "string"
600
+ },
601
+ "message": {
602
+ "type": "string"
603
+ },
604
+ "task": {
605
+ "description": "The task that failed · absent for a run-level cause",
606
+ "type": "string"
607
+ }
608
+ },
609
+ "required": [
610
+ "code",
611
+ "message"
612
+ ],
613
+ "type": "object"
614
+ },
615
+ "spend": {
616
+ "additionalProperties": false,
617
+ "properties": {
618
+ "by_source": {
619
+ "additionalProperties": {
620
+ "type": "number"
621
+ },
622
+ "type": "object"
623
+ },
624
+ "priced_calls": {
625
+ "minimum": 0,
626
+ "type": "integer"
627
+ },
628
+ "pricing_as_of": {
629
+ "type": "string"
630
+ },
631
+ "qualifier": {
632
+ "enum": [
633
+ "priced",
634
+ "partially_priced",
635
+ "unpriced",
636
+ "unmetered"
637
+ ],
638
+ "type": "string"
639
+ },
640
+ "total_cost_usd": {
641
+ "description": "Present only when at least one leaf metered real spend",
642
+ "minimum": 0,
643
+ "type": "number"
644
+ },
645
+ "unpriced_calls": {
646
+ "minimum": 0,
647
+ "type": "integer"
648
+ }
649
+ },
650
+ "required": [
651
+ "priced_calls",
652
+ "unpriced_calls",
653
+ "qualifier"
654
+ ],
655
+ "type": "object"
656
+ },
657
+ "status": {
658
+ "enum": [
659
+ "succeeded",
660
+ "failed",
661
+ "paused",
662
+ "cancelled"
663
+ ],
664
+ "type": "string"
665
+ },
666
+ "tasks": {
667
+ "additionalProperties": false,
668
+ "properties": {
669
+ "cancelled": {
670
+ "minimum": 0,
671
+ "type": "integer"
672
+ },
673
+ "failed": {
674
+ "minimum": 0,
675
+ "type": "integer"
676
+ },
677
+ "never_started": {
678
+ "description": "Cancelled at the boundary without ever starting (counted in `cancelled` too)",
679
+ "minimum": 0,
680
+ "type": "integer"
681
+ },
682
+ "ok": {
683
+ "description": "A recovered task IS a success (counted here too)",
684
+ "minimum": 0,
685
+ "type": "integer"
686
+ },
687
+ "recovered": {
688
+ "minimum": 0,
689
+ "type": "integer"
690
+ },
691
+ "skipped": {
692
+ "minimum": 0,
693
+ "type": "integer"
694
+ },
695
+ "total": {
696
+ "minimum": 0,
697
+ "type": "integer"
698
+ }
699
+ },
700
+ "required": [
701
+ "total",
702
+ "ok",
703
+ "failed",
704
+ "recovered",
705
+ "skipped",
706
+ "cancelled",
707
+ "never_started"
708
+ ],
709
+ "type": "object"
710
+ }
711
+ },
712
+ "required": [
713
+ "status",
714
+ "cause",
715
+ "spend"
716
+ ],
717
+ "type": "object"
718
+ },
719
+ "ScheduleApply": {
720
+ "additionalProperties": false,
721
+ "properties": {
722
+ "applied": {
723
+ "const": true,
724
+ "type": "boolean"
725
+ },
726
+ "changed": {
727
+ "type": "boolean"
728
+ },
729
+ "status": {
730
+ "$ref": "#/components/schemas/ScheduleStatus"
731
+ }
732
+ },
733
+ "required": [
734
+ "applied",
735
+ "changed",
736
+ "status"
737
+ ],
738
+ "type": "object"
739
+ },
740
+ "SchedulePut": {
741
+ "additionalProperties": false,
742
+ "properties": {
743
+ "active": {
744
+ "type": "boolean"
745
+ },
746
+ "afterSkip": {
747
+ "enum": [
748
+ "next_slot",
749
+ "on_completion"
750
+ ],
751
+ "type": "string"
752
+ },
753
+ "jitter": {
754
+ "enum": [
755
+ "hash"
756
+ ],
757
+ "type": "string"
758
+ },
759
+ "maxCostUsd": {
760
+ "exclusiveMinimum": 0,
761
+ "type": "number"
762
+ },
763
+ "maxLatenessSeconds": {
764
+ "minimum": 0,
765
+ "type": "integer"
766
+ },
767
+ "missed": {
768
+ "enum": [
769
+ "catch-up",
770
+ "catch-up-once",
771
+ "skip"
772
+ ],
773
+ "type": "string"
774
+ },
775
+ "overlap": {
776
+ "enum": [
777
+ "skip",
778
+ "queue",
779
+ "replace"
780
+ ],
781
+ "type": "string"
782
+ },
783
+ "pauseReason": {
784
+ "maxLength": 1024,
785
+ "type": "string"
786
+ },
787
+ "pauseUntil": {
788
+ "format": "date",
789
+ "type": "string"
790
+ },
791
+ "tolerance": {
792
+ "type": "string"
793
+ },
794
+ "when": {
795
+ "oneOf": [
796
+ {
797
+ "additionalProperties": false,
798
+ "properties": {
799
+ "at": {
800
+ "format": "date-time",
801
+ "type": "string"
802
+ },
803
+ "kind": {
804
+ "const": "once"
805
+ }
806
+ },
807
+ "required": [
808
+ "kind",
809
+ "at"
810
+ ],
811
+ "type": "object"
812
+ },
813
+ {
814
+ "additionalProperties": false,
815
+ "properties": {
816
+ "expression": {
817
+ "maxLength": 4096,
818
+ "type": "string"
819
+ },
820
+ "kind": {
821
+ "const": "cadence"
822
+ }
823
+ },
824
+ "required": [
825
+ "kind",
826
+ "expression"
827
+ ],
828
+ "type": "object"
829
+ }
830
+ ]
831
+ },
832
+ "workflow": {
833
+ "maxLength": 1024,
834
+ "pattern": "^[^/].*\\.nika$",
835
+ "type": "string"
836
+ }
837
+ },
838
+ "required": [
839
+ "workflow",
840
+ "when",
841
+ "maxCostUsd",
842
+ "missed"
843
+ ],
844
+ "type": "object"
845
+ },
846
+ "ScheduleStatus": {
847
+ "additionalProperties": true,
848
+ "description": "Normalized definition, origin, distinct schedule revision, active/pause state, due verdict, bounded next slots with shift evidence, earliest wake hint, and last durable decision.",
849
+ "type": "object"
850
+ },
851
+ "SnapshotValidationAck": {
852
+ "additionalProperties": false,
853
+ "description": "Compact remote acknowledgement that the exact snapshot was revalidated. This is not the engine's public full check report; SDK callers retain the engine-owned report captured with the snapshot and return it only after this acknowledgement succeeds.",
854
+ "properties": {
855
+ "root": {
856
+ "minLength": 1,
857
+ "type": "string"
858
+ },
859
+ "snapshot_digest": {
860
+ "pattern": "^[0-9a-f]{64}$",
861
+ "type": "string"
862
+ },
863
+ "status": {
864
+ "const": "accepted",
865
+ "type": "string"
866
+ },
867
+ "units": {
868
+ "minimum": 1,
869
+ "type": "integer"
870
+ }
871
+ },
872
+ "required": [
873
+ "status",
874
+ "snapshot_digest",
875
+ "root",
876
+ "units"
877
+ ],
878
+ "type": "object"
879
+ },
880
+ "TraceVerification": {
881
+ "additionalProperties": false,
882
+ "description": "Run-scoped verdict on the journal the resident wrote for the job, through the ONE verifier `nika trace verify --json` runs. `verdict` is the CLI's headline word: the attained tier (ok · sealed · anchored · replayed), incomplete for a journal with no terminal frame (the writer's liveness rides `reason`), tampered for a buried seal, broken for an edited chain, and the CLI's refusal classes; `unavailable` only when no journal exists for the job (refused before its first event · queued · a backend keeping none). `reason` is the machine class beside it (the seal tier under a ladder verdict). The CLI's own document rides verbatim (exit · chain · seal · anchor · replay · lines); a filesystem path is never returned.",
883
+ "properties": {
884
+ "anchor": {
885
+ "additionalProperties": true,
886
+ "type": "object"
887
+ },
888
+ "chain": {
889
+ "additionalProperties": true,
890
+ "description": "events · head · headline (intact · torn · incomplete) · liveness (alive · dead · unknown · null)",
891
+ "type": "object"
892
+ },
893
+ "exit": {
894
+ "description": "The CLI's exit class: 0 the reported tier holds · 2 a forged or edited journal · 3 the environment (unchained · unreadable · a missing input) · 5 incomplete lifecycle evidence",
895
+ "enum": [
896
+ 0,
897
+ 2,
898
+ 3,
899
+ 5
900
+ ],
901
+ "type": "integer"
902
+ },
903
+ "lines": {
904
+ "description": "The CLI's ladder lines, the journal path replaced by <journal>",
905
+ "items": {
906
+ "type": "string"
907
+ },
908
+ "type": "array"
909
+ },
910
+ "reason": {
911
+ "enum": [
912
+ "run_not_terminal",
913
+ "trace_journal_unavailable",
914
+ "sealed",
915
+ "unsealed",
916
+ "forged",
917
+ "buried",
918
+ "unattributable",
919
+ "writer_alive",
920
+ "writer_dead",
921
+ "writer_unknown",
922
+ "buried_seal",
923
+ "broken",
924
+ "unchained",
925
+ "empty",
926
+ "unreadable",
927
+ "refused",
928
+ "line_over_long",
929
+ "unknown"
930
+ ],
931
+ "type": "string"
932
+ },
933
+ "replay": {
934
+ "additionalProperties": true,
935
+ "type": "object"
936
+ },
937
+ "seal": {
938
+ "additionalProperties": true,
939
+ "description": "tier (unsealed · sealed · forged · buried · unattributable) and the tier's facts",
940
+ "type": "object"
941
+ },
942
+ "trace_id": {
943
+ "minLength": 1,
944
+ "type": "string"
945
+ },
946
+ "verdict": {
947
+ "enum": [
948
+ "unavailable",
949
+ "ok",
950
+ "sealed",
951
+ "anchored",
952
+ "replayed",
953
+ "incomplete",
954
+ "tampered",
955
+ "broken",
956
+ "unchained",
957
+ "empty",
958
+ "unreadable",
959
+ "refused",
960
+ "line-over-long",
961
+ "unknown"
962
+ ],
963
+ "type": "string"
964
+ },
965
+ "verify_version": {
966
+ "minimum": 1,
967
+ "type": "integer"
968
+ }
969
+ },
970
+ "required": [
971
+ "verdict",
972
+ "reason"
973
+ ],
974
+ "type": "object"
975
+ },
976
+ "WorkflowList": {
977
+ "additionalProperties": false,
978
+ "properties": {
979
+ "workflows": {
980
+ "items": {
981
+ "minLength": 1,
982
+ "type": "string"
983
+ },
984
+ "type": "array"
985
+ }
986
+ },
987
+ "required": [
988
+ "workflows"
989
+ ],
990
+ "type": "object"
991
+ },
992
+ "WorkflowMetadata": {
993
+ "additionalProperties": false,
994
+ "properties": {
995
+ "workflow": {
996
+ "minLength": 1,
997
+ "type": "string"
998
+ }
999
+ },
1000
+ "required": [
1001
+ "workflow"
1002
+ ],
1003
+ "type": "object"
1004
+ }
1005
+ },
1006
+ "securitySchemes": {
1007
+ "bearerAuth": {
1008
+ "description": "Exactly one Authorization: Bearer value from the token file",
1009
+ "scheme": "bearer",
1010
+ "type": "http"
1011
+ }
1012
+ }
1013
+ },
1014
+ "info": {
1015
+ "description": "Authenticated loopback remote execution and declarative schedules. Artifacts, schedule list/delete/trigger/backfill, /v1/arm, and POST /v1/run are absent.",
1016
+ "title": "nika serve",
1017
+ "version": "0.120.0"
1018
+ },
1019
+ "openapi": "3.1.0",
1020
+ "paths": {
1021
+ "/health": {
1022
+ "get": {
1023
+ "responses": {
1024
+ "200": {
1025
+ "content": {
1026
+ "application/json": {
1027
+ "schema": {
1028
+ "$ref": "#/components/schemas/Health"
1029
+ }
1030
+ }
1031
+ },
1032
+ "description": "Engine identity only"
1033
+ }
1034
+ },
1035
+ "security": [],
1036
+ "summary": "Public process liveness"
1037
+ }
1038
+ },
1039
+ "/v1/check": {
1040
+ "post": {
1041
+ "description": "Runs the same admission as POST /v1/jobs (ADR-131 · both forms) over the exact request body, and creates nothing.",
1042
+ "requestBody": {
1043
+ "content": {
1044
+ "application/json": {
1045
+ "schema": {
1046
+ "oneOf": [
1047
+ {
1048
+ "$ref": "#/components/schemas/CheckByName"
1049
+ },
1050
+ {
1051
+ "$ref": "#/components/schemas/ExecutionSnapshot"
1052
+ }
1053
+ ]
1054
+ }
1055
+ }
1056
+ },
1057
+ "required": true
1058
+ },
1059
+ "responses": {
1060
+ "200": {
1061
+ "content": {
1062
+ "application/json": {
1063
+ "schema": {
1064
+ "$ref": "#/components/schemas/SnapshotValidationAck"
1065
+ }
1066
+ }
1067
+ },
1068
+ "description": "Compact snapshot validation acknowledgement, not the full engine check report"
1069
+ },
1070
+ "401": {
1071
+ "content": {
1072
+ "application/json": {
1073
+ "schema": {
1074
+ "$ref": "#/components/schemas/Error"
1075
+ }
1076
+ }
1077
+ },
1078
+ "description": "Error envelope"
1079
+ },
1080
+ "408": {
1081
+ "content": {
1082
+ "application/json": {
1083
+ "schema": {
1084
+ "$ref": "#/components/schemas/Error"
1085
+ }
1086
+ }
1087
+ },
1088
+ "description": "Request deadline"
1089
+ },
1090
+ "413": {
1091
+ "content": {
1092
+ "application/json": {
1093
+ "schema": {
1094
+ "$ref": "#/components/schemas/Error"
1095
+ }
1096
+ }
1097
+ },
1098
+ "description": "Encoded body or decoded snapshot resource limit"
1099
+ },
1100
+ "415": {
1101
+ "content": {
1102
+ "application/json": {
1103
+ "schema": {
1104
+ "$ref": "#/components/schemas/Error"
1105
+ }
1106
+ }
1107
+ },
1108
+ "description": "Content-Type or Content-Encoding refused"
1109
+ },
1110
+ "422": {
1111
+ "content": {
1112
+ "application/json": {
1113
+ "schema": {
1114
+ "$ref": "#/components/schemas/Error"
1115
+ }
1116
+ }
1117
+ },
1118
+ "description": "Malformed, unsupported, tampered, or semantically refused snapshot"
1119
+ }
1120
+ },
1121
+ "summary": "Judge a workflow without creating a job — by served name, or as immutable snapshot bytes"
1122
+ }
1123
+ },
1124
+ "/v1/jobs": {
1125
+ "post": {
1126
+ "description": "Two forms, one admission (ADR-131). `{\"workflow\": \"<name>\"}` names a workflow the served registry lists: the resident captures its world through ExecutionService, exactly as a schedule does. Optional `access` on that form is CLI `--access` for this job only. A snapshot body is the world `nika check <file> --json --sdk-snapshot` prints, decoded and readmitted through the same ExecutionService; its digests are optional caller-supplied integrity digests (a content assertion, never a signature). Snapshot jobs inherit the resident's unpinned plan. The server never interprets a caller filesystem path. Idempotency binds to the exact request bytes.",
1127
+ "parameters": [
1128
+ {
1129
+ "$ref": "#/components/parameters/IdempotencyKey"
1130
+ }
1131
+ ],
1132
+ "requestBody": {
1133
+ "content": {
1134
+ "application/json": {
1135
+ "schema": {
1136
+ "oneOf": [
1137
+ {
1138
+ "$ref": "#/components/schemas/JobByName"
1139
+ },
1140
+ {
1141
+ "$ref": "#/components/schemas/ExecutionSnapshot"
1142
+ }
1143
+ ]
1144
+ }
1145
+ }
1146
+ },
1147
+ "required": true
1148
+ },
1149
+ "responses": {
1150
+ "200": {
1151
+ "content": {
1152
+ "application/json": {
1153
+ "schema": {
1154
+ "$ref": "#/components/schemas/Job"
1155
+ }
1156
+ }
1157
+ },
1158
+ "description": "Idempotent replay"
1159
+ },
1160
+ "202": {
1161
+ "content": {
1162
+ "application/json": {
1163
+ "schema": {
1164
+ "$ref": "#/components/schemas/Job"
1165
+ }
1166
+ }
1167
+ },
1168
+ "description": "Created"
1169
+ },
1170
+ "400": {
1171
+ "content": {
1172
+ "application/json": {
1173
+ "schema": {
1174
+ "$ref": "#/components/schemas/Error"
1175
+ }
1176
+ }
1177
+ },
1178
+ "description": "Invalid idempotency key"
1179
+ },
1180
+ "401": {
1181
+ "content": {
1182
+ "application/json": {
1183
+ "schema": {
1184
+ "$ref": "#/components/schemas/Error"
1185
+ }
1186
+ }
1187
+ },
1188
+ "description": "Error envelope"
1189
+ },
1190
+ "408": {
1191
+ "content": {
1192
+ "application/json": {
1193
+ "schema": {
1194
+ "$ref": "#/components/schemas/Error"
1195
+ }
1196
+ }
1197
+ },
1198
+ "description": "Request deadline"
1199
+ },
1200
+ "409": {
1201
+ "content": {
1202
+ "application/json": {
1203
+ "schema": {
1204
+ "$ref": "#/components/schemas/Error"
1205
+ }
1206
+ }
1207
+ },
1208
+ "description": "Idempotency key already bound to another request"
1209
+ },
1210
+ "413": {
1211
+ "content": {
1212
+ "application/json": {
1213
+ "schema": {
1214
+ "$ref": "#/components/schemas/Error"
1215
+ }
1216
+ }
1217
+ },
1218
+ "description": "Encoded body or decoded snapshot resource limit"
1219
+ },
1220
+ "415": {
1221
+ "content": {
1222
+ "application/json": {
1223
+ "schema": {
1224
+ "$ref": "#/components/schemas/Error"
1225
+ }
1226
+ }
1227
+ },
1228
+ "description": "Content-Type or Content-Encoding refused"
1229
+ },
1230
+ "422": {
1231
+ "content": {
1232
+ "application/json": {
1233
+ "schema": {
1234
+ "$ref": "#/components/schemas/Error"
1235
+ }
1236
+ }
1237
+ },
1238
+ "description": "Malformed, unsupported, tampered, or semantically refused snapshot"
1239
+ },
1240
+ "503": {
1241
+ "content": {
1242
+ "application/json": {
1243
+ "schema": {
1244
+ "$ref": "#/components/schemas/Error"
1245
+ }
1246
+ }
1247
+ },
1248
+ "description": "Execution queue or durable store unavailable"
1249
+ },
1250
+ "507": {
1251
+ "content": {
1252
+ "application/json": {
1253
+ "schema": {
1254
+ "$ref": "#/components/schemas/Error"
1255
+ }
1256
+ }
1257
+ },
1258
+ "description": "Durable job capacity exhausted"
1259
+ }
1260
+ },
1261
+ "summary": "Admit a workflow as a durable job — by served name, or as immutable snapshot bytes"
1262
+ }
1263
+ },
1264
+ "/v1/jobs/{id}": {
1265
+ "get": {
1266
+ "parameters": [
1267
+ {
1268
+ "in": "path",
1269
+ "name": "id",
1270
+ "required": true,
1271
+ "schema": {
1272
+ "format": "uuid",
1273
+ "type": "string"
1274
+ }
1275
+ }
1276
+ ],
1277
+ "responses": {
1278
+ "200": {
1279
+ "content": {
1280
+ "application/json": {
1281
+ "schema": {
1282
+ "$ref": "#/components/schemas/Job"
1283
+ }
1284
+ }
1285
+ },
1286
+ "description": "Job"
1287
+ },
1288
+ "401": {
1289
+ "content": {
1290
+ "application/json": {
1291
+ "schema": {
1292
+ "$ref": "#/components/schemas/Error"
1293
+ }
1294
+ }
1295
+ },
1296
+ "description": "Error envelope"
1297
+ },
1298
+ "404": {
1299
+ "content": {
1300
+ "application/json": {
1301
+ "schema": {
1302
+ "$ref": "#/components/schemas/Error"
1303
+ }
1304
+ }
1305
+ },
1306
+ "description": "Error envelope"
1307
+ }
1308
+ },
1309
+ "summary": "Job identity and status"
1310
+ }
1311
+ },
1312
+ "/v1/jobs/{id}/cancel": {
1313
+ "post": {
1314
+ "description": "A queued job cancels atomically before execution claims it. An active job receives the run-scoped cancellation signal and returns 202 until its execution owner settles: the result may be success, failure or cancellation; expired grace means interrupted, never an invented cancellation. A paused or final observation returns its existing result unchanged.",
1315
+ "parameters": [
1316
+ {
1317
+ "in": "path",
1318
+ "name": "id",
1319
+ "required": true,
1320
+ "schema": {
1321
+ "format": "uuid",
1322
+ "type": "string"
1323
+ }
1324
+ }
1325
+ ],
1326
+ "responses": {
1327
+ "200": {
1328
+ "content": {
1329
+ "application/json": {
1330
+ "schema": {
1331
+ "$ref": "#/components/schemas/Job"
1332
+ }
1333
+ }
1334
+ },
1335
+ "description": "Cancelled before execution, or already ended observation"
1336
+ },
1337
+ "202": {
1338
+ "content": {
1339
+ "application/json": {
1340
+ "schema": {
1341
+ "$ref": "#/components/schemas/Job"
1342
+ }
1343
+ }
1344
+ },
1345
+ "description": "Cancellation requested; execution has not yet settled"
1346
+ },
1347
+ "401": {
1348
+ "content": {
1349
+ "application/json": {
1350
+ "schema": {
1351
+ "$ref": "#/components/schemas/Error"
1352
+ }
1353
+ }
1354
+ },
1355
+ "description": "Error envelope"
1356
+ },
1357
+ "404": {
1358
+ "content": {
1359
+ "application/json": {
1360
+ "schema": {
1361
+ "$ref": "#/components/schemas/Error"
1362
+ }
1363
+ }
1364
+ },
1365
+ "description": "Error envelope"
1366
+ },
1367
+ "503": {
1368
+ "content": {
1369
+ "application/json": {
1370
+ "schema": {
1371
+ "$ref": "#/components/schemas/Error"
1372
+ }
1373
+ }
1374
+ },
1375
+ "description": "Error envelope"
1376
+ }
1377
+ },
1378
+ "summary": "Request cancellation or replay an ended observation"
1379
+ }
1380
+ },
1381
+ "/v1/jobs/{id}/events": {
1382
+ "get": {
1383
+ "parameters": [
1384
+ {
1385
+ "in": "path",
1386
+ "name": "id",
1387
+ "required": true,
1388
+ "schema": {
1389
+ "format": "uuid",
1390
+ "type": "string"
1391
+ }
1392
+ },
1393
+ {
1394
+ "$ref": "#/components/parameters/LastEventId"
1395
+ }
1396
+ ],
1397
+ "responses": {
1398
+ "200": {
1399
+ "content": {
1400
+ "text/event-stream": {
1401
+ "schema": {
1402
+ "type": "string"
1403
+ },
1404
+ "x-nika-event-schema": {
1405
+ "$ref": "#/components/schemas/JobEvent"
1406
+ }
1407
+ }
1408
+ },
1409
+ "description": "text/event-stream; sends bounded retry guidance and cursor-neutral heartbeat comments; Last-Event-ID replays only persisted events after that sequence; terminal data adds declared outputs and receipt when available; failures add redacted {code,message}"
1410
+ },
1411
+ "400": {
1412
+ "content": {
1413
+ "application/json": {
1414
+ "schema": {
1415
+ "$ref": "#/components/schemas/Error"
1416
+ }
1417
+ }
1418
+ },
1419
+ "description": "Error envelope"
1420
+ },
1421
+ "401": {
1422
+ "content": {
1423
+ "application/json": {
1424
+ "schema": {
1425
+ "$ref": "#/components/schemas/Error"
1426
+ }
1427
+ }
1428
+ },
1429
+ "description": "Error envelope"
1430
+ },
1431
+ "404": {
1432
+ "content": {
1433
+ "application/json": {
1434
+ "schema": {
1435
+ "$ref": "#/components/schemas/Error"
1436
+ }
1437
+ }
1438
+ },
1439
+ "description": "Error envelope"
1440
+ }
1441
+ },
1442
+ "summary": "Job event SSE"
1443
+ }
1444
+ },
1445
+ "/v1/jobs/{id}/status": {
1446
+ "get": {
1447
+ "parameters": [
1448
+ {
1449
+ "in": "path",
1450
+ "name": "id",
1451
+ "required": true,
1452
+ "schema": {
1453
+ "format": "uuid",
1454
+ "type": "string"
1455
+ }
1456
+ }
1457
+ ],
1458
+ "responses": {
1459
+ "200": {
1460
+ "content": {
1461
+ "application/json": {
1462
+ "schema": {
1463
+ "$ref": "#/components/schemas/JobStatusOnly"
1464
+ }
1465
+ }
1466
+ },
1467
+ "description": "Status"
1468
+ },
1469
+ "401": {
1470
+ "content": {
1471
+ "application/json": {
1472
+ "schema": {
1473
+ "$ref": "#/components/schemas/Error"
1474
+ }
1475
+ }
1476
+ },
1477
+ "description": "Error envelope"
1478
+ },
1479
+ "404": {
1480
+ "content": {
1481
+ "application/json": {
1482
+ "schema": {
1483
+ "$ref": "#/components/schemas/Error"
1484
+ }
1485
+ }
1486
+ },
1487
+ "description": "Error envelope"
1488
+ }
1489
+ },
1490
+ "summary": "Status only; diagnosis lives on GET /v1/jobs/{id} and SSE"
1491
+ }
1492
+ },
1493
+ "/v1/jobs/{id}/trace/verify": {
1494
+ "get": {
1495
+ "description": "Locates the journal the resident wrote for this job under the project it serves (by the job's execution and trace identity) and verifies it through the same verifier `nika trace verify` runs; the vocabulary is the CLI's. `unavailable` is the honest refusal when no journal exists. The response never exposes a filesystem path.",
1496
+ "parameters": [
1497
+ {
1498
+ "in": "path",
1499
+ "name": "id",
1500
+ "required": true,
1501
+ "schema": {
1502
+ "format": "uuid",
1503
+ "type": "string"
1504
+ }
1505
+ }
1506
+ ],
1507
+ "responses": {
1508
+ "200": {
1509
+ "content": {
1510
+ "application/json": {
1511
+ "schema": {
1512
+ "$ref": "#/components/schemas/TraceVerification"
1513
+ }
1514
+ }
1515
+ },
1516
+ "description": "Typed trace verdict"
1517
+ },
1518
+ "401": {
1519
+ "content": {
1520
+ "application/json": {
1521
+ "schema": {
1522
+ "$ref": "#/components/schemas/Error"
1523
+ }
1524
+ }
1525
+ },
1526
+ "description": "Error envelope"
1527
+ },
1528
+ "404": {
1529
+ "content": {
1530
+ "application/json": {
1531
+ "schema": {
1532
+ "$ref": "#/components/schemas/Error"
1533
+ }
1534
+ }
1535
+ },
1536
+ "description": "Error envelope"
1537
+ }
1538
+ },
1539
+ "summary": "Verify the job's trace journal"
1540
+ }
1541
+ },
1542
+ "/v1/openapi.json": {
1543
+ "get": {
1544
+ "responses": {
1545
+ "200": {
1546
+ "description": "OpenAPI 3.1"
1547
+ },
1548
+ "401": {
1549
+ "description": "Bearer required"
1550
+ }
1551
+ },
1552
+ "summary": "This document"
1553
+ }
1554
+ },
1555
+ "/v1/schedules/{id}": {
1556
+ "get": {
1557
+ "responses": {
1558
+ "200": {
1559
+ "content": {
1560
+ "application/json": {
1561
+ "schema": {
1562
+ "$ref": "#/components/schemas/ScheduleStatus"
1563
+ }
1564
+ }
1565
+ },
1566
+ "description": "Fresh planned status",
1567
+ "headers": {
1568
+ "ETag": {
1569
+ "schema": {
1570
+ "type": "string"
1571
+ }
1572
+ }
1573
+ }
1574
+ },
1575
+ "401": {
1576
+ "content": {
1577
+ "application/json": {
1578
+ "schema": {
1579
+ "$ref": "#/components/schemas/Error"
1580
+ }
1581
+ }
1582
+ },
1583
+ "description": "Error envelope"
1584
+ },
1585
+ "404": {
1586
+ "content": {
1587
+ "application/json": {
1588
+ "schema": {
1589
+ "$ref": "#/components/schemas/Error"
1590
+ }
1591
+ }
1592
+ },
1593
+ "description": "Error envelope"
1594
+ }
1595
+ },
1596
+ "summary": "Read one declarative resident schedule"
1597
+ },
1598
+ "parameters": [
1599
+ {
1600
+ "in": "path",
1601
+ "name": "id",
1602
+ "required": true,
1603
+ "schema": {
1604
+ "maxLength": 255,
1605
+ "minLength": 1,
1606
+ "type": "string"
1607
+ }
1608
+ }
1609
+ ],
1610
+ "put": {
1611
+ "description": "Create requires If-None-Match: *. Update requires the exact ETag in If-Match. Identical lost-response retries are unchanged and retain the revision.",
1612
+ "parameters": [
1613
+ {
1614
+ "$ref": "#/components/parameters/IfNoneMatch"
1615
+ },
1616
+ {
1617
+ "$ref": "#/components/parameters/IfMatch"
1618
+ }
1619
+ ],
1620
+ "requestBody": {
1621
+ "content": {
1622
+ "application/json": {
1623
+ "schema": {
1624
+ "$ref": "#/components/schemas/SchedulePut"
1625
+ }
1626
+ }
1627
+ },
1628
+ "required": true
1629
+ },
1630
+ "responses": {
1631
+ "200": {
1632
+ "content": {
1633
+ "application/json": {
1634
+ "schema": {
1635
+ "$ref": "#/components/schemas/ScheduleApply"
1636
+ }
1637
+ }
1638
+ },
1639
+ "description": "Applied or unchanged",
1640
+ "headers": {
1641
+ "ETag": {
1642
+ "schema": {
1643
+ "type": "string"
1644
+ }
1645
+ }
1646
+ }
1647
+ },
1648
+ "401": {
1649
+ "content": {
1650
+ "application/json": {
1651
+ "schema": {
1652
+ "$ref": "#/components/schemas/Error"
1653
+ }
1654
+ }
1655
+ },
1656
+ "description": "Error envelope"
1657
+ },
1658
+ "412": {
1659
+ "content": {
1660
+ "application/json": {
1661
+ "schema": {
1662
+ "$ref": "#/components/schemas/Error"
1663
+ }
1664
+ }
1665
+ },
1666
+ "description": "Error envelope"
1667
+ },
1668
+ "413": {
1669
+ "content": {
1670
+ "application/json": {
1671
+ "schema": {
1672
+ "$ref": "#/components/schemas/Error"
1673
+ }
1674
+ }
1675
+ },
1676
+ "description": "Error envelope"
1677
+ },
1678
+ "415": {
1679
+ "content": {
1680
+ "application/json": {
1681
+ "schema": {
1682
+ "$ref": "#/components/schemas/Error"
1683
+ }
1684
+ }
1685
+ },
1686
+ "description": "Error envelope"
1687
+ },
1688
+ "422": {
1689
+ "content": {
1690
+ "application/json": {
1691
+ "schema": {
1692
+ "$ref": "#/components/schemas/Error"
1693
+ }
1694
+ }
1695
+ },
1696
+ "description": "Error envelope"
1697
+ },
1698
+ "503": {
1699
+ "content": {
1700
+ "application/json": {
1701
+ "schema": {
1702
+ "$ref": "#/components/schemas/Error"
1703
+ }
1704
+ }
1705
+ },
1706
+ "description": "Error envelope"
1707
+ }
1708
+ },
1709
+ "summary": "Create or revision-conditionally update one resident schedule"
1710
+ }
1711
+ },
1712
+ "/v1/workflows": {
1713
+ "get": {
1714
+ "responses": {
1715
+ "200": {
1716
+ "content": {
1717
+ "application/json": {
1718
+ "schema": {
1719
+ "$ref": "#/components/schemas/WorkflowList"
1720
+ }
1721
+ }
1722
+ },
1723
+ "description": "Project-relative .nika names under the served registry (--workflows)"
1724
+ },
1725
+ "401": {
1726
+ "content": {
1727
+ "application/json": {
1728
+ "schema": {
1729
+ "$ref": "#/components/schemas/Error"
1730
+ }
1731
+ }
1732
+ },
1733
+ "description": "Error envelope"
1734
+ }
1735
+ },
1736
+ "summary": "Contained workflow names"
1737
+ }
1738
+ },
1739
+ "/v1/workflows/{name}": {
1740
+ "get": {
1741
+ "parameters": [
1742
+ {
1743
+ "in": "path",
1744
+ "name": "name",
1745
+ "required": true,
1746
+ "schema": {
1747
+ "type": "string"
1748
+ }
1749
+ }
1750
+ ],
1751
+ "responses": {
1752
+ "200": {
1753
+ "content": {
1754
+ "application/json": {
1755
+ "schema": {
1756
+ "$ref": "#/components/schemas/WorkflowMetadata"
1757
+ }
1758
+ }
1759
+ },
1760
+ "description": "Contained name"
1761
+ },
1762
+ "401": {
1763
+ "content": {
1764
+ "application/json": {
1765
+ "schema": {
1766
+ "$ref": "#/components/schemas/Error"
1767
+ }
1768
+ }
1769
+ },
1770
+ "description": "Error envelope"
1771
+ },
1772
+ "404": {
1773
+ "content": {
1774
+ "application/json": {
1775
+ "schema": {
1776
+ "$ref": "#/components/schemas/Error"
1777
+ }
1778
+ }
1779
+ },
1780
+ "description": "Error envelope"
1781
+ }
1782
+ },
1783
+ "summary": "Workflow metadata without source bytes"
1784
+ }
1785
+ }
1786
+ },
1787
+ "security": [
1788
+ {
1789
+ "bearerAuth": []
1790
+ }
1791
+ ],
1792
+ "servers": [
1793
+ {
1794
+ "url": "http://127.0.0.1"
1795
+ }
1796
+ ]
1797
+ }