@openwop/spec-artifacts 2.42.6 → 2.42.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CORPUS-STAMP.json +70 -67
  2. package/api/seams-v2.yaml +238 -322
  3. package/api/v2/asyncapi.yaml +83 -113
  4. package/api/v2/openapi.yaml +408 -724
  5. package/package.json +1 -1
  6. package/schemas/audit-verify-result.schema.json +2 -2
  7. package/schemas/v2/audit-verify-result.schema.json +2 -2
  8. package/schemas/v2/capabilities.schema.json +4 -7
  9. package/schemas/v2/error-envelope.schema.json +144 -69
  10. package/spec/v1/alias-detectors.json +6 -0
  11. package/spec/v1/core-standard-manifest.json +2 -2
  12. package/spec/v1/deprecations.json +22 -0
  13. package/spec/v1/gaps.json +188 -1
  14. package/spec/v1/migrations.json +18 -0
  15. package/spec/v2/README.md +35 -37
  16. package/spec/v2/core/capabilities.md +186 -119
  17. package/spec/v2/core/conformance.md +78 -27
  18. package/spec/v2/core/connection-packs.md +8 -3
  19. package/spec/v2/core/conversation.md +10 -4
  20. package/spec/v2/core/errors.md +30 -9
  21. package/spec/v2/core/events.md +116 -80
  22. package/spec/v2/core/form-content-packs.md +11 -13
  23. package/spec/v2/core/headers.md +23 -14
  24. package/spec/v2/core/host-services.md +22 -5
  25. package/spec/v2/core/i18n.md +64 -0
  26. package/spec/v2/core/idempotency.md +48 -36
  27. package/spec/v2/core/identity.md +110 -42
  28. package/spec/v2/core/interop.md +82 -21
  29. package/spec/v2/core/interrupt.md +79 -40
  30. package/spec/v2/core/node-pack-runtimes.md +18 -4
  31. package/spec/v2/core/oauth.md +40 -6
  32. package/spec/v2/core/overview.md +61 -33
  33. package/spec/v2/core/packs.md +53 -28
  34. package/spec/v2/core/persistence.md +61 -80
  35. package/spec/v2/core/portability.md +44 -0
  36. package/spec/v2/core/replay.md +56 -42
  37. package/spec/v2/core/runs.md +198 -60
  38. package/spec/v2/core/security-defaults.md +57 -33
  39. package/spec/v2/core/tool-catalog.md +29 -6
  40. package/spec/v2/core/versioning.md +115 -50
  41. package/spec/v2/core/webhooks.md +61 -20
  42. package/spec/v2/core/workflow-chain-packs.md +16 -14
  43. package/spec/v2/corrections.json +17 -1
  44. package/spec/v2/corrections.schema.json +1 -1
  45. package/spec/v2/declaration.json +26 -9
  46. package/spec/v2/declaration.schema.json +10 -0
  47. package/spec/v2/errors.json +121 -4
  48. package/spec/v2/errors.schema.json +38 -0
  49. package/spec/v2/ext/README.md +36 -23
  50. package/spec/v2/ext/a2uiSurface/README.md +75 -89
  51. package/spec/v2/ext/brand/README.md +15 -15
  52. package/spec/v2/ext/canvas/README.md +15 -15
  53. package/spec/v2/ext/chat/README.md +15 -15
  54. package/spec/v2/ext/coordination/README.md +15 -15
  55. package/spec/v2/ext/dataIntegration/README.md +17 -20
  56. package/spec/v2/ext/entities/README.md +15 -15
  57. package/spec/v2/ext/grpc-transport/README.md +6 -8
  58. package/spec/v2/ext/kanban/README.md +15 -15
  59. package/spec/v2/ext/knowledge/README.md +15 -15
  60. package/spec/v2/ext/launchStudio/README.md +16 -16
  61. package/spec/v2/ext/messaging/README.md +15 -15
  62. package/spec/v2/ext/portability/README.md +3 -17
  63. package/spec/v2/ext/provider-idempotency/README.md +7 -10
  64. package/spec/v2/ext/restTransport/README.md +30 -19
  65. package/spec/v2/ext/sandbox-runtime-notes/README.md +7 -9
  66. package/spec/v2/ext/webResearch/README.md +16 -16
  67. package/spec/v2/profiles.json +6 -2
  68. package/spec/v2/release.json +2 -2
  69. package/spec/v2/surface-baseline.json +544 -2
package/api/seams-v2.yaml CHANGED
@@ -1,15 +1,16 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP conformance seams profile (openwop-conformance-seams-v2)
4
- version: 2.42.6
5
- description: 'GENERATED by scripts/derive-v2-api.py. RFC 0168 §C: the seams are a versioned conformance profile with their
6
- own document and path space (/conformance/seams/…), validated against the canonical v2 schemas with no tolerance path,
7
- forbidden from the capability namespace (a host advertises the profile, never a testSeams flag). This document carries
8
- the nine operations the v1 canonical document used to carry; the 2.0.0 suite driver (P3-E2) rewrites the remaining host-sample-test-seams.md
9
- paths into this space, and P3-E3 adds the two RFC 0176 seams (event-log seed, inbound webhook receiver).'
4
+ version: 2.42.8
5
+ description: 'The OpenWOP conformance seams profile (`openwop-conformance-seams-v2`): test-only operations in their own
6
+ path space, `/conformance/seams/…`. The profile is versioned and validated against the canonical v2 schemas with no tolerance
7
+ path. It is not a capability: a host advertises the profile, never a `testSeams` flag.
8
+
9
+
10
+ Generated from `api/openapi.yaml` by `scripts/derive-v2-api.py`; do not edit.'
10
11
  servers:
11
12
  - url: https://{host}
12
- description: openwop-compliant server
13
+ description: An OpenWOP server.
13
14
  variables:
14
15
  host:
15
16
  default: api.example.com
@@ -19,18 +20,10 @@ paths:
19
20
  get:
20
21
  tags:
21
22
  - host
22
- summary: Read the persisted durable A2A task projection (RFC 0100, host-extension).
23
- description: 'Returns the persisted `A2ATaskState` for `taskId` (== the backing
24
-
25
- `runId`) per RFC 0100 §2 — a host-extension convenience read of the
26
-
27
- durable projection that survives caller disconnect. The normative A2A
28
-
29
- read surface remains the A2A `tasks/get` JSON-RPC method. Hosts that do
30
-
31
- not advertise `capabilities.a2a.durableTasks` return `501`.
32
-
33
- '
23
+ summary: Read the persisted durable A2A task projection (host extension).
24
+ description: 'Returns the persisted `A2ATaskState` for `taskId` (equal to the backing `runId`): a host-extension convenience
25
+ read of the durable projection, which survives caller disconnect. The normative A2A read surface remains the A2A `tasks/get`
26
+ JSON-RPC method. Hosts that do not advertise `capabilities.a2a.durableTasks` return `501`.'
34
27
  operationId: getA2ATaskState
