@shipeasy/openapi 2.4.0 → 3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipeasy/openapi",
3
- "version": "2.4.0",
3
+ "version": "3.0.0",
4
4
  "description": "Shipeasy admin OpenAPI 3.2 spec (hand-authored, single source of truth) + the generated TypeScript client, Zod schemas, and types. Consumed by @shipeasy/cli and @shipeasy/mcp.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -223,12 +223,26 @@ CreateConfigRequest:
223
223
  additionalProperties: {}
224
224
  description: JSON Schema (draft 2020-12) describing the shape of the config value. Top-level `type` must be `'object'`; every published value is validated against this schema.
225
225
  value:
226
+ type: object
227
+ additionalProperties: {}
226
228
  description: "Initial config value. Either a single JSON object applied to every env, or a `{ env: value }` map seeding per-env values. Must match `schema`. Defaults to `{}` on every env when omitted."
229
+ dev:
230
+ type: object
231
+ additionalProperties: {}
232
+ description: "Seed the **dev** env's initial value (version 1), overriding `value` for dev. Published immediately. Must match `schema`."
233
+ staging:
234
+ type: object
235
+ additionalProperties: {}
236
+ description: "Seed the **staging** env's initial value (version 1), overriding `value` for staging. Published immediately. Must match `schema`."
237
+ prod:
238
+ type: object
239
+ additionalProperties: {}
240
+ description: "Seed the **prod** env's initial value (version 1), overriding `value` for prod. Published immediately. Must match `schema`."
227
241
  required:
228
242
  - name
229
243
  - schema
230
244
  additionalProperties: false
231
- description: Body for `POST /api/admin/configs`. `name` + `schema` required.
245
+ description: "Body for `POST /api/admin/configs`. `name` + `schema` required. Per-env `dev`/`staging`/`prod` values are published to that env at version 1 (overriding `value`)."
232
246
  CreateConfigResponse:
233
247
  type: object
234
248
  properties:
@@ -251,11 +265,25 @@ UpdateConfigRequest:
251
265
  type: object
252
266
  additionalProperties: {}
253
267
  value:
254
- description: Flat value applied to **every** env. Publishes a new version per env. To target one env, use `PUT /{id}/drafts` then `POST /{id}/publish`.
268
+ type: object
269
+ additionalProperties: {}
270
+ description: Flat value applied to **every** env. Publishes a new version per env. To publish one env only, pass that env's key (`dev`/`staging`/`prod`) instead.
271
+ dev:
272
+ type: object
273
+ additionalProperties: {}
274
+ description: "Publish a new version to the **dev** env only, immediately (no draft). Overrides `value` for dev. Must match the effective schema."
275
+ staging:
276
+ type: object
277
+ additionalProperties: {}
278
+ description: "Publish a new version to the **staging** env only, immediately (no draft). Overrides `value` for staging. Must match the effective schema."
279
+ prod:
280
+ type: object
281
+ additionalProperties: {}
282
+ description: "Publish a new version to the **prod** env only, immediately (no draft). Overrides `value` for prod. Must match the effective schema."
255
283
  folder:
256
284
  $ref: ./common.yaml#/Folder
257
285
  additionalProperties: false
258
- description: Body for `PATCH /api/admin/configs/{id}`. Partial — only supplied fields change. `value` republishes on every env.
286
+ description: "Body for `PATCH /api/admin/configs/{id}`. Partial — only supplied fields change. `value` republishes on every env; per-env `dev`/`staging`/`prod` publish a new version to just that env."
259
287
  UpdateConfigResponse:
260
288
  type: object
261
289
  properties:
@@ -300,6 +328,8 @@ SaveConfigDraftRequest:
300
328
  env:
301
329
  $ref: ./common.yaml#/Env
302
330
  value:
331
+ type: object
332
+ additionalProperties: {}
303
333
  description: Draft value to stage on `env`. Validated against the config's current schema.
304
334
  required:
305
335
  - env
@@ -205,6 +205,9 @@ GateApiRow:
205
205
  locked:
206
206
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
207
207
  type: boolean
208
+ whitelist:
209
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
210
+ type: boolean
208
211
  required:
209
212
  - id
210
213
  - type
@@ -517,6 +520,9 @@ CreateGateRequest:
517
520
  locked:
518
521
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
519
522
  type: boolean
523
+ whitelist:
524
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
525
+ type: boolean
520
526
  required:
521
527
  - id
522
528
  - type
@@ -802,6 +808,9 @@ UpdateGateRequest:
802
808
  locked:
803
809
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
804
810
  type: boolean
811
+ whitelist:
812
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
813
+ type: boolean
805
814
  required:
806
815
  - id
807
816
  - type
@@ -94,14 +94,6 @@ ListI18nKeysResponse:
94
94
  anyOf:
95
95
  - type: string
96
96
  - type: "null"
97
- chunkId:
98
- description: Owning chunk (authoring grouping) id.
99
- type: string
100
- chunkName:
101
- description: Name of the owning chunk (authoring grouping), or `null` when it cannot be resolved.
102
- anyOf:
103
- - type: string
104
- - type: "null"
105
97
  updatedAt:
106
98
  description: ISO-8601 timestamp of the last edit.
107
99
  type: string
@@ -116,8 +108,6 @@ ListI18nKeysResponse:
116
108
  - variables
117
109
  - profileId
118
110
  - profileName
119
- - chunkId
120
- - chunkName
121
111
  - updatedAt
122
112
  - updatedBy
123
113
  additionalProperties: false
@@ -138,12 +128,6 @@ PushI18nKeysRequest:
138
128
  type: string
139
129
  format: uuid
140
130
  description: Target profile id to add keys to.
141
- chunk:
142
- description: Logical grouping the new keys are filed under. Defaults to `default`.
143
- type: string
144
- minLength: 1
145
- maxLength: 64
146
- default: default
147
131
  keys:
148
132
  type: array
149
133
  minItems: 1
@@ -174,12 +158,16 @@ PushI18nKeysRequest:
174
158
  - key
175
159
  - value
176
160
  additionalProperties: false
177
- description: Keys to add. Insert-only — existing keys are reported back as `skipped`.
161
+ description: Keys to add. Insert-only by default — existing keys are reported back as `skipped` (set `force` to overwrite them instead).
162
+ force:
163
+ type: boolean
164
+ default: false
165
+ description: Overwrite keys that already exist with the submitted value instead of skipping them. Overwritten keys come back as `updated`. Off by default so a routine push can never clobber live translations.
178
166
  required:
179
167
  - profile_id
180
168
  - keys
181
169
  additionalProperties: false
182
- description: "Body for `POST /api/admin/i18n/keys`. Insert-only: keys that already exist are never overwritten — use `PUT /keys/{id}` to change a value."
170
+ description: "Body for `POST /api/admin/i18n/keys`. Insert-only by default: keys that already exist are never overwritten — pass `force: true` to overwrite them in bulk, or use `PUT /keys/{id}` to change one value."
183
171
  PushI18nKeysResponse:
184
172
  type: object
185
173
  properties:
@@ -192,23 +180,30 @@ PushI18nKeysResponse:
192
180
  type: array
193
181
  items:
194
182
  type: string
195
- description: Key names that already existed and were left untouched.
183
+ description: Key names that already existed and were left untouched. Always empty when `force` was set — those key names come back under `updated` instead.
184
+ updated:
185
+ type: array
186
+ items:
187
+ type: string
188
+ description: Key names that already existed and were overwritten with the submitted value. Only ever non-empty when the push set `force`.
196
189
  pushed_count:
197
190
  type: number
198
191
  description: Number of keys inserted (== `added.length`).
199
192
  skipped_count:
200
193
  type: number
201
194
  description: Number of keys skipped (== `skipped.length`).
202
- chunk:
203
- description: The chunk the keys were filed under.
204
- type: string
195
+ updated_count:
196
+ type: number
197
+ description: Number of existing keys overwritten (== `updated.length`).
205
198
  required:
206
199
  - added
207
200
  - skipped
201
+ - updated
208
202
  - pushed_count
209
203
  - skipped_count
204
+ - updated_count
210
205
  additionalProperties: false
211
- description: Result of an insert-only key push.
206
+ description: Result of a key push — what was inserted, what was left alone, and (with `force`) what was overwritten.
212
207
  UpdateI18nKeyRequest:
213
208
  type: object
214
209
  properties:
@@ -249,12 +244,6 @@ UpsertI18nKeysRequest:
249
244
  type: string
250
245
  format: uuid
251
246
  description: Target profile id to upsert keys into.
