@shipeasy/openapi 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-EPLLHLZN.js → chunk-LYNWK55D.js} +23 -1
- package/dist/chunk-LYNWK55D.js.map +1 -0
- package/dist/{chunk-SPH5HWCD.js → chunk-PRN4AEAM.js} +396 -187
- package/dist/chunk-PRN4AEAM.js.map +1 -0
- package/dist/{client-pVkoo3Bf.d.ts → client-DO5HTb_L.d.ts} +886 -241
- package/dist/client.d.ts +1 -1
- package/dist/client.js +7 -1
- package/dist/custom.d.ts +23 -1
- package/dist/custom.js +12 -4
- package/dist/custom.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +770 -104
- package/dist/schemas.js +57 -5
- package/openapi.json +2177 -775
- package/openapi.yaml +1373 -409
- package/package.json +1 -1
- package/spec/components/errors.yaml +30 -1
- package/spec/components/parameters.yaml +8 -0
- package/spec/components/responses.yaml +15 -0
- package/spec/components/schemas/common.yaml +11 -0
- package/spec/components/schemas/connectors.yaml +5 -11
- package/spec/components/schemas/errors-api.yaml +66 -3
- package/spec/components/schemas/experiment-api-row.yaml +293 -0
- package/spec/components/schemas/experiments.yaml +54 -299
- package/spec/components/schemas/gate-templates.yaml +41 -2
- package/spec/components/schemas/gates.yaml +19 -0
- package/spec/components/schemas/keys.yaml +2 -1
- package/spec/components/schemas/metrics.yaml +17 -17
- package/spec/components/schemas/ops.yaml +105 -2
- package/spec/components/schemas/projects.yaml +119 -1
- package/spec/components/schemas/universes.yaml +83 -1
- package/spec/openapi.yaml +35 -2
- package/spec/paths/alert-rules.yaml +11 -2
- package/spec/paths/attributes.yaml +14 -3
- package/spec/paths/configs.yaml +24 -9
- package/spec/paths/connectors.yaml +42 -8
- package/spec/paths/errors.yaml +100 -6
- package/spec/paths/events.yaml +19 -4
- package/spec/paths/experiments.yaml +45 -11
- package/spec/paths/gate-templates.yaml +9 -5
- package/spec/paths/gates.yaml +21 -6
- package/spec/paths/i18n.yaml +18 -5
- package/spec/paths/keys.yaml +3 -1
- package/spec/paths/killswitches.yaml +24 -6
- package/spec/paths/metrics.yaml +15 -3
- package/spec/paths/ops.yaml +114 -3
- package/spec/paths/projects.yaml +3 -3
- package/spec/paths/universes.yaml +11 -2
- package/dist/chunk-EPLLHLZN.js.map +0 -1
- package/dist/chunk-SPH5HWCD.js.map +0 -1
|
@@ -34,8 +34,8 @@ ListMetricsResponse:
|
|
|
34
34
|
winsorizePct:
|
|
35
35
|
description: Winsorise percentile applied to the metric.
|
|
36
36
|
type: number
|
|
37
|
-
|
|
38
|
-
description:
|
|
37
|
+
defaultMinEffectOfInterest:
|
|
38
|
+
description: Metric-level default minimum effect of interest (relative, 0–1), or `null`.
|
|
39
39
|
anyOf:
|
|
40
40
|
- type: number
|
|
41
41
|
- type: "null"
|
|
@@ -89,8 +89,8 @@ GetMetricResponse:
|
|
|
89
89
|
winsorizePct:
|
|
90
90
|
description: Winsorise percentile applied to the metric.
|
|
91
91
|
type: number
|
|
92
|
-
|
|
93
|
-
description:
|
|
92
|
+
defaultMinEffectOfInterest:
|
|
93
|
+
description: Metric-level default minimum effect of interest (relative, 0–1), or `null`.
|
|
94
94
|
anyOf:
|
|
95
95
|
- type: number
|
|
96
96
|
- type: "null"
|
|
@@ -397,9 +397,9 @@ MetricWinsorizePct:
|
|
|
397
397
|
type: integer
|
|
398
398
|
minimum: 1
|
|
399
399
|
maximum: 99
|
|
400
|
-
|
|
400
|
+
MetricDefaultMinEffectOfInterest:
|
|
401
401
|
default: null
|
|
402
|
-
description:
|
|
402
|
+
description: Default minimum effect of interest (relative, 0–1) — the smallest change in this metric worth acting on, used as the power-planning baseline. Intrinsic to the metric; an experiment overrides it per-attachment with `min_effect_of_interest` when a specific decision has a different cost/risk bar. `null` to omit.
|
|
403
403
|
anyOf:
|
|
404
404
|
- type: number
|
|
405
405
|
- type: "null"
|
|
@@ -429,8 +429,8 @@ CreateMetricWithQuery:
|
|
|
429
429
|
$ref: "#/MetricQueryDsl"
|
|
430
430
|
winsorize_pct:
|
|
431
431
|
$ref: "#/MetricWinsorizePct"
|
|
432
|
-
|
|
433
|
-
$ref: "#/
|
|
432
|
+
default_min_effect_of_interest:
|
|
433
|
+
$ref: "#/MetricDefaultMinEffectOfInterest"
|
|
434
434
|
direction:
|
|
435
435
|
$ref: "#/MetricDirection"
|
|
436
436
|
required:
|
|
@@ -452,8 +452,8 @@ CreateMetricWithQueryIr:
|
|
|
452
452
|
$ref: "#/QueryIr"
|
|
453
453
|
winsorize_pct:
|
|
454
454
|
$ref: "#/MetricWinsorizePct"
|
|
455
|
-
|
|
456
|
-
$ref: "#/
|
|
455
|
+
default_min_effect_of_interest:
|
|
456
|
+
$ref: "#/MetricDefaultMinEffectOfInterest"
|
|
457
457
|
direction:
|
|
458
458
|
$ref: "#/MetricDirection"
|
|
459
459
|
required:
|
|
@@ -479,8 +479,8 @@ UpdateMetricWithQuery:
|
|
|
479
479
|
$ref: "#/MetricQueryDsl"
|
|
480
480
|
winsorize_pct:
|
|
481
481
|
$ref: "#/MetricWinsorizePct"
|
|
482
|
-
|
|
483
|
-
$ref: "#/
|
|
482
|
+
default_min_effect_of_interest:
|
|
483
|
+
$ref: "#/MetricDefaultMinEffectOfInterest"
|
|
484
484
|
direction:
|
|
485
485
|
$ref: "#/MetricDirection"
|
|
486
486
|
required:
|
|
@@ -498,8 +498,8 @@ UpdateMetricWithQueryIr:
|
|
|
498
498
|
$ref: "#/QueryIr"
|
|
499
499
|
winsorize_pct:
|
|
500
500
|
$ref: "#/MetricWinsorizePct"
|
|
501
|
-
|
|
502
|
-
$ref: "#/
|
|
501
|
+
default_min_effect_of_interest:
|
|
502
|
+
$ref: "#/MetricDefaultMinEffectOfInterest"
|
|
503
503
|
direction:
|
|
504
504
|
$ref: "#/MetricDirection"
|
|
505
505
|
required:
|
|
@@ -515,12 +515,12 @@ UpdateMetricFields:
|
|
|
515
515
|
$ref: "#/MetricEventName"
|
|
516
516
|
winsorize_pct:
|
|
517
517
|
$ref: "#/MetricWinsorizePct"
|
|
518
|
-
|
|
519
|
-
$ref: "#/
|
|
518
|
+
default_min_effect_of_interest:
|
|
519
|
+
$ref: "#/MetricDefaultMinEffectOfInterest"
|
|
520
520
|
direction:
|
|
521
521
|
$ref: "#/MetricDirection"
|
|
522
522
|
additionalProperties: false
|
|
523
|
-
description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation,
|
|
523
|
+
description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation, default minimum effect of interest, direction).
|
|
524
524
|
CreateMetricResponse:
|
|
525
525
|
type: object
|
|
526
526
|
properties:
|
|
@@ -245,6 +245,11 @@ OpsErrorContext:
|
|
|
245
245
|
items:
|
|
246
246
|
type: string
|
|
247
247
|
description: "Distinct, id-normalized routes this error has surfaced on (UUIDs/ids collapsed to `#`)."
|
|
248
|
+
stackTail:
|
|
249
|
+
anyOf:
|
|
250
|
+
- type: string
|
|
251
|
+
- type: "null"
|
|
252
|
+
description: "The last 3 non-empty lines of the latest occurrence's stack — the innermost frames closest to where the throw bubbled out, baked in as an at-a-glance locator. `null` when the source supplied no stack. Fetch the full stack via `related.error`."
|
|
248
253
|
sdkVersion:
|
|
249
254
|
anyOf:
|
|
250
255
|
- type: string
|
|
@@ -380,6 +385,11 @@ OpsAlertMetricSummary:
|
|
|
380
385
|
OpsMeasurePlanContext:
|
|
381
386
|
type: object
|
|
382
387
|
properties:
|
|
388
|
+
goal:
|
|
389
|
+
anyOf:
|
|
390
|
+
- type: string
|
|
391
|
+
- type: "null"
|
|
392
|
+
description: "The customer's underlying intent in their own words — WHAT they want to learn or achieve and WHY, independent of the specific steps. The plan below is a best-effort proposal made without repo access; when the code reveals a better path, this goal is the target you optimize for, not literal step-adherence."
|
|
383
393
|
created:
|
|
384
394
|
type: array
|
|
385
395
|
items:
|
|
@@ -927,6 +937,97 @@ LinkPrToOpsItemResponse:
|
|
|
927
937
|
- id
|
|
928
938
|
additionalProperties: false
|
|
929
939
|
description: Response for the update / link-pr endpoints.
|
|
940
|
+
OpsCommentAuthorType:
|
|
941
|
+
type: string
|
|
942
|
+
enum:
|
|
943
|
+
- user
|
|
944
|
+
- system
|
|
945
|
+
description: >-
|
|
946
|
+
Who wrote a comment. `user` is a teammate (their email is in `authorEmail`);
|
|
947
|
+
`system` is Jarvis — the AI agent — which authors comments when an ops-notify
|
|
948
|
+
escalation lands on the item and when it is `@shipeasy`-mentioned in a thread.
|
|
949
|
+
OpsComment:
|
|
950
|
+
type: object
|
|
951
|
+
properties:
|
|
952
|
+
id:
|
|
953
|
+
type: string
|
|
954
|
+
description: Comment id.
|
|
955
|
+
feedbackId:
|
|
956
|
+
type: string
|
|
957
|
+
description: The queue item this comment hangs off.
|
|
958
|
+
parentId:
|
|
959
|
+
anyOf:
|
|
960
|
+
- type: string
|
|
961
|
+
- type: "null"
|
|
962
|
+
description: The top-level comment this is a reply to, or `null` for a top-level comment.
|
|
963
|
+
authorType:
|
|
964
|
+
$ref: "#/OpsCommentAuthorType"
|
|
965
|
+
authorEmail:
|
|
966
|
+
anyOf:
|
|
967
|
+
- type: string
|
|
968
|
+
- type: "null"
|
|
969
|
+
description: The teammate who wrote it, or `null` for a `system` (Jarvis) comment.
|
|
970
|
+
body:
|
|
971
|
+
type: string
|
|
972
|
+
description: Comment body as markdown (may contain sanitised inline image/video embeds).
|
|
973
|
+
createdAt:
|
|
974
|
+
type: string
|
|
975
|
+
description: ISO-8601 creation timestamp.
|
|
976
|
+
updatedAt:
|
|
977
|
+
type: string
|
|
978
|
+
description: ISO-8601 last-edit timestamp.
|
|
979
|
+
required:
|
|
980
|
+
- id
|
|
981
|
+
- feedbackId
|
|
982
|
+
- parentId
|
|
983
|
+
- authorType
|
|
984
|
+
- authorEmail
|
|
985
|
+
- body
|
|
986
|
+
- createdAt
|
|
987
|
+
- updatedAt
|
|
988
|
+
additionalProperties: false
|
|
989
|
+
description: A single comment on a queue item.
|
|
990
|
+
ListOpsCommentsResponse:
|
|
991
|
+
type: object
|
|
992
|
+
properties:
|
|
993
|
+
comments:
|
|
994
|
+
type: array
|
|
995
|
+
items:
|
|
996
|
+
$ref: "#/OpsComment"
|
|
997
|
+
required:
|
|
998
|
+
- comments
|
|
999
|
+
additionalProperties: false
|
|
1000
|
+
description: Response for `GET /api/admin/ops/{handle}/comments` — the thread, oldest first.
|
|
1001
|
+
CreateOpsCommentRequest:
|
|
1002
|
+
type: object
|
|
1003
|
+
properties:
|
|
1004
|
+
body:
|
|
1005
|
+
type: string
|
|
1006
|
+
minLength: 1
|
|
1007
|
+
maxLength: 10000
|
|
1008
|
+
description: The comment body as markdown. Mentions (`@teammate`, `@shipeasy`) are parsed from it.
|
|
1009
|
+
parentId:
|
|
1010
|
+
anyOf:
|
|
1011
|
+
- type: string
|
|
1012
|
+
- type: "null"
|
|
1013
|
+
description: >-
|
|
1014
|
+
Reply under this top-level comment. Omit / `null` for a top-level
|
|
1015
|
+
comment. Replying to a reply attaches to the same top-level parent
|
|
1016
|
+
(threading is one level deep).
|
|
1017
|
+
required:
|
|
1018
|
+
- body
|
|
1019
|
+
additionalProperties: false
|
|
1020
|
+
description: Body for `POST /api/admin/ops/{handle}/comments`.
|
|
1021
|
+
CreateOpsCommentResponse:
|
|
1022
|
+
type: object
|
|
1023
|
+
properties:
|
|
1024
|
+
id:
|
|
1025
|
+
type: string
|
|
1026
|
+
description: Newly created comment id.
|
|
1027
|
+
required:
|
|
1028
|
+
- id
|
|
1029
|
+
additionalProperties: false
|
|
1030
|
+
description: Response for `POST /api/admin/ops/{handle}/comments`.
|
|
930
1031
|
NotifyOpsRequest:
|
|
931
1032
|
type: object
|
|
932
1033
|
properties:
|
|
@@ -946,8 +1047,10 @@ NotifyOpsRequest:
|
|
|
946
1047
|
items:
|
|
947
1048
|
type: string
|
|
948
1049
|
href:
|
|
949
|
-
description: Dashboard-relative deep link to the related item.
|
|
950
|
-
|
|
1050
|
+
description: Dashboard-relative deep link to the related item. `null` is accepted and treated as "no link".
|
|
1051
|
+
anyOf:
|
|
1052
|
+
- type: string
|
|
1053
|
+
- type: "null"
|
|
951
1054
|
dedupeKey:
|
|
952
1055
|
description: Stable per-escalation key (e.g. `feedback:7`) so re-runs dedupe to one row.
|
|
953
1056
|
type: string
|
|
@@ -19,7 +19,9 @@ GetCurrentProjectResponse:
|
|
|
19
19
|
type: string
|
|
20
20
|
enum:
|
|
21
21
|
- free
|
|
22
|
-
-
|
|
22
|
+
- pro
|
|
23
|
+
- business
|
|
24
|
+
- enterprise
|
|
23
25
|
description: Billing plan tier.
|
|
24
26
|
status:
|
|
25
27
|
type: string
|
|
@@ -74,6 +76,50 @@ GetCurrentProjectResponse:
|
|
|
74
76
|
- type: boolean
|
|
75
77
|
- type: number
|
|
76
78
|
description: Whether the feedback/ops module is enabled.
|
|
79
|
+
minSampleSize:
|
|
80
|
+
type: integer
|
|
81
|
+
description: Verdict power guard — minimum users per arm before a ship/hold verdict.
|
|
82
|
+
minRuntimeDays:
|
|
83
|
+
type: integer
|
|
84
|
+
description: Minimum days an experiment must run before a verdict (peeking guard).
|
|
85
|
+
defaultPower:
|
|
86
|
+
type: number
|
|
87
|
+
description: Target statistical power (1−β) feeding the realized-MDE calculation.
|
|
88
|
+
ciConfidence:
|
|
89
|
+
type: number
|
|
90
|
+
description: Confidence level for the interval surfaced on results.
|
|
91
|
+
defaultAllocationPct:
|
|
92
|
+
type: integer
|
|
93
|
+
description: Default traffic allocation (basis points) new experiments start with.
|
|
94
|
+
defaultHoldout:
|
|
95
|
+
type: integer
|
|
96
|
+
description: Default holdout carve-out (basis points) that seeds each new universe's holdout.
|
|
97
|
+
defaultWinsorizePct:
|
|
98
|
+
type: integer
|
|
99
|
+
description: Default winsorization percentile new metrics start with.
|
|
100
|
+
defaultMei:
|
|
101
|
+
anyOf:
|
|
102
|
+
- type: number
|
|
103
|
+
- type: "null"
|
|
104
|
+
description: Default minimum effect of interest (relative, 0–1) new metrics start with, or null.
|
|
105
|
+
cupedBaselineDays:
|
|
106
|
+
type: integer
|
|
107
|
+
description: CUPED baseline window — days of pre-experiment history, frozen at start.
|
|
108
|
+
cupedMinOverlap:
|
|
109
|
+
type: number
|
|
110
|
+
description: CUPED selection-bias guard — min share of users with a baseline, else skip.
|
|
111
|
+
cupedMinBaselineUsers:
|
|
112
|
+
type: integer
|
|
113
|
+
description: CUPED — minimum users with a baseline before it runs at all.
|
|
114
|
+
msprtTauMeiFactor:
|
|
115
|
+
type: number
|
|
116
|
+
description: mSPRT prior width — τ = minimum effect of interest × this factor.
|
|
117
|
+
msprtTauSdFactor:
|
|
118
|
+
type: number
|
|
119
|
+
description: mSPRT fallback prior width — τ = this × control SD when no MEI is set.
|
|
120
|
+
srmThreshold:
|
|
121
|
+
type: number
|
|
122
|
+
description: SRM chi-square p-value below which the run is called invalid.
|
|
77
123
|
createdAt:
|
|
78
124
|
type: string
|
|
79
125
|
description: ISO-8601 timestamp of project creation.
|
|
@@ -218,5 +264,77 @@ UpdateProjectRequest:
|
|
|
218
264
|
moduleEvents:
|
|
219
265
|
type: boolean
|
|
220
266
|
description: Enable/disable the events module.
|
|
267
|
+
minSampleSize:
|
|
268
|
+
type: integer
|
|
269
|
+
minimum: 2
|
|
270
|
+
maximum: 1000000
|
|
271
|
+
description: Verdict power guard — minimum users per arm before a ship/hold verdict.
|
|
272
|
+
minRuntimeDays:
|
|
273
|
+
type: integer
|
|
274
|
+
minimum: 0
|
|
275
|
+
maximum: 365
|
|
276
|
+
description: Minimum days an experiment must run before a verdict (peeking guard).
|
|
277
|
+
defaultPower:
|
|
278
|
+
type: number
|
|
279
|
+
minimum: 0.5
|
|
280
|
+
maximum: 0.99
|
|
281
|
+
description: Target statistical power (1−β) feeding the realized-MDE calculation.
|
|
282
|
+
ciConfidence:
|
|
283
|
+
type: number
|
|
284
|
+
minimum: 0.5
|
|
285
|
+
maximum: 0.999
|
|
286
|
+
description: Confidence level for the interval surfaced on results (any value in [0.5, 0.999], e.g. 0.90, 0.95, 0.975, 0.99).
|
|
287
|
+
defaultAllocationPct:
|
|
288
|
+
type: integer
|
|
289
|
+
minimum: 1
|
|
290
|
+
maximum: 10000
|
|
291
|
+
description: Default traffic allocation (basis points, 1000 = 10%) new experiments start with; overridable per experiment.
|
|
292
|
+
defaultHoldout:
|
|
293
|
+
type: integer
|
|
294
|
+
minimum: 0
|
|
295
|
+
maximum: 10000
|
|
296
|
+
description: Default holdout carve-out (basis points) that seeds each new universe's holdout (0 = none).
|
|
297
|
+
defaultWinsorizePct:
|
|
298
|
+
type: integer
|
|
299
|
+
minimum: 1
|
|
300
|
+
maximum: 99
|
|
301
|
+
description: Default winsorization percentile new metrics start with; overridable per metric.
|
|
302
|
+
defaultMei:
|
|
303
|
+
anyOf:
|
|
304
|
+
- type: number
|
|
305
|
+
minimum: 0
|
|
306
|
+
maximum: 1
|
|
307
|
+
- type: "null"
|
|
308
|
+
description: Default minimum effect of interest (relative, 0–1) new metrics start with; overridable per metric and per experiment. Null clears it.
|
|
309
|
+
cupedBaselineDays:
|
|
310
|
+
type: integer
|
|
311
|
+
minimum: 1
|
|
312
|
+
maximum: 365
|
|
313
|
+
description: CUPED baseline window — days of pre-experiment history, frozen at start.
|
|
314
|
+
cupedMinOverlap:
|
|
315
|
+
type: number
|
|
316
|
+
minimum: 0.01
|
|
317
|
+
maximum: 0.99
|
|
318
|
+
description: CUPED selection-bias guard — min share of users with a baseline, else skip.
|
|
319
|
+
cupedMinBaselineUsers:
|
|
320
|
+
type: integer
|
|
321
|
+
minimum: 10
|
|
322
|
+
maximum: 100000
|
|
323
|
+
description: CUPED — minimum users with a baseline before it runs at all.
|
|
324
|
+
msprtTauMeiFactor:
|
|
325
|
+
type: number
|
|
326
|
+
minimum: 0.1
|
|
327
|
+
maximum: 2
|
|
328
|
+
description: mSPRT prior width — τ = minimum effect of interest × this factor.
|
|
329
|
+
msprtTauSdFactor:
|
|
330
|
+
type: number
|
|
331
|
+
minimum: 0.05
|
|
332
|
+
maximum: 1
|
|
333
|
+
description: mSPRT fallback prior width — τ = this × control SD when no MEI is set.
|
|
334
|
+
srmThreshold:
|
|
335
|
+
type: number
|
|
336
|
+
minimum: 0.0001
|
|
337
|
+
maximum: 0.05
|
|
338
|
+
description: SRM chi-square p-value below which the run is called invalid.
|
|
221
339
|
additionalProperties: false
|
|
222
340
|
description: "Body for `PATCH /api/admin/projects/{id}`. Partial — every field is optional; only supplied fields change. The project id in the path must match the caller's own project."
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
# The universe owns the config schema for every experiment/variant in it — an
|
|
2
|
+
# ordered list of `{ name, type, default }`. Experiments may only override the
|
|
3
|
+
# per-variant value of a declared param, never add fields (universe rework).
|
|
4
|
+
UniverseParam:
|
|
5
|
+
type: object
|
|
6
|
+
properties:
|
|
7
|
+
name:
|
|
8
|
+
type: string
|
|
9
|
+
minLength: 1
|
|
10
|
+
maxLength: 128
|
|
11
|
+
pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
|
|
12
|
+
description: Param key, referenced by `groups[].params` on every experiment in the universe.
|
|
13
|
+
type:
|
|
14
|
+
type: string
|
|
15
|
+
enum:
|
|
16
|
+
- bool
|
|
17
|
+
- string
|
|
18
|
+
- int
|
|
19
|
+
- number
|
|
20
|
+
description: Scalar type of the param's value.
|
|
21
|
+
default:
|
|
22
|
+
description: "Universe-wide default. Returned when the assigned variant doesn't override this param (resolution: variant override → universe default)."
|
|
23
|
+
required:
|
|
24
|
+
- name
|
|
25
|
+
- type
|
|
26
|
+
- default
|
|
27
|
+
additionalProperties: false
|
|
28
|
+
UniverseParamSchema:
|
|
29
|
+
type: array
|
|
30
|
+
items:
|
|
31
|
+
$ref: "#/UniverseParam"
|
|
32
|
+
description: The universe's ordered config schema — the single source of truth for its params.
|
|
1
33
|
ListUniversesResponse:
|
|
2
34
|
type: object
|
|
3
35
|
properties:
|
|
@@ -14,6 +46,11 @@ ListUniversesResponse:
|
|
|
14
46
|
maxLength: 128
|
|
15
47
|
pattern: ^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$
|
|
16
48
|
description: Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create.
|
|
49
|
+
description:
|
|
50
|
+
anyOf:
|
|
51
|
+
- type: string
|
|
52
|
+
- type: "null"
|
|
53
|
+
description: Human-readable blurb shown in the universe picker/hovercard.
|
|
17
54
|
unitType:
|
|
18
55
|
type: string
|
|
19
56
|
description: Unit of randomisation. Snake-case in request (`unit_type`), camelCase in response.
|
|
@@ -26,6 +63,16 @@ ListUniversesResponse:
|
|
|
26
63
|
maxItems: 2
|
|
27
64
|
- type: "null"
|
|
28
65
|
description: Reserved holdout bucket range, or `null` if none.
|
|
66
|
+
recommendedHeadroom:
|
|
67
|
+
type: integer
|
|
68
|
+
minimum: 0
|
|
69
|
+
maximum: 10000
|
|
70
|
+
description: Basis points of headroom seeded into each new experiment's reserved tail (0 = none).
|
|
71
|
+
paramSchema:
|
|
72
|
+
anyOf:
|
|
73
|
+
- $ref: "#/UniverseParamSchema"
|
|
74
|
+
- type: "null"
|
|
75
|
+
description: The universe-owned config schema, or `null` on pre-rework universes not yet seeded.
|
|
29
76
|
createdAt:
|
|
30
77
|
type: string
|
|
31
78
|
description: ISO-8601 timestamp of creation.
|
|
@@ -54,6 +101,13 @@ CreateUniverseRequest:
|
|
|
54
101
|
description: Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create.
|
|
55
102
|
folder:
|
|
56
103
|
$ref: ./common.yaml#/Folder
|
|
104
|
+
description:
|
|
105
|
+
default: null
|
|
106
|
+
anyOf:
|
|
107
|
+
- type: string
|
|
108
|
+
maxLength: 2000
|
|
109
|
+
- type: "null"
|
|
110
|
+
description: Human-readable blurb shown in the universe picker/hovercard.
|
|
57
111
|
unit_type:
|
|
58
112
|
default: user_id
|
|
59
113
|
description: Unit of randomisation. Typically `user_id`. Use `account_id` to keep whole accounts in the same group across an experiment.
|
|
@@ -70,6 +124,18 @@ CreateUniverseRequest:
|
|
|
70
124
|
maxItems: 2
|
|
71
125
|
- type: "null"
|
|
72
126
|
description: Inclusive `[lo, hi]` bucket range (0–9999) reserved as the **holdout** — callers hashed into this slice are excluded from every experiment in the universe. `null` disables the holdout. Pro plan or higher required.
|
|
127
|
+
recommended_headroom:
|
|
128
|
+
default: 0
|
|
129
|
+
type: integer
|
|
130
|
+
minimum: 0
|
|
131
|
+
maximum: 10000
|
|
132
|
+
description: Basis points of reserved headroom seeded into each new experiment created in this universe (0 = none). Lets variants be appended into a running experiment without reshuffling.
|
|
133
|
+
param_schema:
|
|
134
|
+
default: null
|
|
135
|
+
anyOf:
|
|
136
|
+
- $ref: "#/UniverseParamSchema"
|
|
137
|
+
- type: "null"
|
|
138
|
+
description: The universe-owned config schema — an ordered `{ name, type, default }[]`. Experiments may only override values per variant, never add fields. `null` starts an empty schema.
|
|
73
139
|
required:
|
|
74
140
|
- name
|
|
75
141
|
additionalProperties: false
|
|
@@ -94,6 +160,12 @@ UpdateUniverseRequest:
|
|
|
94
160
|
properties:
|
|
95
161
|
folder:
|
|
96
162
|
$ref: ./common.yaml#/Folder
|
|
163
|
+
description:
|
|
164
|
+
anyOf:
|
|
165
|
+
- type: string
|
|
166
|
+
maxLength: 2000
|
|
167
|
+
- type: "null"
|
|
168
|
+
description: Human-readable blurb shown in the universe picker/hovercard.
|
|
97
169
|
holdout_range:
|
|
98
170
|
anyOf:
|
|
99
171
|
- type: array
|
|
@@ -105,8 +177,18 @@ UpdateUniverseRequest:
|
|
|
105
177
|
maxItems: 2
|
|
106
178
|
- type: "null"
|
|
107
179
|
description: Inclusive `[lo, hi]` bucket range (0–9999) reserved as the **holdout** — callers hashed into this slice are excluded from every experiment in the universe. `null` disables the holdout. Pro plan or higher required.
|
|
180
|
+
recommended_headroom:
|
|
181
|
+
type: integer
|
|
182
|
+
minimum: 0
|
|
183
|
+
maximum: 10000
|
|
184
|
+
description: Basis points of reserved headroom seeded into new experiments in this universe.
|
|
185
|
+
param_schema:
|
|
186
|
+
anyOf:
|
|
187
|
+
- $ref: "#/UniverseParamSchema"
|
|
188
|
+
- type: "null"
|
|
189
|
+
description: Replace the universe config schema. Additive changes + default edits are always allowed; removing a param a running experiment overrides is rejected (deprecate-only).
|
|
108
190
|
additionalProperties: false
|
|
109
|
-
description: Body for `PATCH /api/admin/universes/{id}`.
|
|
191
|
+
description: Body for `PATCH /api/admin/universes/{id}`. `name` and `unit_type` are immutable after create; `holdout_range`, `description`, `recommended_headroom` and `param_schema` are mutable.
|
|
110
192
|
UpdateUniverseResponse:
|
|
111
193
|
type: object
|
|
112
194
|
properties:
|
package/spec/openapi.yaml
CHANGED
|
@@ -21,9 +21,28 @@ security:
|
|
|
21
21
|
- bearerSdkKey: []
|
|
22
22
|
tags:
|
|
23
23
|
- name: Release
|
|
24
|
-
summary:
|
|
24
|
+
summary: >-
|
|
25
|
+
Feature delivery — flags, kill switches, dynamic configs, A/B experiments,
|
|
26
|
+
and the universes they bucket in.
|
|
25
27
|
kind: nav
|
|
26
|
-
description:
|
|
28
|
+
description: |-
|
|
29
|
+
Release: the feature-delivery surface. One roof over the five resources
|
|
30
|
+
that decide which code path a user gets — feature gates (flags), kill
|
|
31
|
+
switches, dynamic configs, A/B/n experiments, and the universes that bucket
|
|
32
|
+
them — each exposed as its own subcommand group.
|
|
33
|
+
|
|
34
|
+
**Groups.**
|
|
35
|
+
- `flags` — boolean feature gates: AND-combined targeting rules + a percentage rollout (basis points), evaluated on the SDK hot path.
|
|
36
|
+
- `killswitch` (`ks`) — per-env boolean overrides for incident response; no rules, no rollout, versioned per environment.
|
|
37
|
+
- `configs` — JSON-Schema-validated structured values with a draft → publish workflow, delivered per environment.
|
|
38
|
+
- `experiments` — randomised A/B/n assignment plus the analysis pipeline (t-test, sequential testing, SRM detection); `universes` hold the shared bucketing space and holdouts the experiments draw from.
|
|
39
|
+
|
|
40
|
+
**Delivery model.** Every write rebuilds the project's KV blob and purges
|
|
41
|
+
the CDN — SDKs poll at the plan interval and never touch the database on
|
|
42
|
+
the hot path. The destructive verb is `archive` (soft-delete), never
|
|
43
|
+
`delete`.
|
|
44
|
+
|
|
45
|
+
Run `shipeasy release <group> --help` for the full contract of each group.
|
|
27
46
|
- name: Flags
|
|
28
47
|
parent: Release
|
|
29
48
|
description: |-
|
|
@@ -161,6 +180,16 @@ tags:
|
|
|
161
180
|
**Immutable metric.** The bound metric (and its aggregation) is fixed at create time — there is no update path for `metricId`. Tune `threshold`/`comparator`/`windowHours`/`severity`/`name`/`enabled` instead, or delete + recreate to repoint the rule at a different metric.
|
|
162
181
|
|
|
163
182
|
**Delivery.** `notify` optionally targets a Slack channel and/or email for this rule; `null` falls back to the project's default notification settings. Slack targets require a connected Slack connector.
|
|
183
|
+
- name: Comments
|
|
184
|
+
parent: Ops
|
|
185
|
+
description: |-
|
|
186
|
+
Comments on a queue item — the discussion thread that hangs off any bug,
|
|
187
|
+
feature request, or auto-filed error/alert ticket. Append a comment or read
|
|
188
|
+
the thread; one level of threaded replies via `parentId`.
|
|
189
|
+
|
|
190
|
+
**Mentions.** `@teammate` in a body raises an in-app notification for that
|
|
191
|
+
person; `@shipeasy` asks Jarvis (the AI agent) to read the item and reply.
|
|
192
|
+
Comments authored by Jarvis carry `authorType: system`.
|
|
164
193
|
- name: Projects
|
|
165
194
|
description: |-
|
|
166
195
|
Projects: the account-level container every other resource is scoped to.
|
|
@@ -285,6 +314,8 @@ paths:
|
|
|
285
314
|
$ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}
|
|
286
315
|
/api/admin/ops/{handle}/link-pr:
|
|
287
316
|
$ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1link-pr
|
|
317
|
+
/api/admin/ops/{handle}/comments:
|
|
318
|
+
$ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1comments
|
|
288
319
|
/api/admin/notifications:
|
|
289
320
|
$ref: ./paths/ops.yaml#/~1api~1admin~1notifications
|
|
290
321
|
/api/admin/slack/channels:
|
|
@@ -319,6 +350,8 @@ paths:
|
|
|
319
350
|
$ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}
|
|
320
351
|
/api/admin/errors/{id}/file:
|
|
321
352
|
$ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}~1file
|
|
353
|
+
/api/admin/errors/{id}/resolve:
|
|
354
|
+
$ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}~1resolve
|
|
322
355
|
/api/admin/errors/{id}/series:
|
|
323
356
|
$ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}~1series
|
|
324
357
|
/api/admin/connectors:
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- Alerts
|
|
11
11
|
parameters:
|
|
12
12
|
- $ref: ../components/parameters.yaml#/ProjectId
|
|
13
|
+
- $ref: ../components/parameters.yaml#/Q
|
|
13
14
|
responses:
|
|
14
15
|
"200":
|
|
15
16
|
description: List alert rules
|
|
@@ -103,6 +104,13 @@
|
|
|
103
104
|
$ref: ../components/schemas/alert-rules.yaml#/CreateAlertRuleResponse
|
|
104
105
|
example:
|
|
105
106
|
id: ar_01j7w8a1b2c3d4e5f6g7h8i9j0
|
|
107
|
+
links:
|
|
108
|
+
UpdateAlertRule:
|
|
109
|
+
operationId: updateAlertRule
|
|
110
|
+
parameters: { id: $response.body#/id }
|
|
111
|
+
DeleteAlertRule:
|
|
112
|
+
operationId: deleteAlertRule
|
|
113
|
+
parameters: { id: $response.body#/id }
|
|
106
114
|
"400":
|
|
107
115
|
$ref: ../components/responses.yaml#/BadRequest
|
|
108
116
|
"401":
|
|
@@ -120,6 +128,7 @@
|
|
|
120
128
|
- UNAUTHORIZED
|
|
121
129
|
- FORBIDDEN
|
|
122
130
|
- ALREADY_EXISTS
|
|
131
|
+
- METRIC_NOT_FOUND
|
|
123
132
|
- REFERENCED_NOT_FOUND
|
|
124
133
|
- VALIDATION
|
|
125
134
|
x-cli:
|
|
@@ -146,7 +155,7 @@
|
|
|
146
155
|
required: true
|
|
147
156
|
description: Stable opaque alert-rule id (`ar_…`) or the rule's `name`.
|
|
148
157
|
schema:
|
|
149
|
-
|
|
158
|
+
$ref: ../components/schemas/common.yaml#/ResourceId
|
|
150
159
|
requestBody:
|
|
151
160
|
required: true
|
|
152
161
|
content:
|
|
@@ -217,7 +226,7 @@
|
|
|
217
226
|
required: true
|
|
218
227
|
description: Stable opaque alert-rule id (`ar_…`) or the rule's `name`.
|
|
219
228
|
schema:
|
|
220
|
-
|
|
229
|
+
$ref: ../components/schemas/common.yaml#/ResourceId
|
|
221
230
|
responses:
|
|
222
231
|
"200":
|
|
223
232
|
description: Delete an alert rule
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- Attributes
|
|
11
11
|
parameters:
|
|
12
12
|
- $ref: ../components/parameters.yaml#/ProjectId
|
|
13
|
+
- $ref: ../components/parameters.yaml#/Q
|
|
13
14
|
responses:
|
|
14
15
|
"200":
|
|
15
16
|
description: List targeting attributes
|
|
@@ -76,6 +77,16 @@
|
|
|
76
77
|
example:
|
|
77
78
|
id: attr_01j7w8a1b2c3
|
|
78
79
|
name: plan
|
|
80
|
+
links:
|
|
81
|
+
GetAttribute:
|
|
82
|
+
operationId: getAttribute
|
|
83
|
+
parameters: { id: $response.body#/id }
|
|
84
|
+
UpdateAttribute:
|
|
85
|
+
operationId: updateAttribute
|
|
86
|
+
parameters: { id: $response.body#/id }
|
|
87
|
+
DeleteAttribute:
|
|
88
|
+
operationId: deleteAttribute
|
|
89
|
+
parameters: { id: $response.body#/id }
|
|
79
90
|
"400":
|
|
80
91
|
$ref: ../components/responses.yaml#/BadRequest
|
|
81
92
|
"401":
|
|
@@ -115,7 +126,7 @@
|
|
|
115
126
|
required: true
|
|
116
127
|
description: The attribute id.
|
|
117
128
|
schema:
|
|
118
|
-
|
|
129
|
+
$ref: ../components/schemas/common.yaml#/ResourceId
|
|
119
130
|
responses:
|
|
120
131
|
"200":
|
|
121
132
|
description: Get a targeting attribute
|
|
@@ -169,7 +180,7 @@
|
|
|
169
180
|
required: true
|
|
170
181
|
description: The attribute id.
|
|
171
182
|
schema:
|
|
172
|
-
|
|
183
|
+
$ref: ../components/schemas/common.yaml#/ResourceId
|
|
173
184
|
requestBody:
|
|
174
185
|
required: true
|
|
175
186
|
content:
|
|
@@ -228,7 +239,7 @@
|
|
|
228
239
|
required: true
|
|
229
240
|
description: The attribute id.
|
|
230
241
|
schema:
|
|
231
|
-
|
|
242
|
+
$ref: ../components/schemas/common.yaml#/ResourceId
|
|
232
243
|
responses:
|
|
233
244
|
"200":
|
|
234
245
|
description: Archive a targeting attribute
|