35
28
  security:
36
29
  - ApiKeyAuth:
@@ -61,7 +54,7 @@ paths:
61
54
  '404':
62
55
  $ref: '#/components/responses/NotFound'
63
56
  '501':
64
- description: Host does not advertise capabilities.a2a.durableTasks (RFC 0100).
57
+ description: Host does not advertise `capabilities.a2a.durableTasks`.
65
58
  content:
66
59
  application/json:
67
60
  schema:
@@ -70,14 +63,9 @@ paths:
70
63
  get:
71
64
  tags:
72
65
  - host
73
- summary: List workspace file metadata for the caller's tenant·workspace (RFC 0059).
74
- description: 'Returns file metadata (no bodies) for the caller''s `{tenant,
75
-
76
- workspace}` per RFC 0059 §C. Optional `?prefix=` filters the flat
77
-
78
- `path` namespace to entries starting with the given prefix.
79
-
80
- '
66
+ summary: List workspace file metadata for the caller's tenant·workspace.
67
+ description: Returns file metadata, without bodies, for the caller's `{tenant, workspace}`. An optional `?prefix=` filters
68
+ the flat `path` namespace to entries starting with that prefix.
81
69
  operationId: listWorkspaceFiles
82
70
  security:
83
71
  - ApiKeyAuth:
@@ -108,7 +96,7 @@ paths:
108
96
  '403':
109
97
  $ref: '#/components/responses/Forbidden'
110
98
  '501':
111
- description: Host does not advertise capabilities.workspace.supported (RFC 0059).
99
+ description: Host does not advertise `capabilities.workspace.supported`.
112
100
  content:
113
101
  application/json:
114
102
  schema:
@@ -117,14 +105,9 @@ paths:
117
105
  get:
118
106
  tags:
119
107
  - host
120
- summary: Read one workspace file (RFC 0059).
121
- description: 'Returns the `WorkspaceFile` at `path` for the caller''s `{tenant,
122
-
123
- workspace}`. When `capabilities.workspace.versioned: true`, an
124
-
125
- optional `?version=N` returns the historical snapshot at version N.
126
-
127
- '
108
+ summary: Read one workspace file.
109
+ description: 'Returns the `WorkspaceFile` at `path` for the caller''s `{tenant, workspace}`. When `capabilities.workspace.versioned:
110
+ true`, an optional `?version=N` returns the historical snapshot at version N.'
128
111
  operationId: getWorkspaceFile
129
112
  security:
130
113
  - ApiKeyAuth:
@@ -150,7 +133,7 @@ paths:
150
133
  '404':
151
134
  $ref: '#/components/responses/NotFound'
152
135
  '501':
153
- description: Host does not advertise capabilities.workspace.supported (RFC 0059).
136
+ description: Host does not advertise `capabilities.workspace.supported`.
154
137
  content:
155
138
  application/json:
156
139
  schema:
@@ -158,20 +141,11 @@ paths:
158
141
  put:
159
142
  tags:
160
143
  - host
161
- summary: Atomic create/replace of a workspace file (RFC 0059).
162
- description: 'Atomically creates or replaces the file at `path` per RFC 0059 §C.
163
-
164
- MUST honor `If-Match: <etag>` — a stale token returns `409
165
-
166
- workspace_conflict` (`details.currentVersion` carries the live
167
-
168
- version). On success the host bumps `version`, recomputes `etag`,
169
-
170
- and emits a `workspace.updated` event. A `content` exceeding
171
-
172
- `capabilities.workspace.maxFileBytes` returns `workspace_too_large`.
173
-
174
- '
144
+ summary: Atomically create or replace a workspace file.
145
+ description: 'Atomically creates or replaces the file at `path`. MUST honor `If-Match: <etag>`: a stale token returns
146
+ `409 workspace_conflict`, with `details.currentVersion` carrying the live version. On success the host bumps `version`,
147
+ recomputes `etag`, and emits a `workspace.updated` event. A `content` exceeding `capabilities.workspace.maxFileBytes`
148
+ returns `workspace_too_large`.'
175
149
  operationId: putWorkspaceFile
176
150
  security:
177
151
  - ApiKeyAuth:
@@ -216,7 +190,7 @@ paths:
216
190
  schema:
217
191
  $ref: ../schemas/v2/error-envelope.schema.json
218
192
  '501':
219
- description: Host does not advertise capabilities.workspace.supported (RFC 0059).
193
+ description: Host does not advertise `capabilities.workspace.supported`.
220
194
  content:
221
195
  application/json:
222
196
  schema:
@@ -224,12 +198,9 @@ paths:
224
198
  delete:
225
199
  tags:
226
200
  - host
227
- summary: Delete a workspace file (RFC 0059).
228
- description: 'Removes the file at `path` (and, when `versioned: true`, writes a
229
-
230
- tombstone). Emits a `workspace.updated` event on success.
231
-
232
- '
201
+ summary: Delete a workspace file.
202
+ description: 'Removes the file at `path` (and, when `versioned: true`, writes a tombstone). Emits a `workspace.updated`
203
+ event on success.'
233
204
  operationId: deleteWorkspaceFile
234
205
  security:
235
206
  - ApiKeyAuth:
@@ -251,7 +222,7 @@ paths:
251
222
  '404':
252
223
  $ref: '#/components/responses/NotFound'
253
224
  '501':
254
- description: Host does not advertise capabilities.workspace.supported (RFC 0059).
225
+ description: Host does not advertise `capabilities.workspace.supported`.
255
226
  content:
256
227
  application/json:
257
228
  schema:
@@ -264,35 +235,15 @@ paths:
264
235
  tags:
265
236
  - packs-test
266
237
  summary: Publish a pack tarball to the isolated test catalog.
267
- description: 'Mirror of `PUT /v1/packs/{name}/-/{version}.tgz` per
268
-
269
- `spec/v1/node-packs.md` §"PUT /v1/packs/{name}/-/{version}.tgz".
270
-
271
- Request shape, response shape, status codes, and the 19-code
272
-
273
- publish error catalog (`invalid_pack_scope`, `invalid_pack_name`,
274
-
275
- `invalid_version`, `invalid_body`, eight `tarball_*` codes,
276
-
277
- `invalid_manifest`, `manifest_mismatch` (or the granular
278
-
279
- `manifest_name_mismatch` / `manifest_version_mismatch` pair),
238
+ description: 'Mirrors the registry''s `PUT /v1/packs/{name}/-/{version}.tgz` (`spec/v1/node-packs.md`). The request
239
+ shape, response shape, status codes, and publish error catalog MUST be served verbatim: `invalid_pack_scope`, `invalid_pack_name`,
240
+ `invalid_version`, `invalid_body`, eight `tarball_*` codes, `invalid_manifest`, `manifest_mismatch` (or the granular
241
+ `manifest_name_mismatch` / `manifest_version_mismatch` pair), `pack_integrity_failure`, `unsupported_runtime`, `forbidden`,
242
+ `conflict`/`version_conflict`.
280
243
 
281
- `pack_integrity_failure`, `unsupported_runtime`, `forbidden`,
282
244
 
283
- `conflict`/`version_conflict`) MUST be served verbatim. The
284
-
285
- test catalog MUST be isolated per RFC 0025 §C — a pack PUT''d
286
-
287
- here MUST NOT appear in `GET /v1/packs/{name}` listings.
288
-
289
- The mirrored production path is registry-service surface
290
-
291
- (`registry-operations.md`), not defined in this host document
292
-
293
- (see the `packs-test` tag scope note).
294
-
295
- '
245
+ The test catalog MUST be isolated: a pack PUT here MUST NOT appear in `GET /v1/packs/{name}` listings. The mirrored
246
+ production path is registry-service surface (`registry-operations.md`), not defined in this document.'
296
247
  operationId: putTestPackTarball
297
248
  security:
298
249
  - ApiKeyAuth:
@@ -352,29 +303,12 @@ paths:
352
303
  schema:
353
304
  $ref: '#/components/schemas/TestPackPublishRecord'
354
305
  '400':
355
- description: 'One of the 17 spec-documented 400-class publish error codes:
356
-
357
- URL/scope (`invalid_pack_scope`, `invalid_pack_name`, `invalid_version`),
358
-
359
- body shape (`invalid_body`),
360
-
361
- tarball extraction (`tarball_gunzip_failed`, `tarball_too_large`,
362
-
363
- `tarball_manifest_missing`, `tarball_manifest_too_large`,
364
-
365
- `tarball_manifest_not_json`, `tarball_entry_missing`,
366
-
367
- `tarball_entry_too_large`, `tarball_path_traversal`,
368
-
369
- `tarball_tar_parse_failed`),
370
-
371
- manifest contents (`invalid_manifest`, `manifest_mismatch` or
372
-
373
- the granular `manifest_name_mismatch` / `manifest_version_mismatch` pair,
374
-
375
- `pack_integrity_failure`, `unsupported_runtime`).
376
-
377
- '
306
+ description: 'One of the documented 400-class publish error codes: URL or scope (`invalid_pack_scope`, `invalid_pack_name`,
307
+ `invalid_version`), body shape (`invalid_body`), tarball extraction (`tarball_gunzip_failed`, `tarball_too_large`,
308
+ `tarball_manifest_missing`, `tarball_manifest_too_large`, `tarball_manifest_not_json`, `tarball_entry_missing`,
309
+ `tarball_entry_too_large`, `tarball_path_traversal`, `tarball_tar_parse_failed`), or manifest contents (`invalid_manifest`,
310
+ `manifest_mismatch` or the granular `manifest_name_mismatch` / `manifest_version_mismatch` pair, `pack_integrity_failure`,
311
+ `unsupported_runtime`).'
378
312
  content:
379
313
  application/json:
380
314
  schema:
@@ -404,10 +338,9 @@ paths:
404
338
  tags:
405
339
  - packs-test
406
340
  summary: Fetch a published test-catalog tarball.
407
- description: 'Mirror of `GET /v1/packs/{name}/-/{version}.tgz`. Returns the gzipped tarball bytes with `Content-Type:
408
- application/tar+gzip` and an `ETag: "sha256-..."` matching the manifest''s `tarballSha256`. The mirrored production
409
- path is registry-service surface (`registry-operations.md`), not defined in this host document (see the `packs-test`
410
- tag scope note).'
341
+ description: 'Mirrors the registry''s `GET /v1/packs/{name}/-/{version}.tgz`. Returns the gzipped tarball bytes with
342
+ `Content-Type: application/tar+gzip` and an `ETag: "sha256-..."` matching the manifest''s `tarballSha256`. The mirrored
343
+ production path is registry-service surface (`registry-operations.md`), not defined in this document.'
411
344
  operationId: getTestPackTarball
412
345
  security:
413
346
  - ApiKeyAuth:
@@ -452,26 +385,11 @@ paths:
452
385
  delete:
453
386
  tags:
454
387
  - packs-test
455
- summary: Unpublish a test-catalog version (mirrors unpublish-window semantics).
456
- description: 'Mirror of `DELETE /v1/packs/{name}/-/{version}` per
457
-
458
- `spec/v1/node-packs.md`. Returns `400 unpublish_window_expired`
459
-
460
- for versions older than the registry''s unpublish window
461
-
462
- (default 72h). Test-mode implementations MAY shorten the
463
-
464
- window for tractable conformance fixtures but MUST surface
465
-
466
- the same error code. The mirrored production path is
467
-
468
- registry-service surface (`registry-operations.md`), not
469
-
470
- defined in this host document (see the `packs-test` tag
471
-
472
- scope note).
473
-
474
- '
388
+ summary: Unpublish a test-catalog version (same unpublish-window semantics as the registry).
389
+ description: Mirrors the registry's `DELETE /v1/packs/{name}/-/{version}` (`spec/v1/node-packs.md`). Returns `400 unpublish_window_expired`
390
+ for versions older than the registry's unpublish window (default 72h). Test-mode implementations MAY shorten the window
391
+ for tractable conformance fixtures but MUST surface the same error code. The mirrored production path is registry-service
392
+ surface (`registry-operations.md`), not defined in this document.
475
393
  operationId: deleteTestPackVersion
476
394
  security:
477
395
  - ApiKeyAuth:
@@ -511,17 +429,9 @@ paths:
511
429
  tags:
512
430
  - packs-test
513
431
  summary: Fetch the detached Ed25519 signature for a test-catalog pack.
514
- description: 'Mirror of `GET /v1/packs/{name}/-/{version}.sig`. Returns the
515
-
516
- signature blob over `pack.json` for this version. MAY 302-redirect
517
-
518
- to a storage-backend signed URL. The mirrored production path is
519
-
520
- registry-service surface (`registry-operations.md`), not defined
521
-
522
- in this host document (see the `packs-test` tag scope note).
523
-
524
- '
432
+ description: Mirrors the registry's `GET /v1/packs/{name}/-/{version}.sig`. Returns the signature blob over `pack.json`
433
+ for this version. MAY 302-redirect to a storage-backend signed URL. The mirrored production path is registry-service
434
+ surface (`registry-operations.md`), not defined in this document.
525
435
  operationId: getTestPackSignature
526
436
  security:
527
437
  - ApiKeyAuth:
@@ -560,19 +470,9 @@ paths:
560
470
  schema:
561
471
  $ref: ../schemas/v2/error-envelope.schema.json
562
472
  '404':
563
- description: '`signature_not_available` — version is missing, yanked,
564
-
565
- unsigned at publish time, OR the registry''s storage backend
566
-
567
- is unwired. The four cases are intentionally
568
-
569
- indistinguishable per spec/v1/node-packs.md §"GET /v1/packs/{name}/-/{version}.sig".
570
-
571
- Also returned when the host does not advertise
572
-
573
- `capabilities.packs.testMode.supported: true`.
574
-
575
- '
473
+ description: '`signature_not_available`: the version is missing, yanked, or unsigned at publish time, or the registry''s
474
+ storage backend is unwired. The four cases are intentionally indistinguishable (spec/v1/node-packs.md). Also returned
475
+ when the host does not advertise `capabilities.packs.testMode.supported: true`.'
576
476
  content:
577
477
  application/json:
578
478
  schema:
@@ -582,11 +482,11 @@ paths:
582
482
  tags:
583
483
  - Seams
584
484
  operationId: seedEra2EventLog
585
- summary: Persist a run whose event log is in v1 vocabulary (era 2) — RFC 0176 §A/§B/§C witnesses
586
- description: 'The host MUST persist the rows verbatim (v1 `type` strings, the given `sequence` space, no era stamp:
587
- the run reads as era `2` by the absent-⇒-`2` rule of persistence.md) and MUST NOT translate at write time; the read
588
- projection is what the scenarios `v2-v1-events-translated`, `v2-unmapped-type-refused`, `v2-fork-a-v1-run` and `v2-pinned-run-disposition`
589
- witness. `status` is the snapshot status the seeded run holds.'
485
+ summary: Persist a run whose event log uses v1 vocabulary (era 2)
486
+ description: 'Seeds a run whose stored event log is in v1 vocabulary. The host MUST persist the rows verbatim: v1 `type`
487
+ strings, the given `sequence` space, and no era stamp, so the run reads as era `2` by the absent-⇒-`2` rule of persistence.md.
488
+ The host MUST NOT translate at write time. The scenarios `v2-v1-events-translated`, `v2-unmapped-type-refused`, `v2-fork-a-v1-run`
489
+ and `v2-pinned-run-disposition` witness the read projection. `status` is the snapshot status the seeded run holds.'
590
490
  requestBody:
591
491
  required: true
592
492
  content:
@@ -653,14 +553,15 @@ paths:
653
553
  tags:
654
554
  - Seams
655
555
  operationId: appendEra2Event
656
- summary: Append a v2-named event to a seeded era-2 run through the host's production writer — RFC 0176 §A writer-rule
657
- witness
658
- description: 'The host MUST append the event through the SAME writer its own code uses for that run — the storage boundary
659
- that applies the writer rule (persistence.md §The writer rule) — and MUST NOT branch on the seam: an era-2 run stores
556
+ summary: Append a v2-named event to a seeded era-2 run through the host's production writer
557
+ description: 'The host MUST append the event through the same writer its own code uses for that run (the storage boundary
558
+ that applies the writer rule, persistence.md §The writer rule) and MUST NOT branch on the seam. An era-2 run stores
660
559
  the event under its v1 spelling (the codemap''s v1 side), so the production read returns the v2 `type` given here.
560
+
561
+
661
562
  The seam MUST refuse a `runId` that `seedEra2EventLog` did not create with `404`, exactly as for an unknown run, so
662
- it cannot inject into a real run; a terminal run answers `409 run_terminal`; a `type` that is not a v2 registry name
663
- answers `400`. Consumed by `v2-era-2-append-vocabulary`.'
563
+ it cannot inject into a real run. A terminal run answers `409 run_terminal`; a `type` that is not a v2 registry name
564
+ answers `400`. Used by `v2-era-2-append-vocabulary`.'
664
565
  requestBody:
665
566
  required: true
666
567
  content:
@@ -705,22 +606,71 @@ paths:
705
606
  $ref: '#/components/responses/NotFound'
706
607
  '409':
707
608
  description: The run is terminal (`run_terminal`).
609
+ /conformance/seams/sample/test/mock-ai/dispatch-budgets:
610
+ get:
611
+ tags:
612
+ - Seams
613
+ operationId: getMockDispatchBudgets
614
+ summary: Per-attempt output budgets the conformance mock provider received for one node — RFC 0033 §C witness
615
+ description: 'One entry per call the host''s conformance mock provider received for `nodeId` since its program was last
616
+ seeded (seeding clears the history), in call order; `maxTokens` is the output budget THAT call carried to the provider,
617
+ or `null` when it carried none. Each entry is per attempt: it MUST NOT be accumulated across attempts, the node or
618
+ the run, and MUST record what reached the provider, not what the retry router intended. An unseeded `nodeId` answers
619
+ an empty `attempts`. OPTIONAL; consumed by `envelope-completion-distinguishes-truncation` (RFC 0033 §C: a schema-violation
620
+ retry SHALL NOT carry an increased budget). An unserved seam leaves that leg a partial witness, never `blocked`.'
621
+ parameters:
622
+ - name: nodeId
623
+ in: query
624
+ required: true
625
+ schema:
626
+ type: string
627
+ minLength: 1
628
+ responses:
629
+ '200':
630
+ description: The per-attempt budgets.
631
+ content:
632
+ application/json:
633
+ schema:
634
+ type: object
635
+ additionalProperties: false
636
+ required:
637
+ - nodeId
638
+ - attempts
639
+ properties:
640
+ nodeId:
641
+ type: string
642
+ attempts:
643
+ type: array
644
+ items:
645
+ type: object
646
+ additionalProperties: false
647
+ required:
648
+ - maxTokens
649
+ properties:
650
+ maxTokens:
651
+ type:
652
+ - integer
653
+ - 'null'
654
+ minimum: 0
655
+ '400':
656
+ $ref: '#/components/responses/ValidationError'
657
+ '401':
658
+ $ref: '#/components/responses/Unauthenticated'
708
659
  /conformance/seams/sample/effect-seams/fire:
709
660
  post:
710
661
  tags:
711
662
  - Seams
712
663
  operationId: fireEffectSeam
713
- summary: Fire one named effect-seam manifest row inside a run — RFC 0173 §C no-re-fire witness
664
+ summary: Fire one named effect seam inside a run
714
665
  description: 'The host runs a workflow that drives the named seam once. The scenario then forks the run in `replay`
715
- mode and reads `GET /runs/{runId}/effects` on the fork: a GUARDED seam MUST NOT produce a new effect attempt there,
716
- because replay suppression is unconditional (`replay.md` §Suppression rule 1) and does not depend on `branchReFires`,
717
- which states only what a `branch` re-fires by design (§Branch: a host "MUST NOT report that as replay suppression").
718
- The witness is the host own Layer-2 ledger, so the leg needs no externally reachable receiver. Without this seam the
719
- replay-suppression obligation is only claims-checkable. HOW THE TARGET IS CHOSEN (suite 2.0.3): the scenario fires
720
- the first `GET /host/effect-seams` row with `guarded: true`, not every row, and records `inapplicable` without calling
721
- this operation at all when no row is guarded. Stated here because it is a contract an implementer cannot see from
722
- the request body — until 2.0.2 the filter also required `branchReFires: false`, and a host whose seams all honestly
723
- re-fire on branch would have built this seam only to find the scenario still declining to call it.'
666
+ mode and reads `GET /runs/{runId}/effects` on the fork. A guarded seam MUST NOT produce a new effect attempt there:
667
+ replay suppression is unconditional (`replay.md` §Suppression rule 1) and does not depend on `branchReFires`, which
668
+ states only what a `branch` re-fires by design (§Branch: a host "MUST NOT report that as replay suppression"). The
669
+ witness is the host''s own Layer-2 ledger, so the leg needs no externally reachable receiver.
670
+
671
+
672
+ The scenario fires the first `GET /host/effect-seams` row with `guarded: true`, not every row. When no row is guarded
673
+ it records `inapplicable` without calling this operation.'
724
674
  requestBody:
725
675
  required: true
726
676
  content:
@@ -734,12 +684,12 @@ paths:
734
684
  seam:
735
685
  type: string
736
686
  minLength: 1
737
- description: The `seam` value of a row in GET /host/effect-seams.
687
+ description: The `seam` value of a row in `GET /host/effect-seams`.
738
688
  receiverUrl:
739
689
  type: string
740
690
  format: uri
741
- description: Optional destination for seams whose kind needs one. Omitted, the host uses its own unreachable
742
- fixture destination — the witness is the effect ledger, not delivery.
691
+ description: Optional destination, for seams whose kind needs one. Omitted, the host uses its own unreachable
692
+ fixture destination; the witness is the effect ledger, not delivery.
743
693
  responses:
744
694
  '201':
745
695
  description: The run that fired the seam.
@@ -764,11 +714,10 @@ paths:
764
714
  tags:
765
715
  - Seams
766
716
  operationId: forceEffectTransportRetry
767
- summary: Drive one effect through the suite fixture provider with a forced transport retry — RFC 0173 §D.2 G4 witness
768
- description: 'The host issues one outbound effect to `providerUrl` and retries it at the transport layer. The suite
769
- fixture provider records the idempotency key of each attempt: a Layer-2 host MUST present the SAME business-identity
770
- key across both attempts, so a provider that sees a changed key fails the leg. Without this seam the effect-identity
771
- obligation is only claims-checkable.'
717
+ summary: Drive one effect through the suite's fixture provider with a forced transport retry
718
+ description: The host issues one outbound effect to `providerUrl` and retries it at the transport layer. The fixture
719
+ provider records the idempotency key of each attempt. A Layer-2 host MUST present the same business-identity key on
720
+ both attempts; a provider that sees a changed key fails the leg.
772
721
  requestBody:
773
722
  required: true
774
723
  content:
@@ -809,12 +758,11 @@ paths:
809
758
  tags:
810
759
  - Seams
811
760
  operationId: armIdempotencyHold
812
- summary: Hold the caller's next same-key create in flight — RFC 0213 §B witness
761
+ summary: Hold the caller's next same-key create in flight
813
762
  description: 'Arms a single-use hold: the caller tenant''s next real `POST /runs` carrying `key` as its Idempotency-Key
814
763
  keeps its Layer-1 claim in flight for `holdMs` after claiming, then completes normally. The seam MUST NOT answer a
815
764
  create or emit a 409: the refusal a concurrent same-key create receives while the claim is held comes from the host''s
816
- production in-flight branch (idempotency.md §Concurrency). Keyed by (tenant, key); single-use; an unarmed key is never
817
- delayed.'
765
+ production in-flight branch (idempotency.md §Concurrency). Keyed by (tenant, key); an unarmed key is never delayed.'
818
766
  requestBody:
819
767
  required: true
820
768
  content:
@@ -858,10 +806,11 @@ paths:
858
806
  tags:
859
807
  - Seams
860
808
  operationId: receiveWebhookDelivery
861
- summary: Run a webhook delivery through the host's inbound receiver — RFC 0176 §D.2 witness
862
- description: The v2 host as a subscriber. The host verifies `headers` + `body` with its production verifier using `secret`
863
- as the subscription secret and reports the verdict; an `X-openwop-*`-only scheme-`v1` delivery over `{timestamp}.{rawBody}`
864
- MUST be accepted (`v2-v1-signed-webhook-accepted`), and a tampered signature MUST be refused.
809
+ summary: Run a webhook delivery through the host's inbound receiver
810
+ description: Exercises the host as a webhook subscriber. The host verifies `headers` and `body` with its production
811
+ verifier, using `secret` as the subscription secret, and reports the verdict. A scheme-`v1` delivery carrying only
812
+ `X-openwop-*` headers, signed over `{timestamp}.{rawBody}`, MUST be accepted (`v2-v1-signed-webhook-accepted`); a
813
+ tampered signature MUST be refused.
865
814
  requestBody:
866
815
  required: true
867
816
  content:
@@ -907,19 +856,24 @@ paths:
907
856
  tags:
908
857
  - Seams
909
858
  operationId: emitA2uiSurface
910
- summary: Admit one `ui.a2ui-surface` envelope into a run through the production envelope-admission path — RFC 0209 witness
911
- description: 'A real `ui.a2ui-surface` envelope is emitted by a model inside a node turn, so the suite cannot choose
912
- one from the canonical wire. This seam supplies the envelope ONLY. The host MUST admit it through its PRODUCTION envelope-admission
913
- path — the envelope-kind catalog (`supportedEnvelopes`, `schemaVersions`, `envelopeStrictness`, events.md §"The envelope-kind
914
- catalog"), validation against the ONE per-kind branch the schema version selects (never the `anyOf` union), the RFC
915
- 0209 cross-field rules (every message `surfaceId` equals the payload `surfaceId`; a `createSurface.catalogId` equals
916
- the payload `catalogId`), the surface-fold guard (spec/v2/ext/a2uiSurface/README.md §"The fold"), trust propagation
917
- and SR-1 redaction — and MUST record it exactly as production would. It MUST NOT be a mock that records without those
918
- rules. `envelope.nodeId`, when present, binds the surface to that node, so a surface emitted at a node suspended on
919
- an `approval` interrupt is the surface whose `resume` action would resolve it (§"Trust": a tainted fold blocks that
920
- interrupt). Refusals use the canonical error envelope: `422 unknown_schema_version` above the floor or under `strict`
921
- below it, `422 envelope_invalid` for a payload that fails its branch, a cross-field rule or the fold guard, `422 unknown_envelope_kind`
922
- when the host does not list the kind; `details` SHOULD name the rule. A host that has not wired the seam answers `404`/`405`,
859
+ summary: Admit one `ui.a2ui-surface` envelope into a run through the production admission path
860
+ description: 'Supplies one `ui.a2ui-surface` envelope for the host to admit. A real one is emitted by a model inside
861
+ a node turn, so the suite cannot choose one from the canonical wire; this seam supplies the envelope only.
862
+
863
+
864
+ The host MUST admit it through its production envelope-admission path and MUST record it exactly as production would.
865
+ That path covers the envelope-kind catalog (`supportedEnvelopes`, `schemaVersions`, `envelopeStrictness`; events.md
866
+ §"The envelope-kind catalog"), validation against the one per-kind branch the schema version selects (never the `anyOf`
867
+ union), the cross-field rules (every message `surfaceId` equals the payload `surfaceId`; a `createSurface.catalogId`
868
+ equals the payload `catalogId`), the surface-fold guard (spec/v2/ext/a2uiSurface/README.md §"The fold"), trust propagation,
869
+ and SR-1 redaction. It MUST NOT be a mock that records without those rules. `envelope.nodeId`, when present, binds
870
+ the surface to that node, so a surface emitted at a node suspended on an `approval` interrupt is the surface whose
871
+ `resume` action would resolve it (§"Trust": a tainted fold blocks that interrupt).
872
+
873
+
874
+ Refusals use the canonical error envelope: `422 unknown_schema_version` above the floor, or below it under `strict`;
875
+ `422 envelope_invalid` for a payload that fails its branch, a cross-field rule, or the fold guard; `422 unknown_envelope_kind`
876
+ when the host does not list the kind. `details` SHOULD name the rule. A host that has not wired the seam answers `404`/`405`,
923
877
  and the scenario records `inapplicable`.'
924
878
  requestBody:
925
879
  required: true
@@ -969,19 +923,23 @@ paths:
969
923
  tags:
970
924
  - Seams
971
925
  operationId: startOAuthAuthorization
972
- summary: Begin an authorization-code grant for the caller through the production authorization-URL builder — RFC 0199
973
- §A/§B witness
974
- description: 'Points `provider` at the given endpoints (the suite''s authorization-server double) — a test-only provider
975
- definition, or, with `connection`, the connection pack''s provider through the host''s PRODUCTION registration path,
976
- which runs the RFC 0199 §B.3 discovery and pins its tuple — and then begins an authorization-code grant for the AUTHENTICATED
977
- caller by calling the host''s PRODUCTION authorization-URL builder, returning the URL a user agent would be redirected
978
- to. The builder MUST be the one production uses (PKCE S256, a fresh `state` bound to the caller''s Subject and the
979
- provider, the provider''s fixed redirect URI, `iss` expectations, `resource` for an MCP reach); a seam that assembles
980
- its own URL measures a stub, and a bundle citing it MUST say which. The grant completes on the host''s PRODUCTION
981
- callback route, which the suite calls as the user agent. `redirectUri` is a probe: the host MUST ignore it (the redirect
982
- URI is fixed per provider, oauth.md rule 5). A refused grant — an MCP-reach provider with no `issuer`, `pkce: "unsupported"`,
983
- or discovered metadata that disagrees with the manifest or the pinned tuple — is `422 connection_auth_metadata_mismatch`
984
- and no authorization URL is issued. A host that has not wired the seam answers `404`, and the scenarios record `blocked`.'
926
+ summary: Begin an authorization-code grant through the production authorization-URL builder
927
+ description: 'Points `provider` at the given endpoints (the suite''s authorization-server double), then begins an authorization-code
928
+ grant for the authenticated caller by calling the host''s production authorization-URL builder, and returns the URL
929
+ a user agent would be redirected to. The provider is a test-only provider definition or, with `connection`, the connection
930
+ pack''s provider registered through the host''s production registration path, which runs discovery and pins its tuple.
931
+
932
+
933
+ The builder MUST be the one production uses: PKCE S256, a fresh `state` bound to the caller''s Subject and the provider,
934
+ the provider''s fixed redirect URI, `iss` expectations, and `resource` for an MCP reach. A seam that assembles its
935
+ own URL measures a stub, and a bundle citing it MUST say which. The grant completes on the host''s production callback
936
+ route, which the suite calls as the user agent. `redirectUri` is a probe: the host MUST ignore it (the redirect URI
937
+ is fixed per provider, oauth.md rule 5).
938
+
939
+
940
+ A refused grant (an MCP-reach provider with no `issuer`, `pkce: "unsupported"`, or discovered metadata that disagrees
941
+ with the manifest or the pinned tuple) is `422 connection_auth_metadata_mismatch`, and no authorization URL is issued.
942
+ A host that has not wired the seam answers `404`, and the scenarios record `blocked`.'
985
943
  requestBody:
986
944
  required: true
987
945
  content:
@@ -1019,8 +977,8 @@ paths:
1019
977
  minLength: 1
1020
978
  connection:
1021
979
  $ref: ../schemas/v2/connection-pack-manifest.schema.json
1022
- description: A connection pack whose provider is reached as an MCP server (RFC 0199 §B); registered through
1023
- the production path.
980
+ description: A connection pack whose provider is reached as an MCP server; registered through the production
981
+ path.
1024
982
  redirectUri:
1025
983
  type: string
1026
984
  description: A probe the host MUST ignore.
@@ -1056,14 +1014,13 @@ paths:
1056
1014
  tags:
1057
1015
  - Seams
1058
1016
  operationId: expireOAuthAccessToken
1059
- summary: Expire the caller's stored access token for a provider so its next use refreshes — RFC 0199 §C.2(b) / RFC 0047
1060
- §C.3 witness
1061
- description: 'Marks the access token of the caller''s stored credential for `provider` expired. Nothing else: the next
1062
- node that uses it refreshes through the host''s PRODUCTION refresh path against the provider''s token endpoint (the
1063
- suite''s double, which decides whether the refresh token is still good). A terminal refresh failure then follows oauth.md
1064
- §Token lifecycle — `connector.auth-expired`, and either the node fails `connector_auth_expired` or, under `oauth.credentialInterrupt`,
1065
- it suspends on a `credential` interrupt with `reason: "expired"`. `404` when the caller holds no credential for the
1066
- provider.'
1017
+ summary: Expire the caller's stored access token for a provider so its next use refreshes
1018
+ description: 'Marks the access token of the caller''s stored credential for `provider` expired, and nothing else. The
1019
+ next node that uses it refreshes through the host''s production refresh path against the provider''s token endpoint
1020
+ (the suite''s double, which decides whether the refresh token is still good). A terminal refresh failure then follows
1021
+ oauth.md §Token lifecycle: `connector.auth-expired`, and either the node fails `connector_auth_expired` or, under
1022
+ `oauth.credentialInterrupt`, it suspends on a `credential` interrupt with `reason: "expired"`. `404` when the caller
1023
+ holds no credential for the provider.'
1067
1024
  requestBody:
1068
1025
  required: true
1069
1026
  content:
@@ -1091,9 +1048,9 @@ paths:
1091
1048
  tags:
1092
1049
  - Seams
1093
1050
  operationId: mintLaneCredential
1094
- summary: Mint a fresh credential on an advertised lane for the caller's tenant — RFC 0170 §B.3 witness
1051
+ summary: Mint a fresh credential on an advertised lane for the caller's tenant
1095
1052
  description: 'Issues a new credential on `lane` (an advertised `auth.lanes[].lane` whose `revocation` is `next-request`;
1096
- absent ⇒ `api-key`) for the AUTHENTICATED caller''s tenant, through the host''s PRODUCTION issuance path, so the credential
1053
+ absent ⇒ `api-key`) for the authenticated caller''s tenant, through the host''s production issuance path, so the credential
1097
1054
  it returns authenticates on the canonical API exactly as an ordinary one does. The suite uses it only to hold a credential
1098
1055
  it can then revoke: the revocation, and the refusal on the next request (`401 credential_revoked`), are production
1099
1056
  behaviour the seam does not simulate. A host that has not wired the seam answers `404`, and the scenario records the
@@ -1136,8 +1093,7 @@ paths:
1136
1093
  - kind
1137
1094
  description: 'How the suite presents `credential` on the canonical API. Absent ⇒ bearer. A lane whose
1138
1095
  production credential is cookie-borne (a `session` lane) answers `{ kind: "cookie", name }`, and the
1139
- suite sends `Cookie: <name>=<credential>`. Added so a cookie lane that honours `next-request` revocation
1140
- can be witnessed without advertising a false rule.'
1096
+ suite sends `Cookie: <name>=<credential>`.'
1141
1097
  properties:
1142
1098
  kind:
1143
1099
  type: string
@@ -1147,7 +1103,7 @@ paths:
1147
1103
  name:
1148
1104
  type: string
1149
1105
  pattern: ^[!#$%&'*+.^_`|~0-9A-Za-z-]+$