252
- chunk:
253
- description: Logical grouping the keys are filed under. Defaults to `default`.
254
- type: string
255
- minLength: 1
256
- maxLength: 64
257
- default: default
258
247
  keys:
259
248
  type: array
260
249
  minItems: 1
@@ -297,12 +286,8 @@ UpsertI18nKeysResponse:
297
286
  upserted:
298
287
  type: number
299
288
  description: Number of keys written (inserted or overwritten).
300
- chunk:
301
- type: string
302
- description: The chunk the keys were filed under.
303
289
  required:
304
290
  - upserted
305
- - chunk
306
291
  additionalProperties: false
307
292
  description: Result of a bulk key upsert. The affected profile's KV snapshot is rebuilt (and the CDN purged) before this returns.
308
293
  ListI18nDraftsResponse:
@@ -465,12 +450,9 @@ UpsertI18nDraftKeyResponse:
465
450
  $ref: "./common.yaml#/OkResponse"
466
451
  PublishI18nProfileRequest:
467
452
  type: object
468
- properties:
469
- chunk:
470
- description: Optional chunk label to stamp on the audit log. Publishing is profile-wide regardless — the whole profile is snapshotted into one KV blob.
471
- type: string
453
+ properties: {}
472
454
  additionalProperties: false
473
- description: Body for `POST /api/admin/i18n/profiles/{profileId}/publish`. The `chunk` is an audit label only.
455
+ description: Body for `POST /api/admin/i18n/profiles/{profileId}/publish`. Publishing is profile-wide — the whole profile is snapshotted into one KV blob — so the body takes no options.
474
456
  PublishI18nProfileResponse:
475
457
  type: object
476
458
  properties:
@@ -481,11 +463,6 @@ PublishI18nProfileResponse:
481
463
  profile_id:
482
464
  type: string
483
465
  description: Profile that was published.
484
- chunk:
485
- anyOf:
486
- - type: string
487
- - type: "null"
488
- description: Audit chunk label, or `null` when none was given.
489
466
  published_at:
490
467
  type: string
491
468
  description: ISO-8601 timestamp of the publish.
@@ -514,7 +491,6 @@ PublishI18nProfileResponse:
514
491
  required:
515
492
  - ok
516
493
  - profile_id
517
- - chunk
518
494
  - published_at
519
495
  - version
520
496
  - key_count
@@ -487,6 +487,11 @@ MetricDirection:
487
487
  - lower_better
488
488
  - neutral
489
489
  description: Desired direction of movement. `higher_better` (default), `lower_better`, or `neutral` (guardrail).
490
+ MetricDisplayUnit:
491
+ description: Display unit (e.g. `ms`, `%`, `$`), or `null` when unitless.
492
+ anyOf:
493
+ - type: string
494
+ - type: "null"
490
495
  CreateMetricRequest:
491
496
  oneOf:
492
497
  - $ref: "#/CreateMetricWithQuery"
@@ -509,6 +514,8 @@ CreateMetricWithQuery:
509
514
  $ref: "#/MetricDefaultMinEffectOfInterest"
510
515
  direction:
511
516
  $ref: "#/MetricDirection"
517
+ unit:
518
+ $ref: "#/MetricDisplayUnit"
512
519
  required:
513
520
  - name
514
521
  - event_name
@@ -532,6 +539,8 @@ CreateMetricWithQueryIr:
532
539
  $ref: "#/MetricDefaultMinEffectOfInterest"
533
540
  direction:
534
541
  $ref: "#/MetricDirection"
542
+ unit:
543
+ $ref: "#/MetricDisplayUnit"
535
544
  required:
536
545
  - name
537
546
  - event_name
@@ -559,6 +568,8 @@ UpdateMetricWithQuery:
559
568
  $ref: "#/MetricDefaultMinEffectOfInterest"
560
569
  direction:
561
570
  $ref: "#/MetricDirection"
571
+ unit:
572
+ $ref: "#/MetricDisplayUnit"
562
573
  required:
563
574
  - query
564
575
  additionalProperties: false
@@ -578,6 +589,8 @@ UpdateMetricWithQueryIr:
578
589
  $ref: "#/MetricDefaultMinEffectOfInterest"
579
590
  direction:
580
591
  $ref: "#/MetricDirection"
592
+ unit:
593
+ $ref: "#/MetricDisplayUnit"
581
594
  required:
582
595
  - query_ir
583
596
  additionalProperties: false
