@openwop/openwop-conformance 2.42.1 → 2.42.3
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/CHANGELOG.md +37 -0
- package/README.md +1 -1
- package/coverage.md +1 -0
- package/dist/lib/certification-bundle-verify.js +13 -0
- package/dist/spec-artifacts.lock.json +2 -2
- package/package.json +2 -2
- package/requirements.json +91 -55
- package/schemas/CORPUS-STAMP.json +15 -15
- package/src/lib/carries-payload.ts +42 -0
- package/src/lib/certification-bundle-verify.ts +13 -0
- package/src/lib/effect-refire.ts +34 -0
- package/src/scenarios/certification-bundle-redaction.test.ts +1 -1
- package/src/scenarios/inbound-credential-no-passthrough.test.ts +13 -2
- package/src/scenarios/v2-a2ui-v09-surface.test.ts +8 -12
- package/src/scenarios/v2-advertised-fixtures-exist.test.ts +17 -3
- package/src/scenarios/v2-artifact-a2a-shape.test.ts +8 -2
- package/src/scenarios/v2-bound-id-kinds.test.ts +13 -4
- package/src/scenarios/v2-effect-identity-business-key.test.ts +48 -10
- package/src/scenarios/v2-effect-seam-manifest.test.ts +3 -9
- package/src/scenarios/v2-effect-seam-no-refire.test.ts +18 -5
- package/src/scenarios/v2-era-2-append-vocabulary.test.ts +52 -9
- package/src/scenarios/v2-interop-trace-context.test.ts +23 -0
- package/src/scenarios/v2-mcp-tasks.test.ts +16 -3
- package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +11 -0
- package/src/scenarios/v2-poll-cursor-v2.test.ts +28 -5
- package/src/scenarios/v2-profiles-derived-only.test.ts +9 -2
- package/src/scenarios/v2-webhook-delivery-isolation.test.ts +28 -8
- package/src/scenarios/v2-webhook-durable-delivery.test.ts +16 -0
- package/src/scenarios/v2-webhook-endpoint-verification.test.ts +25 -6
- package/src/scenarios/v2-webhook-message-id-stable.test.ts +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# `@openwop/openwop-conformance` Changelog
|
|
2
2
|
|
|
3
|
+
## [2.42.3] — 2026-09-27 — the unfailable-leg audit: 19 legs a non-conforming host could pass now measure their requirement
|
|
4
|
+
|
|
5
|
+
- **The unfailable-leg audit: 19 legs that a non-conforming host could pass now measure their requirement.** A scanner (`scripts/audit-unfailable-legs.mjs`, an audit aid, not a gate) flagged 66 legs that witness an Accepted RFC's Falsifiability row and have a shape this corpus has shipped as a defect before: satisfiable bounds (the 1 ≤ 1 no-refire leg), loops over a possibly empty list, `if`-guarded assertions, always-defined checks, and the host's own ledger as the only witness. A reviewer judged each one against a single bar: would a host that breaks the rule record `executed-pass`?
|
|
6
|
+
- **Confirmed and fixed (12):**
|
|
7
|
+
- `0173.effect-identity-business-key`: a no-op run's empty ledger passed on setup asserts.
|
|
8
|
+
- `.retry`: an omitted `providerKey` folded to `''`, so "one distinct key" passed.
|
|
9
|
+
- `0205.artifact-url-part-scoped`: a 3xx to a public pre-signed URL passed.
|
|
10
|
+
- `0176.era-2-append-vocabulary`: cancel appends names that are the same in v1 and v2, so the writer rule was never tested. It now records `blocked` unless a renamed type is appended. Its `era` leg now requires `eventLogSchemaVersion`.
|
|
11
|
+
- `0171.poll-cursor-v2.shape`: `lastSequence` must equal the log's highest sequence, and `status`/`isTerminal` must say terminal.
|
|
12
|
+
- `0173.webhook-durable-delivery`: exponential backoff must actually grow, second gap ≥ 1.5× the first.
|
|
13
|
+
- `0175.mrtr-rounds-ceiling.refused`: the refusal must come at the ceiling, not before it.
|
|
14
|
+
- `0215.no-head-of-line`: a serial dispatcher with a short timeout passed as a partial witness. It now fails below the concurrency floor and is otherwise `blocked`.
|
|
15
|
+
- `0187.bound-id-kinds.per-kind`, effectId/deliveryId: no-op runs record `inapplicable` before any assertion.
|
|
16
|
+
- `0173.effect-seam-manifest`: removed a loop that could not fail.
|
|
17
|
+
- RFC 0173 cites `effect-seam-no-refire` for replay suppression.
|
|
18
|
+
- RFC 0186 says its row is a schema-validation witness.
|
|
19
|
+
- **Plausible, tightened (7):**
|
|
20
|
+
- `0201.message-id-stable`: all four delivery keys are required, otherwise `blocked`.
|
|
21
|
+
- `0169.profiles-derived-only`: records need `status`, `since` and `witness`; a tautology is removed.
|
|
22
|
+
- `0200.inbound-credential-no-passthrough`: waits for THIS run's delivery.
|
|
23
|
+
- `0168.advertised-fixtures-exist`: samples across the whole list.
|
|
24
|
+
- `0198.task-update-approver-checked`: polls about 3 s rather than one 750 ms read.
|
|
25
|
+
- `0201.endpoint-verification`: a late echo control and a scaled grace; a missing control is `blocked`.
|
|
26
|
+
- `0207.a2a-malformed-ignored`: the task must not fail or be rejected.
|
|
27
|
+
- **Not defects:** 47 of the 66 flags; each reviewer recorded its reason.
|
|
28
|
+
- **Measured against the v2 reference host** (loopback regression lane) before merge.
|
|
29
|
+
- **RFC 0217 gap G1 closes in the contract peer.** `spec/v1/gaps.json` records MyndHyve's certified production witness of `0217.dead-letter-read-after-unregister` (openwop#1631). No scenario change.
|
|
30
|
+
- **Version moved ahead of publication.** `@openwop/openwop-conformance` and its exact-pinned peer `@openwop/spec-artifacts` move to `2.42.3` because `2.42.2` is tagged. Not tagged, not published.
|
|
31
|
+
|
|
32
|
+
## [2.42.2] — 2026-09-26 — four conformance legs now measure what their spec says: effect re-fire, keying fallback, A2UI JSON values, digest-safe scrubbing
|
|
33
|
+
|
|
34
|
+
- **`0173.effect-seam-no-refire` can detect a re-fire.** The leg asserted that the replay fork's ledger count was at most the parent's. The seam fires one attempt on the source run, so a host that re-fires on replay read 1 ≤ 1 and passed, over exactly the defect the leg exists for. ws3 measured it: openwop-app with `sideEffecting` dropped still passed. The leg now fails if the fork records any attempt the parent never made, using the new `lib/effect-refire.ts`. An inherited row repeats a parent attempt's `(nodeId, attempt, at)`, while a re-fire is a new attempt, and one parent row covers at most one fork row. A host whose fork projection is empty passes, as does one that projects the parent's attempts as history. The `effect-ledger-projection` schema description, which said the scenario "compares row COUNTS", is corrected. New suite self-test `src/lib/effect-refire.test.ts` uses a re-firing host stub as its first leg. It is sabotage-proved: with the old count rule restored, that leg fails.
|
|
35
|
+
- **RFC 0209 §C.11 compares JSON values, not JSON text, so a JSONB host can pass.** In `v2-a2ui-v09-surface`, `carries()` compared `JSON.stringify(subtree) === JSON.stringify(sent)`, which is order-sensitive. RFC 8259 §4 gives object member order no meaning, and a Postgres JSONB host re-sorts keys. ws5 measured `{version,catalogId,surfaceId,messages}` coming back as `{version,messages,catalogId,surfaceId}` on pg16. So `recorded-as-recorded` and `0209.legacy-readable` could never pass on a conforming JSONB host. The comparison now uses RFC 8785 (JCS) forms, via the new `lib/carries-payload.ts` built on `lib/jcs.ts`. A changed value, an added or dropped member, and reordered messages still fail. New suite self-test `src/lib/carries-payload.test.ts` covers the measured reordering as the positive leg and four negative controls. It is sabotage-proved: with the text comparison restored, the reordering leg fails. RFC 0209 carries a dated correction note. A sweep of every scenario for `JSON.stringify` equality found no other comparison of a suite-sent payload with a host-returned one. The rest compare two answers from the same host and route (`tools/list` twice, source vs fork, `v1` vs `v2` discovery), or arrays of numbers.
|
|
36
|
+
- **The 0173 retry leg accepts the keying the spec allows.** `v2-effect-identity-business-key` demanded `keying: business-identity` on every retried attempt. `idempotency.md` §Layer 2 makes the activity recipe "the fallback for a provider with no business key", and the seam's effect (a POST to a suite-chosen `providerUrl`) has none. So a host honestly declaring `activity-recipe` failed a rule the spec does not state. The leg now requires every attempt to declare a documented keying, the same one across attempts, and the same provider key. The last check was already there and is unchanged. Raised by openwop-app, whose seam began writing one ledger row per attempt.
|
|
37
|
+
- **`scrubEvidence` never rewrites inside a hex digest.** 2.40.3 stopped the environment sweep from collecting short and bare-integer values, after openwop-app's `OPENWOP_WEBHOOK_SECRET_ROTATION_OVERLAP_S=60` rewrote the "60" inside `discovery.sha256`. That failed the host's certify at random, roughly one bundle in five. But a credential the emitter hands over explicitly is still scrubbed whatever its shape, so the scrub itself could still corrupt a digest. A string that is wholly a hex digest (32+ hex characters, bare or `sha256:`-prefixed) is now left untouched unless it IS a secret. A secret inside a digest is a coincidence, not a leak, and rewriting it only breaks the evidence. A real leak in any other string is still redacted. Name classification needs no separate rule: a `*_S` / `*_MS` / `*_SECONDS` setting is a bare integer, which 2.40.3's floor already excludes. New suite self-test `src/lib/scrub-evidence-digest.test.ts` hands the scrub secrets that are substrings of a digest and asserts the digest survives while a neighbouring leak is redacted. It is sabotage-proved: without the guard, two of its three legs fail. **The 2.40.3 redaction leg was vacuous:** its fixture digest contained no "60", so it passed whether or not the value was scrubbed. The fixture now contains one.
|
|
38
|
+
- **Version moved ahead of publication.** `@openwop/openwop-conformance` and its exact-pinned peer `@openwop/spec-artifacts` move to `2.42.2` because `2.42.1` is tagged, and this cycle changes a shipped file: `spec/v1/gaps.json` records RFC 0111 gap G5 `closed` (RFC 0111 `Accepted`, witnessed by MyndHyve on 2.42.1). No scenario, schema or `MUST` change. Not tagged, not published.
|
|
39
|
+
|
|
3
40
|
## [2.42.1] — 2026-09-26 — RFC 0111's live witness scenarios outlast a real host, and the MCP run-transport leg identifies its own run
|
|
4
41
|
|
|
5
42
|
- **RFC 0111's live scenarios no longer die at vitest's 30 s default.** `context-budget-transcript-bound` and `context-summarization-replay` drive the live-model fixture `conformance-context-budget-live` (six real model turns and six child runs; 30–40 s per run on MyndHyve production, 2026-09-26), and the global `testTimeout: 30_000` killed both before any assertion — which `OPENWOP_POLL_TIMEOUT_SCALE` could not reach. Each now carries a per-test timeout from `liveScenarioTimeoutMs(runs)` (`src/lib/polling.ts`: the scaled sum of `LIVE_RUN_POLL_MS` = 180 s per run plus 60 s for seam reads — 240 s / 420 s at scale 1) and polls with `{ timeoutMs: LIVE_RUN_POLL_MS }`, so the named poll deadline always fires before the test deadline, at every scale. The global timeout is unchanged. Self-test: `src/lib/polling.test.ts` (3 new); an unscaled helper fails 2 of them and a 30 s helper 3.
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# --legacy-peer-deps is REQUIRED, not optional: the exact peer pin is what npm's
|
|
12
12
|
# default resolver refuses. npm 10.9 fails outright with
|
|
13
13
|
# "Cannot read properties of null (reading 'edgesOut')" — use npm >= 11.
|
|
14
|
-
npm install --legacy-peer-deps @openwop/openwop-conformance@2.42.
|
|
14
|
+
npm install --legacy-peer-deps @openwop/openwop-conformance@2.42.3 @openwop/spec-artifacts@2.42.3
|
|
15
15
|
# or run without install:
|
|
16
16
|
npx @openwop/openwop-conformance --base-url https://api.example.com --api-key hk_test_...
|
|
17
17
|
```
|
package/coverage.md
CHANGED
|
@@ -269,6 +269,7 @@ Every OpenAPI operation should have:
|
|
|
269
269
|
| `putTestPackTarball`, `getTestPackTarball`, `deleteTestPackVersion`, `getTestPackSignature` | `pack-registry-publish.test.ts` covers the 19-code publish error catalog through the RFC 0025 `/v1/packs-test/*` mirror namespace, gated on `capabilities.packs.testMode.supported: true` (RFC 0025 §A). 26 scenarios soft-skip when the advertisement is absent; when present, the suite exercises URL/scope, body-shape, tarball-extraction, manifest-contents, integrity, auth/conflict, unpublish-window, and signature-endpoint pairing. | Soft-skip on advertisement absence; behavioral on advertisement presence | Add real-tarball-builder fixtures so the manifest_mismatch / pack_integrity_failure / unsupported_runtime branches assert against a meaningful gzip+tar payload (currently soft-skipped with explanatory comments). |
|
|
270
270
|
| `getContentPage` | `localized-content-delivery.test.ts` (RFC 0103 §D) — always-on `localized-content-page-response.schema.json` shape + the §C `resolveSection` merge; gated live legs assert negotiated delivery + `Content-Language`. Public (anonymous-capable) endpoint, `security: []`. | Gated behavioral legs: published-only delivery, tenant isolation, no cross-tenant enumeration (`content-no-cross-tenant-enumeration`); cross-tenant slug → same `404`. | Behavioral legs soft-skip without a live `GET /v1/content/pages/{slug}`; non-vacuous against openwop-app + MyndHyve. |
|
|
271
271
|
| `listContentPages`, `createContentPage` | `localized-content-delivery.test.ts` (RFC 0103 §D) — `localized-content-page.schema.json` shape + §A coherence. | Protected admin ops document `401`/`403`; create documents `400`. Tenant-scoped (`content-response-tenant-scoped`). | Behavioral list/create round-trip pending a host admin seam. |
|
|
272
|
+
| `deleteContentPage` | No leg asserts it. `v2-content-locale-keys.test.ts` calls it only as best-effort cleanup, and its result is not asserted (RFC 0103 §D; added to the contract 2026-09-26). | `401`/`403`/`404`; `204` with no body. The same `404` for a `pageId` outside the caller's tenant (§F). | Uncovered. A behavioral delete (the page, its sections and its overlays are gone, and delivery answers `404`) is pending a host admin seam. The other four §D admin operations have no contract yet (RFC 0103 gap G12). |
|
|
272
273
|
| `putContentSection` | `localized-content-delivery.test.ts` (RFC 0103 §D) — `localized-content-section.schema.json` shape + the locale-targeted write body. | `401`/`403`/`404`/`400`; base-locale key + bad-key-case negatives. | Behavioral locale-targeted upsert pending a host admin seam. |
|
|
273
274
|
| `getContentSettings`, `putContentSettings` | `localized-content-delivery.test.ts` (RFC 0103 §B) — `localized-content-language-settings.schema.json` shape (base ∉ supported). | `401`/`403`; put documents `400` for the base ∈ supported violation. | Behavioral settings round-trip pending a host admin seam. |
|
|
274
275
|
|
|
@@ -208,6 +208,8 @@ export function verifyBundleV2(bundle) {
|
|
|
208
208
|
export function redactionMarker(secret) {
|
|
209
209
|
return `«redacted:${createHash('sha256').update(secret).digest('hex').slice(0, 12)}»`;
|
|
210
210
|
}
|
|
211
|
+
/** A whole-string hex digest: `sha256:`-prefixed or bare, 32+ hex characters. */
|
|
212
|
+
const HEX_DIGEST = /^(sha256:)?[0-9a-f]{32,}$/i;
|
|
211
213
|
/**
|
|
212
214
|
* Replace every occurrence of every secret in every string of `value` (keys
|
|
213
215
|
* included) with `redactionMarker(secret)`. Empty / whitespace-only secrets
|
|
@@ -223,6 +225,17 @@ export function scrubEvidence(value, secrets) {
|
|
|
223
225
|
if (live.length === 0)
|
|
224
226
|
return { value, redactedAt };
|
|
225
227
|
const scrubString = (s, path) => {
|
|
228
|
+
// A string that is wholly a hex digest (a sha256, a key fingerprint) is
|
|
229
|
+
// scrubbed only when it IS a secret, never for a secret found inside it.
|
|
230
|
+
// A secret inside a digest is a coincidence, not a leak: the digest does
|
|
231
|
+
// not disclose it. Rewriting it only corrupts the evidence. Suite 2.40.3
|
|
232
|
+
// floored the env sweep after openwop-app's `…_ROTATION_OVERLAP_S=60`
|
|
233
|
+
// rewrote the "60" inside `discovery.sha256`, but an explicitly handed
|
|
234
|
+
// credential is still scrubbed whatever its shape, so a short one (or any
|
|
235
|
+
// hex one) could still hit a digest at random. This closes that class at
|
|
236
|
+
// the scrub instead of at each source of secrets.
|
|
237
|
+
if (HEX_DIGEST.test(s) && !live.includes(s))
|
|
238
|
+
return s;
|
|
226
239
|
let out = s;
|
|
227
240
|
let hit = false;
|
|
228
241
|
for (const secret of live) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "2.42.
|
|
3
|
+
"version": "2.42.3",
|
|
4
4
|
"description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"@openwop/spec-artifacts": "file:../spec-artifacts"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@openwop/spec-artifacts": "2.42.
|
|
59
|
+
"@openwop/spec-artifacts": "2.42.3"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/requirements.json
CHANGED
|
@@ -14752,7 +14752,7 @@
|
|
|
14752
14752
|
{
|
|
14753
14753
|
"id": "openwop.it.inbound-credential-no-passthrough.no-webhook-delivery-carries-the-caller-s-authorization-cookie-or-proxy-authoriza",
|
|
14754
14754
|
"file": "inbound-credential-no-passthrough.test.ts",
|
|
14755
|
-
"line":
|
|
14755
|
+
"line": 71,
|
|
14756
14756
|
"title": "no webhook delivery carries the caller's Authorization, Cookie or Proxy-Authorization",
|
|
14757
14757
|
"explicitId": "openwop.requirement.0200.inbound-credential-no-passthrough",
|
|
14758
14758
|
"citations": [
|
|
@@ -27246,7 +27246,7 @@
|
|
|
27246
27246
|
{
|
|
27247
27247
|
"id": "openwop.it.v2-a2ui-v09-surface.a-version-2-envelope-carrying-a-version-1-body-is-refused-the-positive-is-admitt",
|
|
27248
27248
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27249
|
-
"line":
|
|
27249
|
+
"line": 131,
|
|
27250
27250
|
"title": "a version-2 envelope carrying a version-1 body is refused; the positive is admitted; above the floor is refused; below it follows envelopeStrictness",
|
|
27251
27251
|
"explicitId": "openwop.requirement.0209.version-selects-branch",
|
|
27252
27252
|
"citations": [
|
|
@@ -27290,7 +27290,7 @@
|
|
|
27290
27290
|
{
|
|
27291
27291
|
"id": "openwop.it.v2-a2ui-v09-surface.no-first-createsurface-a-message-after-deletesurface-and-a-second-createsurface",
|
|
27292
27292
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27293
|
-
"line":
|
|
27293
|
+
"line": 157,
|
|
27294
27294
|
"title": "no first createSurface, a message after deleteSurface, and a second createSurface are each refused; the valid steps are admitted",
|
|
27295
27295
|
"explicitId": "openwop.requirement.0209.fold-guarded",
|
|
27296
27296
|
"citations": [
|
|
@@ -27304,7 +27304,7 @@
|
|
|
27304
27304
|
{
|
|
27305
27305
|
"id": "openwop.it.v2-a2ui-v09-surface.a-createsurface-catalogid-differing-from-the-payload-catalogid-is-refused",
|
|
27306
27306
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27307
|
-
"line":
|
|
27307
|
+
"line": 182,
|
|
27308
27308
|
"title": "a createSurface.catalogId differing from the payload catalogId is refused",
|
|
27309
27309
|
"explicitId": "openwop.requirement.0209.catalog-equality",
|
|
27310
27310
|
"citations": [
|
|
@@ -27322,7 +27322,7 @@
|
|
|
27322
27322
|
{
|
|
27323
27323
|
"id": "openwop.it.v2-a2ui-v09-surface.a-message-whose-surfaceid-differs-from-the-payload-surfaceid-is-refused",
|
|
27324
27324
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27325
|
-
"line":
|
|
27325
|
+
"line": 196,
|
|
27326
27326
|
"title": "a message whose surfaceId differs from the payload surfaceId is refused",
|
|
27327
27327
|
"explicitId": "openwop.it.v2-a2ui-v09-surface.surface-id-equality",
|
|
27328
27328
|
"citations": [
|
|
@@ -27340,7 +27340,7 @@
|
|
|
27340
27340
|
{
|
|
27341
27341
|
"id": "openwop.it.v2-a2ui-v09-surface.a-recorded-version-2-surface-is-returned-byte-equal-on-poll-and-carried-by-a-for",
|
|
27342
27342
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27343
|
-
"line":
|
|
27343
|
+
"line": 214,
|
|
27344
27344
|
"title": "a recorded version-2 surface is returned byte-equal on poll and carried by a fork at a later fromSeq",
|
|
27345
27345
|
"explicitId": "openwop.it.v2-a2ui-v09-surface.recorded-as-recorded",
|
|
27346
27346
|
"citations": [
|
|
@@ -27351,7 +27351,7 @@
|
|
|
27351
27351
|
},
|
|
27352
27352
|
{
|
|
27353
27353
|
"section": "RFC 0209 §C.11",
|
|
27354
|
-
"requirement": "the run's poll MUST return the recorded surface payload
|
|
27354
|
+
"requirement": "the run's poll MUST return the recorded surface payload unchanged as JSON (JCS-equal; member order carries no meaning) — no surface is regenerated"
|
|
27355
27355
|
},
|
|
27356
27356
|
{
|
|
27357
27357
|
"section": "RFC 0209 §C.9",
|
|
@@ -27377,7 +27377,7 @@
|
|
|
27377
27377
|
{
|
|
27378
27378
|
"id": "openwop.it.v2-a2ui-v09-surface.a-version-1-surface-recorded-at-floor-1-is-returned-byte-equal-on-poll-and-carri",
|
|
27379
27379
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27380
|
-
"line":
|
|
27380
|
+
"line": 241,
|
|
27381
27381
|
"title": "a version-1 surface recorded at floor 1 is returned byte-equal on poll and carried by a fork",
|
|
27382
27382
|
"explicitId": "openwop.requirement.0209.legacy-readable",
|
|
27383
27383
|
"citations": [
|
|
@@ -27388,7 +27388,7 @@
|
|
|
27388
27388
|
},
|
|
27389
27389
|
{
|
|
27390
27390
|
"section": "RFC 0209 §C.11",
|
|
27391
|
-
"requirement": "the poll MUST return the version-1 surface
|
|
27391
|
+
"requirement": "the poll MUST return the version-1 surface unchanged as JSON (JCS-equal)"
|
|
27392
27392
|
},
|
|
27393
27393
|
{
|
|
27394
27394
|
"section": "RFC 0209 §C.11",
|
|
@@ -27414,7 +27414,7 @@
|
|
|
27414
27414
|
{
|
|
27415
27415
|
"id": "openwop.it.v2-a2ui-v09-surface.one-untrusted-update-taints-a-trusted-surface-a-later-trusted-update-does-not-la",
|
|
27416
27416
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27417
|
-
"line":
|
|
27417
|
+
"line": 265,
|
|
27418
27418
|
"title": "one untrusted update taints a trusted surface, a later trusted update does not launder it, and the approval does not advance; an all-trusted surface does",
|
|
27419
27419
|
"explicitId": "openwop.requirement.0209.taint-sticky",
|
|
27420
27420
|
"citations": [
|
|
@@ -27428,7 +27428,7 @@
|
|
|
27428
27428
|
{
|
|
27429
27429
|
"id": "openwop.it.v2-a2ui-v09-surface.records-why-render-needs-root-has-no-server-side-witness-and-where-its-witness-l",
|
|
27430
27430
|
"file": "v2-a2ui-v09-surface.test.ts",
|
|
27431
|
-
"line":
|
|
27431
|
+
"line": 304,
|
|
27432
27432
|
"title": "records why render-needs-root has no server-side witness, and where its witness lives",
|
|
27433
27433
|
"explicitId": "openwop.requirement.0209.render-needs-root",
|
|
27434
27434
|
"citations": [
|
|
@@ -27568,7 +27568,7 @@
|
|
|
27568
27568
|
{
|
|
27569
27569
|
"id": "openwop.it.v2-artifact-a2a-shape.records-why-export-alias-equivalence-has-no-wire-witness",
|
|
27570
27570
|
"file": "v2-artifact-a2a-shape.test.ts",
|
|
27571
|
-
"line":
|
|
27571
|
+
"line": 138,
|
|
27572
27572
|
"title": "records why export-alias-equivalence has no wire witness",
|
|
27573
27573
|
"explicitId": "openwop.requirement.0205.export-alias-equivalence",
|
|
27574
27574
|
"citations": [
|
|
@@ -27753,7 +27753,7 @@
|
|
|
27753
27753
|
{
|
|
27754
27754
|
"id": "openwop.it.v2-bound-id-kinds.deliveryid-every-record-in-the-dead-letter-read-carries-a-bound-id-in-the-caller",
|
|
27755
27755
|
"file": "v2-bound-id-kinds.test.ts",
|
|
27756
|
-
"line":
|
|
27756
|
+
"line": 235,
|
|
27757
27757
|
"title": "deliveryId: every record in the dead-letter read carries a bound id in the caller's tenant",
|
|
27758
27758
|
"explicitId": "openwop.requirement.0187.bound-id-kinds.per-kind",
|
|
27759
27759
|
"citations": [
|
|
@@ -28805,10 +28805,20 @@
|
|
|
28805
28805
|
{
|
|
28806
28806
|
"id": "openwop.it.v2-effect-identity-business-key.the-same-provider-key-is-presented-across-two-transport-retries",
|
|
28807
28807
|
"file": "v2-effect-identity-business-key.test.ts",
|
|
28808
|
-
"line":
|
|
28808
|
+
"line": 107,
|
|
28809
28809
|
"title": "the same provider key is presented across two transport retries",
|
|
28810
28810
|
"explicitId": "openwop.requirement.0173.effect-identity-business-key.retry",
|
|
28811
28811
|
"citations": [
|
|
28812
|
+
{
|
|
28813
|
+
"section": "spec/v2/core/idempotency.md §Layer 2: effect identity",
|
|
28814
|
+
"requirement": null,
|
|
28815
|
+
"interpolated": true
|
|
28816
|
+
},
|
|
28817
|
+
{
|
|
28818
|
+
"section": "spec/v2/core/idempotency.md §Layer 2: effect identity",
|
|
28819
|
+
"requirement": null,
|
|
28820
|
+
"interpolated": true
|
|
28821
|
+
},
|
|
28812
28822
|
{
|
|
28813
28823
|
"section": "spec/v2/core/idempotency.md §Layer 2: effect identity",
|
|
28814
28824
|
"requirement": null,
|
|
@@ -28861,11 +28871,6 @@
|
|
|
28861
28871
|
"requirement": null,
|
|
28862
28872
|
"interpolated": true
|
|
28863
28873
|
},
|
|
28864
|
-
{
|
|
28865
|
-
"section": "RFC 0173 §C.1",
|
|
28866
|
-
"requirement": null,
|
|
28867
|
-
"interpolated": true
|
|
28868
|
-
},
|
|
28869
28874
|
{
|
|
28870
28875
|
"section": "effect-seam-manifest.schema.json seams[].branchReFires",
|
|
28871
28876
|
"requirement": null,
|
|
@@ -28876,7 +28881,7 @@
|
|
|
28876
28881
|
{
|
|
28877
28882
|
"id": "openwop.it.v2-effect-seam-manifest.the-replay-facet-names-the-manifest-address-as-the-constant-host-effect-seams",
|
|
28878
28883
|
"file": "v2-effect-seam-manifest.test.ts",
|
|
28879
|
-
"line":
|
|
28884
|
+
"line": 112,
|
|
28880
28885
|
"title": "the replay facet names the manifest address as the constant /host/effect-seams",
|
|
28881
28886
|
"explicitId": "openwop.requirement.0173.effect-seam-manifest.facet",
|
|
28882
28887
|
"citations": [
|
|
@@ -28889,7 +28894,7 @@
|
|
|
28889
28894
|
{
|
|
28890
28895
|
"id": "openwop.it.v2-effect-seam-no-refire.driving-one-seam-of-each-kind-observes-no-re-fire-on-replay",
|
|
28891
28896
|
"file": "v2-effect-seam-no-refire.test.ts",
|
|
28892
|
-
"line":
|
|
28897
|
+
"line": 44,
|
|
28893
28898
|
"title": "driving one seam of each kind observes no re-fire on replay",
|
|
28894
28899
|
"explicitId": "openwop.requirement.0173.effect-seam-no-refire",
|
|
28895
28900
|
"citations": [
|
|
@@ -28976,7 +28981,7 @@
|
|
|
28976
28981
|
{
|
|
28977
28982
|
"id": "openwop.it.v2-era-2-append-vocabulary.the-run-keeps-the-era-it-was-created-with-an-append-does-not-promote-it-to-era-3",
|
|
28978
28983
|
"file": "v2-era-2-append-vocabulary.test.ts",
|
|
28979
|
-
"line":
|
|
28984
|
+
"line": 165,
|
|
28980
28985
|
"title": "the run keeps the era it was created with; an append does not promote it to era 3",
|
|
28981
28986
|
"explicitId": "openwop.requirement.0176.era-2-append-vocabulary",
|
|
28982
28987
|
"citations": [
|
|
@@ -29583,13 +29588,23 @@
|
|
|
29583
29588
|
{
|
|
29584
29589
|
"section": "spec/v2/core/interop.md §\"Trace context\" (RFC 0207)",
|
|
29585
29590
|
"requirement": "SendMessage MUST answer a normal result"
|
|
29591
|
+
},
|
|
29592
|
+
{
|
|
29593
|
+
"section": "spec/v2/core/interop.md §\"Trace context\" (RFC 0207)",
|
|
29594
|
+
"requirement": null,
|
|
29595
|
+
"interpolated": true
|
|
29596
|
+
},
|
|
29597
|
+
{
|
|
29598
|
+
"section": "spec/v2/core/interop.md §\"Trace context\" (RFC 0207)",
|
|
29599
|
+
"requirement": null,
|
|
29600
|
+
"interpolated": true
|
|
29586
29601
|
}
|
|
29587
29602
|
]
|
|
29588
29603
|
},
|
|
29589
29604
|
{
|
|
29590
29605
|
"id": "openwop.it.v2-interop-trace-context.a2a-interface-metadata-openwop-traceparent-is-the-parent-not-the-transport-heade",
|
|
29591
29606
|
"file": "v2-interop-trace-context.test.ts",
|
|
29592
|
-
"line":
|
|
29607
|
+
"line": 358,
|
|
29593
29608
|
"title": "A2A interface: metadata.openwop.traceparent is the parent, not the transport header",
|
|
29594
29609
|
"explicitId": "openwop.requirement.0207.a2a-inbound-adopts",
|
|
29595
29610
|
"citations": [
|
|
@@ -30493,7 +30508,7 @@
|
|
|
30493
30508
|
{
|
|
30494
30509
|
"id": "openwop.it.v2-mcp-tasks.a-mount-that-lists-the-tasks-extension-in-server-discover-also-lists-extensions",
|
|
30495
30510
|
"file": "v2-mcp-tasks.test.ts",
|
|
30496
|
-
"line":
|
|
30511
|
+
"line": 248,
|
|
30497
30512
|
"title": "a mount that lists the Tasks extension in server/discover also lists extensions in mcp.features",
|
|
30498
30513
|
"explicitId": "openwop.requirement.0198.advertised-via-discover",
|
|
30499
30514
|
"citations": [
|
|
@@ -30507,7 +30522,7 @@
|
|
|
30507
30522
|
{
|
|
30508
30523
|
"id": "openwop.it.v2-mcp-tasks.a-tools-call-declaring-the-extension-on-a-run-that-is-not-terminal-is-answered-c",
|
|
30509
30524
|
"file": "v2-mcp-tasks.test.ts",
|
|
30510
|
-
"line":
|
|
30525
|
+
"line": 255,
|
|
30511
30526
|
"title": "a tools/call declaring the extension on a run that is not terminal is answered CreateTaskResult",
|
|
30512
30527
|
"explicitId": "openwop.requirement.0198.task-when-nonterminal",
|
|
30513
30528
|
"citations": [
|
|
@@ -30546,7 +30561,7 @@
|
|
|
30546
30561
|
{
|
|
30547
30562
|
"id": "openwop.it.v2-mcp-tasks.taskid-is-the-run-id-in-its-projected-wire-form-with-an-opaque-segment-of-at-lea",
|
|
30548
30563
|
"file": "v2-mcp-tasks.test.ts",
|
|
30549
|
-
"line":
|
|
30564
|
+
"line": 275,
|
|
30550
30565
|
"title": "taskId is the run id in its projected wire form, with an opaque segment of at least 22 characters",
|
|
30551
30566
|
"explicitId": "openwop.requirement.0198.task-id-is-run-id",
|
|
30552
30567
|
"citations": [
|
|
@@ -30570,7 +30585,7 @@
|
|
|
30570
30585
|
{
|
|
30571
30586
|
"id": "openwop.it.v2-mcp-tasks.tasks-get-projects-input-required-keyed-by-interruptid-and-a-failed-run-as-compl",
|
|
30572
30587
|
"file": "v2-mcp-tasks.test.ts",
|
|
30573
|
-
"line":
|
|
30588
|
+
"line": 291,
|
|
30574
30589
|
"title": "tasks/get projects input_required keyed by interruptId, and a failed run as completed with isError true",
|
|
30575
30590
|
"explicitId": "openwop.requirement.0198.task-status-projection",
|
|
30576
30591
|
"citations": [
|
|
@@ -30602,7 +30617,7 @@
|
|
|
30602
30617
|
{
|
|
30603
30618
|
"id": "openwop.it.v2-mcp-tasks.tasks-update-answered-twice-resolves-the-interrupt-once-and-the-task-completes",
|
|
30604
30619
|
"file": "v2-mcp-tasks.test.ts",
|
|
30605
|
-
"line":
|
|
30620
|
+
"line": 314,
|
|
30606
30621
|
"title": "tasks/update answered twice resolves the interrupt once and the task completes",
|
|
30607
30622
|
"explicitId": "openwop.requirement.0198.task-update-resolves-once",
|
|
30608
30623
|
"citations": [
|
|
@@ -30630,7 +30645,7 @@
|
|
|
30630
30645
|
{
|
|
30631
30646
|
"id": "openwop.it.v2-mcp-tasks.a-tasks-update-from-a-caller-not-in-approverslist-resolves-nothing",
|
|
30632
30647
|
"file": "v2-mcp-tasks.test.ts",
|
|
30633
|
-
"line":
|
|
30648
|
+
"line": 334,
|
|
30634
30649
|
"title": "a tasks/update from a caller not in approversList resolves nothing",
|
|
30635
30650
|
"explicitId": "openwop.requirement.0198.task-update-approver-checked",
|
|
30636
30651
|
"citations": [
|
|
@@ -30658,7 +30673,7 @@
|
|
|
30658
30673
|
{
|
|
30659
30674
|
"id": "openwop.it.v2-mcp-tasks.tasks-get-appends-nothing-to-the-run-log",
|
|
30660
30675
|
"file": "v2-mcp-tasks.test.ts",
|
|
30661
|
-
"line":
|
|
30676
|
+
"line": 365,
|
|
30662
30677
|
"title": "tasks/get appends nothing to the run log",
|
|
30663
30678
|
"explicitId": "openwop.requirement.0198.task-get-read-only",
|
|
30664
30679
|
"citations": [
|
|
@@ -30672,7 +30687,7 @@
|
|
|
30672
30687
|
{
|
|
30673
30688
|
"id": "openwop.it.v2-mcp-tasks.an-unreadable-task-is-answered-32602-exactly-as-a-nonexistent-one",
|
|
30674
30689
|
"file": "v2-mcp-tasks.test.ts",
|
|
30675
|
-
"line":
|
|
30690
|
+
"line": 380,
|
|
30676
30691
|
"title": "an unreadable task is answered -32602 exactly as a nonexistent one",
|
|
30677
30692
|
"explicitId": "openwop.requirement.0198.task-unreadable-not-found",
|
|
30678
30693
|
"citations": [
|
|
@@ -30704,7 +30719,7 @@
|
|
|
30704
30719
|
{
|
|
30705
30720
|
"id": "openwop.it.v2-mcp-tasks.a-subscriptions-listen-acknowledgement-leaves-out-a-task-the-caller-cannot-read",
|
|
30706
30721
|
"file": "v2-mcp-tasks.test.ts",
|
|
30707
|
-
"line":
|
|
30722
|
+
"line": 413,
|
|
30708
30723
|
"title": "a subscriptions/listen acknowledgement leaves out a task the caller cannot read",
|
|
30709
30724
|
"explicitId": "openwop.requirement.0198.listen-omits-unreadable",
|
|
30710
30725
|
"citations": [
|
|
@@ -30732,7 +30747,7 @@
|
|
|
30732
30747
|
{
|
|
30733
30748
|
"id": "openwop.it.v2-mcp-tasks.tasks-cancel-cancels-the-run-on-a-terminal-task-it-is-acknowledged-and-appends-n",
|
|
30734
30749
|
"file": "v2-mcp-tasks.test.ts",
|
|
30735
|
-
"line":
|
|
30750
|
+
"line": 435,
|
|
30736
30751
|
"title": "tasks/cancel cancels the run; on a terminal task it is acknowledged and appends nothing",
|
|
30737
30752
|
"explicitId": "openwop.requirement.0198.task-cancel-cancels-run",
|
|
30738
30753
|
"citations": [
|
|
@@ -30764,7 +30779,7 @@
|
|
|
30764
30779
|
{
|
|
30765
30780
|
"id": "openwop.it.v2-mcp-tasks.a-client-disconnect-before-the-host-answers-a-task-less-tools-call-cancels-the-r",
|
|
30766
30781
|
"file": "v2-mcp-tasks.test.ts",
|
|
30767
|
-
"line":
|
|
30782
|
+
"line": 454,
|
|
30768
30783
|
"title": "a client disconnect before the host answers a task-less tools/call cancels the run it started",
|
|
30769
30784
|
"explicitId": "openwop.requirement.0198.disconnect-cancels-run",
|
|
30770
30785
|
"citations": [
|
|
@@ -30787,7 +30802,7 @@
|
|
|
30787
30802
|
{
|
|
30788
30803
|
"id": "openwop.it.v2-mcp-tasks.a-disconnect-after-createtaskresult-never-affects-the-run",
|
|
30789
30804
|
"file": "v2-mcp-tasks.test.ts",
|
|
30790
|
-
"line":
|
|
30805
|
+
"line": 474,
|
|
30791
30806
|
"title": "a disconnect after CreateTaskResult never affects the run",
|
|
30792
30807
|
"explicitId": "openwop.requirement.0198.task-survives-disconnect",
|
|
30793
30808
|
"citations": [
|
|
@@ -30806,7 +30821,7 @@
|
|
|
30806
30821
|
{
|
|
30807
30822
|
"id": "openwop.it.v2-mcp-tasks.a-blocking-tools-call-on-an-sse-stream-whose-run-is-cancelled-carries-no-notific",
|
|
30808
30823
|
"file": "v2-mcp-tasks.test.ts",
|
|
30809
|
-
"line":
|
|
30824
|
+
"line": 489,
|
|
30810
30825
|
"title": "a blocking tools/call on an SSE stream whose run is cancelled carries no notifications/cancelled and ends isError true",
|
|
30811
30826
|
"explicitId": "openwop.requirement.0198.no-server-cancelled",
|
|
30812
30827
|
"citations": [
|
|
@@ -30912,6 +30927,11 @@
|
|
|
30912
30927
|
"requirement": null,
|
|
30913
30928
|
"interpolated": true
|
|
30914
30929
|
},
|
|
30930
|
+
{
|
|
30931
|
+
"section": "interop.md §The MCP round ceiling",
|
|
30932
|
+
"requirement": null,
|
|
30933
|
+
"interpolated": true
|
|
30934
|
+
},
|
|
30915
30935
|
{
|
|
30916
30936
|
"section": "interop.md §The MCP round ceiling",
|
|
30917
30937
|
"requirement": null,
|
|
@@ -31675,7 +31695,7 @@
|
|
|
31675
31695
|
{
|
|
31676
31696
|
"id": "openwop.it.v2-poll-cursor-v2.the-response-is-the-closed-runid-events-lastsequence-status-isterminal",
|
|
31677
31697
|
"file": "v2-poll-cursor-v2.test.ts",
|
|
31678
|
-
"line":
|
|
31698
|
+
"line": 65,
|
|
31679
31699
|
"title": "the response is the closed { runId, events, lastSequence, status, isTerminal }",
|
|
31680
31700
|
"explicitId": "openwop.requirement.0171.poll-cursor-v2.shape",
|
|
31681
31701
|
"citations": [
|
|
@@ -31709,14 +31729,24 @@
|
|
|
31709
31729
|
},
|
|
31710
31730
|
{
|
|
31711
31731
|
"section": "spec/v2/core/events.md §Poll",
|
|
31712
|
-
"requirement":
|
|
31732
|
+
"requirement": null,
|
|
31733
|
+
"interpolated": true
|
|
31734
|
+
},
|
|
31735
|
+
{
|
|
31736
|
+
"section": "spec/v2/core/events.md §Poll",
|
|
31737
|
+
"requirement": "isTerminal is whether the run is terminal: the run was observed terminal, so isTerminal MUST be true"
|
|
31738
|
+
},
|
|
31739
|
+
{
|
|
31740
|
+
"section": "spec/v2/core/events.md §Poll",
|
|
31741
|
+
"requirement": null,
|
|
31742
|
+
"interpolated": true
|
|
31713
31743
|
}
|
|
31714
31744
|
]
|
|
31715
31745
|
},
|
|
31716
31746
|
{
|
|
31717
31747
|
"id": "openwop.it.v2-poll-cursor-v2.omitting-the-cursor-returns-from-the-first-event-sequence-0",
|
|
31718
31748
|
"file": "v2-poll-cursor-v2.test.ts",
|
|
31719
|
-
"line":
|
|
31749
|
+
"line": 100,
|
|
31720
31750
|
"title": "omitting the cursor returns from the first event (sequence 0)",
|
|
31721
31751
|
"explicitId": "openwop.requirement.0171.poll-cursor-v2.from-first",
|
|
31722
31752
|
"citations": [
|
|
@@ -31729,7 +31759,7 @@
|
|
|
31729
31759
|
{
|
|
31730
31760
|
"id": "openwop.it.v2-poll-cursor-v2.aftersequence-n-returns-only-events-with-sequence-n",
|
|
31731
31761
|
"file": "v2-poll-cursor-v2.test.ts",
|
|
31732
|
-
"line":
|
|
31762
|
+
"line": 110,
|
|
31733
31763
|
"title": "afterSequence=N returns only events with sequence > N",
|
|
31734
31764
|
"explicitId": "openwop.requirement.0171.poll-cursor-v2.after-sequence",
|
|
31735
31765
|
"citations": [
|
|
@@ -31751,7 +31781,7 @@
|
|
|
31751
31781
|
{
|
|
31752
31782
|
"id": "openwop.it.v2-poll-cursor-v2.a-cursor-past-the-end-of-the-log-returns-200-with-an-empty-events-array",
|
|
31753
31783
|
"file": "v2-poll-cursor-v2.test.ts",
|
|
31754
|
-
"line":
|
|
31784
|
+
"line": 144,
|
|
31755
31785
|
"title": "a cursor past the end of the log returns 200 with an empty events array",
|
|
31756
31786
|
"explicitId": "openwop.requirement.0171.poll-cursor-v2.past-end",
|
|
31757
31787
|
"citations": [
|
|
@@ -31835,7 +31865,7 @@
|
|
|
31835
31865
|
{
|
|
31836
31866
|
"id": "openwop.it.v2-profiles-derived-only.the-v2-document-carries-no-root-profiles",
|
|
31837
31867
|
"file": "v2-profiles-derived-only.test.ts",
|
|
31838
|
-
"line":
|
|
31868
|
+
"line": 48,
|
|
31839
31869
|
"title": "the v2 document carries no root `profiles[]`",
|
|
31840
31870
|
"explicitId": "openwop.requirement.0169.profiles-derived-only.no-root-profiles",
|
|
31841
31871
|
"citations": [
|
|
@@ -31848,7 +31878,7 @@
|
|
|
31848
31878
|
{
|
|
31849
31879
|
"id": "openwop.it.v2-profiles-derived-only.every-registry-profile-is-derivable-from-the-document-the-discovery-core-predica",
|
|
31850
31880
|
"file": "v2-profiles-derived-only.test.ts",
|
|
31851
|
-
"line":
|
|
31881
|
+
"line": 54,
|
|
31852
31882
|
"title": "every registry profile is derivable from the document; the discovery-core predicate holds on a valid document",
|
|
31853
31883
|
"explicitId": "openwop.requirement.0169.profiles-derived-only.derivable",
|
|
31854
31884
|
"citations": [
|
|
@@ -31861,11 +31891,6 @@
|
|
|
31861
31891
|
"requirement": null,
|
|
31862
31892
|
"interpolated": true
|
|
31863
31893
|
},
|
|
31864
|
-
{
|
|
31865
|
-
"section": "spec/v2/core/capabilities.md §7",
|
|
31866
|
-
"requirement": null,
|
|
31867
|
-
"interpolated": true
|
|
31868
|
-
},
|
|
31869
31894
|
{
|
|
31870
31895
|
"section": "spec/v2/core/capabilities.md §7",
|
|
31871
31896
|
"requirement": "openwop-discovery-core (metadata protocolVersions + preferredVersion, both REQUIRED at the root) MUST derive true from every valid v2 document"
|
|
@@ -33222,7 +33247,7 @@
|
|
|
33222
33247
|
{
|
|
33223
33248
|
"id": "openwop.requirement.0215.no-head-of-line",
|
|
33224
33249
|
"file": "v2-webhook-delivery-isolation.test.ts",
|
|
33225
|
-
"line":
|
|
33250
|
+
"line": 113,
|
|
33226
33251
|
"title": null,
|
|
33227
33252
|
"explicitId": "openwop.requirement.0215.no-head-of-line",
|
|
33228
33253
|
"citations": [
|
|
@@ -33251,7 +33276,8 @@
|
|
|
33251
33276
|
},
|
|
33252
33277
|
{
|
|
33253
33278
|
"section": "webhooks.md §Durability (RFC 0215 §A.1, §A.2)",
|
|
33254
|
-
"requirement":
|
|
33279
|
+
"requirement": null,
|
|
33280
|
+
"interpolated": true
|
|
33255
33281
|
},
|
|
33256
33282
|
{
|
|
33257
33283
|
"section": "webhooks.md §Durability (RFC 0215 §A.1, §A.2)",
|
|
@@ -33353,6 +33379,11 @@
|
|
|
33353
33379
|
"requirement": null,
|
|
33354
33380
|
"interpolated": true
|
|
33355
33381
|
},
|
|
33382
|
+
{
|
|
33383
|
+
"section": "webhooks.md §Durability",
|
|
33384
|
+
"requirement": null,
|
|
33385
|
+
"interpolated": true
|
|
33386
|
+
},
|
|
33356
33387
|
{
|
|
33357
33388
|
"section": "webhooks.md §Surfaces",
|
|
33358
33389
|
"requirement": "DELETE /webhooks/{webhookId} MUST answer 204"
|
|
@@ -33362,7 +33393,7 @@
|
|
|
33362
33393
|
{
|
|
33363
33394
|
"id": "openwop.it.v2-webhook-durable-delivery.an-exhausted-delivery-is-dead-lettered-never-dropped",
|
|
33364
33395
|
"file": "v2-webhook-durable-delivery.test.ts",
|
|
33365
|
-
"line":
|
|
33396
|
+
"line": 376,
|
|
33366
33397
|
"title": "an exhausted delivery is dead-lettered, never dropped",
|
|
33367
33398
|
"explicitId": "openwop.requirement.0173.webhook-durable-delivery.dead-letter",
|
|
33368
33399
|
"citations": [
|
|
@@ -33396,7 +33427,7 @@
|
|
|
33396
33427
|
{
|
|
33397
33428
|
"id": "openwop.it.v2-webhook-durable-delivery.the-dead-letter-read-is-served-and-its-records-carry-no-payload",
|
|
33398
33429
|
"file": "v2-webhook-durable-delivery.test.ts",
|
|
33399
|
-
"line":
|
|
33430
|
+
"line": 470,
|
|
33400
33431
|
"title": "the dead-letter read is served and its records carry no payload",
|
|
33401
33432
|
"explicitId": "openwop.requirement.0188.dead-letter-read",
|
|
33402
33433
|
"citations": [
|
|
@@ -33409,7 +33440,7 @@
|
|
|
33409
33440
|
{
|
|
33410
33441
|
"id": "openwop.it.v2-webhook-durable-delivery.after-unregister-the-dead-letter-read-answers-404-not-found-as-for-a-subscriptio",
|
|
33411
33442
|
"file": "v2-webhook-durable-delivery.test.ts",
|
|
33412
|
-
"line":
|
|
33443
|
+
"line": 491,
|
|
33413
33444
|
"title": "after unregister, the dead-letter read answers 404 not_found, as for a subscription that never existed",
|
|
33414
33445
|
"explicitId": "openwop.requirement.0217.dead-letter-read-after-unregister",
|
|
33415
33446
|
"citations": [
|
|
@@ -33436,7 +33467,7 @@
|
|
|
33436
33467
|
{
|
|
33437
33468
|
"id": "openwop.it.v2-webhook-durable-delivery.a-dead-letter-record-carries-no-delivered-payload",
|
|
33438
33469
|
"file": "v2-webhook-durable-delivery.test.ts",
|
|
33439
|
-
"line":
|
|
33470
|
+
"line": 524,
|
|
33440
33471
|
"title": "a dead-letter record carries no delivered payload",
|
|
33441
33472
|
"explicitId": "openwop.requirement.0188.dead-letter-content-free",
|
|
33442
33473
|
"citations": [
|
|
@@ -33473,7 +33504,7 @@
|
|
|
33473
33504
|
{
|
|
33474
33505
|
"id": "openwop.it.v2-webhook-endpoint-verification.no-echo-wrong-echo-and-a-redirect-are-refused-and-persist-nothing-an-echo-is-acc",
|
|
33475
33506
|
"file": "v2-webhook-endpoint-verification.test.ts",
|
|
33476
|
-
"line":
|
|
33507
|
+
"line": 68,
|
|
33477
33508
|
"title": "no-echo, wrong-echo and a redirect are refused and persist nothing; an echo is accepted",
|
|
33478
33509
|
"explicitId": "openwop.requirement.0201.endpoint-verification",
|
|
33479
33510
|
"citations": [
|
|
@@ -33492,6 +33523,11 @@
|
|
|
33492
33523
|
"requirement": null,
|
|
33493
33524
|
"interpolated": true
|
|
33494
33525
|
},
|
|
33526
|
+
{
|
|
33527
|
+
"section": "RFC 0201 §D.14",
|
|
33528
|
+
"requirement": null,
|
|
33529
|
+
"interpolated": true
|
|
33530
|
+
},
|
|
33495
33531
|
{
|
|
33496
33532
|
"section": "RFC 0201 §D.13–§D.14",
|
|
33497
33533
|
"requirement": null,
|