1150
- description: The cookie name (RFC 6265 token). Required when `kind` is `cookie`.
1106
+ description: The cookie name (an RFC 6265 token). Required when `kind` is `cookie`.
1151
1107
  if:
1152
1108
  properties:
1153
1109
  kind:
@@ -1170,8 +1126,8 @@ paths:
1170
1126
  tags:
1171
1127
  - Seams
1172
1128
  operationId: revokeLaneCredential
1173
- summary: Revoke a credential the mint seam issued — RFC 0170 §B.3 witness
1174
- description: Revokes `credential` through the host's PRODUCTION revocation path. On a `next-request` lane the very next
1129
+ summary: Revoke a credential the mint seam issued
1130
+ description: Revokes `credential` through the host's production revocation path. On a `next-request` lane the very next
1175
1131
  request presenting it MUST be refused `401 credential_revoked` (identity.md §2.2); the suite observes that on the
1176
1132
  canonical API, not through this seam. `404` when no active credential matches.
1177
1133
  requestBody:
@@ -1217,16 +1173,25 @@ paths:
1217
1173
  tags:
1218
1174
  - Seams
1219
1175
  operationId: getTranscriptWindow
1220
- summary: The host's own accounting of what it fed the model on one orchestrator turn — RFC 0111 witness
1221
- description: 'The orchestrator transcript a host assembles each iteration is host-internal and never crosses the wire.
1222
- This seam returns what the host fed the model on turn `iteration` of `runId`: `tokenCount` in the advertised `contextBudget.tokenCounter`
1223
- unit (MUST be ≤ `transcriptTokenBudget`), `eventIds` (the verbatim recent tail, in event-log order), `summarizedRanges`,
1224
- and `entries[] { eventId, rendered }` — the exact text fed per item, REQUIRED when `tokenCounter` is `chars` so the
1225
- suite can sum the rendered Unicode code points and require it to equal `tokenCount`. A summary substitution''s entry
1226
- names its `context.summarized` event and renders the summary text. Served in test mode only; `rendered` MUST NOT carry
1227
- secret material (SR-1). The ceiling is advertise-and-attest: the seam proves the declared accounting is consistent
1228
- and bounded, not that nothing else reached the model. A turn past the run''s last answers `400`/`422`; an unwired
1229
- seam answers `404`/`405`.'
1176
+ summary: Read the host's accounting of what it fed the model on one orchestrator turn
1177
+ description: 'Returns what the host fed the model on turn `iteration` of `runId`. The orchestrator transcript a host
1178
+ assembles each iteration is host-internal and never crosses the wire, so this seam reports the host''s own accounting:
1179
+
1180
+
1181
+ - `tokenCount`, in the advertised `contextBudget.tokenCounter` unit. MUST be ≤ `transcriptTokenBudget`.
1182
+
1183
+ - `eventIds`: the verbatim recent tail, in event-log order.
1184
+
1185
+ - `summarizedRanges`.
1186
+
1187
+ - `entries[] { eventId, rendered }`: the exact text fed per item. REQUIRED when `tokenCounter` is `chars`, so the
1188
+ suite can sum the rendered Unicode code points and require the sum to equal `tokenCount`. A summary substitution''s
1189
+ entry names its `context.summarized` event and renders the summary text.
1190
+
1191
+
1192
+ Served in test mode only; `rendered` MUST NOT carry secret material (SR-1). The ceiling is advertise-and-attest: the
1193
+ seam proves the declared accounting is consistent and bounded, not that nothing else reached the model. A turn past
1194
+ the run''s last answers `400`/`422`; an unwired seam answers `404`/`405`.'
1230
1195
  parameters:
1231
1196
  - name: runId
1232
1197
  in: query
@@ -1312,28 +1277,14 @@ components:
1312
1277
  type: http
1313
1278
  scheme: bearer
1314
1279
  bearerFormat: API key
1315
- description: 'openwop API key. Format implementation-defined; reference impl uses `hk_`/`hk_test_` prefixes.
1316
-
1317
- Each key carries one or more scopes from the canonical vocabulary
1318
-
1319
- (`manifest:read`, `runs:create`, `runs:read`, `runs:cancel`,
1320
-
1321
- `artifacts:read`, `webhooks:manage`, `approvals:respond`, `audit:read`).
1322
-
1323
- See `auth.md`.
1324
-
1325
- '
1280
+ description: OpenWOP API key. The format is implementation-defined; the reference implementation uses `hk_`/`hk_test_`
1281
+ prefixes. Each key carries one or more scopes from the canonical vocabulary (`manifest:read`, `runs:create`, `runs:read`,
1282
+ `runs:cancel`, `artifacts:read`, `webhooks:manage`, `approvals:respond`, `audit:read`). Scope matching is in `spec/v2/core/identity.md`
1283
+ §2.1.
1326
1284
  OAuth2:
1327
1285
  type: oauth2
1328
- description: 'RFC 0200 §F. OAuth 2.0 lanes — v1 `openwop-auth-oauth2-client-credentials`,
1329
-
1330
- v2 `auth.lanes[].lane: "oauth2"`. Discovery is RFC 9728 Protected Resource
1331
-
1332
- Metadata at the path-inserted well-known URI (`identity.md` §2.5).
1333
-
1334
- Placeholder URLs.
1335
-
1336
- '
1286
+ description: 'The OAuth 2.0 lane (`auth.lanes[].lane: "oauth2"`). Discovery is RFC 9728 Protected Resource Metadata
1287
+ at the path-inserted well-known URI (`identity.md` §2.5). The URLs are placeholders.'
1337
1288
  flows:
1338
1289
  clientCredentials:
1339
1290
  tokenUrl: https://issuer.example/oauth2/token
@@ -1385,26 +1336,14 @@ components:
1385
1336
  OpenIdConnect:
1386
1337
  type: openIdConnect
1387
1338
  openIdConnectUrl: https://issuer.example/.well-known/openid-configuration
1388
- description: 'RFC 0200 §F. v1 `openwop-auth-oidc-user-bearer` / v2 `auth.lanes[].lane: "oidc"`.
1389
-
1390
- An ID token MAY be the bearer only when its `aud` equals the host''s configured
1391
-
1392
- audience (`identity.md` §2.1); any other `aud` is `audience_mismatch`.
1393
-
1394
- Placeholder URL.
1395
-
1396
- '
1339
+ description: 'The OpenID Connect lane (`auth.lanes[].lane: "oidc"`). An ID token MAY be the bearer only when its `aud`
1340
+ equals the host''s configured audience (`identity.md` §2.1); any other `aud` is `audience_mismatch`. The URL is a
1341
+ placeholder.'
1397
1342
  MutualTLS:
1398
1343
  type: mutualTLS
1399
- description: 'RFC 0200 §F. v1 `openwop-auth-mtls` / v2 `auth.lanes[].lane: "mtls"`. In OpenWOP
1400
-
1401
- mTLS is required *in addition to* a bearer, never instead of one, so it appears
1402
-
1403
- in no canonical requirement below: a host that requires it adds `MutualTLS: []`
1404
-
1405
- inside each requirement object (AND).
1406
-
1407
- '
1344
+ description: 'The mTLS lane (`auth.lanes[].lane: "mtls"`). mTLS is required *in addition to* a bearer, never instead
1345
+ of one, so it appears in no canonical requirement below. A host that requires it adds `MutualTLS: []` inside each
1346
+ requirement object (AND).'
1408
1347
  parameters:
1409
1348
  IdempotencyKey:
1410
1349
  in: header
@@ -1413,15 +1352,8 @@ components:
1413
1352
  schema:
1414
1353
  type: string
1415
1354
  maxLength: 255
1416
- description: 'Per-mutation idempotency token (see `idempotency.md` Layer 1).
1417
-
1418
- Server caches `(tenantId, endpoint, key)` → response for ≥24h.
1419
-
1420
- Duplicate requests return the cached response with header
1421
-
1422
- `OpenWOP-Idempotent-Replay: true`.
1423
-
1424
- '
1355
+ description: 'Per-mutation idempotency token (`idempotency.md` Layer 1). The server caches `(tenantId, endpoint, key)`
1356
+ → response for ≥24h. A duplicate request returns the cached response with `OpenWOP-Idempotent-Replay: true`.'
1425
1357
  WorkspacePath:
1426
1358
  in: path
1427
1359
  name: path
@@ -1429,13 +1361,8 @@ components:
1429
1361
  schema:
1430
1362
  type: string
1431
1363
  pattern: ^[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$
1432
- description: 'RFC 0059 workspace-relative file path. Flat namespace with
1433
-
1434
- `/`-in-names; no `..`, no leading `/`. Matches
1435
-
1436
- `workspace-file.schema.json#path`.
1437
-
1438
- '
1364
+ description: Workspace-relative file path in a flat namespace that allows `/` in names; no `..` and no leading `/`.
1365
+ Matches `workspace-file.schema.json#path`.
1439
1366
  WorkspacePrefix:
1440
1367
  in: query
1441
1368
  name: prefix
@@ -1443,7 +1370,7 @@ components:
1443
1370
  schema:
1444
1371
  type: string
1445
1372
  maxLength: 256
1446
- description: RFC 0059. Optional prefix filter over the flat `path` namespace for `listWorkspaceFiles`.
1373
+ description: Optional prefix filter over the flat `path` namespace for `listWorkspaceFiles`.
1447
1374
  WorkspaceVersion:
1448
1375
  in: query
1449
1376
  name: version
@@ -1451,11 +1378,8 @@ components:
1451
1378
  schema:
1452
1379
  type: integer
1453
1380
  minimum: 1
1454
- description: 'RFC 0059. When `capabilities.workspace.versioned: true`, request the
1455
-
1456
- historical snapshot at this version. Absent = latest.
1457
-
1458
- '
1381
+ description: 'When `capabilities.workspace.versioned: true`, requests the historical snapshot at this version. Absent
1382
+ means latest.'
1459
1383
  IfMatch:
1460
1384
  in: header
1461
1385
  name: If-Match
@@ -1463,11 +1387,8 @@ components:
1463
1387
  schema:
1464
1388
  type: string
1465
1389
  maxLength: 255
1466
- description: 'RFC 0059 optimistic-concurrency token — the file''s current `etag`.
1467
-
1468
- A `PUT` carrying a stale `If-Match` returns `409 workspace_conflict`.
1469
-
1470
- '
1390
+ description: 'Optimistic-concurrency token: the file''s current `etag`. A `PUT` carrying a stale `If-Match` returns
1391
+ `409 workspace_conflict`.'
1471
1392
  PackName:
1472
1393
  in: path
1473
1394
  name: name
@@ -1490,8 +1411,8 @@ components:
1490
1411
  description: Missing or invalid credential.
1491
1412
  headers:
1492
1413
  WWW-Authenticate:
1493
- description: RFC 0200 §B — `Bearer` challenge; `resource_metadata` and `error="invalid_token"` on a host with an
1494
- oauth2/oidc lane. Never on a non-disclosure 404.
1414
+ description: A `Bearer` challenge. On a host with an oauth2 or oidc lane it carries `resource_metadata` and `error="invalid_token"`.
1415
+ Never sent on a non-disclosure 404.
1495
1416
  schema:
1496
1417
  type: string
1497
1418
  content:
@@ -1502,8 +1423,8 @@ components:
1502
1423
  description: Credential valid but lacks required scope or fails resource binding.
1503
1424
  headers:
1504
1425
  WWW-Authenticate:
1505
- description: RFC 0200 §B — `error="insufficient_scope"` with every required `scope` on a scope refusal; absent on
1506
- a resource-binding 403.
1426
+ description: On a scope refusal, `error="insufficient_scope"` with every required `scope`. Absent on a resource-binding
1427
+ 403.
1507
1428
  schema:
1508
1429
  type: string
1509
1430
  content:
@@ -1526,13 +1447,8 @@ components:
1526
1447
  Error:
1527
1448
  $ref: ../schemas/v2/error-envelope.schema.json
1528
1449
  TestPackPublishRecord:
1529
- description: 'Response body for a successful publish against the test-mode
1530
-
1531
- registry namespace (RFC 0025). Mirror of the production publish
1532
-
1450
+ description: Response body for a successful publish to the test-mode registry namespace. Mirrors the production publish
1533
1451
  record returned by `PUT /v1/packs/{name}/-/{version}.tgz`.
1534
-
1535
- '
1536
1452
  type: object
1537
1453
  required:
1538
1454
  - name