@@ -595,8 +608,10 @@ UpdateMetricFields:
595
608
  $ref: "#/MetricDefaultMinEffectOfInterest"
596
609
  direction:
597
610
  $ref: "#/MetricDirection"
611
+ unit:
612
+ $ref: "#/MetricDisplayUnit"
598
613
  additionalProperties: false
599
- description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation, default minimum effect of interest, direction).
614
+ description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation, default minimum effect of interest, direction, display unit).
600
615
  CreateMetricResponse:
601
616
  type: object
602
617
  properties:
@@ -356,6 +356,11 @@ OpsRun:
356
356
  - type: string
357
357
  - type: "null"
358
358
  description: The agent-run session id recorded on the ack (dashboard deep-links to the run page), or `null`.
359
+ sessionUrl:
360
+ anyOf:
361
+ - type: string
362
+ - type: "null"
363
+ description: "The run's session-page deep link, or `null`. DERIVED (never stored): rebuilt from `sessionId` + the run's trigger connector — Claude's routine id (`?trigger=`), Copilot's repo (`/tasks/`), Cursor/Jules from the id alone."
359
364
  startedAt:
360
365
  type: string
361
366
  description: ISO-8601 timestamp the run started (the ack time).
@@ -365,15 +370,7 @@ OpsRun:
365
370
  - type: "null"
366
371
  description: ISO-8601 timestamp the run closed, or `null` while still open.
367
372
  completedAction:
368
- anyOf:
369
- - type: string
370
- enum:
371
- - link_pr
372
- - notify
373
- - status
374
- - superseded
375
- - type: "null"
376
- description: "Which final action closed the run — `link_pr`/`notify` are the agent's terminal ops actions, `status` a completion status flip (ready_for_qa/resolved), `superseded` a newer ack replacing it. `null` while the run is open."
373
+ $ref: "#/OpsRunActionOrNull"
377
374
  prNumber:
378
375
  anyOf:
379
376
  - type: number
@@ -390,6 +387,7 @@ OpsRun:
390
387
  - connectorId
391
388
  - ackedBy
392
389
  - sessionId
390
+ - sessionUrl
393
391
  - startedAt
394
392
  - completedAt
395
393
  - completedAction
@@ -918,6 +916,28 @@ CreateBugRequest:
918
916
  - $ref: "#/OpsItemPriority"
919
917
  - type: "null"
920
918
  description: Initial triage priority, or `null`.
919
+ status:
920
+ anyOf:
921
+ - $ref: "#/OpsItemStatus"
922
+ description: Initial lifecycle status; defaults to `open` when omitted.
923
+ assigneeId:
924
+ anyOf:
925
+ - type: string
926
+ - type: "null"
927
+ description: The `users.id` of the person to assign as owner at creation, or `null`.
928
+ subscribers:
929
+ type: array
930
+ items:
931
+ type: string
932
+ format: email
933
+ default: []
934
+ description: Emails of teammates to subscribe to this item's Slack pings at creation.
935
+ tags:
936
+ type: array
937
+ items:
938
+ type: string
939
+ default: []
940
+ description: Tag names to attach at creation (get-or-created by name, deduped case-insensitively).
921
941
  reporterEmail:
922
942
  anyOf:
923
943
  - type: string
@@ -987,6 +1007,28 @@ CreateFeatureRequestRequest:
987
1007
  - $ref: "#/OpsItemPriority"
988
1008
  - type: "null"
989
1009
  description: Initial triage priority, or `null`.
1010
+ status:
1011
+ anyOf:
1012
+ - $ref: "#/OpsItemStatus"
1013
+ description: Initial lifecycle status; defaults to `open` when omitted.
1014
+ assigneeId:
1015
+ anyOf:
1016
+ - type: string
1017
+ - type: "null"
1018
+ description: The `users.id` of the person to assign as owner at creation, or `null`.
1019
+ subscribers:
1020
+ type: array
1021
+ items:
1022
+ type: string
1023
+ format: email
1024
+ default: []
1025
+ description: Emails of teammates to subscribe to this item's Slack pings at creation.
1026
+ tags:
1027
+ type: array
1028
+ items:
1029
+ type: string
1030
+ default: []
1031
+ description: Tag names to attach at creation (get-or-created by name, deduped case-insensitively).
990
1032
  reporterEmail:
991
1033
  anyOf:
992
1034
  - type: string
@@ -1127,6 +1169,22 @@ OpsItemNotifyOrNull:
1127
1169
  - $ref: ./common.yaml#/NotificationTarget
1128
1170
  - type: "null"
1129
1171
  description: Where this item's completion notification lands, or `null`.
1172
+ OpsRunAction:
1173
+ type: string
1174
+ enum:
1175
+ - link_pr
1176
+ - notify
1177
+ - status
1178
+ - superseded
1179
+ description: >-
1180
+ The final action that closed a run record — `link_pr`/`notify` are the
1181
+ agent's terminal ops actions, `status` a completion status flip
1182
+ (ready_for_qa/resolved), `superseded` a newer ack replacing an open run.
1183
+ OpsRunActionOrNull:
1184
+ anyOf:
1185
+ - $ref: "#/OpsRunAction"
1186
+ - type: "null"
1187
+ description: Which final action closed the run, or `null` while it is open (or a non-run record).
1130
1188
  UpdateOpsItemStatusRequest:
1131
1189
  type: object
1132
1190
  properties:
@@ -1681,22 +1739,19 @@ OpsInvestigation:
1681
1739
  anyOf:
1682
1740
  - type: string
1683
1741
  - type: "null"
1684
- description: The agent-run session id, or `null`.
1685
- ackedBy:
1742
+ description: "The agent-run session id, or `null`."
1743
+ sessionUrl:
1686
1744
  anyOf:
1687
1745
  - type: string
1688
1746
  - type: "null"
1689
- description: Email of the human who acked (run records for a human ack), or `null`.
1690
- completedAction:
1747
+ description: "The run's session-page deep link, or `null`. DERIVED (never stored): rebuilt from `sessionId` + the run's trigger connector — Claude's routine id (`?trigger=`), Copilot's repo (`/tasks/`), Cursor/Jules from the id alone. Only `working` run records carry one."
1748
+ ackedBy:
1691
1749
  anyOf:
1692
1750
  - type: string
1693
- enum:
1694
- - link_pr
1695
- - notify
1696
- - status
1697
- - superseded
1698
1751
  - type: "null"
1699
- description: "Which final action closed a `working` run record, or `null` (open run / non-run record)."
1752
+ description: Email of the human who acked (run records for a human ack), or `null`.
1753
+ completedAction:
1754
+ $ref: "#/OpsRunActionOrNull"
1700
1755
  createdAt:
1701
1756
  type: string
1702
1757
  description: ISO-8601 creation timestamp.
@@ -1724,6 +1779,7 @@ OpsInvestigation:
1724
1779
  - startedAt
1725
1780
  - completedAt
1726
1781
  - sessionId
1782
+ - sessionUrl
1727
1783
  - ackedBy
1728
1784
  - completedAction
1729
1785
  - createdAt
@@ -1840,6 +1896,94 @@ CreateOpsInvestigationRequest:
1840
1896
  - kind
1841
1897
  additionalProperties: false
1842
1898
  description: "Body for `POST /api/admin/ops/{handle}/investigation`. `kind` is required; include at least one content field (`summary`/`findings`/`question`/`qaNotes`) — the panel renders whatever it gets."
1899
+ UpdateOpsInvestigationRequest:
1900
+ type: object
1901
+ properties:
1902
+ kind:
1903
+ type: string
1904
+ enum:
1905
+ - investigated
1906
+ - detected
1907
+ - question
1908
+ - ready_for_qa
1909
+ - working
1910
+ - note
1911
+ description: Reclassify the record's lifecycle stage (e.g. flip a `working` run into `investigated` once findings land).
1912
+ summary:
1913
+ type: string
1914
+ maxLength: 2000
1915
+ description: One-line summary of the record.
1916
+ findings:
1917
+ type: string
1918
+ maxLength: 50000
1919
+ description: The full findings write-up (markdown).
1920
+ question:
1921
+ type: string
1922
+ maxLength: 10000
1923
+ description: A blocking question for the team (markdown).
1924
+ qaNotes:
1925
+ type: string
1926
+ maxLength: 50000
1927
+ description: How to verify the fix — QA notes (markdown).
1928
+ model:
1929
+ type: string
1930
+ maxLength: 200
1931
+ description: The model the agent ran on.
1932
+ prNumber:
1933
+ type: integer
1934
+ description: A PR the record references.
1935
+ prUrl:
1936
+ type: string
1937
+ format: uri
1938
+ maxLength: 2000
1939
+ description: HTML URL of that PR.
1940
+ sources:
1941
+ type: array
1942
+ maxItems: 200
1943
+ items:
1944
+ type: object
1945
+ properties:
1946
+ path:
1947
+ type: string
1948
+ description: Repo-relative file path inspected.
1949
+ url:
1950
+ type: string
1951
+ description: External link consulted.
1952
+ label:
1953
+ type: string
1954
+ description: Human-readable label for the source.
1955
+ additionalProperties: false
1956
+ description: One file/link inspected while producing the record.
1957
+ description: The files/links inspected.
1958
+ confidence:
1959
+ type: string
1960
+ enum:
1961
+ - low
1962
+ - medium
1963
+ - high
1964
+ description: Self-reported confidence in the record.
1965
+ tokensUsed:
1966
+ type: integer
1967
+ description: Tokens the run consumed.
1968
+ durationMs:
1969
+ type: integer
1970
+ description: Run duration in milliseconds.
1971
+ visibility:
1972
+ type: string
1973
+ enum:
1974
+ - draft
1975
+ - published
1976
+ description: Record visibility. `draft` keeps it out of the panel; `published` surfaces it.
1977
+ completedAt:
1978
+ type: string
1979
+ description: ISO-8601 timestamp the work finished. Set it (or flip `kind` off `working`) to mark a run record done.
1980
+ sessionId:
1981
+ type: string
1982
+ maxLength: 300
1983
+ description: The agent-run session id, so the dashboard can deep-link to the run.
1984
+ additionalProperties: false
1985
+ minProperties: 1
1986
+ description: "Body for `PATCH /api/admin/ops/{handle}/investigation/{investigationId}` — a partial update of one existing investigation record (typically the `working` run record you were handed). Send only the fields you want to change; at least one is required."
1843
1987
  NotificationFeedItem:
1844
1988
  type: object
1845
1989
  properties:
package/spec/openapi.yaml CHANGED
@@ -209,6 +209,15 @@ tags:
209
209
  **Mentions.** `@teammate` in a body raises an in-app notification for that
210
210
  person; `@shipeasy` asks Jarvis (the AI agent) to read the item and reply.
211
211
  Comments authored by Jarvis carry `authorType: system`.
212
+ - name: Investigations
213
+ parent: Ops
214
+ description: |-
215
+ Investigation records on a queue item — the structured, read-only write-ups
216
+ an AI agent produces while working it (findings / a blocking question / QA
217
+ notes), plus the `working` run rows an ack or an AI hand-off opens. This is
218
+ the AI-write seam the cockpit's detail panel renders: `list` reads what a
219
+ previous run found, `create` appends a new record, and `update` fills in the
220
+ `working` run record you were handed (findings, PR, confidence) as you work.
212
221
  - name: Projects
213
222
  description: |-
214
223
  Projects: the account-level container every other resource is scoped to.
@@ -219,14 +228,14 @@ tags:
219
228
  - name: i18n
220
229
  description: |-
221
230
  String Manager (i18n): the worker-safe REST surface — locale profiles, the
222
- insert-only key push, single-key overwrite, chunk publish, and the read-only
231
+ insert-only key push, single-key overwrite, profile publish, and the read-only
223
232
  key/draft listings.
224
233
 
225
234
  The fs/AST parts (scan, validate, install-loader, codemod) are NOT part of
226
235
  this API — they stay in the fs-having CLI/MCP.
227
236
  - name: Profiles
228
237
  parent: i18n
229
- description: Locale profiles (e.g. `en:prod`) — create, list, and publish a profile's chunks to the CDN.
238
+ description: Locale profiles (e.g. `en:prod`) — create, list, and publish a profile to the CDN.
230
239
  - name: Keys
231
240
  parent: i18n
232
241
  description: Translation keys — the insert-only push, single-key overwrite, and key listing.
@@ -351,6 +360,8 @@ paths:
351
360
  $ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1ack
352
361
  /api/admin/ops/{handle}/investigation:
353
362
  $ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1investigation
363
+ /api/admin/ops/{handle}/investigation/{investigationId}:
364
+ $ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1investigation~1{investigationId}
354
365
  /api/admin/agent-profiles:
355
366
  $ref: ./paths/ops.yaml#/~1api~1admin~1agent-profiles
356
367
  /api/admin/ops/{handle}/comments: